diff --git a/kernel/drivers/module-bbswitch/pspec.xml b/kernel/drivers/module-bbswitch/pspec.xml index 10cdb969..2c2ad81c 100644 --- a/kernel/drivers/module-bbswitch/pspec.xml +++ b/kernel/drivers/module-bbswitch/pspec.xml @@ -13,7 +13,7 @@ Kernel module allowing to switch dedicated graphics card on Optimus laptops kernel module allowing to switch dedicated graphics card on Optimus laptops - kernel-module-headers + kernel-module-headers https://github.com/Bumblebee-Project/bbswitch/archive/v0.8.tar.gz @@ -24,7 +24,7 @@ module-bbswitch - kernel + kernel bbswitch-common @@ -62,6 +62,13 @@ + + 2023-01-03 + 0.8 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-12-07 0.8 diff --git a/kernel/drivers/module-broadcom-wl/pspec.xml b/kernel/drivers/module-broadcom-wl/pspec.xml index 9663fa92..a3f43faf 100755 --- a/kernel/drivers/module-broadcom-wl/pspec.xml +++ b/kernel/drivers/module-broadcom-wl/pspec.xml @@ -15,7 +15,7 @@ https://docs.broadcom.com/docs-and-downloads/docs/linux_sta/hybrid-v35-nodebug-pcoem-6_30_223_271.tar.gz https://docs.broadcom.com/docs-and-downloads/docs/linux_sta/hybrid-v35_64-nodebug-pcoem-6_30_223_271.tar.gz - kernel-module-headers + kernel-module-headers broadcom-wl-6.30.223.271-debian-fix-kernel-warnings.patch @@ -41,7 +41,7 @@ module-broadcom-wl - kernel + kernel module-broadcom-wl-userspace @@ -70,6 +70,13 @@ + + 2023-01-03 + 6.30.223.271 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-12-07 6.30.223.271 diff --git a/kernel/drivers/module-virtualbox-guest/pspec.xml b/kernel/drivers/module-virtualbox-guest/pspec.xml index 7814ef3b..4ad0015a 100644 --- a/kernel/drivers/module-virtualbox-guest/pspec.xml +++ b/kernel/drivers/module-virtualbox-guest/pspec.xml @@ -14,7 +14,7 @@ This package provides the kernel modules needed for mouse integration and shared folder support between VirtualBox host and guest systems. https://sourceforge.net/projects/pisilinux/files/source/module-virtualbox-guest-7.0.4.tar.xz - kernel-module-headers + kernel-module-headers @@ -24,7 +24,7 @@ module-virtualbox-guest - kernel + kernel baselayout module-virtualbox-guest-userspace @@ -55,6 +55,13 @@ + + 2023-01-03 + 7.0.4 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-12-07 7.0.4 diff --git a/kernel/drivers/module-virtualbox/pspec.xml b/kernel/drivers/module-virtualbox/pspec.xml index 815cce57..e6873759 100644 --- a/kernel/drivers/module-virtualbox/pspec.xml +++ b/kernel/drivers/module-virtualbox/pspec.xml @@ -14,7 +14,7 @@ This package provides the kernel support for VirtualBox. https://sourceforge.net/projects/pisilinux/files/source/module-virtualbox-7.0.4.tar.xz - kernel-module-headers + kernel-module-headers Mbps */ ++DECLARE_EWMA(tp, 10, 2); ++ ++struct rtw89_traffic_stats { ++ /* units in bytes */ ++ u64 tx_unicast; ++ u64 rx_unicast; ++ u32 tx_avg_len; ++ u32 rx_avg_len; ++ ++ /* count for packets */ ++ u64 tx_cnt; ++ u64 rx_cnt; ++ ++ /* units in Mbps */ ++ u32 tx_throughput; ++ u32 rx_throughput; ++ u32 tx_throughput_raw; ++ u32 rx_throughput_raw; ++ enum rtw89_tfc_lv tx_tfc_lv; ++ enum rtw89_tfc_lv rx_tfc_lv; ++ struct ewma_tp tx_ewma_tp; ++ struct ewma_tp rx_ewma_tp; ++ ++ u16 tx_rate; ++ u16 rx_rate; ++}; ++ ++struct rtw89_btc_statistic { ++ u8 rssi; /* 0%~110% (dBm = rssi -110) */ ++ struct rtw89_traffic_stats traffic; ++}; ++ ++#define BTC_WL_RSSI_THMAX 4 ++ ++struct rtw89_btc_wl_link_info { ++ struct rtw89_btc_statistic stat; ++ enum rtw89_tfc_dir dir; ++ u8 rssi_state[BTC_WL_RSSI_THMAX]; ++ u8 mac_addr[ETH_ALEN]; ++ u8 busy; ++ u8 ch; ++ u8 bw; ++ u8 band; ++ u8 role; ++ u8 pid; ++ u8 phy; ++ u8 dtim_period; ++ u8 mode; ++ ++ u8 mac_id; ++ u8 tx_retry; ++ ++ u32 bcn_period; ++ u32 busy_t; ++ u32 tx_time; ++ u32 client_cnt; ++ u32 rx_rate_drop_cnt; ++ ++ u32 active: 1; ++ u32 noa: 1; ++ u32 client_ps: 1; ++ u32 connected: 2; ++}; ++ ++union rtw89_btc_wl_state_map { ++ u32 val; ++ struct rtw89_btc_wl_smap map; ++}; ++ ++struct rtw89_btc_bt_hfp_desc { ++ u32 exist: 1; ++ u32 type: 2; ++ u32 rsvd: 29; ++}; ++ ++struct rtw89_btc_bt_hid_desc { ++ u32 exist: 1; ++ u32 slot_info: 2; ++ u32 pair_cnt: 2; ++ u32 type: 8; ++ u32 rsvd: 19; ++}; ++ ++struct rtw89_btc_bt_a2dp_desc { ++ u8 exist: 1; ++ u8 exist_last: 1; ++ u8 play_latency: 1; ++ u8 type: 3; ++ u8 active: 1; ++ u8 sink: 1; ++ ++ u8 bitpool; ++ u16 vendor_id; ++ u32 device_name; ++ u32 flush_time; ++}; ++ ++struct rtw89_btc_bt_pan_desc { ++ u32 exist: 1; ++ u32 type: 1; ++ u32 active: 1; ++ u32 rsvd: 29; ++}; ++ ++struct rtw89_btc_bt_rfk_info { ++ u32 run: 1; ++ u32 req: 1; ++ u32 timeout: 1; ++ u32 rsvd: 29; ++}; ++ ++union rtw89_btc_bt_rfk_info_map { ++ u32 val; ++ struct rtw89_btc_bt_rfk_info map; ++}; ++ ++struct rtw89_btc_bt_ver_info { ++ u32 fw_coex; /* match with which coex_ver */ ++ u32 fw; ++}; ++ ++struct rtw89_btc_bool_sta_chg { ++ u32 now: 1; ++ u32 last: 1; ++ u32 remain: 1; ++ u32 srvd: 29; ++}; ++ ++struct rtw89_btc_u8_sta_chg { ++ u8 now; ++ u8 last; ++ u8 remain; ++ u8 rsvd; ++}; ++ ++struct rtw89_btc_wl_scan_info { ++ u8 band[RTW89_PHY_MAX]; ++ u8 phy_map; ++ u8 rsvd; ++}; ++ ++struct rtw89_btc_wl_dbcc_info { ++ u8 op_band[RTW89_PHY_MAX]; /* op band in each phy */ ++ u8 scan_band[RTW89_PHY_MAX]; /* scan band in each phy */ ++ u8 real_band[RTW89_PHY_MAX]; ++ u8 role[RTW89_PHY_MAX]; /* role in each phy */ ++}; ++ ++struct rtw89_btc_wl_active_role { ++ u8 connected: 1; ++ u8 pid: 3; ++ u8 phy: 1; ++ u8 noa: 1; ++ u8 band: 2; ++ ++ u8 client_ps: 1; ++ u8 bw: 7; ++ ++ u8 role; ++ u8 ch; ++ ++ u16 tx_lvl; ++ u16 rx_lvl; ++ u16 tx_rate; ++ u16 rx_rate; ++}; ++ ++struct rtw89_btc_wl_role_info_bpos { ++ u16 none: 1; ++ u16 station: 1; ++ u16 ap: 1; ++ u16 vap: 1; ++ u16 adhoc: 1; ++ u16 adhoc_master: 1; ++ u16 mesh: 1; ++ u16 moniter: 1; ++ u16 p2p_device: 1; ++ u16 p2p_gc: 1; ++ u16 p2p_go: 1; ++ u16 nan: 1; ++}; ++ ++union rtw89_btc_wl_role_info_map { ++ u16 val; ++ struct rtw89_btc_wl_role_info_bpos role; ++}; ++ ++struct rtw89_btc_wl_role_info { /* struct size must be n*4 bytes */ ++ u8 connect_cnt; ++ u8 link_mode; ++ union rtw89_btc_wl_role_info_map role_map; ++ struct rtw89_btc_wl_active_role active_role[RTW89_MAX_HW_PORT_NUM]; ++}; ++ ++struct rtw89_btc_wl_ver_info { ++ u32 fw_coex; /* match with which coex_ver */ ++ u32 fw; ++ u32 mac; ++ u32 bb; ++ u32 rf; ++}; ++ ++struct rtw89_btc_wl_afh_info { ++ u8 en; ++ u8 ch; ++ u8 bw; ++ u8 rsvd; ++} __packed; ++ ++struct rtw89_btc_wl_rfk_info { ++ u32 state: 2; ++ u32 path_map: 4; ++ u32 phy_map: 2; ++ u32 band: 2; ++ u32 type: 8; ++ u32 rsvd: 14; ++}; ++ ++struct rtw89_btc_bt_smap { ++ u32 connect: 1; ++ u32 ble_connect: 1; ++ u32 acl_busy: 1; ++ u32 sco_busy: 1; ++ u32 mesh_busy: 1; ++ u32 inq_pag: 1; ++}; ++ ++union rtw89_btc_bt_state_map { ++ u32 val; ++ struct rtw89_btc_bt_smap map; ++}; ++ ++#define BTC_BT_RSSI_THMAX 4 ++#define BTC_BT_AFH_GROUP 12 ++ ++struct rtw89_btc_bt_link_info { ++ struct rtw89_btc_u8_sta_chg profile_cnt; ++ struct rtw89_btc_bool_sta_chg multi_link; ++ struct rtw89_btc_bool_sta_chg relink; ++ struct rtw89_btc_bt_hfp_desc hfp_desc; ++ struct rtw89_btc_bt_hid_desc hid_desc; ++ struct rtw89_btc_bt_a2dp_desc a2dp_desc; ++ struct rtw89_btc_bt_pan_desc pan_desc; ++ union rtw89_btc_bt_state_map status; ++ ++ u8 sut_pwr_level[BTC_PROFILE_MAX]; ++ u8 golden_rx_shift[BTC_PROFILE_MAX]; ++ u8 rssi_state[BTC_BT_RSSI_THMAX]; ++ u8 afh_map[BTC_BT_AFH_GROUP]; ++ ++ u32 role_sw: 1; ++ u32 slave_role: 1; ++ u32 afh_update: 1; ++ u32 cqddr: 1; ++ u32 rssi: 8; ++ u32 tx_3m: 1; ++ u32 rsvd: 19; ++}; ++ ++struct rtw89_btc_3rdcx_info { ++ u8 type; /* 0: none, 1:zigbee, 2:LTE */ ++ u8 hw_coex; ++ u16 rsvd; ++}; ++ ++struct rtw89_btc_dm_emap { ++ u32 init: 1; ++ u32 pta_owner: 1; ++ u32 wl_rfk_timeout: 1; ++ u32 bt_rfk_timeout: 1; ++ ++ u32 wl_fw_hang: 1; ++ u32 offload_mismatch: 1; ++ u32 cycle_hang: 1; ++ u32 w1_hang: 1; ++ ++ u32 b1_hang: 1; ++ u32 tdma_no_sync: 1; ++ u32 wl_slot_drift: 1; ++}; ++ ++union rtw89_btc_dm_error_map { ++ u32 val; ++ struct rtw89_btc_dm_emap map; ++}; ++ ++struct rtw89_btc_rf_para { ++ u32 tx_pwr_freerun; ++ u32 rx_gain_freerun; ++ u32 tx_pwr_perpkt; ++ u32 rx_gain_perpkt; ++}; ++ ++struct rtw89_btc_wl_info { ++ struct rtw89_btc_wl_link_info link_info[RTW89_MAX_HW_PORT_NUM]; ++ struct rtw89_btc_wl_rfk_info rfk_info; ++ struct rtw89_btc_wl_ver_info ver_info; ++ struct rtw89_btc_wl_afh_info afh_info; ++ struct rtw89_btc_wl_role_info role_info; ++ struct rtw89_btc_wl_scan_info scan_info; ++ struct rtw89_btc_wl_dbcc_info dbcc_info; ++ struct rtw89_btc_rf_para rf_para; ++ union rtw89_btc_wl_state_map status; ++ ++ u8 port_id[RTW89_WIFI_ROLE_MLME_MAX]; ++ u8 rssi_level; ++ ++ u32 scbd; ++}; ++ ++struct rtw89_btc_module { ++ struct rtw89_btc_ant_info ant; ++ u8 rfe_type; ++ u8 cv; ++ ++ u8 bt_solo: 1; ++ u8 bt_pos: 1; ++ u8 switch_type: 1; ++ ++ u8 rsvd; ++}; ++ ++#define RTW89_BTC_DM_MAXSTEP 30 ++#define RTW89_BTC_DM_CNT_MAX (RTW89_BTC_DM_MAXSTEP * 8) ++ ++struct rtw89_btc_dm_step { ++ u16 step[RTW89_BTC_DM_MAXSTEP]; ++ u8 step_pos; ++ bool step_ov; ++}; ++ ++struct rtw89_btc_init_info { ++ struct rtw89_btc_module module; ++ u8 wl_guard_ch; ++ ++ u8 wl_only: 1; ++ u8 wl_init_ok: 1; ++ u8 dbcc_en: 1; ++ u8 cx_other: 1; ++ u8 bt_only: 1; ++ ++ u16 rsvd; ++}; ++ ++struct rtw89_btc_wl_tx_limit_para { ++ u16 enable; ++ u32 tx_time; /* unit: us */ ++ u16 tx_retry; ++}; ++ ++struct rtw89_btc_bt_scan_info { ++ u16 win; ++ u16 intvl; ++ u32 enable: 1; ++ u32 interlace: 1; ++ u32 rsvd: 30; ++}; ++ ++enum rtw89_btc_bt_scan_type { ++ BTC_SCAN_INQ = 0, ++ BTC_SCAN_PAGE, ++ BTC_SCAN_BLE, ++ BTC_SCAN_INIT, ++ BTC_SCAN_TV, ++ BTC_SCAN_ADV, ++ BTC_SCAN_MAX1, ++}; ++ ++struct rtw89_btc_bt_info { ++ struct rtw89_btc_bt_link_info link_info; ++ struct rtw89_btc_bt_scan_info scan_info[BTC_SCAN_MAX1]; ++ struct rtw89_btc_bt_ver_info ver_info; ++ struct rtw89_btc_bool_sta_chg enable; ++ struct rtw89_btc_bool_sta_chg inq_pag; ++ struct rtw89_btc_rf_para rf_para; ++ union rtw89_btc_bt_rfk_info_map rfk_info; ++ ++ u8 raw_info[BTC_BTINFO_MAX]; /* raw bt info from mailbox */ ++ ++ u32 scbd; ++ u32 feature; ++ ++ u32 mbx_avl: 1; ++ u32 whql_test: 1; ++ u32 igno_wl: 1; ++ u32 reinit: 1; ++ u32 ble_scan_en: 1; ++ u32 btg_type: 1; ++ u32 inq: 1; ++ u32 pag: 1; ++ u32 run_patch_code: 1; ++ u32 hi_lna_rx: 1; ++ u32 rsvd: 22; ++}; ++ ++struct rtw89_btc_cx { ++ struct rtw89_btc_wl_info wl; ++ struct rtw89_btc_bt_info bt; ++ struct rtw89_btc_3rdcx_info other; ++ u32 state_map; ++ u32 cnt_bt[BTC_BCNT_NUM]; ++ u32 cnt_wl[BTC_WCNT_NUM]; ++}; ++ ++struct rtw89_btc_fbtc_tdma { ++ u8 type; ++ u8 rxflctrl; ++ u8 txpause; ++ u8 wtgle_n; ++ u8 leak_n; ++ u8 ext_ctrl; ++ u8 rsvd0; ++ u8 rsvd1; ++} __packed; ++ ++#define CXMREG_MAX 30 ++#define FCXMAX_STEP 255 /*STEP trace record cnt, Max:65535, default:255*/ ++#define BTCRPT_VER 1 ++#define BTC_CYCLE_SLOT_MAX 48 /* must be even number, non-zero */ ++ ++enum rtw89_btc_bt_rfk_counter { ++ BTC_BCNT_RFK_REQ = 0, ++ BTC_BCNT_RFK_GO = 1, ++ BTC_BCNT_RFK_REJECT = 2, ++ BTC_BCNT_RFK_FAIL = 3, ++ BTC_BCNT_RFK_TIMEOUT = 4, ++ BTC_BCNT_RFK_MAX ++}; ++ ++struct rtw89_btc_fbtc_rpt_ctrl { ++ u16 fver; ++ u16 rpt_cnt; /* tmr counters */ ++ u32 wl_fw_coex_ver; /* match which driver's coex version */ ++ u32 wl_fw_cx_offload; ++ u32 wl_fw_ver; ++ u32 rpt_enable; ++ u32 rpt_para; /* ms */ ++ u32 mb_send_fail_cnt; /* fw send mailbox fail counter */ ++ u32 mb_send_ok_cnt; /* fw send mailbox ok counter */ ++ u32 mb_recv_cnt; /* fw recv mailbox counter */ ++ u32 mb_a2dp_empty_cnt; /* a2dp empty count */ ++ u32 mb_a2dp_flct_cnt; /* a2dp empty flow control counter */ ++ u32 mb_a2dp_full_cnt; /* a2dp empty full counter */ ++ u32 bt_rfk_cnt[BTC_BCNT_RFK_MAX]; ++ u32 c2h_cnt; /* fw send c2h counter */ ++ u32 h2c_cnt; /* fw recv h2c counter */ ++} __packed; ++ ++enum rtw89_fbtc_ext_ctrl_type { ++ CXECTL_OFF = 0x0, /* tdma off */ ++ CXECTL_B2 = 0x1, /* allow B2 (beacon-early) */ ++ CXECTL_EXT = 0x2, ++ CXECTL_MAX ++}; ++ ++union rtw89_btc_fbtc_rxflct { ++ u8 val; ++ u8 type: 3; ++ u8 tgln_n: 5; ++}; ++ ++enum rtw89_btc_cxst_state { ++ CXST_OFF = 0x0, ++ CXST_B2W = 0x1, ++ CXST_W1 = 0x2, ++ CXST_W2 = 0x3, ++ CXST_W2B = 0x4, ++ CXST_B1 = 0x5, ++ CXST_B2 = 0x6, ++ CXST_B3 = 0x7, ++ CXST_B4 = 0x8, ++ CXST_LK = 0x9, ++ CXST_BLK = 0xa, ++ CXST_E2G = 0xb, ++ CXST_E5G = 0xc, ++ CXST_EBT = 0xd, ++ CXST_ENULL = 0xe, ++ CXST_WLK = 0xf, ++ CXST_W1FDD = 0x10, ++ CXST_B1FDD = 0x11, ++ CXST_MAX = 0x12, ++}; ++ ++enum { ++ CXBCN_ALL = 0x0, ++ CXBCN_ALL_OK, ++ CXBCN_BT_SLOT, ++ CXBCN_BT_OK, ++ CXBCN_MAX ++}; ++ ++enum btc_slot_type { ++ SLOT_MIX = 0x0, /* accept BT Lower-Pri Tx/Rx request 0x778 = 1 */ ++ SLOT_ISO = 0x1, /* no accept BT Lower-Pri Tx/Rx request 0x778 = d*/ ++ CXSTYPE_NUM, ++}; ++ ++enum { /* TIME */ ++ CXT_BT = 0x0, ++ CXT_WL = 0x1, ++ CXT_MAX ++}; ++ ++enum { /* TIME-A2DP */ ++ CXT_FLCTRL_OFF = 0x0, ++ CXT_FLCTRL_ON = 0x1, ++ CXT_FLCTRL_MAX ++}; ++ ++enum { /* STEP TYPE */ ++ CXSTEP_NONE = 0x0, ++ CXSTEP_EVNT = 0x1, ++ CXSTEP_SLOT = 0x2, ++ CXSTEP_MAX, ++}; ++ ++#define FCXGPIODBG_VER 1 ++#define BTC_DBG_MAX1 32 ++struct rtw89_btc_fbtc_gpio_dbg { ++ u8 fver; ++ u8 rsvd; ++ u16 rsvd2; ++ u32 en_map; /* which debug signal (see btc_wl_gpio_debug) is enable */ ++ u32 pre_state; /* the debug signal is 1 or 0 */ ++ u8 gpio_map[BTC_DBG_MAX1]; /*the debug signals to GPIO-Position */ ++} __packed; ++ ++#define FCXMREG_VER 1 ++struct rtw89_btc_fbtc_mreg_val { ++ u8 fver; ++ u8 reg_num; ++ __le16 rsvd; ++ __le32 mreg_val[CXMREG_MAX]; ++} __packed; ++ ++#define RTW89_DEF_FBTC_MREG(__type, __bytes, __offset) \ ++ { .type = cpu_to_le16(__type), .bytes = cpu_to_le16(__bytes), \ ++ .offset = cpu_to_le32(__offset), } ++ ++struct rtw89_btc_fbtc_mreg { ++ __le16 type; ++ __le16 bytes; ++ __le32 offset; ++} __packed; ++ ++struct rtw89_btc_fbtc_slot { ++ __le16 dur; ++ __le32 cxtbl; ++ __le16 cxtype; ++} __packed; ++ ++#define FCXSLOTS_VER 1 ++struct rtw89_btc_fbtc_slots { ++ u8 fver; ++ u8 tbl_num; ++ __le16 rsvd; ++ __le32 update_map; ++ struct rtw89_btc_fbtc_slot slot[CXST_MAX]; ++} __packed; ++ ++#define FCXSTEP_VER 2 ++struct rtw89_btc_fbtc_step { ++ u8 type; ++ u8 val; ++ __le16 difft; ++} __packed; ++ ++struct rtw89_btc_fbtc_steps { ++ u8 fver; ++ u8 rsvd; ++ __le16 cnt; ++ __le16 pos_old; ++ __le16 pos_new; ++ struct rtw89_btc_fbtc_step step[FCXMAX_STEP]; ++} __packed; ++ ++#define FCXCYSTA_VER 2 ++struct rtw89_btc_fbtc_cysta { /* statistics for cycles */ ++ u8 fver; ++ u8 rsvd; ++ __le16 cycles; /* total cycle number */ ++ __le16 cycles_a2dp[CXT_FLCTRL_MAX]; ++ __le16 a2dpept; /* a2dp empty cnt */ ++ __le16 a2dpeptto; /* a2dp empty timeout cnt*/ ++ __le16 tavg_cycle[CXT_MAX]; /* avg wl/bt cycle time */ ++ __le16 tmax_cycle[CXT_MAX]; /* max wl/bt cycle time */ ++ __le16 tmaxdiff_cycle[CXT_MAX]; /* max wl-wl bt-bt cycle diff time */ ++ __le16 tavg_a2dp[CXT_FLCTRL_MAX]; /* avg a2dp PSTDMA/TDMA time */ ++ __le16 tmax_a2dp[CXT_FLCTRL_MAX]; /* max a2dp PSTDMA/TDMA time */ ++ __le16 tavg_a2dpept; /* avg a2dp empty time */ ++ __le16 tmax_a2dpept; /* max a2dp empty time */ ++ __le16 tavg_lk; /* avg leak-slot time */ ++ __le16 tmax_lk; /* max leak-slot time */ ++ __le32 slot_cnt[CXST_MAX]; /* slot count */ ++ __le32 bcn_cnt[CXBCN_MAX]; ++ __le32 leakrx_cnt; /* the rximr occur at leak slot */ ++ __le32 collision_cnt; /* counter for event/timer occur at same time */ ++ __le32 skip_cnt; ++ __le32 exception; ++ __le32 except_cnt; ++ __le16 tslot_cycle[BTC_CYCLE_SLOT_MAX]; ++} __packed; ++ ++#define FCXNULLSTA_VER 1 ++struct rtw89_btc_fbtc_cynullsta { /* cycle null statistics */ ++ u8 fver; ++ u8 rsvd; ++ __le16 rsvd2; ++ __le32 max_t[2]; /* max_t for 0:null0/1:null1 */ ++ __le32 avg_t[2]; /* avg_t for 0:null0/1:null1 */ ++ __le32 result[2][4]; /* 0:fail, 1:ok, 2:on_time, 3:retry */ ++} __packed; ++ ++#define FCX_BTVER_VER 1 ++struct rtw89_btc_fbtc_btver { ++ u8 fver; ++ u8 rsvd; ++ __le16 rsvd2; ++ __le32 coex_ver; /*bit[15:8]->shared, bit[7:0]->non-shared */ ++ __le32 fw_ver; ++ __le32 feature; ++} __packed; ++ ++#define FCX_BTSCAN_VER 1 ++struct rtw89_btc_fbtc_btscan { ++ u8 fver; ++ u8 rsvd; ++ __le16 rsvd2; ++ u8 scan[6]; ++} __packed; ++ ++#define FCX_BTAFH_VER 1 ++struct rtw89_btc_fbtc_btafh { ++ u8 fver; ++ u8 rsvd; ++ __le16 rsvd2; ++ u8 afh_l[4]; /*bit0:2402, bit1: 2403.... bit31:2433 */ ++ u8 afh_m[4]; /*bit0:2434, bit1: 2435.... bit31:2465 */ ++ u8 afh_h[4]; /*bit0:2466, bit1:2467......bit14:2480 */ ++} __packed; ++ ++#define FCX_BTDEVINFO_VER 1 ++struct rtw89_btc_fbtc_btdevinfo { ++ u8 fver; ++ u8 rsvd; ++ __le16 vendor_id; ++ __le32 dev_name; /* only 24 bits valid */ ++ __le32 flush_time; ++} __packed; ++ ++#define RTW89_BTC_WL_DEF_TX_PWR GENMASK(7, 0) ++struct rtw89_btc_rf_trx_para { ++ u32 wl_tx_power; /* absolute Tx power (dBm), 0xff-> no BTC control */ ++ u32 wl_rx_gain; /* rx gain table index (TBD.) */ ++ u8 bt_tx_power; /* decrease Tx power (dB) */ ++ u8 bt_rx_gain; /* LNA constrain level */ ++}; ++ ++struct rtw89_btc_dm { ++ struct rtw89_btc_fbtc_slot slot[CXST_MAX]; ++ struct rtw89_btc_fbtc_slot slot_now[CXST_MAX]; ++ struct rtw89_btc_fbtc_tdma tdma; ++ struct rtw89_btc_fbtc_tdma tdma_now; ++ struct rtw89_mac_ax_coex_gnt gnt; ++ struct rtw89_btc_init_info init_info; /* pass to wl_fw if offload */ ++ struct rtw89_btc_rf_trx_para rf_trx_para; ++ struct rtw89_btc_wl_tx_limit_para wl_tx_limit; ++ struct rtw89_btc_dm_step dm_step; ++ union rtw89_btc_dm_error_map error; ++ u32 cnt_dm[BTC_DCNT_NUM]; ++ u32 cnt_notify[BTC_NCNT_NUM]; ++ ++ u32 update_slot_map; ++ u32 set_ant_path; ++ ++ u32 wl_only: 1; ++ u32 wl_fw_cx_offload: 1; ++ u32 freerun: 1; ++ u32 wl_ps_ctrl: 2; ++ u32 wl_mimo_ps: 1; ++ u32 leak_ap: 1; ++ u32 noisy_level: 3; ++ u32 coex_info_map: 8; ++ u32 bt_only: 1; ++ u32 wl_btg_rx: 1; ++ u32 trx_para_level: 8; ++ u32 wl_stb_chg: 1; ++ u32 rsvd: 3; ++ ++ u16 slot_dur[CXST_MAX]; ++ ++ u8 run_reason; ++ u8 run_action; ++}; ++ ++struct rtw89_btc_ctrl { ++ u32 manual: 1; ++ u32 igno_bt: 1; ++ u32 always_freerun: 1; ++ u32 trace_step: 16; ++ u32 rsvd: 12; ++}; ++ ++struct rtw89_btc_dbg { ++ /* cmd "rb" */ ++ bool rb_done; ++ u32 rb_val; ++}; ++ ++#define FCXTDMA_VER 1 ++ ++enum rtw89_btc_btf_fw_event { ++ BTF_EVNT_RPT = 0, ++ BTF_EVNT_BT_INFO = 1, ++ BTF_EVNT_BT_SCBD = 2, ++ BTF_EVNT_BT_REG = 3, ++ BTF_EVNT_CX_RUNINFO = 4, ++ BTF_EVNT_BT_PSD = 5, ++ BTF_EVNT_BUF_OVERFLOW, ++ BTF_EVNT_C2H_LOOPBACK, ++ BTF_EVNT_MAX, ++}; ++ ++enum btf_fw_event_report { ++ BTC_RPT_TYPE_CTRL = 0x0, ++ BTC_RPT_TYPE_TDMA, ++ BTC_RPT_TYPE_SLOT, ++ BTC_RPT_TYPE_CYSTA, ++ BTC_RPT_TYPE_STEP, ++ BTC_RPT_TYPE_NULLSTA, ++ BTC_RPT_TYPE_MREG, ++ BTC_RPT_TYPE_GPIO_DBG, ++ BTC_RPT_TYPE_BT_VER, ++ BTC_RPT_TYPE_BT_SCAN, ++ BTC_RPT_TYPE_BT_AFH, ++ BTC_RPT_TYPE_BT_DEVICE, ++ BTC_RPT_TYPE_TEST, ++ BTC_RPT_TYPE_MAX = 31 ++}; ++ ++enum rtw_btc_btf_reg_type { ++ REG_MAC = 0x0, ++ REG_BB = 0x1, ++ REG_RF = 0x2, ++ REG_BT_RF = 0x3, ++ REG_BT_MODEM = 0x4, ++ REG_BT_BLUEWIZE = 0x5, ++ REG_BT_VENDOR = 0x6, ++ REG_BT_LE = 0x7, ++ REG_MAX_TYPE, ++}; ++ ++struct rtw89_btc_rpt_cmn_info { ++ u32 rx_cnt; ++ u32 rx_len; ++ u32 req_len; /* expected rsp len */ ++ u8 req_fver; /* expected rsp fver */ ++ u8 rsp_fver; /* fver from fw */ ++ u8 valid; ++} __packed; ++ ++struct rtw89_btc_report_ctrl_state { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_rpt_ctrl finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_tdma { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_tdma finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_slots { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_slots finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_cysta { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_cysta finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_step { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_steps finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_nullsta { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_cynullsta finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_mreg { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_mreg_val finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_gpio_dbg { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_gpio_dbg finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_btver { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_btver finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_btscan { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_btscan finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_btafh { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_btafh finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_btdev { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_btdevinfo finfo; /* info from fw */ ++}; ++ ++enum rtw89_btc_btfre_type { ++ BTFRE_INVALID_INPUT = 0x0, /* invalid input parameters */ ++ BTFRE_UNDEF_TYPE, ++ BTFRE_EXCEPTION, ++ BTFRE_MAX, ++}; ++ ++struct rtw89_btc_btf_fwinfo { ++ u32 cnt_c2h; ++ u32 cnt_h2c; ++ u32 cnt_h2c_fail; ++ u32 event[BTF_EVNT_MAX]; ++ ++ u32 err[BTFRE_MAX]; ++ u32 len_mismch; ++ u32 fver_mismch; ++ u32 rpt_en_map; ++ ++ struct rtw89_btc_report_ctrl_state rpt_ctrl; ++ struct rtw89_btc_rpt_fbtc_tdma rpt_fbtc_tdma; ++ struct rtw89_btc_rpt_fbtc_slots rpt_fbtc_slots; ++ struct rtw89_btc_rpt_fbtc_cysta rpt_fbtc_cysta; ++ struct rtw89_btc_rpt_fbtc_step rpt_fbtc_step; ++ struct rtw89_btc_rpt_fbtc_nullsta rpt_fbtc_nullsta; ++ struct rtw89_btc_rpt_fbtc_mreg rpt_fbtc_mregval; ++ struct rtw89_btc_rpt_fbtc_gpio_dbg rpt_fbtc_gpio_dbg; ++ struct rtw89_btc_rpt_fbtc_btver rpt_fbtc_btver; ++ struct rtw89_btc_rpt_fbtc_btscan rpt_fbtc_btscan; ++ struct rtw89_btc_rpt_fbtc_btafh rpt_fbtc_btafh; ++ struct rtw89_btc_rpt_fbtc_btdev rpt_fbtc_btdev; ++}; ++ ++#define RTW89_BTC_POLICY_MAXLEN 512 ++ ++struct rtw89_btc { ++ struct rtw89_btc_cx cx; ++ struct rtw89_btc_dm dm; ++ struct rtw89_btc_ctrl ctrl; ++ struct rtw89_btc_module mdinfo; ++ struct rtw89_btc_btf_fwinfo fwinfo; ++ struct rtw89_btc_dbg dbg; ++ ++ struct work_struct eapol_notify_work; ++ struct work_struct arp_notify_work; ++ struct work_struct dhcp_notify_work; ++ struct work_struct icmp_notify_work; ++ ++ u32 bt_req_len; ++ ++ u8 policy[RTW89_BTC_POLICY_MAXLEN]; ++ u16 policy_len; ++ u16 policy_type; ++ bool bt_req_en; ++ bool update_policy_force; ++ bool lps; ++}; ++ ++enum rtw89_ra_mode { ++ RTW89_RA_MODE_CCK = BIT(0), ++ RTW89_RA_MODE_OFDM = BIT(1), ++ RTW89_RA_MODE_HT = BIT(2), ++ RTW89_RA_MODE_VHT = BIT(3), ++ RTW89_RA_MODE_HE = BIT(4), ++}; ++ ++enum rtw89_ra_report_mode { ++ RTW89_RA_RPT_MODE_LEGACY, ++ RTW89_RA_RPT_MODE_HT, ++ RTW89_RA_RPT_MODE_VHT, ++ RTW89_RA_RPT_MODE_HE, ++}; ++ ++enum rtw89_dig_noisy_level { ++ RTW89_DIG_NOISY_LEVEL0 = -1, ++ RTW89_DIG_NOISY_LEVEL1 = 0, ++ RTW89_DIG_NOISY_LEVEL2 = 1, ++ RTW89_DIG_NOISY_LEVEL3 = 2, ++ RTW89_DIG_NOISY_LEVEL_MAX = 3, ++}; ++ ++enum rtw89_gi_ltf { ++ RTW89_GILTF_LGI_4XHE32 = 0, ++ RTW89_GILTF_SGI_4XHE08 = 1, ++ RTW89_GILTF_2XHE16 = 2, ++ RTW89_GILTF_2XHE08 = 3, ++ RTW89_GILTF_1XHE16 = 4, ++ RTW89_GILTF_1XHE08 = 5, ++ RTW89_GILTF_MAX ++}; ++ ++enum rtw89_rx_frame_type { ++ RTW89_RX_TYPE_MGNT = 0, ++ RTW89_RX_TYPE_CTRL = 1, ++ RTW89_RX_TYPE_DATA = 2, ++ RTW89_RX_TYPE_RSVD = 3, ++}; ++ ++struct rtw89_ra_info { ++ u8 is_dis_ra:1; ++ /* Bit0 : CCK ++ * Bit1 : OFDM ++ * Bit2 : HT ++ * Bit3 : VHT ++ * Bit4 : HE ++ */ ++ u8 mode_ctrl:5; ++ u8 bw_cap:2; ++ u8 macid; ++ u8 dcm_cap:1; ++ u8 er_cap:1; ++ u8 init_rate_lv:2; ++ u8 upd_all:1; ++ u8 en_sgi:1; ++ u8 ldpc_cap:1; ++ u8 stbc_cap:1; ++ u8 ss_num:3; ++ u8 giltf:3; ++ u8 upd_bw_nss_mask:1; ++ u8 upd_mask:1; ++ u64 ra_mask; /* 63 bits ra_mask + 1 bit CSI ctrl */ ++ /* BFee CSI */ ++ u8 band_num; ++ u8 ra_csi_rate_en:1; ++ u8 fixed_csi_rate_en:1; ++ u8 cr_tbl_sel:1; ++ u8 rsvd2:5; ++ u8 csi_mcs_ss_idx; ++ u8 csi_mode:2; ++ u8 csi_gi_ltf:3; ++ u8 csi_bw:3; ++}; ++ ++#define RTW89_PPDU_MAX_USR 4 ++#define RTW89_PPDU_MAC_INFO_USR_SIZE 4 ++#define RTW89_PPDU_MAC_INFO_SIZE 8 ++#define RTW89_PPDU_MAC_RX_CNT_SIZE 96 ++ ++#define RTW89_MAX_RX_AGG_NUM 64 ++#define RTW89_MAX_TX_AGG_NUM 128 ++ ++struct rtw89_ampdu_params { ++ u16 agg_num; ++ bool amsdu; ++}; ++ ++struct rtw89_ra_report { ++ struct rate_info txrate; ++ u32 bit_rate; ++ u16 hw_rate; ++}; ++ ++DECLARE_EWMA(rssi, 10, 16); ++ ++struct rtw89_sta { ++ u8 mac_id; ++ bool disassoc; ++ struct rtw89_vif *rtwvif; ++ struct rtw89_ra_info ra; ++ struct rtw89_ra_report ra_report; ++ int max_agg_wait; ++ u8 prev_rssi; ++ struct ewma_rssi avg_rssi; ++ struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS]; ++ struct ieee80211_rx_status rx_status; ++ u16 rx_hw_rate; ++ __le32 htc_template; ++ ++ bool use_cfg_mask; ++ struct cfg80211_bitrate_mask mask; ++ ++ bool cctl_tx_time; ++ u32 ampdu_max_time:4; ++ bool cctl_tx_retry_limit; ++ u32 data_tx_cnt_lmt:6; ++}; ++ ++#define RTW89_MAX_ADDR_CAM_NUM 128 ++#define RTW89_MAX_BSSID_CAM_NUM 20 ++#define RTW89_MAX_SEC_CAM_NUM 128 ++#define RTW89_SEC_CAM_IN_ADDR_CAM 7 ++ ++struct rtw89_addr_cam_entry { ++ u8 addr_cam_idx; ++ u8 offset; ++ u8 len; ++ u8 valid : 1; ++ u8 addr_mask : 6; ++ u8 wapi : 1; ++ u8 mask_sel : 2; ++ u8 bssid_cam_idx: 6; ++ u8 tma[ETH_ALEN]; ++ u8 sma[ETH_ALEN]; ++ ++ u8 sec_ent_mode; ++ DECLARE_BITMAP(sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM); ++ u8 sec_ent_keyid[RTW89_SEC_CAM_IN_ADDR_CAM]; ++ u8 sec_ent[RTW89_SEC_CAM_IN_ADDR_CAM]; ++ struct rtw89_sec_cam_entry *sec_entries[RTW89_SEC_CAM_IN_ADDR_CAM]; ++}; ++ ++struct rtw89_bssid_cam_entry { ++ u8 bssid[ETH_ALEN]; ++ u8 phy_idx; ++ u8 bssid_cam_idx; ++ u8 offset; ++ u8 len; ++ u8 valid : 1; ++ u8 num; ++}; ++ ++struct rtw89_sec_cam_entry { ++ u8 sec_cam_idx; ++ u8 offset; ++ u8 len; ++ u8 type : 4; ++ u8 ext_key : 1; ++ u8 spp_mode : 1; ++ /* 256 bits */ ++ u8 key[32]; ++}; ++ ++struct rtw89_efuse { ++ bool valid; ++ u8 xtal_cap; ++ u8 addr[ETH_ALEN]; ++ u8 rfe_type; ++ char country_code[2]; ++}; ++ ++struct rtw89_phy_rate_pattern { ++ u64 ra_mask; ++ u16 rate; ++ u8 ra_mode; ++ bool enable; ++}; ++ ++struct rtw89_vif { ++ struct list_head list; ++ u8 mac_id; ++ u8 port; ++ u8 mac_addr[ETH_ALEN]; ++ u8 bssid[ETH_ALEN]; ++ u8 phy_idx; ++ u8 mac_idx; ++ u8 net_type; ++ u8 wifi_role; ++ u8 self_role; ++ u8 wmm; ++ u8 bcn_hit_cond; ++ u8 hit_rule; ++ bool trigger; ++ bool lsig_txop; ++ u8 tgt_ind; ++ u8 frm_tgt_ind; ++ bool wowlan_pattern; ++ bool wowlan_uc; ++ bool wowlan_magic; ++ bool is_hesta; ++ bool last_a_ctrl; ++ union { ++ struct { ++ struct ieee80211_sta *ap; ++ } mgd; ++ struct { ++ struct list_head sta_list; ++ } ap; ++ }; ++ struct rtw89_addr_cam_entry addr_cam; ++ struct rtw89_bssid_cam_entry bssid_cam; ++ struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS]; ++ struct rtw89_traffic_stats stats; ++ struct rtw89_phy_rate_pattern rate_pattern; ++}; ++ ++enum rtw89_lv1_rcvy_step { ++ RTW89_LV1_RCVY_STEP_1, ++ RTW89_LV1_RCVY_STEP_2, ++}; ++ ++struct rtw89_hci_ops { ++ int (*tx_write)(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req); ++ void (*tx_kick_off)(struct rtw89_dev *rtwdev, u8 txch); ++ void (*flush_queues)(struct rtw89_dev *rtwdev, u32 queues, bool drop); ++ void (*reset)(struct rtw89_dev *rtwdev); ++ int (*start)(struct rtw89_dev *rtwdev); ++ void (*stop)(struct rtw89_dev *rtwdev); ++ void (*recalc_int_mit)(struct rtw89_dev *rtwdev); ++ ++ u8 (*read8)(struct rtw89_dev *rtwdev, u32 addr); ++ u16 (*read16)(struct rtw89_dev *rtwdev, u32 addr); ++ u32 (*read32)(struct rtw89_dev *rtwdev, u32 addr); ++ void (*write8)(struct rtw89_dev *rtwdev, u32 addr, u8 data); ++ void (*write16)(struct rtw89_dev *rtwdev, u32 addr, u16 data); ++ void (*write32)(struct rtw89_dev *rtwdev, u32 addr, u32 data); ++ ++ int (*mac_pre_init)(struct rtw89_dev *rtwdev); ++ int (*mac_post_init)(struct rtw89_dev *rtwdev); ++ int (*deinit)(struct rtw89_dev *rtwdev); ++ ++ u32 (*check_and_reclaim_tx_resource)(struct rtw89_dev *rtwdev, u8 txch); ++ int (*mac_lv1_rcvy)(struct rtw89_dev *rtwdev, enum rtw89_lv1_rcvy_step step); ++ void (*dump_err_status)(struct rtw89_dev *rtwdev); ++ int (*napi_poll)(struct napi_struct *napi, int budget); ++}; ++ ++struct rtw89_hci_info { ++ const struct rtw89_hci_ops *ops; ++ enum rtw89_hci_type type; ++ u32 rpwm_addr; ++ u32 cpwm_addr; ++}; ++ ++struct rtw89_chip_ops { ++ void (*bb_reset)(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx); ++ void (*bb_sethw)(struct rtw89_dev *rtwdev); ++ u32 (*read_rf)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask); ++ bool (*write_rf)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask, u32 data); ++ void (*set_channel)(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_params *param); ++ void (*set_channel_help)(struct rtw89_dev *rtwdev, bool enter, ++ struct rtw89_channel_help_params *p); ++ int (*read_efuse)(struct rtw89_dev *rtwdev, u8 *log_map); ++ int (*read_phycap)(struct rtw89_dev *rtwdev, u8 *phycap_map); ++ void (*fem_setup)(struct rtw89_dev *rtwdev); ++ void (*rfk_init)(struct rtw89_dev *rtwdev); ++ void (*rfk_channel)(struct rtw89_dev *rtwdev); ++ void (*rfk_band_changed)(struct rtw89_dev *rtwdev); ++ void (*rfk_scan)(struct rtw89_dev *rtwdev, bool start); ++ void (*rfk_track)(struct rtw89_dev *rtwdev); ++ void (*power_trim)(struct rtw89_dev *rtwdev); ++ void (*set_txpwr)(struct rtw89_dev *rtwdev); ++ void (*set_txpwr_ctrl)(struct rtw89_dev *rtwdev); ++ int (*init_txpwr_unit)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); ++ u8 (*get_thermal)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path); ++ void (*ctrl_btg)(struct rtw89_dev *rtwdev, bool btg); ++ void (*query_ppdu)(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_phy_ppdu *phy_ppdu, ++ struct ieee80211_rx_status *status); ++ void (*bb_ctrl_btc_preagc)(struct rtw89_dev *rtwdev, bool bt_en); ++ void (*set_txpwr_ul_tb_offset)(struct rtw89_dev *rtwdev, ++ s16 pw_ofst, enum rtw89_mac_idx mac_idx); ++ ++ void (*btc_set_rfe)(struct rtw89_dev *rtwdev); ++ void (*btc_init_cfg)(struct rtw89_dev *rtwdev); ++ void (*btc_set_wl_pri)(struct rtw89_dev *rtwdev, u8 map, bool state); ++ void (*btc_set_wl_txpwr_ctrl)(struct rtw89_dev *rtwdev, u32 txpwr_val); ++ s8 (*btc_get_bt_rssi)(struct rtw89_dev *rtwdev, s8 val); ++ void (*btc_bt_aci_imp)(struct rtw89_dev *rtwdev); ++ void (*btc_update_bt_cnt)(struct rtw89_dev *rtwdev); ++ void (*btc_wl_s1_standby)(struct rtw89_dev *rtwdev, bool state); ++}; ++ ++enum rtw89_dma_ch { ++ RTW89_DMA_ACH0 = 0, ++ RTW89_DMA_ACH1 = 1, ++ RTW89_DMA_ACH2 = 2, ++ RTW89_DMA_ACH3 = 3, ++ RTW89_DMA_ACH4 = 4, ++ RTW89_DMA_ACH5 = 5, ++ RTW89_DMA_ACH6 = 6, ++ RTW89_DMA_ACH7 = 7, ++ RTW89_DMA_B0MG = 8, ++ RTW89_DMA_B0HI = 9, ++ RTW89_DMA_B1MG = 10, ++ RTW89_DMA_B1HI = 11, ++ RTW89_DMA_H2C = 12, ++ RTW89_DMA_CH_NUM = 13 ++}; ++ ++enum rtw89_qta_mode { ++ RTW89_QTA_SCC, ++ RTW89_QTA_DLFW, ++ ++ /* keep last */ ++ RTW89_QTA_INVALID, ++}; ++ ++struct rtw89_hfc_ch_cfg { ++ u16 min; ++ u16 max; ++#define grp_0 0 ++#define grp_1 1 ++#define grp_num 2 ++ u8 grp; ++}; ++ ++struct rtw89_hfc_ch_info { ++ u16 aval; ++ u16 used; ++}; ++ ++struct rtw89_hfc_pub_cfg { ++ u16 grp0; ++ u16 grp1; ++ u16 pub_max; ++ u16 wp_thrd; ++}; ++ ++struct rtw89_hfc_pub_info { ++ u16 g0_used; ++ u16 g1_used; ++ u16 g0_aval; ++ u16 g1_aval; ++ u16 pub_aval; ++ u16 wp_aval; ++}; ++ ++struct rtw89_hfc_prec_cfg { ++ u16 ch011_prec; ++ u16 h2c_prec; ++ u16 wp_ch07_prec; ++ u16 wp_ch811_prec; ++ u8 ch011_full_cond; ++ u8 h2c_full_cond; ++ u8 wp_ch07_full_cond; ++ u8 wp_ch811_full_cond; ++}; ++ ++struct rtw89_hfc_param { ++ bool en; ++ bool h2c_en; ++ u8 mode; ++ const struct rtw89_hfc_ch_cfg *ch_cfg; ++ struct rtw89_hfc_ch_info ch_info[RTW89_DMA_CH_NUM]; ++ struct rtw89_hfc_pub_cfg pub_cfg; ++ struct rtw89_hfc_pub_info pub_info; ++ struct rtw89_hfc_prec_cfg prec_cfg; ++}; ++ ++struct rtw89_hfc_param_ini { ++ const struct rtw89_hfc_ch_cfg *ch_cfg; ++ const struct rtw89_hfc_pub_cfg *pub_cfg; ++ const struct rtw89_hfc_prec_cfg *prec_cfg; ++ u8 mode; ++}; ++ ++struct rtw89_dle_size { ++ u16 pge_size; ++ u16 lnk_pge_num; ++ u16 unlnk_pge_num; ++}; ++ ++struct rtw89_wde_quota { ++ u16 hif; ++ u16 wcpu; ++ u16 pkt_in; ++ u16 cpu_io; ++}; ++ ++struct rtw89_ple_quota { ++ u16 cma0_tx; ++ u16 cma1_tx; ++ u16 c2h; ++ u16 h2c; ++ u16 wcpu; ++ u16 mpdu_proc; ++ u16 cma0_dma; ++ u16 cma1_dma; ++ u16 bb_rpt; ++ u16 wd_rel; ++ u16 cpu_io; ++}; ++ ++struct rtw89_dle_mem { ++ enum rtw89_qta_mode mode; ++ const struct rtw89_dle_size *wde_size; ++ const struct rtw89_dle_size *ple_size; ++ const struct rtw89_wde_quota *wde_min_qt; ++ const struct rtw89_wde_quota *wde_max_qt; ++ const struct rtw89_ple_quota *ple_min_qt; ++ const struct rtw89_ple_quota *ple_max_qt; ++}; ++ ++struct rtw89_reg_def { ++ u32 addr; ++ u32 mask; ++}; ++ ++struct rtw89_reg2_def { ++ u32 addr; ++ u32 data; ++}; ++ ++struct rtw89_reg3_def { ++ u32 addr; ++ u32 mask; ++ u32 data; ++}; ++ ++struct rtw89_reg5_def { ++ u8 flag; /* recognized by parsers */ ++ u8 path; ++ u32 addr; ++ u32 mask; ++ u32 data; ++}; ++ ++struct rtw89_phy_table { ++ const struct rtw89_reg2_def *regs; ++ u32 n_regs; ++ enum rtw89_rf_path rf_path; ++}; ++ ++struct rtw89_txpwr_table { ++ const void *data; ++ u32 size; ++ void (*load)(struct rtw89_dev *rtwdev, ++ const struct rtw89_txpwr_table *tbl); ++}; ++ ++struct rtw89_chip_info { ++ enum rtw89_core_chip_id chip_id; ++ const struct rtw89_chip_ops *ops; ++ const char *fw_name; ++ u32 fifo_size; ++ u16 max_amsdu_limit; ++ bool dis_2g_40m_ul_ofdma; ++ const struct rtw89_hfc_param_ini *hfc_param_ini; ++ const struct rtw89_dle_mem *dle_mem; ++ u32 rf_base_addr[2]; ++ u8 rf_path_num; ++ u8 tx_nss; ++ u8 rx_nss; ++ u8 acam_num; ++ u8 bcam_num; ++ u8 scam_num; ++ ++ u8 sec_ctrl_efuse_size; ++ u32 physical_efuse_size; ++ u32 logical_efuse_size; ++ u32 limit_efuse_size; ++ u32 phycap_addr; ++ u32 phycap_size; ++ ++ const struct rtw89_pwr_cfg * const *pwr_on_seq; ++ const struct rtw89_pwr_cfg * const *pwr_off_seq; ++ const struct rtw89_phy_table *bb_table; ++ const struct rtw89_phy_table *rf_table[RF_PATH_MAX]; ++ const struct rtw89_phy_table *nctl_table; ++ const struct rtw89_txpwr_table *byr_table; ++ const struct rtw89_phy_dig_gain_table *dig_table; ++ const s8 (*txpwr_lmt_2g)[RTW89_2G_BW_NUM][RTW89_NTX_NUM] ++ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] ++ [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; ++ const s8 (*txpwr_lmt_5g)[RTW89_5G_BW_NUM][RTW89_NTX_NUM] ++ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] ++ [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; ++ const s8 (*txpwr_lmt_ru_2g)[RTW89_RU_NUM][RTW89_NTX_NUM] ++ [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; ++ const s8 (*txpwr_lmt_ru_5g)[RTW89_RU_NUM][RTW89_NTX_NUM] ++ [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; ++ ++ u8 txpwr_factor_rf; ++ u8 txpwr_factor_mac; ++ ++ u32 para_ver; ++ u32 wlcx_desired; ++ u8 btcx_desired; ++ u8 scbd; ++ u8 mailbox; ++ ++ u8 afh_guard_ch; ++ const u8 *wl_rssi_thres; ++ const u8 *bt_rssi_thres; ++ u8 rssi_tol; ++ ++ u8 mon_reg_num; ++ const struct rtw89_btc_fbtc_mreg *mon_reg; ++ u8 rf_para_ulink_num; ++ const struct rtw89_btc_rf_trx_para *rf_para_ulink; ++ u8 rf_para_dlink_num; ++ const struct rtw89_btc_rf_trx_para *rf_para_dlink; ++ u8 ps_mode_supported; ++}; ++ ++enum rtw89_hcifc_mode { ++ RTW89_HCIFC_POH = 0, ++ RTW89_HCIFC_STF = 1, ++ RTW89_HCIFC_SDIO = 2, ++ ++ /* keep last */ ++ RTW89_HCIFC_MODE_INVALID, ++}; ++ ++struct rtw89_dle_info { ++ enum rtw89_qta_mode qta_mode; ++ u16 wde_pg_size; ++ u16 ple_pg_size; ++ u16 c0_rx_qta; ++ u16 c1_rx_qta; ++}; ++ ++enum rtw89_host_rpr_mode { ++ RTW89_RPR_MODE_POH = 0, ++ RTW89_RPR_MODE_STF ++}; ++ ++struct rtw89_mac_info { ++ struct rtw89_dle_info dle_info; ++ struct rtw89_hfc_param hfc_param; ++ enum rtw89_qta_mode qta_mode; ++ u8 rpwm_seq_num; ++ u8 cpwm_seq_num; ++}; ++ ++enum rtw89_fw_type { ++ RTW89_FW_NORMAL = 1, ++ RTW89_FW_WOWLAN = 3, ++}; ++ ++struct rtw89_fw_suit { ++ const u8 *data; ++ u32 size; ++ u8 major_ver; ++ u8 minor_ver; ++ u8 sub_ver; ++ u8 sub_idex; ++ u16 build_year; ++ u16 build_mon; ++ u16 build_date; ++ u16 build_hour; ++ u16 build_min; ++ u8 cmd_ver; ++}; ++ ++#define RTW89_FW_VER_CODE(major, minor, sub, idx) \ ++ (((major) << 24) | ((minor) << 16) | ((sub) << 8) | (idx)) ++#define RTW89_FW_SUIT_VER_CODE(s) \ ++ RTW89_FW_VER_CODE((s)->major_ver, (s)->minor_ver, (s)->sub_ver, (s)->sub_idex) ++ ++struct rtw89_fw_info { ++ const struct firmware *firmware; ++ struct rtw89_dev *rtwdev; ++ struct completion completion; ++ u8 h2c_seq; ++ u8 rec_seq; ++ struct rtw89_fw_suit normal; ++ struct rtw89_fw_suit wowlan; ++ bool fw_log_enable; ++ bool old_ht_ra_format; ++}; ++ ++struct rtw89_cam_info { ++ DECLARE_BITMAP(addr_cam_map, RTW89_MAX_ADDR_CAM_NUM); ++ DECLARE_BITMAP(bssid_cam_map, RTW89_MAX_BSSID_CAM_NUM); ++ DECLARE_BITMAP(sec_cam_map, RTW89_MAX_SEC_CAM_NUM); ++}; ++ ++enum rtw89_sar_sources { ++ RTW89_SAR_SOURCE_NONE, ++ RTW89_SAR_SOURCE_COMMON, ++ ++ RTW89_SAR_SOURCE_NR, ++}; ++ ++struct rtw89_sar_cfg_common { ++ bool set[RTW89_SUBBAND_NR]; ++ s32 cfg[RTW89_SUBBAND_NR]; ++}; ++ ++struct rtw89_sar_info { ++ /* used to decide how to acces SAR cfg union */ ++ enum rtw89_sar_sources src; ++ ++ /* reserved for different knids of SAR cfg struct. ++ * supposed that a single cfg struct cannot handle various SAR sources. ++ */ ++ union { ++ struct rtw89_sar_cfg_common cfg_common; ++ }; ++}; ++ ++struct rtw89_hal { ++ u32 rx_fltr; ++ u8 cv; ++ u8 current_channel; ++ u8 current_primary_channel; ++ enum rtw89_subband current_subband; ++ u8 current_band_width; ++ u8 current_band_type; ++ /* center channel for different available bandwidth, ++ * val of (bw > current_band_width) is invalid ++ */ ++ u8 cch_by_bw[RTW89_MAX_CHANNEL_WIDTH + 1]; ++ u32 sw_amsdu_max_size; ++ u32 antenna_tx; ++ u32 antenna_rx; ++ u8 tx_nss; ++ u8 rx_nss; ++}; ++ ++#define RTW89_MAX_MAC_ID_NUM 128 ++ ++enum rtw89_flags { ++ RTW89_FLAG_POWERON, ++ RTW89_FLAG_FW_RDY, ++ RTW89_FLAG_RUNNING, ++ RTW89_FLAG_BFEE_MON, ++ RTW89_FLAG_BFEE_EN, ++ RTW89_FLAG_NAPI_RUNNING, ++ RTW89_FLAG_LEISURE_PS, ++ RTW89_FLAG_LOW_POWER_MODE, ++ RTW89_FLAG_INACTIVE_PS, ++ ++ NUM_OF_RTW89_FLAGS, ++}; ++ ++struct rtw89_pkt_stat { ++ u16 beacon_nr; ++ u32 rx_rate_cnt[RTW89_HW_RATE_NR]; ++}; ++ ++DECLARE_EWMA(thermal, 4, 4); ++ ++struct rtw89_phy_stat { ++ struct ewma_thermal avg_thermal[RF_PATH_MAX]; ++ struct rtw89_pkt_stat cur_pkt_stat; ++ struct rtw89_pkt_stat last_pkt_stat; ++}; ++ ++#define RTW89_DACK_PATH_NR 2 ++#define RTW89_DACK_IDX_NR 2 ++#define RTW89_DACK_MSBK_NR 16 ++struct rtw89_dack_info { ++ bool dack_done; ++ u8 msbk_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR][RTW89_DACK_MSBK_NR]; ++ u8 dadck_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR]; ++ u16 addck_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR]; ++ u16 biask_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR]; ++ u32 dack_cnt; ++ bool addck_timeout[RTW89_DACK_PATH_NR]; ++ bool dadck_timeout[RTW89_DACK_PATH_NR]; ++ bool msbk_timeout[RTW89_DACK_PATH_NR]; ++}; ++ ++#define RTW89_IQK_CHS_NR 2 ++#define RTW89_IQK_PATH_NR 4 ++struct rtw89_iqk_info { ++ bool lok_cor_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; ++ bool lok_fin_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; ++ bool iqk_tx_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; ++ bool iqk_rx_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; ++ u32 iqk_fail_cnt; ++ bool is_iqk_init; ++ u32 iqk_channel[RTW89_IQK_CHS_NR]; ++ u8 iqk_band[RTW89_IQK_PATH_NR]; ++ u8 iqk_ch[RTW89_IQK_PATH_NR]; ++ u8 iqk_bw[RTW89_IQK_PATH_NR]; ++ u8 kcount; ++ u8 iqk_times; ++ u8 version; ++ u32 nb_txcfir[RTW89_IQK_PATH_NR]; ++ u32 nb_rxcfir[RTW89_IQK_PATH_NR]; ++ u32 bp_txkresult[RTW89_IQK_PATH_NR]; ++ u32 bp_rxkresult[RTW89_IQK_PATH_NR]; ++ u32 bp_iqkenable[RTW89_IQK_PATH_NR]; ++ bool is_wb_txiqk[RTW89_IQK_PATH_NR]; ++ bool is_wb_rxiqk[RTW89_IQK_PATH_NR]; ++ bool is_nbiqk; ++ bool iqk_fft_en; ++ bool iqk_xym_en; ++ bool iqk_sram_en; ++ bool iqk_cfir_en; ++ u8 thermal[RTW89_IQK_PATH_NR]; ++ bool thermal_rek_en; ++ u32 syn1to2; ++ u8 iqk_mcc_ch[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; ++ u8 iqk_table_idx[RTW89_IQK_PATH_NR]; ++}; ++ ++#define RTW89_DPK_RF_PATH 2 ++#define RTW89_DPK_AVG_THERMAL_NUM 8 ++#define RTW89_DPK_BKUP_NUM 2 ++struct rtw89_dpk_bkup_para { ++ enum rtw89_band band; ++ enum rtw89_bandwidth bw; ++ u8 ch; ++ bool path_ok; ++ u8 txagc_dpk; ++ u8 ther_dpk; ++ u8 gs; ++ u16 pwsf; ++}; ++ ++struct rtw89_dpk_info { ++ bool is_dpk_enable; ++ bool is_dpk_reload_en; ++ u16 dc_i[RTW89_DPK_RF_PATH]; ++ u16 dc_q[RTW89_DPK_RF_PATH]; ++ u8 corr_val[RTW89_DPK_RF_PATH]; ++ u8 corr_idx[RTW89_DPK_RF_PATH]; ++ u8 cur_idx[RTW89_DPK_RF_PATH]; ++ struct rtw89_dpk_bkup_para bp[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; ++}; ++ ++struct rtw89_fem_info { ++ bool elna_2g; ++ bool elna_5g; ++ bool epa_2g; ++ bool epa_5g; ++}; ++ ++struct rtw89_phy_ch_info { ++ u8 rssi_min; ++ u16 rssi_min_macid; ++ u8 pre_rssi_min; ++ u8 rssi_max; ++ u16 rssi_max_macid; ++ u8 rxsc_160; ++ u8 rxsc_80; ++ u8 rxsc_40; ++ u8 rxsc_20; ++ u8 rxsc_l; ++ u8 is_noisy; ++}; ++ ++struct rtw89_agc_gaincode_set { ++ u8 lna_idx; ++ u8 tia_idx; ++ u8 rxb_idx; ++}; ++ ++#define IGI_RSSI_TH_NUM 5 ++#define FA_TH_NUM 4 ++#define LNA_GAIN_NUM 7 ++#define TIA_GAIN_NUM 2 ++struct rtw89_dig_info { ++ struct rtw89_agc_gaincode_set cur_gaincode; ++ bool force_gaincode_idx_en; ++ struct rtw89_agc_gaincode_set force_gaincode; ++ u8 igi_rssi_th[IGI_RSSI_TH_NUM]; ++ u16 fa_th[FA_TH_NUM]; ++ u8 igi_rssi; ++ u8 igi_fa_rssi; ++ u8 fa_rssi_ofst; ++ u8 dyn_igi_max; ++ u8 dyn_igi_min; ++ bool dyn_pd_th_en; ++ u8 dyn_pd_th_max; ++ u8 pd_low_th_ofst; ++ u8 ib_pbk; ++ s8 ib_pkpwr; ++ s8 lna_gain_a[LNA_GAIN_NUM]; ++ s8 lna_gain_g[LNA_GAIN_NUM]; ++ s8 *lna_gain; ++ s8 tia_gain_a[TIA_GAIN_NUM]; ++ s8 tia_gain_g[TIA_GAIN_NUM]; ++ s8 *tia_gain; ++ bool is_linked_pre; ++ bool bypass_dig; ++}; ++ ++enum rtw89_multi_cfo_mode { ++ RTW89_PKT_BASED_AVG_MODE = 0, ++ RTW89_ENTRY_BASED_AVG_MODE = 1, ++ RTW89_TP_BASED_AVG_MODE = 2, ++}; ++ ++enum rtw89_phy_cfo_status { ++ RTW89_PHY_DCFO_STATE_NORMAL = 0, ++ RTW89_PHY_DCFO_STATE_ENHANCE = 1, ++ RTW89_PHY_DCFO_STATE_MAX ++}; ++ ++struct rtw89_cfo_tracking_info { ++ u16 cfo_timer_ms; ++ bool cfo_trig_by_timer_en; ++ enum rtw89_phy_cfo_status phy_cfo_status; ++ u8 phy_cfo_trk_cnt; ++ bool is_adjust; ++ enum rtw89_multi_cfo_mode rtw89_multi_cfo_mode; ++ bool apply_compensation; ++ u8 crystal_cap; ++ u8 crystal_cap_default; ++ u8 def_x_cap; ++ s8 x_cap_ofst; ++ u32 sta_cfo_tolerance; ++ s32 cfo_tail[CFO_TRACK_MAX_USER]; ++ u16 cfo_cnt[CFO_TRACK_MAX_USER]; ++ s32 cfo_avg_pre; ++ s32 cfo_avg[CFO_TRACK_MAX_USER]; ++ s32 pre_cfo_avg[CFO_TRACK_MAX_USER]; ++ u32 packet_count; ++ u32 packet_count_pre; ++ s32 residual_cfo_acc; ++ u8 phy_cfotrk_state; ++ u8 phy_cfotrk_cnt; ++}; ++ ++/* 2GL, 2GH, 5GL1, 5GH1, 5GM1, 5GM2, 5GH1, 5GH2 */ ++#define TSSI_TRIM_CH_GROUP_NUM 8 ++ ++#define TSSI_CCK_CH_GROUP_NUM 6 ++#define TSSI_MCS_2G_CH_GROUP_NUM 5 ++#define TSSI_MCS_5G_CH_GROUP_NUM 14 ++#define TSSI_MCS_CH_GROUP_NUM \ ++ (TSSI_MCS_2G_CH_GROUP_NUM + TSSI_MCS_5G_CH_GROUP_NUM) ++ ++struct rtw89_tssi_info { ++ u8 thermal[RF_PATH_MAX]; ++ s8 tssi_trim[RF_PATH_MAX][TSSI_TRIM_CH_GROUP_NUM]; ++ s8 tssi_cck[RF_PATH_MAX][TSSI_CCK_CH_GROUP_NUM]; ++ s8 tssi_mcs[RF_PATH_MAX][TSSI_MCS_CH_GROUP_NUM]; ++ s8 extra_ofst[RF_PATH_MAX]; ++ bool tssi_tracking_check[RF_PATH_MAX]; ++ u8 default_txagc_offset[RF_PATH_MAX]; ++ u32 base_thermal[RF_PATH_MAX]; ++}; ++ ++struct rtw89_power_trim_info { ++ bool pg_thermal_trim; ++ bool pg_pa_bias_trim; ++ u8 thermal_trim[RF_PATH_MAX]; ++ u8 pa_bias_trim[RF_PATH_MAX]; ++}; ++ ++struct rtw89_regulatory { ++ char alpha2[3]; ++ u8 txpwr_regd[RTW89_BAND_MAX]; ++}; ++ ++enum rtw89_ifs_clm_application { ++ RTW89_IFS_CLM_INIT = 0, ++ RTW89_IFS_CLM_BACKGROUND = 1, ++ RTW89_IFS_CLM_ACS = 2, ++ RTW89_IFS_CLM_DIG = 3, ++ RTW89_IFS_CLM_TDMA_DIG = 4, ++ RTW89_IFS_CLM_DBG = 5, ++ RTW89_IFS_CLM_DBG_MANUAL = 6 ++}; ++ ++enum rtw89_env_racing_lv { ++ RTW89_RAC_RELEASE = 0, ++ RTW89_RAC_LV_1 = 1, ++ RTW89_RAC_LV_2 = 2, ++ RTW89_RAC_LV_3 = 3, ++ RTW89_RAC_LV_4 = 4, ++ RTW89_RAC_MAX_NUM = 5 ++}; ++ ++struct rtw89_ccx_para_info { ++ enum rtw89_env_racing_lv rac_lv; ++ u16 mntr_time; ++ u8 nhm_manual_th_ofst; ++ u8 nhm_manual_th0; ++ enum rtw89_ifs_clm_application ifs_clm_app; ++ u32 ifs_clm_manual_th_times; ++ u32 ifs_clm_manual_th0; ++ u8 fahm_manual_th_ofst; ++ u8 fahm_manual_th0; ++ u8 fahm_numer_opt; ++ u8 fahm_denom_opt; ++}; ++ ++enum rtw89_ccx_edcca_opt_sc_idx { ++ RTW89_CCX_EDCCA_SEG0_P0 = 0, ++ RTW89_CCX_EDCCA_SEG0_S1 = 1, ++ RTW89_CCX_EDCCA_SEG0_S2 = 2, ++ RTW89_CCX_EDCCA_SEG0_S3 = 3, ++ RTW89_CCX_EDCCA_SEG1_P0 = 4, ++ RTW89_CCX_EDCCA_SEG1_S1 = 5, ++ RTW89_CCX_EDCCA_SEG1_S2 = 6, ++ RTW89_CCX_EDCCA_SEG1_S3 = 7 ++}; ++ ++enum rtw89_ccx_edcca_opt_bw_idx { ++ RTW89_CCX_EDCCA_BW20_0 = 0, ++ RTW89_CCX_EDCCA_BW20_1 = 1, ++ RTW89_CCX_EDCCA_BW20_2 = 2, ++ RTW89_CCX_EDCCA_BW20_3 = 3, ++ RTW89_CCX_EDCCA_BW20_4 = 4, ++ RTW89_CCX_EDCCA_BW20_5 = 5, ++ RTW89_CCX_EDCCA_BW20_6 = 6, ++ RTW89_CCX_EDCCA_BW20_7 = 7 ++}; ++ ++#define RTW89_NHM_TH_NUM 11 ++#define RTW89_FAHM_TH_NUM 11 ++#define RTW89_NHM_RPT_NUM 12 ++#define RTW89_FAHM_RPT_NUM 12 ++#define RTW89_IFS_CLM_NUM 4 ++struct rtw89_env_monitor_info { ++ u32 ccx_trigger_time; ++ u64 start_time; ++ u8 ccx_rpt_stamp; ++ u8 ccx_watchdog_result; ++ bool ccx_ongoing; ++ u8 ccx_rac_lv; ++ bool ccx_manual_ctrl; ++ u8 ccx_pre_rssi; ++ u16 clm_mntr_time; ++ u16 nhm_mntr_time; ++ u16 ifs_clm_mntr_time; ++ enum rtw89_ifs_clm_application ifs_clm_app; ++ u16 fahm_mntr_time; ++ u16 edcca_clm_mntr_time; ++ u16 ccx_period; ++ u8 ccx_unit_idx; ++ enum rtw89_ccx_edcca_opt_bw_idx ccx_edcca_opt_bw_idx; ++ u8 nhm_th[RTW89_NHM_TH_NUM]; ++ u16 ifs_clm_th_l[RTW89_IFS_CLM_NUM]; ++ u16 ifs_clm_th_h[RTW89_IFS_CLM_NUM]; ++ u8 fahm_numer_opt; ++ u8 fahm_denom_opt; ++ u8 fahm_th[RTW89_FAHM_TH_NUM]; ++ u16 clm_result; ++ u16 nhm_result[RTW89_NHM_RPT_NUM]; ++ u8 nhm_wgt[RTW89_NHM_RPT_NUM]; ++ u16 nhm_tx_cnt; ++ u16 nhm_cca_cnt; ++ u16 nhm_idle_cnt; ++ u16 ifs_clm_tx; ++ u16 ifs_clm_edcca_excl_cca; ++ u16 ifs_clm_ofdmfa; ++ u16 ifs_clm_ofdmcca_excl_fa; ++ u16 ifs_clm_cckfa; ++ u16 ifs_clm_cckcca_excl_fa; ++ u16 ifs_clm_total_ifs; ++ u8 ifs_clm_his[RTW89_IFS_CLM_NUM]; ++ u16 ifs_clm_avg[RTW89_IFS_CLM_NUM]; ++ u16 ifs_clm_cca[RTW89_IFS_CLM_NUM]; ++ u16 fahm_result[RTW89_FAHM_RPT_NUM]; ++ u16 fahm_denom_result; ++ u16 edcca_clm_result; ++ u8 clm_ratio; ++ u8 nhm_rpt[RTW89_NHM_RPT_NUM]; ++ u8 nhm_tx_ratio; ++ u8 nhm_cca_ratio; ++ u8 nhm_idle_ratio; ++ u8 nhm_ratio; ++ u16 nhm_result_sum; ++ u8 nhm_pwr; ++ u8 ifs_clm_tx_ratio; ++ u8 ifs_clm_edcca_excl_cca_ratio; ++ u8 ifs_clm_cck_fa_ratio; ++ u8 ifs_clm_ofdm_fa_ratio; ++ u8 ifs_clm_cck_cca_excl_fa_ratio; ++ u8 ifs_clm_ofdm_cca_excl_fa_ratio; ++ u16 ifs_clm_cck_fa_permil; ++ u16 ifs_clm_ofdm_fa_permil; ++ u32 ifs_clm_ifs_avg[RTW89_IFS_CLM_NUM]; ++ u32 ifs_clm_cca_avg[RTW89_IFS_CLM_NUM]; ++ u8 fahm_rpt[RTW89_FAHM_RPT_NUM]; ++ u16 fahm_result_sum; ++ u8 fahm_ratio; ++ u8 fahm_denom_ratio; ++ u8 fahm_pwr; ++ u8 edcca_clm_ratio; ++}; ++ ++enum rtw89_ser_rcvy_step { ++ RTW89_SER_DRV_STOP_TX, ++ RTW89_SER_DRV_STOP_RX, ++ RTW89_SER_DRV_STOP_RUN, ++ RTW89_SER_HAL_STOP_DMA, ++ RTW89_NUM_OF_SER_FLAGS ++}; ++ ++struct rtw89_ser { ++ u8 state; ++ u8 alarm_event; ++ ++ struct work_struct ser_hdl_work; ++ struct delayed_work ser_alarm_work; ++ struct state_ent *st_tbl; ++ struct event_ent *ev_tbl; ++ struct list_head msg_q; ++ spinlock_t msg_q_lock; /* lock when read/write ser msg */ ++ DECLARE_BITMAP(flags, RTW89_NUM_OF_SER_FLAGS); ++}; ++ ++enum rtw89_mac_ax_ps_mode { ++ RTW89_MAC_AX_PS_MODE_ACTIVE = 0, ++ RTW89_MAC_AX_PS_MODE_LEGACY = 1, ++ RTW89_MAC_AX_PS_MODE_WMMPS = 2, ++ RTW89_MAC_AX_PS_MODE_MAX = 3, ++}; ++ ++enum rtw89_last_rpwm_mode { ++ RTW89_LAST_RPWM_PS = 0x0, ++ RTW89_LAST_RPWM_ACTIVE = 0x6, ++}; ++ ++struct rtw89_lps_parm { ++ u8 macid; ++ u8 psmode; /* enum rtw89_mac_ax_ps_mode */ ++ u8 lastrpwm; /* enum rtw89_last_rpwm_mode */ ++}; ++ ++struct rtw89_ppdu_sts_info { ++ struct sk_buff_head rx_queue[RTW89_PHY_MAX]; ++ u8 curr_rx_ppdu_cnt[RTW89_PHY_MAX]; ++}; ++ ++struct rtw89_early_h2c { ++ struct list_head list; ++ u8 *h2c; ++ u16 h2c_len; ++}; ++ ++struct rtw89_dev { ++ struct ieee80211_hw *hw; ++ struct device *dev; ++ ++ bool dbcc_en; ++ const struct rtw89_chip_info *chip; ++ struct rtw89_hal hal; ++ struct rtw89_mac_info mac; ++ struct rtw89_fw_info fw; ++ struct rtw89_hci_info hci; ++ struct rtw89_efuse efuse; ++ struct rtw89_traffic_stats stats; ++ ++ /* ensures exclusive access from mac80211 callbacks */ ++ struct mutex mutex; ++ struct list_head rtwvifs_list; ++ /* used to protect rf read write */ ++ struct mutex rf_mutex; ++ struct workqueue_struct *txq_wq; ++ struct work_struct txq_work; ++ struct delayed_work txq_reinvoke_work; ++ /* used to protect ba_list */ ++ spinlock_t ba_lock; ++ /* txqs to setup ba session */ ++ struct list_head ba_list; ++ struct work_struct ba_work; ++ ++ struct rtw89_cam_info cam_info; ++ ++ struct sk_buff_head c2h_queue; ++ struct work_struct c2h_work; ++ ++ struct list_head early_h2c_list; ++ ++ struct rtw89_ser ser; ++ ++ DECLARE_BITMAP(hw_port, RTW89_MAX_HW_PORT_NUM); ++ DECLARE_BITMAP(mac_id_map, RTW89_MAX_MAC_ID_NUM); ++ DECLARE_BITMAP(flags, NUM_OF_RTW89_FLAGS); ++ ++ struct rtw89_phy_stat phystat; ++ struct rtw89_dack_info dack; ++ struct rtw89_iqk_info iqk; ++ struct rtw89_dpk_info dpk; ++ bool is_tssi_mode[RF_PATH_MAX]; ++ bool is_bt_iqk_timeout; ++ ++ struct rtw89_fem_info fem; ++ struct rtw89_txpwr_byrate byr[RTW89_BAND_MAX]; ++ struct rtw89_tssi_info tssi; ++ struct rtw89_power_trim_info pwr_trim; ++ ++ struct rtw89_cfo_tracking_info cfo_tracking; ++ struct rtw89_env_monitor_info env_monitor; ++ struct rtw89_dig_info dig; ++ struct rtw89_phy_ch_info ch_info; ++ struct delayed_work track_work; ++ struct delayed_work coex_act1_work; ++ struct delayed_work coex_bt_devinfo_work; ++ struct delayed_work coex_rfk_chk_work; ++ struct delayed_work cfo_track_work; ++ struct rtw89_ppdu_sts_info ppdu_sts; ++ u8 total_sta_assoc; ++ bool scanning; ++ ++ const struct rtw89_regulatory *regd; ++ struct rtw89_sar_info sar; ++ ++ struct rtw89_btc btc; ++ enum rtw89_ps_mode ps_mode; ++ bool lps_enabled; ++ ++ /* napi structure */ ++ struct net_device netdev; ++ struct napi_struct napi; ++ int napi_budget_countdown; ++ ++ /* HCI related data, keep last */ ++ u8 priv[0] __aligned(sizeof(void *)); ++}; ++ ++static inline int rtw89_hci_tx_write(struct rtw89_dev *rtwdev, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ return rtwdev->hci.ops->tx_write(rtwdev, tx_req); ++} ++ ++static inline void rtw89_hci_reset(struct rtw89_dev *rtwdev) ++{ ++ rtwdev->hci.ops->reset(rtwdev); ++} ++ ++static inline int rtw89_hci_start(struct rtw89_dev *rtwdev) ++{ ++ return rtwdev->hci.ops->start(rtwdev); ++} ++ ++static inline void rtw89_hci_stop(struct rtw89_dev *rtwdev) ++{ ++ rtwdev->hci.ops->stop(rtwdev); ++} ++ ++static inline int rtw89_hci_deinit(struct rtw89_dev *rtwdev) ++{ ++ return rtwdev->hci.ops->deinit(rtwdev); ++} ++ ++static inline void rtw89_hci_recalc_int_mit(struct rtw89_dev *rtwdev) ++{ ++ rtwdev->hci.ops->recalc_int_mit(rtwdev); ++} ++ ++static inline u32 rtw89_hci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, u8 txch) ++{ ++ return rtwdev->hci.ops->check_and_reclaim_tx_resource(rtwdev, txch); ++} ++ ++static inline void rtw89_hci_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch) ++{ ++ return rtwdev->hci.ops->tx_kick_off(rtwdev, txch); ++} ++ ++static inline void rtw89_hci_flush_queues(struct rtw89_dev *rtwdev, u32 queues, ++ bool drop) ++{ ++ if (rtwdev->hci.ops->flush_queues) ++ return rtwdev->hci.ops->flush_queues(rtwdev, queues, drop); ++} ++ ++static inline u8 rtw89_read8(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ return rtwdev->hci.ops->read8(rtwdev, addr); ++} ++ ++static inline u16 rtw89_read16(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ return rtwdev->hci.ops->read16(rtwdev, addr); ++} ++ ++static inline u32 rtw89_read32(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ return rtwdev->hci.ops->read32(rtwdev, addr); ++} ++ ++static inline void rtw89_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) ++{ ++ rtwdev->hci.ops->write8(rtwdev, addr, data); ++} ++ ++static inline void rtw89_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) ++{ ++ rtwdev->hci.ops->write16(rtwdev, addr, data); ++} ++ ++static inline void rtw89_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) ++{ ++ rtwdev->hci.ops->write32(rtwdev, addr, data); ++} ++ ++static inline void ++rtw89_write8_set(struct rtw89_dev *rtwdev, u32 addr, u8 bit) ++{ ++ u8 val; ++ ++ val = rtw89_read8(rtwdev, addr); ++ rtw89_write8(rtwdev, addr, val | bit); ++} ++ ++static inline void ++rtw89_write16_set(struct rtw89_dev *rtwdev, u32 addr, u16 bit) ++{ ++ u16 val; ++ ++ val = rtw89_read16(rtwdev, addr); ++ rtw89_write16(rtwdev, addr, val | bit); ++} ++ ++static inline void ++rtw89_write32_set(struct rtw89_dev *rtwdev, u32 addr, u32 bit) ++{ ++ u32 val; ++ ++ val = rtw89_read32(rtwdev, addr); ++ rtw89_write32(rtwdev, addr, val | bit); ++} ++ ++static inline void ++rtw89_write8_clr(struct rtw89_dev *rtwdev, u32 addr, u8 bit) ++{ ++ u8 val; ++ ++ val = rtw89_read8(rtwdev, addr); ++ rtw89_write8(rtwdev, addr, val & ~bit); ++} ++ ++static inline void ++rtw89_write16_clr(struct rtw89_dev *rtwdev, u32 addr, u16 bit) ++{ ++ u16 val; ++ ++ val = rtw89_read16(rtwdev, addr); ++ rtw89_write16(rtwdev, addr, val & ~bit); ++} ++ ++static inline void ++rtw89_write32_clr(struct rtw89_dev *rtwdev, u32 addr, u32 bit) ++{ ++ u32 val; ++ ++ val = rtw89_read32(rtwdev, addr); ++ rtw89_write32(rtwdev, addr, val & ~bit); ++} ++ ++static inline u32 ++rtw89_read32_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask) ++{ ++ u32 shift = __ffs(mask); ++ u32 orig; ++ u32 ret; ++ ++ orig = rtw89_read32(rtwdev, addr); ++ ret = (orig & mask) >> shift; ++ ++ return ret; ++} ++ ++static inline u16 ++rtw89_read16_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask) ++{ ++ u32 shift = __ffs(mask); ++ u32 orig; ++ u32 ret; ++ ++ orig = rtw89_read16(rtwdev, addr); ++ ret = (orig & mask) >> shift; ++ ++ return ret; ++} ++ ++static inline u8 ++rtw89_read8_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask) ++{ ++ u32 shift = __ffs(mask); ++ u32 orig; ++ u32 ret; ++ ++ orig = rtw89_read8(rtwdev, addr); ++ ret = (orig & mask) >> shift; ++ ++ return ret; ++} ++ ++static inline void ++rtw89_write32_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u32 data) ++{ ++ u32 shift = __ffs(mask); ++ u32 orig; ++ u32 set; ++ ++ WARN(addr & 0x3, "should be 4-byte aligned, addr = 0x%08x\n", addr); ++ ++ orig = rtw89_read32(rtwdev, addr); ++ set = (orig & ~mask) | ((data << shift) & mask); ++ rtw89_write32(rtwdev, addr, set); ++} ++ ++static inline void ++rtw89_write16_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u16 data) ++{ ++ u32 shift; ++ u16 orig, set; ++ ++ mask &= 0xffff; ++ shift = __ffs(mask); ++ ++ orig = rtw89_read16(rtwdev, addr); ++ set = (orig & ~mask) | ((data << shift) & mask); ++ rtw89_write16(rtwdev, addr, set); ++} ++ ++static inline void ++rtw89_write8_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u8 data) ++{ ++ u32 shift; ++ u8 orig, set; ++ ++ mask &= 0xff; ++ shift = __ffs(mask); ++ ++ orig = rtw89_read8(rtwdev, addr); ++ set = (orig & ~mask) | ((data << shift) & mask); ++ rtw89_write8(rtwdev, addr, set); ++} ++ ++static inline u32 ++rtw89_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask) ++{ ++ u32 val; ++ ++ mutex_lock(&rtwdev->rf_mutex); ++ val = rtwdev->chip->ops->read_rf(rtwdev, rf_path, addr, mask); ++ mutex_unlock(&rtwdev->rf_mutex); ++ ++ return val; ++} ++ ++static inline void ++rtw89_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask, u32 data) ++{ ++ mutex_lock(&rtwdev->rf_mutex); ++ rtwdev->chip->ops->write_rf(rtwdev, rf_path, addr, mask, data); ++ mutex_unlock(&rtwdev->rf_mutex); ++} ++ ++static inline struct ieee80211_txq *rtw89_txq_to_txq(struct rtw89_txq *rtwtxq) ++{ ++ void *p = rtwtxq; ++ ++ return container_of(p, struct ieee80211_txq, drv_priv); ++} ++ ++static inline void rtw89_core_txq_init(struct rtw89_dev *rtwdev, ++ struct ieee80211_txq *txq) ++{ ++ struct rtw89_txq *rtwtxq; ++ ++ if (!txq) ++ return; ++ ++ rtwtxq = (struct rtw89_txq *)txq->drv_priv; ++ INIT_LIST_HEAD(&rtwtxq->list); ++} ++ ++static inline struct ieee80211_vif *rtwvif_to_vif(struct rtw89_vif *rtwvif) ++{ ++ void *p = rtwvif; ++ ++ return container_of(p, struct ieee80211_vif, drv_priv); ++} ++ ++static inline struct ieee80211_sta *rtwsta_to_sta(struct rtw89_sta *rtwsta) ++{ ++ void *p = rtwsta; ++ ++ return container_of(p, struct ieee80211_sta, drv_priv); ++} ++ ++static inline ++void rtw89_chip_set_channel_prepare(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_help_params *p) ++{ ++ rtwdev->chip->ops->set_channel_help(rtwdev, true, p); ++} ++ ++static inline ++void rtw89_chip_set_channel_done(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_help_params *p) ++{ ++ rtwdev->chip->ops->set_channel_help(rtwdev, false, p); ++} ++ ++static inline void rtw89_chip_fem_setup(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->fem_setup) ++ chip->ops->fem_setup(rtwdev); ++} ++ ++static inline void rtw89_chip_bb_sethw(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->bb_sethw) ++ chip->ops->bb_sethw(rtwdev); ++} ++ ++static inline void rtw89_chip_rfk_init(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->rfk_init) ++ chip->ops->rfk_init(rtwdev); ++} ++ ++static inline void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->rfk_channel) ++ chip->ops->rfk_channel(rtwdev); ++} ++ ++static inline void rtw89_chip_rfk_band_changed(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->rfk_band_changed) ++ chip->ops->rfk_band_changed(rtwdev); ++} ++ ++static inline void rtw89_chip_rfk_scan(struct rtw89_dev *rtwdev, bool start) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->rfk_scan) ++ chip->ops->rfk_scan(rtwdev, start); ++} ++ ++static inline void rtw89_chip_rfk_track(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->rfk_track) ++ chip->ops->rfk_track(rtwdev); ++} ++ ++static inline void rtw89_chip_set_txpwr_ctrl(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->set_txpwr_ctrl) ++ chip->ops->set_txpwr_ctrl(rtwdev); ++} ++ ++static inline void rtw89_chip_set_txpwr(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ u8 ch = rtwdev->hal.current_channel; ++ ++ if (!ch) ++ return; ++ ++ if (chip->ops->set_txpwr) ++ chip->ops->set_txpwr(rtwdev); ++} ++ ++static inline void rtw89_chip_power_trim(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->power_trim) ++ chip->ops->power_trim(rtwdev); ++} ++ ++static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->init_txpwr_unit) ++ chip->ops->init_txpwr_unit(rtwdev, phy_idx); ++} ++ ++static inline u8 rtw89_chip_get_thermal(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path rf_path) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (!chip->ops->get_thermal) ++ return 0x10; ++ ++ return chip->ops->get_thermal(rtwdev, rf_path); ++} ++ ++static inline void rtw89_chip_query_ppdu(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_phy_ppdu *phy_ppdu, ++ struct ieee80211_rx_status *status) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->query_ppdu) ++ chip->ops->query_ppdu(rtwdev, phy_ppdu, status); ++} ++ ++static inline void rtw89_chip_bb_ctrl_btc_preagc(struct rtw89_dev *rtwdev, ++ bool bt_en) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->bb_ctrl_btc_preagc) ++ chip->ops->bb_ctrl_btc_preagc(rtwdev, bt_en); ++} ++ ++static inline ++void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (!vif->bss_conf.he_support || !vif->bss_conf.assoc) ++ return; ++ ++ if (chip->ops->set_txpwr_ul_tb_offset) ++ chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif->mac_idx); ++} ++ ++static inline void rtw89_load_txpwr_table(struct rtw89_dev *rtwdev, ++ const struct rtw89_txpwr_table *tbl) ++{ ++ tbl->load(rtwdev, tbl); ++} ++ ++static inline u8 rtw89_regd_get(struct rtw89_dev *rtwdev, u8 band) ++{ ++ return rtwdev->regd->txpwr_regd[band]; ++} ++ ++static inline void rtw89_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->ctrl_btg) ++ chip->ops->ctrl_btg(rtwdev, btg); ++} ++ ++static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) ++{ ++ __le16 fc = hdr->frame_control; ++ ++ if (ieee80211_has_tods(fc)) ++ return hdr->addr1; ++ else if (ieee80211_has_fromds(fc)) ++ return hdr->addr2; ++ else ++ return hdr->addr3; ++} ++ ++static inline bool rtw89_sta_has_beamformer_cap(struct ieee80211_sta *sta) ++{ ++ if ((sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || ++ (sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) || ++ (sta->he_cap.he_cap_elem.phy_cap_info[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) || ++ (sta->he_cap.he_cap_elem.phy_cap_info[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) ++ return true; ++ return false; ++} ++ ++static inline struct rtw89_fw_suit *rtw89_fw_suit_get(struct rtw89_dev *rtwdev, ++ enum rtw89_fw_type type) ++{ ++ struct rtw89_fw_info *fw_info = &rtwdev->fw; ++ ++ if (type == RTW89_FW_WOWLAN) ++ return &fw_info->wowlan; ++ return &fw_info->normal; ++} ++ ++int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel); ++int rtw89_h2c_tx(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb, bool fwdl); ++void rtw89_core_tx_kick_off(struct rtw89_dev *rtwdev, u8 qsel); ++void rtw89_core_fill_txdesc(struct rtw89_dev *rtwdev, ++ struct rtw89_tx_desc_info *desc_info, ++ void *txdesc); ++void rtw89_core_rx(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_desc_info *desc_info, ++ struct sk_buff *skb); ++void rtw89_core_query_rxdesc(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_desc_info *desc_info, ++ u8 *data, u32 data_offset); ++void rtw89_core_napi_start(struct rtw89_dev *rtwdev); ++void rtw89_core_napi_stop(struct rtw89_dev *rtwdev); ++void rtw89_core_napi_init(struct rtw89_dev *rtwdev); ++void rtw89_core_napi_deinit(struct rtw89_dev *rtwdev); ++int rtw89_core_sta_add(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++int rtw89_core_sta_remove(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++int rtw89_core_init(struct rtw89_dev *rtwdev); ++void rtw89_core_deinit(struct rtw89_dev *rtwdev); ++int rtw89_core_register(struct rtw89_dev *rtwdev); ++void rtw89_core_unregister(struct rtw89_dev *rtwdev); ++void rtw89_set_channel(struct rtw89_dev *rtwdev); ++u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size); ++void rtw89_core_release_bit_map(unsigned long *addr, u8 bit); ++void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits); ++void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc); ++int rtw89_chip_info_setup(struct rtw89_dev *rtwdev); ++u16 rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate); ++int rtw89_regd_init(struct rtw89_dev *rtwdev, ++ void (*reg_notifier)(struct wiphy *wiphy, struct regulatory_request *request)); ++void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request); ++void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, ++ struct rtw89_traffic_stats *stats); ++int rtw89_core_start(struct rtw89_dev *rtwdev); ++void rtw89_core_stop(struct rtw89_dev *rtwdev); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c +new file mode 100644 +index 000000000000..29eb188c888c +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/debug.c +@@ -0,0 +1,2489 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "coex.h" ++#include "debug.h" ++#include "fw.h" ++#include "mac.h" ++#include "ps.h" ++#include "reg.h" ++#include "sar.h" ++ ++#ifdef CONFIG_RTW89_DEBUGMSG ++unsigned int rtw89_debug_mask; ++EXPORT_SYMBOL(rtw89_debug_mask); ++module_param_named(debug_mask, rtw89_debug_mask, uint, 0644); ++MODULE_PARM_DESC(debug_mask, "Debugging mask"); ++#endif ++ ++#ifdef CONFIG_RTW89_DEBUGFS ++struct rtw89_debugfs_priv { ++ struct rtw89_dev *rtwdev; ++ int (*cb_read)(struct seq_file *m, void *v); ++ ssize_t (*cb_write)(struct file *filp, const char __user *buffer, ++ size_t count, loff_t *loff); ++ union { ++ u32 cb_data; ++ struct { ++ u32 addr; ++ u8 len; ++ } read_reg; ++ struct { ++ u32 addr; ++ u32 mask; ++ u8 path; ++ } read_rf; ++ struct { ++ u8 ss_dbg:1; ++ u8 dle_dbg:1; ++ u8 dmac_dbg:1; ++ u8 cmac_dbg:1; ++ u8 dbg_port:1; ++ } dbgpkg_en; ++ struct { ++ u32 start; ++ u32 len; ++ u8 sel; ++ } mac_mem; ++ }; ++}; ++ ++static int rtw89_debugfs_single_show(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ ++ return debugfs_priv->cb_read(m, v); ++} ++ ++static ssize_t rtw89_debugfs_single_write(struct file *filp, ++ const char __user *buffer, ++ size_t count, loff_t *loff) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; ++ ++ return debugfs_priv->cb_write(filp, buffer, count, loff); ++} ++ ++static ssize_t rtw89_debugfs_seq_file_write(struct file *filp, ++ const char __user *buffer, ++ size_t count, loff_t *loff) ++{ ++ struct seq_file *seqpriv = (struct seq_file *)filp->private_data; ++ struct rtw89_debugfs_priv *debugfs_priv = seqpriv->private; ++ ++ return debugfs_priv->cb_write(filp, buffer, count, loff); ++} ++ ++static int rtw89_debugfs_single_open(struct inode *inode, struct file *filp) ++{ ++ return single_open(filp, rtw89_debugfs_single_show, inode->i_private); ++} ++ ++static int rtw89_debugfs_close(struct inode *inode, struct file *filp) ++{ ++ return 0; ++} ++ ++static const struct file_operations file_ops_single_r = { ++ .owner = THIS_MODULE, ++ .open = rtw89_debugfs_single_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static const struct file_operations file_ops_common_rw = { ++ .owner = THIS_MODULE, ++ .open = rtw89_debugfs_single_open, ++ .release = single_release, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .write = rtw89_debugfs_seq_file_write, ++}; ++ ++static const struct file_operations file_ops_single_w = { ++ .owner = THIS_MODULE, ++ .write = rtw89_debugfs_single_write, ++ .open = simple_open, ++ .release = rtw89_debugfs_close, ++}; ++ ++static ssize_t ++rtw89_debug_priv_read_reg_select(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct seq_file *m = (struct seq_file *)filp->private_data; ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ char buf[32]; ++ size_t buf_size; ++ u32 addr, len; ++ int num; ++ ++ buf_size = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, buf_size)) ++ return -EFAULT; ++ ++ buf[buf_size] = '\0'; ++ num = sscanf(buf, "%x %x", &addr, &len); ++ if (num != 2) { ++ rtw89_info(rtwdev, "invalid format: \n"); ++ return -EINVAL; ++ } ++ ++ debugfs_priv->read_reg.addr = addr; ++ debugfs_priv->read_reg.len = len; ++ ++ rtw89_info(rtwdev, "select read %d bytes from 0x%08x\n", len, addr); ++ ++ return count; ++} ++ ++static int rtw89_debug_priv_read_reg_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ u32 addr, data; ++ u8 len; ++ ++ len = debugfs_priv->read_reg.len; ++ addr = debugfs_priv->read_reg.addr; ++ ++ switch (len) { ++ case 1: ++ data = rtw89_read8(rtwdev, addr); ++ break; ++ case 2: ++ data = rtw89_read16(rtwdev, addr); ++ break; ++ case 4: ++ data = rtw89_read32(rtwdev, addr); ++ break; ++ default: ++ rtw89_info(rtwdev, "invalid read reg len %d\n", len); ++ return -EINVAL; ++ } ++ ++ seq_printf(m, "get %d bytes at 0x%08x=0x%08x\n", len, addr, data); ++ ++ return 0; ++} ++ ++static ssize_t rtw89_debug_priv_write_reg_set(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ char buf[32]; ++ size_t buf_size; ++ u32 addr, val, len; ++ int num; ++ ++ buf_size = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, buf_size)) ++ return -EFAULT; ++ ++ buf[buf_size] = '\0'; ++ num = sscanf(buf, "%x %x %x", &addr, &val, &len); ++ if (num != 3) { ++ rtw89_info(rtwdev, "invalid format: \n"); ++ return -EINVAL; ++ } ++ ++ switch (len) { ++ case 1: ++ rtw89_info(rtwdev, "reg write8 0x%08x: 0x%02x\n", addr, val); ++ rtw89_write8(rtwdev, addr, (u8)val); ++ break; ++ case 2: ++ rtw89_info(rtwdev, "reg write16 0x%08x: 0x%04x\n", addr, val); ++ rtw89_write16(rtwdev, addr, (u16)val); ++ break; ++ case 4: ++ rtw89_info(rtwdev, "reg write32 0x%08x: 0x%08x\n", addr, val); ++ rtw89_write32(rtwdev, addr, (u32)val); ++ break; ++ default: ++ rtw89_info(rtwdev, "invalid read write len %d\n", len); ++ break; ++ } ++ ++ return count; ++} ++ ++static ssize_t ++rtw89_debug_priv_read_rf_select(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct seq_file *m = (struct seq_file *)filp->private_data; ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ char buf[32]; ++ size_t buf_size; ++ u32 addr, mask; ++ u8 path; ++ int num; ++ ++ buf_size = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, buf_size)) ++ return -EFAULT; ++ ++ buf[buf_size] = '\0'; ++ num = sscanf(buf, "%hhd %x %x", &path, &addr, &mask); ++ if (num != 3) { ++ rtw89_info(rtwdev, "invalid format: \n"); ++ return -EINVAL; ++ } ++ ++ if (path >= rtwdev->chip->rf_path_num) { ++ rtw89_info(rtwdev, "wrong rf path\n"); ++ return -EINVAL; ++ } ++ debugfs_priv->read_rf.addr = addr; ++ debugfs_priv->read_rf.mask = mask; ++ debugfs_priv->read_rf.path = path; ++ ++ rtw89_info(rtwdev, "select read rf path %d from 0x%08x\n", path, addr); ++ ++ return count; ++} ++ ++static int rtw89_debug_priv_read_rf_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ u32 addr, data, mask; ++ u8 path; ++ ++ addr = debugfs_priv->read_rf.addr; ++ mask = debugfs_priv->read_rf.mask; ++ path = debugfs_priv->read_rf.path; ++ ++ data = rtw89_read_rf(rtwdev, path, addr, mask); ++ ++ seq_printf(m, "path %d, rf register 0x%08x=0x%08x\n", path, addr, data); ++ ++ return 0; ++} ++ ++static ssize_t rtw89_debug_priv_write_rf_set(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ char buf[32]; ++ size_t buf_size; ++ u32 addr, val, mask; ++ u8 path; ++ int num; ++ ++ buf_size = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, buf_size)) ++ return -EFAULT; ++ ++ buf[buf_size] = '\0'; ++ num = sscanf(buf, "%hhd %x %x %x", &path, &addr, &mask, &val); ++ if (num != 4) { ++ rtw89_info(rtwdev, "invalid format: \n"); ++ return -EINVAL; ++ } ++ ++ if (path >= rtwdev->chip->rf_path_num) { ++ rtw89_info(rtwdev, "wrong rf path\n"); ++ return -EINVAL; ++ } ++ ++ rtw89_info(rtwdev, "path %d, rf register write 0x%08x=0x%08x (mask = 0x%08x)\n", ++ path, addr, val, mask); ++ rtw89_write_rf(rtwdev, path, addr, mask, val); ++ ++ return count; ++} ++ ++static int rtw89_debug_priv_rf_reg_dump_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ u32 addr, offset, data; ++ u8 path; ++ ++ for (path = 0; path < chip->rf_path_num; path++) { ++ seq_printf(m, "RF path %d:\n\n", path); ++ for (addr = 0; addr < 0x100; addr += 4) { ++ seq_printf(m, "0x%08x: ", addr); ++ for (offset = 0; offset < 4; offset++) { ++ data = rtw89_read_rf(rtwdev, path, ++ addr + offset, RFREG_MASK); ++ seq_printf(m, "0x%05x ", data); ++ } ++ seq_puts(m, "\n"); ++ } ++ seq_puts(m, "\n"); ++ } ++ ++ return 0; ++} ++ ++struct txpwr_ent { ++ const char *txt; ++ u8 len; ++}; ++ ++struct txpwr_map { ++ const struct txpwr_ent *ent; ++ u8 size; ++ u32 addr_from; ++ u32 addr_to; ++}; ++ ++#define __GEN_TXPWR_ENT2(_t, _e0, _e1) \ ++ { .len = 2, .txt = _t "\t- " _e0 " " _e1 } ++ ++#define __GEN_TXPWR_ENT4(_t, _e0, _e1, _e2, _e3) \ ++ { .len = 4, .txt = _t "\t- " _e0 " " _e1 " " _e2 " " _e3 } ++ ++#define __GEN_TXPWR_ENT8(_t, _e0, _e1, _e2, _e3, _e4, _e5, _e6, _e7) \ ++ { .len = 8, .txt = _t "\t- " \ ++ _e0 " " _e1 " " _e2 " " _e3 " " \ ++ _e4 " " _e5 " " _e6 " " _e7 } ++ ++static const struct txpwr_ent __txpwr_ent_byr[] = { ++ __GEN_TXPWR_ENT4("CCK ", "1M ", "2M ", "5.5M ", "11M "), ++ __GEN_TXPWR_ENT4("LEGACY ", "6M ", "9M ", "12M ", "18M "), ++ __GEN_TXPWR_ENT4("LEGACY ", "24M ", "36M ", "48M ", "54M "), ++ /* 1NSS */ ++ __GEN_TXPWR_ENT4("MCS_1NSS ", "MCS0 ", "MCS1 ", "MCS2 ", "MCS3 "), ++ __GEN_TXPWR_ENT4("MCS_1NSS ", "MCS4 ", "MCS5 ", "MCS6 ", "MCS7 "), ++ __GEN_TXPWR_ENT4("MCS_1NSS ", "MCS8 ", "MCS9 ", "MCS10", "MCS11"), ++ __GEN_TXPWR_ENT4("HEDCM_1NSS", "MCS0 ", "MCS1 ", "MCS3 ", "MCS4 "), ++ /* 2NSS */ ++ __GEN_TXPWR_ENT4("MCS_2NSS ", "MCS0 ", "MCS1 ", "MCS2 ", "MCS3 "), ++ __GEN_TXPWR_ENT4("MCS_2NSS ", "MCS4 ", "MCS5 ", "MCS6 ", "MCS7 "), ++ __GEN_TXPWR_ENT4("MCS_2NSS ", "MCS8 ", "MCS9 ", "MCS10", "MCS11"), ++ __GEN_TXPWR_ENT4("HEDCM_2NSS", "MCS0 ", "MCS1 ", "MCS3 ", "MCS4 "), ++}; ++ ++static_assert((ARRAY_SIZE(__txpwr_ent_byr) * 4) == ++ (R_AX_PWR_BY_RATE_MAX - R_AX_PWR_BY_RATE + 4)); ++ ++static const struct txpwr_map __txpwr_map_byr = { ++ .ent = __txpwr_ent_byr, ++ .size = ARRAY_SIZE(__txpwr_ent_byr), ++ .addr_from = R_AX_PWR_BY_RATE, ++ .addr_to = R_AX_PWR_BY_RATE_MAX, ++}; ++ ++static const struct txpwr_ent __txpwr_ent_lmt[] = { ++ /* 1TX */ ++ __GEN_TXPWR_ENT2("CCK_1TX_20M ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("CCK_1TX_40M ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("OFDM_1TX ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_0 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_1 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_2 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_3 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_4 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_5 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_6 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_7 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_40M_0 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_40M_1 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_40M_2 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_40M_3 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_80M_0 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_80M_1 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_160M ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_40M_0p5", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_40M_2p5", "NON_BF", "BF"), ++ /* 2TX */ ++ __GEN_TXPWR_ENT2("CCK_2TX_20M ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("CCK_2TX_40M ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("OFDM_2TX ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_0 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_1 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_2 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_3 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_4 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_5 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_6 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_7 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_40M_0 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_40M_1 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_40M_2 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_40M_3 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_80M_0 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_80M_1 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_160M ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_40M_0p5", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_40M_2p5", "NON_BF", "BF"), ++}; ++ ++static_assert((ARRAY_SIZE(__txpwr_ent_lmt) * 2) == ++ (R_AX_PWR_LMT_MAX - R_AX_PWR_LMT + 4)); ++ ++static const struct txpwr_map __txpwr_map_lmt = { ++ .ent = __txpwr_ent_lmt, ++ .size = ARRAY_SIZE(__txpwr_ent_lmt), ++ .addr_from = R_AX_PWR_LMT, ++ .addr_to = R_AX_PWR_LMT_MAX, ++}; ++ ++static const struct txpwr_ent __txpwr_ent_lmt_ru[] = { ++ /* 1TX */ ++ __GEN_TXPWR_ENT8("1TX", "RU26__0", "RU26__1", "RU26__2", "RU26__3", ++ "RU26__4", "RU26__5", "RU26__6", "RU26__7"), ++ __GEN_TXPWR_ENT8("1TX", "RU52__0", "RU52__1", "RU52__2", "RU52__3", ++ "RU52__4", "RU52__5", "RU52__6", "RU52__7"), ++ __GEN_TXPWR_ENT8("1TX", "RU106_0", "RU106_1", "RU106_2", "RU106_3", ++ "RU106_4", "RU106_5", "RU106_6", "RU106_7"), ++ /* 2TX */ ++ __GEN_TXPWR_ENT8("2TX", "RU26__0", "RU26__1", "RU26__2", "RU26__3", ++ "RU26__4", "RU26__5", "RU26__6", "RU26__7"), ++ __GEN_TXPWR_ENT8("2TX", "RU52__0", "RU52__1", "RU52__2", "RU52__3", ++ "RU52__4", "RU52__5", "RU52__6", "RU52__7"), ++ __GEN_TXPWR_ENT8("2TX", "RU106_0", "RU106_1", "RU106_2", "RU106_3", ++ "RU106_4", "RU106_5", "RU106_6", "RU106_7"), ++}; ++ ++static_assert((ARRAY_SIZE(__txpwr_ent_lmt_ru) * 8) == ++ (R_AX_PWR_RU_LMT_MAX - R_AX_PWR_RU_LMT + 4)); ++ ++static const struct txpwr_map __txpwr_map_lmt_ru = { ++ .ent = __txpwr_ent_lmt_ru, ++ .size = ARRAY_SIZE(__txpwr_ent_lmt_ru), ++ .addr_from = R_AX_PWR_RU_LMT, ++ .addr_to = R_AX_PWR_RU_LMT_MAX, ++}; ++ ++static u8 __print_txpwr_ent(struct seq_file *m, const struct txpwr_ent *ent, ++ const u8 *buf, const u8 cur) ++{ ++ char *fmt; ++ ++ switch (ent->len) { ++ case 2: ++ fmt = "%s\t| %3d, %3d,\tdBm\n"; ++ seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1]); ++ return 2; ++ case 4: ++ fmt = "%s\t| %3d, %3d, %3d, %3d,\tdBm\n"; ++ seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1], ++ buf[cur + 2], buf[cur + 3]); ++ return 4; ++ case 8: ++ fmt = "%s\t| %3d, %3d, %3d, %3d, %3d, %3d, %3d, %3d,\tdBm\n"; ++ seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1], ++ buf[cur + 2], buf[cur + 3], buf[cur + 4], ++ buf[cur + 5], buf[cur + 6], buf[cur + 7]); ++ return 8; ++ default: ++ return 0; ++ } ++} ++ ++static int __print_txpwr_map(struct seq_file *m, struct rtw89_dev *rtwdev, ++ const struct txpwr_map *map) ++{ ++ u8 fct = rtwdev->chip->txpwr_factor_mac; ++ u8 *buf, cur, i; ++ u32 val, addr; ++ int ret; ++ ++ buf = vzalloc(map->addr_to - map->addr_from + 4); ++ if (!buf) ++ return -ENOMEM; ++ ++ for (addr = map->addr_from; addr <= map->addr_to; addr += 4) { ++ ret = rtw89_mac_txpwr_read32(rtwdev, RTW89_PHY_0, addr, &val); ++ if (ret) ++ val = MASKDWORD; ++ ++ cur = addr - map->addr_from; ++ for (i = 0; i < 4; i++, val >>= 8) ++ buf[cur + i] = FIELD_GET(MASKBYTE0, val) >> fct; ++ } ++ ++ for (cur = 0, i = 0; i < map->size; i++) ++ cur += __print_txpwr_ent(m, &map->ent[i], buf, cur); ++ ++ vfree(buf); ++ return 0; ++} ++ ++#define case_REGD(_regd) \ ++ case RTW89_ ## _regd: \ ++ seq_puts(m, #_regd "\n"); \ ++ break ++ ++static void __print_regd(struct seq_file *m, struct rtw89_dev *rtwdev) ++{ ++ u8 band = rtwdev->hal.current_band_type; ++ u8 regd = rtw89_regd_get(rtwdev, band); ++ ++ switch (regd) { ++ default: ++ seq_printf(m, "UNKNOWN: %d\n", regd); ++ break; ++ case_REGD(WW); ++ case_REGD(ETSI); ++ case_REGD(FCC); ++ case_REGD(MKK); ++ case_REGD(NA); ++ case_REGD(IC); ++ case_REGD(KCC); ++ case_REGD(NCC); ++ case_REGD(CHILE); ++ case_REGD(ACMA); ++ case_REGD(MEXICO); ++ case_REGD(UKRAINE); ++ case_REGD(CN); ++ } ++} ++ ++#undef case_REGD ++ ++static int rtw89_debug_priv_txpwr_table_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ int ret = 0; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ ++ seq_puts(m, "[Regulatory] "); ++ __print_regd(m, rtwdev); ++ ++ seq_puts(m, "[SAR]\n"); ++ rtw89_print_sar(m, rtwdev); ++ ++ seq_puts(m, "\n[TX power byrate]\n"); ++ ret = __print_txpwr_map(m, rtwdev, &__txpwr_map_byr); ++ if (ret) ++ goto err; ++ ++ seq_puts(m, "\n[TX power limit]\n"); ++ ret = __print_txpwr_map(m, rtwdev, &__txpwr_map_lmt); ++ if (ret) ++ goto err; ++ ++ seq_puts(m, "\n[TX power limit_ru]\n"); ++ ret = __print_txpwr_map(m, rtwdev, &__txpwr_map_lmt_ru); ++ if (ret) ++ goto err; ++ ++err: ++ mutex_unlock(&rtwdev->mutex); ++ return ret; ++} ++ ++static ssize_t ++rtw89_debug_priv_mac_reg_dump_select(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct seq_file *m = (struct seq_file *)filp->private_data; ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ char buf[32]; ++ size_t buf_size; ++ int sel; ++ int ret; ++ ++ buf_size = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, buf_size)) ++ return -EFAULT; ++ ++ buf[buf_size] = '\0'; ++ ret = kstrtoint(buf, 0, &sel); ++ if (ret) ++ return ret; ++ ++ if (sel < RTW89_DBG_SEL_MAC_00 || sel > RTW89_DBG_SEL_RFC) { ++ rtw89_info(rtwdev, "invalid args: %d\n", sel); ++ return -EINVAL; ++ } ++ ++ debugfs_priv->cb_data = sel; ++ rtw89_info(rtwdev, "select mac page dump %d\n", debugfs_priv->cb_data); ++ ++ return count; ++} ++ ++#define RTW89_MAC_PAGE_SIZE 0x100 ++ ++static int rtw89_debug_priv_mac_reg_dump_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ enum rtw89_debug_mac_reg_sel reg_sel = debugfs_priv->cb_data; ++ u32 start, end; ++ u32 i, j, k, page; ++ u32 val; ++ ++ switch (reg_sel) { ++ case RTW89_DBG_SEL_MAC_00: ++ seq_puts(m, "Debug selected MAC page 0x00\n"); ++ start = 0x000; ++ end = 0x014; ++ break; ++ case RTW89_DBG_SEL_MAC_40: ++ seq_puts(m, "Debug selected MAC page 0x40\n"); ++ start = 0x040; ++ end = 0x07f; ++ break; ++ case RTW89_DBG_SEL_MAC_80: ++ seq_puts(m, "Debug selected MAC page 0x80\n"); ++ start = 0x080; ++ end = 0x09f; ++ break; ++ case RTW89_DBG_SEL_MAC_C0: ++ seq_puts(m, "Debug selected MAC page 0xc0\n"); ++ start = 0x0c0; ++ end = 0x0df; ++ break; ++ case RTW89_DBG_SEL_MAC_E0: ++ seq_puts(m, "Debug selected MAC page 0xe0\n"); ++ start = 0x0e0; ++ end = 0x0ff; ++ break; ++ case RTW89_DBG_SEL_BB: ++ seq_puts(m, "Debug selected BB register\n"); ++ start = 0x100; ++ end = 0x17f; ++ break; ++ case RTW89_DBG_SEL_IQK: ++ seq_puts(m, "Debug selected IQK register\n"); ++ start = 0x180; ++ end = 0x1bf; ++ break; ++ case RTW89_DBG_SEL_RFC: ++ seq_puts(m, "Debug selected RFC register\n"); ++ start = 0x1c0; ++ end = 0x1ff; ++ break; ++ default: ++ seq_puts(m, "Selected invalid register page\n"); ++ return -EINVAL; ++ } ++ ++ for (i = start; i <= end; i++) { ++ page = i << 8; ++ for (j = page; j < page + RTW89_MAC_PAGE_SIZE; j += 16) { ++ seq_printf(m, "%08xh : ", 0x18600000 + j); ++ for (k = 0; k < 4; k++) { ++ val = rtw89_read32(rtwdev, j + (k << 2)); ++ seq_printf(m, "%08x ", val); ++ } ++ seq_puts(m, "\n"); ++ } ++ } ++ ++ return 0; ++} ++ ++static ssize_t ++rtw89_debug_priv_mac_mem_dump_select(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct seq_file *m = (struct seq_file *)filp->private_data; ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ char buf[32]; ++ size_t buf_size; ++ u32 sel, start_addr, len; ++ int num; ++ ++ buf_size = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, buf_size)) ++ return -EFAULT; ++ ++ buf[buf_size] = '\0'; ++ num = sscanf(buf, "%x %x %x", &sel, &start_addr, &len); ++ if (num != 3) { ++ rtw89_info(rtwdev, "invalid format: \n"); ++ return -EINVAL; ++ } ++ ++ debugfs_priv->mac_mem.sel = sel; ++ debugfs_priv->mac_mem.start = start_addr; ++ debugfs_priv->mac_mem.len = len; ++ ++ rtw89_info(rtwdev, "select mem %d start %d len %d\n", ++ sel, start_addr, len); ++ ++ return count; ++} ++ ++static const u32 mac_mem_base_addr_table[RTW89_MAC_MEM_MAX] = { ++ [RTW89_MAC_MEM_SHARED_BUF] = SHARED_BUF_BASE_ADDR, ++ [RTW89_MAC_MEM_DMAC_TBL] = DMAC_TBL_BASE_ADDR, ++ [RTW89_MAC_MEM_SHCUT_MACHDR] = SHCUT_MACHDR_BASE_ADDR, ++ [RTW89_MAC_MEM_STA_SCHED] = STA_SCHED_BASE_ADDR, ++ [RTW89_MAC_MEM_RXPLD_FLTR_CAM] = RXPLD_FLTR_CAM_BASE_ADDR, ++ [RTW89_MAC_MEM_SECURITY_CAM] = SECURITY_CAM_BASE_ADDR, ++ [RTW89_MAC_MEM_WOW_CAM] = WOW_CAM_BASE_ADDR, ++ [RTW89_MAC_MEM_CMAC_TBL] = CMAC_TBL_BASE_ADDR, ++ [RTW89_MAC_MEM_ADDR_CAM] = ADDR_CAM_BASE_ADDR, ++ [RTW89_MAC_MEM_BA_CAM] = BA_CAM_BASE_ADDR, ++ [RTW89_MAC_MEM_BCN_IE_CAM0] = BCN_IE_CAM0_BASE_ADDR, ++ [RTW89_MAC_MEM_BCN_IE_CAM1] = BCN_IE_CAM1_BASE_ADDR, ++}; ++ ++static void rtw89_debug_dump_mac_mem(struct seq_file *m, ++ struct rtw89_dev *rtwdev, ++ u8 sel, u32 start_addr, u32 len) ++{ ++ u32 base_addr, start_page, residue; ++ u32 i, j, p, pages; ++ u32 dump_len, remain; ++ u32 val; ++ ++ remain = len; ++ pages = len / MAC_MEM_DUMP_PAGE_SIZE + 1; ++ start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE; ++ residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE; ++ base_addr = mac_mem_base_addr_table[sel]; ++ base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE; ++ ++ for (p = 0; p < pages; p++) { ++ dump_len = min_t(u32, remain, MAC_MEM_DUMP_PAGE_SIZE); ++ rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, base_addr); ++ for (i = R_AX_INDIR_ACCESS_ENTRY + residue; ++ i < R_AX_INDIR_ACCESS_ENTRY + dump_len;) { ++ seq_printf(m, "%08xh:", i); ++ for (j = 0; ++ j < 4 && i < R_AX_INDIR_ACCESS_ENTRY + dump_len; ++ j++, i += 4) { ++ val = rtw89_read32(rtwdev, i); ++ seq_printf(m, " %08x", val); ++ remain -= 4; ++ } ++ seq_puts(m, "\n"); ++ } ++ base_addr += MAC_MEM_DUMP_PAGE_SIZE; ++ } ++} ++ ++static int ++rtw89_debug_priv_mac_mem_dump_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ rtw89_debug_dump_mac_mem(m, rtwdev, ++ debugfs_priv->mac_mem.sel, ++ debugfs_priv->mac_mem.start, ++ debugfs_priv->mac_mem.len); ++ mutex_unlock(&rtwdev->mutex); ++ ++ return 0; ++} ++ ++static ssize_t ++rtw89_debug_priv_mac_dbg_port_dump_select(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct seq_file *m = (struct seq_file *)filp->private_data; ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ char buf[32]; ++ size_t buf_size; ++ int sel, set; ++ int num; ++ bool enable; ++ ++ buf_size = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, buf_size)) ++ return -EFAULT; ++ ++ buf[buf_size] = '\0'; ++ num = sscanf(buf, "%d %d", &sel, &set); ++ if (num != 2) { ++ rtw89_info(rtwdev, "invalid format: \n"); ++ return -EINVAL; ++ } ++ ++ enable = set == 0 ? false : true; ++ switch (sel) { ++ case 0: ++ debugfs_priv->dbgpkg_en.ss_dbg = enable; ++ break; ++ case 1: ++ debugfs_priv->dbgpkg_en.dle_dbg = enable; ++ break; ++ case 2: ++ debugfs_priv->dbgpkg_en.dmac_dbg = enable; ++ break; ++ case 3: ++ debugfs_priv->dbgpkg_en.cmac_dbg = enable; ++ break; ++ case 4: ++ debugfs_priv->dbgpkg_en.dbg_port = enable; ++ break; ++ default: ++ rtw89_info(rtwdev, "invalid args: sel %d set %d\n", sel, set); ++ return -EINVAL; ++ } ++ ++ rtw89_info(rtwdev, "%s debug port dump %d\n", ++ enable ? "Enable" : "Disable", sel); ++ ++ return count; ++} ++ ++static int rtw89_debug_mac_dump_ss_dbg(struct rtw89_dev *rtwdev, ++ struct seq_file *m) ++{ ++ return 0; ++} ++ ++static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev, ++ struct seq_file *m) ++{ ++#define DLE_DFI_DUMP(__type, __target, __sel) \ ++({ \ ++ u32 __ctrl; \ ++ u32 __reg_ctrl = R_AX_##__type##_DBG_FUN_INTF_CTL; \ ++ u32 __reg_data = R_AX_##__type##_DBG_FUN_INTF_DATA; \ ++ u32 __data, __val32; \ ++ int __ret; \ ++ \ ++ __ctrl = FIELD_PREP(B_AX_##__type##_DFI_TRGSEL_MASK, \ ++ DLE_DFI_TYPE_##__target) | \ ++ FIELD_PREP(B_AX_##__type##_DFI_ADDR_MASK, __sel) | \ ++ B_AX_WDE_DFI_ACTIVE; \ ++ rtw89_write32(rtwdev, __reg_ctrl, __ctrl); \ ++ __ret = read_poll_timeout(rtw89_read32, __val32, \ ++ !(__val32 & B_AX_##__type##_DFI_ACTIVE), \ ++ 1000, 50000, false, \ ++ rtwdev, __reg_ctrl); \ ++ if (__ret) { \ ++ rtw89_err(rtwdev, "failed to dump DLE %s %s %d\n", \ ++ #__type, #__target, __sel); \ ++ return __ret; \ ++ } \ ++ \ ++ __data = rtw89_read32(rtwdev, __reg_data); \ ++ __data; \ ++}) ++ ++#define DLE_DFI_FREE_PAGE_DUMP(__m, __type) \ ++({ \ ++ u32 __freepg, __pubpg; \ ++ u32 __freepg_head, __freepg_tail, __pubpg_num; \ ++ \ ++ __freepg = DLE_DFI_DUMP(__type, FREEPG, 0); \ ++ __pubpg = DLE_DFI_DUMP(__type, FREEPG, 1); \ ++ __freepg_head = FIELD_GET(B_AX_DLE_FREE_HEADPG, __freepg); \ ++ __freepg_tail = FIELD_GET(B_AX_DLE_FREE_TAILPG, __freepg); \ ++ __pubpg_num = FIELD_GET(B_AX_DLE_PUB_PGNUM, __pubpg); \ ++ seq_printf(__m, "[%s] freepg head: %d\n", \ ++ #__type, __freepg_head); \ ++ seq_printf(__m, "[%s] freepg tail: %d\n", \ ++ #__type, __freepg_tail); \ ++ seq_printf(__m, "[%s] pubpg num : %d\n", \ ++ #__type, __pubpg_num); \ ++}) ++ ++#define case_QUOTA(__m, __type, __id) \ ++ case __type##_QTAID_##__id: \ ++ val32 = DLE_DFI_DUMP(__type, QUOTA, __type##_QTAID_##__id); \ ++ rsv_pgnum = FIELD_GET(B_AX_DLE_RSV_PGNUM, val32); \ ++ use_pgnum = FIELD_GET(B_AX_DLE_USE_PGNUM, val32); \ ++ seq_printf(__m, "[%s][%s] rsv_pgnum: %d\n", \ ++ #__type, #__id, rsv_pgnum); \ ++ seq_printf(__m, "[%s][%s] use_pgnum: %d\n", \ ++ #__type, #__id, use_pgnum); \ ++ break ++ u32 quota_id; ++ u32 val32; ++ u16 rsv_pgnum, use_pgnum; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL); ++ if (ret) { ++ seq_puts(m, "[DLE] : DMAC not enabled\n"); ++ return ret; ++ } ++ ++ DLE_DFI_FREE_PAGE_DUMP(m, WDE); ++ DLE_DFI_FREE_PAGE_DUMP(m, PLE); ++ for (quota_id = 0; quota_id <= WDE_QTAID_CPUIO; quota_id++) { ++ switch (quota_id) { ++ case_QUOTA(m, WDE, HOST_IF); ++ case_QUOTA(m, WDE, WLAN_CPU); ++ case_QUOTA(m, WDE, DATA_CPU); ++ case_QUOTA(m, WDE, PKTIN); ++ case_QUOTA(m, WDE, CPUIO); ++ } ++ } ++ for (quota_id = 0; quota_id <= PLE_QTAID_CPUIO; quota_id++) { ++ switch (quota_id) { ++ case_QUOTA(m, PLE, B0_TXPL); ++ case_QUOTA(m, PLE, B1_TXPL); ++ case_QUOTA(m, PLE, C2H); ++ case_QUOTA(m, PLE, H2C); ++ case_QUOTA(m, PLE, WLAN_CPU); ++ case_QUOTA(m, PLE, MPDU); ++ case_QUOTA(m, PLE, CMAC0_RX); ++ case_QUOTA(m, PLE, CMAC1_RX); ++ case_QUOTA(m, PLE, CMAC1_BBRPT); ++ case_QUOTA(m, PLE, WDRLS); ++ case_QUOTA(m, PLE, CPUIO); ++ } ++ } ++ ++ return 0; ++ ++#undef case_QUOTA ++#undef DLE_DFI_DUMP ++#undef DLE_DFI_FREE_PAGE_DUMP ++} ++ ++static int rtw89_debug_mac_dump_dmac_dbg(struct rtw89_dev *rtwdev, ++ struct seq_file *m) ++{ ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL); ++ if (ret) { ++ seq_puts(m, "[DMAC] : DMAC not enabled\n"); ++ return ret; ++ } ++ ++ seq_printf(m, "R_AX_DMAC_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR)); ++ seq_printf(m, "[0]R_AX_WDRLS_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR)); ++ seq_printf(m, "[1]R_AX_SEC_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_ERR_IMR_ISR)); ++ seq_printf(m, "[2.1]R_AX_MPDU_TX_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR)); ++ seq_printf(m, "[2.2]R_AX_MPDU_RX_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR)); ++ seq_printf(m, "[3]R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR)); ++ seq_printf(m, "[4]R_AX_WDE_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); ++ seq_printf(m, "[5.1]R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); ++ seq_printf(m, "[5.2]R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1)); ++ seq_printf(m, "[6]R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); ++ seq_printf(m, "[7]R_AX_PKTIN_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); ++ seq_printf(m, "[8.1]R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR)); ++ seq_printf(m, "[8.2]R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); ++ seq_printf(m, "[8.3]R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); ++ seq_printf(m, "[10]R_AX_CPUIO_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_CPUIO_ERR_ISR)); ++ seq_printf(m, "[11.1]R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); ++ seq_printf(m, "[11.2]R_AX_BBRPT_CHINFO_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR_ISR)); ++ seq_printf(m, "[11.3]R_AX_BBRPT_DFS_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR_ISR)); ++ seq_printf(m, "[11.4]R_AX_LA_ERRFLAG=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_LA_ERRFLAG)); ++ ++ return 0; ++} ++ ++static int rtw89_debug_mac_dump_cmac_dbg(struct rtw89_dev *rtwdev, ++ struct seq_file *m) ++{ ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_CMAC_SEL); ++ if (ret) { ++ seq_puts(m, "[CMAC] : CMAC 0 not enabled\n"); ++ return ret; ++ } ++ ++ seq_printf(m, "R_AX_CMAC_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR)); ++ seq_printf(m, "[0]R_AX_SCHEDULE_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR)); ++ seq_printf(m, "[1]R_AX_PTCL_ISR0=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PTCL_ISR0)); ++ seq_printf(m, "[3]R_AX_DLE_CTRL=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_DLE_CTRL)); ++ seq_printf(m, "[4]R_AX_PHYINFO_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR)); ++ seq_printf(m, "[5]R_AX_TXPWR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPWR_ISR)); ++ seq_printf(m, "[6]R_AX_RMAC_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RMAC_ERR_ISR)); ++ seq_printf(m, "[7]R_AX_TMAC_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR)); ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, 1, RTW89_CMAC_SEL); ++ if (ret) { ++ seq_puts(m, "[CMAC] : CMAC 1 not enabled\n"); ++ return ret; ++ } ++ ++ seq_printf(m, "R_AX_CMAC_ERR_ISR_C1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR_C1)); ++ seq_printf(m, "[0]R_AX_SCHEDULE_ERR_ISR_C1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR_C1)); ++ seq_printf(m, "[1]R_AX_PTCL_ISR0_C1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PTCL_ISR0_C1)); ++ seq_printf(m, "[3]R_AX_DLE_CTRL_C1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_DLE_CTRL_C1)); ++ seq_printf(m, "[4]R_AX_PHYINFO_ERR_ISR_C1=0x%02x\n", ++ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR_C1)); ++ seq_printf(m, "[5]R_AX_TXPWR_ISR_C1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPWR_ISR_C1)); ++ seq_printf(m, "[6]R_AX_RMAC_ERR_ISR_C1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RMAC_ERR_ISR_C1)); ++ seq_printf(m, "[7]R_AX_TMAC_ERR_IMR_ISR_C1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR_C1)); ++ ++ return 0; ++} ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c0 = { ++ .sel_addr = R_AX_PTCL_DBG, ++ .sel_byte = 1, ++ .sel_msk = B_AX_PTCL_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x3F, ++ .rd_addr = R_AX_PTCL_DBG_INFO, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PTCL_DBG_INFO_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c1 = { ++ .sel_addr = R_AX_PTCL_DBG_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_PTCL_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x3F, ++ .rd_addr = R_AX_PTCL_DBG_INFO_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PTCL_DBG_INFO_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_sch_c0 = { ++ .sel_addr = R_AX_SCH_DBG_SEL, ++ .sel_byte = 1, ++ .sel_msk = B_AX_SCH_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x2F, ++ .rd_addr = R_AX_SCH_DBG, ++ .rd_byte = 4, ++ .rd_msk = B_AX_SCHEDULER_DBG_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_sch_c1 = { ++ .sel_addr = R_AX_SCH_DBG_SEL_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_SCH_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x2F, ++ .rd_addr = R_AX_SCH_DBG_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_SCHEDULER_DBG_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_tmac_c0 = { ++ .sel_addr = R_AX_MACTX_DBG_SEL_CNT, ++ .sel_byte = 1, ++ .sel_msk = B_AX_DBGSEL_MACTX_MASK, ++ .srt = 0x00, ++ .end = 0x19, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_tmac_c1 = { ++ .sel_addr = R_AX_MACTX_DBG_SEL_CNT_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_DBGSEL_MACTX_MASK, ++ .srt = 0x00, ++ .end = 0x19, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_rmac_c0 = { ++ .sel_addr = R_AX_RX_DEBUG_SELECT, ++ .sel_byte = 1, ++ .sel_msk = B_AX_DEBUG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x58, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_rmac_c1 = { ++ .sel_addr = R_AX_RX_DEBUG_SELECT_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_DEBUG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x58, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_rmacst_c0 = { ++ .sel_addr = R_AX_RX_STATE_MONITOR, ++ .sel_byte = 1, ++ .sel_msk = B_AX_STATE_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x17, ++ .rd_addr = R_AX_RX_STATE_MONITOR, ++ .rd_byte = 4, ++ .rd_msk = B_AX_RX_STATE_MONITOR_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_rmacst_c1 = { ++ .sel_addr = R_AX_RX_STATE_MONITOR_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_STATE_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x17, ++ .rd_addr = R_AX_RX_STATE_MONITOR_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_RX_STATE_MONITOR_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_rmac_plcp_c0 = { ++ .sel_addr = R_AX_RMAC_PLCP_MON, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PCLP_MON_SEL_MASK, ++ .srt = 0x0, ++ .end = 0xF, ++ .rd_addr = R_AX_RMAC_PLCP_MON, ++ .rd_byte = 4, ++ .rd_msk = B_AX_RMAC_PLCP_MON_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_rmac_plcp_c1 = { ++ .sel_addr = R_AX_RMAC_PLCP_MON_C1, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PCLP_MON_SEL_MASK, ++ .srt = 0x0, ++ .end = 0xF, ++ .rd_addr = R_AX_RMAC_PLCP_MON_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_RMAC_PLCP_MON_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_trxptcl_c0 = { ++ .sel_addr = R_AX_DBGSEL_TRXPTCL, ++ .sel_byte = 1, ++ .sel_msk = B_AX_DBGSEL_TRXPTCL_MASK, ++ .srt = 0x08, ++ .end = 0x10, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_trxptcl_c1 = { ++ .sel_addr = R_AX_DBGSEL_TRXPTCL_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_DBGSEL_TRXPTCL_MASK, ++ .srt = 0x08, ++ .end = 0x10, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_tx_infol_c0 = { ++ .sel_addr = R_AX_WMAC_TX_CTRL_DEBUG, ++ .sel_byte = 1, ++ .sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x07, ++ .rd_addr = R_AX_WMAC_TX_INFO0_DEBUG, ++ .rd_byte = 4, ++ .rd_msk = B_AX_TX_CTRL_INFO_P0_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_tx_infoh_c0 = { ++ .sel_addr = R_AX_WMAC_TX_CTRL_DEBUG, ++ .sel_byte = 1, ++ .sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x07, ++ .rd_addr = R_AX_WMAC_TX_INFO1_DEBUG, ++ .rd_byte = 4, ++ .rd_msk = B_AX_TX_CTRL_INFO_P1_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_tx_infol_c1 = { ++ .sel_addr = R_AX_WMAC_TX_CTRL_DEBUG_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x07, ++ .rd_addr = R_AX_WMAC_TX_INFO0_DEBUG_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_TX_CTRL_INFO_P0_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_tx_infoh_c1 = { ++ .sel_addr = R_AX_WMAC_TX_CTRL_DEBUG_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x07, ++ .rd_addr = R_AX_WMAC_TX_INFO1_DEBUG_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_TX_CTRL_INFO_P1_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infol_c0 = { ++ .sel_addr = R_AX_WMAC_TX_TF_INFO_0, ++ .sel_byte = 1, ++ .sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x04, ++ .rd_addr = R_AX_WMAC_TX_TF_INFO_1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WMAC_TX_TF_INFO_P0_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infoh_c0 = { ++ .sel_addr = R_AX_WMAC_TX_TF_INFO_0, ++ .sel_byte = 1, ++ .sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x04, ++ .rd_addr = R_AX_WMAC_TX_TF_INFO_2, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WMAC_TX_TF_INFO_P1_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infol_c1 = { ++ .sel_addr = R_AX_WMAC_TX_TF_INFO_0_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x04, ++ .rd_addr = R_AX_WMAC_TX_TF_INFO_1_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WMAC_TX_TF_INFO_P0_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infoh_c1 = { ++ .sel_addr = R_AX_WMAC_TX_TF_INFO_0_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x04, ++ .rd_addr = R_AX_WMAC_TX_TF_INFO_2_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WMAC_TX_TF_INFO_P1_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_freepg = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80000000, ++ .end = 0x80000001, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_quota = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80010000, ++ .end = 0x80010004, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_pagellt = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80020000, ++ .end = 0x80020FFF, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_pktinfo = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80030000, ++ .end = 0x80030FFF, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_prepkt = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80040000, ++ .end = 0x80040FFF, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_nxtpkt = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80050000, ++ .end = 0x80050FFF, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_qlnktbl = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80060000, ++ .end = 0x80060453, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_qempty = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80070000, ++ .end = 0x80070011, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_freepg = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80000000, ++ .end = 0x80000001, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_quota = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80010000, ++ .end = 0x8001000A, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_pagellt = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80020000, ++ .end = 0x80020DBF, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_pktinfo = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80030000, ++ .end = 0x80030DBF, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_prepkt = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80040000, ++ .end = 0x80040DBF, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_nxtpkt = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80050000, ++ .end = 0x80050DBF, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_qlnktbl = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80060000, ++ .end = 0x80060041, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_qempty = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80070000, ++ .end = 0x80070001, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pktinfo = { ++ .sel_addr = R_AX_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_DFI_DATA_MASK, ++ .srt = 0x80000000, ++ .end = 0x8000017f, ++ .rd_addr = R_AX_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pcie_txdma = { ++ .sel_addr = R_AX_PCIE_DBG_CTRL, ++ .sel_byte = 2, ++ .sel_msk = B_AX_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x03, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pcie_rxdma = { ++ .sel_addr = R_AX_PCIE_DBG_CTRL, ++ .sel_byte = 2, ++ .sel_msk = B_AX_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x04, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pcie_cvt = { ++ .sel_addr = R_AX_PCIE_DBG_CTRL, ++ .sel_byte = 2, ++ .sel_msk = B_AX_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x01, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pcie_cxpl = { ++ .sel_addr = R_AX_PCIE_DBG_CTRL, ++ .sel_byte = 2, ++ .sel_msk = B_AX_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x05, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pcie_io = { ++ .sel_addr = R_AX_PCIE_DBG_CTRL, ++ .sel_byte = 2, ++ .sel_msk = B_AX_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x05, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pcie_misc = { ++ .sel_addr = R_AX_PCIE_DBG_CTRL, ++ .sel_byte = 2, ++ .sel_msk = B_AX_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x06, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pcie_misc2 = { ++ .sel_addr = R_AX_DBG_CTRL, ++ .sel_byte = 1, ++ .sel_msk = B_AX_DBG_SEL0, ++ .srt = 0x34, ++ .end = 0x3C, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info * ++rtw89_debug_mac_dbg_port_sel(struct seq_file *m, ++ struct rtw89_dev *rtwdev, u32 sel) ++{ ++ const struct rtw89_mac_dbg_port_info *info; ++ u32 val32; ++ u16 val16; ++ u8 val8; ++ ++ switch (sel) { ++ case RTW89_DBG_PORT_SEL_PTCL_C0: ++ info = &dbg_port_ptcl_c0; ++ val16 = rtw89_read16(rtwdev, R_AX_PTCL_DBG); ++ val16 |= B_AX_PTCL_DBG_EN; ++ rtw89_write16(rtwdev, R_AX_PTCL_DBG, val16); ++ seq_puts(m, "Enable PTCL C0 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PTCL_C1: ++ info = &dbg_port_ptcl_c1; ++ val16 = rtw89_read16(rtwdev, R_AX_PTCL_DBG_C1); ++ val16 |= B_AX_PTCL_DBG_EN; ++ rtw89_write16(rtwdev, R_AX_PTCL_DBG_C1, val16); ++ seq_puts(m, "Enable PTCL C1 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_SCH_C0: ++ info = &dbg_port_sch_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_SCH_DBG_SEL); ++ val32 |= B_AX_SCH_DBG_EN; ++ rtw89_write32(rtwdev, R_AX_SCH_DBG_SEL, val32); ++ seq_puts(m, "Enable SCH C0 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_SCH_C1: ++ info = &dbg_port_sch_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_SCH_DBG_SEL_C1); ++ val32 |= B_AX_SCH_DBG_EN; ++ rtw89_write32(rtwdev, R_AX_SCH_DBG_SEL_C1, val32); ++ seq_puts(m, "Enable SCH C1 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TMAC_C0: ++ info = &dbg_port_tmac_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL); ++ val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_TMAC, ++ B_AX_DBGSEL_TRXPTCL_MASK); ++ rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C0, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C0, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); ++ val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); ++ rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); ++ seq_puts(m, "Enable TMAC C0 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TMAC_C1: ++ info = &dbg_port_tmac_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1); ++ val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_TMAC, ++ B_AX_DBGSEL_TRXPTCL_MASK); ++ rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C1, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C1, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); ++ val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); ++ rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); ++ seq_puts(m, "Enable TMAC C1 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_RMAC_C0: ++ info = &dbg_port_rmac_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL); ++ val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_RMAC, ++ B_AX_DBGSEL_TRXPTCL_MASK); ++ rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C0, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C0, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); ++ val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); ++ rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); ++ ++ val8 = rtw89_read8(rtwdev, R_AX_DBGSEL_TRXPTCL); ++ val8 = u8_replace_bits(val8, RMAC_CMAC_DBG_SEL, ++ B_AX_DBGSEL_TRXPTCL_MASK); ++ rtw89_write8(rtwdev, R_AX_DBGSEL_TRXPTCL, val8); ++ seq_puts(m, "Enable RMAC C0 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_RMAC_C1: ++ info = &dbg_port_rmac_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1); ++ val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_RMAC, ++ B_AX_DBGSEL_TRXPTCL_MASK); ++ rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C1, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C1, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); ++ val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); ++ rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); ++ ++ val8 = rtw89_read8(rtwdev, R_AX_DBGSEL_TRXPTCL_C1); ++ val8 = u8_replace_bits(val8, RMAC_CMAC_DBG_SEL, ++ B_AX_DBGSEL_TRXPTCL_MASK); ++ rtw89_write8(rtwdev, R_AX_DBGSEL_TRXPTCL_C1, val8); ++ seq_puts(m, "Enable RMAC C1 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_RMACST_C0: ++ info = &dbg_port_rmacst_c0; ++ seq_puts(m, "Enable RMAC state C0 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_RMACST_C1: ++ info = &dbg_port_rmacst_c1; ++ seq_puts(m, "Enable RMAC state C1 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_RMAC_PLCP_C0: ++ info = &dbg_port_rmac_plcp_c0; ++ seq_puts(m, "Enable RMAC PLCP C0 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_RMAC_PLCP_C1: ++ info = &dbg_port_rmac_plcp_c1; ++ seq_puts(m, "Enable RMAC PLCP C1 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TRXPTCL_C0: ++ info = &dbg_port_trxptcl_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C0, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C0, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); ++ val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); ++ rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); ++ seq_puts(m, "Enable TRXPTCL C0 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TRXPTCL_C1: ++ info = &dbg_port_trxptcl_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C1, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C1, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); ++ val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); ++ rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); ++ seq_puts(m, "Enable TRXPTCL C1 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TX_INFOL_C0: ++ info = &dbg_port_tx_infol_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1, val32); ++ seq_puts(m, "Enable tx infol dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TX_INFOH_C0: ++ info = &dbg_port_tx_infoh_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1, val32); ++ seq_puts(m, "Enable tx infoh dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TX_INFOL_C1: ++ info = &dbg_port_tx_infol_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); ++ seq_puts(m, "Enable tx infol dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TX_INFOH_C1: ++ info = &dbg_port_tx_infoh_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); ++ seq_puts(m, "Enable tx infoh dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TXTF_INFOL_C0: ++ info = &dbg_port_txtf_infol_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1, val32); ++ seq_puts(m, "Enable tx tf infol dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TXTF_INFOH_C0: ++ info = &dbg_port_txtf_infoh_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1, val32); ++ seq_puts(m, "Enable tx tf infoh dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TXTF_INFOL_C1: ++ info = &dbg_port_txtf_infol_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); ++ seq_puts(m, "Enable tx tf infol dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TXTF_INFOH_C1: ++ info = &dbg_port_txtf_infoh_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); ++ seq_puts(m, "Enable tx tf infoh dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG: ++ info = &dbg_port_wde_bufmgn_freepg; ++ seq_puts(m, "Enable wde bufmgn freepg dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_BUFMGN_QUOTA: ++ info = &dbg_port_wde_bufmgn_quota; ++ seq_puts(m, "Enable wde bufmgn quota dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_BUFMGN_PAGELLT: ++ info = &dbg_port_wde_bufmgn_pagellt; ++ seq_puts(m, "Enable wde bufmgn pagellt dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_BUFMGN_PKTINFO: ++ info = &dbg_port_wde_bufmgn_pktinfo; ++ seq_puts(m, "Enable wde bufmgn pktinfo dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_QUEMGN_PREPKT: ++ info = &dbg_port_wde_quemgn_prepkt; ++ seq_puts(m, "Enable wde quemgn prepkt dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_QUEMGN_NXTPKT: ++ info = &dbg_port_wde_quemgn_nxtpkt; ++ seq_puts(m, "Enable wde quemgn nxtpkt dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_QUEMGN_QLNKTBL: ++ info = &dbg_port_wde_quemgn_qlnktbl; ++ seq_puts(m, "Enable wde quemgn qlnktbl dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_QUEMGN_QEMPTY: ++ info = &dbg_port_wde_quemgn_qempty; ++ seq_puts(m, "Enable wde quemgn qempty dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_BUFMGN_FREEPG: ++ info = &dbg_port_ple_bufmgn_freepg; ++ seq_puts(m, "Enable ple bufmgn freepg dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_BUFMGN_QUOTA: ++ info = &dbg_port_ple_bufmgn_quota; ++ seq_puts(m, "Enable ple bufmgn quota dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_BUFMGN_PAGELLT: ++ info = &dbg_port_ple_bufmgn_pagellt; ++ seq_puts(m, "Enable ple bufmgn pagellt dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_BUFMGN_PKTINFO: ++ info = &dbg_port_ple_bufmgn_pktinfo; ++ seq_puts(m, "Enable ple bufmgn pktinfo dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_QUEMGN_PREPKT: ++ info = &dbg_port_ple_quemgn_prepkt; ++ seq_puts(m, "Enable ple quemgn prepkt dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_QUEMGN_NXTPKT: ++ info = &dbg_port_ple_quemgn_nxtpkt; ++ seq_puts(m, "Enable ple quemgn nxtpkt dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_QUEMGN_QLNKTBL: ++ info = &dbg_port_ple_quemgn_qlnktbl; ++ seq_puts(m, "Enable ple quemgn qlnktbl dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_QUEMGN_QEMPTY: ++ info = &dbg_port_ple_quemgn_qempty; ++ seq_puts(m, "Enable ple quemgn qempty dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PKTINFO: ++ info = &dbg_port_pktinfo; ++ seq_puts(m, "Enable pktinfo dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PCIE_TXDMA: ++ info = &dbg_port_pcie_txdma; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, PCIE_TXDMA_DBG_SEL, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, PCIE_TXDMA_DBG_SEL, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ seq_puts(m, "Enable pcie txdma dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PCIE_RXDMA: ++ info = &dbg_port_pcie_rxdma; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, PCIE_RXDMA_DBG_SEL, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, PCIE_RXDMA_DBG_SEL, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ seq_puts(m, "Enable pcie rxdma dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PCIE_CVT: ++ info = &dbg_port_pcie_cvt; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, PCIE_CVT_DBG_SEL, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, PCIE_CVT_DBG_SEL, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ seq_puts(m, "Enable pcie cvt dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PCIE_CXPL: ++ info = &dbg_port_pcie_cxpl; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, PCIE_CXPL_DBG_SEL, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, PCIE_CXPL_DBG_SEL, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ seq_puts(m, "Enable pcie cxpl dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PCIE_IO: ++ info = &dbg_port_pcie_io; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, PCIE_IO_DBG_SEL, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, PCIE_IO_DBG_SEL, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ seq_puts(m, "Enable pcie io dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PCIE_MISC: ++ info = &dbg_port_pcie_misc; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, PCIE_MISC_DBG_SEL, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, PCIE_MISC_DBG_SEL, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ seq_puts(m, "Enable pcie misc dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PCIE_MISC2: ++ info = &dbg_port_pcie_misc2; ++ val16 = rtw89_read16(rtwdev, R_AX_PCIE_DBG_CTRL); ++ val16 = u16_replace_bits(val16, PCIE_MISC2_DBG_SEL, ++ B_AX_DBG_SEL_MASK); ++ rtw89_write16(rtwdev, R_AX_PCIE_DBG_CTRL, val16); ++ seq_puts(m, "Enable pcie misc2 dump.\n"); ++ break; ++ default: ++ seq_puts(m, "Dbg port select err\n"); ++ return NULL; ++ } ++ ++ return info; ++} ++ ++static bool is_dbg_port_valid(struct rtw89_dev *rtwdev, u32 sel) ++{ ++ if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE && ++ sel >= RTW89_DBG_PORT_SEL_PCIE_TXDMA && ++ sel <= RTW89_DBG_PORT_SEL_PCIE_MISC2) ++ return false; ++ if (rtwdev->chip->chip_id == RTL8852B && ++ sel >= RTW89_DBG_PORT_SEL_PTCL_C1 && ++ sel <= RTW89_DBG_PORT_SEL_TXTF_INFOH_C1) ++ return false; ++ if (rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL) && ++ sel >= RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG && ++ sel <= RTW89_DBG_PORT_SEL_PKTINFO) ++ return false; ++ if (rtw89_mac_check_mac_en(rtwdev, 0, RTW89_CMAC_SEL) && ++ sel >= RTW89_DBG_PORT_SEL_PTCL_C0 && ++ sel <= RTW89_DBG_PORT_SEL_TXTF_INFOH_C0) ++ return false; ++ if (rtw89_mac_check_mac_en(rtwdev, 1, RTW89_CMAC_SEL) && ++ sel >= RTW89_DBG_PORT_SEL_PTCL_C1 && ++ sel <= RTW89_DBG_PORT_SEL_TXTF_INFOH_C1) ++ return false; ++ ++ return true; ++} ++ ++static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev, ++ struct seq_file *m, u32 sel) ++{ ++ const struct rtw89_mac_dbg_port_info *info; ++ u8 val8; ++ u16 val16; ++ u32 val32; ++ u32 i; ++ ++ info = rtw89_debug_mac_dbg_port_sel(m, rtwdev, sel); ++ if (!info) { ++ rtw89_err(rtwdev, "failed to select debug port %d\n", sel); ++ return -EINVAL; ++ } ++ ++#define case_DBG_SEL(__sel) \ ++ case RTW89_DBG_PORT_SEL_##__sel: \ ++ seq_puts(m, "Dump debug port " #__sel ":\n"); \ ++ break ++ ++ switch (sel) { ++ case_DBG_SEL(PTCL_C0); ++ case_DBG_SEL(PTCL_C1); ++ case_DBG_SEL(SCH_C0); ++ case_DBG_SEL(SCH_C1); ++ case_DBG_SEL(TMAC_C0); ++ case_DBG_SEL(TMAC_C1); ++ case_DBG_SEL(RMAC_C0); ++ case_DBG_SEL(RMAC_C1); ++ case_DBG_SEL(RMACST_C0); ++ case_DBG_SEL(RMACST_C1); ++ case_DBG_SEL(TRXPTCL_C0); ++ case_DBG_SEL(TRXPTCL_C1); ++ case_DBG_SEL(TX_INFOL_C0); ++ case_DBG_SEL(TX_INFOH_C0); ++ case_DBG_SEL(TX_INFOL_C1); ++ case_DBG_SEL(TX_INFOH_C1); ++ case_DBG_SEL(TXTF_INFOL_C0); ++ case_DBG_SEL(TXTF_INFOH_C0); ++ case_DBG_SEL(TXTF_INFOL_C1); ++ case_DBG_SEL(TXTF_INFOH_C1); ++ case_DBG_SEL(WDE_BUFMGN_FREEPG); ++ case_DBG_SEL(WDE_BUFMGN_QUOTA); ++ case_DBG_SEL(WDE_BUFMGN_PAGELLT); ++ case_DBG_SEL(WDE_BUFMGN_PKTINFO); ++ case_DBG_SEL(WDE_QUEMGN_PREPKT); ++ case_DBG_SEL(WDE_QUEMGN_NXTPKT); ++ case_DBG_SEL(WDE_QUEMGN_QLNKTBL); ++ case_DBG_SEL(WDE_QUEMGN_QEMPTY); ++ case_DBG_SEL(PLE_BUFMGN_FREEPG); ++ case_DBG_SEL(PLE_BUFMGN_QUOTA); ++ case_DBG_SEL(PLE_BUFMGN_PAGELLT); ++ case_DBG_SEL(PLE_BUFMGN_PKTINFO); ++ case_DBG_SEL(PLE_QUEMGN_PREPKT); ++ case_DBG_SEL(PLE_QUEMGN_NXTPKT); ++ case_DBG_SEL(PLE_QUEMGN_QLNKTBL); ++ case_DBG_SEL(PLE_QUEMGN_QEMPTY); ++ case_DBG_SEL(PKTINFO); ++ case_DBG_SEL(PCIE_TXDMA); ++ case_DBG_SEL(PCIE_RXDMA); ++ case_DBG_SEL(PCIE_CVT); ++ case_DBG_SEL(PCIE_CXPL); ++ case_DBG_SEL(PCIE_IO); ++ case_DBG_SEL(PCIE_MISC); ++ case_DBG_SEL(PCIE_MISC2); ++ } ++ ++#undef case_DBG_SEL ++ ++ seq_printf(m, "Sel addr = 0x%X\n", info->sel_addr); ++ seq_printf(m, "Read addr = 0x%X\n", info->rd_addr); ++ ++ for (i = info->srt; i <= info->end; i++) { ++ switch (info->sel_byte) { ++ case 1: ++ default: ++ rtw89_write8_mask(rtwdev, info->sel_addr, ++ info->sel_msk, i); ++ seq_printf(m, "0x%02X: ", i); ++ break; ++ case 2: ++ rtw89_write16_mask(rtwdev, info->sel_addr, ++ info->sel_msk, i); ++ seq_printf(m, "0x%04X: ", i); ++ break; ++ case 4: ++ rtw89_write32_mask(rtwdev, info->sel_addr, ++ info->sel_msk, i); ++ seq_printf(m, "0x%04X: ", i); ++ break; ++ } ++ ++ udelay(10); ++ ++ switch (info->rd_byte) { ++ case 1: ++ default: ++ val8 = rtw89_read8_mask(rtwdev, ++ info->rd_addr, info->rd_msk); ++ seq_printf(m, "0x%02X\n", val8); ++ break; ++ case 2: ++ val16 = rtw89_read16_mask(rtwdev, ++ info->rd_addr, info->rd_msk); ++ seq_printf(m, "0x%04X\n", val16); ++ break; ++ case 4: ++ val32 = rtw89_read32_mask(rtwdev, ++ info->rd_addr, info->rd_msk); ++ seq_printf(m, "0x%08X\n", val32); ++ break; ++ } ++ } ++ ++ return 0; ++} ++ ++static int rtw89_debug_mac_dump_dbg_port(struct rtw89_dev *rtwdev, ++ struct seq_file *m) ++{ ++ u32 sel; ++ int ret = 0; ++ ++ for (sel = RTW89_DBG_PORT_SEL_PTCL_C0; ++ sel < RTW89_DBG_PORT_SEL_LAST; sel++) { ++ if (!is_dbg_port_valid(rtwdev, sel)) ++ continue; ++ ret = rtw89_debug_mac_dbg_port_dump(rtwdev, m, sel); ++ if (ret) { ++ rtw89_err(rtwdev, ++ "failed to dump debug port %d\n", sel); ++ break; ++ } ++ } ++ ++ return ret; ++} ++ ++static int ++rtw89_debug_priv_mac_dbg_port_dump_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ ++ if (debugfs_priv->dbgpkg_en.ss_dbg) ++ rtw89_debug_mac_dump_ss_dbg(rtwdev, m); ++ if (debugfs_priv->dbgpkg_en.dle_dbg) ++ rtw89_debug_mac_dump_dle_dbg(rtwdev, m); ++ if (debugfs_priv->dbgpkg_en.dmac_dbg) ++ rtw89_debug_mac_dump_dmac_dbg(rtwdev, m); ++ if (debugfs_priv->dbgpkg_en.cmac_dbg) ++ rtw89_debug_mac_dump_cmac_dbg(rtwdev, m); ++ if (debugfs_priv->dbgpkg_en.dbg_port) ++ rtw89_debug_mac_dump_dbg_port(rtwdev, m); ++ ++ return 0; ++}; ++ ++static u8 *rtw89_hex2bin_user(struct rtw89_dev *rtwdev, ++ const char __user *user_buf, size_t count) ++{ ++ char *buf; ++ u8 *bin; ++ int num; ++ int err = 0; ++ ++ buf = memdup_user(user_buf, count); ++ if (IS_ERR(buf)) ++ return buf; ++ ++ num = count / 2; ++ bin = kmalloc(num, GFP_KERNEL); ++ if (!bin) { ++ err = -EFAULT; ++ goto out; ++ } ++ ++ if (hex2bin(bin, buf, num)) { ++ rtw89_info(rtwdev, "valid format: H1H2H3...\n"); ++ kfree(bin); ++ err = -EINVAL; ++ } ++ ++out: ++ kfree(buf); ++ ++ return err ? ERR_PTR(err) : bin; ++} ++ ++static ssize_t rtw89_debug_priv_send_h2c_set(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ u8 *h2c; ++ u16 h2c_len = count / 2; ++ ++ h2c = rtw89_hex2bin_user(rtwdev, user_buf, count); ++ if (IS_ERR(h2c)) ++ return -EFAULT; ++ ++ rtw89_fw_h2c_raw(rtwdev, h2c, h2c_len); ++ ++ kfree(h2c); ++ ++ return count; ++} ++ ++static int ++rtw89_debug_priv_early_h2c_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ struct rtw89_early_h2c *early_h2c; ++ int seq = 0; ++ ++ mutex_lock(&rtwdev->mutex); ++ list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) ++ seq_printf(m, "%d: %*ph\n", ++seq, early_h2c->h2c_len, early_h2c->h2c); ++ mutex_unlock(&rtwdev->mutex); ++ ++ return 0; ++} ++ ++static ssize_t ++rtw89_debug_priv_early_h2c_set(struct file *filp, const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct seq_file *m = (struct seq_file *)filp->private_data; ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ struct rtw89_early_h2c *early_h2c; ++ u8 *h2c; ++ u16 h2c_len = count / 2; ++ ++ h2c = rtw89_hex2bin_user(rtwdev, user_buf, count); ++ if (IS_ERR(h2c)) ++ return -EFAULT; ++ ++ if (h2c_len >= 2 && h2c[0] == 0x00 && h2c[1] == 0x00) { ++ kfree(h2c); ++ rtw89_fw_free_all_early_h2c(rtwdev); ++ goto out; ++ } ++ ++ early_h2c = kmalloc(sizeof(*early_h2c), GFP_KERNEL); ++ if (!early_h2c) { ++ kfree(h2c); ++ return -EFAULT; ++ } ++ ++ early_h2c->h2c = h2c; ++ early_h2c->h2c_len = h2c_len; ++ ++ mutex_lock(&rtwdev->mutex); ++ list_add_tail(&early_h2c->list, &rtwdev->early_h2c_list); ++ mutex_unlock(&rtwdev->mutex); ++ ++out: ++ return count; ++} ++ ++static int rtw89_debug_priv_btc_info_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ ++ rtw89_btc_dump_info(rtwdev, m); ++ ++ return 0; ++} ++ ++static ssize_t rtw89_debug_priv_btc_manual_set(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ bool btc_manual; ++ ++ if (kstrtobool_from_user(user_buf, count, &btc_manual)) ++ goto out; ++ ++ btc->ctrl.manual = btc_manual; ++out: ++ return count; ++} ++ ++static ssize_t rtw89_debug_fw_log_btc_manual_set(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ struct rtw89_fw_info *fw_info = &rtwdev->fw; ++ bool fw_log_manual; ++ ++ if (kstrtobool_from_user(user_buf, count, &fw_log_manual)) ++ goto out; ++ ++ mutex_lock(&rtwdev->mutex); ++ fw_info->fw_log_enable = fw_log_manual; ++ rtw89_fw_h2c_fw_log(rtwdev, fw_log_manual); ++ mutex_unlock(&rtwdev->mutex); ++out: ++ return count; ++} ++ ++static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) ++{ ++ static const char * const he_gi_str[] = { ++ [NL80211_RATE_INFO_HE_GI_0_8] = "0.8", ++ [NL80211_RATE_INFO_HE_GI_1_6] = "1.6", ++ [NL80211_RATE_INFO_HE_GI_3_2] = "3.2", ++ }; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rate_info *rate = &rtwsta->ra_report.txrate; ++ struct ieee80211_rx_status *status = &rtwsta->rx_status; ++ struct seq_file *m = (struct seq_file *)data; ++ u8 rssi; ++ ++ seq_printf(m, "TX rate [%d]: ", rtwsta->mac_id); ++ ++ if (rate->flags & RATE_INFO_FLAGS_MCS) ++ seq_printf(m, "HT MCS-%d%s", rate->mcs, ++ rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : ""); ++ else if (rate->flags & RATE_INFO_FLAGS_VHT_MCS) ++ seq_printf(m, "VHT %dSS MCS-%d%s", rate->nss, rate->mcs, ++ rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : ""); ++ else if (rate->flags & RATE_INFO_FLAGS_HE_MCS) ++ seq_printf(m, "HE %dSS MCS-%d GI:%s", rate->nss, rate->mcs, ++ rate->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ? ++ he_gi_str[rate->he_gi] : "N/A"); ++ else ++ seq_printf(m, "Legacy %d", rate->legacy); ++ seq_printf(m, "\t(hw_rate=0x%x)", rtwsta->ra_report.hw_rate); ++ seq_printf(m, "\t==> agg_wait=%d (%d)\n", rtwsta->max_agg_wait, ++ sta->max_rc_amsdu_len); ++ ++ seq_printf(m, "RX rate [%d]: ", rtwsta->mac_id); ++ ++ switch (status->encoding) { ++ case RX_ENC_LEGACY: ++ seq_printf(m, "Legacy %d", status->rate_idx + ++ (status->band == NL80211_BAND_5GHZ ? 4 : 0)); ++ break; ++ case RX_ENC_HT: ++ seq_printf(m, "HT MCS-%d%s", status->rate_idx, ++ status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : ""); ++ break; ++ case RX_ENC_VHT: ++ seq_printf(m, "VHT %dSS MCS-%d%s", status->nss, status->rate_idx, ++ status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : ""); ++ break; ++ case RX_ENC_HE: ++ seq_printf(m, "HE %dSS MCS-%d GI:%s", status->nss, status->rate_idx, ++ status->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ? ++ he_gi_str[rate->he_gi] : "N/A"); ++ break; ++ } ++ seq_printf(m, "\t(hw_rate=0x%x)\n", rtwsta->rx_hw_rate); ++ ++ rssi = ewma_rssi_read(&rtwsta->avg_rssi); ++ seq_printf(m, "RSSI: %d dBm (raw=%d, prev=%d)\n", ++ RTW89_RSSI_RAW_TO_DBM(rssi), rssi, rtwsta->prev_rssi); ++} ++ ++static void ++rtw89_debug_append_rx_rate(struct seq_file *m, struct rtw89_pkt_stat *pkt_stat, ++ enum rtw89_hw_rate first_rate, int len) ++{ ++ int i; ++ ++ for (i = 0; i < len; i++) ++ seq_printf(m, "%s%u", i == 0 ? "" : ", ", ++ pkt_stat->rx_rate_cnt[first_rate + i]); ++} ++ ++static const struct rtw89_rx_rate_cnt_info { ++ enum rtw89_hw_rate first_rate; ++ int len; ++ const char *rate_mode; ++} rtw89_rx_rate_cnt_infos[] = { ++ {RTW89_HW_RATE_CCK1, 4, "Legacy:"}, ++ {RTW89_HW_RATE_OFDM6, 8, "OFDM:"}, ++ {RTW89_HW_RATE_MCS0, 8, "HT 0:"}, ++ {RTW89_HW_RATE_MCS8, 8, "HT 1:"}, ++ {RTW89_HW_RATE_VHT_NSS1_MCS0, 10, "VHT 1SS:"}, ++ {RTW89_HW_RATE_VHT_NSS2_MCS0, 10, "VHT 2SS:"}, ++ {RTW89_HW_RATE_HE_NSS1_MCS0, 12, "HE 1SS:"}, ++ {RTW89_HW_RATE_HE_NSS2_MCS0, 12, "HE 2ss:"}, ++}; ++ ++static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ struct rtw89_traffic_stats *stats = &rtwdev->stats; ++ struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.last_pkt_stat; ++ const struct rtw89_rx_rate_cnt_info *info; ++ int i; ++ ++ seq_printf(m, "TP TX: %u [%u] Mbps (lv: %d), RX: %u [%u] Mbps (lv: %d)\n", ++ stats->tx_throughput, stats->tx_throughput_raw, stats->tx_tfc_lv, ++ stats->rx_throughput, stats->rx_throughput_raw, stats->rx_tfc_lv); ++ seq_printf(m, "Beacon: %u\n", pkt_stat->beacon_nr); ++ seq_printf(m, "Avg packet length: TX=%u, RX=%u\n", stats->tx_avg_len, ++ stats->rx_avg_len); ++ ++ seq_puts(m, "RX count:\n"); ++ for (i = 0; i < ARRAY_SIZE(rtw89_rx_rate_cnt_infos); i++) { ++ info = &rtw89_rx_rate_cnt_infos[i]; ++ seq_printf(m, "%10s [", info->rate_mode); ++ rtw89_debug_append_rx_rate(m, pkt_stat, ++ info->first_rate, info->len); ++ seq_puts(m, "]\n"); ++ } ++ ++ ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_info_get_iter, m); ++ ++ return 0; ++} ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_read_reg = { ++ .cb_read = rtw89_debug_priv_read_reg_get, ++ .cb_write = rtw89_debug_priv_read_reg_select, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_write_reg = { ++ .cb_write = rtw89_debug_priv_write_reg_set, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_read_rf = { ++ .cb_read = rtw89_debug_priv_read_rf_get, ++ .cb_write = rtw89_debug_priv_read_rf_select, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_write_rf = { ++ .cb_write = rtw89_debug_priv_write_rf_set, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_rf_reg_dump = { ++ .cb_read = rtw89_debug_priv_rf_reg_dump_get, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_txpwr_table = { ++ .cb_read = rtw89_debug_priv_txpwr_table_get, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_mac_reg_dump = { ++ .cb_read = rtw89_debug_priv_mac_reg_dump_get, ++ .cb_write = rtw89_debug_priv_mac_reg_dump_select, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_mac_mem_dump = { ++ .cb_read = rtw89_debug_priv_mac_mem_dump_get, ++ .cb_write = rtw89_debug_priv_mac_mem_dump_select, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_mac_dbg_port_dump = { ++ .cb_read = rtw89_debug_priv_mac_dbg_port_dump_get, ++ .cb_write = rtw89_debug_priv_mac_dbg_port_dump_select, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_send_h2c = { ++ .cb_write = rtw89_debug_priv_send_h2c_set, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_early_h2c = { ++ .cb_read = rtw89_debug_priv_early_h2c_get, ++ .cb_write = rtw89_debug_priv_early_h2c_set, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_btc_info = { ++ .cb_read = rtw89_debug_priv_btc_info_get, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_btc_manual = { ++ .cb_write = rtw89_debug_priv_btc_manual_set, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_fw_log_manual = { ++ .cb_write = rtw89_debug_fw_log_btc_manual_set, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_phy_info = { ++ .cb_read = rtw89_debug_priv_phy_info_get, ++}; ++ ++#define rtw89_debugfs_add(name, mode, fopname, parent) \ ++ do { \ ++ rtw89_debug_priv_ ##name.rtwdev = rtwdev; \ ++ if (!debugfs_create_file(#name, mode, \ ++ parent, &rtw89_debug_priv_ ##name, \ ++ &file_ops_ ##fopname)) \ ++ pr_debug("Unable to initialize debugfs:%s\n", #name); \ ++ } while (0) ++ ++#define rtw89_debugfs_add_w(name) \ ++ rtw89_debugfs_add(name, S_IFREG | 0222, single_w, debugfs_topdir) ++#define rtw89_debugfs_add_rw(name) \ ++ rtw89_debugfs_add(name, S_IFREG | 0666, common_rw, debugfs_topdir) ++#define rtw89_debugfs_add_r(name) \ ++ rtw89_debugfs_add(name, S_IFREG | 0444, single_r, debugfs_topdir) ++ ++void rtw89_debugfs_init(struct rtw89_dev *rtwdev) ++{ ++ struct dentry *debugfs_topdir; ++ ++ debugfs_topdir = debugfs_create_dir("rtw89", ++ rtwdev->hw->wiphy->debugfsdir); ++ ++ rtw89_debugfs_add_rw(read_reg); ++ rtw89_debugfs_add_w(write_reg); ++ rtw89_debugfs_add_rw(read_rf); ++ rtw89_debugfs_add_w(write_rf); ++ rtw89_debugfs_add_r(rf_reg_dump); ++ rtw89_debugfs_add_r(txpwr_table); ++ rtw89_debugfs_add_rw(mac_reg_dump); ++ rtw89_debugfs_add_rw(mac_mem_dump); ++ rtw89_debugfs_add_rw(mac_dbg_port_dump); ++ rtw89_debugfs_add_w(send_h2c); ++ rtw89_debugfs_add_rw(early_h2c); ++ rtw89_debugfs_add_r(btc_info); ++ rtw89_debugfs_add_w(btc_manual); ++ rtw89_debugfs_add_w(fw_log_manual); ++ rtw89_debugfs_add_r(phy_info); ++} ++#endif ++ ++#ifdef CONFIG_RTW89_DEBUGMSG ++void __rtw89_debug(struct rtw89_dev *rtwdev, ++ enum rtw89_debug_mask mask, ++ const char *fmt, ...) ++{ ++ struct va_format vaf = { ++ .fmt = fmt, ++ }; ++ ++ va_list args; ++ ++ va_start(args, fmt); ++ vaf.va = &args; ++ ++ if (rtw89_debug_mask & mask) ++ dev_printk(KERN_DEBUG, rtwdev->dev, "%pV", &vaf); ++ ++ va_end(args); ++} ++EXPORT_SYMBOL(__rtw89_debug); ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/debug.h b/drivers/net/wireless/realtek/rtw89/debug.h +new file mode 100644 +index 000000000000..f14b726c1a9f +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/debug.h +@@ -0,0 +1,77 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_DEBUG_H__ ++#define __RTW89_DEBUG_H__ ++ ++#include "core.h" ++ ++enum rtw89_debug_mask { ++ RTW89_DBG_TXRX = BIT(0), ++ RTW89_DBG_RFK = BIT(1), ++ RTW89_DBG_RFK_TRACK = BIT(2), ++ RTW89_DBG_CFO = BIT(3), ++ RTW89_DBG_TSSI = BIT(4), ++ RTW89_DBG_TXPWR = BIT(5), ++ RTW89_DBG_HCI = BIT(6), ++ RTW89_DBG_RA = BIT(7), ++ RTW89_DBG_REGD = BIT(8), ++ RTW89_DBG_PHY_TRACK = BIT(9), ++ RTW89_DBG_DIG = BIT(10), ++ RTW89_DBG_SER = BIT(11), ++ RTW89_DBG_FW = BIT(12), ++ RTW89_DBG_BTC = BIT(13), ++ RTW89_DBG_BF = BIT(14), ++}; ++ ++enum rtw89_debug_mac_reg_sel { ++ RTW89_DBG_SEL_MAC_00, ++ RTW89_DBG_SEL_MAC_40, ++ RTW89_DBG_SEL_MAC_80, ++ RTW89_DBG_SEL_MAC_C0, ++ RTW89_DBG_SEL_MAC_E0, ++ RTW89_DBG_SEL_BB, ++ RTW89_DBG_SEL_IQK, ++ RTW89_DBG_SEL_RFC, ++}; ++ ++#ifdef CONFIG_RTW89_DEBUGFS ++void rtw89_debugfs_init(struct rtw89_dev *rtwdev); ++#else ++static inline void rtw89_debugfs_init(struct rtw89_dev *rtwdev) {} ++#endif ++ ++#define rtw89_info(rtwdev, a...) dev_info((rtwdev)->dev, ##a) ++#define rtw89_warn(rtwdev, a...) dev_warn((rtwdev)->dev, ##a) ++#define rtw89_err(rtwdev, a...) dev_err((rtwdev)->dev, ##a) ++ ++#ifdef CONFIG_RTW89_DEBUGMSG ++extern unsigned int rtw89_debug_mask; ++#define rtw89_debug(rtwdev, a...) __rtw89_debug(rtwdev, ##a) ++ ++__printf(3, 4) ++void __rtw89_debug(struct rtw89_dev *rtwdev, ++ enum rtw89_debug_mask mask, ++ const char *fmt, ...); ++static inline void rtw89_hex_dump(struct rtw89_dev *rtwdev, ++ enum rtw89_debug_mask mask, ++ const char *prefix_str, ++ const void *buf, size_t len) ++{ ++ if (!(rtw89_debug_mask & mask)) ++ return; ++ ++ print_hex_dump_bytes(prefix_str, DUMP_PREFIX_OFFSET, buf, len); ++} ++#else ++static inline void rtw89_debug(struct rtw89_dev *rtwdev, ++ enum rtw89_debug_mask mask, ++ const char *fmt, ...) {} ++static inline void rtw89_hex_dump(struct rtw89_dev *rtwdev, ++ enum rtw89_debug_mask mask, ++ const char *prefix_str, ++ const void *buf, size_t len) {} ++#endif ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/efuse.c b/drivers/net/wireless/realtek/rtw89/efuse.c +new file mode 100644 +index 000000000000..c0b80f3da56c +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/efuse.c +@@ -0,0 +1,188 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "debug.h" ++#include "efuse.h" ++#include "reg.h" ++ ++enum rtw89_efuse_bank { ++ RTW89_EFUSE_BANK_WIFI, ++ RTW89_EFUSE_BANK_BT, ++}; ++ ++static int rtw89_switch_efuse_bank(struct rtw89_dev *rtwdev, ++ enum rtw89_efuse_bank bank) ++{ ++ u8 val; ++ ++ val = rtw89_read32_mask(rtwdev, R_AX_EFUSE_CTRL_1, ++ B_AX_EF_CELL_SEL_MASK); ++ if (bank == val) ++ return 0; ++ ++ rtw89_write32_mask(rtwdev, R_AX_EFUSE_CTRL_1, B_AX_EF_CELL_SEL_MASK, ++ bank); ++ ++ val = rtw89_read32_mask(rtwdev, R_AX_EFUSE_CTRL_1, ++ B_AX_EF_CELL_SEL_MASK); ++ if (bank == val) ++ return 0; ++ ++ return -EBUSY; ++} ++ ++static int rtw89_dump_physical_efuse_map(struct rtw89_dev *rtwdev, u8 *map, ++ u32 dump_addr, u32 dump_size) ++{ ++ u32 efuse_ctl; ++ u32 addr; ++ int ret; ++ ++ rtw89_switch_efuse_bank(rtwdev, RTW89_EFUSE_BANK_WIFI); ++ ++ for (addr = dump_addr; addr < dump_addr + dump_size; addr++) { ++ efuse_ctl = u32_encode_bits(addr, B_AX_EF_ADDR_MASK); ++ rtw89_write32(rtwdev, R_AX_EFUSE_CTRL, efuse_ctl & ~B_AX_EF_RDY); ++ ++ ret = read_poll_timeout_atomic(rtw89_read32, efuse_ctl, ++ efuse_ctl & B_AX_EF_RDY, 1, 1000000, ++ true, rtwdev, R_AX_EFUSE_CTRL); ++ if (ret) ++ return -EBUSY; ++ ++ *map++ = (u8)(efuse_ctl & 0xff); ++ } ++ ++ return 0; ++} ++ ++#define invalid_efuse_header(hdr1, hdr2) \ ++ ((hdr1) == 0xff || (hdr2) == 0xff) ++#define invalid_efuse_content(word_en, i) \ ++ (((word_en) & BIT(i)) != 0x0) ++#define get_efuse_blk_idx(hdr1, hdr2) \ ++ ((((hdr2) & 0xf0) >> 4) | (((hdr1) & 0x0f) << 4)) ++#define block_idx_to_logical_idx(blk_idx, i) \ ++ (((blk_idx) << 3) + ((i) << 1)) ++static int rtw89_dump_logical_efuse_map(struct rtw89_dev *rtwdev, u8 *phy_map, ++ u8 *log_map) ++{ ++ u32 physical_size = rtwdev->chip->physical_efuse_size; ++ u32 logical_size = rtwdev->chip->logical_efuse_size; ++ u8 sec_ctrl_size = rtwdev->chip->sec_ctrl_efuse_size; ++ u32 phy_idx = sec_ctrl_size; ++ u32 log_idx; ++ u8 hdr1, hdr2; ++ u8 blk_idx; ++ u8 word_en; ++ int i; ++ ++ while (phy_idx < physical_size - sec_ctrl_size) { ++ hdr1 = phy_map[phy_idx]; ++ hdr2 = phy_map[phy_idx + 1]; ++ if (invalid_efuse_header(hdr1, hdr2)) ++ break; ++ ++ blk_idx = get_efuse_blk_idx(hdr1, hdr2); ++ word_en = hdr2 & 0xf; ++ phy_idx += 2; ++ ++ for (i = 0; i < 4; i++) { ++ if (invalid_efuse_content(word_en, i)) ++ continue; ++ ++ log_idx = block_idx_to_logical_idx(blk_idx, i); ++ if (phy_idx + 1 > physical_size - sec_ctrl_size - 1 || ++ log_idx + 1 > logical_size) ++ return -EINVAL; ++ ++ log_map[log_idx] = phy_map[phy_idx]; ++ log_map[log_idx + 1] = phy_map[phy_idx + 1]; ++ phy_idx += 2; ++ } ++ } ++ return 0; ++} ++ ++int rtw89_parse_efuse_map(struct rtw89_dev *rtwdev) ++{ ++ u32 phy_size = rtwdev->chip->physical_efuse_size; ++ u32 log_size = rtwdev->chip->logical_efuse_size; ++ u8 *phy_map = NULL; ++ u8 *log_map = NULL; ++ int ret; ++ ++ if (rtw89_read16(rtwdev, R_AX_SYS_WL_EFUSE_CTRL) & B_AX_AUTOLOAD_SUS) ++ rtwdev->efuse.valid = true; ++ else ++ rtw89_warn(rtwdev, "failed to check efuse autoload\n"); ++ ++ phy_map = kmalloc(phy_size, GFP_KERNEL); ++ log_map = kmalloc(log_size, GFP_KERNEL); ++ ++ if (!phy_map || !log_map) { ++ ret = -ENOMEM; ++ goto out_free; ++ } ++ ++ ret = rtw89_dump_physical_efuse_map(rtwdev, phy_map, 0, phy_size); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to dump efuse physical map\n"); ++ goto out_free; ++ } ++ ++ memset(log_map, 0xff, log_size); ++ ret = rtw89_dump_logical_efuse_map(rtwdev, phy_map, log_map); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to dump efuse logical map\n"); ++ goto out_free; ++ } ++ ++ rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "log_map: ", log_map, log_size); ++ ++ ret = rtwdev->chip->ops->read_efuse(rtwdev, log_map); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to read efuse map\n"); ++ goto out_free; ++ } ++ ++out_free: ++ kfree(log_map); ++ kfree(phy_map); ++ ++ return ret; ++} ++ ++int rtw89_parse_phycap_map(struct rtw89_dev *rtwdev) ++{ ++ u32 phycap_addr = rtwdev->chip->phycap_addr; ++ u32 phycap_size = rtwdev->chip->phycap_size; ++ u8 *phycap_map = NULL; ++ int ret = 0; ++ ++ if (!phycap_size) ++ return 0; ++ ++ phycap_map = kmalloc(phycap_size, GFP_KERNEL); ++ if (!phycap_map) ++ return -ENOMEM; ++ ++ ret = rtw89_dump_physical_efuse_map(rtwdev, phycap_map, ++ phycap_addr, phycap_size); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to dump phycap map\n"); ++ goto out_free; ++ } ++ ++ ret = rtwdev->chip->ops->read_phycap(rtwdev, phycap_map); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to read phycap map\n"); ++ goto out_free; ++ } ++ ++out_free: ++ kfree(phycap_map); ++ ++ return ret; ++} +diff --git a/drivers/net/wireless/realtek/rtw89/efuse.h b/drivers/net/wireless/realtek/rtw89/efuse.h +new file mode 100644 +index 000000000000..622ff95e7476 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/efuse.h +@@ -0,0 +1,13 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_EFUSE_H__ ++#define __RTW89_EFUSE_H__ ++ ++#include "core.h" ++ ++int rtw89_parse_efuse_map(struct rtw89_dev *rtwdev); ++int rtw89_parse_phycap_map(struct rtw89_dev *rtwdev); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +new file mode 100644 +index 000000000000..212aaf577d3c +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -0,0 +1,1641 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "cam.h" ++#include "coex.h" ++#include "debug.h" ++#include "fw.h" ++#include "mac.h" ++#include "phy.h" ++#include "reg.h" ++ ++static struct sk_buff *rtw89_fw_h2c_alloc_skb(u32 len, bool header) ++{ ++ struct sk_buff *skb; ++ u32 header_len = 0; ++ ++ if (header) ++ header_len = H2C_HEADER_LEN; ++ ++ skb = dev_alloc_skb(len + header_len + 24); ++ if (!skb) ++ return NULL; ++ skb_reserve(skb, header_len + 24); ++ memset(skb->data, 0, len); ++ ++ return skb; ++} ++ ++struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(u32 len) ++{ ++ return rtw89_fw_h2c_alloc_skb(len, true); ++} ++ ++struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(u32 len) ++{ ++ return rtw89_fw_h2c_alloc_skb(len, false); ++} ++ ++static u8 _fw_get_rdy(struct rtw89_dev *rtwdev) ++{ ++ u8 val = rtw89_read8(rtwdev, R_AX_WCPU_FW_CTRL); ++ ++ return FIELD_GET(B_AX_WCPU_FWDL_STS_MASK, val); ++} ++ ++#define FWDL_WAIT_CNT 400000 ++int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev) ++{ ++ u8 val; ++ int ret; ++ ++ ret = read_poll_timeout_atomic(_fw_get_rdy, val, ++ val == RTW89_FWDL_WCPU_FW_INIT_RDY, ++ 1, FWDL_WAIT_CNT, false, rtwdev); ++ if (ret) { ++ switch (val) { ++ case RTW89_FWDL_CHECKSUM_FAIL: ++ rtw89_err(rtwdev, "fw checksum fail\n"); ++ return -EINVAL; ++ ++ case RTW89_FWDL_SECURITY_FAIL: ++ rtw89_err(rtwdev, "fw security fail\n"); ++ return -EINVAL; ++ ++ case RTW89_FWDL_CV_NOT_MATCH: ++ rtw89_err(rtwdev, "fw cv not match\n"); ++ return -EINVAL; ++ ++ default: ++ return -EBUSY; ++ } ++ } ++ ++ set_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); ++ ++ return 0; ++} ++ ++static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, ++ struct rtw89_fw_bin_info *info) ++{ ++ struct rtw89_fw_hdr_section_info *section_info; ++ const u8 *fw_end = fw + len; ++ const u8 *bin; ++ u32 i; ++ ++ if (!info) ++ return -EINVAL; ++ ++ info->section_num = GET_FW_HDR_SEC_NUM(fw); ++ info->hdr_len = RTW89_FW_HDR_SIZE + ++ info->section_num * RTW89_FW_SECTION_HDR_SIZE; ++ SET_FW_HDR_PART_SIZE(fw, FWDL_SECTION_PER_PKT_LEN); ++ ++ bin = fw + info->hdr_len; ++ ++ /* jump to section header */ ++ fw += RTW89_FW_HDR_SIZE; ++ section_info = info->section_info; ++ for (i = 0; i < info->section_num; i++) { ++ section_info->len = GET_FWSECTION_HDR_SEC_SIZE(fw); ++ if (GET_FWSECTION_HDR_CHECKSUM(fw)) ++ section_info->len += FWDL_SECTION_CHKSUM_LEN; ++ section_info->redl = GET_FWSECTION_HDR_REDL(fw); ++ section_info->dladdr = ++ GET_FWSECTION_HDR_DL_ADDR(fw) & 0x1fffffff; ++ section_info->addr = bin; ++ bin += section_info->len; ++ fw += RTW89_FW_SECTION_HDR_SIZE; ++ section_info++; ++ } ++ ++ if (fw_end != bin) { ++ rtw89_err(rtwdev, "[ERR]fw bin size\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static ++int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, ++ struct rtw89_fw_suit *fw_suit) ++{ ++ struct rtw89_fw_info *fw_info = &rtwdev->fw; ++ const u8 *mfw = fw_info->firmware->data; ++ u32 mfw_len = fw_info->firmware->size; ++ const struct rtw89_mfw_hdr *mfw_hdr = (const struct rtw89_mfw_hdr *)mfw; ++ const struct rtw89_mfw_info *mfw_info; ++ int i; ++ ++ if (mfw_hdr->sig != RTW89_MFW_SIG) { ++ rtw89_debug(rtwdev, RTW89_DBG_FW, "use legacy firmware\n"); ++ /* legacy firmware support normal type only */ ++ if (type != RTW89_FW_NORMAL) ++ return -EINVAL; ++ fw_suit->data = mfw; ++ fw_suit->size = mfw_len; ++ return 0; ++ } ++ ++ for (i = 0; i < mfw_hdr->fw_nr; i++) { ++ mfw_info = &mfw_hdr->info[i]; ++ if (mfw_info->cv != rtwdev->hal.cv || ++ mfw_info->type != type || ++ mfw_info->mp) ++ continue; ++ ++ fw_suit->data = mfw + le32_to_cpu(mfw_info->shift); ++ fw_suit->size = le32_to_cpu(mfw_info->size); ++ return 0; ++ } ++ ++ rtw89_err(rtwdev, "no suitable firmware found\n"); ++ return -ENOENT; ++} ++ ++static void rtw89_fw_update_ver(struct rtw89_dev *rtwdev, ++ enum rtw89_fw_type type, ++ struct rtw89_fw_suit *fw_suit) ++{ ++ const u8 *hdr = fw_suit->data; ++ ++ fw_suit->major_ver = GET_FW_HDR_MAJOR_VERSION(hdr); ++ fw_suit->minor_ver = GET_FW_HDR_MINOR_VERSION(hdr); ++ fw_suit->sub_ver = GET_FW_HDR_SUBVERSION(hdr); ++ fw_suit->sub_idex = GET_FW_HDR_SUBINDEX(hdr); ++ fw_suit->build_year = GET_FW_HDR_YEAR(hdr); ++ fw_suit->build_mon = GET_FW_HDR_MONTH(hdr); ++ fw_suit->build_date = GET_FW_HDR_DATE(hdr); ++ fw_suit->build_hour = GET_FW_HDR_HOUR(hdr); ++ fw_suit->build_min = GET_FW_HDR_MIN(hdr); ++ fw_suit->cmd_ver = GET_FW_HDR_CMD_VERSERION(hdr); ++ ++ rtw89_info(rtwdev, ++ "Firmware version %u.%u.%u.%u, cmd version %u, type %u\n", ++ fw_suit->major_ver, fw_suit->minor_ver, fw_suit->sub_ver, ++ fw_suit->sub_idex, fw_suit->cmd_ver, type); ++} ++ ++static ++int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type) ++{ ++ struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); ++ int ret; ++ ++ ret = rtw89_mfw_recognize(rtwdev, type, fw_suit); ++ if (ret) ++ return ret; ++ ++ rtw89_fw_update_ver(rtwdev, type, fw_suit); ++ ++ return 0; ++} ++ ++static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); ++ ++ if (chip->chip_id == RTL8852A && ++ RTW89_FW_SUIT_VER_CODE(fw_suit) <= RTW89_FW_VER_CODE(0, 13, 29, 0)) ++ rtwdev->fw.old_ht_ra_format = true; ++} ++ ++int rtw89_fw_recognize(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL); ++ if (ret) ++ return ret; ++ ++ /* It still works if wowlan firmware isn't existing. */ ++ __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN); ++ ++ rtw89_fw_recognize_features(rtwdev); ++ ++ return 0; ++} ++ ++void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb, ++ u8 type, u8 cat, u8 class, u8 func, ++ bool rack, bool dack, u32 len) ++{ ++ struct fwcmd_hdr *hdr; ++ ++ hdr = (struct fwcmd_hdr *)skb_push(skb, 8); ++ ++ if (!(rtwdev->fw.h2c_seq % 4)) ++ rack = true; ++ hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) | ++ FIELD_PREP(H2C_HDR_CAT, cat) | ++ FIELD_PREP(H2C_HDR_CLASS, class) | ++ FIELD_PREP(H2C_HDR_FUNC, func) | ++ FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq)); ++ ++ hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN, ++ len + H2C_HEADER_LEN) | ++ (rack ? H2C_HDR_REC_ACK : 0) | ++ (dack ? H2C_HDR_DONE_ACK : 0)); ++ ++ rtwdev->fw.h2c_seq++; ++} ++ ++static void rtw89_h2c_pkt_set_hdr_fwdl(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb, ++ u8 type, u8 cat, u8 class, u8 func, ++ u32 len) ++{ ++ struct fwcmd_hdr *hdr; ++ ++ hdr = (struct fwcmd_hdr *)skb_push(skb, 8); ++ ++ hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) | ++ FIELD_PREP(H2C_HDR_CAT, cat) | ++ FIELD_PREP(H2C_HDR_CLASS, class) | ++ FIELD_PREP(H2C_HDR_FUNC, func) | ++ FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq)); ++ ++ hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN, ++ len + H2C_HEADER_LEN)); ++} ++ ++static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 len) ++{ ++ struct sk_buff *skb; ++ u32 ret = 0; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(len); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw hdr dl\n"); ++ return -ENOMEM; ++ } ++ ++ skb_put_data(skb, fw, len); ++ rtw89_h2c_pkt_set_hdr_fwdl(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_FWDL, ++ H2C_FUNC_MAC_FWHDR_DL, len); ++ ++ ret = rtw89_h2c_tx(rtwdev, skb, false); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ ret = -1; ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return ret; ++} ++ ++static int rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 len) ++{ ++ u8 val; ++ int ret; ++ ++ ret = __rtw89_fw_download_hdr(rtwdev, fw, len); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]FW header download\n"); ++ return ret; ++ } ++ ++ ret = read_poll_timeout_atomic(rtw89_read8, val, val & B_AX_FWDL_PATH_RDY, ++ 1, FWDL_WAIT_CNT, false, ++ rtwdev, R_AX_WCPU_FW_CTRL); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]FWDL path ready\n"); ++ return ret; ++ } ++ ++ rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0); ++ rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); ++ ++ return 0; ++} ++ ++static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev, ++ struct rtw89_fw_hdr_section_info *info) ++{ ++ struct sk_buff *skb; ++ const u8 *section = info->addr; ++ u32 residue_len = info->len; ++ u32 pkt_len; ++ int ret; ++ ++ while (residue_len) { ++ if (residue_len >= FWDL_SECTION_PER_PKT_LEN) ++ pkt_len = FWDL_SECTION_PER_PKT_LEN; ++ else ++ pkt_len = residue_len; ++ ++ skb = rtw89_fw_h2c_alloc_skb_no_hdr(pkt_len); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); ++ return -ENOMEM; ++ } ++ skb_put_data(skb, section, pkt_len); ++ ++ ret = rtw89_h2c_tx(rtwdev, skb, true); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ ret = -1; ++ goto fail; ++ } ++ ++ section += pkt_len; ++ residue_len -= pkt_len; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return ret; ++} ++ ++static int rtw89_fw_download_main(struct rtw89_dev *rtwdev, const u8 *fw, ++ struct rtw89_fw_bin_info *info) ++{ ++ struct rtw89_fw_hdr_section_info *section_info = info->section_info; ++ u8 section_num = info->section_num; ++ int ret; ++ ++ while (section_num--) { ++ ret = __rtw89_fw_download_main(rtwdev, section_info); ++ if (ret) ++ return ret; ++ section_info++; ++ } ++ ++ mdelay(5); ++ ++ ret = rtw89_fw_check_rdy(rtwdev); ++ if (ret) { ++ rtw89_warn(rtwdev, "download firmware fail\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void rtw89_fw_prog_cnt_dump(struct rtw89_dev *rtwdev) ++{ ++ u32 val32; ++ u16 index; ++ ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, ++ FIELD_PREP(B_AX_DBG_SEL0, FW_PROG_CNTR_DBG_SEL) | ++ FIELD_PREP(B_AX_DBG_SEL1, FW_PROG_CNTR_DBG_SEL)); ++ rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_SEL_0XC0_MASK, MAC_DBG_SEL); ++ ++ for (index = 0; index < 15; index++) { ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_PORT_SEL); ++ rtw89_err(rtwdev, "[ERR]fw PC = 0x%x\n", val32); ++ fsleep(10); ++ } ++} ++ ++static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev) ++{ ++ u32 val32; ++ u16 val16; ++ ++ val32 = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL); ++ rtw89_err(rtwdev, "[ERR]fwdl 0x1E0 = 0x%x\n", val32); ++ ++ val16 = rtw89_read16(rtwdev, R_AX_BOOT_DBG + 2); ++ rtw89_err(rtwdev, "[ERR]fwdl 0x83F2 = 0x%x\n", val16); ++ ++ rtw89_fw_prog_cnt_dump(rtwdev); ++} ++ ++int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type) ++{ ++ struct rtw89_fw_info *fw_info = &rtwdev->fw; ++ struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); ++ struct rtw89_fw_bin_info info; ++ const u8 *fw = fw_suit->data; ++ u32 len = fw_suit->size; ++ u8 val; ++ int ret; ++ ++ if (!fw || !len) { ++ rtw89_err(rtwdev, "fw type %d isn't recognized\n", type); ++ return -ENOENT; ++ } ++ ++ ret = rtw89_fw_hdr_parser(rtwdev, fw, len, &info); ++ if (ret) { ++ rtw89_err(rtwdev, "parse fw header fail\n"); ++ goto fwdl_err; ++ } ++ ++ ret = read_poll_timeout_atomic(rtw89_read8, val, val & B_AX_H2C_PATH_RDY, ++ 1, FWDL_WAIT_CNT, false, ++ rtwdev, R_AX_WCPU_FW_CTRL); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]H2C path ready\n"); ++ goto fwdl_err; ++ } ++ ++ ret = rtw89_fw_download_hdr(rtwdev, fw, info.hdr_len); ++ if (ret) { ++ ret = -EBUSY; ++ goto fwdl_err; ++ } ++ ++ ret = rtw89_fw_download_main(rtwdev, fw, &info); ++ if (ret) { ++ ret = -EBUSY; ++ goto fwdl_err; ++ } ++ ++ fw_info->h2c_seq = 0; ++ fw_info->rec_seq = 0; ++ rtwdev->mac.rpwm_seq_num = RPWM_SEQ_NUM_MAX; ++ rtwdev->mac.cpwm_seq_num = CPWM_SEQ_NUM_MAX; ++ ++ return ret; ++ ++fwdl_err: ++ rtw89_fw_dl_fail_dump(rtwdev); ++ return ret; ++} ++ ++int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_fw_info *fw = &rtwdev->fw; ++ ++ wait_for_completion(&fw->completion); ++ if (!fw->firmware) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static void rtw89_load_firmware_cb(const struct firmware *firmware, void *context) ++{ ++ struct rtw89_fw_info *fw = context; ++ struct rtw89_dev *rtwdev = fw->rtwdev; ++ ++ if (!firmware || !firmware->data) { ++ rtw89_err(rtwdev, "failed to request firmware\n"); ++ complete_all(&fw->completion); ++ return; ++ } ++ ++ fw->firmware = firmware; ++ complete_all(&fw->completion); ++} ++ ++int rtw89_load_firmware(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_fw_info *fw = &rtwdev->fw; ++ const char *fw_name = rtwdev->chip->fw_name; ++ int ret; ++ ++ fw->rtwdev = rtwdev; ++ init_completion(&fw->completion); ++ ++ ret = request_firmware_nowait(THIS_MODULE, true, fw_name, rtwdev->dev, ++ GFP_KERNEL, fw, rtw89_load_firmware_cb); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to async firmware request\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++void rtw89_unload_firmware(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_fw_info *fw = &rtwdev->fw; ++ ++ rtw89_wait_firmware_completion(rtwdev); ++ ++ if (fw->firmware) ++ release_firmware(fw->firmware); ++} ++ ++#define H2C_CAM_LEN 60 ++int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_CAM_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_CAM_LEN); ++ rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif, skb->data); ++ rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif, skb->data); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, ++ H2C_CL_MAC_ADDR_CAM_UPDATE, ++ H2C_FUNC_MAC_ADDR_CAM_UPD, 0, 1, ++ H2C_CAM_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_BA_CAM_LEN 4 ++int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, bool valid, u8 macid, ++ struct ieee80211_ampdu_params *params) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_BA_CAM_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_BA_CAM_LEN); ++ SET_BA_CAM_MACID(skb->data, macid); ++ if (!valid) ++ goto end; ++ SET_BA_CAM_VALID(skb->data, valid); ++ SET_BA_CAM_TID(skb->data, params->tid); ++ if (params->buf_size > 64) ++ SET_BA_CAM_BMAP_SIZE(skb->data, 4); ++ else ++ SET_BA_CAM_BMAP_SIZE(skb->data, 0); ++ /* If init req is set, hw will set the ssn */ ++ SET_BA_CAM_INIT_REQ(skb->data, 0); ++ SET_BA_CAM_SSN(skb->data, params->ssn); ++ ++end: ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, ++ H2C_CL_BA_CAM, ++ H2C_FUNC_MAC_BA_CAM, 0, 1, ++ H2C_BA_CAM_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_LOG_CFG_LEN 12 ++int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable) ++{ ++ struct sk_buff *skb; ++ u32 comp = enable ? BIT(RTW89_FW_LOG_COMP_INIT) | BIT(RTW89_FW_LOG_COMP_TASK) | ++ BIT(RTW89_FW_LOG_COMP_PS) | BIT(RTW89_FW_LOG_COMP_ERROR) : 0; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LOG_CFG_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw log cfg\n"); ++ return -ENOMEM; ++ } ++ ++ skb_put(skb, H2C_LOG_CFG_LEN); ++ SET_LOG_CFG_LEVEL(skb->data, RTW89_FW_LOG_LEVEL_SER); ++ SET_LOG_CFG_PATH(skb->data, BIT(RTW89_FW_LOG_LEVEL_C2H)); ++ SET_LOG_CFG_COMP(skb->data, comp); ++ SET_LOG_CFG_COMP_EXT(skb->data, 0); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, ++ H2C_CL_FW_INFO, ++ H2C_FUNC_LOG_CFG, 0, 0, ++ H2C_LOG_CFG_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_GENERAL_PKT_LEN 6 ++#define H2C_GENERAL_PKT_ID_UND 0xff ++int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_GENERAL_PKT_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_GENERAL_PKT_LEN); ++ SET_GENERAL_PKT_MACID(skb->data, macid); ++ SET_GENERAL_PKT_PROBRSP_ID(skb->data, H2C_GENERAL_PKT_ID_UND); ++ SET_GENERAL_PKT_PSPOLL_ID(skb->data, H2C_GENERAL_PKT_ID_UND); ++ SET_GENERAL_PKT_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND); ++ SET_GENERAL_PKT_QOS_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND); ++ SET_GENERAL_PKT_CTS2SELF_ID(skb->data, H2C_GENERAL_PKT_ID_UND); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, ++ H2C_CL_FW_INFO, ++ H2C_FUNC_MAC_GENERAL_PKT, 0, 1, ++ H2C_GENERAL_PKT_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_LPS_PARM_LEN 8 ++int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, ++ struct rtw89_lps_parm *lps_param) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LPS_PARM_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_LPS_PARM_LEN); ++ ++ SET_LPS_PARM_MACID(skb->data, lps_param->macid); ++ SET_LPS_PARM_PSMODE(skb->data, lps_param->psmode); ++ SET_LPS_PARM_LASTRPWM(skb->data, lps_param->lastrpwm); ++ SET_LPS_PARM_RLBM(skb->data, 1); ++ SET_LPS_PARM_SMARTPS(skb->data, 1); ++ SET_LPS_PARM_AWAKEINTERVAL(skb->data, 1); ++ SET_LPS_PARM_VOUAPSD(skb->data, 0); ++ SET_LPS_PARM_VIUAPSD(skb->data, 0); ++ SET_LPS_PARM_BEUAPSD(skb->data, 0); ++ SET_LPS_PARM_BKUAPSD(skb->data, 0); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, ++ H2C_CL_MAC_PS, ++ H2C_FUNC_MAC_LPS_PARM, 0, 1, ++ H2C_LPS_PARM_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_CMC_TBL_LEN 68 ++int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, u8 macid) ++{ ++ struct rtw89_hal *hal = &rtwdev->hal; ++ struct sk_buff *skb; ++ u8 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_B; ++ u8 map_b = hal->antenna_tx == RF_AB ? 1 : 0; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_CMC_TBL_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_CMC_TBL_LEN); ++ SET_CTRL_INFO_MACID(skb->data, macid); ++ SET_CTRL_INFO_OPERATION(skb->data, 1); ++ SET_CMC_TBL_TXPWR_MODE(skb->data, 0); ++ SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path); ++ SET_CMC_TBL_PATH_MAP_A(skb->data, 0); ++ SET_CMC_TBL_PATH_MAP_B(skb->data, map_b); ++ SET_CMC_TBL_PATH_MAP_C(skb->data, 0); ++ SET_CMC_TBL_PATH_MAP_D(skb->data, 0); ++ SET_CMC_TBL_ANTSEL_A(skb->data, 0); ++ SET_CMC_TBL_ANTSEL_B(skb->data, 0); ++ SET_CMC_TBL_ANTSEL_C(skb->data, 0); ++ SET_CMC_TBL_ANTSEL_D(skb->data, 0); ++ SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0); ++ SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, ++ H2C_FUNC_MAC_CCTLINFO_UD, 0, 1, ++ H2C_CMC_TBL_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev, ++ struct ieee80211_sta *sta, u8 *pads) ++{ ++ bool ppe_th; ++ u8 ppe16, ppe8; ++ u8 nss = min(sta->rx_nss, rtwdev->hal.tx_nss) - 1; ++ u8 ppe_thres_hdr = sta->he_cap.ppe_thres[0]; ++ u8 ru_bitmap; ++ u8 n, idx, sh; ++ u16 ppe; ++ int i; ++ ++ if (!sta->he_cap.has_he) ++ return; ++ ++ ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT, ++ sta->he_cap.he_cap_elem.phy_cap_info[6]); ++ if (!ppe_th) { ++ u8 pad; ++ ++ pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_MASK, ++ sta->he_cap.he_cap_elem.phy_cap_info[9]); ++ ++ for (i = 0; i < RTW89_PPE_BW_NUM; i++) ++ pads[i] = pad; ++ } ++ ++ ru_bitmap = FIELD_GET(IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK, ppe_thres_hdr); ++ n = hweight8(ru_bitmap); ++ n = 7 + (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) * nss; ++ ++ for (i = 0; i < RTW89_PPE_BW_NUM; i++) { ++ if (!(ru_bitmap & BIT(i))) { ++ pads[i] = 1; ++ continue; ++ } ++ ++ idx = n >> 3; ++ sh = n & 7; ++ n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2; ++ ++ ppe = le16_to_cpu(*((__le16 *)&sta->he_cap.ppe_thres[idx])); ++ ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; ++ sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE; ++ ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; ++ ++ if (ppe16 != 7 && ppe8 == 7) ++ pads[i] = 2; ++ else if (ppe8 != 7) ++ pads[i] = 1; ++ else ++ pads[i] = 0; ++ } ++} ++ ++int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_hal *hal = &rtwdev->hal; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ struct sk_buff *skb; ++ u8 pads[RTW89_PPE_BW_NUM]; ++ ++ memset(pads, 0, sizeof(pads)); ++ __get_sta_he_pkt_padding(rtwdev, sta, pads); ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_CMC_TBL_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_CMC_TBL_LEN); ++ SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id); ++ SET_CTRL_INFO_OPERATION(skb->data, 1); ++ SET_CMC_TBL_DISRTSFB(skb->data, 1); ++ SET_CMC_TBL_DISDATAFB(skb->data, 1); ++ if (hal->current_band_type == RTW89_BAND_2G) ++ SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, RTW89_HW_RATE_CCK1); ++ else ++ SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, RTW89_HW_RATE_OFDM6); ++ SET_CMC_TBL_RTS_TXCNT_LMT_SEL(skb->data, 0); ++ SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 0); ++ if (vif->type == NL80211_IFTYPE_STATION) ++ SET_CMC_TBL_ULDL(skb->data, 1); ++ else ++ SET_CMC_TBL_ULDL(skb->data, 0); ++ SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif->port); ++ SET_CMC_TBL_NOMINAL_PKT_PADDING(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); ++ SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); ++ SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); ++ SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data, sta->he_cap.has_he); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, ++ H2C_FUNC_MAC_CCTLINFO_UD, 0, 1, ++ H2C_CMC_TBL_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, ++ struct rtw89_sta *rtwsta) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_CMC_TBL_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_CMC_TBL_LEN); ++ SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id); ++ SET_CTRL_INFO_OPERATION(skb->data, 1); ++ if (rtwsta->cctl_tx_time) { ++ SET_CMC_TBL_AMPDU_TIME_SEL(skb->data, 1); ++ SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta->ampdu_max_time); ++ } ++ if (rtwsta->cctl_tx_retry_limit) { ++ SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 1); ++ SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta->data_tx_cnt_lmt); ++ } ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, ++ H2C_FUNC_MAC_CCTLINFO_UD, 0, 1, ++ H2C_CMC_TBL_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_VIF_MAINTAIN_LEN 4 ++int rtw89_fw_h2c_vif_maintain(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, ++ enum rtw89_upd_mode upd_mode) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_VIF_MAINTAIN_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_VIF_MAINTAIN_LEN); ++ SET_FWROLE_MAINTAIN_MACID(skb->data, rtwvif->mac_id); ++ SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, rtwvif->self_role); ++ SET_FWROLE_MAINTAIN_UPD_MODE(skb->data, upd_mode); ++ SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif->wifi_role); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, ++ H2C_FUNC_MAC_FWROLE_MAINTAIN, 0, 1, ++ H2C_VIF_MAINTAIN_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_JOIN_INFO_LEN 4 ++int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u8 dis_conn) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_JOIN_INFO_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_JOIN_INFO_LEN); ++ SET_JOININFO_MACID(skb->data, rtwvif->mac_id); ++ SET_JOININFO_OP(skb->data, dis_conn); ++ SET_JOININFO_BAND(skb->data, rtwvif->mac_idx); ++ SET_JOININFO_WMM(skb->data, rtwvif->wmm); ++ SET_JOININFO_TGR(skb->data, rtwvif->trigger); ++ SET_JOININFO_ISHESTA(skb->data, 0); ++ SET_JOININFO_DLBW(skb->data, 0); ++ SET_JOININFO_TF_MAC_PAD(skb->data, 0); ++ SET_JOININFO_DL_T_PE(skb->data, 0); ++ SET_JOININFO_PORT_ID(skb->data, rtwvif->port); ++ SET_JOININFO_NET_TYPE(skb->data, rtwvif->net_type); ++ SET_JOININFO_WIFI_ROLE(skb->data, rtwvif->wifi_role); ++ SET_JOININFO_SELF_ROLE(skb->data, rtwvif->self_role); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, ++ H2C_FUNC_MAC_JOININFO, 0, 1, ++ H2C_JOIN_INFO_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp, ++ bool pause) ++{ ++ struct rtw89_fw_macid_pause_grp h2c = {{0}}; ++ u8 len = sizeof(struct rtw89_fw_macid_pause_grp); ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_JOIN_INFO_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); ++ return -ENOMEM; ++ } ++ h2c.mask_grp[grp] = cpu_to_le32(BIT(sh)); ++ if (pause) ++ h2c.pause_grp[grp] = cpu_to_le32(BIT(sh)); ++ skb_put_data(skb, &h2c, len); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, ++ H2C_FUNC_MAC_MACID_PAUSE, 1, 0, ++ len); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_EDCA_LEN 12 ++int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u8 ac, u32 val) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_EDCA_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c edca\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_EDCA_LEN); ++ RTW89_SET_EDCA_SEL(skb->data, 0); ++ RTW89_SET_EDCA_BAND(skb->data, rtwvif->mac_idx); ++ RTW89_SET_EDCA_WMM(skb->data, 0); ++ RTW89_SET_EDCA_AC(skb->data, ac); ++ RTW89_SET_EDCA_PARAM(skb->data, val); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, ++ H2C_FUNC_USR_EDCA, 0, 1, ++ H2C_EDCA_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_OFLD_CFG_LEN 8 ++int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev) ++{ ++ static const u8 cfg[] = {0x09, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00}; ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_OFLD_CFG_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c ofld\n"); ++ return -ENOMEM; ++ } ++ skb_put_data(skb, cfg, H2C_OFLD_CFG_LEN); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, ++ H2C_FUNC_OFLD_CFG, 0, 1, ++ H2C_OFLD_CFG_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_RA_LEN 16 ++int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi) ++{ ++ struct sk_buff *skb; ++ u8 *cmd; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_RA_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_RA_LEN); ++ cmd = skb->data; ++ rtw89_debug(rtwdev, RTW89_DBG_RA, ++ "ra cmd msk: %llx ", ra->ra_mask); ++ ++ RTW89_SET_FWCMD_RA_MODE(cmd, ra->mode_ctrl); ++ RTW89_SET_FWCMD_RA_BW_CAP(cmd, ra->bw_cap); ++ RTW89_SET_FWCMD_RA_MACID(cmd, ra->macid); ++ RTW89_SET_FWCMD_RA_DCM(cmd, ra->dcm_cap); ++ RTW89_SET_FWCMD_RA_ER(cmd, ra->er_cap); ++ RTW89_SET_FWCMD_RA_INIT_RATE_LV(cmd, ra->init_rate_lv); ++ RTW89_SET_FWCMD_RA_UPD_ALL(cmd, ra->upd_all); ++ RTW89_SET_FWCMD_RA_SGI(cmd, ra->en_sgi); ++ RTW89_SET_FWCMD_RA_LDPC(cmd, ra->ldpc_cap); ++ RTW89_SET_FWCMD_RA_STBC(cmd, ra->stbc_cap); ++ RTW89_SET_FWCMD_RA_SS_NUM(cmd, ra->ss_num); ++ RTW89_SET_FWCMD_RA_GILTF(cmd, ra->giltf); ++ RTW89_SET_FWCMD_RA_UPD_BW_NSS_MASK(cmd, ra->upd_bw_nss_mask); ++ RTW89_SET_FWCMD_RA_UPD_MASK(cmd, ra->upd_mask); ++ RTW89_SET_FWCMD_RA_MASK_0(cmd, FIELD_GET(MASKBYTE0, ra->ra_mask)); ++ RTW89_SET_FWCMD_RA_MASK_1(cmd, FIELD_GET(MASKBYTE1, ra->ra_mask)); ++ RTW89_SET_FWCMD_RA_MASK_2(cmd, FIELD_GET(MASKBYTE2, ra->ra_mask)); ++ RTW89_SET_FWCMD_RA_MASK_3(cmd, FIELD_GET(MASKBYTE3, ra->ra_mask)); ++ RTW89_SET_FWCMD_RA_MASK_4(cmd, FIELD_GET(MASKBYTE4, ra->ra_mask)); ++ ++ if (csi) { ++ RTW89_SET_FWCMD_RA_BFEE_CSI_CTL(cmd, 1); ++ RTW89_SET_FWCMD_RA_BAND_NUM(cmd, ra->band_num); ++ RTW89_SET_FWCMD_RA_CR_TBL_SEL(cmd, ra->cr_tbl_sel); ++ RTW89_SET_FWCMD_RA_FIXED_CSI_RATE_EN(cmd, ra->fixed_csi_rate_en); ++ RTW89_SET_FWCMD_RA_RA_CSI_RATE_EN(cmd, ra->ra_csi_rate_en); ++ RTW89_SET_FWCMD_RA_FIXED_CSI_MCS_SS_IDX(cmd, ra->csi_mcs_ss_idx); ++ RTW89_SET_FWCMD_RA_FIXED_CSI_MODE(cmd, ra->csi_mode); ++ RTW89_SET_FWCMD_RA_FIXED_CSI_GI_LTF(cmd, ra->csi_gi_ltf); ++ RTW89_SET_FWCMD_RA_FIXED_CSI_BW(cmd, ra->csi_bw); ++ } ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA, ++ H2C_FUNC_OUTSRC_RA_MACIDCFG, 0, 0, ++ H2C_RA_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_LEN_CXDRVHDR 2 ++#define H2C_LEN_CXDRVINFO_INIT (12 + H2C_LEN_CXDRVHDR) ++int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_init_info *init_info = &dm->init_info; ++ struct rtw89_btc_module *module = &init_info->module; ++ struct rtw89_btc_ant_info *ant = &module->ant; ++ struct sk_buff *skb; ++ u8 *cmd; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LEN_CXDRVINFO_INIT); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_LEN_CXDRVINFO_INIT); ++ cmd = skb->data; ++ ++ RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_INIT); ++ RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_INIT - H2C_LEN_CXDRVHDR); ++ ++ RTW89_SET_FWCMD_CXINIT_ANT_TYPE(cmd, ant->type); ++ RTW89_SET_FWCMD_CXINIT_ANT_NUM(cmd, ant->num); ++ RTW89_SET_FWCMD_CXINIT_ANT_ISO(cmd, ant->isolation); ++ RTW89_SET_FWCMD_CXINIT_ANT_POS(cmd, ant->single_pos); ++ RTW89_SET_FWCMD_CXINIT_ANT_DIVERSITY(cmd, ant->diversity); ++ ++ RTW89_SET_FWCMD_CXINIT_MOD_RFE(cmd, module->rfe_type); ++ RTW89_SET_FWCMD_CXINIT_MOD_CV(cmd, module->cv); ++ RTW89_SET_FWCMD_CXINIT_MOD_BT_SOLO(cmd, module->bt_solo); ++ RTW89_SET_FWCMD_CXINIT_MOD_BT_POS(cmd, module->bt_pos); ++ RTW89_SET_FWCMD_CXINIT_MOD_SW_TYPE(cmd, module->switch_type); ++ ++ RTW89_SET_FWCMD_CXINIT_WL_GCH(cmd, init_info->wl_guard_ch); ++ RTW89_SET_FWCMD_CXINIT_WL_ONLY(cmd, init_info->wl_only); ++ RTW89_SET_FWCMD_CXINIT_WL_INITOK(cmd, init_info->wl_init_ok); ++ RTW89_SET_FWCMD_CXINIT_DBCC_EN(cmd, init_info->dbcc_en); ++ RTW89_SET_FWCMD_CXINIT_CX_OTHER(cmd, init_info->cx_other); ++ RTW89_SET_FWCMD_CXINIT_BT_ONLY(cmd, init_info->bt_only); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_OUTSRC, BTFC_SET, ++ SET_DRV_INFO, 0, 0, ++ H2C_LEN_CXDRVINFO_INIT); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_LEN_CXDRVINFO_ROLE (4 + 12 * RTW89_MAX_HW_PORT_NUM + H2C_LEN_CXDRVHDR) ++int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_wl_role_info *role_info = &wl->role_info; ++ struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; ++ struct rtw89_btc_wl_active_role *active = role_info->active_role; ++ struct sk_buff *skb; ++ u8 *cmd; ++ int i; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LEN_CXDRVINFO_ROLE); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_LEN_CXDRVINFO_ROLE); ++ cmd = skb->data; ++ ++ RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE); ++ RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE - H2C_LEN_CXDRVHDR); ++ ++ RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); ++ RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); ++ ++ RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none); ++ RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station); ++ RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap); ++ RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap); ++ RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc); ++ RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master); ++ RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh); ++ RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter); ++ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device); ++ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc); ++ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go); ++ RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan); ++ ++ for (i = 0; i < RTW89_MAX_HW_PORT_NUM; i++, active++) { ++ RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i); ++ } ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_OUTSRC, BTFC_SET, ++ SET_DRV_INFO, 0, 0, ++ H2C_LEN_CXDRVINFO_ROLE); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR) ++int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_ctrl *ctrl = &btc->ctrl; ++ struct sk_buff *skb; ++ u8 *cmd; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LEN_CXDRVINFO_CTRL); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_LEN_CXDRVINFO_CTRL); ++ cmd = skb->data; ++ ++ RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_CTRL); ++ RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_CTRL - H2C_LEN_CXDRVHDR); ++ ++ RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, ctrl->manual); ++ RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, ctrl->igno_bt); ++ RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, ctrl->always_freerun); ++ RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, ctrl->trace_step); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_OUTSRC, BTFC_SET, ++ SET_DRV_INFO, 0, 0, ++ H2C_LEN_CXDRVINFO_CTRL); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_LEN_CXDRVINFO_RFK (4 + H2C_LEN_CXDRVHDR) ++int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_wl_rfk_info *rfk_info = &wl->rfk_info; ++ struct sk_buff *skb; ++ u8 *cmd; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LEN_CXDRVINFO_RFK); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_LEN_CXDRVINFO_RFK); ++ cmd = skb->data; ++ ++ RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_RFK); ++ RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_RFK - H2C_LEN_CXDRVHDR); ++ ++ RTW89_SET_FWCMD_CXRFK_STATE(cmd, rfk_info->state); ++ RTW89_SET_FWCMD_CXRFK_PATH_MAP(cmd, rfk_info->path_map); ++ RTW89_SET_FWCMD_CXRFK_PHY_MAP(cmd, rfk_info->phy_map); ++ RTW89_SET_FWCMD_CXRFK_BAND(cmd, rfk_info->band); ++ RTW89_SET_FWCMD_CXRFK_TYPE(cmd, rfk_info->type); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_OUTSRC, BTFC_SET, ++ SET_DRV_INFO, 0, 0, ++ H2C_LEN_CXDRVINFO_RFK); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, ++ struct rtw89_fw_h2c_rf_reg_info *info, ++ u16 len, u8 page) ++{ ++ struct sk_buff *skb; ++ u8 class = info->rf_path == RF_PATH_A ? ++ H2C_CL_OUTSRC_RF_REG_A : H2C_CL_OUTSRC_RF_REG_B; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(len); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c rf reg\n"); ++ return -ENOMEM; ++ } ++ skb_put_data(skb, info->rtw89_phy_config_rf_h2c[page], len); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_OUTSRC, class, page, 0, 0, ++ len); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, ++ u8 h2c_class, u8 h2c_func, u8 *buf, u16 len, ++ bool rack, bool dack) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(len); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for raw with hdr\n"); ++ return -ENOMEM; ++ } ++ skb_put_data(skb, buf, len); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_OUTSRC, h2c_class, h2c_func, rack, dack, ++ len); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_no_hdr(len); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c raw\n"); ++ return -ENOMEM; ++ } ++ skb_put_data(skb, buf, len); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_early_h2c *early_h2c; ++ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) { ++ rtw89_fw_h2c_raw(rtwdev, early_h2c->h2c, early_h2c->h2c_len); ++ } ++} ++ ++void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_early_h2c *early_h2c, *tmp; ++ ++ mutex_lock(&rtwdev->mutex); ++ list_for_each_entry_safe(early_h2c, tmp, &rtwdev->early_h2c_list, list) { ++ list_del(&early_h2c->list); ++ kfree(early_h2c->h2c); ++ kfree(early_h2c); ++ } ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h) ++{ ++ skb_queue_tail(&rtwdev->c2h_queue, c2h); ++ ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work); ++} ++ ++static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb) ++{ ++ u8 category = RTW89_GET_C2H_CATEGORY(skb->data); ++ u8 class = RTW89_GET_C2H_CLASS(skb->data); ++ u8 func = RTW89_GET_C2H_FUNC(skb->data); ++ u16 len = RTW89_GET_C2H_LEN(skb->data); ++ bool dump = true; ++ ++ if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) ++ return; ++ ++ switch (category) { ++ case RTW89_C2H_CAT_TEST: ++ break; ++ case RTW89_C2H_CAT_MAC: ++ rtw89_mac_c2h_handle(rtwdev, skb, len, class, func); ++ if (class == RTW89_MAC_C2H_CLASS_INFO && ++ func == RTW89_MAC_C2H_FUNC_C2H_LOG) ++ dump = false; ++ break; ++ case RTW89_C2H_CAT_OUTSRC: ++ if (class >= RTW89_PHY_C2H_CLASS_BTC_MIN && ++ class <= RTW89_PHY_C2H_CLASS_BTC_MAX) ++ rtw89_btc_c2h_handle(rtwdev, skb, len, class, func); ++ else ++ rtw89_phy_c2h_handle(rtwdev, skb, len, class, func); ++ break; ++ } ++ ++ if (dump) ++ rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "C2H: ", skb->data, skb->len); ++} ++ ++void rtw89_fw_c2h_work(struct work_struct *work) ++{ ++ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, ++ c2h_work); ++ struct sk_buff *skb, *tmp; ++ ++ skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) { ++ skb_unlink(skb, &rtwdev->c2h_queue); ++ mutex_lock(&rtwdev->mutex); ++ rtw89_fw_c2h_cmd_handle(rtwdev, skb); ++ mutex_unlock(&rtwdev->mutex); ++ dev_kfree_skb_any(skb); ++ } ++} ++ ++static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev, ++ struct rtw89_mac_h2c_info *info) ++{ ++ static const u32 h2c_reg[RTW89_H2CREG_MAX] = { ++ R_AX_H2CREG_DATA0, R_AX_H2CREG_DATA1, ++ R_AX_H2CREG_DATA2, R_AX_H2CREG_DATA3 ++ }; ++ u8 i, val, len; ++ int ret; ++ ++ ret = read_poll_timeout(rtw89_read8, val, val == 0, 1000, 5000, false, ++ rtwdev, R_AX_H2CREG_CTRL); ++ if (ret) { ++ rtw89_warn(rtwdev, "FW does not process h2c registers\n"); ++ return ret; ++ } ++ ++ len = DIV_ROUND_UP(info->content_len + RTW89_H2CREG_HDR_LEN, ++ sizeof(info->h2creg[0])); ++ ++ RTW89_SET_H2CREG_HDR_FUNC(&info->h2creg[0], info->id); ++ RTW89_SET_H2CREG_HDR_LEN(&info->h2creg[0], len); ++ for (i = 0; i < RTW89_H2CREG_MAX; i++) ++ rtw89_write32(rtwdev, h2c_reg[i], info->h2creg[i]); ++ ++ rtw89_write8(rtwdev, R_AX_H2CREG_CTRL, B_AX_H2CREG_TRIGGER); ++ ++ return 0; ++} ++ ++static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev, ++ struct rtw89_mac_c2h_info *info) ++{ ++ static const u32 c2h_reg[RTW89_C2HREG_MAX] = { ++ R_AX_C2HREG_DATA0, R_AX_C2HREG_DATA1, ++ R_AX_C2HREG_DATA2, R_AX_C2HREG_DATA3 ++ }; ++ u32 ret; ++ u8 i, val; ++ ++ info->id = RTW89_FWCMD_C2HREG_FUNC_NULL; ++ ++ ret = read_poll_timeout_atomic(rtw89_read8, val, val, 1, ++ RTW89_C2H_TIMEOUT, false, rtwdev, ++ R_AX_C2HREG_CTRL); ++ if (ret) { ++ rtw89_warn(rtwdev, "c2h reg timeout\n"); ++ return ret; ++ } ++ ++ for (i = 0; i < RTW89_C2HREG_MAX; i++) ++ info->c2hreg[i] = rtw89_read32(rtwdev, c2h_reg[i]); ++ ++ rtw89_write8(rtwdev, R_AX_C2HREG_CTRL, 0); ++ ++ info->id = RTW89_GET_C2H_HDR_FUNC(*info->c2hreg); ++ info->content_len = (RTW89_GET_C2H_HDR_LEN(*info->c2hreg) << 2) - ++ RTW89_C2HREG_HDR_LEN; ++ ++ return 0; ++} ++ ++int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev, ++ struct rtw89_mac_h2c_info *h2c_info, ++ struct rtw89_mac_c2h_info *c2h_info) ++{ ++ u32 ret; ++ ++ if (h2c_info && h2c_info->id != RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE) ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ if (!h2c_info && !c2h_info) ++ return -EINVAL; ++ ++ if (!h2c_info) ++ goto recv_c2h; ++ ++ ret = rtw89_fw_write_h2c_reg(rtwdev, h2c_info); ++ if (ret) ++ return ret; ++ ++recv_c2h: ++ if (!c2h_info) ++ return 0; ++ ++ ret = rtw89_fw_read_c2h_reg(rtwdev, c2h_info); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev) ++{ ++ if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) { ++ rtw89_err(rtwdev, "[ERR]pwr is off\n"); ++ return; ++ } ++ ++ rtw89_info(rtwdev, "FW status = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM0)); ++ rtw89_info(rtwdev, "FW BADADDR = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM1)); ++ rtw89_info(rtwdev, "FW EPC/RA = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM2)); ++ rtw89_info(rtwdev, "FW MISC = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM3)); ++ rtw89_info(rtwdev, "R_AX_HALT_C2H = 0x%x\n", ++ rtw89_read32(rtwdev, R_AX_HALT_C2H)); ++ rtw89_info(rtwdev, "R_AX_SER_DBG_INFO = 0x%x\n", ++ rtw89_read32(rtwdev, R_AX_SER_DBG_INFO)); ++ ++ rtw89_fw_prog_cnt_dump(rtwdev); ++} +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +new file mode 100644 +index 000000000000..7ee0d9323310 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -0,0 +1,1378 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_FW_H__ ++#define __RTW89_FW_H__ ++ ++#include "core.h" ++ ++enum rtw89_fw_dl_status { ++ RTW89_FWDL_INITIAL_STATE = 0, ++ RTW89_FWDL_FWDL_ONGOING = 1, ++ RTW89_FWDL_CHECKSUM_FAIL = 2, ++ RTW89_FWDL_SECURITY_FAIL = 3, ++ RTW89_FWDL_CV_NOT_MATCH = 4, ++ RTW89_FWDL_RSVD0 = 5, ++ RTW89_FWDL_WCPU_FWDL_RDY = 6, ++ RTW89_FWDL_WCPU_FW_INIT_RDY = 7 ++}; ++ ++#define RTW89_GET_C2H_HDR_FUNC(info) \ ++ u32_get_bits(info, GENMASK(6, 0)) ++#define RTW89_GET_C2H_HDR_LEN(info) \ ++ u32_get_bits(info, GENMASK(11, 8)) ++ ++#define RTW89_SET_H2CREG_HDR_FUNC(info, val) \ ++ u32p_replace_bits(info, val, GENMASK(6, 0)) ++#define RTW89_SET_H2CREG_HDR_LEN(info, val) \ ++ u32p_replace_bits(info, val, GENMASK(11, 8)) ++ ++#define RTW89_H2CREG_MAX 4 ++#define RTW89_C2HREG_MAX 4 ++#define RTW89_C2HREG_HDR_LEN 2 ++#define RTW89_H2CREG_HDR_LEN 2 ++#define RTW89_C2H_TIMEOUT 1000000 ++struct rtw89_mac_c2h_info { ++ u8 id; ++ u8 content_len; ++ u32 c2hreg[RTW89_C2HREG_MAX]; ++}; ++ ++struct rtw89_mac_h2c_info { ++ u8 id; ++ u8 content_len; ++ u32 h2creg[RTW89_H2CREG_MAX]; ++}; ++ ++enum rtw89_mac_h2c_type { ++ RTW89_FWCMD_H2CREG_FUNC_H2CREG_LB = 0, ++ RTW89_FWCMD_H2CREG_FUNC_CNSL_CMD, ++ RTW89_FWCMD_H2CREG_FUNC_FWERR, ++ RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE, ++ RTW89_FWCMD_H2CREG_FUNC_GETPKT_INFORM, ++ RTW89_FWCMD_H2CREG_FUNC_SCH_TX_EN ++}; ++ ++enum rtw89_mac_c2h_type { ++ RTW89_FWCMD_C2HREG_FUNC_C2HREG_LB = 0, ++ RTW89_FWCMD_C2HREG_FUNC_ERR_RPT, ++ RTW89_FWCMD_C2HREG_FUNC_ERR_MSG, ++ RTW89_FWCMD_C2HREG_FUNC_PHY_CAP, ++ RTW89_FWCMD_C2HREG_FUNC_TX_PAUSE_RPT, ++ RTW89_FWCMD_C2HREG_FUNC_NULL = 0xFF ++}; ++ ++struct rtw89_c2h_phy_cap { ++ u32 func:7; ++ u32 ack:1; ++ u32 len:4; ++ u32 seq:4; ++ u32 rx_nss:8; ++ u32 bw:8; ++ ++ u32 tx_nss:8; ++ u32 prot:8; ++ u32 nic:8; ++ u32 wl_func:8; ++ ++ u32 hw_type:8; ++} __packed; ++ ++enum rtw89_fw_c2h_category { ++ RTW89_C2H_CAT_TEST, ++ RTW89_C2H_CAT_MAC, ++ RTW89_C2H_CAT_OUTSRC, ++}; ++ ++enum rtw89_fw_log_level { ++ RTW89_FW_LOG_LEVEL_OFF, ++ RTW89_FW_LOG_LEVEL_CRT, ++ RTW89_FW_LOG_LEVEL_SER, ++ RTW89_FW_LOG_LEVEL_WARN, ++ RTW89_FW_LOG_LEVEL_LOUD, ++ RTW89_FW_LOG_LEVEL_TR, ++}; ++ ++enum rtw89_fw_log_path { ++ RTW89_FW_LOG_LEVEL_UART, ++ RTW89_FW_LOG_LEVEL_C2H, ++ RTW89_FW_LOG_LEVEL_SNI, ++}; ++ ++enum rtw89_fw_log_comp { ++ RTW89_FW_LOG_COMP_VER, ++ RTW89_FW_LOG_COMP_INIT, ++ RTW89_FW_LOG_COMP_TASK, ++ RTW89_FW_LOG_COMP_CNS, ++ RTW89_FW_LOG_COMP_H2C, ++ RTW89_FW_LOG_COMP_C2H, ++ RTW89_FW_LOG_COMP_TX, ++ RTW89_FW_LOG_COMP_RX, ++ RTW89_FW_LOG_COMP_IPSEC, ++ RTW89_FW_LOG_COMP_TIMER, ++ RTW89_FW_LOG_COMP_DBGPKT, ++ RTW89_FW_LOG_COMP_PS, ++ RTW89_FW_LOG_COMP_ERROR, ++ RTW89_FW_LOG_COMP_WOWLAN, ++ RTW89_FW_LOG_COMP_SECURE_BOOT, ++ RTW89_FW_LOG_COMP_BTC, ++ RTW89_FW_LOG_COMP_BB, ++ RTW89_FW_LOG_COMP_TWT, ++ RTW89_FW_LOG_COMP_RF, ++ RTW89_FW_LOG_COMP_MCC = 20, ++}; ++ ++#define FWDL_SECTION_MAX_NUM 10 ++#define FWDL_SECTION_CHKSUM_LEN 8 ++#define FWDL_SECTION_PER_PKT_LEN 2020 ++ ++struct rtw89_fw_hdr_section_info { ++ u8 redl; ++ const u8 *addr; ++ u32 len; ++ u32 dladdr; ++}; ++ ++struct rtw89_fw_bin_info { ++ u8 section_num; ++ u32 hdr_len; ++ struct rtw89_fw_hdr_section_info section_info[FWDL_SECTION_MAX_NUM]; ++}; ++ ++struct rtw89_fw_macid_pause_grp { ++ __le32 pause_grp[4]; ++ __le32 mask_grp[4]; ++} __packed; ++ ++struct rtw89_h2creg_sch_tx_en { ++ u8 func:7; ++ u8 ack:1; ++ u8 total_len:4; ++ u8 seq_num:4; ++ u16 tx_en:16; ++ u16 mask:16; ++ u8 band:1; ++ u16 rsvd:15; ++} __packed; ++ ++#define RTW89_SET_FWCMD_RA_IS_DIS(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(0)) ++#define RTW89_SET_FWCMD_RA_MODE(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(5, 1)) ++#define RTW89_SET_FWCMD_RA_BW_CAP(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(7, 6)) ++#define RTW89_SET_FWCMD_RA_MACID(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(15, 8)) ++#define RTW89_SET_FWCMD_RA_DCM(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(16)) ++#define RTW89_SET_FWCMD_RA_ER(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(17)) ++#define RTW89_SET_FWCMD_RA_INIT_RATE_LV(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(19, 18)) ++#define RTW89_SET_FWCMD_RA_UPD_ALL(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(20)) ++#define RTW89_SET_FWCMD_RA_SGI(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(21)) ++#define RTW89_SET_FWCMD_RA_LDPC(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(22)) ++#define RTW89_SET_FWCMD_RA_STBC(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(23)) ++#define RTW89_SET_FWCMD_RA_SS_NUM(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(26, 24)) ++#define RTW89_SET_FWCMD_RA_GILTF(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(29, 27)) ++#define RTW89_SET_FWCMD_RA_UPD_BW_NSS_MASK(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(30)) ++#define RTW89_SET_FWCMD_RA_UPD_MASK(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(31)) ++#define RTW89_SET_FWCMD_RA_MASK_0(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_RA_MASK_1(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(15, 8)) ++#define RTW89_SET_FWCMD_RA_MASK_2(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(23, 16)) ++#define RTW89_SET_FWCMD_RA_MASK_3(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(31, 24)) ++#define RTW89_SET_FWCMD_RA_MASK_4(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x02, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_RA_BFEE_CSI_CTL(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x02, val, BIT(31)) ++#define RTW89_SET_FWCMD_RA_BAND_NUM(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_RA_RA_CSI_RATE_EN(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, BIT(8)) ++#define RTW89_SET_FWCMD_RA_FIXED_CSI_RATE_EN(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, BIT(9)) ++#define RTW89_SET_FWCMD_RA_CR_TBL_SEL(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, BIT(10)) ++#define RTW89_SET_FWCMD_RA_FIXED_CSI_MCS_SS_IDX(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(23, 16)) ++#define RTW89_SET_FWCMD_RA_FIXED_CSI_MODE(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(25, 24)) ++#define RTW89_SET_FWCMD_RA_FIXED_CSI_GI_LTF(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(28, 26)) ++#define RTW89_SET_FWCMD_RA_FIXED_CSI_BW(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(31, 29)) ++ ++#define RTW89_SET_FWCMD_SEC_IDX(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_SEC_OFFSET(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(15, 8)) ++#define RTW89_SET_FWCMD_SEC_LEN(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(23, 16)) ++#define RTW89_SET_FWCMD_SEC_TYPE(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(3, 0)) ++#define RTW89_SET_FWCMD_SEC_EXT_KEY(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, BIT(4)) ++#define RTW89_SET_FWCMD_SEC_SPP_MODE(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, BIT(5)) ++#define RTW89_SET_FWCMD_SEC_KEY0(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x02, val, GENMASK(31, 0)) ++#define RTW89_SET_FWCMD_SEC_KEY1(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(31, 0)) ++#define RTW89_SET_FWCMD_SEC_KEY2(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x04, val, GENMASK(31, 0)) ++#define RTW89_SET_FWCMD_SEC_KEY3(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x05, val, GENMASK(31, 0)) ++ ++#define RTW89_SET_EDCA_SEL(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(1, 0)) ++#define RTW89_SET_EDCA_BAND(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(3)) ++#define RTW89_SET_EDCA_WMM(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(4)) ++#define RTW89_SET_EDCA_AC(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(6, 5)) ++#define RTW89_SET_EDCA_PARAM(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(31, 0)) ++#define FW_EDCA_PARAM_TXOPLMT_MSK GENMASK(26, 16) ++#define FW_EDCA_PARAM_CWMAX_MSK GENMASK(15, 12) ++#define FW_EDCA_PARAM_CWMIN_MSK GENMASK(11, 8) ++#define FW_EDCA_PARAM_AIFS_MSK GENMASK(7, 0) ++ ++#define GET_FWSECTION_HDR_SEC_SIZE(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 1), GENMASK(23, 0)) ++#define GET_FWSECTION_HDR_CHECKSUM(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 1), BIT(28)) ++#define GET_FWSECTION_HDR_REDL(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 1), BIT(29)) ++#define GET_FWSECTION_HDR_DL_ADDR(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr)), GENMASK(31, 0)) ++ ++#define GET_FW_HDR_MAJOR_VERSION(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 1), GENMASK(7, 0)) ++#define GET_FW_HDR_MINOR_VERSION(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 1), GENMASK(15, 8)) ++#define GET_FW_HDR_SUBVERSION(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 1), GENMASK(23, 16)) ++#define GET_FW_HDR_SUBINDEX(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 1), GENMASK(31, 24)) ++#define GET_FW_HDR_MONTH(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 4), GENMASK(7, 0)) ++#define GET_FW_HDR_DATE(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 4), GENMASK(15, 8)) ++#define GET_FW_HDR_HOUR(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 4), GENMASK(23, 16)) ++#define GET_FW_HDR_MIN(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 4), GENMASK(31, 24)) ++#define GET_FW_HDR_YEAR(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 5), GENMASK(31, 0)) ++#define GET_FW_HDR_SEC_NUM(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 6), GENMASK(15, 8)) ++#define GET_FW_HDR_CMD_VERSERION(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 7), GENMASK(31, 24)) ++#define SET_FW_HDR_PART_SIZE(fwhdr, val) \ ++ le32p_replace_bits((__le32 *)(fwhdr) + 7, val, GENMASK(15, 0)) ++ ++#define SET_CTRL_INFO_MACID(table, val) \ ++ le32p_replace_bits((__le32 *)(table) + 0, val, GENMASK(6, 0)) ++#define SET_CTRL_INFO_OPERATION(table, val) \ ++ le32p_replace_bits((__le32 *)(table) + 0, val, BIT(7)) ++#define SET_CMC_TBL_MASK_DATARATE GENMASK(8, 0) ++#define SET_CMC_TBL_DATARATE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(8, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DATARATE, \ ++ GENMASK(8, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_FORCE_TXOP BIT(0) ++#define SET_CMC_TBL_FORCE_TXOP(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(9)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_FORCE_TXOP, \ ++ BIT(9)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_BW GENMASK(1, 0) ++#define SET_CMC_TBL_DATA_BW(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(11, 10)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DATA_BW, \ ++ GENMASK(11, 10)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_GI_LTF GENMASK(2, 0) ++#define SET_CMC_TBL_DATA_GI_LTF(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(14, 12)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DATA_GI_LTF, \ ++ GENMASK(14, 12)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DARF_TC_INDEX BIT(0) ++#define SET_CMC_TBL_DARF_TC_INDEX(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(15)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DARF_TC_INDEX, \ ++ BIT(15)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ARFR_CTRL GENMASK(3, 0) ++#define SET_CMC_TBL_ARFR_CTRL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(19, 16)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_ARFR_CTRL, \ ++ GENMASK(19, 16)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ACQ_RPT_EN BIT(0) ++#define SET_CMC_TBL_ACQ_RPT_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(20)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_ACQ_RPT_EN, \ ++ BIT(20)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_MGQ_RPT_EN BIT(0) ++#define SET_CMC_TBL_MGQ_RPT_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(21)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_MGQ_RPT_EN, \ ++ BIT(21)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ULQ_RPT_EN BIT(0) ++#define SET_CMC_TBL_ULQ_RPT_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(22)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_ULQ_RPT_EN, \ ++ BIT(22)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_TWTQ_RPT_EN BIT(0) ++#define SET_CMC_TBL_TWTQ_RPT_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(23)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_TWTQ_RPT_EN, \ ++ BIT(23)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DISRTSFB BIT(0) ++#define SET_CMC_TBL_DISRTSFB(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(25)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DISRTSFB, \ ++ BIT(25)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DISDATAFB BIT(0) ++#define SET_CMC_TBL_DISDATAFB(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(26)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DISDATAFB, \ ++ BIT(26)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_TRYRATE BIT(0) ++#define SET_CMC_TBL_TRYRATE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(27)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_TRYRATE, \ ++ BIT(27)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_AMPDU_DENSITY GENMASK(3, 0) ++#define SET_CMC_TBL_AMPDU_DENSITY(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(31, 28)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_AMPDU_DENSITY, \ ++ GENMASK(31, 28)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_RTY_LOWEST_RATE GENMASK(8, 0) ++#define SET_CMC_TBL_DATA_RTY_LOWEST_RATE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, GENMASK(8, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_DATA_RTY_LOWEST_RATE, \ ++ GENMASK(8, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_AMPDU_TIME_SEL BIT(0) ++#define SET_CMC_TBL_AMPDU_TIME_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, BIT(9)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_AMPDU_TIME_SEL, \ ++ BIT(9)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_AMPDU_LEN_SEL BIT(0) ++#define SET_CMC_TBL_AMPDU_LEN_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, BIT(10)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_AMPDU_LEN_SEL, \ ++ BIT(10)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_RTS_TXCNT_LMT_SEL BIT(0) ++#define SET_CMC_TBL_RTS_TXCNT_LMT_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, BIT(11)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_RTS_TXCNT_LMT_SEL, \ ++ BIT(11)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_RTS_TXCNT_LMT GENMASK(3, 0) ++#define SET_CMC_TBL_RTS_TXCNT_LMT(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, GENMASK(15, 12)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_RTS_TXCNT_LMT, \ ++ GENMASK(15, 12)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_RTSRATE GENMASK(8, 0) ++#define SET_CMC_TBL_RTSRATE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, GENMASK(24, 16)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_RTSRATE, \ ++ GENMASK(24, 16)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_VCS_STBC BIT(0) ++#define SET_CMC_TBL_VCS_STBC(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, BIT(27)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_VCS_STBC, \ ++ BIT(27)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_RTS_RTY_LOWEST_RATE GENMASK(3, 0) ++#define SET_CMC_TBL_RTS_RTY_LOWEST_RATE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, GENMASK(31, 28)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_RTS_RTY_LOWEST_RATE, \ ++ GENMASK(31, 28)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_TX_CNT_LMT GENMASK(5, 0) ++#define SET_CMC_TBL_DATA_TX_CNT_LMT(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(5, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_DATA_TX_CNT_LMT, \ ++ GENMASK(5, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_TXCNT_LMT_SEL BIT(0) ++#define SET_CMC_TBL_DATA_TXCNT_LMT_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, BIT(6)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_DATA_TXCNT_LMT_SEL, \ ++ BIT(6)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_MAX_AGG_NUM_SEL BIT(0) ++#define SET_CMC_TBL_MAX_AGG_NUM_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, BIT(7)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_MAX_AGG_NUM_SEL, \ ++ BIT(7)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_RTS_EN BIT(0) ++#define SET_CMC_TBL_RTS_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, BIT(8)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_RTS_EN, \ ++ BIT(8)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CTS2SELF_EN BIT(0) ++#define SET_CMC_TBL_CTS2SELF_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, BIT(9)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_CTS2SELF_EN, \ ++ BIT(9)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CCA_RTS GENMASK(1, 0) ++#define SET_CMC_TBL_CCA_RTS(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(11, 10)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_CCA_RTS, \ ++ GENMASK(11, 10)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_HW_RTS_EN BIT(0) ++#define SET_CMC_TBL_HW_RTS_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, BIT(12)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_HW_RTS_EN, \ ++ BIT(12)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_RTS_DROP_DATA_MODE GENMASK(1, 0) ++#define SET_CMC_TBL_RTS_DROP_DATA_MODE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(14, 13)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_RTS_DROP_DATA_MODE, \ ++ GENMASK(14, 13)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_AMPDU_MAX_LEN GENMASK(10, 0) ++#define SET_CMC_TBL_AMPDU_MAX_LEN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(26, 16)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_AMPDU_MAX_LEN, \ ++ GENMASK(26, 16)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_UL_MU_DIS BIT(0) ++#define SET_CMC_TBL_UL_MU_DIS(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, BIT(27)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_UL_MU_DIS, \ ++ BIT(27)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_AMPDU_MAX_TIME GENMASK(3, 0) ++#define SET_CMC_TBL_AMPDU_MAX_TIME(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(31, 28)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_AMPDU_MAX_TIME, \ ++ GENMASK(31, 28)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_MAX_AGG_NUM GENMASK(7, 0) ++#define SET_CMC_TBL_MAX_AGG_NUM(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(7, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_MAX_AGG_NUM, \ ++ GENMASK(7, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_BA_BMAP GENMASK(1, 0) ++#define SET_CMC_TBL_BA_BMAP(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(9, 8)); \ ++ le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_BA_BMAP, \ ++ GENMASK(9, 8)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_VO_LFTIME_SEL GENMASK(2, 0) ++#define SET_CMC_TBL_VO_LFTIME_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(18, 16)); \ ++ le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_VO_LFTIME_SEL, \ ++ GENMASK(18, 16)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_VI_LFTIME_SEL GENMASK(2, 0) ++#define SET_CMC_TBL_VI_LFTIME_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(21, 19)); \ ++ le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_VI_LFTIME_SEL, \ ++ GENMASK(21, 19)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_BE_LFTIME_SEL GENMASK(2, 0) ++#define SET_CMC_TBL_BE_LFTIME_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(24, 22)); \ ++ le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_BE_LFTIME_SEL, \ ++ GENMASK(24, 22)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_BK_LFTIME_SEL GENMASK(2, 0) ++#define SET_CMC_TBL_BK_LFTIME_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(27, 25)); \ ++ le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_BK_LFTIME_SEL, \ ++ GENMASK(27, 25)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_SECTYPE GENMASK(3, 0) ++#define SET_CMC_TBL_SECTYPE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(31, 28)); \ ++ le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_SECTYPE, \ ++ GENMASK(31, 28)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_MULTI_PORT_ID GENMASK(2, 0) ++#define SET_CMC_TBL_MULTI_PORT_ID(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(2, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_MULTI_PORT_ID, \ ++ GENMASK(2, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_BMC BIT(0) ++#define SET_CMC_TBL_BMC(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(3)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_BMC, \ ++ BIT(3)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_MBSSID GENMASK(3, 0) ++#define SET_CMC_TBL_MBSSID(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(7, 4)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_MBSSID, \ ++ GENMASK(7, 4)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_NAVUSEHDR BIT(0) ++#define SET_CMC_TBL_NAVUSEHDR(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(8)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_NAVUSEHDR, \ ++ BIT(8)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_TXPWR_MODE GENMASK(2, 0) ++#define SET_CMC_TBL_TXPWR_MODE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(11, 9)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_TXPWR_MODE, \ ++ GENMASK(11, 9)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_DCM BIT(0) ++#define SET_CMC_TBL_DATA_DCM(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(12)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_DATA_DCM, \ ++ BIT(12)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_ER BIT(0) ++#define SET_CMC_TBL_DATA_ER(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(13)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_DATA_ER, \ ++ BIT(13)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_LDPC BIT(0) ++#define SET_CMC_TBL_DATA_LDPC(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(14)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_DATA_LDPC, \ ++ BIT(14)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_STBC BIT(0) ++#define SET_CMC_TBL_DATA_STBC(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(15)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_DATA_STBC, \ ++ BIT(15)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_A_CTRL_BQR BIT(0) ++#define SET_CMC_TBL_A_CTRL_BQR(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(16)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_A_CTRL_BQR, \ ++ BIT(16)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_A_CTRL_UPH BIT(0) ++#define SET_CMC_TBL_A_CTRL_UPH(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(17)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_A_CTRL_UPH, \ ++ BIT(17)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_A_CTRL_BSR BIT(0) ++#define SET_CMC_TBL_A_CTRL_BSR(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(18)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_A_CTRL_BSR, \ ++ BIT(18)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_A_CTRL_CAS BIT(0) ++#define SET_CMC_TBL_A_CTRL_CAS(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(19)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_A_CTRL_CAS, \ ++ BIT(19)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_BW_ER BIT(0) ++#define SET_CMC_TBL_DATA_BW_ER(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(20)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_DATA_BW_ER, \ ++ BIT(20)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_LSIG_TXOP_EN BIT(0) ++#define SET_CMC_TBL_LSIG_TXOP_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(21)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_LSIG_TXOP_EN, \ ++ BIT(21)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CTRL_CNT_VLD BIT(0) ++#define SET_CMC_TBL_CTRL_CNT_VLD(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(27)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_CTRL_CNT_VLD, \ ++ BIT(27)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CTRL_CNT GENMASK(3, 0) ++#define SET_CMC_TBL_CTRL_CNT(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(31, 28)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_CTRL_CNT, \ ++ GENMASK(31, 28)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_RESP_REF_RATE GENMASK(8, 0) ++#define SET_CMC_TBL_RESP_REF_RATE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(8, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_RESP_REF_RATE, \ ++ GENMASK(8, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ALL_ACK_SUPPORT BIT(0) ++#define SET_CMC_TBL_ALL_ACK_SUPPORT(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, BIT(12)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ALL_ACK_SUPPORT, \ ++ BIT(12)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_BSR_QUEUE_SIZE_FORMAT BIT(0) ++#define SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, BIT(13)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_BSR_QUEUE_SIZE_FORMAT, \ ++ BIT(13)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_NTX_PATH_EN GENMASK(3, 0) ++#define SET_CMC_TBL_NTX_PATH_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(19, 16)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_NTX_PATH_EN, \ ++ GENMASK(19, 16)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_PATH_MAP_A GENMASK(1, 0) ++#define SET_CMC_TBL_PATH_MAP_A(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(21, 20)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_PATH_MAP_A, \ ++ GENMASK(21, 20)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_PATH_MAP_B GENMASK(1, 0) ++#define SET_CMC_TBL_PATH_MAP_B(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(23, 22)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_PATH_MAP_B, \ ++ GENMASK(23, 22)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_PATH_MAP_C GENMASK(1, 0) ++#define SET_CMC_TBL_PATH_MAP_C(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(25, 24)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_PATH_MAP_C, \ ++ GENMASK(25, 24)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_PATH_MAP_D GENMASK(1, 0) ++#define SET_CMC_TBL_PATH_MAP_D(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(27, 26)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_PATH_MAP_D, \ ++ GENMASK(27, 26)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ANTSEL_A BIT(0) ++#define SET_CMC_TBL_ANTSEL_A(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, BIT(28)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ANTSEL_A, \ ++ BIT(28)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ANTSEL_B BIT(0) ++#define SET_CMC_TBL_ANTSEL_B(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, BIT(29)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ANTSEL_B, \ ++ BIT(29)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ANTSEL_C BIT(0) ++#define SET_CMC_TBL_ANTSEL_C(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, BIT(30)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ANTSEL_C, \ ++ BIT(30)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ANTSEL_D BIT(0) ++#define SET_CMC_TBL_ANTSEL_D(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, BIT(31)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ANTSEL_D, \ ++ BIT(31)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ADDR_CAM_INDEX GENMASK(7, 0) ++#define SET_CMC_TBL_ADDR_CAM_INDEX(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(7, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_ADDR_CAM_INDEX, \ ++ GENMASK(7, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_PAID GENMASK(8, 0) ++#define SET_CMC_TBL_PAID(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(16, 8)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_PAID, \ ++ GENMASK(16, 8)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ULDL BIT(0) ++#define SET_CMC_TBL_ULDL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, BIT(17)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_ULDL, \ ++ BIT(17)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DOPPLER_CTRL GENMASK(1, 0) ++#define SET_CMC_TBL_DOPPLER_CTRL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(19, 18)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_DOPPLER_CTRL, \ ++ GENMASK(19, 18)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING GENMASK(1, 0) ++#define SET_CMC_TBL_NOMINAL_PKT_PADDING(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(21, 20)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, \ ++ GENMASK(21, 20)); \ ++} while (0) ++#define SET_CMC_TBL_NOMINAL_PKT_PADDING40(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(23, 22)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, \ ++ GENMASK(23, 22)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_TXPWR_TOLERENCE GENMASK(3, 0) ++#define SET_CMC_TBL_TXPWR_TOLERENCE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(27, 24)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_TXPWR_TOLERENCE, \ ++ GENMASK(27, 24)); \ ++} while (0) ++#define SET_CMC_TBL_NOMINAL_PKT_PADDING80(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(31, 30)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, \ ++ GENMASK(31, 30)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_NC GENMASK(2, 0) ++#define SET_CMC_TBL_NC(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(2, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_NC, \ ++ GENMASK(2, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_NR GENMASK(2, 0) ++#define SET_CMC_TBL_NR(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(5, 3)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_NR, \ ++ GENMASK(5, 3)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_NG GENMASK(1, 0) ++#define SET_CMC_TBL_NG(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(7, 6)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_NG, \ ++ GENMASK(7, 6)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CB GENMASK(1, 0) ++#define SET_CMC_TBL_CB(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(9, 8)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CB, \ ++ GENMASK(9, 8)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CS GENMASK(1, 0) ++#define SET_CMC_TBL_CS(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(11, 10)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CS, \ ++ GENMASK(11, 10)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_TXBF_EN BIT(0) ++#define SET_CMC_TBL_CSI_TXBF_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, BIT(12)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_TXBF_EN, \ ++ BIT(12)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_STBC_EN BIT(0) ++#define SET_CMC_TBL_CSI_STBC_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, BIT(13)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_STBC_EN, \ ++ BIT(13)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_LDPC_EN BIT(0) ++#define SET_CMC_TBL_CSI_LDPC_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, BIT(14)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_LDPC_EN, \ ++ BIT(14)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_PARA_EN BIT(0) ++#define SET_CMC_TBL_CSI_PARA_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, BIT(15)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_PARA_EN, \ ++ BIT(15)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_FIX_RATE GENMASK(8, 0) ++#define SET_CMC_TBL_CSI_FIX_RATE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(24, 16)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_FIX_RATE, \ ++ GENMASK(24, 16)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_GI_LTF GENMASK(2, 0) ++#define SET_CMC_TBL_CSI_GI_LTF(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(27, 25)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_GI_LTF, \ ++ GENMASK(27, 25)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_GID_SEL BIT(0) ++#define SET_CMC_TBL_CSI_GID_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, BIT(29)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_GID_SEL, \ ++ BIT(29)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_BW GENMASK(1, 0) ++#define SET_CMC_TBL_CSI_BW(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(31, 30)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_BW, \ ++ GENMASK(31, 30)); \ ++} while (0) ++ ++#define SET_FWROLE_MAINTAIN_MACID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0)) ++#define SET_FWROLE_MAINTAIN_SELF_ROLE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(9, 8)) ++#define SET_FWROLE_MAINTAIN_UPD_MODE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(12, 10)) ++#define SET_FWROLE_MAINTAIN_WIFI_ROLE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(16, 13)) ++ ++#define SET_JOININFO_MACID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0)) ++#define SET_JOININFO_OP(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(8)) ++#define SET_JOININFO_BAND(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(9)) ++#define SET_JOININFO_WMM(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(11, 10)) ++#define SET_JOININFO_TGR(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(12)) ++#define SET_JOININFO_ISHESTA(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(13)) ++#define SET_JOININFO_DLBW(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 14)) ++#define SET_JOININFO_TF_MAC_PAD(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(17, 16)) ++#define SET_JOININFO_DL_T_PE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(20, 18)) ++#define SET_JOININFO_PORT_ID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(23, 21)) ++#define SET_JOININFO_NET_TYPE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(25, 24)) ++#define SET_JOININFO_WIFI_ROLE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(29, 26)) ++#define SET_JOININFO_SELF_ROLE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 30)) ++ ++#define SET_GENERAL_PKT_MACID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0)) ++#define SET_GENERAL_PKT_PROBRSP_ID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)) ++#define SET_GENERAL_PKT_PSPOLL_ID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(23, 16)) ++#define SET_GENERAL_PKT_NULL_ID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)) ++#define SET_GENERAL_PKT_QOS_NULL_ID(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(7, 0)) ++#define SET_GENERAL_PKT_CTS2SELF_ID(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(15, 8)) ++ ++#define SET_LOG_CFG_LEVEL(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0)) ++#define SET_LOG_CFG_PATH(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)) ++#define SET_LOG_CFG_COMP(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(31, 0)) ++#define SET_LOG_CFG_COMP_EXT(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 2, val, GENMASK(31, 0)) ++ ++#define SET_BA_CAM_VALID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(0)) ++#define SET_BA_CAM_INIT_REQ(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(1)) ++#define SET_BA_CAM_ENTRY_IDX(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(3, 2)) ++#define SET_BA_CAM_TID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 4)) ++#define SET_BA_CAM_MACID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)) ++#define SET_BA_CAM_BMAP_SIZE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(19, 16)) ++#define SET_BA_CAM_SSN(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 20)) ++ ++#define SET_LPS_PARM_MACID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0)) ++#define SET_LPS_PARM_PSMODE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)) ++#define SET_LPS_PARM_RLBM(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(19, 16)) ++#define SET_LPS_PARM_SMARTPS(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(23, 20)) ++#define SET_LPS_PARM_AWAKEINTERVAL(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)) ++#define SET_LPS_PARM_VOUAPSD(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, BIT(0)) ++#define SET_LPS_PARM_VIUAPSD(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, BIT(1)) ++#define SET_LPS_PARM_BEUAPSD(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, BIT(2)) ++#define SET_LPS_PARM_BKUAPSD(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, BIT(3)) ++#define SET_LPS_PARM_LASTRPWM(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(15, 8)) ++ ++enum rtw89_btc_btf_h2c_class { ++ BTFC_SET = 0x10, ++ BTFC_GET = 0x11, ++ BTFC_FW_EVENT = 0x12, ++}; ++ ++enum rtw89_btc_btf_set { ++ SET_REPORT_EN = 0x0, ++ SET_SLOT_TABLE, ++ SET_MREG_TABLE, ++ SET_CX_POLICY, ++ SET_GPIO_DBG, ++ SET_DRV_INFO, ++ SET_DRV_EVENT, ++ SET_BT_WREG_ADDR, ++ SET_BT_WREG_VAL, ++ SET_BT_RREG_ADDR, ++ SET_BT_WL_CH_INFO, ++ SET_BT_INFO_REPORT, ++ SET_BT_IGNORE_WLAN_ACT, ++ SET_BT_TX_PWR, ++ SET_BT_LNA_CONSTRAIN, ++ SET_BT_GOLDEN_RX_RANGE, ++ SET_BT_PSD_REPORT, ++ SET_H2C_TEST, ++ SET_MAX1, ++}; ++ ++enum rtw89_btc_cxdrvinfo { ++ CXDRVINFO_INIT = 0, ++ CXDRVINFO_ROLE, ++ CXDRVINFO_DBCC, ++ CXDRVINFO_SMAP, ++ CXDRVINFO_RFK, ++ CXDRVINFO_RUN, ++ CXDRVINFO_CTRL, ++ CXDRVINFO_SCAN, ++ CXDRVINFO_MAX, ++}; ++ ++#define RTW89_SET_FWCMD_CXHDR_TYPE(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 0, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXHDR_LEN(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 1, val, GENMASK(7, 0)) ++ ++#define RTW89_SET_FWCMD_CXINIT_ANT_TYPE(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 2, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXINIT_ANT_NUM(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 3, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXINIT_ANT_ISO(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 4, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXINIT_ANT_POS(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 5, val, BIT(0)) ++#define RTW89_SET_FWCMD_CXINIT_ANT_DIVERSITY(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 5, val, BIT(1)) ++#define RTW89_SET_FWCMD_CXINIT_MOD_RFE(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 6, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXINIT_MOD_CV(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 7, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXINIT_MOD_BT_SOLO(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 8, val, BIT(0)) ++#define RTW89_SET_FWCMD_CXINIT_MOD_BT_POS(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 8, val, BIT(1)) ++#define RTW89_SET_FWCMD_CXINIT_MOD_SW_TYPE(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 8, val, BIT(2)) ++#define RTW89_SET_FWCMD_CXINIT_WL_GCH(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 10, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXINIT_WL_ONLY(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 11, val, BIT(0)) ++#define RTW89_SET_FWCMD_CXINIT_WL_INITOK(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 11, val, BIT(1)) ++#define RTW89_SET_FWCMD_CXINIT_DBCC_EN(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 11, val, BIT(2)) ++#define RTW89_SET_FWCMD_CXINIT_CX_OTHER(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 11, val, BIT(3)) ++#define RTW89_SET_FWCMD_CXINIT_BT_ONLY(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 11, val, BIT(4)) ++ ++#define RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 2, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 3, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(0)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(1)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(2)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(3)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(4)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(5)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(6)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(7)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(8)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(9)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(10)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(11)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (6 + 12 * (n)), val, BIT(0)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (6 + 12 * (n)), val, GENMASK(3, 1)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (6 + 12 * (n)), val, BIT(4)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (6 + 12 * (n)), val, BIT(5)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (6 + 12 * (n)), val, GENMASK(7, 6)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (7 + 12 * (n)), val, BIT(0)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (7 + 12 * (n)), val, GENMASK(7, 1)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (8 + 12 * (n)), val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (9 + 12 * (n)), val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, val, n) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + (10 + 12 * (n))), val, GENMASK(15, 0)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, val, n) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + (12 + 12 * (n))), val, GENMASK(15, 0)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, val, n) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + (14 + 12 * (n))), val, GENMASK(15, 0)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, val, n) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + (16 + 12 * (n))), val, GENMASK(15, 0)) ++ ++#define RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, BIT(0)) ++#define RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, BIT(1)) ++#define RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, BIT(2)) ++#define RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(18, 3)) ++ ++#define RTW89_SET_FWCMD_CXRFK_STATE(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(1, 0)) ++#define RTW89_SET_FWCMD_CXRFK_PATH_MAP(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(5, 2)) ++#define RTW89_SET_FWCMD_CXRFK_PHY_MAP(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(7, 6)) ++#define RTW89_SET_FWCMD_CXRFK_BAND(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(9, 8)) ++#define RTW89_SET_FWCMD_CXRFK_TYPE(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(17, 10)) ++ ++#define RTW89_C2H_HEADER_LEN 8 ++ ++#define RTW89_GET_C2H_CATEGORY(c2h) \ ++ le32_get_bits(*((__le32 *)c2h), GENMASK(1, 0)) ++#define RTW89_GET_C2H_CLASS(c2h) \ ++ le32_get_bits(*((__le32 *)c2h), GENMASK(7, 2)) ++#define RTW89_GET_C2H_FUNC(c2h) \ ++ le32_get_bits(*((__le32 *)c2h), GENMASK(15, 8)) ++#define RTW89_GET_C2H_LEN(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 1), GENMASK(13, 0)) ++ ++#define RTW89_GET_C2H_LOG_SRT_PRT(c2h) (char *)((__le32 *)(c2h) + 2) ++#define RTW89_GET_C2H_LOG_LEN(len) ((len) - RTW89_C2H_HEADER_LEN) ++ ++#define RTW89_GET_MAC_C2H_DONE_ACK_CAT(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(1, 0)) ++#define RTW89_GET_MAC_C2H_DONE_ACK_CLASS(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(7, 2)) ++#define RTW89_GET_MAC_C2H_DONE_ACK_FUNC(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(15, 8)) ++#define RTW89_GET_MAC_C2H_DONE_ACK_H2C_RETURN(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(23, 16)) ++#define RTW89_GET_MAC_C2H_DONE_ACK_H2C_SEQ(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(31, 24)) ++ ++#define RTW89_GET_MAC_C2H_REV_ACK_CAT(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(1, 0)) ++#define RTW89_GET_MAC_C2H_REV_ACK_CLASS(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(7, 2)) ++#define RTW89_GET_MAC_C2H_REV_ACK_FUNC(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(15, 8)) ++#define RTW89_GET_MAC_C2H_REV_ACK_H2C_SEQ(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(23, 16)) ++ ++#define RTW89_GET_PHY_C2H_RA_RPT_MACID(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(15, 0)) ++#define RTW89_GET_PHY_C2H_RA_RPT_RETRY_RATIO(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(23, 16)) ++#define RTW89_GET_PHY_C2H_RA_RPT_MCSNSS(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 3), GENMASK(6, 0)) ++#define RTW89_GET_PHY_C2H_RA_RPT_MD_SEL(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 3), GENMASK(9, 8)) ++#define RTW89_GET_PHY_C2H_RA_RPT_GILTF(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 3), GENMASK(12, 10)) ++#define RTW89_GET_PHY_C2H_RA_RPT_BW(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 3), GENMASK(14, 13)) ++ ++/* VHT, HE, HT-old: [6:4]: NSS, [3:0]: MCS ++ * HT-new: [6:5]: NA, [4:0]: MCS ++ */ ++#define RTW89_RA_RATE_MASK_NSS GENMASK(6, 4) ++#define RTW89_RA_RATE_MASK_MCS GENMASK(3, 0) ++#define RTW89_RA_RATE_MASK_HT_MCS GENMASK(4, 0) ++#define RTW89_MK_HT_RATE(nss, mcs) (FIELD_PREP(GENMASK(4, 3), nss) | \ ++ FIELD_PREP(GENMASK(2, 0), mcs)) ++ ++#define RTW89_FW_HDR_SIZE 32 ++#define RTW89_FW_SECTION_HDR_SIZE 16 ++ ++#define RTW89_MFW_SIG 0xFF ++ ++struct rtw89_mfw_info { ++ u8 cv; ++ u8 type; /* enum rtw89_fw_type */ ++ u8 mp; ++ u8 rsvd; ++ __le32 shift; ++ __le32 size; ++ u8 rsvd2[4]; ++} __packed; ++ ++struct rtw89_mfw_hdr { ++ u8 sig; /* RTW89_MFW_SIG */ ++ u8 fw_nr; ++ u8 rsvd[14]; ++ struct rtw89_mfw_info info[]; ++} __packed; ++ ++struct fwcmd_hdr { ++ __le32 hdr0; ++ __le32 hdr1; ++}; ++ ++#define RTW89_H2C_RF_PAGE_SIZE 500 ++#define RTW89_H2C_RF_PAGE_NUM 3 ++struct rtw89_fw_h2c_rf_reg_info { ++ enum rtw89_rf_path rf_path; ++ __le32 rtw89_phy_config_rf_h2c[RTW89_H2C_RF_PAGE_NUM][RTW89_H2C_RF_PAGE_SIZE]; ++ u16 curr_idx; ++}; ++ ++#define H2C_SEC_CAM_LEN 24 ++ ++#define H2C_HEADER_LEN 8 ++#define H2C_HDR_CAT GENMASK(1, 0) ++#define H2C_HDR_CLASS GENMASK(7, 2) ++#define H2C_HDR_FUNC GENMASK(15, 8) ++#define H2C_HDR_DEL_TYPE GENMASK(19, 16) ++#define H2C_HDR_H2C_SEQ GENMASK(31, 24) ++#define H2C_HDR_TOTAL_LEN GENMASK(13, 0) ++#define H2C_HDR_REC_ACK BIT(14) ++#define H2C_HDR_DONE_ACK BIT(15) ++ ++#define FWCMD_TYPE_H2C 0 ++ ++#define H2C_CAT_MAC 0x1 ++ ++/* CLASS 0 - FW INFO */ ++#define H2C_CL_FW_INFO 0x0 ++#define H2C_FUNC_LOG_CFG 0x0 ++#define H2C_FUNC_MAC_GENERAL_PKT 0x1 ++ ++/* CLASS 2 - PS */ ++#define H2C_CL_MAC_PS 0x2 ++#define H2C_FUNC_MAC_LPS_PARM 0x0 ++ ++/* CLASS 3 - FW download */ ++#define H2C_CL_MAC_FWDL 0x3 ++#define H2C_FUNC_MAC_FWHDR_DL 0x0 ++ ++/* CLASS 5 - Frame Exchange */ ++#define H2C_CL_MAC_FR_EXCHG 0x5 ++#define H2C_FUNC_MAC_CCTLINFO_UD 0x2 ++ ++/* CLASS 6 - Address CAM */ ++#define H2C_CL_MAC_ADDR_CAM_UPDATE 0x6 ++#define H2C_FUNC_MAC_ADDR_CAM_UPD 0x0 ++ ++/* CLASS 8 - Media Status Report */ ++#define H2C_CL_MAC_MEDIA_RPT 0x8 ++#define H2C_FUNC_MAC_JOININFO 0x0 ++#define H2C_FUNC_MAC_FWROLE_MAINTAIN 0x4 ++ ++/* CLASS 9 - FW offload */ ++#define H2C_CL_MAC_FW_OFLD 0x9 ++#define H2C_FUNC_MAC_MACID_PAUSE 0x8 ++#define H2C_FUNC_USR_EDCA 0xF ++#define H2C_FUNC_OFLD_CFG 0x14 ++ ++/* CLASS 10 - Security CAM */ ++#define H2C_CL_MAC_SEC_CAM 0xa ++#define H2C_FUNC_MAC_SEC_UPD 0x1 ++ ++/* CLASS 12 - BA CAM */ ++#define H2C_CL_BA_CAM 0xc ++#define H2C_FUNC_MAC_BA_CAM 0x0 ++ ++#define H2C_CAT_OUTSRC 0x2 ++ ++#define H2C_CL_OUTSRC_RA 0x1 ++#define H2C_FUNC_OUTSRC_RA_MACIDCFG 0x0 ++ ++#define H2C_CL_OUTSRC_RF_REG_A 0x8 ++#define H2C_CL_OUTSRC_RF_REG_B 0x9 ++ ++int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev); ++int rtw89_fw_recognize(struct rtw89_dev *rtwdev); ++int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type); ++int rtw89_load_firmware(struct rtw89_dev *rtwdev); ++void rtw89_unload_firmware(struct rtw89_dev *rtwdev); ++int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev); ++void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb, ++ u8 type, u8 cat, u8 class, u8 func, ++ bool rack, bool dack, u32 len); ++int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, u8 macid); ++int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, ++ struct rtw89_sta *rtwsta); ++int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); ++void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h); ++void rtw89_fw_c2h_work(struct work_struct *work); ++int rtw89_fw_h2c_vif_maintain(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, ++ enum rtw89_upd_mode upd_mode); ++int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u8 dis_conn); ++int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp, ++ bool pause); ++int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u8 ac, u32 val); ++int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev); ++int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi); ++int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev); ++int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev); ++int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev); ++int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev); ++int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, ++ struct rtw89_fw_h2c_rf_reg_info *info, ++ u16 len, u8 page); ++int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, ++ u8 h2c_class, u8 h2c_func, u8 *buf, u16 len, ++ bool rack, bool dack); ++int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len); ++void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev); ++void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev); ++int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid); ++int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, bool valid, u8 macid, ++ struct ieee80211_ampdu_params *params); ++int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, ++ struct rtw89_lps_parm *lps_param); ++struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(u32 len); ++struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(u32 len); ++int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev, ++ struct rtw89_mac_h2c_info *h2c_info, ++ struct rtw89_mac_c2h_info *c2h_info); ++int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable); ++void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +new file mode 100644 +index 000000000000..0171a5a7b1de +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -0,0 +1,3838 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "cam.h" ++#include "debug.h" ++#include "fw.h" ++#include "mac.h" ++#include "ps.h" ++#include "reg.h" ++#include "util.h" ++ ++int rtw89_mac_check_mac_en(struct rtw89_dev *rtwdev, u8 mac_idx, ++ enum rtw89_mac_hwmod_sel sel) ++{ ++ u32 val, r_val; ++ ++ if (sel == RTW89_DMAC_SEL) { ++ r_val = rtw89_read32(rtwdev, R_AX_DMAC_FUNC_EN); ++ val = (B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN); ++ } else if (sel == RTW89_CMAC_SEL && mac_idx == 0) { ++ r_val = rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN); ++ val = B_AX_CMAC_EN; ++ } else if (sel == RTW89_CMAC_SEL && mac_idx == 1) { ++ r_val = rtw89_read32(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND); ++ val = B_AX_CMAC1_FEN; ++ } else { ++ return -EINVAL; ++ } ++ if (r_val == RTW89_R32_EA || r_val == RTW89_R32_DEAD || ++ (val & r_val) != val) ++ return -EFAULT; ++ ++ return 0; ++} ++ ++int rtw89_mac_write_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 val) ++{ ++ u8 lte_ctrl; ++ int ret; ++ ++ ret = read_poll_timeout(rtw89_read8, lte_ctrl, (lte_ctrl & BIT(5)) != 0, ++ 50, 50000, false, rtwdev, R_AX_LTE_CTRL + 3); ++ if (ret) ++ rtw89_err(rtwdev, "[ERR]lte not ready(W)\n"); ++ ++ rtw89_write32(rtwdev, R_AX_LTE_WDATA, val); ++ rtw89_write32(rtwdev, R_AX_LTE_CTRL, 0xC00F0000 | offset); ++ ++ return ret; ++} ++ ++int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val) ++{ ++ u8 lte_ctrl; ++ int ret; ++ ++ ret = read_poll_timeout(rtw89_read8, lte_ctrl, (lte_ctrl & BIT(5)) != 0, ++ 50, 50000, false, rtwdev, R_AX_LTE_CTRL + 3); ++ if (ret) ++ rtw89_err(rtwdev, "[ERR]lte not ready(W)\n"); ++ ++ rtw89_write32(rtwdev, R_AX_LTE_CTRL, 0x800F0000 | offset); ++ *val = rtw89_read32(rtwdev, R_AX_LTE_RDATA); ++ ++ return ret; ++} ++ ++static ++int dle_dfi_ctrl(struct rtw89_dev *rtwdev, struct rtw89_mac_dle_dfi_ctrl *ctrl) ++{ ++ u32 ctrl_reg, data_reg, ctrl_data; ++ u32 val; ++ int ret; ++ ++ switch (ctrl->type) { ++ case DLE_CTRL_TYPE_WDE: ++ ctrl_reg = R_AX_WDE_DBG_FUN_INTF_CTL; ++ data_reg = R_AX_WDE_DBG_FUN_INTF_DATA; ++ ctrl_data = FIELD_PREP(B_AX_WDE_DFI_TRGSEL_MASK, ctrl->target) | ++ FIELD_PREP(B_AX_WDE_DFI_ADDR_MASK, ctrl->addr) | ++ B_AX_WDE_DFI_ACTIVE; ++ break; ++ case DLE_CTRL_TYPE_PLE: ++ ctrl_reg = R_AX_PLE_DBG_FUN_INTF_CTL; ++ data_reg = R_AX_PLE_DBG_FUN_INTF_DATA; ++ ctrl_data = FIELD_PREP(B_AX_PLE_DFI_TRGSEL_MASK, ctrl->target) | ++ FIELD_PREP(B_AX_PLE_DFI_ADDR_MASK, ctrl->addr) | ++ B_AX_PLE_DFI_ACTIVE; ++ break; ++ default: ++ rtw89_warn(rtwdev, "[ERR] dfi ctrl type %d\n", ctrl->type); ++ return -EINVAL; ++ } ++ ++ rtw89_write32(rtwdev, ctrl_reg, ctrl_data); ++ ++ ret = read_poll_timeout_atomic(rtw89_read32, val, !(val & B_AX_WDE_DFI_ACTIVE), ++ 1, 1000, false, rtwdev, ctrl_reg); ++ if (ret) { ++ rtw89_warn(rtwdev, "[ERR] dle dfi ctrl 0x%X set 0x%X timeout\n", ++ ctrl_reg, ctrl_data); ++ return ret; ++ } ++ ++ ctrl->out_data = rtw89_read32(rtwdev, data_reg); ++ return 0; ++} ++ ++static int dle_dfi_quota(struct rtw89_dev *rtwdev, ++ struct rtw89_mac_dle_dfi_quota *quota) ++{ ++ struct rtw89_mac_dle_dfi_ctrl ctrl; ++ int ret; ++ ++ ctrl.type = quota->dle_type; ++ ctrl.target = DLE_DFI_TYPE_QUOTA; ++ ctrl.addr = quota->qtaid; ++ ret = dle_dfi_ctrl(rtwdev, &ctrl); ++ if (ret) { ++ rtw89_warn(rtwdev, "[ERR]dle_dfi_ctrl %d\n", ret); ++ return ret; ++ } ++ ++ quota->rsv_pgnum = FIELD_GET(B_AX_DLE_RSV_PGNUM, ctrl.out_data); ++ quota->use_pgnum = FIELD_GET(B_AX_DLE_USE_PGNUM, ctrl.out_data); ++ return 0; ++} ++ ++static int dle_dfi_qempty(struct rtw89_dev *rtwdev, ++ struct rtw89_mac_dle_dfi_qempty *qempty) ++{ ++ struct rtw89_mac_dle_dfi_ctrl ctrl; ++ u32 ret; ++ ++ ctrl.type = qempty->dle_type; ++ ctrl.target = DLE_DFI_TYPE_QEMPTY; ++ ctrl.addr = qempty->grpsel; ++ ret = dle_dfi_ctrl(rtwdev, &ctrl); ++ if (ret) { ++ rtw89_warn(rtwdev, "[ERR]dle_dfi_ctrl %d\n", ret); ++ return ret; ++ } ++ ++ qempty->qempty = FIELD_GET(B_AX_DLE_QEMPTY_GRP, ctrl.out_data); ++ return 0; ++} ++ ++static void dump_err_status_dispatcher(struct rtw89_dev *rtwdev) ++{ ++ rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ALWAYS_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ALWAYS_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); ++ rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ALWAYS_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ALWAYS_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); ++ rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ALWAYS_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ALWAYS_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR)); ++} ++ ++static void rtw89_mac_dump_qta_lost(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_mac_dle_dfi_qempty qempty; ++ struct rtw89_mac_dle_dfi_quota quota; ++ struct rtw89_mac_dle_dfi_ctrl ctrl; ++ u32 val, not_empty, i; ++ int ret; ++ ++ qempty.dle_type = DLE_CTRL_TYPE_PLE; ++ qempty.grpsel = 0; ++ ret = dle_dfi_qempty(rtwdev, &qempty); ++ if (ret) ++ rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__); ++ else ++ rtw89_info(rtwdev, "DLE group0 empty: 0x%x\n", qempty.qempty); ++ ++ for (not_empty = ~qempty.qempty, i = 0; not_empty != 0; not_empty >>= 1, i++) { ++ if (!(not_empty & BIT(0))) ++ continue; ++ ctrl.type = DLE_CTRL_TYPE_PLE; ++ ctrl.target = DLE_DFI_TYPE_QLNKTBL; ++ ctrl.addr = (QLNKTBL_ADDR_INFO_SEL_0 ? QLNKTBL_ADDR_INFO_SEL : 0) | ++ FIELD_PREP(QLNKTBL_ADDR_TBL_IDX_MASK, i); ++ ret = dle_dfi_ctrl(rtwdev, &ctrl); ++ if (ret) ++ rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__); ++ else ++ rtw89_info(rtwdev, "qidx%d pktcnt = %ld\n", i, ++ FIELD_GET(QLNKTBL_DATA_SEL1_PKT_CNT_MASK, ++ ctrl.out_data)); ++ } ++ ++ quota.dle_type = DLE_CTRL_TYPE_PLE; ++ quota.qtaid = 6; ++ ret = dle_dfi_quota(rtwdev, "a); ++ if (ret) ++ rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__); ++ else ++ rtw89_info(rtwdev, "quota6 rsv/use: 0x%x/0x%x\n", ++ quota.rsv_pgnum, quota.use_pgnum); ++ ++ val = rtw89_read32(rtwdev, R_AX_PLE_QTA6_CFG); ++ rtw89_info(rtwdev, "[PLE][CMAC0_RX]min_pgnum=0x%lx\n", ++ FIELD_GET(B_AX_PLE_Q6_MIN_SIZE_MASK, val)); ++ rtw89_info(rtwdev, "[PLE][CMAC0_RX]max_pgnum=0x%lx\n", ++ FIELD_GET(B_AX_PLE_Q6_MAX_SIZE_MASK, val)); ++ ++ dump_err_status_dispatcher(rtwdev); ++} ++ ++static void rtw89_mac_dump_l0_to_l1(struct rtw89_dev *rtwdev, ++ enum mac_ax_err_info err) ++{ ++ u32 dbg, event; ++ ++ dbg = rtw89_read32(rtwdev, R_AX_SER_DBG_INFO); ++ event = FIELD_GET(B_AX_L0_TO_L1_EVENT_MASK, dbg); ++ ++ switch (event) { ++ case MAC_AX_L0_TO_L1_RX_QTA_LOST: ++ rtw89_info(rtwdev, "quota lost!\n"); ++ rtw89_mac_dump_qta_lost(rtwdev); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void rtw89_mac_dump_err_status(struct rtw89_dev *rtwdev, ++ enum mac_ax_err_info err) ++{ ++ u32 dmac_err, cmac_err; ++ ++ if (err != MAC_AX_ERR_L1_ERR_DMAC && ++ err != MAC_AX_ERR_L0_PROMOTE_TO_L1) ++ return; ++ ++ rtw89_info(rtwdev, "--->\nerr=0x%x\n", err); ++ rtw89_info(rtwdev, "R_AX_SER_DBG_INFO =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SER_DBG_INFO)); ++ ++ cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR); ++ rtw89_info(rtwdev, "R_AX_CMAC_ERR_ISR =0x%08x\n", cmac_err); ++ dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR); ++ rtw89_info(rtwdev, "R_AX_DMAC_ERR_ISR =0x%08x\n", dmac_err); ++ ++ if (dmac_err) { ++ rtw89_info(rtwdev, "R_AX_WDE_ERR_FLAG_CFG =0x%08x ", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG)); ++ rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_CFG =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG)); ++ } ++ ++ if (dmac_err & B_AX_WDRLS_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_WDRLS_ERR_IMR =0x%08x ", ++ rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_WDRLS_ERR_ISR =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR)); ++ } ++ ++ if (dmac_err & B_AX_WSEC_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_SEC_ERR_IMR_ISR =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_DEBUG)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D00 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D04 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D10 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D14 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D18 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D20 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D24 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D28 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D2C =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT)); ++ } ++ ++ if (dmac_err & B_AX_MPDU_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_MPDU_TX_ERR_IMR =0x%08x ", ++ rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_MPDU_TX_ERR_ISR =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR)); ++ rtw89_info(rtwdev, "R_AX_MPDU_RX_ERR_IMR =0x%08x ", ++ rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_MPDU_RX_ERR_ISR =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR)); ++ } ++ ++ if (dmac_err & B_AX_STA_SCHEDULER_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_IMR =0x%08x ", ++ rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_ISR= 0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR)); ++ } ++ ++ if (dmac_err & B_AX_WDE_DLE_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_WDE_ERR_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_WDE_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); ++ rtw89_info(rtwdev, "R_AX_PLE_ERR_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); ++ dump_err_status_dispatcher(rtwdev); ++ } ++ ++ if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); ++ rtw89_info(rtwdev, "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1)); ++ } ++ ++ if (dmac_err & B_AX_PLE_DLE_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_WDE_ERR_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_WDE_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); ++ rtw89_info(rtwdev, "R_AX_PLE_ERR_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); ++ rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_0=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0)); ++ rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1)); ++ rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_2=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2)); ++ rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS)); ++ rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_0=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0)); ++ rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1)); ++ rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_2=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2)); ++ rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS)); ++ rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_0=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0)); ++ rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1)); ++ rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_2=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2)); ++ dump_err_status_dispatcher(rtwdev); ++ } ++ ++ if (dmac_err & B_AX_PKTIN_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_PKTIN_ERR_IMR =0x%08x ", ++ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_PKTIN_ERR_ISR =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); ++ rtw89_info(rtwdev, "R_AX_PKTIN_ERR_IMR =0x%08x ", ++ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_PKTIN_ERR_ISR =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); ++ } ++ ++ if (dmac_err & B_AX_DISPATCH_ERR_FLAG) ++ dump_err_status_dispatcher(rtwdev); ++ ++ if (dmac_err & B_AX_DLE_CPUIO_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_CPUIO_ERR_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_CPUIO_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_CPUIO_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_CPUIO_ERR_ISR)); ++ } ++ ++ if (dmac_err & BIT(11)) { ++ rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); ++ } ++ ++ if (cmac_err & B_AX_SCHEDULE_TOP_ERR_IND) { ++ rtw89_info(rtwdev, "R_AX_SCHEDULE_ERR_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_SCHEDULE_ERR_ISR=0x%04x\n", ++ rtw89_read16(rtwdev, R_AX_SCHEDULE_ERR_ISR)); ++ } ++ ++ if (cmac_err & B_AX_PTCL_TOP_ERR_IND) { ++ rtw89_info(rtwdev, "R_AX_PTCL_IMR0=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_PTCL_IMR0)); ++ rtw89_info(rtwdev, "R_AX_PTCL_ISR0=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PTCL_ISR0)); ++ } ++ ++ if (cmac_err & B_AX_DMA_TOP_ERR_IND) { ++ rtw89_info(rtwdev, "R_AX_DLE_CTRL=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_DLE_CTRL)); ++ } ++ ++ if (cmac_err & B_AX_PHYINTF_ERR_IND) { ++ rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR)); ++ } ++ ++ if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) { ++ rtw89_info(rtwdev, "R_AX_TXPWR_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_TXPWR_IMR)); ++ rtw89_info(rtwdev, "R_AX_TXPWR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPWR_ISR)); ++ } ++ ++ if (cmac_err & B_AX_WMAC_RX_ERR_IND) { ++ rtw89_info(rtwdev, "R_AX_DBGSEL_TRXPTCL=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL)); ++ rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR)); ++ } ++ ++ if (cmac_err & B_AX_WMAC_TX_ERR_IND) { ++ rtw89_info(rtwdev, "R_AX_TMAC_ERR_IMR_ISR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR)); ++ rtw89_info(rtwdev, "R_AX_DBGSEL_TRXPTCL=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL)); ++ } ++ ++ rtwdev->hci.ops->dump_err_status(rtwdev); ++ ++ if (err == MAC_AX_ERR_L0_PROMOTE_TO_L1) ++ rtw89_mac_dump_l0_to_l1(rtwdev, err); ++ ++ rtw89_info(rtwdev, "<---\n"); ++} ++ ++u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev) ++{ ++ u32 err; ++ int ret; ++ ++ ret = read_poll_timeout(rtw89_read32, err, (err != 0), 1000, 100000, ++ false, rtwdev, R_AX_HALT_C2H_CTRL); ++ if (ret) { ++ rtw89_warn(rtwdev, "Polling FW err status fail\n"); ++ return ret; ++ } ++ ++ err = rtw89_read32(rtwdev, R_AX_HALT_C2H); ++ rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); ++ ++ rtw89_fw_st_dbg_dump(rtwdev); ++ rtw89_mac_dump_err_status(rtwdev, err); ++ ++ return err; ++} ++EXPORT_SYMBOL(rtw89_mac_get_err_status); ++ ++int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err) ++{ ++ u32 halt; ++ int ret = 0; ++ ++ if (err > MAC_AX_SET_ERR_MAX) { ++ rtw89_err(rtwdev, "Bad set-err-status value 0x%08x\n", err); ++ return -EINVAL; ++ } ++ ++ ret = read_poll_timeout(rtw89_read32, halt, (halt == 0x0), 1000, ++ 100000, false, rtwdev, R_AX_HALT_H2C_CTRL); ++ if (ret) { ++ rtw89_err(rtwdev, "FW doesn't receive previous msg\n"); ++ return -EFAULT; ++ } ++ ++ rtw89_write32(rtwdev, R_AX_HALT_H2C, err); ++ rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, B_AX_HALT_H2C_TRIGGER); ++ ++ return 0; ++} ++EXPORT_SYMBOL(rtw89_mac_set_err_status); ++ ++const struct rtw89_hfc_prec_cfg rtw_hfc_preccfg_pcie = { ++ 2, 40, 0, 0, 1, 0, 0, 0 ++}; ++ ++static int hfc_reset_param(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ struct rtw89_hfc_param_ini param_ini = {NULL}; ++ u8 qta_mode = rtwdev->mac.dle_info.qta_mode; ++ ++ switch (rtwdev->hci.type) { ++ case RTW89_HCI_TYPE_PCIE: ++ param_ini = rtwdev->chip->hfc_param_ini[qta_mode]; ++ param->en = 0; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ if (param_ini.pub_cfg) ++ param->pub_cfg = *param_ini.pub_cfg; ++ ++ if (param_ini.prec_cfg) { ++ param->prec_cfg = *param_ini.prec_cfg; ++ rtwdev->hal.sw_amsdu_max_size = ++ param->prec_cfg.wp_ch07_prec * HFC_PAGE_UNIT; ++ } ++ ++ if (param_ini.ch_cfg) ++ param->ch_cfg = param_ini.ch_cfg; ++ ++ memset(¶m->ch_info, 0, sizeof(param->ch_info)); ++ memset(¶m->pub_info, 0, sizeof(param->pub_info)); ++ param->mode = param_ini.mode; ++ ++ return 0; ++} ++ ++static int hfc_ch_cfg_chk(struct rtw89_dev *rtwdev, u8 ch) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ const struct rtw89_hfc_ch_cfg *ch_cfg = param->ch_cfg; ++ const struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; ++ const struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; ++ ++ if (ch >= RTW89_DMA_CH_NUM) ++ return -EINVAL; ++ ++ if ((ch_cfg[ch].min && ch_cfg[ch].min < prec_cfg->ch011_prec) || ++ ch_cfg[ch].max > pub_cfg->pub_max) ++ return -EINVAL; ++ if (ch_cfg[ch].grp >= grp_num) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int hfc_pub_info_chk(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ const struct rtw89_hfc_pub_cfg *cfg = ¶m->pub_cfg; ++ struct rtw89_hfc_pub_info *info = ¶m->pub_info; ++ ++ if (info->g0_used + info->g1_used + info->pub_aval != cfg->pub_max) { ++ if (rtwdev->chip->chip_id == RTL8852A) ++ return 0; ++ else ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++static int hfc_pub_cfg_chk(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ const struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; ++ ++ if (pub_cfg->grp0 + pub_cfg->grp1 != pub_cfg->pub_max) ++ return 0; ++ ++ return 0; ++} ++ ++static int hfc_ch_ctrl(struct rtw89_dev *rtwdev, u8 ch) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ const struct rtw89_hfc_ch_cfg *cfg = param->ch_cfg; ++ int ret = 0; ++ u32 val = 0; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ ret = hfc_ch_cfg_chk(rtwdev, ch); ++ if (ret) ++ return ret; ++ ++ if (ch > RTW89_DMA_B1HI) ++ return -EINVAL; ++ ++ val = u32_encode_bits(cfg[ch].min, B_AX_MIN_PG_MASK) | ++ u32_encode_bits(cfg[ch].max, B_AX_MAX_PG_MASK) | ++ (cfg[ch].grp ? B_AX_GRP : 0); ++ rtw89_write32(rtwdev, R_AX_ACH0_PAGE_CTRL + ch * 4, val); ++ ++ return 0; ++} ++ ++static int hfc_upd_ch_info(struct rtw89_dev *rtwdev, u8 ch) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ struct rtw89_hfc_ch_info *info = param->ch_info; ++ const struct rtw89_hfc_ch_cfg *cfg = param->ch_cfg; ++ u32 val; ++ u32 ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ if (ch > RTW89_DMA_H2C) ++ return -EINVAL; ++ ++ val = rtw89_read32(rtwdev, R_AX_ACH0_PAGE_INFO + ch * 4); ++ info[ch].aval = u32_get_bits(val, B_AX_AVAL_PG_MASK); ++ if (ch < RTW89_DMA_H2C) ++ info[ch].used = u32_get_bits(val, B_AX_USE_PG_MASK); ++ else ++ info[ch].used = cfg[ch].min - info[ch].aval; ++ ++ return 0; ++} ++ ++static int hfc_pub_ctrl(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_hfc_pub_cfg *cfg = &rtwdev->mac.hfc_param.pub_cfg; ++ u32 val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ ret = hfc_pub_cfg_chk(rtwdev); ++ if (ret) ++ return ret; ++ ++ val = u32_encode_bits(cfg->grp0, B_AX_PUBPG_G0_MASK) | ++ u32_encode_bits(cfg->grp1, B_AX_PUBPG_G1_MASK); ++ rtw89_write32(rtwdev, R_AX_PUB_PAGE_CTRL1, val); ++ ++ val = u32_encode_bits(cfg->wp_thrd, B_AX_WP_THRD_MASK); ++ rtw89_write32(rtwdev, R_AX_WP_PAGE_CTRL2, val); ++ ++ return 0; ++} ++ ++static int hfc_upd_mix_info(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; ++ struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; ++ struct rtw89_hfc_pub_info *info = ¶m->pub_info; ++ u32 val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ val = rtw89_read32(rtwdev, R_AX_PUB_PAGE_INFO1); ++ info->g0_used = u32_get_bits(val, B_AX_G0_USE_PG_MASK); ++ info->g1_used = u32_get_bits(val, B_AX_G1_USE_PG_MASK); ++ val = rtw89_read32(rtwdev, R_AX_PUB_PAGE_INFO3); ++ info->g0_aval = u32_get_bits(val, B_AX_G0_AVAL_PG_MASK); ++ info->g1_aval = u32_get_bits(val, B_AX_G1_AVAL_PG_MASK); ++ info->pub_aval = ++ u32_get_bits(rtw89_read32(rtwdev, R_AX_PUB_PAGE_INFO2), ++ B_AX_PUB_AVAL_PG_MASK); ++ info->wp_aval = ++ u32_get_bits(rtw89_read32(rtwdev, R_AX_WP_PAGE_INFO1), ++ B_AX_WP_AVAL_PG_MASK); ++ ++ val = rtw89_read32(rtwdev, R_AX_HCI_FC_CTRL); ++ param->en = val & B_AX_HCI_FC_EN ? 1 : 0; ++ param->h2c_en = val & B_AX_HCI_FC_CH12_EN ? 1 : 0; ++ param->mode = u32_get_bits(val, B_AX_HCI_FC_MODE_MASK); ++ prec_cfg->ch011_full_cond = ++ u32_get_bits(val, B_AX_HCI_FC_WD_FULL_COND_MASK); ++ prec_cfg->h2c_full_cond = ++ u32_get_bits(val, B_AX_HCI_FC_CH12_FULL_COND_MASK); ++ prec_cfg->wp_ch07_full_cond = ++ u32_get_bits(val, B_AX_HCI_FC_WP_CH07_FULL_COND_MASK); ++ prec_cfg->wp_ch811_full_cond = ++ u32_get_bits(val, B_AX_HCI_FC_WP_CH811_FULL_COND_MASK); ++ ++ val = rtw89_read32(rtwdev, R_AX_CH_PAGE_CTRL); ++ prec_cfg->ch011_prec = u32_get_bits(val, B_AX_PREC_PAGE_CH011_MASK); ++ prec_cfg->h2c_prec = u32_get_bits(val, B_AX_PREC_PAGE_CH12_MASK); ++ ++ val = rtw89_read32(rtwdev, R_AX_PUB_PAGE_CTRL2); ++ pub_cfg->pub_max = u32_get_bits(val, B_AX_PUBPG_ALL_MASK); ++ ++ val = rtw89_read32(rtwdev, R_AX_WP_PAGE_CTRL1); ++ prec_cfg->wp_ch07_prec = u32_get_bits(val, B_AX_PREC_PAGE_WP_CH07_MASK); ++ prec_cfg->wp_ch811_prec = u32_get_bits(val, B_AX_PREC_PAGE_WP_CH811_MASK); ++ ++ val = rtw89_read32(rtwdev, R_AX_WP_PAGE_CTRL2); ++ pub_cfg->wp_thrd = u32_get_bits(val, B_AX_WP_THRD_MASK); ++ ++ val = rtw89_read32(rtwdev, R_AX_PUB_PAGE_CTRL1); ++ pub_cfg->grp0 = u32_get_bits(val, B_AX_PUBPG_G0_MASK); ++ pub_cfg->grp1 = u32_get_bits(val, B_AX_PUBPG_G1_MASK); ++ ++ ret = hfc_pub_info_chk(rtwdev); ++ if (param->en && ret) ++ return ret; ++ ++ return 0; ++} ++ ++static void hfc_h2c_cfg(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ const struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; ++ u32 val; ++ ++ val = u32_encode_bits(prec_cfg->h2c_prec, B_AX_PREC_PAGE_CH12_MASK); ++ rtw89_write32(rtwdev, R_AX_CH_PAGE_CTRL, val); ++ ++ rtw89_write32_mask(rtwdev, R_AX_HCI_FC_CTRL, ++ B_AX_HCI_FC_CH12_FULL_COND_MASK, ++ prec_cfg->h2c_full_cond); ++} ++ ++static void hfc_mix_cfg(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ const struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; ++ const struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; ++ u32 val; ++ ++ val = u32_encode_bits(prec_cfg->ch011_prec, B_AX_PREC_PAGE_CH011_MASK) | ++ u32_encode_bits(prec_cfg->h2c_prec, B_AX_PREC_PAGE_CH12_MASK); ++ rtw89_write32(rtwdev, R_AX_CH_PAGE_CTRL, val); ++ ++ val = u32_encode_bits(pub_cfg->pub_max, B_AX_PUBPG_ALL_MASK); ++ rtw89_write32(rtwdev, R_AX_PUB_PAGE_CTRL2, val); ++ ++ val = u32_encode_bits(prec_cfg->wp_ch07_prec, ++ B_AX_PREC_PAGE_WP_CH07_MASK) | ++ u32_encode_bits(prec_cfg->wp_ch811_prec, ++ B_AX_PREC_PAGE_WP_CH811_MASK); ++ rtw89_write32(rtwdev, R_AX_WP_PAGE_CTRL1, val); ++ ++ val = u32_replace_bits(rtw89_read32(rtwdev, R_AX_HCI_FC_CTRL), ++ param->mode, B_AX_HCI_FC_MODE_MASK); ++ val = u32_replace_bits(val, prec_cfg->ch011_full_cond, ++ B_AX_HCI_FC_WD_FULL_COND_MASK); ++ val = u32_replace_bits(val, prec_cfg->h2c_full_cond, ++ B_AX_HCI_FC_CH12_FULL_COND_MASK); ++ val = u32_replace_bits(val, prec_cfg->wp_ch07_full_cond, ++ B_AX_HCI_FC_WP_CH07_FULL_COND_MASK); ++ val = u32_replace_bits(val, prec_cfg->wp_ch811_full_cond, ++ B_AX_HCI_FC_WP_CH811_FULL_COND_MASK); ++ rtw89_write32(rtwdev, R_AX_HCI_FC_CTRL, val); ++} ++ ++static void hfc_func_en(struct rtw89_dev *rtwdev, bool en, bool h2c_en) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ u32 val; ++ ++ val = rtw89_read32(rtwdev, R_AX_HCI_FC_CTRL); ++ param->en = en; ++ param->h2c_en = h2c_en; ++ val = en ? (val | B_AX_HCI_FC_EN) : (val & ~B_AX_HCI_FC_EN); ++ val = h2c_en ? (val | B_AX_HCI_FC_CH12_EN) : ++ (val & ~B_AX_HCI_FC_CH12_EN); ++ rtw89_write32(rtwdev, R_AX_HCI_FC_CTRL, val); ++} ++ ++static int hfc_init(struct rtw89_dev *rtwdev, bool reset, bool en, bool h2c_en) ++{ ++ u8 ch; ++ u32 ret = 0; ++ ++ if (reset) ++ ret = hfc_reset_param(rtwdev); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ hfc_func_en(rtwdev, false, false); ++ ++ if (!en && h2c_en) { ++ hfc_h2c_cfg(rtwdev); ++ hfc_func_en(rtwdev, en, h2c_en); ++ return ret; ++ } ++ ++ for (ch = RTW89_DMA_ACH0; ch < RTW89_DMA_H2C; ch++) { ++ ret = hfc_ch_ctrl(rtwdev, ch); ++ if (ret) ++ return ret; ++ } ++ ++ ret = hfc_pub_ctrl(rtwdev); ++ if (ret) ++ return ret; ++ ++ hfc_mix_cfg(rtwdev); ++ if (en || h2c_en) { ++ hfc_func_en(rtwdev, en, h2c_en); ++ udelay(10); ++ } ++ for (ch = RTW89_DMA_ACH0; ch < RTW89_DMA_H2C; ch++) { ++ ret = hfc_upd_ch_info(rtwdev, ch); ++ if (ret) ++ return ret; ++ } ++ ret = hfc_upd_mix_info(rtwdev); ++ ++ return ret; ++} ++ ++#define PWR_POLL_CNT 2000 ++static int pwr_cmd_poll(struct rtw89_dev *rtwdev, ++ const struct rtw89_pwr_cfg *cfg) ++{ ++ u8 val = 0; ++ int ret; ++ u32 addr = cfg->base == PWR_INTF_MSK_SDIO ? ++ cfg->addr | SDIO_LOCAL_BASE_ADDR : cfg->addr; ++ ++ ret = read_poll_timeout(rtw89_read8, val, !((val ^ cfg->val) & cfg->msk), ++ 1000, 1000 * PWR_POLL_CNT, false, rtwdev, addr); ++ ++ if (!ret) ++ return 0; ++ ++ rtw89_warn(rtwdev, "[ERR] Polling timeout\n"); ++ rtw89_warn(rtwdev, "[ERR] addr: %X, %X\n", addr, cfg->addr); ++ rtw89_warn(rtwdev, "[ERR] val: %X, %X\n", val, cfg->val); ++ ++ return -EBUSY; ++} ++ ++static int rtw89_mac_sub_pwr_seq(struct rtw89_dev *rtwdev, u8 cv_msk, ++ u8 intf_msk, const struct rtw89_pwr_cfg *cfg) ++{ ++ const struct rtw89_pwr_cfg *cur_cfg; ++ u32 addr; ++ u8 val; ++ ++ for (cur_cfg = cfg; cur_cfg->cmd != PWR_CMD_END; cur_cfg++) { ++ if (!(cur_cfg->intf_msk & intf_msk) || ++ !(cur_cfg->cv_msk & cv_msk)) ++ continue; ++ ++ switch (cur_cfg->cmd) { ++ case PWR_CMD_WRITE: ++ addr = cur_cfg->addr; ++ ++ if (cur_cfg->base == PWR_BASE_SDIO) ++ addr |= SDIO_LOCAL_BASE_ADDR; ++ ++ val = rtw89_read8(rtwdev, addr); ++ val &= ~(cur_cfg->msk); ++ val |= (cur_cfg->val & cur_cfg->msk); ++ ++ rtw89_write8(rtwdev, addr, val); ++ break; ++ case PWR_CMD_POLL: ++ if (pwr_cmd_poll(rtwdev, cur_cfg)) ++ return -EBUSY; ++ break; ++ case PWR_CMD_DELAY: ++ if (cur_cfg->val == PWR_DELAY_US) ++ udelay(cur_cfg->addr); ++ else ++ fsleep(cur_cfg->addr * 1000); ++ break; ++ default: ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ ++static int rtw89_mac_pwr_seq(struct rtw89_dev *rtwdev, ++ const struct rtw89_pwr_cfg * const *cfg_seq) ++{ ++ int ret; ++ ++ for (; *cfg_seq; cfg_seq++) { ++ ret = rtw89_mac_sub_pwr_seq(rtwdev, BIT(rtwdev->hal.cv), ++ PWR_INTF_MSK_PCIE, *cfg_seq); ++ if (ret) ++ return -EBUSY; ++ } ++ ++ return 0; ++} ++ ++static enum rtw89_rpwm_req_pwr_state ++rtw89_mac_get_req_pwr_state(struct rtw89_dev *rtwdev) ++{ ++ enum rtw89_rpwm_req_pwr_state state; ++ ++ switch (rtwdev->ps_mode) { ++ case RTW89_PS_MODE_RFOFF: ++ state = RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFOFF; ++ break; ++ case RTW89_PS_MODE_CLK_GATED: ++ state = RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED; ++ break; ++ case RTW89_PS_MODE_PWR_GATED: ++ state = RTW89_MAC_RPWM_REQ_PWR_STATE_PWR_GATED; ++ break; ++ default: ++ state = RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE; ++ break; ++ } ++ return state; ++} ++ ++static void rtw89_mac_send_rpwm(struct rtw89_dev *rtwdev, ++ enum rtw89_rpwm_req_pwr_state req_pwr_state) ++{ ++ u16 request; ++ ++ request = rtw89_read16(rtwdev, R_AX_RPWM); ++ request ^= request | PS_RPWM_TOGGLE; ++ ++ rtwdev->mac.rpwm_seq_num = (rtwdev->mac.rpwm_seq_num + 1) & ++ RPWM_SEQ_NUM_MAX; ++ request |= FIELD_PREP(PS_RPWM_SEQ_NUM, rtwdev->mac.rpwm_seq_num); ++ ++ request |= req_pwr_state; ++ ++ if (req_pwr_state < RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED) ++ request |= PS_RPWM_ACK; ++ ++ rtw89_write16(rtwdev, rtwdev->hci.rpwm_addr, request); ++} ++ ++static int rtw89_mac_check_cpwm_state(struct rtw89_dev *rtwdev, ++ enum rtw89_rpwm_req_pwr_state req_pwr_state) ++{ ++ bool request_deep_mode; ++ bool in_deep_mode; ++ u8 rpwm_req_num; ++ u8 cpwm_rsp_seq; ++ u8 cpwm_seq; ++ u8 cpwm_status; ++ ++ if (req_pwr_state >= RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED) ++ request_deep_mode = true; ++ else ++ request_deep_mode = false; ++ ++ if (rtw89_read32_mask(rtwdev, R_AX_LDM, B_AX_EN_32K)) ++ in_deep_mode = true; ++ else ++ in_deep_mode = false; ++ ++ if (request_deep_mode != in_deep_mode) ++ return -EPERM; ++ ++ if (request_deep_mode) ++ return 0; ++ ++ rpwm_req_num = rtwdev->mac.rpwm_seq_num; ++ cpwm_rsp_seq = rtw89_read16_mask(rtwdev, R_AX_CPWM, ++ PS_CPWM_RSP_SEQ_NUM); ++ ++ if (rpwm_req_num != cpwm_rsp_seq) ++ return -EPERM; ++ ++ rtwdev->mac.cpwm_seq_num = (rtwdev->mac.cpwm_seq_num + 1) & ++ CPWM_SEQ_NUM_MAX; ++ ++ cpwm_seq = rtw89_read16_mask(rtwdev, R_AX_CPWM, PS_CPWM_SEQ_NUM); ++ if (cpwm_seq != rtwdev->mac.cpwm_seq_num) ++ return -EPERM; ++ ++ cpwm_status = rtw89_read16_mask(rtwdev, R_AX_CPWM, PS_CPWM_STATE); ++ if (cpwm_status != req_pwr_state) ++ return -EPERM; ++ ++ return 0; ++} ++ ++void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter) ++{ ++ enum rtw89_rpwm_req_pwr_state state; ++ int ret; ++ ++ if (enter) ++ state = rtw89_mac_get_req_pwr_state(rtwdev); ++ else ++ state = RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE; ++ ++ rtw89_mac_send_rpwm(rtwdev, state); ++ ret = read_poll_timeout_atomic(rtw89_mac_check_cpwm_state, ret, !ret, ++ 1000, 15000, false, rtwdev, state); ++ if (ret) ++ rtw89_err(rtwdev, "firmware failed to ack for %s ps mode\n", ++ enter ? "entering" : "leaving"); ++} ++ ++static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on) ++{ ++#define PWR_ACT 1 ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ const struct rtw89_pwr_cfg * const *cfg_seq; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ int ret; ++ u8 val; ++ ++ if (on) ++ cfg_seq = chip->pwr_on_seq; ++ else ++ cfg_seq = chip->pwr_off_seq; ++ ++ if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) ++ __rtw89_leave_ps_mode(rtwdev); ++ ++ val = rtw89_read32_mask(rtwdev, R_AX_IC_PWR_STATE, B_AX_WLMAC_PWR_STE_MASK); ++ if (on && val == PWR_ACT) { ++ rtw89_err(rtwdev, "MAC has already powered on\n"); ++ return -EBUSY; ++ } ++ ++ ret = rtw89_mac_pwr_seq(rtwdev, cfg_seq); ++ if (ret) ++ return ret; ++ ++ if (on) { ++ set_bit(RTW89_FLAG_POWERON, rtwdev->flags); ++ rtw89_write8(rtwdev, R_AX_SCOREBOARD + 3, MAC_AX_NOTIFY_TP_MAJOR); ++ } else { ++ clear_bit(RTW89_FLAG_POWERON, rtwdev->flags); ++ clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); ++ rtw89_write8(rtwdev, R_AX_SCOREBOARD + 3, MAC_AX_NOTIFY_PWR_MAJOR); ++ hal->current_channel = 0; ++ } ++ ++ return 0; ++#undef PWR_ACT ++} ++ ++void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev) ++{ ++ rtw89_mac_power_switch(rtwdev, false); ++} ++ ++static int cmac_func_en(struct rtw89_dev *rtwdev, u8 mac_idx, bool en) ++{ ++ u32 func_en = 0; ++ u32 ck_en = 0; ++ u32 c1pc_en = 0; ++ u32 addrl_func_en[] = {R_AX_CMAC_FUNC_EN, R_AX_CMAC_FUNC_EN_C1}; ++ u32 addrl_ck_en[] = {R_AX_CK_EN, R_AX_CK_EN_C1}; ++ ++ func_en = B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN | ++ B_AX_PHYINTF_EN | B_AX_CMAC_DMA_EN | B_AX_PTCLTOP_EN | ++ B_AX_SCHEDULER_EN | B_AX_TMAC_EN | B_AX_RMAC_EN; ++ ck_en = B_AX_CMAC_CKEN | B_AX_PHYINTF_CKEN | B_AX_CMAC_DMA_CKEN | ++ B_AX_PTCLTOP_CKEN | B_AX_SCHEDULER_CKEN | B_AX_TMAC_CKEN | ++ B_AX_RMAC_CKEN; ++ c1pc_en = B_AX_R_SYM_WLCMAC1_PC_EN | ++ B_AX_R_SYM_WLCMAC1_P1_PC_EN | ++ B_AX_R_SYM_WLCMAC1_P2_PC_EN | ++ B_AX_R_SYM_WLCMAC1_P3_PC_EN | ++ B_AX_R_SYM_WLCMAC1_P4_PC_EN; ++ ++ if (en) { ++ if (mac_idx == RTW89_MAC_1) { ++ rtw89_write32_set(rtwdev, R_AX_AFE_CTRL1, c1pc_en); ++ rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, ++ B_AX_R_SYM_ISO_CMAC12PP); ++ rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, ++ B_AX_CMAC1_FEN); ++ } ++ rtw89_write32_set(rtwdev, addrl_ck_en[mac_idx], ck_en); ++ rtw89_write32_set(rtwdev, addrl_func_en[mac_idx], func_en); ++ } else { ++ rtw89_write32_clr(rtwdev, addrl_func_en[mac_idx], func_en); ++ rtw89_write32_clr(rtwdev, addrl_ck_en[mac_idx], ck_en); ++ if (mac_idx == RTW89_MAC_1) { ++ rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, ++ B_AX_CMAC1_FEN); ++ rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, ++ B_AX_R_SYM_ISO_CMAC12PP); ++ rtw89_write32_clr(rtwdev, R_AX_AFE_CTRL1, c1pc_en); ++ } ++ } ++ ++ return 0; ++} ++ ++static int dmac_func_en(struct rtw89_dev *rtwdev) ++{ ++ u32 val32; ++ u32 ret = 0; ++ ++ val32 = (B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MAC_SEC_EN | ++ B_AX_DISPATCHER_EN | B_AX_DLE_CPUIO_EN | B_AX_PKT_IN_EN | ++ B_AX_DMAC_TBL_EN | B_AX_PKT_BUF_EN | B_AX_STA_SCH_EN | ++ B_AX_TXPKT_CTRL_EN | B_AX_WD_RLS_EN | B_AX_MPDU_PROC_EN); ++ rtw89_write32(rtwdev, R_AX_DMAC_FUNC_EN, val32); ++ ++ val32 = (B_AX_MAC_SEC_CLK_EN | B_AX_DISPATCHER_CLK_EN | ++ B_AX_DLE_CPUIO_CLK_EN | B_AX_PKT_IN_CLK_EN | ++ B_AX_STA_SCH_CLK_EN | B_AX_TXPKT_CTRL_CLK_EN | ++ B_AX_WD_RLS_CLK_EN); ++ rtw89_write32(rtwdev, R_AX_DMAC_CLK_EN, val32); ++ ++ return ret; ++} ++ ++static int chip_func_en(struct rtw89_dev *rtwdev) ++{ ++ rtw89_write32_set(rtwdev, R_AX_SPSLDO_ON_CTRL0, B_AX_OCP_L1_MASK); ++ ++ return 0; ++} ++ ++static int rtw89_mac_sys_init(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ ret = dmac_func_en(rtwdev); ++ if (ret) ++ return ret; ++ ++ ret = cmac_func_en(rtwdev, 0, true); ++ if (ret) ++ return ret; ++ ++ ret = chip_func_en(rtwdev); ++ if (ret) ++ return ret; ++ ++ return ret; ++} ++ ++/* PCIE 64 */ ++const struct rtw89_dle_size wde_size0 = { ++ RTW89_WDE_PG_64, 4095, 1, ++}; ++ ++/* DLFW */ ++const struct rtw89_dle_size wde_size4 = { ++ RTW89_WDE_PG_64, 0, 4096, ++}; ++ ++/* PCIE */ ++const struct rtw89_dle_size ple_size0 = { ++ RTW89_PLE_PG_128, 1520, 16, ++}; ++ ++/* DLFW */ ++const struct rtw89_dle_size ple_size4 = { ++ RTW89_PLE_PG_128, 64, 1472, ++}; ++ ++/* PCIE 64 */ ++const struct rtw89_wde_quota wde_qt0 = { ++ 3792, 196, 0, 107, ++}; ++ ++/* DLFW */ ++const struct rtw89_wde_quota wde_qt4 = { ++ 0, 0, 0, 0, ++}; ++ ++/* PCIE SCC */ ++const struct rtw89_ple_quota ple_qt4 = { ++ 264, 0, 16, 20, 26, 13, 356, 0, 32, 40, 8, ++}; ++ ++/* PCIE SCC */ ++const struct rtw89_ple_quota ple_qt5 = { ++ 264, 0, 32, 20, 64, 13, 1101, 0, 64, 128, 120, ++}; ++ ++/* DLFW */ ++const struct rtw89_ple_quota ple_qt13 = { ++ 0, 0, 16, 48, 0, 0, 0, 0, 0, 0, 0 ++}; ++ ++static const struct rtw89_dle_mem *get_dle_mem_cfg(struct rtw89_dev *rtwdev, ++ enum rtw89_qta_mode mode) ++{ ++ struct rtw89_mac_info *mac = &rtwdev->mac; ++ const struct rtw89_dle_mem *cfg; ++ ++ cfg = &rtwdev->chip->dle_mem[mode]; ++ if (!cfg) ++ return NULL; ++ ++ if (cfg->mode != mode) { ++ rtw89_warn(rtwdev, "qta mode unmatch!\n"); ++ return NULL; ++ } ++ ++ mac->dle_info.wde_pg_size = cfg->wde_size->pge_size; ++ mac->dle_info.ple_pg_size = cfg->ple_size->pge_size; ++ mac->dle_info.qta_mode = mode; ++ mac->dle_info.c0_rx_qta = cfg->ple_min_qt->cma0_dma; ++ mac->dle_info.c1_rx_qta = cfg->ple_min_qt->cma1_dma; ++ ++ return cfg; ++} ++ ++static inline u32 dle_used_size(const struct rtw89_dle_size *wde, ++ const struct rtw89_dle_size *ple) ++{ ++ return wde->pge_size * (wde->lnk_pge_num + wde->unlnk_pge_num) + ++ ple->pge_size * (ple->lnk_pge_num + ple->unlnk_pge_num); ++} ++ ++static void dle_func_en(struct rtw89_dev *rtwdev, bool enable) ++{ ++ if (enable) ++ rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN, ++ B_AX_DLE_WDE_EN | B_AX_DLE_PLE_EN); ++ else ++ rtw89_write32_clr(rtwdev, R_AX_DMAC_FUNC_EN, ++ B_AX_DLE_WDE_EN | B_AX_DLE_PLE_EN); ++} ++ ++static void dle_clk_en(struct rtw89_dev *rtwdev, bool enable) ++{ ++ if (enable) ++ rtw89_write32_set(rtwdev, R_AX_DMAC_CLK_EN, ++ B_AX_DLE_WDE_CLK_EN | B_AX_DLE_PLE_CLK_EN); ++ else ++ rtw89_write32_clr(rtwdev, R_AX_DMAC_CLK_EN, ++ B_AX_DLE_WDE_CLK_EN | B_AX_DLE_PLE_CLK_EN); ++} ++ ++static int dle_mix_cfg(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg) ++{ ++ const struct rtw89_dle_size *size_cfg; ++ u32 val; ++ u8 bound = 0; ++ ++ val = rtw89_read32(rtwdev, R_AX_WDE_PKTBUF_CFG); ++ size_cfg = cfg->wde_size; ++ ++ switch (size_cfg->pge_size) { ++ default: ++ case RTW89_WDE_PG_64: ++ val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_64, ++ B_AX_WDE_PAGE_SEL_MASK); ++ break; ++ case RTW89_WDE_PG_128: ++ val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_128, ++ B_AX_WDE_PAGE_SEL_MASK); ++ break; ++ case RTW89_WDE_PG_256: ++ rtw89_err(rtwdev, "[ERR]WDE DLE doesn't support 256 byte!\n"); ++ return -EINVAL; ++ } ++ ++ val = u32_replace_bits(val, bound, B_AX_WDE_START_BOUND_MASK); ++ val = u32_replace_bits(val, size_cfg->lnk_pge_num, ++ B_AX_WDE_FREE_PAGE_NUM_MASK); ++ rtw89_write32(rtwdev, R_AX_WDE_PKTBUF_CFG, val); ++ ++ val = rtw89_read32(rtwdev, R_AX_PLE_PKTBUF_CFG); ++ bound = (size_cfg->lnk_pge_num + size_cfg->unlnk_pge_num) ++ * size_cfg->pge_size / DLE_BOUND_UNIT; ++ size_cfg = cfg->ple_size; ++ ++ switch (size_cfg->pge_size) { ++ default: ++ case RTW89_PLE_PG_64: ++ rtw89_err(rtwdev, "[ERR]PLE DLE doesn't support 64 byte!\n"); ++ return -EINVAL; ++ case RTW89_PLE_PG_128: ++ val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_128, ++ B_AX_PLE_PAGE_SEL_MASK); ++ break; ++ case RTW89_PLE_PG_256: ++ val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_256, ++ B_AX_PLE_PAGE_SEL_MASK); ++ break; ++ } ++ ++ val = u32_replace_bits(val, bound, B_AX_PLE_START_BOUND_MASK); ++ val = u32_replace_bits(val, size_cfg->lnk_pge_num, ++ B_AX_PLE_FREE_PAGE_NUM_MASK); ++ rtw89_write32(rtwdev, R_AX_PLE_PKTBUF_CFG, val); ++ ++ return 0; ++} ++ ++#define INVALID_QT_WCPU U16_MAX ++#define SET_QUOTA_VAL(_min_x, _max_x, _module, _idx) \ ++ do { \ ++ val = ((_min_x) & \ ++ B_AX_ ## _module ## _MIN_SIZE_MASK) | \ ++ (((_max_x) << 16) & \ ++ B_AX_ ## _module ## _MAX_SIZE_MASK); \ ++ rtw89_write32(rtwdev, \ ++ R_AX_ ## _module ## _QTA ## _idx ## _CFG, \ ++ val); \ ++ } while (0) ++#define SET_QUOTA(_x, _module, _idx) \ ++ SET_QUOTA_VAL(min_cfg->_x, max_cfg->_x, _module, _idx) ++ ++static void wde_quota_cfg(struct rtw89_dev *rtwdev, ++ const struct rtw89_wde_quota *min_cfg, ++ const struct rtw89_wde_quota *max_cfg, ++ u16 ext_wde_min_qt_wcpu) ++{ ++ u16 min_qt_wcpu = ext_wde_min_qt_wcpu != INVALID_QT_WCPU ? ++ ext_wde_min_qt_wcpu : min_cfg->wcpu; ++ u32 val; ++ ++ SET_QUOTA(hif, WDE, 0); ++ SET_QUOTA_VAL(min_qt_wcpu, max_cfg->wcpu, WDE, 1); ++ SET_QUOTA(pkt_in, WDE, 3); ++ SET_QUOTA(cpu_io, WDE, 4); ++} ++ ++static void ple_quota_cfg(struct rtw89_dev *rtwdev, ++ const struct rtw89_ple_quota *min_cfg, ++ const struct rtw89_ple_quota *max_cfg) ++{ ++ u32 val; ++ ++ SET_QUOTA(cma0_tx, PLE, 0); ++ SET_QUOTA(cma1_tx, PLE, 1); ++ SET_QUOTA(c2h, PLE, 2); ++ SET_QUOTA(h2c, PLE, 3); ++ SET_QUOTA(wcpu, PLE, 4); ++ SET_QUOTA(mpdu_proc, PLE, 5); ++ SET_QUOTA(cma0_dma, PLE, 6); ++ SET_QUOTA(cma1_dma, PLE, 7); ++ SET_QUOTA(bb_rpt, PLE, 8); ++ SET_QUOTA(wd_rel, PLE, 9); ++ SET_QUOTA(cpu_io, PLE, 10); ++} ++ ++#undef SET_QUOTA ++ ++static void dle_quota_cfg(struct rtw89_dev *rtwdev, ++ const struct rtw89_dle_mem *cfg, ++ u16 ext_wde_min_qt_wcpu) ++{ ++ wde_quota_cfg(rtwdev, cfg->wde_min_qt, cfg->wde_max_qt, ext_wde_min_qt_wcpu); ++ ple_quota_cfg(rtwdev, cfg->ple_min_qt, cfg->ple_max_qt); ++} ++ ++static int dle_init(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode, ++ enum rtw89_qta_mode ext_mode) ++{ ++ const struct rtw89_dle_mem *cfg, *ext_cfg; ++ u16 ext_wde_min_qt_wcpu = INVALID_QT_WCPU; ++ int ret = 0; ++ u32 ini; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ cfg = get_dle_mem_cfg(rtwdev, mode); ++ if (!cfg) { ++ rtw89_err(rtwdev, "[ERR]get_dle_mem_cfg\n"); ++ ret = -EINVAL; ++ goto error; ++ } ++ ++ if (mode == RTW89_QTA_DLFW) { ++ ext_cfg = get_dle_mem_cfg(rtwdev, ext_mode); ++ if (!ext_cfg) { ++ rtw89_err(rtwdev, "[ERR]get_dle_ext_mem_cfg %d\n", ++ ext_mode); ++ ret = -EINVAL; ++ goto error; ++ } ++ ext_wde_min_qt_wcpu = ext_cfg->wde_min_qt->wcpu; ++ } ++ ++ if (dle_used_size(cfg->wde_size, cfg->ple_size) != rtwdev->chip->fifo_size) { ++ rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n"); ++ ret = -EINVAL; ++ goto error; ++ } ++ ++ dle_func_en(rtwdev, false); ++ dle_clk_en(rtwdev, true); ++ ++ ret = dle_mix_cfg(rtwdev, cfg); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] dle mix cfg\n"); ++ goto error; ++ } ++ dle_quota_cfg(rtwdev, cfg, ext_wde_min_qt_wcpu); ++ ++ dle_func_en(rtwdev, true); ++ ++ ret = read_poll_timeout(rtw89_read32, ini, ++ (ini & WDE_MGN_INI_RDY) == WDE_MGN_INI_RDY, 1, ++ 2000, false, rtwdev, R_AX_WDE_INI_STATUS); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]WDE cfg ready\n"); ++ return ret; ++ } ++ ++ ret = read_poll_timeout(rtw89_read32, ini, ++ (ini & WDE_MGN_INI_RDY) == WDE_MGN_INI_RDY, 1, ++ 2000, false, rtwdev, R_AX_PLE_INI_STATUS); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]PLE cfg ready\n"); ++ return ret; ++ } ++ ++ return 0; ++error: ++ dle_func_en(rtwdev, false); ++ rtw89_err(rtwdev, "[ERR]trxcfg wde 0x8900 = %x\n", ++ rtw89_read32(rtwdev, R_AX_WDE_INI_STATUS)); ++ rtw89_err(rtwdev, "[ERR]trxcfg ple 0x8D00 = %x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_INI_STATUS)); ++ ++ return ret; ++} ++ ++static bool dle_is_txq_empty(struct rtw89_dev *rtwdev) ++{ ++ u32 msk32; ++ u32 val32; ++ ++ msk32 = B_AX_WDE_EMPTY_QUE_CMAC0_ALL_AC | B_AX_WDE_EMPTY_QUE_CMAC0_MBH | ++ B_AX_WDE_EMPTY_QUE_CMAC1_MBH | B_AX_WDE_EMPTY_QUE_CMAC0_WMM0 | ++ B_AX_WDE_EMPTY_QUE_CMAC0_WMM1 | B_AX_WDE_EMPTY_QUE_OTHERS | ++ B_AX_PLE_EMPTY_QUE_DMAC_MPDU_TX | B_AX_PLE_EMPTY_QTA_DMAC_H2C | ++ B_AX_PLE_EMPTY_QUE_DMAC_SEC_TX | B_AX_WDE_EMPTY_QUE_DMAC_PKTIN | ++ B_AX_WDE_EMPTY_QTA_DMAC_HIF | B_AX_WDE_EMPTY_QTA_DMAC_WLAN_CPU | ++ B_AX_WDE_EMPTY_QTA_DMAC_PKTIN | B_AX_WDE_EMPTY_QTA_DMAC_CPUIO | ++ B_AX_PLE_EMPTY_QTA_DMAC_B0_TXPL | ++ B_AX_PLE_EMPTY_QTA_DMAC_B1_TXPL | ++ B_AX_PLE_EMPTY_QTA_DMAC_MPDU_TX | ++ B_AX_PLE_EMPTY_QTA_DMAC_CPUIO | ++ B_AX_WDE_EMPTY_QTA_DMAC_DATA_CPU | ++ B_AX_PLE_EMPTY_QTA_DMAC_WLAN_CPU; ++ val32 = rtw89_read32(rtwdev, R_AX_DLE_EMPTY0); ++ ++ if ((val32 & msk32) == msk32) ++ return true; ++ ++ return false; ++} ++ ++static int sta_sch_init(struct rtw89_dev *rtwdev) ++{ ++ u32 p_val; ++ u8 val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ val = rtw89_read8(rtwdev, R_AX_SS_CTRL); ++ val |= B_AX_SS_EN; ++ rtw89_write8(rtwdev, R_AX_SS_CTRL, val); ++ ++ ret = read_poll_timeout(rtw89_read32, p_val, p_val & B_AX_SS_INIT_DONE_1, ++ 1, TRXCFG_WAIT_CNT, false, rtwdev, R_AX_SS_CTRL); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]STA scheduler init\n"); ++ return ret; ++ } ++ ++ rtw89_write32_set(rtwdev, R_AX_SS_CTRL, B_AX_SS_WARM_INIT_FLG); ++ ++ return 0; ++} ++ ++static int mpdu_proc_init(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ rtw89_write32(rtwdev, R_AX_ACTION_FWD0, TRXCFG_MPDU_PROC_ACT_FRWD); ++ rtw89_write32(rtwdev, R_AX_TF_FWD, TRXCFG_MPDU_PROC_TF_FRWD); ++ rtw89_write32_set(rtwdev, R_AX_MPDU_PROC, ++ B_AX_APPEND_FCS | B_AX_A_ICV_ERR); ++ rtw89_write32(rtwdev, R_AX_CUT_AMSDU_CTRL, TRXCFG_MPDU_PROC_CUT_CTRL); ++ ++ return 0; ++} ++ ++static int sec_eng_init(struct rtw89_dev *rtwdev) ++{ ++ u32 val = 0; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ val = rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL); ++ /* init clock */ ++ val |= (B_AX_CLK_EN_CGCMP | B_AX_CLK_EN_WAPI | B_AX_CLK_EN_WEP_TKIP); ++ /* init TX encryption */ ++ val |= (B_AX_SEC_TX_ENC | B_AX_SEC_RX_DEC); ++ val |= (B_AX_MC_DEC | B_AX_BC_DEC); ++ val &= ~B_AX_TX_PARTIAL_MODE; ++ rtw89_write32(rtwdev, R_AX_SEC_ENG_CTRL, val); ++ ++ /* init MIC ICV append */ ++ val = rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC); ++ val |= (B_AX_APPEND_ICV | B_AX_APPEND_MIC); ++ ++ /* option init */ ++ rtw89_write32(rtwdev, R_AX_SEC_MPDU_PROC, val); ++ ++ return 0; ++} ++ ++static int dmac_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ int ret; ++ ++ ret = dle_init(rtwdev, rtwdev->mac.qta_mode, RTW89_QTA_INVALID); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]DLE init %d\n", ret); ++ return ret; ++ } ++ ++ ret = hfc_init(rtwdev, true, true, true); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]HCI FC init %d\n", ret); ++ return ret; ++ } ++ ++ ret = sta_sch_init(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]STA SCH init %d\n", ret); ++ return ret; ++ } ++ ++ ret = mpdu_proc_init(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]MPDU Proc init %d\n", ret); ++ return ret; ++ } ++ ++ ret = sec_eng_init(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]Security Engine init %d\n", ret); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++static int addr_cam_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 val, reg; ++ u16 p_val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_ADDR_CAM_CTRL, mac_idx); ++ ++ val = rtw89_read32(rtwdev, reg); ++ val |= u32_encode_bits(0x7f, B_AX_ADDR_CAM_RANGE_MASK) | ++ B_AX_ADDR_CAM_CLR | B_AX_ADDR_CAM_EN; ++ rtw89_write32(rtwdev, reg, val); ++ ++ ret = read_poll_timeout(rtw89_read16, p_val, !(p_val & B_AX_ADDR_CAM_CLR), ++ 1, TRXCFG_WAIT_CNT, false, rtwdev, B_AX_ADDR_CAM_CLR); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]ADDR_CAM reset\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int scheduler_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 ret; ++ u32 reg; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_PREBKF_CFG_0, mac_idx); ++ rtw89_write32_mask(rtwdev, reg, B_AX_PREBKF_TIME_MASK, SCH_PREBKF_24US); ++ ++ return 0; ++} ++ ++static int rtw89_mac_typ_fltr_opt(struct rtw89_dev *rtwdev, ++ enum rtw89_machdr_frame_type type, ++ enum rtw89_mac_fwd_target fwd_target, ++ u8 mac_idx) ++{ ++ u32 reg; ++ u32 val; ++ ++ switch (fwd_target) { ++ case RTW89_FWD_DONT_CARE: ++ val = RX_FLTR_FRAME_DROP; ++ break; ++ case RTW89_FWD_TO_HOST: ++ val = RX_FLTR_FRAME_TO_HOST; ++ break; ++ case RTW89_FWD_TO_WLAN_CPU: ++ val = RX_FLTR_FRAME_TO_WLCPU; ++ break; ++ default: ++ rtw89_err(rtwdev, "[ERR]set rx filter fwd target err\n"); ++ return -EINVAL; ++ } ++ ++ switch (type) { ++ case RTW89_MGNT: ++ reg = rtw89_mac_reg_by_idx(R_AX_MGNT_FLTR, mac_idx); ++ break; ++ case RTW89_CTRL: ++ reg = rtw89_mac_reg_by_idx(R_AX_CTRL_FLTR, mac_idx); ++ break; ++ case RTW89_DATA: ++ reg = rtw89_mac_reg_by_idx(R_AX_DATA_FLTR, mac_idx); ++ break; ++ default: ++ rtw89_err(rtwdev, "[ERR]set rx filter type err\n"); ++ return -EINVAL; ++ } ++ rtw89_write32(rtwdev, reg, val); ++ ++ return 0; ++} ++ ++static int rx_fltr_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ int ret, i; ++ u32 mac_ftlr, plcp_ftlr; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ for (i = RTW89_MGNT; i <= RTW89_DATA; i++) { ++ ret = rtw89_mac_typ_fltr_opt(rtwdev, i, RTW89_FWD_TO_HOST, ++ mac_idx); ++ if (ret) ++ return ret; ++ } ++ mac_ftlr = rtwdev->hal.rx_fltr; ++ plcp_ftlr = B_AX_CCK_CRC_CHK | B_AX_CCK_SIG_CHK | ++ B_AX_LSIG_PARITY_CHK_EN | B_AX_SIGA_CRC_CHK | ++ B_AX_VHT_SU_SIGB_CRC_CHK | B_AX_VHT_MU_SIGB_CRC_CHK | ++ B_AX_HE_SIGB_CRC_CHK; ++ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, mac_idx), ++ mac_ftlr); ++ rtw89_write16(rtwdev, rtw89_mac_reg_by_idx(R_AX_PLCP_HDR_FLTR, mac_idx), ++ plcp_ftlr); ++ ++ return 0; ++} ++ ++static void _patch_dis_resp_chk(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 reg, val32; ++ u32 b_rsp_chk_nav, b_rsp_chk_cca; ++ ++ b_rsp_chk_nav = B_AX_RSP_CHK_TXNAV | B_AX_RSP_CHK_INTRA_NAV | ++ B_AX_RSP_CHK_BASIC_NAV; ++ b_rsp_chk_cca = B_AX_RSP_CHK_SEC_CCA_80 | B_AX_RSP_CHK_SEC_CCA_40 | ++ B_AX_RSP_CHK_SEC_CCA_20 | B_AX_RSP_CHK_BTCCA | ++ B_AX_RSP_CHK_EDCCA | B_AX_RSP_CHK_CCA; ++ ++ switch (rtwdev->chip->chip_id) { ++ case RTL8852A: ++ case RTL8852B: ++ reg = rtw89_mac_reg_by_idx(R_AX_RSP_CHK_SIG, mac_idx); ++ val32 = rtw89_read32(rtwdev, reg) & ~b_rsp_chk_nav; ++ rtw89_write32(rtwdev, reg, val32); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_0, mac_idx); ++ val32 = rtw89_read32(rtwdev, reg) & ~b_rsp_chk_cca; ++ rtw89_write32(rtwdev, reg, val32); ++ break; ++ default: ++ reg = rtw89_mac_reg_by_idx(R_AX_RSP_CHK_SIG, mac_idx); ++ val32 = rtw89_read32(rtwdev, reg) | b_rsp_chk_nav; ++ rtw89_write32(rtwdev, reg, val32); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_0, mac_idx); ++ val32 = rtw89_read32(rtwdev, reg) | b_rsp_chk_cca; ++ rtw89_write32(rtwdev, reg, val32); ++ break; ++ } ++} ++ ++static int cca_ctrl_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 val, reg; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_CCA_CONTROL, mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val |= (B_AX_TB_CHK_BASIC_NAV | B_AX_TB_CHK_BTCCA | ++ B_AX_TB_CHK_EDCCA | B_AX_TB_CHK_CCA_P20 | ++ B_AX_SIFS_CHK_BTCCA | B_AX_SIFS_CHK_CCA_P20 | ++ B_AX_CTN_CHK_INTRA_NAV | ++ B_AX_CTN_CHK_BASIC_NAV | B_AX_CTN_CHK_BTCCA | ++ B_AX_CTN_CHK_EDCCA | B_AX_CTN_CHK_CCA_S80 | ++ B_AX_CTN_CHK_CCA_S40 | B_AX_CTN_CHK_CCA_S20 | ++ B_AX_CTN_CHK_CCA_P20 | B_AX_SIFS_CHK_EDCCA); ++ val &= ~(B_AX_TB_CHK_TX_NAV | B_AX_TB_CHK_CCA_S80 | ++ B_AX_TB_CHK_CCA_S40 | B_AX_TB_CHK_CCA_S20 | ++ B_AX_SIFS_CHK_CCA_S80 | B_AX_SIFS_CHK_CCA_S40 | ++ B_AX_SIFS_CHK_CCA_S20 | B_AX_CTN_CHK_TXNAV); ++ ++ rtw89_write32(rtwdev, reg, val); ++ ++ _patch_dis_resp_chk(rtwdev, mac_idx); ++ ++ return 0; ++} ++ ++static int spatial_reuse_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 reg; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ reg = rtw89_mac_reg_by_idx(R_AX_RX_SR_CTRL, mac_idx); ++ rtw89_write8_clr(rtwdev, reg, B_AX_SR_EN); ++ ++ return 0; ++} ++ ++static int tmac_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 reg; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_MAC_LOOPBACK, mac_idx); ++ rtw89_write32_clr(rtwdev, reg, B_AX_MACLBK_EN); ++ ++ return 0; ++} ++ ++static int trxptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 reg, val, sifs; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_0, mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val &= ~B_AX_WMAC_SPEC_SIFS_CCK_MASK; ++ val |= FIELD_PREP(B_AX_WMAC_SPEC_SIFS_CCK_MASK, WMAC_SPEC_SIFS_CCK); ++ ++ switch (rtwdev->chip->chip_id) { ++ case RTL8852A: ++ sifs = WMAC_SPEC_SIFS_OFDM_52A; ++ break; ++ case RTL8852B: ++ sifs = WMAC_SPEC_SIFS_OFDM_52B; ++ break; ++ default: ++ sifs = WMAC_SPEC_SIFS_OFDM_52C; ++ break; ++ } ++ val &= ~B_AX_WMAC_SPEC_SIFS_OFDM_MASK; ++ val |= FIELD_PREP(B_AX_WMAC_SPEC_SIFS_OFDM_MASK, sifs); ++ rtw89_write32(rtwdev, reg, val); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_RXTRIG_TEST_USER_2, mac_idx); ++ rtw89_write32_set(rtwdev, reg, B_AX_RXTRIG_FCSCHK_EN); ++ ++ return 0; ++} ++ ++static int rmac_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++#define TRXCFG_RMAC_CCA_TO 32 ++#define TRXCFG_RMAC_DATA_TO 15 ++#define RX_MAX_LEN_UNIT 512 ++#define PLD_RLS_MAX_PG 127 ++ int ret; ++ u32 reg, rx_max_len, rx_qta; ++ u16 val; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_RESPBA_CAM_CTRL, mac_idx); ++ rtw89_write8_set(rtwdev, reg, B_AX_SSN_SEL); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_DLK_PROTECT_CTL, mac_idx); ++ val = rtw89_read16(rtwdev, reg); ++ val = u16_replace_bits(val, TRXCFG_RMAC_DATA_TO, ++ B_AX_RX_DLK_DATA_TIME_MASK); ++ val = u16_replace_bits(val, TRXCFG_RMAC_CCA_TO, ++ B_AX_RX_DLK_CCA_TIME_MASK); ++ rtw89_write16(rtwdev, reg, val); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_RCR, mac_idx); ++ rtw89_write8_mask(rtwdev, reg, B_AX_CH_EN_MASK, 0x1); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, mac_idx); ++ if (mac_idx == RTW89_MAC_0) ++ rx_qta = rtwdev->mac.dle_info.c0_rx_qta; ++ else ++ rx_qta = rtwdev->mac.dle_info.c1_rx_qta; ++ rx_qta = rx_qta > PLD_RLS_MAX_PG ? PLD_RLS_MAX_PG : rx_qta; ++ rx_max_len = (rx_qta - 1) * rtwdev->mac.dle_info.ple_pg_size / ++ RX_MAX_LEN_UNIT; ++ rx_max_len = rx_max_len > B_AX_RX_MPDU_MAX_LEN_SIZE ? ++ B_AX_RX_MPDU_MAX_LEN_SIZE : rx_max_len; ++ rtw89_write32_mask(rtwdev, reg, B_AX_RX_MPDU_MAX_LEN_MASK, rx_max_len); ++ ++ if (rtwdev->chip->chip_id == RTL8852A && ++ rtwdev->hal.cv == CHIP_CBV) { ++ rtw89_write16_mask(rtwdev, ++ rtw89_mac_reg_by_idx(R_AX_DLK_PROTECT_CTL, mac_idx), ++ B_AX_RX_DLK_CCA_TIME_MASK, 0); ++ rtw89_write16_set(rtwdev, rtw89_mac_reg_by_idx(R_AX_RCR, mac_idx), ++ BIT(12)); ++ } ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_PLCP_HDR_FLTR, mac_idx); ++ rtw89_write8_clr(rtwdev, reg, B_AX_VHT_SU_SIGB_CRC_CHK); ++ ++ return ret; ++} ++ ++static int cmac_com_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 val, reg; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE, mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val = u32_replace_bits(val, 0, B_AX_TXSC_20M_MASK); ++ val = u32_replace_bits(val, 0, B_AX_TXSC_40M_MASK); ++ val = u32_replace_bits(val, 0, B_AX_TXSC_80M_MASK); ++ rtw89_write32(rtwdev, reg, val); ++ ++ return 0; ++} ++ ++static bool is_qta_dbcc(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode) ++{ ++ const struct rtw89_dle_mem *cfg; ++ ++ cfg = get_dle_mem_cfg(rtwdev, mode); ++ if (!cfg) { ++ rtw89_err(rtwdev, "[ERR]get_dle_mem_cfg\n"); ++ return false; ++ } ++ ++ return (cfg->ple_min_qt->cma1_dma && cfg->ple_max_qt->cma1_dma); ++} ++ ++static int ptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 val, reg; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) { ++ reg = rtw89_mac_reg_by_idx(R_AX_SIFS_SETTING, mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val = u32_replace_bits(val, S_AX_CTS2S_TH_1K, ++ B_AX_HW_CTS2SELF_PKT_LEN_TH_MASK); ++ val |= B_AX_HW_CTS2SELF_EN; ++ rtw89_write32(rtwdev, reg, val); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_PTCL_FSM_MON, mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val = u32_replace_bits(val, S_AX_PTCL_TO_2MS, B_AX_PTCL_TX_ARB_TO_THR_MASK); ++ val &= ~B_AX_PTCL_TX_ARB_TO_MODE; ++ rtw89_write32(rtwdev, reg, val); ++ } ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_SIFS_SETTING, mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val = u32_replace_bits(val, S_AX_CTS2S_TH_SEC_256B, B_AX_HW_CTS2SELF_PKT_LEN_TH_TWW_MASK); ++ val |= B_AX_HW_CTS2SELF_EN; ++ rtw89_write32(rtwdev, reg, val); ++ ++ return 0; ++} ++ ++static int cmac_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ int ret; ++ ++ ret = scheduler_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d SCH init %d\n", mac_idx, ret); ++ return ret; ++ } ++ ++ ret = addr_cam_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d ADDR_CAM reset %d\n", mac_idx, ++ ret); ++ return ret; ++ } ++ ++ ret = rx_fltr_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d RX filter init %d\n", mac_idx, ++ ret); ++ return ret; ++ } ++ ++ ret = cca_ctrl_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d CCA CTRL init %d\n", mac_idx, ++ ret); ++ return ret; ++ } ++ ++ ret = spatial_reuse_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d Spatial Reuse init %d\n", ++ mac_idx, ret); ++ return ret; ++ } ++ ++ ret = tmac_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d TMAC init %d\n", mac_idx, ret); ++ return ret; ++ } ++ ++ ret = trxptcl_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d TRXPTCL init %d\n", mac_idx, ret); ++ return ret; ++ } ++ ++ ret = rmac_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d RMAC init %d\n", mac_idx, ret); ++ return ret; ++ } ++ ++ ret = cmac_com_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d Com init %d\n", mac_idx, ret); ++ return ret; ++ } ++ ++ ret = ptcl_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d PTCL init %d\n", mac_idx, ret); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++static int rtw89_mac_read_phycap(struct rtw89_dev *rtwdev, ++ struct rtw89_mac_c2h_info *c2h_info) ++{ ++ struct rtw89_mac_h2c_info h2c_info = {0}; ++ u32 ret; ++ ++ h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE; ++ h2c_info.content_len = 0; ++ ++ ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, c2h_info); ++ if (ret) ++ return ret; ++ ++ if (c2h_info->id != RTW89_FWCMD_C2HREG_FUNC_PHY_CAP) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_hal *hal = &rtwdev->hal; ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_mac_c2h_info c2h_info = {0}; ++ struct rtw89_c2h_phy_cap *cap = ++ (struct rtw89_c2h_phy_cap *)&c2h_info.c2hreg[0]; ++ u32 ret; ++ ++ ret = rtw89_mac_read_phycap(rtwdev, &c2h_info); ++ if (ret) ++ return ret; ++ ++ hal->tx_nss = cap->tx_nss ? ++ min_t(u8, cap->tx_nss, chip->tx_nss) : chip->tx_nss; ++ hal->rx_nss = cap->rx_nss ? ++ min_t(u8, cap->rx_nss, chip->rx_nss) : chip->rx_nss; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_FW, ++ "phycap hal/phy/chip: tx_nss=0x%x/0x%x/0x%x rx_nss=0x%x/0x%x/0x%x\n", ++ hal->tx_nss, cap->tx_nss, chip->tx_nss, ++ hal->rx_nss, cap->rx_nss, chip->rx_nss); ++ ++ return 0; ++} ++ ++static int rtw89_hw_sch_tx_en_h2c(struct rtw89_dev *rtwdev, u8 band, ++ u16 tx_en_u16, u16 mask_u16) ++{ ++ u32 ret; ++ struct rtw89_mac_c2h_info c2h_info = {0}; ++ struct rtw89_mac_h2c_info h2c_info = {0}; ++ struct rtw89_h2creg_sch_tx_en *h2creg = ++ (struct rtw89_h2creg_sch_tx_en *)h2c_info.h2creg; ++ ++ h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_SCH_TX_EN; ++ h2c_info.content_len = sizeof(*h2creg) - RTW89_H2CREG_HDR_LEN; ++ h2creg->tx_en = tx_en_u16; ++ h2creg->mask = mask_u16; ++ h2creg->band = band; ++ ++ ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info); ++ if (ret) ++ return ret; ++ ++ if (c2h_info.id != RTW89_FWCMD_C2HREG_FUNC_TX_PAUSE_RPT) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int rtw89_set_hw_sch_tx_en(struct rtw89_dev *rtwdev, u8 mac_idx, ++ u16 tx_en, u16 tx_en_mask) ++{ ++ u32 reg = rtw89_mac_reg_by_idx(R_AX_CTN_TXEN, mac_idx); ++ u16 val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) ++ return rtw89_hw_sch_tx_en_h2c(rtwdev, mac_idx, ++ tx_en, tx_en_mask); ++ ++ val = rtw89_read16(rtwdev, reg); ++ val = (val & ~tx_en_mask) | (tx_en & tx_en_mask); ++ rtw89_write16(rtwdev, reg, val); ++ ++ return 0; ++} ++ ++int rtw89_mac_stop_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, ++ u16 *tx_en, enum rtw89_sch_tx_sel sel) ++{ ++ int ret; ++ ++ *tx_en = rtw89_read16(rtwdev, ++ rtw89_mac_reg_by_idx(R_AX_CTN_TXEN, mac_idx)); ++ ++ switch (sel) { ++ case RTW89_SCH_TX_SEL_ALL: ++ ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, 0, 0xffff); ++ if (ret) ++ return ret; ++ break; ++ case RTW89_SCH_TX_SEL_HIQ: ++ ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, ++ 0, B_AX_CTN_TXEN_HGQ); ++ if (ret) ++ return ret; ++ break; ++ case RTW89_SCH_TX_SEL_MG0: ++ ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, ++ 0, B_AX_CTN_TXEN_MGQ); ++ if (ret) ++ return ret; ++ break; ++ case RTW89_SCH_TX_SEL_MACID: ++ ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, 0, 0xffff); ++ if (ret) ++ return ret; ++ break; ++ default: ++ return 0; ++ } ++ ++ return 0; ++} ++ ++int rtw89_mac_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u16 tx_en) ++{ ++ int ret; ++ ++ ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, tx_en, 0xffff); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static u16 rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, ++ bool wd) ++{ ++ u32 val, reg; ++ int ret; ++ ++ reg = wd ? R_AX_WD_BUF_REQ : R_AX_PL_BUF_REQ; ++ val = buf_len; ++ val |= B_AX_WD_BUF_REQ_EXEC; ++ rtw89_write32(rtwdev, reg, val); ++ ++ reg = wd ? R_AX_WD_BUF_STATUS : R_AX_PL_BUF_STATUS; ++ ++ ret = read_poll_timeout(rtw89_read32, val, val & B_AX_WD_BUF_STAT_DONE, ++ 1, 2000, false, rtwdev, reg); ++ if (ret) ++ return 0xffff; ++ ++ return FIELD_GET(B_AX_WD_BUF_STAT_PKTID_MASK, val); ++} ++ ++static int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev, ++ struct rtw89_cpuio_ctrl *ctrl_para, ++ bool wd) ++{ ++ u32 val, cmd_type, reg; ++ int ret; ++ ++ cmd_type = ctrl_para->cmd_type; ++ ++ reg = wd ? R_AX_WD_CPUQ_OP_2 : R_AX_PL_CPUQ_OP_2; ++ val = 0; ++ val = u32_replace_bits(val, ctrl_para->start_pktid, ++ B_AX_WD_CPUQ_OP_STRT_PKTID_MASK); ++ val = u32_replace_bits(val, ctrl_para->end_pktid, ++ B_AX_WD_CPUQ_OP_END_PKTID_MASK); ++ rtw89_write32(rtwdev, reg, val); ++ ++ reg = wd ? R_AX_WD_CPUQ_OP_1 : R_AX_PL_CPUQ_OP_1; ++ val = 0; ++ val = u32_replace_bits(val, ctrl_para->src_pid, ++ B_AX_CPUQ_OP_SRC_PID_MASK); ++ val = u32_replace_bits(val, ctrl_para->src_qid, ++ B_AX_CPUQ_OP_SRC_QID_MASK); ++ val = u32_replace_bits(val, ctrl_para->dst_pid, ++ B_AX_CPUQ_OP_DST_PID_MASK); ++ val = u32_replace_bits(val, ctrl_para->dst_qid, ++ B_AX_CPUQ_OP_DST_QID_MASK); ++ rtw89_write32(rtwdev, reg, val); ++ ++ reg = wd ? R_AX_WD_CPUQ_OP_0 : R_AX_PL_CPUQ_OP_0; ++ val = 0; ++ val = u32_replace_bits(val, cmd_type, ++ B_AX_CPUQ_OP_CMD_TYPE_MASK); ++ val = u32_replace_bits(val, ctrl_para->macid, ++ B_AX_CPUQ_OP_MACID_MASK); ++ val = u32_replace_bits(val, ctrl_para->pkt_num, ++ B_AX_CPUQ_OP_PKTNUM_MASK); ++ val |= B_AX_WD_CPUQ_OP_EXEC; ++ rtw89_write32(rtwdev, reg, val); ++ ++ reg = wd ? R_AX_WD_CPUQ_OP_STATUS : R_AX_PL_CPUQ_OP_STATUS; ++ ++ ret = read_poll_timeout(rtw89_read32, val, val & B_AX_WD_CPUQ_OP_STAT_DONE, ++ 1, 2000, false, rtwdev, reg); ++ if (ret) ++ return ret; ++ ++ if (cmd_type == CPUIO_OP_CMD_GET_1ST_PID || ++ cmd_type == CPUIO_OP_CMD_GET_NEXT_PID) ++ ctrl_para->pktid = FIELD_GET(B_AX_WD_CPUQ_OP_PKTID_MASK, val); ++ ++ return 0; ++} ++ ++static int dle_quota_change(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode) ++{ ++ const struct rtw89_dle_mem *cfg; ++ struct rtw89_cpuio_ctrl ctrl_para = {0}; ++ u16 pkt_id; ++ int ret; ++ ++ cfg = get_dle_mem_cfg(rtwdev, mode); ++ if (!cfg) { ++ rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n"); ++ return -EINVAL; ++ } ++ ++ if (dle_used_size(cfg->wde_size, cfg->ple_size) != rtwdev->chip->fifo_size) { ++ rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n"); ++ return -EINVAL; ++ } ++ ++ dle_quota_cfg(rtwdev, cfg, INVALID_QT_WCPU); ++ ++ pkt_id = rtw89_mac_dle_buf_req(rtwdev, 0x20, true); ++ if (pkt_id == 0xffff) { ++ rtw89_err(rtwdev, "[ERR]WDE DLE buf req\n"); ++ return -ENOMEM; ++ } ++ ++ ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD; ++ ctrl_para.start_pktid = pkt_id; ++ ctrl_para.end_pktid = pkt_id; ++ ctrl_para.pkt_num = 0; ++ ctrl_para.dst_pid = WDE_DLE_PORT_ID_WDRLS; ++ ctrl_para.dst_qid = WDE_DLE_QUEID_NO_REPORT; ++ ret = rtw89_mac_set_cpuio(rtwdev, &ctrl_para, true); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]WDE DLE enqueue to head\n"); ++ return -EFAULT; ++ } ++ ++ pkt_id = rtw89_mac_dle_buf_req(rtwdev, 0x20, false); ++ if (pkt_id == 0xffff) { ++ rtw89_err(rtwdev, "[ERR]PLE DLE buf req\n"); ++ return -ENOMEM; ++ } ++ ++ ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD; ++ ctrl_para.start_pktid = pkt_id; ++ ctrl_para.end_pktid = pkt_id; ++ ctrl_para.pkt_num = 0; ++ ctrl_para.dst_pid = PLE_DLE_PORT_ID_PLRLS; ++ ctrl_para.dst_qid = PLE_DLE_QUEID_NO_REPORT; ++ ret = rtw89_mac_set_cpuio(rtwdev, &ctrl_para, false); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]PLE DLE enqueue to head\n"); ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++static int band_idle_ck_b(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ int ret; ++ u32 reg; ++ u8 val; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_PTCL_TX_CTN_SEL, mac_idx); ++ ++ ret = read_poll_timeout(rtw89_read8, val, ++ (val & B_AX_PTCL_TX_ON_STAT) == 0, ++ SW_CVR_DUR_US, ++ SW_CVR_DUR_US * PTCL_IDLE_POLL_CNT, ++ false, rtwdev, reg); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int band1_enable(struct rtw89_dev *rtwdev) ++{ ++ int ret, i; ++ u32 sleep_bak[4] = {0}; ++ u32 pause_bak[4] = {0}; ++ u16 tx_en; ++ ++ ret = rtw89_mac_stop_sch_tx(rtwdev, 0, &tx_en, RTW89_SCH_TX_SEL_ALL); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]stop sch tx %d\n", ret); ++ return ret; ++ } ++ ++ for (i = 0; i < 4; i++) { ++ sleep_bak[i] = rtw89_read32(rtwdev, R_AX_MACID_SLEEP_0 + i * 4); ++ pause_bak[i] = rtw89_read32(rtwdev, R_AX_SS_MACID_PAUSE_0 + i * 4); ++ rtw89_write32(rtwdev, R_AX_MACID_SLEEP_0 + i * 4, U32_MAX); ++ rtw89_write32(rtwdev, R_AX_SS_MACID_PAUSE_0 + i * 4, U32_MAX); ++ } ++ ++ ret = band_idle_ck_b(rtwdev, 0); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]tx idle poll %d\n", ret); ++ return ret; ++ } ++ ++ ret = dle_quota_change(rtwdev, rtwdev->mac.qta_mode); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]DLE quota change %d\n", ret); ++ return ret; ++ } ++ ++ for (i = 0; i < 4; i++) { ++ rtw89_write32(rtwdev, R_AX_MACID_SLEEP_0 + i * 4, sleep_bak[i]); ++ rtw89_write32(rtwdev, R_AX_SS_MACID_PAUSE_0 + i * 4, pause_bak[i]); ++ } ++ ++ ret = rtw89_mac_resume_sch_tx(rtwdev, 0, tx_en); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC1 resume sch tx %d\n", ret); ++ return ret; ++ } ++ ++ ret = cmac_func_en(rtwdev, 1, true); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC1 func en %d\n", ret); ++ return ret; ++ } ++ ++ ret = cmac_init(rtwdev, 1); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC1 init %d\n", ret); ++ return ret; ++ } ++ ++ rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, ++ B_AX_R_SYM_FEN_WLBBFUN_1 | B_AX_R_SYM_FEN_WLBBGLB_1); ++ ++ return 0; ++} ++ ++static int rtw89_mac_enable_imr(struct rtw89_dev *rtwdev, u8 mac_idx, ++ enum rtw89_mac_hwmod_sel sel) ++{ ++ u32 reg, val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, sel); ++ if (ret) { ++ rtw89_err(rtwdev, "MAC%d mac_idx%d is not ready\n", ++ sel, mac_idx); ++ return ret; ++ } ++ ++ if (sel == RTW89_DMAC_SEL) { ++ rtw89_write32_clr(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR, ++ B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN | ++ B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR_INT_EN | ++ B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR_INT_EN); ++ rtw89_write32_clr(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1, ++ B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN | ++ B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR_INT_EN); ++ rtw89_write32_clr(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR, ++ B_AX_HDT_PKT_FAIL_DBG_INT_EN | ++ B_AX_HDT_OFFSET_UNMATCH_INT_EN); ++ rtw89_write32_clr(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR, ++ B_AX_CPU_SHIFT_EN_ERR_INT_EN); ++ rtw89_write32_clr(rtwdev, R_AX_PLE_ERR_IMR, ++ B_AX_PLE_GETNPG_STRPG_ERR_INT_EN); ++ rtw89_write32_clr(rtwdev, R_AX_WDRLS_ERR_IMR, ++ B_AX_WDRLS_PLEBREQ_TO_ERR_INT_EN); ++ rtw89_write32_set(rtwdev, R_AX_HD0IMR, B_AX_WDT_PTFM_INT_EN); ++ rtw89_write32_clr(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR, ++ B_AX_TXPKTCTL_USRCTL_NOINIT_ERR_INT_EN); ++ } else if (sel == RTW89_CMAC_SEL) { ++ reg = rtw89_mac_reg_by_idx(R_AX_SCHEDULE_ERR_IMR, mac_idx); ++ rtw89_write32_clr(rtwdev, reg, ++ B_AX_SORT_NON_IDLE_ERR_INT_EN); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_DLE_CTRL, mac_idx); ++ rtw89_write32_clr(rtwdev, reg, ++ B_AX_NO_RESERVE_PAGE_ERR_IMR | ++ B_AX_RXDATA_FSM_HANG_ERROR_IMR); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_PTCL_IMR0, mac_idx); ++ val = B_AX_F2PCMD_USER_ALLC_ERR_INT_EN | ++ B_AX_TX_RECORD_PKTID_ERR_INT_EN | ++ B_AX_FSM_TIMEOUT_ERR_INT_EN; ++ rtw89_write32(rtwdev, reg, val); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_PHYINFO_ERR_IMR, mac_idx); ++ rtw89_write32_set(rtwdev, reg, ++ B_AX_PHY_TXON_TIMEOUT_INT_EN | ++ B_AX_CCK_CCA_TIMEOUT_INT_EN | ++ B_AX_OFDM_CCA_TIMEOUT_INT_EN | ++ B_AX_DATA_ON_TIMEOUT_INT_EN | ++ B_AX_STS_ON_TIMEOUT_INT_EN | ++ B_AX_CSI_ON_TIMEOUT_INT_EN); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_RMAC_ERR_ISR, mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val |= (B_AX_RMAC_RX_CSI_TIMEOUT_INT_EN | ++ B_AX_RMAC_RX_TIMEOUT_INT_EN | ++ B_AX_RMAC_CSI_TIMEOUT_INT_EN); ++ val &= ~(B_AX_RMAC_CCA_TO_IDLE_TIMEOUT_INT_EN | ++ B_AX_RMAC_DATA_ON_TO_IDLE_TIMEOUT_INT_EN | ++ B_AX_RMAC_CCA_TIMEOUT_INT_EN | ++ B_AX_RMAC_DATA_ON_TIMEOUT_INT_EN); ++ rtw89_write32(rtwdev, reg, val); ++ } else { ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int rtw89_mac_dbcc_enable(struct rtw89_dev *rtwdev, bool enable) ++{ ++ int ret = 0; ++ ++ if (enable) { ++ ret = band1_enable(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] band1_enable %d\n", ret); ++ return ret; ++ } ++ ++ ret = rtw89_mac_enable_imr(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] enable CMAC1 IMR %d\n", ret); ++ return ret; ++ } ++ } else { ++ rtw89_err(rtwdev, "[ERR] disable dbcc is not implemented not\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int set_host_rpr(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) { ++ rtw89_write32_mask(rtwdev, R_AX_WDRLS_CFG, ++ B_AX_WDRLS_MODE_MASK, RTW89_RPR_MODE_POH); ++ rtw89_write32_set(rtwdev, R_AX_RLSRPT0_CFG0, ++ B_AX_RLSRPT0_FLTR_MAP_MASK); ++ } else { ++ rtw89_write32_mask(rtwdev, R_AX_WDRLS_CFG, ++ B_AX_WDRLS_MODE_MASK, RTW89_RPR_MODE_STF); ++ rtw89_write32_clr(rtwdev, R_AX_RLSRPT0_CFG0, ++ B_AX_RLSRPT0_FLTR_MAP_MASK); ++ } ++ ++ rtw89_write32_mask(rtwdev, R_AX_RLSRPT0_CFG1, B_AX_RLSRPT0_AGGNUM_MASK, 30); ++ rtw89_write32_mask(rtwdev, R_AX_RLSRPT0_CFG1, B_AX_RLSRPT0_TO_MASK, 255); ++ ++ return 0; ++} ++ ++static int rtw89_mac_trx_init(struct rtw89_dev *rtwdev) ++{ ++ enum rtw89_qta_mode qta_mode = rtwdev->mac.qta_mode; ++ int ret; ++ ++ ret = dmac_init(rtwdev, 0); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]DMAC init %d\n", ret); ++ return ret; ++ } ++ ++ ret = cmac_init(rtwdev, 0); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d init %d\n", 0, ret); ++ return ret; ++ } ++ ++ if (is_qta_dbcc(rtwdev, qta_mode)) { ++ ret = rtw89_mac_dbcc_enable(rtwdev, true); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]dbcc_enable init %d\n", ret); ++ return ret; ++ } ++ } ++ ++ ret = rtw89_mac_enable_imr(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] enable DMAC IMR %d\n", ret); ++ return ret; ++ } ++ ++ ret = rtw89_mac_enable_imr(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] to enable CMAC0 IMR %d\n", ret); ++ return ret; ++ } ++ ++ ret = set_host_rpr(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] set host rpr %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev) ++{ ++ clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); ++ ++ rtw89_write32_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_WCPU_EN); ++ rtw89_write32_clr(rtwdev, R_AX_SYS_CLK_CTRL, B_AX_CPU_CLK_EN); ++} ++ ++static int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, ++ bool dlfw) ++{ ++ u32 val; ++ int ret; ++ ++ if (rtw89_read32(rtwdev, R_AX_PLATFORM_ENABLE) & B_AX_WCPU_EN) ++ return -EFAULT; ++ ++ rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0); ++ rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); ++ ++ rtw89_write32_set(rtwdev, R_AX_SYS_CLK_CTRL, B_AX_CPU_CLK_EN); ++ ++ val = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL); ++ val &= ~(B_AX_WCPU_FWDL_EN | B_AX_H2C_PATH_RDY | B_AX_FWDL_PATH_RDY); ++ val = u32_replace_bits(val, RTW89_FWDL_INITIAL_STATE, ++ B_AX_WCPU_FWDL_STS_MASK); ++ ++ if (dlfw) ++ val |= B_AX_WCPU_FWDL_EN; ++ ++ rtw89_write32(rtwdev, R_AX_WCPU_FW_CTRL, val); ++ rtw89_write16_mask(rtwdev, R_AX_BOOT_REASON, B_AX_BOOT_REASON_MASK, ++ boot_reason); ++ rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_WCPU_EN); ++ ++ if (!dlfw) { ++ mdelay(5); ++ ++ ret = rtw89_fw_check_rdy(rtwdev); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int rtw89_mac_fw_dl_pre_init(struct rtw89_dev *rtwdev) ++{ ++ u32 val; ++ int ret; ++ ++ val = B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_DISPATCHER_EN | ++ B_AX_PKT_BUF_EN; ++ rtw89_write32(rtwdev, R_AX_DMAC_FUNC_EN, val); ++ ++ val = B_AX_DISPATCHER_CLK_EN; ++ rtw89_write32(rtwdev, R_AX_DMAC_CLK_EN, val); ++ ++ ret = dle_init(rtwdev, RTW89_QTA_DLFW, rtwdev->mac.qta_mode); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]DLE pre init %d\n", ret); ++ return ret; ++ } ++ ++ ret = hfc_init(rtwdev, true, false, true); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]HCI FC pre init %d\n", ret); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++static void rtw89_mac_hci_func_en(struct rtw89_dev *rtwdev) ++{ ++ rtw89_write32_set(rtwdev, R_AX_HCI_FUNC_EN, ++ B_AX_HCI_TXDMA_EN | B_AX_HCI_RXDMA_EN); ++} ++ ++void rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev) ++{ ++ rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN, ++ B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); ++ rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, ++ B_AX_WLRF1_CTRL_7 | B_AX_WLRF1_CTRL_1 | ++ B_AX_WLRF_CTRL_7 | B_AX_WLRF_CTRL_1); ++ rtw89_write8_set(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_ALL_CYCLE); ++} ++ ++void rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev) ++{ ++ rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, ++ B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); ++ rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, ++ B_AX_WLRF1_CTRL_7 | B_AX_WLRF1_CTRL_1 | ++ B_AX_WLRF_CTRL_7 | B_AX_WLRF_CTRL_1); ++ rtw89_write8_clr(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_ALL_CYCLE); ++} ++ ++int rtw89_mac_partial_init(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ ret = rtw89_mac_power_switch(rtwdev, true); ++ if (ret) { ++ rtw89_mac_power_switch(rtwdev, false); ++ ret = rtw89_mac_power_switch(rtwdev, true); ++ if (ret) ++ return ret; ++ } ++ ++ rtw89_mac_hci_func_en(rtwdev); ++ ++ if (rtwdev->hci.ops->mac_pre_init) { ++ ret = rtwdev->hci.ops->mac_pre_init(rtwdev); ++ if (ret) ++ return ret; ++ } ++ ++ ret = rtw89_mac_fw_dl_pre_init(rtwdev); ++ if (ret) ++ return ret; ++ ++ rtw89_mac_disable_cpu(rtwdev); ++ ret = rtw89_mac_enable_cpu(rtwdev, 0, true); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_fw_download(rtwdev, RTW89_FW_NORMAL); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++int rtw89_mac_init(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ ret = rtw89_mac_partial_init(rtwdev); ++ if (ret) ++ goto fail; ++ ++ rtw89_mac_enable_bb_rf(rtwdev); ++ if (ret) ++ goto fail; ++ ++ ret = rtw89_mac_sys_init(rtwdev); ++ if (ret) ++ goto fail; ++ ++ ret = rtw89_mac_trx_init(rtwdev); ++ if (ret) ++ goto fail; ++ ++ if (rtwdev->hci.ops->mac_post_init) { ++ ret = rtwdev->hci.ops->mac_post_init(rtwdev); ++ if (ret) ++ goto fail; ++ } ++ ++ rtw89_fw_send_all_early_h2c(rtwdev); ++ rtw89_fw_h2c_set_ofld_cfg(rtwdev); ++ ++ return ret; ++fail: ++ rtw89_mac_power_switch(rtwdev, false); ++ ++ return ret; ++} ++ ++static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid) ++{ ++ u8 i; ++ ++ for (i = 0; i < 4; i++) { ++ rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, ++ DMAC_TBL_BASE_ADDR + (macid << 4) + (i << 2)); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, 0); ++ } ++} ++ ++static void rtw89_mac_cmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid) ++{ ++ rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, ++ CMAC_TBL_BASE_ADDR + macid * CCTL_INFO_SIZE); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, 0x4); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 4, 0x400A0004); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 8, 0); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 12, 0); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 16, 0); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 20, 0xE43000B); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 24, 0); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 28, 0xB8109); ++} ++ ++static int rtw89_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause) ++{ ++ u8 sh = FIELD_GET(GENMASK(4, 0), macid); ++ u8 grp = macid >> 5; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ rtw89_fw_h2c_macid_pause(rtwdev, sh, grp, pause); ++ ++ return 0; ++} ++ ++static const struct rtw89_port_reg rtw_port_base = { ++ .port_cfg = R_AX_PORT_CFG_P0, ++ .tbtt_prohib = R_AX_TBTT_PROHIB_P0, ++ .bcn_area = R_AX_BCN_AREA_P0, ++ .bcn_early = R_AX_BCNERLYINT_CFG_P0, ++ .tbtt_early = R_AX_TBTTERLYINT_CFG_P0, ++ .tbtt_agg = R_AX_TBTT_AGG_P0, ++ .bcn_space = R_AX_BCN_SPACE_CFG_P0, ++ .bcn_forcetx = R_AX_BCN_FORCETX_P0, ++ .bcn_err_cnt = R_AX_BCN_ERR_CNT_P0, ++ .bcn_err_flag = R_AX_BCN_ERR_FLAG_P0, ++ .dtim_ctrl = R_AX_DTIM_CTRL_P0, ++ .tbtt_shift = R_AX_TBTT_SHIFT_P0, ++ .bcn_cnt_tmr = R_AX_BCN_CNT_TMR_P0, ++ .tsftr_l = R_AX_TSFTR_LOW_P0, ++ .tsftr_h = R_AX_TSFTR_HIGH_P0 ++}; ++ ++#define BCN_INTERVAL 100 ++#define BCN_ERLY_DEF 160 ++#define BCN_SETUP_DEF 2 ++#define BCN_HOLD_DEF 200 ++#define BCN_MASK_DEF 0 ++#define TBTT_ERLY_DEF 5 ++#define BCN_SET_UNIT 32 ++#define BCN_ERLY_SET_DLY (10 * 2) ++ ++static void rtw89_mac_port_cfg_func_sw(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ if (!rtw89_read32_port_mask(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN)) ++ return; ++ ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK); ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 1); ++ rtw89_write16_port_clr(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK); ++ rtw89_write16_port_clr(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK); ++ ++ msleep(vif->bss_conf.beacon_int + 1); ++ ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN | ++ B_AX_BRK_SETUP); ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TSFTR_RST); ++ rtw89_write32_port(rtwdev, rtwvif, p->bcn_cnt_tmr, 0); ++} ++ ++static void rtw89_mac_port_cfg_tx_rpt(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, bool en) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ if (en) ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TXBCN_RPT_EN); ++ else ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TXBCN_RPT_EN); ++} ++ ++static void rtw89_mac_port_cfg_rx_rpt(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, bool en) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ if (en) ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_RXBCN_RPT_EN); ++ else ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_RXBCN_RPT_EN); ++} ++ ++static void rtw89_mac_port_cfg_net_type(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->port_cfg, B_AX_NET_TYPE_MASK, ++ rtwvif->net_type); ++} ++ ++static void rtw89_mac_port_cfg_bcn_prct(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ bool en = rtwvif->net_type != RTW89_NET_TYPE_NO_LINK; ++ u32 bits = B_AX_TBTT_PROHIB_EN | B_AX_BRK_SETUP; ++ ++ if (en) ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, bits); ++ else ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, bits); ++} ++ ++static void rtw89_mac_port_cfg_rx_sw(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ bool en = rtwvif->net_type == RTW89_NET_TYPE_INFRA || ++ rtwvif->net_type == RTW89_NET_TYPE_AD_HOC; ++ u32 bit = B_AX_RX_BSSID_FIT_EN; ++ ++ if (en) ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, bit); ++ else ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, bit); ++} ++ ++static void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ bool en = rtwvif->net_type == RTW89_NET_TYPE_INFRA || ++ rtwvif->net_type == RTW89_NET_TYPE_AD_HOC; ++ ++ if (en) ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TSF_UDT_EN); ++ else ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TSF_UDT_EN); ++} ++ ++static void rtw89_mac_port_cfg_tx_sw(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ bool en = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || ++ rtwvif->net_type == RTW89_NET_TYPE_AD_HOC; ++ ++ if (en) ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN); ++ else ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN); ++} ++ ++static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ u16 bcn_int = vif->bss_conf.beacon_int ? vif->bss_conf.beacon_int : BCN_INTERVAL; ++ ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_space, B_AX_BCN_SPACE_MASK, ++ bcn_int); ++} ++ ++static void rtw89_mac_port_cfg_bcn_setup_time(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, ++ B_AX_TBTT_SETUP_MASK, BCN_SETUP_DEF); ++} ++ ++static void rtw89_mac_port_cfg_bcn_hold_time(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, ++ B_AX_TBTT_HOLD_MASK, BCN_HOLD_DEF); ++} ++ ++static void rtw89_mac_port_cfg_bcn_mask_area(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_area, ++ B_AX_BCN_MSK_AREA_MASK, BCN_MASK_DEF); ++} ++ ++static void rtw89_mac_port_cfg_tbtt_early(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_early, ++ B_AX_TBTTERLY_MASK, TBTT_ERLY_DEF); ++} ++ ++static void rtw89_mac_port_cfg_bss_color(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ static const u32 masks[RTW89_PORT_NUM] = { ++ B_AX_BSS_COLOB_AX_PORT_0_MASK, B_AX_BSS_COLOB_AX_PORT_1_MASK, ++ B_AX_BSS_COLOB_AX_PORT_2_MASK, B_AX_BSS_COLOB_AX_PORT_3_MASK, ++ B_AX_BSS_COLOB_AX_PORT_4_MASK, ++ }; ++ u8 port = rtwvif->port; ++ u32 reg_base; ++ u32 reg; ++ u8 bss_color; ++ ++ bss_color = vif->bss_conf.he_bss_color.color; ++ reg_base = port >= 4 ? R_AX_PTCL_BSS_COLOR_1 : R_AX_PTCL_BSS_COLOR_0; ++ reg = rtw89_mac_reg_by_idx(reg_base, rtwvif->mac_idx); ++ rtw89_write32_mask(rtwdev, reg, masks[port], bss_color); ++} ++ ++static void rtw89_mac_port_cfg_mbssid(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ u8 port = rtwvif->port; ++ u32 reg; ++ ++ if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) ++ return; ++ ++ if (port == 0) { ++ reg = rtw89_mac_reg_by_idx(R_AX_MBSSID_CTRL, rtwvif->mac_idx); ++ rtw89_write32_clr(rtwdev, reg, B_AX_P0MB_ALL_MASK); ++ } ++} ++ ++static void rtw89_mac_port_cfg_hiq_drop(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ u8 port = rtwvif->port; ++ u32 reg; ++ u32 val; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_MBSSID_DROP_0, rtwvif->mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val &= ~FIELD_PREP(B_AX_PORT_DROP_4_0_MASK, BIT(port)); ++ if (port == 0) ++ val &= ~BIT(0); ++ rtw89_write32(rtwdev, reg, val); ++} ++ ++static void rtw89_mac_port_cfg_func_en(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN); ++} ++ ++static void rtw89_mac_port_cfg_bcn_early(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK, ++ BCN_ERLY_DEF); ++} ++ ++int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ int ret; ++ ++ ret = rtw89_mac_port_update(rtwdev, rtwvif); ++ if (ret) ++ return ret; ++ ++ rtw89_mac_dmac_tbl_init(rtwdev, rtwvif->mac_id); ++ rtw89_mac_cmac_tbl_init(rtwdev, rtwvif->mac_id); ++ ++ ret = rtw89_set_macid_pause(rtwdev, rtwvif->mac_id, false); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_fw_h2c_vif_maintain(rtwdev, rtwvif, RTW89_VIF_CREATE); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_cam_init(rtwdev, rtwvif); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_fw_h2c_default_cmac_tbl(rtwdev, rtwvif->mac_id); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ int ret; ++ ++ ret = rtw89_fw_h2c_vif_maintain(rtwdev, rtwvif, RTW89_VIF_REMOVE); ++ if (ret) ++ return ret; ++ ++ rtw89_cam_deinit(rtwdev, rtwvif); ++ ++ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ u8 port = rtwvif->port; ++ ++ if (port >= RTW89_PORT_NUM) ++ return -EINVAL; ++ ++ rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_tx_rpt(rtwdev, rtwvif, false); ++ rtw89_mac_port_cfg_rx_rpt(rtwdev, rtwvif, false); ++ rtw89_mac_port_cfg_net_type(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_bcn_prct(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_rx_sw(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_bcn_setup_time(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_bcn_hold_time(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_bcn_mask_area(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_tbtt_early(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_hiq_drop(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_func_en(rtwdev, rtwvif); ++ fsleep(BCN_ERLY_SET_DLY); ++ rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif); ++ ++ return 0; ++} ++ ++int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ int ret; ++ ++ rtwvif->mac_id = rtw89_core_acquire_bit_map(rtwdev->mac_id_map, ++ RTW89_MAX_MAC_ID_NUM); ++ if (rtwvif->mac_id == RTW89_MAX_MAC_ID_NUM) ++ return -ENOSPC; ++ ++ ret = rtw89_mac_vif_init(rtwdev, rtwvif); ++ if (ret) ++ goto release_mac_id; ++ ++ return 0; ++ ++release_mac_id: ++ rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwvif->mac_id); ++ ++ return ret; ++} ++ ++int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ int ret; ++ ++ ret = rtw89_mac_vif_deinit(rtwdev, rtwvif); ++ rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwvif->mac_id); ++ ++ return ret; ++} ++ ++static void ++rtw89_mac_c2h_macid_pause(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) ++{ ++} ++ ++static void ++rtw89_mac_c2h_rec_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_FW, ++ "C2H rev ack recv, cat: %d, class: %d, func: %d, seq : %d\n", ++ RTW89_GET_MAC_C2H_REV_ACK_CAT(c2h->data), ++ RTW89_GET_MAC_C2H_REV_ACK_CLASS(c2h->data), ++ RTW89_GET_MAC_C2H_REV_ACK_FUNC(c2h->data), ++ RTW89_GET_MAC_C2H_REV_ACK_H2C_SEQ(c2h->data)); ++} ++ ++static void ++rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_FW, ++ "C2H done ack recv, cat: %d, class: %d, func: %d, ret: %d, seq : %d\n", ++ RTW89_GET_MAC_C2H_DONE_ACK_CAT(c2h->data), ++ RTW89_GET_MAC_C2H_DONE_ACK_CLASS(c2h->data), ++ RTW89_GET_MAC_C2H_DONE_ACK_FUNC(c2h->data), ++ RTW89_GET_MAC_C2H_DONE_ACK_H2C_RETURN(c2h->data), ++ RTW89_GET_MAC_C2H_DONE_ACK_H2C_SEQ(c2h->data)); ++} ++ ++static void ++rtw89_mac_c2h_log(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) ++{ ++ rtw89_info(rtwdev, "%*s", RTW89_GET_C2H_LOG_LEN(len), ++ RTW89_GET_C2H_LOG_SRT_PRT(c2h->data)); ++} ++ ++static ++void (* const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev, ++ struct sk_buff *c2h, u32 len) = { ++ [RTW89_MAC_C2H_FUNC_EFUSE_DUMP] = NULL, ++ [RTW89_MAC_C2H_FUNC_READ_RSP] = NULL, ++ [RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP] = NULL, ++ [RTW89_MAC_C2H_FUNC_BCN_RESEND] = NULL, ++ [RTW89_MAC_C2H_FUNC_MACID_PAUSE] = rtw89_mac_c2h_macid_pause, ++}; ++ ++static ++void (* const rtw89_mac_c2h_info_handler[])(struct rtw89_dev *rtwdev, ++ struct sk_buff *c2h, u32 len) = { ++ [RTW89_MAC_C2H_FUNC_REC_ACK] = rtw89_mac_c2h_rec_ack, ++ [RTW89_MAC_C2H_FUNC_DONE_ACK] = rtw89_mac_c2h_done_ack, ++ [RTW89_MAC_C2H_FUNC_C2H_LOG] = rtw89_mac_c2h_log, ++}; ++ ++void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, ++ u32 len, u8 class, u8 func) ++{ ++ void (*handler)(struct rtw89_dev *rtwdev, ++ struct sk_buff *c2h, u32 len) = NULL; ++ ++ switch (class) { ++ case RTW89_MAC_C2H_CLASS_INFO: ++ if (func < RTW89_MAC_C2H_FUNC_INFO_MAX) ++ handler = rtw89_mac_c2h_info_handler[func]; ++ break; ++ case RTW89_MAC_C2H_CLASS_OFLD: ++ if (func < RTW89_MAC_C2H_FUNC_OFLD_MAX) ++ handler = rtw89_mac_c2h_ofld_handler[func]; ++ break; ++ case RTW89_MAC_C2H_CLASS_FWDBG: ++ return; ++ default: ++ rtw89_info(rtwdev, "c2h class %d not support\n", class); ++ return; ++ } ++ if (!handler) { ++ rtw89_info(rtwdev, "c2h class %d func %d not support\n", class, ++ func); ++ return; ++ } ++ handler(rtwdev, skb, len); ++} ++ ++bool rtw89_mac_get_txpwr_cr(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, ++ u32 reg_base, u32 *cr) ++{ ++ const struct rtw89_dle_mem *dle_mem = rtwdev->chip->dle_mem; ++ enum rtw89_qta_mode mode = dle_mem->mode; ++ u32 addr = rtw89_mac_reg_by_idx(reg_base, phy_idx); ++ ++ if (addr < R_AX_PWR_RATE_CTRL || addr > CMAC1_END_ADDR) { ++ rtw89_err(rtwdev, "[TXPWR] addr=0x%x exceed txpwr cr\n", ++ addr); ++ goto error; ++ } ++ ++ if (addr >= CMAC1_START_ADDR && addr <= CMAC1_END_ADDR) ++ if (mode == RTW89_QTA_SCC) { ++ rtw89_err(rtwdev, ++ "[TXPWR] addr=0x%x but hw not enable\n", ++ addr); ++ goto error; ++ } ++ ++ *cr = addr; ++ return true; ++ ++error: ++ rtw89_err(rtwdev, "[TXPWR] check txpwr cr 0x%x(phy%d) fail\n", ++ addr, phy_idx); ++ ++ return false; ++} ++ ++int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) ++{ ++ u32 reg = rtw89_mac_reg_by_idx(R_AX_PPDU_STAT, mac_idx); ++ int ret = 0; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ if (!enable) { ++ rtw89_write32_clr(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN); ++ return ret; ++ } ++ ++ rtw89_write32(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN | ++ B_AX_APP_MAC_INFO_RPT | ++ B_AX_APP_RX_CNT_RPT | B_AX_APP_PLCP_HDR_RPT | ++ B_AX_PPDU_STAT_RPT_CRC32); ++ rtw89_write32_mask(rtwdev, R_AX_HW_RPT_FWD, B_AX_FWD_PPDU_STAT_MASK, ++ RTW89_PRPT_DEST_HOST); ++ ++ return ret; ++} ++ ++void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++#define MAC_AX_TIME_TH_SH 5 ++#define MAC_AX_LEN_TH_SH 4 ++#define MAC_AX_TIME_TH_MAX 255 ++#define MAC_AX_LEN_TH_MAX 255 ++#define MAC_AX_TIME_TH_DEF 88 ++#define MAC_AX_LEN_TH_DEF 4080 ++ struct ieee80211_hw *hw = rtwdev->hw; ++ u32 rts_threshold = hw->wiphy->rts_threshold; ++ u32 time_th, len_th; ++ u32 reg; ++ ++ if (rts_threshold == (u32)-1) { ++ time_th = MAC_AX_TIME_TH_DEF; ++ len_th = MAC_AX_LEN_TH_DEF; ++ } else { ++ time_th = MAC_AX_TIME_TH_MAX << MAC_AX_TIME_TH_SH; ++ len_th = rts_threshold; ++ } ++ ++ time_th = min_t(u32, time_th >> MAC_AX_TIME_TH_SH, MAC_AX_TIME_TH_MAX); ++ len_th = min_t(u32, len_th >> MAC_AX_LEN_TH_SH, MAC_AX_LEN_TH_MAX); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_AGG_LEN_HT_0, mac_idx); ++ rtw89_write16_mask(rtwdev, reg, B_AX_RTS_TXTIME_TH_MASK, time_th); ++ rtw89_write16_mask(rtwdev, reg, B_AX_RTS_LEN_TH_MASK, len_th); ++} ++ ++void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop) ++{ ++ bool empty; ++ int ret; ++ ++ if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) ++ return; ++ ++ ret = read_poll_timeout(dle_is_txq_empty, empty, empty, ++ 10000, 200000, false, rtwdev); ++ if (ret && !drop && (rtwdev->total_sta_assoc || rtwdev->scanning)) ++ rtw89_info(rtwdev, "timed out to flush queues\n"); ++} ++ ++int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex) ++{ ++ u8 val; ++ u16 val16; ++ u32 val32; ++ int ret; ++ ++ rtw89_write8_set(rtwdev, R_AX_GPIO_MUXCFG, B_AX_ENBT); ++ rtw89_write8_set(rtwdev, R_AX_BTC_FUNC_EN, B_AX_PTA_WL_TX_EN); ++ rtw89_write8_set(rtwdev, R_AX_BT_COEX_CFG_2 + 1, B_AX_GNT_BT_POLARITY >> 8); ++ rtw89_write8_set(rtwdev, R_AX_CSR_MODE, B_AX_STATIS_BT_EN | B_AX_WL_ACT_MSK); ++ rtw89_write8_set(rtwdev, R_AX_CSR_MODE + 2, B_AX_BT_CNT_RST >> 16); ++ rtw89_write8_clr(rtwdev, R_AX_TRXPTCL_RESP_0 + 3, B_AX_RSP_CHK_BTCCA >> 24); ++ ++ val16 = rtw89_read16(rtwdev, R_AX_CCA_CFG_0); ++ val16 = (val16 | B_AX_BTCCA_EN) & ~B_AX_BTCCA_BRK_TXOP_EN; ++ rtw89_write16(rtwdev, R_AX_CCA_CFG_0, val16); ++ ++ ret = rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_2, &val32); ++ if (ret) { ++ rtw89_err(rtwdev, "Read R_AX_LTE_SW_CFG_2 fail!\n"); ++ return ret; ++ } ++ val32 = val32 & B_AX_WL_RX_CTRL; ++ ret = rtw89_mac_write_lte(rtwdev, R_AX_LTE_SW_CFG_2, val32); ++ if (ret) { ++ rtw89_err(rtwdev, "Write R_AX_LTE_SW_CFG_2 fail!\n"); ++ return ret; ++ } ++ ++ switch (coex->pta_mode) { ++ case RTW89_MAC_AX_COEX_RTK_MODE: ++ val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG); ++ val &= ~B_AX_BTMODE_MASK; ++ val |= FIELD_PREP(B_AX_BTMODE_MASK, MAC_AX_BT_MODE_0_3); ++ rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG, val); ++ ++ val = rtw89_read8(rtwdev, R_AX_TDMA_MODE); ++ rtw89_write8(rtwdev, R_AX_TDMA_MODE, val | B_AX_RTK_BT_ENABLE); ++ ++ val = rtw89_read8(rtwdev, R_AX_BT_COEX_CFG_5); ++ val &= ~B_AX_BT_RPT_SAMPLE_RATE_MASK; ++ val |= FIELD_PREP(B_AX_BT_RPT_SAMPLE_RATE_MASK, MAC_AX_RTK_RATE); ++ rtw89_write8(rtwdev, R_AX_BT_COEX_CFG_5, val); ++ break; ++ case RTW89_MAC_AX_COEX_CSR_MODE: ++ val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG); ++ val &= ~B_AX_BTMODE_MASK; ++ val |= FIELD_PREP(B_AX_BTMODE_MASK, MAC_AX_BT_MODE_2); ++ rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG, val); ++ ++ val16 = rtw89_read16(rtwdev, R_AX_CSR_MODE); ++ val16 &= ~B_AX_BT_PRI_DETECT_TO_MASK; ++ val16 |= FIELD_PREP(B_AX_BT_PRI_DETECT_TO_MASK, MAC_AX_CSR_PRI_TO); ++ val16 &= ~B_AX_BT_TRX_INIT_DETECT_MASK; ++ val16 |= FIELD_PREP(B_AX_BT_TRX_INIT_DETECT_MASK, MAC_AX_CSR_TRX_TO); ++ val16 &= ~B_AX_BT_STAT_DELAY_MASK; ++ val16 |= FIELD_PREP(B_AX_BT_STAT_DELAY_MASK, MAC_AX_CSR_DELAY); ++ val16 |= B_AX_ENHANCED_BT; ++ rtw89_write16(rtwdev, R_AX_CSR_MODE, val16); ++ ++ rtw89_write8(rtwdev, R_AX_BT_COEX_CFG_2, MAC_AX_CSR_RATE); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ switch (coex->direction) { ++ case RTW89_MAC_AX_COEX_INNER: ++ val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG + 1); ++ val = (val & ~BIT(2)) | BIT(1); ++ rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG + 1, val); ++ break; ++ case RTW89_MAC_AX_COEX_OUTPUT: ++ val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG + 1); ++ val = val | BIT(1) | BIT(0); ++ rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG + 1, val); ++ break; ++ case RTW89_MAC_AX_COEX_INPUT: ++ val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG + 1); ++ val = val & ~(BIT(2) | BIT(1)); ++ rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG + 1, val); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++int rtw89_mac_cfg_gnt(struct rtw89_dev *rtwdev, ++ const struct rtw89_mac_ax_coex_gnt *gnt_cfg) ++{ ++ u32 val, ret; ++ ++ ret = rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_1, &val); ++ if (ret) { ++ rtw89_err(rtwdev, "Read LTE fail!\n"); ++ return ret; ++ } ++ val = (gnt_cfg->band[0].gnt_bt ? ++ B_AX_GNT_BT_RFC_S0_SW_VAL | B_AX_GNT_BT_BB_S0_SW_VAL : 0) | ++ (gnt_cfg->band[0].gnt_bt_sw_en ? ++ B_AX_GNT_BT_RFC_S0_SW_CTRL | B_AX_GNT_BT_BB_S0_SW_CTRL : 0) | ++ (gnt_cfg->band[0].gnt_wl ? ++ B_AX_GNT_WL_RFC_S0_SW_VAL | B_AX_GNT_WL_BB_S0_SW_VAL : 0) | ++ (gnt_cfg->band[0].gnt_wl_sw_en ? ++ B_AX_GNT_WL_RFC_S0_SW_CTRL | B_AX_GNT_WL_BB_S0_SW_CTRL : 0) | ++ (gnt_cfg->band[1].gnt_bt ? ++ B_AX_GNT_BT_RFC_S1_SW_VAL | B_AX_GNT_BT_BB_S1_SW_VAL : 0) | ++ (gnt_cfg->band[1].gnt_bt_sw_en ? ++ B_AX_GNT_BT_RFC_S1_SW_CTRL | B_AX_GNT_BT_BB_S1_SW_CTRL : 0) | ++ (gnt_cfg->band[1].gnt_wl ? ++ B_AX_GNT_WL_RFC_S1_SW_VAL | B_AX_GNT_WL_BB_S1_SW_VAL : 0) | ++ (gnt_cfg->band[1].gnt_wl_sw_en ? ++ B_AX_GNT_WL_RFC_S1_SW_CTRL | B_AX_GNT_WL_BB_S1_SW_CTRL : 0); ++ ret = rtw89_mac_write_lte(rtwdev, R_AX_LTE_SW_CFG_1, val); ++ if (ret) { ++ rtw89_err(rtwdev, "Write LTE fail!\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++int rtw89_mac_cfg_plt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt) ++{ ++ u32 reg; ++ u8 val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, plt->band, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_BT_PLT, plt->band); ++ val = (plt->tx & RTW89_MAC_AX_PLT_LTE_RX ? B_AX_TX_PLT_GNT_LTE_RX : 0) | ++ (plt->tx & RTW89_MAC_AX_PLT_GNT_BT_TX ? B_AX_TX_PLT_GNT_BT_TX : 0) | ++ (plt->tx & RTW89_MAC_AX_PLT_GNT_BT_RX ? B_AX_TX_PLT_GNT_BT_RX : 0) | ++ (plt->tx & RTW89_MAC_AX_PLT_GNT_WL ? B_AX_TX_PLT_GNT_WL : 0) | ++ (plt->rx & RTW89_MAC_AX_PLT_LTE_RX ? B_AX_RX_PLT_GNT_LTE_RX : 0) | ++ (plt->rx & RTW89_MAC_AX_PLT_GNT_BT_TX ? B_AX_RX_PLT_GNT_BT_TX : 0) | ++ (plt->rx & RTW89_MAC_AX_PLT_GNT_BT_RX ? B_AX_RX_PLT_GNT_BT_RX : 0) | ++ (plt->rx & RTW89_MAC_AX_PLT_GNT_WL ? B_AX_RX_PLT_GNT_WL : 0); ++ rtw89_write8(rtwdev, reg, val); ++ ++ return 0; ++} ++ ++void rtw89_mac_cfg_sb(struct rtw89_dev *rtwdev, u32 val) ++{ ++ u32 fw_sb; ++ ++ fw_sb = rtw89_read32(rtwdev, R_AX_SCOREBOARD); ++ fw_sb = FIELD_GET(B_MAC_AX_SB_FW_MASK, fw_sb); ++ fw_sb = fw_sb & ~B_MAC_AX_BTGS1_NOTIFY; ++ if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) ++ fw_sb = fw_sb | MAC_AX_NOTIFY_PWR_MAJOR; ++ else ++ fw_sb = fw_sb | MAC_AX_NOTIFY_TP_MAJOR; ++ val = FIELD_GET(B_MAC_AX_SB_DRV_MASK, val); ++ val = B_AX_TOGGLE | ++ FIELD_PREP(B_MAC_AX_SB_DRV_MASK, val) | ++ FIELD_PREP(B_MAC_AX_SB_FW_MASK, fw_sb); ++ rtw89_write32(rtwdev, R_AX_SCOREBOARD, val); ++ fsleep(1000); /* avoid BT FW loss information */ ++} ++ ++u32 rtw89_mac_get_sb(struct rtw89_dev *rtwdev) ++{ ++ return rtw89_read32(rtwdev, R_AX_SCOREBOARD); ++} ++ ++int rtw89_mac_cfg_ctrl_path(struct rtw89_dev *rtwdev, bool wl) ++{ ++ u8 val = rtw89_read8(rtwdev, R_AX_SYS_SDIO_CTRL + 3); ++ ++ val = wl ? val | BIT(2) : val & ~BIT(2); ++ rtw89_write8(rtwdev, R_AX_SYS_SDIO_CTRL + 3, val); ++ ++ return 0; ++} ++ ++bool rtw89_mac_get_ctrl_path(struct rtw89_dev *rtwdev) ++{ ++ u8 val = rtw89_read8(rtwdev, R_AX_SYS_SDIO_CTRL + 3); ++ ++ return FIELD_GET(B_AX_LTE_MUX_CTRL_PATH >> 24, val); ++} ++ ++static void rtw89_mac_bfee_ctrl(struct rtw89_dev *rtwdev, u8 mac_idx, bool en) ++{ ++ u32 reg; ++ u32 mask = B_AX_BFMEE_HT_NDPA_EN | B_AX_BFMEE_VHT_NDPA_EN | ++ B_AX_BFMEE_HE_NDPA_EN; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BF, "set bfee ndpa_en to %d\n", en); ++ reg = rtw89_mac_reg_by_idx(R_AX_BFMEE_RESP_OPTION, mac_idx); ++ if (en) { ++ set_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags); ++ rtw89_write32_set(rtwdev, reg, mask); ++ } else { ++ clear_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags); ++ rtw89_write32_clr(rtwdev, reg, mask); ++ } ++} ++ ++static int rtw89_mac_init_bfee(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 reg; ++ u32 val32; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ /* AP mode set tx gid to 63 */ ++ /* STA mode set tx gid to 0(default) */ ++ reg = rtw89_mac_reg_by_idx(R_AX_BFMER_CTRL_0, mac_idx); ++ rtw89_write32_set(rtwdev, reg, B_AX_BFMER_NDP_BFEN); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_RRSC, mac_idx); ++ rtw89_write32(rtwdev, reg, CSI_RRSC_BMAP); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_BFMEE_RESP_OPTION, mac_idx); ++ val32 = FIELD_PREP(B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK, BFRP_RX_STANDBY_TIMER); ++ val32 |= FIELD_PREP(B_AX_BFMEE_NDP_RX_STANDBY_TIMER_MASK, NDP_RX_STANDBY_TIMER); ++ rtw89_write32(rtwdev, reg, val32); ++ rtw89_mac_bfee_ctrl(rtwdev, mac_idx, true); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); ++ rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL | ++ B_AX_BFMEE_USE_NSTS | ++ B_AX_BFMEE_CSI_GID_SEL | ++ B_AX_BFMEE_CSI_FORCE_RETE_EN); ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_RATE, mac_idx); ++ rtw89_write32(rtwdev, reg, ++ u32_encode_bits(CSI_INIT_RATE_HT, B_AX_BFMEE_HT_CSI_RATE_MASK) | ++ u32_encode_bits(CSI_INIT_RATE_VHT, B_AX_BFMEE_VHT_CSI_RATE_MASK) | ++ u32_encode_bits(CSI_INIT_RATE_HE, B_AX_BFMEE_HE_CSI_RATE_MASK)); ++ ++ return 0; ++} ++ ++static int rtw89_mac_set_csi_para_reg(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ u8 mac_idx = rtwvif->mac_idx; ++ u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1; ++ u8 port_sel = rtwvif->port; ++ u8 sound_dim = 3, t; ++ u8 *phy_cap = sta->he_cap.he_cap_elem.phy_cap_info; ++ u32 reg; ++ u16 val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ if ((phy_cap[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) || ++ (phy_cap[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) { ++ ldpc_en &= !!(phy_cap[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD); ++ stbc_en &= !!(phy_cap[2] & IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ); ++ t = FIELD_GET(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK, ++ phy_cap[5]); ++ sound_dim = min(sound_dim, t); ++ } ++ if ((sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || ++ (sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) { ++ ldpc_en &= !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); ++ stbc_en &= !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK); ++ t = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK, ++ sta->vht_cap.cap); ++ sound_dim = min(sound_dim, t); ++ } ++ nc = min(nc, sound_dim); ++ nr = min(nr, sound_dim); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); ++ rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL); ++ ++ val = FIELD_PREP(B_AX_BFMEE_CSIINFO0_NC_MASK, nc) | ++ FIELD_PREP(B_AX_BFMEE_CSIINFO0_NR_MASK, nr) | ++ FIELD_PREP(B_AX_BFMEE_CSIINFO0_NG_MASK, ng) | ++ FIELD_PREP(B_AX_BFMEE_CSIINFO0_CB_MASK, cb) | ++ FIELD_PREP(B_AX_BFMEE_CSIINFO0_CS_MASK, cs) | ++ FIELD_PREP(B_AX_BFMEE_CSIINFO0_LDPC_EN, ldpc_en) | ++ FIELD_PREP(B_AX_BFMEE_CSIINFO0_STBC_EN, stbc_en); ++ ++ if (port_sel == 0) ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); ++ else ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_1, mac_idx); ++ ++ rtw89_write16(rtwdev, reg, val); ++ ++ return 0; ++} ++ ++static int rtw89_mac_csi_rrsc(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M); ++ u32 reg; ++ u8 mac_idx = rtwvif->mac_idx; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ if (sta->he_cap.has_he) { ++ rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) | ++ BIT(RTW89_MAC_BF_RRSC_HE_MSC3) | ++ BIT(RTW89_MAC_BF_RRSC_HE_MSC5)); ++ } ++ if (sta->vht_cap.vht_supported) { ++ rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) | ++ BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) | ++ BIT(RTW89_MAC_BF_RRSC_VHT_MSC5)); ++ } ++ if (sta->ht_cap.ht_supported) { ++ rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) | ++ BIT(RTW89_MAC_BF_RRSC_HT_MSC3) | ++ BIT(RTW89_MAC_BF_RRSC_HT_MSC5)); ++ } ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); ++ rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL); ++ rtw89_write32_clr(rtwdev, reg, B_AX_BFMEE_CSI_FORCE_RETE_EN); ++ rtw89_write32(rtwdev, ++ rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_RRSC, mac_idx), ++ rrsc); ++ ++ return 0; ++} ++ ++void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ ++ if (rtw89_sta_has_beamformer_cap(sta)) { ++ rtw89_debug(rtwdev, RTW89_DBG_BF, ++ "initialize bfee for new association\n"); ++ rtw89_mac_init_bfee(rtwdev, rtwvif->mac_idx); ++ rtw89_mac_set_csi_para_reg(rtwdev, vif, sta); ++ rtw89_mac_csi_rrsc(rtwdev, vif, sta); ++ } ++} ++ ++void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ ++ rtw89_mac_bfee_ctrl(rtwdev, rtwvif->mac_idx, false); ++} ++ ++void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ++ struct ieee80211_bss_conf *conf) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ u8 mac_idx = rtwvif->mac_idx; ++ __le32 *p; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BF, "update bf GID table\n"); ++ ++ p = (__le32 *)conf->mu_group.membership; ++ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION_EN0, mac_idx), ++ le32_to_cpu(p[0])); ++ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION_EN1, mac_idx), ++ le32_to_cpu(p[1])); ++ ++ p = (__le32 *)conf->mu_group.position; ++ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION0, mac_idx), ++ le32_to_cpu(p[0])); ++ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION1, mac_idx), ++ le32_to_cpu(p[1])); ++ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION2, mac_idx), ++ le32_to_cpu(p[2])); ++ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION3, mac_idx), ++ le32_to_cpu(p[3])); ++} ++ ++struct rtw89_mac_bf_monitor_iter_data { ++ struct rtw89_dev *rtwdev; ++ struct ieee80211_sta *down_sta; ++ int count; ++}; ++ ++static ++void rtw89_mac_bf_monitor_calc_iter(void *data, struct ieee80211_sta *sta) ++{ ++ struct rtw89_mac_bf_monitor_iter_data *iter_data = ++ (struct rtw89_mac_bf_monitor_iter_data *)data; ++ struct ieee80211_sta *down_sta = iter_data->down_sta; ++ int *count = &iter_data->count; ++ ++ if (down_sta == sta) ++ return; ++ ++ if (rtw89_sta_has_beamformer_cap(sta)) ++ (*count)++; ++} ++ ++void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev, ++ struct ieee80211_sta *sta, bool disconnect) ++{ ++ struct rtw89_mac_bf_monitor_iter_data data; ++ ++ data.rtwdev = rtwdev; ++ data.down_sta = disconnect ? sta : NULL; ++ data.count = 0; ++ ieee80211_iterate_stations_atomic(rtwdev->hw, ++ rtw89_mac_bf_monitor_calc_iter, ++ &data); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BF, "bfee STA count=%d\n", data.count); ++ if (data.count) ++ set_bit(RTW89_FLAG_BFEE_MON, rtwdev->flags); ++ else ++ clear_bit(RTW89_FLAG_BFEE_MON, rtwdev->flags); ++} ++ ++void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_traffic_stats *stats = &rtwdev->stats; ++ struct rtw89_vif *rtwvif; ++ bool en = stats->tx_tfc_lv > stats->rx_tfc_lv ? false : true; ++ bool old = test_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags); ++ ++ if (en == old) ++ return; ++ ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ rtw89_mac_bfee_ctrl(rtwdev, rtwvif->mac_idx, en); ++} ++ ++static int ++__rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, ++ u32 tx_time) ++{ ++#define MAC_AX_DFLT_TX_TIME 5280 ++ u8 mac_idx = rtwsta->rtwvif->mac_idx; ++ u32 max_tx_time = tx_time == 0 ? MAC_AX_DFLT_TX_TIME : tx_time; ++ u32 reg; ++ int ret = 0; ++ ++ if (rtwsta->cctl_tx_time) { ++ rtwsta->ampdu_max_time = (max_tx_time - 512) >> 9; ++ ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta); ++ } else { ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to check cmac in set txtime\n"); ++ return ret; ++ } ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_AMPDU_AGG_LIMIT, mac_idx); ++ rtw89_write32_mask(rtwdev, reg, B_AX_AMPDU_MAX_TIME_MASK, ++ max_tx_time >> 5); ++ } ++ ++ return ret; ++} ++ ++int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, ++ bool resume, u32 tx_time) ++{ ++ int ret = 0; ++ ++ if (!resume) { ++ rtwsta->cctl_tx_time = true; ++ ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta, tx_time); ++ } else { ++ ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta, tx_time); ++ rtwsta->cctl_tx_time = false; ++ } ++ ++ return ret; ++} ++ ++int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, ++ u32 *tx_time) ++{ ++ u8 mac_idx = rtwsta->rtwvif->mac_idx; ++ u32 reg; ++ int ret = 0; ++ ++ if (rtwsta->cctl_tx_time) { ++ *tx_time = (rtwsta->ampdu_max_time + 1) << 9; ++ } else { ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to check cmac in tx_time\n"); ++ return ret; ++ } ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_AMPDU_AGG_LIMIT, mac_idx); ++ *tx_time = rtw89_read32_mask(rtwdev, reg, B_AX_AMPDU_MAX_TIME_MASK) << 5; ++ } ++ ++ return ret; ++} ++ ++int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev, ++ struct rtw89_sta *rtwsta, ++ bool resume, u8 tx_retry) ++{ ++ int ret = 0; ++ ++ rtwsta->data_tx_cnt_lmt = tx_retry; ++ ++ if (!resume) { ++ rtwsta->cctl_tx_retry_limit = true; ++ ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta); ++ } else { ++ ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta); ++ rtwsta->cctl_tx_retry_limit = false; ++ } ++ ++ return ret; ++} ++ ++int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev, ++ struct rtw89_sta *rtwsta, u8 *tx_retry) ++{ ++ u8 mac_idx = rtwsta->rtwvif->mac_idx; ++ u32 reg; ++ int ret = 0; ++ ++ if (rtwsta->cctl_tx_retry_limit) { ++ *tx_retry = rtwsta->data_tx_cnt_lmt; ++ } else { ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to check cmac in rty_lmt\n"); ++ return ret; ++ } ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TXCNT, mac_idx); ++ *tx_retry = rtw89_read32_mask(rtwdev, reg, B_AX_L_TXCNT_LMT_MASK); ++ } ++ ++ return ret; ++} ++ ++int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, bool en) ++{ ++ u8 mac_idx = rtwvif->mac_idx; ++ u16 set = B_AX_MUEDCA_EN_0 | B_AX_SET_MUEDCATIMER_TF_0; ++ u32 reg; ++ u32 ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_MUEDCA_EN, mac_idx); ++ if (en) ++ rtw89_write16_set(rtwdev, reg, set); ++ else ++ rtw89_write16_clr(rtwdev, reg, set); ++ ++ return 0; ++} +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +new file mode 100644 +index 000000000000..6f3db8a2a9c2 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -0,0 +1,860 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_MAC_H__ ++#define __RTW89_MAC_H__ ++ ++#include "core.h" ++ ++#define MAC_MEM_DUMP_PAGE_SIZE 0x40000 ++#define ADDR_CAM_ENT_SIZE 0x40 ++#define BSSID_CAM_ENT_SIZE 0x08 ++#define HFC_PAGE_UNIT 64 ++ ++enum rtw89_mac_hwmod_sel { ++ RTW89_DMAC_SEL = 0, ++ RTW89_CMAC_SEL = 1, ++ ++ RTW89_MAC_INVALID, ++}; ++ ++enum rtw89_mac_fwd_target { ++ RTW89_FWD_DONT_CARE = 0, ++ RTW89_FWD_TO_HOST = 1, ++ RTW89_FWD_TO_WLAN_CPU = 2 ++}; ++ ++enum rtw89_mac_wd_dma_intvl { ++ RTW89_MAC_WD_DMA_INTVL_0S, ++ RTW89_MAC_WD_DMA_INTVL_256NS, ++ RTW89_MAC_WD_DMA_INTVL_512NS, ++ RTW89_MAC_WD_DMA_INTVL_768NS, ++ RTW89_MAC_WD_DMA_INTVL_1US, ++ RTW89_MAC_WD_DMA_INTVL_1_5US, ++ RTW89_MAC_WD_DMA_INTVL_2US, ++ RTW89_MAC_WD_DMA_INTVL_4US, ++ RTW89_MAC_WD_DMA_INTVL_8US, ++ RTW89_MAC_WD_DMA_INTVL_16US, ++ RTW89_MAC_WD_DMA_INTVL_DEF = 0xFE ++}; ++ ++enum rtw89_mac_multi_tag_num { ++ RTW89_MAC_TAG_NUM_1, ++ RTW89_MAC_TAG_NUM_2, ++ RTW89_MAC_TAG_NUM_3, ++ RTW89_MAC_TAG_NUM_4, ++ RTW89_MAC_TAG_NUM_5, ++ RTW89_MAC_TAG_NUM_6, ++ RTW89_MAC_TAG_NUM_7, ++ RTW89_MAC_TAG_NUM_8, ++ RTW89_MAC_TAG_NUM_DEF = 0xFE ++}; ++ ++enum rtw89_mac_lbc_tmr { ++ RTW89_MAC_LBC_TMR_8US = 0, ++ RTW89_MAC_LBC_TMR_16US, ++ RTW89_MAC_LBC_TMR_32US, ++ RTW89_MAC_LBC_TMR_64US, ++ RTW89_MAC_LBC_TMR_128US, ++ RTW89_MAC_LBC_TMR_256US, ++ RTW89_MAC_LBC_TMR_512US, ++ RTW89_MAC_LBC_TMR_1MS, ++ RTW89_MAC_LBC_TMR_2MS, ++ RTW89_MAC_LBC_TMR_4MS, ++ RTW89_MAC_LBC_TMR_8MS, ++ RTW89_MAC_LBC_TMR_DEF = 0xFE ++}; ++ ++enum rtw89_mac_cpuio_op_cmd_type { ++ CPUIO_OP_CMD_GET_1ST_PID = 0, ++ CPUIO_OP_CMD_GET_NEXT_PID = 1, ++ CPUIO_OP_CMD_ENQ_TO_TAIL = 4, ++ CPUIO_OP_CMD_ENQ_TO_HEAD = 5, ++ CPUIO_OP_CMD_DEQ = 8, ++ CPUIO_OP_CMD_DEQ_ENQ_ALL = 9, ++ CPUIO_OP_CMD_DEQ_ENQ_TO_TAIL = 12 ++}; ++ ++enum rtw89_mac_wde_dle_port_id { ++ WDE_DLE_PORT_ID_DISPATCH = 0, ++ WDE_DLE_PORT_ID_PKTIN = 1, ++ WDE_DLE_PORT_ID_CMAC0 = 3, ++ WDE_DLE_PORT_ID_CMAC1 = 4, ++ WDE_DLE_PORT_ID_CPU_IO = 6, ++ WDE_DLE_PORT_ID_WDRLS = 7, ++ WDE_DLE_PORT_ID_END = 8 ++}; ++ ++enum rtw89_mac_wde_dle_queid_wdrls { ++ WDE_DLE_QUEID_TXOK = 0, ++ WDE_DLE_QUEID_DROP_RETRY_LIMIT = 1, ++ WDE_DLE_QUEID_DROP_LIFETIME_TO = 2, ++ WDE_DLE_QUEID_DROP_MACID_DROP = 3, ++ WDE_DLE_QUEID_NO_REPORT = 4 ++}; ++ ++enum rtw89_mac_ple_dle_port_id { ++ PLE_DLE_PORT_ID_DISPATCH = 0, ++ PLE_DLE_PORT_ID_MPDU = 1, ++ PLE_DLE_PORT_ID_SEC = 2, ++ PLE_DLE_PORT_ID_CMAC0 = 3, ++ PLE_DLE_PORT_ID_CMAC1 = 4, ++ PLE_DLE_PORT_ID_WDRLS = 5, ++ PLE_DLE_PORT_ID_CPU_IO = 6, ++ PLE_DLE_PORT_ID_PLRLS = 7, ++ PLE_DLE_PORT_ID_END = 8 ++}; ++ ++enum rtw89_mac_ple_dle_queid_plrls { ++ PLE_DLE_QUEID_NO_REPORT = 0x0 ++}; ++ ++enum rtw89_machdr_frame_type { ++ RTW89_MGNT = 0, ++ RTW89_CTRL = 1, ++ RTW89_DATA = 2, ++}; ++ ++enum rtw89_mac_dle_dfi_type { ++ DLE_DFI_TYPE_FREEPG = 0, ++ DLE_DFI_TYPE_QUOTA = 1, ++ DLE_DFI_TYPE_PAGELLT = 2, ++ DLE_DFI_TYPE_PKTINFO = 3, ++ DLE_DFI_TYPE_PREPKTLLT = 4, ++ DLE_DFI_TYPE_NXTPKTLLT = 5, ++ DLE_DFI_TYPE_QLNKTBL = 6, ++ DLE_DFI_TYPE_QEMPTY = 7, ++}; ++ ++enum rtw89_mac_dle_wde_quota_id { ++ WDE_QTAID_HOST_IF = 0, ++ WDE_QTAID_WLAN_CPU = 1, ++ WDE_QTAID_DATA_CPU = 2, ++ WDE_QTAID_PKTIN = 3, ++ WDE_QTAID_CPUIO = 4, ++}; ++ ++enum rtw89_mac_dle_ple_quota_id { ++ PLE_QTAID_B0_TXPL = 0, ++ PLE_QTAID_B1_TXPL = 1, ++ PLE_QTAID_C2H = 2, ++ PLE_QTAID_H2C = 3, ++ PLE_QTAID_WLAN_CPU = 4, ++ PLE_QTAID_MPDU = 5, ++ PLE_QTAID_CMAC0_RX = 6, ++ PLE_QTAID_CMAC1_RX = 7, ++ PLE_QTAID_CMAC1_BBRPT = 8, ++ PLE_QTAID_WDRLS = 9, ++ PLE_QTAID_CPUIO = 10, ++}; ++ ++enum rtw89_mac_dle_ctrl_type { ++ DLE_CTRL_TYPE_WDE = 0, ++ DLE_CTRL_TYPE_PLE = 1, ++ DLE_CTRL_TYPE_NUM = 2, ++}; ++ ++enum rtw89_mac_ax_l0_to_l1_event { ++ MAC_AX_L0_TO_L1_CHIF_IDLE = 0, ++ MAC_AX_L0_TO_L1_CMAC_DMA_IDLE = 1, ++ MAC_AX_L0_TO_L1_RLS_PKID = 2, ++ MAC_AX_L0_TO_L1_PTCL_IDLE = 3, ++ MAC_AX_L0_TO_L1_RX_QTA_LOST = 4, ++ MAC_AX_L0_TO_L1_DLE_STAT_HANG = 5, ++ MAC_AX_L0_TO_L1_PCIE_STUCK = 6, ++ MAC_AX_L0_TO_L1_EVENT_MAX = 15, ++}; ++ ++enum rtw89_mac_dbg_port_sel { ++ /* CMAC 0 related */ ++ RTW89_DBG_PORT_SEL_PTCL_C0 = 0, ++ RTW89_DBG_PORT_SEL_SCH_C0, ++ RTW89_DBG_PORT_SEL_TMAC_C0, ++ RTW89_DBG_PORT_SEL_RMAC_C0, ++ RTW89_DBG_PORT_SEL_RMACST_C0, ++ RTW89_DBG_PORT_SEL_RMAC_PLCP_C0, ++ RTW89_DBG_PORT_SEL_TRXPTCL_C0, ++ RTW89_DBG_PORT_SEL_TX_INFOL_C0, ++ RTW89_DBG_PORT_SEL_TX_INFOH_C0, ++ RTW89_DBG_PORT_SEL_TXTF_INFOL_C0, ++ RTW89_DBG_PORT_SEL_TXTF_INFOH_C0, ++ /* CMAC 1 related */ ++ RTW89_DBG_PORT_SEL_PTCL_C1, ++ RTW89_DBG_PORT_SEL_SCH_C1, ++ RTW89_DBG_PORT_SEL_TMAC_C1, ++ RTW89_DBG_PORT_SEL_RMAC_C1, ++ RTW89_DBG_PORT_SEL_RMACST_C1, ++ RTW89_DBG_PORT_SEL_RMAC_PLCP_C1, ++ RTW89_DBG_PORT_SEL_TRXPTCL_C1, ++ RTW89_DBG_PORT_SEL_TX_INFOL_C1, ++ RTW89_DBG_PORT_SEL_TX_INFOH_C1, ++ RTW89_DBG_PORT_SEL_TXTF_INFOL_C1, ++ RTW89_DBG_PORT_SEL_TXTF_INFOH_C1, ++ /* DLE related */ ++ RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG, ++ RTW89_DBG_PORT_SEL_WDE_BUFMGN_QUOTA, ++ RTW89_DBG_PORT_SEL_WDE_BUFMGN_PAGELLT, ++ RTW89_DBG_PORT_SEL_WDE_BUFMGN_PKTINFO, ++ RTW89_DBG_PORT_SEL_WDE_QUEMGN_PREPKT, ++ RTW89_DBG_PORT_SEL_WDE_QUEMGN_NXTPKT, ++ RTW89_DBG_PORT_SEL_WDE_QUEMGN_QLNKTBL, ++ RTW89_DBG_PORT_SEL_WDE_QUEMGN_QEMPTY, ++ RTW89_DBG_PORT_SEL_PLE_BUFMGN_FREEPG, ++ RTW89_DBG_PORT_SEL_PLE_BUFMGN_QUOTA, ++ RTW89_DBG_PORT_SEL_PLE_BUFMGN_PAGELLT, ++ RTW89_DBG_PORT_SEL_PLE_BUFMGN_PKTINFO, ++ RTW89_DBG_PORT_SEL_PLE_QUEMGN_PREPKT, ++ RTW89_DBG_PORT_SEL_PLE_QUEMGN_NXTPKT, ++ RTW89_DBG_PORT_SEL_PLE_QUEMGN_QLNKTBL, ++ RTW89_DBG_PORT_SEL_PLE_QUEMGN_QEMPTY, ++ RTW89_DBG_PORT_SEL_PKTINFO, ++ /* PCIE related */ ++ RTW89_DBG_PORT_SEL_PCIE_TXDMA, ++ RTW89_DBG_PORT_SEL_PCIE_RXDMA, ++ RTW89_DBG_PORT_SEL_PCIE_CVT, ++ RTW89_DBG_PORT_SEL_PCIE_CXPL, ++ RTW89_DBG_PORT_SEL_PCIE_IO, ++ RTW89_DBG_PORT_SEL_PCIE_MISC, ++ RTW89_DBG_PORT_SEL_PCIE_MISC2, ++ ++ /* keep last */ ++ RTW89_DBG_PORT_SEL_LAST, ++ RTW89_DBG_PORT_SEL_MAX = RTW89_DBG_PORT_SEL_LAST, ++ RTW89_DBG_PORT_SEL_INVALID = RTW89_DBG_PORT_SEL_LAST, ++}; ++ ++/* SRAM mem dump */ ++#define R_AX_INDIR_ACCESS_ENTRY 0x40000 ++ ++#define STA_SCHED_BASE_ADDR 0x18808000 ++#define RXPLD_FLTR_CAM_BASE_ADDR 0x18813000 ++#define SECURITY_CAM_BASE_ADDR 0x18814000 ++#define WOW_CAM_BASE_ADDR 0x18815000 ++#define CMAC_TBL_BASE_ADDR 0x18840000 ++#define ADDR_CAM_BASE_ADDR 0x18850000 ++#define BSSID_CAM_BASE_ADDR 0x18853000 ++#define BA_CAM_BASE_ADDR 0x18854000 ++#define BCN_IE_CAM0_BASE_ADDR 0x18855000 ++#define SHARED_BUF_BASE_ADDR 0x18700000 ++#define DMAC_TBL_BASE_ADDR 0x18800000 ++#define SHCUT_MACHDR_BASE_ADDR 0x18800800 ++#define BCN_IE_CAM1_BASE_ADDR 0x188A0000 ++ ++#define CCTL_INFO_SIZE 32 ++ ++enum rtw89_mac_mem_sel { ++ RTW89_MAC_MEM_SHARED_BUF, ++ RTW89_MAC_MEM_DMAC_TBL, ++ RTW89_MAC_MEM_SHCUT_MACHDR, ++ RTW89_MAC_MEM_STA_SCHED, ++ RTW89_MAC_MEM_RXPLD_FLTR_CAM, ++ RTW89_MAC_MEM_SECURITY_CAM, ++ RTW89_MAC_MEM_WOW_CAM, ++ RTW89_MAC_MEM_CMAC_TBL, ++ RTW89_MAC_MEM_ADDR_CAM, ++ RTW89_MAC_MEM_BA_CAM, ++ RTW89_MAC_MEM_BCN_IE_CAM0, ++ RTW89_MAC_MEM_BCN_IE_CAM1, ++ ++ /* keep last */ ++ RTW89_MAC_MEM_LAST, ++ RTW89_MAC_MEM_MAX = RTW89_MAC_MEM_LAST, ++ RTW89_MAC_MEM_INVALID = RTW89_MAC_MEM_LAST, ++}; ++ ++enum rtw89_rpwm_req_pwr_state { ++ RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE = 0, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFON = 1, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_BAND1_RFON = 2, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFOFF = 3, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_BAND1_RFOFF = 4, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED = 5, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_PWR_GATED = 6, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_HIOE_PWR_GATED = 7, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_MAX, ++}; ++ ++struct rtw89_pwr_cfg { ++ u16 addr; ++ u8 cv_msk; ++ u8 intf_msk; ++ u8 base:4; ++ u8 cmd:4; ++ u8 msk; ++ u8 val; ++}; ++ ++enum rtw89_mac_c2h_ofld_func { ++ RTW89_MAC_C2H_FUNC_EFUSE_DUMP, ++ RTW89_MAC_C2H_FUNC_READ_RSP, ++ RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP, ++ RTW89_MAC_C2H_FUNC_BCN_RESEND, ++ RTW89_MAC_C2H_FUNC_MACID_PAUSE, ++ RTW89_MAC_C2H_FUNC_OFLD_MAX, ++}; ++ ++enum rtw89_mac_c2h_info_func { ++ RTW89_MAC_C2H_FUNC_REC_ACK, ++ RTW89_MAC_C2H_FUNC_DONE_ACK, ++ RTW89_MAC_C2H_FUNC_C2H_LOG, ++ RTW89_MAC_C2H_FUNC_INFO_MAX, ++}; ++ ++enum rtw89_mac_c2h_class { ++ RTW89_MAC_C2H_CLASS_INFO, ++ RTW89_MAC_C2H_CLASS_OFLD, ++ RTW89_MAC_C2H_CLASS_TWT, ++ RTW89_MAC_C2H_CLASS_WOW, ++ RTW89_MAC_C2H_CLASS_MCC, ++ RTW89_MAC_C2H_CLASS_FWDBG, ++ RTW89_MAC_C2H_CLASS_MAX, ++}; ++ ++struct rtw89_mac_ax_coex { ++#define RTW89_MAC_AX_COEX_RTK_MODE 0 ++#define RTW89_MAC_AX_COEX_CSR_MODE 1 ++ u8 pta_mode; ++#define RTW89_MAC_AX_COEX_INNER 0 ++#define RTW89_MAC_AX_COEX_OUTPUT 1 ++#define RTW89_MAC_AX_COEX_INPUT 2 ++ u8 direction; ++}; ++ ++struct rtw89_mac_ax_plt { ++#define RTW89_MAC_AX_PLT_LTE_RX BIT(0) ++#define RTW89_MAC_AX_PLT_GNT_BT_TX BIT(1) ++#define RTW89_MAC_AX_PLT_GNT_BT_RX BIT(2) ++#define RTW89_MAC_AX_PLT_GNT_WL BIT(3) ++ u8 band; ++ u8 tx; ++ u8 rx; ++}; ++ ++enum rtw89_mac_bf_rrsc_rate { ++ RTW89_MAC_BF_RRSC_6M = 0, ++ RTW89_MAC_BF_RRSC_9M = 1, ++ RTW89_MAC_BF_RRSC_12M, ++ RTW89_MAC_BF_RRSC_18M, ++ RTW89_MAC_BF_RRSC_24M, ++ RTW89_MAC_BF_RRSC_36M, ++ RTW89_MAC_BF_RRSC_48M, ++ RTW89_MAC_BF_RRSC_54M, ++ RTW89_MAC_BF_RRSC_HT_MSC0, ++ RTW89_MAC_BF_RRSC_HT_MSC1, ++ RTW89_MAC_BF_RRSC_HT_MSC2, ++ RTW89_MAC_BF_RRSC_HT_MSC3, ++ RTW89_MAC_BF_RRSC_HT_MSC4, ++ RTW89_MAC_BF_RRSC_HT_MSC5, ++ RTW89_MAC_BF_RRSC_HT_MSC6, ++ RTW89_MAC_BF_RRSC_HT_MSC7, ++ RTW89_MAC_BF_RRSC_VHT_MSC0, ++ RTW89_MAC_BF_RRSC_VHT_MSC1, ++ RTW89_MAC_BF_RRSC_VHT_MSC2, ++ RTW89_MAC_BF_RRSC_VHT_MSC3, ++ RTW89_MAC_BF_RRSC_VHT_MSC4, ++ RTW89_MAC_BF_RRSC_VHT_MSC5, ++ RTW89_MAC_BF_RRSC_VHT_MSC6, ++ RTW89_MAC_BF_RRSC_VHT_MSC7, ++ RTW89_MAC_BF_RRSC_HE_MSC0, ++ RTW89_MAC_BF_RRSC_HE_MSC1, ++ RTW89_MAC_BF_RRSC_HE_MSC2, ++ RTW89_MAC_BF_RRSC_HE_MSC3, ++ RTW89_MAC_BF_RRSC_HE_MSC4, ++ RTW89_MAC_BF_RRSC_HE_MSC5, ++ RTW89_MAC_BF_RRSC_HE_MSC6, ++ RTW89_MAC_BF_RRSC_HE_MSC7 = 31, ++ RTW89_MAC_BF_RRSC_MAX = 32 ++}; ++ ++#define RTW89_R32_EA 0xEAEAEAEA ++#define RTW89_R32_DEAD 0xDEADBEEF ++#define MAC_REG_POOL_COUNT 10 ++#define ACCESS_CMAC(_addr) \ ++ ({typeof(_addr) __addr = (_addr); \ ++ __addr >= R_AX_CMAC_REG_START && __addr <= R_AX_CMAC_REG_END; }) ++ ++#define PTCL_IDLE_POLL_CNT 10000 ++#define SW_CVR_DUR_US 8 ++#define SW_CVR_CNT 8 ++ ++#define DLE_BOUND_UNIT (8 * 1024) ++#define DLE_WAIT_CNT 2000 ++#define TRXCFG_WAIT_CNT 2000 ++ ++#define RTW89_WDE_PG_64 64 ++#define RTW89_WDE_PG_128 128 ++#define RTW89_WDE_PG_256 256 ++ ++#define S_AX_WDE_PAGE_SEL_64 0 ++#define S_AX_WDE_PAGE_SEL_128 1 ++#define S_AX_WDE_PAGE_SEL_256 2 ++ ++#define RTW89_PLE_PG_64 64 ++#define RTW89_PLE_PG_128 128 ++#define RTW89_PLE_PG_256 256 ++ ++#define S_AX_PLE_PAGE_SEL_64 0 ++#define S_AX_PLE_PAGE_SEL_128 1 ++#define S_AX_PLE_PAGE_SEL_256 2 ++ ++#define SDIO_LOCAL_BASE_ADDR 0x80000000 ++ ++#define PWR_CMD_WRITE 0 ++#define PWR_CMD_POLL 1 ++#define PWR_CMD_DELAY 2 ++#define PWR_CMD_END 3 ++ ++#define PWR_INTF_MSK_SDIO BIT(0) ++#define PWR_INTF_MSK_USB BIT(1) ++#define PWR_INTF_MSK_PCIE BIT(2) ++#define PWR_INTF_MSK_ALL 0x7 ++ ++#define PWR_BASE_MAC 0 ++#define PWR_BASE_USB 1 ++#define PWR_BASE_PCIE 2 ++#define PWR_BASE_SDIO 3 ++ ++#define PWR_CV_MSK_A BIT(0) ++#define PWR_CV_MSK_B BIT(1) ++#define PWR_CV_MSK_C BIT(2) ++#define PWR_CV_MSK_D BIT(3) ++#define PWR_CV_MSK_E BIT(4) ++#define PWR_CV_MSK_F BIT(5) ++#define PWR_CV_MSK_G BIT(6) ++#define PWR_CV_MSK_TEST BIT(7) ++#define PWR_CV_MSK_ALL 0xFF ++ ++#define PWR_DELAY_US 0 ++#define PWR_DELAY_MS 1 ++ ++/* STA scheduler */ ++#define SS_MACID_SH 8 ++#define SS_TX_LEN_MSK 0x1FFFFF ++#define SS_CTRL1_R_TX_LEN 5 ++#define SS_CTRL1_R_NEXT_LINK 20 ++#define SS_LINK_SIZE 256 ++ ++/* MAC debug port */ ++#define TMAC_DBG_SEL_C0 0xA5 ++#define RMAC_DBG_SEL_C0 0xA6 ++#define TRXPTCL_DBG_SEL_C0 0xA7 ++#define TMAC_DBG_SEL_C1 0xB5 ++#define RMAC_DBG_SEL_C1 0xB6 ++#define TRXPTCL_DBG_SEL_C1 0xB7 ++#define FW_PROG_CNTR_DBG_SEL 0xF2 ++#define PCIE_TXDMA_DBG_SEL 0x30 ++#define PCIE_RXDMA_DBG_SEL 0x31 ++#define PCIE_CVT_DBG_SEL 0x32 ++#define PCIE_CXPL_DBG_SEL 0x33 ++#define PCIE_IO_DBG_SEL 0x37 ++#define PCIE_MISC_DBG_SEL 0x38 ++#define PCIE_MISC2_DBG_SEL 0x00 ++#define MAC_DBG_SEL 1 ++#define RMAC_CMAC_DBG_SEL 1 ++ ++/* TRXPTCL dbg port sel */ ++#define TRXPTRL_DBG_SEL_TMAC 0 ++#define TRXPTRL_DBG_SEL_RMAC 1 ++ ++struct rtw89_cpuio_ctrl { ++ u16 pkt_num; ++ u16 start_pktid; ++ u16 end_pktid; ++ u8 cmd_type; ++ u8 macid; ++ u8 src_pid; ++ u8 src_qid; ++ u8 dst_pid; ++ u8 dst_qid; ++ u16 pktid; ++}; ++ ++struct rtw89_mac_dbg_port_info { ++ u32 sel_addr; ++ u8 sel_byte; ++ u32 sel_msk; ++ u32 srt; ++ u32 end; ++ u32 rd_addr; ++ u8 rd_byte; ++ u32 rd_msk; ++}; ++ ++#define QLNKTBL_ADDR_INFO_SEL BIT(0) ++#define QLNKTBL_ADDR_INFO_SEL_0 0 ++#define QLNKTBL_ADDR_INFO_SEL_1 1 ++#define QLNKTBL_ADDR_TBL_IDX_MASK GENMASK(10, 1) ++#define QLNKTBL_DATA_SEL1_PKT_CNT_MASK GENMASK(11, 0) ++ ++struct rtw89_mac_dle_dfi_ctrl { ++ enum rtw89_mac_dle_ctrl_type type; ++ u32 target; ++ u32 addr; ++ u32 out_data; ++}; ++ ++struct rtw89_mac_dle_dfi_quota { ++ enum rtw89_mac_dle_ctrl_type dle_type; ++ u32 qtaid; ++ u16 rsv_pgnum; ++ u16 use_pgnum; ++}; ++ ++struct rtw89_mac_dle_dfi_qempty { ++ enum rtw89_mac_dle_ctrl_type dle_type; ++ u32 grpsel; ++ u32 qempty; ++}; ++ ++/* Define DBG and recovery enum */ ++enum mac_ax_err_info { ++ /* Get error info */ ++ ++ /* L0 */ ++ MAC_AX_ERR_L0_ERR_CMAC0 = 0x0001, ++ MAC_AX_ERR_L0_ERR_CMAC1 = 0x0002, ++ MAC_AX_ERR_L0_RESET_DONE = 0x0003, ++ MAC_AX_ERR_L0_PROMOTE_TO_L1 = 0x0010, ++ ++ /* L1 */ ++ MAC_AX_ERR_L1_ERR_DMAC = 0x1000, ++ MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE = 0x1001, ++ MAC_AX_ERR_L1_RESET_RECOVERY_DONE = 0x1002, ++ MAC_AX_ERR_L1_PROMOTE_TO_L2 = 0x1010, ++ MAC_AX_ERR_L1_RCVY_STOP_DONE = 0x1011, ++ ++ /* L2 */ ++ /* address hole (master) */ ++ MAC_AX_ERR_L2_ERR_AH_DMA = 0x2000, ++ MAC_AX_ERR_L2_ERR_AH_HCI = 0x2010, ++ MAC_AX_ERR_L2_ERR_AH_RLX4081 = 0x2020, ++ MAC_AX_ERR_L2_ERR_AH_IDDMA = 0x2030, ++ MAC_AX_ERR_L2_ERR_AH_HIOE = 0x2040, ++ MAC_AX_ERR_L2_ERR_AH_IPSEC = 0x2050, ++ MAC_AX_ERR_L2_ERR_AH_RX4281 = 0x2060, ++ MAC_AX_ERR_L2_ERR_AH_OTHERS = 0x2070, ++ ++ /* AHB bridge timeout (master) */ ++ MAC_AX_ERR_L2_ERR_AHB_TO_DMA = 0x2100, ++ MAC_AX_ERR_L2_ERR_AHB_TO_HCI = 0x2110, ++ MAC_AX_ERR_L2_ERR_AHB_TO_RLX4081 = 0x2120, ++ MAC_AX_ERR_L2_ERR_AHB_TO_IDDMA = 0x2130, ++ MAC_AX_ERR_L2_ERR_AHB_TO_HIOE = 0x2140, ++ MAC_AX_ERR_L2_ERR_AHB_TO_IPSEC = 0x2150, ++ MAC_AX_ERR_L2_ERR_AHB_TO_RX4281 = 0x2160, ++ MAC_AX_ERR_L2_ERR_AHB_TO_OTHERS = 0x2170, ++ ++ /* APB_SA bridge timeout (master + slave) */ ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WVA = 0x2200, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_UART = 0x2201, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_CPULOCAL = 0x2202, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_AXIDMA = 0x2203, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_HIOE = 0x2204, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_IDDMA = 0x2205, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_IPSEC = 0x2206, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WON = 0x2207, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WDMAC = 0x2208, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WCMAC = 0x2209, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_OTHERS = 0x220A, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_WVA = 0x2210, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_UART = 0x2211, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_CPULOCAL = 0x2212, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_AXIDMA = 0x2213, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_HIOE = 0x2214, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_IDDMA = 0x2215, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_IPSEC = 0x2216, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_WDMAC = 0x2218, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_WCMAC = 0x2219, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_OTHERS = 0x221A, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WVA = 0x2220, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_UART = 0x2221, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_CPULOCAL = 0x2222, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_AXIDMA = 0x2223, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_HIOE = 0x2224, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_IDDMA = 0x2225, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_IPSEC = 0x2226, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WON = 0x2227, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WDMAC = 0x2228, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WCMAC = 0x2229, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_OTHERS = 0x222A, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WVA = 0x2230, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_UART = 0x2231, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_CPULOCAL = 0x2232, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_AXIDMA = 0x2233, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_HIOE = 0x2234, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_IDDMA = 0x2235, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_IPSEC = 0x2236, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WON = 0x2237, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WDMAC = 0x2238, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WCMAC = 0x2239, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_OTHERS = 0x223A, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WVA = 0x2240, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_UART = 0x2241, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_CPULOCAL = 0x2242, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_AXIDMA = 0x2243, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_HIOE = 0x2244, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_IDDMA = 0x2245, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_IPSEC = 0x2246, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WON = 0x2247, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WDMAC = 0x2248, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WCMAC = 0x2249, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_OTHERS = 0x224A, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WVA = 0x2250, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_UART = 0x2251, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_CPULOCAL = 0x2252, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_AXIDMA = 0x2253, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_HIOE = 0x2254, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_IDDMA = 0x2255, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_IPSEC = 0x2256, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WON = 0x2257, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WDMAC = 0x2258, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WCMAC = 0x2259, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_OTHERS = 0x225A, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WVA = 0x2260, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_UART = 0x2261, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_CPULOCAL = 0x2262, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_AXIDMA = 0x2263, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_HIOE = 0x2264, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_IDDMA = 0x2265, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_IPSEC = 0x2266, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WON = 0x2267, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WDMAC = 0x2268, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WCMAC = 0x2269, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_OTHERS = 0x226A, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WVA = 0x2270, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_UART = 0x2271, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_CPULOCAL = 0x2272, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_AXIDMA = 0x2273, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_HIOE = 0x2274, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_IDDMA = 0x2275, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_IPSEC = 0x2276, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WON = 0x2277, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WDMAC = 0x2278, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WCMAC = 0x2279, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_OTHERS = 0x227A, ++ ++ /* APB_BBRF bridge timeout (master) */ ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_DMA = 0x2300, ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_HCI = 0x2310, ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_RLX4081 = 0x2320, ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_IDDMA = 0x2330, ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_HIOE = 0x2340, ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_IPSEC = 0x2350, ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_RX4281 = 0x2360, ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_OTHERS = 0x2370, ++ MAC_AX_ERR_L2_RESET_DONE = 0x2400, ++ MAC_AX_ERR_CPU_EXCEPTION = 0x3000, ++ MAC_AX_GET_ERR_MAX, ++ MAC_AX_DUMP_SHAREBUFF_INDICATOR = 0x80000000, ++ ++ /* set error info */ ++ MAC_AX_ERR_L1_DISABLE_EN = 0x0001, ++ MAC_AX_ERR_L1_RCVY_EN = 0x0002, ++ MAC_AX_ERR_L1_RCVY_STOP_REQ = 0x0003, ++ MAC_AX_ERR_L1_RCVY_START_REQ = 0x0004, ++ MAC_AX_ERR_L0_CFG_NOTIFY = 0x0010, ++ MAC_AX_ERR_L0_CFG_DIS_NOTIFY = 0x0011, ++ MAC_AX_ERR_L0_CFG_HANDSHAKE = 0x0012, ++ MAC_AX_ERR_L0_RCVY_EN = 0x0013, ++ MAC_AX_SET_ERR_MAX, ++}; ++ ++extern const struct rtw89_hfc_prec_cfg rtw_hfc_preccfg_pcie; ++extern const struct rtw89_dle_size wde_size0; ++extern const struct rtw89_dle_size wde_size4; ++extern const struct rtw89_dle_size ple_size0; ++extern const struct rtw89_dle_size ple_size4; ++extern const struct rtw89_wde_quota wde_qt0; ++extern const struct rtw89_wde_quota wde_qt4; ++extern const struct rtw89_ple_quota ple_qt4; ++extern const struct rtw89_ple_quota ple_qt5; ++extern const struct rtw89_ple_quota ple_qt13; ++ ++static inline u32 rtw89_mac_reg_by_idx(u32 reg_base, u8 band) ++{ ++ return band == 0 ? reg_base : (reg_base + 0x2000); ++} ++ ++static inline u32 rtw89_mac_reg_by_port(u32 base, u8 port, u8 mac_idx) ++{ ++ return rtw89_mac_reg_by_idx(base + port * 0x40, mac_idx); ++} ++ ++static inline u32 ++rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u32 base, u32 mask) ++{ ++ u32 reg; ++ ++ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); ++ return rtw89_read32_mask(rtwdev, reg, mask); ++} ++ ++static inline void ++rtw89_write32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base, ++ u32 data) ++{ ++ u32 reg; ++ ++ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); ++ rtw89_write32(rtwdev, reg, data); ++} ++ ++static inline void ++rtw89_write32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u32 base, u32 mask, u32 data) ++{ ++ u32 reg; ++ ++ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); ++ rtw89_write32_mask(rtwdev, reg, mask, data); ++} ++ ++static inline void ++rtw89_write16_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u32 base, u32 mask, u16 data) ++{ ++ u32 reg; ++ ++ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); ++ rtw89_write16_mask(rtwdev, reg, mask, data); ++} ++ ++static inline void ++rtw89_write32_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u32 base, u32 bit) ++{ ++ u32 reg; ++ ++ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); ++ rtw89_write32_clr(rtwdev, reg, bit); ++} ++ ++static inline void ++rtw89_write16_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u32 base, u16 bit) ++{ ++ u32 reg; ++ ++ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); ++ rtw89_write16_clr(rtwdev, reg, bit); ++} ++ ++static inline void ++rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u32 base, u32 bit) ++{ ++ u32 reg; ++ ++ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); ++ rtw89_write32_set(rtwdev, reg, bit); ++} ++ ++void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev); ++int rtw89_mac_partial_init(struct rtw89_dev *rtwdev); ++int rtw89_mac_init(struct rtw89_dev *rtwdev); ++int rtw89_mac_check_mac_en(struct rtw89_dev *rtwdev, u8 band, ++ enum rtw89_mac_hwmod_sel sel); ++int rtw89_mac_write_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 val); ++int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val); ++int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); ++int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); ++int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); ++void rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev); ++void rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev); ++u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev); ++int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err); ++void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, ++ u32 len, u8 class, u8 func); ++int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev); ++int rtw89_mac_stop_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, ++ u16 *tx_en, enum rtw89_sch_tx_sel sel); ++int rtw89_mac_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u16 tx_en); ++int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_ids, bool enable); ++void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx); ++void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop); ++int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex); ++int rtw89_mac_cfg_gnt(struct rtw89_dev *rtwdev, ++ const struct rtw89_mac_ax_coex_gnt *gnt_cfg); ++int rtw89_mac_cfg_plt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt); ++void rtw89_mac_cfg_sb(struct rtw89_dev *rtwdev, u32 val); ++u32 rtw89_mac_get_sb(struct rtw89_dev *rtwdev); ++bool rtw89_mac_get_ctrl_path(struct rtw89_dev *rtwdev); ++int rtw89_mac_cfg_ctrl_path(struct rtw89_dev *rtwdev, bool wl); ++bool rtw89_mac_get_txpwr_cr(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, ++ u32 reg_base, u32 *cr); ++void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter); ++void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ++ struct ieee80211_bss_conf *conf); ++void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev, ++ struct ieee80211_sta *sta, bool disconnect); ++void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev); ++int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); ++int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); ++int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, bool en); ++ ++static inline void rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev) ++{ ++ if (!test_bit(RTW89_FLAG_BFEE_MON, rtwdev->flags)) ++ return; ++ ++ _rtw89_mac_bf_monitor_track(rtwdev); ++} ++ ++static inline int rtw89_mac_txpwr_read32(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, ++ u32 reg_base, u32 *val) ++{ ++ u32 cr; ++ ++ if (!rtw89_mac_get_txpwr_cr(rtwdev, phy_idx, reg_base, &cr)) ++ return -EINVAL; ++ ++ *val = rtw89_read32(rtwdev, cr); ++ return 0; ++} ++ ++static inline int rtw89_mac_txpwr_write32(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, ++ u32 reg_base, u32 val) ++{ ++ u32 cr; ++ ++ if (!rtw89_mac_get_txpwr_cr(rtwdev, phy_idx, reg_base, &cr)) ++ return -EINVAL; ++ ++ rtw89_write32(rtwdev, cr, val); ++ return 0; ++} ++ ++static inline int rtw89_mac_txpwr_write32_mask(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, ++ u32 reg_base, u32 mask, u32 val) ++{ ++ u32 cr; ++ ++ if (!rtw89_mac_get_txpwr_cr(rtwdev, phy_idx, reg_base, &cr)) ++ return -EINVAL; ++ ++ rtw89_write32_mask(rtwdev, cr, mask, val); ++ return 0; ++} ++ ++int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, ++ bool resume, u32 tx_time); ++int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, ++ u32 *tx_time); ++int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev, ++ struct rtw89_sta *rtwsta, ++ bool resume, u8 tx_retry); ++int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev, ++ struct rtw89_sta *rtwsta, u8 *tx_retry); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c +new file mode 100644 +index 000000000000..16dc6fb7dbb0 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/mac80211.c +@@ -0,0 +1,676 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "cam.h" ++#include "coex.h" ++#include "debug.h" ++#include "fw.h" ++#include "mac.h" ++#include "phy.h" ++#include "ps.h" ++#include "reg.h" ++#include "sar.h" ++#include "ser.h" ++ ++static void rtw89_ops_tx(struct ieee80211_hw *hw, ++ struct ieee80211_tx_control *control, ++ struct sk_buff *skb) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ struct ieee80211_vif *vif = info->control.vif; ++ struct ieee80211_sta *sta = control->sta; ++ int ret, qsel; ++ ++ ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to transmit skb: %d\n", ret); ++ ieee80211_free_txskb(hw, skb); ++ } ++ rtw89_core_tx_kick_off(rtwdev, qsel); ++} ++ ++static void rtw89_ops_wake_tx_queue(struct ieee80211_hw *hw, ++ struct ieee80211_txq *txq) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ ieee80211_schedule_txq(hw, txq); ++ queue_work(rtwdev->txq_wq, &rtwdev->txq_work); ++} ++ ++static int rtw89_ops_start(struct ieee80211_hw *hw) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ int ret; ++ ++ mutex_lock(&rtwdev->mutex); ++ ret = rtw89_core_start(rtwdev); ++ mutex_unlock(&rtwdev->mutex); ++ ++ return ret; ++} ++ ++static void rtw89_ops_stop(struct ieee80211_hw *hw) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_core_stop(rtwdev); ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ ++ if ((changed & IEEE80211_CONF_CHANGE_IDLE) && ++ !(hw->conf.flags & IEEE80211_CONF_IDLE)) ++ rtw89_leave_ips(rtwdev); ++ ++ if (changed & IEEE80211_CONF_CHANGE_PS) { ++ if (hw->conf.flags & IEEE80211_CONF_PS) { ++ rtwdev->lps_enabled = true; ++ } else { ++ rtw89_leave_lps(rtwdev); ++ rtwdev->lps_enabled = false; ++ } ++ } ++ ++ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) ++ rtw89_set_channel(rtwdev); ++ ++ if ((changed & IEEE80211_CONF_CHANGE_IDLE) && ++ (hw->conf.flags & IEEE80211_CONF_IDLE)) ++ rtw89_enter_ips(rtwdev); ++ ++ mutex_unlock(&rtwdev->mutex); ++ ++ return 0; ++} ++ ++static int rtw89_ops_add_interface(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ int ret = 0; ++ ++ mutex_lock(&rtwdev->mutex); ++ list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list); ++ rtw89_leave_ps_mode(rtwdev); ++ ++ rtw89_traffic_stats_init(rtwdev, &rtwvif->stats); ++ rtw89_vif_type_mapping(vif, false); ++ rtwvif->port = rtw89_core_acquire_bit_map(rtwdev->hw_port, ++ RTW89_MAX_HW_PORT_NUM); ++ if (rtwvif->port == RTW89_MAX_HW_PORT_NUM) { ++ ret = -ENOSPC; ++ goto out; ++ } ++ ++ rtwvif->bcn_hit_cond = 0; ++ rtwvif->mac_idx = RTW89_MAC_0; ++ rtwvif->phy_idx = RTW89_PHY_0; ++ rtwvif->hit_rule = 0; ++ ether_addr_copy(rtwvif->mac_addr, vif->addr); ++ ++ ret = rtw89_mac_add_vif(rtwdev, rtwvif); ++ if (ret) { ++ rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port); ++ goto out; ++ } ++ ++ rtw89_core_txq_init(rtwdev, vif->txq); ++ ++ rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_START); ++out: ++ mutex_unlock(&rtwdev->mutex); ++ ++ return ret; ++} ++ ++static void rtw89_ops_remove_interface(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_STOP); ++ rtw89_mac_remove_vif(rtwdev, rtwvif); ++ rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port); ++ list_del_init(&rtwvif->list); ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static void rtw89_ops_configure_filter(struct ieee80211_hw *hw, ++ unsigned int changed_flags, ++ unsigned int *new_flags, ++ u64 multicast) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ ++ *new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL | ++ FIF_BCN_PRBRESP_PROMISC; ++ ++ if (changed_flags & FIF_ALLMULTI) { ++ if (*new_flags & FIF_ALLMULTI) ++ rtwdev->hal.rx_fltr &= ~B_AX_A_MC; ++ else ++ rtwdev->hal.rx_fltr |= B_AX_A_MC; ++ } ++ if (changed_flags & FIF_FCSFAIL) { ++ if (*new_flags & FIF_FCSFAIL) ++ rtwdev->hal.rx_fltr |= B_AX_A_CRC32_ERR; ++ else ++ rtwdev->hal.rx_fltr &= ~B_AX_A_CRC32_ERR; ++ } ++ if (changed_flags & FIF_OTHER_BSS) { ++ if (*new_flags & FIF_OTHER_BSS) ++ rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH; ++ else ++ rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH; ++ } ++ if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { ++ if (*new_flags & FIF_BCN_PRBRESP_PROMISC) { ++ rtwdev->hal.rx_fltr &= ~B_AX_A_BCN_CHK_EN; ++ rtwdev->hal.rx_fltr &= ~B_AX_A_BC; ++ rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH; ++ } else { ++ rtwdev->hal.rx_fltr |= B_AX_A_BCN_CHK_EN; ++ rtwdev->hal.rx_fltr |= B_AX_A_BC; ++ rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH; ++ } ++ } ++ ++ rtw89_write32_mask(rtwdev, ++ rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0), ++ B_AX_RX_FLTR_CFG_MASK, ++ rtwdev->hal.rx_fltr); ++ if (!rtwdev->dbcc_en) ++ goto out; ++ rtw89_write32_mask(rtwdev, ++ rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_1), ++ B_AX_RX_FLTR_CFG_MASK, ++ rtwdev->hal.rx_fltr); ++ ++out: ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = { ++ [IEEE80211_AC_VO] = 3, ++ [IEEE80211_AC_VI] = 2, ++ [IEEE80211_AC_BE] = 0, ++ [IEEE80211_AC_BK] = 1, ++}; ++ ++static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, u8 aifsn) ++{ ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ u8 slot_time; ++ u8 sifs; ++ ++ slot_time = vif->bss_conf.use_short_slot ? 9 : 20; ++ sifs = rtwdev->hal.current_band_type == RTW89_BAND_5G ? 16 : 10; ++ ++ return aifsn * slot_time + sifs; ++} ++ ++static void ____rtw89_conf_tx_edca(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, u16 ac) ++{ ++ struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac]; ++ u32 val; ++ u8 ecw_max, ecw_min; ++ u8 aifs; ++ ++ /* 2^ecw - 1 = cw; ecw = log2(cw + 1) */ ++ ecw_max = ilog2(params->cw_max + 1); ++ ecw_min = ilog2(params->cw_min + 1); ++ aifs = rtw89_aifsn_to_aifs(rtwdev, rtwvif, params->aifs); ++ val = FIELD_PREP(FW_EDCA_PARAM_TXOPLMT_MSK, params->txop) | ++ FIELD_PREP(FW_EDCA_PARAM_CWMAX_MSK, ecw_max) | ++ FIELD_PREP(FW_EDCA_PARAM_CWMIN_MSK, ecw_min) | ++ FIELD_PREP(FW_EDCA_PARAM_AIFS_MSK, aifs); ++ rtw89_fw_h2c_set_edca(rtwdev, rtwvif, ac_to_fw_idx[ac], val); ++} ++ ++static const u32 ac_to_mu_edca_param[IEEE80211_NUM_ACS] = { ++ [IEEE80211_AC_VO] = R_AX_MUEDCA_VO_PARAM_0, ++ [IEEE80211_AC_VI] = R_AX_MUEDCA_VI_PARAM_0, ++ [IEEE80211_AC_BE] = R_AX_MUEDCA_BE_PARAM_0, ++ [IEEE80211_AC_BK] = R_AX_MUEDCA_BK_PARAM_0, ++}; ++ ++static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, u16 ac) ++{ ++ struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac]; ++ struct ieee80211_he_mu_edca_param_ac_rec *mu_edca; ++ u8 aifs, aifsn; ++ u16 timer_32us; ++ u32 reg; ++ u32 val; ++ ++ if (!params->mu_edca) ++ return; ++ ++ mu_edca = ¶ms->mu_edca_param_rec; ++ aifsn = FIELD_GET(GENMASK(3, 0), mu_edca->aifsn); ++ aifs = aifsn ? rtw89_aifsn_to_aifs(rtwdev, rtwvif, aifsn) : 0; ++ timer_32us = mu_edca->mu_edca_timer << 8; ++ ++ val = FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_TIMER_MASK, timer_32us) | ++ FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_CW_MASK, mu_edca->ecw_min_max) | ++ FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_AIFS_MASK, aifs); ++ reg = rtw89_mac_reg_by_idx(ac_to_mu_edca_param[ac], rtwvif->mac_idx); ++ rtw89_write32(rtwdev, reg, val); ++ ++ rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif, true); ++} ++ ++static void __rtw89_conf_tx(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, u16 ac) ++{ ++ ____rtw89_conf_tx_edca(rtwdev, rtwvif, ac); ++ ____rtw89_conf_tx_mu_edca(rtwdev, rtwvif, ac); ++} ++ ++static void rtw89_conf_tx(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ u16 ac; ++ ++ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) ++ __rtw89_conf_tx(rtwdev, rtwvif, ac); ++} ++ ++static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_bss_conf *conf) ++{ ++ struct ieee80211_sta *sta; ++ ++ if (vif->type != NL80211_IFTYPE_STATION) ++ return; ++ ++ sta = ieee80211_find_sta(vif, conf->bssid); ++ if (!sta) { ++ rtw89_err(rtwdev, "can't find sta to set sta_assoc state\n"); ++ return; ++ } ++ rtw89_core_sta_assoc(rtwdev, vif, sta); ++} ++ ++static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_bss_conf *conf, ++ u32 changed) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ ++ if (changed & BSS_CHANGED_ASSOC) { ++ if (conf->assoc) { ++ rtw89_station_mode_sta_assoc(rtwdev, vif, conf); ++ rtw89_phy_set_bss_color(rtwdev, vif); ++ rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif); ++ rtw89_mac_port_update(rtwdev, rtwvif); ++ } ++ } ++ ++ if (changed & BSS_CHANGED_BSSID) { ++ ether_addr_copy(rtwvif->bssid, conf->bssid); ++ rtw89_cam_bssid_changed(rtwdev, rtwvif); ++ rtw89_fw_h2c_cam(rtwdev, rtwvif); ++ } ++ ++ if (changed & BSS_CHANGED_ERP_SLOT) ++ rtw89_conf_tx(rtwdev, rtwvif); ++ ++ if (changed & BSS_CHANGED_HE_BSS_COLOR) ++ rtw89_phy_set_bss_color(rtwdev, vif); ++ ++ if (changed & BSS_CHANGED_MU_GROUPS) ++ rtw89_mac_bf_set_gid_table(rtwdev, vif, conf); ++ ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static int rtw89_ops_conf_tx(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, u16 ac, ++ const struct ieee80211_tx_queue_params *params) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ rtwvif->tx_params[ac] = *params; ++ __rtw89_conf_tx(rtwdev, rtwvif, ac); ++ mutex_unlock(&rtwdev->mutex); ++ ++ return 0; ++} ++ ++static int __rtw89_ops_sta_state(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ enum ieee80211_sta_state old_state, ++ enum ieee80211_sta_state new_state) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ if (old_state == IEEE80211_STA_NOTEXIST && ++ new_state == IEEE80211_STA_NONE) ++ return rtw89_core_sta_add(rtwdev, vif, sta); ++ ++ if (old_state == IEEE80211_STA_AUTH && ++ new_state == IEEE80211_STA_ASSOC) { ++ if (vif->type == NL80211_IFTYPE_STATION) ++ return 0; /* defer to bss_info_changed to have vif info */ ++ return rtw89_core_sta_assoc(rtwdev, vif, sta); ++ } ++ ++ if (old_state == IEEE80211_STA_ASSOC && ++ new_state == IEEE80211_STA_AUTH) ++ return rtw89_core_sta_disassoc(rtwdev, vif, sta); ++ ++ if (old_state == IEEE80211_STA_AUTH && ++ new_state == IEEE80211_STA_NONE) ++ return rtw89_core_sta_disconnect(rtwdev, vif, sta); ++ ++ if (old_state == IEEE80211_STA_NONE && ++ new_state == IEEE80211_STA_NOTEXIST) ++ return rtw89_core_sta_remove(rtwdev, vif, sta); ++ ++ return 0; ++} ++ ++static int rtw89_ops_sta_state(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ enum ieee80211_sta_state old_state, ++ enum ieee80211_sta_state new_state) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ int ret; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ ret = __rtw89_ops_sta_state(hw, vif, sta, old_state, new_state); ++ mutex_unlock(&rtwdev->mutex); ++ ++ return ret; ++} ++ ++static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ struct ieee80211_key_conf *key) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ int ret = 0; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ ++ switch (cmd) { ++ case SET_KEY: ++ rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_EAPOL_END); ++ ret = rtw89_cam_sec_key_add(rtwdev, vif, sta, key); ++ if (ret && ret != -EOPNOTSUPP) { ++ rtw89_err(rtwdev, "failed to add key to sec cam\n"); ++ goto out; ++ } ++ break; ++ case DISABLE_KEY: ++ rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1, ++ false); ++ rtw89_mac_flush_txq(rtwdev, BIT(rtwdev->hw->queues) - 1, false); ++ ret = rtw89_cam_sec_key_del(rtwdev, vif, sta, key, true); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to remove key from sec cam\n"); ++ goto out; ++ } ++ break; ++ } ++ ++out: ++ mutex_unlock(&rtwdev->mutex); ++ ++ return ret; ++} ++ ++static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_ampdu_params *params) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct ieee80211_sta *sta = params->sta; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ u16 tid = params->tid; ++ struct ieee80211_txq *txq = sta->txq[tid]; ++ struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv; ++ ++ switch (params->action) { ++ case IEEE80211_AMPDU_TX_START: ++ return IEEE80211_AMPDU_TX_START_IMMEDIATE; ++ case IEEE80211_AMPDU_TX_STOP_CONT: ++ case IEEE80211_AMPDU_TX_STOP_FLUSH: ++ case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: ++ mutex_lock(&rtwdev->mutex); ++ clear_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags); ++ rtw89_fw_h2c_ba_cam(rtwdev, false, rtwsta->mac_id, params); ++ mutex_unlock(&rtwdev->mutex); ++ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); ++ break; ++ case IEEE80211_AMPDU_TX_OPERATIONAL: ++ mutex_lock(&rtwdev->mutex); ++ set_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags); ++ rtwsta->ampdu_params[tid].agg_num = params->buf_size; ++ rtwsta->ampdu_params[tid].amsdu = params->amsdu; ++ rtw89_leave_ps_mode(rtwdev); ++ rtw89_fw_h2c_ba_cam(rtwdev, true, rtwsta->mac_id, params); ++ mutex_unlock(&rtwdev->mutex); ++ break; ++ case IEEE80211_AMPDU_RX_START: ++ case IEEE80211_AMPDU_RX_STOP: ++ break; ++ default: ++ WARN_ON(1); ++ return -ENOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static int rtw89_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) ++ rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0); ++ mutex_unlock(&rtwdev->mutex); ++ ++ return 0; ++} ++ ++static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ struct station_info *sinfo) ++{ ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ ++ sinfo->txrate = rtwsta->ra_report.txrate; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); ++} ++ ++static void rtw89_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ++ u32 queues, bool drop) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_lps(rtwdev); ++ rtw89_hci_flush_queues(rtwdev, queues, drop); ++ rtw89_mac_flush_txq(rtwdev, queues, drop); ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++struct rtw89_iter_bitrate_mask_data { ++ struct rtw89_dev *rtwdev; ++ struct ieee80211_vif *vif; ++ const struct cfg80211_bitrate_mask *mask; ++}; ++ ++static void rtw89_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta) ++{ ++ struct rtw89_iter_bitrate_mask_data *br_data = data; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif); ++ ++ if (vif != br_data->vif) ++ return; ++ ++ rtwsta->use_cfg_mask = true; ++ rtwsta->mask = *br_data->mask; ++ rtw89_phy_ra_updata_sta(br_data->rtwdev, sta); ++} ++ ++static void rtw89_ra_mask_info_update(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ const struct cfg80211_bitrate_mask *mask) ++{ ++ struct rtw89_iter_bitrate_mask_data br_data = { .rtwdev = rtwdev, ++ .vif = vif, ++ .mask = mask}; ++ ++ ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_ra_mask_info_update_iter, ++ &br_data); ++} ++ ++static int rtw89_ops_set_bitrate_mask(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ const struct cfg80211_bitrate_mask *mask) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_phy_rate_pattern_vif(rtwdev, vif, mask); ++ rtw89_ra_mask_info_update(rtwdev, vif, mask); ++ mutex_unlock(&rtwdev->mutex); ++ ++ return 0; ++} ++ ++static ++int rtw89_ops_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ ++ if (rx_ant != hw->wiphy->available_antennas_rx) ++ return -EINVAL; ++ ++ mutex_lock(&rtwdev->mutex); ++ hal->antenna_tx = tx_ant; ++ hal->antenna_rx = rx_ant; ++ mutex_unlock(&rtwdev->mutex); ++ ++ return 0; ++} ++ ++static ++int rtw89_ops_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ ++ *tx_ant = hal->antenna_tx; ++ *rx_ant = hal->antenna_rx; ++ ++ return 0; ++} ++ ++static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ const u8 *mac_addr) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtwdev->scanning = true; ++ rtw89_leave_lps(rtwdev); ++ rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, hal->current_band_type); ++ rtw89_chip_rfk_scan(rtwdev, true); ++ rtw89_hci_recalc_int_mit(rtwdev); ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_chip_rfk_scan(rtwdev, false); ++ rtw89_btc_ntfy_scan_finish(rtwdev, RTW89_PHY_0); ++ rtwdev->scanning = false; ++ rtwdev->dig.bypass_dig = true; ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static void rtw89_ops_reconfig_complete(struct ieee80211_hw *hw, ++ enum ieee80211_reconfig_type reconfig_type) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ if (reconfig_type == IEEE80211_RECONFIG_TYPE_RESTART) ++ rtw89_ser_recfg_done(rtwdev); ++} ++ ++const struct ieee80211_ops rtw89_ops = { ++ .tx = rtw89_ops_tx, ++ .wake_tx_queue = rtw89_ops_wake_tx_queue, ++ .start = rtw89_ops_start, ++ .stop = rtw89_ops_stop, ++ .config = rtw89_ops_config, ++ .add_interface = rtw89_ops_add_interface, ++ .remove_interface = rtw89_ops_remove_interface, ++ .configure_filter = rtw89_ops_configure_filter, ++ .bss_info_changed = rtw89_ops_bss_info_changed, ++ .conf_tx = rtw89_ops_conf_tx, ++ .sta_state = rtw89_ops_sta_state, ++ .set_key = rtw89_ops_set_key, ++ .ampdu_action = rtw89_ops_ampdu_action, ++ .set_rts_threshold = rtw89_ops_set_rts_threshold, ++ .sta_statistics = rtw89_ops_sta_statistics, ++ .flush = rtw89_ops_flush, ++ .set_bitrate_mask = rtw89_ops_set_bitrate_mask, ++ .set_antenna = rtw89_ops_set_antenna, ++ .get_antenna = rtw89_ops_get_antenna, ++ .sw_scan_start = rtw89_ops_sw_scan_start, ++ .sw_scan_complete = rtw89_ops_sw_scan_complete, ++ .reconfig_complete = rtw89_ops_reconfig_complete, ++ .set_sar_specs = rtw89_ops_set_sar_specs, ++}; ++EXPORT_SYMBOL(rtw89_ops); +diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c +new file mode 100644 +index 000000000000..e9731012bca9 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/pci.c +@@ -0,0 +1,3060 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2020 Realtek Corporation ++ */ ++ ++#include ++ ++#include "mac.h" ++#include "pci.h" ++#include "reg.h" ++#include "ser.h" ++ ++static bool rtw89_pci_disable_clkreq; ++static bool rtw89_pci_disable_aspm_l1; ++static bool rtw89_pci_disable_l1ss; ++module_param_named(disable_clkreq, rtw89_pci_disable_clkreq, bool, 0644); ++module_param_named(disable_aspm_l1, rtw89_pci_disable_aspm_l1, bool, 0644); ++module_param_named(disable_aspm_l1ss, rtw89_pci_disable_l1ss, bool, 0644); ++MODULE_PARM_DESC(disable_clkreq, "Set Y to disable PCI clkreq support"); ++MODULE_PARM_DESC(disable_aspm_l1, "Set Y to disable PCI ASPM L1 support"); ++MODULE_PARM_DESC(disable_aspm_l1ss, "Set Y to disable PCI L1SS support"); ++ ++static int rtw89_pci_rst_bdram_pcie(struct rtw89_dev *rtwdev) ++{ ++ u32 val; ++ int ret; ++ ++ rtw89_write32(rtwdev, R_AX_PCIE_INIT_CFG1, ++ rtw89_read32(rtwdev, R_AX_PCIE_INIT_CFG1) | B_AX_RST_BDRAM); ++ ++ ret = read_poll_timeout_atomic(rtw89_read32, val, !(val & B_AX_RST_BDRAM), ++ 1, RTW89_PCI_POLL_BDRAM_RST_CNT, false, ++ rtwdev, R_AX_PCIE_INIT_CFG1); ++ ++ if (ret) ++ return -EBUSY; ++ ++ return 0; ++} ++ ++static u32 rtw89_pci_dma_recalc(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_dma_ring *bd_ring, ++ u32 cur_idx, bool tx) ++{ ++ u32 cnt, cur_rp, wp, rp, len; ++ ++ rp = bd_ring->rp; ++ wp = bd_ring->wp; ++ len = bd_ring->len; ++ ++ cur_rp = FIELD_GET(TXBD_HW_IDX_MASK, cur_idx); ++ if (tx) ++ cnt = cur_rp >= rp ? cur_rp - rp : len - (rp - cur_rp); ++ else ++ cnt = cur_rp >= wp ? cur_rp - wp : len - (wp - cur_rp); ++ ++ bd_ring->rp = cur_rp; ++ ++ return cnt; ++} ++ ++static u32 rtw89_pci_txbd_recalc(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; ++ u32 addr_idx = bd_ring->addr_idx; ++ u32 cnt, idx; ++ ++ idx = rtw89_read32(rtwdev, addr_idx); ++ cnt = rtw89_pci_dma_recalc(rtwdev, bd_ring, idx, true); ++ ++ return cnt; ++} ++ ++static void rtw89_pci_release_fwcmd(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci, ++ u32 cnt, bool release_all) ++{ ++ struct rtw89_pci_tx_data *tx_data; ++ struct sk_buff *skb; ++ u32 qlen; ++ ++ while (cnt--) { ++ skb = skb_dequeue(&rtwpci->h2c_queue); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to pre-release fwcmd\n"); ++ return; ++ } ++ skb_queue_tail(&rtwpci->h2c_release_queue, skb); ++ } ++ ++ qlen = skb_queue_len(&rtwpci->h2c_release_queue); ++ if (!release_all) ++ qlen = qlen > RTW89_PCI_MULTITAG ? qlen - RTW89_PCI_MULTITAG : 0; ++ ++ while (qlen--) { ++ skb = skb_dequeue(&rtwpci->h2c_release_queue); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to release fwcmd\n"); ++ return; ++ } ++ tx_data = RTW89_PCI_TX_SKB_CB(skb); ++ dma_unmap_single(&rtwpci->pdev->dev, tx_data->dma, skb->len, ++ DMA_TO_DEVICE); ++ dev_kfree_skb_any(skb); ++ } ++} ++ ++static void rtw89_pci_reclaim_tx_fwcmd(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci) ++{ ++ struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[RTW89_TXCH_CH12]; ++ u32 cnt; ++ ++ cnt = rtw89_pci_txbd_recalc(rtwdev, tx_ring); ++ if (!cnt) ++ return; ++ rtw89_pci_release_fwcmd(rtwdev, rtwpci, cnt, false); ++} ++ ++static u32 rtw89_pci_rxbd_recalc(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_rx_ring *rx_ring) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; ++ u32 addr_idx = bd_ring->addr_idx; ++ u32 cnt, idx; ++ ++ idx = rtw89_read32(rtwdev, addr_idx); ++ cnt = rtw89_pci_dma_recalc(rtwdev, bd_ring, idx, false); ++ ++ return cnt; ++} ++ ++static void rtw89_pci_sync_skb_for_cpu(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb) ++{ ++ struct rtw89_pci_rx_info *rx_info; ++ dma_addr_t dma; ++ ++ rx_info = RTW89_PCI_RX_SKB_CB(skb); ++ dma = rx_info->dma; ++ dma_sync_single_for_cpu(rtwdev->dev, dma, RTW89_PCI_RX_BUF_SIZE, ++ DMA_FROM_DEVICE); ++} ++ ++static void rtw89_pci_sync_skb_for_device(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb) ++{ ++ struct rtw89_pci_rx_info *rx_info; ++ dma_addr_t dma; ++ ++ rx_info = RTW89_PCI_RX_SKB_CB(skb); ++ dma = rx_info->dma; ++ dma_sync_single_for_device(rtwdev->dev, dma, RTW89_PCI_RX_BUF_SIZE, ++ DMA_FROM_DEVICE); ++} ++ ++static int rtw89_pci_rxbd_info_update(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb) ++{ ++ struct rtw89_pci_rxbd_info *rxbd_info; ++ struct rtw89_pci_rx_info *rx_info = RTW89_PCI_RX_SKB_CB(skb); ++ ++ rxbd_info = (struct rtw89_pci_rxbd_info *)skb->data; ++ rx_info->fs = le32_get_bits(rxbd_info->dword, RTW89_PCI_RXBD_FS); ++ rx_info->ls = le32_get_bits(rxbd_info->dword, RTW89_PCI_RXBD_LS); ++ rx_info->len = le32_get_bits(rxbd_info->dword, RTW89_PCI_RXBD_WRITE_SIZE); ++ rx_info->tag = le32_get_bits(rxbd_info->dword, RTW89_PCI_RXBD_TAG); ++ ++ return 0; ++} ++ ++static bool ++rtw89_skb_put_rx_data(struct rtw89_dev *rtwdev, bool fs, bool ls, ++ struct sk_buff *new, ++ const struct sk_buff *skb, u32 offset, ++ const struct rtw89_pci_rx_info *rx_info, ++ const struct rtw89_rx_desc_info *desc_info) ++{ ++ u32 copy_len = rx_info->len - offset; ++ ++ if (unlikely(skb_tailroom(new) < copy_len)) { ++ rtw89_debug(rtwdev, RTW89_DBG_TXRX, ++ "invalid rx data length bd_len=%d desc_len=%d offset=%d (fs=%d ls=%d)\n", ++ rx_info->len, desc_info->pkt_size, offset, fs, ls); ++ rtw89_hex_dump(rtwdev, RTW89_DBG_TXRX, "rx_data: ", ++ skb->data, rx_info->len); ++ /* length of a single segment skb is desc_info->pkt_size */ ++ if (fs && ls) { ++ copy_len = desc_info->pkt_size; ++ } else { ++ rtw89_info(rtwdev, "drop rx data due to invalid length\n"); ++ return false; ++ } ++ } ++ ++ skb_put_data(new, skb->data + offset, copy_len); ++ ++ return true; ++} ++ ++static u32 rtw89_pci_rxbd_deliver_skbs(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_rx_ring *rx_ring) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; ++ struct rtw89_pci_rx_info *rx_info; ++ struct rtw89_rx_desc_info *desc_info = &rx_ring->diliver_desc; ++ struct sk_buff *new = rx_ring->diliver_skb; ++ struct sk_buff *skb; ++ u32 rxinfo_size = sizeof(struct rtw89_pci_rxbd_info); ++ u32 offset; ++ u32 cnt = 1; ++ bool fs, ls; ++ int ret; ++ ++ skb = rx_ring->buf[bd_ring->wp]; ++ rtw89_pci_sync_skb_for_cpu(rtwdev, skb); ++ ++ ret = rtw89_pci_rxbd_info_update(rtwdev, skb); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to update %d RXBD info: %d\n", ++ bd_ring->wp, ret); ++ goto err_sync_device; ++ } ++ ++ rx_info = RTW89_PCI_RX_SKB_CB(skb); ++ fs = rx_info->fs; ++ ls = rx_info->ls; ++ ++ if (fs) { ++ if (new) { ++ rtw89_err(rtwdev, "skb should not be ready before first segment start\n"); ++ goto err_sync_device; ++ } ++ if (desc_info->ready) { ++ rtw89_warn(rtwdev, "desc info should not be ready before first segment start\n"); ++ goto err_sync_device; ++ } ++ ++ rtw89_core_query_rxdesc(rtwdev, desc_info, skb->data, rxinfo_size); ++ ++ new = dev_alloc_skb(desc_info->pkt_size); ++ if (!new) ++ goto err_sync_device; ++ ++ rx_ring->diliver_skb = new; ++ ++ /* first segment has RX desc */ ++ offset = desc_info->offset; ++ offset += desc_info->long_rxdesc ? sizeof(struct rtw89_rxdesc_long) : ++ sizeof(struct rtw89_rxdesc_short); ++ } else { ++ offset = sizeof(struct rtw89_pci_rxbd_info); ++ if (!new) { ++ rtw89_warn(rtwdev, "no last skb\n"); ++ goto err_sync_device; ++ } ++ } ++ if (!rtw89_skb_put_rx_data(rtwdev, fs, ls, new, skb, offset, rx_info, desc_info)) ++ goto err_sync_device; ++ rtw89_pci_sync_skb_for_device(rtwdev, skb); ++ rtw89_pci_rxbd_increase(rx_ring, 1); ++ ++ if (!desc_info->ready) { ++ rtw89_warn(rtwdev, "no rx desc information\n"); ++ goto err_free_resource; ++ } ++ if (ls) { ++ rtw89_core_rx(rtwdev, desc_info, new); ++ rx_ring->diliver_skb = NULL; ++ desc_info->ready = false; ++ } ++ ++ return cnt; ++ ++err_sync_device: ++ rtw89_pci_sync_skb_for_device(rtwdev, skb); ++ rtw89_pci_rxbd_increase(rx_ring, 1); ++err_free_resource: ++ if (new) ++ dev_kfree_skb_any(new); ++ rx_ring->diliver_skb = NULL; ++ desc_info->ready = false; ++ ++ return cnt; ++} ++ ++static void rtw89_pci_rxbd_deliver(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_rx_ring *rx_ring, ++ u32 cnt) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; ++ u32 rx_cnt; ++ ++ while (cnt && rtwdev->napi_budget_countdown > 0) { ++ rx_cnt = rtw89_pci_rxbd_deliver_skbs(rtwdev, rx_ring); ++ if (!rx_cnt) { ++ rtw89_err(rtwdev, "failed to deliver RXBD skb\n"); ++ ++ /* skip the rest RXBD bufs */ ++ rtw89_pci_rxbd_increase(rx_ring, cnt); ++ break; ++ } ++ ++ cnt -= rx_cnt; ++ } ++ ++ rtw89_write16(rtwdev, bd_ring->addr_idx, bd_ring->wp); ++} ++ ++static int rtw89_pci_poll_rxq_dma(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci, int budget) ++{ ++ struct rtw89_pci_rx_ring *rx_ring; ++ int countdown = rtwdev->napi_budget_countdown; ++ u32 cnt; ++ ++ rx_ring = &rtwpci->rx_rings[RTW89_RXCH_RXQ]; ++ ++ cnt = rtw89_pci_rxbd_recalc(rtwdev, rx_ring); ++ if (!cnt) ++ return 0; ++ ++ cnt = min_t(u32, budget, cnt); ++ ++ rtw89_pci_rxbd_deliver(rtwdev, rx_ring, cnt); ++ ++ /* In case of flushing pending SKBs, the countdown may exceed. */ ++ if (rtwdev->napi_budget_countdown <= 0) ++ return budget; ++ ++ return budget - countdown; ++} ++ ++static void rtw89_pci_tx_status(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring, ++ struct sk_buff *skb, u8 tx_status) ++{ ++ struct ieee80211_tx_info *info; ++ ++ info = IEEE80211_SKB_CB(skb); ++ ieee80211_tx_info_clear_status(info); ++ ++ if (info->flags & IEEE80211_TX_CTL_NO_ACK) ++ info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; ++ if (tx_status == RTW89_TX_DONE) { ++ info->flags |= IEEE80211_TX_STAT_ACK; ++ tx_ring->tx_acked++; ++ } else { ++ if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) ++ rtw89_debug(rtwdev, RTW89_DBG_FW, ++ "failed to TX of status %x\n", tx_status); ++ switch (tx_status) { ++ case RTW89_TX_RETRY_LIMIT: ++ tx_ring->tx_retry_lmt++; ++ break; ++ case RTW89_TX_LIFE_TIME: ++ tx_ring->tx_life_time++; ++ break; ++ case RTW89_TX_MACID_DROP: ++ tx_ring->tx_mac_id_drop++; ++ break; ++ default: ++ rtw89_warn(rtwdev, "invalid TX status %x\n", tx_status); ++ break; ++ } ++ } ++ ++ ieee80211_tx_status_ni(rtwdev->hw, skb); ++} ++ ++static void rtw89_pci_reclaim_txbd(struct rtw89_dev *rtwdev, struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_tx_wd *txwd; ++ u32 cnt; ++ ++ cnt = rtw89_pci_txbd_recalc(rtwdev, tx_ring); ++ while (cnt--) { ++ txwd = list_first_entry_or_null(&tx_ring->busy_pages, struct rtw89_pci_tx_wd, list); ++ if (!txwd) { ++ rtw89_warn(rtwdev, "No busy txwd pages available\n"); ++ break; ++ } ++ ++ list_del_init(&txwd->list); ++ } ++} ++ ++static void rtw89_pci_release_busy_txwd(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; ++ struct rtw89_pci_tx_wd *txwd; ++ int i; ++ ++ for (i = 0; i < wd_ring->page_num; i++) { ++ txwd = list_first_entry_or_null(&tx_ring->busy_pages, struct rtw89_pci_tx_wd, list); ++ if (!txwd) ++ break; ++ ++ list_del_init(&txwd->list); ++ } ++} ++ ++static void rtw89_pci_release_txwd_skb(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring, ++ struct rtw89_pci_tx_wd *txwd, u16 seq, ++ u8 tx_status) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_data *tx_data; ++ struct sk_buff *skb, *tmp; ++ u8 txch = tx_ring->txch; ++ ++ if (!list_empty(&txwd->list)) { ++ rtw89_warn(rtwdev, "queue %d txwd %d is not idle\n", ++ txch, seq); ++ return; ++ } ++ ++ /* currently, support for only one frame */ ++ if (skb_queue_len(&txwd->queue) != 1) { ++ rtw89_warn(rtwdev, "empty pending queue %d page %d\n", ++ txch, seq); ++ return; ++ } ++ ++ skb_queue_walk_safe(&txwd->queue, skb, tmp) { ++ skb_unlink(skb, &txwd->queue); ++ ++ tx_data = RTW89_PCI_TX_SKB_CB(skb); ++ dma_unmap_single(&rtwpci->pdev->dev, tx_data->dma, skb->len, ++ DMA_TO_DEVICE); ++ ++ rtw89_pci_tx_status(rtwdev, tx_ring, skb, tx_status); ++ } ++ ++ rtw89_pci_enqueue_txwd(tx_ring, txwd); ++} ++ ++static void rtw89_pci_release_rpp(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_rpp_fmt *rpp) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring; ++ struct rtw89_pci_tx_wd_ring *wd_ring; ++ struct rtw89_pci_tx_wd *txwd; ++ u16 seq; ++ u8 qsel, tx_status, txch; ++ ++ seq = le32_get_bits(rpp->dword, RTW89_PCI_RPP_SEQ); ++ qsel = le32_get_bits(rpp->dword, RTW89_PCI_RPP_QSEL); ++ tx_status = le32_get_bits(rpp->dword, RTW89_PCI_RPP_TX_STATUS); ++ txch = rtw89_core_get_ch_dma(rtwdev, qsel); ++ ++ if (txch == RTW89_TXCH_CH12) { ++ rtw89_warn(rtwdev, "should no fwcmd release report\n"); ++ return; ++ } ++ ++ tx_ring = &rtwpci->tx_rings[txch]; ++ rtw89_pci_reclaim_txbd(rtwdev, tx_ring); ++ wd_ring = &tx_ring->wd_ring; ++ txwd = &wd_ring->pages[seq]; ++ ++ rtw89_pci_release_txwd_skb(rtwdev, tx_ring, txwd, seq, tx_status); ++} ++ ++static void rtw89_pci_release_pending_txwd_skb(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; ++ struct rtw89_pci_tx_wd *txwd; ++ int i; ++ ++ for (i = 0; i < wd_ring->page_num; i++) { ++ txwd = &wd_ring->pages[i]; ++ ++ if (!list_empty(&txwd->list)) ++ continue; ++ ++ rtw89_pci_release_txwd_skb(rtwdev, tx_ring, txwd, i, RTW89_TX_MACID_DROP); ++ } ++} ++ ++static u32 rtw89_pci_release_tx_skbs(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_rx_ring *rx_ring, ++ u32 max_cnt) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; ++ struct rtw89_pci_rx_info *rx_info; ++ struct rtw89_pci_rpp_fmt *rpp; ++ struct rtw89_rx_desc_info desc_info = {}; ++ struct sk_buff *skb; ++ u32 cnt = 0; ++ u32 rpp_size = sizeof(struct rtw89_pci_rpp_fmt); ++ u32 rxinfo_size = sizeof(struct rtw89_pci_rxbd_info); ++ u32 offset; ++ int ret; ++ ++ skb = rx_ring->buf[bd_ring->wp]; ++ rtw89_pci_sync_skb_for_cpu(rtwdev, skb); ++ ++ ret = rtw89_pci_rxbd_info_update(rtwdev, skb); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to update %d RXBD info: %d\n", ++ bd_ring->wp, ret); ++ goto err_sync_device; ++ } ++ ++ rx_info = RTW89_PCI_RX_SKB_CB(skb); ++ if (!rx_info->fs || !rx_info->ls) { ++ rtw89_err(rtwdev, "cannot process RP frame not set FS/LS\n"); ++ return cnt; ++ } ++ ++ rtw89_core_query_rxdesc(rtwdev, &desc_info, skb->data, rxinfo_size); ++ ++ /* first segment has RX desc */ ++ offset = desc_info.offset; ++ offset += desc_info.long_rxdesc ? sizeof(struct rtw89_rxdesc_long) : ++ sizeof(struct rtw89_rxdesc_short); ++ for (; offset + rpp_size <= rx_info->len; offset += rpp_size) { ++ rpp = (struct rtw89_pci_rpp_fmt *)(skb->data + offset); ++ rtw89_pci_release_rpp(rtwdev, rpp); ++ } ++ ++ rtw89_pci_sync_skb_for_device(rtwdev, skb); ++ rtw89_pci_rxbd_increase(rx_ring, 1); ++ cnt++; ++ ++ return cnt; ++ ++err_sync_device: ++ rtw89_pci_sync_skb_for_device(rtwdev, skb); ++ return 0; ++} ++ ++static void rtw89_pci_release_tx(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_rx_ring *rx_ring, ++ u32 cnt) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; ++ u32 release_cnt; ++ ++ while (cnt) { ++ release_cnt = rtw89_pci_release_tx_skbs(rtwdev, rx_ring, cnt); ++ if (!release_cnt) { ++ rtw89_err(rtwdev, "failed to release TX skbs\n"); ++ ++ /* skip the rest RXBD bufs */ ++ rtw89_pci_rxbd_increase(rx_ring, cnt); ++ break; ++ } ++ ++ cnt -= release_cnt; ++ } ++ ++ rtw89_write16(rtwdev, bd_ring->addr_idx, bd_ring->wp); ++} ++ ++static int rtw89_pci_poll_rpq_dma(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci, int budget) ++{ ++ struct rtw89_pci_rx_ring *rx_ring; ++ u32 cnt; ++ int work_done; ++ ++ rx_ring = &rtwpci->rx_rings[RTW89_RXCH_RPQ]; ++ ++ spin_lock_bh(&rtwpci->trx_lock); ++ ++ cnt = rtw89_pci_rxbd_recalc(rtwdev, rx_ring); ++ if (cnt == 0) ++ goto out_unlock; ++ ++ rtw89_pci_release_tx(rtwdev, rx_ring, cnt); ++ ++out_unlock: ++ spin_unlock_bh(&rtwpci->trx_lock); ++ ++ /* always release all RPQ */ ++ work_done = min_t(int, cnt, budget); ++ rtwdev->napi_budget_countdown -= work_done; ++ ++ return work_done; ++} ++ ++static void rtw89_pci_isr_rxd_unavail(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci) ++{ ++ struct rtw89_pci_rx_ring *rx_ring; ++ struct rtw89_pci_dma_ring *bd_ring; ++ u32 reg_idx; ++ u16 hw_idx, hw_idx_next, host_idx; ++ int i; ++ ++ for (i = 0; i < RTW89_RXCH_NUM; i++) { ++ rx_ring = &rtwpci->rx_rings[i]; ++ bd_ring = &rx_ring->bd_ring; ++ ++ reg_idx = rtw89_read32(rtwdev, bd_ring->addr_idx); ++ hw_idx = FIELD_GET(TXBD_HW_IDX_MASK, reg_idx); ++ host_idx = FIELD_GET(TXBD_HOST_IDX_MASK, reg_idx); ++ hw_idx_next = (hw_idx + 1) % bd_ring->len; ++ ++ if (hw_idx_next == host_idx) ++ rtw89_warn(rtwdev, "%d RXD unavailable\n", i); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXRX, ++ "%d RXD unavailable, idx=0x%08x, len=%d\n", ++ i, reg_idx, bd_ring->len); ++ } ++} ++ ++static void rtw89_pci_recognize_intrs(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci, ++ struct rtw89_pci_isrs *isrs) ++{ ++ isrs->halt_c2h_isrs = rtw89_read32(rtwdev, R_AX_HISR0) & rtwpci->halt_c2h_intrs; ++ isrs->isrs[0] = rtw89_read32(rtwdev, R_AX_PCIE_HISR00) & rtwpci->intrs[0]; ++ isrs->isrs[1] = rtw89_read32(rtwdev, R_AX_PCIE_HISR10) & rtwpci->intrs[1]; ++ ++ rtw89_write32(rtwdev, R_AX_HISR0, isrs->halt_c2h_isrs); ++ rtw89_write32(rtwdev, R_AX_PCIE_HISR00, isrs->isrs[0]); ++ rtw89_write32(rtwdev, R_AX_PCIE_HISR10, isrs->isrs[1]); ++} ++ ++static void rtw89_pci_clear_isr0(struct rtw89_dev *rtwdev, u32 isr00) ++{ ++ /* write 1 clear */ ++ rtw89_write32(rtwdev, R_AX_PCIE_HISR00, isr00); ++} ++ ++static void rtw89_pci_enable_intr(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci) ++{ ++ rtw89_write32(rtwdev, R_AX_HIMR0, rtwpci->halt_c2h_intrs); ++ rtw89_write32(rtwdev, R_AX_PCIE_HIMR00, rtwpci->intrs[0]); ++ rtw89_write32(rtwdev, R_AX_PCIE_HIMR10, rtwpci->intrs[1]); ++} ++ ++static void rtw89_pci_disable_intr(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci) ++{ ++ rtw89_write32(rtwdev, R_AX_HIMR0, 0); ++ rtw89_write32(rtwdev, R_AX_PCIE_HIMR00, 0); ++ rtw89_write32(rtwdev, R_AX_PCIE_HIMR10, 0); ++} ++ ++static irqreturn_t rtw89_pci_interrupt_threadfn(int irq, void *dev) ++{ ++ struct rtw89_dev *rtwdev = dev; ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_isrs isrs; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&rtwpci->irq_lock, flags); ++ rtw89_pci_recognize_intrs(rtwdev, rtwpci, &isrs); ++ spin_unlock_irqrestore(&rtwpci->irq_lock, flags); ++ ++ if (unlikely(isrs.isrs[0] & B_AX_RDU_INT)) ++ rtw89_pci_isr_rxd_unavail(rtwdev, rtwpci); ++ ++ if (unlikely(isrs.halt_c2h_isrs & B_AX_HALT_C2H_INT_EN)) ++ rtw89_ser_notify(rtwdev, rtw89_mac_get_err_status(rtwdev)); ++ ++ if (likely(rtwpci->running)) { ++ local_bh_disable(); ++ napi_schedule(&rtwdev->napi); ++ local_bh_enable(); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t rtw89_pci_interrupt_handler(int irq, void *dev) ++{ ++ struct rtw89_dev *rtwdev = dev; ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ unsigned long flags; ++ irqreturn_t irqret = IRQ_WAKE_THREAD; ++ ++ spin_lock_irqsave(&rtwpci->irq_lock, flags); ++ ++ /* If interrupt event is on the road, it is still trigger interrupt ++ * even we have done pci_stop() to turn off IMR. ++ */ ++ if (unlikely(!rtwpci->running)) { ++ irqret = IRQ_HANDLED; ++ goto exit; ++ } ++ ++ rtw89_pci_disable_intr(rtwdev, rtwpci); ++exit: ++ spin_unlock_irqrestore(&rtwpci->irq_lock, flags); ++ ++ return irqret; ++} ++ ++#define case_TXCHADDRS(txch) \ ++ case RTW89_TXCH_##txch: \ ++ *addr_num = R_AX_##txch##_TXBD_NUM; \ ++ *addr_idx = R_AX_##txch##_TXBD_IDX; \ ++ *addr_bdram = R_AX_##txch##_BDRAM_CTRL; \ ++ *addr_desa_l = R_AX_##txch##_TXBD_DESA_L; \ ++ *addr_desa_h = R_AX_##txch##_TXBD_DESA_H; \ ++ break ++ ++static int rtw89_pci_get_txch_addrs(enum rtw89_tx_channel txch, ++ u32 *addr_num, ++ u32 *addr_idx, ++ u32 *addr_bdram, ++ u32 *addr_desa_l, ++ u32 *addr_desa_h) ++{ ++ switch (txch) { ++ case_TXCHADDRS(ACH0); ++ case_TXCHADDRS(ACH1); ++ case_TXCHADDRS(ACH2); ++ case_TXCHADDRS(ACH3); ++ case_TXCHADDRS(ACH4); ++ case_TXCHADDRS(ACH5); ++ case_TXCHADDRS(ACH6); ++ case_TXCHADDRS(ACH7); ++ case_TXCHADDRS(CH8); ++ case_TXCHADDRS(CH9); ++ case_TXCHADDRS(CH10); ++ case_TXCHADDRS(CH11); ++ case_TXCHADDRS(CH12); ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++#undef case_TXCHADDRS ++ ++#define case_RXCHADDRS(rxch) \ ++ case RTW89_RXCH_##rxch: \ ++ *addr_num = R_AX_##rxch##_RXBD_NUM; \ ++ *addr_idx = R_AX_##rxch##_RXBD_IDX; \ ++ *addr_desa_l = R_AX_##rxch##_RXBD_DESA_L; \ ++ *addr_desa_h = R_AX_##rxch##_RXBD_DESA_H; \ ++ break ++ ++static int rtw89_pci_get_rxch_addrs(enum rtw89_rx_channel rxch, ++ u32 *addr_num, ++ u32 *addr_idx, ++ u32 *addr_desa_l, ++ u32 *addr_desa_h) ++{ ++ switch (rxch) { ++ case_RXCHADDRS(RXQ); ++ case_RXCHADDRS(RPQ); ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++#undef case_RXCHADDRS ++ ++static u32 rtw89_pci_get_avail_txbd_num(struct rtw89_pci_tx_ring *ring) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &ring->bd_ring; ++ ++ /* reserved 1 desc check ring is full or not */ ++ if (bd_ring->rp > bd_ring->wp) ++ return bd_ring->rp - bd_ring->wp - 1; ++ ++ return bd_ring->len - (bd_ring->wp - bd_ring->rp) - 1; ++} ++ ++static ++u32 __rtw89_pci_check_and_reclaim_tx_fwcmd_resource(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[RTW89_TXCH_CH12]; ++ u32 cnt; ++ ++ spin_lock_bh(&rtwpci->trx_lock); ++ rtw89_pci_reclaim_tx_fwcmd(rtwdev, rtwpci); ++ cnt = rtw89_pci_get_avail_txbd_num(tx_ring); ++ spin_unlock_bh(&rtwpci->trx_lock); ++ ++ return cnt; ++} ++ ++static u32 __rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, ++ u8 txch) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[txch]; ++ struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; ++ u32 bd_cnt, wd_cnt, min_cnt = 0; ++ struct rtw89_pci_rx_ring *rx_ring; ++ u32 cnt; ++ ++ rx_ring = &rtwpci->rx_rings[RTW89_RXCH_RPQ]; ++ ++ spin_lock_bh(&rtwpci->trx_lock); ++ bd_cnt = rtw89_pci_get_avail_txbd_num(tx_ring); ++ wd_cnt = wd_ring->curr_num; ++ ++ if (wd_cnt == 0 || bd_cnt == 0) { ++ cnt = rtw89_pci_rxbd_recalc(rtwdev, rx_ring); ++ if (!cnt) ++ goto out_unlock; ++ rtw89_pci_release_tx(rtwdev, rx_ring, cnt); ++ } ++ ++ bd_cnt = rtw89_pci_get_avail_txbd_num(tx_ring); ++ wd_cnt = wd_ring->curr_num; ++ min_cnt = min(bd_cnt, wd_cnt); ++ if (min_cnt == 0) ++ rtw89_warn(rtwdev, "still no tx resource after reclaim\n"); ++ ++out_unlock: ++ spin_unlock_bh(&rtwpci->trx_lock); ++ ++ return min_cnt; ++} ++ ++static u32 rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, ++ u8 txch) ++{ ++ if (txch == RTW89_TXCH_CH12) ++ return __rtw89_pci_check_and_reclaim_tx_fwcmd_resource(rtwdev); ++ ++ return __rtw89_pci_check_and_reclaim_tx_resource(rtwdev, txch); ++} ++ ++static void __rtw89_pci_tx_kick_off(struct rtw89_dev *rtwdev, struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; ++ u32 host_idx, addr; ++ ++ addr = bd_ring->addr_idx; ++ host_idx = bd_ring->wp; ++ rtw89_write16(rtwdev, addr, host_idx); ++} ++ ++static void rtw89_pci_tx_bd_ring_update(struct rtw89_dev *rtwdev, struct rtw89_pci_tx_ring *tx_ring, ++ int n_txbd) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; ++ u32 host_idx, len; ++ ++ len = bd_ring->len; ++ host_idx = bd_ring->wp + n_txbd; ++ host_idx = host_idx < len ? host_idx : host_idx - len; ++ ++ bd_ring->wp = host_idx; ++} ++ ++static void rtw89_pci_ops_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[txch]; ++ ++ spin_lock_bh(&rtwpci->trx_lock); ++ __rtw89_pci_tx_kick_off(rtwdev, tx_ring); ++ spin_unlock_bh(&rtwpci->trx_lock); ++} ++ ++static void __pci_flush_txch(struct rtw89_dev *rtwdev, u8 txch, bool drop) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[txch]; ++ struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; ++ u32 cur_idx, cur_rp; ++ u8 i; ++ ++ /* Because the time taked by the I/O is a bit dynamic, it's hard to ++ * define a reasonable fixed total timeout to use read_poll_timeout* ++ * helper. Instead, we can ensure a reasonable polling times, so we ++ * just use for loop with udelay here. ++ */ ++ for (i = 0; i < 60; i++) { ++ cur_idx = rtw89_read32(rtwdev, bd_ring->addr_idx); ++ cur_rp = FIELD_GET(TXBD_HW_IDX_MASK, cur_idx); ++ if (cur_rp == bd_ring->wp) ++ return; ++ ++ udelay(1); ++ } ++ ++ if (!drop) ++ rtw89_info(rtwdev, "timed out to flush pci txch: %d\n", txch); ++} ++ ++static void __rtw89_pci_ops_flush_txchs(struct rtw89_dev *rtwdev, u32 txchs, ++ bool drop) ++{ ++ u8 i; ++ ++ for (i = 0; i < RTW89_TXCH_NUM; i++) { ++ /* It may be unnecessary to flush FWCMD queue. */ ++ if (i == RTW89_TXCH_CH12) ++ continue; ++ ++ if (txchs & BIT(i)) ++ __pci_flush_txch(rtwdev, i, drop); ++ } ++} ++ ++static void rtw89_pci_ops_flush_queues(struct rtw89_dev *rtwdev, u32 queues, ++ bool drop) ++{ ++ __rtw89_pci_ops_flush_txchs(rtwdev, BIT(RTW89_TXCH_NUM) - 1, drop); ++} ++ ++static int rtw89_pci_txwd_submit(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring, ++ struct rtw89_pci_tx_wd *txwd, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; ++ struct rtw89_txwd_body *txwd_body; ++ struct rtw89_txwd_info *txwd_info; ++ struct rtw89_pci_tx_wp_info *txwp_info; ++ struct rtw89_pci_tx_addr_info_32 *txaddr_info; ++ struct pci_dev *pdev = rtwpci->pdev; ++ struct sk_buff *skb = tx_req->skb; ++ struct rtw89_pci_tx_data *tx_data = RTW89_PCI_TX_SKB_CB(skb); ++ bool en_wd_info = desc_info->en_wd_info; ++ u32 txwd_len; ++ u32 txwp_len; ++ u32 txaddr_info_len; ++ dma_addr_t dma; ++ int ret; ++ ++ rtw89_core_fill_txdesc(rtwdev, desc_info, txwd->vaddr); ++ ++ dma = dma_map_single(&pdev->dev, skb->data, skb->len, DMA_TO_DEVICE); ++ if (dma_mapping_error(&pdev->dev, dma)) { ++ rtw89_err(rtwdev, "failed to map skb dma data\n"); ++ ret = -EBUSY; ++ goto err; ++ } ++ ++ tx_data->dma = dma; ++ ++ txaddr_info_len = sizeof(*txaddr_info); ++ txwp_len = sizeof(*txwp_info); ++ txwd_len = sizeof(*txwd_body); ++ txwd_len += en_wd_info ? sizeof(*txwd_info) : 0; ++ ++ txwp_info = txwd->vaddr + txwd_len; ++ txwp_info->seq0 = cpu_to_le16(txwd->seq | RTW89_PCI_TXWP_VALID); ++ txwp_info->seq1 = 0; ++ txwp_info->seq2 = 0; ++ txwp_info->seq3 = 0; ++ ++ tx_ring->tx_cnt++; ++ txaddr_info = txwd->vaddr + txwd_len + txwp_len; ++ txaddr_info->length = cpu_to_le16(skb->len); ++ txaddr_info->option = cpu_to_le16(RTW89_PCI_ADDR_MSDU_LS | ++ RTW89_PCI_ADDR_NUM(1)); ++ txaddr_info->dma = cpu_to_le32(dma); ++ ++ txwd->len = txwd_len + txwp_len + txaddr_info_len; ++ ++ skb_queue_tail(&txwd->queue, skb); ++ ++ return 0; ++ ++err: ++ return ret; ++} ++ ++static int rtw89_pci_fwcmd_submit(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring, ++ struct rtw89_pci_tx_bd_32 *txbd, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; ++ struct rtw89_txwd_body *txwd_body; ++ struct pci_dev *pdev = rtwpci->pdev; ++ struct sk_buff *skb = tx_req->skb; ++ struct rtw89_pci_tx_data *tx_data = RTW89_PCI_TX_SKB_CB(skb); ++ dma_addr_t dma; ++ ++ txwd_body = (struct rtw89_txwd_body *)skb_push(skb, sizeof(*txwd_body)); ++ memset(txwd_body, 0, sizeof(*txwd_body)); ++ rtw89_core_fill_txdesc(rtwdev, desc_info, txwd_body); ++ ++ dma = dma_map_single(&pdev->dev, skb->data, skb->len, DMA_TO_DEVICE); ++ if (dma_mapping_error(&pdev->dev, dma)) { ++ rtw89_err(rtwdev, "failed to map fwcmd dma data\n"); ++ return -EBUSY; ++ } ++ ++ tx_data->dma = dma; ++ txbd->option = cpu_to_le16(RTW89_PCI_TXBD_OPTION_LS); ++ txbd->length = cpu_to_le16(skb->len); ++ txbd->dma = cpu_to_le32(tx_data->dma); ++ skb_queue_tail(&rtwpci->h2c_queue, skb); ++ ++ rtw89_pci_tx_bd_ring_update(rtwdev, tx_ring, 1); ++ ++ return 0; ++} ++ ++static int rtw89_pci_txbd_submit(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring, ++ struct rtw89_pci_tx_bd_32 *txbd, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ struct rtw89_pci_tx_wd *txwd; ++ int ret; ++ ++ /* FWCMD queue doesn't have wd pages. Instead, it submits the CMD ++ * buffer with WD BODY only. So here we don't need to check the free ++ * pages of the wd ring. ++ */ ++ if (tx_ring->txch == RTW89_TXCH_CH12) ++ return rtw89_pci_fwcmd_submit(rtwdev, tx_ring, txbd, tx_req); ++ ++ txwd = rtw89_pci_dequeue_txwd(tx_ring); ++ if (!txwd) { ++ rtw89_err(rtwdev, "no available TXWD\n"); ++ ret = -ENOSPC; ++ goto err; ++ } ++ ++ ret = rtw89_pci_txwd_submit(rtwdev, tx_ring, txwd, tx_req); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to submit TXWD %d\n", txwd->seq); ++ goto err_enqueue_wd; ++ } ++ ++ list_add_tail(&txwd->list, &tx_ring->busy_pages); ++ ++ txbd->option = cpu_to_le16(RTW89_PCI_TXBD_OPTION_LS); ++ txbd->length = cpu_to_le16(txwd->len); ++ txbd->dma = cpu_to_le32(txwd->paddr); ++ ++ rtw89_pci_tx_bd_ring_update(rtwdev, tx_ring, 1); ++ ++ return 0; ++ ++err_enqueue_wd: ++ rtw89_pci_enqueue_txwd(tx_ring, txwd); ++err: ++ return ret; ++} ++ ++static int rtw89_pci_tx_write(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req, ++ u8 txch) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring; ++ struct rtw89_pci_tx_bd_32 *txbd; ++ u32 n_avail_txbd; ++ int ret = 0; ++ ++ /* check the tx type and dma channel for fw cmd queue */ ++ if ((txch == RTW89_TXCH_CH12 || ++ tx_req->tx_type == RTW89_CORE_TX_TYPE_FWCMD) && ++ (txch != RTW89_TXCH_CH12 || ++ tx_req->tx_type != RTW89_CORE_TX_TYPE_FWCMD)) { ++ rtw89_err(rtwdev, "only fw cmd uses dma channel 12\n"); ++ return -EINVAL; ++ } ++ ++ tx_ring = &rtwpci->tx_rings[txch]; ++ spin_lock_bh(&rtwpci->trx_lock); ++ ++ n_avail_txbd = rtw89_pci_get_avail_txbd_num(tx_ring); ++ if (n_avail_txbd == 0) { ++ rtw89_err(rtwdev, "no available TXBD\n"); ++ ret = -ENOSPC; ++ goto err_unlock; ++ } ++ ++ txbd = rtw89_pci_get_next_txbd(tx_ring); ++ ret = rtw89_pci_txbd_submit(rtwdev, tx_ring, txbd, tx_req); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to submit TXBD\n"); ++ goto err_unlock; ++ } ++ ++ spin_unlock_bh(&rtwpci->trx_lock); ++ return 0; ++ ++err_unlock: ++ spin_unlock_bh(&rtwpci->trx_lock); ++ return ret; ++} ++ ++static int rtw89_pci_ops_tx_write(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) ++{ ++ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; ++ int ret; ++ ++ ret = rtw89_pci_tx_write(rtwdev, tx_req, desc_info->ch_dma); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to TX Queue %d\n", desc_info->ch_dma); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static const struct rtw89_pci_bd_ram bd_ram_table[RTW89_TXCH_NUM] = { ++ [RTW89_TXCH_ACH0] = {.start_idx = 0, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_ACH1] = {.start_idx = 5, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_ACH2] = {.start_idx = 10, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_ACH3] = {.start_idx = 15, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_ACH4] = {.start_idx = 20, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_ACH5] = {.start_idx = 25, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_ACH6] = {.start_idx = 30, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_ACH7] = {.start_idx = 35, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_CH8] = {.start_idx = 40, .max_num = 5, .min_num = 1}, ++ [RTW89_TXCH_CH9] = {.start_idx = 45, .max_num = 5, .min_num = 1}, ++ [RTW89_TXCH_CH10] = {.start_idx = 50, .max_num = 5, .min_num = 1}, ++ [RTW89_TXCH_CH11] = {.start_idx = 55, .max_num = 5, .min_num = 1}, ++ [RTW89_TXCH_CH12] = {.start_idx = 60, .max_num = 4, .min_num = 1}, ++}; ++ ++static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring; ++ struct rtw89_pci_rx_ring *rx_ring; ++ struct rtw89_pci_dma_ring *bd_ring; ++ const struct rtw89_pci_bd_ram *bd_ram; ++ u32 addr_num; ++ u32 addr_bdram; ++ u32 addr_desa_l; ++ u32 val32; ++ int i; ++ ++ for (i = 0; i < RTW89_TXCH_NUM; i++) { ++ tx_ring = &rtwpci->tx_rings[i]; ++ bd_ring = &tx_ring->bd_ring; ++ bd_ram = &bd_ram_table[i]; ++ addr_num = bd_ring->addr_num; ++ addr_bdram = bd_ring->addr_bdram; ++ addr_desa_l = bd_ring->addr_desa_l; ++ bd_ring->wp = 0; ++ bd_ring->rp = 0; ++ ++ val32 = FIELD_PREP(BDRAM_SIDX_MASK, bd_ram->start_idx) | ++ FIELD_PREP(BDRAM_MAX_MASK, bd_ram->max_num) | ++ FIELD_PREP(BDRAM_MIN_MASK, bd_ram->min_num); ++ ++ rtw89_write16(rtwdev, addr_num, bd_ring->len); ++ rtw89_write32(rtwdev, addr_bdram, val32); ++ rtw89_write32(rtwdev, addr_desa_l, bd_ring->dma); ++ } ++ ++ for (i = 0; i < RTW89_RXCH_NUM; i++) { ++ rx_ring = &rtwpci->rx_rings[i]; ++ bd_ring = &rx_ring->bd_ring; ++ addr_num = bd_ring->addr_num; ++ addr_desa_l = bd_ring->addr_desa_l; ++ bd_ring->wp = 0; ++ bd_ring->rp = 0; ++ rx_ring->diliver_skb = NULL; ++ rx_ring->diliver_desc.ready = false; ++ ++ rtw89_write16(rtwdev, addr_num, bd_ring->len); ++ rtw89_write32(rtwdev, addr_desa_l, bd_ring->dma); ++ } ++} ++ ++static void rtw89_pci_release_tx_ring(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring) ++{ ++ rtw89_pci_release_busy_txwd(rtwdev, tx_ring); ++ rtw89_pci_release_pending_txwd_skb(rtwdev, tx_ring); ++} ++ ++static void rtw89_pci_ops_reset(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ int txch; ++ ++ rtw89_pci_reset_trx_rings(rtwdev); ++ ++ spin_lock_bh(&rtwpci->trx_lock); ++ for (txch = 0; txch < RTW89_TXCH_NUM; txch++) { ++ if (txch == RTW89_TXCH_CH12) { ++ rtw89_pci_release_fwcmd(rtwdev, rtwpci, ++ skb_queue_len(&rtwpci->h2c_queue), true); ++ continue; ++ } ++ rtw89_pci_release_tx_ring(rtwdev, &rtwpci->tx_rings[txch]); ++ } ++ spin_unlock_bh(&rtwpci->trx_lock); ++} ++ ++static int rtw89_pci_ops_start(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ unsigned long flags; ++ ++ rtw89_core_napi_start(rtwdev); ++ ++ spin_lock_irqsave(&rtwpci->irq_lock, flags); ++ rtwpci->running = true; ++ rtw89_pci_enable_intr(rtwdev, rtwpci); ++ spin_unlock_irqrestore(&rtwpci->irq_lock, flags); ++ ++ return 0; ++} ++ ++static void rtw89_pci_ops_stop(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct pci_dev *pdev = rtwpci->pdev; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&rtwpci->irq_lock, flags); ++ rtwpci->running = false; ++ rtw89_pci_disable_intr(rtwdev, rtwpci); ++ spin_unlock_irqrestore(&rtwpci->irq_lock, flags); ++ ++ synchronize_irq(pdev->irq); ++ rtw89_core_napi_stop(rtwdev); ++} ++ ++static void rtw89_pci_ops_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data); ++ ++static u32 rtw89_pci_ops_read32_cmac(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ u32 val = readl(rtwpci->mmap + addr); ++ int count; ++ ++ for (count = 0; ; count++) { ++ if (val != RTW89_R32_DEAD) ++ return val; ++ if (count >= MAC_REG_POOL_COUNT) { ++ rtw89_warn(rtwdev, "addr %#x = %#x\n", addr, val); ++ return RTW89_R32_DEAD; ++ } ++ rtw89_pci_ops_write32(rtwdev, R_AX_CK_EN, B_AX_CMAC_ALLCKEN); ++ val = readl(rtwpci->mmap + addr); ++ } ++ ++ return val; ++} ++ ++static u8 rtw89_pci_ops_read8(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ u32 addr32, val32, shift; ++ ++ if (!ACCESS_CMAC(addr)) ++ return readb(rtwpci->mmap + addr); ++ ++ addr32 = addr & ~0x3; ++ shift = (addr & 0x3) * 8; ++ val32 = rtw89_pci_ops_read32_cmac(rtwdev, addr32); ++ return val32 >> shift; ++} ++ ++static u16 rtw89_pci_ops_read16(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ u32 addr32, val32, shift; ++ ++ if (!ACCESS_CMAC(addr)) ++ return readw(rtwpci->mmap + addr); ++ ++ addr32 = addr & ~0x3; ++ shift = (addr & 0x3) * 8; ++ val32 = rtw89_pci_ops_read32_cmac(rtwdev, addr32); ++ return val32 >> shift; ++} ++ ++static u32 rtw89_pci_ops_read32(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ ++ if (!ACCESS_CMAC(addr)) ++ return readl(rtwpci->mmap + addr); ++ ++ return rtw89_pci_ops_read32_cmac(rtwdev, addr); ++} ++ ++static void rtw89_pci_ops_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ ++ writeb(data, rtwpci->mmap + addr); ++} ++ ++static void rtw89_pci_ops_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ ++ writew(data, rtwpci->mmap + addr); ++} ++ ++static void rtw89_pci_ops_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ ++ writel(data, rtwpci->mmap + addr); ++} ++ ++static void rtw89_pci_ctrl_dma_all(struct rtw89_dev *rtwdev, bool enable) ++{ ++ if (enable) { ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, ++ B_AX_TXHCI_EN | B_AX_RXHCI_EN); ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP1, ++ B_AX_STOP_PCIEIO); ++ } else { ++ rtw89_write32_set(rtwdev, R_AX_PCIE_DMA_STOP1, ++ B_AX_STOP_PCIEIO); ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, ++ B_AX_TXHCI_EN | B_AX_RXHCI_EN); ++ } ++} ++ ++static int rtw89_pci_check_mdio(struct rtw89_dev *rtwdev, u8 addr, u8 speed, u16 rw_bit) ++{ ++ u16 val; ++ ++ rtw89_write8(rtwdev, R_AX_MDIO_CFG, addr & 0x1F); ++ ++ val = rtw89_read16(rtwdev, R_AX_MDIO_CFG); ++ switch (speed) { ++ case PCIE_PHY_GEN1: ++ if (addr < 0x20) ++ val = u16_replace_bits(val, MDIO_PG0_G1, B_AX_MDIO_PHY_ADDR_MASK); ++ else ++ val = u16_replace_bits(val, MDIO_PG1_G1, B_AX_MDIO_PHY_ADDR_MASK); ++ break; ++ case PCIE_PHY_GEN2: ++ if (addr < 0x20) ++ val = u16_replace_bits(val, MDIO_PG0_G2, B_AX_MDIO_PHY_ADDR_MASK); ++ else ++ val = u16_replace_bits(val, MDIO_PG1_G2, B_AX_MDIO_PHY_ADDR_MASK); ++ break; ++ default: ++ rtw89_err(rtwdev, "[ERR]Error Speed %d!\n", speed); ++ return -EINVAL; ++ }; ++ rtw89_write16(rtwdev, R_AX_MDIO_CFG, val); ++ rtw89_write16_set(rtwdev, R_AX_MDIO_CFG, rw_bit); ++ ++ return read_poll_timeout(rtw89_read16, val, !(val & rw_bit), 10, 2000, ++ false, rtwdev, R_AX_MDIO_CFG); ++} ++ ++static int ++rtw89_read16_mdio(struct rtw89_dev *rtwdev, u8 addr, u8 speed, u16 *val) ++{ ++ int ret; ++ ++ ret = rtw89_pci_check_mdio(rtwdev, addr, speed, B_AX_MDIO_RFLAG); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]MDIO R16 0x%X fail ret=%d!\n", addr, ret); ++ return ret; ++ } ++ *val = rtw89_read16(rtwdev, R_AX_MDIO_RDATA); ++ ++ return 0; ++} ++ ++static int ++rtw89_write16_mdio(struct rtw89_dev *rtwdev, u8 addr, u16 data, u8 speed) ++{ ++ int ret; ++ ++ rtw89_write16(rtwdev, R_AX_MDIO_WDATA, data); ++ ret = rtw89_pci_check_mdio(rtwdev, addr, speed, B_AX_MDIO_WFLAG); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]MDIO W16 0x%X = %x fail ret=%d!\n", addr, data, ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int rtw89_write16_mdio_set(struct rtw89_dev *rtwdev, u8 addr, u16 mask, u8 speed) ++{ ++ int ret; ++ u16 val; ++ ++ ret = rtw89_read16_mdio(rtwdev, addr, speed, &val); ++ if (ret) ++ return ret; ++ ret = rtw89_write16_mdio(rtwdev, addr, val | mask, speed); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int rtw89_write16_mdio_clr(struct rtw89_dev *rtwdev, u8 addr, u16 mask, u8 speed) ++{ ++ int ret; ++ u16 val; ++ ++ ret = rtw89_read16_mdio(rtwdev, addr, speed, &val); ++ if (ret) ++ return ret; ++ ret = rtw89_write16_mdio(rtwdev, addr, val & ~mask, speed); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int rtw89_dbi_write8(struct rtw89_dev *rtwdev, u16 addr, u8 data) ++{ ++ u16 write_addr; ++ u16 remainder = addr & ~(B_AX_DBI_ADDR_MSK | B_AX_DBI_WREN_MSK); ++ u8 flag; ++ int ret; ++ ++ write_addr = addr & B_AX_DBI_ADDR_MSK; ++ write_addr |= u16_encode_bits(BIT(remainder), B_AX_DBI_WREN_MSK); ++ rtw89_write8(rtwdev, R_AX_DBI_WDATA + remainder, data); ++ rtw89_write16(rtwdev, R_AX_DBI_FLAG, write_addr); ++ rtw89_write8(rtwdev, R_AX_DBI_FLAG + 2, B_AX_DBI_WFLAG >> 16); ++ ++ ret = read_poll_timeout_atomic(rtw89_read8, flag, !flag, 10, ++ 10 * RTW89_PCI_WR_RETRY_CNT, false, ++ rtwdev, R_AX_DBI_FLAG + 2); ++ if (ret) ++ WARN(flag, "failed to write to DBI register, addr=0x%04x\n", ++ addr); ++ ++ return ret; ++} ++ ++static int rtw89_dbi_read8(struct rtw89_dev *rtwdev, u16 addr, u8 *value) ++{ ++ u16 read_addr = addr & B_AX_DBI_ADDR_MSK; ++ u8 flag; ++ int ret; ++ ++ rtw89_write16(rtwdev, R_AX_DBI_FLAG, read_addr); ++ rtw89_write8(rtwdev, R_AX_DBI_FLAG + 2, B_AX_DBI_RFLAG >> 16); ++ ++ ret = read_poll_timeout_atomic(rtw89_read8, flag, !flag, 10, ++ 10 * RTW89_PCI_WR_RETRY_CNT, false, ++ rtwdev, R_AX_DBI_FLAG + 2); ++ ++ if (!ret) { ++ read_addr = R_AX_DBI_RDATA + (addr & 3); ++ *value = rtw89_read8(rtwdev, read_addr); ++ } else { ++ WARN(1, "failed to read DBI register, addr=0x%04x\n", addr); ++ ret = -EIO; ++ } ++ ++ return ret; ++} ++ ++static int rtw89_dbi_write8_set(struct rtw89_dev *rtwdev, u16 addr, u8 bit) ++{ ++ u8 value; ++ int ret; ++ ++ ret = rtw89_dbi_read8(rtwdev, addr, &value); ++ if (ret) ++ return ret; ++ ++ value |= bit; ++ ret = rtw89_dbi_write8(rtwdev, addr, value); ++ ++ return ret; ++} ++ ++static int rtw89_dbi_write8_clr(struct rtw89_dev *rtwdev, u16 addr, u8 bit) ++{ ++ u8 value; ++ int ret; ++ ++ ret = rtw89_dbi_read8(rtwdev, addr, &value); ++ if (ret) ++ return ret; ++ ++ value &= ~bit; ++ ret = rtw89_dbi_write8(rtwdev, addr, value); ++ ++ return ret; ++} ++ ++static int ++__get_target(struct rtw89_dev *rtwdev, u16 *target, enum rtw89_pcie_phy phy_rate) ++{ ++ u16 val, tar; ++ int ret; ++ ++ /* Enable counter */ ++ ret = rtw89_read16_mdio(rtwdev, RAC_CTRL_PPR_V1, phy_rate, &val); ++ if (ret) ++ return ret; ++ ret = rtw89_write16_mdio(rtwdev, RAC_CTRL_PPR_V1, val & ~B_AX_CLK_CALIB_EN, ++ phy_rate); ++ if (ret) ++ return ret; ++ ret = rtw89_write16_mdio(rtwdev, RAC_CTRL_PPR_V1, val | B_AX_CLK_CALIB_EN, ++ phy_rate); ++ if (ret) ++ return ret; ++ ++ fsleep(300); ++ ++ ret = rtw89_read16_mdio(rtwdev, RAC_CTRL_PPR_V1, phy_rate, &tar); ++ if (ret) ++ return ret; ++ ret = rtw89_write16_mdio(rtwdev, RAC_CTRL_PPR_V1, val & ~B_AX_CLK_CALIB_EN, ++ phy_rate); ++ if (ret) ++ return ret; ++ ++ tar = tar & 0x0FFF; ++ if (tar == 0 || tar == 0x0FFF) { ++ rtw89_err(rtwdev, "[ERR]Get target failed.\n"); ++ return -EINVAL; ++ } ++ ++ *target = tar; ++ ++ return 0; ++} ++ ++static int rtw89_pci_auto_refclk_cal(struct rtw89_dev *rtwdev, bool autook_en) ++{ ++ enum rtw89_pcie_phy phy_rate; ++ u16 val16, mgn_set, div_set, tar; ++ u8 val8, bdr_ori; ++ bool l1_flag = false; ++ int ret = 0; ++ ++ if ((rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv == CHIP_CBV) || ++ rtwdev->chip->chip_id == RTL8852C) ++ return 0; ++ ++ ret = rtw89_dbi_read8(rtwdev, RTW89_PCIE_PHY_RATE, &val8); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]dbi_r8_pcie %X\n", RTW89_PCIE_PHY_RATE); ++ return ret; ++ } ++ ++ if (FIELD_GET(RTW89_PCIE_PHY_RATE_MASK, val8) == 0x1) { ++ phy_rate = PCIE_PHY_GEN1; ++ } else if (FIELD_GET(RTW89_PCIE_PHY_RATE_MASK, val8) == 0x2) { ++ phy_rate = PCIE_PHY_GEN2; ++ } else { ++ rtw89_err(rtwdev, "[ERR]PCIe PHY rate %#x not support\n", val8); ++ return -EOPNOTSUPP; ++ } ++ /* Disable L1BD */ ++ ret = rtw89_dbi_read8(rtwdev, RTW89_PCIE_L1_CTRL, &bdr_ori); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]dbi_r8_pcie %X\n", RTW89_PCIE_L1_CTRL); ++ return ret; ++ } ++ ++ if (bdr_ori & RTW89_PCIE_BIT_L1) { ++ ret = rtw89_dbi_write8(rtwdev, RTW89_PCIE_L1_CTRL, ++ bdr_ori & ~RTW89_PCIE_BIT_L1); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]dbi_w8_pcie %X\n", RTW89_PCIE_L1_CTRL); ++ return ret; ++ } ++ l1_flag = true; ++ } ++ ++ ret = rtw89_read16_mdio(rtwdev, RAC_CTRL_PPR_V1, phy_rate, &val16); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]mdio_r16_pcie %X\n", RAC_CTRL_PPR_V1); ++ goto end; ++ } ++ ++ if (val16 & B_AX_CALIB_EN) { ++ ret = rtw89_write16_mdio(rtwdev, RAC_CTRL_PPR_V1, ++ val16 & ~B_AX_CALIB_EN, phy_rate); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]mdio_w16_pcie %X\n", RAC_CTRL_PPR_V1); ++ goto end; ++ } ++ } ++ ++ if (!autook_en) ++ goto end; ++ /* Set div */ ++ ret = rtw89_write16_mdio_clr(rtwdev, RAC_CTRL_PPR_V1, B_AX_DIV, phy_rate); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]mdio_w16_pcie %X\n", RAC_CTRL_PPR_V1); ++ goto end; ++ } ++ ++ /* Obtain div and margin */ ++ ret = __get_target(rtwdev, &tar, phy_rate); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]1st get target fail %d\n", ret); ++ goto end; ++ } ++ ++ mgn_set = tar * INTF_INTGRA_HOSTREF_V1 / INTF_INTGRA_MINREF_V1 - tar; ++ ++ if (mgn_set >= 128) { ++ div_set = 0x0003; ++ mgn_set = 0x000F; ++ } else if (mgn_set >= 64) { ++ div_set = 0x0003; ++ mgn_set >>= 3; ++ } else if (mgn_set >= 32) { ++ div_set = 0x0002; ++ mgn_set >>= 2; ++ } else if (mgn_set >= 16) { ++ div_set = 0x0001; ++ mgn_set >>= 1; ++ } else if (mgn_set == 0) { ++ rtw89_err(rtwdev, "[ERR]cal mgn is 0,tar = %d\n", tar); ++ goto end; ++ } else { ++ div_set = 0x0000; ++ } ++ ++ ret = rtw89_read16_mdio(rtwdev, RAC_CTRL_PPR_V1, phy_rate, &val16); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]mdio_r16_pcie %X\n", RAC_CTRL_PPR_V1); ++ goto end; ++ } ++ ++ val16 |= u16_encode_bits(div_set, B_AX_DIV); ++ ++ ret = rtw89_write16_mdio(rtwdev, RAC_CTRL_PPR_V1, val16, phy_rate); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]mdio_w16_pcie %X\n", RAC_CTRL_PPR_V1); ++ goto end; ++ } ++ ++ ret = __get_target(rtwdev, &tar, phy_rate); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]2nd get target fail %d\n", ret); ++ goto end; ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_HCI, "[TRACE]target = 0x%X, div = 0x%X, margin = 0x%X\n", ++ tar, div_set, mgn_set); ++ ret = rtw89_write16_mdio(rtwdev, RAC_SET_PPR_V1, ++ (tar & 0x0FFF) | (mgn_set << 12), phy_rate); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]mdio_w16_pcie %X\n", RAC_SET_PPR_V1); ++ goto end; ++ } ++ ++ /* Enable function */ ++ ret = rtw89_write16_mdio_set(rtwdev, RAC_CTRL_PPR_V1, B_AX_CALIB_EN, phy_rate); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]mdio_w16_pcie %X\n", RAC_CTRL_PPR_V1); ++ goto end; ++ } ++ ++ /* CLK delay = 0 */ ++ ret = rtw89_dbi_write8(rtwdev, RTW89_PCIE_CLK_CTRL, PCIE_CLKDLY_HW_0); ++ ++end: ++ /* Set L1BD to ori */ ++ if (l1_flag) { ++ ret = rtw89_dbi_write8(rtwdev, RTW89_PCIE_L1_CTRL, bdr_ori); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]dbi_w8_pcie %X\n", RTW89_PCIE_L1_CTRL); ++ return ret; ++ } ++ } ++ ++ return ret; ++} ++ ++static int rtw89_pci_deglitch_setting(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ if (rtwdev->chip->chip_id != RTL8852A) ++ return 0; ++ ++ ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA24, B_AX_DEGLITCH, ++ PCIE_PHY_GEN1); ++ if (ret) ++ return ret; ++ ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA24, B_AX_DEGLITCH, ++ PCIE_PHY_GEN2); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static void rtw89_pci_rxdma_prefth(struct rtw89_dev *rtwdev) ++{ ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_DIS_RXDMA_PRE); ++} ++ ++static void rtw89_pci_l1off_pwroff(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->chip->chip_id == RTL8852C) ++ return; ++ ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_PS_CTRL, B_AX_L1OFF_PWR_OFF_EN); ++} ++ ++static u32 rtw89_pci_l2_rxen_lat(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ if (rtwdev->chip->chip_id == RTL8852C) ++ return 0; ++ ++ ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA26, B_AX_RXEN, ++ PCIE_PHY_GEN1); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA26, B_AX_RXEN, ++ PCIE_PHY_GEN2); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static void rtw89_pci_aphy_pwrcut(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->chip->chip_id != RTL8852A) ++ return; ++ ++ rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_PSUS_OFF_CAPC_EN); ++} ++ ++static void rtw89_pci_hci_ldo(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->chip->chip_id != RTL8852A) ++ return; ++ ++ rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL, ++ B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); ++ rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, ++ B_AX_PCIE_DIS_WLSUS_AFT_PDN); ++} ++ ++static void rtw89_pci_set_sic(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->chip->chip_id == RTL8852C) ++ return; ++ ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_EXP_CTRL, ++ B_AX_SIC_EN_FORCE_CLKREQ); ++} ++ ++static void rtw89_pci_set_dbg(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->chip->chip_id == RTL8852C) ++ return; ++ ++ rtw89_write32_set(rtwdev, R_AX_PCIE_DBG_CTRL, ++ B_AX_ASFF_FULL_NO_STK | B_AX_EN_STUCK_DBG); ++ ++ if (rtwdev->chip->chip_id == RTL8852A) ++ rtw89_write32_set(rtwdev, R_AX_PCIE_EXP_CTRL, ++ B_AX_EN_CHKDSC_NO_RX_STUCK); ++} ++ ++static void rtw89_pci_clr_idx_all(struct rtw89_dev *rtwdev) ++{ ++ u32 val = B_AX_CLR_ACH0_IDX | B_AX_CLR_ACH1_IDX | B_AX_CLR_ACH2_IDX | ++ B_AX_CLR_ACH3_IDX | B_AX_CLR_CH8_IDX | B_AX_CLR_CH9_IDX | ++ B_AX_CLR_CH12_IDX; ++ ++ if (rtwdev->chip->chip_id == RTL8852A) ++ val |= B_AX_CLR_ACH4_IDX | B_AX_CLR_ACH5_IDX | ++ B_AX_CLR_ACH6_IDX | B_AX_CLR_ACH7_IDX; ++ /* clear DMA indexes */ ++ rtw89_write32_set(rtwdev, R_AX_TXBD_RWPTR_CLR1, val); ++ if (rtwdev->chip->chip_id == RTL8852A) ++ rtw89_write32_set(rtwdev, R_AX_TXBD_RWPTR_CLR2, ++ B_AX_CLR_CH10_IDX | B_AX_CLR_CH11_IDX); ++ rtw89_write32_set(rtwdev, R_AX_RXBD_RWPTR_CLR, ++ B_AX_CLR_RXQ_IDX | B_AX_CLR_RPQ_IDX); ++} ++ ++static int rtw89_pci_ops_deinit(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->chip->chip_id == RTL8852A) { ++ /* ltr sw trigger */ ++ rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_APP_LTR_IDLE); ++ } ++ rtw89_pci_ctrl_dma_all(rtwdev, false); ++ rtw89_pci_clr_idx_all(rtwdev); ++ ++ return 0; ++} ++ ++static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev) ++{ ++ u32 dma_busy; ++ u32 check; ++ u32 lbc; ++ int ret; ++ ++ rtw89_pci_rxdma_prefth(rtwdev); ++ rtw89_pci_l1off_pwroff(rtwdev); ++ rtw89_pci_deglitch_setting(rtwdev); ++ ret = rtw89_pci_l2_rxen_lat(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] pcie l2 rxen lat %d\n", ret); ++ return ret; ++ } ++ ++ rtw89_pci_aphy_pwrcut(rtwdev); ++ rtw89_pci_hci_ldo(rtwdev); ++ ++ ret = rtw89_pci_auto_refclk_cal(rtwdev, false); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] pcie autok fail %d\n", ret); ++ return ret; ++ } ++ ++ rtw89_pci_set_sic(rtwdev); ++ rtw89_pci_set_dbg(rtwdev); ++ ++ if (rtwdev->chip->chip_id == RTL8852A) ++ rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, ++ B_AX_PCIE_AUXCLK_GATE); ++ ++ lbc = rtw89_read32(rtwdev, R_AX_LBC_WATCHDOG); ++ lbc = u32_replace_bits(lbc, RTW89_MAC_LBC_TMR_128US, B_AX_LBC_TIMER); ++ lbc |= B_AX_LBC_FLAG | B_AX_LBC_EN; ++ rtw89_write32(rtwdev, R_AX_LBC_WATCHDOG, lbc); ++ ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, ++ B_AX_PCIE_TXRST_KEEP_REG | B_AX_PCIE_RXRST_KEEP_REG); ++ rtw89_write32_set(rtwdev, R_AX_PCIE_DMA_STOP1, B_AX_STOP_WPDMA); ++ ++ /* stop DMA activities */ ++ rtw89_pci_ctrl_dma_all(rtwdev, false); ++ ++ /* check PCI at idle state */ ++ check = B_AX_PCIEIO_BUSY | B_AX_PCIEIO_TX_BUSY | B_AX_PCIEIO_RX_BUSY; ++ ret = read_poll_timeout(rtw89_read32, dma_busy, (dma_busy & check) == 0, ++ 100, 3000, false, rtwdev, R_AX_PCIE_DMA_BUSY1); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to poll io busy\n"); ++ return ret; ++ } ++ ++ rtw89_pci_clr_idx_all(rtwdev); ++ ++ /* configure TX/RX op modes */ ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_TX_TRUNC_MODE | ++ B_AX_RX_TRUNC_MODE); ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_RXBD_MODE); ++ rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_PCIE_MAX_TXDMA_MASK, 7); ++ rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_PCIE_MAX_RXDMA_MASK, 3); ++ /* multi-tag mode */ ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_LATENCY_CONTROL); ++ rtw89_write32_mask(rtwdev, R_AX_PCIE_EXP_CTRL, B_AX_MAX_TAG_NUM, ++ RTW89_MAC_TAG_NUM_8); ++ rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG2, B_AX_WD_ITVL_IDLE, ++ RTW89_MAC_WD_DMA_INTVL_256NS); ++ rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG2, B_AX_WD_ITVL_ACT, ++ RTW89_MAC_WD_DMA_INTVL_256NS); ++ ++ /* fill TRX BD indexes */ ++ rtw89_pci_ops_reset(rtwdev); ++ ++ ret = rtw89_pci_rst_bdram_pcie(rtwdev); ++ if (ret) { ++ rtw89_warn(rtwdev, "reset bdram busy\n"); ++ return ret; ++ } ++ ++ /* enable FW CMD queue to download firmware */ ++ rtw89_write32_set(rtwdev, R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_ALL); ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP1, B_AX_STOP_CH12); ++ rtw89_write32_set(rtwdev, R_AX_PCIE_DMA_STOP2, B_AX_TX_STOP2_ALL); ++ ++ /* start DMA activities */ ++ rtw89_pci_ctrl_dma_all(rtwdev, true); ++ ++ return 0; ++} ++ ++static int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev) ++{ ++ u32 val; ++ ++ val = rtw89_read32(rtwdev, R_AX_LTR_CTRL_0); ++ if (rtw89_pci_ltr_is_err_reg_val(val)) ++ return -EINVAL; ++ val = rtw89_read32(rtwdev, R_AX_LTR_CTRL_1); ++ if (rtw89_pci_ltr_is_err_reg_val(val)) ++ return -EINVAL; ++ val = rtw89_read32(rtwdev, R_AX_LTR_IDLE_LATENCY); ++ if (rtw89_pci_ltr_is_err_reg_val(val)) ++ return -EINVAL; ++ val = rtw89_read32(rtwdev, R_AX_LTR_ACTIVE_LATENCY); ++ if (rtw89_pci_ltr_is_err_reg_val(val)) ++ return -EINVAL; ++ ++ rtw89_write32_clr(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_HW_EN); ++ rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_EN); ++ rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_SPACE_IDX_MASK, ++ PCI_LTR_SPC_500US); ++ rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_IDLE_TIMER_IDX_MASK, ++ PCI_LTR_IDLE_TIMER_800US); ++ rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_1, B_AX_LTR_RX0_TH_MASK, 0x28); ++ rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_1, B_AX_LTR_RX1_TH_MASK, 0x28); ++ rtw89_write32(rtwdev, R_AX_LTR_IDLE_LATENCY, 0x88e088e0); ++ rtw89_write32(rtwdev, R_AX_LTR_ACTIVE_LATENCY, 0x880b880b); ++ ++ return 0; ++} ++ ++static int rtw89_pci_ops_mac_post_init(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ ret = rtw89_pci_ltr_set(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "pci ltr set fail\n"); ++ return ret; ++ } ++ if (rtwdev->chip->chip_id == RTL8852A) { ++ /* ltr sw trigger */ ++ rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_APP_LTR_ACT); ++ } ++ /* ADDR info 8-byte mode */ ++ rtw89_write32_set(rtwdev, R_AX_TX_ADDRESS_INFO_MODE_SETTING, ++ B_AX_HOST_ADDR_INFO_8B_SEL); ++ rtw89_write32_clr(rtwdev, R_AX_PKTIN_SETTING, B_AX_WD_ADDR_INFO_LENGTH); ++ ++ /* enable DMA for all queues */ ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_ALL); ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP2, B_AX_TX_STOP2_ALL); ++ ++ /* Release PCI IO */ ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP1, ++ B_AX_STOP_WPDMA | B_AX_STOP_PCIEIO); ++ ++ return 0; ++} ++ ++static int rtw89_pci_claim_device(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ int ret; ++ ++ ret = pci_enable_device(pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to enable pci device\n"); ++ return ret; ++ } ++ ++ pci_set_master(pdev); ++ pci_set_drvdata(pdev, rtwdev->hw); ++ ++ rtwpci->pdev = pdev; ++ ++ return 0; ++} ++ ++static void rtw89_pci_declaim_device(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ pci_clear_master(pdev); ++ pci_disable_device(pdev); ++} ++ ++static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ unsigned long resource_len; ++ u8 bar_id = 2; ++ int ret; ++ ++ ret = pci_request_regions(pdev, KBUILD_MODNAME); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to request pci regions\n"); ++ goto err; ++ } ++ ++ ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to set dma mask to 32-bit\n"); ++ goto err_release_regions; ++ } ++ ++ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to set consistent dma mask to 32-bit\n"); ++ goto err_release_regions; ++ } ++ ++ resource_len = pci_resource_len(pdev, bar_id); ++ rtwpci->mmap = pci_iomap(pdev, bar_id, resource_len); ++ if (!rtwpci->mmap) { ++ rtw89_err(rtwdev, "failed to map pci io\n"); ++ ret = -EIO; ++ goto err_release_regions; ++ } ++ ++ return 0; ++ ++err_release_regions: ++ pci_release_regions(pdev); ++err: ++ return ret; ++} ++ ++static void rtw89_pci_clear_mapping(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ ++ if (rtwpci->mmap) { ++ pci_iounmap(pdev, rtwpci->mmap); ++ pci_release_regions(pdev); ++ } ++} ++ ++static void rtw89_pci_free_tx_wd_ring(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev, ++ struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; ++ u8 *head = wd_ring->head; ++ dma_addr_t dma = wd_ring->dma; ++ u32 page_size = wd_ring->page_size; ++ u32 page_num = wd_ring->page_num; ++ u32 ring_sz = page_size * page_num; ++ ++ dma_free_coherent(&pdev->dev, ring_sz, head, dma); ++ wd_ring->head = NULL; ++} ++ ++static void rtw89_pci_free_tx_ring(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev, ++ struct rtw89_pci_tx_ring *tx_ring) ++{ ++ int ring_sz; ++ u8 *head; ++ dma_addr_t dma; ++ ++ head = tx_ring->bd_ring.head; ++ dma = tx_ring->bd_ring.dma; ++ ring_sz = tx_ring->bd_ring.desc_size * tx_ring->bd_ring.len; ++ dma_free_coherent(&pdev->dev, ring_sz, head, dma); ++ ++ tx_ring->bd_ring.head = NULL; ++} ++ ++static void rtw89_pci_free_tx_rings(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring; ++ int i; ++ ++ for (i = 0; i < RTW89_TXCH_NUM; i++) { ++ tx_ring = &rtwpci->tx_rings[i]; ++ rtw89_pci_free_tx_wd_ring(rtwdev, pdev, tx_ring); ++ rtw89_pci_free_tx_ring(rtwdev, pdev, tx_ring); ++ } ++} ++ ++static void rtw89_pci_free_rx_ring(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev, ++ struct rtw89_pci_rx_ring *rx_ring) ++{ ++ struct rtw89_pci_rx_info *rx_info; ++ struct sk_buff *skb; ++ dma_addr_t dma; ++ u32 buf_sz; ++ u8 *head; ++ int ring_sz = rx_ring->bd_ring.desc_size * rx_ring->bd_ring.len; ++ int i; ++ ++ buf_sz = rx_ring->buf_sz; ++ for (i = 0; i < rx_ring->bd_ring.len; i++) { ++ skb = rx_ring->buf[i]; ++ if (!skb) ++ continue; ++ ++ rx_info = RTW89_PCI_RX_SKB_CB(skb); ++ dma = rx_info->dma; ++ dma_unmap_single(&pdev->dev, dma, buf_sz, DMA_FROM_DEVICE); ++ dev_kfree_skb(skb); ++ rx_ring->buf[i] = NULL; ++ } ++ ++ head = rx_ring->bd_ring.head; ++ dma = rx_ring->bd_ring.dma; ++ dma_free_coherent(&pdev->dev, ring_sz, head, dma); ++ ++ rx_ring->bd_ring.head = NULL; ++} ++ ++static void rtw89_pci_free_rx_rings(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_rx_ring *rx_ring; ++ int i; ++ ++ for (i = 0; i < RTW89_RXCH_NUM; i++) { ++ rx_ring = &rtwpci->rx_rings[i]; ++ rtw89_pci_free_rx_ring(rtwdev, pdev, rx_ring); ++ } ++} ++ ++static void rtw89_pci_free_trx_rings(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ rtw89_pci_free_rx_rings(rtwdev, pdev); ++ rtw89_pci_free_tx_rings(rtwdev, pdev); ++} ++ ++static int rtw89_pci_init_rx_bd(struct rtw89_dev *rtwdev, struct pci_dev *pdev, ++ struct rtw89_pci_rx_ring *rx_ring, ++ struct sk_buff *skb, int buf_sz, u32 idx) ++{ ++ struct rtw89_pci_rx_info *rx_info; ++ struct rtw89_pci_rx_bd_32 *rx_bd; ++ dma_addr_t dma; ++ ++ if (!skb) ++ return -EINVAL; ++ ++ dma = dma_map_single(&pdev->dev, skb->data, buf_sz, DMA_FROM_DEVICE); ++ if (dma_mapping_error(&pdev->dev, dma)) ++ return -EBUSY; ++ ++ rx_info = RTW89_PCI_RX_SKB_CB(skb); ++ rx_bd = RTW89_PCI_RX_BD(rx_ring, idx); ++ ++ memset(rx_bd, 0, sizeof(*rx_bd)); ++ rx_bd->buf_size = cpu_to_le16(buf_sz); ++ rx_bd->dma = cpu_to_le32(dma); ++ rx_info->dma = dma; ++ ++ return 0; ++} ++ ++static int rtw89_pci_alloc_tx_wd_ring(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev, ++ struct rtw89_pci_tx_ring *tx_ring, ++ enum rtw89_tx_channel txch) ++{ ++ struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; ++ struct rtw89_pci_tx_wd *txwd; ++ dma_addr_t dma; ++ dma_addr_t cur_paddr; ++ u8 *head; ++ u8 *cur_vaddr; ++ u32 page_size = RTW89_PCI_TXWD_PAGE_SIZE; ++ u32 page_num = RTW89_PCI_TXWD_NUM_MAX; ++ u32 ring_sz = page_size * page_num; ++ u32 page_offset; ++ int i; ++ ++ /* FWCMD queue doesn't use txwd as pages */ ++ if (txch == RTW89_TXCH_CH12) ++ return 0; ++ ++ head = dma_alloc_coherent(&pdev->dev, ring_sz, &dma, GFP_KERNEL); ++ if (!head) ++ return -ENOMEM; ++ ++ INIT_LIST_HEAD(&wd_ring->free_pages); ++ wd_ring->head = head; ++ wd_ring->dma = dma; ++ wd_ring->page_size = page_size; ++ wd_ring->page_num = page_num; ++ ++ page_offset = 0; ++ for (i = 0; i < page_num; i++) { ++ txwd = &wd_ring->pages[i]; ++ cur_paddr = dma + page_offset; ++ cur_vaddr = head + page_offset; ++ ++ skb_queue_head_init(&txwd->queue); ++ INIT_LIST_HEAD(&txwd->list); ++ txwd->paddr = cur_paddr; ++ txwd->vaddr = cur_vaddr; ++ txwd->len = page_size; ++ txwd->seq = i; ++ rtw89_pci_enqueue_txwd(tx_ring, txwd); ++ ++ page_offset += page_size; ++ } ++ ++ return 0; ++} ++ ++static int rtw89_pci_alloc_tx_ring(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev, ++ struct rtw89_pci_tx_ring *tx_ring, ++ u32 desc_size, u32 len, ++ enum rtw89_tx_channel txch) ++{ ++ int ring_sz = desc_size * len; ++ u8 *head; ++ dma_addr_t dma; ++ u32 addr_num; ++ u32 addr_idx; ++ u32 addr_bdram; ++ u32 addr_desa_l; ++ u32 addr_desa_h; ++ int ret; ++ ++ ret = rtw89_pci_alloc_tx_wd_ring(rtwdev, pdev, tx_ring, txch); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to alloc txwd ring of txch %d\n", txch); ++ goto err; ++ } ++ ++ ret = rtw89_pci_get_txch_addrs(txch, &addr_num, &addr_idx, &addr_bdram, ++ &addr_desa_l, &addr_desa_h); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to get address of txch %d", txch); ++ goto err_free_wd_ring; ++ } ++ ++ head = dma_alloc_coherent(&pdev->dev, ring_sz, &dma, GFP_KERNEL); ++ if (!head) { ++ ret = -ENOMEM; ++ goto err_free_wd_ring; ++ } ++ ++ INIT_LIST_HEAD(&tx_ring->busy_pages); ++ tx_ring->bd_ring.head = head; ++ tx_ring->bd_ring.dma = dma; ++ tx_ring->bd_ring.len = len; ++ tx_ring->bd_ring.desc_size = desc_size; ++ tx_ring->bd_ring.addr_num = addr_num; ++ tx_ring->bd_ring.addr_idx = addr_idx; ++ tx_ring->bd_ring.addr_bdram = addr_bdram; ++ tx_ring->bd_ring.addr_desa_l = addr_desa_l; ++ tx_ring->bd_ring.addr_desa_h = addr_desa_h; ++ tx_ring->bd_ring.wp = 0; ++ tx_ring->bd_ring.rp = 0; ++ tx_ring->txch = txch; ++ ++ return 0; ++ ++err_free_wd_ring: ++ rtw89_pci_free_tx_wd_ring(rtwdev, pdev, tx_ring); ++err: ++ return ret; ++} ++ ++static int rtw89_pci_alloc_tx_rings(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring; ++ u32 desc_size; ++ u32 len; ++ u32 i, tx_allocated; ++ int ret; ++ ++ for (i = 0; i < RTW89_TXCH_NUM; i++) { ++ tx_ring = &rtwpci->tx_rings[i]; ++ desc_size = sizeof(struct rtw89_pci_tx_bd_32); ++ len = RTW89_PCI_TXBD_NUM_MAX; ++ ret = rtw89_pci_alloc_tx_ring(rtwdev, pdev, tx_ring, ++ desc_size, len, i); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to alloc tx ring %d\n", i); ++ goto err_free; ++ } ++ } ++ ++ return 0; ++ ++err_free: ++ tx_allocated = i; ++ for (i = 0; i < tx_allocated; i++) { ++ tx_ring = &rtwpci->tx_rings[i]; ++ rtw89_pci_free_tx_ring(rtwdev, pdev, tx_ring); ++ } ++ ++ return ret; ++} ++ ++static int rtw89_pci_alloc_rx_ring(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev, ++ struct rtw89_pci_rx_ring *rx_ring, ++ u32 desc_size, u32 len, u32 rxch) ++{ ++ struct sk_buff *skb; ++ u8 *head; ++ dma_addr_t dma; ++ u32 addr_num; ++ u32 addr_idx; ++ u32 addr_desa_l; ++ u32 addr_desa_h; ++ int ring_sz = desc_size * len; ++ int buf_sz = RTW89_PCI_RX_BUF_SIZE; ++ int i, allocated; ++ int ret; ++ ++ ret = rtw89_pci_get_rxch_addrs(rxch, &addr_num, &addr_idx, ++ &addr_desa_l, &addr_desa_h); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to get address of rxch %d", rxch); ++ return ret; ++ } ++ ++ head = dma_alloc_coherent(&pdev->dev, ring_sz, &dma, GFP_KERNEL); ++ if (!head) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ rx_ring->bd_ring.head = head; ++ rx_ring->bd_ring.dma = dma; ++ rx_ring->bd_ring.len = len; ++ rx_ring->bd_ring.desc_size = desc_size; ++ rx_ring->bd_ring.addr_num = addr_num; ++ rx_ring->bd_ring.addr_idx = addr_idx; ++ rx_ring->bd_ring.addr_desa_l = addr_desa_l; ++ rx_ring->bd_ring.addr_desa_h = addr_desa_h; ++ rx_ring->bd_ring.wp = 0; ++ rx_ring->bd_ring.rp = 0; ++ rx_ring->buf_sz = buf_sz; ++ rx_ring->diliver_skb = NULL; ++ rx_ring->diliver_desc.ready = false; ++ ++ for (i = 0; i < len; i++) { ++ skb = dev_alloc_skb(buf_sz); ++ if (!skb) { ++ ret = -ENOMEM; ++ goto err_free; ++ } ++ ++ memset(skb->data, 0, buf_sz); ++ rx_ring->buf[i] = skb; ++ ret = rtw89_pci_init_rx_bd(rtwdev, pdev, rx_ring, skb, ++ buf_sz, i); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to init rx buf %d\n", i); ++ dev_kfree_skb_any(skb); ++ rx_ring->buf[i] = NULL; ++ goto err_free; ++ } ++ } ++ ++ return 0; ++ ++err_free: ++ allocated = i; ++ for (i = 0; i < allocated; i++) { ++ skb = rx_ring->buf[i]; ++ if (!skb) ++ continue; ++ dma = *((dma_addr_t *)skb->cb); ++ dma_unmap_single(&pdev->dev, dma, buf_sz, DMA_FROM_DEVICE); ++ dev_kfree_skb(skb); ++ rx_ring->buf[i] = NULL; ++ } ++ ++ head = rx_ring->bd_ring.head; ++ dma = rx_ring->bd_ring.dma; ++ dma_free_coherent(&pdev->dev, ring_sz, head, dma); ++ ++ rx_ring->bd_ring.head = NULL; ++err: ++ return ret; ++} ++ ++static int rtw89_pci_alloc_rx_rings(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_rx_ring *rx_ring; ++ u32 desc_size; ++ u32 len; ++ int i, rx_allocated; ++ int ret; ++ ++ for (i = 0; i < RTW89_RXCH_NUM; i++) { ++ rx_ring = &rtwpci->rx_rings[i]; ++ desc_size = sizeof(struct rtw89_pci_rx_bd_32); ++ len = RTW89_PCI_RXBD_NUM_MAX; ++ ret = rtw89_pci_alloc_rx_ring(rtwdev, pdev, rx_ring, ++ desc_size, len, i); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to alloc rx ring %d\n", i); ++ goto err_free; ++ } ++ } ++ ++ return 0; ++ ++err_free: ++ rx_allocated = i; ++ for (i = 0; i < rx_allocated; i++) { ++ rx_ring = &rtwpci->rx_rings[i]; ++ rtw89_pci_free_rx_ring(rtwdev, pdev, rx_ring); ++ } ++ ++ return ret; ++} ++ ++static int rtw89_pci_alloc_trx_rings(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ int ret; ++ ++ ret = rtw89_pci_alloc_tx_rings(rtwdev, pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to alloc dma tx rings\n"); ++ goto err; ++ } ++ ++ ret = rtw89_pci_alloc_rx_rings(rtwdev, pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to alloc dma rx rings\n"); ++ goto err_free_tx_rings; ++ } ++ ++ return 0; ++ ++err_free_tx_rings: ++ rtw89_pci_free_tx_rings(rtwdev, pdev); ++err: ++ return ret; ++} ++ ++static void rtw89_pci_h2c_init(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci) ++{ ++ skb_queue_head_init(&rtwpci->h2c_queue); ++ skb_queue_head_init(&rtwpci->h2c_release_queue); ++} ++ ++static int rtw89_pci_setup_resource(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ int ret; ++ ++ ret = rtw89_pci_setup_mapping(rtwdev, pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to setup pci mapping\n"); ++ goto err; ++ } ++ ++ ret = rtw89_pci_alloc_trx_rings(rtwdev, pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to alloc pci trx rings\n"); ++ goto err_pci_unmap; ++ } ++ ++ rtw89_pci_h2c_init(rtwdev, rtwpci); ++ ++ spin_lock_init(&rtwpci->irq_lock); ++ spin_lock_init(&rtwpci->trx_lock); ++ ++ return 0; ++ ++err_pci_unmap: ++ rtw89_pci_clear_mapping(rtwdev, pdev); ++err: ++ return ret; ++} ++ ++static void rtw89_pci_clear_resource(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ ++ rtw89_pci_free_trx_rings(rtwdev, pdev); ++ rtw89_pci_clear_mapping(rtwdev, pdev); ++ rtw89_pci_release_fwcmd(rtwdev, rtwpci, ++ skb_queue_len(&rtwpci->h2c_queue), true); ++} ++ ++static void rtw89_pci_default_intr_mask(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ ++ rtwpci->halt_c2h_intrs = B_AX_HALT_C2H_INT_EN | 0; ++ rtwpci->intrs[0] = B_AX_TXDMA_STUCK_INT_EN | ++ B_AX_RXDMA_INT_EN | ++ B_AX_RXP1DMA_INT_EN | ++ B_AX_RPQDMA_INT_EN | ++ B_AX_RXDMA_STUCK_INT_EN | ++ B_AX_RDU_INT_EN | ++ B_AX_RPQBD_FULL_INT_EN | ++ B_AX_HS0ISR_IND_INT_EN; ++ ++ rtwpci->intrs[1] = B_AX_HC10ISR_IND_INT_EN; ++} ++ ++static int rtw89_pci_request_irq(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ unsigned long flags = 0; ++ int ret; ++ ++ flags |= PCI_IRQ_LEGACY | PCI_IRQ_MSI; ++ ret = pci_alloc_irq_vectors(pdev, 1, 1, flags); ++ if (ret < 0) { ++ rtw89_err(rtwdev, "failed to alloc irq vectors, ret %d\n", ret); ++ goto err; ++ } ++ ++ ret = devm_request_threaded_irq(rtwdev->dev, pdev->irq, ++ rtw89_pci_interrupt_handler, ++ rtw89_pci_interrupt_threadfn, ++ IRQF_SHARED, KBUILD_MODNAME, rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to request threaded irq\n"); ++ goto err_free_vector; ++ } ++ ++ rtw89_pci_default_intr_mask(rtwdev); ++ ++ return 0; ++ ++err_free_vector: ++ pci_free_irq_vectors(pdev); ++err: ++ return ret; ++} ++ ++static void rtw89_pci_free_irq(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ devm_free_irq(rtwdev->dev, pdev->irq, rtwdev); ++ pci_free_irq_vectors(pdev); ++} ++ ++static void rtw89_pci_clkreq_set(struct rtw89_dev *rtwdev, bool enable) ++{ ++ int ret; ++ ++ if (rtw89_pci_disable_clkreq) ++ return; ++ ++ ret = rtw89_dbi_write8(rtwdev, RTW89_PCIE_CLK_CTRL, ++ PCIE_CLKDLY_HW_30US); ++ if (ret) ++ rtw89_err(rtwdev, "failed to set CLKREQ Delay\n"); ++ ++ if (enable) ++ ret = rtw89_dbi_write8_set(rtwdev, RTW89_PCIE_L1_CTRL, ++ RTW89_PCIE_BIT_CLK); ++ else ++ ret = rtw89_dbi_write8_clr(rtwdev, RTW89_PCIE_L1_CTRL, ++ RTW89_PCIE_BIT_CLK); ++ if (ret) ++ rtw89_err(rtwdev, "failed to %s CLKREQ_L1, ret=%d", ++ enable ? "set" : "unset", ret); ++} ++ ++static void rtw89_pci_aspm_set(struct rtw89_dev *rtwdev, bool enable) ++{ ++ u8 value = 0; ++ int ret; ++ ++ if (rtw89_pci_disable_aspm_l1) ++ return; ++ ++ ret = rtw89_dbi_read8(rtwdev, RTW89_PCIE_ASPM_CTRL, &value); ++ if (ret) ++ rtw89_err(rtwdev, "failed to read ASPM Delay\n"); ++ ++ value &= ~(RTW89_L1DLY_MASK | RTW89_L0DLY_MASK); ++ value |= FIELD_PREP(RTW89_L1DLY_MASK, PCIE_L1DLY_16US) | ++ FIELD_PREP(RTW89_L0DLY_MASK, PCIE_L0SDLY_4US); ++ ++ ret = rtw89_dbi_write8(rtwdev, RTW89_PCIE_ASPM_CTRL, value); ++ if (ret) ++ rtw89_err(rtwdev, "failed to read ASPM Delay\n"); ++ ++ if (enable) ++ ret = rtw89_dbi_write8_set(rtwdev, RTW89_PCIE_L1_CTRL, ++ RTW89_PCIE_BIT_L1); ++ else ++ ret = rtw89_dbi_write8_clr(rtwdev, RTW89_PCIE_L1_CTRL, ++ RTW89_PCIE_BIT_L1); ++ if (ret) ++ rtw89_err(rtwdev, "failed to %s ASPM L1, ret=%d", ++ enable ? "set" : "unset", ret); ++} ++ ++static void rtw89_pci_recalc_int_mit(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_traffic_stats *stats = &rtwdev->stats; ++ enum rtw89_tfc_lv tx_tfc_lv = stats->tx_tfc_lv; ++ enum rtw89_tfc_lv rx_tfc_lv = stats->rx_tfc_lv; ++ u32 val = 0; ++ ++ if (!rtwdev->scanning && ++ (tx_tfc_lv >= RTW89_TFC_HIGH || rx_tfc_lv >= RTW89_TFC_HIGH)) ++ val = B_AX_RXMIT_RXP2_SEL | B_AX_RXMIT_RXP1_SEL | ++ FIELD_PREP(B_AX_RXCOUNTER_MATCH_MASK, RTW89_PCI_RXBD_NUM_MAX / 2) | ++ FIELD_PREP(B_AX_RXTIMER_UNIT_MASK, AX_RXTIMER_UNIT_64US) | ++ FIELD_PREP(B_AX_RXTIMER_MATCH_MASK, 2048 / 64); ++ ++ rtw89_write32(rtwdev, R_AX_INT_MIT_RX, val); ++} ++ ++static void rtw89_pci_link_cfg(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct pci_dev *pdev = rtwpci->pdev; ++ u16 link_ctrl; ++ int ret; ++ ++ /* Though there is standard PCIE configuration space to set the ++ * link control register, but by Realtek's design, driver should ++ * check if host supports CLKREQ/ASPM to enable the HW module. ++ * ++ * These functions are implemented by two HW modules associated, ++ * one is responsible to access PCIE configuration space to ++ * follow the host settings, and another is in charge of doing ++ * CLKREQ/ASPM mechanisms, it is default disabled. Because sometimes ++ * the host does not support it, and due to some reasons or wrong ++ * settings (ex. CLKREQ# not Bi-Direction), it could lead to device ++ * loss if HW misbehaves on the link. ++ * ++ * Hence it's designed that driver should first check the PCIE ++ * configuration space is sync'ed and enabled, then driver can turn ++ * on the other module that is actually working on the mechanism. ++ */ ++ ret = pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &link_ctrl); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to read PCI cap, ret=%d\n", ret); ++ return; ++ } ++ ++ if (link_ctrl & PCI_EXP_LNKCTL_CLKREQ_EN) ++ rtw89_pci_clkreq_set(rtwdev, true); ++ ++ if (link_ctrl & PCI_EXP_LNKCTL_ASPM_L1) ++ rtw89_pci_aspm_set(rtwdev, true); ++} ++ ++static void rtw89_pci_l1ss_set(struct rtw89_dev *rtwdev, bool enable) ++{ ++ int ret; ++ ++ if (enable) ++ ret = rtw89_dbi_write8_set(rtwdev, RTW89_PCIE_TIMER_CTRL, ++ RTW89_PCIE_BIT_L1SUB); ++ else ++ ret = rtw89_dbi_write8_clr(rtwdev, RTW89_PCIE_TIMER_CTRL, ++ RTW89_PCIE_BIT_L1SUB); ++ if (ret) ++ rtw89_err(rtwdev, "failed to %s L1SS, ret=%d", ++ enable ? "set" : "unset", ret); ++} ++ ++static void rtw89_pci_l1ss_cfg(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct pci_dev *pdev = rtwpci->pdev; ++ u32 l1ss_cap_ptr, l1ss_ctrl; ++ ++ if (rtw89_pci_disable_l1ss) ++ return; ++ ++ l1ss_cap_ptr = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); ++ if (!l1ss_cap_ptr) ++ return; ++ ++ pci_read_config_dword(pdev, l1ss_cap_ptr + PCI_L1SS_CTL1, &l1ss_ctrl); ++ ++ if (l1ss_ctrl & PCI_L1SS_CTL1_L1SS_MASK) ++ rtw89_pci_l1ss_set(rtwdev, true); ++} ++ ++static void rtw89_pci_ctrl_dma_all_pcie(struct rtw89_dev *rtwdev, u8 en) ++{ ++ u32 val32; ++ ++ if (en == MAC_AX_FUNC_EN) { ++ val32 = B_AX_STOP_PCIEIO; ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP1, val32); ++ ++ val32 = B_AX_TXHCI_EN | B_AX_RXHCI_EN; ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, val32); ++ } else { ++ val32 = B_AX_STOP_PCIEIO; ++ rtw89_write32_set(rtwdev, R_AX_PCIE_DMA_STOP1, val32); ++ ++ val32 = B_AX_TXHCI_EN | B_AX_RXHCI_EN; ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, val32); ++ } ++} ++ ++static int rtw89_pci_poll_io_idle(struct rtw89_dev *rtwdev) ++{ ++ int ret = 0; ++ u32 sts; ++ u32 busy = B_AX_PCIEIO_BUSY | B_AX_PCIEIO_TX_BUSY | B_AX_PCIEIO_RX_BUSY; ++ ++ ret = read_poll_timeout_atomic(rtw89_read32, sts, (sts & busy) == 0x0, ++ 10, 1000, false, rtwdev, ++ R_AX_PCIE_DMA_BUSY1); ++ if (ret) { ++ rtw89_err(rtwdev, "pci dmach busy1 0x%X\n", ++ rtw89_read32(rtwdev, R_AX_PCIE_DMA_BUSY1)); ++ return -EINVAL; ++ } ++ return ret; ++} ++ ++static int rtw89_pci_lv1rst_stop_dma(struct rtw89_dev *rtwdev) ++{ ++ u32 val, dma_rst = 0; ++ int ret; ++ ++ rtw89_pci_ctrl_dma_all_pcie(rtwdev, MAC_AX_FUNC_DIS); ++ ret = rtw89_pci_poll_io_idle(rtwdev); ++ if (ret) { ++ val = rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG); ++ rtw89_debug(rtwdev, RTW89_DBG_HCI, ++ "[PCIe] poll_io_idle fail, before 0x%08x: 0x%08x\n", ++ R_AX_DBG_ERR_FLAG, val); ++ if (val & B_AX_TX_STUCK || val & B_AX_PCIE_TXBD_LEN0) ++ dma_rst |= B_AX_HCI_TXDMA_EN; ++ if (val & B_AX_RX_STUCK) ++ dma_rst |= B_AX_HCI_RXDMA_EN; ++ val = rtw89_read32(rtwdev, R_AX_HCI_FUNC_EN); ++ rtw89_write32(rtwdev, R_AX_HCI_FUNC_EN, val & ~dma_rst); ++ rtw89_write32(rtwdev, R_AX_HCI_FUNC_EN, val | dma_rst); ++ ret = rtw89_pci_poll_io_idle(rtwdev); ++ val = rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG); ++ rtw89_debug(rtwdev, RTW89_DBG_HCI, ++ "[PCIe] poll_io_idle fail, after 0x%08x: 0x%08x\n", ++ R_AX_DBG_ERR_FLAG, val); ++ } ++ ++ return ret; ++} ++ ++static void rtw89_pci_ctrl_hci_dma_en(struct rtw89_dev *rtwdev, u8 en) ++{ ++ u32 val32; ++ ++ if (en == MAC_AX_FUNC_EN) { ++ val32 = B_AX_HCI_TXDMA_EN | B_AX_HCI_RXDMA_EN; ++ rtw89_write32_set(rtwdev, R_AX_HCI_FUNC_EN, val32); ++ } else { ++ val32 = B_AX_HCI_TXDMA_EN | B_AX_HCI_RXDMA_EN; ++ rtw89_write32_clr(rtwdev, R_AX_HCI_FUNC_EN, val32); ++ } ++} ++ ++static int rtw89_pci_rst_bdram(struct rtw89_dev *rtwdev) ++{ ++ int ret = 0; ++ u32 val32, sts; ++ ++ val32 = B_AX_RST_BDRAM; ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, val32); ++ ++ ret = read_poll_timeout_atomic(rtw89_read32, sts, ++ (sts & B_AX_RST_BDRAM) == 0x0, 1, 100, ++ true, rtwdev, R_AX_PCIE_INIT_CFG1); ++ return ret; ++} ++ ++static int rtw89_pci_lv1rst_start_dma(struct rtw89_dev *rtwdev) ++{ ++ u32 ret; ++ ++ rtw89_pci_ctrl_hci_dma_en(rtwdev, MAC_AX_FUNC_DIS); ++ rtw89_pci_ctrl_hci_dma_en(rtwdev, MAC_AX_FUNC_EN); ++ rtw89_pci_clr_idx_all(rtwdev); ++ ++ ret = rtw89_pci_rst_bdram(rtwdev); ++ if (ret) ++ return ret; ++ ++ rtw89_pci_ctrl_dma_all_pcie(rtwdev, MAC_AX_FUNC_EN); ++ return ret; ++} ++ ++static int rtw89_pci_ops_mac_lv1_recovery(struct rtw89_dev *rtwdev, ++ enum rtw89_lv1_rcvy_step step) ++{ ++ int ret; ++ ++ switch (step) { ++ case RTW89_LV1_RCVY_STEP_1: ++ ret = rtw89_pci_lv1rst_stop_dma(rtwdev); ++ if (ret) ++ rtw89_err(rtwdev, "lv1 rcvy pci stop dma fail\n"); ++ ++ break; ++ ++ case RTW89_LV1_RCVY_STEP_2: ++ ret = rtw89_pci_lv1rst_start_dma(rtwdev); ++ if (ret) ++ rtw89_err(rtwdev, "lv1 rcvy pci start dma fail\n"); ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ return ret; ++} ++ ++static void rtw89_pci_ops_dump_err_status(struct rtw89_dev *rtwdev) ++{ ++ rtw89_info(rtwdev, "R_AX_RPQ_RXBD_IDX =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX)); ++ rtw89_info(rtwdev, "R_AX_DBG_ERR_FLAG=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG)); ++ rtw89_info(rtwdev, "R_AX_LBC_WATCHDOG=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_LBC_WATCHDOG)); ++} ++ ++static int rtw89_pci_napi_poll(struct napi_struct *napi, int budget) ++{ ++ struct rtw89_dev *rtwdev = container_of(napi, struct rtw89_dev, napi); ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ unsigned long flags; ++ int work_done; ++ ++ rtwdev->napi_budget_countdown = budget; ++ ++ rtw89_pci_clear_isr0(rtwdev, B_AX_RPQDMA_INT | B_AX_RPQBD_FULL_INT); ++ work_done = rtw89_pci_poll_rpq_dma(rtwdev, rtwpci, rtwdev->napi_budget_countdown); ++ if (work_done == budget) ++ return budget; ++ ++ rtw89_pci_clear_isr0(rtwdev, B_AX_RXP1DMA_INT | B_AX_RXDMA_INT | B_AX_RDU_INT); ++ work_done += rtw89_pci_poll_rxq_dma(rtwdev, rtwpci, rtwdev->napi_budget_countdown); ++ if (work_done < budget && napi_complete_done(napi, work_done)) { ++ spin_lock_irqsave(&rtwpci->irq_lock, flags); ++ if (likely(rtwpci->running)) ++ rtw89_pci_enable_intr(rtwdev, rtwpci); ++ spin_unlock_irqrestore(&rtwpci->irq_lock, flags); ++ } ++ ++ return work_done; ++} ++ ++static int __maybe_unused rtw89_pci_suspend(struct device *dev) ++{ ++ struct ieee80211_hw *hw = dev_get_drvdata(dev); ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, ++ B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); ++ rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); ++ rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST); ++ rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, ++ B_AX_PCIE_PERST_KEEP_REG | B_AX_PCIE_TRAIN_KEEP_REG); ++ ++ return 0; ++} ++ ++static void rtw89_pci_l2_hci_ldo(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->chip->chip_id == RTL8852C) ++ return; ++ ++ /* Hardware need write the reg twice to ensure the setting work */ ++ rtw89_dbi_write8_set(rtwdev, RTW89_PCIE_RST_MSTATE, ++ RTW89_PCIE_BIT_CFG_RST_MSTATE); ++ rtw89_dbi_write8_set(rtwdev, RTW89_PCIE_RST_MSTATE, ++ RTW89_PCIE_BIT_CFG_RST_MSTATE); ++} ++ ++static int __maybe_unused rtw89_pci_resume(struct device *dev) ++{ ++ struct ieee80211_hw *hw = dev_get_drvdata(dev); ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL, ++ B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); ++ rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); ++ rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST); ++ rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, ++ B_AX_PCIE_PERST_KEEP_REG | B_AX_PCIE_TRAIN_KEEP_REG); ++ rtw89_pci_l2_hci_ldo(rtwdev); ++ rtw89_pci_link_cfg(rtwdev); ++ rtw89_pci_l1ss_cfg(rtwdev); ++ ++ return 0; ++} ++ ++SIMPLE_DEV_PM_OPS(rtw89_pm_ops, rtw89_pci_suspend, rtw89_pci_resume); ++EXPORT_SYMBOL(rtw89_pm_ops); ++ ++static const struct rtw89_hci_ops rtw89_pci_ops = { ++ .tx_write = rtw89_pci_ops_tx_write, ++ .tx_kick_off = rtw89_pci_ops_tx_kick_off, ++ .flush_queues = rtw89_pci_ops_flush_queues, ++ .reset = rtw89_pci_ops_reset, ++ .start = rtw89_pci_ops_start, ++ .stop = rtw89_pci_ops_stop, ++ .recalc_int_mit = rtw89_pci_recalc_int_mit, ++ ++ .read8 = rtw89_pci_ops_read8, ++ .read16 = rtw89_pci_ops_read16, ++ .read32 = rtw89_pci_ops_read32, ++ .write8 = rtw89_pci_ops_write8, ++ .write16 = rtw89_pci_ops_write16, ++ .write32 = rtw89_pci_ops_write32, ++ ++ .mac_pre_init = rtw89_pci_ops_mac_pre_init, ++ .mac_post_init = rtw89_pci_ops_mac_post_init, ++ .deinit = rtw89_pci_ops_deinit, ++ ++ .check_and_reclaim_tx_resource = rtw89_pci_check_and_reclaim_tx_resource, ++ .mac_lv1_rcvy = rtw89_pci_ops_mac_lv1_recovery, ++ .dump_err_status = rtw89_pci_ops_dump_err_status, ++ .napi_poll = rtw89_pci_napi_poll, ++}; ++ ++static int rtw89_pci_probe(struct pci_dev *pdev, ++ const struct pci_device_id *id) ++{ ++ struct ieee80211_hw *hw; ++ struct rtw89_dev *rtwdev; ++ int driver_data_size; ++ int ret; ++ ++ driver_data_size = sizeof(struct rtw89_dev) + sizeof(struct rtw89_pci); ++ hw = ieee80211_alloc_hw(driver_data_size, &rtw89_ops); ++ if (!hw) { ++ dev_err(&pdev->dev, "failed to allocate hw\n"); ++ return -ENOMEM; ++ } ++ ++ rtwdev = hw->priv; ++ rtwdev->hw = hw; ++ rtwdev->dev = &pdev->dev; ++ rtwdev->hci.ops = &rtw89_pci_ops; ++ rtwdev->hci.type = RTW89_HCI_TYPE_PCIE; ++ rtwdev->hci.rpwm_addr = R_AX_PCIE_HRPWM; ++ rtwdev->hci.cpwm_addr = R_AX_CPWM; ++ ++ SET_IEEE80211_DEV(rtwdev->hw, &pdev->dev); ++ ++ switch (id->driver_data) { ++ case RTL8852A: ++ rtwdev->chip = &rtw8852a_chip_info; ++ break; ++ default: ++ return -ENOENT; ++ } ++ ++ ret = rtw89_core_init(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to initialise core\n"); ++ goto err_release_hw; ++ } ++ ++ ret = rtw89_pci_claim_device(rtwdev, pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to claim pci device\n"); ++ goto err_core_deinit; ++ } ++ ++ ret = rtw89_pci_setup_resource(rtwdev, pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to setup pci resource\n"); ++ goto err_declaim_pci; ++ } ++ ++ ret = rtw89_chip_info_setup(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to setup chip information\n"); ++ goto err_clear_resource; ++ } ++ ++ rtw89_pci_link_cfg(rtwdev); ++ rtw89_pci_l1ss_cfg(rtwdev); ++ ++ ret = rtw89_core_register(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to register core\n"); ++ goto err_clear_resource; ++ } ++ ++ rtw89_core_napi_init(rtwdev); ++ ++ ret = rtw89_pci_request_irq(rtwdev, pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to request pci irq\n"); ++ goto err_unregister; ++ } ++ ++ return 0; ++ ++err_unregister: ++ rtw89_core_napi_deinit(rtwdev); ++ rtw89_core_unregister(rtwdev); ++err_clear_resource: ++ rtw89_pci_clear_resource(rtwdev, pdev); ++err_declaim_pci: ++ rtw89_pci_declaim_device(rtwdev, pdev); ++err_core_deinit: ++ rtw89_core_deinit(rtwdev); ++err_release_hw: ++ ieee80211_free_hw(hw); ++ ++ return ret; ++} ++ ++static void rtw89_pci_remove(struct pci_dev *pdev) ++{ ++ struct ieee80211_hw *hw = pci_get_drvdata(pdev); ++ struct rtw89_dev *rtwdev; ++ ++ rtwdev = hw->priv; ++ ++ rtw89_pci_free_irq(rtwdev, pdev); ++ rtw89_core_napi_deinit(rtwdev); ++ rtw89_core_unregister(rtwdev); ++ rtw89_pci_clear_resource(rtwdev, pdev); ++ rtw89_pci_declaim_device(rtwdev, pdev); ++ rtw89_core_deinit(rtwdev); ++ ieee80211_free_hw(hw); ++} ++ ++static const struct pci_device_id rtw89_pci_id_table[] = { ++ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8852), .driver_data = RTL8852A }, ++ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xa85a), .driver_data = RTL8852A }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(pci, rtw89_pci_id_table); ++ ++static struct pci_driver rtw89_pci_driver = { ++ .name = "rtw89_pci", ++ .id_table = rtw89_pci_id_table, ++ .probe = rtw89_pci_probe, ++ .remove = rtw89_pci_remove, ++ .driver.pm = &rtw89_pm_ops, ++}; ++module_pci_driver(rtw89_pci_driver); ++ ++MODULE_AUTHOR("Realtek Corporation"); ++MODULE_DESCRIPTION("Realtek 802.11ax wireless PCI driver"); ++MODULE_LICENSE("Dual BSD/GPL"); +diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h +new file mode 100644 +index 000000000000..34333c441aea +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/pci.h +@@ -0,0 +1,635 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_PCI_H__ ++#define __RTW89_PCI_H__ ++ ++#include "txrx.h" ++ ++#define MDIO_PG0_G1 0 ++#define MDIO_PG1_G1 1 ++#define MDIO_PG0_G2 2 ++#define MDIO_PG1_G2 3 ++#define RAC_ANA10 0x10 ++#define RAC_ANA19 0x19 ++#define RAC_ANA1F 0x1F ++#define RAC_ANA24 0x24 ++#define B_AX_DEGLITCH GENMASK(11, 8) ++#define RAC_ANA26 0x26 ++#define B_AX_RXEN GENMASK(15, 14) ++#define RAC_CTRL_PPR_V1 0x30 ++#define B_AX_CLK_CALIB_EN BIT(12) ++#define B_AX_CALIB_EN BIT(13) ++#define B_AX_DIV GENMASK(15, 14) ++#define RAC_SET_PPR_V1 0x31 ++ ++#define R_AX_DBI_FLAG 0x1090 ++#define B_AX_DBI_RFLAG BIT(17) ++#define B_AX_DBI_WFLAG BIT(16) ++#define B_AX_DBI_WREN_MSK GENMASK(15, 12) ++#define B_AX_DBI_ADDR_MSK GENMASK(11, 2) ++#define R_AX_DBI_WDATA 0x1094 ++#define R_AX_DBI_RDATA 0x1098 ++ ++#define R_AX_MDIO_WDATA 0x10A4 ++#define R_AX_MDIO_RDATA 0x10A6 ++ ++#define RTW89_PCI_WR_RETRY_CNT 20 ++ ++/* Interrupts */ ++#define R_AX_HIMR0 0x01A0 ++#define B_AX_HALT_C2H_INT_EN BIT(21) ++#define R_AX_HISR0 0x01A4 ++ ++#define R_AX_MDIO_CFG 0x10A0 ++#define B_AX_MDIO_PHY_ADDR_MASK GENMASK(13, 12) ++#define B_AX_MDIO_RFLAG BIT(9) ++#define B_AX_MDIO_WFLAG BIT(8) ++#define B_AX_MDIO_ADDR_MASK GENMASK(4, 0) ++ ++#define R_AX_PCIE_HIMR00 0x10B0 ++#define B_AX_HC00ISR_IND_INT_EN BIT(27) ++#define B_AX_HD1ISR_IND_INT_EN BIT(26) ++#define B_AX_HD0ISR_IND_INT_EN BIT(25) ++#define B_AX_HS0ISR_IND_INT_EN BIT(24) ++#define B_AX_RETRAIN_INT_EN BIT(21) ++#define B_AX_RPQBD_FULL_INT_EN BIT(20) ++#define B_AX_RDU_INT_EN BIT(19) ++#define B_AX_RXDMA_STUCK_INT_EN BIT(18) ++#define B_AX_TXDMA_STUCK_INT_EN BIT(17) ++#define B_AX_PCIE_HOTRST_INT_EN BIT(16) ++#define B_AX_PCIE_FLR_INT_EN BIT(15) ++#define B_AX_PCIE_PERST_INT_EN BIT(14) ++#define B_AX_TXDMA_CH12_INT_EN BIT(13) ++#define B_AX_TXDMA_CH9_INT_EN BIT(12) ++#define B_AX_TXDMA_CH8_INT_EN BIT(11) ++#define B_AX_TXDMA_ACH7_INT_EN BIT(10) ++#define B_AX_TXDMA_ACH6_INT_EN BIT(9) ++#define B_AX_TXDMA_ACH5_INT_EN BIT(8) ++#define B_AX_TXDMA_ACH4_INT_EN BIT(7) ++#define B_AX_TXDMA_ACH3_INT_EN BIT(6) ++#define B_AX_TXDMA_ACH2_INT_EN BIT(5) ++#define B_AX_TXDMA_ACH1_INT_EN BIT(4) ++#define B_AX_TXDMA_ACH0_INT_EN BIT(3) ++#define B_AX_RPQDMA_INT_EN BIT(2) ++#define B_AX_RXP1DMA_INT_EN BIT(1) ++#define B_AX_RXDMA_INT_EN BIT(0) ++ ++#define R_AX_PCIE_HISR00 0x10B4 ++#define B_AX_HC00ISR_IND_INT BIT(27) ++#define B_AX_HD1ISR_IND_INT BIT(26) ++#define B_AX_HD0ISR_IND_INT BIT(25) ++#define B_AX_HS0ISR_IND_INT BIT(24) ++#define B_AX_RETRAIN_INT BIT(21) ++#define B_AX_RPQBD_FULL_INT BIT(20) ++#define B_AX_RDU_INT BIT(19) ++#define B_AX_RXDMA_STUCK_INT BIT(18) ++#define B_AX_TXDMA_STUCK_INT BIT(17) ++#define B_AX_PCIE_HOTRST_INT BIT(16) ++#define B_AX_PCIE_FLR_INT BIT(15) ++#define B_AX_PCIE_PERST_INT BIT(14) ++#define B_AX_TXDMA_CH12_INT BIT(13) ++#define B_AX_TXDMA_CH9_INT BIT(12) ++#define B_AX_TXDMA_CH8_INT BIT(11) ++#define B_AX_TXDMA_ACH7_INT BIT(10) ++#define B_AX_TXDMA_ACH6_INT BIT(9) ++#define B_AX_TXDMA_ACH5_INT BIT(8) ++#define B_AX_TXDMA_ACH4_INT BIT(7) ++#define B_AX_TXDMA_ACH3_INT BIT(6) ++#define B_AX_TXDMA_ACH2_INT BIT(5) ++#define B_AX_TXDMA_ACH1_INT BIT(4) ++#define B_AX_TXDMA_ACH0_INT BIT(3) ++#define B_AX_RPQDMA_INT BIT(2) ++#define B_AX_RXP1DMA_INT BIT(1) ++#define B_AX_RXDMA_INT BIT(0) ++ ++#define R_AX_PCIE_HIMR10 0x13B0 ++#define B_AX_HC10ISR_IND_INT_EN BIT(28) ++#define B_AX_TXDMA_CH11_INT_EN BIT(12) ++#define B_AX_TXDMA_CH10_INT_EN BIT(11) ++ ++#define R_AX_PCIE_HISR10 0x13B4 ++#define B_AX_HC10ISR_IND_INT BIT(28) ++#define B_AX_TXDMA_CH11_INT BIT(12) ++#define B_AX_TXDMA_CH10_INT BIT(11) ++ ++/* TX/RX */ ++#define R_AX_RXQ_RXBD_IDX 0x1050 ++#define R_AX_RPQ_RXBD_IDX 0x1054 ++#define R_AX_ACH0_TXBD_IDX 0x1058 ++#define R_AX_ACH1_TXBD_IDX 0x105C ++#define R_AX_ACH2_TXBD_IDX 0x1060 ++#define R_AX_ACH3_TXBD_IDX 0x1064 ++#define R_AX_ACH4_TXBD_IDX 0x1068 ++#define R_AX_ACH5_TXBD_IDX 0x106C ++#define R_AX_ACH6_TXBD_IDX 0x1070 ++#define R_AX_ACH7_TXBD_IDX 0x1074 ++#define R_AX_CH8_TXBD_IDX 0x1078 /* Management Queue band 0 */ ++#define R_AX_CH9_TXBD_IDX 0x107C /* HI Queue band 0 */ ++#define R_AX_CH10_TXBD_IDX 0x137C /* Management Queue band 1 */ ++#define R_AX_CH11_TXBD_IDX 0x1380 /* HI Queue band 1 */ ++#define R_AX_CH12_TXBD_IDX 0x1080 /* FWCMD Queue */ ++#define TXBD_HW_IDX_MASK GENMASK(27, 16) ++#define TXBD_HOST_IDX_MASK GENMASK(11, 0) ++ ++#define R_AX_ACH0_TXBD_DESA_L 0x1110 ++#define R_AX_ACH0_TXBD_DESA_H 0x1114 ++#define R_AX_ACH1_TXBD_DESA_L 0x1118 ++#define R_AX_ACH1_TXBD_DESA_H 0x111C ++#define R_AX_ACH2_TXBD_DESA_L 0x1120 ++#define R_AX_ACH2_TXBD_DESA_H 0x1124 ++#define R_AX_ACH3_TXBD_DESA_L 0x1128 ++#define R_AX_ACH3_TXBD_DESA_H 0x112C ++#define R_AX_ACH4_TXBD_DESA_L 0x1130 ++#define R_AX_ACH4_TXBD_DESA_H 0x1134 ++#define R_AX_ACH5_TXBD_DESA_L 0x1138 ++#define R_AX_ACH5_TXBD_DESA_H 0x113C ++#define R_AX_ACH6_TXBD_DESA_L 0x1140 ++#define R_AX_ACH6_TXBD_DESA_H 0x1144 ++#define R_AX_ACH7_TXBD_DESA_L 0x1148 ++#define R_AX_ACH7_TXBD_DESA_H 0x114C ++#define R_AX_CH8_TXBD_DESA_L 0x1150 ++#define R_AX_CH8_TXBD_DESA_H 0x1154 ++#define R_AX_CH9_TXBD_DESA_L 0x1158 ++#define R_AX_CH9_TXBD_DESA_H 0x115C ++#define R_AX_CH10_TXBD_DESA_L 0x1358 ++#define R_AX_CH10_TXBD_DESA_H 0x135C ++#define R_AX_CH11_TXBD_DESA_L 0x1360 ++#define R_AX_CH11_TXBD_DESA_H 0x1364 ++#define R_AX_CH12_TXBD_DESA_L 0x1160 ++#define R_AX_CH12_TXBD_DESA_H 0x1164 ++#define R_AX_RXQ_RXBD_DESA_L 0x1100 ++#define R_AX_RXQ_RXBD_DESA_H 0x1104 ++#define R_AX_RPQ_RXBD_DESA_L 0x1108 ++#define R_AX_RPQ_RXBD_DESA_H 0x110C ++#define B_AX_DESC_NUM_MSK GENMASK(11, 0) ++ ++#define R_AX_RXQ_RXBD_NUM 0x1020 ++#define R_AX_RPQ_RXBD_NUM 0x1022 ++#define R_AX_ACH0_TXBD_NUM 0x1024 ++#define R_AX_ACH1_TXBD_NUM 0x1026 ++#define R_AX_ACH2_TXBD_NUM 0x1028 ++#define R_AX_ACH3_TXBD_NUM 0x102A ++#define R_AX_ACH4_TXBD_NUM 0x102C ++#define R_AX_ACH5_TXBD_NUM 0x102E ++#define R_AX_ACH6_TXBD_NUM 0x1030 ++#define R_AX_ACH7_TXBD_NUM 0x1032 ++#define R_AX_CH8_TXBD_NUM 0x1034 ++#define R_AX_CH9_TXBD_NUM 0x1036 ++#define R_AX_CH10_TXBD_NUM 0x1338 ++#define R_AX_CH11_TXBD_NUM 0x133A ++#define R_AX_CH12_TXBD_NUM 0x1038 ++ ++#define R_AX_ACH0_BDRAM_CTRL 0x1200 ++#define R_AX_ACH1_BDRAM_CTRL 0x1204 ++#define R_AX_ACH2_BDRAM_CTRL 0x1208 ++#define R_AX_ACH3_BDRAM_CTRL 0x120C ++#define R_AX_ACH4_BDRAM_CTRL 0x1210 ++#define R_AX_ACH5_BDRAM_CTRL 0x1214 ++#define R_AX_ACH6_BDRAM_CTRL 0x1218 ++#define R_AX_ACH7_BDRAM_CTRL 0x121C ++#define R_AX_CH8_BDRAM_CTRL 0x1220 ++#define R_AX_CH9_BDRAM_CTRL 0x1224 ++#define R_AX_CH10_BDRAM_CTRL 0x1320 ++#define R_AX_CH11_BDRAM_CTRL 0x1324 ++#define R_AX_CH12_BDRAM_CTRL 0x1228 ++#define BDRAM_SIDX_MASK GENMASK(7, 0) ++#define BDRAM_MAX_MASK GENMASK(15, 8) ++#define BDRAM_MIN_MASK GENMASK(23, 16) ++ ++#define R_AX_PCIE_INIT_CFG1 0x1000 ++#define B_AX_PCIE_RXRST_KEEP_REG BIT(23) ++#define B_AX_PCIE_TXRST_KEEP_REG BIT(22) ++#define B_AX_PCIE_PERST_KEEP_REG BIT(21) ++#define B_AX_PCIE_FLR_KEEP_REG BIT(20) ++#define B_AX_PCIE_TRAIN_KEEP_REG BIT(19) ++#define B_AX_RXBD_MODE BIT(18) ++#define B_AX_PCIE_MAX_RXDMA_MASK GENMASK(16, 14) ++#define B_AX_RXHCI_EN BIT(13) ++#define B_AX_LATENCY_CONTROL BIT(12) ++#define B_AX_TXHCI_EN BIT(11) ++#define B_AX_PCIE_MAX_TXDMA_MASK GENMASK(10, 8) ++#define B_AX_TX_TRUNC_MODE BIT(5) ++#define B_AX_RX_TRUNC_MODE BIT(4) ++#define B_AX_RST_BDRAM BIT(3) ++#define B_AX_DIS_RXDMA_PRE BIT(2) ++ ++#define R_AX_TXDMA_ADDR_H 0x10F0 ++#define R_AX_RXDMA_ADDR_H 0x10F4 ++ ++#define R_AX_PCIE_DMA_STOP1 0x1010 ++#define B_AX_STOP_PCIEIO BIT(20) ++#define B_AX_STOP_WPDMA BIT(19) ++#define B_AX_STOP_CH12 BIT(18) ++#define B_AX_STOP_CH9 BIT(17) ++#define B_AX_STOP_CH8 BIT(16) ++#define B_AX_STOP_ACH7 BIT(15) ++#define B_AX_STOP_ACH6 BIT(14) ++#define B_AX_STOP_ACH5 BIT(13) ++#define B_AX_STOP_ACH4 BIT(12) ++#define B_AX_STOP_ACH3 BIT(11) ++#define B_AX_STOP_ACH2 BIT(10) ++#define B_AX_STOP_ACH1 BIT(9) ++#define B_AX_STOP_ACH0 BIT(8) ++#define B_AX_STOP_RPQ BIT(1) ++#define B_AX_STOP_RXQ BIT(0) ++#define B_AX_TX_STOP1_ALL GENMASK(18, 8) ++ ++#define R_AX_PCIE_DMA_STOP2 0x1310 ++#define B_AX_STOP_CH11 BIT(1) ++#define B_AX_STOP_CH10 BIT(0) ++#define B_AX_TX_STOP2_ALL GENMASK(1, 0) ++ ++#define R_AX_TXBD_RWPTR_CLR1 0x1014 ++#define B_AX_CLR_CH12_IDX BIT(10) ++#define B_AX_CLR_CH9_IDX BIT(9) ++#define B_AX_CLR_CH8_IDX BIT(8) ++#define B_AX_CLR_ACH7_IDX BIT(7) ++#define B_AX_CLR_ACH6_IDX BIT(6) ++#define B_AX_CLR_ACH5_IDX BIT(5) ++#define B_AX_CLR_ACH4_IDX BIT(4) ++#define B_AX_CLR_ACH3_IDX BIT(3) ++#define B_AX_CLR_ACH2_IDX BIT(2) ++#define B_AX_CLR_ACH1_IDX BIT(1) ++#define B_AX_CLR_ACH0_IDX BIT(0) ++#define B_AX_TXBD_CLR1_ALL GENMASK(10, 0) ++ ++#define R_AX_RXBD_RWPTR_CLR 0x1018 ++#define B_AX_CLR_RPQ_IDX BIT(1) ++#define B_AX_CLR_RXQ_IDX BIT(0) ++#define B_AX_RXBD_CLR_ALL GENMASK(1, 0) ++ ++#define R_AX_TXBD_RWPTR_CLR2 0x1314 ++#define B_AX_CLR_CH11_IDX BIT(1) ++#define B_AX_CLR_CH10_IDX BIT(0) ++#define B_AX_TXBD_CLR2_ALL GENMASK(1, 0) ++ ++#define R_AX_PCIE_DMA_BUSY1 0x101C ++#define B_AX_PCIEIO_RX_BUSY BIT(22) ++#define B_AX_PCIEIO_TX_BUSY BIT(21) ++#define B_AX_PCIEIO_BUSY BIT(20) ++#define B_AX_WPDMA_BUSY BIT(19) ++ ++#define R_AX_PCIE_DMA_BUSY2 0x131C ++#define B_AX_CH11_BUSY BIT(1) ++#define B_AX_CH10_BUSY BIT(0) ++ ++/* Configure */ ++#define R_AX_PCIE_INIT_CFG1 0x1000 ++#define B_AX_PCIE_RXRST_KEEP_REG BIT(23) ++#define B_AX_PCIE_TXRST_KEEP_REG BIT(22) ++#define B_AX_DIS_RXDMA_PRE BIT(2) ++ ++#define R_AX_PCIE_INIT_CFG2 0x1004 ++#define B_AX_WD_ITVL_IDLE GENMASK(27, 24) ++#define B_AX_WD_ITVL_ACT GENMASK(19, 16) ++ ++#define R_AX_PCIE_PS_CTRL 0x1008 ++#define B_AX_L1OFF_PWR_OFF_EN BIT(5) ++ ++#define R_AX_INT_MIT_RX 0x10D4 ++#define B_AX_RXMIT_RXP2_SEL BIT(19) ++#define B_AX_RXMIT_RXP1_SEL BIT(18) ++#define B_AX_RXTIMER_UNIT_MASK GENMASK(17, 16) ++#define AX_RXTIMER_UNIT_64US 0 ++#define AX_RXTIMER_UNIT_128US 1 ++#define AX_RXTIMER_UNIT_256US 2 ++#define AX_RXTIMER_UNIT_512US 3 ++#define B_AX_RXCOUNTER_MATCH_MASK GENMASK(15, 8) ++#define B_AX_RXTIMER_MATCH_MASK GENMASK(7, 0) ++ ++#define R_AX_DBG_ERR_FLAG 0x11C4 ++#define B_AX_PCIE_RPQ_FULL BIT(29) ++#define B_AX_PCIE_RXQ_FULL BIT(28) ++#define B_AX_CPL_STATUS_MASK GENMASK(27, 25) ++#define B_AX_RX_STUCK BIT(22) ++#define B_AX_TX_STUCK BIT(21) ++#define B_AX_PCIEDBG_TXERR0 BIT(16) ++#define B_AX_PCIE_RXP1_ERR0 BIT(4) ++#define B_AX_PCIE_TXBD_LEN0 BIT(1) ++#define B_AX_PCIE_TXBD_4KBOUD_LENERR BIT(0) ++ ++#define R_AX_LBC_WATCHDOG 0x11D8 ++#define B_AX_LBC_TIMER GENMASK(7, 4) ++#define B_AX_LBC_FLAG BIT(1) ++#define B_AX_LBC_EN BIT(0) ++ ++#define R_AX_PCIE_EXP_CTRL 0x13F0 ++#define B_AX_EN_CHKDSC_NO_RX_STUCK BIT(20) ++#define B_AX_MAX_TAG_NUM GENMASK(18, 16) ++#define B_AX_SIC_EN_FORCE_CLKREQ BIT(4) ++ ++#define R_AX_PCIE_RX_PREF_ADV 0x13F4 ++#define B_AX_RXDMA_PREF_ADV_EN BIT(0) ++ ++#define RTW89_PCI_TXBD_NUM_MAX 256 ++#define RTW89_PCI_RXBD_NUM_MAX 256 ++#define RTW89_PCI_TXWD_NUM_MAX 512 ++#define RTW89_PCI_TXWD_PAGE_SIZE 128 ++#define RTW89_PCI_ADDRINFO_MAX 4 ++#define RTW89_PCI_RX_BUF_SIZE 11460 ++ ++#define RTW89_PCI_POLL_BDRAM_RST_CNT 100 ++#define RTW89_PCI_MULTITAG 8 ++ ++/* PCIE CFG register */ ++#define RTW89_PCIE_ASPM_CTRL 0x070F ++#define RTW89_L1DLY_MASK GENMASK(5, 3) ++#define RTW89_L0DLY_MASK GENMASK(2, 0) ++#define RTW89_PCIE_TIMER_CTRL 0x0718 ++#define RTW89_PCIE_BIT_L1SUB BIT(5) ++#define RTW89_PCIE_L1_CTRL 0x0719 ++#define RTW89_PCIE_BIT_CLK BIT(4) ++#define RTW89_PCIE_BIT_L1 BIT(3) ++#define RTW89_PCIE_CLK_CTRL 0x0725 ++#define RTW89_PCIE_RST_MSTATE 0x0B48 ++#define RTW89_PCIE_BIT_CFG_RST_MSTATE BIT(0) ++#define RTW89_PCIE_PHY_RATE 0x82 ++#define RTW89_PCIE_PHY_RATE_MASK GENMASK(1, 0) ++#define INTF_INTGRA_MINREF_V1 90 ++#define INTF_INTGRA_HOSTREF_V1 100 ++ ++enum rtw89_pcie_phy { ++ PCIE_PHY_GEN1, ++ PCIE_PHY_GEN2, ++ PCIE_PHY_GEN1_UNDEFINE = 0x7F, ++}; ++ ++enum mac_ax_func_sw { ++ MAC_AX_FUNC_DIS, ++ MAC_AX_FUNC_EN, ++}; ++ ++enum rtw89_pcie_l0sdly { ++ PCIE_L0SDLY_1US = 0, ++ PCIE_L0SDLY_2US = 1, ++ PCIE_L0SDLY_3US = 2, ++ PCIE_L0SDLY_4US = 3, ++ PCIE_L0SDLY_5US = 4, ++ PCIE_L0SDLY_6US = 5, ++ PCIE_L0SDLY_7US = 6, ++}; ++ ++enum rtw89_pcie_l1dly { ++ PCIE_L1DLY_16US = 4, ++ PCIE_L1DLY_32US = 5, ++ PCIE_L1DLY_64US = 6, ++ PCIE_L1DLY_HW_INFI = 7, ++}; ++ ++enum rtw89_pcie_clkdly_hw { ++ PCIE_CLKDLY_HW_0 = 0, ++ PCIE_CLKDLY_HW_30US = 0x1, ++ PCIE_CLKDLY_HW_50US = 0x2, ++ PCIE_CLKDLY_HW_100US = 0x3, ++ PCIE_CLKDLY_HW_150US = 0x4, ++ PCIE_CLKDLY_HW_200US = 0x5, ++}; ++ ++struct rtw89_pci_bd_ram { ++ u8 start_idx; ++ u8 max_num; ++ u8 min_num; ++}; ++ ++struct rtw89_pci_tx_data { ++ dma_addr_t dma; ++}; ++ ++struct rtw89_pci_rx_info { ++ dma_addr_t dma; ++ u32 fs:1, ls:1, tag:11, len:14; ++}; ++ ++#define RTW89_PCI_TXBD_OPTION_LS BIT(14) ++ ++struct rtw89_pci_tx_bd_32 { ++ __le16 length; ++ __le16 option; ++ __le32 dma; ++} __packed; ++ ++#define RTW89_PCI_TXWP_VALID BIT(15) ++ ++struct rtw89_pci_tx_wp_info { ++ __le16 seq0; ++ __le16 seq1; ++ __le16 seq2; ++ __le16 seq3; ++} __packed; ++ ++#define RTW89_PCI_ADDR_MSDU_LS BIT(15) ++#define RTW89_PCI_ADDR_LS BIT(14) ++#define RTW89_PCI_ADDR_HIGH(a) (((a) << 6) & GENMASK(13, 6)) ++#define RTW89_PCI_ADDR_NUM(x) ((x) & GENMASK(5, 0)) ++ ++struct rtw89_pci_tx_addr_info_32 { ++ __le16 length; ++ __le16 option; ++ __le32 dma; ++} __packed; ++ ++#define RTW89_PCI_RPP_POLLUTED BIT(31) ++#define RTW89_PCI_RPP_SEQ GENMASK(30, 16) ++#define RTW89_PCI_RPP_TX_STATUS GENMASK(15, 13) ++#define RTW89_TX_DONE 0x0 ++#define RTW89_TX_RETRY_LIMIT 0x1 ++#define RTW89_TX_LIFE_TIME 0x2 ++#define RTW89_TX_MACID_DROP 0x3 ++#define RTW89_PCI_RPP_QSEL GENMASK(12, 8) ++#define RTW89_PCI_RPP_MACID GENMASK(7, 0) ++ ++struct rtw89_pci_rpp_fmt { ++ __le32 dword; ++} __packed; ++ ++struct rtw89_pci_rx_bd_32 { ++ __le16 buf_size; ++ __le16 rsvd; ++ __le32 dma; ++} __packed; ++ ++#define RTW89_PCI_RXBD_FS BIT(15) ++#define RTW89_PCI_RXBD_LS BIT(14) ++#define RTW89_PCI_RXBD_WRITE_SIZE GENMASK(13, 0) ++#define RTW89_PCI_RXBD_TAG GENMASK(28, 16) ++ ++struct rtw89_pci_rxbd_info { ++ __le32 dword; ++}; ++ ++struct rtw89_pci_tx_wd { ++ struct list_head list; ++ struct sk_buff_head queue; ++ ++ void *vaddr; ++ dma_addr_t paddr; ++ u32 len; ++ u32 seq; ++}; ++ ++struct rtw89_pci_dma_ring { ++ void *head; ++ u8 desc_size; ++ dma_addr_t dma; ++ ++ u32 addr_num; ++ u32 addr_idx; ++ u32 addr_bdram; ++ u32 addr_desa_l; ++ u32 addr_desa_h; ++ ++ u32 len; ++ u32 wp; /* host idx */ ++ u32 rp; /* hw idx */ ++}; ++ ++struct rtw89_pci_tx_wd_ring { ++ void *head; ++ dma_addr_t dma; ++ ++ struct rtw89_pci_tx_wd pages[RTW89_PCI_TXWD_NUM_MAX]; ++ struct list_head free_pages; ++ ++ u32 page_size; ++ u32 page_num; ++ u32 curr_num; ++}; ++ ++#define RTW89_RX_TAG_MAX 0x1fff ++ ++struct rtw89_pci_tx_ring { ++ struct rtw89_pci_tx_wd_ring wd_ring; ++ struct rtw89_pci_dma_ring bd_ring; ++ struct list_head busy_pages; ++ u8 txch; ++ bool dma_enabled; ++ u16 tag; /* range from 0x0001 ~ 0x1fff */ ++ ++ u64 tx_cnt; ++ u64 tx_acked; ++ u64 tx_retry_lmt; ++ u64 tx_life_time; ++ u64 tx_mac_id_drop; ++}; ++ ++struct rtw89_pci_rx_ring { ++ struct rtw89_pci_dma_ring bd_ring; ++ struct sk_buff *buf[RTW89_PCI_RXBD_NUM_MAX]; ++ u32 buf_sz; ++ struct sk_buff *diliver_skb; ++ struct rtw89_rx_desc_info diliver_desc; ++}; ++ ++struct rtw89_pci_isrs { ++ u32 halt_c2h_isrs; ++ u32 isrs[2]; ++}; ++ ++struct rtw89_pci { ++ struct pci_dev *pdev; ++ ++ /* protect HW irq related registers */ ++ spinlock_t irq_lock; ++ /* protect TRX resources (exclude RXQ) */ ++ spinlock_t trx_lock; ++ bool running; ++ struct rtw89_pci_tx_ring tx_rings[RTW89_TXCH_NUM]; ++ struct rtw89_pci_rx_ring rx_rings[RTW89_RXCH_NUM]; ++ struct sk_buff_head h2c_queue; ++ struct sk_buff_head h2c_release_queue; ++ ++ u32 halt_c2h_intrs; ++ u32 intrs[2]; ++ void __iomem *mmap; ++}; ++ ++static inline struct rtw89_pci_rx_info *RTW89_PCI_RX_SKB_CB(struct sk_buff *skb) ++{ ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ ++ BUILD_BUG_ON(sizeof(struct rtw89_pci_tx_data) > ++ sizeof(info->status.status_driver_data)); ++ ++ return (struct rtw89_pci_rx_info *)skb->cb; ++} ++ ++static inline struct rtw89_pci_rx_bd_32 * ++RTW89_PCI_RX_BD(struct rtw89_pci_rx_ring *rx_ring, u32 idx) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; ++ u8 *head = bd_ring->head; ++ u32 desc_size = bd_ring->desc_size; ++ u32 offset = idx * desc_size; ++ ++ return (struct rtw89_pci_rx_bd_32 *)(head + offset); ++} ++ ++static inline void ++rtw89_pci_rxbd_increase(struct rtw89_pci_rx_ring *rx_ring, u32 cnt) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; ++ ++ bd_ring->wp += cnt; ++ ++ if (bd_ring->wp >= bd_ring->len) ++ bd_ring->wp -= bd_ring->len; ++} ++ ++static inline struct rtw89_pci_tx_data *RTW89_PCI_TX_SKB_CB(struct sk_buff *skb) ++{ ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ ++ return (struct rtw89_pci_tx_data *)info->status.status_driver_data; ++} ++ ++static inline struct rtw89_pci_tx_bd_32 * ++rtw89_pci_get_next_txbd(struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; ++ struct rtw89_pci_tx_bd_32 *tx_bd, *head; ++ ++ head = bd_ring->head; ++ tx_bd = head + bd_ring->wp; ++ ++ return tx_bd; ++} ++ ++static inline struct rtw89_pci_tx_wd * ++rtw89_pci_dequeue_txwd(struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; ++ struct rtw89_pci_tx_wd *txwd; ++ ++ txwd = list_first_entry_or_null(&wd_ring->free_pages, ++ struct rtw89_pci_tx_wd, list); ++ if (!txwd) ++ return NULL; ++ ++ list_del_init(&txwd->list); ++ txwd->len = 0; ++ wd_ring->curr_num--; ++ ++ return txwd; ++} ++ ++static inline void ++rtw89_pci_enqueue_txwd(struct rtw89_pci_tx_ring *tx_ring, ++ struct rtw89_pci_tx_wd *txwd) ++{ ++ struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; ++ ++ memset(txwd->vaddr, 0, wd_ring->page_size); ++ list_add_tail(&txwd->list, &wd_ring->free_pages); ++ wd_ring->curr_num++; ++} ++ ++static inline bool rtw89_pci_ltr_is_err_reg_val(u32 val) ++{ ++ return val == 0xffffffff || val == 0xeaeaeaea; ++} ++ ++extern const struct dev_pm_ops rtw89_pm_ops; ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c +new file mode 100644 +index 000000000000..53c36cc82c57 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/phy.c +@@ -0,0 +1,2868 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "debug.h" ++#include "fw.h" ++#include "phy.h" ++#include "ps.h" ++#include "reg.h" ++#include "sar.h" ++#include "coex.h" ++ ++static u16 get_max_amsdu_len(struct rtw89_dev *rtwdev, ++ const struct rtw89_ra_report *report) ++{ ++ const struct rate_info *txrate = &report->txrate; ++ u32 bit_rate = report->bit_rate; ++ u8 mcs; ++ ++ /* lower than ofdm, do not aggregate */ ++ if (bit_rate < 550) ++ return 1; ++ ++ /* prevent hardware rate fallback to G mode rate */ ++ if (txrate->flags & RATE_INFO_FLAGS_MCS) ++ mcs = txrate->mcs & 0x07; ++ else if (txrate->flags & (RATE_INFO_FLAGS_VHT_MCS | RATE_INFO_FLAGS_HE_MCS)) ++ mcs = txrate->mcs; ++ else ++ mcs = 0; ++ ++ if (mcs <= 2) ++ return 1; ++ ++ /* lower than 20M vht 2ss mcs8, make it small */ ++ if (bit_rate < 1800) ++ return 1200; ++ ++ /* lower than 40M vht 2ss mcs9, make it medium */ ++ if (bit_rate < 4000) ++ return 2600; ++ ++ /* not yet 80M vht 2ss mcs8/9, make it twice regular packet size */ ++ if (bit_rate < 7000) ++ return 3500; ++ ++ return rtwdev->chip->max_amsdu_limit; ++} ++ ++static u64 get_mcs_ra_mask(u16 mcs_map, u8 highest_mcs, u8 gap) ++{ ++ u64 ra_mask = 0; ++ u8 mcs_cap; ++ int i, nss; ++ ++ for (i = 0, nss = 12; i < 4; i++, mcs_map >>= 2, nss += 12) { ++ mcs_cap = mcs_map & 0x3; ++ switch (mcs_cap) { ++ case 2: ++ ra_mask |= GENMASK_ULL(highest_mcs, 0) << nss; ++ break; ++ case 1: ++ ra_mask |= GENMASK_ULL(highest_mcs - gap, 0) << nss; ++ break; ++ case 0: ++ ra_mask |= GENMASK_ULL(highest_mcs - gap * 2, 0) << nss; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ return ra_mask; ++} ++ ++static u64 get_he_ra_mask(struct ieee80211_sta *sta) ++{ ++ struct ieee80211_sta_he_cap cap = sta->he_cap; ++ u16 mcs_map; ++ ++ switch (sta->bandwidth) { ++ case IEEE80211_STA_RX_BW_160: ++ if (cap.he_cap_elem.phy_cap_info[0] & ++ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) ++ mcs_map = le16_to_cpu(cap.he_mcs_nss_supp.rx_mcs_80p80); ++ else ++ mcs_map = le16_to_cpu(cap.he_mcs_nss_supp.rx_mcs_160); ++ break; ++ default: ++ mcs_map = le16_to_cpu(cap.he_mcs_nss_supp.rx_mcs_80); ++ } ++ ++ /* MCS11, MCS9, MCS7 */ ++ return get_mcs_ra_mask(mcs_map, 11, 2); ++} ++ ++#define RA_FLOOR_TABLE_SIZE 7 ++#define RA_FLOOR_UP_GAP 3 ++static u64 rtw89_phy_ra_mask_rssi(struct rtw89_dev *rtwdev, u8 rssi, ++ u8 ratr_state) ++{ ++ u8 rssi_lv_t[RA_FLOOR_TABLE_SIZE] = {30, 44, 48, 52, 56, 60, 100}; ++ u8 rssi_lv = 0; ++ u8 i; ++ ++ rssi >>= 1; ++ for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) { ++ if (i >= ratr_state) ++ rssi_lv_t[i] += RA_FLOOR_UP_GAP; ++ if (rssi < rssi_lv_t[i]) { ++ rssi_lv = i; ++ break; ++ } ++ } ++ if (rssi_lv == 0) ++ return 0xffffffffffffffffULL; ++ else if (rssi_lv == 1) ++ return 0xfffffffffffffff0ULL; ++ else if (rssi_lv == 2) ++ return 0xffffffffffffffe0ULL; ++ else if (rssi_lv == 3) ++ return 0xffffffffffffffc0ULL; ++ else if (rssi_lv == 4) ++ return 0xffffffffffffff80ULL; ++ else if (rssi_lv >= 5) ++ return 0xffffffffffffff00ULL; ++ ++ return 0xffffffffffffffffULL; ++} ++ ++static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta) ++{ ++ struct rtw89_hal *hal = &rtwdev->hal; ++ struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta); ++ struct cfg80211_bitrate_mask *mask = &rtwsta->mask; ++ enum nl80211_band band; ++ u64 cfg_mask; ++ ++ if (!rtwsta->use_cfg_mask) ++ return -1; ++ ++ switch (hal->current_band_type) { ++ case RTW89_BAND_2G: ++ band = NL80211_BAND_2GHZ; ++ cfg_mask = u64_encode_bits(mask->control[NL80211_BAND_2GHZ].legacy, ++ RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES); ++ break; ++ case RTW89_BAND_5G: ++ band = NL80211_BAND_5GHZ; ++ cfg_mask = u64_encode_bits(mask->control[NL80211_BAND_5GHZ].legacy, ++ RA_MASK_OFDM_RATES); ++ break; ++ default: ++ rtw89_warn(rtwdev, "unhandled band type %d\n", hal->current_band_type); ++ return -1; ++ } ++ ++ if (sta->he_cap.has_he) { ++ cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[0], ++ RA_MASK_HE_1SS_RATES); ++ cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[1], ++ RA_MASK_HE_2SS_RATES); ++ } else if (sta->vht_cap.vht_supported) { ++ cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[0], ++ RA_MASK_VHT_1SS_RATES); ++ cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[1], ++ RA_MASK_VHT_2SS_RATES); ++ } else if (sta->ht_cap.ht_supported) { ++ cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[0], ++ RA_MASK_HT_1SS_RATES); ++ cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[1], ++ RA_MASK_HT_2SS_RATES); ++ } ++ ++ return cfg_mask; ++} ++ ++static const u64 ++rtw89_ra_mask_ht_rates[4] = {RA_MASK_HT_1SS_RATES, RA_MASK_HT_2SS_RATES, ++ RA_MASK_HT_3SS_RATES, RA_MASK_HT_4SS_RATES}; ++static const u64 ++rtw89_ra_mask_vht_rates[4] = {RA_MASK_VHT_1SS_RATES, RA_MASK_VHT_2SS_RATES, ++ RA_MASK_VHT_3SS_RATES, RA_MASK_VHT_4SS_RATES}; ++static const u64 ++rtw89_ra_mask_he_rates[4] = {RA_MASK_HE_1SS_RATES, RA_MASK_HE_2SS_RATES, ++ RA_MASK_HE_3SS_RATES, RA_MASK_HE_4SS_RATES}; ++ ++static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, ++ struct ieee80211_sta *sta, bool csi) ++{ ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_vif *rtwvif = rtwsta->rtwvif; ++ struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern; ++ struct rtw89_ra_info *ra = &rtwsta->ra; ++ const u64 *high_rate_masks = rtw89_ra_mask_ht_rates; ++ u8 rssi = ewma_rssi_read(&rtwsta->avg_rssi); ++ u64 high_rate_mask = 0; ++ u64 ra_mask = 0; ++ u8 mode = 0; ++ u8 csi_mode = RTW89_RA_RPT_MODE_LEGACY; ++ u8 bw_mode = 0; ++ u8 stbc_en = 0; ++ u8 ldpc_en = 0; ++ u8 i; ++ bool sgi = false; ++ ++ memset(ra, 0, sizeof(*ra)); ++ /* Set the ra mask from sta's capability */ ++ if (sta->he_cap.has_he) { ++ mode |= RTW89_RA_MODE_HE; ++ csi_mode = RTW89_RA_RPT_MODE_HE; ++ ra_mask |= get_he_ra_mask(sta); ++ high_rate_masks = rtw89_ra_mask_he_rates; ++ if (sta->he_cap.he_cap_elem.phy_cap_info[2] & ++ IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ) ++ stbc_en = 1; ++ if (sta->he_cap.he_cap_elem.phy_cap_info[1] & ++ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD) ++ ldpc_en = 1; ++ } else if (sta->vht_cap.vht_supported) { ++ u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map); ++ ++ mode |= RTW89_RA_MODE_VHT; ++ csi_mode = RTW89_RA_RPT_MODE_VHT; ++ /* MCS9, MCS8, MCS7 */ ++ ra_mask |= get_mcs_ra_mask(mcs_map, 9, 1); ++ high_rate_masks = rtw89_ra_mask_vht_rates; ++ if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK) ++ stbc_en = 1; ++ if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) ++ ldpc_en = 1; ++ } else if (sta->ht_cap.ht_supported) { ++ mode |= RTW89_RA_MODE_HT; ++ csi_mode = RTW89_RA_RPT_MODE_HT; ++ ra_mask |= ((u64)sta->ht_cap.mcs.rx_mask[3] << 48) | ++ ((u64)sta->ht_cap.mcs.rx_mask[2] << 36) | ++ (sta->ht_cap.mcs.rx_mask[1] << 24) | ++ (sta->ht_cap.mcs.rx_mask[0] << 12); ++ high_rate_masks = rtw89_ra_mask_ht_rates; ++ if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) ++ stbc_en = 1; ++ if (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) ++ ldpc_en = 1; ++ } ++ ++ if (rtwdev->hal.current_band_type == RTW89_BAND_2G) { ++ if (sta->supp_rates[NL80211_BAND_2GHZ] <= 0xf) ++ mode |= RTW89_RA_MODE_CCK; ++ else ++ mode |= RTW89_RA_MODE_CCK | RTW89_RA_MODE_OFDM; ++ } else { ++ mode |= RTW89_RA_MODE_OFDM; ++ } ++ ++ if (mode >= RTW89_RA_MODE_HT) { ++ for (i = 0; i < rtwdev->hal.tx_nss; i++) ++ high_rate_mask |= high_rate_masks[i]; ++ ra_mask &= high_rate_mask; ++ if (mode & RTW89_RA_MODE_OFDM) ++ ra_mask |= RA_MASK_SUBOFDM_RATES; ++ if (mode & RTW89_RA_MODE_CCK) ++ ra_mask |= RA_MASK_SUBCCK_RATES; ++ } else if (mode & RTW89_RA_MODE_OFDM) { ++ if (mode & RTW89_RA_MODE_CCK) ++ ra_mask |= RA_MASK_SUBCCK_RATES; ++ ra_mask |= RA_MASK_OFDM_RATES; ++ } else { ++ ra_mask = RA_MASK_CCK_RATES; ++ } ++ ++ if (mode != RTW89_RA_MODE_CCK) { ++ ra_mask &= rtw89_phy_ra_mask_rssi(rtwdev, rssi, 0); ++ ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta); ++ } ++ ++ switch (sta->bandwidth) { ++ case IEEE80211_STA_RX_BW_80: ++ bw_mode = RTW89_CHANNEL_WIDTH_80; ++ sgi = sta->vht_cap.vht_supported && ++ (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); ++ break; ++ case IEEE80211_STA_RX_BW_40: ++ bw_mode = RTW89_CHANNEL_WIDTH_40; ++ sgi = sta->ht_cap.ht_supported && ++ (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40); ++ break; ++ default: ++ bw_mode = RTW89_CHANNEL_WIDTH_20; ++ sgi = sta->ht_cap.ht_supported && ++ (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20); ++ break; ++ } ++ ++ if (sta->he_cap.he_cap_elem.phy_cap_info[3] & ++ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM) ++ ra->dcm_cap = 1; ++ ++ if (rate_pattern->enable) { ++ ra_mask = rtw89_phy_ra_mask_cfg(rtwdev, rtwsta); ++ ra_mask &= rate_pattern->ra_mask; ++ mode = rate_pattern->ra_mode; ++ } ++ ++ ra->bw_cap = bw_mode; ++ ra->mode_ctrl = mode; ++ ra->macid = rtwsta->mac_id; ++ ra->stbc_cap = stbc_en; ++ ra->ldpc_cap = ldpc_en; ++ ra->ss_num = min(sta->rx_nss, rtwdev->hal.tx_nss) - 1; ++ ra->en_sgi = sgi; ++ ra->ra_mask = ra_mask; ++ ++ if (!csi) ++ return; ++ ++ ra->fixed_csi_rate_en = false; ++ ra->ra_csi_rate_en = true; ++ ra->cr_tbl_sel = false; ++ ra->band_num = rtwvif->phy_idx; ++ ra->csi_bw = bw_mode; ++ ra->csi_gi_ltf = RTW89_GILTF_LGI_4XHE32; ++ ra->csi_mcs_ss_idx = 5; ++ ra->csi_mode = csi_mode; ++} ++ ++void rtw89_phy_ra_updata_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) ++{ ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_ra_info *ra = &rtwsta->ra; ++ ++ rtw89_phy_ra_sta_update(rtwdev, sta, false); ++ ra->upd_mask = 1; ++ rtw89_debug(rtwdev, RTW89_DBG_RA, ++ "ra updat: macid = %d, bw = %d, nss = %d, gi = %d %d", ++ ra->macid, ++ ra->bw_cap, ++ ra->ss_num, ++ ra->en_sgi, ++ ra->giltf); ++ ++ rtw89_fw_h2c_ra(rtwdev, ra, false); ++} ++ ++static bool __check_rate_pattern(struct rtw89_phy_rate_pattern *next, ++ u16 rate_base, u64 ra_mask, u8 ra_mode, ++ u32 rate_ctrl, u32 ctrl_skip, bool force) ++{ ++ u8 n, c; ++ ++ if (rate_ctrl == ctrl_skip) ++ return true; ++ ++ n = hweight32(rate_ctrl); ++ if (n == 0) ++ return true; ++ ++ if (force && n != 1) ++ return false; ++ ++ if (next->enable) ++ return false; ++ ++ c = __fls(rate_ctrl); ++ next->rate = rate_base + c; ++ next->ra_mode = ra_mode; ++ next->ra_mask = ra_mask; ++ next->enable = true; ++ ++ return true; ++} ++ ++void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ const struct cfg80211_bitrate_mask *mask) ++{ ++ struct ieee80211_supported_band *sband; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ struct rtw89_phy_rate_pattern next_pattern = {0}; ++ static const u16 hw_rate_he[] = {RTW89_HW_RATE_HE_NSS1_MCS0, ++ RTW89_HW_RATE_HE_NSS2_MCS0, ++ RTW89_HW_RATE_HE_NSS3_MCS0, ++ RTW89_HW_RATE_HE_NSS4_MCS0}; ++ static const u16 hw_rate_vht[] = {RTW89_HW_RATE_VHT_NSS1_MCS0, ++ RTW89_HW_RATE_VHT_NSS2_MCS0, ++ RTW89_HW_RATE_VHT_NSS3_MCS0, ++ RTW89_HW_RATE_VHT_NSS4_MCS0}; ++ static const u16 hw_rate_ht[] = {RTW89_HW_RATE_MCS0, ++ RTW89_HW_RATE_MCS8, ++ RTW89_HW_RATE_MCS16, ++ RTW89_HW_RATE_MCS24}; ++ u8 band = rtwdev->hal.current_band_type; ++ u8 tx_nss = rtwdev->hal.tx_nss; ++ u8 i; ++ ++ for (i = 0; i < tx_nss; i++) ++ if (!__check_rate_pattern(&next_pattern, hw_rate_he[i], ++ RA_MASK_HE_RATES, RTW89_RA_MODE_HE, ++ mask->control[band].he_mcs[i], ++ 0, true)) ++ goto out; ++ ++ for (i = 0; i < tx_nss; i++) ++ if (!__check_rate_pattern(&next_pattern, hw_rate_vht[i], ++ RA_MASK_VHT_RATES, RTW89_RA_MODE_VHT, ++ mask->control[band].vht_mcs[i], ++ 0, true)) ++ goto out; ++ ++ for (i = 0; i < tx_nss; i++) ++ if (!__check_rate_pattern(&next_pattern, hw_rate_ht[i], ++ RA_MASK_HT_RATES, RTW89_RA_MODE_HT, ++ mask->control[band].ht_mcs[i], ++ 0, true)) ++ goto out; ++ ++ /* lagacy cannot be empty for nl80211_parse_tx_bitrate_mask, and ++ * require at least one basic rate for ieee80211_set_bitrate_mask, ++ * so the decision just depends on if all bitrates are set or not. ++ */ ++ sband = rtwdev->hw->wiphy->bands[band]; ++ if (band == RTW89_BAND_2G) { ++ if (!__check_rate_pattern(&next_pattern, RTW89_HW_RATE_CCK1, ++ RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES, ++ RTW89_RA_MODE_CCK | RTW89_RA_MODE_OFDM, ++ mask->control[band].legacy, ++ BIT(sband->n_bitrates) - 1, false)) ++ goto out; ++ } else { ++ if (!__check_rate_pattern(&next_pattern, RTW89_HW_RATE_OFDM6, ++ RA_MASK_OFDM_RATES, RTW89_RA_MODE_OFDM, ++ mask->control[band].legacy, ++ BIT(sband->n_bitrates) - 1, false)) ++ goto out; ++ } ++ ++ if (!next_pattern.enable) ++ goto out; ++ ++ rtwvif->rate_pattern = next_pattern; ++ rtw89_debug(rtwdev, RTW89_DBG_RA, ++ "configure pattern: rate 0x%x, mask 0x%llx, mode 0x%x\n", ++ next_pattern.rate, ++ next_pattern.ra_mask, ++ next_pattern.ra_mode); ++ return; ++ ++out: ++ rtwvif->rate_pattern.enable = false; ++ rtw89_debug(rtwdev, RTW89_DBG_RA, "unset rate pattern\n"); ++} ++ ++static void rtw89_phy_ra_updata_sta_iter(void *data, struct ieee80211_sta *sta) ++{ ++ struct rtw89_dev *rtwdev = (struct rtw89_dev *)data; ++ ++ rtw89_phy_ra_updata_sta(rtwdev, sta); ++} ++ ++void rtw89_phy_ra_update(struct rtw89_dev *rtwdev) ++{ ++ ieee80211_iterate_stations_atomic(rtwdev->hw, ++ rtw89_phy_ra_updata_sta_iter, ++ rtwdev); ++} ++ ++void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) ++{ ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_ra_info *ra = &rtwsta->ra; ++ u8 rssi = ewma_rssi_read(&rtwsta->avg_rssi) >> RSSI_FACTOR; ++ bool csi = rtw89_sta_has_beamformer_cap(sta); ++ ++ rtw89_phy_ra_sta_update(rtwdev, sta, csi); ++ ++ if (rssi > 40) ++ ra->init_rate_lv = 1; ++ else if (rssi > 20) ++ ra->init_rate_lv = 2; ++ else if (rssi > 1) ++ ra->init_rate_lv = 3; ++ else ++ ra->init_rate_lv = 0; ++ ra->upd_all = 1; ++ rtw89_debug(rtwdev, RTW89_DBG_RA, ++ "ra assoc: macid = %d, mode = %d, bw = %d, nss = %d, lv = %d", ++ ra->macid, ++ ra->mode_ctrl, ++ ra->bw_cap, ++ ra->ss_num, ++ ra->init_rate_lv); ++ rtw89_debug(rtwdev, RTW89_DBG_RA, ++ "ra assoc: dcm = %d, er = %d, ldpc = %d, stbc = %d, gi = %d %d", ++ ra->dcm_cap, ++ ra->er_cap, ++ ra->ldpc_cap, ++ ra->stbc_cap, ++ ra->en_sgi, ++ ra->giltf); ++ ++ rtw89_fw_h2c_ra(rtwdev, ra, csi); ++} ++ ++u8 rtw89_phy_get_txsc(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_params *param, ++ enum rtw89_bandwidth dbw) ++{ ++ enum rtw89_bandwidth cbw = param->bandwidth; ++ u8 pri_ch = param->primary_chan; ++ u8 central_ch = param->center_chan; ++ u8 txsc_idx = 0; ++ u8 tmp = 0; ++ ++ if (cbw == dbw || cbw == RTW89_CHANNEL_WIDTH_20) ++ return txsc_idx; ++ ++ switch (cbw) { ++ case RTW89_CHANNEL_WIDTH_40: ++ txsc_idx = pri_ch > central_ch ? 1 : 2; ++ break; ++ case RTW89_CHANNEL_WIDTH_80: ++ if (dbw == RTW89_CHANNEL_WIDTH_20) { ++ if (pri_ch > central_ch) ++ txsc_idx = (pri_ch - central_ch) >> 1; ++ else ++ txsc_idx = ((central_ch - pri_ch) >> 1) + 1; ++ } else { ++ txsc_idx = pri_ch > central_ch ? 9 : 10; ++ } ++ break; ++ case RTW89_CHANNEL_WIDTH_160: ++ if (pri_ch > central_ch) ++ tmp = (pri_ch - central_ch) >> 1; ++ else ++ tmp = ((central_ch - pri_ch) >> 1) + 1; ++ ++ if (dbw == RTW89_CHANNEL_WIDTH_20) { ++ txsc_idx = tmp; ++ } else if (dbw == RTW89_CHANNEL_WIDTH_40) { ++ if (tmp == 1 || tmp == 3) ++ txsc_idx = 9; ++ else if (tmp == 5 || tmp == 7) ++ txsc_idx = 11; ++ else if (tmp == 2 || tmp == 4) ++ txsc_idx = 10; ++ else if (tmp == 6 || tmp == 8) ++ txsc_idx = 12; ++ else ++ return 0xff; ++ } else { ++ txsc_idx = pri_ch > central_ch ? 13 : 14; ++ } ++ break; ++ case RTW89_CHANNEL_WIDTH_80_80: ++ if (dbw == RTW89_CHANNEL_WIDTH_20) { ++ if (pri_ch > central_ch) ++ txsc_idx = (10 - (pri_ch - central_ch)) >> 1; ++ else ++ txsc_idx = ((central_ch - pri_ch) >> 1) + 5; ++ } else if (dbw == RTW89_CHANNEL_WIDTH_40) { ++ txsc_idx = pri_ch > central_ch ? 10 : 12; ++ } else { ++ txsc_idx = 14; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ return txsc_idx; ++} ++ ++u32 rtw89_phy_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ const u32 *base_addr = chip->rf_base_addr; ++ u32 val, direct_addr; ++ ++ if (rf_path >= rtwdev->chip->rf_path_num) { ++ rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path); ++ return INV_RF_DATA; ++ } ++ ++ addr &= 0xff; ++ direct_addr = base_addr[rf_path] + (addr << 2); ++ mask &= RFREG_MASK; ++ ++ val = rtw89_phy_read32_mask(rtwdev, direct_addr, mask); ++ ++ return val; ++} ++EXPORT_SYMBOL(rtw89_phy_read_rf); ++ ++bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask, u32 data) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ const u32 *base_addr = chip->rf_base_addr; ++ u32 direct_addr; ++ ++ if (rf_path >= rtwdev->chip->rf_path_num) { ++ rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path); ++ return false; ++ } ++ ++ addr &= 0xff; ++ direct_addr = base_addr[rf_path] + (addr << 2); ++ mask &= RFREG_MASK; ++ ++ rtw89_phy_write32_mask(rtwdev, direct_addr, mask, data); ++ ++ /* delay to ensure writing properly */ ++ udelay(1); ++ ++ return true; ++} ++EXPORT_SYMBOL(rtw89_phy_write_rf); ++ ++static void rtw89_phy_bb_reset(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ chip->ops->bb_reset(rtwdev, phy_idx); ++} ++ ++static void rtw89_phy_config_bb_reg(struct rtw89_dev *rtwdev, ++ const struct rtw89_reg2_def *reg, ++ enum rtw89_rf_path rf_path, ++ void *extra_data) ++{ ++ if (reg->addr == 0xfe) ++ mdelay(50); ++ else if (reg->addr == 0xfd) ++ mdelay(5); ++ else if (reg->addr == 0xfc) ++ mdelay(1); ++ else if (reg->addr == 0xfb) ++ udelay(50); ++ else if (reg->addr == 0xfa) ++ udelay(5); ++ else if (reg->addr == 0xf9) ++ udelay(1); ++ else ++ rtw89_phy_write32(rtwdev, reg->addr, reg->data); ++} ++ ++static void ++rtw89_phy_cofig_rf_reg_store(struct rtw89_dev *rtwdev, ++ const struct rtw89_reg2_def *reg, ++ enum rtw89_rf_path rf_path, ++ struct rtw89_fw_h2c_rf_reg_info *info) ++{ ++ u16 idx = info->curr_idx % RTW89_H2C_RF_PAGE_SIZE; ++ u8 page = info->curr_idx / RTW89_H2C_RF_PAGE_SIZE; ++ ++ info->rtw89_phy_config_rf_h2c[page][idx] = ++ cpu_to_le32((reg->addr << 20) | reg->data); ++ info->curr_idx++; ++} ++ ++static int rtw89_phy_config_rf_reg_fw(struct rtw89_dev *rtwdev, ++ struct rtw89_fw_h2c_rf_reg_info *info) ++{ ++ u16 page = info->curr_idx / RTW89_H2C_RF_PAGE_SIZE; ++ u16 len = (info->curr_idx % RTW89_H2C_RF_PAGE_SIZE) * 4; ++ u8 i; ++ int ret = 0; ++ ++ if (page > RTW89_H2C_RF_PAGE_NUM) { ++ rtw89_warn(rtwdev, ++ "rf reg h2c total page num %d larger than %d (RTW89_H2C_RF_PAGE_NUM)\n", ++ page, RTW89_H2C_RF_PAGE_NUM); ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < page; i++) { ++ ret = rtw89_fw_h2c_rf_reg(rtwdev, info, ++ RTW89_H2C_RF_PAGE_SIZE * 4, i); ++ if (ret) ++ return ret; ++ } ++ ret = rtw89_fw_h2c_rf_reg(rtwdev, info, len, i); ++ if (ret) ++ return ret; ++ info->curr_idx = 0; ++ ++ return 0; ++} ++ ++static void rtw89_phy_config_rf_reg(struct rtw89_dev *rtwdev, ++ const struct rtw89_reg2_def *reg, ++ enum rtw89_rf_path rf_path, ++ void *extra_data) ++{ ++ if (reg->addr == 0xfe) { ++ mdelay(50); ++ } else if (reg->addr == 0xfd) { ++ mdelay(5); ++ } else if (reg->addr == 0xfc) { ++ mdelay(1); ++ } else if (reg->addr == 0xfb) { ++ udelay(50); ++ } else if (reg->addr == 0xfa) { ++ udelay(5); ++ } else if (reg->addr == 0xf9) { ++ udelay(1); ++ } else { ++ rtw89_write_rf(rtwdev, rf_path, reg->addr, 0xfffff, reg->data); ++ rtw89_phy_cofig_rf_reg_store(rtwdev, reg, rf_path, ++ (struct rtw89_fw_h2c_rf_reg_info *)extra_data); ++ } ++} ++ ++static int rtw89_phy_sel_headline(struct rtw89_dev *rtwdev, ++ const struct rtw89_phy_table *table, ++ u32 *headline_size, u32 *headline_idx, ++ u8 rfe, u8 cv) ++{ ++ const struct rtw89_reg2_def *reg; ++ u32 headline; ++ u32 compare, target; ++ u8 rfe_para, cv_para; ++ u8 cv_max = 0; ++ bool case_matched = false; ++ u32 i; ++ ++ for (i = 0; i < table->n_regs; i++) { ++ reg = &table->regs[i]; ++ headline = get_phy_headline(reg->addr); ++ if (headline != PHY_HEADLINE_VALID) ++ break; ++ } ++ *headline_size = i; ++ if (*headline_size == 0) ++ return 0; ++ ++ /* case 1: RFE match, CV match */ ++ compare = get_phy_compare(rfe, cv); ++ for (i = 0; i < *headline_size; i++) { ++ reg = &table->regs[i]; ++ target = get_phy_target(reg->addr); ++ if (target == compare) { ++ *headline_idx = i; ++ return 0; ++ } ++ } ++ ++ /* case 2: RFE match, CV don't care */ ++ compare = get_phy_compare(rfe, PHY_COND_DONT_CARE); ++ for (i = 0; i < *headline_size; i++) { ++ reg = &table->regs[i]; ++ target = get_phy_target(reg->addr); ++ if (target == compare) { ++ *headline_idx = i; ++ return 0; ++ } ++ } ++ ++ /* case 3: RFE match, CV max in table */ ++ for (i = 0; i < *headline_size; i++) { ++ reg = &table->regs[i]; ++ rfe_para = get_phy_cond_rfe(reg->addr); ++ cv_para = get_phy_cond_cv(reg->addr); ++ if (rfe_para == rfe) { ++ if (cv_para >= cv_max) { ++ cv_max = cv_para; ++ *headline_idx = i; ++ case_matched = true; ++ } ++ } ++ } ++ ++ if (case_matched) ++ return 0; ++ ++ /* case 4: RFE don't care, CV max in table */ ++ for (i = 0; i < *headline_size; i++) { ++ reg = &table->regs[i]; ++ rfe_para = get_phy_cond_rfe(reg->addr); ++ cv_para = get_phy_cond_cv(reg->addr); ++ if (rfe_para == PHY_COND_DONT_CARE) { ++ if (cv_para >= cv_max) { ++ cv_max = cv_para; ++ *headline_idx = i; ++ case_matched = true; ++ } ++ } ++ } ++ ++ if (case_matched) ++ return 0; ++ ++ return -EINVAL; ++} ++ ++static void rtw89_phy_init_reg(struct rtw89_dev *rtwdev, ++ const struct rtw89_phy_table *table, ++ void (*config)(struct rtw89_dev *rtwdev, ++ const struct rtw89_reg2_def *reg, ++ enum rtw89_rf_path rf_path, ++ void *data), ++ void *extra_data) ++{ ++ const struct rtw89_reg2_def *reg; ++ enum rtw89_rf_path rf_path = table->rf_path; ++ u8 rfe = rtwdev->efuse.rfe_type; ++ u8 cv = rtwdev->hal.cv; ++ u32 i; ++ u32 headline_size = 0, headline_idx = 0; ++ u32 target = 0, cfg_target; ++ u8 cond; ++ bool is_matched = true; ++ bool target_found = false; ++ int ret; ++ ++ ret = rtw89_phy_sel_headline(rtwdev, table, &headline_size, ++ &headline_idx, rfe, cv); ++ if (ret) { ++ rtw89_err(rtwdev, "invalid PHY package: %d/%d\n", rfe, cv); ++ return; ++ } ++ ++ cfg_target = get_phy_target(table->regs[headline_idx].addr); ++ for (i = headline_size; i < table->n_regs; i++) { ++ reg = &table->regs[i]; ++ cond = get_phy_cond(reg->addr); ++ switch (cond) { ++ case PHY_COND_BRANCH_IF: ++ case PHY_COND_BRANCH_ELIF: ++ target = get_phy_target(reg->addr); ++ break; ++ case PHY_COND_BRANCH_ELSE: ++ is_matched = false; ++ if (!target_found) { ++ rtw89_warn(rtwdev, "failed to load CR %x/%x\n", ++ reg->addr, reg->data); ++ return; ++ } ++ break; ++ case PHY_COND_BRANCH_END: ++ is_matched = true; ++ target_found = false; ++ break; ++ case PHY_COND_CHECK: ++ if (target_found) { ++ is_matched = false; ++ break; ++ } ++ ++ if (target == cfg_target) { ++ is_matched = true; ++ target_found = true; ++ } else { ++ is_matched = false; ++ target_found = false; ++ } ++ break; ++ default: ++ if (is_matched) ++ config(rtwdev, reg, rf_path, extra_data); ++ break; ++ } ++ } ++} ++ ++void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ const struct rtw89_phy_table *bb_table = chip->bb_table; ++ ++ rtw89_phy_init_reg(rtwdev, bb_table, rtw89_phy_config_bb_reg, NULL); ++ rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_0); ++ rtw89_phy_bb_reset(rtwdev, RTW89_PHY_0); ++} ++ ++static u32 rtw89_phy_nctl_poll(struct rtw89_dev *rtwdev) ++{ ++ rtw89_phy_write32(rtwdev, 0x8080, 0x4); ++ udelay(1); ++ return rtw89_phy_read32(rtwdev, 0x8080); ++} ++ ++void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ const struct rtw89_phy_table *rf_table; ++ struct rtw89_fw_h2c_rf_reg_info *rf_reg_info; ++ u8 path; ++ ++ rf_reg_info = kzalloc(sizeof(*rf_reg_info), GFP_KERNEL); ++ if (!rf_reg_info) ++ return; ++ ++ for (path = RF_PATH_A; path < chip->rf_path_num; path++) { ++ rf_reg_info->rf_path = path; ++ rf_table = chip->rf_table[path]; ++ rtw89_phy_init_reg(rtwdev, rf_table, rtw89_phy_config_rf_reg, ++ (void *)rf_reg_info); ++ if (rtw89_phy_config_rf_reg_fw(rtwdev, rf_reg_info)) ++ rtw89_warn(rtwdev, "rf path %d reg h2c config failed\n", ++ path); ++ } ++ kfree(rf_reg_info); ++} ++ ++static void rtw89_phy_init_rf_nctl(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ const struct rtw89_phy_table *nctl_table; ++ u32 val; ++ int ret; ++ ++ /* IQK/DPK clock & reset */ ++ rtw89_phy_write32_set(rtwdev, 0x0c60, 0x3); ++ rtw89_phy_write32_set(rtwdev, 0x0c6c, 0x1); ++ rtw89_phy_write32_set(rtwdev, 0x58ac, 0x8000000); ++ rtw89_phy_write32_set(rtwdev, 0x78ac, 0x8000000); ++ ++ /* check 0x8080 */ ++ rtw89_phy_write32(rtwdev, 0x8000, 0x8); ++ ++ ret = read_poll_timeout(rtw89_phy_nctl_poll, val, val == 0x4, 10, ++ 1000, false, rtwdev); ++ if (ret) ++ rtw89_err(rtwdev, "failed to poll nctl block\n"); ++ ++ nctl_table = chip->nctl_table; ++ rtw89_phy_init_reg(rtwdev, nctl_table, rtw89_phy_config_bb_reg, NULL); ++} ++ ++static u32 rtw89_phy0_phy1_offset(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ u32 phy_page = addr >> 8; ++ u32 ofst = 0; ++ ++ switch (phy_page) { ++ case 0x6: ++ case 0x7: ++ case 0x8: ++ case 0x9: ++ case 0xa: ++ case 0xb: ++ case 0xc: ++ case 0xd: ++ case 0x19: ++ case 0x1a: ++ case 0x1b: ++ ofst = 0x2000; ++ break; ++ default: ++ /* warning case */ ++ ofst = 0; ++ break; ++ } ++ ++ if (phy_page >= 0x40 && phy_page <= 0x4f) ++ ofst = 0x2000; ++ ++ return ofst; ++} ++ ++void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, ++ u32 data, enum rtw89_phy_idx phy_idx) ++{ ++ if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1) ++ addr += rtw89_phy0_phy1_offset(rtwdev, addr); ++ rtw89_phy_write32_mask(rtwdev, addr, mask, data); ++} ++ ++void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask, ++ u32 val) ++{ ++ rtw89_phy_write32_idx(rtwdev, addr, mask, val, RTW89_PHY_0); ++ ++ if (!rtwdev->dbcc_en) ++ return; ++ ++ rtw89_phy_write32_idx(rtwdev, addr, mask, val, RTW89_PHY_1); ++} ++ ++void rtw89_phy_write_reg3_tbl(struct rtw89_dev *rtwdev, ++ const struct rtw89_phy_reg3_tbl *tbl) ++{ ++ const struct rtw89_reg3_def *reg3; ++ int i; ++ ++ for (i = 0; i < tbl->size; i++) { ++ reg3 = &tbl->reg3[i]; ++ rtw89_phy_write32_mask(rtwdev, reg3->addr, reg3->mask, reg3->data); ++ } ++} ++ ++const u8 rtw89_rs_idx_max[] = { ++ [RTW89_RS_CCK] = RTW89_RATE_CCK_MAX, ++ [RTW89_RS_OFDM] = RTW89_RATE_OFDM_MAX, ++ [RTW89_RS_MCS] = RTW89_RATE_MCS_MAX, ++ [RTW89_RS_HEDCM] = RTW89_RATE_HEDCM_MAX, ++ [RTW89_RS_OFFSET] = RTW89_RATE_OFFSET_MAX, ++}; ++ ++const u8 rtw89_rs_nss_max[] = { ++ [RTW89_RS_CCK] = 1, ++ [RTW89_RS_OFDM] = 1, ++ [RTW89_RS_MCS] = RTW89_NSS_MAX, ++ [RTW89_RS_HEDCM] = RTW89_NSS_HEDCM_MAX, ++ [RTW89_RS_OFFSET] = 1, ++}; ++ ++static const u8 _byr_of_rs[] = { ++ [RTW89_RS_CCK] = offsetof(struct rtw89_txpwr_byrate, cck), ++ [RTW89_RS_OFDM] = offsetof(struct rtw89_txpwr_byrate, ofdm), ++ [RTW89_RS_MCS] = offsetof(struct rtw89_txpwr_byrate, mcs), ++ [RTW89_RS_HEDCM] = offsetof(struct rtw89_txpwr_byrate, hedcm), ++ [RTW89_RS_OFFSET] = offsetof(struct rtw89_txpwr_byrate, offset), ++}; ++ ++#define _byr_seek(rs, raw) ((s8 *)(raw) + _byr_of_rs[rs]) ++#define _byr_idx(rs, nss, idx) ((nss) * rtw89_rs_idx_max[rs] + (idx)) ++#define _byr_chk(rs, nss, idx) \ ++ ((nss) < rtw89_rs_nss_max[rs] && (idx) < rtw89_rs_idx_max[rs]) ++ ++void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev, ++ const struct rtw89_txpwr_table *tbl) ++{ ++ const struct rtw89_txpwr_byrate_cfg *cfg = tbl->data; ++ const struct rtw89_txpwr_byrate_cfg *end = cfg + tbl->size; ++ s8 *byr; ++ u32 data; ++ u8 i, idx; ++ ++ for (; cfg < end; cfg++) { ++ byr = _byr_seek(cfg->rs, &rtwdev->byr[cfg->band]); ++ data = cfg->data; ++ ++ for (i = 0; i < cfg->len; i++, data >>= 8) { ++ idx = _byr_idx(cfg->rs, cfg->nss, (cfg->shf + i)); ++ byr[idx] = (s8)(data & 0xff); ++ } ++ } ++} ++ ++#define _phy_txpwr_rf_to_mac(rtwdev, txpwr_rf) \ ++({ \ ++ const struct rtw89_chip_info *__c = (rtwdev)->chip; \ ++ (txpwr_rf) >> (__c->txpwr_factor_rf - __c->txpwr_factor_mac); \ ++}) ++ ++s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, ++ const struct rtw89_rate_desc *rate_desc) ++{ ++ enum rtw89_band band = rtwdev->hal.current_band_type; ++ s8 *byr; ++ u8 idx; ++ ++ if (rate_desc->rs == RTW89_RS_CCK) ++ band = RTW89_BAND_2G; ++ ++ if (!_byr_chk(rate_desc->rs, rate_desc->nss, rate_desc->idx)) { ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, ++ "[TXPWR] unknown byrate desc rs=%d nss=%d idx=%d\n", ++ rate_desc->rs, rate_desc->nss, rate_desc->idx); ++ ++ return 0; ++ } ++ ++ byr = _byr_seek(rate_desc->rs, &rtwdev->byr[band]); ++ idx = _byr_idx(rate_desc->rs, rate_desc->nss, rate_desc->idx); ++ ++ return _phy_txpwr_rf_to_mac(rtwdev, byr[idx]); ++} ++ ++static u8 rtw89_channel_to_idx(struct rtw89_dev *rtwdev, u8 channel) ++{ ++ switch (channel) { ++ case 1 ... 14: ++ return channel - 1; ++ case 36 ... 64: ++ return (channel - 36) / 2; ++ case 100 ... 144: ++ return ((channel - 100) / 2) + 15; ++ case 149 ... 177: ++ return ((channel - 149) / 2) + 38; ++ default: ++ rtw89_warn(rtwdev, "unknown channel: %d\n", channel); ++ return 0; ++ } ++} ++ ++s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, ++ u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ u8 ch_idx = rtw89_channel_to_idx(rtwdev, ch); ++ u8 band = rtwdev->hal.current_band_type; ++ u8 regd = rtw89_regd_get(rtwdev, band); ++ s8 lmt = 0, sar; ++ ++ switch (band) { ++ case RTW89_BAND_2G: ++ lmt = (*chip->txpwr_lmt_2g)[bw][ntx][rs][bf][regd][ch_idx]; ++ break; ++ case RTW89_BAND_5G: ++ lmt = (*chip->txpwr_lmt_5g)[bw][ntx][rs][bf][regd][ch_idx]; ++ break; ++ default: ++ rtw89_warn(rtwdev, "unknown band type: %d\n", band); ++ return 0; ++ } ++ ++ lmt = _phy_txpwr_rf_to_mac(rtwdev, lmt); ++ sar = rtw89_query_sar(rtwdev); ++ ++ return min(lmt, sar); ++} ++ ++#define __fill_txpwr_limit_nonbf_bf(ptr, bw, ntx, rs, ch) \ ++ do { \ ++ u8 __i; \ ++ for (__i = 0; __i < RTW89_BF_NUM; __i++) \ ++ ptr[__i] = rtw89_phy_read_txpwr_limit(rtwdev, \ ++ bw, ntx, \ ++ rs, __i, \ ++ (ch)); \ ++ } while (0) ++ ++static void rtw89_phy_fill_txpwr_limit_20m(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit *lmt, ++ u8 ntx, u8 ch) ++{ ++ __fill_txpwr_limit_nonbf_bf(lmt->cck_20m, RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_CCK, ch); ++ __fill_txpwr_limit_nonbf_bf(lmt->cck_40m, RTW89_CHANNEL_WIDTH_40, ++ ntx, RTW89_RS_CCK, ch); ++ __fill_txpwr_limit_nonbf_bf(lmt->ofdm, RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_OFDM, ch); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_MCS, ch); ++} ++ ++static void rtw89_phy_fill_txpwr_limit_40m(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit *lmt, ++ u8 ntx, u8 ch) ++{ ++ __fill_txpwr_limit_nonbf_bf(lmt->cck_20m, RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_CCK, ch - 2); ++ __fill_txpwr_limit_nonbf_bf(lmt->cck_40m, RTW89_CHANNEL_WIDTH_40, ++ ntx, RTW89_RS_CCK, ch); ++ __fill_txpwr_limit_nonbf_bf(lmt->ofdm, RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_OFDM, ch - 2); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_MCS, ch - 2); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_MCS, ch + 2); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], RTW89_CHANNEL_WIDTH_40, ++ ntx, RTW89_RS_MCS, ch); ++} ++ ++static void rtw89_phy_fill_txpwr_limit_80m(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit *lmt, ++ u8 ntx, u8 ch) ++{ ++ s8 val_0p5_n[RTW89_BF_NUM]; ++ s8 val_0p5_p[RTW89_BF_NUM]; ++ u8 i; ++ ++ __fill_txpwr_limit_nonbf_bf(lmt->ofdm, RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_OFDM, ch - 6); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_MCS, ch - 6); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_MCS, ch - 2); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[2], RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_MCS, ch + 2); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[3], RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_MCS, ch + 6); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], RTW89_CHANNEL_WIDTH_40, ++ ntx, RTW89_RS_MCS, ch - 4); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[1], RTW89_CHANNEL_WIDTH_40, ++ ntx, RTW89_RS_MCS, ch + 4); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[0], RTW89_CHANNEL_WIDTH_80, ++ ntx, RTW89_RS_MCS, ch); ++ ++ __fill_txpwr_limit_nonbf_bf(val_0p5_n, RTW89_CHANNEL_WIDTH_40, ++ ntx, RTW89_RS_MCS, ch - 4); ++ __fill_txpwr_limit_nonbf_bf(val_0p5_p, RTW89_CHANNEL_WIDTH_40, ++ ntx, RTW89_RS_MCS, ch + 4); ++ ++ for (i = 0; i < RTW89_BF_NUM; i++) ++ lmt->mcs_40m_0p5[i] = min_t(s8, val_0p5_n[i], val_0p5_p[i]); ++} ++ ++void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit *lmt, ++ u8 ntx) ++{ ++ u8 ch = rtwdev->hal.current_channel; ++ u8 bw = rtwdev->hal.current_band_width; ++ ++ memset(lmt, 0, sizeof(*lmt)); ++ ++ switch (bw) { ++ case RTW89_CHANNEL_WIDTH_20: ++ rtw89_phy_fill_txpwr_limit_20m(rtwdev, lmt, ntx, ch); ++ break; ++ case RTW89_CHANNEL_WIDTH_40: ++ rtw89_phy_fill_txpwr_limit_40m(rtwdev, lmt, ntx, ch); ++ break; ++ case RTW89_CHANNEL_WIDTH_80: ++ rtw89_phy_fill_txpwr_limit_80m(rtwdev, lmt, ntx, ch); ++ break; ++ } ++} ++ ++static s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, ++ u8 ru, u8 ntx, u8 ch) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ u8 ch_idx = rtw89_channel_to_idx(rtwdev, ch); ++ u8 band = rtwdev->hal.current_band_type; ++ u8 regd = rtw89_regd_get(rtwdev, band); ++ s8 lmt_ru = 0, sar; ++ ++ switch (band) { ++ case RTW89_BAND_2G: ++ lmt_ru = (*chip->txpwr_lmt_ru_2g)[ru][ntx][regd][ch_idx]; ++ break; ++ case RTW89_BAND_5G: ++ lmt_ru = (*chip->txpwr_lmt_ru_5g)[ru][ntx][regd][ch_idx]; ++ break; ++ default: ++ rtw89_warn(rtwdev, "unknown band type: %d\n", band); ++ return 0; ++ } ++ ++ lmt_ru = _phy_txpwr_rf_to_mac(rtwdev, lmt_ru); ++ sar = rtw89_query_sar(rtwdev); ++ ++ return min(lmt_ru, sar); ++} ++ ++static void ++rtw89_phy_fill_txpwr_limit_ru_20m(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit_ru *lmt_ru, ++ u8 ntx, u8 ch) ++{ ++ lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, ++ ntx, ch); ++ lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, ++ ntx, ch); ++ lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, ++ ntx, ch); ++} ++ ++static void ++rtw89_phy_fill_txpwr_limit_ru_40m(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit_ru *lmt_ru, ++ u8 ntx, u8 ch) ++{ ++ lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, ++ ntx, ch - 2); ++ lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, ++ ntx, ch + 2); ++ lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, ++ ntx, ch - 2); ++ lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, ++ ntx, ch + 2); ++ lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, ++ ntx, ch - 2); ++ lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, ++ ntx, ch + 2); ++} ++ ++static void ++rtw89_phy_fill_txpwr_limit_ru_80m(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit_ru *lmt_ru, ++ u8 ntx, u8 ch) ++{ ++ lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, ++ ntx, ch - 6); ++ lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, ++ ntx, ch - 2); ++ lmt_ru->ru26[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, ++ ntx, ch + 2); ++ lmt_ru->ru26[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, ++ ntx, ch + 6); ++ lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, ++ ntx, ch - 6); ++ lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, ++ ntx, ch - 2); ++ lmt_ru->ru52[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, ++ ntx, ch + 2); ++ lmt_ru->ru52[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, ++ ntx, ch + 6); ++ lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, ++ ntx, ch - 6); ++ lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, ++ ntx, ch - 2); ++ lmt_ru->ru106[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, ++ ntx, ch + 2); ++ lmt_ru->ru106[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, ++ ntx, ch + 6); ++} ++ ++void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit_ru *lmt_ru, ++ u8 ntx) ++{ ++ u8 ch = rtwdev->hal.current_channel; ++ u8 bw = rtwdev->hal.current_band_width; ++ ++ memset(lmt_ru, 0, sizeof(*lmt_ru)); ++ ++ switch (bw) { ++ case RTW89_CHANNEL_WIDTH_20: ++ rtw89_phy_fill_txpwr_limit_ru_20m(rtwdev, lmt_ru, ntx, ch); ++ break; ++ case RTW89_CHANNEL_WIDTH_40: ++ rtw89_phy_fill_txpwr_limit_ru_40m(rtwdev, lmt_ru, ntx, ch); ++ break; ++ case RTW89_CHANNEL_WIDTH_80: ++ rtw89_phy_fill_txpwr_limit_ru_80m(rtwdev, lmt_ru, ntx, ch); ++ break; ++ } ++} ++ ++struct rtw89_phy_iter_ra_data { ++ struct rtw89_dev *rtwdev; ++ struct sk_buff *c2h; ++}; ++ ++static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) ++{ ++ struct rtw89_phy_iter_ra_data *ra_data = (struct rtw89_phy_iter_ra_data *)data; ++ struct rtw89_dev *rtwdev = ra_data->rtwdev; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_ra_report *ra_report = &rtwsta->ra_report; ++ struct sk_buff *c2h = ra_data->c2h; ++ u8 mode, rate, bw, giltf, mac_id; ++ ++ mac_id = RTW89_GET_PHY_C2H_RA_RPT_MACID(c2h->data); ++ if (mac_id != rtwsta->mac_id) ++ return; ++ ++ memset(ra_report, 0, sizeof(*ra_report)); ++ ++ rate = RTW89_GET_PHY_C2H_RA_RPT_MCSNSS(c2h->data); ++ bw = RTW89_GET_PHY_C2H_RA_RPT_BW(c2h->data); ++ giltf = RTW89_GET_PHY_C2H_RA_RPT_GILTF(c2h->data); ++ mode = RTW89_GET_PHY_C2H_RA_RPT_MD_SEL(c2h->data); ++ ++ switch (mode) { ++ case RTW89_RA_RPT_MODE_LEGACY: ++ ra_report->txrate.legacy = rtw89_ra_report_to_bitrate(rtwdev, rate); ++ break; ++ case RTW89_RA_RPT_MODE_HT: ++ ra_report->txrate.flags |= RATE_INFO_FLAGS_MCS; ++ if (rtwdev->fw.old_ht_ra_format) ++ rate = RTW89_MK_HT_RATE(FIELD_GET(RTW89_RA_RATE_MASK_NSS, rate), ++ FIELD_GET(RTW89_RA_RATE_MASK_MCS, rate)); ++ else ++ rate = FIELD_GET(RTW89_RA_RATE_MASK_HT_MCS, rate); ++ ra_report->txrate.mcs = rate; ++ if (giltf) ++ ra_report->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; ++ break; ++ case RTW89_RA_RPT_MODE_VHT: ++ ra_report->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS; ++ ra_report->txrate.mcs = FIELD_GET(RTW89_RA_RATE_MASK_MCS, rate); ++ ra_report->txrate.nss = FIELD_GET(RTW89_RA_RATE_MASK_NSS, rate) + 1; ++ if (giltf) ++ ra_report->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; ++ break; ++ case RTW89_RA_RPT_MODE_HE: ++ ra_report->txrate.flags |= RATE_INFO_FLAGS_HE_MCS; ++ ra_report->txrate.mcs = FIELD_GET(RTW89_RA_RATE_MASK_MCS, rate); ++ ra_report->txrate.nss = FIELD_GET(RTW89_RA_RATE_MASK_NSS, rate) + 1; ++ if (giltf == RTW89_GILTF_2XHE08 || giltf == RTW89_GILTF_1XHE08) ++ ra_report->txrate.he_gi = NL80211_RATE_INFO_HE_GI_0_8; ++ else if (giltf == RTW89_GILTF_2XHE16 || giltf == RTW89_GILTF_1XHE16) ++ ra_report->txrate.he_gi = NL80211_RATE_INFO_HE_GI_1_6; ++ else ++ ra_report->txrate.he_gi = NL80211_RATE_INFO_HE_GI_3_2; ++ break; ++ } ++ ++ if (bw == RTW89_CHANNEL_WIDTH_80) ++ ra_report->txrate.bw = RATE_INFO_BW_80; ++ else if (bw == RTW89_CHANNEL_WIDTH_40) ++ ra_report->txrate.bw = RATE_INFO_BW_40; ++ else ++ ra_report->txrate.bw = RATE_INFO_BW_20; ++ ++ ra_report->bit_rate = cfg80211_calculate_bitrate(&ra_report->txrate); ++ ra_report->hw_rate = FIELD_PREP(RTW89_HW_RATE_MASK_MOD, mode) | ++ FIELD_PREP(RTW89_HW_RATE_MASK_VAL, rate); ++ sta->max_rc_amsdu_len = get_max_amsdu_len(rtwdev, ra_report); ++ rtwsta->max_agg_wait = sta->max_rc_amsdu_len / 1500 - 1; ++} ++ ++static void ++rtw89_phy_c2h_ra_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) ++{ ++ struct rtw89_phy_iter_ra_data ra_data; ++ ++ ra_data.rtwdev = rtwdev; ++ ra_data.c2h = c2h; ++ ieee80211_iterate_stations_atomic(rtwdev->hw, ++ rtw89_phy_c2h_ra_rpt_iter, ++ &ra_data); ++} ++ ++static ++void (* const rtw89_phy_c2h_ra_handler[])(struct rtw89_dev *rtwdev, ++ struct sk_buff *c2h, u32 len) = { ++ [RTW89_PHY_C2H_FUNC_STS_RPT] = rtw89_phy_c2h_ra_rpt, ++ [RTW89_PHY_C2H_FUNC_MU_GPTBL_RPT] = NULL, ++ [RTW89_PHY_C2H_FUNC_TXSTS] = NULL, ++}; ++ ++void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, ++ u32 len, u8 class, u8 func) ++{ ++ void (*handler)(struct rtw89_dev *rtwdev, ++ struct sk_buff *c2h, u32 len) = NULL; ++ ++ switch (class) { ++ case RTW89_PHY_C2H_CLASS_RA: ++ if (func < RTW89_PHY_C2H_FUNC_RA_MAX) ++ handler = rtw89_phy_c2h_ra_handler[func]; ++ break; ++ default: ++ rtw89_info(rtwdev, "c2h class %d not support\n", class); ++ return; ++ } ++ if (!handler) { ++ rtw89_info(rtwdev, "c2h class %d func %d not support\n", class, ++ func); ++ return; ++ } ++ handler(rtwdev, skb, len); ++} ++ ++static u8 rtw89_phy_cfo_get_xcap_reg(struct rtw89_dev *rtwdev, bool sc_xo) ++{ ++ u32 reg_mask; ++ ++ if (sc_xo) ++ reg_mask = B_AX_XTAL_SC_XO_MASK; ++ else ++ reg_mask = B_AX_XTAL_SC_XI_MASK; ++ ++ return (u8)rtw89_read32_mask(rtwdev, R_AX_XTAL_ON_CTRL0, reg_mask); ++} ++ ++static void rtw89_phy_cfo_set_xcap_reg(struct rtw89_dev *rtwdev, bool sc_xo, ++ u8 val) ++{ ++ u32 reg_mask; ++ ++ if (sc_xo) ++ reg_mask = B_AX_XTAL_SC_XO_MASK; ++ else ++ reg_mask = B_AX_XTAL_SC_XI_MASK; ++ ++ rtw89_write32_mask(rtwdev, R_AX_XTAL_ON_CTRL0, reg_mask, val); ++} ++ ++static void rtw89_phy_cfo_set_crystal_cap(struct rtw89_dev *rtwdev, ++ u8 crystal_cap, bool force) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ u8 sc_xi_val, sc_xo_val; ++ ++ if (!force && cfo->crystal_cap == crystal_cap) ++ return; ++ crystal_cap = clamp_t(u8, crystal_cap, 0, 127); ++ rtw89_phy_cfo_set_xcap_reg(rtwdev, true, crystal_cap); ++ rtw89_phy_cfo_set_xcap_reg(rtwdev, false, crystal_cap); ++ sc_xo_val = rtw89_phy_cfo_get_xcap_reg(rtwdev, true); ++ sc_xi_val = rtw89_phy_cfo_get_xcap_reg(rtwdev, false); ++ cfo->crystal_cap = sc_xi_val; ++ cfo->x_cap_ofst = (s8)((int)cfo->crystal_cap - cfo->def_x_cap); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Set sc_xi=0x%x\n", sc_xi_val); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Set sc_xo=0x%x\n", sc_xo_val); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Get xcap_ofst=%d\n", ++ cfo->x_cap_ofst); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Set xcap OK\n"); ++} ++ ++static void rtw89_phy_cfo_reset(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ u8 cap; ++ ++ cfo->def_x_cap = cfo->crystal_cap_default & B_AX_XTAL_SC_MASK; ++ cfo->is_adjust = false; ++ if (cfo->crystal_cap == cfo->def_x_cap) ++ return; ++ cap = cfo->crystal_cap; ++ cap += (cap > cfo->def_x_cap ? -1 : 1); ++ rtw89_phy_cfo_set_crystal_cap(rtwdev, cap, false); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "(0x%x) approach to dflt_val=(0x%x)\n", cfo->crystal_cap, ++ cfo->def_x_cap); ++} ++ ++static void rtw89_dcfo_comp(struct rtw89_dev *rtwdev, s32 curr_cfo) ++{ ++ bool is_linked = rtwdev->total_sta_assoc > 0; ++ s32 cfo_avg_312; ++ s32 dcfo_comp; ++ int sign; ++ ++ if (!is_linked) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "DCFO: is_linked=%d\n", ++ is_linked); ++ return; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "DCFO: curr_cfo=%d\n", curr_cfo); ++ if (curr_cfo == 0) ++ return; ++ dcfo_comp = rtw89_phy_read32_mask(rtwdev, R_DCFO, B_DCFO); ++ sign = curr_cfo > 0 ? 1 : -1; ++ cfo_avg_312 = (curr_cfo << 3) / 5 + sign * dcfo_comp; ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "DCFO: avg_cfo=%d\n", cfo_avg_312); ++ if (rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv == CHIP_CBV) ++ cfo_avg_312 = -cfo_avg_312; ++ rtw89_phy_set_phy_regs(rtwdev, R_DCFO_COMP_S0, B_DCFO_COMP_S0_MSK, ++ cfo_avg_312); ++} ++ ++static void rtw89_dcfo_comp_init(struct rtw89_dev *rtwdev) ++{ ++ rtw89_phy_set_phy_regs(rtwdev, R_DCFO_OPT, B_DCFO_OPT_EN, 1); ++ rtw89_phy_set_phy_regs(rtwdev, R_DCFO_WEIGHT, B_DCFO_WEIGHT_MSK, 8); ++ rtw89_write32_clr(rtwdev, R_AX_PWR_UL_CTRL2, B_AX_PWR_UL_CFO_MASK); ++} ++ ++static void rtw89_phy_cfo_init(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ struct rtw89_efuse *efuse = &rtwdev->efuse; ++ ++ cfo->crystal_cap_default = efuse->xtal_cap & B_AX_XTAL_SC_MASK; ++ cfo->crystal_cap = cfo->crystal_cap_default; ++ cfo->def_x_cap = cfo->crystal_cap; ++ cfo->is_adjust = false; ++ cfo->x_cap_ofst = 0; ++ cfo->rtw89_multi_cfo_mode = RTW89_TP_BASED_AVG_MODE; ++ cfo->apply_compensation = false; ++ cfo->residual_cfo_acc = 0; ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Default xcap=%0x\n", ++ cfo->crystal_cap_default); ++ rtw89_phy_cfo_set_crystal_cap(rtwdev, cfo->crystal_cap_default, true); ++ rtw89_phy_set_phy_regs(rtwdev, R_DCFO, B_DCFO, 1); ++ rtw89_dcfo_comp_init(rtwdev); ++ cfo->cfo_timer_ms = 2000; ++ cfo->cfo_trig_by_timer_en = false; ++ cfo->phy_cfo_trk_cnt = 0; ++ cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_NORMAL; ++} ++ ++static void rtw89_phy_cfo_crystal_cap_adjust(struct rtw89_dev *rtwdev, ++ s32 curr_cfo) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ s8 crystal_cap = cfo->crystal_cap; ++ s32 cfo_abs = abs(curr_cfo); ++ int sign; ++ ++ if (!cfo->is_adjust) { ++ if (cfo_abs > CFO_TRK_ENABLE_TH) ++ cfo->is_adjust = true; ++ } else { ++ if (cfo_abs < CFO_TRK_STOP_TH) ++ cfo->is_adjust = false; ++ } ++ if (!cfo->is_adjust) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Stop CFO tracking\n"); ++ return; ++ } ++ sign = curr_cfo > 0 ? 1 : -1; ++ if (cfo_abs > CFO_TRK_STOP_TH_4) ++ crystal_cap += 7 * sign; ++ else if (cfo_abs > CFO_TRK_STOP_TH_3) ++ crystal_cap += 5 * sign; ++ else if (cfo_abs > CFO_TRK_STOP_TH_2) ++ crystal_cap += 3 * sign; ++ else if (cfo_abs > CFO_TRK_STOP_TH_1) ++ crystal_cap += 1 * sign; ++ else ++ return; ++ rtw89_phy_cfo_set_crystal_cap(rtwdev, (u8)crystal_cap, false); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "X_cap{Curr,Default}={0x%x,0x%x}\n", ++ cfo->crystal_cap, cfo->def_x_cap); ++} ++ ++static s32 rtw89_phy_average_cfo_calc(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ s32 cfo_khz_all = 0; ++ s32 cfo_cnt_all = 0; ++ s32 cfo_all_avg = 0; ++ u8 i; ++ ++ if (rtwdev->total_sta_assoc != 1) ++ return 0; ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "one_entry_only\n"); ++ for (i = 0; i < CFO_TRACK_MAX_USER; i++) { ++ if (cfo->cfo_cnt[i] == 0) ++ continue; ++ cfo_khz_all += cfo->cfo_tail[i]; ++ cfo_cnt_all += cfo->cfo_cnt[i]; ++ cfo_all_avg = phy_div(cfo_khz_all, cfo_cnt_all); ++ cfo->pre_cfo_avg[i] = cfo->cfo_avg[i]; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "CFO track for macid = %d\n", i); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "Total cfo=%dK, pkt_cnt=%d, avg_cfo=%dK\n", ++ cfo_khz_all, cfo_cnt_all, cfo_all_avg); ++ return cfo_all_avg; ++} ++ ++static s32 rtw89_phy_multi_sta_cfo_calc(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ struct rtw89_traffic_stats *stats = &rtwdev->stats; ++ s32 target_cfo = 0; ++ s32 cfo_khz_all = 0; ++ s32 cfo_khz_all_tp_wgt = 0; ++ s32 cfo_avg = 0; ++ s32 max_cfo_lb = BIT(31); ++ s32 min_cfo_ub = GENMASK(30, 0); ++ u16 cfo_cnt_all = 0; ++ u8 active_entry_cnt = 0; ++ u8 sta_cnt = 0; ++ u32 tp_all = 0; ++ u8 i; ++ u8 cfo_tol = 0; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Multi entry cfo_trk\n"); ++ if (cfo->rtw89_multi_cfo_mode == RTW89_PKT_BASED_AVG_MODE) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Pkt based avg mode\n"); ++ for (i = 0; i < CFO_TRACK_MAX_USER; i++) { ++ if (cfo->cfo_cnt[i] == 0) ++ continue; ++ cfo_khz_all += cfo->cfo_tail[i]; ++ cfo_cnt_all += cfo->cfo_cnt[i]; ++ cfo_avg = phy_div(cfo_khz_all, (s32)cfo_cnt_all); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "Msta cfo=%d, pkt_cnt=%d, avg_cfo=%d\n", ++ cfo_khz_all, cfo_cnt_all, cfo_avg); ++ target_cfo = cfo_avg; ++ } ++ } else if (cfo->rtw89_multi_cfo_mode == RTW89_ENTRY_BASED_AVG_MODE) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Entry based avg mode\n"); ++ for (i = 0; i < CFO_TRACK_MAX_USER; i++) { ++ if (cfo->cfo_cnt[i] == 0) ++ continue; ++ cfo->cfo_avg[i] = phy_div(cfo->cfo_tail[i], ++ (s32)cfo->cfo_cnt[i]); ++ cfo_khz_all += cfo->cfo_avg[i]; ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "Macid=%d, cfo_avg=%d\n", i, ++ cfo->cfo_avg[i]); ++ } ++ sta_cnt = rtwdev->total_sta_assoc; ++ cfo_avg = phy_div(cfo_khz_all, (s32)sta_cnt); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "Msta cfo_acc=%d, ent_cnt=%d, avg_cfo=%d\n", ++ cfo_khz_all, sta_cnt, cfo_avg); ++ target_cfo = cfo_avg; ++ } else if (cfo->rtw89_multi_cfo_mode == RTW89_TP_BASED_AVG_MODE) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "TP based avg mode\n"); ++ cfo_tol = cfo->sta_cfo_tolerance; ++ for (i = 0; i < CFO_TRACK_MAX_USER; i++) { ++ sta_cnt++; ++ if (cfo->cfo_cnt[i] != 0) { ++ cfo->cfo_avg[i] = phy_div(cfo->cfo_tail[i], ++ (s32)cfo->cfo_cnt[i]); ++ active_entry_cnt++; ++ } else { ++ cfo->cfo_avg[i] = cfo->pre_cfo_avg[i]; ++ } ++ max_cfo_lb = max(cfo->cfo_avg[i] - cfo_tol, max_cfo_lb); ++ min_cfo_ub = min(cfo->cfo_avg[i] + cfo_tol, min_cfo_ub); ++ cfo_khz_all += cfo->cfo_avg[i]; ++ /* need tp for each entry */ ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "[%d] cfo_avg=%d, tp=tbd\n", ++ i, cfo->cfo_avg[i]); ++ if (sta_cnt >= rtwdev->total_sta_assoc) ++ break; ++ } ++ tp_all = stats->rx_throughput; /* need tp for each entry */ ++ cfo_avg = phy_div(cfo_khz_all_tp_wgt, (s32)tp_all); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Assoc sta cnt=%d\n", ++ sta_cnt); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Active sta cnt=%d\n", ++ active_entry_cnt); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "Msta cfo with tp_wgt=%d, avg_cfo=%d\n", ++ cfo_khz_all_tp_wgt, cfo_avg); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "cfo_lb=%d,cfo_ub=%d\n", ++ max_cfo_lb, min_cfo_ub); ++ if (max_cfo_lb <= min_cfo_ub) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "cfo win_size=%d\n", ++ min_cfo_ub - max_cfo_lb); ++ target_cfo = clamp(cfo_avg, max_cfo_lb, min_cfo_ub); ++ } else { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "No intersection of cfo torlence windows\n"); ++ target_cfo = phy_div(cfo_khz_all, (s32)sta_cnt); ++ } ++ for (i = 0; i < CFO_TRACK_MAX_USER; i++) ++ cfo->pre_cfo_avg[i] = cfo->cfo_avg[i]; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Target cfo=%d\n", target_cfo); ++ return target_cfo; ++} ++ ++static void rtw89_phy_cfo_statistics_reset(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ ++ memset(&cfo->cfo_tail, 0, sizeof(cfo->cfo_tail)); ++ memset(&cfo->cfo_cnt, 0, sizeof(cfo->cfo_cnt)); ++ cfo->packet_count = 0; ++ cfo->packet_count_pre = 0; ++ cfo->cfo_avg_pre = 0; ++} ++ ++static void rtw89_phy_cfo_dm(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ s32 new_cfo = 0; ++ bool x_cap_update = false; ++ u8 pre_x_cap = cfo->crystal_cap; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "CFO:total_sta_assoc=%d\n", ++ rtwdev->total_sta_assoc); ++ if (rtwdev->total_sta_assoc == 0) { ++ rtw89_phy_cfo_reset(rtwdev); ++ return; ++ } ++ if (cfo->packet_count == 0) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Pkt cnt = 0\n"); ++ return; ++ } ++ if (cfo->packet_count == cfo->packet_count_pre) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Pkt cnt doesn't change\n"); ++ return; ++ } ++ if (rtwdev->total_sta_assoc == 1) ++ new_cfo = rtw89_phy_average_cfo_calc(rtwdev); ++ else ++ new_cfo = rtw89_phy_multi_sta_cfo_calc(rtwdev); ++ if (new_cfo == 0) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "curr_cfo=0\n"); ++ return; ++ } ++ rtw89_phy_cfo_crystal_cap_adjust(rtwdev, new_cfo); ++ cfo->cfo_avg_pre = new_cfo; ++ x_cap_update = cfo->crystal_cap == pre_x_cap ? false : true; ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Xcap_up=%d\n", x_cap_update); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Xcap: D:%x C:%x->%x, ofst=%d\n", ++ cfo->def_x_cap, pre_x_cap, cfo->crystal_cap, ++ cfo->x_cap_ofst); ++ if (x_cap_update) { ++ if (new_cfo > 0) ++ new_cfo -= CFO_SW_COMP_FINE_TUNE; ++ else ++ new_cfo += CFO_SW_COMP_FINE_TUNE; ++ } ++ rtw89_dcfo_comp(rtwdev, new_cfo); ++ rtw89_phy_cfo_statistics_reset(rtwdev); ++} ++ ++void rtw89_phy_cfo_track_work(struct work_struct *work) ++{ ++ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, ++ cfo_track_work.work); ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ ++ mutex_lock(&rtwdev->mutex); ++ if (!cfo->cfo_trig_by_timer_en) ++ goto out; ++ rtw89_leave_ps_mode(rtwdev); ++ rtw89_phy_cfo_dm(rtwdev); ++ ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->cfo_track_work, ++ msecs_to_jiffies(cfo->cfo_timer_ms)); ++out: ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static void rtw89_phy_cfo_start_work(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ ++ ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->cfo_track_work, ++ msecs_to_jiffies(cfo->cfo_timer_ms)); ++} ++ ++void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ struct rtw89_traffic_stats *stats = &rtwdev->stats; ++ ++ switch (cfo->phy_cfo_status) { ++ case RTW89_PHY_DCFO_STATE_NORMAL: ++ if (stats->tx_throughput >= CFO_TP_UPPER) { ++ cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_ENHANCE; ++ cfo->cfo_trig_by_timer_en = true; ++ cfo->cfo_timer_ms = CFO_COMP_PERIOD; ++ rtw89_phy_cfo_start_work(rtwdev); ++ } ++ break; ++ case RTW89_PHY_DCFO_STATE_ENHANCE: ++ if (cfo->phy_cfo_trk_cnt >= CFO_PERIOD_CNT) { ++ cfo->phy_cfo_trk_cnt = 0; ++ cfo->cfo_trig_by_timer_en = false; ++ } ++ if (cfo->cfo_trig_by_timer_en == 1) ++ cfo->phy_cfo_trk_cnt++; ++ if (stats->tx_throughput <= CFO_TP_LOWER) { ++ cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_NORMAL; ++ cfo->phy_cfo_trk_cnt = 0; ++ cfo->cfo_trig_by_timer_en = false; ++ } ++ break; ++ default: ++ cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_NORMAL; ++ cfo->phy_cfo_trk_cnt = 0; ++ break; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "[CFO]WatchDog tp=%d,state=%d,timer_en=%d,trk_cnt=%d,thermal=%ld\n", ++ stats->tx_throughput, cfo->phy_cfo_status, ++ cfo->cfo_trig_by_timer_en, cfo->phy_cfo_trk_cnt, ++ ewma_thermal_read(&rtwdev->phystat.avg_thermal[0])); ++ if (cfo->cfo_trig_by_timer_en) ++ return; ++ rtw89_phy_cfo_dm(rtwdev); ++} ++ ++void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val, ++ struct rtw89_rx_phy_ppdu *phy_ppdu) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ u8 macid = phy_ppdu->mac_id; ++ ++ cfo->cfo_tail[macid] += cfo_val; ++ cfo->cfo_cnt[macid]++; ++ cfo->packet_count++; ++} ++ ++static void rtw89_phy_stat_thermal_update(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_phy_stat *phystat = &rtwdev->phystat; ++ int i; ++ u8 th; ++ ++ for (i = 0; i < rtwdev->chip->rf_path_num; i++) { ++ th = rtw89_chip_get_thermal(rtwdev, i); ++ if (th) ++ ewma_thermal_add(&phystat->avg_thermal[i], th); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, ++ "path(%d) thermal cur=%u avg=%ld", i, th, ++ ewma_thermal_read(&phystat->avg_thermal[i])); ++ } ++} ++ ++struct rtw89_phy_iter_rssi_data { ++ struct rtw89_dev *rtwdev; ++ struct rtw89_phy_ch_info *ch_info; ++ bool rssi_changed; ++}; ++ ++static void rtw89_phy_stat_rssi_update_iter(void *data, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_phy_iter_rssi_data *rssi_data = ++ (struct rtw89_phy_iter_rssi_data *)data; ++ struct rtw89_phy_ch_info *ch_info = rssi_data->ch_info; ++ unsigned long rssi_curr; ++ ++ rssi_curr = ewma_rssi_read(&rtwsta->avg_rssi); ++ ++ if (rssi_curr < ch_info->rssi_min) { ++ ch_info->rssi_min = rssi_curr; ++ ch_info->rssi_min_macid = rtwsta->mac_id; ++ } ++ ++ if (rtwsta->prev_rssi == 0) { ++ rtwsta->prev_rssi = rssi_curr; ++ } else if (abs((int)rtwsta->prev_rssi - (int)rssi_curr) > (3 << RSSI_FACTOR)) { ++ rtwsta->prev_rssi = rssi_curr; ++ rssi_data->rssi_changed = true; ++ } ++} ++ ++static void rtw89_phy_stat_rssi_update(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_phy_iter_rssi_data rssi_data = {0}; ++ ++ rssi_data.rtwdev = rtwdev; ++ rssi_data.ch_info = &rtwdev->ch_info; ++ rssi_data.ch_info->rssi_min = U8_MAX; ++ ieee80211_iterate_stations_atomic(rtwdev->hw, ++ rtw89_phy_stat_rssi_update_iter, ++ &rssi_data); ++ if (rssi_data.rssi_changed) ++ rtw89_btc_ntfy_wl_sta(rtwdev); ++} ++ ++static void rtw89_phy_stat_init(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_phy_stat *phystat = &rtwdev->phystat; ++ int i; ++ ++ for (i = 0; i < rtwdev->chip->rf_path_num; i++) ++ ewma_thermal_init(&phystat->avg_thermal[i]); ++ ++ rtw89_phy_stat_thermal_update(rtwdev); ++ ++ memset(&phystat->cur_pkt_stat, 0, sizeof(phystat->cur_pkt_stat)); ++ memset(&phystat->last_pkt_stat, 0, sizeof(phystat->last_pkt_stat)); ++} ++ ++void rtw89_phy_stat_track(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_phy_stat *phystat = &rtwdev->phystat; ++ ++ rtw89_phy_stat_thermal_update(rtwdev); ++ rtw89_phy_stat_rssi_update(rtwdev); ++ ++ phystat->last_pkt_stat = phystat->cur_pkt_stat; ++ memset(&phystat->cur_pkt_stat, 0, sizeof(phystat->cur_pkt_stat)); ++} ++ ++static u16 rtw89_phy_ccx_us_to_idx(struct rtw89_dev *rtwdev, u32 time_us) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ ++ return time_us >> (ilog2(CCX_US_BASE_RATIO) + env->ccx_unit_idx); ++} ++ ++static u32 rtw89_phy_ccx_idx_to_us(struct rtw89_dev *rtwdev, u16 idx) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ ++ return idx << (ilog2(CCX_US_BASE_RATIO) + env->ccx_unit_idx); ++} ++ ++static void rtw89_phy_ccx_top_setting_init(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ ++ env->ccx_manual_ctrl = false; ++ env->ccx_ongoing = false; ++ env->ccx_rac_lv = RTW89_RAC_RELEASE; ++ env->ccx_rpt_stamp = 0; ++ env->ccx_period = 0; ++ env->ccx_unit_idx = RTW89_CCX_32_US; ++ env->ccx_trigger_time = 0; ++ env->ccx_edcca_opt_bw_idx = RTW89_CCX_EDCCA_BW20_0; ++ ++ rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_CCX_EN_MSK, 1); ++ rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_CCX_TRIG_OPT_MSK, 1); ++ rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_MEASUREMENT_TRIG_MSK, 1); ++ rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_CCX_EDCCA_OPT_MSK, ++ RTW89_CCX_EDCCA_BW20_0); ++} ++ ++static u16 rtw89_phy_ccx_get_report(struct rtw89_dev *rtwdev, u16 report, ++ u16 score) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ u32 numer = 0; ++ u16 ret = 0; ++ ++ numer = report * score + (env->ccx_period >> 1); ++ if (env->ccx_period) ++ ret = numer / env->ccx_period; ++ ++ return ret >= score ? score - 1 : ret; ++} ++ ++static void rtw89_phy_ccx_ms_to_period_unit(struct rtw89_dev *rtwdev, ++ u16 time_ms, u32 *period, ++ u32 *unit_idx) ++{ ++ u32 idx; ++ u8 quotient; ++ ++ if (time_ms >= CCX_MAX_PERIOD) ++ time_ms = CCX_MAX_PERIOD; ++ ++ quotient = CCX_MAX_PERIOD_UNIT * time_ms / CCX_MAX_PERIOD; ++ ++ if (quotient < 4) ++ idx = RTW89_CCX_4_US; ++ else if (quotient < 8) ++ idx = RTW89_CCX_8_US; ++ else if (quotient < 16) ++ idx = RTW89_CCX_16_US; ++ else ++ idx = RTW89_CCX_32_US; ++ ++ *unit_idx = idx; ++ *period = (time_ms * MS_TO_4US_RATIO) >> idx; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "[Trigger Time] period:%d, unit_idx:%d\n", ++ *period, *unit_idx); ++} ++ ++static void rtw89_phy_ccx_racing_release(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "lv:(%d)->(0)\n", env->ccx_rac_lv); ++ ++ env->ccx_ongoing = false; ++ env->ccx_rac_lv = RTW89_RAC_RELEASE; ++ env->ifs_clm_app = RTW89_IFS_CLM_BACKGROUND; ++} ++ ++static bool rtw89_phy_ifs_clm_th_update_check(struct rtw89_dev *rtwdev, ++ struct rtw89_ccx_para_info *para) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ bool is_update = env->ifs_clm_app != para->ifs_clm_app; ++ u8 i = 0; ++ u16 *ifs_th_l = env->ifs_clm_th_l; ++ u16 *ifs_th_h = env->ifs_clm_th_h; ++ u32 ifs_th0_us = 0, ifs_th_times = 0; ++ u32 ifs_th_h_us[RTW89_IFS_CLM_NUM] = {0}; ++ ++ if (!is_update) ++ goto ifs_update_finished; ++ ++ switch (para->ifs_clm_app) { ++ case RTW89_IFS_CLM_INIT: ++ case RTW89_IFS_CLM_BACKGROUND: ++ case RTW89_IFS_CLM_ACS: ++ case RTW89_IFS_CLM_DBG: ++ case RTW89_IFS_CLM_DIG: ++ case RTW89_IFS_CLM_TDMA_DIG: ++ ifs_th0_us = IFS_CLM_TH0_UPPER; ++ ifs_th_times = IFS_CLM_TH_MUL; ++ break; ++ case RTW89_IFS_CLM_DBG_MANUAL: ++ ifs_th0_us = para->ifs_clm_manual_th0; ++ ifs_th_times = para->ifs_clm_manual_th_times; ++ break; ++ default: ++ break; ++ } ++ ++ /* Set sampling threshold for 4 different regions, unit in idx_cnt. ++ * low[i] = high[i-1] + 1 ++ * high[i] = high[i-1] * ifs_th_times ++ */ ++ ifs_th_l[IFS_CLM_TH_START_IDX] = 0; ++ ifs_th_h_us[IFS_CLM_TH_START_IDX] = ifs_th0_us; ++ ifs_th_h[IFS_CLM_TH_START_IDX] = rtw89_phy_ccx_us_to_idx(rtwdev, ++ ifs_th0_us); ++ for (i = 1; i < RTW89_IFS_CLM_NUM; i++) { ++ ifs_th_l[i] = ifs_th_h[i - 1] + 1; ++ ifs_th_h_us[i] = ifs_th_h_us[i - 1] * ifs_th_times; ++ ifs_th_h[i] = rtw89_phy_ccx_us_to_idx(rtwdev, ifs_th_h_us[i]); ++ } ++ ++ifs_update_finished: ++ if (!is_update) ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "No need to update IFS_TH\n"); ++ ++ return is_update; ++} ++ ++static void rtw89_phy_ifs_clm_set_th_reg(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ u8 i = 0; ++ ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T1, B_IFS_T1_TH_LOW_MSK, ++ env->ifs_clm_th_l[0]); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T2, B_IFS_T2_TH_LOW_MSK, ++ env->ifs_clm_th_l[1]); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T3, B_IFS_T3_TH_LOW_MSK, ++ env->ifs_clm_th_l[2]); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T4, B_IFS_T4_TH_LOW_MSK, ++ env->ifs_clm_th_l[3]); ++ ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T1, B_IFS_T1_TH_HIGH_MSK, ++ env->ifs_clm_th_h[0]); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T2, B_IFS_T2_TH_HIGH_MSK, ++ env->ifs_clm_th_h[1]); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T3, B_IFS_T3_TH_HIGH_MSK, ++ env->ifs_clm_th_h[2]); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T4, B_IFS_T4_TH_HIGH_MSK, ++ env->ifs_clm_th_h[3]); ++ ++ for (i = 0; i < RTW89_IFS_CLM_NUM; i++) ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "Update IFS_T%d_th{low, high} : {%d, %d}\n", ++ i + 1, env->ifs_clm_th_l[i], env->ifs_clm_th_h[i]); ++} ++ ++static void rtw89_phy_ifs_clm_setting_init(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ struct rtw89_ccx_para_info para = {0}; ++ ++ env->ifs_clm_app = RTW89_IFS_CLM_BACKGROUND; ++ env->ifs_clm_mntr_time = 0; ++ ++ para.ifs_clm_app = RTW89_IFS_CLM_INIT; ++ if (rtw89_phy_ifs_clm_th_update_check(rtwdev, ¶)) ++ rtw89_phy_ifs_clm_set_th_reg(rtwdev); ++ ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER, B_IFS_COLLECT_EN, ++ true); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T1, B_IFS_T1_EN_MSK, true); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T2, B_IFS_T2_EN_MSK, true); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T3, B_IFS_T3_EN_MSK, true); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T4, B_IFS_T4_EN_MSK, true); ++} ++ ++static int rtw89_phy_ccx_racing_ctrl(struct rtw89_dev *rtwdev, ++ enum rtw89_env_racing_lv level) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ int ret = 0; ++ ++ if (level >= RTW89_RAC_MAX_NUM) { ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "[WARNING] Wrong LV=%d\n", level); ++ return -EINVAL; ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "ccx_ongoing=%d, level:(%d)->(%d)\n", env->ccx_ongoing, ++ env->ccx_rac_lv, level); ++ ++ if (env->ccx_ongoing) { ++ if (level <= env->ccx_rac_lv) ++ ret = -EINVAL; ++ else ++ env->ccx_ongoing = false; ++ } ++ ++ if (ret == 0) ++ env->ccx_rac_lv = level; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "ccx racing success=%d\n", ++ !ret); ++ ++ return ret; ++} ++ ++static void rtw89_phy_ccx_trigger(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER, B_IFS_COUNTER_CLR_MSK, 0); ++ rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_MEASUREMENT_TRIG_MSK, 0); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER, B_IFS_COUNTER_CLR_MSK, 1); ++ rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_MEASUREMENT_TRIG_MSK, 1); ++ ++ env->ccx_rpt_stamp++; ++ env->ccx_ongoing = true; ++} ++ ++static void rtw89_phy_ifs_clm_get_utility(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ u8 i = 0; ++ u32 res = 0; ++ ++ env->ifs_clm_tx_ratio = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_tx, PERCENT); ++ env->ifs_clm_edcca_excl_cca_ratio = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_edcca_excl_cca, ++ PERCENT); ++ env->ifs_clm_cck_fa_ratio = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_cckfa, PERCENT); ++ env->ifs_clm_ofdm_fa_ratio = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_ofdmfa, PERCENT); ++ env->ifs_clm_cck_cca_excl_fa_ratio = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_cckcca_excl_fa, ++ PERCENT); ++ env->ifs_clm_ofdm_cca_excl_fa_ratio = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_ofdmcca_excl_fa, ++ PERCENT); ++ env->ifs_clm_cck_fa_permil = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_cckfa, PERMIL); ++ env->ifs_clm_ofdm_fa_permil = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_ofdmfa, PERMIL); ++ ++ for (i = 0; i < RTW89_IFS_CLM_NUM; i++) { ++ if (env->ifs_clm_his[i] > ENV_MNTR_IFSCLM_HIS_MAX) { ++ env->ifs_clm_ifs_avg[i] = ENV_MNTR_FAIL_DWORD; ++ } else { ++ env->ifs_clm_ifs_avg[i] = ++ rtw89_phy_ccx_idx_to_us(rtwdev, ++ env->ifs_clm_avg[i]); ++ } ++ ++ res = rtw89_phy_ccx_idx_to_us(rtwdev, env->ifs_clm_cca[i]); ++ res += env->ifs_clm_his[i] >> 1; ++ if (env->ifs_clm_his[i]) ++ res /= env->ifs_clm_his[i]; ++ else ++ res = 0; ++ env->ifs_clm_cca_avg[i] = res; ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "IFS-CLM ratio {Tx, EDCCA_exclu_cca} = {%d, %d}\n", ++ env->ifs_clm_tx_ratio, env->ifs_clm_edcca_excl_cca_ratio); ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "IFS-CLM FA ratio {CCK, OFDM} = {%d, %d}\n", ++ env->ifs_clm_cck_fa_ratio, env->ifs_clm_ofdm_fa_ratio); ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "IFS-CLM FA permil {CCK, OFDM} = {%d, %d}\n", ++ env->ifs_clm_cck_fa_permil, env->ifs_clm_ofdm_fa_permil); ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "IFS-CLM CCA_exclu_FA ratio {CCK, OFDM} = {%d, %d}\n", ++ env->ifs_clm_cck_cca_excl_fa_ratio, ++ env->ifs_clm_ofdm_cca_excl_fa_ratio); ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "Time:[his, ifs_avg(us), cca_avg(us)]\n"); ++ for (i = 0; i < RTW89_IFS_CLM_NUM; i++) ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "T%d:[%d, %d, %d]\n", ++ i + 1, env->ifs_clm_his[i], env->ifs_clm_ifs_avg[i], ++ env->ifs_clm_cca_avg[i]); ++} ++ ++static bool rtw89_phy_ifs_clm_get_result(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ u8 i = 0; ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_IFSCNT, B_IFSCNT_DONE_MSK) == 0) { ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "Get IFS_CLM report Fail\n"); ++ return false; ++ } ++ ++ env->ifs_clm_tx = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_TX_CNT, ++ B_IFS_CLM_TX_CNT_MSK); ++ env->ifs_clm_edcca_excl_cca = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_TX_CNT, ++ B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK); ++ env->ifs_clm_cckcca_excl_fa = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_CCA, ++ B_IFS_CLM_CCKCCA_EXCLUDE_FA_MSK); ++ env->ifs_clm_ofdmcca_excl_fa = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_CCA, ++ B_IFS_CLM_OFDMCCA_EXCLUDE_FA_MSK); ++ env->ifs_clm_cckfa = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_FA, ++ B_IFS_CLM_CCK_FA_MSK); ++ env->ifs_clm_ofdmfa = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_FA, ++ B_IFS_CLM_OFDM_FA_MSK); ++ ++ env->ifs_clm_his[0] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_HIS, B_IFS_T1_HIS_MSK); ++ env->ifs_clm_his[1] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_HIS, B_IFS_T2_HIS_MSK); ++ env->ifs_clm_his[2] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_HIS, B_IFS_T3_HIS_MSK); ++ env->ifs_clm_his[3] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_HIS, B_IFS_T4_HIS_MSK); ++ ++ env->ifs_clm_avg[0] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_AVG_L, B_IFS_T1_AVG_MSK); ++ env->ifs_clm_avg[1] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_AVG_L, B_IFS_T2_AVG_MSK); ++ env->ifs_clm_avg[2] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_AVG_H, B_IFS_T3_AVG_MSK); ++ env->ifs_clm_avg[3] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_AVG_H, B_IFS_T4_AVG_MSK); ++ ++ env->ifs_clm_cca[0] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CCA_L, B_IFS_T1_CCA_MSK); ++ env->ifs_clm_cca[1] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CCA_L, B_IFS_T2_CCA_MSK); ++ env->ifs_clm_cca[2] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CCA_H, B_IFS_T3_CCA_MSK); ++ env->ifs_clm_cca[3] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CCA_H, B_IFS_T4_CCA_MSK); ++ ++ env->ifs_clm_total_ifs = ++ rtw89_phy_read32_mask(rtwdev, R_IFSCNT, B_IFSCNT_TOTAL_CNT_MSK); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "IFS-CLM total_ifs = %d\n", ++ env->ifs_clm_total_ifs); ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "{Tx, EDCCA_exclu_cca} = {%d, %d}\n", ++ env->ifs_clm_tx, env->ifs_clm_edcca_excl_cca); ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "IFS-CLM FA{CCK, OFDM} = {%d, %d}\n", ++ env->ifs_clm_cckfa, env->ifs_clm_ofdmfa); ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "IFS-CLM CCA_exclu_FA{CCK, OFDM} = {%d, %d}\n", ++ env->ifs_clm_cckcca_excl_fa, env->ifs_clm_ofdmcca_excl_fa); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "Time:[his, avg, cca]\n"); ++ for (i = 0; i < RTW89_IFS_CLM_NUM; i++) ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "T%d:[%d, %d, %d]\n", i + 1, env->ifs_clm_his[i], ++ env->ifs_clm_avg[i], env->ifs_clm_cca[i]); ++ ++ rtw89_phy_ifs_clm_get_utility(rtwdev); ++ ++ return true; ++} ++ ++static int rtw89_phy_ifs_clm_set(struct rtw89_dev *rtwdev, ++ struct rtw89_ccx_para_info *para) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ u32 period = 0; ++ u32 unit_idx = 0; ++ ++ if (para->mntr_time == 0) { ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "[WARN] MNTR_TIME is 0\n"); ++ return -EINVAL; ++ } ++ ++ if (rtw89_phy_ccx_racing_ctrl(rtwdev, para->rac_lv)) ++ return -EINVAL; ++ ++ if (para->mntr_time != env->ifs_clm_mntr_time) { ++ rtw89_phy_ccx_ms_to_period_unit(rtwdev, para->mntr_time, ++ &period, &unit_idx); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER, ++ B_IFS_CLM_PERIOD_MSK, period); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER, ++ B_IFS_CLM_COUNTER_UNIT_MSK, unit_idx); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "Update IFS-CLM time ((%d)) -> ((%d))\n", ++ env->ifs_clm_mntr_time, para->mntr_time); ++ ++ env->ifs_clm_mntr_time = para->mntr_time; ++ env->ccx_period = (u16)period; ++ env->ccx_unit_idx = (u8)unit_idx; ++ } ++ ++ if (rtw89_phy_ifs_clm_th_update_check(rtwdev, para)) { ++ env->ifs_clm_app = para->ifs_clm_app; ++ rtw89_phy_ifs_clm_set_th_reg(rtwdev); ++ } ++ ++ return 0; ++} ++ ++void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ struct rtw89_ccx_para_info para = {0}; ++ u8 chk_result = RTW89_PHY_ENV_MON_CCX_FAIL; ++ ++ env->ccx_watchdog_result = RTW89_PHY_ENV_MON_CCX_FAIL; ++ if (env->ccx_manual_ctrl) { ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "CCX in manual ctrl\n"); ++ return; ++ } ++ ++ /* only ifs_clm for now */ ++ if (rtw89_phy_ifs_clm_get_result(rtwdev)) ++ env->ccx_watchdog_result |= RTW89_PHY_ENV_MON_IFS_CLM; ++ ++ rtw89_phy_ccx_racing_release(rtwdev); ++ para.mntr_time = 1900; ++ para.rac_lv = RTW89_RAC_LV_1; ++ para.ifs_clm_app = RTW89_IFS_CLM_BACKGROUND; ++ ++ if (rtw89_phy_ifs_clm_set(rtwdev, ¶) == 0) ++ chk_result |= RTW89_PHY_ENV_MON_IFS_CLM; ++ if (chk_result) ++ rtw89_phy_ccx_trigger(rtwdev); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "get_result=0x%x, chk_result:0x%x\n", ++ env->ccx_watchdog_result, chk_result); ++} ++ ++static void rtw89_phy_dig_read_gain_table(struct rtw89_dev *rtwdev, int type) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ const struct rtw89_phy_dig_gain_cfg *cfg; ++ const char *msg; ++ u8 i; ++ s8 gain_base; ++ s8 *gain_arr; ++ u32 tmp; ++ ++ switch (type) { ++ case RTW89_DIG_GAIN_LNA_G: ++ gain_arr = dig->lna_gain_g; ++ gain_base = LNA0_GAIN; ++ cfg = chip->dig_table->cfg_lna_g; ++ msg = "lna_gain_g"; ++ break; ++ case RTW89_DIG_GAIN_TIA_G: ++ gain_arr = dig->tia_gain_g; ++ gain_base = TIA0_GAIN_G; ++ cfg = chip->dig_table->cfg_tia_g; ++ msg = "tia_gain_g"; ++ break; ++ case RTW89_DIG_GAIN_LNA_A: ++ gain_arr = dig->lna_gain_a; ++ gain_base = LNA0_GAIN; ++ cfg = chip->dig_table->cfg_lna_a; ++ msg = "lna_gain_a"; ++ break; ++ case RTW89_DIG_GAIN_TIA_A: ++ gain_arr = dig->tia_gain_a; ++ gain_base = TIA0_GAIN_A; ++ cfg = chip->dig_table->cfg_tia_a; ++ msg = "tia_gain_a"; ++ break; ++ default: ++ return; ++ } ++ ++ for (i = 0; i < cfg->size; i++) { ++ tmp = rtw89_phy_read32_mask(rtwdev, cfg->table[i].addr, ++ cfg->table[i].mask); ++ tmp >>= DIG_GAIN_SHIFT; ++ gain_arr[i] = sign_extend32(tmp, U4_MAX_BIT) + gain_base; ++ gain_base += DIG_GAIN; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "%s[%d]=%d\n", ++ msg, i, gain_arr[i]); ++ } ++} ++ ++static void rtw89_phy_dig_update_gain_para(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ u32 tmp; ++ u8 i; ++ ++ tmp = rtw89_phy_read32_mask(rtwdev, R_PATH0_IB_PKPW, ++ B_PATH0_IB_PKPW_MSK); ++ dig->ib_pkpwr = sign_extend32(tmp >> DIG_GAIN_SHIFT, U8_MAX_BIT); ++ dig->ib_pbk = rtw89_phy_read32_mask(rtwdev, R_PATH0_IB_PBK, ++ B_PATH0_IB_PBK_MSK); ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "ib_pkpwr=%d, ib_pbk=%d\n", ++ dig->ib_pkpwr, dig->ib_pbk); ++ ++ for (i = RTW89_DIG_GAIN_LNA_G; i < RTW89_DIG_GAIN_MAX; i++) ++ rtw89_phy_dig_read_gain_table(rtwdev, i); ++} ++ ++static const u8 rssi_nolink = 22; ++static const u8 igi_rssi_th[IGI_RSSI_TH_NUM] = {68, 84, 90, 98, 104}; ++static const u16 fa_th_2g[FA_TH_NUM] = {22, 44, 66, 88}; ++static const u16 fa_th_5g[FA_TH_NUM] = {4, 8, 12, 16}; ++static const u16 fa_th_nolink[FA_TH_NUM] = {196, 352, 440, 528}; ++ ++static void rtw89_phy_dig_update_rssi_info(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_phy_ch_info *ch_info = &rtwdev->ch_info; ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ bool is_linked = rtwdev->total_sta_assoc > 0; ++ ++ if (is_linked) { ++ dig->igi_rssi = ch_info->rssi_min >> 1; ++ } else { ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "RSSI update : NO Link\n"); ++ dig->igi_rssi = rssi_nolink; ++ } ++} ++ ++static void rtw89_phy_dig_update_para(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ bool is_linked = rtwdev->total_sta_assoc > 0; ++ const u16 *fa_th_src = NULL; ++ ++ switch (rtwdev->hal.current_band_type) { ++ case RTW89_BAND_2G: ++ dig->lna_gain = dig->lna_gain_g; ++ dig->tia_gain = dig->tia_gain_g; ++ fa_th_src = is_linked ? fa_th_2g : fa_th_nolink; ++ dig->force_gaincode_idx_en = false; ++ dig->dyn_pd_th_en = true; ++ break; ++ case RTW89_BAND_5G: ++ default: ++ dig->lna_gain = dig->lna_gain_a; ++ dig->tia_gain = dig->tia_gain_a; ++ fa_th_src = is_linked ? fa_th_5g : fa_th_nolink; ++ dig->force_gaincode_idx_en = true; ++ dig->dyn_pd_th_en = true; ++ break; ++ } ++ memcpy(dig->fa_th, fa_th_src, sizeof(dig->fa_th)); ++ memcpy(dig->igi_rssi_th, igi_rssi_th, sizeof(dig->igi_rssi_th)); ++} ++ ++static const u8 pd_low_th_offset = 20, dynamic_igi_min = 0x20; ++static const u8 igi_max_performance_mode = 0x5a; ++static const u8 dynamic_pd_threshold_max; ++ ++static void rtw89_phy_dig_para_reset(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ ++ dig->cur_gaincode.lna_idx = LNA_IDX_MAX; ++ dig->cur_gaincode.tia_idx = TIA_IDX_MAX; ++ dig->cur_gaincode.rxb_idx = RXB_IDX_MAX; ++ dig->force_gaincode.lna_idx = LNA_IDX_MAX; ++ dig->force_gaincode.tia_idx = TIA_IDX_MAX; ++ dig->force_gaincode.rxb_idx = RXB_IDX_MAX; ++ ++ dig->dyn_igi_max = igi_max_performance_mode; ++ dig->dyn_igi_min = dynamic_igi_min; ++ dig->dyn_pd_th_max = dynamic_pd_threshold_max; ++ dig->pd_low_th_ofst = pd_low_th_offset; ++ dig->is_linked_pre = false; ++} ++ ++static void rtw89_phy_dig_init(struct rtw89_dev *rtwdev) ++{ ++ rtw89_phy_dig_update_gain_para(rtwdev); ++ rtw89_phy_dig_reset(rtwdev); ++} ++ ++static u8 rtw89_phy_dig_lna_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ u8 lna_idx; ++ ++ if (rssi < dig->igi_rssi_th[0]) ++ lna_idx = RTW89_DIG_GAIN_LNA_IDX6; ++ else if (rssi < dig->igi_rssi_th[1]) ++ lna_idx = RTW89_DIG_GAIN_LNA_IDX5; ++ else if (rssi < dig->igi_rssi_th[2]) ++ lna_idx = RTW89_DIG_GAIN_LNA_IDX4; ++ else if (rssi < dig->igi_rssi_th[3]) ++ lna_idx = RTW89_DIG_GAIN_LNA_IDX3; ++ else if (rssi < dig->igi_rssi_th[4]) ++ lna_idx = RTW89_DIG_GAIN_LNA_IDX2; ++ else ++ lna_idx = RTW89_DIG_GAIN_LNA_IDX1; ++ ++ return lna_idx; ++} ++ ++static u8 rtw89_phy_dig_tia_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ u8 tia_idx; ++ ++ if (rssi < dig->igi_rssi_th[0]) ++ tia_idx = RTW89_DIG_GAIN_TIA_IDX1; ++ else ++ tia_idx = RTW89_DIG_GAIN_TIA_IDX0; ++ ++ return tia_idx; ++} ++ ++#define IB_PBK_BASE 110 ++#define WB_RSSI_BASE 10 ++static u8 rtw89_phy_dig_rxb_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi, ++ struct rtw89_agc_gaincode_set *set) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ s8 lna_gain = dig->lna_gain[set->lna_idx]; ++ s8 tia_gain = dig->tia_gain[set->tia_idx]; ++ s32 wb_rssi = rssi + lna_gain + tia_gain; ++ s32 rxb_idx_tmp = IB_PBK_BASE + WB_RSSI_BASE; ++ u8 rxb_idx; ++ ++ rxb_idx_tmp += dig->ib_pkpwr - dig->ib_pbk - wb_rssi; ++ rxb_idx = clamp_t(s32, rxb_idx_tmp, RXB_IDX_MIN, RXB_IDX_MAX); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "wb_rssi=%03d, rxb_idx_tmp=%03d\n", ++ wb_rssi, rxb_idx_tmp); ++ ++ return rxb_idx; ++} ++ ++static void rtw89_phy_dig_gaincode_by_rssi(struct rtw89_dev *rtwdev, u8 rssi, ++ struct rtw89_agc_gaincode_set *set) ++{ ++ set->lna_idx = rtw89_phy_dig_lna_idx_by_rssi(rtwdev, rssi); ++ set->tia_idx = rtw89_phy_dig_tia_idx_by_rssi(rtwdev, rssi); ++ set->rxb_idx = rtw89_phy_dig_rxb_idx_by_rssi(rtwdev, rssi, set); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, ++ "final_rssi=%03d, (lna,tia,rab)=(%d,%d,%02d)\n", ++ rssi, set->lna_idx, set->tia_idx, set->rxb_idx); ++} ++ ++#define IGI_OFFSET_MAX 25 ++#define IGI_OFFSET_MUL 2 ++static void rtw89_phy_dig_igi_offset_by_env(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ enum rtw89_dig_noisy_level noisy_lv; ++ u8 igi_offset = dig->fa_rssi_ofst; ++ u16 fa_ratio = 0; ++ ++ fa_ratio = env->ifs_clm_cck_fa_permil + env->ifs_clm_ofdm_fa_permil; ++ ++ if (fa_ratio < dig->fa_th[0]) ++ noisy_lv = RTW89_DIG_NOISY_LEVEL0; ++ else if (fa_ratio < dig->fa_th[1]) ++ noisy_lv = RTW89_DIG_NOISY_LEVEL1; ++ else if (fa_ratio < dig->fa_th[2]) ++ noisy_lv = RTW89_DIG_NOISY_LEVEL2; ++ else if (fa_ratio < dig->fa_th[3]) ++ noisy_lv = RTW89_DIG_NOISY_LEVEL3; ++ else ++ noisy_lv = RTW89_DIG_NOISY_LEVEL_MAX; ++ ++ if (noisy_lv == RTW89_DIG_NOISY_LEVEL0 && igi_offset < 2) ++ igi_offset = 0; ++ else ++ igi_offset += noisy_lv * IGI_OFFSET_MUL; ++ ++ igi_offset = min_t(u8, igi_offset, IGI_OFFSET_MAX); ++ dig->fa_rssi_ofst = igi_offset; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, ++ "fa_th: [+6 (%d) +4 (%d) +2 (%d) 0 (%d) -2 ]\n", ++ dig->fa_th[3], dig->fa_th[2], dig->fa_th[1], dig->fa_th[0]); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, ++ "fa(CCK,OFDM,ALL)=(%d,%d,%d)%%, noisy_lv=%d, ofst=%d\n", ++ env->ifs_clm_cck_fa_permil, env->ifs_clm_ofdm_fa_permil, ++ env->ifs_clm_cck_fa_permil + env->ifs_clm_ofdm_fa_permil, ++ noisy_lv, igi_offset); ++} ++ ++static void rtw89_phy_dig_set_lna_idx(struct rtw89_dev *rtwdev, u8 lna_idx) ++{ ++ rtw89_phy_write32_mask(rtwdev, R_PATH0_LNA_INIT, ++ B_PATH0_LNA_INIT_IDX_MSK, lna_idx); ++ rtw89_phy_write32_mask(rtwdev, R_PATH1_LNA_INIT, ++ B_PATH1_LNA_INIT_IDX_MSK, lna_idx); ++} ++ ++static void rtw89_phy_dig_set_tia_idx(struct rtw89_dev *rtwdev, u8 tia_idx) ++{ ++ rtw89_phy_write32_mask(rtwdev, R_PATH0_TIA_INIT, ++ B_PATH0_TIA_INIT_IDX_MSK, tia_idx); ++ rtw89_phy_write32_mask(rtwdev, R_PATH1_TIA_INIT, ++ B_PATH1_TIA_INIT_IDX_MSK, tia_idx); ++} ++ ++static void rtw89_phy_dig_set_rxb_idx(struct rtw89_dev *rtwdev, u8 rxb_idx) ++{ ++ rtw89_phy_write32_mask(rtwdev, R_PATH0_RXB_INIT, ++ B_PATH0_RXB_INIT_IDX_MSK, rxb_idx); ++ rtw89_phy_write32_mask(rtwdev, R_PATH1_RXB_INIT, ++ B_PATH1_RXB_INIT_IDX_MSK, rxb_idx); ++} ++ ++static void rtw89_phy_dig_set_igi_cr(struct rtw89_dev *rtwdev, ++ const struct rtw89_agc_gaincode_set set) ++{ ++ rtw89_phy_dig_set_lna_idx(rtwdev, set.lna_idx); ++ rtw89_phy_dig_set_tia_idx(rtwdev, set.tia_idx); ++ rtw89_phy_dig_set_rxb_idx(rtwdev, set.rxb_idx); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "Set (lna,tia,rxb)=((%d,%d,%02d))\n", ++ set.lna_idx, set.tia_idx, set.rxb_idx); ++} ++ ++static const struct rtw89_reg_def sdagc_config[4] = { ++ {R_PATH0_P20_FOLLOW_BY_PAGCUGC, B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, ++ {R_PATH0_S20_FOLLOW_BY_PAGCUGC, B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, ++ {R_PATH1_P20_FOLLOW_BY_PAGCUGC, B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, ++ {R_PATH1_S20_FOLLOW_BY_PAGCUGC, B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, ++}; ++ ++static void rtw89_phy_dig_sdagc_follow_pagc_config(struct rtw89_dev *rtwdev, ++ bool enable) ++{ ++ u8 i = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(sdagc_config); i++) ++ rtw89_phy_write32_mask(rtwdev, sdagc_config[i].addr, ++ sdagc_config[i].mask, enable); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "sdagc_follow_pagc=%d\n", enable); ++} ++ ++static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, u8 rssi, ++ bool enable) ++{ ++ enum rtw89_bandwidth cbw = rtwdev->hal.current_band_width; ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ u8 final_rssi = 0, under_region = dig->pd_low_th_ofst; ++ u32 val = 0; ++ ++ under_region += PD_TH_SB_FLTR_CMP_VAL; ++ ++ switch (cbw) { ++ case RTW89_CHANNEL_WIDTH_40: ++ under_region += PD_TH_BW40_CMP_VAL; ++ break; ++ case RTW89_CHANNEL_WIDTH_80: ++ under_region += PD_TH_BW80_CMP_VAL; ++ break; ++ case RTW89_CHANNEL_WIDTH_20: ++ fallthrough; ++ default: ++ under_region += PD_TH_BW20_CMP_VAL; ++ break; ++ } ++ ++ dig->dyn_pd_th_max = dig->igi_rssi; ++ ++ final_rssi = min_t(u8, rssi, dig->igi_rssi); ++ final_rssi = clamp_t(u8, final_rssi, PD_TH_MIN_RSSI + under_region, ++ PD_TH_MAX_RSSI + under_region); ++ ++ if (enable) { ++ val = (final_rssi - under_region - PD_TH_MIN_RSSI) >> 1; ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, ++ "dyn_max=%d, final_rssi=%d, total=%d, PD_low=%d\n", ++ dig->igi_rssi, final_rssi, under_region, val); ++ } else { ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, ++ "Dynamic PD th dsiabled, Set PD_low_bd=0\n"); ++ } ++ ++ rtw89_phy_write32_mask(rtwdev, R_SEG0R_PD, B_SEG0R_PD_LOWER_BOUND_MSK, ++ val); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0R_PD, ++ B_SEG0R_PD_SPATIAL_REUSE_EN_MSK, enable); ++} ++ ++void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ ++ dig->bypass_dig = false; ++ rtw89_phy_dig_para_reset(rtwdev); ++ rtw89_phy_dig_set_igi_cr(rtwdev, dig->force_gaincode); ++ rtw89_phy_dig_dyn_pd_th(rtwdev, rssi_nolink, false); ++ rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, false); ++ rtw89_phy_dig_update_para(rtwdev); ++} ++ ++#define IGI_RSSI_MIN 10 ++void rtw89_phy_dig(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ bool is_linked = rtwdev->total_sta_assoc > 0; ++ ++ if (unlikely(dig->bypass_dig)) { ++ dig->bypass_dig = false; ++ return; ++ } ++ ++ if (!dig->is_linked_pre && is_linked) { ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "First connected\n"); ++ rtw89_phy_dig_update_para(rtwdev); ++ } else if (dig->is_linked_pre && !is_linked) { ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "First disconnected\n"); ++ rtw89_phy_dig_update_para(rtwdev); ++ } ++ dig->is_linked_pre = is_linked; ++ ++ rtw89_phy_dig_igi_offset_by_env(rtwdev); ++ rtw89_phy_dig_update_rssi_info(rtwdev); ++ ++ dig->dyn_igi_min = (dig->igi_rssi > IGI_RSSI_MIN) ? ++ dig->igi_rssi - IGI_RSSI_MIN : 0; ++ dig->dyn_igi_max = dig->dyn_igi_min + IGI_OFFSET_MAX; ++ dig->igi_fa_rssi = dig->dyn_igi_min + dig->fa_rssi_ofst; ++ ++ dig->igi_fa_rssi = clamp(dig->igi_fa_rssi, dig->dyn_igi_min, ++ dig->dyn_igi_max); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, ++ "rssi=%03d, dyn(max,min)=(%d,%d), final_rssi=%d\n", ++ dig->igi_rssi, dig->dyn_igi_max, dig->dyn_igi_min, ++ dig->igi_fa_rssi); ++ ++ if (dig->force_gaincode_idx_en) { ++ rtw89_phy_dig_set_igi_cr(rtwdev, dig->force_gaincode); ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, ++ "Force gaincode index enabled.\n"); ++ } else { ++ rtw89_phy_dig_gaincode_by_rssi(rtwdev, dig->igi_fa_rssi, ++ &dig->cur_gaincode); ++ rtw89_phy_dig_set_igi_cr(rtwdev, dig->cur_gaincode); ++ } ++ ++ rtw89_phy_dig_dyn_pd_th(rtwdev, dig->igi_fa_rssi, dig->dyn_pd_th_en); ++ ++ if (dig->dyn_pd_th_en && dig->igi_fa_rssi > dig->dyn_pd_th_max) ++ rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, true); ++ else ++ rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, false); ++} ++ ++static void rtw89_phy_env_monitor_init(struct rtw89_dev *rtwdev) ++{ ++ rtw89_phy_ccx_top_setting_init(rtwdev); ++ rtw89_phy_ifs_clm_setting_init(rtwdev); ++} ++ ++void rtw89_phy_dm_init(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ rtw89_phy_stat_init(rtwdev); ++ ++ rtw89_chip_bb_sethw(rtwdev); ++ ++ rtw89_phy_env_monitor_init(rtwdev); ++ rtw89_phy_dig_init(rtwdev); ++ rtw89_phy_cfo_init(rtwdev); ++ ++ rtw89_phy_init_rf_nctl(rtwdev); ++ rtw89_chip_rfk_init(rtwdev); ++ rtw89_load_txpwr_table(rtwdev, chip->byr_table); ++ rtw89_chip_set_txpwr_ctrl(rtwdev); ++ rtw89_chip_power_trim(rtwdev); ++} ++ ++void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) ++{ ++ enum rtw89_phy_idx phy_idx = RTW89_PHY_0; ++ u8 bss_color; ++ ++ if (!vif->bss_conf.he_support || !vif->bss_conf.assoc) ++ return; ++ ++ bss_color = vif->bss_conf.he_bss_color.color; ++ ++ rtw89_phy_write32_idx(rtwdev, R_BSS_CLR_MAP, B_BSS_CLR_MAP_VLD0, 0x1, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_BSS_CLR_MAP, B_BSS_CLR_MAP_TGT, bss_color, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_BSS_CLR_MAP, B_BSS_CLR_MAP_STAID, ++ vif->bss_conf.aid, phy_idx); ++} +diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h +new file mode 100644 +index 000000000000..370129345e0f +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/phy.h +@@ -0,0 +1,311 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_PHY_H__ ++#define __RTW89_PHY_H__ ++ ++#include "core.h" ++ ++#define RTW89_PHY_ADDR_OFFSET 0x10000 ++ ++#define get_phy_headline(addr) FIELD_GET(GENMASK(31, 28), addr) ++#define PHY_HEADLINE_VALID 0xf ++#define get_phy_target(addr) FIELD_GET(GENMASK(27, 0), addr) ++#define get_phy_compare(rfe, cv) (FIELD_PREP(GENMASK(23, 16), rfe) | \ ++ FIELD_PREP(GENMASK(7, 0), cv)) ++ ++#define get_phy_cond(addr) FIELD_GET(GENMASK(31, 28), addr) ++#define get_phy_cond_rfe(addr) FIELD_GET(GENMASK(23, 16), addr) ++#define get_phy_cond_pkg(addr) FIELD_GET(GENMASK(15, 8), addr) ++#define get_phy_cond_cv(addr) FIELD_GET(GENMASK(7, 0), addr) ++#define phy_div(a, b) ({typeof(b) _b = (b); (_b) ? ((a) / (_b)) : 0; }) ++#define PHY_COND_BRANCH_IF 0x8 ++#define PHY_COND_BRANCH_ELIF 0x9 ++#define PHY_COND_BRANCH_ELSE 0xa ++#define PHY_COND_BRANCH_END 0xb ++#define PHY_COND_CHECK 0x4 ++#define PHY_COND_DONT_CARE 0xff ++ ++#define RA_MASK_CCK_RATES GENMASK_ULL(3, 0) ++#define RA_MASK_OFDM_RATES GENMASK_ULL(11, 4) ++#define RA_MASK_SUBCCK_RATES 0x5ULL ++#define RA_MASK_SUBOFDM_RATES 0x10ULL ++#define RA_MASK_HT_1SS_RATES GENMASK_ULL(19, 12) ++#define RA_MASK_HT_2SS_RATES GENMASK_ULL(31, 24) ++#define RA_MASK_HT_3SS_RATES GENMASK_ULL(43, 36) ++#define RA_MASK_HT_4SS_RATES GENMASK_ULL(55, 48) ++#define RA_MASK_HT_RATES GENMASK_ULL(55, 12) ++#define RA_MASK_VHT_1SS_RATES GENMASK_ULL(21, 12) ++#define RA_MASK_VHT_2SS_RATES GENMASK_ULL(33, 24) ++#define RA_MASK_VHT_3SS_RATES GENMASK_ULL(45, 36) ++#define RA_MASK_VHT_4SS_RATES GENMASK_ULL(57, 48) ++#define RA_MASK_VHT_RATES GENMASK_ULL(57, 12) ++#define RA_MASK_HE_1SS_RATES GENMASK_ULL(23, 12) ++#define RA_MASK_HE_2SS_RATES GENMASK_ULL(35, 24) ++#define RA_MASK_HE_3SS_RATES GENMASK_ULL(47, 36) ++#define RA_MASK_HE_4SS_RATES GENMASK_ULL(59, 48) ++#define RA_MASK_HE_RATES GENMASK_ULL(59, 12) ++ ++#define CFO_TRK_ENABLE_TH (2 << 2) ++#define CFO_TRK_STOP_TH_4 (30 << 2) ++#define CFO_TRK_STOP_TH_3 (20 << 2) ++#define CFO_TRK_STOP_TH_2 (10 << 2) ++#define CFO_TRK_STOP_TH_1 (00 << 2) ++#define CFO_TRK_STOP_TH (2 << 2) ++#define CFO_SW_COMP_FINE_TUNE (2 << 2) ++#define CFO_PERIOD_CNT 15 ++#define CFO_TP_UPPER 100 ++#define CFO_TP_LOWER 50 ++#define CFO_COMP_PERIOD 250 ++#define CFO_COMP_WEIGHT 8 ++#define MAX_CFO_TOLERANCE 30 ++ ++#define CCX_MAX_PERIOD 2097 ++#define CCX_MAX_PERIOD_UNIT 32 ++#define MS_TO_4US_RATIO 250 ++#define ENV_MNTR_FAIL_DWORD 0xffffffff ++#define ENV_MNTR_IFSCLM_HIS_MAX 127 ++#define PERMIL 1000 ++#define PERCENT 100 ++#define IFS_CLM_TH0_UPPER 64 ++#define IFS_CLM_TH_MUL 4 ++#define IFS_CLM_TH_START_IDX 0 ++ ++#define TIA0_GAIN_A 12 ++#define TIA0_GAIN_G 16 ++#define LNA0_GAIN (-24) ++#define U4_MAX_BIT 3 ++#define U8_MAX_BIT 7 ++#define DIG_GAIN_SHIFT 2 ++#define DIG_GAIN 8 ++ ++#define LNA_IDX_MAX 6 ++#define LNA_IDX_MIN 0 ++#define TIA_IDX_MAX 1 ++#define TIA_IDX_MIN 0 ++#define RXB_IDX_MAX 31 ++#define RXB_IDX_MIN 0 ++ ++#define PD_TH_MAX_RSSI 70 ++#define PD_TH_MIN_RSSI 8 ++#define PD_TH_BW80_CMP_VAL 6 ++#define PD_TH_BW40_CMP_VAL 3 ++#define PD_TH_BW20_CMP_VAL 0 ++#define PD_TH_CMP_VAL 3 ++#define PD_TH_SB_FLTR_CMP_VAL 7 ++ ++#define PHYSTS_MGNT BIT(RTW89_RX_TYPE_MGNT) ++#define PHYSTS_CTRL BIT(RTW89_RX_TYPE_CTRL) ++#define PHYSTS_DATA BIT(RTW89_RX_TYPE_DATA) ++#define PHYSTS_RSVD BIT(RTW89_RX_TYPE_RSVD) ++#define PPDU_FILTER_BITMAP (PHYSTS_MGNT | PHYSTS_DATA) ++ ++enum rtw89_phy_c2h_ra_func { ++ RTW89_PHY_C2H_FUNC_STS_RPT, ++ RTW89_PHY_C2H_FUNC_MU_GPTBL_RPT, ++ RTW89_PHY_C2H_FUNC_TXSTS, ++ RTW89_PHY_C2H_FUNC_RA_MAX, ++}; ++ ++enum rtw89_phy_c2h_class { ++ RTW89_PHY_C2H_CLASS_RUA, ++ RTW89_PHY_C2H_CLASS_RA, ++ RTW89_PHY_C2H_CLASS_DM, ++ RTW89_PHY_C2H_CLASS_BTC_MIN = 0x10, ++ RTW89_PHY_C2H_CLASS_BTC_MAX = 0x17, ++ RTW89_PHY_C2H_CLASS_MAX, ++}; ++ ++enum rtw89_env_monitor_result_level { ++ RTW89_PHY_ENV_MON_CCX_FAIL = 0, ++ RTW89_PHY_ENV_MON_NHM = BIT(0), ++ RTW89_PHY_ENV_MON_CLM = BIT(1), ++ RTW89_PHY_ENV_MON_FAHM = BIT(2), ++ RTW89_PHY_ENV_MON_IFS_CLM = BIT(3), ++ RTW89_PHY_ENV_MON_EDCCA_CLM = BIT(4), ++}; ++ ++#define CCX_US_BASE_RATIO 4 ++enum rtw89_ccx_unit { ++ RTW89_CCX_4_US = 0, ++ RTW89_CCX_8_US = 1, ++ RTW89_CCX_16_US = 2, ++ RTW89_CCX_32_US = 3 ++}; ++ ++enum rtw89_dig_gain_type { ++ RTW89_DIG_GAIN_LNA_G = 0, ++ RTW89_DIG_GAIN_TIA_G = 1, ++ RTW89_DIG_GAIN_LNA_A = 2, ++ RTW89_DIG_GAIN_TIA_A = 3, ++ RTW89_DIG_GAIN_MAX = 4 ++}; ++ ++enum rtw89_dig_gain_lna_idx { ++ RTW89_DIG_GAIN_LNA_IDX1 = 1, ++ RTW89_DIG_GAIN_LNA_IDX2 = 2, ++ RTW89_DIG_GAIN_LNA_IDX3 = 3, ++ RTW89_DIG_GAIN_LNA_IDX4 = 4, ++ RTW89_DIG_GAIN_LNA_IDX5 = 5, ++ RTW89_DIG_GAIN_LNA_IDX6 = 6 ++}; ++ ++enum rtw89_dig_gain_tia_idx { ++ RTW89_DIG_GAIN_TIA_IDX0 = 0, ++ RTW89_DIG_GAIN_TIA_IDX1 = 1 ++}; ++ ++struct rtw89_txpwr_byrate_cfg { ++ enum rtw89_band band; ++ enum rtw89_nss nss; ++ enum rtw89_rate_section rs; ++ u8 shf; ++ u8 len; ++ u32 data; ++}; ++ ++#define DELTA_SWINGIDX_SIZE 30 ++ ++struct rtw89_txpwr_track_cfg { ++ const u8 (*delta_swingidx_5gb_n)[DELTA_SWINGIDX_SIZE]; ++ const u8 (*delta_swingidx_5gb_p)[DELTA_SWINGIDX_SIZE]; ++ const u8 (*delta_swingidx_5ga_n)[DELTA_SWINGIDX_SIZE]; ++ const u8 (*delta_swingidx_5ga_p)[DELTA_SWINGIDX_SIZE]; ++ const u8 *delta_swingidx_2gb_n; ++ const u8 *delta_swingidx_2gb_p; ++ const u8 *delta_swingidx_2ga_n; ++ const u8 *delta_swingidx_2ga_p; ++ const u8 *delta_swingidx_2g_cck_b_n; ++ const u8 *delta_swingidx_2g_cck_b_p; ++ const u8 *delta_swingidx_2g_cck_a_n; ++ const u8 *delta_swingidx_2g_cck_a_p; ++}; ++ ++struct rtw89_phy_dig_gain_cfg { ++ const struct rtw89_reg_def *table; ++ u8 size; ++}; ++ ++struct rtw89_phy_dig_gain_table { ++ const struct rtw89_phy_dig_gain_cfg *cfg_lna_g; ++ const struct rtw89_phy_dig_gain_cfg *cfg_tia_g; ++ const struct rtw89_phy_dig_gain_cfg *cfg_lna_a; ++ const struct rtw89_phy_dig_gain_cfg *cfg_tia_a; ++}; ++ ++struct rtw89_phy_reg3_tbl { ++ const struct rtw89_reg3_def *reg3; ++ int size; ++}; ++ ++#define DECLARE_PHY_REG3_TBL(_name) \ ++const struct rtw89_phy_reg3_tbl _name ## _tbl = { \ ++ .reg3 = _name, \ ++ .size = ARRAY_SIZE(_name), \ ++} ++ ++static inline void rtw89_phy_write8(struct rtw89_dev *rtwdev, ++ u32 addr, u8 data) ++{ ++ rtw89_write8(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, data); ++} ++ ++static inline void rtw89_phy_write16(struct rtw89_dev *rtwdev, ++ u32 addr, u16 data) ++{ ++ rtw89_write16(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, data); ++} ++ ++static inline void rtw89_phy_write32(struct rtw89_dev *rtwdev, ++ u32 addr, u32 data) ++{ ++ rtw89_write32(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, data); ++} ++ ++static inline void rtw89_phy_write32_set(struct rtw89_dev *rtwdev, ++ u32 addr, u32 bits) ++{ ++ rtw89_write32_set(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, bits); ++} ++ ++static inline void rtw89_phy_write32_clr(struct rtw89_dev *rtwdev, ++ u32 addr, u32 bits) ++{ ++ rtw89_write32_clr(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, bits); ++} ++ ++static inline void rtw89_phy_write32_mask(struct rtw89_dev *rtwdev, ++ u32 addr, u32 mask, u32 data) ++{ ++ rtw89_write32_mask(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, mask, data); ++} ++ ++static inline u8 rtw89_phy_read8(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ return rtw89_read8(rtwdev, addr | RTW89_PHY_ADDR_OFFSET); ++} ++ ++static inline u16 rtw89_phy_read16(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ return rtw89_read16(rtwdev, addr | RTW89_PHY_ADDR_OFFSET); ++} ++ ++static inline u32 rtw89_phy_read32(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ return rtw89_read32(rtwdev, addr | RTW89_PHY_ADDR_OFFSET); ++} ++ ++static inline u32 rtw89_phy_read32_mask(struct rtw89_dev *rtwdev, ++ u32 addr, u32 mask) ++{ ++ return rtw89_read32_mask(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, mask); ++} ++ ++void rtw89_phy_write_reg3_tbl(struct rtw89_dev *rtwdev, ++ const struct rtw89_phy_reg3_tbl *tbl); ++u8 rtw89_phy_get_txsc(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_params *param, ++ enum rtw89_bandwidth dbw); ++u32 rtw89_phy_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask); ++bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask, u32 data); ++void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev); ++void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev); ++void rtw89_phy_dm_init(struct rtw89_dev *rtwdev); ++void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, ++ u32 data, enum rtw89_phy_idx phy_idx); ++void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev, ++ const struct rtw89_txpwr_table *tbl); ++s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, ++ const struct rtw89_rate_desc *rate_desc); ++void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit *lmt, ++ u8 ntx); ++void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit_ru *lmt_ru, ++ u8 ntx); ++s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, ++ u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch); ++void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta); ++void rtw89_phy_ra_update(struct rtw89_dev *rtwdev); ++void rtw89_phy_ra_updata_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta); ++void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ const struct cfg80211_bitrate_mask *mask); ++void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, ++ u32 len, u8 class, u8 func); ++void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev); ++void rtw89_phy_cfo_track_work(struct work_struct *work); ++void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val, ++ struct rtw89_rx_phy_ppdu *phy_ppdu); ++void rtw89_phy_stat_track(struct rtw89_dev *rtwdev); ++void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev); ++void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask, ++ u32 val); ++void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev); ++void rtw89_phy_dig(struct rtw89_dev *rtwdev); ++void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c +new file mode 100644 +index 000000000000..7eaa01e41ef2 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/ps.c +@@ -0,0 +1,150 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "coex.h" ++#include "core.h" ++#include "debug.h" ++#include "fw.h" ++#include "mac.h" ++#include "ps.h" ++#include "reg.h" ++#include "util.h" ++ ++static int rtw89_fw_leave_lps_check(struct rtw89_dev *rtwdev, u8 macid) ++{ ++ u32 pwr_en_bit = 0xE; ++ u32 chk_msk = pwr_en_bit << (4 * macid); ++ u32 polling; ++ int ret; ++ ++ ret = read_poll_timeout_atomic(rtw89_read32_mask, polling, !polling, ++ 1000, 50000, false, rtwdev, ++ R_AX_PPWRBIT_SETTING, chk_msk); ++ if (ret) { ++ rtw89_info(rtwdev, "rtw89: failed to leave lps state\n"); ++ return -EBUSY; ++ } ++ ++ return 0; ++} ++ ++static void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev) ++{ ++ if (!rtwdev->ps_mode) ++ return; ++ ++ if (test_and_set_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags)) ++ return; ++ ++ rtw89_mac_power_mode_change(rtwdev, true); ++} ++ ++void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev) ++{ ++ if (!rtwdev->ps_mode) ++ return; ++ ++ if (test_and_clear_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags)) ++ rtw89_mac_power_mode_change(rtwdev, false); ++} ++ ++static void __rtw89_enter_lps(struct rtw89_dev *rtwdev, u8 mac_id) ++{ ++ struct rtw89_lps_parm lps_param = { ++ .macid = mac_id, ++ .psmode = RTW89_MAC_AX_PS_MODE_LEGACY, ++ .lastrpwm = RTW89_LAST_RPWM_PS, ++ }; ++ ++ rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_FW_CTRL); ++ rtw89_fw_h2c_lps_parm(rtwdev, &lps_param); ++} ++ ++static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, u8 mac_id) ++{ ++ struct rtw89_lps_parm lps_param = { ++ .macid = mac_id, ++ .psmode = RTW89_MAC_AX_PS_MODE_ACTIVE, ++ .lastrpwm = RTW89_LAST_RPWM_ACTIVE, ++ }; ++ ++ rtw89_fw_h2c_lps_parm(rtwdev, &lps_param); ++ rtw89_fw_leave_lps_check(rtwdev, 0); ++ rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_ON); ++} ++ ++void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev) ++{ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ __rtw89_leave_ps_mode(rtwdev); ++} ++ ++void rtw89_enter_lps(struct rtw89_dev *rtwdev, u8 mac_id) ++{ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ if (test_and_set_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags)) ++ return; ++ ++ __rtw89_enter_lps(rtwdev, mac_id); ++ __rtw89_enter_ps_mode(rtwdev); ++} ++ ++static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION) ++ return; ++ ++ __rtw89_leave_ps_mode(rtwdev); ++ __rtw89_leave_lps(rtwdev, rtwvif->mac_id); ++} ++ ++void rtw89_leave_lps(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_vif *rtwvif; ++ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ if (!test_and_clear_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags)) ++ return; ++ ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ rtw89_leave_lps_vif(rtwdev, rtwvif); ++} ++ ++void rtw89_enter_ips(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_vif *rtwvif; ++ ++ set_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags); ++ ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ rtw89_mac_vif_deinit(rtwdev, rtwvif); ++ ++ rtw89_core_stop(rtwdev); ++} ++ ++void rtw89_leave_ips(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_vif *rtwvif; ++ int ret; ++ ++ ret = rtw89_core_start(rtwdev); ++ if (ret) ++ rtw89_err(rtwdev, "failed to leave idle state\n"); ++ ++ rtw89_set_channel(rtwdev); ++ ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ rtw89_mac_vif_init(rtwdev, rtwvif); ++ ++ clear_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags); ++} ++ ++void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl) ++{ ++ if (btc_ctrl) ++ rtw89_leave_lps(rtwdev); ++} +diff --git a/drivers/net/wireless/realtek/rtw89/ps.h b/drivers/net/wireless/realtek/rtw89/ps.h +new file mode 100644 +index 000000000000..a184b68994aa +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/ps.h +@@ -0,0 +1,16 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_PS_H_ ++#define __RTW89_PS_H_ ++ ++void rtw89_enter_lps(struct rtw89_dev *rtwdev, u8 mac_id); ++void rtw89_leave_lps(struct rtw89_dev *rtwdev); ++void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev); ++void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev); ++void rtw89_enter_ips(struct rtw89_dev *rtwdev); ++void rtw89_leave_ips(struct rtw89_dev *rtwdev); ++void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +new file mode 100644 +index 000000000000..365d8c8ce57b +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -0,0 +1,2159 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_REG_H__ ++#define __RTW89_REG_H__ ++ ++#define R_AX_SYS_WL_EFUSE_CTRL 0x000A ++#define B_AX_AUTOLOAD_SUS BIT(5) ++ ++#define R_AX_SYS_FUNC_EN 0x0002 ++#define B_AX_FEN_BB_GLB_RSTN BIT(1) ++#define B_AX_FEN_BBRSTB BIT(0) ++ ++#define R_AX_SYS_PW_CTRL 0x0004 ++#define B_AX_PSUS_OFF_CAPC_EN BIT(14) ++ ++#define R_AX_SYS_CLK_CTRL 0x0008 ++#define B_AX_CPU_CLK_EN BIT(14) ++ ++#define R_AX_RSV_CTRL 0x001C ++#define B_AX_R_DIS_PRST BIT(6) ++#define B_AX_WLOCK_1C_BIT6 BIT(5) ++ ++#define R_AX_EFUSE_CTRL_1 0x0038 ++#define B_AX_EF_PGPD_MASK GENMASK(30, 28) ++#define B_AX_EF_RDT BIT(27) ++#define B_AX_EF_VDDQST_MASK GENMASK(26, 24) ++#define B_AX_EF_PGTS_MASK GENMASK(23, 20) ++#define B_AX_EF_PD_DIS BIT(11) ++#define B_AX_EF_POR BIT(10) ++#define B_AX_EF_CELL_SEL_MASK GENMASK(9, 8) ++ ++#define R_AX_SPSLDO_ON_CTRL0 0x0200 ++#define B_AX_OCP_L1_MASK GENMASK(15, 13) ++ ++#define R_AX_EFUSE_CTRL 0x0030 ++#define B_AX_EF_MODE_SEL_MASK GENMASK(31, 30) ++#define B_AX_EF_RDY BIT(29) ++#define B_AX_EF_COMP_RESULT BIT(28) ++#define B_AX_EF_ADDR_MASK GENMASK(26, 16) ++#define B_AX_EF_DATA_MASK GENMASK(15, 0) ++ ++#define R_AX_GPIO_MUXCFG 0x0040 ++#define B_AX_BOOT_MODE BIT(19) ++#define B_AX_WL_EECS_EXT_32K_SEL BIT(18) ++#define B_AX_WL_SEC_BONDING_OPT_STS BIT(17) ++#define B_AX_SECSIC_SEL BIT(16) ++#define B_AX_ENHTP BIT(14) ++#define B_AX_BT_AOD_GPIO3 BIT(13) ++#define B_AX_ENSIC BIT(12) ++#define B_AX_SIC_SWRST BIT(11) ++#define B_AX_PO_WIFI_PTA_PINS BIT(10) ++#define B_AX_PO_BT_PTA_PINS BIT(9) ++#define B_AX_ENUARTTX BIT(8) ++#define B_AX_BTMODE_MASK GENMASK(7, 6) ++#define MAC_AX_BT_MODE_0_3 0 ++#define MAC_AX_BT_MODE_2 2 ++#define B_AX_ENBT BIT(5) ++#define B_AX_EROM_EN BIT(4) ++#define B_AX_ENUARTRX BIT(2) ++#define B_AX_GPIOSEL_MASK GENMASK(1, 0) ++ ++#define R_AX_DBG_CTRL 0x0058 ++#define B_AX_DBG_SEL1_4BIT GENMASK(31, 30) ++#define B_AX_DBG_SEL1_16BIT BIT(27) ++#define B_AX_DBG_SEL1 GENMASK(23, 16) ++#define B_AX_DBG_SEL0_4BIT GENMASK(15, 14) ++#define B_AX_DBG_SEL0_16BIT BIT(11) ++#define B_AX_DBG_SEL0 GENMASK(7, 0) ++ ++#define R_AX_SYS_SDIO_CTRL 0x0070 ++#define B_AX_PCIE_DIS_L2_CTRL_LDO_HCI BIT(15) ++#define B_AX_PCIE_DIS_WLSUS_AFT_PDN BIT(14) ++#define B_AX_PCIE_AUXCLK_GATE BIT(11) ++#define B_AX_LTE_MUX_CTRL_PATH BIT(26) ++ ++#define R_AX_PLATFORM_ENABLE 0x0088 ++#define B_AX_WCPU_EN BIT(1) ++ ++#define R_AX_SCOREBOARD 0x00AC ++#define B_AX_TOGGLE BIT(31) ++#define B_MAC_AX_SB_FW_MASK GENMASK(30, 24) ++#define B_MAC_AX_SB_DRV_MASK GENMASK(23, 0) ++#define B_MAC_AX_BTGS1_NOTIFY BIT(0) ++#define MAC_AX_NOTIFY_TP_MAJOR 0x81 ++#define MAC_AX_NOTIFY_PWR_MAJOR 0x80 ++ ++#define R_AX_DBG_PORT_SEL 0x00C0 ++#define B_AX_DEBUG_ST_MASK GENMASK(31, 0) ++ ++#define R_AX_SYS_CFG1 0x00F0 ++#define B_AX_CHIP_VER_MASK GENMASK(15, 12) ++ ++#define R_AX_SYS_STATUS1 0x00F4 ++#define B_AX_SEL_0XC0_MASK GENMASK(17, 16) ++ ++#define R_AX_HALT_H2C_CTRL 0x0160 ++#define R_AX_HALT_H2C 0x0168 ++#define B_AX_HALT_H2C_TRIGGER BIT(0) ++#define R_AX_HALT_C2H_CTRL 0x0164 ++#define R_AX_HALT_C2H 0x016C ++ ++#define R_AX_WCPU_FW_CTRL 0x01E0 ++#define B_AX_WCPU_FWDL_STS_MASK GENMASK(7, 5) ++#define B_AX_FWDL_PATH_RDY BIT(2) ++#define B_AX_H2C_PATH_RDY BIT(1) ++#define B_AX_WCPU_FWDL_EN BIT(0) ++ ++#define R_AX_RPWM 0x01E4 ++#define R_AX_PCIE_HRPWM 0x10C0 ++#define PS_RPWM_TOGGLE BIT(15) ++#define PS_RPWM_ACK BIT(14) ++#define PS_RPWM_SEQ_NUM GENMASK(13, 12) ++#define PS_RPWM_STATE 0x7 ++#define RPWM_SEQ_NUM_MAX 3 ++#define PS_CPWM_SEQ_NUM GENMASK(13, 12) ++#define PS_CPWM_RSP_SEQ_NUM GENMASK(9, 8) ++#define PS_CPWM_STATE GENMASK(2, 0) ++#define CPWM_SEQ_NUM_MAX 3 ++ ++#define R_AX_BOOT_REASON 0x01E6 ++#define B_AX_BOOT_REASON_MASK GENMASK(2, 0) ++ ++#define R_AX_LDM 0x01E8 ++#define B_AX_EN_32K BIT(31) ++ ++#define R_AX_UDM0 0x01F0 ++#define R_AX_UDM1 0x01F4 ++#define R_AX_UDM2 0x01F8 ++#define R_AX_UDM3 0x01FC ++ ++#define R_AX_XTAL_ON_CTRL0 0x0280 ++#define B_AX_XTAL_SC_LPS BIT(31) ++#define B_AX_XTAL_SC_XO_MASK GENMASK(23, 17) ++#define B_AX_XTAL_SC_XI_MASK GENMASK(16, 10) ++#define B_AX_XTAL_SC_MASK GENMASK(6, 0) ++ ++#define R_AX_GPIO0_7_FUNC_SEL 0x02D0 ++ ++#define R_AX_WLRF_CTRL 0x02F0 ++#define B_AX_WLRF1_CTRL_7 BIT(15) ++#define B_AX_WLRF1_CTRL_1 BIT(9) ++#define B_AX_WLRF_CTRL_7 BIT(7) ++#define B_AX_WLRF_CTRL_1 BIT(1) ++ ++#define R_AX_IC_PWR_STATE 0x03F0 ++#define B_AX_WHOLE_SYS_PWR_STE_MASK GENMASK(25, 16) ++#define B_AX_WLMAC_PWR_STE_MASK GENMASK(9, 8) ++#define B_AX_UART_HCISYS_PWR_STE_MASK GENMASK(7, 6) ++#define B_AX_SDIO_HCISYS_PWR_STE_MASK GENMASK(5, 4) ++#define B_AX_USB_HCISYS_PWR_STE_MASK GENMASK(3, 2) ++#define B_AX_PCIE_HCISYS_PWR_STE_MASK GENMASK(1, 0) ++ ++#define R_AX_FILTER_MODEL_ADDR 0x0C04 ++ ++#define R_AX_PCIE_DBG_CTRL 0x11C0 ++#define B_AX_DBG_DUMMY_MASK GENMASK(23, 16) ++#define B_AX_DBG_SEL_MASK GENMASK(15, 13) ++#define B_AX_PCIE_DBG_SEL BIT(12) ++#define B_AX_MRD_TIMEOUT_EN BIT(10) ++#define B_AX_ASFF_FULL_NO_STK BIT(1) ++#define B_AX_EN_STUCK_DBG BIT(0) ++ ++#define R_AX_PHYREG_SET 0x8040 ++#define PHYREG_SET_ALL_CYCLE 0x8 ++ ++#define R_AX_HD0IMR 0x8110 ++#define B_AX_WDT_PTFM_INT_EN BIT(5) ++#define B_AX_CPWM_INT_EN BIT(2) ++#define B_AX_GT3_INT_EN BIT(1) ++#define B_AX_C2H_INT_EN BIT(0) ++#define R_AX_HD0ISR 0x8114 ++#define B_AX_C2H_INT BIT(0) ++ ++#define R_AX_H2CREG_DATA0 0x8140 ++#define R_AX_H2CREG_DATA1 0x8144 ++#define R_AX_H2CREG_DATA2 0x8148 ++#define R_AX_H2CREG_DATA3 0x814C ++#define R_AX_C2HREG_DATA0 0x8150 ++#define R_AX_C2HREG_DATA1 0x8154 ++#define R_AX_C2HREG_DATA2 0x8158 ++#define R_AX_C2HREG_DATA3 0x815C ++#define R_AX_H2CREG_CTRL 0x8160 ++#define B_AX_H2CREG_TRIGGER BIT(0) ++#define R_AX_C2HREG_CTRL 0x8164 ++#define B_AX_C2HREG_TRIGGER BIT(0) ++#define R_AX_CPWM 0x8170 ++ ++#define R_AX_HCI_FUNC_EN 0x8380 ++#define B_AX_HCI_RXDMA_EN BIT(1) ++#define B_AX_HCI_TXDMA_EN BIT(0) ++ ++#define R_AX_BOOT_DBG 0x83F0 ++ ++#define R_AX_DMAC_FUNC_EN 0x8400 ++#define B_AX_MAC_FUNC_EN BIT(30) ++#define B_AX_DMAC_FUNC_EN BIT(29) ++#define B_AX_MPDU_PROC_EN BIT(28) ++#define B_AX_WD_RLS_EN BIT(27) ++#define B_AX_DLE_WDE_EN BIT(26) ++#define B_AX_TXPKT_CTRL_EN BIT(25) ++#define B_AX_STA_SCH_EN BIT(24) ++#define B_AX_DLE_PLE_EN BIT(23) ++#define B_AX_PKT_BUF_EN BIT(22) ++#define B_AX_DMAC_TBL_EN BIT(21) ++#define B_AX_PKT_IN_EN BIT(20) ++#define B_AX_DLE_CPUIO_EN BIT(19) ++#define B_AX_DISPATCHER_EN BIT(18) ++#define B_AX_MAC_SEC_EN BIT(16) ++ ++#define R_AX_DMAC_CLK_EN 0x8404 ++#define B_AX_WD_RLS_CLK_EN BIT(27) ++#define B_AX_DLE_WDE_CLK_EN BIT(26) ++#define B_AX_TXPKT_CTRL_CLK_EN BIT(25) ++#define B_AX_STA_SCH_CLK_EN BIT(24) ++#define B_AX_DLE_PLE_CLK_EN BIT(23) ++#define B_AX_PKT_IN_CLK_EN BIT(20) ++#define B_AX_DLE_CPUIO_CLK_EN BIT(19) ++#define B_AX_DISPATCHER_CLK_EN BIT(18) ++#define B_AX_MAC_SEC_CLK_EN BIT(16) ++ ++#define PCI_LTR_IDLE_TIMER_1US 0 ++#define PCI_LTR_IDLE_TIMER_10US 1 ++#define PCI_LTR_IDLE_TIMER_100US 2 ++#define PCI_LTR_IDLE_TIMER_200US 3 ++#define PCI_LTR_IDLE_TIMER_400US 4 ++#define PCI_LTR_IDLE_TIMER_800US 5 ++#define PCI_LTR_IDLE_TIMER_1_6MS 6 ++#define PCI_LTR_IDLE_TIMER_3_2MS 7 ++#define PCI_LTR_IDLE_TIMER_R_ERR 0xFD ++#define PCI_LTR_IDLE_TIMER_DEF 0xFE ++#define PCI_LTR_IDLE_TIMER_IGNORE 0xFF ++ ++#define PCI_LTR_SPC_10US 0 ++#define PCI_LTR_SPC_100US 1 ++#define PCI_LTR_SPC_500US 2 ++#define PCI_LTR_SPC_1MS 3 ++#define PCI_LTR_SPC_R_ERR 0xFD ++#define PCI_LTR_SPC_DEF 0xFE ++#define PCI_LTR_SPC_IGNORE 0xFF ++ ++#define R_AX_LTR_CTRL_0 0x8410 ++#define B_AX_LTR_SPACE_IDX_MASK GENMASK(13, 12) ++#define B_AX_LTR_IDLE_TIMER_IDX_MASK GENMASK(10, 8) ++#define B_AX_APP_LTR_ACT BIT(5) ++#define B_AX_APP_LTR_IDLE BIT(4) ++#define B_AX_LTR_EN BIT(1) ++#define B_AX_LTR_HW_EN BIT(0) ++ ++#define R_AX_LTR_CTRL_1 0x8414 ++#define B_AX_LTR_RX1_TH_MASK GENMASK(27, 16) ++#define B_AX_LTR_RX0_TH_MASK GENMASK(11, 0) ++ ++#define R_AX_LTR_IDLE_LATENCY 0x8418 ++ ++#define R_AX_LTR_ACTIVE_LATENCY 0x841C ++ ++#define R_AX_SER_DBG_INFO 0x8424 ++#define B_AX_L0_TO_L1_EVENT_MASK GENMASK(31, 28) ++ ++#define R_AX_DLE_EMPTY0 0x8430 ++#define B_AX_PLE_EMPTY_QTA_DMAC_CPUIO BIT(26) ++#define B_AX_PLE_EMPTY_QTA_DMAC_MPDU_TX BIT(25) ++#define B_AX_PLE_EMPTY_QTA_DMAC_WLAN_CPU BIT(24) ++#define B_AX_PLE_EMPTY_QTA_DMAC_H2C BIT(23) ++#define B_AX_PLE_EMPTY_QTA_DMAC_B1_TXPL BIT(22) ++#define B_AX_PLE_EMPTY_QTA_DMAC_B0_TXPL BIT(21) ++#define B_AX_WDE_EMPTY_QTA_DMAC_CPUIO BIT(20) ++#define B_AX_WDE_EMPTY_QTA_DMAC_PKTIN BIT(19) ++#define B_AX_WDE_EMPTY_QTA_DMAC_DATA_CPU BIT(18) ++#define B_AX_WDE_EMPTY_QTA_DMAC_WLAN_CPU BIT(17) ++#define B_AX_WDE_EMPTY_QTA_DMAC_HIF BIT(16) ++#define B_AX_WDE_EMPTY_QUE_DMAC_PKTIN BIT(10) ++#define B_AX_PLE_EMPTY_QUE_DMAC_SEC_TX BIT(9) ++#define B_AX_PLE_EMPTY_QUE_DMAC_MPDU_TX BIT(8) ++#define B_AX_WDE_EMPTY_QUE_OTHERS BIT(7) ++#define B_AX_WDE_EMPTY_QUE_CMAC0_WMM1 BIT(4) ++#define B_AX_WDE_EMPTY_QUE_CMAC0_WMM0 BIT(3) ++#define B_AX_WDE_EMPTY_QUE_CMAC1_MBH BIT(2) ++#define B_AX_WDE_EMPTY_QUE_CMAC0_MBH BIT(1) ++#define B_AX_WDE_EMPTY_QUE_CMAC0_ALL_AC BIT(0) ++ ++#define R_AX_DMAC_ERR_ISR 0x8524 ++#define B_AX_DLE_CPUIO_ERR_FLAG BIT(10) ++#define B_AX_APB_BRIDGE_ERR_FLAG BIT(9) ++#define B_AX_DISPATCH_ERR_FLAG BIT(8) ++#define B_AX_PKTIN_ERR_FLAG BIT(7) ++#define B_AX_PLE_DLE_ERR_FLAG BIT(6) ++#define B_AX_TXPKTCTRL_ERR_FLAG BIT(5) ++#define B_AX_WDE_DLE_ERR_FLAG BIT(4) ++#define B_AX_STA_SCHEDULER_ERR_FLAG BIT(3) ++#define B_AX_MPDU_ERR_FLAG BIT(2) ++#define B_AX_WSEC_ERR_FLAG BIT(1) ++#define B_AX_WDRLS_ERR_FLAG BIT(0) ++ ++#define R_AX_DISPATCHER_GLOBAL_SETTING_0 0x8800 ++#define B_AX_PL_PAGE_128B_SEL BIT(9) ++#define B_AX_WD_PAGE_64B_SEL BIT(8) ++#define R_AX_OTHER_DISPATCHER_ERR_ISR 0x8804 ++#define R_AX_HOST_DISPATCHER_ERR_ISR 0x8808 ++#define R_AX_CPU_DISPATCHER_ERR_ISR 0x880C ++#define R_AX_TX_ADDRESS_INFO_MODE_SETTING 0x8810 ++#define B_AX_HOST_ADDR_INFO_8B_SEL BIT(0) ++ ++#define R_AX_HOST_DISPATCHER_ERR_IMR 0x8850 ++#define B_AX_HDT_OFFSET_UNMATCH_INT_EN BIT(7) ++#define B_AX_HDT_PKT_FAIL_DBG_INT_EN BIT(2) ++ ++#define R_AX_CPU_DISPATCHER_ERR_IMR 0x8854 ++#define B_AX_CPU_SHIFT_EN_ERR_INT_EN BIT(25) ++ ++#define R_AX_OTHER_DISPATCHER_ERR_IMR 0x8858 ++ ++#define R_AX_HCI_FC_CTRL 0x8A00 ++#define B_AX_HCI_FC_CH12_FULL_COND_MASK GENMASK(11, 10) ++#define B_AX_HCI_FC_WP_CH811_FULL_COND_MASK GENMASK(9, 8) ++#define B_AX_HCI_FC_WP_CH07_FULL_COND_MASK GENMASK(7, 6) ++#define B_AX_HCI_FC_WD_FULL_COND_MASK GENMASK(5, 4) ++#define B_AX_HCI_FC_CH12_EN BIT(3) ++#define B_AX_HCI_FC_MODE_MASK GENMASK(2, 1) ++#define B_AX_HCI_FC_EN BIT(0) ++ ++#define R_AX_CH_PAGE_CTRL 0x8A04 ++#define B_AX_PREC_PAGE_CH12_MASK GENMASK(24, 16) ++#define B_AX_PREC_PAGE_CH011_MASK GENMASK(8, 0) ++ ++#define B_AX_MAX_PG_MASK GENMASK(28, 16) ++#define B_AX_MIN_PG_MASK GENMASK(12, 0) ++#define B_AX_GRP BIT(31) ++#define R_AX_ACH0_PAGE_CTRL 0x8A10 ++#define R_AX_ACH1_PAGE_CTRL 0x8A14 ++#define R_AX_ACH2_PAGE_CTRL 0x8A18 ++#define R_AX_ACH3_PAGE_CTRL 0x8A1C ++#define R_AX_ACH4_PAGE_CTRL 0x8A20 ++#define R_AX_ACH5_PAGE_CTRL 0x8A24 ++#define R_AX_ACH6_PAGE_CTRL 0x8A28 ++#define R_AX_ACH7_PAGE_CTRL 0x8A2C ++#define R_AX_CH8_PAGE_CTRL 0x8A30 ++#define R_AX_CH9_PAGE_CTRL 0x8A34 ++#define R_AX_CH10_PAGE_CTRL 0x8A38 ++#define R_AX_CH11_PAGE_CTRL 0x8A3C ++ ++#define B_AX_AVAL_PG_MASK GENMASK(27, 16) ++#define B_AX_USE_PG_MASK GENMASK(12, 0) ++#define R_AX_ACH0_PAGE_INFO 0x8A50 ++#define R_AX_ACH1_PAGE_INFO 0x8A54 ++#define R_AX_ACH2_PAGE_INFO 0x8A58 ++#define R_AX_ACH3_PAGE_INFO 0x8A5C ++#define R_AX_ACH4_PAGE_INFO 0x8A60 ++#define R_AX_ACH5_PAGE_INFO 0x8A64 ++#define R_AX_ACH6_PAGE_INFO 0x8A68 ++#define R_AX_ACH7_PAGE_INFO 0x8A6C ++#define R_AX_CH8_PAGE_INFO 0x8A70 ++#define R_AX_CH9_PAGE_INFO 0x8A74 ++#define R_AX_CH10_PAGE_INFO 0x8A78 ++#define R_AX_CH11_PAGE_INFO 0x8A7C ++#define R_AX_CH12_PAGE_INFO 0x8A80 ++ ++#define R_AX_PUB_PAGE_INFO3 0x8A8C ++#define B_AX_G1_AVAL_PG_MASK GENMASK(28, 16) ++#define B_AX_G0_AVAL_PG_MASK GENMASK(12, 0) ++ ++#define R_AX_PUB_PAGE_CTRL1 0x8A90 ++#define B_AX_PUBPG_G1_MASK GENMASK(28, 16) ++#define B_AX_PUBPG_G0_MASK GENMASK(12, 0) ++ ++#define R_AX_PUB_PAGE_CTRL2 0x8A94 ++#define B_AX_PUBPG_ALL_MASK GENMASK(12, 0) ++ ++#define R_AX_PUB_PAGE_INFO1 0x8A98 ++#define B_AX_G1_USE_PG_MASK GENMASK(28, 16) ++#define B_AX_G0_USE_PG_MASK GENMASK(12, 0) ++ ++#define R_AX_PUB_PAGE_INFO2 0x8A9C ++#define B_AX_PUB_AVAL_PG_MASK GENMASK(12, 0) ++ ++#define R_AX_WP_PAGE_CTRL1 0x8AA0 ++#define B_AX_PREC_PAGE_WP_CH811_MASK GENMASK(24, 16) ++#define B_AX_PREC_PAGE_WP_CH07_MASK GENMASK(8, 0) ++ ++#define R_AX_WP_PAGE_CTRL2 0x8AA4 ++#define B_AX_WP_THRD_MASK GENMASK(12, 0) ++ ++#define R_AX_WP_PAGE_INFO1 0x8AA8 ++#define B_AX_WP_AVAL_PG_MASK GENMASK(28, 16) ++ ++#define R_AX_WDE_PKTBUF_CFG 0x8C08 ++#define B_AX_WDE_START_BOUND_MASK GENMASK(13, 8) ++#define B_AX_WDE_PAGE_SEL_MASK GENMASK(1, 0) ++#define B_AX_WDE_FREE_PAGE_NUM_MASK GENMASK(28, 16) ++#define R_AX_WDE_ERR_FLAG_CFG 0x8C34 ++#define R_AX_WDE_ERR_IMR 0x8C38 ++#define R_AX_WDE_ERR_ISR 0x8C3C ++ ++#define B_AX_WDE_MAX_SIZE_MASK GENMASK(27, 16) ++#define B_AX_WDE_MIN_SIZE_MASK GENMASK(11, 0) ++#define R_AX_WDE_QTA0_CFG 0x8C40 ++#define R_AX_WDE_QTA1_CFG 0x8C44 ++#define R_AX_WDE_QTA2_CFG 0x8C48 ++#define R_AX_WDE_QTA3_CFG 0x8C4C ++#define R_AX_WDE_QTA4_CFG 0x8C50 ++ ++#define B_AX_DLE_PUB_PGNUM GENMASK(12, 0) ++#define B_AX_DLE_FREE_HEADPG GENMASK(11, 0) ++#define B_AX_DLE_FREE_TAILPG GENMASK(27, 16) ++#define B_AX_DLE_USE_PGNUM GENMASK(27, 16) ++#define B_AX_DLE_RSV_PGNUM GENMASK(11, 0) ++#define B_AX_DLE_QEMPTY_GRP GENMASK(31, 0) ++ ++#define R_AX_WDE_INI_STATUS 0x8D00 ++#define B_AX_WDE_Q_MGN_INI_RDY BIT(1) ++#define B_AX_WDE_BUF_MGN_INI_RDY BIT(0) ++#define WDE_MGN_INI_RDY (B_AX_WDE_Q_MGN_INI_RDY | B_AX_WDE_BUF_MGN_INI_RDY) ++#define R_AX_WDE_DBG_FUN_INTF_CTL 0x8D10 ++#define B_AX_WDE_DFI_ACTIVE BIT(31) ++#define B_AX_WDE_DFI_TRGSEL_MASK GENMASK(19, 16) ++#define B_AX_WDE_DFI_ADDR_MASK GENMASK(15, 0) ++#define R_AX_WDE_DBG_FUN_INTF_DATA 0x8D14 ++#define B_AX_WDE_DFI_DATA_MASK GENMASK(31, 0) ++ ++#define R_AX_PLE_PKTBUF_CFG 0x9008 ++#define B_AX_PLE_START_BOUND_MASK GENMASK(13, 8) ++#define B_AX_PLE_PAGE_SEL_MASK GENMASK(1, 0) ++#define B_AX_PLE_FREE_PAGE_NUM_MASK GENMASK(28, 16) ++#define R_AX_PLE_ERR_FLAG_CFG 0x9034 ++ ++#define R_AX_PLE_ERR_IMR 0x9038 ++#define B_AX_PLE_GETNPG_STRPG_ERR_INT_EN BIT(5) ++ ++#define R_AX_PLE_ERR_FLAG_ISR 0x903C ++#define B_AX_PLE_MAX_SIZE_MASK GENMASK(27, 16) ++#define B_AX_PLE_MIN_SIZE_MASK GENMASK(11, 0) ++#define R_AX_PLE_QTA0_CFG 0x9040 ++#define R_AX_PLE_QTA1_CFG 0x9044 ++#define R_AX_PLE_QTA2_CFG 0x9048 ++#define R_AX_PLE_QTA3_CFG 0x904C ++#define R_AX_PLE_QTA4_CFG 0x9050 ++#define R_AX_PLE_QTA5_CFG 0x9054 ++#define R_AX_PLE_QTA6_CFG 0x9058 ++#define B_AX_PLE_Q6_MAX_SIZE_MASK GENMASK(27, 16) ++#define B_AX_PLE_Q6_MIN_SIZE_MASK GENMASK(11, 0) ++#define R_AX_PLE_QTA7_CFG 0x905C ++#define R_AX_PLE_QTA8_CFG 0x9060 ++#define R_AX_PLE_QTA9_CFG 0x9064 ++#define R_AX_PLE_QTA10_CFG 0x9068 ++ ++#define R_AX_PLE_INI_STATUS 0x9100 ++#define B_AX_PLE_Q_MGN_INI_RDY BIT(1) ++#define B_AX_PLE_BUF_MGN_INI_RDY BIT(0) ++#define PLE_MGN_INI_RDY (B_AX_PLE_Q_MGN_INI_RDY | B_AX_PLE_BUF_MGN_INI_RDY) ++#define R_AX_PLE_DBG_FUN_INTF_CTL 0x9110 ++#define B_AX_PLE_DFI_ACTIVE BIT(31) ++#define B_AX_PLE_DFI_TRGSEL_MASK GENMASK(19, 16) ++#define B_AX_PLE_DFI_ADDR_MASK GENMASK(15, 0) ++#define R_AX_PLE_DBG_FUN_INTF_DATA 0x9114 ++#define B_AX_PLE_DFI_DATA_MASK GENMASK(31, 0) ++ ++#define R_AX_WDRLS_CFG 0x9408 ++#define B_AX_RLSRPT_BUFREQ_TO_MASK GENMASK(15, 8) ++#define B_AX_WDRLS_MODE_MASK GENMASK(1, 0) ++ ++#define R_AX_RLSRPT0_CFG0 0x9410 ++#define B_AX_RLSRPT0_FLTR_MAP_MASK GENMASK(27, 24) ++#define B_AX_RLSRPT0_PKTTYPE_MASK GENMASK(19, 16) ++#define B_AX_RLSRPT0_PID_MASK GENMASK(10, 8) ++#define B_AX_RLSRPT0_QID_MASK GENMASK(5, 0) ++ ++#define R_AX_RLSRPT0_CFG1 0x9414 ++#define B_AX_RLSRPT0_TO_MASK GENMASK(23, 16) ++#define B_AX_RLSRPT0_AGGNUM_MASK GENMASK(7, 0) ++ ++#define R_AX_WDRLS_ERR_IMR 0x9430 ++#define B_AX_WDRLS_RPT1_FRZTO_ERR_INT_EN BIT(13) ++#define B_AX_WDRLS_RPT1_AGGNUM0_ERR_INT_EN BIT(12) ++#define B_AX_WDRLS_RPT0_FRZTO_ERR_INT_EN BIT(9) ++#define B_AX_WDRLS_RPT0_AGGNUM0_ERR_INT_EN BIT(8) ++#define B_AX_WDRLS_PLEBREQ_PKTID_ISNULL_ERR_INT_EN BIT(5) ++#define B_AX_WDRLS_PLEBREQ_TO_ERR_INT_EN BIT(4) ++#define B_AX_WDRLS_CTL_FRZTO_ERR_INT_EN BIT(2) ++#define B_AX_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN BIT(1) ++#define B_AX_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN BIT(0) ++#define R_AX_WDRLS_ERR_ISR 0x9434 ++ ++#define R_AX_BBRPT_COM_ERR_IMR_ISR 0x960C ++#define R_AX_BBRPT_CHINFO_ERR_IMR_ISR 0x962C ++#define R_AX_BBRPT_DFS_ERR_IMR_ISR 0x963C ++#define R_AX_LA_ERRFLAG 0x966C ++ ++#define R_AX_WD_BUF_REQ 0x9800 ++#define R_AX_PL_BUF_REQ 0x9820 ++#define B_AX_WD_BUF_REQ_EXEC BIT(31) ++#define B_AX_WD_BUF_REQ_QUOTA_ID_MASK GENMASK(23, 16) ++#define B_AX_WD_BUF_REQ_LEN_MASK GENMASK(15, 0) ++ ++#define R_AX_WD_BUF_STATUS 0x9804 ++#define R_AX_PL_BUF_STATUS 0x9824 ++#define B_AX_WD_BUF_STAT_DONE BIT(31) ++#define B_AX_WD_BUF_STAT_PKTID_MASK GENMASK(11, 0) ++ ++#define R_AX_WD_CPUQ_OP_0 0x9810 ++#define R_AX_PL_CPUQ_OP_0 0x9830 ++#define B_AX_WD_CPUQ_OP_EXEC BIT(31) ++#define B_AX_CPUQ_OP_CMD_TYPE_MASK GENMASK(27, 24) ++#define B_AX_CPUQ_OP_MACID_MASK GENMASK(23, 16) ++#define B_AX_CPUQ_OP_PKTNUM_MASK GENMASK(7, 0) ++ ++#define R_AX_WD_CPUQ_OP_1 0x9814 ++#define R_AX_PL_CPUQ_OP_1 0x9834 ++#define B_AX_CPUQ_OP_SRC_PID_MASK GENMASK(24, 22) ++#define B_AX_CPUQ_OP_SRC_QID_MASK GENMASK(21, 16) ++#define B_AX_CPUQ_OP_DST_PID_MASK GENMASK(8, 6) ++#define B_AX_CPUQ_OP_DST_QID_MASK GENMASK(5, 0) ++ ++#define R_AX_WD_CPUQ_OP_2 0x9818 ++#define R_AX_PL_CPUQ_OP_2 0x9838 ++#define B_AX_WD_CPUQ_OP_STRT_PKTID_MASK GENMASK(27, 16) ++#define B_AX_WD_CPUQ_OP_END_PKTID_MASK GENMASK(11, 0) ++ ++#define R_AX_WD_CPUQ_OP_STATUS 0x981C ++#define R_AX_PL_CPUQ_OP_STATUS 0x983C ++#define B_AX_WD_CPUQ_OP_STAT_DONE BIT(31) ++#define B_AX_WD_CPUQ_OP_PKTID_MASK GENMASK(11, 0) ++#define R_AX_CPUIO_ERR_IMR 0x9840 ++#define R_AX_CPUIO_ERR_ISR 0x9844 ++ ++#define R_AX_SEC_ERR_IMR_ISR 0x991C ++ ++#define R_AX_PKTIN_SETTING 0x9A00 ++#define B_AX_WD_ADDR_INFO_LENGTH BIT(1) ++#define R_AX_PKTIN_ERR_IMR 0x9A20 ++#define R_AX_PKTIN_ERR_ISR 0x9A24 ++ ++#define R_AX_MPDU_TX_ERR_ISR 0x9BF0 ++#define R_AX_MPDU_TX_ERR_IMR 0x9BF4 ++ ++#define R_AX_MPDU_PROC 0x9C00 ++#define B_AX_A_ICV_ERR BIT(1) ++#define B_AX_APPEND_FCS BIT(0) ++ ++#define R_AX_ACTION_FWD0 0x9C04 ++#define TRXCFG_MPDU_PROC_ACT_FRWD 0x02A95A95 ++ ++#define R_AX_TF_FWD 0x9C14 ++#define TRXCFG_MPDU_PROC_TF_FRWD 0x0000AA55 ++ ++#define R_AX_HW_RPT_FWD 0x9C18 ++#define B_AX_FWD_PPDU_STAT_MASK GENMASK(1, 0) ++#define RTW89_PRPT_DEST_HOST 1 ++#define RTW89_PRPT_DEST_WLCPU 2 ++ ++#define R_AX_CUT_AMSDU_CTRL 0x9C40 ++#define TRXCFG_MPDU_PROC_CUT_CTRL 0x010E05F0 ++ ++#define R_AX_MPDU_RX_ERR_ISR 0x9CF0 ++#define R_AX_MPDU_RX_ERR_IMR 0x9CF4 ++ ++#define R_AX_SEC_ENG_CTRL 0x9D00 ++#define B_AX_TX_PARTIAL_MODE BIT(11) ++#define B_AX_CLK_EN_CGCMP BIT(10) ++#define B_AX_CLK_EN_WAPI BIT(9) ++#define B_AX_CLK_EN_WEP_TKIP BIT(8) ++#define B_AX_BMC_MGNT_DEC BIT(5) ++#define B_AX_UC_MGNT_DEC BIT(4) ++#define B_AX_MC_DEC BIT(3) ++#define B_AX_BC_DEC BIT(2) ++#define B_AX_SEC_RX_DEC BIT(1) ++#define B_AX_SEC_TX_ENC BIT(0) ++ ++#define R_AX_SEC_MPDU_PROC 0x9D04 ++#define B_AX_APPEND_ICV BIT(1) ++#define B_AX_APPEND_MIC BIT(0) ++ ++#define R_AX_SEC_CAM_ACCESS 0x9D10 ++#define R_AX_SEC_CAM_RDATA 0x9D14 ++#define R_AX_SEC_CAM_WDATA 0x9D18 ++#define R_AX_SEC_DEBUG 0x9D1C ++#define R_AX_SEC_TX_DEBUG 0x9D20 ++#define R_AX_SEC_RX_DEBUG 0x9D24 ++#define R_AX_SEC_TRX_PKT_CNT 0x9D28 ++#define R_AX_SEC_TRX_BLK_CNT 0x9D2C ++ ++#define R_AX_SS_CTRL 0x9E10 ++#define B_AX_SS_INIT_DONE_1 BIT(31) ++#define B_AX_SS_WARM_INIT_FLG BIT(29) ++#define B_AX_SS_EN BIT(0) ++ ++#define R_AX_SS_MACID_PAUSE_0 0x9EB0 ++#define B_AX_SS_MACID31_0_PAUSE_SH 0 ++#define B_AX_SS_MACID31_0_PAUSE_MASK GENMASK(31, 0) ++ ++#define R_AX_SS_MACID_PAUSE_1 0x9EB4 ++#define B_AX_SS_MACID63_32_PAUSE_SH 0 ++#define B_AX_SS_MACID63_32_PAUSE_MASK GENMASK(31, 0) ++ ++#define R_AX_SS_MACID_PAUSE_2 0x9EB8 ++#define B_AX_SS_MACID95_64_PAUSE_SH 0 ++#define B_AX_SS_MACID95_64_PAUSE_MASK GENMASK(31, 0) ++ ++#define R_AX_SS_MACID_PAUSE_3 0x9EBC ++#define B_AX_SS_MACID127_96_PAUSE_SH 0 ++#define B_AX_SS_MACID127_96_PAUSE_MASK GENMASK(31, 0) ++ ++#define R_AX_STA_SCHEDULER_ERR_IMR 0x9EF0 ++#define R_AX_STA_SCHEDULER_ERR_ISR 0x9EF4 ++ ++#define R_AX_TXPKTCTL_ERR_IMR_ISR 0x9F1C ++#define R_AX_TXPKTCTL_ERR_IMR_ISR_B1 0x9F2C ++#define B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR_INT_EN BIT(9) ++#define B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN BIT(3) ++#define B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR_INT_EN BIT(2) ++#define B_AX_TXPKTCTL_USRCTL_NOINIT_ERR_INT_EN BIT(1) ++ ++#define R_AX_DBG_FUN_INTF_CTL 0x9F30 ++#define B_AX_DFI_ACTIVE BIT(31) ++#define B_AX_DFI_TRGSEL_MASK GENMASK(19, 16) ++#define B_AX_DFI_ADDR_MASK GENMASK(15, 0) ++#define R_AX_DBG_FUN_INTF_DATA 0x9F34 ++#define B_AX_DFI_DATA_MASK GENMASK(31, 0) ++ ++#define R_AX_AFE_CTRL1 0x0024 ++ ++#define B_AX_R_SYM_WLCMAC1_P4_PC_EN BIT(4) ++#define B_AX_R_SYM_WLCMAC1_P3_PC_EN BIT(3) ++#define B_AX_R_SYM_WLCMAC1_P2_PC_EN BIT(2) ++#define B_AX_R_SYM_WLCMAC1_P1_PC_EN BIT(1) ++#define B_AX_R_SYM_WLCMAC1_PC_EN BIT(0) ++ ++#define R_AX_SYS_ISO_CTRL_EXTEND 0x0080 ++#define B_AX_CMAC1_FEN BIT(30) ++#define B_AX_R_SYM_FEN_WLBBGLB_1 BIT(17) ++#define B_AX_R_SYM_FEN_WLBBFUN_1 BIT(16) ++#define B_AX_R_SYM_ISO_CMAC12PP BIT(5) ++ ++#define R_AX_CMAC_REG_START 0xC000 ++ ++#define R_AX_CMAC_FUNC_EN 0xC000 ++#define R_AX_CMAC_FUNC_EN_C1 0xE000 ++#define B_AX_CMAC_CRPRT BIT(31) ++#define B_AX_CMAC_EN BIT(30) ++#define B_AX_CMAC_TXEN BIT(29) ++#define B_AX_CMAC_RXEN BIT(28) ++#define B_AX_FORCE_CMACREG_GCKEN BIT(15) ++#define B_AX_PHYINTF_EN BIT(5) ++#define B_AX_CMAC_DMA_EN BIT(4) ++#define B_AX_PTCLTOP_EN BIT(3) ++#define B_AX_SCHEDULER_EN BIT(2) ++#define B_AX_TMAC_EN BIT(1) ++#define B_AX_RMAC_EN BIT(0) ++ ++#define R_AX_CK_EN 0xC004 ++#define R_AX_CK_EN_C1 0xE004 ++#define B_AX_CMAC_ALLCKEN GENMASK(31, 0) ++#define B_AX_CMAC_CKEN BIT(30) ++#define B_AX_PHYINTF_CKEN BIT(5) ++#define B_AX_CMAC_DMA_CKEN BIT(4) ++#define B_AX_PTCLTOP_CKEN BIT(3) ++#define B_AX_SCHEDULER_CKEN BIT(2) ++#define B_AX_TMAC_CKEN BIT(1) ++#define B_AX_RMAC_CKEN BIT(0) ++ ++#define R_AX_WMAC_RFMOD 0xC010 ++#define R_AX_WMAC_RFMOD_C1 0xE010 ++#define B_AX_WMAC_RFMOD_MASK GENMASK(1, 0) ++ ++#define R_AX_GID_POSITION0 0xC070 ++#define R_AX_GID_POSITION0_C1 0xE070 ++#define R_AX_GID_POSITION1 0xC074 ++#define R_AX_GID_POSITION1_C1 0xE074 ++#define R_AX_GID_POSITION2 0xC078 ++#define R_AX_GID_POSITION2_C1 0xE078 ++#define R_AX_GID_POSITION3 0xC07C ++#define R_AX_GID_POSITION3_C1 0xE07C ++#define R_AX_GID_POSITION_EN0 0xC080 ++#define R_AX_GID_POSITION_EN0_C1 0xE080 ++#define R_AX_GID_POSITION_EN1 0xC084 ++#define R_AX_GID_POSITION_EN1_C1 0xE084 ++ ++#define R_AX_TX_SUB_CARRIER_VALUE 0xC088 ++#define R_AX_TX_SUB_CARRIER_VALUE_C1 0xE088 ++#define B_AX_TXSC_80M_MASK GENMASK(11, 8) ++#define B_AX_TXSC_40M_MASK GENMASK(7, 4) ++#define B_AX_TXSC_20M_MASK GENMASK(3, 0) ++ ++#define R_AX_CMAC_ERR_ISR 0xC164 ++#define R_AX_CMAC_ERR_ISR_C1 0xE164 ++#define B_AX_WMAC_TX_ERR_IND BIT(7) ++#define B_AX_WMAC_RX_ERR_IND BIT(6) ++#define B_AX_TXPWR_CTRL_ERR_IND BIT(5) ++#define B_AX_PHYINTF_ERR_IND BIT(4) ++#define B_AX_DMA_TOP_ERR_IND BIT(3) ++#define B_AX_PTCL_TOP_ERR_IND BIT(1) ++#define B_AX_SCHEDULE_TOP_ERR_IND BIT(0) ++ ++#define R_AX_MACID_SLEEP_0 0xC2C0 ++#define R_AX_MACID_SLEEP_0_C1 0xE2C0 ++#define B_AX_MACID31_0_SLEEP_SH 0 ++#define B_AX_MACID31_0_SLEEP_MASK GENMASK(31, 0) ++ ++#define R_AX_MACID_SLEEP_1 0xC2C4 ++#define R_AX_MACID_SLEEP_1_C1 0xE2C4 ++#define B_AX_MACID63_32_SLEEP_SH 0 ++#define B_AX_MACID63_32_SLEEP_MASK GENMASK(31, 0) ++ ++#define R_AX_MACID_SLEEP_2 0xC2C8 ++#define R_AX_MACID_SLEEP_2_C1 0xE2C8 ++#define B_AX_MACID95_64_SLEEP_SH 0 ++#define B_AX_MACID95_64_SLEEP_MASK GENMASK(31, 0) ++ ++#define R_AX_MACID_SLEEP_3 0xC2CC ++#define R_AX_MACID_SLEEP_3_C1 0xE2CC ++#define B_AX_MACID127_96_SLEEP_SH 0 ++#define B_AX_MACID127_96_SLEEP_MASK GENMASK(31, 0) ++ ++#define SCH_PREBKF_24US 0x18 ++#define R_AX_PREBKF_CFG_0 0xC338 ++#define R_AX_PREBKF_CFG_0_C1 0xE338 ++#define B_AX_PREBKF_TIME_MASK GENMASK(4, 0) ++ ++#define R_AX_CCA_CFG_0 0xC340 ++#define R_AX_CCA_CFG_0_C1 0xE340 ++#define B_AX_BTCCA_BRK_TXOP_EN BIT(9) ++#define B_AX_BTCCA_EN BIT(5) ++#define B_AX_EDCCA_EN BIT(4) ++#define B_AX_SEC80_EN BIT(3) ++#define B_AX_SEC40_EN BIT(2) ++#define B_AX_SEC20_EN BIT(1) ++#define B_AX_CCA_EN BIT(0) ++ ++#define R_AX_CTN_TXEN 0xC348 ++#define R_AX_CTN_TXEN_C1 0xE348 ++#define B_AX_CTN_TXEN_TWT_1 BIT(15) ++#define B_AX_CTN_TXEN_TWT_0 BIT(14) ++#define B_AX_CTN_TXEN_ULQ BIT(13) ++#define B_AX_CTN_TXEN_BCNQ BIT(12) ++#define B_AX_CTN_TXEN_HGQ BIT(11) ++#define B_AX_CTN_TXEN_CPUMGQ BIT(10) ++#define B_AX_CTN_TXEN_MGQ1 BIT(9) ++#define B_AX_CTN_TXEN_MGQ BIT(8) ++#define B_AX_CTN_TXEN_VO_1 BIT(7) ++#define B_AX_CTN_TXEN_VI_1 BIT(6) ++#define B_AX_CTN_TXEN_BK_1 BIT(5) ++#define B_AX_CTN_TXEN_BE_1 BIT(4) ++#define B_AX_CTN_TXEN_VO_0 BIT(3) ++#define B_AX_CTN_TXEN_VI_0 BIT(2) ++#define B_AX_CTN_TXEN_BK_0 BIT(1) ++#define B_AX_CTN_TXEN_BE_0 BIT(0) ++ ++#define R_AX_MUEDCA_BE_PARAM_0 0xC350 ++#define R_AX_MUEDCA_BE_PARAM_0_C1 0xE350 ++#define B_AX_MUEDCA_BE_PARAM_0_TIMER_MASK GENMASK(31, 16) ++#define B_AX_MUEDCA_BE_PARAM_0_CW_MASK GENMASK(15, 8) ++#define B_AX_MUEDCA_BE_PARAM_0_AIFS_MASK GENMASK(7, 0) ++ ++#define R_AX_MUEDCA_BK_PARAM_0 0xC354 ++#define R_AX_MUEDCA_BK_PARAM_0_C1 0xE354 ++#define R_AX_MUEDCA_VI_PARAM_0 0xC358 ++#define R_AX_MUEDCA_VI_PARAM_0_C1 0xE358 ++#define R_AX_MUEDCA_VO_PARAM_0 0xC35C ++#define R_AX_MUEDCA_VO_PARAM_0_C1 0xE35C ++ ++#define R_AX_MUEDCA_EN 0xC370 ++#define R_AX_MUEDCA_EN_C1 0xE370 ++#define B_AX_MUEDCA_WMM_SEL BIT(8) ++#define B_AX_SET_MUEDCATIMER_TF_0 BIT(4) ++#define B_AX_MUEDCA_EN_0 BIT(0) ++ ++#define R_AX_CCA_CONTROL 0xC390 ++#define R_AX_CCA_CONTROL_C1 0xE390 ++#define B_AX_TB_CHK_TX_NAV BIT(31) ++#define B_AX_TB_CHK_BASIC_NAV BIT(30) ++#define B_AX_TB_CHK_BTCCA BIT(29) ++#define B_AX_TB_CHK_EDCCA BIT(28) ++#define B_AX_TB_CHK_CCA_S80 BIT(27) ++#define B_AX_TB_CHK_CCA_S40 BIT(26) ++#define B_AX_TB_CHK_CCA_S20 BIT(25) ++#define B_AX_TB_CHK_CCA_P20 BIT(24) ++#define B_AX_SIFS_CHK_BTCCA BIT(21) ++#define B_AX_SIFS_CHK_EDCCA BIT(20) ++#define B_AX_SIFS_CHK_CCA_S80 BIT(19) ++#define B_AX_SIFS_CHK_CCA_S40 BIT(18) ++#define B_AX_SIFS_CHK_CCA_S20 BIT(17) ++#define B_AX_SIFS_CHK_CCA_P20 BIT(16) ++#define B_AX_CTN_CHK_TXNAV BIT(8) ++#define B_AX_CTN_CHK_INTRA_NAV BIT(7) ++#define B_AX_CTN_CHK_BASIC_NAV BIT(6) ++#define B_AX_CTN_CHK_BTCCA BIT(5) ++#define B_AX_CTN_CHK_EDCCA BIT(4) ++#define B_AX_CTN_CHK_CCA_S80 BIT(3) ++#define B_AX_CTN_CHK_CCA_S40 BIT(2) ++#define B_AX_CTN_CHK_CCA_S20 BIT(1) ++#define B_AX_CTN_CHK_CCA_P20 BIT(0) ++ ++#define R_AX_SCHEDULE_ERR_IMR 0xC3E8 ++#define R_AX_SCHEDULE_ERR_IMR_C1 0xE3E8 ++#define B_AX_SORT_NON_IDLE_ERR_INT_EN BIT(1) ++#define B_AX_FSM_TIMEOUT_ERR_INT_EN BIT(0) ++ ++#define R_AX_SCHEDULE_ERR_ISR 0xC3EC ++#define R_AX_SCHEDULE_ERR_ISR_C1 0xE3EC ++ ++#define R_AX_SCH_DBG_SEL 0xC3F4 ++#define R_AX_SCH_DBG_SEL_C1 0xE3F4 ++#define B_AX_SCH_DBG_EN BIT(16) ++#define B_AX_SCH_CFG_CMD_SEL GENMASK(15, 8) ++#define B_AX_SCH_DBG_SEL_MASK GENMASK(7, 0) ++ ++#define R_AX_SCH_DBG 0xC3F8 ++#define R_AX_SCH_DBG_C1 0xE3F8 ++#define B_AX_SCHEDULER_DBG_MASK GENMASK(31, 0) ++ ++#define R_AX_PORT_CFG_P0 0xC400 ++#define R_AX_PORT_CFG_P1 0xC440 ++#define R_AX_PORT_CFG_P2 0xC480 ++#define R_AX_PORT_CFG_P3 0xC4C0 ++#define R_AX_PORT_CFG_P4 0xC500 ++#define B_AX_BRK_SETUP BIT(16) ++#define B_AX_TBTT_UPD_SHIFT_SEL BIT(15) ++#define B_AX_BCN_DROP_ALLOW BIT(14) ++#define B_AX_TBTT_PROHIB_EN BIT(13) ++#define B_AX_BCNTX_EN BIT(12) ++#define B_AX_NET_TYPE_MASK GENMASK(11, 10) ++#define B_AX_BCN_FORCETX_EN BIT(9) ++#define B_AX_TXBCN_BTCCA_EN BIT(8) ++#define B_AX_BCNERR_CNT_EN BIT(7) ++#define B_AX_BCN_AGRES BIT(6) ++#define B_AX_TSFTR_RST BIT(5) ++#define B_AX_RX_BSSID_FIT_EN BIT(4) ++#define B_AX_TSF_UDT_EN BIT(3) ++#define B_AX_PORT_FUNC_EN BIT(2) ++#define B_AX_TXBCN_RPT_EN BIT(1) ++#define B_AX_RXBCN_RPT_EN BIT(0) ++ ++#define R_AX_TBTT_PROHIB_P0 0xC404 ++#define R_AX_TBTT_PROHIB_P1 0xC444 ++#define R_AX_TBTT_PROHIB_P2 0xC484 ++#define R_AX_TBTT_PROHIB_P3 0xC4C4 ++#define R_AX_TBTT_PROHIB_P4 0xC504 ++#define B_AX_TBTT_HOLD_MASK GENMASK(27, 16) ++#define B_AX_TBTT_SETUP_MASK GENMASK(7, 0) ++ ++#define R_AX_BCN_AREA_P0 0xC408 ++#define R_AX_BCN_AREA_P1 0xC448 ++#define R_AX_BCN_AREA_P2 0xC488 ++#define R_AX_BCN_AREA_P3 0xC4C8 ++#define R_AX_BCN_AREA_P4 0xC508 ++#define B_AX_BCN_MSK_AREA_MASK GENMASK(27, 16) ++#define B_AX_BCN_CTN_AREA_MASK GENMASK(11, 0) ++ ++#define R_AX_BCNERLYINT_CFG_P0 0xC40C ++#define R_AX_BCNERLYINT_CFG_P1 0xC44C ++#define R_AX_BCNERLYINT_CFG_P2 0xC48C ++#define R_AX_BCNERLYINT_CFG_P3 0xC4CC ++#define R_AX_BCNERLYINT_CFG_P4 0xC50C ++#define B_AX_BCNERLY_MASK GENMASK(11, 0) ++ ++#define R_AX_TBTTERLYINT_CFG_P0 0xC40E ++#define R_AX_TBTTERLYINT_CFG_P1 0xC44E ++#define R_AX_TBTTERLYINT_CFG_P2 0xC48E ++#define R_AX_TBTTERLYINT_CFG_P3 0xC4CE ++#define R_AX_TBTTERLYINT_CFG_P4 0xC50E ++#define B_AX_TBTTERLY_MASK GENMASK(11, 0) ++ ++#define R_AX_TBTT_AGG_P0 0xC412 ++#define R_AX_TBTT_AGG_P1 0xC452 ++#define R_AX_TBTT_AGG_P2 0xC492 ++#define R_AX_TBTT_AGG_P3 0xC4D2 ++#define R_AX_TBTT_AGG_P4 0xC512 ++#define B_AX_TBTT_AGG_NUM_MASK GENMASK(15, 8) ++ ++#define R_AX_BCN_SPACE_CFG_P0 0xC414 ++#define R_AX_BCN_SPACE_CFG_P1 0xC454 ++#define R_AX_BCN_SPACE_CFG_P2 0xC494 ++#define R_AX_BCN_SPACE_CFG_P3 0xC4D4 ++#define R_AX_BCN_SPACE_CFG_P4 0xC514 ++#define B_AX_SUB_BCN_SPACE_MASK GENMASK(23, 16) ++#define B_AX_BCN_SPACE_MASK GENMASK(15, 0) ++ ++#define R_AX_BCN_FORCETX_P0 0xC418 ++#define R_AX_BCN_FORCETX_P1 0xC458 ++#define R_AX_BCN_FORCETX_P2 0xC498 ++#define R_AX_BCN_FORCETX_P3 0xC4D8 ++#define R_AX_BCN_FORCETX_P4 0xC518 ++#define B_AX_FORCE_BCN_CURRCNT_MASK GENMASK(23, 16) ++#define B_AX_FORCE_BCN_NUM_MASK GENMASK(15, 0) ++#define B_AX_BCN_MAX_ERR_MASK GENMASK(7, 0) ++ ++#define R_AX_BCN_ERR_CNT_P0 0xC420 ++#define R_AX_BCN_ERR_CNT_P1 0xC460 ++#define R_AX_BCN_ERR_CNT_P2 0xC4A0 ++#define R_AX_BCN_ERR_CNT_P3 0xC4E0 ++#define R_AX_BCN_ERR_CNT_P4 0xC520 ++#define B_AX_BCN_ERR_CNT_SUM_MASK GENMASK(31, 24) ++#define B_AX_BCN_ERR_CNT_NAV_MASK GENMASK(23, 16) ++#define B_AX_BCN_ERR_CNT_EDCCA_MASK GENMASK(15, 0) ++#define B_AX_BCN_ERR_CNT_CCA_MASK GENMASK(7, 0) ++ ++#define R_AX_BCN_ERR_FLAG_P0 0xC424 ++#define R_AX_BCN_ERR_FLAG_P1 0xC464 ++#define R_AX_BCN_ERR_FLAG_P2 0xC4A4 ++#define R_AX_BCN_ERR_FLAG_P3 0xC4E4 ++#define R_AX_BCN_ERR_FLAG_P4 0xC524 ++#define B_AX_BCN_ERR_FLAG_OTHERS BIT(6) ++#define B_AX_BCN_ERR_FLAG_MAC BIT(5) ++#define B_AX_BCN_ERR_FLAG_TXON BIT(4) ++#define B_AX_BCN_ERR_FLAG_SRCHEND BIT(3) ++#define B_AX_BCN_ERR_FLAG_INVALID BIT(2) ++#define B_AX_BCN_ERR_FLAG_CMP BIT(1) ++#define B_AX_BCN_ERR_FLAG_LOCK BIT(0) ++ ++#define R_AX_DTIM_CTRL_P0 0xC426 ++#define R_AX_DTIM_CTRL_P1 0xC466 ++#define R_AX_DTIM_CTRL_P2 0xC4A6 ++#define R_AX_DTIM_CTRL_P3 0xC4E6 ++#define R_AX_DTIM_CTRL_P4 0xC526 ++#define B_AX_DTIM_NUM_MASK GENMASK(15, 0) ++#define B_AX_DTIM_CURRCNT_MASK GENMASK(7, 0) ++ ++#define R_AX_TBTT_SHIFT_P0 0xC428 ++#define R_AX_TBTT_SHIFT_P1 0xC468 ++#define R_AX_TBTT_SHIFT_P2 0xC4A8 ++#define R_AX_TBTT_SHIFT_P3 0xC4E8 ++#define R_AX_TBTT_SHIFT_P4 0xC528 ++#define B_AX_TBTT_SHIFT_OFST_MASK GENMASK(11, 0) ++ ++#define R_AX_BCN_CNT_TMR_P0 0xC434 ++#define R_AX_BCN_CNT_TMR_P1 0xC474 ++#define R_AX_BCN_CNT_TMR_P2 0xC4B4 ++#define R_AX_BCN_CNT_TMR_P3 0xC4F4 ++#define R_AX_BCN_CNT_TMR_P4 0xC534 ++#define B_AX_BCN_CNT_TMR_MASK GENMASK(31, 0) ++ ++#define R_AX_TSFTR_LOW_P0 0xC438 ++#define R_AX_TSFTR_LOW_P1 0xC478 ++#define R_AX_TSFTR_LOW_P2 0xC4B8 ++#define R_AX_TSFTR_LOW_P3 0xC4F8 ++#define R_AX_TSFTR_LOW_P4 0xC538 ++#define B_AX_TSFTR_LOW_MASK GENMASK(31, 0) ++ ++#define R_AX_TSFTR_HIGH_P0 0xC43C ++#define R_AX_TSFTR_HIGH_P1 0xC47C ++#define R_AX_TSFTR_HIGH_P2 0xC4BC ++#define R_AX_TSFTR_HIGH_P3 0xC4FC ++#define R_AX_TSFTR_HIGH_P4 0xC53C ++#define B_AX_TSFTR_HIGH_MASK GENMASK(31, 0) ++ ++#define R_AX_MBSSID_CTRL 0xC568 ++#define R_AX_MBSSID_CTRL_C1 0xE568 ++#define B_AX_P0MB_ALL_MASK GENMASK(23, 1) ++#define B_AX_P0MB_NUM_MASK GENMASK(19, 16) ++#define B_AX_P0MB15_EN BIT(15) ++#define B_AX_P0MB14_EN BIT(14) ++#define B_AX_P0MB13_EN BIT(13) ++#define B_AX_P0MB12_EN BIT(12) ++#define B_AX_P0MB11_EN BIT(11) ++#define B_AX_P0MB10_EN BIT(10) ++#define B_AX_P0MB9_EN BIT(9) ++#define B_AX_P0MB8_EN BIT(8) ++#define B_AX_P0MB7_EN BIT(7) ++#define B_AX_P0MB6_EN BIT(6) ++#define B_AX_P0MB5_EN BIT(5) ++#define B_AX_P0MB4_EN BIT(4) ++#define B_AX_P0MB3_EN BIT(3) ++#define B_AX_P0MB2_EN BIT(2) ++#define B_AX_P0MB1_EN BIT(1) ++ ++#define R_AX_AMPDU_AGG_LIMIT 0xC610 ++#define B_AX_AMPDU_MAX_TIME_MASK GENMASK(31, 24) ++#define B_AX_RA_TRY_RATE_AGG_LMT_MASK GENMASK(23, 16) ++#define B_AX_RTS_MAX_AGG_NUM_MASK GENMASK(15, 8) ++#define B_AX_MAX_AGG_NUM_MASK GENMASK(7, 0) ++ ++#define R_AX_AGG_LEN_HT_0 0xC614 ++#define R_AX_AGG_LEN_HT_0_C1 0xE614 ++#define B_AX_AMPDU_MAX_LEN_HT_MASK GENMASK(31, 16) ++#define B_AX_RTS_TXTIME_TH_MASK GENMASK(15, 8) ++#define B_AX_RTS_LEN_TH_MASK GENMASK(7, 0) ++ ++#define S_AX_CTS2S_TH_SEC_256B 1 ++#define R_AX_SIFS_SETTING 0xC624 ++#define R_AX_SIFS_SETTING_C1 0xE624 ++#define B_AX_HW_CTS2SELF_PKT_LEN_TH_MASK GENMASK(31, 24) ++#define B_AX_HW_CTS2SELF_PKT_LEN_TH_TWW_MASK GENMASK(23, 18) ++#define B_AX_HW_CTS2SELF_EN BIT(16) ++#define B_AX_SPEC_SIFS_OFDM_PTCL_SH 8 ++#define B_AX_SPEC_SIFS_OFDM_PTCL_MASK GENMASK(15, 8) ++#define B_AX_SPEC_SIFS_CCK_PTCL_MASK GENMASK(7, 0) ++#define S_AX_CTS2S_TH_1K 4 ++ ++#define R_AX_TXRATE_CHK 0xC628 ++#define R_AX_TXRATE_CHK_C1 0xE628 ++#define B_AX_DEFT_RATE_MASK GENMASK(15, 7) ++#define B_AX_BAND_MODE BIT(4) ++#define B_AX_MAX_TXNSS_MASK GENMASK(3, 2) ++#define B_AX_RTS_LIMIT_IN_OFDM6 BIT(1) ++#define B_AX_CHECK_CCK_EN BIT(0) ++ ++#define R_AX_TXCNT 0xC62C ++#define R_AX_TXCNT_C1 0xE62C ++#define B_AX_ADD_TXCNT_BY BIT(31) ++#define B_AX_S_TXCNT_LMT_MASK GENMASK(29, 24) ++#define B_AX_L_TXCNT_LMT_MASK GENMASK(21, 16) ++ ++#define R_AX_MBSSID_DROP_0 0xC63C ++#define R_AX_MBSSID_DROP_0_C1 0xE63C ++#define B_AX_GI_LTF_FB_SEL BIT(30) ++#define B_AX_RATE_SEL_MASK GENMASK(29, 24) ++#define B_AX_PORT_DROP_4_0_MASK GENMASK(20, 16) ++#define B_AX_MBSSID_DROP_15_0_MASK GENMASK(15, 0) ++ ++#define R_AX_BT_PLT 0xC67C ++#define R_AX_BT_PLT_C1 0xE67C ++#define B_AX_BT_PLT_PKT_CNT_MASK GENMASK(31, 16) ++#define B_AX_BT_PLT_RST BIT(9) ++#define B_AX_PLT_EN BIT(8) ++#define B_AX_RX_PLT_GNT_LTE_RX BIT(7) ++#define B_AX_RX_PLT_GNT_BT_RX BIT(6) ++#define B_AX_RX_PLT_GNT_BT_TX BIT(5) ++#define B_AX_RX_PLT_GNT_WL BIT(4) ++#define B_AX_TX_PLT_GNT_LTE_RX BIT(3) ++#define B_AX_TX_PLT_GNT_BT_RX BIT(2) ++#define B_AX_TX_PLT_GNT_BT_TX BIT(1) ++#define B_AX_TX_PLT_GNT_WL BIT(0) ++ ++#define R_AX_PTCL_BSS_COLOR_0 0xC6A0 ++#define R_AX_PTCL_BSS_COLOR_0_C1 0xE6A0 ++#define B_AX_BSS_COLOB_AX_PORT_3_MASK GENMASK(29, 24) ++#define B_AX_BSS_COLOB_AX_PORT_2_MASK GENMASK(21, 16) ++#define B_AX_BSS_COLOB_AX_PORT_1_MASK GENMASK(13, 8) ++#define B_AX_BSS_COLOB_AX_PORT_0_MASK GENMASK(5, 0) ++ ++#define R_AX_PTCL_BSS_COLOR_1 0xC6A4 ++#define R_AX_PTCL_BSS_COLOR_1_C1 0xE6A4 ++#define B_AX_BSS_COLOB_AX_PORT_4_MASK GENMASK(5, 0) ++ ++#define R_AX_PTCL_IMR0 0xC6C0 ++#define R_AX_PTCL_IMR0_C1 0xE6C0 ++#define B_AX_F2PCMD_USER_ALLC_ERR_INT_EN BIT(28) ++#define B_AX_TX_RECORD_PKTID_ERR_INT_EN BIT(23) ++ ++#define R_AX_PTCL_ISR0 0xC6C4 ++#define R_AX_PTCL_ISR0_C1 0xE6C4 ++ ++#define S_AX_PTCL_TO_2MS 0x3F ++#define R_AX_PTCL_FSM_MON 0xC6E8 ++#define R_AX_PTCL_FSM_MON_C1 0xE6E8 ++#define B_AX_PTCL_TX_ARB_TO_MODE BIT(6) ++#define B_AX_PTCL_TX_ARB_TO_THR_MASK GENMASK(5, 0) ++ ++#define R_AX_PTCL_TX_CTN_SEL 0xC6EC ++#define R_AX_PTCL_TX_CTN_SEL_C1 0xE6EC ++#define B_AX_PTCL_TX_ON_STAT BIT(7) ++ ++#define R_AX_PTCL_DBG_INFO 0xC6F0 ++#define R_AX_PTCL_DBG_INFO_C1 0xE6F0 ++#define B_AX_PTCL_DBG_INFO_MASK GENMASK(31, 0) ++#define R_AX_PTCL_DBG 0xC6F4 ++#define R_AX_PTCL_DBG_C1 0xE6F4 ++#define B_AX_PTCL_DBG_EN BIT(8) ++#define B_AX_PTCL_DBG_SEL_MASK GENMASK(7, 0) ++ ++#define R_AX_DLE_CTRL 0xC800 ++#define R_AX_DLE_CTRL_C1 0xE800 ++#define B_AX_NO_RESERVE_PAGE_ERR_IMR BIT(23) ++#define B_AX_RXDATA_FSM_HANG_ERROR_IMR BIT(15) ++#define R_AX_RXDMA_PKT_INFO_0 0xC814 ++#define R_AX_RXDMA_PKT_INFO_1 0xC818 ++#define R_AX_RXDMA_PKT_INFO_2 0xC81C ++ ++#define R_AX_TCR1 0xCA04 ++#define R_AX_TCR1_C1 0xEA04 ++#define B_AX_TXDFIFO_THRESHOLD GENMASK(31, 28) ++#define B_AX_TCR_CCK_LOCK_CLK BIT(27) ++#define B_AX_TCR_FORCE_READ_TXDFIFO BIT(26) ++#define B_AX_TCR_USTIME GENMASK(23, 16) ++#define B_AX_TCR_SMOOTH_VAL BIT(15) ++#define B_AX_TCR_SMOOTH_CTRL BIT(14) ++#define B_AX_CS_REQ_VAL BIT(13) ++#define B_AX_CS_REQ_SEL BIT(12) ++#define B_AX_TCR_ZLD_USTIME_AFTERPHYTXON GENMASK(11, 8) ++#define B_AX_TCR_TXTIMEOUT GENMASK(7, 0) ++ ++#define R_AX_PPWRBIT_SETTING 0xCA0C ++#define R_AX_PPWRBIT_SETTING_C1 0xEA0C ++ ++#define R_AX_MACTX_DBG_SEL_CNT 0xCA20 ++#define R_AX_MACTX_DBG_SEL_CNT_C1 0xEA20 ++#define B_AX_MACTX_MPDU_CNT GENMASK(31, 24) ++#define B_AX_MACTX_DMA_CNT GENMASK(23, 16) ++#define B_AX_LENGTH_ERR_FLAG_U3 BIT(11) ++#define B_AX_LENGTH_ERR_FLAG_U2 BIT(10) ++#define B_AX_LENGTH_ERR_FLAG_U1 BIT(9) ++#define B_AX_LENGTH_ERR_FLAG_U0 BIT(8) ++#define B_AX_DBGSEL_MACTX_MASK GENMASK(5, 0) ++ ++#define R_AX_WMAC_TX_CTRL_DEBUG 0xCAE4 ++#define R_AX_WMAC_TX_CTRL_DEBUG_C1 0xEAE4 ++#define B_AX_TX_CTRL_DEBUG_SEL_MASK GENMASK(3, 0) ++ ++#define R_AX_WMAC_TX_INFO0_DEBUG 0xCAE8 ++#define R_AX_WMAC_TX_INFO0_DEBUG_C1 0xEAE8 ++#define B_AX_TX_CTRL_INFO_P0_MASK GENMASK(31, 0) ++ ++#define R_AX_WMAC_TX_INFO1_DEBUG 0xCAEC ++#define R_AX_WMAC_TX_INFO1_DEBUG_C1 0xEAEC ++#define B_AX_TX_CTRL_INFO_P1_MASK GENMASK(31, 0) ++ ++#define R_AX_RSP_CHK_SIG 0xCC00 ++#define R_AX_RSP_CHK_SIG_C1 0xEC00 ++#define B_AX_RSP_STATIC_RTS_CHK_SERV_BW_EN BIT(30) ++#define B_AX_RSP_TBPPDU_CHK_PWR BIT(29) ++#define B_AX_RSP_CHK_BASIC_NAV BIT(21) ++#define B_AX_RSP_CHK_INTRA_NAV BIT(20) ++#define B_AX_RSP_CHK_TXNAV BIT(19) ++#define B_AX_TXDATA_END_PS_OPT BIT(18) ++#define B_AX_CHECK_SOUNDING_SEQ BIT(17) ++#define B_AX_RXBA_IGNOREA2 BIT(16) ++#define B_AX_ACKTO_CCK_MASK GENMASK(15, 8) ++#define B_AX_ACKTO_MASK GENMASK(7, 0) ++ ++#define R_AX_TRXPTCL_RESP_0 0xCC04 ++#define R_AX_TRXPTCL_RESP_0_C1 0xEC04 ++#define B_AX_WMAC_RESP_STBC_EN BIT(31) ++#define B_AX_WMAC_RXFTM_TXACK_SC BIT(30) ++#define B_AX_WMAC_RXFTM_TXACKBWEQ BIT(29) ++#define B_AX_RSP_CHK_SEC_CCA_80 BIT(28) ++#define B_AX_RSP_CHK_SEC_CCA_40 BIT(27) ++#define B_AX_RSP_CHK_SEC_CCA_20 BIT(26) ++#define B_AX_RSP_CHK_BTCCA BIT(25) ++#define B_AX_RSP_CHK_EDCCA BIT(24) ++#define B_AX_RSP_CHK_CCA BIT(23) ++#define B_AX_WMAC_LDPC_EN BIT(22) ++#define B_AX_WMAC_SGIEN BIT(21) ++#define B_AX_WMAC_SPLCPEN BIT(20) ++#define B_AX_WMAC_BESP_EARLY_TXBA BIT(17) ++#define B_AX_WMAC_SPEC_SIFS_OFDM_MASK GENMASK(15, 8) ++#define B_AX_WMAC_SPEC_SIFS_CCK_MASK GENMASK(7, 0) ++#define WMAC_SPEC_SIFS_OFDM_52A 0x15 ++#define WMAC_SPEC_SIFS_OFDM_52B 0x11 ++#define WMAC_SPEC_SIFS_OFDM_52C 0x11 ++#define WMAC_SPEC_SIFS_CCK 0xA ++ ++#define R_AX_MAC_LOOPBACK 0xCC20 ++#define R_AX_MAC_LOOPBACK_C1 0xEC20 ++#define B_AX_MACLBK_EN BIT(0) ++ ++#define R_AX_RXTRIG_TEST_USER_2 0xCCB0 ++#define R_AX_RXTRIG_TEST_USER_2_C1 0xECB0 ++#define B_AX_RXTRIG_MACID_MASK GENMASK(31, 24) ++#define B_AX_RXTRIG_RU26_DIS BIT(21) ++#define B_AX_RXTRIG_FCSCHK_EN BIT(20) ++#define B_AX_RXTRIG_PORT_SEL_MASK GENMASK(19, 17) ++#define B_AX_RXTRIG_EN BIT(16) ++#define B_AX_RXTRIG_USERINFO_2_MASK GENMASK(15, 0) ++ ++#define R_AX_WMAC_TX_TF_INFO_0 0xCCD0 ++#define R_AX_WMAC_TX_TF_INFO_0_C1 0xECD0 ++#define B_AX_WMAC_TX_TF_INFO_SEL_MASK GENMASK(2, 0) ++ ++#define R_AX_WMAC_TX_TF_INFO_1 0xCCD4 ++#define R_AX_WMAC_TX_TF_INFO_1_C1 0xECD4 ++#define B_AX_WMAC_TX_TF_INFO_P0_MASK GENMASK(31, 0) ++ ++#define R_AX_WMAC_TX_TF_INFO_2 0xCCD8 ++#define R_AX_WMAC_TX_TF_INFO_2_C1 0xECD8 ++#define B_AX_WMAC_TX_TF_INFO_P1_MASK GENMASK(31, 0) ++ ++#define R_AX_TMAC_ERR_IMR_ISR 0xCCEC ++#define R_AX_TMAC_ERR_IMR_ISR_C1 0xECEC ++ ++#define R_AX_DBGSEL_TRXPTCL 0xCCF4 ++#define R_AX_DBGSEL_TRXPTCL_C1 0xECF4 ++#define B_AX_DBGSEL_TRXPTCL_MASK GENMASK(7, 0) ++ ++#define R_AX_PHYINFO_ERR_IMR 0xCCFC ++#define R_AX_PHYINFO_ERR_IMR_C1 0xECFC ++#define B_AX_CSI_ON_TIMEOUT BIT(29) ++#define B_AX_STS_ON_TIMEOUT BIT(28) ++#define B_AX_DATA_ON_TIMEOUT BIT(27) ++#define B_AX_OFDM_CCA_TIMEOUT BIT(26) ++#define B_AX_CCK_CCA_TIMEOUT BIT(25) ++#define B_AXC_PHY_TXON_TIMEOUT BIT(24) ++#define B_AX_CSI_ON_TIMEOUT_INT_EN BIT(21) ++#define B_AX_STS_ON_TIMEOUT_INT_EN BIT(20) ++#define B_AX_DATA_ON_TIMEOUT_INT_EN BIT(19) ++#define B_AX_OFDM_CCA_TIMEOUT_INT_EN BIT(18) ++#define B_AX_CCK_CCA_TIMEOUT_INT_EN BIT(17) ++#define B_AX_PHY_TXON_TIMEOUT_INT_EN BIT(16) ++#define B_AX_PHYINTF_TIMEOUT_THR_MSAK GENMASK(5, 0) ++ ++#define R_AX_PHYINFO_ERR_ISR 0xCCFC ++#define R_AX_PHYINFO_ERR_ISR_C1 0xECFC ++ ++#define R_AX_BFMER_CTRL_0 0xCD78 ++#define R_AX_BFMER_CTRL_0_C1 0xED78 ++#define B_AX_BFMER_HE_CSI_OFFSET_MASK GENMASK(31, 24) ++#define B_AX_BFMER_VHT_CSI_OFFSET_MASK GENMASK(23, 16) ++#define B_AX_BFMER_HT_CSI_OFFSET_MASK GENMASK(15, 8) ++#define B_AX_BFMER_NDP_BFEN BIT(2) ++#define B_AX_BFMER_VHT_BFPRT_CHK BIT(0) ++ ++#define R_AX_BFMEE_RESP_OPTION 0xCD80 ++#define R_AX_BFMEE_RESP_OPTION_C1 0xED80 ++#define B_AX_BFMEE_NDP_RX_STANDBY_TIMER_MASK GENMASK(31, 24) ++#define B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK GENMASK(23, 20) ++#define B_AX_MU_BFRPTSEG_SEL_MASK GENMASK(18, 17) ++#define B_AX_BFMEE_NDP_RXSTDBY_SEL BIT(16) ++#define BFRP_RX_STANDBY_TIMER 0x0 ++#define NDP_RX_STANDBY_TIMER 0xFF ++#define B_AX_BFMEE_HE_NDPA_EN BIT(2) ++#define B_AX_BFMEE_VHT_NDPA_EN BIT(1) ++#define B_AX_BFMEE_HT_NDPA_EN BIT(0) ++ ++#define R_AX_TRXPTCL_RESP_CSI_CTRL_0 0xCD88 ++#define R_AX_TRXPTCL_RESP_CSI_CTRL_0_C1 0xED88 ++#define R_AX_TRXPTCL_RESP_CSI_CTRL_1 0xCD94 ++#define R_AX_TRXPTCL_RESP_CSI_CTRL_1_C1 0xED94 ++#define B_AX_BFMEE_CSISEQ_SEL BIT(29) ++#define B_AX_BFMEE_BFPARAM_SEL BIT(28) ++#define B_AX_BFMEE_OFDM_LEN_TH_MASK GENMASK(27, 24) ++#define B_AX_BFMEE_BF_PORT_SEL BIT(23) ++#define B_AX_BFMEE_USE_NSTS BIT(22) ++#define B_AX_BFMEE_CSI_RATE_FB_EN BIT(21) ++#define B_AX_BFMEE_CSI_GID_SEL BIT(20) ++#define B_AX_BFMEE_CSI_RSC_MASK GENMASK(19, 18) ++#define B_AX_BFMEE_CSI_FORCE_RETE_EN BIT(17) ++#define B_AX_BFMEE_CSI_USE_NDPARATE BIT(16) ++#define B_AX_BFMEE_CSI_WITHHTC_EN BIT(15) ++#define B_AX_BFMEE_CSIINFO0_BF_EN BIT(14) ++#define B_AX_BFMEE_CSIINFO0_STBC_EN BIT(13) ++#define B_AX_BFMEE_CSIINFO0_LDPC_EN BIT(12) ++#define B_AX_BFMEE_CSIINFO0_CS_MASK GENMASK(11, 10) ++#define B_AX_BFMEE_CSIINFO0_CB_MASK GENMASK(9, 8) ++#define B_AX_BFMEE_CSIINFO0_NG_MASK GENMASK(7, 6) ++#define B_AX_BFMEE_CSIINFO0_NR_MASK GENMASK(5, 3) ++#define B_AX_BFMEE_CSIINFO0_NC_MASK GENMASK(2, 0) ++ ++#define R_AX_TRXPTCL_RESP_CSI_RRSC 0xCD8C ++#define R_AX_TRXPTCL_RESP_CSI_RRSC_C1 0xED8C ++#define CSI_RRSC_BMAP 0x29292911 ++ ++#define R_AX_TRXPTCL_RESP_CSI_RATE 0xCD90 ++#define R_AX_TRXPTCL_RESP_CSI_RATE_C1 0xED90 ++#define B_AX_BFMEE_HE_CSI_RATE_MASK GENMASK(22, 16) ++#define B_AX_BFMEE_VHT_CSI_RATE_MASK GENMASK(14, 8) ++#define B_AX_BFMEE_HT_CSI_RATE_MASK GENMASK(6, 0) ++#define CSI_INIT_RATE_HE 0x3 ++#define CSI_INIT_RATE_VHT 0x3 ++#define CSI_INIT_RATE_HT 0x3 ++ ++#define R_AX_RCR 0xCE00 ++#define R_AX_RCR_C1 0xEE00 ++#define B_AX_STOP_RX_IN BIT(11) ++#define B_AX_DRV_INFO_SIZE_MASK GENMASK(10, 8) ++#define B_AX_CH_EN_MASK GENMASK(3, 0) ++ ++#define R_AX_DLK_PROTECT_CTL 0xCE02 ++#define R_AX_DLK_PROTECT_CTL_C1 0xEE02 ++#define B_AX_RX_DLK_CCA_TIME_MASK GENMASK(15, 8) ++#define B_AX_RX_DLK_DATA_TIME_MASK GENMASK(7, 4) ++ ++#define R_AX_PLCP_HDR_FLTR 0xCE04 ++#define R_AX_PLCP_HDR_FLTR_C1 0xEE04 ++#define B_AX_DIS_CHK_MIN_LEN BIT(8) ++#define B_AX_HE_SIGB_CRC_CHK BIT(6) ++#define B_AX_VHT_MU_SIGB_CRC_CHK BIT(5) ++#define B_AX_VHT_SU_SIGB_CRC_CHK BIT(4) ++#define B_AX_SIGA_CRC_CHK BIT(3) ++#define B_AX_LSIG_PARITY_CHK_EN BIT(2) ++#define B_AX_CCK_SIG_CHK BIT(1) ++#define B_AX_CCK_CRC_CHK BIT(0) ++ ++#define R_AX_RX_FLTR_OPT 0xCE20 ++#define R_AX_RX_FLTR_OPT_C1 0xEE20 ++#define B_AX_UID_FILTER_MASK GENMASK(31, 24) ++#define B_AX_UNSPT_FILTER_SH 22 ++#define B_AX_UNSPT_FILTER_MASK GENMASK(23, 22) ++#define B_AX_RX_MPDU_MAX_LEN_MASK GENMASK(21, 16) ++#define B_AX_RX_MPDU_MAX_LEN_SIZE 0x3f ++#define B_AX_A_FTM_REQ BIT(14) ++#define B_AX_A_ERR_PKT BIT(13) ++#define B_AX_A_UNSUP_PKT BIT(12) ++#define B_AX_A_CRC32_ERR BIT(11) ++#define B_AX_A_PWR_MGNT BIT(10) ++#define B_AX_A_BCN_CHK_RULE_MASK GENMASK(9, 8) ++#define B_AX_A_BCN_CHK_EN BIT(7) ++#define B_AX_A_MC_LIST_CAM_MATCH BIT(6) ++#define B_AX_A_BC_CAM_MATCH BIT(5) ++#define B_AX_A_UC_CAM_MATCH BIT(4) ++#define B_AX_A_MC BIT(3) ++#define B_AX_A_BC BIT(2) ++#define B_AX_A_A1_MATCH BIT(1) ++#define B_AX_SNIFFER_MODE BIT(0) ++#define DEFAULT_AX_RX_FLTR (B_AX_A_A1_MATCH | B_AX_A_BC | B_AX_A_MC | \ ++ B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH | \ ++ B_AX_A_PWR_MGNT | B_AX_A_FTM_REQ | \ ++ u32_encode_bits(3, B_AX_UID_FILTER_MASK) | \ ++ B_AX_A_BCN_CHK_EN) ++#define B_AX_RX_FLTR_CFG_MASK ((u32)~B_AX_RX_MPDU_MAX_LEN_MASK) ++ ++#define R_AX_CTRL_FLTR 0xCE24 ++#define R_AX_CTRL_FLTR_C1 0xEE24 ++#define R_AX_MGNT_FLTR 0xCE28 ++#define R_AX_MGNT_FLTR_C1 0xEE28 ++#define R_AX_DATA_FLTR 0xCE2C ++#define R_AX_DATA_FLTR_C1 0xEE2C ++#define RX_FLTR_FRAME_DROP 0x00000000 ++#define RX_FLTR_FRAME_TO_HOST 0x55555555 ++#define RX_FLTR_FRAME_TO_WLCPU 0xAAAAAAAA ++ ++#define R_AX_ADDR_CAM_CTRL 0xCE34 ++#define R_AX_ADDR_CAM_CTRL_C1 0xEE34 ++#define B_AX_ADDR_CAM_RANGE_MASK GENMASK(23, 16) ++#define B_AX_ADDR_CAM_CMPLIMT_MASK GENMASK(15, 12) ++#define B_AX_ADDR_CAM_CLR BIT(8) ++#define B_AX_ADDR_CAM_A2_B0_CHK BIT(2) ++#define B_AX_ADDR_CAM_SRCH_PERPKT BIT(1) ++#define B_AX_ADDR_CAM_EN BIT(0) ++ ++#define R_AX_RESPBA_CAM_CTRL 0xCE3C ++#define R_AX_RESPBA_CAM_CTRL_C1 0xEE3C ++#define B_AX_SSN_SEL BIT(2) ++ ++#define R_AX_PPDU_STAT 0xCE40 ++#define R_AX_PPDU_STAT_C1 0xEE40 ++#define B_AX_PPDU_STAT_RPT_TRIG BIT(8) ++#define B_AX_PPDU_STAT_RPT_CRC32 BIT(5) ++#define B_AX_PPDU_STAT_RPT_A1M BIT(4) ++#define B_AX_APP_PLCP_HDR_RPT BIT(3) ++#define B_AX_APP_RX_CNT_RPT BIT(2) ++#define B_AX_APP_MAC_INFO_RPT BIT(1) ++#define B_AX_PPDU_STAT_RPT_EN BIT(0) ++ ++#define R_AX_RX_SR_CTRL 0xCE4A ++#define R_AX_RX_SR_CTRL_C1 0xEE4A ++#define B_AX_SR_EN BIT(0) ++ ++#define R_AX_RX_STATE_MONITOR 0xCEF0 ++#define R_AX_RX_STATE_MONITOR_C1 0xEEF0 ++#define B_AX_RX_STATE_MONITOR_MASK GENMASK(31, 0) ++#define B_AX_STATE_CUR_MASK GENMASK(31, 16) ++#define B_AX_STATE_NXT_MASK GENMASK(13, 8) ++#define B_AX_STATE_UPD BIT(7) ++#define B_AX_STATE_SEL_MASK GENMASK(4, 0) ++ ++#define R_AX_RMAC_ERR_ISR 0xCEF4 ++#define R_AX_RMAC_ERR_ISR_C1 0xEEF4 ++#define B_AX_RXERR_INTPS_EN BIT(31) ++#define B_AX_RMAC_RX_CSI_TIMEOUT_INT_EN BIT(19) ++#define B_AX_RMAC_RX_TIMEOUT_INT_EN BIT(18) ++#define B_AX_RMAC_CSI_TIMEOUT_INT_EN BIT(17) ++#define B_AX_RMAC_DATA_ON_TIMEOUT_INT_EN BIT(16) ++#define B_AX_RMAC_CCA_TIMEOUT_INT_EN BIT(15) ++#define B_AX_RMAC_DMA_TIMEOUT_INT_EN BIT(14) ++#define B_AX_RMAC_DATA_ON_TO_IDLE_TIMEOUT_INT_EN BIT(13) ++#define B_AX_RMAC_CCA_TO_IDLE_TIMEOUT_INT_EN BIT(12) ++#define B_AX_RMAC_RX_CSI_TIMEOUT_FLAG BIT(7) ++#define B_AX_RMAC_RX_TIMEOUT_FLAG BIT(6) ++#define B_AX_BMAC_CSI_TIMEOUT_FLAG BIT(5) ++#define B_AX_BMAC_DATA_ON_TIMEOUT_FLAG BIT(4) ++#define B_AX_BMAC_CCA_TIMEOUT_FLAG BIT(3) ++#define B_AX_BMAC_DMA_TIMEOUT_FLAG BIT(2) ++#define B_AX_BMAC_DATA_ON_TO_IDLE_TIMEOUT_FLAG BIT(1) ++#define B_AX_BMAC_CCA_TO_IDLE_TIMEOUT_FLAG BIT(0) ++ ++#define R_AX_RMAC_PLCP_MON 0xCEF8 ++#define R_AX_RMAC_PLCP_MON_C1 0xEEF8 ++#define B_AX_RMAC_PLCP_MON_MASK GENMASK(31, 0) ++#define B_AX_PCLP_MON_SEL_MASK GENMASK(31, 28) ++#define B_AX_PCLP_MON_CONT_MASK GENMASK(27, 0) ++ ++#define R_AX_RX_DEBUG_SELECT 0xCEFC ++#define R_AX_RX_DEBUG_SELECT_C1 0xEEFC ++#define B_AX_DEBUG_SEL_MASK GENMASK(7, 0) ++ ++#define R_AX_PWR_RATE_CTRL 0xD200 ++#define R_AX_PWR_RATE_CTRL_C1 0xF200 ++#define B_AX_FORCE_PWR_BY_RATE_EN BIT(9) ++#define B_AX_FORCE_PWR_BY_RATE_VALUE_MASK GENMASK(8, 0) ++ ++#define R_AX_PWR_RATE_OFST_CTRL 0xD204 ++#define R_AX_PWR_COEXT_CTRL 0xD220 ++#define B_AX_TXAGC_BT_EN BIT(1) ++#define B_AX_TXAGC_BT_MASK GENMASK(11, 3) ++ ++#define R_AX_PWR_UL_CTRL0 0xD240 ++#define R_AX_PWR_UL_CTRL2 0xD248 ++#define B_AX_PWR_UL_CFO_MASK GENMASK(2, 0) ++#define B_AX_PWR_UL_CTRL2_MASK 0x07700007 ++#define R_AX_PWR_UL_TB_CTRL 0xD288 ++#define B_AX_PWR_UL_TB_CTRL_EN BIT(31) ++#define R_AX_PWR_UL_TB_1T 0xD28C ++#define B_AX_PWR_UL_TB_1T_MASK GENMASK(4, 0) ++#define R_AX_PWR_UL_TB_2T 0xD290 ++#define B_AX_PWR_UL_TB_2T_MASK GENMASK(4, 0) ++#define R_AX_PWR_BY_RATE_TABLE0 0xD2C0 ++#define R_AX_PWR_BY_RATE_TABLE10 0xD2E8 ++#define R_AX_PWR_BY_RATE R_AX_PWR_BY_RATE_TABLE0 ++#define R_AX_PWR_BY_RATE_MAX R_AX_PWR_BY_RATE_TABLE10 ++#define R_AX_PWR_LMT_TABLE0 0xD2EC ++#define R_AX_PWR_LMT_TABLE19 0xD338 ++#define R_AX_PWR_LMT R_AX_PWR_LMT_TABLE0 ++#define R_AX_PWR_LMT_MAX R_AX_PWR_LMT_TABLE19 ++#define R_AX_PWR_RU_LMT_TABLE0 0xD33C ++#define R_AX_PWR_RU_LMT_TABLE11 0xD368 ++#define R_AX_PWR_RU_LMT R_AX_PWR_RU_LMT_TABLE0 ++#define R_AX_PWR_RU_LMT_MAX R_AX_PWR_RU_LMT_TABLE11 ++#define R_AX_PWR_MACID_LMT_TABLE0 0xD36C ++#define R_AX_PWR_MACID_LMT_TABLE127 0xD568 ++ ++#define R_AX_TXPWR_IMR 0xD9E0 ++#define R_AX_TXPWR_IMR_C1 0xF9E0 ++#define R_AX_TXPWR_ISR 0xD9E4 ++#define R_AX_TXPWR_ISR_C1 0xF9E4 ++ ++#define R_AX_BTC_CFG 0xDA00 ++#define B_AX_DIS_BTC_CLK_G BIT(2) ++ ++#define R_AX_WL_PRI_MSK 0xDA10 ++#define B_AX_PTA_WL_PRI_MASK_BCNQ BIT(8) ++ ++#define R_AX_BTC_FUNC_EN 0xDA20 ++#define R_AX_BTC_FUNC_EN_C1 0xFA20 ++#define B_AX_PTA_WL_TX_EN BIT(1) ++#define B_AX_PTA_EDCCA_EN BIT(0) ++ ++#define R_BTC_BREAK_TABLE 0xDA2C ++#define BTC_BREAK_PARAM 0xf0ffffff ++ ++#define R_BTC_BT_COEX_MSK_TABLE 0xDA30 ++#define B_BTC_PRI_MASK_TX_RESP_V1 BIT(3) ++ ++#define R_AX_BT_COEX_CFG_2 0xDA34 ++#define R_AX_BT_COEX_CFG_2_C1 0xFA34 ++#define B_AX_GNT_BT_BYPASS_PRIORITY BIT(12) ++#define B_AX_GNT_BT_POLARITY BIT(8) ++#define B_AX_TIMER_MASK GENMASK(7, 0) ++#define MAC_AX_CSR_RATE 80 ++ ++#define R_AX_CSR_MODE 0xDA40 ++#define R_AX_CSR_MODE_C1 0xFA40 ++#define B_AX_BT_CNT_RST BIT(16) ++#define B_AX_BT_STAT_DELAY_MASK GENMASK(15, 12) ++#define MAC_AX_CSR_DELAY 0 ++#define B_AX_BT_TRX_INIT_DETECT_MASK GENMASK(11, 8) ++#define MAC_AX_CSR_TRX_TO 4 ++#define B_AX_BT_PRI_DETECT_TO_MASK GENMASK(7, 4) ++#define MAC_AX_CSR_PRI_TO 5 ++#define B_AX_WL_ACT_MSK BIT(3) ++#define B_AX_STATIS_BT_EN BIT(2) ++#define B_AX_WL_ACT_MASK_ENABLE BIT(1) ++#define B_AX_ENHANCED_BT BIT(0) ++ ++#define R_AX_BT_STAST_HIGH 0xDA44 ++#define B_AX_STATIS_BT_HI_RX_MASK GENMASK(31, 16) ++#define B_AX_STATIS_BT_HI_TX_MASK GENMASK(15, 0) ++#define R_AX_BT_STAST_LOW 0xDA48 ++#define B_AX_STATIS_BT_LO_TX_1_MASK GENMASK(15, 0) ++#define B_AX_STATIS_BT_LO_RX_1_MASK GENMASK(31, 16) ++ ++#define R_AX_TDMA_MODE 0xDA4C ++#define R_AX_TDMA_MODE_C1 0xFA4C ++#define B_AX_R_BT_CMD_RPT_MASK GENMASK(31, 16) ++#define B_AX_R_RPT_FROM_BT_MASK GENMASK(15, 8) ++#define B_AX_BT_HID_ISR_SET_MASK GENMASK(7, 6) ++#define B_AX_TDMA_BT_START_NOTIFY BIT(5) ++#define B_AX_ENABLE_TDMA_FW_MODE BIT(4) ++#define B_AX_ENABLE_PTA_TDMA_MODE BIT(3) ++#define B_AX_ENABLE_COEXIST_TAB_IN_TDMA BIT(2) ++#define B_AX_GPIO2_GPIO3_EXANGE_OR_NO_BT_CCA BIT(1) ++#define B_AX_RTK_BT_ENABLE BIT(0) ++ ++#define R_AX_BT_COEX_CFG_5 0xDA6C ++#define R_AX_BT_COEX_CFG_5_C1 0xFA6C ++#define B_AX_BT_TIME_MASK GENMASK(31, 6) ++#define B_AX_BT_RPT_SAMPLE_RATE_MASK GENMASK(5, 0) ++#define MAC_AX_RTK_RATE 5 ++ ++#define R_AX_LTE_CTRL 0xDAF0 ++#define R_AX_LTE_WDATA 0xDAF4 ++#define R_AX_LTE_RDATA 0xDAF8 ++ ++#define CMAC1_START_ADDR 0xE000 ++#define CMAC1_END_ADDR 0xFFFF ++#define R_AX_CMAC_REG_END 0xFFFF ++ ++#define R_AX_LTE_SW_CFG_1 0x0038 ++#define R_AX_LTE_SW_CFG_1_C1 0x2038 ++#define B_AX_GNT_BT_RFC_S1_SW_VAL BIT(31) ++#define B_AX_GNT_BT_RFC_S1_SW_CTRL BIT(30) ++#define B_AX_GNT_WL_RFC_S1_SW_VAL BIT(29) ++#define B_AX_GNT_WL_RFC_S1_SW_CTRL BIT(28) ++#define B_AX_GNT_BT_BB_S1_SW_VAL BIT(27) ++#define B_AX_GNT_BT_BB_S1_SW_CTRL BIT(26) ++#define B_AX_GNT_WL_BB_S1_SW_VAL BIT(25) ++#define B_AX_GNT_WL_BB_S1_SW_CTRL BIT(24) ++#define B_AX_BT_SW_CTRL_WL_PRIORITY BIT(19) ++#define B_AX_WL_SW_CTRL_WL_PRIORITY BIT(18) ++#define B_AX_LTE_PATTERN_2_EN BIT(17) ++#define B_AX_LTE_PATTERN_1_EN BIT(16) ++#define B_AX_GNT_BT_RFC_S0_SW_VAL BIT(15) ++#define B_AX_GNT_BT_RFC_S0_SW_CTRL BIT(14) ++#define B_AX_GNT_WL_RFC_S0_SW_VAL BIT(13) ++#define B_AX_GNT_WL_RFC_S0_SW_CTRL BIT(12) ++#define B_AX_GNT_BT_BB_S0_SW_VAL BIT(11) ++#define B_AX_GNT_BT_BB_S0_SW_CTRL BIT(10) ++#define B_AX_GNT_WL_BB_S0_SW_VAL BIT(9) ++#define B_AX_GNT_WL_BB_S0_SW_CTRL BIT(8) ++#define B_AX_LTECOEX_FUN_EN BIT(7) ++#define B_AX_LTECOEX_3WIRE_CTRL_MUX BIT(6) ++#define B_AX_LTECOEX_OP_MODE_SEL_MASK GENMASK(5, 4) ++#define B_AX_LTECOEX_UART_MUX BIT(3) ++#define B_AX_LTECOEX_UART_MODE_SEL_MASK GENMASK(2, 0) ++ ++#define R_AX_LTE_SW_CFG_2 0x003C ++#define R_AX_LTE_SW_CFG_2_C1 0x203C ++#define B_AX_WL_RX_CTRL BIT(8) ++#define B_AX_GNT_WL_RX_SW_VAL BIT(7) ++#define B_AX_GNT_WL_RX_SW_CTRL BIT(6) ++#define B_AX_GNT_WL_TX_SW_VAL BIT(5) ++#define B_AX_GNT_WL_TX_SW_CTRL BIT(4) ++#define B_AX_GNT_BT_RX_SW_VAL BIT(3) ++#define B_AX_GNT_BT_RX_SW_CTRL BIT(2) ++#define B_AX_GNT_BT_TX_SW_VAL BIT(1) ++#define B_AX_GNT_BT_TX_SW_CTRL BIT(0) ++ ++#define RR_MOD 0x00 ++#define RR_MOD_IQK GENMASK(19, 4) ++#define RR_MOD_DPK GENMASK(19, 5) ++#define RR_MOD_MASK GENMASK(19, 16) ++#define RR_MOD_V_DOWN 0x0 ++#define RR_MOD_V_STANDBY 0x1 ++#define RR_MOD_V_TX 0x2 ++#define RR_MOD_V_RX 0x3 ++#define RR_MOD_V_TXIQK 0x4 ++#define RR_MOD_V_DPK 0x5 ++#define RR_MOD_V_RXK1 0x6 ++#define RR_MOD_V_RXK2 0x7 ++#define RR_MOD_M_RXG GENMASK(13, 4) ++#define RR_MOD_M_RXBB GENMASK(9, 5) ++#define RR_MODOPT 0x01 ++#define RR_MODOPT_M_TXPWR GENMASK(5, 0) ++#define RR_WLSEL 0x02 ++#define RR_WLSEL_AG GENMASK(18, 16) ++#define RR_RSV1 0x05 ++#define RR_RSV1_RST BIT(0) ++#define RR_DTXLOK 0x08 ++#define RR_RSV2 0x09 ++#define RR_CFGCH 0x18 ++#define RR_BTC 0x1a ++#define RR_BTC_TXBB GENMASK(14, 12) ++#define RR_BTC_RXBB GENMASK(11, 10) ++#define RR_RCKC 0x1b ++#define RR_RCKC_CA GENMASK(14, 10) ++#define RR_RCKS 0x1c ++#define RR_RCKO 0x1d ++#define RR_RCKO_OFF GENMASK(13, 9) ++#define RR_RXKPLL 0x1e ++#define RR_RXKPLL_OFF GENMASK(5, 0) ++#define RR_RXKPLL_POW BIT(19) ++#define RR_RSV4 0x1f ++#define RR_RXK 0x20 ++#define RR_RXK_PLLEN BIT(5) ++#define RR_RXK_SEL5G BIT(7) ++#define RR_RXK_SEL2G BIT(8) ++#define RR_LUTWA 0x33 ++#define RR_LUTWA_MASK GENMASK(9, 0) ++#define RR_LUTWD1 0x3e ++#define RR_LUTWD0 0x3f ++#define RR_TM 0x42 ++#define RR_TM_TRI BIT(19) ++#define RR_TM_VAL GENMASK(6, 1) ++#define RR_TM2 0x43 ++#define RR_TM2_OFF GENMASK(19, 16) ++#define RR_TXG1 0x51 ++#define RR_TXG1_ATT2 BIT(19) ++#define RR_TXG1_ATT1 BIT(11) ++#define RR_TXG2 0x52 ++#define RR_TXG2_ATT0 BIT(11) ++#define RR_BSPAD 0x54 ++#define RR_TXGA 0x55 ++#define RR_TXGA_LOK_EN BIT(0) ++#define RR_TXGA_TRK_EN BIT(7) ++#define RR_GAINTX 0x56 ++#define RR_GAINTX_ALL GENMASK(15, 0) ++#define RR_GAINTX_PAD GENMASK(9, 5) ++#define RR_GAINTX_BB GENMASK(4, 0) ++#define RR_TXMO 0x58 ++#define RR_TXMO_COI GENMASK(19, 15) ++#define RR_TXMO_COQ GENMASK(14, 10) ++#define RR_TXMO_FII GENMASK(9, 6) ++#define RR_TXMO_FIQ GENMASK(5, 2) ++#define RR_TXA 0x5d ++#define RR_TXA_TRK GENMASK(19, 14) ++#define RR_TXRSV 0x5c ++#define RR_TXRSV_GAPK BIT(19) ++#define RR_BIAS 0x5e ++#define RR_BIAS_GAPK BIT(19) ++#define RR_BIASA 0x60 ++#define RR_BIASA_TXG GENMASK(15, 12) ++#define RR_BIASA_TXA GENMASK(19, 16) ++#define RR_BIASA_A GENMASK(2, 0) ++#define RR_BIASA2 0x63 ++#define RR_BIASA2_LB GENMASK(4, 2) ++#define RR_TXATANK 0x64 ++#define RR_TXATANK_LBSW GENMASK(16, 15) ++#define RR_TRXIQ 0x66 ++#define RR_RSV6 0x6d ++#define RR_TXPOW 0x7f ++#define RR_TXPOW_TXG BIT(1) ++#define RR_TXPOW_TXA BIT(8) ++#define RR_RXPOW 0x80 ++#define RR_RXPOW_IQK GENMASK(17, 16) ++#define RR_RXBB 0x83 ++#define RR_RXBB_C2G GENMASK(16, 10) ++#define RR_RXBB_C1G GENMASK(9, 8) ++#define RR_RXBB_ATTR GENMASK(7, 4) ++#define RR_RXBB_ATTC GENMASK(2, 0) ++#define RR_XGLNA2 0x85 ++#define RR_XGLNA2_SW GENMASK(1, 0) ++#define RR_RXA 0x8a ++#define RR_RXA_DPK GENMASK(9, 8) ++#define RR_RXA2 0x8c ++#define RR_RXA2_C2 GENMASK(9, 3) ++#define RR_RXA2_C1 GENMASK(12, 10) ++#define RR_RXIQGEN 0x8d ++#define RR_RXIQGEN_ATTL GENMASK(12, 8) ++#define RR_RXIQGEN_ATTH GENMASK(14, 13) ++#define RR_RXBB2 0x8f ++#define RR_EN_TIA_IDA GENMASK(11, 10) ++#define RR_RXBB2_DAC_EN BIT(13) ++#define RR_XALNA2 0x90 ++#define RR_XALNA2_SW GENMASK(1, 0) ++#define RR_DCK 0x92 ++#define RR_DCK_FINE BIT(1) ++#define RR_DCK_LV BIT(0) ++#define RR_DCK1 0x93 ++#define RR_DCK1_SEL BIT(3) ++#define RR_DCK2 0x94 ++#define RR_DCK2_CYCLE GENMASK(7, 2) ++#define RR_MIXER 0x9f ++#define RR_MIXER_GN GENMASK(4, 3) ++#define RR_XTALX2 0xb8 ++#define RR_MALSEL 0xbe ++#define RR_RCKD 0xde ++#define RR_RCKD_POW GENMASK(19, 13) ++#define RR_RCKD_BW BIT(2) ++#define RR_TXADBG 0xde ++#define RR_LUTDBG 0xdf ++#define RR_LUTDBG_LOK BIT(2) ++#define RR_LUTWE2 0xee ++#define RR_LUTWE 0xef ++#define RR_LUTWE_LOK BIT(2) ++#define RR_RFC 0xf0 ++#define RR_RFC_CKEN BIT(1) ++ ++#define R_UPD_P0 0x0000 ++#define R_RSTB_WATCH_DOG 0x000C ++#define B_P0_RSTB_WATCH_DOG BIT(0) ++#define B_P1_RSTB_WATCH_DOG BIT(1) ++#define B_UPD_P0_EN BIT(30) ++#define R_ANAPAR_PW15 0x030C ++#define B_ANAPAR_PW15 GENMASK(31, 24) ++#define B_ANAPAR_PW15_H GENMASK(27, 24) ++#define B_ANAPAR_PW15_H2 GENMASK(27, 26) ++#define R_ANAPAR 0x032C ++#define B_ANAPAR_15 GENMASK(31, 16) ++#define B_ANAPAR_ADCCLK BIT(30) ++#define B_ANAPAR_FLTRST BIT(22) ++#define B_ANAPAR_CRXBB GENMASK(18, 16) ++#define B_ANAPAR_14 GENMASK(15, 0) ++#define R_UPD_CLK_ADC 0x0700 ++#define B_UPD_CLK_ADC_ON BIT(24) ++#define B_UPD_CLK_ADC_VAL GENMASK(26, 25) ++#define R_RSTB_ASYNC 0x0704 ++#define B_RSTB_ASYNC_ALL BIT(1) ++#define R_PMAC_GNT 0x0980 ++#define B_PMAC_GNT_TXEN BIT(0) ++#define B_PMAC_GNT_RXEN BIT(16) ++#define B_PMAC_GNT_P1 GENMASK(20, 17) ++#define B_PMAC_GNT_P2 GENMASK(29, 26) ++#define R_PMAC_RX_CFG1 0x0988 ++#define B_PMAC_OPT1_MSK GENMASK(11, 0) ++#define R_PMAC_RXMOD 0x0994 ++#define B_PMAC_RXMOD_MSK GENMASK(7, 4) ++#define R_MAC_SEL 0x09A4 ++#define B_MAC_SEL_MOD GENMASK(4, 2) ++#define B_MAC_SEL_DPD_EN BIT(10) ++#define B_MAC_SEL_PWR_EN BIT(16) ++#define R_PMAC_TX_CTRL 0x09C0 ++#define B_PMAC_TXEN_DIS BIT(0) ++#define R_PMAC_TX_PRD 0x09C4 ++#define B_PMAC_TX_PRD_MSK GENMASK(31, 8) ++#define B_PMAC_CTX_EN BIT(0) ++#define B_PMAC_PTX_EN BIT(4) ++#define R_PMAC_TX_CNT 0x09C8 ++#define B_PMAC_TX_CNT_MSK GENMASK(31, 0) ++#define R_CCX 0x0C00 ++#define B_CCX_EDCCA_OPT_MSK GENMASK(6, 4) ++#define B_MEASUREMENT_TRIG_MSK BIT(2) ++#define B_CCX_TRIG_OPT_MSK BIT(1) ++#define B_CCX_EN_MSK BIT(0) ++#define R_IFS_COUNTER 0x0C28 ++#define B_IFS_CLM_PERIOD_MSK GENMASK(31, 16) ++#define B_IFS_CLM_COUNTER_UNIT_MSK GENMASK(15, 14) ++#define B_IFS_COUNTER_CLR_MSK BIT(13) ++#define B_IFS_COLLECT_EN BIT(12) ++#define R_IFS_T1 0x0C2C ++#define B_IFS_T1_TH_HIGH_MSK GENMASK(31, 16) ++#define B_IFS_T1_EN_MSK BIT(15) ++#define B_IFS_T1_TH_LOW_MSK GENMASK(14, 0) ++#define R_IFS_T2 0x0C30 ++#define B_IFS_T2_TH_HIGH_MSK GENMASK(31, 16) ++#define B_IFS_T2_EN_MSK BIT(15) ++#define B_IFS_T2_TH_LOW_MSK GENMASK(14, 0) ++#define R_IFS_T3 0x0C34 ++#define B_IFS_T3_TH_HIGH_MSK GENMASK(31, 16) ++#define B_IFS_T3_EN_MSK BIT(15) ++#define B_IFS_T3_TH_LOW_MSK GENMASK(14, 0) ++#define R_IFS_T4 0x0C38 ++#define B_IFS_T4_TH_HIGH_MSK GENMASK(31, 16) ++#define B_IFS_T4_EN_MSK BIT(15) ++#define B_IFS_T4_TH_LOW_MSK GENMASK(14, 0) ++#define R_PD_CTRL 0x0C3C ++#define B_PD_HIT_DIS BIT(9) ++#define R_IOQ_IQK_DPK 0x0C60 ++#define B_IOQ_IQK_DPK_EN BIT(1) ++#define R_P0_EN_SOUND_WO_NDP 0x0D7C ++#define B_P0_EN_SOUND_WO_NDP BIT(1) ++#define R_SPOOF_ASYNC_RST 0x0D84 ++#define B_SPOOF_ASYNC_RST BIT(15) ++#define R_NDP_BRK0 0xDA0 ++#define R_NDP_BRK1 0xDA4 ++#define B_NDP_RU_BRK BIT(0) ++#define R_BRK_ASYNC_RST_EN_1 0x0DC0 ++#define R_BRK_ASYNC_RST_EN_2 0x0DC4 ++#define R_BRK_ASYNC_RST_EN_3 0x0DC8 ++#define R_P0_RXCK 0x12A0 ++#define B_P0_RXCK_VAL GENMASK(18, 16) ++#define B_P0_RXCK_ON BIT(19) ++#define B_P0_RXCK_BW3 BIT(30) ++#define R_P0_NRBW 0x12B8 ++#define B_P0_NRBW_DBG BIT(30) ++#define R_S0_RXDC 0x12D4 ++#define B_S0_RXDC_I GENMASK(25, 16) ++#define B_S0_RXDC_Q GENMASK(31, 26) ++#define R_S0_RXDC2 0x12D8 ++#define B_S0_RXDC2_SEL GENMASK(9, 8) ++#define B_S0_RXDC2_AVG GENMASK(7, 6) ++#define B_S0_RXDC2_MEN GENMASK(5, 4) ++#define B_S0_RXDC2_Q2 GENMASK(3, 0) ++#define R_CFO_COMP_SEG0_L 0x1384 ++#define R_CFO_COMP_SEG0_H 0x1388 ++#define R_CFO_COMP_SEG0_CTRL 0x138C ++#define R_DBG32_D 0x1730 ++#define R_TX_COUNTER 0x1A40 ++#define R_IFS_CLM_TX_CNT 0x1ACC ++#define B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK GENMASK(31, 16) ++#define B_IFS_CLM_TX_CNT_MSK GENMASK(15, 0) ++#define R_IFS_CLM_CCA 0x1AD0 ++#define B_IFS_CLM_OFDMCCA_EXCLUDE_FA_MSK GENMASK(31, 16) ++#define B_IFS_CLM_CCKCCA_EXCLUDE_FA_MSK GENMASK(15, 0) ++#define R_IFS_CLM_FA 0x1AD4 ++#define B_IFS_CLM_OFDM_FA_MSK GENMASK(31, 16) ++#define B_IFS_CLM_CCK_FA_MSK GENMASK(15, 0) ++#define R_IFS_HIS 0x1AD8 ++#define B_IFS_T4_HIS_MSK GENMASK(31, 24) ++#define B_IFS_T3_HIS_MSK GENMASK(23, 16) ++#define B_IFS_T2_HIS_MSK GENMASK(15, 8) ++#define B_IFS_T1_HIS_MSK GENMASK(7, 0) ++#define R_IFS_AVG_L 0x1ADC ++#define B_IFS_T2_AVG_MSK GENMASK(31, 16) ++#define B_IFS_T1_AVG_MSK GENMASK(15, 0) ++#define R_IFS_AVG_H 0x1AE0 ++#define B_IFS_T4_AVG_MSK GENMASK(31, 16) ++#define B_IFS_T3_AVG_MSK GENMASK(15, 0) ++#define R_IFS_CCA_L 0x1AE4 ++#define B_IFS_T2_CCA_MSK GENMASK(31, 16) ++#define B_IFS_T1_CCA_MSK GENMASK(15, 0) ++#define R_IFS_CCA_H 0x1AE8 ++#define B_IFS_T4_CCA_MSK GENMASK(31, 16) ++#define B_IFS_T3_CCA_MSK GENMASK(15, 0) ++#define R_IFSCNT 0x1AEC ++#define B_IFSCNT_DONE_MSK BIT(16) ++#define B_IFSCNT_TOTAL_CNT_MSK GENMASK(15, 0) ++#define R_TXAGC_TP 0x1C04 ++#define B_TXAGC_TP GENMASK(2, 0) ++#define R_TSSI_THER 0x1C10 ++#define B_TSSI_THER GENMASK(29, 24) ++#define R_TXAGC_BB 0x1C60 ++#define B_TXAGC_BB_OFT GENMASK(31, 16) ++#define B_TXAGC_BB GENMASK(31, 24) ++#define R_S0_ADDCK 0x1E00 ++#define B_S0_ADDCK_I GENMASK(9, 0) ++#define B_S0_ADDCK_Q GENMASK(19, 10) ++#define R_ADC_FIFO 0x20fc ++#define B_ADC_FIFO_RST GENMASK(31, 24) ++#define R_TXFIR0 0x2300 ++#define B_TXFIR_C01 GENMASK(23, 0) ++#define R_TXFIR2 0x2304 ++#define B_TXFIR_C23 GENMASK(23, 0) ++#define R_TXFIR4 0x2308 ++#define B_TXFIR_C45 GENMASK(23, 0) ++#define R_TXFIR6 0x230c ++#define B_TXFIR_C67 GENMASK(23, 0) ++#define R_TXFIR8 0x2310 ++#define B_TXFIR_C89 GENMASK(23, 0) ++#define R_TXFIRA 0x2314 ++#define B_TXFIR_CAB GENMASK(23, 0) ++#define R_TXFIRC 0x2318 ++#define B_TXFIR_CCD GENMASK(23, 0) ++#define R_TXFIRE 0x231c ++#define B_TXFIR_CEF GENMASK(23, 0) ++#define R_RXCCA 0x2344 ++#define B_RXCCA_DIS BIT(31) ++#define R_RXSC 0x237C ++#define B_RXSC_EN BIT(0) ++#define R_RXSCOBC 0x23B0 ++#define B_RXSCOBC_TH GENMASK(18, 0) ++#define R_RXSCOCCK 0x23B4 ++#define B_RXSCOCCK_TH GENMASK(18, 0) ++#define R_P1_EN_SOUND_WO_NDP 0x2D7C ++#define B_P1_EN_SOUND_WO_NDP BIT(1) ++#define R_P1_DBGMOD 0x32B8 ++#define B_P1_DBGMOD_ON BIT(30) ++#define R_S1_RXDC 0x32D4 ++#define B_S1_RXDC_I GENMASK(25, 16) ++#define B_S1_RXDC_Q GENMASK(31, 26) ++#define R_S1_RXDC2 0x32D8 ++#define B_S1_RXDC2_EN GENMASK(5, 4) ++#define B_S1_RXDC2_SEL GENMASK(9, 8) ++#define B_S1_RXDC2_Q2 GENMASK(3, 0) ++#define R_TXAGC_BB_S1 0x3C60 ++#define B_TXAGC_BB_S1_OFT GENMASK(31, 16) ++#define B_TXAGC_BB_S1 GENMASK(31, 24) ++#define R_S1_ADDCK 0x3E00 ++#define B_S1_ADDCK_I GENMASK(9, 0) ++#define B_S1_ADDCK_Q GENMASK(19, 10) ++#define R_DCFO 0x4264 ++#define B_DCFO GENMASK(1, 0) ++#define R_SEG0CSI 0x42AC ++#define B_SEG0CSI_IDX GENMASK(10, 0) ++#define R_SEG0CSI_EN 0x42C4 ++#define B_SEG0CSI_EN BIT(23) ++#define R_BSS_CLR_MAP 0x43ac ++#define B_BSS_CLR_MAP_VLD0 BIT(28) ++#define B_BSS_CLR_MAP_TGT GENMASK(27, 22) ++#define B_BSS_CLR_MAP_STAID GENMASK(21, 11) ++#define R_CFO_TRK0 0x4404 ++#define R_CFO_TRK1 0x440C ++#define B_CFO_TRK_MSK GENMASK(14, 10) ++#define R_DCFO_COMP_S0 0x448C ++#define B_DCFO_COMP_S0_MSK GENMASK(11, 0) ++#define R_DCFO_WEIGHT 0x4490 ++#define B_DCFO_WEIGHT_MSK GENMASK(27, 24) ++#define R_DCFO_OPT 0x4494 ++#define B_DCFO_OPT_EN BIT(29) ++#define R_BANDEDGE 0x4498 ++#define B_BANDEDGE_EN BIT(30) ++#define R_TXPATH_SEL 0x458C ++#define B_TXPATH_SEL_MSK GENMASK(31, 28) ++#define R_TXPWR 0x4594 ++#define B_TXPWR_MSK GENMASK(30, 22) ++#define R_TXNSS_MAP 0x45B4 ++#define B_TXNSS_MAP_MSK GENMASK(20, 17) ++#define R_PATH0_IB_PKPW 0x4628 ++#define B_PATH0_IB_PKPW_MSK GENMASK(11, 6) ++#define R_PATH0_LNA_ERR1 0x462C ++#define B_PATH0_LNA_ERR_G1_A_MSK GENMASK(29, 24) ++#define B_PATH0_LNA_ERR_G0_G_MSK GENMASK(17, 12) ++#define B_PATH0_LNA_ERR_G0_A_MSK GENMASK(11, 6) ++#define R_PATH0_LNA_ERR2 0x4630 ++#define B_PATH0_LNA_ERR_G2_G_MSK GENMASK(23, 18) ++#define B_PATH0_LNA_ERR_G2_A_MSK GENMASK(17, 12) ++#define B_PATH0_LNA_ERR_G1_G_MSK GENMASK(5, 0) ++#define R_PATH0_LNA_ERR3 0x4634 ++#define B_PATH0_LNA_ERR_G4_G_MSK GENMASK(29, 24) ++#define B_PATH0_LNA_ERR_G4_A_MSK GENMASK(23, 18) ++#define B_PATH0_LNA_ERR_G3_G_MSK GENMASK(11, 6) ++#define B_PATH0_LNA_ERR_G3_A_MSK GENMASK(5, 0) ++#define R_PATH0_LNA_ERR4 0x4638 ++#define B_PATH0_LNA_ERR_G6_A_MSK GENMASK(29, 24) ++#define B_PATH0_LNA_ERR_G5_G_MSK GENMASK(17, 12) ++#define B_PATH0_LNA_ERR_G5_A_MSK GENMASK(11, 6) ++#define R_PATH0_LNA_ERR5 0x463C ++#define B_PATH0_LNA_ERR_G6_G_MSK GENMASK(5, 0) ++#define R_PATH0_TIA_ERR_G0 0x4640 ++#define B_PATH0_TIA_ERR_G0_G_MSK GENMASK(23, 18) ++#define B_PATH0_TIA_ERR_G0_A_MSK GENMASK(17, 12) ++#define R_PATH0_TIA_ERR_G1 0x4644 ++#define B_PATH0_TIA_ERR_G1_SEL GENMASK(31, 30) ++#define B_PATH0_TIA_ERR_G1_G_MSK GENMASK(11, 6) ++#define B_PATH0_TIA_ERR_G1_A_MSK GENMASK(5, 0) ++#define R_PATH0_IB_PBK 0x4650 ++#define B_PATH0_IB_PBK_MSK GENMASK(14, 10) ++#define R_PATH0_RXB_INIT 0x4658 ++#define B_PATH0_RXB_INIT_IDX_MSK GENMASK(9, 5) ++#define R_PATH0_LNA_INIT 0x4668 ++#define B_PATH0_LNA_INIT_IDX_MSK GENMASK(26, 24) ++#define R_PATH0_BTG 0x466C ++#define B_PATH0_BTG_SHEN GENMASK(18, 17) ++#define R_PATH0_TIA_INIT 0x4674 ++#define B_PATH0_TIA_INIT_IDX_MSK BIT(17) ++#define R_PATH0_P20_FOLLOW_BY_PAGCUGC 0x46A0 ++#define B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) ++#define R_PATH0_S20_FOLLOW_BY_PAGCUGC 0x46A4 ++#define B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) ++#define R_P0_NBIIDX 0x469C ++#define B_P0_NBIIDX_VAL GENMASK(11, 0) ++#define B_P0_NBIIDX_NOTCH_EN BIT(12) ++#define R_P1_MODE 0x4718 ++#define B_P1_MODE_SEL GENMASK(31, 30) ++#define R_PATH1_LNA_INIT 0x473C ++#define B_PATH1_LNA_INIT_IDX_MSK GENMASK(26, 24) ++#define R_PATH1_TIA_INIT 0x4748 ++#define B_PATH1_TIA_INIT_IDX_MSK BIT(17) ++#define R_PATH1_BTG 0x4740 ++#define B_PATH1_BTG_SHEN GENMASK(18, 17) ++#define R_PATH1_RXB_INIT 0x472C ++#define B_PATH1_RXB_INIT_IDX_MSK GENMASK(9, 5) ++#define R_PATH1_P20_FOLLOW_BY_PAGCUGC 0x4774 ++#define B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) ++#define R_PATH1_S20_FOLLOW_BY_PAGCUGC 0x4778 ++#define B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) ++#define R_P1_NBIIDX 0x4770 ++#define B_P1_NBIIDX_VAL GENMASK(11, 0) ++#define B_P1_NBIIDX_NOTCH_EN BIT(12) ++#define R_SEG0R_PD 0x481C ++#define B_SEG0R_PD_SPATIAL_REUSE_EN_MSK BIT(29) ++#define B_SEG0R_PD_LOWER_BOUND_MSK GENMASK(10, 6) ++#define R_2P4G_BAND 0x4970 ++#define B_2P4G_BAND_SEL BIT(1) ++#define R_FC0_BW 0x4974 ++#define B_FC0_BW_INV GENMASK(6, 0) ++#define B_FC0_BW_SET GENMASK(31, 30) ++#define R_CHBW_MOD 0x4978 ++#define B_CHBW_MOD_PRICH GENMASK(11, 8) ++#define B_CHBW_MOD_SBW GENMASK(13, 12) ++#define R_CFO_COMP_SEG1_L 0x5384 ++#define R_CFO_COMP_SEG1_H 0x5388 ++#define R_CFO_COMP_SEG1_CTRL 0x538C ++#define B_CFO_COMP_VALID_BIT BIT(29) ++#define B_CFO_COMP_WEIGHT_MSK GENMASK(27, 24) ++#define B_CFO_COMP_VAL_MSK GENMASK(11, 0) ++#define R_DPD_OFT_EN 0x5800 ++#define B_DPD_OFT_EN BIT(28) ++#define R_DPD_OFT_ADDR 0x5804 ++#define B_DPD_OFT_ADDR GENMASK(31, 27) ++#define R_P0_TMETER 0x5810 ++#define B_P0_TMETER GENMASK(15, 10) ++#define B_P0_TMETER_DIS BIT(16) ++#define B_P0_TMETER_TRK BIT(24) ++#define R_P0_TSSI_TRK 0x5818 ++#define B_P0_TSSI_TRK_EN BIT(30) ++#define B_P0_TSSI_OFT_EN BIT(28) ++#define B_P0_TSSI_OFT GENMASK(7, 0) ++#define R_P0_TSSI_AVG 0x5820 ++#define B_P0_TSSI_AVG GENMASK(15, 12) ++#define R_P0_RFCTM 0x5864 ++#define B_P0_RFCTM_VAL GENMASK(25, 20) ++#define R_P0_RFCTM_RDY BIT(26) ++#define R_P0_TXDPD 0x58D4 ++#define B_P0_TXDPD GENMASK(31, 28) ++#define R_P0_TXPW_RSTB 0x58DC ++#define B_P0_TXPW_RSTB_MANON BIT(30) ++#define B_P0_TXPW_RSTB_TSSI BIT(31) ++#define R_P0_TSSI_MV_AVG 0x58E4 ++#define B_P0_TSSI_MV_AVG GENMASK(13, 11) ++#define R_TXGAIN_SCALE 0x58F0 ++#define B_TXGAIN_SCALE_EN BIT(19) ++#define B_TXGAIN_SCALE_OFT GENMASK(31, 24) ++#define R_P0_TSSI_BASE 0x5C00 ++#define R_S0_DACKI 0x5E00 ++#define B_S0_DACKI_AR GENMASK(31, 28) ++#define B_S0_DACKI_EN BIT(3) ++#define R_S0_DACKI2 0x5E30 ++#define B_S0_DACKI2_K GENMASK(21, 12) ++#define R_S0_DACKI7 0x5E44 ++#define B_S0_DACKI7_K GENMASK(15, 8) ++#define R_S0_DACKI8 0x5E48 ++#define B_S0_DACKI8_K GENMASK(15, 8) ++#define R_S0_DACKQ 0x5E50 ++#define B_S0_DACKQ_AR GENMASK(31, 28) ++#define B_S0_DACKQ_EN BIT(3) ++#define R_S0_DACKQ2 0x5E80 ++#define B_S0_DACKQ2_K GENMASK(21, 12) ++#define R_S0_DACKQ7 0x5E94 ++#define B_S0_DACKQ7_K GENMASK(15, 8) ++#define R_S0_DACKQ8 0x5E98 ++#define B_S0_DACKQ8_K GENMASK(15, 8) ++#define R_P1_TMETER 0x7810 ++#define B_P1_TMETER GENMASK(15, 10) ++#define B_P1_TMETER_DIS BIT(16) ++#define B_P1_TMETER_TRK BIT(24) ++#define R_P1_TSSI_TRK 0x7818 ++#define B_P1_TSSI_TRK_EN BIT(30) ++#define B_P1_TSSI_OFT_EN BIT(28) ++#define B_P1_TSSI_OFT GENMASK(7, 0) ++#define R_P1_TSSI_AVG 0x7820 ++#define B_P1_TSSI_AVG GENMASK(15, 12) ++#define R_P1_RFCTM 0x7864 ++#define R_P1_RFCTM_RDY BIT(26) ++#define B_P1_RFCTM_VAL GENMASK(25, 20) ++#define R_P1_TXPW_RSTB 0x78DC ++#define B_P1_TXPW_RSTB_MANON BIT(30) ++#define B_P1_TXPW_RSTB_TSSI BIT(31) ++#define R_P1_TSSI_MV_AVG 0x78E4 ++#define B_P1_TSSI_MV_AVG GENMASK(13, 11) ++#define R_TSSI_THOF 0x7C00 ++#define R_S1_DACKI 0x7E00 ++#define B_S1_DACKI_AR GENMASK(31, 28) ++#define B_S1_DACKI_EN BIT(3) ++#define R_S1_DACKI2 0x7E30 ++#define B_S1_DACKI2_K GENMASK(21, 12) ++#define R_S1_DACKI7 0x7E44 ++#define B_S1_DACKI_K GENMASK(15, 8) ++#define R_S1_DACKI8 0x7E48 ++#define B_S1_DACKI8_K GENMASK(15, 8) ++#define R_S1_DACKQ 0x7E50 ++#define B_S1_DACKQ_AR GENMASK(31, 28) ++#define B_S1_DACKQ_EN BIT(3) ++#define R_S1_DACKQ2 0x7E80 ++#define B_S1_DACKQ2_K GENMASK(21, 12) ++#define R_S1_DACKQ7 0x7E94 ++#define B_S1_DACKQ7_K GENMASK(15, 8) ++#define R_S1_DACKQ8 0x7E98 ++#define B_S1_DACKQ8_K GENMASK(15, 8) ++#define R_NCTL_CFG 0x8000 ++#define B_NCTL_CFG_SPAGE GENMASK(2, 1) ++#define R_NCTL_RPT 0x8008 ++#define B_NCTL_RPT_FLG BIT(26) ++#define R_NCTL_N1 0x8010 ++#define B_NCTL_N1_CIP GENMASK(7, 0) ++#define R_NCTL_N2 0x8014 ++#define R_IQK_COM 0x8018 ++#define R_IQK_DIF 0x801C ++#define B_IQK_DIF_TRX GENMASK(1, 0) ++#define R_IQK_DIF1 0x8020 ++#define B_IQK_DIF1_TXPI GENMASK(19, 0) ++#define R_IQK_DIF2 0x8024 ++#define B_IQK_DIF2_RXPI GENMASK(19, 0) ++#define R_IQK_DIF4 0x802C ++#define B_IQK_DIF4_TXT GENMASK(11, 0) ++#define B_IQK_DIF4_RXT GENMASK(27, 16) ++#define R_IQK_CFG 0x8034 ++#define B_IQK_CFG_SET GENMASK(5, 4) ++#define R_TPG_MOD 0x806C ++#define B_TPG_MOD_F GENMASK(2, 1) ++#define R_MDPK_SYNC 0x8070 ++#define B_MDPK_SYNC_SEL BIT(31) ++#define B_MDPK_SYNC_MAN GENMASK(31, 28) ++#define R_MDPK_RX_DCK 0x8074 ++#define R_NCTL_RW 0x8080 ++#define R_KIP_SYSCFG 0x8088 ++#define R_KIP_CLK 0x808C ++#define R_LDL_NORM 0x80A0 ++#define B_LDL_NORM_PN GENMASK(12, 8) ++#define B_LDL_NORM_OP GENMASK(1, 0) ++#define R_DPK_CTL 0x80B0 ++#define B_DPK_CTL_EN BIT(28) ++#define R_DPK_CFG 0x80B8 ++#define B_DPK_CFG_IDX GENMASK(14, 12) ++#define R_DPK_CFG2 0x80BC ++#define B_DPK_CFG2_ST BIT(14) ++#define R_DPK_CFG3 0x80C0 ++#define R_KPATH_CFG 0x80D0 ++#define R_KIP_RPT1 0x80D4 ++#define B_KIP_RPT1_SEL GENMASK(21, 16) ++#define R_SRAM_IQRX 0x80D8 ++#define R_GAPK 0x80E0 ++#define B_GAPK_ADR BIT(0) ++#define R_SRAM_IQRX2 0x80E8 ++#define R_DPK_TRK 0x80f0 ++#define B_DPK_TRK_DIS BIT(31) ++#define R_RPT_COM 0x80FC ++#define B_PRT_COM_SYNERR BIT(30) ++#define B_PRT_COM_DCI GENMASK(27, 16) ++#define B_PRT_COM_CORV GENMASK(15, 8) ++#define B_PRT_COM_DCQ GENMASK(11, 0) ++#define B_PRT_COM_GL GENMASK(7, 4) ++#define B_PRT_COM_CORI GENMASK(7, 0) ++#define R_COEF_SEL 0x8104 ++#define B_COEF_SEL_IQC BIT(0) ++#define B_COEF_SEL_MDPD BIT(8) ++#define R_CFIR_SYS 0x8120 ++#define R_IQK_RES 0x8124 ++#define B_IQK_RES_TXCFIR GENMASK(11, 8) ++#define B_IQK_RES_RXCFIR GENMASK(3, 0) ++#define R_TXIQC 0x8138 ++#define R_RXIQC 0x813c ++#define B_RXIQC_BYPASS BIT(0) ++#define B_RXIQC_BYPASS2 BIT(2) ++#define B_RXIQC_NEWP GENMASK(19, 8) ++#define B_RXIQC_NEWX GENMASK(31, 20) ++#define R_KIP 0x8140 ++#define B_KIP_DBCC BIT(0) ++#define B_KIP_RFGAIN BIT(8) ++#define R_RFGAIN 0x8144 ++#define B_RFGAIN_PAD GENMASK(4, 0) ++#define B_RFGAIN_TXBB GENMASK(12, 8) ++#define R_RFGAIN_BND 0x8148 ++#define B_RFGAIN_BND GENMASK(4, 0) ++#define R_CFIR_MAP 0x8150 ++#define R_CFIR_LUT 0x8154 ++#define B_CFIR_LUT_SEL BIT(8) ++#define B_CFIR_LUT_G3 BIT(3) ++#define B_CFIR_LUT_G2 BIT(2) ++#define B_CFIR_LUT_GP GENMASK(1, 0) ++#define R_DPD_V1 0x81a0 ++#define R_DPD_CH0 0x81AC ++#define R_DPD_BND 0x81B4 ++#define R_DPD_CH0A 0x81BC ++#define R_TXAGC_RFK 0x81C4 ++#define B_TXAGC_RFK_CH0 GENMASK(5, 0) ++#define R_DPD_COM 0x81C8 ++#define R_KIP_IQP 0x81CC ++#define B_KIP_IQP_IQSW GENMASK(5, 0) ++#define R_KIP_RPT 0x81D4 ++#define B_KIP_RPT_SEL GENMASK(21, 16) ++#define R_W_COEF 0x81D8 ++#define R_LOAD_COEF 0x81DC ++#define B_LOAD_COEF_MDPD BIT(16) ++#define B_LOAD_COEF_CFIR GENMASK(1, 0) ++#define B_LOAD_COEF_AUTO BIT(0) ++#define R_RPT_PER 0x81FC ++#define R_RXCFIR_P0C0 0x8D40 ++#define R_RXCFIR_P0C1 0x8D84 ++#define R_RXCFIR_P0C2 0x8DC8 ++#define R_RXCFIR_P0C3 0x8E0C ++#define R_TXCFIR_P0C0 0x8F50 ++#define R_TXCFIR_P0C1 0x8F84 ++#define R_TXCFIR_P0C2 0x8FB8 ++#define R_TXCFIR_P0C3 0x8FEC ++#define R_RXCFIR_P1C0 0x9140 ++#define R_RXCFIR_P1C1 0x9184 ++#define R_RXCFIR_P1C2 0x91C8 ++#define R_RXCFIR_P1C3 0x920C ++#define R_TXCFIR_P1C0 0x9350 ++#define R_TXCFIR_P1C1 0x9384 ++#define R_TXCFIR_P1C2 0x93B8 ++#define R_TXCFIR_P1C3 0x93EC ++#define R_IQKINF 0x9FE0 ++#define B_IQKINF_VER GENMASK(31, 24) ++#define B_IQKINF_FAIL_RXGRP GENMASK(23, 16) ++#define B_IQKINF_FAIL_TXGRP GENMASK(15, 8) ++#define B_IQKINF_FAIL GENMASK(3, 0) ++#define B_IQKINF_F_RX BIT(3) ++#define B_IQKINF_FTX BIT(2) ++#define B_IQKINF_FFIN BIT(1) ++#define B_IQKINF_FCOR BIT(0) ++#define R_IQKCH 0x9FE4 ++#define B_IQKCH_CH GENMASK(15, 8) ++#define B_IQKCH_BW GENMASK(7, 4) ++#define B_IQKCH_BAND GENMASK(3, 0) ++#define R_IQKINF2 0x9FE8 ++#define B_IQKINF2_FCNT GENMASK(23, 16) ++#define B_IQKINF2_KCNT GENMASK(15, 8) ++#define B_IQKINF2_NCTLV GENMAKS(7, 0) ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c +new file mode 100644 +index 000000000000..f00b94ecfff4 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/regd.c +@@ -0,0 +1,353 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "debug.h" ++#include "ps.h" ++ ++#define COUNTRY_REGD(_alpha2, _txpwr_regd_2g, _txpwr_regd_5g) \ ++ {.alpha2 = (_alpha2), \ ++ .txpwr_regd[RTW89_BAND_2G] = (_txpwr_regd_2g), \ ++ .txpwr_regd[RTW89_BAND_5G] = (_txpwr_regd_5g) \ ++ } ++ ++static const struct rtw89_regulatory rtw89_ww_regd = ++ COUNTRY_REGD("00", RTW89_WW, RTW89_WW); ++ ++static const struct rtw89_regulatory rtw89_regd_map[] = { ++ COUNTRY_REGD("AR", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("BO", RTW89_WW, RTW89_FCC), ++ COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("CL", RTW89_WW, RTW89_CHILE), ++ COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("CR", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("EC", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("SV", RTW89_WW, RTW89_FCC), ++ COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("HN", RTW89_WW, RTW89_FCC), ++ COUNTRY_REGD("MX", RTW89_FCC, RTW89_MEXICO), ++ COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("US", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("UY", RTW89_WW, RTW89_FCC), ++ COUNTRY_REGD("VE", RTW89_WW, RTW89_FCC), ++ COUNTRY_REGD("PR", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("DO", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("AT", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CY", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("DK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("EE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("FI", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("FR", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("DE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GR", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("HU", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IS", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IT", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LV", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LI", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LT", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LU", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MT", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MC", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NL", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("PL", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("PT", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SI", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ES", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GB", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AL", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("HR", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("EG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IQ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IL", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("JO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KW", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LB", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LS", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("OM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("QA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("RO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("RU", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("RS", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ME", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ZA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TR", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("UA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("YE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ZW", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BD", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("HK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI), ++ COUNTRY_REGD("KR", RTW89_KCC, RTW89_KCC), ++ COUNTRY_REGD("MY", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("PK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("PH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("TH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("VN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AU", RTW89_WW, RTW89_ACMA), ++ COUNTRY_REGD("NZ", RTW89_WW, RTW89_ACMA), ++ COUNTRY_REGD("PG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CA", RTW89_IC, RTW89_IC), ++ COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK), ++ COUNTRY_REGD("JM", RTW89_WW, RTW89_FCC), ++ COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("TT", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("TN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AF", RTW89_ETSI, RTW89_ETSI), ++ COUNTRY_REGD("DZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AS", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("AD", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AI", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AQ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("AM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("BY", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BZ", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("BJ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("BT", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BW", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BV", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("BN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BF", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BI", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CV", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("CF", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TD", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CX", RTW89_WW, RTW89_ACMA), ++ COUNTRY_REGD("CC", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CD", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CI", RTW89_ETSI, RTW89_ETSI), ++ COUNTRY_REGD("DJ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("GQ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ER", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ET", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("FK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("FO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("FJ", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("GF", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("PF", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TF", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GI", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GL", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("GP", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("GG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GW", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GY", RTW89_FCC, RTW89_NCC), ++ COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("HM", RTW89_WW, RTW89_ACMA), ++ COUNTRY_REGD("VA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("JE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KI", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LR", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LY", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MW", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MV", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ML", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MH", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("MQ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MR", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MU", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("YT", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("MD", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MS", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NR", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NP", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NC", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NU", RTW89_WW, RTW89_ACMA), ++ COUNTRY_REGD("NF", RTW89_WW, RTW89_ACMA), ++ COUNTRY_REGD("MP", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("PW", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("RE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("RW", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("MF", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("SX", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("PM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("VC", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("WS", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("SM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ST", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("SC", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("SL", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SB", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GS", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("SJ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TJ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TK", RTW89_WW, RTW89_ACMA), ++ COUNTRY_REGD("TO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TC", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TV", RTW89_ETSI, RTW89_NA), ++ COUNTRY_REGD("UG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("VI", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("UZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("VU", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("WF", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("EH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ZM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IR", RTW89_WW, RTW89_ETSI), ++}; ++ ++static const struct rtw89_regulatory *rtw89_regd_find_reg_by_name(char *alpha2) ++{ ++ u32 i; ++ ++ for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) { ++ if (!memcmp(rtw89_regd_map[i].alpha2, alpha2, 2)) ++ return &rtw89_regd_map[i]; ++ } ++ ++ return &rtw89_ww_regd; ++} ++ ++static bool rtw89_regd_is_ww(const struct rtw89_regulatory *regd) ++{ ++ return regd == &rtw89_ww_regd; ++} ++ ++int rtw89_regd_init(struct rtw89_dev *rtwdev, ++ void (*reg_notifier)(struct wiphy *wiphy, ++ struct regulatory_request *request)) ++{ ++ const struct rtw89_regulatory *chip_regd; ++ struct wiphy *wiphy = rtwdev->hw->wiphy; ++ int ret; ++ ++ if (!wiphy) ++ return -EINVAL; ++ ++ chip_regd = rtw89_regd_find_reg_by_name(rtwdev->efuse.country_code); ++ if (!rtw89_regd_is_ww(chip_regd)) { ++ rtwdev->regd = chip_regd; ++ /* Ignore country ie if there is a country domain programmed in chip */ ++ wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; ++ wiphy->regulatory_flags |= REGULATORY_STRICT_REG; ++ ++ ret = regulatory_hint(rtwdev->hw->wiphy, rtwdev->regd->alpha2); ++ if (ret) ++ rtw89_warn(rtwdev, "failed to hint regulatory:%d\n", ret); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_REGD, ++ "efuse country code %c%c, mapping to 2g txregd %d, 5g txregd %d\n", ++ rtwdev->efuse.country_code[0], rtwdev->efuse.country_code[1], ++ rtwdev->regd->txpwr_regd[RTW89_BAND_2G], ++ rtwdev->regd->txpwr_regd[RTW89_BAND_5G]); ++ ++ return 0; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_REGD, ++ "worldwide roaming chip, follow the setting of stack(%c%c), mapping to 2g txregd %d, 5g txregd %d\n", ++ rtwdev->regd->alpha2[0], rtwdev->regd->alpha2[1], ++ rtwdev->regd->txpwr_regd[RTW89_BAND_2G], ++ rtwdev->regd->txpwr_regd[RTW89_BAND_5G]); ++ ++ return 0; ++} ++ ++static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev, ++ struct wiphy *wiphy, ++ struct regulatory_request *request) ++{ ++ rtwdev->regd = rtw89_regd_find_reg_by_name(request->alpha2); ++ /* This notification might be set from the system of distros, ++ * and it does not expect the regulatory will be modified by ++ * connecting to an AP (i.e. country ie). ++ */ ++ if (request->initiator == NL80211_REGDOM_SET_BY_USER && ++ !rtw89_regd_is_ww(rtwdev->regd)) ++ wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; ++ else ++ wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE; ++} ++ ++void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request) ++{ ++ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ ++ if (wiphy->regd) { ++ rtw89_debug(rtwdev, RTW89_DBG_REGD, ++ "There is a country domain programmed in chip, ignore notifications\n"); ++ goto exit; ++ } ++ rtw89_regd_notifier_apply(rtwdev, wiphy, request); ++ rtw89_debug(rtwdev, RTW89_DBG_REGD, ++ "get alpha2 %c%c from initiator %d, mapping to 2g txregd %d, 5g txregd %d\n", ++ request->alpha2[0], request->alpha2[1], request->initiator, ++ rtwdev->regd->txpwr_regd[RTW89_BAND_2G], ++ rtwdev->regd->txpwr_regd[RTW89_BAND_5G]); ++ ++ rtw89_chip_set_txpwr(rtwdev); ++ ++exit: ++ mutex_unlock(&rtwdev->mutex); ++} +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +new file mode 100644 +index 000000000000..b1b87f0aadbb +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +@@ -0,0 +1,2036 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "coex.h" ++#include "mac.h" ++#include "phy.h" ++#include "reg.h" ++#include "rtw8852a.h" ++#include "rtw8852a_rfk.h" ++#include "rtw8852a_table.h" ++#include "txrx.h" ++ ++static const struct rtw89_hfc_ch_cfg rtw8852a_hfc_chcfg_pcie[] = { ++ {128, 1896, grp_0}, /* ACH 0 */ ++ {128, 1896, grp_0}, /* ACH 1 */ ++ {128, 1896, grp_0}, /* ACH 2 */ ++ {128, 1896, grp_0}, /* ACH 3 */ ++ {128, 1896, grp_1}, /* ACH 4 */ ++ {128, 1896, grp_1}, /* ACH 5 */ ++ {128, 1896, grp_1}, /* ACH 6 */ ++ {128, 1896, grp_1}, /* ACH 7 */ ++ {32, 1896, grp_0}, /* B0MGQ */ ++ {128, 1896, grp_0}, /* B0HIQ */ ++ {32, 1896, grp_1}, /* B1MGQ */ ++ {128, 1896, grp_1}, /* B1HIQ */ ++ {40, 0, 0} /* FWCMDQ */ ++}; ++ ++static const struct rtw89_hfc_pub_cfg rtw8852a_hfc_pubcfg_pcie = { ++ 1896, /* Group 0 */ ++ 1896, /* Group 1 */ ++ 3792, /* Public Max */ ++ 0 /* WP threshold */ ++}; ++ ++static const struct rtw89_hfc_param_ini rtw8852a_hfc_param_ini_pcie[] = { ++ [RTW89_QTA_SCC] = {rtw8852a_hfc_chcfg_pcie, &rtw8852a_hfc_pubcfg_pcie, ++ &rtw_hfc_preccfg_pcie, RTW89_HCIFC_POH}, ++ [RTW89_QTA_DLFW] = {NULL, NULL, &rtw_hfc_preccfg_pcie, RTW89_HCIFC_POH}, ++ [RTW89_QTA_INVALID] = {NULL}, ++}; ++ ++static const struct rtw89_dle_mem rtw8852a_dle_mem_pcie[] = { ++ [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &wde_size0, &ple_size0, &wde_qt0, ++ &wde_qt0, &ple_qt4, &ple_qt5}, ++ [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &wde_size4, &ple_size4, ++ &wde_qt4, &wde_qt4, &ple_qt13, &ple_qt13}, ++ [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, ++ NULL}, ++}; ++ ++static const struct rtw89_reg2_def rtw8852a_pmac_ht20_mcs7_tbl[] = { ++ {0x44AC, 0x00000000}, ++ {0x44B0, 0x00000000}, ++ {0x44B4, 0x00000000}, ++ {0x44B8, 0x00000000}, ++ {0x44BC, 0x00000000}, ++ {0x44C0, 0x00000000}, ++ {0x44C4, 0x00000000}, ++ {0x44C8, 0x00000000}, ++ {0x44CC, 0x00000000}, ++ {0x44D0, 0x00000000}, ++ {0x44D4, 0x00000000}, ++ {0x44D8, 0x00000000}, ++ {0x44DC, 0x00000000}, ++ {0x44E0, 0x00000000}, ++ {0x44E4, 0x00000000}, ++ {0x44E8, 0x00000000}, ++ {0x44EC, 0x00000000}, ++ {0x44F0, 0x00000000}, ++ {0x44F4, 0x00000000}, ++ {0x44F8, 0x00000000}, ++ {0x44FC, 0x00000000}, ++ {0x4500, 0x00000000}, ++ {0x4504, 0x00000000}, ++ {0x4508, 0x00000000}, ++ {0x450C, 0x00000000}, ++ {0x4510, 0x00000000}, ++ {0x4514, 0x00000000}, ++ {0x4518, 0x00000000}, ++ {0x451C, 0x00000000}, ++ {0x4520, 0x00000000}, ++ {0x4524, 0x00000000}, ++ {0x4528, 0x00000000}, ++ {0x452C, 0x00000000}, ++ {0x4530, 0x4E1F3E81}, ++ {0x4534, 0x00000000}, ++ {0x4538, 0x0000005A}, ++ {0x453C, 0x00000000}, ++ {0x4540, 0x00000000}, ++ {0x4544, 0x00000000}, ++ {0x4548, 0x00000000}, ++ {0x454C, 0x00000000}, ++ {0x4550, 0x00000000}, ++ {0x4554, 0x00000000}, ++ {0x4558, 0x00000000}, ++ {0x455C, 0x00000000}, ++ {0x4560, 0x4060001A}, ++ {0x4564, 0x40000000}, ++ {0x4568, 0x00000000}, ++ {0x456C, 0x00000000}, ++ {0x4570, 0x04000007}, ++ {0x4574, 0x0000DC87}, ++ {0x4578, 0x00000BAB}, ++ {0x457C, 0x03E00000}, ++ {0x4580, 0x00000048}, ++ {0x4584, 0x00000000}, ++ {0x4588, 0x000003E8}, ++ {0x458C, 0x30000000}, ++ {0x4590, 0x00000000}, ++ {0x4594, 0x10000000}, ++ {0x4598, 0x00000001}, ++ {0x459C, 0x00030000}, ++ {0x45A0, 0x01000000}, ++ {0x45A4, 0x03000200}, ++ {0x45A8, 0xC00001C0}, ++ {0x45AC, 0x78018000}, ++ {0x45B0, 0x80000000}, ++ {0x45B4, 0x01C80600}, ++ {0x45B8, 0x00000002}, ++ {0x4594, 0x10000000} ++}; ++ ++static const struct rtw89_reg3_def rtw8852a_btc_preagc_en_defs[] = { ++ {0x4624, GENMASK(20, 14), 0x40}, ++ {0x46f8, GENMASK(20, 14), 0x40}, ++ {0x4674, GENMASK(20, 19), 0x2}, ++ {0x4748, GENMASK(20, 19), 0x2}, ++ {0x4650, GENMASK(14, 10), 0x18}, ++ {0x4724, GENMASK(14, 10), 0x18}, ++ {0x4688, GENMASK(1, 0), 0x3}, ++ {0x475c, GENMASK(1, 0), 0x3}, ++}; ++ ++static DECLARE_PHY_REG3_TBL(rtw8852a_btc_preagc_en_defs); ++ ++static const struct rtw89_reg3_def rtw8852a_btc_preagc_dis_defs[] = { ++ {0x4624, GENMASK(20, 14), 0x1a}, ++ {0x46f8, GENMASK(20, 14), 0x1a}, ++ {0x4674, GENMASK(20, 19), 0x1}, ++ {0x4748, GENMASK(20, 19), 0x1}, ++ {0x4650, GENMASK(14, 10), 0x12}, ++ {0x4724, GENMASK(14, 10), 0x12}, ++ {0x4688, GENMASK(1, 0), 0x0}, ++ {0x475c, GENMASK(1, 0), 0x0}, ++}; ++ ++static DECLARE_PHY_REG3_TBL(rtw8852a_btc_preagc_dis_defs); ++ ++static const struct rtw89_pwr_cfg rtw8852a_pwron[] = { ++ {0x00C6, ++ PWR_CV_MSK_B, ++ PWR_INTF_MSK_PCIE, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(6), BIT(6)}, ++ {0x1086, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_SDIO, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), 0}, ++ {0x1086, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_SDIO, ++ PWR_BASE_MAC, ++ PWR_CMD_POLL, BIT(1), BIT(1)}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(4) | BIT(3), 0}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(7), 0}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(2), 0}, ++ {0x0006, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_POLL, BIT(1), BIT(1)}, ++ {0x0006, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_POLL, BIT(0), 0}, ++ {0x106D, ++ PWR_CV_MSK_B | PWR_CV_MSK_C, ++ PWR_INTF_MSK_USB, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(6), 0}, ++ {0x0088, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0088, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0088, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0088, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0088, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0083, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(6), 0}, ++ {0x0080, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(5), BIT(5)}, ++ {0x0024, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0), 0}, ++ {0x02A0, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x02A2, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(7) | BIT(6) | BIT(5), 0}, ++ {0x0071, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_PCIE, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(4), 0}, ++ {0x0010, ++ PWR_CV_MSK_A, ++ PWR_INTF_MSK_PCIE, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(2), BIT(2)}, ++ {0x02A0, ++ PWR_CV_MSK_A, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(7) | BIT(6), 0}, ++ {0xFFFF, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ 0, ++ PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw89_pwr_cfg rtw8852a_pwroff[] = { ++ {0x02F0, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, 0xFF, 0}, ++ {0x02F1, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, 0xFF, 0}, ++ {0x0006, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0002, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(1) | BIT(0), 0}, ++ {0x0082, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(1) | BIT(0), 0}, ++ {0x106D, ++ PWR_CV_MSK_B | PWR_CV_MSK_C, ++ PWR_INTF_MSK_USB, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(6), BIT(6)}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_POLL, BIT(1), 0}, ++ {0x0091, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_PCIE, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_PCIE, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(2), BIT(2)}, ++ {0x0007, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_USB, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(4), 0}, ++ {0x0007, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_SDIO, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(6) | BIT(4), 0}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_SDIO, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(4) | BIT(3), BIT(3)}, ++ {0x0005, ++ PWR_CV_MSK_C | PWR_CV_MSK_D | PWR_CV_MSK_E | PWR_CV_MSK_F | ++ PWR_CV_MSK_G, ++ PWR_INTF_MSK_USB, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(4) | BIT(3), BIT(3)}, ++ {0x1086, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_SDIO, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x1086, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_SDIO, ++ PWR_BASE_MAC, ++ PWR_CMD_POLL, BIT(1), 0}, ++ {0xFFFF, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ 0, ++ PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw89_pwr_cfg * const pwr_on_seq_8852a[] = { ++ rtw8852a_pwron, NULL ++}; ++ ++static const struct rtw89_pwr_cfg * const pwr_off_seq_8852a[] = { ++ rtw8852a_pwroff, NULL ++}; ++ ++static void rtw8852ae_efuse_parsing(struct rtw89_efuse *efuse, ++ struct rtw8852a_efuse *map) ++{ ++ ether_addr_copy(efuse->addr, map->e.mac_addr); ++ efuse->rfe_type = map->rfe_type; ++ efuse->xtal_cap = map->xtal_k; ++} ++ ++static void rtw8852a_efuse_parsing_tssi(struct rtw89_dev *rtwdev, ++ struct rtw8852a_efuse *map) ++{ ++ struct rtw89_tssi_info *tssi = &rtwdev->tssi; ++ struct rtw8852a_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi}; ++ u8 i, j; ++ ++ tssi->thermal[RF_PATH_A] = map->path_a_therm; ++ tssi->thermal[RF_PATH_B] = map->path_b_therm; ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi, ++ sizeof(ofst[i]->cck_tssi)); ++ ++ for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++) ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n", ++ i, j, tssi->tssi_cck[i][j]); ++ ++ memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi, ++ sizeof(ofst[i]->bw40_tssi)); ++ memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM, ++ ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g)); ++ ++ for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++) ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n", ++ i, j, tssi->tssi_mcs[i][j]); ++ } ++} ++ ++static int rtw8852a_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map) ++{ ++ struct rtw89_efuse *efuse = &rtwdev->efuse; ++ struct rtw8852a_efuse *map; ++ ++ map = (struct rtw8852a_efuse *)log_map; ++ ++ efuse->country_code[0] = map->country_code[0]; ++ efuse->country_code[1] = map->country_code[1]; ++ rtw8852a_efuse_parsing_tssi(rtwdev, map); ++ ++ switch (rtwdev->hci.type) { ++ case RTW89_HCI_TYPE_PCIE: ++ rtw8852ae_efuse_parsing(efuse, map); ++ break; ++ default: ++ return -ENOTSUPP; ++ } ++ ++ rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type); ++ ++ return 0; ++} ++ ++static void rtw8852a_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map) ++{ ++ struct rtw89_tssi_info *tssi = &rtwdev->tssi; ++ static const u32 tssi_trim_addr[RF_PATH_NUM_8852A] = {0x5D6, 0x5AB}; ++ u32 addr = rtwdev->chip->phycap_addr; ++ bool pg = false; ++ u32 ofst; ++ u8 i, j; ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) { ++ /* addrs are in decreasing order */ ++ ofst = tssi_trim_addr[i] - addr - j; ++ tssi->tssi_trim[i][j] = phycap_map[ofst]; ++ ++ if (phycap_map[ofst] != 0xff) ++ pg = true; ++ } ++ } ++ ++ if (!pg) { ++ memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim)); ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM] no PG, set all trim info to 0\n"); ++ } ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) ++ for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n", ++ i, j, tssi->tssi_trim[i][j], ++ tssi_trim_addr[i] - j); ++} ++ ++static void rtw8852a_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev, ++ u8 *phycap_map) ++{ ++ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; ++ static const u32 thm_trim_addr[RF_PATH_NUM_8852A] = {0x5DF, 0x5DC}; ++ u32 addr = rtwdev->chip->phycap_addr; ++ u8 i; ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n", ++ i, info->thermal_trim[i]); ++ ++ if (info->thermal_trim[i] != 0xff) ++ info->pg_thermal_trim = true; ++ } ++} ++ ++static void rtw8852a_thermal_trim(struct rtw89_dev *rtwdev) ++{ ++#define __thm_setting(raw) \ ++({ \ ++ u8 __v = (raw); \ ++ ((__v & 0x1) << 3) | ((__v & 0x1f) >> 1); \ ++}) ++ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; ++ u8 i, val; ++ ++ if (!info->pg_thermal_trim) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[THERMAL][TRIM] no PG, do nothing\n"); ++ ++ return; ++ } ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ val = __thm_setting(info->thermal_trim[i]); ++ rtw89_write_rf(rtwdev, i, RR_TM2, RR_TM2_OFF, val); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n", ++ i, val); ++ } ++#undef __thm_setting ++} ++ ++static void rtw8852a_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev, ++ u8 *phycap_map) ++{ ++ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; ++ static const u32 pabias_trim_addr[RF_PATH_NUM_8852A] = {0x5DE, 0x5DB}; ++ u32 addr = rtwdev->chip->phycap_addr; ++ u8 i; ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n", ++ i, info->pa_bias_trim[i]); ++ ++ if (info->pa_bias_trim[i] != 0xff) ++ info->pg_pa_bias_trim = true; ++ } ++} ++ ++static void rtw8852a_pa_bias_trim(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; ++ u8 pabias_2g, pabias_5g; ++ u8 i; ++ ++ if (!info->pg_pa_bias_trim) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[PA_BIAS][TRIM] no PG, do nothing\n"); ++ ++ return; ++ } ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]); ++ pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n", ++ i, pabias_2g, pabias_5g); ++ ++ rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG, pabias_2g); ++ rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA, pabias_5g); ++ } ++} ++ ++static int rtw8852a_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map) ++{ ++ rtw8852a_phycap_parsing_tssi(rtwdev, phycap_map); ++ rtw8852a_phycap_parsing_thermal_trim(rtwdev, phycap_map); ++ rtw8852a_phycap_parsing_pa_bias_trim(rtwdev, phycap_map); ++ ++ return 0; ++} ++ ++static void rtw8852a_power_trim(struct rtw89_dev *rtwdev) ++{ ++ rtw8852a_thermal_trim(rtwdev); ++ rtw8852a_pa_bias_trim(rtwdev); ++} ++ ++static void rtw8852a_set_channel_mac(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_params *param, ++ u8 mac_idx) ++{ ++ u32 rf_mod = rtw89_mac_reg_by_idx(R_AX_WMAC_RFMOD, mac_idx); ++ u32 sub_carr = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE, ++ mac_idx); ++ u32 chk_rate = rtw89_mac_reg_by_idx(R_AX_TXRATE_CHK, mac_idx); ++ u8 txsc20 = 0, txsc40 = 0; ++ ++ switch (param->bandwidth) { ++ case RTW89_CHANNEL_WIDTH_80: ++ txsc40 = rtw89_phy_get_txsc(rtwdev, param, ++ RTW89_CHANNEL_WIDTH_40); ++ fallthrough; ++ case RTW89_CHANNEL_WIDTH_40: ++ txsc20 = rtw89_phy_get_txsc(rtwdev, param, ++ RTW89_CHANNEL_WIDTH_20); ++ break; ++ default: ++ break; ++ } ++ ++ switch (param->bandwidth) { ++ case RTW89_CHANNEL_WIDTH_80: ++ rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(1)); ++ rtw89_write32(rtwdev, sub_carr, txsc20 | (txsc40 << 4)); ++ break; ++ case RTW89_CHANNEL_WIDTH_40: ++ rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(0)); ++ rtw89_write32(rtwdev, sub_carr, txsc20); ++ break; ++ case RTW89_CHANNEL_WIDTH_20: ++ rtw89_write8_clr(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK); ++ rtw89_write32(rtwdev, sub_carr, 0); ++ break; ++ default: ++ break; ++ } ++ ++ if (param->center_chan > 14) ++ rtw89_write8_set(rtwdev, chk_rate, ++ B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6); ++ else ++ rtw89_write8_clr(rtwdev, chk_rate, ++ B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6); ++} ++ ++static const u32 rtw8852a_sco_barker_threshold[14] = { ++ 0x1cfea, 0x1d0e1, 0x1d1d7, 0x1d2cd, 0x1d3c3, 0x1d4b9, 0x1d5b0, 0x1d6a6, ++ 0x1d79c, 0x1d892, 0x1d988, 0x1da7f, 0x1db75, 0x1ddc4 ++}; ++ ++static const u32 rtw8852a_sco_cck_threshold[14] = { ++ 0x27de3, 0x27f35, 0x28088, 0x281da, 0x2832d, 0x2847f, 0x285d2, 0x28724, ++ 0x28877, 0x289c9, 0x28b1c, 0x28c6e, 0x28dc1, 0x290ed ++}; ++ ++static int rtw8852a_ctrl_sco_cck(struct rtw89_dev *rtwdev, u8 central_ch, ++ u8 primary_ch, enum rtw89_bandwidth bw) ++{ ++ u8 ch_element; ++ ++ if (bw == RTW89_CHANNEL_WIDTH_20) { ++ ch_element = central_ch - 1; ++ } else if (bw == RTW89_CHANNEL_WIDTH_40) { ++ if (primary_ch == 1) ++ ch_element = central_ch - 1 + 2; ++ else ++ ch_element = central_ch - 1 - 2; ++ } else { ++ rtw89_warn(rtwdev, "Invalid BW:%d for CCK\n", bw); ++ return -EINVAL; ++ } ++ rtw89_phy_write32_mask(rtwdev, R_RXSCOBC, B_RXSCOBC_TH, ++ rtw8852a_sco_barker_threshold[ch_element]); ++ rtw89_phy_write32_mask(rtwdev, R_RXSCOCCK, B_RXSCOCCK_TH, ++ rtw8852a_sco_cck_threshold[ch_element]); ++ ++ return 0; ++} ++ ++static void rtw8852a_ch_setting(struct rtw89_dev *rtwdev, u8 central_ch, ++ u8 path) ++{ ++ u32 val; ++ ++ val = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); ++ if (val == INV_RF_DATA) { ++ rtw89_warn(rtwdev, "Invalid RF_0x18 for Path-%d\n", path); ++ return; ++ } ++ val &= ~0x303ff; ++ val |= central_ch; ++ if (central_ch > 14) ++ val |= (BIT(16) | BIT(8)); ++ rtw89_write_rf(rtwdev, path, RR_CFGCH, RFREG_MASK, val); ++} ++ ++static u8 rtw8852a_sco_mapping(u8 central_ch) ++{ ++ if (central_ch == 1) ++ return 109; ++ else if (central_ch >= 2 && central_ch <= 6) ++ return 108; ++ else if (central_ch >= 7 && central_ch <= 10) ++ return 107; ++ else if (central_ch >= 11 && central_ch <= 14) ++ return 106; ++ else if (central_ch == 36 || central_ch == 38) ++ return 51; ++ else if (central_ch >= 40 && central_ch <= 58) ++ return 50; ++ else if (central_ch >= 60 && central_ch <= 64) ++ return 49; ++ else if (central_ch == 100 || central_ch == 102) ++ return 48; ++ else if (central_ch >= 104 && central_ch <= 126) ++ return 47; ++ else if (central_ch >= 128 && central_ch <= 151) ++ return 46; ++ else if (central_ch >= 153 && central_ch <= 177) ++ return 45; ++ else ++ return 0; ++} ++ ++static void rtw8852a_ctrl_ch(struct rtw89_dev *rtwdev, u8 central_ch, ++ enum rtw89_phy_idx phy_idx) ++{ ++ u8 sco_comp; ++ bool is_2g = central_ch <= 14; ++ ++ if (phy_idx == RTW89_PHY_0) { ++ /* Path A */ ++ rtw8852a_ch_setting(rtwdev, central_ch, RF_PATH_A); ++ if (is_2g) ++ rtw89_phy_write32_idx(rtwdev, R_PATH0_TIA_ERR_G1, ++ B_PATH0_TIA_ERR_G1_SEL, 1, ++ phy_idx); ++ else ++ rtw89_phy_write32_idx(rtwdev, R_PATH0_TIA_ERR_G1, ++ B_PATH0_TIA_ERR_G1_SEL, 0, ++ phy_idx); ++ ++ /* Path B */ ++ if (!rtwdev->dbcc_en) { ++ rtw8852a_ch_setting(rtwdev, central_ch, RF_PATH_B); ++ if (is_2g) ++ rtw89_phy_write32_idx(rtwdev, R_P1_MODE, ++ B_P1_MODE_SEL, ++ 1, phy_idx); ++ else ++ rtw89_phy_write32_idx(rtwdev, R_P1_MODE, ++ B_P1_MODE_SEL, ++ 0, phy_idx); ++ } else { ++ if (is_2g) ++ rtw89_phy_write32_clr(rtwdev, R_2P4G_BAND, ++ B_2P4G_BAND_SEL); ++ else ++ rtw89_phy_write32_set(rtwdev, R_2P4G_BAND, ++ B_2P4G_BAND_SEL); ++ } ++ /* SCO compensate FC setting */ ++ sco_comp = rtw8852a_sco_mapping(central_ch); ++ rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, ++ sco_comp, phy_idx); ++ } else { ++ /* Path B */ ++ rtw8852a_ch_setting(rtwdev, central_ch, RF_PATH_B); ++ if (is_2g) ++ rtw89_phy_write32_idx(rtwdev, R_P1_MODE, ++ B_P1_MODE_SEL, ++ 1, phy_idx); ++ else ++ rtw89_phy_write32_idx(rtwdev, R_P1_MODE, ++ B_P1_MODE_SEL, ++ 1, phy_idx); ++ /* SCO compensate FC setting */ ++ sco_comp = rtw8852a_sco_mapping(central_ch); ++ rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, ++ sco_comp, phy_idx); ++ } ++ ++ /* Band edge */ ++ if (is_2g) ++ rtw89_phy_write32_idx(rtwdev, R_BANDEDGE, B_BANDEDGE_EN, 1, ++ phy_idx); ++ else ++ rtw89_phy_write32_idx(rtwdev, R_BANDEDGE, B_BANDEDGE_EN, 0, ++ phy_idx); ++ ++ /* CCK parameters */ ++ if (central_ch == 14) { ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, ++ 0x3b13ff); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, ++ 0x1c42de); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, ++ 0xfdb0ad); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, ++ 0xf60f6e); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, ++ 0xfd8f92); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, 0x2d011); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, 0x1c02c); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, ++ 0xfff00a); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, ++ 0x3d23ff); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, ++ 0x29b354); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, 0xfc1c8); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, ++ 0xfdb053); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, ++ 0xf86f9a); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, ++ 0xfaef92); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, ++ 0xfe5fcc); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, ++ 0xffdff5); ++ } ++} ++ ++static void rtw8852a_bw_setting(struct rtw89_dev *rtwdev, u8 bw, u8 path) ++{ ++ u32 val = 0; ++ u32 adc_sel[2] = {0x12d0, 0x32d0}; ++ u32 wbadc_sel[2] = {0x12ec, 0x32ec}; ++ ++ val = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); ++ if (val == INV_RF_DATA) { ++ rtw89_warn(rtwdev, "Invalid RF_0x18 for Path-%d\n", path); ++ return; ++ } ++ val &= ~(BIT(11) | BIT(10)); ++ switch (bw) { ++ case RTW89_CHANNEL_WIDTH_5: ++ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x1); ++ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x0); ++ val |= (BIT(11) | BIT(10)); ++ break; ++ case RTW89_CHANNEL_WIDTH_10: ++ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x2); ++ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x1); ++ val |= (BIT(11) | BIT(10)); ++ break; ++ case RTW89_CHANNEL_WIDTH_20: ++ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); ++ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); ++ val |= (BIT(11) | BIT(10)); ++ break; ++ case RTW89_CHANNEL_WIDTH_40: ++ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); ++ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); ++ val |= BIT(11); ++ break; ++ case RTW89_CHANNEL_WIDTH_80: ++ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); ++ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); ++ val |= BIT(10); ++ break; ++ default: ++ rtw89_warn(rtwdev, "Fail to set ADC\n"); ++ } ++ ++ rtw89_write_rf(rtwdev, path, RR_CFGCH, RFREG_MASK, val); ++} ++ ++static void ++rtw8852a_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw, ++ enum rtw89_phy_idx phy_idx) ++{ ++ /* Switch bandwidth */ ++ switch (bw) { ++ case RTW89_CHANNEL_WIDTH_5: ++ rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x0, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x1, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, ++ 0x0, phy_idx); ++ break; ++ case RTW89_CHANNEL_WIDTH_10: ++ rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x0, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x2, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, ++ 0x0, phy_idx); ++ break; ++ case RTW89_CHANNEL_WIDTH_20: ++ rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x0, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, ++ 0x0, phy_idx); ++ break; ++ case RTW89_CHANNEL_WIDTH_40: ++ rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x1, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, ++ pri_ch, ++ phy_idx); ++ if (pri_ch == RTW89_SC_20_UPPER) ++ rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 1); ++ else ++ rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 0); ++ break; ++ case RTW89_CHANNEL_WIDTH_80: ++ rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x2, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, ++ pri_ch, ++ phy_idx); ++ break; ++ default: ++ rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw, ++ pri_ch); ++ } ++ ++ if (phy_idx == RTW89_PHY_0) { ++ rtw8852a_bw_setting(rtwdev, bw, RF_PATH_A); ++ if (!rtwdev->dbcc_en) ++ rtw8852a_bw_setting(rtwdev, bw, RF_PATH_B); ++ } else { ++ rtw8852a_bw_setting(rtwdev, bw, RF_PATH_B); ++ } ++} ++ ++static void rtw8852a_spur_elimination(struct rtw89_dev *rtwdev, u8 central_ch) ++{ ++ if (central_ch == 153) { ++ rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, B_P0_NBIIDX_VAL, ++ 0x210); ++ rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL, ++ 0x210); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x7c0); ++ rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, ++ B_P0_NBIIDX_NOTCH_EN, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, ++ B_P1_NBIIDX_NOTCH_EN, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, ++ 0x1); ++ } else if (central_ch == 151) { ++ rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, B_P0_NBIIDX_VAL, ++ 0x210); ++ rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL, ++ 0x210); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x40); ++ rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, ++ B_P0_NBIIDX_NOTCH_EN, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, ++ B_P1_NBIIDX_NOTCH_EN, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, ++ 0x1); ++ } else if (central_ch == 155) { ++ rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, B_P0_NBIIDX_VAL, ++ 0x2d0); ++ rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL, ++ 0x2d0); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x740); ++ rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, ++ B_P0_NBIIDX_NOTCH_EN, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, ++ B_P1_NBIIDX_NOTCH_EN, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, ++ 0x1); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, ++ B_P0_NBIIDX_NOTCH_EN, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, ++ B_P1_NBIIDX_NOTCH_EN, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, ++ 0x0); ++ } ++} ++ ++static void rtw8852a_bb_reset_all(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, ++ phy_idx); ++} ++ ++static void rtw8852a_bb_reset_en(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, bool en) ++{ ++ if (en) ++ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, ++ 1, ++ phy_idx); ++ else ++ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, ++ 0, ++ phy_idx); ++} ++ ++static void rtw8852a_bb_reset(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ rtw89_phy_write32_set(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON); ++ rtw89_phy_write32_set(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); ++ rtw89_phy_write32_set(rtwdev, R_P1_TXPW_RSTB, B_P1_TXPW_RSTB_MANON); ++ rtw89_phy_write32_set(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); ++ rtw8852a_bb_reset_all(rtwdev, phy_idx); ++ rtw89_phy_write32_clr(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON); ++ rtw89_phy_write32_clr(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); ++ rtw89_phy_write32_clr(rtwdev, R_P1_TXPW_RSTB, B_P1_TXPW_RSTB_MANON); ++ rtw89_phy_write32_clr(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); ++} ++ ++static void rtw8852a_bb_macid_ctrl_init(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ u32 addr; ++ ++ for (addr = R_AX_PWR_MACID_LMT_TABLE0; ++ addr <= R_AX_PWR_MACID_LMT_TABLE127; addr += 4) ++ rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0); ++} ++ ++static void rtw8852a_bb_sethw(struct rtw89_dev *rtwdev) ++{ ++ rtw89_phy_write32_clr(rtwdev, R_P0_EN_SOUND_WO_NDP, B_P0_EN_SOUND_WO_NDP); ++ rtw89_phy_write32_clr(rtwdev, R_P1_EN_SOUND_WO_NDP, B_P1_EN_SOUND_WO_NDP); ++ ++ if (rtwdev->hal.cv <= CHIP_CCV) { ++ rtw89_phy_write32_set(rtwdev, R_RSTB_WATCH_DOG, B_P0_RSTB_WATCH_DOG); ++ rtw89_phy_write32(rtwdev, R_BRK_ASYNC_RST_EN_1, 0x864FA000); ++ rtw89_phy_write32(rtwdev, R_BRK_ASYNC_RST_EN_2, 0x3F); ++ rtw89_phy_write32(rtwdev, R_BRK_ASYNC_RST_EN_3, 0x7FFF); ++ rtw89_phy_write32_set(rtwdev, R_SPOOF_ASYNC_RST, B_SPOOF_ASYNC_RST); ++ rtw89_phy_write32_set(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON); ++ rtw89_phy_write32_set(rtwdev, R_P1_TXPW_RSTB, B_P1_TXPW_RSTB_MANON); ++ } ++ rtw89_phy_write32_mask(rtwdev, R_CFO_TRK0, B_CFO_TRK_MSK, 0x1f); ++ rtw89_phy_write32_mask(rtwdev, R_CFO_TRK1, B_CFO_TRK_MSK, 0x0c); ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0x0, RTW89_PHY_0); ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0x0, RTW89_PHY_1); ++ rtw89_phy_write32_clr(rtwdev, R_NDP_BRK0, B_NDP_RU_BRK); ++ rtw89_phy_write32_set(rtwdev, R_NDP_BRK1, B_NDP_RU_BRK); ++ ++ rtw8852a_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0); ++} ++ ++static void rtw8852a_bbrst_for_rfk(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ rtw89_phy_write32_set(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); ++ rtw89_phy_write32_set(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); ++ rtw8852a_bb_reset_all(rtwdev, phy_idx); ++ rtw89_phy_write32_clr(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); ++ rtw89_phy_write32_clr(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); ++ udelay(1); ++} ++ ++static void rtw8852a_set_channel_bb(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_params *param, ++ enum rtw89_phy_idx phy_idx) ++{ ++ bool cck_en = param->center_chan > 14 ? false : true; ++ u8 pri_ch_idx = param->pri_ch_idx; ++ ++ if (param->center_chan <= 14) ++ rtw8852a_ctrl_sco_cck(rtwdev, param->center_chan, ++ param->primary_chan, param->bandwidth); ++ ++ rtw8852a_ctrl_ch(rtwdev, param->center_chan, phy_idx); ++ rtw8852a_ctrl_bw(rtwdev, pri_ch_idx, param->bandwidth, phy_idx); ++ if (cck_en) { ++ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 1); ++ rtw8852a_bbrst_for_rfk(rtwdev, phy_idx); ++ } ++ rtw8852a_spur_elimination(rtwdev, param->center_chan); ++ rtw8852a_bb_reset_all(rtwdev, phy_idx); ++} ++ ++static void rtw8852a_set_channel(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_params *params) ++{ ++ rtw8852a_set_channel_mac(rtwdev, params, RTW89_MAC_0); ++ rtw8852a_set_channel_bb(rtwdev, params, RTW89_PHY_0); ++} ++ ++static void rtw8852a_dfs_en(struct rtw89_dev *rtwdev, bool en) ++{ ++ if (en) ++ rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 1); ++ else ++ rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 0); ++} ++ ++static void rtw8852a_tssi_cont_en(struct rtw89_dev *rtwdev, bool en, ++ enum rtw89_rf_path path) ++{ ++ static const u32 tssi_trk[2] = {0x5818, 0x7818}; ++ static const u32 ctrl_bbrst[2] = {0x58dc, 0x78dc}; ++ ++ if (en) { ++ rtw89_phy_write32_mask(rtwdev, ctrl_bbrst[path], BIT(30), 0x0); ++ rtw89_phy_write32_mask(rtwdev, tssi_trk[path], BIT(30), 0x0); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, ctrl_bbrst[path], BIT(30), 0x1); ++ rtw89_phy_write32_mask(rtwdev, tssi_trk[path], BIT(30), 0x1); ++ } ++} ++ ++static void rtw8852a_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, ++ u8 phy_idx) ++{ ++ if (!rtwdev->dbcc_en) { ++ rtw8852a_tssi_cont_en(rtwdev, en, RF_PATH_A); ++ rtw8852a_tssi_cont_en(rtwdev, en, RF_PATH_B); ++ } else { ++ if (phy_idx == RTW89_PHY_0) ++ rtw8852a_tssi_cont_en(rtwdev, en, RF_PATH_A); ++ else ++ rtw8852a_tssi_cont_en(rtwdev, en, RF_PATH_B); ++ } ++} ++ ++static void rtw8852a_adc_en(struct rtw89_dev *rtwdev, bool en) ++{ ++ if (en) ++ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, ++ 0x0); ++ else ++ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, ++ 0xf); ++} ++ ++static void rtw8852a_set_channel_help(struct rtw89_dev *rtwdev, bool enter, ++ struct rtw89_channel_help_params *p) ++{ ++ u8 phy_idx = RTW89_PHY_0; ++ ++ if (enter) { ++ rtw89_mac_stop_sch_tx(rtwdev, RTW89_MAC_0, &p->tx_en, RTW89_SCH_TX_SEL_ALL); ++ rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false); ++ rtw8852a_dfs_en(rtwdev, false); ++ rtw8852a_tssi_cont_en_phyidx(rtwdev, false, RTW89_PHY_0); ++ rtw8852a_adc_en(rtwdev, false); ++ fsleep(40); ++ rtw8852a_bb_reset_en(rtwdev, phy_idx, false); ++ } else { ++ rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); ++ rtw8852a_adc_en(rtwdev, true); ++ rtw8852a_dfs_en(rtwdev, true); ++ rtw8852a_tssi_cont_en_phyidx(rtwdev, true, RTW89_PHY_0); ++ rtw8852a_bb_reset_en(rtwdev, phy_idx, true); ++ rtw89_mac_resume_sch_tx(rtwdev, RTW89_MAC_0, p->tx_en); ++ } ++} ++ ++static void rtw8852a_fem_setup(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_efuse *efuse = &rtwdev->efuse; ++ ++ switch (efuse->rfe_type) { ++ case 11: ++ case 12: ++ case 17: ++ case 18: ++ case 51: ++ case 53: ++ rtwdev->fem.epa_2g = true; ++ rtwdev->fem.elna_2g = true; ++ fallthrough; ++ case 9: ++ case 10: ++ case 15: ++ case 16: ++ rtwdev->fem.epa_5g = true; ++ rtwdev->fem.elna_5g = true; ++ break; ++ default: ++ break; ++ } ++} ++ ++static void rtw8852a_rfk_init(struct rtw89_dev *rtwdev) ++{ ++ rtwdev->is_tssi_mode[RF_PATH_A] = false; ++ rtwdev->is_tssi_mode[RF_PATH_B] = false; ++ ++ rtw8852a_rck(rtwdev); ++ rtw8852a_dack(rtwdev); ++ rtw8852a_rx_dck(rtwdev, RTW89_PHY_0, true); ++} ++ ++static void rtw8852a_rfk_channel(struct rtw89_dev *rtwdev) ++{ ++ enum rtw89_phy_idx phy_idx = RTW89_PHY_0; ++ ++ rtw8852a_rx_dck(rtwdev, phy_idx, true); ++ rtw8852a_iqk(rtwdev, phy_idx); ++ rtw8852a_tssi(rtwdev, phy_idx); ++ rtw8852a_dpk(rtwdev, phy_idx); ++} ++ ++static void rtw8852a_rfk_band_changed(struct rtw89_dev *rtwdev) ++{ ++ rtw8852a_tssi_scan(rtwdev, RTW89_PHY_0); ++} ++ ++static void rtw8852a_rfk_scan(struct rtw89_dev *rtwdev, bool start) ++{ ++ rtw8852a_wifi_scan_notify(rtwdev, start, RTW89_PHY_0); ++} ++ ++static void rtw8852a_rfk_track(struct rtw89_dev *rtwdev) ++{ ++ rtw8852a_dpk_track(rtwdev); ++ rtw8852a_iqk_track(rtwdev); ++ rtw8852a_tssi_track(rtwdev); ++} ++ ++static u32 rtw8852a_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, s16 ref) ++{ ++ s8 ofst_int = 0; ++ u8 base_cw_0db = 0x27; ++ u16 tssi_16dbm_cw = 0x12c; ++ s16 pwr_s10_3 = 0; ++ s16 rf_pwr_cw = 0; ++ u16 bb_pwr_cw = 0; ++ u32 pwr_cw = 0; ++ u32 tssi_ofst_cw = 0; ++ ++ pwr_s10_3 = (ref << 1) + (s16)(ofst_int) + (s16)(base_cw_0db << 3); ++ bb_pwr_cw = FIELD_GET(GENMASK(2, 0), pwr_s10_3); ++ rf_pwr_cw = FIELD_GET(GENMASK(8, 3), pwr_s10_3); ++ rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63); ++ pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw; ++ ++ tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3)); ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, ++ "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n", ++ tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw); ++ ++ return (tssi_ofst_cw << 18) | (pwr_cw << 9) | (ref & GENMASK(8, 0)); ++} ++ ++static ++void rtw8852a_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, ++ s16 pw_ofst, enum rtw89_mac_idx mac_idx) ++{ ++ s32 val_1t = 0; ++ s32 val_2t = 0; ++ u32 reg; ++ ++ if (pw_ofst < -16 || pw_ofst > 15) { ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] Err pwr_offset=%d\n", ++ pw_ofst); ++ return; ++ } ++ reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_CTRL, mac_idx); ++ rtw89_write32_set(rtwdev, reg, B_AX_PWR_UL_TB_CTRL_EN); ++ val_1t = (s32)pw_ofst; ++ reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_1T, mac_idx); ++ rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, val_1t); ++ val_2t = max(val_1t - 3, -16); ++ reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_2T, mac_idx); ++ rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_MASK, val_2t); ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] Set TB pwr_offset=(%d, %d)\n", ++ val_1t, val_2t); ++} ++ ++static void rtw8852a_set_txpwr_ref(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ static const u32 addr[RF_PATH_NUM_8852A] = {0x5800, 0x7800}; ++ const u32 mask = 0x7FFFFFF; ++ const u8 ofst_ofdm = 0x4; ++ const u8 ofst_cck = 0x8; ++ s16 ref_ofdm = 0; ++ s16 ref_cck = 0; ++ u32 val; ++ u8 i; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n"); ++ ++ rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL, ++ GENMASK(27, 10), 0x0); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n"); ++ val = rtw8852a_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm); ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) ++ rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val, ++ phy_idx); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n"); ++ val = rtw8852a_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck); ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) ++ rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val, ++ phy_idx); ++} ++ ++static void rtw8852a_set_txpwr_byrate(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ u8 ch = rtwdev->hal.current_channel; ++ static const u8 rs[] = { ++ RTW89_RS_CCK, ++ RTW89_RS_OFDM, ++ RTW89_RS_MCS, ++ RTW89_RS_HEDCM, ++ }; ++ s8 tmp; ++ u8 i, j; ++ u32 val, shf, addr = R_AX_PWR_BY_RATE; ++ struct rtw89_rate_desc cur; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, ++ "[TXPWR] set txpwr byrate with ch=%d\n", ch); ++ ++ for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) { ++ for (i = 0; i < ARRAY_SIZE(rs); i++) { ++ if (cur.nss >= rtw89_rs_nss_max[rs[i]]) ++ continue; ++ ++ val = 0; ++ cur.rs = rs[i]; ++ ++ for (j = 0; j < rtw89_rs_idx_max[rs[i]]; j++) { ++ cur.idx = j; ++ shf = (j % 4) * 8; ++ tmp = rtw89_phy_read_txpwr_byrate(rtwdev, &cur); ++ val |= (tmp << shf); ++ ++ if ((j + 1) % 4) ++ continue; ++ ++ rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); ++ val = 0; ++ addr += 4; ++ } ++ } ++ } ++} ++ ++static void rtw8852a_set_txpwr_offset(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ struct rtw89_rate_desc desc = { ++ .nss = RTW89_NSS_1, ++ .rs = RTW89_RS_OFFSET, ++ }; ++ u32 val = 0; ++ s8 v; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n"); ++ ++ for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) { ++ v = rtw89_phy_read_txpwr_byrate(rtwdev, &desc); ++ val |= ((v & 0xf) << (4 * desc.idx)); ++ } ++ ++ rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_OFST_CTRL, ++ GENMASK(19, 0), val); ++} ++ ++static void rtw8852a_set_txpwr_limit(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++#define __MAC_TXPWR_LMT_PAGE_SIZE 40 ++ u8 ch = rtwdev->hal.current_channel; ++ u8 bw = rtwdev->hal.current_band_width; ++ struct rtw89_txpwr_limit lmt[NTX_NUM_8852A]; ++ u32 addr, val; ++ const s8 *ptr; ++ u8 i, j, k; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, ++ "[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw); ++ ++ for (i = 0; i < NTX_NUM_8852A; i++) { ++ rtw89_phy_fill_txpwr_limit(rtwdev, &lmt[i], i); ++ ++ for (j = 0; j < __MAC_TXPWR_LMT_PAGE_SIZE; j += 4) { ++ addr = R_AX_PWR_LMT + j + __MAC_TXPWR_LMT_PAGE_SIZE * i; ++ ptr = (s8 *)&lmt[i] + j; ++ val = 0; ++ ++ for (k = 0; k < 4; k++) ++ val |= (ptr[k] << (8 * k)); ++ ++ rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); ++ } ++ } ++#undef __MAC_TXPWR_LMT_PAGE_SIZE ++} ++ ++static void rtw8852a_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++#define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24 ++ u8 ch = rtwdev->hal.current_channel; ++ u8 bw = rtwdev->hal.current_band_width; ++ struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852A]; ++ u32 addr, val; ++ const s8 *ptr; ++ u8 i, j, k; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, ++ "[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw); ++ ++ for (i = 0; i < NTX_NUM_8852A; i++) { ++ rtw89_phy_fill_txpwr_limit_ru(rtwdev, &lmt_ru[i], i); ++ ++ for (j = 0; j < __MAC_TXPWR_LMT_RU_PAGE_SIZE; j += 4) { ++ addr = R_AX_PWR_RU_LMT + j + ++ __MAC_TXPWR_LMT_RU_PAGE_SIZE * i; ++ ptr = (s8 *)&lmt_ru[i] + j; ++ val = 0; ++ ++ for (k = 0; k < 4; k++) ++ val |= (ptr[k] << (8 * k)); ++ ++ rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); ++ } ++ } ++ ++#undef __MAC_TXPWR_LMT_RU_PAGE_SIZE ++} ++ ++static void rtw8852a_set_txpwr(struct rtw89_dev *rtwdev) ++{ ++ rtw8852a_set_txpwr_byrate(rtwdev, RTW89_PHY_0); ++ rtw8852a_set_txpwr_limit(rtwdev, RTW89_PHY_0); ++ rtw8852a_set_txpwr_limit_ru(rtwdev, RTW89_PHY_0); ++} ++ ++static void rtw8852a_set_txpwr_ctrl(struct rtw89_dev *rtwdev) ++{ ++ rtw8852a_set_txpwr_ref(rtwdev, RTW89_PHY_0); ++ rtw8852a_set_txpwr_offset(rtwdev, RTW89_PHY_0); ++} ++ ++static int ++rtw8852a_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) ++{ ++ int ret; ++ ++ ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL2, 0x07763333); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_COEXT_CTRL, 0x01ebf004); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL0, 0x0002f8ff); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++void rtw8852a_bb_set_plcp_tx(struct rtw89_dev *rtwdev) ++{ ++ u8 i = 0; ++ u32 addr, val; ++ ++ for (i = 0; i < ARRAY_SIZE(rtw8852a_pmac_ht20_mcs7_tbl); i++) { ++ addr = rtw8852a_pmac_ht20_mcs7_tbl[i].addr; ++ val = rtw8852a_pmac_ht20_mcs7_tbl[i].data; ++ rtw89_phy_write32(rtwdev, addr, val); ++ } ++} ++ ++static void rtw8852a_stop_pmac_tx(struct rtw89_dev *rtwdev, ++ struct rtw8852a_bb_pmac_info *tx_info, ++ enum rtw89_phy_idx idx) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC Stop Tx"); ++ if (tx_info->mode == CONT_TX) ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_CTX_EN, 0, ++ idx); ++ else if (tx_info->mode == PKTS_TX) ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_PTX_EN, 0, ++ idx); ++} ++ ++static void rtw8852a_start_pmac_tx(struct rtw89_dev *rtwdev, ++ struct rtw8852a_bb_pmac_info *tx_info, ++ enum rtw89_phy_idx idx) ++{ ++ enum rtw8852a_pmac_mode mode = tx_info->mode; ++ u32 pkt_cnt = tx_info->tx_cnt; ++ u16 period = tx_info->period; ++ ++ if (mode == CONT_TX && !tx_info->is_cck) { ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_CTX_EN, 1, ++ idx); ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CTx Start"); ++ } else if (mode == PKTS_TX) { ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_PTX_EN, 1, ++ idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, ++ B_PMAC_TX_PRD_MSK, period, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CNT, B_PMAC_TX_CNT_MSK, ++ pkt_cnt, idx); ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC PTx Start"); ++ } ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CTRL, B_PMAC_TXEN_DIS, 1, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CTRL, B_PMAC_TXEN_DIS, 0, idx); ++} ++ ++void rtw8852a_bb_set_pmac_tx(struct rtw89_dev *rtwdev, ++ struct rtw8852a_bb_pmac_info *tx_info, ++ enum rtw89_phy_idx idx) ++{ ++ if (!tx_info->en_pmac_tx) { ++ rtw8852a_stop_pmac_tx(rtwdev, tx_info, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0, idx); ++ if (rtwdev->hal.current_band_type == RTW89_BAND_2G) ++ rtw89_phy_write32_clr(rtwdev, R_RXCCA, B_RXCCA_DIS); ++ return; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC Tx Enable"); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_TXEN, 1, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_RXEN, 1, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_RX_CFG1, B_PMAC_OPT1_MSK, 0x3f, ++ idx); ++ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 1, idx); ++ rtw89_phy_write32_set(rtwdev, R_RXCCA, B_RXCCA_DIS); ++ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, idx); ++ rtw8852a_start_pmac_tx(rtwdev, tx_info, idx); ++} ++ ++void rtw8852a_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable, ++ u16 tx_cnt, u16 period, u16 tx_time, ++ enum rtw89_phy_idx idx) ++{ ++ struct rtw8852a_bb_pmac_info tx_info = {0}; ++ ++ tx_info.en_pmac_tx = enable; ++ tx_info.is_cck = 0; ++ tx_info.mode = PKTS_TX; ++ tx_info.tx_cnt = tx_cnt; ++ tx_info.period = period; ++ tx_info.tx_time = tx_time; ++ rtw8852a_bb_set_pmac_tx(rtwdev, &tx_info, idx); ++} ++ ++void rtw8852a_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm, ++ enum rtw89_phy_idx idx) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CFG Tx PWR = %d", pwr_dbm); ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 1, idx); ++ rtw89_phy_write32_idx(rtwdev, R_TXPWR, B_TXPWR_MSK, pwr_dbm, idx); ++} ++ ++void rtw8852a_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path) ++{ ++ u32 rst_mask0 = 0; ++ u32 rst_mask1 = 0; ++ ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 7, RTW89_PHY_0); ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 7, RTW89_PHY_1); ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CFG Tx Path = %d", tx_path); ++ if (!rtwdev->dbcc_en) { ++ if (tx_path == RF_PATH_A) { ++ rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, ++ B_TXPATH_SEL_MSK, 1); ++ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, ++ B_TXNSS_MAP_MSK, 0); ++ } else if (tx_path == RF_PATH_B) { ++ rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, ++ B_TXPATH_SEL_MSK, 2); ++ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, ++ B_TXNSS_MAP_MSK, 0); ++ } else if (tx_path == RF_PATH_AB) { ++ rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, ++ B_TXPATH_SEL_MSK, 3); ++ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, ++ B_TXNSS_MAP_MSK, 4); ++ } else { ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "Error Tx Path"); ++ } ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, ++ 1); ++ rtw89_phy_write32_idx(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, 2, ++ RTW89_PHY_1); ++ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, ++ 0); ++ rtw89_phy_write32_idx(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 4, ++ RTW89_PHY_1); ++ } ++ rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI; ++ rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI; ++ if (tx_path == RF_PATH_A) { ++ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 1); ++ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 3); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 1); ++ rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 3); ++ } ++} ++ ++void rtw8852a_bb_tx_mode_switch(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx idx, u8 mode) ++{ ++ if (mode != 0) ++ return; ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "Tx mode switch"); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_TXEN, 0, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_RXEN, 0, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_RX_CFG1, B_PMAC_OPT1_MSK, 0, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_RXMOD, B_PMAC_RXMOD_MSK, 0, idx); ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_DPD_EN, 0, idx); ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, idx); ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 0, idx); ++} ++ ++static void rtw8852a_bb_ctrl_btc_preagc(struct rtw89_dev *rtwdev, bool bt_en) ++{ ++ rtw89_phy_write_reg3_tbl(rtwdev, bt_en ? &rtw8852a_btc_preagc_en_defs_tbl : ++ &rtw8852a_btc_preagc_dis_defs_tbl); ++} ++ ++static u8 rtw8852a_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) ++{ ++ if (rtwdev->is_tssi_mode[rf_path]) { ++ u32 addr = 0x1c10 + (rf_path << 13); ++ ++ return (u8)rtw89_phy_read32_mask(rtwdev, addr, 0x3F000000); ++ } ++ ++ rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); ++ rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0); ++ rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); ++ ++ fsleep(200); ++ ++ return (u8)rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL); ++} ++ ++static void rtw8852a_btc_set_rfe(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_module *module = &btc->mdinfo; ++ ++ module->rfe_type = rtwdev->efuse.rfe_type; ++ module->cv = rtwdev->hal.cv; ++ module->bt_solo = 0; ++ module->switch_type = BTC_SWITCH_INTERNAL; ++ ++ if (module->rfe_type > 0) ++ module->ant.num = (module->rfe_type % 2 ? 2 : 3); ++ else ++ module->ant.num = 2; ++ ++ module->ant.diversity = 0; ++ module->ant.isolation = 10; ++ ++ if (module->ant.num == 3) { ++ module->ant.type = BTC_ANT_DEDICATED; ++ module->bt_pos = BTC_BT_ALONE; ++ } else { ++ module->ant.type = BTC_ANT_SHARED; ++ module->bt_pos = BTC_BT_BTG; ++ } ++} ++ ++static ++void rtw8852a_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val) ++{ ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, 0xfffff, 0x20000); ++ rtw89_write_rf(rtwdev, path, RR_LUTWA, 0xfffff, group); ++ rtw89_write_rf(rtwdev, path, RR_LUTWD0, 0xfffff, val); ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, 0xfffff, 0x0); ++} ++ ++static void rtw8852a_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) ++{ ++ if (btg) { ++ rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG, B_PATH0_BTG_SHEN, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG, B_PATH1_BTG_SHEN, 0x3); ++ rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG, B_PATH0_BTG_SHEN, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG, B_PATH1_BTG_SHEN, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xf); ++ rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P2, 0x4); ++ } ++} ++ ++static void rtw8852a_btc_init_cfg(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_module *module = &btc->mdinfo; ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ const struct rtw89_mac_ax_coex coex_params = { ++ .pta_mode = RTW89_MAC_AX_COEX_RTK_MODE, ++ .direction = RTW89_MAC_AX_COEX_INNER, ++ }; ++ ++ /* PTA init */ ++ rtw89_mac_coex_init(rtwdev, &coex_params); ++ ++ /* set WL Tx response = Hi-Pri */ ++ chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true); ++ chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true); ++ ++ /* set rf gnt debug off */ ++ rtw89_write_rf(rtwdev, RF_PATH_A, RR_WLSEL, 0xfffff, 0x0); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_WLSEL, 0xfffff, 0x0); ++ ++ /* set WL Tx thru in TRX mask table if GNT_WL = 0 && BT_S1 = ss group */ ++ if (module->ant.type == BTC_ANT_SHARED) { ++ rtw8852a_set_trx_mask(rtwdev, ++ RF_PATH_A, BTC_BT_SS_GROUP, 0x5ff); ++ rtw8852a_set_trx_mask(rtwdev, ++ RF_PATH_B, BTC_BT_SS_GROUP, 0x5ff); ++ } else { /* set WL Tx stb if GNT_WL = 0 && BT_S1 = ss group for 3-ant */ ++ rtw8852a_set_trx_mask(rtwdev, ++ RF_PATH_A, BTC_BT_SS_GROUP, 0x5df); ++ rtw8852a_set_trx_mask(rtwdev, ++ RF_PATH_B, BTC_BT_SS_GROUP, 0x5df); ++ } ++ ++ /* set PTA break table */ ++ rtw89_write32(rtwdev, R_BTC_BREAK_TABLE, BTC_BREAK_PARAM); ++ ++ /* enable BT counter 0xda40[16,2] = 2b'11 */ ++ rtw89_write32_set(rtwdev, ++ R_AX_CSR_MODE, B_AX_BT_CNT_RST | B_AX_STATIS_BT_EN); ++ btc->cx.wl.status.map.init_ok = true; ++} ++ ++static ++void rtw8852a_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state) ++{ ++ u32 bitmap = 0; ++ u32 reg = 0; ++ ++ switch (map) { ++ case BTC_PRI_MASK_TX_RESP: ++ reg = R_BTC_BT_COEX_MSK_TABLE; ++ bitmap = B_BTC_PRI_MASK_TX_RESP_V1; ++ break; ++ case BTC_PRI_MASK_BEACON: ++ reg = R_AX_WL_PRI_MSK; ++ bitmap = B_AX_PTA_WL_PRI_MASK_BCNQ; ++ break; ++ default: ++ return; ++ } ++ ++ if (state) ++ rtw89_write32_set(rtwdev, reg, bitmap); ++ else ++ rtw89_write32_clr(rtwdev, reg, bitmap); ++} ++ ++static inline u32 __btc_ctrl_val_all_time(u32 ctrl) ++{ ++ return FIELD_GET(GENMASK(15, 0), ctrl); ++} ++ ++static inline u32 __btc_ctrl_rst_all_time(u32 cur) ++{ ++ return cur & ~B_AX_FORCE_PWR_BY_RATE_EN; ++} ++ ++static inline u32 __btc_ctrl_gen_all_time(u32 cur, u32 val) ++{ ++ u32 hv = cur & ~B_AX_FORCE_PWR_BY_RATE_VALUE_MASK; ++ u32 lv = val & B_AX_FORCE_PWR_BY_RATE_VALUE_MASK; ++ ++ return hv | lv | B_AX_FORCE_PWR_BY_RATE_EN; ++} ++ ++static inline u32 __btc_ctrl_val_gnt_bt(u32 ctrl) ++{ ++ return FIELD_GET(GENMASK(31, 16), ctrl); ++} ++ ++static inline u32 __btc_ctrl_rst_gnt_bt(u32 cur) ++{ ++ return cur & ~B_AX_TXAGC_BT_EN; ++} ++ ++static inline u32 __btc_ctrl_gen_gnt_bt(u32 cur, u32 val) ++{ ++ u32 ov = cur & ~B_AX_TXAGC_BT_MASK; ++ u32 iv = FIELD_PREP(B_AX_TXAGC_BT_MASK, val); ++ ++ return ov | iv | B_AX_TXAGC_BT_EN; ++} ++ ++static void ++rtw8852a_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val) ++{ ++ const u32 __btc_cr_all_time = R_AX_PWR_RATE_CTRL; ++ const u32 __btc_cr_gnt_bt = R_AX_PWR_COEXT_CTRL; ++ ++#define __do_clr(_chk) ((_chk) == GENMASK(15, 0)) ++#define __handle(_case) \ ++ do { \ ++ const u32 _reg = __btc_cr_ ## _case; \ ++ u32 _val = __btc_ctrl_val_ ## _case(txpwr_val); \ ++ u32 _cur, _wrt; \ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, \ ++ "btc ctrl %s: 0x%x\n", #_case, _val); \ ++ rtw89_mac_txpwr_read32(rtwdev, RTW89_PHY_0, _reg, &_cur);\ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, \ ++ "btc ctrl ori 0x%x: 0x%x\n", _reg, _cur); \ ++ _wrt = __do_clr(_val) ? \ ++ __btc_ctrl_rst_ ## _case(_cur) : \ ++ __btc_ctrl_gen_ ## _case(_cur, _val); \ ++ rtw89_mac_txpwr_write32(rtwdev, RTW89_PHY_0, _reg, _wrt);\ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, \ ++ "btc ctrl set 0x%x: 0x%x\n", _reg, _wrt); \ ++ } while (0) ++ ++ __handle(all_time); ++ __handle(gnt_bt); ++ ++#undef __handle ++#undef __do_clr ++} ++ ++static ++s8 rtw8852a_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) ++{ ++ return clamp_t(s8, val, -100, 0) + 100; ++} ++ ++static struct rtw89_btc_rf_trx_para rtw89_btc_8852a_rf_ul[] = { ++ {255, 0, 0, 7}, /* 0 -> original */ ++ {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ ++ {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ ++ {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ ++ {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ ++ {255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ ++ {6, 1, 0, 7}, ++ {13, 1, 0, 7}, ++ {13, 1, 0, 7} ++}; ++ ++static struct rtw89_btc_rf_trx_para rtw89_btc_8852a_rf_dl[] = { ++ {255, 0, 0, 7}, /* 0 -> original */ ++ {255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */ ++ {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ ++ {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ ++ {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ ++ {255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ ++ {255, 1, 0, 7}, ++ {255, 1, 0, 7}, ++ {255, 1, 0, 7} ++}; ++ ++static const ++u8 rtw89_btc_8852a_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {60, 50, 40, 30}; ++static const ++u8 rtw89_btc_8852a_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {40, 36, 31, 28}; ++ ++static struct rtw89_btc_fbtc_mreg rtw89_btc_8852a_mon_reg[] = { ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda24), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda28), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda2c), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda30), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda4c), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda10), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda20), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda34), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xcef4), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x8424), ++ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980), ++ RTW89_DEF_FBTC_MREG(REG_BT_MODEM, 4, 0x178), ++}; ++ ++static ++void rtw8852a_btc_bt_aci_imp(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ struct rtw89_btc_bt_link_info *b = &bt->link_info; ++ ++ /* fix LNA2 = level-5 for BT ACI issue at BTG */ ++ if (btc->dm.wl_btg_rx && b->profile_cnt.now != 0) ++ dm->trx_para_level = 1; ++} ++ ++static ++void rtw8852a_btc_update_bt_cnt(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ u32 val; ++ ++ val = rtw89_read32(rtwdev, R_AX_BT_STAST_HIGH); ++ cx->cnt_bt[BTC_BCNT_HIPRI_TX] = FIELD_GET(B_AX_STATIS_BT_HI_TX_MASK, val); ++ cx->cnt_bt[BTC_BCNT_HIPRI_RX] = FIELD_GET(B_AX_STATIS_BT_HI_RX_MASK, val); ++ ++ val = rtw89_read32(rtwdev, R_AX_BT_STAST_LOW); ++ cx->cnt_bt[BTC_BCNT_LOPRI_TX] = FIELD_GET(B_AX_STATIS_BT_LO_TX_1_MASK, val); ++ cx->cnt_bt[BTC_BCNT_LOPRI_RX] = FIELD_GET(B_AX_STATIS_BT_LO_RX_1_MASK, val); ++ ++ /* clock-gate off before reset counter*/ ++ rtw89_write32_set(rtwdev, R_AX_BTC_CFG, B_AX_DIS_BTC_CLK_G); ++ rtw89_write32_clr(rtwdev, R_AX_CSR_MODE, B_AX_BT_CNT_RST); ++ rtw89_write32_set(rtwdev, R_AX_CSR_MODE, B_AX_BT_CNT_RST); ++ rtw89_write32_clr(rtwdev, R_AX_BTC_CFG, B_AX_DIS_BTC_CLK_G); ++} ++ ++static ++void rtw8852a_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state) ++{ ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x1); ++ ++ /* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */ ++ if (state) ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, ++ RFREG_MASK, 0xa2d7c); ++ else ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, ++ RFREG_MASK, 0xa2020); ++ ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); ++} ++ ++static void rtw8852a_query_ppdu(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_phy_ppdu *phy_ppdu, ++ struct ieee80211_rx_status *status) ++{ ++ u8 path; ++ s8 *rx_power = phy_ppdu->rssi; ++ ++ status->signal = max_t(s8, rx_power[RF_PATH_A], rx_power[RF_PATH_B]); ++ for (path = 0; path < rtwdev->chip->rf_path_num; path++) { ++ status->chains |= BIT(path); ++ status->chain_signal[path] = rx_power[path]; ++ } ++} ++ ++static const struct rtw89_chip_ops rtw8852a_chip_ops = { ++ .bb_reset = rtw8852a_bb_reset, ++ .bb_sethw = rtw8852a_bb_sethw, ++ .read_rf = rtw89_phy_read_rf, ++ .write_rf = rtw89_phy_write_rf, ++ .set_channel = rtw8852a_set_channel, ++ .set_channel_help = rtw8852a_set_channel_help, ++ .read_efuse = rtw8852a_read_efuse, ++ .read_phycap = rtw8852a_read_phycap, ++ .fem_setup = rtw8852a_fem_setup, ++ .rfk_init = rtw8852a_rfk_init, ++ .rfk_channel = rtw8852a_rfk_channel, ++ .rfk_band_changed = rtw8852a_rfk_band_changed, ++ .rfk_scan = rtw8852a_rfk_scan, ++ .rfk_track = rtw8852a_rfk_track, ++ .power_trim = rtw8852a_power_trim, ++ .set_txpwr = rtw8852a_set_txpwr, ++ .set_txpwr_ctrl = rtw8852a_set_txpwr_ctrl, ++ .init_txpwr_unit = rtw8852a_init_txpwr_unit, ++ .get_thermal = rtw8852a_get_thermal, ++ .ctrl_btg = rtw8852a_ctrl_btg, ++ .query_ppdu = rtw8852a_query_ppdu, ++ .bb_ctrl_btc_preagc = rtw8852a_bb_ctrl_btc_preagc, ++ .set_txpwr_ul_tb_offset = rtw8852a_set_txpwr_ul_tb_offset, ++ ++ .btc_set_rfe = rtw8852a_btc_set_rfe, ++ .btc_init_cfg = rtw8852a_btc_init_cfg, ++ .btc_set_wl_pri = rtw8852a_btc_set_wl_pri, ++ .btc_set_wl_txpwr_ctrl = rtw8852a_btc_set_wl_txpwr_ctrl, ++ .btc_get_bt_rssi = rtw8852a_btc_get_bt_rssi, ++ .btc_bt_aci_imp = rtw8852a_btc_bt_aci_imp, ++ .btc_update_bt_cnt = rtw8852a_btc_update_bt_cnt, ++ .btc_wl_s1_standby = rtw8852a_btc_wl_s1_standby, ++}; ++ ++const struct rtw89_chip_info rtw8852a_chip_info = { ++ .chip_id = RTL8852A, ++ .ops = &rtw8852a_chip_ops, ++ .fw_name = "rtw89/rtw8852a_fw.bin", ++ .fifo_size = 458752, ++ .max_amsdu_limit = 3500, ++ .dis_2g_40m_ul_ofdma = true, ++ .hfc_param_ini = rtw8852a_hfc_param_ini_pcie, ++ .dle_mem = rtw8852a_dle_mem_pcie, ++ .rf_base_addr = {0xc000, 0xd000}, ++ .pwr_on_seq = pwr_on_seq_8852a, ++ .pwr_off_seq = pwr_off_seq_8852a, ++ .bb_table = &rtw89_8852a_phy_bb_table, ++ .rf_table = {&rtw89_8852a_phy_radioa_table, ++ &rtw89_8852a_phy_radiob_table,}, ++ .nctl_table = &rtw89_8852a_phy_nctl_table, ++ .byr_table = &rtw89_8852a_byr_table, ++ .txpwr_lmt_2g = &rtw89_8852a_txpwr_lmt_2g, ++ .txpwr_lmt_5g = &rtw89_8852a_txpwr_lmt_5g, ++ .txpwr_lmt_ru_2g = &rtw89_8852a_txpwr_lmt_ru_2g, ++ .txpwr_lmt_ru_5g = &rtw89_8852a_txpwr_lmt_ru_5g, ++ .txpwr_factor_rf = 2, ++ .txpwr_factor_mac = 1, ++ .dig_table = &rtw89_8852a_phy_dig_table, ++ .rf_path_num = 2, ++ .tx_nss = 2, ++ .rx_nss = 2, ++ .acam_num = 128, ++ .bcam_num = 10, ++ .scam_num = 128, ++ .sec_ctrl_efuse_size = 4, ++ .physical_efuse_size = 1216, ++ .logical_efuse_size = 1536, ++ .limit_efuse_size = 1152, ++ .phycap_addr = 0x580, ++ .phycap_size = 128, ++ .para_ver = 0x05050764, ++ .wlcx_desired = 0x05050000, ++ .btcx_desired = 0x5, ++ .scbd = 0x1, ++ .mailbox = 0x1, ++ .afh_guard_ch = 6, ++ .wl_rssi_thres = rtw89_btc_8852a_wl_rssi_thres, ++ .bt_rssi_thres = rtw89_btc_8852a_bt_rssi_thres, ++ .rssi_tol = 2, ++ .mon_reg_num = ARRAY_SIZE(rtw89_btc_8852a_mon_reg), ++ .mon_reg = rtw89_btc_8852a_mon_reg, ++ .rf_para_ulink_num = ARRAY_SIZE(rtw89_btc_8852a_rf_ul), ++ .rf_para_ulink = rtw89_btc_8852a_rf_ul, ++ .rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8852a_rf_dl), ++ .rf_para_dlink = rtw89_btc_8852a_rf_dl, ++ .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) | ++ BIT(RTW89_PS_MODE_CLK_GATED) | ++ BIT(RTW89_PS_MODE_PWR_GATED), ++}; ++EXPORT_SYMBOL(rtw8852a_chip_info); ++ ++MODULE_FIRMWARE("rtw89/rtw8852a_fw.bin"); +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.h b/drivers/net/wireless/realtek/rtw89/rtw8852a.h +new file mode 100644 +index 000000000000..633384374de0 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.h +@@ -0,0 +1,109 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_8852A_H__ ++#define __RTW89_8852A_H__ ++ ++#include "core.h" ++ ++#define RF_PATH_NUM_8852A 2 ++#define NTX_NUM_8852A 2 ++ ++enum rtw8852a_pmac_mode { ++ NONE_TEST, ++ PKTS_TX, ++ PKTS_RX, ++ CONT_TX ++}; ++ ++struct rtw8852au_efuse { ++ u8 rsvd[0x38]; ++ u8 mac_addr[ETH_ALEN]; ++}; ++ ++struct rtw8852ae_efuse { ++ u8 mac_addr[ETH_ALEN]; ++}; ++ ++struct rtw8852a_tssi_offset { ++ u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM]; ++ u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM]; ++ u8 rsvd[7]; ++ u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM]; ++} __packed; ++ ++struct rtw8852a_efuse { ++ u8 rsvd[0x210]; ++ struct rtw8852a_tssi_offset path_a_tssi; ++ u8 rsvd1[10]; ++ struct rtw8852a_tssi_offset path_b_tssi; ++ u8 rsvd2[94]; ++ u8 channel_plan; ++ u8 xtal_k; ++ u8 rsvd3; ++ u8 iqk_lck; ++ u8 rsvd4[5]; ++ u8 reg_setting:2; ++ u8 tx_diversity:1; ++ u8 rx_diversity:2; ++ u8 ac_mode:1; ++ u8 module_type:2; ++ u8 rsvd5; ++ u8 shared_ant:1; ++ u8 coex_type:3; ++ u8 ant_iso:1; ++ u8 radio_on_off:1; ++ u8 rsvd6:2; ++ u8 eeprom_version; ++ u8 customer_id; ++ u8 tx_bb_swing_2g; ++ u8 tx_bb_swing_5g; ++ u8 tx_cali_pwr_trk_mode; ++ u8 trx_path_selection; ++ u8 rfe_type; ++ u8 country_code[2]; ++ u8 rsvd7[3]; ++ u8 path_a_therm; ++ u8 path_b_therm; ++ u8 rsvd8[46]; ++ u8 path_a_cck_pwr_idx[6]; ++ u8 path_a_bw40_1tx_pwr_idx[5]; ++ u8 path_a_ofdm_1tx_pwr_idx_diff:4; ++ u8 path_a_bw20_1tx_pwr_idx_diff:4; ++ u8 path_a_bw20_2tx_pwr_idx_diff:4; ++ u8 path_a_bw40_2tx_pwr_idx_diff:4; ++ u8 path_a_cck_2tx_pwr_idx_diff:4; ++ u8 path_a_ofdm_2tx_pwr_idx_diff:4; ++ u8 rsvd9[0xf2]; ++ union { ++ struct rtw8852au_efuse u; ++ struct rtw8852ae_efuse e; ++ }; ++} __packed; ++ ++struct rtw8852a_bb_pmac_info { ++ u8 en_pmac_tx:1; ++ u8 is_cck:1; ++ u8 mode:3; ++ u8 rsvd:3; ++ u16 tx_cnt; ++ u16 period; ++ u16 tx_time; ++ u8 duty_cycle; ++}; ++ ++void rtw8852a_bb_set_plcp_tx(struct rtw89_dev *rtwdev); ++void rtw8852a_bb_set_pmac_tx(struct rtw89_dev *rtwdev, ++ struct rtw8852a_bb_pmac_info *tx_info, ++ enum rtw89_phy_idx idx); ++void rtw8852a_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable, ++ u16 tx_cnt, u16 period, u16 tx_time, ++ enum rtw89_phy_idx idx); ++void rtw8852a_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm, ++ enum rtw89_phy_idx idx); ++void rtw8852a_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path); ++void rtw8852a_bb_tx_mode_switch(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx idx, u8 mode); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c +new file mode 100644 +index 000000000000..c021e93eb07b +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c +@@ -0,0 +1,3911 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "coex.h" ++#include "debug.h" ++#include "mac.h" ++#include "phy.h" ++#include "reg.h" ++#include "rtw8852a.h" ++#include "rtw8852a_rfk.h" ++#include "rtw8852a_rfk_table.h" ++#include "rtw8852a_table.h" ++ ++static void ++_rfk_write_rf(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) ++{ ++ rtw89_write_rf(rtwdev, def->path, def->addr, def->mask, def->data); ++} ++ ++static void ++_rfk_write32_mask(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) ++{ ++ rtw89_phy_write32_mask(rtwdev, def->addr, def->mask, def->data); ++} ++ ++static void ++_rfk_write32_set(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) ++{ ++ rtw89_phy_write32_set(rtwdev, def->addr, def->mask); ++} ++ ++static void ++_rfk_write32_clr(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) ++{ ++ rtw89_phy_write32_clr(rtwdev, def->addr, def->mask); ++} ++ ++static void ++_rfk_delay(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) ++{ ++ udelay(def->data); ++} ++ ++static void ++(*_rfk_handler[])(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) = { ++ [RTW89_RFK_F_WRF] = _rfk_write_rf, ++ [RTW89_RFK_F_WM] = _rfk_write32_mask, ++ [RTW89_RFK_F_WS] = _rfk_write32_set, ++ [RTW89_RFK_F_WC] = _rfk_write32_clr, ++ [RTW89_RFK_F_DELAY] = _rfk_delay, ++}; ++ ++static_assert(ARRAY_SIZE(_rfk_handler) == RTW89_RFK_F_NUM); ++ ++static void ++rtw89_rfk_parser(struct rtw89_dev *rtwdev, const struct rtw89_rfk_tbl *tbl) ++{ ++ const struct rtw89_reg5_def *p = tbl->defs; ++ const struct rtw89_reg5_def *end = tbl->defs + tbl->size; ++ ++ for (; p < end; p++) ++ _rfk_handler[p->flag](rtwdev, p); ++} ++ ++#define rtw89_rfk_parser_by_cond(rtwdev, cond, tbl_t, tbl_f) \ ++ do { \ ++ typeof(rtwdev) _dev = (rtwdev); \ ++ if (cond) \ ++ rtw89_rfk_parser(_dev, (tbl_t)); \ ++ else \ ++ rtw89_rfk_parser(_dev, (tbl_f)); \ ++ } while (0) ++ ++static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x, PHY%d\n", ++ rtwdev->dbcc_en, phy_idx); ++ ++ if (!rtwdev->dbcc_en) ++ return RF_AB; ++ ++ if (phy_idx == RTW89_PHY_0) ++ return RF_A; ++ else ++ return RF_B; ++} ++ ++static const u32 rtw8852a_backup_bb_regs[] = {0x2344, 0x58f0, 0x78f0}; ++static const u32 rtw8852a_backup_rf_regs[] = {0xef, 0xde, 0x0, 0x1e, 0x2, 0x85, 0x90, 0x5}; ++#define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852a_backup_bb_regs) ++#define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8852a_backup_rf_regs) ++ ++static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[]) ++{ ++ u32 i; ++ ++ for (i = 0; i < BACKUP_BB_REGS_NR; i++) { ++ backup_bb_reg_val[i] = ++ rtw89_phy_read32_mask(rtwdev, rtw8852a_backup_bb_regs[i], ++ MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]backup bb reg : %x, value =%x\n", ++ rtw8852a_backup_bb_regs[i], backup_bb_reg_val[i]); ++ } ++} ++ ++static void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[], ++ u8 rf_path) ++{ ++ u32 i; ++ ++ for (i = 0; i < BACKUP_RF_REGS_NR; i++) { ++ backup_rf_reg_val[i] = ++ rtw89_read_rf(rtwdev, rf_path, ++ rtw8852a_backup_rf_regs[i], RFREG_MASK); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]backup rf S%d reg : %x, value =%x\n", rf_path, ++ rtw8852a_backup_rf_regs[i], backup_rf_reg_val[i]); ++ } ++} ++ ++static void _rfk_restore_bb_reg(struct rtw89_dev *rtwdev, ++ u32 backup_bb_reg_val[]) ++{ ++ u32 i; ++ ++ for (i = 0; i < BACKUP_BB_REGS_NR; i++) { ++ rtw89_phy_write32_mask(rtwdev, rtw8852a_backup_bb_regs[i], ++ MASKDWORD, backup_bb_reg_val[i]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]restore bb reg : %x, value =%x\n", ++ rtw8852a_backup_bb_regs[i], backup_bb_reg_val[i]); ++ } ++} ++ ++static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev, ++ u32 backup_rf_reg_val[], u8 rf_path) ++{ ++ u32 i; ++ ++ for (i = 0; i < BACKUP_RF_REGS_NR; i++) { ++ rtw89_write_rf(rtwdev, rf_path, rtw8852a_backup_rf_regs[i], ++ RFREG_MASK, backup_rf_reg_val[i]); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]restore rf S%d reg: %x, value =%x\n", rf_path, ++ rtw8852a_backup_rf_regs[i], backup_rf_reg_val[i]); ++ } ++} ++ ++static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) ++{ ++ u8 path; ++ u32 rf_mode; ++ int ret; ++ ++ for (path = 0; path < RF_PATH_MAX; path++) { ++ if (!(kpath & BIT(path))) ++ continue; ++ ++ ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, rf_mode != 2, ++ 2, 5000, false, rtwdev, path, 0x00, ++ RR_MOD_MASK); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", ++ path, ret); ++ } ++} ++ ++static void _dack_dump(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u8 i; ++ u8 t; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n", ++ dack->addck_d[0][0], dack->addck_d[0][1]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DACK]S1 ADC_DCK ic = 0x%x, qc = 0x%x\n", ++ dack->addck_d[1][0], dack->addck_d[1][1]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n", ++ dack->dadck_d[0][0], dack->dadck_d[0][1]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n", ++ dack->dadck_d[1][0], dack->dadck_d[1][1]); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n", ++ dack->biask_d[0][0], dack->biask_d[0][1]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DACK]S1 biask ic = 0x%x, qc = 0x%x\n", ++ dack->biask_d[1][0], dack->biask_d[1][1]); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n"); ++ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { ++ t = dack->msbk_d[0][0][i]; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n"); ++ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { ++ t = dack->msbk_d[0][1][i]; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n"); ++ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { ++ t = dack->msbk_d[1][0][i]; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n"); ++ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { ++ t = dack->msbk_d[1][1][i]; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); ++ } ++} ++ ++static void _afe_init(struct rtw89_dev *rtwdev) ++{ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_afe_init_defs_tbl); ++} ++ ++static void _addck_backup(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ ++ rtw89_phy_write32_clr(rtwdev, R_S0_RXDC2, B_S0_RXDC2_SEL); ++ dack->addck_d[0][0] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_ADDCK, ++ B_S0_ADDCK_Q); ++ dack->addck_d[0][1] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_ADDCK, ++ B_S0_ADDCK_I); ++ ++ rtw89_phy_write32_clr(rtwdev, R_S1_RXDC2, B_S1_RXDC2_SEL); ++ dack->addck_d[1][0] = (u16)rtw89_phy_read32_mask(rtwdev, R_S1_ADDCK, ++ B_S1_ADDCK_Q); ++ dack->addck_d[1][1] = (u16)rtw89_phy_read32_mask(rtwdev, R_S1_ADDCK, ++ B_S1_ADDCK_I); ++} ++ ++static void _addck_reload(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ ++ rtw89_phy_write32_mask(rtwdev, R_S0_RXDC, B_S0_RXDC_I, dack->addck_d[0][0]); ++ rtw89_phy_write32_mask(rtwdev, R_S0_RXDC2, B_S0_RXDC2_Q2, ++ (dack->addck_d[0][1] >> 6)); ++ rtw89_phy_write32_mask(rtwdev, R_S0_RXDC, B_S0_RXDC_Q, ++ (dack->addck_d[0][1] & 0x3f)); ++ rtw89_phy_write32_set(rtwdev, R_S0_RXDC2, B_S0_RXDC2_MEN); ++ rtw89_phy_write32_mask(rtwdev, R_S1_RXDC, B_S1_RXDC_I, dack->addck_d[1][0]); ++ rtw89_phy_write32_mask(rtwdev, R_S1_RXDC2, B_S1_RXDC2_Q2, ++ (dack->addck_d[1][1] >> 6)); ++ rtw89_phy_write32_mask(rtwdev, R_S1_RXDC, B_S1_RXDC_Q, ++ (dack->addck_d[1][1] & 0x3f)); ++ rtw89_phy_write32_set(rtwdev, R_S1_RXDC2, B_S1_RXDC2_EN); ++} ++ ++static void _dack_backup_s0(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u8 i; ++ ++ rtw89_phy_write32_set(rtwdev, R_S0_DACKI, B_S0_DACKI_EN); ++ rtw89_phy_write32_set(rtwdev, R_S0_DACKQ, B_S0_DACKQ_EN); ++ rtw89_phy_write32_set(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG); ++ ++ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { ++ rtw89_phy_write32_mask(rtwdev, R_S0_DACKI, B_S0_DACKI_AR, i); ++ dack->msbk_d[0][0][i] = ++ (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKI7, B_S0_DACKI7_K); ++ rtw89_phy_write32_mask(rtwdev, R_S0_DACKQ, B_S0_DACKQ_AR, i); ++ dack->msbk_d[0][1][i] = ++ (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKQ7, B_S0_DACKQ7_K); ++ } ++ dack->biask_d[0][0] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_DACKI2, ++ B_S0_DACKI2_K); ++ dack->biask_d[0][1] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_DACKQ2, ++ B_S0_DACKQ2_K); ++ dack->dadck_d[0][0] = (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKI8, ++ B_S0_DACKI8_K) - 8; ++ dack->dadck_d[0][1] = (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKQ8, ++ B_S0_DACKQ8_K) - 8; ++} ++ ++static void _dack_backup_s1(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u8 i; ++ ++ rtw89_phy_write32_set(rtwdev, R_S1_DACKI, B_S1_DACKI_EN); ++ rtw89_phy_write32_set(rtwdev, R_S1_DACKQ, B_S1_DACKQ_EN); ++ rtw89_phy_write32_set(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON); ++ ++ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { ++ rtw89_phy_write32_mask(rtwdev, R_S1_DACKI, B_S1_DACKI_AR, i); ++ dack->msbk_d[1][0][i] = ++ (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKI7, B_S1_DACKI_K); ++ rtw89_phy_write32_mask(rtwdev, R_S1_DACKQ, B_S1_DACKQ_AR, i); ++ dack->msbk_d[1][1][i] = ++ (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKQ7, B_S1_DACKQ7_K); ++ } ++ dack->biask_d[1][0] = ++ (u16)rtw89_phy_read32_mask(rtwdev, R_S1_DACKI2, B_S1_DACKI2_K); ++ dack->biask_d[1][1] = ++ (u16)rtw89_phy_read32_mask(rtwdev, R_S1_DACKQ2, B_S1_DACKQ2_K); ++ dack->dadck_d[1][0] = ++ (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKI8, B_S1_DACKI8_K) - 8; ++ dack->dadck_d[1][1] = ++ (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKQ8, B_S1_DACKQ8_K) - 8; ++} ++ ++static void _dack_reload_by_path(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, u8 index) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u32 tmp = 0, tmp_offset, tmp_reg; ++ u8 i; ++ u32 idx_offset, path_offset; ++ ++ if (index == 0) ++ idx_offset = 0; ++ else ++ idx_offset = 0x50; ++ ++ if (path == RF_PATH_A) ++ path_offset = 0; ++ else ++ path_offset = 0x2000; ++ ++ tmp_offset = idx_offset + path_offset; ++ /* msbk_d: 15/14/13/12 */ ++ tmp = 0x0; ++ for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) ++ tmp |= dack->msbk_d[path][index][i + 12] << (i * 8); ++ tmp_reg = 0x5e14 + tmp_offset; ++ rtw89_phy_write32(rtwdev, tmp_reg, tmp); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, ++ rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); ++ /* msbk_d: 11/10/9/8 */ ++ tmp = 0x0; ++ for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) ++ tmp |= dack->msbk_d[path][index][i + 8] << (i * 8); ++ tmp_reg = 0x5e18 + tmp_offset; ++ rtw89_phy_write32(rtwdev, tmp_reg, tmp); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, ++ rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); ++ /* msbk_d: 7/6/5/4 */ ++ tmp = 0x0; ++ for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) ++ tmp |= dack->msbk_d[path][index][i + 4] << (i * 8); ++ tmp_reg = 0x5e1c + tmp_offset; ++ rtw89_phy_write32(rtwdev, tmp_reg, tmp); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, ++ rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); ++ /* msbk_d: 3/2/1/0 */ ++ tmp = 0x0; ++ for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) ++ tmp |= dack->msbk_d[path][index][i] << (i * 8); ++ tmp_reg = 0x5e20 + tmp_offset; ++ rtw89_phy_write32(rtwdev, tmp_reg, tmp); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, ++ rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); ++ /* dadak_d/biask_d */ ++ tmp = 0x0; ++ tmp = (dack->biask_d[path][index] << 22) | ++ (dack->dadck_d[path][index] << 14); ++ tmp_reg = 0x5e24 + tmp_offset; ++ rtw89_phy_write32(rtwdev, tmp_reg, tmp); ++} ++ ++static void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) ++{ ++ u8 i; ++ ++ for (i = 0; i < 2; i++) ++ _dack_reload_by_path(rtwdev, path, i); ++ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_rfk_dack_reload_defs_a_tbl, ++ &rtw8852a_rfk_dack_reload_defs_b_tbl); ++} ++ ++#define ADDC_T_AVG 100 ++static void _check_addc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) ++{ ++ s32 dc_re = 0, dc_im = 0; ++ u32 tmp; ++ u32 i; ++ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_rfk_check_addc_defs_a_tbl, ++ &rtw8852a_rfk_check_addc_defs_b_tbl); ++ ++ for (i = 0; i < ADDC_T_AVG; i++) { ++ tmp = rtw89_phy_read32_mask(rtwdev, R_DBG32_D, MASKDWORD); ++ dc_re += sign_extend32(FIELD_GET(0xfff000, tmp), 11); ++ dc_im += sign_extend32(FIELD_GET(0xfff, tmp), 11); ++ } ++ ++ dc_re /= ADDC_T_AVG; ++ dc_im /= ADDC_T_AVG; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DACK]S%d,dc_re = 0x%x,dc_im =0x%x\n", path, dc_re, dc_im); ++} ++ ++static void _addck(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u32 val; ++ int ret; ++ ++ /* S0 */ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_reset_defs_a_tbl); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]before S0 ADDCK\n"); ++ _check_addc(rtwdev, RF_PATH_A); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_trigger_defs_a_tbl); ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x1e00, BIT(0)); ++ if (ret) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADDCK timeout\n"); ++ dack->addck_timeout[0] = true; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 ADDCK\n"); ++ _check_addc(rtwdev, RF_PATH_A); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_restore_defs_a_tbl); ++ ++ /* S1 */ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_reset_defs_b_tbl); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]before S1 ADDCK\n"); ++ _check_addc(rtwdev, RF_PATH_B); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_trigger_defs_b_tbl); ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x3e00, BIT(0)); ++ if (ret) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADDCK timeout\n"); ++ dack->addck_timeout[1] = true; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 ADDCK\n"); ++ _check_addc(rtwdev, RF_PATH_B); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_restore_defs_b_tbl); ++} ++ ++static void _check_dadc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_rfk_check_dadc_defs_f_a_tbl, ++ &rtw8852a_rfk_check_dadc_defs_f_b_tbl); ++ ++ _check_addc(rtwdev, path); ++ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_rfk_check_dadc_defs_r_a_tbl, ++ &rtw8852a_rfk_check_dadc_defs_r_b_tbl); ++} ++ ++static void _dack_s0(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u32 val; ++ int ret; ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_f_a_tbl); ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x5e28, BIT(15)); ++ ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x5e78, BIT(15)); ++ if (ret) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK timeout\n"); ++ dack->msbk_timeout[0] = true; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_m_a_tbl); ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x5e48, BIT(17)); ++ ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x5e98, BIT(17)); ++ if (ret) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DADACK timeout\n"); ++ dack->dadck_timeout[0] = true; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_r_a_tbl); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 DADCK\n"); ++ _check_dadc(rtwdev, RF_PATH_A); ++ ++ _dack_backup_s0(rtwdev); ++ _dack_reload(rtwdev, RF_PATH_A); ++ ++ rtw89_phy_write32_clr(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG); ++} ++ ++static void _dack_s1(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u32 val; ++ int ret; ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_f_b_tbl); ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x7e28, BIT(15)); ++ ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x7e78, BIT(15)); ++ if (ret) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK timeout\n"); ++ dack->msbk_timeout[1] = true; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_m_b_tbl); ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x7e48, BIT(17)); ++ ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x7e98, BIT(17)); ++ if (ret) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DADCK timeout\n"); ++ dack->dadck_timeout[1] = true; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_r_b_tbl); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 DADCK\n"); ++ _check_dadc(rtwdev, RF_PATH_B); ++ ++ _dack_backup_s1(rtwdev); ++ _dack_reload(rtwdev, RF_PATH_B); ++ ++ rtw89_phy_write32_clr(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON); ++} ++ ++static void _dack(struct rtw89_dev *rtwdev) ++{ ++ _dack_s0(rtwdev); ++ _dack_s1(rtwdev); ++} ++ ++static void _dac_cal(struct rtw89_dev *rtwdev, bool force) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u32 rf0_0, rf1_0; ++ u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, RF_AB); ++ ++ dack->dack_done = false; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK b\n"); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK start!!!\n"); ++ rf0_0 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK); ++ rf1_0 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK); ++ _afe_init(rtwdev); ++ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x0); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x0); ++ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x30001); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x30001); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_START); ++ _addck(rtwdev); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_STOP); ++ _addck_backup(rtwdev); ++ _addck_reload(rtwdev); ++ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x40001); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x40001); ++ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RFREG_MASK, 0x0); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RFREG_MASK, 0x0); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_START); ++ _dack(rtwdev); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_STOP); ++ _dack_dump(rtwdev); ++ dack->dack_done = true; ++ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, rf0_0); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, rf1_0); ++ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x1); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x1); ++ dack->dack_cnt++; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); ++} ++ ++#define RTW8852A_NCTL_VER 0xd ++#define RTW8852A_IQK_VER 0x2a ++#define RTW8852A_IQK_SS 2 ++#define RTW8852A_IQK_THR_REK 8 ++#define RTW8852A_IQK_CFIR_GROUP_NR 4 ++ ++enum rtw8852a_iqk_type { ++ ID_TXAGC, ++ ID_FLOK_COARSE, ++ ID_FLOK_FINE, ++ ID_TXK, ++ ID_RXAGC, ++ ID_RXK, ++ ID_NBTXK, ++ ID_NBRXK, ++}; ++ ++static void _iqk_read_fft_dbcc0(struct rtw89_dev *rtwdev, u8 path) ++{ ++ u8 i = 0x0; ++ u32 fft[6] = {0x0}; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00160000); ++ fft[0] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00170000); ++ fft[1] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00180000); ++ fft[2] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00190000); ++ fft[3] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x001a0000); ++ fft[4] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x001b0000); ++ fft[5] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); ++ for (i = 0; i < 6; i++) ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x,fft[%x]= %x\n", ++ path, i, fft[i]); ++} ++ ++static void _iqk_read_xym_dbcc0(struct rtw89_dev *rtwdev, u8 path) ++{ ++ u8 i = 0x0; ++ u32 tmp = 0x0; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, B_NCTL_CFG_SPAGE, path); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF, B_IQK_DIF_TRX, 0x1); ++ ++ for (i = 0x0; i < 0x18; i++) { ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_N2, MASKDWORD, 0x000000c0 + i); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N2, MASKDWORD); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lx38 = %x\n", ++ path, BIT(path), tmp); ++ udelay(1); ++ } ++ rtw89_phy_write32_clr(rtwdev, R_IQK_DIF, B_IQK_DIF_TRX); ++ rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD, 0x40000000); ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_N2, MASKDWORD, 0x80010100); ++ udelay(1); ++} ++ ++static void _iqk_read_txcfir_dbcc0(struct rtw89_dev *rtwdev, u8 path, ++ u8 group) ++{ ++ static const u32 base_addrs[RTW8852A_IQK_SS][RTW8852A_IQK_CFIR_GROUP_NR] = { ++ {0x8f20, 0x8f54, 0x8f88, 0x8fbc}, ++ {0x9320, 0x9354, 0x9388, 0x93bc}, ++ }; ++ u8 idx = 0x0; ++ u32 tmp = 0x0; ++ u32 base_addr; ++ ++ if (path >= RTW8852A_IQK_SS) { ++ rtw89_warn(rtwdev, "cfir path %d out of range\n", path); ++ return; ++ } ++ if (group >= RTW8852A_IQK_CFIR_GROUP_NR) { ++ rtw89_warn(rtwdev, "cfir group %d out of range\n", group); ++ return; ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ rtw89_phy_write32_mask(rtwdev, R_W_COEF + (path << 8), MASKDWORD, 0x00000001); ++ ++ base_addr = base_addrs[path][group]; ++ ++ for (idx = 0; idx < 0x0d; idx++) { ++ tmp = rtw89_phy_read32_mask(rtwdev, base_addr + (idx << 2), MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK] %x = %x\n", ++ base_addr + (idx << 2), tmp); ++ } ++ ++ if (path == 0x0) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C0, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8f50 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C1, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8f84 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C2, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8fb8 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C3, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8fec = %x\n", tmp); ++ } else { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C0, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9350 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C1, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9384 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C2, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x93b8 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C3, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x93ec = %x\n", tmp); ++ } ++ rtw89_phy_write32_clr(rtwdev, R_W_COEF + (path << 8), MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, 0xc); ++ udelay(1); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lxfc = %x\n", path, ++ BIT(path), tmp); ++} ++ ++static void _iqk_read_rxcfir_dbcc0(struct rtw89_dev *rtwdev, u8 path, ++ u8 group) ++{ ++ static const u32 base_addrs[RTW8852A_IQK_SS][RTW8852A_IQK_CFIR_GROUP_NR] = { ++ {0x8d00, 0x8d44, 0x8d88, 0x8dcc}, ++ {0x9100, 0x9144, 0x9188, 0x91cc}, ++ }; ++ u8 idx = 0x0; ++ u32 tmp = 0x0; ++ u32 base_addr; ++ ++ if (path >= RTW8852A_IQK_SS) { ++ rtw89_warn(rtwdev, "cfir path %d out of range\n", path); ++ return; ++ } ++ if (group >= RTW8852A_IQK_CFIR_GROUP_NR) { ++ rtw89_warn(rtwdev, "cfir group %d out of range\n", group); ++ return; ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ rtw89_phy_write32_mask(rtwdev, R_W_COEF + (path << 8), MASKDWORD, 0x00000001); ++ ++ base_addr = base_addrs[path][group]; ++ for (idx = 0; idx < 0x10; idx++) { ++ tmp = rtw89_phy_read32_mask(rtwdev, base_addr + (idx << 2), MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]%x = %x\n", ++ base_addr + (idx << 2), tmp); ++ } ++ ++ if (path == 0x0) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C0, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8d40 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C1, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8d84 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C2, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8dc8 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C3, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8e0c = %x\n", tmp); ++ } else { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C0, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9140 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C1, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9184 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C2, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x91c8 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C3, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x920c = %x\n", tmp); ++ } ++ rtw89_phy_write32_clr(rtwdev, R_W_COEF + (path << 8), MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, 0xd); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lxfc = %x\n", path, ++ BIT(path), tmp); ++} ++ ++static void _iqk_sram(struct rtw89_dev *rtwdev, u8 path) ++{ ++ u32 tmp = 0x0; ++ u32 i = 0x0; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00020000); ++ rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX2, MASKDWORD, 0x00000080); ++ rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x009); ++ ++ for (i = 0; i <= 0x9f; i++) { ++ rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000 + i); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]0x%x\n", tmp); ++ } ++ ++ for (i = 0; i <= 0x9f; i++) { ++ rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000 + i); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]0x%x\n", tmp); ++ } ++ rtw89_phy_write32_clr(rtwdev, R_SRAM_IQRX2, MASKDWORD); ++ rtw89_phy_write32_clr(rtwdev, R_SRAM_IQRX, MASKDWORD); ++} ++ ++static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u32 tmp = 0x0; ++ ++ rtw89_phy_write32_set(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x3); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa041); ++ udelay(1); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H2, 0x3); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x0); ++ udelay(1); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H2, 0x0); ++ udelay(1); ++ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0303); ++ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0000); ++ ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RXK2); ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x1); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RXK2); ++ rtw89_write_rf(rtwdev, path, RR_WLSEL, RR_WLSEL_AG, 0x5); ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x1); ++ break; ++ default: ++ break; ++ } ++ tmp = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); ++ rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, tmp); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x1); ++ fsleep(128); ++} ++ ++static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path, u8 ktype) ++{ ++ u32 tmp; ++ u32 val; ++ int ret; ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, 1, 8200, ++ false, rtwdev, 0xbff8, MASKBYTE0); ++ if (ret) ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]IQK timeout!!!\n"); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ret=%d\n", path, ret); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]S%x, type= %x, 0x8008 = 0x%x\n", path, ktype, tmp); ++ ++ return false; ++} ++ ++static bool _iqk_one_shot(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path, u8 ktype) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ bool fail = false; ++ u32 iqk_cmd = 0x0; ++ u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy_idx, path); ++ u32 addr_rfc_ctl = 0x0; ++ ++ if (path == RF_PATH_A) ++ addr_rfc_ctl = 0x5864; ++ else ++ addr_rfc_ctl = 0x7864; ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); ++ switch (ktype) { ++ case ID_TXAGC: ++ iqk_cmd = 0x008 | (1 << (4 + path)) | (path << 1); ++ break; ++ case ID_FLOK_COARSE: ++ rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x009); ++ iqk_cmd = 0x108 | (1 << (4 + path)); ++ break; ++ case ID_FLOK_FINE: ++ rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x009); ++ iqk_cmd = 0x208 | (1 << (4 + path)); ++ break; ++ case ID_TXK: ++ rtw89_phy_write32_clr(rtwdev, addr_rfc_ctl, 0x20000000); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x025); ++ iqk_cmd = 0x008 | (1 << (path + 4)) | ++ (((0x8 + iqk_info->iqk_bw[path]) & 0xf) << 8); ++ break; ++ case ID_RXAGC: ++ iqk_cmd = 0x508 | (1 << (4 + path)) | (path << 1); ++ break; ++ case ID_RXK: ++ rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); ++ iqk_cmd = 0x008 | (1 << (path + 4)) | ++ (((0xb + iqk_info->iqk_bw[path]) & 0xf) << 8); ++ break; ++ case ID_NBTXK: ++ rtw89_phy_write32_clr(rtwdev, addr_rfc_ctl, 0x20000000); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x025); ++ iqk_cmd = 0x308 | (1 << (4 + path)); ++ break; ++ case ID_NBRXK: ++ rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); ++ iqk_cmd = 0x608 | (1 << (4 + path)); ++ break; ++ default: ++ return false; ++ } ++ ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, iqk_cmd + 1); ++ rtw89_phy_write32_set(rtwdev, R_DPK_CTL, B_DPK_CTL_EN); ++ udelay(1); ++ fail = _iqk_check_cal(rtwdev, path, ktype); ++ if (iqk_info->iqk_xym_en) ++ _iqk_read_xym_dbcc0(rtwdev, path); ++ if (iqk_info->iqk_fft_en) ++ _iqk_read_fft_dbcc0(rtwdev, path); ++ if (iqk_info->iqk_sram_en) ++ _iqk_sram(rtwdev, path); ++ if (iqk_info->iqk_cfir_en) { ++ if (ktype == ID_TXK) { ++ _iqk_read_txcfir_dbcc0(rtwdev, path, 0x0); ++ _iqk_read_txcfir_dbcc0(rtwdev, path, 0x1); ++ _iqk_read_txcfir_dbcc0(rtwdev, path, 0x2); ++ _iqk_read_txcfir_dbcc0(rtwdev, path, 0x3); ++ } else { ++ _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x0); ++ _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x1); ++ _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x2); ++ _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x3); ++ } ++ } ++ ++ rtw89_phy_write32_clr(rtwdev, addr_rfc_ctl, 0x20000000); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); ++ ++ return fail; ++} ++ ++static bool _rxk_group_sel(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ static const u32 rxgn_a[4] = {0x18C, 0x1A0, 0x28C, 0x2A0}; ++ static const u32 attc2_a[4] = {0x0, 0x0, 0x07, 0x30}; ++ static const u32 attc1_a[4] = {0x7, 0x5, 0x1, 0x1}; ++ static const u32 rxgn_g[4] = {0x1CC, 0x1E0, 0x2CC, 0x2E0}; ++ static const u32 attc2_g[4] = {0x0, 0x15, 0x3, 0x1a}; ++ static const u32 attc1_g[4] = {0x1, 0x0, 0x1, 0x0}; ++ u8 gp = 0x0; ++ bool fail = false; ++ u32 rf0 = 0x0; ++ ++ for (gp = 0; gp < 0x4; gp++) { ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, rxgn_g[gp]); ++ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G, attc2_g[gp]); ++ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G, attc1_g[gp]); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, rxgn_a[gp]); ++ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C2, attc2_a[gp]); ++ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C1, attc1_a[gp]); ++ break; ++ default: ++ break; ++ } ++ rtw89_phy_write32_set(rtwdev, R_IQK_CFG, B_IQK_CFG_SET); ++ rf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, ++ rf0 | iqk_info->syn1to2); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_COM, MASKDWORD, 0x40010100); ++ rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_RXCFIR); ++ rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); ++ rtw89_phy_write32_clr(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, gp); ++ rtw89_phy_write32_mask(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_EN, 0x1); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); ++ fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(16 + gp + path * 4), fail); ++ } ++ ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_WLSEL, RR_WLSEL_AG, 0x0); ++ break; ++ default: ++ break; ++ } ++ iqk_info->nb_rxcfir[path] = 0x40000000; ++ rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), ++ B_IQK_RES_RXCFIR, 0x5); ++ iqk_info->is_wb_rxiqk[path] = true; ++ return false; ++} ++ ++static bool _iqk_nbrxk(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u8 group = 0x0; ++ u32 rf0 = 0x0, tmp = 0x0; ++ u32 idxrxgain_a = 0x1a0; ++ u32 idxattc2_a = 0x00; ++ u32 idxattc1_a = 0x5; ++ u32 idxrxgain_g = 0x1E0; ++ u32 idxattc2_g = 0x15; ++ u32 idxattc1_g = 0x0; ++ bool fail = false; ++ ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, idxrxgain_g); ++ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G, idxattc2_g); ++ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G, idxattc1_g); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, idxrxgain_a); ++ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C2, idxattc2_a); ++ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C1, idxattc1_a); ++ break; ++ default: ++ break; ++ } ++ rtw89_phy_write32_set(rtwdev, R_IQK_CFG, B_IQK_CFG_SET); ++ rf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, ++ rf0 | iqk_info->syn1to2); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_COM, MASKDWORD, 0x40010100); ++ rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_RXCFIR); ++ rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); ++ rtw89_phy_write32_clr(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), ++ B_CFIR_LUT_GP, group); ++ rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_EN); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); ++ fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); ++ ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_WLSEL, RR_WLSEL_AG, 0x0); ++ break; ++ default: ++ break; ++ } ++ if (!fail) { ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD); ++ iqk_info->nb_rxcfir[path] = tmp | 0x2; ++ } else { ++ iqk_info->nb_rxcfir[path] = 0x40000002; ++ } ++ return fail; ++} ++ ++static void _iqk_rxclk_setting(struct rtw89_dev *rtwdev, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ ++ if (iqk_info->iqk_bw[path] == RTW89_CHANNEL_WIDTH_80) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), ++ MASKDWORD, 0x4d000a08); ++ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), ++ B_P0_RXCK_VAL, 0x2); ++ rtw89_phy_write32_set(rtwdev, R_P0_RXCK + (path << 13), B_P0_RXCK_ON); ++ rtw89_phy_write32_set(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON); ++ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL, 0x1); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), ++ MASKDWORD, 0x44000a08); ++ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), ++ B_P0_RXCK_VAL, 0x1); ++ rtw89_phy_write32_set(rtwdev, R_P0_RXCK + (path << 13), B_P0_RXCK_ON); ++ rtw89_phy_write32_set(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON); ++ rtw89_phy_write32_clr(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL); ++ } ++} ++ ++static bool _txk_group_sel(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ static const u32 a_txgain[4] = {0xE466, 0x646D, 0xE4E2, 0x64ED}; ++ static const u32 g_txgain[4] = {0x60e8, 0x60f0, 0x61e8, 0x61ED}; ++ static const u32 a_itqt[4] = {0x12, 0x12, 0x12, 0x1b}; ++ static const u32 g_itqt[4] = {0x09, 0x12, 0x12, 0x12}; ++ static const u32 g_attsmxr[4] = {0x0, 0x1, 0x1, 0x1}; ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ bool fail = false; ++ u8 gp = 0x0; ++ u32 tmp = 0x0; ++ ++ for (gp = 0x0; gp < 0x4; gp++) { ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), ++ B_RFGAIN_BND, 0x08); ++ rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, ++ g_txgain[gp]); ++ rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, ++ g_attsmxr[gp]); ++ rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, ++ g_attsmxr[gp]); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), ++ MASKDWORD, g_itqt[gp]); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), ++ B_RFGAIN_BND, 0x04); ++ rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, ++ a_txgain[gp]); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), ++ MASKDWORD, a_itqt[gp]); ++ break; ++ default: ++ break; ++ } ++ rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_TXCFIR); ++ rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); ++ rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), ++ B_CFIR_LUT_GP, gp); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); ++ fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK); ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(8 + gp + path * 4), fail); ++ } ++ ++ iqk_info->nb_txcfir[path] = 0x40000000; ++ rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), ++ B_IQK_RES_TXCFIR, 0x5); ++ iqk_info->is_wb_txiqk[path] = true; ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lx38 = 0x%x\n", path, ++ BIT(path), tmp); ++ return false; ++} ++ ++static bool _iqk_nbtxk(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u8 group = 0x2; ++ u32 a_mode_txgain = 0x64e2; ++ u32 g_mode_txgain = 0x61e8; ++ u32 attsmxr = 0x1; ++ u32 itqt = 0x12; ++ u32 tmp = 0x0; ++ bool fail = false; ++ ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), ++ B_RFGAIN_BND, 0x08); ++ rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, g_mode_txgain); ++ rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, attsmxr); ++ rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, attsmxr); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), ++ B_RFGAIN_BND, 0x04); ++ rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, a_mode_txgain); ++ break; ++ default: ++ break; ++ } ++ rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_TXCFIR); ++ rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); ++ rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, group); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, itqt); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); ++ fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); ++ if (!fail) { ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); ++ iqk_info->nb_txcfir[path] = tmp | 0x2; ++ } else { ++ iqk_info->nb_txcfir[path] = 0x40000002; ++ } ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lx38 = 0x%x\n", path, ++ BIT(path), tmp); ++ return fail; ++} ++ ++static void _lok_res_table(struct rtw89_dev *rtwdev, u8 path, u8 ibias) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ibias = %x\n", path, ibias); ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x2); ++ if (iqk_info->iqk_band[path] == RTW89_BAND_2G) ++ rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, 0x0); ++ else ++ rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, ibias); ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0); ++} ++ ++static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path) ++{ ++ bool is_fail = false; ++ u32 tmp = 0x0; ++ u32 core_i = 0x0; ++ u32 core_q = 0x0; ++ ++ tmp = rtw89_read_rf(rtwdev, path, RR_TXMO, RFREG_MASK); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK][FineLOK] S%x, 0x58 = 0x%x\n", ++ path, tmp); ++ core_i = FIELD_GET(RR_TXMO_COI, tmp); ++ core_q = FIELD_GET(RR_TXMO_COQ, tmp); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, i = 0x%x\n", path, core_i); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, q = 0x%x\n", path, core_q); ++ ++ if (core_i < 0x2 || core_i > 0x1d || core_q < 0x2 || core_q > 0x1d) ++ is_fail = true; ++ return is_fail; ++} ++ ++static bool _iqk_lok(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u32 rf0 = 0x0; ++ u8 itqt = 0x12; ++ bool fail = false; ++ bool tmp = false; ++ ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, 0xe5e0); ++ itqt = 0x09; ++ break; ++ case RTW89_BAND_5G: ++ rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, 0xe4e0); ++ itqt = 0x12; ++ break; ++ default: ++ break; ++ } ++ rtw89_phy_write32_set(rtwdev, R_IQK_CFG, B_IQK_CFG_SET); ++ rf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF1, B_IQK_DIF1_TXPI, ++ rf0 | iqk_info->syn1to2); ++ rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_TXCFIR); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, 0x0); ++ rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_EN); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, itqt); ++ tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_COARSE); ++ iqk_info->lok_cor_fail[0][path] = tmp; ++ fsleep(10); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, itqt); ++ tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_FINE); ++ iqk_info->lok_fin_fail[0][path] = tmp; ++ fail = _lok_finetune_check(rtwdev, path); ++ return fail; ++} ++ ++static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ ++ rtw89_phy_write32_set(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f); ++ udelay(1); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0001); ++ udelay(1); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0041); ++ udelay(1); ++ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0303); ++ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0000); ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_write_rf(rtwdev, path, RR_XALNA2, RR_XALNA2_SW, 0x00); ++ rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_POW, 0x3f); ++ rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT2, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EN, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_LOK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_MASK, 0x000); ++ rtw89_write_rf(rtwdev, path, RR_RSV2, RFREG_MASK, 0x80200); ++ rtw89_write_rf(rtwdev, path, RR_DTXLOK, RFREG_MASK, 0x80200); ++ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, ++ 0x403e0 | iqk_info->syn1to2); ++ udelay(1); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_write_rf(rtwdev, path, RR_XGLNA2, RR_XGLNA2_SW, 0x00); ++ rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_POW, 0x3f); ++ rtw89_write_rf(rtwdev, path, RR_BIASA, RR_BIASA_A, 0x7); ++ rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EN, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_LOK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_MASK, 0x100); ++ rtw89_write_rf(rtwdev, path, RR_RSV2, RFREG_MASK, 0x80200); ++ rtw89_write_rf(rtwdev, path, RR_DTXLOK, RFREG_MASK, 0x80200); ++ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, ++ 0x403e0 | iqk_info->syn1to2); ++ udelay(1); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void _iqk_txclk_setting(struct rtw89_dev *rtwdev, u8 path) ++{ ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0xce000a08); ++} ++ ++static void _iqk_info_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, ++ u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u32 tmp = 0x0; ++ bool flag = 0x0; ++ ++ iqk_info->thermal[path] = ++ ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); ++ iqk_info->thermal_rek_en = false; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_thermal = %d\n", path, ++ iqk_info->thermal[path]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_COR_fail= %d\n", path, ++ iqk_info->lok_cor_fail[0][path]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_FIN_fail= %d\n", path, ++ iqk_info->lok_fin_fail[0][path]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_TXIQK_fail = %d\n", path, ++ iqk_info->iqk_tx_fail[0][path]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_RXIQK_fail= %d,\n", path, ++ iqk_info->iqk_rx_fail[0][path]); ++ flag = iqk_info->lok_cor_fail[0][path]; ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(0) << (path * 4), flag); ++ flag = iqk_info->lok_fin_fail[0][path]; ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(1) << (path * 4), flag); ++ flag = iqk_info->iqk_tx_fail[0][path]; ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(2) << (path * 4), flag); ++ flag = iqk_info->iqk_rx_fail[0][path]; ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(3) << (path * 4), flag); ++ ++ tmp = rtw89_phy_read32_mask(rtwdev, R_IQK_RES + (path << 8), MASKDWORD); ++ iqk_info->bp_iqkenable[path] = tmp; ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); ++ iqk_info->bp_txkresult[path] = tmp; ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD); ++ iqk_info->bp_rxkresult[path] = tmp; ++ ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_KCNT, ++ (u8)iqk_info->iqk_times); ++ ++ tmp = rtw89_phy_read32_mask(rtwdev, R_IQKINF, 0x0000000f << (path * 4)); ++ if (tmp != 0x0) ++ iqk_info->iqk_fail_cnt++; ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF2, 0x00ff0000 << (path * 4), ++ iqk_info->iqk_fail_cnt); ++} ++ ++static ++void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ bool lok_is_fail = false; ++ u8 ibias = 0x1; ++ u8 i = 0; ++ ++ _iqk_txclk_setting(rtwdev, path); ++ ++ for (i = 0; i < 3; i++) { ++ _lok_res_table(rtwdev, path, ibias++); ++ _iqk_txk_setting(rtwdev, path); ++ lok_is_fail = _iqk_lok(rtwdev, phy_idx, path); ++ if (!lok_is_fail) ++ break; ++ } ++ if (iqk_info->is_nbiqk) ++ iqk_info->iqk_tx_fail[0][path] = _iqk_nbtxk(rtwdev, phy_idx, path); ++ else ++ iqk_info->iqk_tx_fail[0][path] = _txk_group_sel(rtwdev, phy_idx, path); ++ ++ _iqk_rxclk_setting(rtwdev, path); ++ _iqk_rxk_setting(rtwdev, path); ++ if (iqk_info->is_nbiqk || rtwdev->dbcc_en || iqk_info->iqk_band[path] == RTW89_BAND_2G) ++ iqk_info->iqk_rx_fail[0][path] = _iqk_nbrxk(rtwdev, phy_idx, path); ++ else ++ iqk_info->iqk_rx_fail[0][path] = _rxk_group_sel(rtwdev, phy_idx, path); ++ ++ _iqk_info_iqk(rtwdev, phy_idx, path); ++} ++ ++static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ u32 reg_rf18 = 0x0, reg_35c = 0x0; ++ u8 idx = 0; ++ u8 get_empty_table = false; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) { ++ if (iqk_info->iqk_mcc_ch[idx][path] == 0) { ++ get_empty_table = true; ++ break; ++ } ++ } ++ if (!get_empty_table) { ++ idx = iqk_info->iqk_table_idx[path] + 1; ++ if (idx > RTW89_IQK_CHS_NR - 1) ++ idx = 0; ++ } ++ reg_rf18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]cfg ch = %d\n", reg_rf18); ++ reg_35c = rtw89_phy_read32_mask(rtwdev, 0x35c, 0x00000c00); ++ ++ iqk_info->iqk_band[path] = hal->current_band_type; ++ iqk_info->iqk_bw[path] = hal->current_band_width; ++ iqk_info->iqk_ch[path] = hal->current_channel; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]iqk_info->iqk_band[%x] = 0x%x\n", path, ++ iqk_info->iqk_band[path]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_info->iqk_bw[%x] = 0x%x\n", ++ path, iqk_info->iqk_bw[path]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_info->iqk_ch[%x] = 0x%x\n", ++ path, iqk_info->iqk_ch[path]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n", path, phy, ++ rtwdev->dbcc_en ? "on" : "off", ++ iqk_info->iqk_band[path] == 0 ? "2G" : ++ iqk_info->iqk_band[path] == 1 ? "5G" : "6G", ++ iqk_info->iqk_ch[path], ++ iqk_info->iqk_bw[path] == 0 ? "20M" : ++ iqk_info->iqk_bw[path] == 1 ? "40M" : "80M"); ++ if (reg_35c == 0x01) ++ iqk_info->syn1to2 = 0x1; ++ else ++ iqk_info->syn1to2 = 0x0; ++ ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_VER, RTW8852A_IQK_VER); ++ rtw89_phy_write32_mask(rtwdev, R_IQKCH, 0x000f << (path * 16), ++ (u8)iqk_info->iqk_band[path]); ++ rtw89_phy_write32_mask(rtwdev, R_IQKCH, 0x00f0 << (path * 16), ++ (u8)iqk_info->iqk_bw[path]); ++ rtw89_phy_write32_mask(rtwdev, R_IQKCH, 0xff00 << (path * 16), ++ (u8)iqk_info->iqk_ch[path]); ++ ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF2, 0x000000ff, RTW8852A_NCTL_VER); ++} ++ ++static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, ++ u8 path) ++{ ++ _iqk_by_path(rtwdev, phy_idx, path); ++} ++ ++static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ ++ rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD, ++ iqk_info->nb_txcfir[path]); ++ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, ++ iqk_info->nb_rxcfir[path]); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_RPT, MASKDWORD); ++ rtw89_phy_write32_clr(rtwdev, R_MDPK_RX_DCK, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); ++ rtw89_phy_write32_clr(rtwdev, R_KPATH_CFG, MASKDWORD); ++ rtw89_phy_write32_clr(rtwdev, R_GAPK, B_GAPK_ADR); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0x10010000); ++ rtw89_phy_write32_clr(rtwdev, R_KIP + (path << 8), B_KIP_RFGAIN); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_MAP + (path << 8), MASKDWORD, 0xe4e4e4e4); ++ rtw89_phy_write32_clr(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); ++ rtw89_phy_write32_clr(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW); ++ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), MASKDWORD, 0x00000002); ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_POW, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); ++ rtw89_write_rf(rtwdev, path, RR_TXRSV, RR_TXRSV_GAPK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_BIAS, RR_BIAS_GAPK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); ++} ++ ++static void _iqk_afebb_restore(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ const struct rtw89_rfk_tbl *tbl; ++ ++ switch (_kpath(rtwdev, phy_idx)) { ++ case RF_A: ++ tbl = &rtw8852a_rfk_iqk_restore_defs_dbcc_path0_tbl; ++ break; ++ case RF_B: ++ tbl = &rtw8852a_rfk_iqk_restore_defs_dbcc_path1_tbl; ++ break; ++ default: ++ tbl = &rtw8852a_rfk_iqk_restore_defs_nondbcc_path01_tbl; ++ break; ++ } ++ ++ rtw89_rfk_parser(rtwdev, tbl); ++} ++ ++static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u8 idx = iqk_info->iqk_table_idx[path]; ++ ++ if (rtwdev->dbcc_en) { ++ rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), ++ B_COEF_SEL_IQC, path & 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), ++ B_CFIR_LUT_G2, path & 0x1); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), ++ B_COEF_SEL_IQC, idx); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), ++ B_CFIR_LUT_G2, idx); ++ } ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_RW, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x81ff010a); ++ rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, MASKDWORD, 0x00200000); ++ rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, MASKDWORD, 0x80000000); ++ rtw89_phy_write32_clr(rtwdev, R_LOAD_COEF + (path << 8), MASKDWORD); ++} ++ ++static void _iqk_macbb_setting(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ const struct rtw89_rfk_tbl *tbl; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===> %s\n", __func__); ++ ++ switch (_kpath(rtwdev, phy_idx)) { ++ case RF_A: ++ tbl = &rtw8852a_rfk_iqk_set_defs_dbcc_path0_tbl; ++ break; ++ case RF_B: ++ tbl = &rtw8852a_rfk_iqk_set_defs_dbcc_path1_tbl; ++ break; ++ default: ++ tbl = &rtw8852a_rfk_iqk_set_defs_nondbcc_path01_tbl; ++ break; ++ } ++ ++ rtw89_rfk_parser(rtwdev, tbl); ++} ++ ++static void _iqk_dbcc(struct rtw89_dev *rtwdev, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u8 phy_idx = 0x0; ++ ++ iqk_info->iqk_times++; ++ ++ if (path == 0x0) ++ phy_idx = RTW89_PHY_0; ++ else ++ phy_idx = RTW89_PHY_1; ++ ++ _iqk_get_ch_info(rtwdev, phy_idx, path); ++ _iqk_macbb_setting(rtwdev, phy_idx, path); ++ _iqk_preset(rtwdev, path); ++ _iqk_start_iqk(rtwdev, phy_idx, path); ++ _iqk_restore(rtwdev, path); ++ _iqk_afebb_restore(rtwdev, phy_idx, path); ++} ++ ++static void _iqk_track(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_iqk_info *iqk = &rtwdev->iqk; ++ u8 path = 0x0; ++ u8 cur_ther; ++ ++ if (iqk->iqk_band[0] == RTW89_BAND_2G) ++ return; ++ if (iqk->iqk_bw[0] < RTW89_CHANNEL_WIDTH_80) ++ return; ++ ++ /* only check path 0 */ ++ for (path = 0; path < 1; path++) { ++ cur_ther = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); ++ ++ if (abs(cur_ther - iqk->thermal[path]) > RTW8852A_IQK_THR_REK) ++ iqk->thermal_rek_en = true; ++ else ++ iqk->thermal_rek_en = false; ++ } ++} ++ ++static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) ++{ ++ u32 rf_reg5, rck_val = 0; ++ u32 val; ++ int ret; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] ====== S%d RCK ======\n", path); ++ ++ rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); ++ ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF0x00 = 0x%x\n", ++ rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); ++ ++ /* RCK trigger */ ++ rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, 0x00240); ++ ++ ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 20, ++ false, rtwdev, path, 0x1c, BIT(3)); ++ if (ret) ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RCK timeout\n"); ++ ++ rck_val = rtw89_read_rf(rtwdev, path, RR_RCKC, RR_RCKC_CA); ++ rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, rck_val); ++ ++ /* RCK_ADC_OFFSET */ ++ rtw89_write_rf(rtwdev, path, RR_RCKO, RR_RCKO_OFF, 0x4); ++ ++ rtw89_write_rf(rtwdev, path, RR_RFC, RR_RFC_CKEN, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_RFC, RR_RFC_CKEN, 0x0); ++ ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[RCK] RF 0x1b / 0x1c / 0x1d = 0x%x / 0x%x / 0x%x\n", ++ rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK), ++ rtw89_read_rf(rtwdev, path, RR_RCKS, RFREG_MASK), ++ rtw89_read_rf(rtwdev, path, RR_RCKO, RFREG_MASK)); ++} ++ ++static void _iqk_init(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u8 ch, path; ++ ++ rtw89_phy_write32_clr(rtwdev, R_IQKINF, MASKDWORD); ++ if (iqk_info->is_iqk_init) ++ return; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ iqk_info->is_iqk_init = true; ++ iqk_info->is_nbiqk = false; ++ iqk_info->iqk_fft_en = false; ++ iqk_info->iqk_sram_en = false; ++ iqk_info->iqk_cfir_en = false; ++ iqk_info->iqk_xym_en = false; ++ iqk_info->thermal_rek_en = false; ++ iqk_info->iqk_times = 0x0; ++ ++ for (ch = 0; ch < RTW89_IQK_CHS_NR; ch++) { ++ iqk_info->iqk_channel[ch] = 0x0; ++ for (path = 0; path < RTW8852A_IQK_SS; path++) { ++ iqk_info->lok_cor_fail[ch][path] = false; ++ iqk_info->lok_fin_fail[ch][path] = false; ++ iqk_info->iqk_tx_fail[ch][path] = false; ++ iqk_info->iqk_rx_fail[ch][path] = false; ++ iqk_info->iqk_mcc_ch[ch][path] = 0x0; ++ iqk_info->iqk_table_idx[path] = 0x0; ++ } ++ } ++} ++ ++static void _doiqk(struct rtw89_dev *rtwdev, bool force, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u32 backup_bb_val[BACKUP_BB_REGS_NR]; ++ u32 backup_rf_val[RTW8852A_IQK_SS][BACKUP_RF_REGS_NR]; ++ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]==========IQK strat!!!!!==========\n"); ++ iqk_info->iqk_times++; ++ iqk_info->kcount = 0; ++ iqk_info->version = RTW8852A_IQK_VER; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); ++ _iqk_get_ch_info(rtwdev, phy_idx, path); ++ _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]); ++ _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path); ++ _iqk_macbb_setting(rtwdev, phy_idx, path); ++ _iqk_preset(rtwdev, path); ++ _iqk_start_iqk(rtwdev, phy_idx, path); ++ _iqk_restore(rtwdev, path); ++ _iqk_afebb_restore(rtwdev, phy_idx, path); ++ _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]); ++ _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); ++} ++ ++static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force) ++{ ++ switch (_kpath(rtwdev, phy_idx)) { ++ case RF_A: ++ _doiqk(rtwdev, force, phy_idx, RF_PATH_A); ++ break; ++ case RF_B: ++ _doiqk(rtwdev, force, phy_idx, RF_PATH_B); ++ break; ++ case RF_AB: ++ _doiqk(rtwdev, force, phy_idx, RF_PATH_A); ++ _doiqk(rtwdev, force, phy_idx, RF_PATH_B); ++ break; ++ default: ++ break; ++ } ++} ++ ++#define RXDCK_VER_8852A 0xe ++ ++static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, bool is_afe) ++{ ++ u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy, path); ++ u32 ori_val; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[RX_DCK] ==== S%d RX DCK (by %s)====\n", ++ path, is_afe ? "AFE" : "RFC"); ++ ++ ori_val = rtw89_phy_read32_mask(rtwdev, R_P0_RXCK + (path << 13), MASKDWORD); ++ ++ if (is_afe) { ++ rtw89_phy_write32_set(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); ++ rtw89_phy_write32_set(rtwdev, R_P0_RXCK + (path << 13), B_P0_RXCK_ON); ++ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), ++ B_P0_RXCK_VAL, 0x3); ++ rtw89_phy_write32_set(rtwdev, R_S0_RXDC2 + (path << 13), B_S0_RXDC2_MEN); ++ rtw89_phy_write32_mask(rtwdev, R_S0_RXDC2 + (path << 13), ++ B_S0_RXDC2_AVG, 0x3); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0x3); ++ rtw89_phy_write32_clr(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK); ++ rtw89_phy_write32_clr(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST); ++ rtw89_phy_write32_set(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_CRXBB, 0x1); ++ } ++ ++ rtw89_write_rf(rtwdev, path, RR_DCK2, RR_DCK2_CYCLE, 0x3f); ++ rtw89_write_rf(rtwdev, path, RR_DCK1, RR_DCK1_SEL, is_afe); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_ONESHOT_START); ++ ++ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1); ++ ++ fsleep(600); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_ONESHOT_STOP); ++ ++ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); ++ ++ if (is_afe) { ++ rtw89_phy_write32_clr(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); ++ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), ++ MASKDWORD, ori_val); ++ } ++} ++ ++static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ bool is_afe) ++{ ++ u8 path, kpath, dck_tune; ++ u32 rf_reg5; ++ u32 addr; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, Cv: %d) ******\n", ++ RXDCK_VER_8852A, rtwdev->hal.cv); ++ ++ kpath = _kpath(rtwdev, phy); ++ ++ for (path = 0; path < 2; path++) { ++ if (!(kpath & BIT(path))) ++ continue; ++ ++ rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); ++ dck_tune = (u8)rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_FINE); ++ ++ if (rtwdev->is_tssi_mode[path]) { ++ addr = 0x5818 + (path << 13); ++ /* TSSI pause */ ++ rtw89_phy_write32_set(rtwdev, addr, BIT(30)); ++ } ++ ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); ++ _set_rx_dck(rtwdev, phy, path, is_afe); ++ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, dck_tune); ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); ++ ++ if (rtwdev->is_tssi_mode[path]) { ++ addr = 0x5818 + (path << 13); ++ /* TSSI resume */ ++ rtw89_phy_write32_clr(rtwdev, addr, BIT(30)); ++ } ++ } ++} ++ ++#define RTW8852A_RF_REL_VERSION 34 ++#define RTW8852A_DPK_VER 0x10 ++#define RTW8852A_DPK_TH_AVG_NUM 4 ++#define RTW8852A_DPK_RF_PATH 2 ++#define RTW8852A_DPK_KIP_REG_NUM 2 ++ ++enum rtw8852a_dpk_id { ++ LBK_RXIQK = 0x06, ++ SYNC = 0x10, ++ MDPK_IDL = 0x11, ++ MDPK_MPA = 0x12, ++ GAIN_LOSS = 0x13, ++ GAIN_CAL = 0x14, ++}; ++ ++static void _rf_direct_cntrl(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, bool is_bybb) ++{ ++ if (is_bybb) ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); ++ else ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); ++} ++ ++static void _dpk_onoff(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, bool off); ++ ++static void _dpk_bkup_kip(struct rtw89_dev *rtwdev, u32 *reg, ++ u32 reg_bkup[][RTW8852A_DPK_KIP_REG_NUM], ++ u8 path) ++{ ++ u8 i; ++ ++ for (i = 0; i < RTW8852A_DPK_KIP_REG_NUM; i++) { ++ reg_bkup[path][i] = rtw89_phy_read32_mask(rtwdev, ++ reg[i] + (path << 8), ++ MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup 0x%x = %x\n", ++ reg[i] + (path << 8), reg_bkup[path][i]); ++ } ++} ++ ++static void _dpk_reload_kip(struct rtw89_dev *rtwdev, u32 *reg, ++ u32 reg_bkup[][RTW8852A_DPK_KIP_REG_NUM], u8 path) ++{ ++ u8 i; ++ ++ for (i = 0; i < RTW8852A_DPK_KIP_REG_NUM; i++) { ++ rtw89_phy_write32_mask(rtwdev, reg[i] + (path << 8), ++ MASKDWORD, reg_bkup[path][i]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Reload 0x%x = %x\n", ++ reg[i] + (path << 8), reg_bkup[path][i]); ++ } ++} ++ ++static u8 _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, enum rtw8852a_dpk_id id) ++{ ++ u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy, path); ++ u16 dpk_cmd = 0x0; ++ u32 val; ++ int ret; ++ ++ dpk_cmd = (u16)((id << 8) | (0x19 + (path << 4))); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_ONESHOT_START); ++ ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, dpk_cmd); ++ rtw89_phy_write32_set(rtwdev, R_DPK_CTL, B_DPK_CTL_EN); ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, ++ 10, 20000, false, rtwdev, 0xbff8, MASKBYTE0); ++ ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_ONESHOT_STOP); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] one-shot for %s = 0x%x (ret=%d)\n", ++ id == 0x06 ? "LBK_RXIQK" : ++ id == 0x10 ? "SYNC" : ++ id == 0x11 ? "MDPK_IDL" : ++ id == 0x12 ? "MDPK_MPA" : ++ id == 0x13 ? "GAIN_LOSS" : "PWR_CAL", ++ dpk_cmd, ret); ++ ++ if (ret) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] one-shot over 20ms!!!!\n"); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static void _dpk_rx_dck(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_EN_TIA_IDA, 0x3); ++ _set_rx_dck(rtwdev, phy, path, false); ++} ++ ++static void _dpk_information(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ ++ u8 kidx = dpk->cur_idx[path]; ++ ++ dpk->bp[path][kidx].band = hal->current_band_type; ++ dpk->bp[path][kidx].ch = hal->current_channel; ++ dpk->bp[path][kidx].bw = hal->current_band_width; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", ++ path, dpk->cur_idx[path], phy, ++ rtwdev->is_tssi_mode[path] ? "on" : "off", ++ rtwdev->dbcc_en ? "on" : "off", ++ dpk->bp[path][kidx].band == 0 ? "2G" : ++ dpk->bp[path][kidx].band == 1 ? "5G" : "6G", ++ dpk->bp[path][kidx].ch, ++ dpk->bp[path][kidx].bw == 0 ? "20M" : ++ dpk->bp[path][kidx].bw == 1 ? "40M" : "80M"); ++} ++ ++static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, u8 kpath) ++{ ++ switch (kpath) { ++ case RF_A: ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sf_defs_a_tbl); ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL) == 0x0) ++ rtw89_phy_write32_set(rtwdev, R_RXCCA, B_RXCCA_DIS); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sr_defs_a_tbl); ++ break; ++ case RF_B: ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sf_defs_b_tbl); ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL) == 0x1) ++ rtw89_phy_write32_set(rtwdev, R_RXCCA, B_RXCCA_DIS); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sr_defs_b_tbl); ++ break; ++ case RF_AB: ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_s_defs_ab_tbl); ++ break; ++ default: ++ break; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Set BB/AFE for PHY%d (kpath=%d)\n", phy, kpath); ++} ++ ++static void _dpk_bb_afe_restore(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, u8 kpath) ++{ ++ switch (kpath) { ++ case RF_A: ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_r_defs_a_tbl); ++ break; ++ case RF_B: ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_r_defs_b_tbl); ++ break; ++ case RF_AB: ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_r_defs_ab_tbl); ++ break; ++ default: ++ break; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Restore BB/AFE for PHY%d (kpath=%d)\n", phy, kpath); ++} ++ ++static void _dpk_tssi_pause(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, bool is_pause) ++{ ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), ++ B_P0_TSSI_TRK_EN, is_pause); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI %s\n", path, ++ is_pause ? "pause" : "resume"); ++} ++ ++static void _dpk_kip_setting(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, u8 kidx) ++{ ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_CLK, MASKDWORD, 0x00093f3f); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x807f030a); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0xce000a08); ++ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG, B_DPK_CFG_IDX, 0x2); ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, B_NCTL_CFG_SPAGE, path); /*subpage_id*/ ++ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0 + (path << 8) + (kidx << 2), ++ MASKDWORD, 0x003f2e2e); ++ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), ++ MASKDWORD, 0x005b5b5b); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] KIP setting for S%d[%d]!!\n", ++ path, kidx); ++} ++ ++static void _dpk_kip_restore(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path) ++{ ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_RPT, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0x10010000); ++ rtw89_phy_write32_clr(rtwdev, R_KIP_CLK, MASKDWORD); ++ ++ if (rtwdev->hal.cv > CHIP_CBV) ++ rtw89_phy_write32_mask(rtwdev, R_DPD_COM + (path << 8), BIT(15), 0x1); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d restore KIP\n", path); ++} ++ ++static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ u8 cur_rxbb; ++ ++ cur_rxbb = (u8)rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_lbk_rxiqk_defs_f_tbl); ++ ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_RXPOW, RR_RXPOW_IQK, 0x2); ++ rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, ++ rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK)); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x1); ++ ++ fsleep(70); ++ ++ rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTL, 0x1f); ++ ++ if (cur_rxbb <= 0xa) ++ rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTH, 0x3); ++ else if (cur_rxbb <= 0x10 && cur_rxbb >= 0xb) ++ rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTH, 0x1); ++ else ++ rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTH, 0x0); ++ ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); ++ ++ _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d LBK RXIQC = 0x%x\n", path, ++ rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD)); ++ ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXPOW, RR_RXPOW_IQK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); /*POW IQKPLL*/ ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_DPK); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_lbk_rxiqk_defs_r_tbl); ++} ++ ++static void _dpk_get_thermal(struct rtw89_dev *rtwdev, u8 kidx, ++ enum rtw89_rf_path path) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ ++ dpk->bp[path][kidx].ther_dpk = ++ ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] thermal@DPK = 0x%x\n", ++ dpk->bp[path][kidx].ther_dpk); ++} ++ ++static u8 _dpk_set_tx_pwr(struct rtw89_dev *rtwdev, u8 gain, ++ enum rtw89_rf_path path) ++{ ++ u8 txagc_ori = 0x38; ++ ++ rtw89_write_rf(rtwdev, path, RR_MODOPT, RFREG_MASK, txagc_ori); ++ ++ return txagc_ori; ++} ++ ++static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain, ++ enum rtw89_rf_path path, u8 kidx) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ ++ if (dpk->bp[path][kidx].band == RTW89_BAND_2G) { ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DPK, 0x280b); ++ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTC, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTR, 0x4); ++ rtw89_write_rf(rtwdev, path, RR_MIXER, RR_MIXER_GN, 0x0); ++ } else { ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DPK, 0x282e); ++ rtw89_write_rf(rtwdev, path, RR_BIASA2, RR_BIASA2_LB, 0x7); ++ rtw89_write_rf(rtwdev, path, RR_TXATANK, RR_TXATANK_LBSW, 0x3); ++ rtw89_write_rf(rtwdev, path, RR_RXA, RR_RXA_DPK, 0x3); ++ } ++ rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_BW, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_TXBB, dpk->bp[path][kidx].bw + 1); ++ rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_RXBB, 0x0); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] RF 0x0/0x1/0x1a = 0x%x/ 0x%x/ 0x%x\n", ++ rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK), ++ rtw89_read_rf(rtwdev, path, RR_MODOPT, RFREG_MASK), ++ rtw89_read_rf(rtwdev, path, RR_BTC, RFREG_MASK)); ++} ++ ++static void _dpk_manual_txcfir(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, bool is_manual) ++{ ++ u8 tmp_pad, tmp_txbb; ++ ++ if (is_manual) { ++ rtw89_phy_write32_mask(rtwdev, R_KIP + (path << 8), B_KIP_RFGAIN, 0x1); ++ tmp_pad = (u8)rtw89_read_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_PAD); ++ rtw89_phy_write32_mask(rtwdev, R_RFGAIN + (path << 8), ++ B_RFGAIN_PAD, tmp_pad); ++ ++ tmp_txbb = (u8)rtw89_read_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_BB); ++ rtw89_phy_write32_mask(rtwdev, R_RFGAIN + (path << 8), ++ B_RFGAIN_TXBB, tmp_txbb); ++ ++ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), ++ B_LOAD_COEF_CFIR, 0x1); ++ rtw89_phy_write32_clr(rtwdev, R_LOAD_COEF + (path << 8), ++ B_LOAD_COEF_CFIR); ++ ++ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), BIT(1), 0x1); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] PAD_man / TXBB_man = 0x%x / 0x%x\n", tmp_pad, ++ tmp_txbb); ++ } else { ++ rtw89_phy_write32_clr(rtwdev, R_KIP + (path << 8), B_KIP_RFGAIN); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] disable manual switch TXCFIR\n"); ++ } ++} ++ ++static void _dpk_bypass_rxcfir(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, bool is_bypass) ++{ ++ if (is_bypass) { ++ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), ++ B_RXIQC_BYPASS2, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), ++ B_RXIQC_BYPASS, 0x1); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Bypass RXIQC (0x8%d3c = 0x%x)\n", 1 + path, ++ rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), ++ MASKDWORD)); ++ } else { ++ rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS2); ++ rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] restore 0x8%d3c = 0x%x\n", 1 + path, ++ rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), ++ MASKDWORD)); ++ } ++} ++ ++static ++void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ ++ if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) ++ rtw89_phy_write32_clr(rtwdev, R_TPG_MOD, B_TPG_MOD_F); ++ else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40) ++ rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x2); ++ else ++ rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x1); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] TPG_Select for %s\n", ++ dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" : ++ dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M"); ++} ++ ++static void _dpk_table_select(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, u8 kidx, u8 gain) ++{ ++ u8 val; ++ ++ val = 0x80 + kidx * 0x20 + gain * 0x10; ++ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0 + (path << 8), MASKBYTE3, val); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] table select for Kidx[%d], Gain[%d] (0x%x)\n", kidx, ++ gain, val); ++} ++ ++static bool _dpk_sync_check(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path) ++{ ++#define DPK_SYNC_TH_DC_I 200 ++#define DPK_SYNC_TH_DC_Q 200 ++#define DPK_SYNC_TH_CORR 170 ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ u16 dc_i, dc_q; ++ u8 corr_val, corr_idx; ++ ++ rtw89_phy_write32_clr(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL); ++ ++ corr_idx = (u8)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORI); ++ corr_val = (u8)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORV); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] S%d Corr_idx / Corr_val = %d / %d\n", path, corr_idx, ++ corr_val); ++ ++ dpk->corr_idx[path] = corr_idx; ++ dpk->corr_val[path] = corr_val; ++ ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x9); ++ ++ dc_i = (u16)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); ++ dc_q = (u16)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); ++ ++ dc_i = abs(sign_extend32(dc_i, 11)); ++ dc_q = abs(sign_extend32(dc_q, 11)); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d DC I/Q, = %d / %d\n", ++ path, dc_i, dc_q); ++ ++ dpk->dc_i[path] = dc_i; ++ dpk->dc_q[path] = dc_q; ++ ++ if (dc_i > DPK_SYNC_TH_DC_I || dc_q > DPK_SYNC_TH_DC_Q || ++ corr_val < DPK_SYNC_TH_CORR) ++ return true; ++ else ++ return false; ++} ++ ++static bool _dpk_sync(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, u8 kidx) ++{ ++ _dpk_tpg_sel(rtwdev, path, kidx); ++ _dpk_one_shot(rtwdev, phy, path, SYNC); ++ return _dpk_sync_check(rtwdev, path); /*1= fail*/ ++} ++ ++static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev) ++{ ++ u16 dgain = 0x0; ++ ++ rtw89_phy_write32_clr(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL); ++ ++ rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_SYNERR); ++ ++ dgain = (u16)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain = 0x%x (%d)\n", dgain, ++ dgain); ++ ++ return dgain; ++} ++ ++static s8 _dpk_dgain_mapping(struct rtw89_dev *rtwdev, u16 dgain) ++{ ++ s8 offset; ++ ++ if (dgain >= 0x783) ++ offset = 0x6; ++ else if (dgain <= 0x782 && dgain >= 0x551) ++ offset = 0x3; ++ else if (dgain <= 0x550 && dgain >= 0x3c4) ++ offset = 0x0; ++ else if (dgain <= 0x3c3 && dgain >= 0x2aa) ++ offset = -3; ++ else if (dgain <= 0x2a9 && dgain >= 0x1e3) ++ offset = -6; ++ else if (dgain <= 0x1e2 && dgain >= 0x156) ++ offset = -9; ++ else if (dgain <= 0x155) ++ offset = -12; ++ else ++ offset = 0x0; ++ ++ return offset; ++} ++ ++static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev) ++{ ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6); ++ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1); ++ return rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL); ++} ++ ++static void _dpk_gainloss(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, enum rtw89_rf_path path, ++ u8 kidx) ++{ ++ _dpk_table_select(rtwdev, path, kidx, 1); ++ _dpk_one_shot(rtwdev, phy, path, GAIN_LOSS); ++} ++ ++#define DPK_TXAGC_LOWER 0x2e ++#define DPK_TXAGC_UPPER 0x3f ++#define DPK_TXAGC_INVAL 0xff ++ ++static u8 _dpk_set_offset(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, s8 gain_offset) ++{ ++ u8 txagc; ++ ++ txagc = (u8)rtw89_read_rf(rtwdev, path, RR_MODOPT, RFREG_MASK); ++ ++ if (txagc - gain_offset < DPK_TXAGC_LOWER) ++ txagc = DPK_TXAGC_LOWER; ++ else if (txagc - gain_offset > DPK_TXAGC_UPPER) ++ txagc = DPK_TXAGC_UPPER; ++ else ++ txagc = txagc - gain_offset; ++ ++ rtw89_write_rf(rtwdev, path, RR_MODOPT, RFREG_MASK, txagc); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] tmp_txagc (GL=%d) = 0x%x\n", ++ gain_offset, txagc); ++ return txagc; ++} ++ ++enum dpk_agc_step { ++ DPK_AGC_STEP_SYNC_DGAIN, ++ DPK_AGC_STEP_GAIN_ADJ, ++ DPK_AGC_STEP_GAIN_LOSS_IDX, ++ DPK_AGC_STEP_GL_GT_CRITERION, ++ DPK_AGC_STEP_GL_LT_CRITERION, ++ DPK_AGC_STEP_SET_TX_GAIN, ++}; ++ ++static u8 _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check) ++{ ++ u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0; ++ u8 i; ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_pas_read_defs_tbl); ++ ++ if (is_check) { ++ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x00); ++ val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); ++ val1_i = abs(sign_extend32(val1_i, 11)); ++ val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); ++ val1_q = abs(sign_extend32(val1_q, 11)); ++ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x1f); ++ val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); ++ val2_i = abs(sign_extend32(val2_i, 11)); ++ val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); ++ val2_q = abs(sign_extend32(val2_q, 11)); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n", ++ (val1_i * val1_i + val1_q * val1_q) / ++ (val2_i * val2_i + val2_q * val2_q)); ++ ++ } else { ++ for (i = 0; i < 32; i++) { ++ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, i); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] PAS_Read[%02d]= 0x%08x\n", i, ++ rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); ++ } ++ } ++ if ((val1_i * val1_i + val1_q * val1_q) >= ++ ((val2_i * val2_i + val2_q * val2_q) * 8 / 5)) ++ return 1; ++ else ++ return 0; ++} ++ ++static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, u8 kidx, u8 init_txagc, ++ bool loss_only) ++{ ++#define DPK_AGC_ADJ_LMT 6 ++#define DPK_DGAIN_UPPER 1922 ++#define DPK_DGAIN_LOWER 342 ++#define DPK_RXBB_UPPER 0x1f ++#define DPK_RXBB_LOWER 0 ++#define DPK_GL_CRIT 7 ++ u8 tmp_txagc, tmp_rxbb = 0, tmp_gl_idx = 0; ++ u8 agc_cnt = 0; ++ bool limited_rxbb = false; ++ s8 offset = 0; ++ u16 dgain = 0; ++ u8 step = DPK_AGC_STEP_SYNC_DGAIN; ++ bool goout = false; ++ ++ tmp_txagc = init_txagc; ++ ++ do { ++ switch (step) { ++ case DPK_AGC_STEP_SYNC_DGAIN: ++ if (_dpk_sync(rtwdev, phy, path, kidx)) { ++ tmp_txagc = DPK_TXAGC_INVAL; ++ goout = true; ++ break; ++ } ++ ++ dgain = _dpk_dgain_read(rtwdev); ++ ++ if (loss_only || limited_rxbb) ++ step = DPK_AGC_STEP_GAIN_LOSS_IDX; ++ else ++ step = DPK_AGC_STEP_GAIN_ADJ; ++ break; ++ ++ case DPK_AGC_STEP_GAIN_ADJ: ++ tmp_rxbb = (u8)rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB); ++ offset = _dpk_dgain_mapping(rtwdev, dgain); ++ ++ if (tmp_rxbb + offset > DPK_RXBB_UPPER) { ++ tmp_rxbb = DPK_RXBB_UPPER; ++ limited_rxbb = true; ++ } else if (tmp_rxbb + offset < DPK_RXBB_LOWER) { ++ tmp_rxbb = DPK_RXBB_LOWER; ++ limited_rxbb = true; ++ } else { ++ tmp_rxbb = tmp_rxbb + offset; ++ } ++ ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB, tmp_rxbb); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Adjust RXBB (%d) = 0x%x\n", offset, ++ tmp_rxbb); ++ if (offset != 0 || agc_cnt == 0) { ++ if (rtwdev->hal.current_band_width < RTW89_CHANNEL_WIDTH_80) ++ _dpk_bypass_rxcfir(rtwdev, path, true); ++ else ++ _dpk_lbk_rxiqk(rtwdev, phy, path); ++ } ++ if (dgain > DPK_DGAIN_UPPER || dgain < DPK_DGAIN_LOWER) ++ step = DPK_AGC_STEP_SYNC_DGAIN; ++ else ++ step = DPK_AGC_STEP_GAIN_LOSS_IDX; ++ ++ agc_cnt++; ++ break; ++ ++ case DPK_AGC_STEP_GAIN_LOSS_IDX: ++ _dpk_gainloss(rtwdev, phy, path, kidx); ++ tmp_gl_idx = _dpk_gainloss_read(rtwdev); ++ ++ if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true)) || ++ tmp_gl_idx > DPK_GL_CRIT) ++ step = DPK_AGC_STEP_GL_GT_CRITERION; ++ else if (tmp_gl_idx == 0) ++ step = DPK_AGC_STEP_GL_LT_CRITERION; ++ else ++ step = DPK_AGC_STEP_SET_TX_GAIN; ++ break; ++ ++ case DPK_AGC_STEP_GL_GT_CRITERION: ++ if (tmp_txagc == DPK_TXAGC_LOWER) { ++ goout = true; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Txagc@lower bound!!\n"); ++ } else { ++ tmp_txagc = _dpk_set_offset(rtwdev, path, 3); ++ } ++ step = DPK_AGC_STEP_GAIN_LOSS_IDX; ++ agc_cnt++; ++ break; ++ ++ case DPK_AGC_STEP_GL_LT_CRITERION: ++ if (tmp_txagc == DPK_TXAGC_UPPER) { ++ goout = true; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Txagc@upper bound!!\n"); ++ } else { ++ tmp_txagc = _dpk_set_offset(rtwdev, path, -2); ++ } ++ step = DPK_AGC_STEP_GAIN_LOSS_IDX; ++ agc_cnt++; ++ break; ++ ++ case DPK_AGC_STEP_SET_TX_GAIN: ++ tmp_txagc = _dpk_set_offset(rtwdev, path, tmp_gl_idx); ++ goout = true; ++ agc_cnt++; ++ break; ++ ++ default: ++ goout = true; ++ break; ++ } ++ } while (!goout && (agc_cnt < DPK_AGC_ADJ_LMT)); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Txagc / RXBB for DPK = 0x%x / 0x%x\n", tmp_txagc, ++ tmp_rxbb); ++ ++ return tmp_txagc; ++} ++ ++static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order) ++{ ++ switch (order) { ++ case 0: ++ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); ++ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x3); ++ rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN, 0x1); ++ break; ++ case 1: ++ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); ++ rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN); ++ rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN); ++ break; ++ case 2: ++ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); ++ rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN); ++ rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN); ++ break; ++ default: ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Wrong MDPD order!!(0x%x)\n", order); ++ break; ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Set MDPD order to 0x%x for IDL\n", order); ++} ++ ++static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, u8 kidx, u8 gain) ++{ ++ _dpk_set_mdpd_para(rtwdev, 0x0); ++ _dpk_table_select(rtwdev, path, kidx, 1); ++ _dpk_one_shot(rtwdev, phy, path, MDPK_IDL); ++} ++ ++static void _dpk_fill_result(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, u8 kidx, u8 gain, ++ u8 txagc) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ ++ u16 pwsf = 0x78; ++ u8 gs = 0x5b; ++ ++ rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_MDPD, kidx); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Fill txagc/ pwsf/ gs = 0x%x/ 0x%x/ 0x%x\n", txagc, ++ pwsf, gs); ++ ++ dpk->bp[path][kidx].txagc_dpk = txagc; ++ rtw89_phy_write32_mask(rtwdev, R_TXAGC_RFK + (path << 8), ++ 0x3F << ((gain << 3) + (kidx << 4)), txagc); ++ ++ dpk->bp[path][kidx].pwsf = pwsf; ++ rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), ++ 0x1FF << (gain << 4), pwsf); ++ ++ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x1); ++ rtw89_phy_write32_clr(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD); ++ ++ dpk->bp[path][kidx].gs = gs; ++ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), ++ MASKDWORD, 0x065b5b5b); ++ ++ rtw89_phy_write32_clr(rtwdev, R_DPD_V1 + (path << 8), MASKDWORD); ++ ++ rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_SEL); ++} ++ ++static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ bool is_reload = false; ++ u8 idx, cur_band, cur_ch; ++ ++ cur_band = rtwdev->hal.current_band_type; ++ cur_ch = rtwdev->hal.current_channel; ++ ++ for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) { ++ if (cur_band != dpk->bp[path][idx].band || ++ cur_ch != dpk->bp[path][idx].ch) ++ continue; ++ ++ rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), ++ B_COEF_SEL_MDPD, idx); ++ dpk->cur_idx[path] = idx; ++ is_reload = true; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] reload S%d[%d] success\n", path, idx); ++ } ++ ++ return is_reload; ++} ++ ++static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, u8 gain) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ u8 txagc = 0, kidx = dpk->cur_idx[path]; ++ bool is_fail = false; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] ========= S%d[%d] DPK Start =========\n", path, ++ kidx); ++ ++ _rf_direct_cntrl(rtwdev, path, false); ++ txagc = _dpk_set_tx_pwr(rtwdev, gain, path); ++ _dpk_rf_setting(rtwdev, gain, path, kidx); ++ _dpk_rx_dck(rtwdev, phy, path); ++ ++ _dpk_kip_setting(rtwdev, path, kidx); ++ _dpk_manual_txcfir(rtwdev, path, true); ++ txagc = _dpk_agc(rtwdev, phy, path, kidx, txagc, false); ++ if (txagc == DPK_TXAGC_INVAL) ++ is_fail = true; ++ _dpk_get_thermal(rtwdev, kidx, path); ++ ++ _dpk_idl_mpa(rtwdev, phy, path, kidx, gain); ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); ++ _dpk_fill_result(rtwdev, path, kidx, gain, txagc); ++ _dpk_manual_txcfir(rtwdev, path, false); ++ ++ if (!is_fail) ++ dpk->bp[path][kidx].path_ok = true; ++ else ++ dpk->bp[path][kidx].path_ok = false; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s\n", path, kidx, ++ is_fail ? "Check" : "Success"); ++ ++ return is_fail; ++} ++ ++static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force, ++ enum rtw89_phy_idx phy, u8 kpath) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ u32 backup_bb_val[BACKUP_BB_REGS_NR]; ++ u32 backup_rf_val[RTW8852A_DPK_RF_PATH][BACKUP_RF_REGS_NR]; ++ u32 kip_bkup[RTW8852A_DPK_RF_PATH][RTW8852A_DPK_KIP_REG_NUM] = {{0}}; ++ u32 kip_reg[] = {R_RXIQC, R_IQK_RES}; ++ u8 path; ++ bool is_fail = true, reloaded[RTW8852A_DPK_RF_PATH] = {false}; ++ ++ if (dpk->is_dpk_reload_en) { ++ for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { ++ if (!(kpath & BIT(path))) ++ continue; ++ ++ reloaded[path] = _dpk_reload_check(rtwdev, phy, path); ++ if (!reloaded[path] && dpk->bp[path][0].ch != 0) ++ dpk->cur_idx[path] = !dpk->cur_idx[path]; ++ else ++ _dpk_onoff(rtwdev, path, false); ++ } ++ } else { ++ for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) ++ dpk->cur_idx[path] = 0; ++ } ++ ++ if ((kpath == RF_A && reloaded[RF_PATH_A]) || ++ (kpath == RF_B && reloaded[RF_PATH_B]) || ++ (kpath == RF_AB && reloaded[RF_PATH_A] && reloaded[RF_PATH_B])) ++ return; ++ ++ _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]); ++ ++ for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { ++ if (!(kpath & BIT(path)) || reloaded[path]) ++ continue; ++ if (rtwdev->is_tssi_mode[path]) ++ _dpk_tssi_pause(rtwdev, path, true); ++ _dpk_bkup_kip(rtwdev, kip_reg, kip_bkup, path); ++ _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path); ++ _dpk_information(rtwdev, phy, path); ++ } ++ ++ _dpk_bb_afe_setting(rtwdev, phy, path, kpath); ++ ++ for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { ++ if (!(kpath & BIT(path)) || reloaded[path]) ++ continue; ++ ++ is_fail = _dpk_main(rtwdev, phy, path, 1); ++ _dpk_onoff(rtwdev, path, is_fail); ++ } ++ ++ _dpk_bb_afe_restore(rtwdev, phy, path, kpath); ++ _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]); ++ ++ for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { ++ if (!(kpath & BIT(path)) || reloaded[path]) ++ continue; ++ ++ _dpk_kip_restore(rtwdev, path); ++ _dpk_reload_kip(rtwdev, kip_reg, kip_bkup, path); ++ _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path); ++ if (rtwdev->is_tssi_mode[path]) ++ _dpk_tssi_pause(rtwdev, path, false); ++ } ++} ++ ++static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ struct rtw89_fem_info *fem = &rtwdev->fem; ++ ++ if (fem->epa_2g && rtwdev->hal.current_band_type == RTW89_BAND_2G) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Skip DPK due to 2G_ext_PA exist!!\n"); ++ return true; ++ } else if (fem->epa_5g && rtwdev->hal.current_band_type == RTW89_BAND_5G) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Skip DPK due to 5G_ext_PA exist!!\n"); ++ return true; ++ } ++ ++ return false; ++} ++ ++static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ u8 path, kpath; ++ ++ kpath = _kpath(rtwdev, phy); ++ ++ for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { ++ if (kpath & BIT(path)) ++ _dpk_onoff(rtwdev, path, true); ++ } ++} ++ ++static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] ****** DPK Start (Ver: 0x%x, Cv: %d, RF_para: %d) ******\n", ++ RTW8852A_DPK_VER, rtwdev->hal.cv, ++ RTW8852A_RF_REL_VERSION); ++ ++ if (_dpk_bypass_check(rtwdev, phy)) ++ _dpk_force_bypass(rtwdev, phy); ++ else ++ _dpk_cal_select(rtwdev, force, phy, _kpath(rtwdev, phy)); ++} ++ ++static void _dpk_onoff(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, bool off) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ u8 val, kidx = dpk->cur_idx[path]; ++ ++ val = dpk->is_dpk_enable && !off && dpk->bp[path][kidx].path_ok; ++ ++ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), ++ MASKBYTE3, 0x6 | val); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path, ++ kidx, dpk->is_dpk_enable && !off ? "enable" : "disable"); ++} ++ ++static void _dpk_track(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 path, kidx; ++ u8 trk_idx = 0, txagc_rf = 0; ++ s8 txagc_bb = 0, txagc_bb_tp = 0, ini_diff = 0, txagc_ofst = 0; ++ u16 pwsf[2]; ++ u8 cur_ther; ++ s8 delta_ther[2] = {0}; ++ ++ for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { ++ kidx = dpk->cur_idx[path]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, ++ "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n", ++ path, kidx, dpk->bp[path][kidx].ch); ++ ++ cur_ther = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, ++ "[DPK_TRK] thermal now = %d\n", cur_ther); ++ ++ if (dpk->bp[path][kidx].ch != 0 && cur_ther != 0) ++ delta_ther[path] = dpk->bp[path][kidx].ther_dpk - cur_ther; ++ ++ if (dpk->bp[path][kidx].band == RTW89_BAND_2G) ++ delta_ther[path] = delta_ther[path] * 3 / 2; ++ else ++ delta_ther[path] = delta_ther[path] * 5 / 2; ++ ++ txagc_rf = (u8)rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), ++ RR_MODOPT_M_TXPWR); ++ ++ if (rtwdev->is_tssi_mode[path]) { ++ trk_idx = (u8)rtw89_read_rf(rtwdev, path, RR_TXA, RR_TXA_TRK); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, ++ "[DPK_TRK] txagc_RF / track_idx = 0x%x / %d\n", ++ txagc_rf, trk_idx); ++ ++ txagc_bb = ++ (s8)rtw89_phy_read32_mask(rtwdev, ++ R_TXAGC_BB + (path << 13), ++ MASKBYTE2); ++ txagc_bb_tp = ++ (u8)rtw89_phy_read32_mask(rtwdev, ++ R_TXAGC_TP + (path << 13), ++ B_TXAGC_TP); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, ++ "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n", ++ txagc_bb_tp, txagc_bb); ++ ++ txagc_ofst = ++ (s8)rtw89_phy_read32_mask(rtwdev, ++ R_TXAGC_BB + (path << 13), ++ MASKBYTE3); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, ++ "[DPK_TRK] txagc_offset / delta_ther = %d / %d\n", ++ txagc_ofst, delta_ther[path]); ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_DPD_COM + (path << 8), ++ BIT(15)) == 0x1) ++ txagc_ofst = 0; ++ ++ if (txagc_rf != 0 && cur_ther != 0) ++ ini_diff = txagc_ofst + delta_ther[path]; ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_P0_TXDPD + (path << 13), ++ B_P0_TXDPD) == 0x0) { ++ pwsf[0] = dpk->bp[path][kidx].pwsf + txagc_bb_tp - ++ txagc_bb + ini_diff + ++ tssi_info->extra_ofst[path]; ++ pwsf[1] = dpk->bp[path][kidx].pwsf + txagc_bb_tp - ++ txagc_bb + ini_diff + ++ tssi_info->extra_ofst[path]; ++ } else { ++ pwsf[0] = dpk->bp[path][kidx].pwsf + ini_diff + ++ tssi_info->extra_ofst[path]; ++ pwsf[1] = dpk->bp[path][kidx].pwsf + ini_diff + ++ tssi_info->extra_ofst[path]; ++ } ++ ++ } else { ++ pwsf[0] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff; ++ pwsf[1] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff; ++ } ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_DPK_TRK, B_DPK_TRK_DIS) == 0x0 && ++ txagc_rf != 0) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, ++ "[DPK_TRK] New pwsf[0] / pwsf[1] = 0x%x / 0x%x\n", ++ pwsf[0], pwsf[1]); ++ ++ rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), ++ 0x000001FF, pwsf[0]); ++ rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), ++ 0x01FF0000, pwsf[1]); ++ } ++ } ++} ++ ++static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ enum rtw89_band band = rtwdev->hal.current_band_type; ++ ++ if (band == RTW89_BAND_2G) ++ rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXG, 0x1); ++ else ++ rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXA, 0x1); ++} ++ ++static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ enum rtw89_band band = rtwdev->hal.current_band_type; ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_sys_defs_tbl); ++ rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, ++ &rtw8852a_tssi_sys_defs_2g_tbl, ++ &rtw8852a_tssi_sys_defs_5g_tbl); ++} ++ ++static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ enum rtw89_band band = rtwdev->hal.current_band_type; ++ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_txpwr_ctrl_bb_defs_a_tbl, ++ &rtw8852a_tssi_txpwr_ctrl_bb_defs_b_tbl); ++ rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, ++ &rtw8852a_tssi_txpwr_ctrl_bb_defs_2g_tbl, ++ &rtw8852a_tssi_txpwr_ctrl_bb_defs_5g_tbl); ++} ++ ++static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_a_tbl, ++ &rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_b_tbl); ++} ++ ++static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_dck_defs_a_tbl, ++ &rtw8852a_tssi_dck_defs_b_tbl); ++} ++ ++static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++#define __get_val(ptr, idx) \ ++({ \ ++ s8 *__ptr = (ptr); \ ++ u8 __idx = (idx), __i, __v; \ ++ u32 __val = 0; \ ++ for (__i = 0; __i < 4; __i++) { \ ++ __v = (__ptr[__idx + __i]); \ ++ __val |= (__v << (8 * __i)); \ ++ } \ ++ __val; \ ++}) ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 ch = rtwdev->hal.current_channel; ++ u8 subband = rtwdev->hal.current_subband; ++ const u8 *thm_up_a = NULL; ++ const u8 *thm_down_a = NULL; ++ const u8 *thm_up_b = NULL; ++ const u8 *thm_down_b = NULL; ++ u8 thermal = 0xff; ++ s8 thm_ofst[64] = {0}; ++ u32 tmp = 0; ++ u8 i, j; ++ ++ switch (subband) { ++ case RTW89_CH_2G: ++ thm_up_a = rtw89_8852a_trk_cfg.delta_swingidx_2ga_p; ++ thm_down_a = rtw89_8852a_trk_cfg.delta_swingidx_2ga_n; ++ thm_up_b = rtw89_8852a_trk_cfg.delta_swingidx_2gb_p; ++ thm_down_b = rtw89_8852a_trk_cfg.delta_swingidx_2gb_n; ++ break; ++ case RTW89_CH_5G_BAND_1: ++ thm_up_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_p[0]; ++ thm_down_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_n[0]; ++ thm_up_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_p[0]; ++ thm_down_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_n[0]; ++ break; ++ case RTW89_CH_5G_BAND_3: ++ thm_up_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_p[1]; ++ thm_down_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_n[1]; ++ thm_up_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_p[1]; ++ thm_down_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_n[1]; ++ break; ++ case RTW89_CH_5G_BAND_4: ++ thm_up_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_p[2]; ++ thm_down_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_n[2]; ++ thm_up_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_p[2]; ++ thm_down_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_n[2]; ++ break; ++ } ++ ++ if (path == RF_PATH_A) { ++ thermal = tssi_info->thermal[RF_PATH_A]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] ch=%d thermal_pathA=0x%x\n", ch, thermal); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, 0x1); ++ ++ if (thermal == 0xff) { ++ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, 32); ++ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 32); ++ ++ for (i = 0; i < 64; i += 4) { ++ rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, 0x0); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] write 0x%x val=0x%08x\n", ++ 0x5c00 + i, 0x0); ++ } ++ ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, thermal); ++ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, ++ thermal); ++ ++ i = 0; ++ for (j = 0; j < 32; j++) ++ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? ++ -thm_down_a[i++] : ++ -thm_down_a[DELTA_SWINGIDX_SIZE - 1]; ++ ++ i = 1; ++ for (j = 63; j >= 32; j--) ++ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? ++ thm_up_a[i++] : ++ thm_up_a[DELTA_SWINGIDX_SIZE - 1]; ++ ++ for (i = 0; i < 64; i += 4) { ++ tmp = __get_val(thm_ofst, i); ++ rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, tmp); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] write 0x%x val=0x%08x\n", ++ 0x5c00 + i, tmp); ++ } ++ } ++ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x0); ++ ++ } else { ++ thermal = tssi_info->thermal[RF_PATH_B]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] ch=%d thermal_pathB=0x%x\n", ch, thermal); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_DIS, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_TRK, 0x1); ++ ++ if (thermal == 0xff) { ++ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, 32); ++ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, 32); ++ ++ for (i = 0; i < 64; i += 4) { ++ rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, 0x0); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] write 0x%x val=0x%08x\n", ++ 0x7c00 + i, 0x0); ++ } ++ ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, thermal); ++ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, ++ thermal); ++ ++ i = 0; ++ for (j = 0; j < 32; j++) ++ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? ++ -thm_down_b[i++] : ++ -thm_down_b[DELTA_SWINGIDX_SIZE - 1]; ++ ++ i = 1; ++ for (j = 63; j >= 32; j--) ++ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? ++ thm_up_b[i++] : ++ thm_up_b[DELTA_SWINGIDX_SIZE - 1]; ++ ++ for (i = 0; i < 64; i += 4) { ++ tmp = __get_val(thm_ofst, i); ++ rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, tmp); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] write 0x%x val=0x%08x\n", ++ 0x7c00 + i, tmp); ++ } ++ } ++ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x0); ++ } ++#undef __get_val ++} ++ ++static void _tssi_set_dac_gain_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_dac_gain_tbl_defs_a_tbl, ++ &rtw8852a_tssi_dac_gain_tbl_defs_b_tbl); ++} ++ ++static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_slope_cal_org_defs_a_tbl, ++ &rtw8852a_tssi_slope_cal_org_defs_b_tbl); ++} ++ ++static void _tssi_set_rf_gap_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_rf_gap_tbl_defs_a_tbl, ++ &rtw8852a_tssi_rf_gap_tbl_defs_b_tbl); ++} ++ ++static void _tssi_set_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_slope_defs_a_tbl, ++ &rtw8852a_tssi_slope_defs_b_tbl); ++} ++ ++static void _tssi_set_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_track_defs_a_tbl, ++ &rtw8852a_tssi_track_defs_b_tbl); ++} ++ ++static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_txagc_ofst_mv_avg_defs_a_tbl, ++ &rtw8852a_tssi_txagc_ofst_mv_avg_defs_b_tbl); ++} ++ ++static void _tssi_pak(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ u8 subband = rtwdev->hal.current_subband; ++ ++ switch (subband) { ++ case RTW89_CH_2G: ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_pak_defs_a_2g_tbl, ++ &rtw8852a_tssi_pak_defs_b_2g_tbl); ++ break; ++ case RTW89_CH_5G_BAND_1: ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_pak_defs_a_5g_1_tbl, ++ &rtw8852a_tssi_pak_defs_b_5g_1_tbl); ++ break; ++ case RTW89_CH_5G_BAND_3: ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_pak_defs_a_5g_3_tbl, ++ &rtw8852a_tssi_pak_defs_b_5g_3_tbl); ++ break; ++ case RTW89_CH_5G_BAND_4: ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_pak_defs_a_5g_4_tbl, ++ &rtw8852a_tssi_pak_defs_b_5g_4_tbl); ++ break; ++ } ++} ++ ++static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 i; ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ _tssi_set_track(rtwdev, phy, i); ++ _tssi_set_txagc_offset_mv_avg(rtwdev, phy, i); ++ ++ rtw89_rfk_parser_by_cond(rtwdev, i == RF_PATH_A, ++ &rtw8852a_tssi_enable_defs_a_tbl, ++ &rtw8852a_tssi_enable_defs_b_tbl); ++ ++ tssi_info->base_thermal[i] = ++ ewma_thermal_read(&rtwdev->phystat.avg_thermal[i]); ++ rtwdev->is_tssi_mode[i] = true; ++ } ++} ++ ++static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_disable_defs_tbl); ++ ++ rtwdev->is_tssi_mode[RF_PATH_A] = false; ++ rtwdev->is_tssi_mode[RF_PATH_B] = false; ++} ++ ++static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch) ++{ ++ switch (ch) { ++ case 1 ... 2: ++ return 0; ++ case 3 ... 5: ++ return 1; ++ case 6 ... 8: ++ return 2; ++ case 9 ... 11: ++ return 3; ++ case 12 ... 13: ++ return 4; ++ case 14: ++ return 5; ++ } ++ ++ return 0; ++} ++ ++#define TSSI_EXTRA_GROUP_BIT (BIT(31)) ++#define TSSI_EXTRA_GROUP(idx) (TSSI_EXTRA_GROUP_BIT | (idx)) ++#define IS_TSSI_EXTRA_GROUP(group) ((group) & TSSI_EXTRA_GROUP_BIT) ++#define TSSI_EXTRA_GET_GROUP_IDX1(group) ((group) & ~TSSI_EXTRA_GROUP_BIT) ++#define TSSI_EXTRA_GET_GROUP_IDX2(group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1) ++ ++static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) ++{ ++ switch (ch) { ++ case 1 ... 2: ++ return 0; ++ case 3 ... 5: ++ return 1; ++ case 6 ... 8: ++ return 2; ++ case 9 ... 11: ++ return 3; ++ case 12 ... 14: ++ return 4; ++ case 36 ... 40: ++ return 5; ++ case 41 ... 43: ++ return TSSI_EXTRA_GROUP(5); ++ case 44 ... 48: ++ return 6; ++ case 49 ... 51: ++ return TSSI_EXTRA_GROUP(6); ++ case 52 ... 56: ++ return 7; ++ case 57 ... 59: ++ return TSSI_EXTRA_GROUP(7); ++ case 60 ... 64: ++ return 8; ++ case 100 ... 104: ++ return 9; ++ case 105 ... 107: ++ return TSSI_EXTRA_GROUP(9); ++ case 108 ... 112: ++ return 10; ++ case 113 ... 115: ++ return TSSI_EXTRA_GROUP(10); ++ case 116 ... 120: ++ return 11; ++ case 121 ... 123: ++ return TSSI_EXTRA_GROUP(11); ++ case 124 ... 128: ++ return 12; ++ case 129 ... 131: ++ return TSSI_EXTRA_GROUP(12); ++ case 132 ... 136: ++ return 13; ++ case 137 ... 139: ++ return TSSI_EXTRA_GROUP(13); ++ case 140 ... 144: ++ return 14; ++ case 149 ... 153: ++ return 15; ++ case 154 ... 156: ++ return TSSI_EXTRA_GROUP(15); ++ case 157 ... 161: ++ return 16; ++ case 162 ... 164: ++ return TSSI_EXTRA_GROUP(16); ++ case 165 ... 169: ++ return 17; ++ case 170 ... 172: ++ return TSSI_EXTRA_GROUP(17); ++ case 173 ... 177: ++ return 18; ++ } ++ ++ return 0; ++} ++ ++static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch) ++{ ++ switch (ch) { ++ case 1 ... 8: ++ return 0; ++ case 9 ... 14: ++ return 1; ++ case 36 ... 48: ++ return 2; ++ case 52 ... 64: ++ return 3; ++ case 100 ... 112: ++ return 4; ++ case 116 ... 128: ++ return 5; ++ case 132 ... 144: ++ return 6; ++ case 149 ... 177: ++ return 7; ++ } ++ ++ return 0; ++} ++ ++static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 ch = rtwdev->hal.current_channel; ++ u32 gidx, gidx_1st, gidx_2nd; ++ s8 de_1st = 0; ++ s8 de_2nd = 0; ++ s8 val; ++ ++ gidx = _tssi_get_ofdm_group(rtwdev, ch); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", ++ path, gidx); ++ ++ if (IS_TSSI_EXTRA_GROUP(gidx)) { ++ gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); ++ gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); ++ de_1st = tssi_info->tssi_mcs[path][gidx_1st]; ++ de_2nd = tssi_info->tssi_mcs[path][gidx_2nd]; ++ val = (de_1st + de_2nd) / 2; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", ++ path, val, de_1st, de_2nd); ++ } else { ++ val = tssi_info->tssi_mcs[path][gidx]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); ++ } ++ ++ return val; ++} ++ ++static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 ch = rtwdev->hal.current_channel; ++ u32 tgidx, tgidx_1st, tgidx_2nd; ++ s8 tde_1st = 0; ++ s8 tde_2nd = 0; ++ s8 val; ++ ++ tgidx = _tssi_get_trim_group(rtwdev, ch); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", ++ path, tgidx); ++ ++ if (IS_TSSI_EXTRA_GROUP(tgidx)) { ++ tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); ++ tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); ++ tde_1st = tssi_info->tssi_trim[path][tgidx_1st]; ++ tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd]; ++ val = (tde_1st + tde_2nd) / 2; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", ++ path, val, tde_1st, tde_2nd); ++ } else { ++ val = tssi_info->tssi_trim[path][tgidx]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", ++ path, val); ++ } ++ ++ return val; ++} ++ ++static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy) ++{ ++#define __DE_MASK 0x003ff000 ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ static const u32 r_cck_long[RF_PATH_NUM_8852A] = {0x5858, 0x7858}; ++ static const u32 r_cck_short[RF_PATH_NUM_8852A] = {0x5860, 0x7860}; ++ static const u32 r_mcs_20m[RF_PATH_NUM_8852A] = {0x5838, 0x7838}; ++ static const u32 r_mcs_40m[RF_PATH_NUM_8852A] = {0x5840, 0x7840}; ++ static const u32 r_mcs_80m[RF_PATH_NUM_8852A] = {0x5848, 0x7848}; ++ static const u32 r_mcs_80m_80m[RF_PATH_NUM_8852A] = {0x5850, 0x7850}; ++ static const u32 r_mcs_5m[RF_PATH_NUM_8852A] = {0x5828, 0x7828}; ++ static const u32 r_mcs_10m[RF_PATH_NUM_8852A] = {0x5830, 0x7830}; ++ u8 ch = rtwdev->hal.current_channel; ++ u8 i, gidx; ++ s8 ofdm_de; ++ s8 trim_de; ++ s32 val; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n", ++ phy, ch); ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ gidx = _tssi_get_cck_group(rtwdev, ch); ++ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i); ++ val = tssi_info->tssi_cck[i][gidx] + trim_de; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n", ++ i, gidx, tssi_info->tssi_cck[i][gidx], trim_de); ++ ++ rtw89_phy_write32_mask(rtwdev, r_cck_long[i], __DE_MASK, val); ++ rtw89_phy_write32_mask(rtwdev, r_cck_short[i], __DE_MASK, val); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n", ++ r_cck_long[i], ++ rtw89_phy_read32_mask(rtwdev, r_cck_long[i], ++ __DE_MASK)); ++ ++ ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i); ++ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i); ++ val = ofdm_de + trim_de; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n", ++ i, ofdm_de, trim_de); ++ ++ rtw89_phy_write32_mask(rtwdev, r_mcs_20m[i], __DE_MASK, val); ++ rtw89_phy_write32_mask(rtwdev, r_mcs_40m[i], __DE_MASK, val); ++ rtw89_phy_write32_mask(rtwdev, r_mcs_80m[i], __DE_MASK, val); ++ rtw89_phy_write32_mask(rtwdev, r_mcs_80m_80m[i], __DE_MASK, val); ++ rtw89_phy_write32_mask(rtwdev, r_mcs_5m[i], __DE_MASK, val); ++ rtw89_phy_write32_mask(rtwdev, r_mcs_10m[i], __DE_MASK, val); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n", ++ r_mcs_20m[i], ++ rtw89_phy_read32_mask(rtwdev, r_mcs_20m[i], ++ __DE_MASK)); ++ } ++#undef __DE_MASK ++} ++ ++static void _tssi_track(struct rtw89_dev *rtwdev) ++{ ++ static const u32 tx_gain_scale_table[] = { ++ 0x400, 0x40e, 0x41d, 0x427, 0x43c, 0x44c, 0x45c, 0x46c, ++ 0x400, 0x39d, 0x3ab, 0x3b8, 0x3c6, 0x3d4, 0x3e2, 0x3f1 ++ }; ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 path; ++ u8 cur_ther; ++ s32 delta_ther = 0, gain_offset_int, gain_offset_float; ++ s8 gain_offset; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRK] %s:\n", ++ __func__); ++ ++ if (!rtwdev->is_tssi_mode[RF_PATH_A]) ++ return; ++ if (!rtwdev->is_tssi_mode[RF_PATH_B]) ++ return; ++ ++ for (path = RF_PATH_A; path < RF_PATH_NUM_8852A; path++) { ++ if (!tssi_info->tssi_tracking_check[path]) { ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRK] return!!!\n"); ++ continue; ++ } ++ ++ cur_ther = (u8)rtw89_phy_read32_mask(rtwdev, ++ R_TSSI_THER + (path << 13), ++ B_TSSI_THER); ++ ++ if (cur_ther == 0 || tssi_info->base_thermal[path] == 0) ++ continue; ++ ++ delta_ther = cur_ther - tssi_info->base_thermal[path]; ++ ++ gain_offset = (s8)delta_ther * 15 / 10; ++ ++ tssi_info->extra_ofst[path] = gain_offset; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRK] base_thermal=%d gain_offset=0x%x path=%d\n", ++ tssi_info->base_thermal[path], gain_offset, path); ++ ++ gain_offset_int = gain_offset >> 3; ++ gain_offset_float = gain_offset & 7; ++ ++ if (gain_offset_int > 15) ++ gain_offset_int = 15; ++ else if (gain_offset_int < -16) ++ gain_offset_int = -16; ++ ++ rtw89_phy_write32_mask(rtwdev, R_DPD_OFT_EN + (path << 13), ++ B_DPD_OFT_EN, 0x1); ++ ++ rtw89_phy_write32_mask(rtwdev, R_TXGAIN_SCALE + (path << 13), ++ B_TXGAIN_SCALE_EN, 0x1); ++ ++ rtw89_phy_write32_mask(rtwdev, R_DPD_OFT_ADDR + (path << 13), ++ B_DPD_OFT_ADDR, gain_offset_int); ++ ++ rtw89_phy_write32_mask(rtwdev, R_TXGAIN_SCALE + (path << 13), ++ B_TXGAIN_SCALE_OFT, ++ tx_gain_scale_table[gain_offset_float]); ++ } ++} ++ ++static void _tssi_high_power(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 ch = rtwdev->hal.current_channel, ch_tmp; ++ u8 bw = rtwdev->hal.current_band_width; ++ u8 subband = rtwdev->hal.current_subband; ++ s8 power; ++ s32 xdbm; ++ ++ if (bw == RTW89_CHANNEL_WIDTH_40) ++ ch_tmp = ch - 2; ++ else if (bw == RTW89_CHANNEL_WIDTH_80) ++ ch_tmp = ch - 6; ++ else ++ ch_tmp = ch; ++ ++ power = rtw89_phy_read_txpwr_limit(rtwdev, bw, RTW89_1TX, ++ RTW89_RS_MCS, RTW89_NONBF, ch_tmp); ++ ++ xdbm = power * 100 / 4; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d xdbm=%d\n", ++ __func__, phy, xdbm); ++ ++ if (xdbm > 1800 && subband == RTW89_CH_2G) { ++ tssi_info->tssi_tracking_check[RF_PATH_A] = true; ++ tssi_info->tssi_tracking_check[RF_PATH_B] = true; ++ } else { ++ rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_tracking_defs_tbl); ++ tssi_info->extra_ofst[RF_PATH_A] = 0; ++ tssi_info->extra_ofst[RF_PATH_B] = 0; ++ tssi_info->tssi_tracking_check[RF_PATH_A] = false; ++ tssi_info->tssi_tracking_check[RF_PATH_B] = false; ++ } ++} ++ ++static void _tssi_hw_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ u8 path, s16 pwr_dbm, u8 enable) ++{ ++ rtw8852a_bb_set_plcp_tx(rtwdev); ++ rtw8852a_bb_cfg_tx_path(rtwdev, path); ++ rtw8852a_bb_set_power(rtwdev, pwr_dbm, phy); ++ rtw8852a_bb_set_pmac_pkt_tx(rtwdev, enable, 20, 5000, 0, phy); ++} ++ ++static void _tssi_pre_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ const struct rtw89_chip_info *mac_reg = rtwdev->chip; ++ u8 ch = rtwdev->hal.current_channel, ch_tmp; ++ u8 bw = rtwdev->hal.current_band_width; ++ u16 tx_en; ++ u8 phy_map = rtw89_btc_phymap(rtwdev, phy, 0); ++ s8 power; ++ s16 xdbm; ++ u32 i, tx_counter = 0; ++ ++ if (bw == RTW89_CHANNEL_WIDTH_40) ++ ch_tmp = ch - 2; ++ else if (bw == RTW89_CHANNEL_WIDTH_80) ++ ch_tmp = ch - 6; ++ else ++ ch_tmp = ch; ++ ++ power = rtw89_phy_read_txpwr_limit(rtwdev, RTW89_CHANNEL_WIDTH_20, RTW89_1TX, ++ RTW89_RS_OFDM, RTW89_NONBF, ch_tmp); ++ ++ xdbm = (power * 100) >> mac_reg->txpwr_factor_mac; ++ ++ if (xdbm > 1800) ++ xdbm = 68; ++ else ++ xdbm = power * 2; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] %s: phy=%d org_power=%d xdbm=%d\n", ++ __func__, phy, power, xdbm); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START); ++ rtw89_mac_stop_sch_tx(rtwdev, phy, &tx_en, RTW89_SCH_TX_SEL_ALL); ++ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy)); ++ tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); ++ ++ _tssi_hw_tx(rtwdev, phy, RF_PATH_AB, xdbm, true); ++ mdelay(15); ++ _tssi_hw_tx(rtwdev, phy, RF_PATH_AB, xdbm, false); ++ ++ tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD) - ++ tx_counter; ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, MASKHWORD) != 0xc000 && ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, MASKHWORD) != 0x0) { ++ for (i = 0; i < 6; i++) { ++ tssi_info->default_txagc_offset[RF_PATH_A] = ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, ++ MASKBYTE3); ++ ++ if (tssi_info->default_txagc_offset[RF_PATH_A] != 0x0) ++ break; ++ } ++ } ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, MASKHWORD) != 0xc000 && ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, MASKHWORD) != 0x0) { ++ for (i = 0; i < 6; i++) { ++ tssi_info->default_txagc_offset[RF_PATH_B] = ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, ++ MASKBYTE3); ++ ++ if (tssi_info->default_txagc_offset[RF_PATH_B] != 0x0) ++ break; ++ } ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] %s: tx counter=%d\n", ++ __func__, tx_counter); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] Backup R_TXAGC_BB=0x%x R_TXAGC_BB_S1=0x%x\n", ++ tssi_info->default_txagc_offset[RF_PATH_A], ++ tssi_info->default_txagc_offset[RF_PATH_B]); ++ ++ rtw8852a_bb_tx_mode_switch(rtwdev, phy, 0); ++ ++ rtw89_mac_resume_sch_tx(rtwdev, phy, tx_en); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP); ++} ++ ++void rtw8852a_rck(struct rtw89_dev *rtwdev) ++{ ++ u8 path; ++ ++ for (path = 0; path < 2; path++) ++ _rck(rtwdev, path); ++} ++ ++void rtw8852a_dack(struct rtw89_dev *rtwdev) ++{ ++ u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_START); ++ _dac_cal(rtwdev, false); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP); ++} ++ ++void rtw8852a_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) ++{ ++ u16 tx_en; ++ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START); ++ rtw89_mac_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); ++ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); ++ ++ _iqk_init(rtwdev); ++ if (rtwdev->dbcc_en) ++ _iqk_dbcc(rtwdev, phy_idx); ++ else ++ _iqk(rtwdev, phy_idx, false); ++ ++ rtw89_mac_resume_sch_tx(rtwdev, phy_idx, tx_en); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP); ++} ++ ++void rtw8852a_iqk_track(struct rtw89_dev *rtwdev) ++{ ++ _iqk_track(rtwdev); ++} ++ ++void rtw8852a_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, ++ bool is_afe) ++{ ++ u16 tx_en; ++ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START); ++ rtw89_mac_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); ++ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); ++ ++ _rx_dck(rtwdev, phy_idx, is_afe); ++ ++ rtw89_mac_resume_sch_tx(rtwdev, phy_idx, tx_en); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); ++} ++ ++void rtw8852a_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) ++{ ++ u16 tx_en; ++ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START); ++ rtw89_mac_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); ++ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); ++ ++ rtwdev->dpk.is_dpk_enable = true; ++ rtwdev->dpk.is_dpk_reload_en = false; ++ _dpk(rtwdev, phy_idx, false); ++ ++ rtw89_mac_resume_sch_tx(rtwdev, phy_idx, tx_en); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP); ++} ++ ++void rtw8852a_dpk_track(struct rtw89_dev *rtwdev) ++{ ++ _dpk_track(rtwdev); ++} ++ ++void rtw8852a_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ u8 i; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", ++ __func__, phy); ++ ++ _tssi_disable(rtwdev, phy); ++ ++ for (i = RF_PATH_A; i < RF_PATH_NUM_8852A; i++) { ++ _tssi_rf_setting(rtwdev, phy, i); ++ _tssi_set_sys(rtwdev, phy); ++ _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i); ++ _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i); ++ _tssi_set_dck(rtwdev, phy, i); ++ _tssi_set_tmeter_tbl(rtwdev, phy, i); ++ _tssi_set_dac_gain_tbl(rtwdev, phy, i); ++ _tssi_slope_cal_org(rtwdev, phy, i); ++ _tssi_set_rf_gap_tbl(rtwdev, phy, i); ++ _tssi_set_slope(rtwdev, phy, i); ++ _tssi_pak(rtwdev, phy, i); ++ } ++ ++ _tssi_enable(rtwdev, phy); ++ _tssi_set_efuse_to_de(rtwdev, phy); ++ _tssi_high_power(rtwdev, phy); ++ _tssi_pre_tx(rtwdev, phy); ++} ++ ++void rtw8852a_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ u8 i; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", ++ __func__, phy); ++ ++ if (!rtwdev->is_tssi_mode[RF_PATH_A]) ++ return; ++ if (!rtwdev->is_tssi_mode[RF_PATH_B]) ++ return; ++ ++ _tssi_disable(rtwdev, phy); ++ ++ for (i = RF_PATH_A; i < RF_PATH_NUM_8852A; i++) { ++ _tssi_rf_setting(rtwdev, phy, i); ++ _tssi_set_sys(rtwdev, phy); ++ _tssi_set_tmeter_tbl(rtwdev, phy, i); ++ _tssi_pak(rtwdev, phy, i); ++ } ++ ++ _tssi_enable(rtwdev, phy); ++ _tssi_set_efuse_to_de(rtwdev, phy); ++} ++ ++void rtw8852a_tssi_track(struct rtw89_dev *rtwdev) ++{ ++ _tssi_track(rtwdev); ++} ++ ++static ++void _rtw8852a_tssi_avg_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) ++ return; ++ ++ /* disable */ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_disable_defs_tbl); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_AVG, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_AVG, 0x0); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_AVG, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_AVG, 0x0); ++ ++ /* enable */ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_enable_defs_ab_tbl); ++} ++ ++static ++void _rtw8852a_tssi_set_avg(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) ++ return; ++ ++ /* disable */ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_disable_defs_tbl); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_AVG, 0x4); ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_AVG, 0x2); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_AVG, 0x4); ++ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_AVG, 0x2); ++ ++ /* enable */ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_enable_defs_ab_tbl); ++} ++ ++static void rtw8852a_tssi_set_avg(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, bool enable) ++{ ++ if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) ++ return; ++ ++ if (enable) { ++ /* SCAN_START */ ++ _rtw8852a_tssi_avg_scan(rtwdev, phy); ++ } else { ++ /* SCAN_END */ ++ _rtw8852a_tssi_set_avg(rtwdev, phy); ++ } ++} ++ ++static void rtw8852a_tssi_default_txagc(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, bool enable) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 i; ++ ++ if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) ++ return; ++ ++ if (enable) { ++ if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, B_TXAGC_BB_OFT) != 0xc000 && ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, B_TXAGC_BB_OFT) != 0x0) { ++ for (i = 0; i < 6; i++) { ++ tssi_info->default_txagc_offset[RF_PATH_A] = ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, ++ B_TXAGC_BB); ++ if (tssi_info->default_txagc_offset[RF_PATH_A]) ++ break; ++ } ++ } ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, B_TXAGC_BB_S1_OFT) != 0xc000 && ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, B_TXAGC_BB_S1_OFT) != 0x0) { ++ for (i = 0; i < 6; i++) { ++ tssi_info->default_txagc_offset[RF_PATH_B] = ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, ++ B_TXAGC_BB_S1); ++ if (tssi_info->default_txagc_offset[RF_PATH_B]) ++ break; ++ } ++ } ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, ++ tssi_info->default_txagc_offset[RF_PATH_A]); ++ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT, ++ tssi_info->default_txagc_offset[RF_PATH_B]); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x1); ++ } ++} ++ ++void rtw8852a_wifi_scan_notify(struct rtw89_dev *rtwdev, ++ bool scan_start, enum rtw89_phy_idx phy_idx) ++{ ++ if (scan_start) { ++ rtw8852a_tssi_default_txagc(rtwdev, phy_idx, true); ++ rtw8852a_tssi_set_avg(rtwdev, phy_idx, true); ++ } else { ++ rtw8852a_tssi_default_txagc(rtwdev, phy_idx, false); ++ rtw8852a_tssi_set_avg(rtwdev, phy_idx, false); ++ } ++} +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h +new file mode 100644 +index 000000000000..ea36553a76b7 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h +@@ -0,0 +1,24 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_8852A_RFK_H__ ++#define __RTW89_8852A_RFK_H__ ++ ++#include "core.h" ++ ++void rtw8852a_rck(struct rtw89_dev *rtwdev); ++void rtw8852a_dack(struct rtw89_dev *rtwdev); ++void rtw8852a_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); ++void rtw8852a_iqk_track(struct rtw89_dev *rtwdev); ++void rtw8852a_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, ++ bool is_afe); ++void rtw8852a_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); ++void rtw8852a_dpk_track(struct rtw89_dev *rtwdev); ++void rtw8852a_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); ++void rtw8852a_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); ++void rtw8852a_tssi_track(struct rtw89_dev *rtwdev); ++void rtw8852a_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, ++ enum rtw89_phy_idx phy_idx); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.c +new file mode 100644 +index 000000000000..510570090502 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.c +@@ -0,0 +1,1607 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "rtw8852a_rfk_table.h" ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_sys_defs[] = { ++ DECL_RFK_WM(0x12a8, 0x00000001, 0x00000001), ++ DECL_RFK_WM(0x12a8, 0x0000000e, 0x00000002), ++ DECL_RFK_WM(0x32a8, 0x00000001, 0x00000001), ++ DECL_RFK_WM(0x32a8, 0x0000000e, 0x00000002), ++ DECL_RFK_WM(0x12bc, 0x000000f0, 0x00000005), ++ DECL_RFK_WM(0x12bc, 0x00000f00, 0x00000005), ++ DECL_RFK_WM(0x12bc, 0x000f0000, 0x00000005), ++ DECL_RFK_WM(0x12bc, 0x0000f000, 0x00000005), ++ DECL_RFK_WM(0x120c, 0x000000ff, 0x00000033), ++ DECL_RFK_WM(0x12c0, 0x0ff00000, 0x00000033), ++ DECL_RFK_WM(0x32bc, 0x000000f0, 0x00000005), ++ DECL_RFK_WM(0x32bc, 0x00000f00, 0x00000005), ++ DECL_RFK_WM(0x32bc, 0x000f0000, 0x00000005), ++ DECL_RFK_WM(0x32bc, 0x0000f000, 0x00000005), ++ DECL_RFK_WM(0x320c, 0x000000ff, 0x00000033), ++ DECL_RFK_WM(0x32c0, 0x0ff00000, 0x00000033), ++ DECL_RFK_WM(0x0300, 0xff000000, 0x00000019), ++ DECL_RFK_WM(0x0304, 0x000000ff, 0x00000019), ++ DECL_RFK_WM(0x0304, 0x0000ff00, 0x0000001d), ++ DECL_RFK_WM(0x0314, 0xffff0000, 0x00002044), ++ DECL_RFK_WM(0x0318, 0x0000ffff, 0x00002042), ++ DECL_RFK_WM(0x0318, 0xffff0000, 0x00002002), ++ DECL_RFK_WM(0x0020, 0x00006000, 0x00000003), ++ DECL_RFK_WM(0x0024, 0x00006000, 0x00000003), ++ DECL_RFK_WM(0x0704, 0xffff0000, 0x0000601e), ++ DECL_RFK_WM(0x2704, 0xffff0000, 0x0000601e), ++ DECL_RFK_WM(0x0700, 0xf0000000, 0x00000004), ++ DECL_RFK_WM(0x2700, 0xf0000000, 0x00000004), ++ DECL_RFK_WM(0x0650, 0x3c000000, 0x00000000), ++ DECL_RFK_WM(0x2650, 0x3c000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_sys_defs); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_sys_defs_2g[] = { ++ DECL_RFK_WM(0x120c, 0x000000ff, 0x00000033), ++ DECL_RFK_WM(0x12c0, 0x0ff00000, 0x00000033), ++ DECL_RFK_WM(0x32c0, 0x0ff00000, 0x00000033), ++ DECL_RFK_WM(0x320c, 0x000000ff, 0x00000033), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_sys_defs_2g); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_sys_defs_5g[] = { ++ DECL_RFK_WM(0x120c, 0x000000ff, 0x00000044), ++ DECL_RFK_WM(0x12c0, 0x0ff00000, 0x00000044), ++ DECL_RFK_WM(0x32c0, 0x0ff00000, 0x00000044), ++ DECL_RFK_WM(0x320c, 0x000000ff, 0x00000044), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_sys_defs_5g); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_defs_a[] = { ++ DECL_RFK_WM(0x5800, 0x000000ff, 0x0000007f), ++ DECL_RFK_WM(0x5800, 0x0000ff00, 0x00000080), ++ DECL_RFK_WM(0x5800, 0x003f0000, 0x0000003f), ++ DECL_RFK_WM(0x5800, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x5800, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x5800, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x5804, 0xf8000000, 0x00000000), ++ DECL_RFK_WM(0x580c, 0x0000007f, 0x00000040), ++ DECL_RFK_WM(0x580c, 0x00007f00, 0x00000040), ++ DECL_RFK_WM(0x580c, 0x00008000, 0x00000000), ++ DECL_RFK_WM(0x580c, 0x0fff0000, 0x00000000), ++ DECL_RFK_WM(0x5810, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x5810, 0x00000200, 0x00000000), ++ DECL_RFK_WM(0x5810, 0x0000fc00, 0x00000000), ++ DECL_RFK_WM(0x5810, 0x00010000, 0x00000001), ++ DECL_RFK_WM(0x5810, 0x00fe0000, 0x00000000), ++ DECL_RFK_WM(0x5810, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x5810, 0x06000000, 0x00000000), ++ DECL_RFK_WM(0x5810, 0x38000000, 0x00000003), ++ DECL_RFK_WM(0x5810, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x5810, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x00000c00, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x00001000, 0x00000001), ++ DECL_RFK_WM(0x5814, 0x00002000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x00004000, 0x00000001), ++ DECL_RFK_WM(0x5814, 0x00038000, 0x00000005), ++ DECL_RFK_WM(0x5814, 0x003c0000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x01c00000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x18000000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0xe0000000, 0x00000000), ++ DECL_RFK_WM(0x5818, 0x000000ff, 0x00000000), ++ DECL_RFK_WM(0x5818, 0x0001ff00, 0x00000018), ++ DECL_RFK_WM(0x5818, 0x03fe0000, 0x00000016), ++ DECL_RFK_WM(0x5818, 0xfc000000, 0x00000000), ++ DECL_RFK_WM(0x581c, 0x000003ff, 0x00000280), ++ DECL_RFK_WM(0x581c, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x581c, 0x00100000, 0x00000000), ++ DECL_RFK_WM(0x581c, 0x01e00000, 0x00000008), ++ DECL_RFK_WM(0x581c, 0x01e00000, 0x0000000e), ++ DECL_RFK_WM(0x581c, 0x1e000000, 0x00000008), ++ DECL_RFK_WM(0x581c, 0x1e000000, 0x0000000e), ++ DECL_RFK_WM(0x581c, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x5820, 0x00000fff, 0x00000080), ++ DECL_RFK_WM(0x5820, 0x0000f000, 0x0000000f), ++ DECL_RFK_WM(0x5820, 0x001f0000, 0x00000000), ++ DECL_RFK_WM(0x5820, 0xffe00000, 0x00000000), ++ DECL_RFK_WM(0x5824, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5824, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5828, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x582c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x582c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5830, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5834, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5834, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5838, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x583c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x583c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5840, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5844, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5844, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5848, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x584c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x584c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5850, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5854, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5854, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5858, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x585c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x585c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5860, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5828, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5828, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5830, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5830, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5838, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5838, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5840, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5840, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5848, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5848, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5850, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5850, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5858, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5858, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5860, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5860, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5860, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x5864, 0x000003ff, 0x000001ff), ++ DECL_RFK_WM(0x5864, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x5864, 0x03f00000, 0x00000000), ++ DECL_RFK_WM(0x5864, 0x04000000, 0x00000000), ++ DECL_RFK_WM(0x5898, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x589c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x58a0, 0x000000ff, 0x000000fd), ++ DECL_RFK_WM(0x58a0, 0x0000ff00, 0x000000e5), ++ DECL_RFK_WM(0x58a0, 0x00ff0000, 0x000000cd), ++ DECL_RFK_WM(0x58a0, 0xff000000, 0x000000b5), ++ DECL_RFK_WM(0x58a4, 0x000000ff, 0x00000016), ++ DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x03fe0000, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x58b0, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x58b4, 0x0000001f, 0x00000000), ++ DECL_RFK_WM(0x58b4, 0x00000020, 0x00000000), ++ DECL_RFK_WM(0x58b4, 0x000001c0, 0x00000000), ++ DECL_RFK_WM(0x58b4, 0x00000200, 0x00000000), ++ DECL_RFK_WM(0x58b4, 0x0000f000, 0x00000002), ++ DECL_RFK_WM(0x58b4, 0x00ff0000, 0x00000000), ++ DECL_RFK_WM(0x58b4, 0x7f000000, 0x0000000a), ++ DECL_RFK_WM(0x58b8, 0x0000007f, 0x00000028), ++ DECL_RFK_WM(0x58b8, 0x00007f00, 0x00000076), ++ DECL_RFK_WM(0x58b8, 0x007f0000, 0x00000000), ++ DECL_RFK_WM(0x58b8, 0x7f000000, 0x00000000), ++ DECL_RFK_WM(0x58bc, 0x000000ff, 0x0000007f), ++ DECL_RFK_WM(0x58bc, 0x0000ff00, 0x00000080), ++ DECL_RFK_WM(0x58bc, 0x00030000, 0x00000003), ++ DECL_RFK_WM(0x58bc, 0x000c0000, 0x00000001), ++ DECL_RFK_WM(0x58bc, 0x00300000, 0x00000002), ++ DECL_RFK_WM(0x58bc, 0x00c00000, 0x00000002), ++ DECL_RFK_WM(0x58bc, 0x07000000, 0x00000007), ++ DECL_RFK_WM(0x58c0, 0x00fe0000, 0x0000003f), ++ DECL_RFK_WM(0x58c0, 0xff000000, 0x00000000), ++ DECL_RFK_WM(0x58c4, 0x0003ffff, 0x0003ffff), ++ DECL_RFK_WM(0x58c4, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x58c4, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x58c8, 0x00ffffff, 0x00000000), ++ DECL_RFK_WM(0x58c8, 0xf0000000, 0x00000000), ++ DECL_RFK_WM(0x58cc, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x58d0, 0x00001fff, 0x00000101), ++ DECL_RFK_WM(0x58d0, 0x0001e000, 0x00000004), ++ DECL_RFK_WM(0x58d0, 0x03fe0000, 0x00000100), ++ DECL_RFK_WM(0x58d0, 0x04000000, 0x00000000), ++ DECL_RFK_WM(0x58d4, 0x000000ff, 0x00000000), ++ DECL_RFK_WM(0x58d4, 0x0003fe00, 0x000000ff), ++ DECL_RFK_WM(0x58d4, 0x07fc0000, 0x00000100), ++ DECL_RFK_WM(0x58d8, 0x000001ff, 0x0000016c), ++ DECL_RFK_WM(0x58d8, 0x0003fe00, 0x0000005c), ++ DECL_RFK_WM(0x58d8, 0x000c0000, 0x00000002), ++ DECL_RFK_WM(0x58d8, 0xfff00000, 0x00000800), ++ DECL_RFK_WM(0x58dc, 0x000000ff, 0x0000007f), ++ DECL_RFK_WM(0x58dc, 0x0000ff00, 0x00000080), ++ DECL_RFK_WM(0x58dc, 0x00010000, 0x00000000), ++ DECL_RFK_WM(0x58dc, 0x3ff00000, 0x00000000), ++ DECL_RFK_WM(0x58dc, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x58f0, 0x000001ff, 0x000001ff), ++ DECL_RFK_WM(0x58f0, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_defs_b[] = { ++ DECL_RFK_WM(0x7800, 0x000000ff, 0x0000007f), ++ DECL_RFK_WM(0x7800, 0x0000ff00, 0x00000080), ++ DECL_RFK_WM(0x7800, 0x003f0000, 0x0000003f), ++ DECL_RFK_WM(0x7800, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x7800, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x7800, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x7804, 0xf8000000, 0x00000000), ++ DECL_RFK_WM(0x780c, 0x0000007f, 0x00000040), ++ DECL_RFK_WM(0x780c, 0x00007f00, 0x00000040), ++ DECL_RFK_WM(0x780c, 0x00008000, 0x00000000), ++ DECL_RFK_WM(0x780c, 0x0fff0000, 0x00000000), ++ DECL_RFK_WM(0x7810, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x7810, 0x00000200, 0x00000000), ++ DECL_RFK_WM(0x7810, 0x0000fc00, 0x00000000), ++ DECL_RFK_WM(0x7810, 0x00010000, 0x00000001), ++ DECL_RFK_WM(0x7810, 0x00fe0000, 0x00000000), ++ DECL_RFK_WM(0x7810, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x7810, 0x06000000, 0x00000000), ++ DECL_RFK_WM(0x7810, 0x38000000, 0x00000003), ++ DECL_RFK_WM(0x7810, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x7810, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x00000c00, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x00001000, 0x00000001), ++ DECL_RFK_WM(0x7814, 0x00002000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x00004000, 0x00000001), ++ DECL_RFK_WM(0x7814, 0x00038000, 0x00000005), ++ DECL_RFK_WM(0x7814, 0x003c0000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x01c00000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x18000000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0xe0000000, 0x00000000), ++ DECL_RFK_WM(0x7818, 0x000000ff, 0x00000000), ++ DECL_RFK_WM(0x7818, 0x0001ff00, 0x00000018), ++ DECL_RFK_WM(0x7818, 0x03fe0000, 0x00000016), ++ DECL_RFK_WM(0x7818, 0xfc000000, 0x00000000), ++ DECL_RFK_WM(0x781c, 0x000003ff, 0x00000280), ++ DECL_RFK_WM(0x781c, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x781c, 0x00100000, 0x00000000), ++ DECL_RFK_WM(0x781c, 0x01e00000, 0x00000008), ++ DECL_RFK_WM(0x781c, 0x01e00000, 0x0000000e), ++ DECL_RFK_WM(0x781c, 0x1e000000, 0x00000008), ++ DECL_RFK_WM(0x781c, 0x1e000000, 0x0000000e), ++ DECL_RFK_WM(0x781c, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x7820, 0x00000fff, 0x00000080), ++ DECL_RFK_WM(0x7820, 0x0000f000, 0x00000000), ++ DECL_RFK_WM(0x7820, 0x001f0000, 0x00000000), ++ DECL_RFK_WM(0x7820, 0xffe00000, 0x00000000), ++ DECL_RFK_WM(0x7824, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7824, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7828, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x782c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x782c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7830, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7834, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7834, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7838, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x783c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x783c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7840, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7844, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7844, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7848, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x784c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x784c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7850, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7854, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7854, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7858, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x785c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x785c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7860, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7828, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7828, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7830, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7830, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7838, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7838, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7840, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7840, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7848, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7848, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7850, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7850, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7858, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7858, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7860, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7860, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7860, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x7864, 0x000003ff, 0x000001ff), ++ DECL_RFK_WM(0x7864, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x7864, 0x03f00000, 0x00000000), ++ DECL_RFK_WM(0x7864, 0x04000000, 0x00000000), ++ DECL_RFK_WM(0x7898, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x789c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x78a0, 0x000000ff, 0x000000fd), ++ DECL_RFK_WM(0x78a0, 0x0000ff00, 0x000000e5), ++ DECL_RFK_WM(0x78a0, 0x00ff0000, 0x000000cd), ++ DECL_RFK_WM(0x78a0, 0xff000000, 0x000000b5), ++ DECL_RFK_WM(0x78a4, 0x000000ff, 0x00000016), ++ DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x03fe0000, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x78b0, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x78b4, 0x0000001f, 0x00000000), ++ DECL_RFK_WM(0x78b4, 0x00000020, 0x00000000), ++ DECL_RFK_WM(0x78b4, 0x000001c0, 0x00000000), ++ DECL_RFK_WM(0x78b4, 0x00000200, 0x00000000), ++ DECL_RFK_WM(0x78b4, 0x0000f000, 0x00000002), ++ DECL_RFK_WM(0x78b4, 0x00ff0000, 0x00000000), ++ DECL_RFK_WM(0x78b4, 0x7f000000, 0x0000000a), ++ DECL_RFK_WM(0x78b8, 0x0000007f, 0x00000028), ++ DECL_RFK_WM(0x78b8, 0x00007f00, 0x00000076), ++ DECL_RFK_WM(0x78b8, 0x007f0000, 0x00000000), ++ DECL_RFK_WM(0x78b8, 0x7f000000, 0x00000000), ++ DECL_RFK_WM(0x78bc, 0x000000ff, 0x0000007f), ++ DECL_RFK_WM(0x78bc, 0x0000ff00, 0x00000080), ++ DECL_RFK_WM(0x78bc, 0x00030000, 0x00000003), ++ DECL_RFK_WM(0x78bc, 0x000c0000, 0x00000001), ++ DECL_RFK_WM(0x78bc, 0x00300000, 0x00000002), ++ DECL_RFK_WM(0x78bc, 0x00c00000, 0x00000002), ++ DECL_RFK_WM(0x78bc, 0x07000000, 0x00000007), ++ DECL_RFK_WM(0x78c0, 0x00fe0000, 0x0000003f), ++ DECL_RFK_WM(0x78c0, 0xff000000, 0x00000000), ++ DECL_RFK_WM(0x78c4, 0x0003ffff, 0x0003ffff), ++ DECL_RFK_WM(0x78c4, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x78c4, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x78c8, 0x00ffffff, 0x00000000), ++ DECL_RFK_WM(0x78c8, 0xf0000000, 0x00000000), ++ DECL_RFK_WM(0x78cc, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x78d0, 0x00001fff, 0x00000101), ++ DECL_RFK_WM(0x78d0, 0x0001e000, 0x00000004), ++ DECL_RFK_WM(0x78d0, 0x03fe0000, 0x00000100), ++ DECL_RFK_WM(0x78d0, 0x04000000, 0x00000000), ++ DECL_RFK_WM(0x78d4, 0x000000ff, 0x00000000), ++ DECL_RFK_WM(0x78d4, 0x0003fe00, 0x000000ff), ++ DECL_RFK_WM(0x78d4, 0x07fc0000, 0x00000100), ++ DECL_RFK_WM(0x78d8, 0x000001ff, 0x0000016c), ++ DECL_RFK_WM(0x78d8, 0x0003fe00, 0x0000005c), ++ DECL_RFK_WM(0x78d8, 0x000c0000, 0x00000002), ++ DECL_RFK_WM(0x78d8, 0xfff00000, 0x00000800), ++ DECL_RFK_WM(0x78dc, 0x000000ff, 0x0000007f), ++ DECL_RFK_WM(0x78dc, 0x0000ff00, 0x00000080), ++ DECL_RFK_WM(0x78dc, 0x00010000, 0x00000000), ++ DECL_RFK_WM(0x78dc, 0x3ff00000, 0x00000000), ++ DECL_RFK_WM(0x78dc, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x78f0, 0x000001ff, 0x000001ff), ++ DECL_RFK_WM(0x78f0, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_defs_2g[] = { ++ DECL_RFK_WM(0x58d8, 0x000001ff, 0x0000013c), ++ DECL_RFK_WM(0x78d8, 0x000001ff, 0x0000013c), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_defs_2g); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_defs_5g[] = { ++ DECL_RFK_WM(0x58d8, 0x000001ff, 0x0000016c), ++ DECL_RFK_WM(0x78d8, 0x000001ff, 0x0000016c), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_defs_5g); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_a[] = { ++ DECL_RFK_WM(0x58a0, 0xffffffff, 0x000000fc), ++ DECL_RFK_WM(0x58e4, 0x0000007f, 0x00000020), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_b[] = { ++ DECL_RFK_WM(0x78a0, 0xffffffff, 0x000000fc), ++ DECL_RFK_WM(0x78e4, 0x0000007f, 0x00000020), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_dck_defs_a[] = { ++ DECL_RFK_WM(0x580c, 0x0fff0000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x00001000, 0x00000001), ++ DECL_RFK_WM(0x5814, 0x00002000, 0x00000001), ++ DECL_RFK_WM(0x5814, 0x00004000, 0x00000001), ++ DECL_RFK_WM(0x5814, 0x00038000, 0x00000005), ++ DECL_RFK_WM(0x5814, 0x003c0000, 0x00000003), ++ DECL_RFK_WM(0x5814, 0x18000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_dck_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_dck_defs_b[] = { ++ DECL_RFK_WM(0x780c, 0x0fff0000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x00001000, 0x00000001), ++ DECL_RFK_WM(0x7814, 0x00002000, 0x00000001), ++ DECL_RFK_WM(0x7814, 0x00004000, 0x00000001), ++ DECL_RFK_WM(0x7814, 0x00038000, 0x00000005), ++ DECL_RFK_WM(0x7814, 0x003c0000, 0x00000003), ++ DECL_RFK_WM(0x7814, 0x18000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_dck_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_dac_gain_tbl_defs_a[] = { ++ DECL_RFK_WM(0x58b0, 0x00000fff, 0x00000000), ++ DECL_RFK_WM(0x58b0, 0x00000800, 0x00000001), ++ DECL_RFK_WM(0x5a00, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a04, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a08, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a0c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a10, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a14, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a18, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a1c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a20, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a24, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a28, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a2c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a30, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a34, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a38, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a3c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a40, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a44, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a48, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a4c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a50, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a54, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a58, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a5c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a60, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a64, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a68, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a6c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a70, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a74, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a78, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a7c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a80, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a84, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a88, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a8c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a90, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a94, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a98, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a9c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5aa0, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5aa4, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5aa8, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5aac, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5ab0, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5ab4, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5ab8, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5abc, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5ac0, 0xffffffff, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_dac_gain_tbl_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_dac_gain_tbl_defs_b[] = { ++ DECL_RFK_WM(0x78b0, 0x00000fff, 0x00000000), ++ DECL_RFK_WM(0x78b0, 0x00000800, 0x00000001), ++ DECL_RFK_WM(0x7a00, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a04, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a08, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a0c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a10, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a14, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a18, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a1c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a20, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a24, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a28, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a2c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a30, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a34, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a38, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a3c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a40, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a44, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a48, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a4c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a50, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a54, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a58, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a5c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a60, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a64, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a68, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a6c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a70, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a74, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a78, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a7c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a80, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a84, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a88, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a8c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a90, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a94, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a98, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a9c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7aa0, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7aa4, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7aa8, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7aac, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7ab0, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7ab4, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7ab8, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7abc, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7ac0, 0xffffffff, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_dac_gain_tbl_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_slope_cal_org_defs_a[] = { ++ DECL_RFK_WM(0x581c, 0x00100000, 0x00000000), ++ DECL_RFK_WM(0x58cc, 0x00001000, 0x00000001), ++ DECL_RFK_WM(0x58cc, 0x00000007, 0x00000000), ++ DECL_RFK_WM(0x58cc, 0x00000038, 0x00000001), ++ DECL_RFK_WM(0x58cc, 0x000001c0, 0x00000002), ++ DECL_RFK_WM(0x58cc, 0x00000e00, 0x00000003), ++ DECL_RFK_WM(0x5828, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x5898, 0x000000ff, 0x00000040), ++ DECL_RFK_WM(0x5830, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x5898, 0x0000ff00, 0x00000040), ++ DECL_RFK_WM(0x5838, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x5898, 0x00ff0000, 0x00000040), ++ DECL_RFK_WM(0x5840, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x5898, 0xff000000, 0x00000040), ++ DECL_RFK_WM(0x5848, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x589c, 0x000000ff, 0x00000040), ++ DECL_RFK_WM(0x5850, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x589c, 0x0000ff00, 0x00000040), ++ DECL_RFK_WM(0x5858, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x589c, 0x00ff0000, 0x00000040), ++ DECL_RFK_WM(0x5860, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x589c, 0xff000000, 0x00000040), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_slope_cal_org_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_slope_cal_org_defs_b[] = { ++ DECL_RFK_WM(0x781c, 0x00100000, 0x00000000), ++ DECL_RFK_WM(0x78cc, 0x00001000, 0x00000001), ++ DECL_RFK_WM(0x78cc, 0x00000007, 0x00000000), ++ DECL_RFK_WM(0x78cc, 0x00000038, 0x00000001), ++ DECL_RFK_WM(0x78cc, 0x000001c0, 0x00000002), ++ DECL_RFK_WM(0x78cc, 0x00000e00, 0x00000003), ++ DECL_RFK_WM(0x7828, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x7898, 0x000000ff, 0x00000040), ++ DECL_RFK_WM(0x7830, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x7898, 0x0000ff00, 0x00000040), ++ DECL_RFK_WM(0x7838, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x7898, 0x00ff0000, 0x00000040), ++ DECL_RFK_WM(0x7840, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x7898, 0xff000000, 0x00000040), ++ DECL_RFK_WM(0x7848, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x789c, 0x000000ff, 0x00000040), ++ DECL_RFK_WM(0x7850, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x789c, 0x0000ff00, 0x00000040), ++ DECL_RFK_WM(0x7878, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x789c, 0x00ff0000, 0x00000040), ++ DECL_RFK_WM(0x7860, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x789c, 0xff000000, 0x00000040), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_slope_cal_org_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_rf_gap_tbl_defs_a[] = { ++ DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x03fe0000, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x07fc0000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_rf_gap_tbl_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_rf_gap_tbl_defs_b[] = { ++ DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x03fe0000, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_rf_gap_tbl_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_slope_defs_a[] = { ++ DECL_RFK_WM(0x5820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x5818, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x00000800, 0x00000001), ++ DECL_RFK_WM(0x581c, 0x20000000, 0x00000001), ++ DECL_RFK_WM(0x5820, 0x0000f000, 0x00000001), ++ DECL_RFK_WM(0x581c, 0x000003ff, 0x00000280), ++ DECL_RFK_WM(0x581c, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x58b8, 0x007f0000, 0x00000000), ++ DECL_RFK_WM(0x58b8, 0x7f000000, 0x00000000), ++ DECL_RFK_WM(0x58b4, 0x7f000000, 0x0000000a), ++ DECL_RFK_WM(0x58b8, 0x0000007f, 0x00000028), ++ DECL_RFK_WM(0x58b8, 0x00007f00, 0x00000076), ++ DECL_RFK_WM(0x5810, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x20000000, 0x00000001), ++ DECL_RFK_WM(0x580c, 0x10000000, 0x00000001), ++ DECL_RFK_WM(0x580c, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x5838, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5858, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5834, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5834, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5838, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5854, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5854, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5858, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5824, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5824, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5828, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x582c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x582c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5830, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x583c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x583c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5840, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5844, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5844, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5848, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x584c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x584c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5850, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x585c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x585c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5860, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5828, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5830, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5840, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5848, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5850, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5860, 0x003ff000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_slope_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_slope_defs_b[] = { ++ DECL_RFK_WM(0x7820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x7818, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x00000800, 0x00000001), ++ DECL_RFK_WM(0x781c, 0x20000000, 0x00000001), ++ DECL_RFK_WM(0x7820, 0x0000f000, 0x00000001), ++ DECL_RFK_WM(0x781c, 0x000003ff, 0x00000280), ++ DECL_RFK_WM(0x781c, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x78b8, 0x007f0000, 0x00000000), ++ DECL_RFK_WM(0x78b8, 0x7f000000, 0x00000000), ++ DECL_RFK_WM(0x78b4, 0x7f000000, 0x0000000a), ++ DECL_RFK_WM(0x78b8, 0x0000007f, 0x00000028), ++ DECL_RFK_WM(0x78b8, 0x00007f00, 0x00000076), ++ DECL_RFK_WM(0x7810, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x20000000, 0x00000001), ++ DECL_RFK_WM(0x780c, 0x10000000, 0x00000001), ++ DECL_RFK_WM(0x780c, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x7838, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7858, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7834, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7834, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7838, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7854, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7854, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7858, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7824, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7824, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7828, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x782c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x782c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7830, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x783c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x783c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7840, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7844, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7844, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7848, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x784c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x784c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7850, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x785c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x785c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7860, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7828, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7830, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7840, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7848, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7850, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7860, 0x003ff000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_slope_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_track_defs_a[] = { ++ DECL_RFK_WM(0x5820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x5818, 0x18000000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x00000800, 0x00000000), ++ DECL_RFK_WM(0x581c, 0x20000000, 0x00000001), ++ DECL_RFK_WM(0x5864, 0x000003ff, 0x000001ff), ++ DECL_RFK_WM(0x5864, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x5820, 0x00000fff, 0x00000080), ++ DECL_RFK_WM(0x5814, 0x01000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_track_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_track_defs_b[] = { ++ DECL_RFK_WM(0x7820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x7818, 0x18000000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x00000800, 0x00000000), ++ DECL_RFK_WM(0x781c, 0x20000000, 0x00000001), ++ DECL_RFK_WM(0x7864, 0x000003ff, 0x000001ff), ++ DECL_RFK_WM(0x7864, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x7820, 0x00000fff, 0x00000080), ++ DECL_RFK_WM(0x7814, 0x01000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_track_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txagc_ofst_mv_avg_defs_a[] = { ++ DECL_RFK_WM(0x58e4, 0x00004000, 0x00000000), ++ DECL_RFK_WM(0x58e4, 0x00004000, 0x00000001), ++ DECL_RFK_WM(0x58e4, 0x00004000, 0x00000000), ++ DECL_RFK_WM(0x58e4, 0x00008000, 0x00000000), ++ DECL_RFK_WM(0x58e4, 0x000f0000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txagc_ofst_mv_avg_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txagc_ofst_mv_avg_defs_b[] = { ++ DECL_RFK_WM(0x78e4, 0x00004000, 0x00000000), ++ DECL_RFK_WM(0x78e4, 0x00004000, 0x00000001), ++ DECL_RFK_WM(0x78e4, 0x00004000, 0x00000000), ++ DECL_RFK_WM(0x78e4, 0x00008000, 0x00000000), ++ DECL_RFK_WM(0x78e4, 0x000f0000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txagc_ofst_mv_avg_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_a_2g[] = { ++ DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x03fe0000, 0x000001d0), ++ DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x0003fe00, 0x000001e8), ++ DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x000001ff, 0x0000000b), ++ DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x07fc0000, 0x00000088), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_a_2g); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_a_5g_1[] = { ++ DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x03fe0000, 0x000001d7), ++ DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x0003fe00, 0x000001fb), ++ DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000005), ++ DECL_RFK_WM(0x58ac, 0x07fc0000, 0x0000007c), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_a_5g_1); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_a_5g_3[] = { ++ DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x03fe0000, 0x000001d8), ++ DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x0003fe00, 0x000001fc), ++ DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000006), ++ DECL_RFK_WM(0x58ac, 0x07fc0000, 0x00000078), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_a_5g_3); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_a_5g_4[] = { ++ DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x03fe0000, 0x000001e5), ++ DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x0003fe00, 0x0000000a), ++ DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000011), ++ DECL_RFK_WM(0x58ac, 0x07fc0000, 0x00000075), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_a_5g_4); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_b_2g[] = { ++ DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x03fe0000, 0x000001cc), ++ DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x0003fe00, 0x000001e2), ++ DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000005), ++ DECL_RFK_WM(0x78ac, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000089), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_b_2g); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_b_5g_1[] = { ++ DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x03fe0000, 0x000001d5), ++ DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x0003fe00, 0x000001fc), ++ DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x0003fe00, 0x00000005), ++ DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000079), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_b_5g_1); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_b_5g_3[] = { ++ DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x03fe0000, 0x000001dc), ++ DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x0003fe00, 0x00000002), ++ DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x0003fe00, 0x0000000b), ++ DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000076), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_b_5g_3); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_b_5g_4[] = { ++ DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x03fe0000, 0x000001f0), ++ DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x0003fe00, 0x00000016), ++ DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x0003fe00, 0x0000001f), ++ DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000072), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_b_5g_4); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_enable_defs_a[] = { ++ DECL_RFK_WRF(0x0, 0x55, 0x00080, 0x00001), ++ DECL_RFK_WM(0x5818, 0x000000ff, 0x000000c0), ++ DECL_RFK_WM(0x5818, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x5818, 0x10000000, 0x00000001), ++ DECL_RFK_WM(0x5820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x5820, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x5818, 0x18000000, 0x00000003), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_enable_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_enable_defs_b[] = { ++ DECL_RFK_WRF(0x1, 0x55, 0x00080, 0x00001), ++ DECL_RFK_WM(0x7818, 0x000000ff, 0x000000c0), ++ DECL_RFK_WM(0x7818, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x7818, 0x10000000, 0x00000001), ++ DECL_RFK_WM(0x7820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x7820, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x7818, 0x18000000, 0x00000003), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_enable_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_disable_defs[] = { ++ DECL_RFK_WM(0x5820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x5818, 0x18000000, 0x00000001), ++ DECL_RFK_WM(0x7820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x7818, 0x18000000, 0x00000001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_disable_defs); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_enable_defs_ab[] = { ++ DECL_RFK_WM(0x5820, 0x80000000, 0x0), ++ DECL_RFK_WM(0x5820, 0x80000000, 0x1), ++ DECL_RFK_WM(0x5818, 0x18000000, 0x3), ++ DECL_RFK_WM(0x7820, 0x80000000, 0x0), ++ DECL_RFK_WM(0x7820, 0x80000000, 0x1), ++ DECL_RFK_WM(0x7818, 0x18000000, 0x3), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_enable_defs_ab); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_tracking_defs[] = { ++ DECL_RFK_WM(0x5800, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x58f0, 0x00080000, 0x00000000), ++ DECL_RFK_WM(0x5804, 0xf8000000, 0x00000000), ++ DECL_RFK_WM(0x58f0, 0xfff00000, 0x00000400), ++ DECL_RFK_WM(0x7800, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x78f0, 0x00080000, 0x00000000), ++ DECL_RFK_WM(0x7804, 0xf8000000, 0x00000000), ++ DECL_RFK_WM(0x78f0, 0xfff00000, 0x00000400), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_tracking_defs); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_afe_init_defs[] = { ++ DECL_RFK_WC(0x12ec, 0x00008000), ++ DECL_RFK_WS(0x12ec, 0x00008000), ++ DECL_RFK_WC(0x5e00, 0x00000001), ++ DECL_RFK_WS(0x5e00, 0x00000001), ++ DECL_RFK_WC(0x32ec, 0x00008000), ++ DECL_RFK_WS(0x32ec, 0x00008000), ++ DECL_RFK_WC(0x7e00, 0x00000001), ++ DECL_RFK_WS(0x7e00, 0x00000001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_afe_init_defs); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_reload_defs_a[] = { ++ DECL_RFK_WS(0x5e00, 0x00000008), ++ DECL_RFK_WS(0x5e50, 0x00000008), ++ DECL_RFK_WS(0x5e10, 0x80000000), ++ DECL_RFK_WS(0x5e60, 0x80000000), ++ DECL_RFK_WC(0x5e00, 0x00000008), ++ DECL_RFK_WC(0x5e50, 0x00000008), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_reload_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_reload_defs_b[] = { ++ DECL_RFK_WS(0x7e00, 0x00000008), ++ DECL_RFK_WS(0x7e50, 0x00000008), ++ DECL_RFK_WS(0x7e10, 0x80000000), ++ DECL_RFK_WS(0x7e60, 0x80000000), ++ DECL_RFK_WC(0x7e00, 0x00000008), ++ DECL_RFK_WC(0x7e50, 0x00000008), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_reload_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_check_addc_defs_a[] = { ++ DECL_RFK_WC(0x20f4, 0x01000000), ++ DECL_RFK_WS(0x20f8, 0x80000000), ++ DECL_RFK_WM(0x20f0, 0x00ff0000, 0x00000001), ++ DECL_RFK_WM(0x20f0, 0x00000f00, 0x00000002), ++ DECL_RFK_WC(0x20f0, 0x0000000f), ++ DECL_RFK_WM(0x20f0, 0x000000c0, 0x00000002), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_check_addc_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_check_addc_defs_b[] = { ++ DECL_RFK_WC(0x20f4, 0x01000000), ++ DECL_RFK_WS(0x20f8, 0x80000000), ++ DECL_RFK_WM(0x20f0, 0x00ff0000, 0x00000001), ++ DECL_RFK_WM(0x20f0, 0x00000f00, 0x00000002), ++ DECL_RFK_WC(0x20f0, 0x0000000f), ++ DECL_RFK_WM(0x20f0, 0x000000c0, 0x00000003), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_check_addc_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_addck_reset_defs_a[] = { ++ DECL_RFK_WC(0x12d8, 0x00000030), ++ DECL_RFK_WC(0x32d8, 0x00000030), ++ DECL_RFK_WS(0x12b8, 0x40000000), ++ DECL_RFK_WC(0x032c, 0x40000000), ++ DECL_RFK_WC(0x032c, 0x00400000), ++ DECL_RFK_WS(0x032c, 0x00400000), ++ DECL_RFK_WS(0x030c, 0x0f000000), ++ DECL_RFK_WC(0x032c, 0x00010000), ++ DECL_RFK_WS(0x12dc, 0x00000002), ++ DECL_RFK_WM(0x030c, 0x0f000000, 0x00000003), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_addck_reset_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_addck_trigger_defs_a[] = { ++ DECL_RFK_WS(0x12d8, 0x000000c0), ++ DECL_RFK_WS(0x12d8, 0x00000800), ++ DECL_RFK_WC(0x12d8, 0x00000800), ++ DECL_RFK_DELAY(1), ++ DECL_RFK_WM(0x12d8, 0x00000300, 0x00000001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_addck_trigger_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_addck_restore_defs_a[] = { ++ DECL_RFK_WC(0x12dc, 0x00000002), ++ DECL_RFK_WS(0x032c, 0x00010000), ++ DECL_RFK_WM(0x030c, 0x0f000000, 0x0000000c), ++ DECL_RFK_WS(0x032c, 0x40000000), ++ DECL_RFK_WC(0x12b8, 0x40000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_addck_restore_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_addck_reset_defs_b[] = { ++ DECL_RFK_WS(0x32b8, 0x40000000), ++ DECL_RFK_WC(0x032c, 0x40000000), ++ DECL_RFK_WC(0x032c, 0x00400000), ++ DECL_RFK_WS(0x032c, 0x00400000), ++ DECL_RFK_WS(0x030c, 0x0f000000), ++ DECL_RFK_WC(0x032c, 0x00010000), ++ DECL_RFK_WS(0x32dc, 0x00000002), ++ DECL_RFK_WM(0x030c, 0x0f000000, 0x00000003), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_addck_reset_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_addck_trigger_defs_b[] = { ++ DECL_RFK_WS(0x32d8, 0x000000c0), ++ DECL_RFK_WS(0x32d8, 0x00000800), ++ DECL_RFK_WC(0x32d8, 0x00000800), ++ DECL_RFK_DELAY(1), ++ DECL_RFK_WM(0x32d8, 0x00000300, 0x00000001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_addck_trigger_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_addck_restore_defs_b[] = { ++ DECL_RFK_WC(0x32dc, 0x00000002), ++ DECL_RFK_WS(0x032c, 0x00010000), ++ DECL_RFK_WM(0x030c, 0x0f000000, 0x0000000c), ++ DECL_RFK_WS(0x032c, 0x40000000), ++ DECL_RFK_WC(0x32b8, 0x40000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_addck_restore_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_check_dadc_defs_f_a[] = { ++ DECL_RFK_WC(0x032c, 0x40000000), ++ DECL_RFK_WS(0x030c, 0x0f000000), ++ DECL_RFK_WM(0x030c, 0x0f000000, 0x00000003), ++ DECL_RFK_WC(0x032c, 0x00010000), ++ DECL_RFK_WS(0x12dc, 0x00000001), ++ DECL_RFK_WS(0x12e8, 0x00000004), ++ DECL_RFK_WRF(0x0, 0x8f, 0x02000, 0x00001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_check_dadc_defs_f_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_check_dadc_defs_f_b[] = { ++ DECL_RFK_WC(0x032c, 0x40000000), ++ DECL_RFK_WS(0x030c, 0x0f000000), ++ DECL_RFK_WM(0x030c, 0x0f000000, 0x00000003), ++ DECL_RFK_WC(0x032c, 0x00010000), ++ DECL_RFK_WS(0x32dc, 0x00000001), ++ DECL_RFK_WS(0x32e8, 0x00000004), ++ DECL_RFK_WRF(0x1, 0x8f, 0x02000, 0x00001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_check_dadc_defs_f_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_check_dadc_defs_r_a[] = { ++ DECL_RFK_WC(0x12dc, 0x00000001), ++ DECL_RFK_WC(0x12e8, 0x00000004), ++ DECL_RFK_WRF(0x0, 0x8f, 0x02000, 0x00000), ++ DECL_RFK_WM(0x032c, 0x00010000, 0x00000001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_check_dadc_defs_r_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_check_dadc_defs_r_b[] = { ++ DECL_RFK_WC(0x32dc, 0x00000001), ++ DECL_RFK_WC(0x32e8, 0x00000004), ++ DECL_RFK_WRF(0x1, 0x8f, 0x02000, 0x00000), ++ DECL_RFK_WM(0x032c, 0x00010000, 0x00000001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_check_dadc_defs_r_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_f_a[] = { ++ DECL_RFK_WS(0x5e00, 0x00000008), ++ DECL_RFK_WC(0x5e10, 0x80000000), ++ DECL_RFK_WS(0x5e50, 0x00000008), ++ DECL_RFK_WC(0x5e60, 0x80000000), ++ DECL_RFK_WS(0x12a0, 0x00008000), ++ DECL_RFK_WM(0x12a0, 0x00007000, 0x00000003), ++ DECL_RFK_WS(0x12b8, 0x40000000), ++ DECL_RFK_WS(0x030c, 0x10000000), ++ DECL_RFK_WC(0x032c, 0x80000000), ++ DECL_RFK_WS(0x12e0, 0x00010000), ++ DECL_RFK_WS(0x12e4, 0x0c000000), ++ DECL_RFK_WM(0x5e00, 0x03ff0000, 0x00000030), ++ DECL_RFK_WM(0x5e50, 0x03ff0000, 0x00000030), ++ DECL_RFK_WC(0x5e00, 0x0c000000), ++ DECL_RFK_WC(0x5e50, 0x0c000000), ++ DECL_RFK_WC(0x5e0c, 0x00000008), ++ DECL_RFK_WC(0x5e5c, 0x00000008), ++ DECL_RFK_WS(0x5e0c, 0x00000001), ++ DECL_RFK_WS(0x5e5c, 0x00000001), ++ DECL_RFK_DELAY(1), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_f_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_m_a[] = { ++ DECL_RFK_WC(0x12e4, 0x0c000000), ++ DECL_RFK_WS(0x5e0c, 0x00000008), ++ DECL_RFK_WS(0x5e5c, 0x00000008), ++ DECL_RFK_DELAY(1), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_m_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_r_a[] = { ++ DECL_RFK_WC(0x5e0c, 0x00000001), ++ DECL_RFK_WC(0x5e5c, 0x00000001), ++ DECL_RFK_WC(0x12e0, 0x00010000), ++ DECL_RFK_WC(0x12a0, 0x00008000), ++ DECL_RFK_WS(0x12a0, 0x00007000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_r_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_f_b[] = { ++ DECL_RFK_WS(0x7e00, 0x00000008), ++ DECL_RFK_WC(0x7e10, 0x80000000), ++ DECL_RFK_WS(0x7e50, 0x00000008), ++ DECL_RFK_WC(0x7e60, 0x80000000), ++ DECL_RFK_WS(0x32a0, 0x00008000), ++ DECL_RFK_WM(0x32a0, 0x00007000, 0x00000003), ++ DECL_RFK_WS(0x32b8, 0x40000000), ++ DECL_RFK_WS(0x030c, 0x10000000), ++ DECL_RFK_WC(0x032c, 0x80000000), ++ DECL_RFK_WS(0x32e0, 0x00010000), ++ DECL_RFK_WS(0x32e4, 0x0c000000), ++ DECL_RFK_WM(0x7e00, 0x03ff0000, 0x00000030), ++ DECL_RFK_WM(0x7e50, 0x03ff0000, 0x00000030), ++ DECL_RFK_WC(0x7e00, 0x0c000000), ++ DECL_RFK_WC(0x7e50, 0x0c000000), ++ DECL_RFK_WC(0x7e0c, 0x00000008), ++ DECL_RFK_WC(0x7e5c, 0x00000008), ++ DECL_RFK_WS(0x7e0c, 0x00000001), ++ DECL_RFK_WS(0x7e5c, 0x00000001), ++ DECL_RFK_DELAY(1), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_f_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_m_b[] = { ++ DECL_RFK_WC(0x32e4, 0x0c000000), ++ DECL_RFK_WM(0x7e0c, 0x00000008, 0x00000001), ++ DECL_RFK_WM(0x7e5c, 0x00000008, 0x00000001), ++ DECL_RFK_DELAY(1), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_m_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_r_b[] = { ++ DECL_RFK_WC(0x7e0c, 0x00000001), ++ DECL_RFK_WC(0x7e5c, 0x00000001), ++ DECL_RFK_WC(0x32e0, 0x00010000), ++ DECL_RFK_WC(0x32a0, 0x00008000), ++ DECL_RFK_WS(0x32a0, 0x00007000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_r_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_sf_defs_a[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000101), ++ DECL_RFK_WS(0x12b8, 0x40000000), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000041), ++ DECL_RFK_WS(0x12b8, 0x10000000), ++ DECL_RFK_WS(0x58c8, 0x01000000), ++ DECL_RFK_WS(0x5864, 0xc0000000), ++ DECL_RFK_WS(0x2008, 0x01ffffff), ++ DECL_RFK_WS(0x0c1c, 0x00000004), ++ DECL_RFK_WS(0x0700, 0x08000000), ++ DECL_RFK_WS(0x0c70, 0x000003ff), ++ DECL_RFK_WS(0x0c60, 0x00000003), ++ DECL_RFK_WS(0x0c6c, 0x00000001), ++ DECL_RFK_WS(0x58ac, 0x08000000), ++ DECL_RFK_WS(0x0c3c, 0x00000200), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_sf_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_sr_defs_a[] = { ++ DECL_RFK_WS(0x4490, 0x80000000), ++ DECL_RFK_WS(0x12a0, 0x00007000), ++ DECL_RFK_WS(0x12a0, 0x00008000), ++ DECL_RFK_WM(0x12a0, 0x00070000, 0x00000003), ++ DECL_RFK_WS(0x12a0, 0x00080000), ++ DECL_RFK_WS(0x0700, 0x01000000), ++ DECL_RFK_WM(0x0700, 0x06000000, 0x00000002), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00001111), ++ DECL_RFK_WM(0x58f0, 0x00080000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_sr_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_sf_defs_b[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000202), ++ DECL_RFK_WS(0x32b8, 0x40000000), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000041), ++ DECL_RFK_WS(0x32b8, 0x10000000), ++ DECL_RFK_WS(0x78c8, 0x01000000), ++ DECL_RFK_WS(0x7864, 0xc0000000), ++ DECL_RFK_WS(0x2008, 0x01ffffff), ++ DECL_RFK_WS(0x2c1c, 0x00000004), ++ DECL_RFK_WS(0x2700, 0x08000000), ++ DECL_RFK_WS(0x0c70, 0x000003ff), ++ DECL_RFK_WS(0x0c60, 0x00000003), ++ DECL_RFK_WS(0x0c6c, 0x00000001), ++ DECL_RFK_WS(0x78ac, 0x08000000), ++ DECL_RFK_WS(0x2c3c, 0x00000200), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_sf_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_sr_defs_b[] = { ++ DECL_RFK_WS(0x6490, 0x80000000), ++ DECL_RFK_WS(0x32a0, 0x00007000), ++ DECL_RFK_WS(0x32a0, 0x00008000), ++ DECL_RFK_WM(0x32a0, 0x00070000, 0x00000003), ++ DECL_RFK_WS(0x32a0, 0x00080000), ++ DECL_RFK_WS(0x2700, 0x01000000), ++ DECL_RFK_WM(0x2700, 0x06000000, 0x00000002), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00002222), ++ DECL_RFK_WM(0x78f0, 0x00080000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_sr_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_s_defs_ab[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000303), ++ DECL_RFK_WS(0x12b8, 0x40000000), ++ DECL_RFK_WS(0x32b8, 0x40000000), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000041), ++ DECL_RFK_WS(0x12b8, 0x10000000), ++ DECL_RFK_WS(0x58c8, 0x01000000), ++ DECL_RFK_WS(0x78c8, 0x01000000), ++ DECL_RFK_WS(0x5864, 0xc0000000), ++ DECL_RFK_WS(0x7864, 0xc0000000), ++ DECL_RFK_WS(0x2008, 0x01ffffff), ++ DECL_RFK_WS(0x0c1c, 0x00000004), ++ DECL_RFK_WS(0x0700, 0x08000000), ++ DECL_RFK_WS(0x0c70, 0x000003ff), ++ DECL_RFK_WS(0x0c60, 0x00000003), ++ DECL_RFK_WS(0x0c6c, 0x00000001), ++ DECL_RFK_WS(0x58ac, 0x08000000), ++ DECL_RFK_WS(0x78ac, 0x08000000), ++ DECL_RFK_WS(0x0c3c, 0x00000200), ++ DECL_RFK_WS(0x2344, 0x80000000), ++ DECL_RFK_WS(0x4490, 0x80000000), ++ DECL_RFK_WS(0x12a0, 0x00007000), ++ DECL_RFK_WS(0x12a0, 0x00008000), ++ DECL_RFK_WM(0x12a0, 0x00070000, 0x00000003), ++ DECL_RFK_WS(0x12a0, 0x00080000), ++ DECL_RFK_WM(0x32a0, 0x00070000, 0x00000003), ++ DECL_RFK_WS(0x32a0, 0x00080000), ++ DECL_RFK_WS(0x0700, 0x01000000), ++ DECL_RFK_WM(0x0700, 0x06000000, 0x00000002), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00003333), ++ DECL_RFK_WM(0x58f0, 0x00080000, 0x00000000), ++ DECL_RFK_WM(0x78f0, 0x00080000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_s_defs_ab); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_r_defs_a[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000101), ++ DECL_RFK_WC(0x12b8, 0x40000000), ++ DECL_RFK_WC(0x5864, 0xc0000000), ++ DECL_RFK_WC(0x2008, 0x01ffffff), ++ DECL_RFK_WC(0x0c1c, 0x00000004), ++ DECL_RFK_WC(0x0700, 0x08000000), ++ DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), ++ DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), ++ DECL_RFK_WC(0x12a0, 0x000ff000), ++ DECL_RFK_WC(0x0700, 0x07000000), ++ DECL_RFK_WC(0x5864, 0x20000000), ++ DECL_RFK_WC(0x0c3c, 0x00000200), ++ DECL_RFK_WC(0x20fc, 0xffff0000), ++ DECL_RFK_WC(0x58c8, 0x01000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_r_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_r_defs_b[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000202), ++ DECL_RFK_WC(0x32b8, 0x40000000), ++ DECL_RFK_WC(0x7864, 0xc0000000), ++ DECL_RFK_WC(0x2008, 0x01ffffff), ++ DECL_RFK_WC(0x2c1c, 0x00000004), ++ DECL_RFK_WC(0x2700, 0x08000000), ++ DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), ++ DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), ++ DECL_RFK_WC(0x32a0, 0x000ff000), ++ DECL_RFK_WC(0x2700, 0x07000000), ++ DECL_RFK_WC(0x7864, 0x20000000), ++ DECL_RFK_WC(0x2c3c, 0x00000200), ++ DECL_RFK_WC(0x20fc, 0xffff0000), ++ DECL_RFK_WC(0x78c8, 0x01000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_r_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_r_defs_ab[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000303), ++ DECL_RFK_WC(0x12b8, 0x40000000), ++ DECL_RFK_WC(0x32b8, 0x40000000), ++ DECL_RFK_WC(0x5864, 0xc0000000), ++ DECL_RFK_WC(0x7864, 0xc0000000), ++ DECL_RFK_WC(0x2008, 0x01ffffff), ++ DECL_RFK_WC(0x0c1c, 0x00000004), ++ DECL_RFK_WC(0x0700, 0x08000000), ++ DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), ++ DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), ++ DECL_RFK_WC(0x12a0, 0x000ff000), ++ DECL_RFK_WC(0x32a0, 0x000ff000), ++ DECL_RFK_WC(0x0700, 0x07000000), ++ DECL_RFK_WC(0x5864, 0x20000000), ++ DECL_RFK_WC(0x7864, 0x20000000), ++ DECL_RFK_WC(0x0c3c, 0x00000200), ++ DECL_RFK_WC(0x20fc, 0xffff0000), ++ DECL_RFK_WC(0x58c8, 0x01000000), ++ DECL_RFK_WC(0x78c8, 0x01000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_r_defs_ab); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_lbk_rxiqk_defs_f[] = { ++ DECL_RFK_WM(0x030c, 0xff000000, 0x0000000f), ++ DECL_RFK_DELAY(1), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000003), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x0000a001), ++ DECL_RFK_DELAY(1), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x0000a041), ++ DECL_RFK_WS(0x8074, 0x80000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_lbk_rxiqk_defs_f); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_lbk_rxiqk_defs_r[] = { ++ DECL_RFK_WC(0x8074, 0x80000000), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x0000001f), ++ DECL_RFK_DELAY(1), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000001), ++ DECL_RFK_DELAY(1), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000041), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000303), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00003333), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_lbk_rxiqk_defs_r); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_pas_read_defs[] = { ++ DECL_RFK_WM(0x80d4, 0x00ff0000, 0x00000006), ++ DECL_RFK_WC(0x80bc, 0x00004000), ++ DECL_RFK_WM(0x80c0, 0x00ff0000, 0x00000008), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_pas_read_defs); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_iqk_set_defs_nondbcc_path01[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000303), ++ DECL_RFK_WM(0x5864, 0x18000000, 0x00000003), ++ DECL_RFK_WM(0x7864, 0x18000000, 0x00000003), ++ DECL_RFK_WM(0x12b8, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x32b8, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000001), ++ DECL_RFK_WM(0x12b8, 0x10000000, 0x00000001), ++ DECL_RFK_WM(0x58c8, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x78c8, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x5864, 0xc0000000, 0x00000003), ++ DECL_RFK_WM(0x7864, 0xc0000000, 0x00000003), ++ DECL_RFK_WM(0x2008, 0x01ffffff, 0x01ffffff), ++ DECL_RFK_WM(0x0c1c, 0x00000004, 0x00000001), ++ DECL_RFK_WM(0x0700, 0x08000000, 0x00000001), ++ DECL_RFK_WM(0x0c70, 0x000003ff, 0x000003ff), ++ DECL_RFK_WM(0x0c60, 0x00000003, 0x00000003), ++ DECL_RFK_WM(0x0c6c, 0x00000001, 0x00000001), ++ DECL_RFK_WM(0x58ac, 0x08000000, 0x00000001), ++ DECL_RFK_WM(0x78ac, 0x08000000, 0x00000001), ++ DECL_RFK_WM(0x0c3c, 0x00000200, 0x00000001), ++ DECL_RFK_WM(0x2344, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x4490, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x12a0, 0x00007000, 0x00000007), ++ DECL_RFK_WM(0x12a0, 0x00008000, 0x00000001), ++ DECL_RFK_WM(0x12a0, 0x00070000, 0x00000003), ++ DECL_RFK_WM(0x12a0, 0x00080000, 0x00000001), ++ DECL_RFK_WM(0x32a0, 0x00070000, 0x00000003), ++ DECL_RFK_WM(0x32a0, 0x00080000, 0x00000001), ++ DECL_RFK_WM(0x0700, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x0700, 0x06000000, 0x00000002), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00003333), ++ DECL_RFK_WM(0x58f0, 0x00080000, 0x00000000), ++ DECL_RFK_WM(0x78f0, 0x00080000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_iqk_set_defs_nondbcc_path01); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_iqk_set_defs_dbcc_path0[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000101), ++ DECL_RFK_WM(0x5864, 0x18000000, 0x00000003), ++ DECL_RFK_WM(0x7864, 0x18000000, 0x00000003), ++ DECL_RFK_WM(0x12b8, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000001), ++ DECL_RFK_WM(0x12b8, 0x10000000, 0x00000001), ++ DECL_RFK_WM(0x58c8, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x5864, 0xc0000000, 0x00000003), ++ DECL_RFK_WM(0x2008, 0x01ffffff, 0x01ffffff), ++ DECL_RFK_WM(0x0c1c, 0x00000004, 0x00000001), ++ DECL_RFK_WM(0x0700, 0x08000000, 0x00000001), ++ DECL_RFK_WM(0x0c70, 0x000003ff, 0x000003ff), ++ DECL_RFK_WM(0x0c60, 0x00000003, 0x00000003), ++ DECL_RFK_WM(0x0c6c, 0x00000001, 0x00000001), ++ DECL_RFK_WM(0x58ac, 0x08000000, 0x00000001), ++ DECL_RFK_WM(0x0c3c, 0x00000200, 0x00000001), ++ DECL_RFK_WM(0x2320, 0x00000001, 0x00000001), ++ DECL_RFK_WM(0x4490, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x12a0, 0x00007000, 0x00000007), ++ DECL_RFK_WM(0x12a0, 0x00008000, 0x00000001), ++ DECL_RFK_WM(0x12a0, 0x00070000, 0x00000003), ++ DECL_RFK_WM(0x12a0, 0x00080000, 0x00000001), ++ DECL_RFK_WM(0x0700, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x0700, 0x06000000, 0x00000002), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00001111), ++ DECL_RFK_WM(0x58f0, 0x00080000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_iqk_set_defs_dbcc_path0); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_iqk_set_defs_dbcc_path1[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000202), ++ DECL_RFK_WM(0x7864, 0x18000000, 0x00000003), ++ DECL_RFK_WM(0x32b8, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000001), ++ DECL_RFK_WM(0x32b8, 0x10000000, 0x00000001), ++ DECL_RFK_WM(0x78c8, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x7864, 0xc0000000, 0x00000003), ++ DECL_RFK_WM(0x2008, 0x01ffffff, 0x01ffffff), ++ DECL_RFK_WM(0x2c1c, 0x00000004, 0x00000001), ++ DECL_RFK_WM(0x2700, 0x08000000, 0x00000001), ++ DECL_RFK_WM(0x0c70, 0x000003ff, 0x000003ff), ++ DECL_RFK_WM(0x0c60, 0x00000003, 0x00000003), ++ DECL_RFK_WM(0x0c6c, 0x00000001, 0x00000001), ++ DECL_RFK_WM(0x78ac, 0x08000000, 0x00000001), ++ DECL_RFK_WM(0x2c3c, 0x00000200, 0x00000001), ++ DECL_RFK_WM(0x6490, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x32a0, 0x00007000, 0x00000007), ++ DECL_RFK_WM(0x32a0, 0x00008000, 0x00000001), ++ DECL_RFK_WM(0x32a0, 0x00070000, 0x00000003), ++ DECL_RFK_WM(0x32a0, 0x00080000, 0x00000001), ++ DECL_RFK_WM(0x2700, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x2700, 0x06000000, 0x00000002), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00002222), ++ DECL_RFK_WM(0x78f0, 0x00080000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_iqk_set_defs_dbcc_path1); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_iqk_restore_defs_nondbcc_path01[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000303), ++ DECL_RFK_WM(0x12b8, 0x40000000, 0x00000000), ++ DECL_RFK_WM(0x32b8, 0x40000000, 0x00000000), ++ DECL_RFK_WM(0x5864, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x7864, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x2008, 0x01ffffff, 0x00000000), ++ DECL_RFK_WM(0x0c1c, 0x00000004, 0x00000000), ++ DECL_RFK_WM(0x0700, 0x08000000, 0x00000000), ++ DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), ++ DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), ++ DECL_RFK_WM(0x12a0, 0x000ff000, 0x00000000), ++ DECL_RFK_WM(0x32a0, 0x000ff000, 0x00000000), ++ DECL_RFK_WM(0x0700, 0x07000000, 0x00000000), ++ DECL_RFK_WM(0x5864, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x7864, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x0c3c, 0x00000200, 0x00000000), ++ DECL_RFK_WM(0x2320, 0x00000001, 0x00000000), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000000), ++ DECL_RFK_WM(0x58c8, 0x01000000, 0x00000000), ++ DECL_RFK_WM(0x78c8, 0x01000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_iqk_restore_defs_nondbcc_path01); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_iqk_restore_defs_dbcc_path0[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000101), ++ DECL_RFK_WM(0x12b8, 0x40000000, 0x00000000), ++ DECL_RFK_WM(0x5864, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x2008, 0x01ffffff, 0x00000000), ++ DECL_RFK_WM(0x0c1c, 0x00000004, 0x00000000), ++ DECL_RFK_WM(0x0700, 0x08000000, 0x00000000), ++ DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), ++ DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), ++ DECL_RFK_WM(0x12a0, 0x000ff000, 0x00000000), ++ DECL_RFK_WM(0x0700, 0x07000000, 0x00000000), ++ DECL_RFK_WM(0x5864, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x0c3c, 0x00000200, 0x00000000), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000000), ++ DECL_RFK_WM(0x58c8, 0x01000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_iqk_restore_defs_dbcc_path0); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_iqk_restore_defs_dbcc_path1[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000202), ++ DECL_RFK_WM(0x32b8, 0x40000000, 0x00000000), ++ DECL_RFK_WM(0x7864, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x2008, 0x01ffffff, 0x00000000), ++ DECL_RFK_WM(0x2c1c, 0x00000004, 0x00000000), ++ DECL_RFK_WM(0x2700, 0x08000000, 0x00000000), ++ DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), ++ DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), ++ DECL_RFK_WM(0x32a0, 0x000ff000, 0x00000000), ++ DECL_RFK_WM(0x2700, 0x07000000, 0x00000000), ++ DECL_RFK_WM(0x7864, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x2c3c, 0x00000200, 0x00000000), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000000), ++ DECL_RFK_WM(0x78c8, 0x01000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_iqk_restore_defs_dbcc_path1); +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.h +new file mode 100644 +index 000000000000..4a4a45d778ff +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.h +@@ -0,0 +1,133 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_8852A_RFK_TABLE_H__ ++#define __RTW89_8852A_RFK_TABLE_H__ ++ ++#include "core.h" ++ ++enum rtw89_rfk_flag { ++ RTW89_RFK_F_WRF = 0, ++ RTW89_RFK_F_WM = 1, ++ RTW89_RFK_F_WS = 2, ++ RTW89_RFK_F_WC = 3, ++ RTW89_RFK_F_DELAY = 4, ++ RTW89_RFK_F_NUM, ++}; ++ ++struct rtw89_rfk_tbl { ++ const struct rtw89_reg5_def *defs; ++ u32 size; ++}; ++ ++#define DECLARE_RFK_TBL(_name) \ ++const struct rtw89_rfk_tbl _name ## _tbl = { \ ++ .defs = _name, \ ++ .size = ARRAY_SIZE(_name), \ ++} ++ ++#define DECL_RFK_WRF(_path, _addr, _mask, _data) \ ++ {.flag = RTW89_RFK_F_WRF, \ ++ .path = _path, \ ++ .addr = _addr, \ ++ .mask = _mask, \ ++ .data = _data,} ++ ++#define DECL_RFK_WM(_addr, _mask, _data) \ ++ {.flag = RTW89_RFK_F_WM, \ ++ .addr = _addr, \ ++ .mask = _mask, \ ++ .data = _data,} ++ ++#define DECL_RFK_WS(_addr, _mask) \ ++ {.flag = RTW89_RFK_F_WS, \ ++ .addr = _addr, \ ++ .mask = _mask,} ++ ++#define DECL_RFK_WC(_addr, _mask) \ ++ {.flag = RTW89_RFK_F_WC, \ ++ .addr = _addr, \ ++ .mask = _mask,} ++ ++#define DECL_RFK_DELAY(_data) \ ++ {.flag = RTW89_RFK_F_DELAY, \ ++ .data = _data,} ++ ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_sys_defs_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_sys_defs_2g_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_sys_defs_5g_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_2g_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_5g_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_dck_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_dck_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_dac_gain_tbl_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_dac_gain_tbl_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_cal_org_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_cal_org_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_rf_gap_tbl_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_rf_gap_tbl_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_track_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_track_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txagc_ofst_mv_avg_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txagc_ofst_mv_avg_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_2g_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_5g_1_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_5g_3_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_5g_4_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_2g_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_5g_1_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_5g_3_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_5g_4_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_enable_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_enable_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_enable_defs_ab_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_disable_defs_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_tracking_defs_tbl; ++ ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_afe_init_defs_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_reload_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_reload_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_addc_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_addc_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_reset_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_trigger_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_restore_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_reset_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_trigger_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_restore_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_f_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_f_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_r_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_r_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_f_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_m_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_r_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_f_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_m_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_r_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sf_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sr_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sf_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sr_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_s_defs_ab_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_r_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_r_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_r_defs_ab_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_lbk_rxiqk_defs_f_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_lbk_rxiqk_defs_r_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_pas_read_defs_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_set_defs_nondbcc_path01_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_set_defs_dbcc_path0_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_set_defs_dbcc_path1_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_restore_defs_nondbcc_path01_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_restore_defs_dbcc_path0_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_restore_defs_dbcc_path1_tbl; ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c +new file mode 100644 +index 000000000000..3a4fe7207420 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c +@@ -0,0 +1,48725 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "phy.h" ++#include "reg.h" ++#include "rtw8852a_table.h" ++ ++static const struct rtw89_reg2_def rtw89_8852a_phy_bb_regs[] = { ++ {0xF0FF0001, 0x00000000}, ++ {0xF03300FF, 0x00000001}, ++ {0xF03500FF, 0x00000002}, ++ {0xF03200FF, 0x00000003}, ++ {0xF03400FF, 0x00000004}, ++ {0xF03600FF, 0x00000005}, ++ {0x704, 0x601E0100}, ++ {0x714, 0x00000000}, ++ {0x718, 0x13332333}, ++ {0x714, 0x00010000}, ++ {0x720, 0x20000000}, ++ {0x980, 0x10002250}, ++ {0x994, 0x00000010}, ++ {0x644, 0x2314283C}, ++ {0x644, 0x3426283C}, ++ {0x994, 0x00000010}, ++ {0xC3C, 0x2840E1BF}, ++ {0xC40, 0x00000000}, ++ {0xC44, 0x00000007}, ++ {0xC48, 0x410E4000}, ++ {0xC54, 0x1001436E}, ++ {0xC58, 0x41000000}, ++ {0x730, 0x00000002}, ++ {0xC60, 0x017FFFF2}, ++ {0xC64, 0x0010A130}, ++ {0xC64, 0x0010A130}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0xC68, 0x10000068}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0xC68, 0x90000068}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0xC68, 0x90000068}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0xC68, 0x10000068}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0xC68, 0x90000068}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0xC68, 0x90000068}, ++ {0xA0000000, 0x00000000}, ++ {0xC68, 0x10000068}, ++ {0xB0000000, 0x00000000}, ++ {0xC64, 0x0010A130}, ++ {0xC54, 0x1EE1436E}, ++ {0xC6C, 0x00000020}, ++ {0x708, 0x00000000}, ++ {0xC6C, 0x00000020}, ++ {0x804, 0x0043F01D}, ++ {0x12D0, 0x00000000}, ++ {0x12EC, 0x888CA72B}, ++ {0x32D0, 0x00000000}, ++ {0x32EC, 0x888CA72B}, ++ {0xD40, 0xF64FA0F7}, ++ {0xD44, 0x0400063F}, ++ {0xD48, 0x0003FF7F}, ++ {0xD4C, 0x00000000}, ++ {0xD50, 0xF64FA0F7}, ++ {0xD54, 0x04100437}, ++ {0xD58, 0x0000FF7F}, ++ {0xD5C, 0x00000000}, ++ {0xD60, 0x00000000}, ++ {0xD64, 0x00000000}, ++ {0xD70, 0x0000001D}, ++ {0xD90, 0x000003FF}, ++ {0xD94, 0x00000000}, ++ {0xD98, 0x0000003F}, ++ {0xD9C, 0x00000000}, ++ {0xDA0, 0x000003FF}, ++ {0xDA4, 0x00000000}, ++ {0xDA8, 0x0000003F}, ++ {0xDAC, 0x00000000}, ++ {0xD00, 0x77777777}, ++ {0xD04, 0xBBBBBBBB}, ++ {0xD08, 0xBBBBBBBB}, ++ {0xD0C, 0x00000070}, ++ {0xD10, 0x20110900}, ++ {0xD10, 0x20110FFF}, ++ {0xD7C, 0x001D050C}, ++ {0xD84, 0x00006207}, ++ {0xD18, 0x50209900}, ++ {0xD80, 0x00804100}, ++ {0x714, 0x00010000}, ++ {0x704, 0x601E00FD}, ++ {0x710, 0xF3810000}, ++ {0x000, 0x0580801F}, ++ {0x000, 0x8580801F}, ++ {0x334, 0xFFFFFFFF}, ++ {0x33C, 0x55000000}, ++ {0x340, 0x00005555}, ++ {0x724, 0x00111200}, ++ {0x5868, 0xA9550000}, ++ {0x5870, 0x33221100}, ++ {0x5874, 0x77665544}, ++ {0x5878, 0xBBAA9988}, ++ {0x587C, 0xFFEEDDCC}, ++ {0x5880, 0x76543210}, ++ {0x5884, 0xFEDCBA98}, ++ {0x5888, 0x00000000}, ++ {0x588C, 0x00000000}, ++ {0x5894, 0x00000008}, ++ {0x7868, 0xA9550000}, ++ {0x7870, 0x33221100}, ++ {0x7874, 0x77665544}, ++ {0x7878, 0xBBAA9988}, ++ {0x787C, 0xFFEEDDCC}, ++ {0x7880, 0x76543210}, ++ {0x7884, 0xFEDCBA98}, ++ {0x7888, 0x00000000}, ++ {0x788C, 0x00000000}, ++ {0x7894, 0x00000008}, ++ {0x240C, 0x00000000}, ++ {0xC70, 0x00000400}, ++ {0x700, 0x00000030}, ++ {0x704, 0x601E00FF}, ++ {0x704, 0x601E00FD}, ++ {0x704, 0x601E00FF}, ++ {0x586C, 0x000000F0}, ++ {0x586C, 0x000000E0}, ++ {0x586C, 0x000000D0}, ++ {0x586C, 0x000000C0}, ++ {0x586C, 0x000000B0}, ++ {0x586C, 0x000000A0}, ++ {0x586C, 0x00000090}, ++ {0x586C, 0x00000080}, ++ {0x586C, 0x00000070}, ++ {0x586C, 0x00000060}, ++ {0x586C, 0x00000050}, ++ {0x586C, 0x00000040}, ++ {0x586C, 0x00000030}, ++ {0x586C, 0x00000020}, ++ {0x586C, 0x00000010}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x586C, 0x00000000}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x586C, 0x03E00000}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x586C, 0x03E00000}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x586C, 0x00000000}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x586C, 0x03E00000}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x586C, 0x03E00000}, ++ {0xA0000000, 0x00000000}, ++ {0x586C, 0x00000000}, ++ {0xB0000000, 0x00000000}, ++ {0x786C, 0x000000F0}, ++ {0x786C, 0x000000E0}, ++ {0x786C, 0x000000D0}, ++ {0x786C, 0x000000C0}, ++ {0x786C, 0x000000B0}, ++ {0x786C, 0x000000A0}, ++ {0x786C, 0x00000090}, ++ {0x786C, 0x00000080}, ++ {0x786C, 0x00000070}, ++ {0x786C, 0x00000060}, ++ {0x786C, 0x00000050}, ++ {0x786C, 0x00000040}, ++ {0x786C, 0x00000030}, ++ {0x786C, 0x00000020}, ++ {0x786C, 0x00000010}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x786C, 0x00000000}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x786C, 0x03E00000}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x786C, 0x03E00000}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x786C, 0x00000000}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x786C, 0x03E00000}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x786C, 0x03E00000}, ++ {0xA0000000, 0x00000000}, ++ {0x786C, 0x00000000}, ++ {0xB0000000, 0x00000000}, ++ {0x5864, 0x080801FF}, ++ {0x7864, 0x080801FF}, ++ {0xC60, 0x017FFFF3}, ++ {0xC6C, 0x00000021}, ++ {0x58AC, 0x08000000}, ++ {0x78AC, 0x08000000}, ++ {0x5864, 0x180801FF}, ++ {0x7864, 0x180801FF}, ++ {0xC60, 0x017FFFF3}, ++ {0xC60, 0x017FFFF3}, ++ {0x2C60, 0x013FFF0A}, ++ {0xC70, 0x00000600}, ++ {0xC70, 0x00000660}, ++ {0xC6C, 0x10001021}, ++ {0x58AC, 0x08000000}, ++ {0x78AC, 0x08000000}, ++ {0x5864, 0x100801FF}, ++ {0x7864, 0x100801FF}, ++ {0x5864, 0x180801FF}, ++ {0x7864, 0x180801FF}, ++ {0x704, 0x601C01FF}, ++ {0x58D4, 0x0401FE00}, ++ {0x78D4, 0x0401FE00}, ++ {0x58F0, 0x000401FF}, ++ {0x78F0, 0x000401FF}, ++ {0x58F0, 0x400401FF}, ++ {0x78F0, 0x400401FF}, ++ {0x12A8, 0x333378A5}, ++ {0x32A8, 0x333378A5}, ++ {0x2300, 0x02748790}, ++ {0x2304, 0x00558670}, ++ {0x2308, 0x002883F0}, ++ {0x230C, 0x00090120}, ++ {0x2310, 0x00000000}, ++ {0x2314, 0x06000000}, ++ {0x2318, 0x00000000}, ++ {0x231C, 0x00000000}, ++ {0x2320, 0x03020100}, ++ {0x2324, 0x07060504}, ++ {0x2328, 0x0B0A0908}, ++ {0x232C, 0x0F0E0D0C}, ++ {0x2330, 0x13121110}, ++ {0x2334, 0x17161514}, ++ {0x2338, 0x0C700022}, ++ {0x233C, 0x0A05298F}, ++ {0x2340, 0x0005298E}, ++ {0x2344, 0x0006318A}, ++ {0x2348, 0xB7E6318A}, ++ {0x234C, 0x80039CE7}, ++ {0x2350, 0x80039CE7}, ++ {0x2354, 0x0005298F}, ++ {0x2358, 0x0015296E}, ++ {0x235C, 0x0C07FC31}, ++ {0x2360, 0x0219A6AE}, ++ {0x2364, 0xE4F624C3}, ++ {0x2368, 0x53626F15}, ++ {0x236C, 0x48000000}, ++ {0x2370, 0x48000000}, ++ {0x2374, 0x074C0000}, ++ {0x2378, 0x202401B5}, ++ {0x237C, 0x00F7000E}, ++ {0x2380, 0x0F0A1111}, ++ {0x2384, 0x30D9000F}, ++ {0x2388, 0x0400EA02}, ++ {0x238C, 0x003CB061}, ++ {0x2390, 0x69C00000}, ++ {0x2394, 0x00000000}, ++ {0x2398, 0x000000F0}, ++ {0x239C, 0x0001FFFF}, ++ {0x23A0, 0x00C80064}, ++ {0x23A4, 0x0190012C}, ++ {0x23A8, 0x001917BE}, ++ {0x23AC, 0x0B308800}, ++ {0x23B0, 0x0001D5B0}, ++ {0x23B4, 0x000285D2}, ++ {0x23B8, 0x00000000}, ++ {0x23BC, 0x00000000}, ++ {0x23C0, 0x00000000}, ++ {0x23C4, 0x00000000}, ++ {0x23C8, 0x00000000}, ++ {0x23CC, 0x00000000}, ++ {0x23D0, 0x00000000}, ++ {0x23D4, 0x00000000}, ++ {0x23D8, 0x00000000}, ++ {0x23DC, 0x00000000}, ++ {0x23E0, 0x00000000}, ++ {0x23E4, 0x00000000}, ++ {0x23E8, 0x00000000}, ++ {0x23EC, 0x00000000}, ++ {0x23F0, 0x00000000}, ++ {0x23F4, 0x00000000}, ++ {0x23F8, 0x00000000}, ++ {0x23FC, 0x00000000}, ++ {0x804, 0x0043F01D}, ++ {0x300, 0xF30CE31C}, ++ {0x304, 0x13EF1F19}, ++ {0x308, 0x0C0CF3F3}, ++ {0x30C, 0x0C0C0C0C}, ++ {0x310, 0x80416000}, ++ {0x314, 0x0041E000}, ++ {0x318, 0x20022042}, ++ {0x31C, 0x20448001}, ++ {0x320, 0x00410040}, ++ {0x324, 0xE000E000}, ++ {0x328, 0xE000E000}, ++ {0x32C, 0xE000E000}, ++ {0x12BC, 0x10104041}, ++ {0x12C0, 0x14411111}, ++ {0x32BC, 0x10104041}, ++ {0x32C0, 0x14411111}, ++ {0x010, 0x0005FFFF}, ++ {0x604, 0x1E1E1E28}, ++ {0x650, 0x00200888}, ++ {0x620, 0x00141230}, ++ {0x35C, 0x000004C4}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5804, 0x04237040}, ++ {0x7804, 0x04237040}, ++ {0x5808, 0x04237040}, ++ {0x7808, 0x04237040}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5804, 0x04231040}, ++ {0x7804, 0x04231040}, ++ {0x5808, 0x04231040}, ++ {0x7808, 0x04231040}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5804, 0x04231040}, ++ {0x7804, 0x04231040}, ++ {0x5808, 0x04231040}, ++ {0x7808, 0x04231040}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5804, 0x04237040}, ++ {0x7804, 0x04237040}, ++ {0x5808, 0x04237040}, ++ {0x7808, 0x04237040}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5804, 0x04231040}, ++ {0x7804, 0x04231040}, ++ {0x5808, 0x04231040}, ++ {0x7808, 0x04231040}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5804, 0x04231040}, ++ {0x7804, 0x04231040}, ++ {0x5808, 0x04231040}, ++ {0x7808, 0x04231040}, ++ {0xA0000000, 0x00000000}, ++ {0x5804, 0x04237040}, ++ {0x7804, 0x04237040}, ++ {0x5808, 0x04237040}, ++ {0x7808, 0x04237040}, ++ {0xB0000000, 0x00000000}, ++ {0x12A0, 0x24903156}, ++ {0x32A0, 0x24903156}, ++ {0x640, 0x1414141E}, ++ {0x12B8, 0x30020000}, ++ {0x12AC, 0x02333121}, ++ {0x9A4, 0x0000001C}, ++ {0x624, 0x01010301}, ++ {0x628, 0x00010101}, ++ {0x5800, 0x03FF807F}, ++ {0x7800, 0x03FF807F}, ++ {0x4000, 0x00000000}, ++ {0x4004, 0xCA014000}, ++ {0x4008, 0xC751D4F0}, ++ {0x400C, 0x44511475}, ++ {0x4010, 0x00000000}, ++ {0x4014, 0x00000000}, ++ {0x4018, 0x4F4C084B}, ++ {0x401C, 0x084A4E52}, ++ {0x4020, 0x4D504E4B}, ++ {0x4024, 0x4F4C0849}, ++ {0x4028, 0x08484C50}, ++ {0x402C, 0x4C50504C}, ++ {0x4030, 0x5454084A}, ++ {0x4034, 0x084B5654}, ++ {0x4038, 0x6A6C605A}, ++ {0x403C, 0x4C4C084C}, ++ {0x4040, 0x084B4E4D}, ++ {0x4044, 0x4E4C4B4B}, ++ {0x4048, 0x4B4B084A}, ++ {0x404C, 0x084A4E4C}, ++ {0x4050, 0x514F4C4A}, ++ {0x4054, 0x524E084A}, ++ {0x4058, 0x084A5154}, ++ {0x405C, 0x53555554}, ++ {0x4060, 0x45450845}, ++ {0x4064, 0x08454144}, ++ {0x4068, 0x40434445}, ++ {0x406C, 0x44450845}, ++ {0x4070, 0x08444043}, ++ {0x4074, 0x42434444}, ++ {0x4078, 0x46450844}, ++ {0x407C, 0x08444843}, ++ {0x4080, 0x4B4E4A47}, ++ {0x4084, 0x4F4C084B}, ++ {0x4088, 0x084A4E52}, ++ {0x408C, 0x4D504E4B}, ++ {0x4090, 0x4F4C0849}, ++ {0x4094, 0x08484C50}, ++ {0x4098, 0x4C50504C}, ++ {0x409C, 0x5454084A}, ++ {0x40A0, 0x084B5654}, ++ {0x40A4, 0x6A6C605A}, ++ {0x40A8, 0x4C4C084C}, ++ {0x40AC, 0x084B4E4D}, ++ {0x40B0, 0x4E4C4B4B}, ++ {0x40B4, 0x4B4B084A}, ++ {0x40B8, 0x084A4E4C}, ++ {0x40BC, 0x514F4C4A}, ++ {0x40C0, 0x524E084A}, ++ {0x40C4, 0x084A5154}, ++ {0x40C8, 0x53555554}, ++ {0x40CC, 0x45450845}, ++ {0x40D0, 0x08454144}, ++ {0x40D4, 0x40434445}, ++ {0x40D8, 0x44450845}, ++ {0x40DC, 0x08444043}, ++ {0x40E0, 0x42434444}, ++ {0x40E4, 0x46450844}, ++ {0x40E8, 0x08444843}, ++ {0x40EC, 0x4B4E4A47}, ++ {0x40F0, 0x00000000}, ++ {0x40F4, 0x00000006}, ++ {0x40F8, 0x00000001}, ++ {0x40FC, 0x8C30C30C}, ++ {0x4100, 0x4C30C30C}, ++ {0x4104, 0x0C30C30C}, ++ {0x4108, 0x0C30C30C}, ++ {0x410C, 0x0C30C30C}, ++ {0x4110, 0x0C30C30C}, ++ {0x4114, 0x28A28A28}, ++ {0x4118, 0x28A28A28}, ++ {0x411C, 0x28A28A28}, ++ {0x4120, 0x28A28A28}, ++ {0x4124, 0x28A28A28}, ++ {0x4128, 0x28A28A28}, ++ {0x412C, 0x06666666}, ++ {0x4130, 0x33333333}, ++ {0x4134, 0x33333333}, ++ {0x4138, 0x33333333}, ++ {0x413C, 0x00000031}, ++ {0x4140, 0x5100600A}, ++ {0x4144, 0x18363113}, ++ {0x4148, 0x1D976DDC}, ++ {0x414C, 0x1C072DD7}, ++ {0x4150, 0x1127CDF4}, ++ {0x4154, 0x1E37BDF1}, ++ {0x4158, 0x1FB7F1D6}, ++ {0x415C, 0x1EA7DDF9}, ++ {0x4160, 0x1FE445DD}, ++ {0x4164, 0x1F97F1FE}, ++ {0x4168, 0x1FF781ED}, ++ {0x416C, 0x1FA7F5FE}, ++ {0x4170, 0x1E07B913}, ++ {0x4174, 0x1FD7FDFF}, ++ {0x4178, 0x1E17B9FA}, ++ {0x417C, 0x19A66914}, ++ {0x4180, 0x10F65598}, ++ {0x4184, 0x14A5A111}, ++ {0x4188, 0x1D3765DB}, ++ {0x418C, 0x17C685CA}, ++ {0x4190, 0x1107C5F3}, ++ {0x4194, 0x1B5785EB}, ++ {0x4198, 0x1F97ED8F}, ++ {0x419C, 0x1BC7A5F3}, ++ {0x41A0, 0x1FE43595}, ++ {0x41A4, 0x1EB7D9FC}, ++ {0x41A8, 0x1FE65DBE}, ++ {0x41AC, 0x1EC7D9FC}, ++ {0x41B0, 0x1976FCFF}, ++ {0x41B4, 0x1F77F5FF}, ++ {0x41B8, 0x1976FDEC}, ++ {0x41BC, 0x198664EF}, ++ {0x41C0, 0x11062D93}, ++ {0x41C4, 0x10C4E910}, ++ {0x41C8, 0x1CA759DB}, ++ {0x41CC, 0x1335A9B5}, ++ {0x41D0, 0x1097B9F3}, ++ {0x41D4, 0x17B72DE1}, ++ {0x41D8, 0x1F67ED42}, ++ {0x41DC, 0x18074DE9}, ++ {0x41E0, 0x1FD40547}, ++ {0x41E4, 0x1D57ADF9}, ++ {0x41E8, 0x1FE52182}, ++ {0x41EC, 0x1D67B1F9}, ++ {0x41F0, 0x14860CE1}, ++ {0x41F4, 0x1EC7E9FE}, ++ {0x41F8, 0x14860DD6}, ++ {0x41FC, 0x195664C7}, ++ {0x4200, 0x0005E58A}, ++ {0x4204, 0x00000000}, ++ {0x4208, 0x00000000}, ++ {0x420C, 0x7A000000}, ++ {0x4210, 0x0F9F3D7A}, ++ {0x4214, 0x0040817C}, ++ {0x4218, 0x00E10204}, ++ {0x421C, 0x227D94CD}, ++ {0x4220, 0x080238E3}, ++ {0x4224, 0x00000210}, ++ {0x4228, 0x04688000}, ++ {0x422C, 0x0060B002}, ++ {0x4230, 0x9A8249A8}, ++ {0x4234, 0x26A1469E}, ++ {0x4238, 0x2099A824}, ++ {0x423C, 0x2359461C}, ++ {0x4240, 0x1631A675}, ++ {0x4244, 0x2C6B1D63}, ++ {0x4248, 0x0000000E}, ++ {0x424C, 0x00000001}, ++ {0x4250, 0x00000001}, ++ {0x4254, 0x00000000}, ++ {0x4258, 0x00000000}, ++ {0x425C, 0x00000000}, ++ {0x4260, 0x0020000C}, ++ {0x4264, 0x00000000}, ++ {0x4268, 0x00000000}, ++ {0x426C, 0x0418317C}, ++ {0x4270, 0x00D6135C}, ++ {0x4274, 0x00000000}, ++ {0x4278, 0x00000000}, ++ {0x427C, 0x00000000}, ++ {0x4280, 0x00000000}, ++ {0x4284, 0x00000000}, ++ {0x4288, 0x00000000}, ++ {0x428C, 0x00000000}, ++ {0x4290, 0x00000000}, ++ {0x4294, 0x00000000}, ++ {0x4298, 0x84026000}, ++ {0x429C, 0x0051AC20}, ++ {0x42A0, 0x02024008}, ++ {0x42A4, 0x00000000}, ++ {0x42A8, 0x00000000}, ++ {0x42AC, 0x22CE803C}, ++ {0x42B0, 0x80000000}, ++ {0x42B4, 0x00E7D03D}, ++ {0x42B8, 0x3D67D67D}, ++ {0x42BC, 0x7D67D65B}, ++ {0x42C0, 0x2802AF59}, ++ {0x42C4, 0x00280280}, ++ {0x42C8, 0x00000000}, ++ {0x42CC, 0x00000000}, ++ {0x42D0, 0x00000003}, ++ {0x42D4, 0x00000001}, ++ {0x42D8, 0x61861800}, ++ {0x42DC, 0x830C30C3}, ++ {0x42E0, 0xC30C30C3}, ++ {0x42E4, 0x830C30C3}, ++ {0x42E8, 0x451450C3}, ++ {0x42EC, 0x05145145}, ++ {0x42F0, 0x05145145}, ++ {0x42F4, 0x05145145}, ++ {0x42F8, 0x0F0C3145}, ++ {0x42FC, 0x030C30CF}, ++ {0x4300, 0x030C30C3}, ++ {0x4304, 0x030CF3C3}, ++ {0x4308, 0x030C30C3}, ++ {0x430C, 0x0F3CF3C3}, ++ {0x4310, 0x0F3CF3CF}, ++ {0x4314, 0x0F3CF3CF}, ++ {0x4318, 0x0F3CF3CF}, ++ {0x431C, 0x0F3CF3CF}, ++ {0x4320, 0x030C10C3}, ++ {0x4324, 0x051430C3}, ++ {0x4328, 0x051490CB}, ++ {0x432C, 0x030CD151}, ++ {0x4330, 0x050C50C7}, ++ {0x4334, 0x051492CB}, ++ {0x4338, 0x05145145}, ++ {0x433C, 0x05145145}, ++ {0x4340, 0x05145145}, ++ {0x4344, 0x05145145}, ++ {0x4348, 0x090CD3CF}, ++ {0x434C, 0x071491C5}, ++ {0x4350, 0x073CF143}, ++ {0x4354, 0x071431C3}, ++ {0x4358, 0x0F3CF1C5}, ++ {0x435C, 0x0F3CF3CF}, ++ {0x4360, 0x0F3CF3CF}, ++ {0x4364, 0x0F3CF3CF}, ++ {0x4368, 0x0F3CF3CF}, ++ {0x436C, 0x090C91CF}, ++ {0x4370, 0x11243143}, ++ {0x4374, 0x9777A777}, ++ {0x4378, 0xBB7BAC95}, ++ {0x437C, 0xB667B889}, ++ {0x4380, 0x7B9B8899}, ++ {0x4384, 0x7A5567C8}, ++ {0x4388, 0x2278CCCC}, ++ {0x438C, 0x7C222222}, ++ {0x4390, 0x0000069B}, ++ {0x4394, 0x001CCCCC}, ++ {0x4398, 0x00000000}, ++ {0x439C, 0x00000008}, ++ {0x49A4, 0x00000000}, ++ {0x43A0, 0x00000000}, ++ {0x43A4, 0x00000000}, ++ {0x43A8, 0x00000000}, ++ {0x43AC, 0x10000800}, ++ {0x43B0, 0x00401802}, ++ {0x43B4, 0x00061004}, ++ {0x43B8, 0x000024D8}, ++ {0x43BC, 0x00000000}, ++ {0x43C0, 0x10000020}, ++ {0x43C4, 0x20000200}, ++ {0x43C8, 0x00000000}, ++ {0x43CC, 0x04000000}, ++ {0x43D0, 0x44000100}, ++ {0x43D4, 0x60804060}, ++ {0x43D8, 0x44204210}, ++ {0x43DC, 0x82108082}, ++ {0x43E0, 0x82108402}, ++ {0x43E4, 0xC8082108}, ++ {0x43E8, 0xC8202084}, ++ {0x43EC, 0x44208208}, ++ {0x43F0, 0x84108204}, ++ {0x43F4, 0xD0108104}, ++ {0x43F8, 0xF8210108}, ++ {0x43FC, 0x6431E930}, ++ {0x4400, 0x02109468}, ++ {0x4404, 0x10C61C22}, ++ {0x4408, 0x02109469}, ++ {0x440C, 0x10C61C22}, ++ {0x4410, 0x00041049}, ++ {0x4414, 0x00000000}, ++ {0x4418, 0x00000000}, ++ {0x441C, 0x6C000000}, ++ {0x4420, 0xB0200020}, ++ {0x4424, 0x00001FF0}, ++ {0x4428, 0x00000000}, ++ {0x442C, 0x00000000}, ++ {0x4430, 0x00000000}, ++ {0x4434, 0x00000000}, ++ {0x4438, 0x65F962F8}, ++ {0x443C, 0x280668A0}, ++ {0x4440, 0x64100820}, ++ {0x4444, 0x4A146304}, ++ {0x4448, 0x0C59008F}, ++ {0x444C, 0x6E30498A}, ++ {0x4450, 0x656E371B}, ++ {0x4454, 0x00000F52}, ++ {0x4458, 0x00000000}, ++ {0x445C, 0x4801442E}, ++ {0x4460, 0x0041A0B8}, ++ {0x4464, 0x00000000}, ++ {0x4468, 0x00000000}, ++ {0x446C, 0x00000000}, ++ {0x4470, 0x00000000}, ++ {0x4474, 0x00000000}, ++ {0x4478, 0x00000000}, ++ {0x447C, 0x00000000}, ++ {0x4480, 0x2A0A6040}, ++ {0x4484, 0x0A0A6829}, ++ {0x4488, 0x00000004}, ++ {0x448C, 0x00000000}, ++ {0x4490, 0x80000000}, ++ {0x4494, 0x10000000}, ++ {0x4498, 0xA0000000}, ++ {0x449C, 0x0000001E}, ++ {0x44A0, 0x02B29397}, ++ {0x44A4, 0x00000400}, ++ {0x44A8, 0x00000001}, ++ {0x44AC, 0x00000000}, ++ {0x44B0, 0x00000000}, ++ {0x44B4, 0x00000000}, ++ {0x44B8, 0x00000000}, ++ {0x44BC, 0x00000000}, ++ {0x44C0, 0x00000000}, ++ {0x44C4, 0x00000000}, ++ {0x44C8, 0x00000000}, ++ {0x44CC, 0x00000000}, ++ {0x44D0, 0x00000000}, ++ {0x44D4, 0x00000000}, ++ {0x44D8, 0x00000000}, ++ {0x44DC, 0x00000000}, ++ {0x44E0, 0x00000000}, ++ {0x44E4, 0x00000000}, ++ {0x44E8, 0x00000000}, ++ {0x44EC, 0x00000000}, ++ {0x44F0, 0x00000000}, ++ {0x44F4, 0x00000000}, ++ {0x44F8, 0x00000000}, ++ {0x44FC, 0x00000000}, ++ {0x4500, 0x00000000}, ++ {0x4504, 0x00000000}, ++ {0x4508, 0x00000000}, ++ {0x450C, 0x00000000}, ++ {0x4510, 0x00000000}, ++ {0x4514, 0x00000000}, ++ {0x4518, 0x00000000}, ++ {0x451C, 0x00000000}, ++ {0x4520, 0x00000000}, ++ {0x4524, 0x00000000}, ++ {0x4528, 0x00000000}, ++ {0x452C, 0x00000000}, ++ {0x4530, 0x4EA20631}, ++ {0x4534, 0x000005C8}, ++ {0x4538, 0x000000FF}, ++ {0x453C, 0x00000000}, ++ {0x4540, 0x00000000}, ++ {0x4544, 0x00000000}, ++ {0x4548, 0x00000000}, ++ {0x454C, 0x00000000}, ++ {0x4550, 0x00000000}, ++ {0x4554, 0x00000000}, ++ {0x4558, 0x00000000}, ++ {0x455C, 0x00000000}, ++ {0x4560, 0x4060001A}, ++ {0x4564, 0x40000000}, ++ {0x4568, 0x00000000}, ++ {0x456C, 0x20000000}, ++ {0x4570, 0x04800406}, ++ {0x4574, 0x00022270}, ++ {0x4578, 0x0002024B}, ++ {0x457C, 0x00200000}, ++ {0x4580, 0x00009B40}, ++ {0x4584, 0x00000000}, ++ {0x4588, 0x00000063}, ++ {0x458C, 0x30000000}, ++ {0x4590, 0x00000000}, ++ {0x4594, 0x05000000}, ++ {0x4598, 0x00000001}, ++ {0x459C, 0x0003FE00}, ++ {0x45A0, 0x00000000}, ++ {0x45A4, 0x00000000}, ++ {0x45A8, 0xC00001C0}, ++ {0x45AC, 0x78028000}, ++ {0x45B0, 0x80000048}, ++ {0x45B4, 0x01C90800}, ++ {0x45B8, 0x00000002}, ++ {0x45BC, 0x06748790}, ++ {0x45C0, 0x80000000}, ++ {0x45C4, 0x00000000}, ++ {0x45C8, 0x00000000}, ++ {0x45CC, 0x00558670}, ++ {0x45D0, 0x002883F0}, ++ {0x45D4, 0x00090120}, ++ {0x45D8, 0x00000000}, ++ {0x45DC, 0xA3A6D3C4}, ++ {0x49A8, 0xAB27B126}, ++ {0x49AC, 0x00006778}, ++ {0x49FC, 0x000001B5}, ++ {0x49B0, 0x11110F0A}, ++ {0x49B4, 0x00000007}, ++ {0x49B8, 0x0000000A}, ++ {0x49BC, 0x0058BC3F}, ++ {0x49C0, 0x00000003}, ++ {0x49C4, 0x000003D9}, ++ {0x49C8, 0x002B1CB0}, ++ {0x4A00, 0x00000000}, ++ {0x49CC, 0x00000001}, ++ {0x49D0, 0x00000010}, ++ {0x49D4, 0x00000001}, ++ {0x49D8, 0x85298FBF}, ++ {0x49DC, 0x18A5296E}, ++ {0x49E0, 0x18C6298C}, ++ {0x49E4, 0x0A739CA7}, ++ {0x49E8, 0x001A50E7}, ++ {0x49EC, 0x00000001}, ++ {0x49F0, 0x00005924}, ++ {0x49F4, 0x0003AAA6}, ++ {0x49F8, 0x0000C4C3}, ++ {0x45E0, 0x00000000}, ++ {0x45E4, 0x00000000}, ++ {0x45E8, 0x00E2E100}, ++ {0x45EC, 0xCB00B6B6}, ++ {0x45F0, 0x59100FCA}, ++ {0x45F4, 0x08882550}, ++ {0x45F8, 0x08CC2660}, ++ {0x45FC, 0x09102660}, ++ {0x4600, 0x00000154}, ++ {0x4604, 0x00000800}, ++ {0x4608, 0x31BF0400}, ++ {0x460C, 0x00E0C0A0}, ++ {0x4610, 0x30604020}, ++ {0x4614, 0x2F346D50}, ++ {0x4618, 0x2E36B6E2}, ++ {0x461C, 0x3E7EF86B}, ++ {0x4620, 0x001FC004}, ++ {0x4624, 0xA8068010}, ++ {0x4628, 0x4602CA80}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x462C, 0x76067E8C}, ++ {0x4630, 0x8EA350E8}, ++ {0x4634, 0xB3B8D8F5}, ++ {0x4638, 0x6FFF0C06}, ++ {0x463C, 0xB8FA4435}, ++ {0x4640, 0xB7C4FEF8}, ++ {0x4644, 0x2A72AD07}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x462C, 0x76078E8C}, ++ {0x4630, 0x8EDB50F6}, ++ {0x4634, 0xB5B8DD75}, ++ {0x4638, 0x6FFF4C06}, ++ {0x463C, 0xB8FA4434}, ++ {0x4640, 0xB7C4FEF8}, ++ {0x4644, 0x2A72AD07}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x462C, 0x76078E8C}, ++ {0x4630, 0x8EDB50F6}, ++ {0x4634, 0xB5B8DD75}, ++ {0x4638, 0x6FFF4C06}, ++ {0x463C, 0xB8FA4434}, ++ {0x4640, 0xB7C4FEF8}, ++ {0x4644, 0x2A72AD07}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x462C, 0x76067E8C}, ++ {0x4630, 0x8EA350E8}, ++ {0x4634, 0xB3B8D8F5}, ++ {0x4638, 0x6FFF0C06}, ++ {0x463C, 0xB8FA4435}, ++ {0x4640, 0xB7C4FEF8}, ++ {0x4644, 0x2A72AD07}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x462C, 0x76078E8C}, ++ {0x4630, 0x8EDB50F6}, ++ {0x4634, 0xB5B8DD75}, ++ {0x4638, 0x6FFF4C06}, ++ {0x463C, 0xB8FA4434}, ++ {0x4640, 0xB7C4FEF8}, ++ {0x4644, 0x2A72AD07}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x462C, 0x76078E8C}, ++ {0x4630, 0x8EDB50F6}, ++ {0x4634, 0xB5B8DD75}, ++ {0x4638, 0x6FFF4C06}, ++ {0x463C, 0xB8FA4434}, ++ {0x4640, 0xB7C4FEF8}, ++ {0x4644, 0x2A72AD07}, ++ {0xA0000000, 0x00000000}, ++ {0x462C, 0x76067E8C}, ++ {0x4630, 0x8EA350E8}, ++ {0x4634, 0xB3B8D8F5}, ++ {0x4638, 0x6FFF0C06}, ++ {0x463C, 0xB8FA4435}, ++ {0x4640, 0xB7C4FEF8}, ++ {0x4644, 0x2A72AD07}, ++ {0xB0000000, 0x00000000}, ++ {0x4648, 0x64204FB2}, ++ {0x464C, 0x4C823404}, ++ {0x4650, 0x9084C800}, ++ {0x4654, 0x9889314F}, ++ {0x4658, 0x5ECC3FF4}, ++ {0x465C, 0xFEECAECE}, ++ {0x4660, 0x47806638}, ++ {0x4664, 0x0F5AF843}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4668, 0x56452994}, ++ {0x466C, 0x54D89ADB}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4668, 0x55452994}, ++ {0x466C, 0x56D89ADB}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4668, 0x55452994}, ++ {0x466C, 0x56D89ADB}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4668, 0x56452994}, ++ {0x466C, 0x54D89ADB}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4668, 0x55452994}, ++ {0x466C, 0x56D89ADB}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4668, 0x55452994}, ++ {0x466C, 0x56D89ADB}, ++ {0xA0000000, 0x00000000}, ++ {0x4668, 0x56452994}, ++ {0x466C, 0x54D89ADB}, ++ {0xB0000000, 0x00000000}, ++ {0x4670, 0xE8DF38D8}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4674, 0x002ACC30}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4674, 0x0028CC30}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4674, 0x0028CC30}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4674, 0x002ACC30}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4674, 0x0028CC30}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4674, 0x0028CC30}, ++ {0xA0000000, 0x00000000}, ++ {0x4674, 0x002ACC30}, ++ {0xB0000000, 0x00000000}, ++ {0x4678, 0x00000000}, ++ {0x467C, 0x00000000}, ++ {0x4680, 0x00000219}, ++ {0x4684, 0x00000000}, ++ {0x4688, 0x00000000}, ++ {0x468C, 0x00000001}, ++ {0x4690, 0x00000001}, ++ {0x4694, 0x00000000}, ++ {0x4698, 0x00000000}, ++ {0x469C, 0x00000151}, ++ {0x46A0, 0x00000498}, ++ {0x46A4, 0x00000498}, ++ {0x46A8, 0x00000000}, ++ {0x46AC, 0x00000000}, ++ {0x46B0, 0x00001146}, ++ {0x46B4, 0x00000000}, ++ {0x46B8, 0x00000000}, ++ {0x46BC, 0x00E2E100}, ++ {0x46C0, 0xCB00B6B6}, ++ {0x46C4, 0x59100FCA}, ++ {0x46C8, 0x08882550}, ++ {0x46CC, 0x08CC2660}, ++ {0x46D0, 0x09102660}, ++ {0x46D4, 0x00000154}, ++ {0x46D8, 0x00000800}, ++ {0x46DC, 0x31BF0400}, ++ {0x46E0, 0x00E0C0A0}, ++ {0x46E4, 0x30604020}, ++ {0x46E8, 0x4F346D50}, ++ {0x46EC, 0x2E36B6E2}, ++ {0x46F0, 0x3E7EF86B}, ++ {0x46F4, 0x001FC004}, ++ {0x46F8, 0xA8068010}, ++ {0x46FC, 0x4602CA80}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4700, 0x7806FECC}, ++ {0x4704, 0x8EC360F1}, ++ {0x4708, 0xB4C4DA7A}, ++ {0x470C, 0x72FF2CC6}, ++ {0x4710, 0xB8FA4439}, ++ {0x4714, 0xB7C4FEF8}, ++ {0x4718, 0x2A72AD09}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4700, 0x78078ECC}, ++ {0x4704, 0x8EDB60F6}, ++ {0x4708, 0xB5C4DD7A}, ++ {0x470C, 0x72FF4CC6}, ++ {0x4710, 0xB8FA4434}, ++ {0x4714, 0xB7C4FEF8}, ++ {0x4718, 0x2A72AD09}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4700, 0x78078ECC}, ++ {0x4704, 0x8EDB60F6}, ++ {0x4708, 0xB5C4DD7A}, ++ {0x470C, 0x72FF4CC6}, ++ {0x4710, 0xB8FA4434}, ++ {0x4714, 0xB7C4FEF8}, ++ {0x4718, 0x2A72AD09}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4700, 0x7806FECC}, ++ {0x4704, 0x8EC360F1}, ++ {0x4708, 0xB4C4DA7A}, ++ {0x470C, 0x72FF2CC6}, ++ {0x4710, 0xB8FA4439}, ++ {0x4714, 0xB7C4FEF8}, ++ {0x4718, 0x2A72AD09}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4700, 0x78078ECC}, ++ {0x4704, 0x8EDB60F6}, ++ {0x4708, 0xB5C4DD7A}, ++ {0x470C, 0x72FF4CC6}, ++ {0x4710, 0xB8FA4434}, ++ {0x4714, 0xB7C4FEF8}, ++ {0x4718, 0x2A72AD09}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4700, 0x78078ECC}, ++ {0x4704, 0x8EDB60F6}, ++ {0x4708, 0xB5C4DD7A}, ++ {0x470C, 0x72FF4CC6}, ++ {0x4710, 0xB8FA4434}, ++ {0x4714, 0xB7C4FEF8}, ++ {0x4718, 0x2A72AD09}, ++ {0xA0000000, 0x00000000}, ++ {0x4700, 0x7806FECC}, ++ {0x4704, 0x8EC360F1}, ++ {0x4708, 0xB4C4DA7A}, ++ {0x470C, 0x72FF2CC6}, ++ {0x4710, 0xB8FA4439}, ++ {0x4714, 0xB7C4FEF8}, ++ {0x4718, 0x2A72AD09}, ++ {0xB0000000, 0x00000000}, ++ {0x471C, 0x64204FB2}, ++ {0x4720, 0x4C823404}, ++ {0x4724, 0x9084C800}, ++ {0x4728, 0x9889314F}, ++ {0x472C, 0x5ECC3FF4}, ++ {0x4730, 0xFEECAECE}, ++ {0x4734, 0x47806638}, ++ {0x4738, 0x0F4A7843}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x473C, 0x56452994}, ++ {0x4740, 0x54D89ADB}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x473C, 0x55452994}, ++ {0x4740, 0x56D89ADB}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x473C, 0x55452994}, ++ {0x4740, 0x56D89ADB}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x473C, 0x56452994}, ++ {0x4740, 0x54D89ADB}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x473C, 0x55452994}, ++ {0x4740, 0x56D89ADB}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x473C, 0x55452994}, ++ {0x4740, 0x56D89ADB}, ++ {0xA0000000, 0x00000000}, ++ {0x473C, 0x56452994}, ++ {0x4740, 0x54D89ADB}, ++ {0xB0000000, 0x00000000}, ++ {0x4744, 0xE8DF38D8}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4748, 0x002ACC30}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4748, 0x0028CC30}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4748, 0x0028CC30}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4748, 0x002ACC30}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4748, 0x0028CC30}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4748, 0x0028CC30}, ++ {0xA0000000, 0x00000000}, ++ {0x4748, 0x002ACC30}, ++ {0xB0000000, 0x00000000}, ++ {0x474C, 0x00000000}, ++ {0x4750, 0x00000000}, ++ {0x4754, 0x00000219}, ++ {0x4758, 0x00000000}, ++ {0x475C, 0x00000000}, ++ {0x4760, 0x00000001}, ++ {0x4764, 0x00000001}, ++ {0x4768, 0x00000000}, ++ {0x476C, 0x00000000}, ++ {0x4770, 0x00000151}, ++ {0x4774, 0x00000498}, ++ {0x4778, 0x00000498}, ++ {0x477C, 0x00000000}, ++ {0x4780, 0x00000000}, ++ {0x4784, 0x00001147}, ++ {0x4788, 0x00000000}, ++ {0x478C, 0xA32103FE}, ++ {0x4790, 0x320A7B28}, ++ {0x4794, 0xC6A7B14F}, ++ {0x4798, 0x000006D7}, ++ {0x479C, 0x009B902A}, ++ {0x47A0, 0x009B902A}, ++ {0x47A4, 0x98682C18}, ++ {0x47A8, 0x6308C4C1}, ++ {0x47AC, 0x6248C631}, ++ {0x47B0, 0x922A8253}, ++ {0x47B4, 0x00000005}, ++ {0x47B8, 0x00001759}, ++ {0x47BC, 0x4B802000}, ++ {0x47C0, 0x831408BE}, ++ {0x47C4, 0x9ABBCACB}, ++ {0x47C8, 0x56767578}, ++ {0x47CC, 0xBBCCBBB3}, ++ {0x47D0, 0x57889989}, ++ {0x47D4, 0x00000F45}, ++ {0x47D8, 0x27039CE9}, ++ {0x47DC, 0x31413432}, ++ {0x47E0, 0x26058342}, ++ {0x47E4, 0x00000006}, ++ {0x47E8, 0x00000005}, ++ {0x47EC, 0x00000005}, ++ {0x47F0, 0xC7013016}, ++ {0x47F4, 0x84413016}, ++ {0x47F8, 0x84413016}, ++ {0x47FC, 0x8C413016}, ++ {0x4800, 0x8C40B028}, ++ {0x4804, 0x3140B028}, ++ {0x4808, 0x2940B028}, ++ {0x480C, 0x8440B028}, ++ {0x4810, 0x2318C610}, ++ {0x4814, 0x45334753}, ++ {0x4818, 0x236A6A88}, ++ {0x481C, 0x576DF814}, ++ {0x4820, 0xA08877AC}, ++ {0x4824, 0x0000087A}, ++ {0x4828, 0xBCEB4A14}, ++ {0x482C, 0x000A3A4A}, ++ {0x4830, 0xBCEB4A14}, ++ {0x4834, 0x000A3A4A}, ++ {0x4838, 0xBCBDBD85}, ++ {0x483C, 0x0CABB99A}, ++ {0x4840, 0x38384242}, ++ {0x4844, 0x8086102E}, ++ {0x4848, 0xCA24C82A}, ++ {0x484C, 0x00008A62}, ++ {0x4850, 0x00000008}, ++ {0x4854, 0x009B902A}, ++ {0x4858, 0x009B902A}, ++ {0x485C, 0x98682C18}, ++ {0x4860, 0x6308C4C1}, ++ {0x4864, 0x6248C631}, ++ {0x4868, 0x922A8253}, ++ {0x486C, 0x00000005}, ++ {0x4870, 0x00001759}, ++ {0x4874, 0x4B802000}, ++ {0x4878, 0x831408BE}, ++ {0x487C, 0x9898A8BB}, ++ {0x4880, 0x54535368}, ++ {0x4884, 0x999999B3}, ++ {0x4888, 0x35555589}, ++ {0x488C, 0x00000745}, ++ {0x4890, 0x27039CE9}, ++ {0x4894, 0x31413432}, ++ {0x4898, 0x26058342}, ++ {0x489C, 0x00000006}, ++ {0x48A0, 0x00000005}, ++ {0x48A4, 0x00000005}, ++ {0x48A8, 0xC7013016}, ++ {0x48AC, 0x84413016}, ++ {0x48B0, 0x84413016}, ++ {0x48B4, 0x8C413016}, ++ {0x48B8, 0x8C40B028}, ++ {0x48BC, 0x3140B028}, ++ {0x48C0, 0x2940B028}, ++ {0x48C4, 0x8440B028}, ++ {0x48C8, 0x2318C610}, ++ {0x48CC, 0x45334753}, ++ {0x48D0, 0x236A6A88}, ++ {0x48D4, 0x576DF814}, ++ {0x48D8, 0xA08877AC}, ++ {0x48DC, 0x0000007A}, ++ {0x48E0, 0xBCEB4A14}, ++ {0x48E4, 0x000A3A4A}, ++ {0x48E8, 0xBCEB4A14}, ++ {0x48EC, 0x000A3A4A}, ++ {0x48F0, 0x9A8A8A85}, ++ {0x48F4, 0x0CA3B99A}, ++ {0x48F8, 0x38384242}, ++ {0x48FC, 0x8086102E}, ++ {0x4900, 0xCA24C82A}, ++ {0x4904, 0x00008A62}, ++ {0x4908, 0x00000008}, ++ {0x490C, 0x80040000}, ++ {0x4910, 0x80040000}, ++ {0x4914, 0xFE800000}, ++ {0x4918, 0x834C0000}, ++ {0x491C, 0x00000000}, ++ {0x4920, 0x00000000}, ++ {0x4924, 0x00000000}, ++ {0x4928, 0x00000000}, ++ {0x492C, 0x00000000}, ++ {0x4930, 0x00000000}, ++ {0x4934, 0x40000000}, ++ {0x4938, 0x00000000}, ++ {0x493C, 0x00000000}, ++ {0x4940, 0x00000000}, ++ {0x4944, 0x00000000}, ++ {0x4948, 0x04065800}, ++ {0x494C, 0x32004080}, ++ {0x4950, 0x0E1E3E05}, ++ {0x4954, 0x0A163068}, ++ {0x4958, 0x00206040}, ++ {0x495C, 0x02020202}, ++ {0x4960, 0x00A16020}, ++ {0x4964, 0x031F4284}, ++ {0x4968, 0x00A10285}, ++ {0x496C, 0x00000005}, ++ {0x4970, 0x00000000}, ++ {0x4974, 0x800CD62D}, ++ {0x4978, 0x00000103}, ++ {0x497C, 0x00000000}, ++ {0x4980, 0x00000000}, ++ {0x4984, 0x00000000}, ++ {0x4988, 0x00000000}, ++ {0x498C, 0x00000000}, ++ {0x4990, 0x00000000}, ++ {0x4994, 0x00000000}, ++ {0x4998, 0x00000000}, ++ {0x499C, 0x00000000}, ++ {0x49A0, 0x00000000}, ++ {0x2404, 0x00000001}, ++ {0xC7C, 0x0000BFE0}, ++ {0x020, 0x0000F381}, ++ {0x024, 0x0000F381}, ++ {0x028, 0x0000F381}, ++ {0x02C, 0x0000F381}, ++ {0xD78, 0x00000005}, ++ {0x12CC, 0x00000CC1}, ++ {0x12D0, 0x00000000}, ++ {0x12D4, 0x00000000}, ++ {0x12D8, 0x00000040}, ++ {0x12DC, 0x4486888C}, ++ {0x12E0, 0xC43A10E1}, ++ {0x12E4, 0x30D52C68}, ++ {0x12E8, 0x02024128}, ++ {0x12EC, 0x888C272B}, ++ {0x12EC, 0x888CA72B}, ++ {0x32CC, 0x00000CC1}, ++ {0x32D0, 0x00000000}, ++ {0x32D4, 0x00000000}, ++ {0x32D8, 0x00000040}, ++ {0x32DC, 0x4486888C}, ++ {0x32E0, 0xC43A10E1}, ++ {0x32E4, 0x30D52C68}, ++ {0x32E8, 0x02024128}, ++ {0x32EC, 0x888C272B}, ++ {0x32EC, 0x888CA72B}, ++ {0x12AC, 0x12333121}, ++ {0x32AC, 0x12333121}, ++ {0x738, 0x004100CC}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5820, 0x80001080}, ++ {0x7820, 0x80001080}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5820, 0xC0001080}, ++ {0x7820, 0xC0001080}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5820, 0xC0001080}, ++ {0x7820, 0xC0001080}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5820, 0x80001080}, ++ {0x7820, 0x80001080}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5820, 0x80001080}, ++ {0x7820, 0x80001080}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5820, 0x80001080}, ++ {0x7820, 0x80001080}, ++ {0xA0000000, 0x00000000}, ++ {0x5820, 0x80001080}, ++ {0x7820, 0x80001080}, ++ {0xB0000000, 0x00000000}, ++ {0x2000, 0x18BBBF84}, ++ {0x0F0, 0x00000002}, ++ {0x0F4, 0x00000016}, ++ {0x0F8, 0x20201013}, ++}; ++ ++static const struct rtw89_reg2_def rtw89_8852a_phy_radioa_regs[] = { ++ {0xF0010000, 0x00000000}, ++ {0xF0010001, 0x00000001}, ++ {0xF0020001, 0x00000002}, ++ {0xF0030001, 0x00000003}, ++ {0xF0250001, 0x00000004}, ++ {0xF0260001, 0x00000005}, ++ {0xF0320001, 0x00000006}, ++ {0xF0330001, 0x00000007}, ++ {0xF0340001, 0x00000008}, ++ {0xF0350001, 0x00000009}, ++ {0xF0360001, 0x0000000A}, ++ {0xF0010002, 0x0000000B}, ++ {0xF0020002, 0x0000000C}, ++ {0xF0030002, 0x0000000D}, ++ {0xF0250002, 0x0000000E}, ++ {0xF0260002, 0x0000000F}, ++ {0xF0320002, 0x00000010}, ++ {0xF0330002, 0x00000011}, ++ {0xF0340002, 0x00000012}, ++ {0xF0350002, 0x00000013}, ++ {0xF0360002, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000001}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x005, 0x00000001}, ++ {0xB0000000, 0x00000000}, ++ {0x000, 0x00030000}, ++ {0x018, 0x00011124}, ++ {0x000, 0x00033C00}, ++ {0x01A, 0x00040004}, ++ {0x0FE, 0x00000000}, ++ {0x055, 0x00080000}, ++ {0x056, 0x0008FFF0}, ++ {0x057, 0x0000C485}, ++ {0x058, 0x000A4164}, ++ {0x059, 0x00010000}, ++ {0x05A, 0x00060000}, ++ {0x05B, 0x0000A000}, ++ {0x05C, 0x00000000}, ++ {0x05D, 0x0001C013}, ++ {0x05E, 0x00000000}, ++ {0x05F, 0x00001FF0}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0xA0000000, 0x00000000}, ++ {0x060, 0x00011000}, ++ {0xB0000000, 0x00000000}, ++ {0x061, 0x0009F338}, ++ {0x062, 0x0009233A}, ++ {0x063, 0x000D6002}, ++ {0x064, 0x000A0CB0}, ++ {0x065, 0x00030EFE}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0xA0000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0xB0000000, 0x00000000}, ++ {0x068, 0x00000000}, ++ {0x069, 0x00030F0A}, ++ {0x06A, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000AD6A4}, ++ {0x052, 0x00091345}, ++ {0x053, 0x00080081}, ++ {0x054, 0x0009BC24}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0xA0000000, 0x00000000}, ++ {0x051, 0x000AD6A4}, ++ {0x052, 0x00091345}, ++ {0x053, 0x00080081}, ++ {0x054, 0x0009BC24}, ++ {0xB0000000, 0x00000000}, ++ {0x0D3, 0x00000143}, ++ {0x043, 0x00005000}, ++ {0x0DD, 0x000003A0}, ++ {0x0B0, 0x000E6700}, ++ {0x0AF, 0x0001F82E}, ++ {0x0B2, 0x000210A7}, ++ {0x0B1, 0x00065FFF}, ++ {0x0BB, 0x000F7A00}, ++ {0x0B3, 0x00013F7A}, ++ {0x0D4, 0x0000000E}, ++ {0x0B7, 0x00001E0C}, ++ {0x0A0, 0x0000004F}, ++ {0x0B4, 0x0007C03E}, ++ {0x0B5, 0x0007E301}, ++ {0x0B6, 0x00080800}, ++ {0x0CA, 0x00002000}, ++ {0x0DD, 0x000003A0}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x00080000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0xA0000000, 0x00000000}, ++ {0x0CC, 0x00080000}, ++ {0xB0000000, 0x00000000}, ++ {0x0A1, 0x0006F300}, ++ {0x0A2, 0x00080500}, ++ {0x0A3, 0x0008050B}, ++ {0x0A4, 0x0006DB12}, ++ {0x0A5, 0x00000000}, ++ {0x0A6, 0x00000000}, ++ {0x0A7, 0x00000000}, ++ {0x0A8, 0x00000000}, ++ {0x0A9, 0x00000000}, ++ {0x0AA, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x000B0000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0A5, 0x000B0000}, ++ {0xB0000000, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00008000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0ED, 0x00008000}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000000}, ++ {0x03E, 0x00008000}, ++ {0x03F, 0x000E1333}, ++ {0x033, 0x00000001}, ++ {0x03E, 0x00008000}, ++ {0x03F, 0x000E7333}, ++ {0x033, 0x00000002}, ++ {0x03E, 0x00008000}, ++ {0x03F, 0x000FA000}, ++ {0x033, 0x00000003}, ++ {0x03E, 0x00004000}, ++ {0x03F, 0x000FA400}, ++ {0x033, 0x00000004}, ++ {0x03E, 0x00004000}, ++ {0x03F, 0x000F5000}, ++ {0x033, 0x00000005}, ++ {0x03E, 0x00004001}, ++ {0x03F, 0x00029400}, ++ {0x033, 0x00000006}, ++ {0x03E, 0x0000AAA1}, ++ {0x03F, 0x00041999}, ++ {0x033, 0x00000007}, ++ {0x03E, 0x0000AAA1}, ++ {0x03F, 0x00034444}, ++ {0x033, 0x00000008}, ++ {0x03E, 0x0000AAA1}, ++ {0x03F, 0x0004D555}, ++ {0x033, 0x00000009}, ++ {0x03E, 0x00005551}, ++ {0x03F, 0x00046AAA}, ++ {0x033, 0x0000000A}, ++ {0x03E, 0x00005551}, ++ {0x03F, 0x00046AAA}, ++ {0x033, 0x0000000B}, ++ {0x03E, 0x00005551}, ++ {0x03F, 0x0008C555}, ++ {0x033, 0x0000000C}, ++ {0x03E, 0x0000CCC1}, ++ {0x03F, 0x00081EB8}, ++ {0x033, 0x0000000D}, ++ {0x03E, 0x0000CCC1}, ++ {0x03F, 0x00071EB8}, ++ {0x033, 0x0000000E}, ++ {0x03E, 0x0000CCC1}, ++ {0x03F, 0x00090000}, ++ {0x033, 0x0000000F}, ++ {0x03E, 0x00006661}, ++ {0x03F, 0x00088000}, ++ {0x033, 0x00000010}, ++ {0x03E, 0x00006661}, ++ {0x03F, 0x00088000}, ++ {0x033, 0x00000011}, ++ {0x03E, 0x00006661}, ++ {0x03F, 0x000DB999}, ++ {0x0ED, 0x00000000}, ++ {0x0ED, 0x00002000}, ++ {0x033, 0x00000002}, ++ {0x03D, 0x0004A883}, ++ {0x03E, 0x00000000}, ++ {0x03F, 0x00000001}, ++ {0x033, 0x00000006}, ++ {0x03D, 0x0004A883}, ++ {0x03E, 0x00000000}, ++ {0x03F, 0x00000001}, ++ {0x0ED, 0x00000000}, ++ {0x018, 0x00001001}, ++ {0x002, 0x0000000D}, ++ {0x0EE, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0xA0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0xB0000000, 0x00000000}, ++ {0x0EE, 0x00000000}, ++ {0x08F, 0x000D0F7A}, ++ {0x08C, 0x00084584}, ++ {0x0EF, 0x00004000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000500}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000500}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00008B00}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00008B00}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00001000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00000015}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00000017}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00008000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x000FECFC}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x000BECFC}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x0003E4FC}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x0001D0FC}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x0001C3FC}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x000103FC}, ++ {0x033, 0x00000006}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x000FECFC}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x000BECFC}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x0003E4FC}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0001D0FC}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x0001C3FC}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x000103FC}, ++ {0x033, 0x0000000E}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x0000000F}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000010}, ++ {0x03F, 0x000FECFC}, ++ {0x033, 0x00000011}, ++ {0x03F, 0x000BECFC}, ++ {0x033, 0x00000012}, ++ {0x03F, 0x0003E4FC}, ++ {0x033, 0x00000013}, ++ {0x03F, 0x0001D0FC}, ++ {0x033, 0x00000014}, ++ {0x03F, 0x0001C3FC}, ++ {0x033, 0x00000015}, ++ {0x03F, 0x000103FC}, ++ {0x033, 0x00000016}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000017}, ++ {0x03F, 0x0000007C}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000100}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00003317}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x00003317}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x00003317}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001A}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001B}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001C}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001D}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001E}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001F}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000020}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000021}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000022}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000023}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000024}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000025}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000026}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000027}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000028}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000029}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002A}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002B}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002C}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002D}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002E}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002F}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000030}, ++ {0x03F, 0x00003338}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000040}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000006}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x000004BA}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000010}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x00000430}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000430}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x03F, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000080}, ++ {0x033, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F358}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F358}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000023}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000024}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000025}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000026}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000027}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EE, 0x00002000}, ++ {0x033, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000068}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000068}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000023}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000024}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000025}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000026}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000027}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000040}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000041}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000042}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000043}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000044}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000045}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000046}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000047}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000048}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000049}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000050}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000051}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000052}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000053}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000054}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000055}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000056}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000057}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000058}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000059}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000060}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000061}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000062}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000063}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000064}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000065}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000066}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000067}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000068}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000069}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000070}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000071}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000072}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000073}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000074}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000075}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000076}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000077}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000078}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000079}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000080}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000081}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000082}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000083}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000084}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000085}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000086}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000087}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x0EE, 0x00000000}, ++ {0x0EE, 0x00004000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00003BEF}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00003BE9}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x00003BE3}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x00003BDD}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x00003BD7}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x00003BD1}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00001BD9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000BD9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000859}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000859}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000819}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000819}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x03F, 0x000039EE}, ++ {0x033, 0x00000013}, ++ {0x03F, 0x000039E8}, ++ {0x033, 0x00000014}, ++ {0x03F, 0x000039E2}, ++ {0x033, 0x00000015}, ++ {0x03F, 0x000039DC}, ++ {0x033, 0x00000016}, ++ {0x03F, 0x000039D6}, ++ {0x033, 0x00000017}, ++ {0x03F, 0x000039D0}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x03F, 0x000019D2}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x03F, 0x000009D2}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x0000001E}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000023}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x00000024}, ++ {0x03F, 0x000039EE}, ++ {0x033, 0x00000025}, ++ {0x03F, 0x000039E8}, ++ {0x033, 0x00000026}, ++ {0x03F, 0x000039E2}, ++ {0x033, 0x00000027}, ++ {0x03F, 0x000039DC}, ++ {0x033, 0x00000028}, ++ {0x03F, 0x000039D6}, ++ {0x033, 0x00000029}, ++ {0x03F, 0x000039D0}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x03F, 0x000019D2}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x03F, 0x000009D2}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000030}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000035}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x00000036}, ++ {0x03F, 0x000039EE}, ++ {0x033, 0x00000037}, ++ {0x03F, 0x000039E8}, ++ {0x033, 0x00000038}, ++ {0x03F, 0x000039E2}, ++ {0x033, 0x00000039}, ++ {0x03F, 0x000039DC}, ++ {0x033, 0x0000003A}, ++ {0x03F, 0x000039D6}, ++ {0x033, 0x0000003B}, ++ {0x03F, 0x000039D0}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x03F, 0x000019D2}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x03F, 0x000009D2}, ++ {0x033, 0x00000040}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000041}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000042}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000043}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000044}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000045}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000046}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000047}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x00000048}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000049}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000050}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000051}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000052}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000053}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000054}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000055}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000056}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000057}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000058}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000059}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x0000005A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000060}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000061}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000062}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000063}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000064}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000065}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000066}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000067}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000068}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000069}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006A}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x0000006B}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x0000006C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000070}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000071}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000072}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000073}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000074}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000075}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000076}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000077}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000078}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000079}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007A}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x0000007B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007C}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x0000007D}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x0000007E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000080}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000081}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000082}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000083}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000084}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000085}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000086}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000087}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000088}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000089}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x0000008A}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x0000008B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000008C}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x0000008D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000008E}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x0000008F}, ++ {0x03F, 0x00000807}, ++ {0x0EE, 0x00000000}, ++ {0x0EF, 0x00080000}, ++ {0x033, 0x00000007}, ++ {0x03E, 0x00000001}, ++ {0x03F, 0x00020F3C}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00080000}, ++ {0x033, 0x0000000C}, ++ {0x03E, 0x00000001}, ++ {0x03F, 0x000305BC}, ++ {0x0EF, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000001}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0EC, 0x00000001}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x03C, 0x00000020}, ++ {0x03D, 0x00000078}, ++ {0x03E, 0x00080000}, ++ {0x03F, 0x00001999}, ++ {0x0EC, 0x00000000}, ++ {0x02F, 0x0002260D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000001}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0DE, 0x00000001}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000002}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00000002}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00000002}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000400}, ++ {0x033, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000023}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000024}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000025}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000026}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000027}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000200}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000006}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000E}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000F}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000010}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000011}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000012}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000013}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000014}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000015}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000016}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000017}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000018}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000019}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001A}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001B}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001C}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001D}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001E}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001F}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000020}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000021}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000022}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000023}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000024}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000025}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000026}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000027}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0xA0000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0xB0000000, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0xA0000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0xB0000000, 0x00000000}, ++ {0x06D, 0x00000C31}, ++ {0x0EF, 0x00020000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x000005FF}, ++ {0x0EF, 0x00000000}, ++ {0x005, 0x00000001}, ++ {0x0EF, 0x00080000}, ++ {0x033, 0x00000001}, ++ {0x03E, 0x00000001}, ++ {0x03F, 0x00022020}, ++ {0x0EF, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0xA0000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0xB0000000, 0x00000000}, ++ {0x002, 0x00000000}, ++ {0x067, 0x00000052}, ++ ++}; ++ ++static const struct rtw89_reg2_def rtw89_8852a_phy_radiob_regs[] = { ++ {0xF0010000, 0x00000000}, ++ {0xF0010001, 0x00000001}, ++ {0xF0020001, 0x00000002}, ++ {0xF0030001, 0x00000003}, ++ {0xF0250001, 0x00000004}, ++ {0xF0260001, 0x00000005}, ++ {0xF0320001, 0x00000006}, ++ {0xF0330001, 0x00000007}, ++ {0xF0340001, 0x00000008}, ++ {0xF0350001, 0x00000009}, ++ {0xF0360001, 0x0000000A}, ++ {0xF0010002, 0x0000000B}, ++ {0xF0020002, 0x0000000C}, ++ {0xF0030002, 0x0000000D}, ++ {0xF0250002, 0x0000000E}, ++ {0xF0260002, 0x0000000F}, ++ {0xF0320002, 0x00000010}, ++ {0xF0330002, 0x00000011}, ++ {0xF0340002, 0x00000012}, ++ {0xF0350002, 0x00000013}, ++ {0xF0360002, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000001}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x005, 0x00000001}, ++ {0xB0000000, 0x00000000}, ++ {0x000, 0x00030000}, ++ {0x018, 0x00011124}, ++ {0x000, 0x00033C00}, ++ {0x01A, 0x00040004}, ++ {0x0FE, 0x00000000}, ++ {0x055, 0x00080000}, ++ {0x056, 0x0008FFF0}, ++ {0x057, 0x0000C485}, ++ {0x058, 0x000A4164}, ++ {0x059, 0x00010000}, ++ {0x05A, 0x00060000}, ++ {0x05B, 0x0000A000}, ++ {0x05C, 0x00000000}, ++ {0x05D, 0x0001C013}, ++ {0x05E, 0x00000000}, ++ {0x05F, 0x00001FF0}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0xA0000000, 0x00000000}, ++ {0x060, 0x00011000}, ++ {0xB0000000, 0x00000000}, ++ {0x061, 0x0009F338}, ++ {0x062, 0x0009233A}, ++ {0x063, 0x000D6002}, ++ {0x064, 0x000A0CB0}, ++ {0x065, 0x00030EFE}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0xA0000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0xB0000000, 0x00000000}, ++ {0x068, 0x00000000}, ++ {0x069, 0x00030F0A}, ++ {0x06A, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000AD6A4}, ++ {0x052, 0x00091345}, ++ {0x053, 0x00080081}, ++ {0x054, 0x0007BC24}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0xA0000000, 0x00000000}, ++ {0x051, 0x000AD6A4}, ++ {0x052, 0x00091345}, ++ {0x053, 0x00080081}, ++ {0x054, 0x0007BC24}, ++ {0xB0000000, 0x00000000}, ++ {0x0D3, 0x00000143}, ++ {0x043, 0x00005000}, ++ {0x0DD, 0x000003A0}, ++ {0x0B0, 0x000E6700}, ++ {0x0AF, 0x0001F82E}, ++ {0x0B2, 0x000210A7}, ++ {0x0B1, 0x00065FFF}, ++ {0x0BB, 0x000F7A00}, ++ {0x0B3, 0x00013F7A}, ++ {0x0D4, 0x0000000E}, ++ {0x0B7, 0x00001E0C}, ++ {0x0A0, 0x0000004F}, ++ {0x0B4, 0x0007C03E}, ++ {0x0B5, 0x0007E301}, ++ {0x0B6, 0x00080800}, ++ {0x0CA, 0x00002000}, ++ {0x0DD, 0x000003A0}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x00080000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0xA0000000, 0x00000000}, ++ {0x0CC, 0x00080000}, ++ {0xB0000000, 0x00000000}, ++ {0x0A1, 0x0006F300}, ++ {0x0A2, 0x00080500}, ++ {0x0A3, 0x0008050B}, ++ {0x0A4, 0x0006DB12}, ++ {0x0A5, 0x00000000}, ++ {0x0A6, 0x00000000}, ++ {0x0A7, 0x00000000}, ++ {0x0A8, 0x00000000}, ++ {0x0A9, 0x00000000}, ++ {0x0AA, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x000B0000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0A5, 0x000B0000}, ++ {0xB0000000, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00008000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0ED, 0x00008000}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000000}, ++ {0x03E, 0x00008000}, ++ {0x03F, 0x000E1333}, ++ {0x033, 0x00000001}, ++ {0x03E, 0x00008000}, ++ {0x03F, 0x000E7333}, ++ {0x033, 0x00000002}, ++ {0x03E, 0x00008000}, ++ {0x03F, 0x000FA000}, ++ {0x033, 0x00000003}, ++ {0x03E, 0x00004000}, ++ {0x03F, 0x000FA400}, ++ {0x033, 0x00000004}, ++ {0x03E, 0x00004000}, ++ {0x03F, 0x000F5000}, ++ {0x033, 0x00000005}, ++ {0x03E, 0x00004001}, ++ {0x03F, 0x00029400}, ++ {0x033, 0x00000006}, ++ {0x03E, 0x0000AAA1}, ++ {0x03F, 0x00041999}, ++ {0x033, 0x00000007}, ++ {0x03E, 0x0000AAA1}, ++ {0x03F, 0x00034444}, ++ {0x033, 0x00000008}, ++ {0x03E, 0x0000AAA1}, ++ {0x03F, 0x0004D555}, ++ {0x033, 0x00000009}, ++ {0x03E, 0x00005551}, ++ {0x03F, 0x00046AAA}, ++ {0x033, 0x0000000A}, ++ {0x03E, 0x00005551}, ++ {0x03F, 0x00046AAA}, ++ {0x033, 0x0000000B}, ++ {0x03E, 0x00005551}, ++ {0x03F, 0x0008C555}, ++ {0x033, 0x0000000C}, ++ {0x03E, 0x0000CCC1}, ++ {0x03F, 0x00081EB8}, ++ {0x033, 0x0000000D}, ++ {0x03E, 0x0000CCC1}, ++ {0x03F, 0x00071EB8}, ++ {0x033, 0x0000000E}, ++ {0x03E, 0x0000CCC1}, ++ {0x03F, 0x00090000}, ++ {0x033, 0x0000000F}, ++ {0x03E, 0x00006661}, ++ {0x03F, 0x00088000}, ++ {0x033, 0x00000010}, ++ {0x03E, 0x00006661}, ++ {0x03F, 0x00088000}, ++ {0x033, 0x00000011}, ++ {0x03E, 0x00006661}, ++ {0x03F, 0x000DB999}, ++ {0x0ED, 0x00000000}, ++ {0x0ED, 0x00002000}, ++ {0x033, 0x00000002}, ++ {0x03D, 0x0004A883}, ++ {0x03E, 0x00000000}, ++ {0x03F, 0x00000001}, ++ {0x033, 0x00000006}, ++ {0x03D, 0x0004A883}, ++ {0x03E, 0x00000000}, ++ {0x03F, 0x00000001}, ++ {0x0ED, 0x00000000}, ++ {0x018, 0x00001001}, ++ {0x002, 0x0000000D}, ++ {0x0EE, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0xA0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0xB0000000, 0x00000000}, ++ {0x0EE, 0x00000000}, ++ {0x08F, 0x000D0F7A}, ++ {0x08C, 0x00084584}, ++ {0x0EF, 0x00004000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000500}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000500}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00008B00}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00008B00}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00001000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00000015}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00000017}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x00000015}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x00000017}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00008000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x000FECFC}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x000BECFC}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x0003E4FC}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x0001D0FC}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x0001C3FC}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x000103FC}, ++ {0x033, 0x00000006}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x000FECFC}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x000BECFC}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x0003E4FC}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0001D0FC}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x0001C3FC}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x000103FC}, ++ {0x033, 0x0000000E}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x0000000F}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000010}, ++ {0x03F, 0x000FECFC}, ++ {0x033, 0x00000011}, ++ {0x03F, 0x000BECFC}, ++ {0x033, 0x00000012}, ++ {0x03F, 0x0003E4FC}, ++ {0x033, 0x00000013}, ++ {0x03F, 0x0001D0FC}, ++ {0x033, 0x00000014}, ++ {0x03F, 0x0001C3FC}, ++ {0x033, 0x00000015}, ++ {0x03F, 0x000103FC}, ++ {0x033, 0x00000016}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000017}, ++ {0x03F, 0x0000007C}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000100}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00003317}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x00003317}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x00003317}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001A}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001B}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001C}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001D}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001E}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001F}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000020}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000021}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000022}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000023}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000024}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000025}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000026}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000027}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000028}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000029}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002A}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002B}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002C}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002D}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002E}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002F}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000030}, ++ {0x03F, 0x00003338}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000040}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000006}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x000004BA}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000010}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x00000430}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000430}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x03F, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000080}, ++ {0x033, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F258}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F258}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000023}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000024}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000025}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000026}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000027}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F358}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F358}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EE, 0x00002000}, ++ {0x033, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000068}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000068}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000023}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000024}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000025}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000026}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000027}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000040}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000041}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000042}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000043}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000044}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000045}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000046}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000047}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000048}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000049}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000050}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000051}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000052}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000053}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000054}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000055}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000056}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000057}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000058}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000059}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000060}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000061}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000062}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000063}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000064}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000065}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000066}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000067}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000068}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000069}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000070}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000071}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000072}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000073}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000074}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000075}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000076}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000077}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000078}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000079}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000080}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000081}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000082}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000083}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000084}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000085}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000086}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000087}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x0EE, 0x00000000}, ++ {0x0EE, 0x00004000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00003BEF}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00003BE9}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x00003BE3}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x00003BDD}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x00003BD7}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x00003BD1}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00001BD9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000BD9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000859}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000859}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000819}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000819}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x03F, 0x000039EE}, ++ {0x033, 0x00000013}, ++ {0x03F, 0x000039E8}, ++ {0x033, 0x00000014}, ++ {0x03F, 0x000039E2}, ++ {0x033, 0x00000015}, ++ {0x03F, 0x000039DC}, ++ {0x033, 0x00000016}, ++ {0x03F, 0x000039D6}, ++ {0x033, 0x00000017}, ++ {0x03F, 0x000039D0}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x03F, 0x000019D2}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x03F, 0x000009D2}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x0000001E}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000023}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x00000024}, ++ {0x03F, 0x000039EE}, ++ {0x033, 0x00000025}, ++ {0x03F, 0x000039E8}, ++ {0x033, 0x00000026}, ++ {0x03F, 0x000039E2}, ++ {0x033, 0x00000027}, ++ {0x03F, 0x000039DC}, ++ {0x033, 0x00000028}, ++ {0x03F, 0x000039D6}, ++ {0x033, 0x00000029}, ++ {0x03F, 0x000039D0}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x03F, 0x000019D2}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x03F, 0x000009D2}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000030}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000035}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x00000036}, ++ {0x03F, 0x000039EE}, ++ {0x033, 0x00000037}, ++ {0x03F, 0x000039E8}, ++ {0x033, 0x00000038}, ++ {0x03F, 0x000039E2}, ++ {0x033, 0x00000039}, ++ {0x03F, 0x000039DC}, ++ {0x033, 0x0000003A}, ++ {0x03F, 0x000039D6}, ++ {0x033, 0x0000003B}, ++ {0x03F, 0x000039D0}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x03F, 0x000019D2}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x03F, 0x000009D2}, ++ {0x033, 0x00000040}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000041}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000042}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000043}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000044}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000045}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000046}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000047}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x00000048}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000049}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000050}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000051}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000052}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000053}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000054}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000055}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000056}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000057}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000058}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000059}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x0000005A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000060}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000061}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000062}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000063}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000064}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000065}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000066}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000067}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000068}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000069}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006A}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x0000006B}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x0000006C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000070}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000071}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000072}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000073}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000074}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000075}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000076}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000077}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000078}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000079}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007A}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x0000007B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007C}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x0000007D}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x0000007E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000080}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000081}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000082}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000083}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000084}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000085}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000086}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000087}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000088}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000089}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x0000008A}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x0000008B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000008C}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x0000008D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000008E}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x0000008F}, ++ {0x03F, 0x00000807}, ++ {0x0EE, 0x00000000}, ++ {0x0EF, 0x00080000}, ++ {0x033, 0x00000007}, ++ {0x03E, 0x00000001}, ++ {0x03F, 0x00020F3C}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00080000}, ++ {0x033, 0x0000000C}, ++ {0x03E, 0x00000001}, ++ {0x03F, 0x000305BC}, ++ {0x0EF, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000001}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0EC, 0x00000001}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x03C, 0x00000020}, ++ {0x03D, 0x00000078}, ++ {0x03E, 0x00080000}, ++ {0x03F, 0x00001999}, ++ {0x0EC, 0x00000000}, ++ {0x02F, 0x0002260D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000001}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0DE, 0x00000001}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000002}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00000002}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00000002}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000400}, ++ {0x033, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000023}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000024}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000025}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000026}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000027}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000200}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000006}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000E}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000F}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000010}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000011}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000012}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000013}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000014}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000015}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000016}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000017}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000018}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000019}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001A}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001B}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001C}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001D}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001E}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001F}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000020}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000021}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000022}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000023}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000024}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000025}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000026}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000027}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0xA0000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0xB0000000, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0xA0000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0xB0000000, 0x00000000}, ++ {0x06D, 0x00000C31}, ++ {0x0EF, 0x00020000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x000005FF}, ++ {0x0EF, 0x00000000}, ++ {0x0A0, 0x00000043}, ++ {0x005, 0x00000001}, ++ {0x0EF, 0x00080000}, ++ {0x033, 0x00000001}, ++ {0x03E, 0x00000001}, ++ {0x03F, 0x00022020}, ++ {0x0EF, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0xA0000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0xB0000000, 0x00000000}, ++ {0x002, 0x00000000}, ++ {0x067, 0x00000052}, ++ ++}; ++ ++static const struct rtw89_reg2_def rtw89_8852a_phy_nctl_regs[] = { ++ {0x8000, 0x00000008}, ++ {0x8008, 0x00000000}, ++ {0x8004, 0xf0862966}, ++ {0x800c, 0x78000000}, ++ {0x8010, 0x88015000}, ++ {0x8014, 0x80010100}, ++ {0x8018, 0x10010100}, ++ {0x801c, 0xa210bc00}, ++ {0x8020, 0x000403e0}, ++ {0x8024, 0x00072160}, ++ {0x8028, 0x00180e00}, ++ {0x8030, 0x400000c0}, ++ {0x8034, 0x56000800}, ++ {0x8038, 0x00000009}, ++ {0x803c, 0x00000008}, ++ {0x8040, 0x00000046}, ++ {0x8044, 0x0010001f}, ++ {0x8048, 0xf0000003}, ++ {0x804c, 0x62ac6162}, ++ {0x8050, 0xf2acf162}, ++ {0x8054, 0x62ac6162}, ++ {0x8058, 0xf2acf162}, ++ {0x805c, 0x150c0b02}, ++ {0x8060, 0x150c0b02}, ++ {0x8064, 0x2aa00047}, ++ {0x8074, 0x80000000}, ++ {0x807c, 0x000000ee}, ++ {0x8088, 0x80000000}, ++ {0x8098, 0x0000ff00}, ++ {0x809c, 0x0000001f}, ++ {0x80a0, 0x00010300}, ++ {0x80b0, 0x00000000}, ++ {0x80d0, 0x00000000}, ++ {0x8114, 0x00000000}, ++ {0x8120, 0x10010000}, ++ {0x8124, 0x00000000}, ++ {0x812c, 0x0000c000}, ++ {0x8138, 0x40000002}, ++ {0x813c, 0x40000002}, ++ {0x8140, 0x00000000}, ++ {0x8144, 0x0b040b03}, ++ {0x8148, 0x0b040b04}, ++ {0x814c, 0x0b040b03}, ++ {0x8150, 0x00000000}, ++ {0x8158, 0xffffffff}, ++ {0x815c, 0xffffffff}, ++ {0x8160, 0xffffffff}, ++ {0x8164, 0xffffffff}, ++ {0x8168, 0xffffffff}, ++ {0x816c, 0x1fffffff}, ++ {0x81ac, 0x003f1a00}, ++ {0x81b0, 0x003f1a00}, ++ {0x81bc, 0x005b5b5b}, ++ {0x81c0, 0x005b5b5b}, ++ {0x81b4, 0x00600060}, ++ {0x81b8, 0x00600060}, ++ {0x81cc, 0x00000000}, ++ {0x81dc, 0x00000002}, ++ {0x8214, 0x00000000}, ++ {0x8220, 0x10010000}, ++ {0x8224, 0x00000000}, ++ {0x822c, 0x0000d000}, ++ {0x8238, 0x40000002}, ++ {0x823c, 0x40000002}, ++ {0x8240, 0x00000000}, ++ {0x8244, 0x0b040b03}, ++ {0x8248, 0x0b040b03}, ++ {0x824c, 0x0b030b03}, ++ {0x8250, 0x00000000}, ++ {0x8258, 0xffffffff}, ++ {0x825c, 0xffffffff}, ++ {0x8260, 0xffffffff}, ++ {0x8264, 0xffffffff}, ++ {0x8268, 0xffffffff}, ++ {0x826c, 0x1fffffff}, ++ {0x82ac, 0x003f1a00}, ++ {0x82b0, 0x003f1a00}, ++ {0x82bc, 0x005b5b5b}, ++ {0x82c0, 0x005b5b5b}, ++ {0x82b4, 0x00600060}, ++ {0x82b8, 0x00600060}, ++ {0x82cc, 0x00000000}, ++ {0x82dc, 0x00000002}, ++ {0x81d8, 0x00000001}, ++ {0x82d8, 0x00000001}, ++ {0x8d00, 0x00000000}, ++ {0x8d04, 0x00000000}, ++ {0x8d08, 0x00000000}, ++ {0x8d0c, 0x00000000}, ++ {0x8d10, 0x00000000}, ++ {0x8d14, 0x00000000}, ++ {0x8d18, 0x00000000}, ++ {0x8d1c, 0x00000000}, ++ {0x8d20, 0x00000000}, ++ {0x8d24, 0x00000000}, ++ {0x8d28, 0x00000000}, ++ {0x8d2c, 0x00000000}, ++ {0x8d30, 0x00000000}, ++ {0x8d34, 0x00000000}, ++ {0x8d38, 0x00000000}, ++ {0x8d3c, 0x00000000}, ++ {0x8d40, 0x00000000}, ++ {0x8d44, 0x00000000}, ++ {0x8d48, 0x00000000}, ++ {0x8d4c, 0x00000000}, ++ {0x8d50, 0x00000000}, ++ {0x8d54, 0x00000000}, ++ {0x8d58, 0x00000000}, ++ {0x8d5c, 0x00000000}, ++ {0x8d60, 0x00000000}, ++ {0x8d64, 0x00000000}, ++ {0x8d68, 0x00000000}, ++ {0x8d6c, 0x00000000}, ++ {0x8d70, 0x00000000}, ++ {0x8d74, 0x00000000}, ++ {0x8d78, 0x00000000}, ++ {0x8d7c, 0x00000000}, ++ {0x8d80, 0x00000000}, ++ {0x8d84, 0x00000000}, ++ {0x8d88, 0x00000000}, ++ {0x8d8c, 0x00000000}, ++ {0x8d90, 0x00000000}, ++ {0x8d94, 0x00000000}, ++ {0x8d98, 0x00000000}, ++ {0x8d9c, 0x00000000}, ++ {0x8da0, 0x00000000}, ++ {0x8da4, 0x00000000}, ++ {0x8da8, 0x00000000}, ++ {0x8dac, 0x00000000}, ++ {0x8db0, 0x00000000}, ++ {0x8db4, 0x00000000}, ++ {0x8db8, 0x00000000}, ++ {0x8dbc, 0x00000000}, ++ {0x8dc0, 0x00000000}, ++ {0x8dc4, 0x00000000}, ++ {0x8dc8, 0x00000000}, ++ {0x8dcc, 0x00000000}, ++ {0x8dd0, 0x00000000}, ++ {0x8dd4, 0x00000000}, ++ {0x8dd8, 0x00000000}, ++ {0x8ddc, 0x00000000}, ++ {0x8de0, 0x00000000}, ++ {0x8de4, 0x00000000}, ++ {0x8de8, 0x00000000}, ++ {0x8dec, 0x00000000}, ++ {0x8df0, 0x00000000}, ++ {0x8df4, 0x00000000}, ++ {0x8df8, 0x00000000}, ++ {0x8dfc, 0x00000000}, ++ {0x8e00, 0x00000000}, ++ {0x8e04, 0x00000000}, ++ {0x8e08, 0x00000000}, ++ {0x8e0c, 0x00000000}, ++ {0x8e10, 0x00000000}, ++ {0x8e14, 0x00000000}, ++ {0x8e18, 0x00000000}, ++ {0x8e1c, 0x00000000}, ++ {0x8e20, 0x00000000}, ++ {0x8e24, 0x00000000}, ++ {0x8e28, 0x00000000}, ++ {0x8e2c, 0x00000000}, ++ {0x8e30, 0x00000000}, ++ {0x8e34, 0x00000000}, ++ {0x8e38, 0x00000000}, ++ {0x8e3c, 0x00000000}, ++ {0x8e40, 0x00000000}, ++ {0x8e44, 0x00000000}, ++ {0x8e48, 0x00000000}, ++ {0x8e4c, 0x00000000}, ++ {0x8e50, 0x00000000}, ++ {0x8e54, 0x00000000}, ++ {0x8e58, 0x00000000}, ++ {0x8e5c, 0x00000000}, ++ {0x8e60, 0x00000000}, ++ {0x8e64, 0x00000000}, ++ {0x8e68, 0x00000000}, ++ {0x8e6c, 0x00000000}, ++ {0x8e70, 0x00000000}, ++ {0x8e74, 0x00000000}, ++ {0x8e78, 0x00000000}, ++ {0x8e7c, 0x00000000}, ++ {0x8e80, 0x00000000}, ++ {0x8e84, 0x00000000}, ++ {0x8e88, 0x00000000}, ++ {0x8e8c, 0x00000000}, ++ {0x8e90, 0x00000000}, ++ {0x8e94, 0x00000000}, ++ {0x8e98, 0x00000000}, ++ {0x8e9c, 0x00000000}, ++ {0x8ea0, 0x00000000}, ++ {0x8ea4, 0x00000000}, ++ {0x8ea8, 0x00000000}, ++ {0x8eac, 0x00000000}, ++ {0x8eb0, 0x00000000}, ++ {0x8eb4, 0x00000000}, ++ {0x8eb8, 0x00000000}, ++ {0x8ebc, 0x00000000}, ++ {0x8ec0, 0x00000000}, ++ {0x8ec4, 0x00000000}, ++ {0x8ec8, 0x00000000}, ++ {0x8ecc, 0x00000000}, ++ {0x8ed0, 0x00000000}, ++ {0x8ed4, 0x00000000}, ++ {0x8ed8, 0x00000000}, ++ {0x8edc, 0x00000000}, ++ {0x8ee0, 0x00000000}, ++ {0x8ee4, 0x00000000}, ++ {0x8ee8, 0x00000000}, ++ {0x8eec, 0x00000000}, ++ {0x8ef0, 0x00000000}, ++ {0x8ef4, 0x00000000}, ++ {0x8ef8, 0x00000000}, ++ {0x8efc, 0x00000000}, ++ {0x8f00, 0x00000000}, ++ {0x8f04, 0x00000000}, ++ {0x8f08, 0x00000000}, ++ {0x8f0c, 0x00000000}, ++ {0x8f10, 0x00000000}, ++ {0x8f14, 0x00000000}, ++ {0x8f18, 0x00000000}, ++ {0x8f1c, 0x00000000}, ++ {0x8f20, 0x00000000}, ++ {0x8f24, 0x00000000}, ++ {0x8f28, 0x00000000}, ++ {0x8f2c, 0x00000000}, ++ {0x8f30, 0x00000000}, ++ {0x8f34, 0x00000000}, ++ {0x8f38, 0x00000000}, ++ {0x8f3c, 0x00000000}, ++ {0x8f40, 0x00000000}, ++ {0x8f44, 0x00000000}, ++ {0x8f48, 0x00000000}, ++ {0x8f4c, 0x00000000}, ++ {0x8f50, 0x00000000}, ++ {0x8f54, 0x00000000}, ++ {0x8f58, 0x00000000}, ++ {0x8f5c, 0x00000000}, ++ {0x8f60, 0x00000000}, ++ {0x8f64, 0x00000000}, ++ {0x8f68, 0x00000000}, ++ {0x8f6c, 0x00000000}, ++ {0x8f70, 0x00000000}, ++ {0x8f74, 0x00000000}, ++ {0x8f78, 0x00000000}, ++ {0x8f7c, 0x00000000}, ++ {0x8f80, 0x00000000}, ++ {0x8f84, 0x00000000}, ++ {0x8f88, 0x00000000}, ++ {0x8f8c, 0x00000000}, ++ {0x8f90, 0x00000000}, ++ {0x8f94, 0x00000000}, ++ {0x8f98, 0x00000000}, ++ {0x8f9c, 0x00000000}, ++ {0x8fa0, 0x00000000}, ++ {0x8fa4, 0x00000000}, ++ {0x8fa8, 0x00000000}, ++ {0x8fac, 0x00000000}, ++ {0x8fb0, 0x00000000}, ++ {0x8fb4, 0x00000000}, ++ {0x8fb8, 0x00000000}, ++ {0x8fbc, 0x00000000}, ++ {0x8fc0, 0x00000000}, ++ {0x8fc4, 0x00000000}, ++ {0x8fc8, 0x00000000}, ++ {0x8fcc, 0x00000000}, ++ {0x8fd0, 0x00000000}, ++ {0x8fd4, 0x00000000}, ++ {0x8fd8, 0x00000000}, ++ {0x8fdc, 0x00000000}, ++ {0x8fe0, 0x00000000}, ++ {0x8fe4, 0x00000000}, ++ {0x8fe8, 0x00000000}, ++ {0x8fec, 0x00000000}, ++ {0x8ff0, 0x00000000}, ++ {0x8ff4, 0x00000000}, ++ {0x8ff8, 0x00000000}, ++ {0x8ffc, 0x00000000}, ++ {0x9000, 0x00000000}, ++ {0x9004, 0x00000000}, ++ {0x9008, 0x00000000}, ++ {0x900c, 0x00000000}, ++ {0x9010, 0x00000000}, ++ {0x9014, 0x00000000}, ++ {0x9018, 0x00000000}, ++ {0x901c, 0x00000000}, ++ {0x9020, 0x00000000}, ++ {0x9024, 0x00000000}, ++ {0x9028, 0x00000000}, ++ {0x902c, 0x00000000}, ++ {0x9030, 0x00000000}, ++ {0x9034, 0x00000000}, ++ {0x9038, 0x00000000}, ++ {0x903c, 0x00000000}, ++ {0x9040, 0x00000000}, ++ {0x9044, 0x00000000}, ++ {0x9048, 0x00000000}, ++ {0x904c, 0x00000000}, ++ {0x9050, 0x00000000}, ++ {0x9054, 0x00000000}, ++ {0x9058, 0x00000000}, ++ {0x905c, 0x00000000}, ++ {0x9060, 0x00000000}, ++ {0x9064, 0x00000000}, ++ {0x9068, 0x00000000}, ++ {0x906c, 0x00000000}, ++ {0x9070, 0x00000000}, ++ {0x9074, 0x00000000}, ++ {0x9078, 0x00000000}, ++ {0x907c, 0x00000000}, ++ {0x9080, 0x00000000}, ++ {0x9084, 0x00000000}, ++ {0x9088, 0x00000000}, ++ {0x908c, 0x00000000}, ++ {0x9090, 0x00000000}, ++ {0x9094, 0x00000000}, ++ {0x9098, 0x00000000}, ++ {0x909c, 0x00000000}, ++ {0x90a0, 0x00000000}, ++ {0x90a4, 0x00000000}, ++ {0x90a8, 0x00000000}, ++ {0x90ac, 0x00000000}, ++ {0x90b0, 0x00000000}, ++ {0x90b4, 0x00000000}, ++ {0x90b8, 0x00000000}, ++ {0x90bc, 0x00000000}, ++ {0x9100, 0x00000000}, ++ {0x9104, 0x00000000}, ++ {0x9108, 0x00000000}, ++ {0x910c, 0x00000000}, ++ {0x9110, 0x00000000}, ++ {0x9114, 0x00000000}, ++ {0x9118, 0x00000000}, ++ {0x911c, 0x00000000}, ++ {0x9120, 0x00000000}, ++ {0x9124, 0x00000000}, ++ {0x9128, 0x00000000}, ++ {0x912c, 0x00000000}, ++ {0x9130, 0x00000000}, ++ {0x9134, 0x00000000}, ++ {0x9138, 0x00000000}, ++ {0x913c, 0x00000000}, ++ {0x9140, 0x00000000}, ++ {0x9144, 0x00000000}, ++ {0x9148, 0x00000000}, ++ {0x914c, 0x00000000}, ++ {0x9150, 0x00000000}, ++ {0x9154, 0x00000000}, ++ {0x9158, 0x00000000}, ++ {0x915c, 0x00000000}, ++ {0x9160, 0x00000000}, ++ {0x9164, 0x00000000}, ++ {0x9168, 0x00000000}, ++ {0x916c, 0x00000000}, ++ {0x9170, 0x00000000}, ++ {0x9174, 0x00000000}, ++ {0x9178, 0x00000000}, ++ {0x917c, 0x00000000}, ++ {0x9180, 0x00000000}, ++ {0x9184, 0x00000000}, ++ {0x9188, 0x00000000}, ++ {0x918c, 0x00000000}, ++ {0x9190, 0x00000000}, ++ {0x9194, 0x00000000}, ++ {0x9198, 0x00000000}, ++ {0x919c, 0x00000000}, ++ {0x91a0, 0x00000000}, ++ {0x91a4, 0x00000000}, ++ {0x91a8, 0x00000000}, ++ {0x91ac, 0x00000000}, ++ {0x91b0, 0x00000000}, ++ {0x91b4, 0x00000000}, ++ {0x91b8, 0x00000000}, ++ {0x91bc, 0x00000000}, ++ {0x91c0, 0x00000000}, ++ {0x91c4, 0x00000000}, ++ {0x91c8, 0x00000000}, ++ {0x91cc, 0x00000000}, ++ {0x91d0, 0x00000000}, ++ {0x91d4, 0x00000000}, ++ {0x91d8, 0x00000000}, ++ {0x91dc, 0x00000000}, ++ {0x91e0, 0x00000000}, ++ {0x91e4, 0x00000000}, ++ {0x91e8, 0x00000000}, ++ {0x91ec, 0x00000000}, ++ {0x91f0, 0x00000000}, ++ {0x91f4, 0x00000000}, ++ {0x91f8, 0x00000000}, ++ {0x91fc, 0x00000000}, ++ {0x9200, 0x00000000}, ++ {0x9204, 0x00000000}, ++ {0x9208, 0x00000000}, ++ {0x920c, 0x00000000}, ++ {0x9210, 0x00000000}, ++ {0x9214, 0x00000000}, ++ {0x9218, 0x00000000}, ++ {0x921c, 0x00000000}, ++ {0x9220, 0x00000000}, ++ {0x9224, 0x00000000}, ++ {0x9228, 0x00000000}, ++ {0x922c, 0x00000000}, ++ {0x9230, 0x00000000}, ++ {0x9234, 0x00000000}, ++ {0x9238, 0x00000000}, ++ {0x923c, 0x00000000}, ++ {0x9240, 0x00000000}, ++ {0x9244, 0x00000000}, ++ {0x9248, 0x00000000}, ++ {0x924c, 0x00000000}, ++ {0x9250, 0x00000000}, ++ {0x9254, 0x00000000}, ++ {0x9258, 0x00000000}, ++ {0x925c, 0x00000000}, ++ {0x9260, 0x00000000}, ++ {0x9264, 0x00000000}, ++ {0x9268, 0x00000000}, ++ {0x926c, 0x00000000}, ++ {0x9270, 0x00000000}, ++ {0x9274, 0x00000000}, ++ {0x9278, 0x00000000}, ++ {0x927c, 0x00000000}, ++ {0x9280, 0x00000000}, ++ {0x9284, 0x00000000}, ++ {0x9288, 0x00000000}, ++ {0x928c, 0x00000000}, ++ {0x9290, 0x00000000}, ++ {0x9294, 0x00000000}, ++ {0x9298, 0x00000000}, ++ {0x929c, 0x00000000}, ++ {0x92a0, 0x00000000}, ++ {0x92a4, 0x00000000}, ++ {0x92a8, 0x00000000}, ++ {0x92ac, 0x00000000}, ++ {0x92b0, 0x00000000}, ++ {0x92b4, 0x00000000}, ++ {0x92b8, 0x00000000}, ++ {0x92bc, 0x00000000}, ++ {0x92c0, 0x00000000}, ++ {0x92c4, 0x00000000}, ++ {0x92c8, 0x00000000}, ++ {0x92cc, 0x00000000}, ++ {0x92d0, 0x00000000}, ++ {0x92d4, 0x00000000}, ++ {0x92d8, 0x00000000}, ++ {0x92dc, 0x00000000}, ++ {0x92e0, 0x00000000}, ++ {0x92e4, 0x00000000}, ++ {0x92e8, 0x00000000}, ++ {0x92ec, 0x00000000}, ++ {0x92f0, 0x00000000}, ++ {0x92f4, 0x00000000}, ++ {0x92f8, 0x00000000}, ++ {0x92fc, 0x00000000}, ++ {0x9300, 0x00000000}, ++ {0x9304, 0x00000000}, ++ {0x9308, 0x00000000}, ++ {0x930c, 0x00000000}, ++ {0x9310, 0x00000000}, ++ {0x9314, 0x00000000}, ++ {0x9318, 0x00000000}, ++ {0x931c, 0x00000000}, ++ {0x9320, 0x00000000}, ++ {0x9324, 0x00000000}, ++ {0x9328, 0x00000000}, ++ {0x932c, 0x00000000}, ++ {0x9330, 0x00000000}, ++ {0x9334, 0x00000000}, ++ {0x9338, 0x00000000}, ++ {0x933c, 0x00000000}, ++ {0x9340, 0x00000000}, ++ {0x9344, 0x00000000}, ++ {0x9348, 0x00000000}, ++ {0x934c, 0x00000000}, ++ {0x9350, 0x00000000}, ++ {0x9354, 0x00000000}, ++ {0x9358, 0x00000000}, ++ {0x935c, 0x00000000}, ++ {0x9360, 0x00000000}, ++ {0x9364, 0x00000000}, ++ {0x9368, 0x00000000}, ++ {0x936c, 0x00000000}, ++ {0x9370, 0x00000000}, ++ {0x9374, 0x00000000}, ++ {0x9378, 0x00000000}, ++ {0x937c, 0x00000000}, ++ {0x9380, 0x00000000}, ++ {0x9384, 0x00000000}, ++ {0x9388, 0x00000000}, ++ {0x938c, 0x00000000}, ++ {0x9390, 0x00000000}, ++ {0x9394, 0x00000000}, ++ {0x9398, 0x00000000}, ++ {0x939c, 0x00000000}, ++ {0x93a0, 0x00000000}, ++ {0x93a4, 0x00000000}, ++ {0x93a8, 0x00000000}, ++ {0x93ac, 0x00000000}, ++ {0x93b0, 0x00000000}, ++ {0x93b4, 0x00000000}, ++ {0x93b8, 0x00000000}, ++ {0x93bc, 0x00000000}, ++ {0x93c0, 0x00000000}, ++ {0x93c4, 0x00000000}, ++ {0x93c8, 0x00000000}, ++ {0x93cc, 0x00000000}, ++ {0x93d0, 0x00000000}, ++ {0x93d4, 0x00000000}, ++ {0x93d8, 0x00000000}, ++ {0x93dc, 0x00000000}, ++ {0x93e0, 0x00000000}, ++ {0x93e4, 0x00000000}, ++ {0x93e8, 0x00000000}, ++ {0x93ec, 0x00000000}, ++ {0x93f0, 0x00000000}, ++ {0x93f4, 0x00000000}, ++ {0x93f8, 0x00000000}, ++ {0x93fc, 0x00000000}, ++ {0x9400, 0x00000000}, ++ {0x9404, 0x00000000}, ++ {0x9408, 0x00000000}, ++ {0x940c, 0x00000000}, ++ {0x9410, 0x00000000}, ++ {0x9414, 0x00000000}, ++ {0x9418, 0x00000000}, ++ {0x941c, 0x00000000}, ++ {0x9420, 0x00000000}, ++ {0x9424, 0x00000000}, ++ {0x9428, 0x00000000}, ++ {0x942c, 0x00000000}, ++ {0x9430, 0x00000000}, ++ {0x9434, 0x00000000}, ++ {0x9438, 0x00000000}, ++ {0x943c, 0x00000000}, ++ {0x9440, 0x00000000}, ++ {0x9444, 0x00000000}, ++ {0x9448, 0x00000000}, ++ {0x944c, 0x00000000}, ++ {0x9450, 0x00000000}, ++ {0x9454, 0x00000000}, ++ {0x9458, 0x00000000}, ++ {0x945c, 0x00000000}, ++ {0x9460, 0x00000000}, ++ {0x9464, 0x00000000}, ++ {0x9468, 0x00000000}, ++ {0x946c, 0x00000000}, ++ {0x9470, 0x00000000}, ++ {0x9474, 0x00000000}, ++ {0x9478, 0x00000000}, ++ {0x947c, 0x00000000}, ++ {0x9480, 0x00000000}, ++ {0x9484, 0x00000000}, ++ {0x9488, 0x00000000}, ++ {0x948c, 0x00000000}, ++ {0x9490, 0x00000000}, ++ {0x9494, 0x00000000}, ++ {0x9498, 0x00000000}, ++ {0x949c, 0x00000000}, ++ {0x94a0, 0x00000000}, ++ {0x94a4, 0x00000000}, ++ {0x94a8, 0x00000000}, ++ {0x94ac, 0x00000000}, ++ {0x94b0, 0x00000000}, ++ {0x94b4, 0x00000000}, ++ {0x94b8, 0x00000000}, ++ {0x94bc, 0x00000000}, ++ {0x81d8, 0x00000000}, ++ {0x82d8, 0x00000000}, ++ {0x9f04, 0x2b251f19}, ++ {0x9f08, 0x433d3731}, ++ {0x9f0c, 0x5b554f49}, ++ {0x9f10, 0x736d6761}, ++ {0x9f14, 0x7f7f7f79}, ++ {0x9f18, 0x120f7f7f}, ++ {0x9f1c, 0x1e1b1815}, ++ {0x9f20, 0x2a272421}, ++ {0x9f24, 0x3633302d}, ++ {0x9f28, 0x3f3f3c39}, ++ {0x9f2c, 0x3f3f3f3f}, ++ {0x8088, 0x00000110}, ++ {0x8000, 0x00000008}, ++ {0x8080, 0x00000005}, ++ {0x8500, 0x00060009}, ++ {0x8504, 0x000418b0}, ++ {0x8508, 0x00089c00}, ++ {0x850c, 0x43000004}, ++ {0x8510, 0x4b044a00}, ++ {0x8514, 0x40098603}, ++ {0x8518, 0x4b05e01f}, ++ {0x851c, 0x400b8703}, ++ {0x8520, 0x4b00e01f}, ++ {0x8524, 0x43800004}, ++ {0x8528, 0x4c000007}, ++ {0x852c, 0x43000004}, ++ {0x8530, 0x57007430}, ++ {0x8534, 0x73000006}, ++ {0x8538, 0x50550004}, ++ {0x853c, 0xb4163000}, ++ {0x8540, 0xe37ea510}, ++ {0x8544, 0xf117f017}, ++ {0x8548, 0xf317f217}, ++ {0x854c, 0xf517f417}, ++ {0x8550, 0xf717f617}, ++ {0x8554, 0xf917f817}, ++ {0x8558, 0xfb17fa17}, ++ {0x855c, 0xfd17fc17}, ++ {0x8560, 0xf117f017}, ++ {0x8564, 0xf317f217}, ++ {0x8568, 0xa503f417}, ++ {0x856c, 0xf116f016}, ++ {0x8570, 0x304e0001}, ++ {0x8574, 0x30873053}, ++ {0x8578, 0x30ab30a8}, ++ {0x857c, 0x30b330ae}, ++ {0x8580, 0x30ba30b6}, ++ {0x8584, 0x30d430c7}, ++ {0x8588, 0x310d3100}, ++ {0x858c, 0x31ed3112}, ++ {0x8590, 0x320a31f1}, ++ {0x8594, 0x3243320b}, ++ {0x8598, 0x31e631b1}, ++ {0x859c, 0x5b00e283}, ++ {0x85a0, 0xe2d15500}, ++ {0x85a4, 0xe2830001}, ++ {0x85a8, 0x5b10e2e3}, ++ {0x85ac, 0x20987410}, ++ {0x85b0, 0xe3750200}, ++ {0x85b4, 0x00002080}, ++ {0x85b8, 0x23f0e375}, ++ {0x85bc, 0xe3750001}, ++ {0x85c0, 0x000023f0}, ++ {0x85c4, 0x5507e375}, ++ {0x85c8, 0xe2d5e2d5}, ++ {0x85cc, 0x20887410}, ++ {0x85d0, 0xe3750200}, ++ {0x85d4, 0x000123f0}, ++ {0x85d8, 0x23f0e375}, ++ {0x85dc, 0xe3750000}, ++ {0x85e0, 0xe2d55517}, ++ {0x85e4, 0x4e004f02}, ++ {0x85e8, 0x52015302}, ++ {0x85ec, 0x7508e2d9}, ++ {0x85f0, 0x74207900}, ++ {0x85f4, 0x57005710}, ++ {0x85f8, 0x75fbe375}, ++ {0x85fc, 0x23f07410}, ++ {0x8600, 0xe3750001}, ++ {0x8604, 0x000023f0}, ++ {0x8608, 0x7430e375}, ++ {0x860c, 0x5b100001}, ++ {0x8610, 0x20907410}, ++ {0x8614, 0xe3750000}, ++ {0x8618, 0x000123f0}, ++ {0x861c, 0x23f0e375}, ++ {0x8620, 0xe3750000}, ++ {0x8624, 0xe2d55507}, ++ {0x8628, 0x7410e2d5}, ++ {0x862c, 0x02002098}, ++ {0x8630, 0x23f0e375}, ++ {0x8634, 0xe3750001}, ++ {0x8638, 0x000023f0}, ++ {0x863c, 0x5517e375}, ++ {0x8640, 0x4f02e2d5}, ++ {0x8644, 0x53024e00}, ++ {0x8648, 0xe2d95201}, ++ {0x864c, 0x30787509}, ++ {0x8650, 0xe2e3e283}, ++ {0x8654, 0xe27b0001}, ++ {0x8658, 0x0001e2e3}, ++ {0x865c, 0x5b30e28f}, ++ {0x8660, 0xe2d15500}, ++ {0x8664, 0xe28f0001}, ++ {0x8668, 0x0001e312}, ++ {0x866c, 0x4380e287}, ++ {0x8670, 0x0001e312}, ++ {0x8674, 0x30e2e283}, ++ {0x8678, 0xe3600023}, ++ {0x867c, 0x54ed0002}, ++ {0x8680, 0x00230baa}, ++ {0x8684, 0x0002e360}, ++ {0x8688, 0xe27be330}, ++ {0x868c, 0xe2830001}, ++ {0x8690, 0x002230dd}, ++ {0x8694, 0x0002e360}, ++ {0x8698, 0x0baa54ec}, ++ {0x869c, 0xe3600022}, ++ {0x86a0, 0xe3300002}, ++ {0x86a4, 0x0001e27b}, ++ {0x86a8, 0x0baae283}, ++ {0x86ac, 0x6d0f6c67}, ++ {0x86b0, 0xe360e2e3}, ++ {0x86b4, 0xe2e36c8b}, ++ {0x86b8, 0x0bace360}, ++ {0x86bc, 0x6d0f6cb3}, ++ {0x86c0, 0xe360e2e3}, ++ {0x86c4, 0x6cdb0bad}, ++ {0x86c8, 0xe2e36d0f}, ++ {0x86cc, 0x6cf7e360}, ++ {0x86d0, 0xe2e36d0f}, ++ {0x86d4, 0x6c09e360}, ++ {0x86d8, 0xe2e36d00}, ++ {0x86dc, 0x6c25e360}, ++ {0x86e0, 0xe360e2e3}, ++ {0x86e4, 0x6c4df8ca}, ++ {0x86e8, 0xe360e2e3}, ++ {0x86ec, 0x6c75f9d3}, ++ {0x86f0, 0xe360e2e3}, ++ {0x86f4, 0xe2e36c99}, ++ {0x86f8, 0xe330e360}, ++ {0x86fc, 0x0001e27b}, ++ {0x8700, 0x314de28f}, ++ {0x8704, 0xe3650022}, ++ {0x8708, 0x54ec0002}, ++ {0x870c, 0x00220baa}, ++ {0x8710, 0x0002e365}, ++ {0x8714, 0xe287e330}, ++ {0x8718, 0xe28f0001}, ++ {0x871c, 0xe3303139}, ++ {0x8720, 0x0001e287}, ++ {0x8724, 0x0ba6e28f}, ++ {0x8728, 0x21e07410}, ++ {0x872c, 0x21e80009}, ++ {0x8730, 0x6e670009}, ++ {0x8734, 0xe32b6f0f}, ++ {0x8738, 0xe365e312}, ++ {0x873c, 0x21e07410}, ++ {0x8740, 0x21e8000a}, ++ {0x8744, 0x6e77000a}, ++ {0x8748, 0xe312e32b}, ++ {0x874c, 0x7410e365}, ++ {0x8750, 0x000b21e0}, ++ {0x8754, 0x000b21e8}, ++ {0x8758, 0xe32b6e8b}, ++ {0x875c, 0xe365e312}, ++ {0x8760, 0x21e07410}, ++ {0x8764, 0x21e8000c}, ++ {0x8768, 0x6e9f000c}, ++ {0x876c, 0xe312e32b}, ++ {0x8770, 0x0baae365}, ++ {0x8774, 0x21e07410}, ++ {0x8778, 0x21e8000d}, ++ {0x877c, 0x6eb3000d}, ++ {0x8780, 0xe32b6f0f}, ++ {0x8784, 0xe365e312}, ++ {0x8788, 0x21e07410}, ++ {0x878c, 0x21e8000e}, ++ {0x8790, 0x6ec7000e}, ++ {0x8794, 0xe312e32b}, ++ {0x8798, 0x0bace365}, ++ {0x879c, 0x21e07410}, ++ {0x87a0, 0x21e8000f}, ++ {0x87a4, 0x6edb000f}, ++ {0x87a8, 0xe32b6f0f}, ++ {0x87ac, 0xe365e312}, ++ {0x87b0, 0x21e07410}, ++ {0x87b4, 0x21e80010}, ++ {0x87b8, 0x6eef0010}, ++ {0x87bc, 0xe312e32b}, ++ {0x87c0, 0xe365e365}, ++ {0x87c4, 0x21e07410}, ++ {0x87c8, 0x21e80013}, ++ {0x87cc, 0x6e110013}, ++ {0x87d0, 0xe32b6f00}, ++ {0x87d4, 0xe365e312}, ++ {0x87d8, 0x7410e365}, ++ {0x87dc, 0x001421e0}, ++ {0x87e0, 0x001421e8}, ++ {0x87e4, 0xe32b6e25}, ++ {0x87e8, 0xe365e312}, ++ {0x87ec, 0x7410fb8c}, ++ {0x87f0, 0x001521e0}, ++ {0x87f4, 0x001521e8}, ++ {0x87f8, 0xe32b6e39}, ++ {0x87fc, 0xe365e312}, ++ {0x8800, 0x21e07410}, ++ {0x8804, 0x21e80016}, ++ {0x8808, 0x6e4d0016}, ++ {0x880c, 0xe312e32b}, ++ {0x8810, 0xfc86e365}, ++ {0x8814, 0x21e07410}, ++ {0x8818, 0x21e80017}, ++ {0x881c, 0x6e610017}, ++ {0x8820, 0xe312e32b}, ++ {0x8824, 0x7410e365}, ++ {0x8828, 0x001821e0}, ++ {0x882c, 0x001821e8}, ++ {0x8830, 0xe32b6e75}, ++ {0x8834, 0xe365e312}, ++ {0x8838, 0x21e07410}, ++ {0x883c, 0x21e80019}, ++ {0x8840, 0x6e890019}, ++ {0x8844, 0xe312e32b}, ++ {0x8848, 0x7410e365}, ++ {0x884c, 0x001a21e0}, ++ {0x8850, 0x001a21e8}, ++ {0x8854, 0xe32b6e99}, ++ {0x8858, 0xe365e312}, ++ {0x885c, 0xe287e330}, ++ {0x8860, 0x00040001}, ++ {0x8864, 0x0007775c}, ++ {0x8868, 0x62006220}, ++ {0x886c, 0x55010004}, ++ {0x8870, 0xe2d15b00}, ++ {0x8874, 0x66055b40}, ++ {0x8878, 0x62000007}, ++ {0x887c, 0xe3506300}, ++ {0x8880, 0xe2d10004}, ++ {0x8884, 0x0a010900}, ++ {0x8888, 0x0d000b40}, ++ {0x888c, 0x00320e01}, ++ {0x8890, 0x95060004}, ++ {0x8894, 0x00074380}, ++ {0x8898, 0x00044d01}, ++ {0x889c, 0x00074300}, ++ {0x88a0, 0x05a30562}, ++ {0x88a4, 0xe3509617}, ++ {0x88a8, 0xe2d10004}, ++ {0x88ac, 0x06a20007}, ++ {0x88b0, 0xe35007a3}, ++ {0x88b4, 0xe2d10004}, ++ {0x88b8, 0x0002e340}, ++ {0x88bc, 0x4380e348}, ++ {0x88c0, 0x4d000007}, ++ {0x88c4, 0x43000004}, ++ {0x88c8, 0x00017900}, ++ {0x88cc, 0x775e0004}, ++ {0x88d0, 0x000731b3}, ++ {0x88d4, 0x07a306a2}, ++ {0x88d8, 0xe29331dd}, ++ {0x88dc, 0x73000005}, ++ {0x88e0, 0xe2930001}, ++ {0x88e4, 0x5d000006}, ++ {0x88e8, 0x42f70004}, ++ {0x88ec, 0x6c000005}, ++ {0x88f0, 0x42000004}, ++ {0x88f4, 0x0004e2ab}, ++ {0x88f8, 0x00074380}, ++ {0x88fc, 0x4a004e00}, ++ {0x8900, 0x00064c00}, ++ {0x8904, 0x60007f00}, ++ {0x8908, 0x00046f00}, ++ {0x890c, 0x00054300}, ++ {0x8910, 0x00017300}, ++ {0x8914, 0xe2930001}, ++ {0x8918, 0x5d010006}, ++ {0x891c, 0x61006002}, ++ {0x8920, 0x00055601}, ++ {0x8924, 0xe2ab7710}, ++ {0x8928, 0x73000005}, ++ {0x892c, 0x43800004}, ++ {0x8930, 0x5e010007}, ++ {0x8934, 0x4d205e00}, ++ {0x8938, 0x4a084e20}, ++ {0x893c, 0x4c3f4960}, ++ {0x8940, 0x00064301}, ++ {0x8944, 0x63807f01}, ++ {0x8948, 0x00046010}, ++ {0x894c, 0x00064300}, ++ {0x8950, 0x00077402}, ++ {0x8954, 0x40004001}, ++ {0x8958, 0x0006ab00}, ++ {0x895c, 0x00077404}, ++ {0x8960, 0x40004001}, ++ {0x8964, 0x0004ab00}, ++ {0x8968, 0x00074380}, ++ {0x896c, 0x4e004d00}, ++ {0x8970, 0x4c004a00}, ++ {0x8974, 0x00064300}, ++ {0x8978, 0x63007f00}, ++ {0x897c, 0x6f006000}, ++ {0x8980, 0x43000004}, ++ {0x8984, 0x00040001}, ++ {0x8988, 0x42bf4380}, ++ {0x898c, 0x48400007}, ++ {0x8990, 0x42ef0004}, ++ {0x8994, 0x4d100007}, ++ {0x8998, 0x42000004}, ++ {0x899c, 0x5f800006}, ++ {0x89a0, 0x5a010007}, ++ {0x89a4, 0x00044a08}, ++ {0x89a8, 0x00054300}, ++ {0x89ac, 0x73807381}, ++ {0x89b0, 0x003f9300}, ++ {0x89b4, 0x00000000}, ++ {0x89b8, 0x00000000}, ++ {0x89bc, 0x00020000}, ++ {0x89c0, 0x5f800006}, ++ {0x89c4, 0x99005f00}, ++ {0x89c8, 0x43800004}, ++ {0x89cc, 0x00074280}, ++ {0x89d0, 0x00044800}, ++ {0x89d4, 0x000742ef}, ++ {0x89d8, 0x00044d00}, ++ {0x89dc, 0x00064200}, ++ {0x89e0, 0x60005f00}, ++ {0x89e4, 0x5a000007}, ++ {0x89e8, 0x48004a00}, ++ {0x89ec, 0x43000004}, ++ {0x89f0, 0x73000005}, ++ {0x89f4, 0x43800001}, ++ {0x89f8, 0x78006505}, ++ {0x89fc, 0x7a007900}, ++ {0x8a00, 0x43007b00}, ++ {0x8a04, 0x43800001}, ++ {0x8a08, 0x43006500}, ++ {0x8a0c, 0x43800001}, ++ {0x8a10, 0x7c006405}, ++ {0x8a14, 0x7e007d00}, ++ {0x8a18, 0x43007f00}, ++ {0x8a1c, 0x43800001}, ++ {0x8a20, 0x43006400}, ++ {0x8a24, 0x00060001}, ++ {0x8a28, 0x55025601}, ++ {0x8a2c, 0x00055400}, ++ {0x8a30, 0x7e127f00}, ++ {0x8a34, 0x76007710}, ++ {0x8a38, 0x74007500}, ++ {0x8a3c, 0x42700004}, ++ {0x8a40, 0x73810005}, ++ {0x8a44, 0x00047380}, ++ {0x8a48, 0x93004200}, ++ {0x8a4c, 0x77000005}, ++ {0x8a50, 0x56000006}, ++ {0x8a54, 0x00060001}, ++ {0x8a58, 0x5f005f80}, ++ {0x8a5c, 0x00059900}, ++ {0x8a60, 0x00067300}, ++ {0x8a64, 0x63006380}, ++ {0x8a68, 0x00019800}, ++ {0x8a6c, 0x7b484380}, ++ {0x8a70, 0x79007a90}, ++ {0x8a74, 0x43007802}, ++ {0x8a78, 0x32cd5503}, ++ {0x8a7c, 0x7b384380}, ++ {0x8a80, 0x79007a80}, ++ {0x8a84, 0x43007802}, ++ {0x8a88, 0x32cd5513}, ++ {0x8a8c, 0x7b404380}, ++ {0x8a90, 0x79007a00}, ++ {0x8a94, 0x43007802}, ++ {0x8a98, 0x74315523}, ++ {0x8a9c, 0x8e007430}, ++ {0x8aa0, 0x74010001}, ++ {0x8aa4, 0x8e007400}, ++ {0x8aa8, 0x74310001}, ++ {0x8aac, 0x8e007430}, ++ {0x8ab0, 0x57020001}, ++ {0x8ab4, 0x97005700}, ++ {0x8ab8, 0x42ef0001}, ++ {0x8abc, 0x56005610}, ++ {0x8ac0, 0x8c004200}, ++ {0x8ac4, 0x4f780001}, ++ {0x8ac8, 0x53884e00}, ++ {0x8acc, 0x5b205201}, ++ {0x8ad0, 0x5480e2f2}, ++ {0x8ad4, 0x54815400}, ++ {0x8ad8, 0x54825400}, ++ {0x8adc, 0xe2fd5400}, ++ {0x8ae0, 0x3012bf1d}, ++ {0x8ae4, 0xe2bee2b6}, ++ {0x8ae8, 0xe2d9e2c6}, ++ {0x8aec, 0x5523e359}, ++ {0x8af0, 0x5525e2cd}, ++ {0x8af4, 0xe359e2d9}, ++ {0x8af8, 0x54bf0001}, ++ {0x8afc, 0x54a354c0}, ++ {0x8b00, 0x54a454c1}, ++ {0x8b04, 0xbf074c18}, ++ {0x8b08, 0x54a454c2}, ++ {0x8b0c, 0x54c1bf04}, ++ {0x8b10, 0xbf0154a3}, ++ {0x8b14, 0x54dfe36a}, ++ {0x8b18, 0x54bf0001}, ++ {0x8b1c, 0x050a54e5}, ++ {0x8b20, 0x000154df}, ++ {0x8b24, 0x43807b80}, ++ {0x8b28, 0x7e007f40}, ++ {0x8b2c, 0x7c027d00}, ++ {0x8b30, 0x5b404300}, ++ {0x8b34, 0x5c015501}, ++ {0x8b38, 0x5480e2dd}, ++ {0x8b3c, 0x54815400}, ++ {0x8b40, 0x54825400}, ++ {0x8b44, 0x7b005400}, ++ {0x8b48, 0xbfe8e2fd}, ++ {0x8b4c, 0x56103012}, ++ {0x8b50, 0x8c005600}, ++ {0x8b54, 0xe36d0001}, ++ {0x8b58, 0xe36de36d}, ++ {0x8b5c, 0x0001e36d}, ++ {0x8b60, 0x57005704}, ++ {0x8b64, 0x57089700}, ++ {0x8b68, 0x97005700}, ++ {0x8b6c, 0x57805781}, ++ {0x8b70, 0x43809700}, ++ {0x8b74, 0x5c010007}, ++ {0x8b78, 0x00045c00}, ++ {0x8b7c, 0x00014300}, ++ {0x8b80, 0x0007427f}, ++ {0x8b84, 0x62006280}, ++ {0x8b88, 0x00049200}, ++ {0x8b8c, 0x00014200}, ++ {0x8b90, 0x0007427f}, ++ {0x8b94, 0x63146394}, ++ {0x8b98, 0x00049100}, ++ {0x8b9c, 0x00014200}, ++ {0x8ba0, 0x79010004}, ++ {0x8ba4, 0xe3757420}, ++ {0x8ba8, 0x57005710}, ++ {0x8bac, 0xe375e375}, ++ {0x8bb0, 0x549f0001}, ++ {0x8bb4, 0x5c015400}, ++ {0x8bb8, 0x540054df}, ++ {0x8bbc, 0x00015c02}, ++ {0x8bc0, 0x07145c01}, ++ {0x8bc4, 0x5c025400}, ++ {0x8bc8, 0x5c020001}, ++ {0x8bcc, 0x54000714}, ++ {0x8bd0, 0x00015c01}, ++ {0x8bd4, 0x4c184c98}, ++ {0x8bd8, 0x003f0001}, ++ {0x8bdc, 0x00000000}, ++ {0x8be0, 0x00000000}, ++ {0x8be4, 0x00020000}, ++ {0x8be8, 0x00000001}, ++ {0x8bec, 0x00000000}, ++ {0x8bf0, 0x00000000}, ++ {0x8bf4, 0x00000000}, ++ {0x8bf8, 0x00010000}, ++ {0x8bfc, 0x5c020004}, ++ {0x8c00, 0x66076204}, ++ {0x8c04, 0x743070c0}, ++ {0x8c08, 0x0c010901}, ++ {0x8c0c, 0x00010ba6}, ++ {0x8080, 0x00000004}, ++ {0x8080, 0x00000000}, ++ {0x8088, 0x00000000}, ++}; ++ ++static const struct rtw89_txpwr_byrate_cfg rtw89_8852a_txpwr_byrate[] = { ++ { 0, 0, 0, 0, 4, 0x50505050, }, ++ { 0, 0, 1, 0, 4, 0x50505050, }, ++ { 0, 0, 1, 4, 4, 0x484c5050, }, ++ { 0, 0, 2, 0, 4, 0x50505050, }, ++ { 0, 0, 2, 4, 4, 0x44484c50, }, ++ { 0, 0, 2, 8, 4, 0x34383c40, }, ++ { 0, 0, 3, 0, 4, 0x50505050, }, ++ { 0, 1, 2, 0, 4, 0x50505050, }, ++ { 0, 1, 2, 4, 4, 0x44484c50, }, ++ { 0, 1, 2, 8, 4, 0x34383c40, }, ++ { 0, 1, 3, 0, 4, 0x50505050, }, ++ { 0, 0, 4, 1, 4, 0x00000000, }, ++ { 0, 0, 4, 0, 1, 0x00000000, }, ++ { 1, 0, 1, 0, 4, 0x50505050, }, ++ { 1, 0, 1, 4, 4, 0x484c5050, }, ++ { 1, 0, 2, 0, 4, 0x50505050, }, ++ { 1, 0, 2, 4, 4, 0x44484c50, }, ++ { 1, 0, 2, 8, 4, 0x34383c40, }, ++ { 1, 0, 3, 0, 4, 0x50505050, }, ++ { 1, 1, 2, 0, 4, 0x50505050, }, ++ { 1, 1, 2, 4, 4, 0x44484c50, }, ++ { 1, 1, 2, 8, 4, 0x34383c40, }, ++ { 1, 1, 3, 0, 4, 0x50505050, }, ++ { 1, 0, 4, 0, 4, 0x00000000, }, ++}; ++ ++static const u8 _txpwr_track_delta_swingidx_5gb_n[][DELTA_SWINGIDX_SIZE] = { ++ {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, ++ 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11}, ++ {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, ++ 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8}, ++ {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, ++ 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, ++}; ++ ++static const u8 _txpwr_track_delta_swingidx_5gb_p[][DELTA_SWINGIDX_SIZE] = { ++ {0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, ++ 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11}, ++ {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, ++ 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8}, ++ {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, ++ 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, ++}; ++ ++static const u8 _txpwr_track_delta_swingidx_5ga_n[][DELTA_SWINGIDX_SIZE] = { ++ {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, ++ 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11}, ++ {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, ++ 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8}, ++ {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, ++ 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, ++}; ++ ++static const u8 _txpwr_track_delta_swingidx_5ga_p[][DELTA_SWINGIDX_SIZE] = { ++ {0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, ++ 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11}, ++ {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, ++ 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8}, ++ {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, ++ 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, ++}; ++ ++static const u8 _txpwr_track_delta_swingidx_2gb_n[] = { ++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, ++ 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7}; ++ ++static const u8 _txpwr_track_delta_swingidx_2gb_p[] = { ++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3}; ++ ++static const u8 _txpwr_track_delta_swingidx_2ga_n[] = { ++ 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, ++ 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5}; ++ ++static const u8 _txpwr_track_delta_swingidx_2ga_p[] = { ++ 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, ++ 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}; ++ ++static const u8 _txpwr_track_delta_swingidx_2g_cck_b_n[] = { ++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, ++ 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7}; ++ ++static const u8 _txpwr_track_delta_swingidx_2g_cck_b_p[] = { ++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3}; ++ ++static const u8 _txpwr_track_delta_swingidx_2g_cck_a_n[] = { ++ 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, ++ 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5}; ++ ++static const u8 _txpwr_track_delta_swingidx_2g_cck_a_p[] = { ++ 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, ++ 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}; ++ ++const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] ++ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] ++ [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { ++ [0][0][0][0][0][0] = 56, ++ [0][0][0][0][0][1] = 56, ++ [0][0][0][0][0][2] = 56, ++ [0][0][0][0][0][3] = 56, ++ [0][0][0][0][0][4] = 56, ++ [0][0][0][0][0][5] = 56, ++ [0][0][0][0][0][6] = 56, ++ [0][0][0][0][0][7] = 56, ++ [0][0][0][0][0][8] = 56, ++ [0][0][0][0][0][9] = 56, ++ [0][0][0][0][0][10] = 56, ++ [0][0][0][0][0][11] = 56, ++ [0][0][0][0][0][12] = 48, ++ [0][0][0][0][0][13] = 76, ++ [0][1][0][0][0][0] = 44, ++ [0][1][0][0][0][1] = 44, ++ [0][1][0][0][0][2] = 44, ++ [0][1][0][0][0][3] = 44, ++ [0][1][0][0][0][4] = 44, ++ [0][1][0][0][0][5] = 44, ++ [0][1][0][0][0][6] = 44, ++ [0][1][0][0][0][7] = 44, ++ [0][1][0][0][0][8] = 44, ++ [0][1][0][0][0][9] = 44, ++ [0][1][0][0][0][10] = 44, ++ [0][1][0][0][0][11] = 44, ++ [0][1][0][0][0][12] = 38, ++ [0][1][0][0][0][13] = 64, ++ [1][0][0][0][0][0] = 0, ++ [1][0][0][0][0][1] = 0, ++ [1][0][0][0][0][2] = 58, ++ [1][0][0][0][0][3] = 58, ++ [1][0][0][0][0][4] = 58, ++ [1][0][0][0][0][5] = 58, ++ [1][0][0][0][0][6] = 46, ++ [1][0][0][0][0][7] = 46, ++ [1][0][0][0][0][8] = 46, ++ [1][0][0][0][0][9] = 32, ++ [1][0][0][0][0][10] = 32, ++ [1][0][0][0][0][11] = 0, ++ [1][0][0][0][0][12] = 0, ++ [1][0][0][0][0][13] = 0, ++ [1][1][0][0][0][0] = 0, ++ [1][1][0][0][0][1] = 0, ++ [1][1][0][0][0][2] = 46, ++ [1][1][0][0][0][3] = 46, ++ [1][1][0][0][0][4] = 46, ++ [1][1][0][0][0][5] = 46, ++ [1][1][0][0][0][6] = 46, ++ [1][1][0][0][0][7] = 46, ++ [1][1][0][0][0][8] = 46, ++ [1][1][0][0][0][9] = 24, ++ [1][1][0][0][0][10] = 24, ++ [1][1][0][0][0][11] = 0, ++ [1][1][0][0][0][12] = 0, ++ [1][1][0][0][0][13] = 0, ++ [0][0][1][0][0][0] = 58, ++ [0][0][1][0][0][1] = 58, ++ [0][0][1][0][0][2] = 58, ++ [0][0][1][0][0][3] = 58, ++ [0][0][1][0][0][4] = 58, ++ [0][0][1][0][0][5] = 58, ++ [0][0][1][0][0][6] = 58, ++ [0][0][1][0][0][7] = 58, ++ [0][0][1][0][0][8] = 58, ++ [0][0][1][0][0][9] = 58, ++ [0][0][1][0][0][10] = 58, ++ [0][0][1][0][0][11] = 56, ++ [0][0][1][0][0][12] = 52, ++ [0][0][1][0][0][13] = 0, ++ [0][1][1][0][0][0] = 46, ++ [0][1][1][0][0][1] = 46, ++ [0][1][1][0][0][2] = 46, ++ [0][1][1][0][0][3] = 46, ++ [0][1][1][0][0][4] = 46, ++ [0][1][1][0][0][5] = 46, ++ [0][1][1][0][0][6] = 46, ++ [0][1][1][0][0][7] = 46, ++ [0][1][1][0][0][8] = 46, ++ [0][1][1][0][0][9] = 46, ++ [0][1][1][0][0][10] = 46, ++ [0][1][1][0][0][11] = 42, ++ [0][1][1][0][0][12] = 40, ++ [0][1][1][0][0][13] = 0, ++ [0][0][2][0][0][0] = 58, ++ [0][0][2][0][0][1] = 58, ++ [0][0][2][0][0][2] = 58, ++ [0][0][2][0][0][3] = 58, ++ [0][0][2][0][0][4] = 58, ++ [0][0][2][0][0][5] = 58, ++ [0][0][2][0][0][6] = 58, ++ [0][0][2][0][0][7] = 58, ++ [0][0][2][0][0][8] = 58, ++ [0][0][2][0][0][9] = 58, ++ [0][0][2][0][0][10] = 58, ++ [0][0][2][0][0][11] = 54, ++ [0][0][2][0][0][12] = 50, ++ [0][0][2][0][0][13] = 0, ++ [0][1][2][0][0][0] = 46, ++ [0][1][2][0][0][1] = 46, ++ [0][1][2][0][0][2] = 46, ++ [0][1][2][0][0][3] = 46, ++ [0][1][2][0][0][4] = 46, ++ [0][1][2][0][0][5] = 46, ++ [0][1][2][0][0][6] = 46, ++ [0][1][2][0][0][7] = 46, ++ [0][1][2][0][0][8] = 46, ++ [0][1][2][0][0][9] = 46, ++ [0][1][2][0][0][10] = 46, ++ [0][1][2][0][0][11] = 42, ++ [0][1][2][0][0][12] = 40, ++ [0][1][2][0][0][13] = 0, ++ [0][1][2][1][0][0] = 34, ++ [0][1][2][1][0][1] = 34, ++ [0][1][2][1][0][2] = 34, ++ [0][1][2][1][0][3] = 34, ++ [0][1][2][1][0][4] = 34, ++ [0][1][2][1][0][5] = 34, ++ [0][1][2][1][0][6] = 34, ++ [0][1][2][1][0][7] = 34, ++ [0][1][2][1][0][8] = 34, ++ [0][1][2][1][0][9] = 34, ++ [0][1][2][1][0][10] = 34, ++ [0][1][2][1][0][11] = 34, ++ [0][1][2][1][0][12] = 34, ++ [0][1][2][1][0][13] = 0, ++ [1][0][2][0][0][0] = 0, ++ [1][0][2][0][0][1] = 0, ++ [1][0][2][0][0][2] = 56, ++ [1][0][2][0][0][3] = 56, ++ [1][0][2][0][0][4] = 58, ++ [1][0][2][0][0][5] = 58, ++ [1][0][2][0][0][6] = 54, ++ [1][0][2][0][0][7] = 50, ++ [1][0][2][0][0][8] = 50, ++ [1][0][2][0][0][9] = 42, ++ [1][0][2][0][0][10] = 40, ++ [1][0][2][0][0][11] = 0, ++ [1][0][2][0][0][12] = 0, ++ [1][0][2][0][0][13] = 0, ++ [1][1][2][0][0][0] = 0, ++ [1][1][2][0][0][1] = 0, ++ [1][1][2][0][0][2] = 46, ++ [1][1][2][0][0][3] = 46, ++ [1][1][2][0][0][4] = 46, ++ [1][1][2][0][0][5] = 46, ++ [1][1][2][0][0][6] = 46, ++ [1][1][2][0][0][7] = 46, ++ [1][1][2][0][0][8] = 46, ++ [1][1][2][0][0][9] = 38, ++ [1][1][2][0][0][10] = 36, ++ [1][1][2][0][0][11] = 0, ++ [1][1][2][0][0][12] = 0, ++ [1][1][2][0][0][13] = 0, ++ [1][1][2][1][0][0] = 0, ++ [1][1][2][1][0][1] = 0, ++ [1][1][2][1][0][2] = 34, ++ [1][1][2][1][0][3] = 34, ++ [1][1][2][1][0][4] = 34, ++ [1][1][2][1][0][5] = 34, ++ [1][1][2][1][0][6] = 34, ++ [1][1][2][1][0][7] = 34, ++ [1][1][2][1][0][8] = 34, ++ [1][1][2][1][0][9] = 34, ++ [1][1][2][1][0][10] = 34, ++ [1][1][2][1][0][11] = 0, ++ [1][1][2][1][0][12] = 0, ++ [1][1][2][1][0][13] = 0, ++ [0][0][0][0][2][0] = 76, ++ [0][0][0][0][1][0] = 56, ++ [0][0][0][0][3][0] = 68, ++ [0][0][0][0][5][0] = 76, ++ [0][0][0][0][6][0] = 56, ++ [0][0][0][0][9][0] = 56, ++ [0][0][0][0][8][0] = 60, ++ [0][0][0][0][11][0] = 56, ++ [0][0][0][0][2][1] = 76, ++ [0][0][0][0][1][1] = 56, ++ [0][0][0][0][3][1] = 68, ++ [0][0][0][0][5][1] = 76, ++ [0][0][0][0][6][1] = 56, ++ [0][0][0][0][9][1] = 56, ++ [0][0][0][0][8][1] = 60, ++ [0][0][0][0][11][1] = 56, ++ [0][0][0][0][2][2] = 76, ++ [0][0][0][0][1][2] = 56, ++ [0][0][0][0][3][2] = 68, ++ [0][0][0][0][5][2] = 76, ++ [0][0][0][0][6][2] = 56, ++ [0][0][0][0][9][2] = 56, ++ [0][0][0][0][8][2] = 60, ++ [0][0][0][0][11][2] = 56, ++ [0][0][0][0][2][3] = 76, ++ [0][0][0][0][1][3] = 56, ++ [0][0][0][0][3][3] = 68, ++ [0][0][0][0][5][3] = 76, ++ [0][0][0][0][6][3] = 56, ++ [0][0][0][0][9][3] = 56, ++ [0][0][0][0][8][3] = 60, ++ [0][0][0][0][11][3] = 56, ++ [0][0][0][0][2][4] = 76, ++ [0][0][0][0][1][4] = 56, ++ [0][0][0][0][3][4] = 68, ++ [0][0][0][0][5][4] = 76, ++ [0][0][0][0][6][4] = 56, ++ [0][0][0][0][9][4] = 56, ++ [0][0][0][0][8][4] = 60, ++ [0][0][0][0][11][4] = 56, ++ [0][0][0][0][2][5] = 76, ++ [0][0][0][0][1][5] = 56, ++ [0][0][0][0][3][5] = 68, ++ [0][0][0][0][5][5] = 76, ++ [0][0][0][0][6][5] = 56, ++ [0][0][0][0][9][5] = 56, ++ [0][0][0][0][8][5] = 60, ++ [0][0][0][0][11][5] = 56, ++ [0][0][0][0][2][6] = 76, ++ [0][0][0][0][1][6] = 56, ++ [0][0][0][0][3][6] = 68, ++ [0][0][0][0][5][6] = 76, ++ [0][0][0][0][6][6] = 56, ++ [0][0][0][0][9][6] = 56, ++ [0][0][0][0][8][6] = 60, ++ [0][0][0][0][11][6] = 56, ++ [0][0][0][0][2][7] = 76, ++ [0][0][0][0][1][7] = 56, ++ [0][0][0][0][3][7] = 68, ++ [0][0][0][0][5][7] = 76, ++ [0][0][0][0][6][7] = 56, ++ [0][0][0][0][9][7] = 56, ++ [0][0][0][0][8][7] = 60, ++ [0][0][0][0][11][7] = 56, ++ [0][0][0][0][2][8] = 76, ++ [0][0][0][0][1][8] = 56, ++ [0][0][0][0][3][8] = 68, ++ [0][0][0][0][5][8] = 76, ++ [0][0][0][0][6][8] = 56, ++ [0][0][0][0][9][8] = 56, ++ [0][0][0][0][8][8] = 60, ++ [0][0][0][0][11][8] = 56, ++ [0][0][0][0][2][9] = 76, ++ [0][0][0][0][1][9] = 56, ++ [0][0][0][0][3][9] = 68, ++ [0][0][0][0][5][9] = 76, ++ [0][0][0][0][6][9] = 56, ++ [0][0][0][0][9][9] = 56, ++ [0][0][0][0][8][9] = 60, ++ [0][0][0][0][11][9] = 56, ++ [0][0][0][0][2][10] = 76, ++ [0][0][0][0][1][10] = 56, ++ [0][0][0][0][3][10] = 68, ++ [0][0][0][0][5][10] = 76, ++ [0][0][0][0][6][10] = 56, ++ [0][0][0][0][9][10] = 56, ++ [0][0][0][0][8][10] = 60, ++ [0][0][0][0][11][10] = 56, ++ [0][0][0][0][2][11] = 68, ++ [0][0][0][0][1][11] = 56, ++ [0][0][0][0][3][11] = 68, ++ [0][0][0][0][5][11] = 68, ++ [0][0][0][0][6][11] = 56, ++ [0][0][0][0][9][11] = 56, ++ [0][0][0][0][8][11] = 60, ++ [0][0][0][0][11][11] = 56, ++ [0][0][0][0][2][12] = 48, ++ [0][0][0][0][1][12] = 56, ++ [0][0][0][0][3][12] = 68, ++ [0][0][0][0][5][12] = 48, ++ [0][0][0][0][6][12] = 56, ++ [0][0][0][0][9][12] = 56, ++ [0][0][0][0][8][12] = 60, ++ [0][0][0][0][11][12] = 56, ++ [0][0][0][0][2][13] = 127, ++ [0][0][0][0][1][13] = 127, ++ [0][0][0][0][3][13] = 76, ++ [0][0][0][0][5][13] = 127, ++ [0][0][0][0][6][13] = 127, ++ [0][0][0][0][9][13] = 127, ++ [0][0][0][0][8][13] = 127, ++ [0][0][0][0][11][13] = 127, ++ [0][1][0][0][2][0] = 74, ++ [0][1][0][0][1][0] = 44, ++ [0][1][0][0][3][0] = 56, ++ [0][1][0][0][5][0] = 74, ++ [0][1][0][0][6][0] = 44, ++ [0][1][0][0][9][0] = 44, ++ [0][1][0][0][8][0] = 48, ++ [0][1][0][0][11][0] = 44, ++ [0][1][0][0][2][1] = 76, ++ [0][1][0][0][1][1] = 44, ++ [0][1][0][0][3][1] = 56, ++ [0][1][0][0][5][1] = 76, ++ [0][1][0][0][6][1] = 44, ++ [0][1][0][0][9][1] = 44, ++ [0][1][0][0][8][1] = 48, ++ [0][1][0][0][11][1] = 44, ++ [0][1][0][0][2][2] = 76, ++ [0][1][0][0][1][2] = 44, ++ [0][1][0][0][3][2] = 56, ++ [0][1][0][0][5][2] = 76, ++ [0][1][0][0][6][2] = 44, ++ [0][1][0][0][9][2] = 44, ++ [0][1][0][0][8][2] = 48, ++ [0][1][0][0][11][2] = 44, ++ [0][1][0][0][2][3] = 76, ++ [0][1][0][0][1][3] = 44, ++ [0][1][0][0][3][3] = 56, ++ [0][1][0][0][5][3] = 76, ++ [0][1][0][0][6][3] = 44, ++ [0][1][0][0][9][3] = 44, ++ [0][1][0][0][8][3] = 48, ++ [0][1][0][0][11][3] = 44, ++ [0][1][0][0][2][4] = 76, ++ [0][1][0][0][1][4] = 44, ++ [0][1][0][0][3][4] = 56, ++ [0][1][0][0][5][4] = 76, ++ [0][1][0][0][6][4] = 44, ++ [0][1][0][0][9][4] = 44, ++ [0][1][0][0][8][4] = 48, ++ [0][1][0][0][11][4] = 44, ++ [0][1][0][0][2][5] = 76, ++ [0][1][0][0][1][5] = 44, ++ [0][1][0][0][3][5] = 56, ++ [0][1][0][0][5][5] = 76, ++ [0][1][0][0][6][5] = 44, ++ [0][1][0][0][9][5] = 44, ++ [0][1][0][0][8][5] = 48, ++ [0][1][0][0][11][5] = 44, ++ [0][1][0][0][2][6] = 76, ++ [0][1][0][0][1][6] = 44, ++ [0][1][0][0][3][6] = 56, ++ [0][1][0][0][5][6] = 76, ++ [0][1][0][0][6][6] = 44, ++ [0][1][0][0][9][6] = 44, ++ [0][1][0][0][8][6] = 48, ++ [0][1][0][0][11][6] = 44, ++ [0][1][0][0][2][7] = 76, ++ [0][1][0][0][1][7] = 44, ++ [0][1][0][0][3][7] = 56, ++ [0][1][0][0][5][7] = 76, ++ [0][1][0][0][6][7] = 44, ++ [0][1][0][0][9][7] = 44, ++ [0][1][0][0][8][7] = 48, ++ [0][1][0][0][11][7] = 44, ++ [0][1][0][0][2][8] = 76, ++ [0][1][0][0][1][8] = 44, ++ [0][1][0][0][3][8] = 56, ++ [0][1][0][0][5][8] = 76, ++ [0][1][0][0][6][8] = 44, ++ [0][1][0][0][9][8] = 44, ++ [0][1][0][0][8][8] = 48, ++ [0][1][0][0][11][8] = 44, ++ [0][1][0][0][2][9] = 76, ++ [0][1][0][0][1][9] = 44, ++ [0][1][0][0][3][9] = 56, ++ [0][1][0][0][5][9] = 76, ++ [0][1][0][0][6][9] = 44, ++ [0][1][0][0][9][9] = 44, ++ [0][1][0][0][8][9] = 48, ++ [0][1][0][0][11][9] = 44, ++ [0][1][0][0][2][10] = 62, ++ [0][1][0][0][1][10] = 44, ++ [0][1][0][0][3][10] = 56, ++ [0][1][0][0][5][10] = 62, ++ [0][1][0][0][6][10] = 44, ++ [0][1][0][0][9][10] = 44, ++ [0][1][0][0][8][10] = 48, ++ [0][1][0][0][11][10] = 44, ++ [0][1][0][0][2][11] = 52, ++ [0][1][0][0][1][11] = 44, ++ [0][1][0][0][3][11] = 56, ++ [0][1][0][0][5][11] = 52, ++ [0][1][0][0][6][11] = 44, ++ [0][1][0][0][9][11] = 44, ++ [0][1][0][0][8][11] = 48, ++ [0][1][0][0][11][11] = 44, ++ [0][1][0][0][2][12] = 38, ++ [0][1][0][0][1][12] = 44, ++ [0][1][0][0][3][12] = 56, ++ [0][1][0][0][5][12] = 38, ++ [0][1][0][0][6][12] = 44, ++ [0][1][0][0][9][12] = 44, ++ [0][1][0][0][8][12] = 48, ++ [0][1][0][0][11][12] = 44, ++ [0][1][0][0][2][13] = 127, ++ [0][1][0][0][1][13] = 127, ++ [0][1][0][0][3][13] = 64, ++ [0][1][0][0][5][13] = 127, ++ [0][1][0][0][6][13] = 127, ++ [0][1][0][0][9][13] = 127, ++ [0][1][0][0][8][13] = 127, ++ [0][1][0][0][11][13] = 127, ++ [1][0][0][0][2][0] = 127, ++ [1][0][0][0][1][0] = 127, ++ [1][0][0][0][3][0] = 127, ++ [1][0][0][0][5][0] = 127, ++ [1][0][0][0][6][0] = 127, ++ [1][0][0][0][9][0] = 127, ++ [1][0][0][0][8][0] = 127, ++ [1][0][0][0][11][0] = 127, ++ [1][0][0][0][2][1] = 127, ++ [1][0][0][0][1][1] = 127, ++ [1][0][0][0][3][1] = 127, ++ [1][0][0][0][5][1] = 127, ++ [1][0][0][0][6][1] = 127, ++ [1][0][0][0][9][1] = 127, ++ [1][0][0][0][8][1] = 127, ++ [1][0][0][0][11][1] = 127, ++ [1][0][0][0][2][2] = 60, ++ [1][0][0][0][1][2] = 58, ++ [1][0][0][0][3][2] = 68, ++ [1][0][0][0][5][2] = 60, ++ [1][0][0][0][6][2] = 58, ++ [1][0][0][0][9][2] = 58, ++ [1][0][0][0][8][2] = 60, ++ [1][0][0][0][11][2] = 58, ++ [1][0][0][0][2][3] = 60, ++ [1][0][0][0][1][3] = 58, ++ [1][0][0][0][3][3] = 68, ++ [1][0][0][0][5][3] = 60, ++ [1][0][0][0][6][3] = 58, ++ [1][0][0][0][9][3] = 58, ++ [1][0][0][0][8][3] = 60, ++ [1][0][0][0][11][3] = 58, ++ [1][0][0][0][2][4] = 60, ++ [1][0][0][0][1][4] = 58, ++ [1][0][0][0][3][4] = 68, ++ [1][0][0][0][5][4] = 60, ++ [1][0][0][0][6][4] = 58, ++ [1][0][0][0][9][4] = 58, ++ [1][0][0][0][8][4] = 60, ++ [1][0][0][0][11][4] = 58, ++ [1][0][0][0][2][5] = 60, ++ [1][0][0][0][1][5] = 58, ++ [1][0][0][0][3][5] = 68, ++ [1][0][0][0][5][5] = 60, ++ [1][0][0][0][6][5] = 58, ++ [1][0][0][0][9][5] = 58, ++ [1][0][0][0][8][5] = 60, ++ [1][0][0][0][11][5] = 58, ++ [1][0][0][0][2][6] = 46, ++ [1][0][0][0][1][6] = 58, ++ [1][0][0][0][3][6] = 68, ++ [1][0][0][0][5][6] = 46, ++ [1][0][0][0][6][6] = 58, ++ [1][0][0][0][9][6] = 58, ++ [1][0][0][0][8][6] = 60, ++ [1][0][0][0][11][6] = 58, ++ [1][0][0][0][2][7] = 46, ++ [1][0][0][0][1][7] = 58, ++ [1][0][0][0][3][7] = 68, ++ [1][0][0][0][5][7] = 46, ++ [1][0][0][0][6][7] = 58, ++ [1][0][0][0][9][7] = 58, ++ [1][0][0][0][8][7] = 60, ++ [1][0][0][0][11][7] = 58, ++ [1][0][0][0][2][8] = 46, ++ [1][0][0][0][1][8] = 58, ++ [1][0][0][0][3][8] = 68, ++ [1][0][0][0][5][8] = 46, ++ [1][0][0][0][6][8] = 58, ++ [1][0][0][0][9][8] = 58, ++ [1][0][0][0][8][8] = 60, ++ [1][0][0][0][11][8] = 58, ++ [1][0][0][0][2][9] = 32, ++ [1][0][0][0][1][9] = 58, ++ [1][0][0][0][3][9] = 68, ++ [1][0][0][0][5][9] = 32, ++ [1][0][0][0][6][9] = 58, ++ [1][0][0][0][9][9] = 58, ++ [1][0][0][0][8][9] = 60, ++ [1][0][0][0][11][9] = 58, ++ [1][0][0][0][2][10] = 32, ++ [1][0][0][0][1][10] = 58, ++ [1][0][0][0][3][10] = 68, ++ [1][0][0][0][5][10] = 32, ++ [1][0][0][0][6][10] = 58, ++ [1][0][0][0][9][10] = 58, ++ [1][0][0][0][8][10] = 60, ++ [1][0][0][0][11][10] = 58, ++ [1][0][0][0][2][11] = 127, ++ [1][0][0][0][1][11] = 127, ++ [1][0][0][0][3][11] = 127, ++ [1][0][0][0][5][11] = 127, ++ [1][0][0][0][6][11] = 127, ++ [1][0][0][0][9][11] = 127, ++ [1][0][0][0][8][11] = 127, ++ [1][0][0][0][11][11] = 127, ++ [1][0][0][0][2][12] = 127, ++ [1][0][0][0][1][12] = 127, ++ [1][0][0][0][3][12] = 127, ++ [1][0][0][0][5][12] = 127, ++ [1][0][0][0][6][12] = 127, ++ [1][0][0][0][9][12] = 127, ++ [1][0][0][0][8][12] = 127, ++ [1][0][0][0][11][12] = 127, ++ [1][0][0][0][2][13] = 127, ++ [1][0][0][0][1][13] = 127, ++ [1][0][0][0][3][13] = 127, ++ [1][0][0][0][5][13] = 127, ++ [1][0][0][0][6][13] = 127, ++ [1][0][0][0][9][13] = 127, ++ [1][0][0][0][8][13] = 127, ++ [1][0][0][0][11][13] = 127, ++ [1][1][0][0][2][0] = 127, ++ [1][1][0][0][1][0] = 127, ++ [1][1][0][0][3][0] = 127, ++ [1][1][0][0][5][0] = 127, ++ [1][1][0][0][6][0] = 127, ++ [1][1][0][0][9][0] = 127, ++ [1][1][0][0][8][0] = 127, ++ [1][1][0][0][11][0] = 127, ++ [1][1][0][0][2][1] = 127, ++ [1][1][0][0][1][1] = 127, ++ [1][1][0][0][3][1] = 127, ++ [1][1][0][0][5][1] = 127, ++ [1][1][0][0][6][1] = 127, ++ [1][1][0][0][9][1] = 127, ++ [1][1][0][0][8][1] = 127, ++ [1][1][0][0][11][1] = 127, ++ [1][1][0][0][2][2] = 48, ++ [1][1][0][0][1][2] = 46, ++ [1][1][0][0][3][2] = 56, ++ [1][1][0][0][5][2] = 48, ++ [1][1][0][0][6][2] = 46, ++ [1][1][0][0][9][2] = 46, ++ [1][1][0][0][8][2] = 48, ++ [1][1][0][0][11][2] = 46, ++ [1][1][0][0][2][3] = 48, ++ [1][1][0][0][1][3] = 46, ++ [1][1][0][0][3][3] = 56, ++ [1][1][0][0][5][3] = 48, ++ [1][1][0][0][6][3] = 46, ++ [1][1][0][0][9][3] = 46, ++ [1][1][0][0][8][3] = 48, ++ [1][1][0][0][11][3] = 46, ++ [1][1][0][0][2][4] = 48, ++ [1][1][0][0][1][4] = 46, ++ [1][1][0][0][3][4] = 56, ++ [1][1][0][0][5][4] = 48, ++ [1][1][0][0][6][4] = 46, ++ [1][1][0][0][9][4] = 46, ++ [1][1][0][0][8][4] = 48, ++ [1][1][0][0][11][4] = 46, ++ [1][1][0][0][2][5] = 58, ++ [1][1][0][0][1][5] = 46, ++ [1][1][0][0][3][5] = 56, ++ [1][1][0][0][5][5] = 58, ++ [1][1][0][0][6][5] = 46, ++ [1][1][0][0][9][5] = 46, ++ [1][1][0][0][8][5] = 48, ++ [1][1][0][0][11][5] = 46, ++ [1][1][0][0][2][6] = 46, ++ [1][1][0][0][1][6] = 46, ++ [1][1][0][0][3][6] = 56, ++ [1][1][0][0][5][6] = 46, ++ [1][1][0][0][6][6] = 46, ++ [1][1][0][0][9][6] = 46, ++ [1][1][0][0][8][6] = 48, ++ [1][1][0][0][11][6] = 46, ++ [1][1][0][0][2][7] = 46, ++ [1][1][0][0][1][7] = 46, ++ [1][1][0][0][3][7] = 56, ++ [1][1][0][0][5][7] = 46, ++ [1][1][0][0][6][7] = 46, ++ [1][1][0][0][9][7] = 46, ++ [1][1][0][0][8][7] = 48, ++ [1][1][0][0][11][7] = 46, ++ [1][1][0][0][2][8] = 46, ++ [1][1][0][0][1][8] = 46, ++ [1][1][0][0][3][8] = 56, ++ [1][1][0][0][5][8] = 46, ++ [1][1][0][0][6][8] = 46, ++ [1][1][0][0][9][8] = 46, ++ [1][1][0][0][8][8] = 48, ++ [1][1][0][0][11][8] = 46, ++ [1][1][0][0][2][9] = 24, ++ [1][1][0][0][1][9] = 46, ++ [1][1][0][0][3][9] = 56, ++ [1][1][0][0][5][9] = 24, ++ [1][1][0][0][6][9] = 46, ++ [1][1][0][0][9][9] = 46, ++ [1][1][0][0][8][9] = 48, ++ [1][1][0][0][11][9] = 46, ++ [1][1][0][0][2][10] = 24, ++ [1][1][0][0][1][10] = 46, ++ [1][1][0][0][3][10] = 56, ++ [1][1][0][0][5][10] = 24, ++ [1][1][0][0][6][10] = 46, ++ [1][1][0][0][9][10] = 46, ++ [1][1][0][0][8][10] = 48, ++ [1][1][0][0][11][10] = 46, ++ [1][1][0][0][2][11] = 127, ++ [1][1][0][0][1][11] = 127, ++ [1][1][0][0][3][11] = 127, ++ [1][1][0][0][5][11] = 127, ++ [1][1][0][0][6][11] = 127, ++ [1][1][0][0][9][11] = 127, ++ [1][1][0][0][8][11] = 127, ++ [1][1][0][0][11][11] = 127, ++ [1][1][0][0][2][12] = 127, ++ [1][1][0][0][1][12] = 127, ++ [1][1][0][0][3][12] = 127, ++ [1][1][0][0][5][12] = 127, ++ [1][1][0][0][6][12] = 127, ++ [1][1][0][0][9][12] = 127, ++ [1][1][0][0][8][12] = 127, ++ [1][1][0][0][11][12] = 127, ++ [1][1][0][0][2][13] = 127, ++ [1][1][0][0][1][13] = 127, ++ [1][1][0][0][3][13] = 127, ++ [1][1][0][0][5][13] = 127, ++ [1][1][0][0][6][13] = 127, ++ [1][1][0][0][9][13] = 127, ++ [1][1][0][0][8][13] = 127, ++ [1][1][0][0][11][13] = 127, ++ [0][0][1][0][2][0] = 66, ++ [0][0][1][0][1][0] = 58, ++ [0][0][1][0][3][0] = 76, ++ [0][0][1][0][5][0] = 66, ++ [0][0][1][0][6][0] = 58, ++ [0][0][1][0][9][0] = 58, ++ [0][0][1][0][8][0] = 60, ++ [0][0][1][0][11][0] = 58, ++ [0][0][1][0][2][1] = 66, ++ [0][0][1][0][1][1] = 58, ++ [0][0][1][0][3][1] = 76, ++ [0][0][1][0][5][1] = 66, ++ [0][0][1][0][6][1] = 58, ++ [0][0][1][0][9][1] = 58, ++ [0][0][1][0][8][1] = 60, ++ [0][0][1][0][11][1] = 58, ++ [0][0][1][0][2][2] = 70, ++ [0][0][1][0][1][2] = 58, ++ [0][0][1][0][3][2] = 76, ++ [0][0][1][0][5][2] = 70, ++ [0][0][1][0][6][2] = 58, ++ [0][0][1][0][9][2] = 58, ++ [0][0][1][0][8][2] = 60, ++ [0][0][1][0][11][2] = 58, ++ [0][0][1][0][2][3] = 74, ++ [0][0][1][0][1][3] = 58, ++ [0][0][1][0][3][3] = 76, ++ [0][0][1][0][5][3] = 74, ++ [0][0][1][0][6][3] = 58, ++ [0][0][1][0][9][3] = 58, ++ [0][0][1][0][8][3] = 60, ++ [0][0][1][0][11][3] = 58, ++ [0][0][1][0][2][4] = 78, ++ [0][0][1][0][1][4] = 58, ++ [0][0][1][0][3][4] = 76, ++ [0][0][1][0][5][4] = 78, ++ [0][0][1][0][6][4] = 58, ++ [0][0][1][0][9][4] = 58, ++ [0][0][1][0][8][4] = 60, ++ [0][0][1][0][11][4] = 58, ++ [0][0][1][0][2][5] = 78, ++ [0][0][1][0][1][5] = 58, ++ [0][0][1][0][3][5] = 76, ++ [0][0][1][0][5][5] = 78, ++ [0][0][1][0][6][5] = 58, ++ [0][0][1][0][9][5] = 58, ++ [0][0][1][0][8][5] = 60, ++ [0][0][1][0][11][5] = 58, ++ [0][0][1][0][2][6] = 78, ++ [0][0][1][0][1][6] = 58, ++ [0][0][1][0][3][6] = 76, ++ [0][0][1][0][5][6] = 78, ++ [0][0][1][0][6][6] = 58, ++ [0][0][1][0][9][6] = 58, ++ [0][0][1][0][8][6] = 60, ++ [0][0][1][0][11][6] = 58, ++ [0][0][1][0][2][7] = 74, ++ [0][0][1][0][1][7] = 58, ++ [0][0][1][0][3][7] = 76, ++ [0][0][1][0][5][7] = 74, ++ [0][0][1][0][6][7] = 58, ++ [0][0][1][0][9][7] = 58, ++ [0][0][1][0][8][7] = 60, ++ [0][0][1][0][11][7] = 58, ++ [0][0][1][0][2][8] = 70, ++ [0][0][1][0][1][8] = 58, ++ [0][0][1][0][3][8] = 76, ++ [0][0][1][0][5][8] = 70, ++ [0][0][1][0][6][8] = 58, ++ [0][0][1][0][9][8] = 58, ++ [0][0][1][0][8][8] = 60, ++ [0][0][1][0][11][8] = 58, ++ [0][0][1][0][2][9] = 66, ++ [0][0][1][0][1][9] = 58, ++ [0][0][1][0][3][9] = 76, ++ [0][0][1][0][5][9] = 66, ++ [0][0][1][0][6][9] = 58, ++ [0][0][1][0][9][9] = 58, ++ [0][0][1][0][8][9] = 60, ++ [0][0][1][0][11][9] = 58, ++ [0][0][1][0][2][10] = 66, ++ [0][0][1][0][1][10] = 58, ++ [0][0][1][0][3][10] = 76, ++ [0][0][1][0][5][10] = 66, ++ [0][0][1][0][6][10] = 58, ++ [0][0][1][0][9][10] = 58, ++ [0][0][1][0][8][10] = 60, ++ [0][0][1][0][11][10] = 58, ++ [0][0][1][0][2][11] = 56, ++ [0][0][1][0][1][11] = 58, ++ [0][0][1][0][3][11] = 76, ++ [0][0][1][0][5][11] = 56, ++ [0][0][1][0][6][11] = 58, ++ [0][0][1][0][9][11] = 58, ++ [0][0][1][0][8][11] = 60, ++ [0][0][1][0][11][11] = 58, ++ [0][0][1][0][2][12] = 52, ++ [0][0][1][0][1][12] = 58, ++ [0][0][1][0][3][12] = 76, ++ [0][0][1][0][5][12] = 52, ++ [0][0][1][0][6][12] = 58, ++ [0][0][1][0][9][12] = 58, ++ [0][0][1][0][8][12] = 60, ++ [0][0][1][0][11][12] = 58, ++ [0][0][1][0][2][13] = 127, ++ [0][0][1][0][1][13] = 127, ++ [0][0][1][0][3][13] = 127, ++ [0][0][1][0][5][13] = 127, ++ [0][0][1][0][6][13] = 127, ++ [0][0][1][0][9][13] = 127, ++ [0][0][1][0][8][13] = 127, ++ [0][0][1][0][11][13] = 127, ++ [0][1][1][0][2][0] = 62, ++ [0][1][1][0][1][0] = 46, ++ [0][1][1][0][3][0] = 64, ++ [0][1][1][0][5][0] = 62, ++ [0][1][1][0][6][0] = 46, ++ [0][1][1][0][9][0] = 46, ++ [0][1][1][0][8][0] = 48, ++ [0][1][1][0][11][0] = 46, ++ [0][1][1][0][2][1] = 62, ++ [0][1][1][0][1][1] = 46, ++ [0][1][1][0][3][1] = 64, ++ [0][1][1][0][5][1] = 62, ++ [0][1][1][0][6][1] = 46, ++ [0][1][1][0][9][1] = 46, ++ [0][1][1][0][8][1] = 48, ++ [0][1][1][0][11][1] = 46, ++ [0][1][1][0][2][2] = 66, ++ [0][1][1][0][1][2] = 46, ++ [0][1][1][0][3][2] = 64, ++ [0][1][1][0][5][2] = 66, ++ [0][1][1][0][6][2] = 46, ++ [0][1][1][0][9][2] = 46, ++ [0][1][1][0][8][2] = 48, ++ [0][1][1][0][11][2] = 46, ++ [0][1][1][0][2][3] = 70, ++ [0][1][1][0][1][3] = 46, ++ [0][1][1][0][3][3] = 64, ++ [0][1][1][0][5][3] = 70, ++ [0][1][1][0][6][3] = 46, ++ [0][1][1][0][9][3] = 46, ++ [0][1][1][0][8][3] = 48, ++ [0][1][1][0][11][3] = 46, ++ [0][1][1][0][2][4] = 78, ++ [0][1][1][0][1][4] = 46, ++ [0][1][1][0][3][4] = 64, ++ [0][1][1][0][5][4] = 78, ++ [0][1][1][0][6][4] = 46, ++ [0][1][1][0][9][4] = 46, ++ [0][1][1][0][8][4] = 48, ++ [0][1][1][0][11][4] = 46, ++ [0][1][1][0][2][5] = 78, ++ [0][1][1][0][1][5] = 46, ++ [0][1][1][0][3][5] = 64, ++ [0][1][1][0][5][5] = 78, ++ [0][1][1][0][6][5] = 46, ++ [0][1][1][0][9][5] = 46, ++ [0][1][1][0][8][5] = 48, ++ [0][1][1][0][11][5] = 46, ++ [0][1][1][0][2][6] = 78, ++ [0][1][1][0][1][6] = 46, ++ [0][1][1][0][3][6] = 64, ++ [0][1][1][0][5][6] = 78, ++ [0][1][1][0][6][6] = 46, ++ [0][1][1][0][9][6] = 46, ++ [0][1][1][0][8][6] = 48, ++ [0][1][1][0][11][6] = 46, ++ [0][1][1][0][2][7] = 70, ++ [0][1][1][0][1][7] = 46, ++ [0][1][1][0][3][7] = 64, ++ [0][1][1][0][5][7] = 70, ++ [0][1][1][0][6][7] = 46, ++ [0][1][1][0][9][7] = 46, ++ [0][1][1][0][8][7] = 48, ++ [0][1][1][0][11][7] = 46, ++ [0][1][1][0][2][8] = 66, ++ [0][1][1][0][1][8] = 46, ++ [0][1][1][0][3][8] = 64, ++ [0][1][1][0][5][8] = 66, ++ [0][1][1][0][6][8] = 46, ++ [0][1][1][0][9][8] = 46, ++ [0][1][1][0][8][8] = 48, ++ [0][1][1][0][11][8] = 46, ++ [0][1][1][0][2][9] = 62, ++ [0][1][1][0][1][9] = 46, ++ [0][1][1][0][3][9] = 64, ++ [0][1][1][0][5][9] = 62, ++ [0][1][1][0][6][9] = 46, ++ [0][1][1][0][9][9] = 46, ++ [0][1][1][0][8][9] = 48, ++ [0][1][1][0][11][9] = 46, ++ [0][1][1][0][2][10] = 62, ++ [0][1][1][0][1][10] = 46, ++ [0][1][1][0][3][10] = 64, ++ [0][1][1][0][5][10] = 62, ++ [0][1][1][0][6][10] = 46, ++ [0][1][1][0][9][10] = 46, ++ [0][1][1][0][8][10] = 48, ++ [0][1][1][0][11][10] = 46, ++ [0][1][1][0][2][11] = 42, ++ [0][1][1][0][1][11] = 46, ++ [0][1][1][0][3][11] = 64, ++ [0][1][1][0][5][11] = 42, ++ [0][1][1][0][6][11] = 46, ++ [0][1][1][0][9][11] = 46, ++ [0][1][1][0][8][11] = 48, ++ [0][1][1][0][11][11] = 46, ++ [0][1][1][0][2][12] = 40, ++ [0][1][1][0][1][12] = 46, ++ [0][1][1][0][3][12] = 64, ++ [0][1][1][0][5][12] = 40, ++ [0][1][1][0][6][12] = 46, ++ [0][1][1][0][9][12] = 46, ++ [0][1][1][0][8][12] = 48, ++ [0][1][1][0][11][12] = 46, ++ [0][1][1][0][2][13] = 127, ++ [0][1][1][0][1][13] = 127, ++ [0][1][1][0][3][13] = 127, ++ [0][1][1][0][5][13] = 127, ++ [0][1][1][0][6][13] = 127, ++ [0][1][1][0][9][13] = 127, ++ [0][1][1][0][8][13] = 127, ++ [0][1][1][0][11][13] = 127, ++ [0][0][2][0][2][0] = 66, ++ [0][0][2][0][1][0] = 58, ++ [0][0][2][0][3][0] = 76, ++ [0][0][2][0][5][0] = 66, ++ [0][0][2][0][6][0] = 58, ++ [0][0][2][0][9][0] = 58, ++ [0][0][2][0][8][0] = 60, ++ [0][0][2][0][11][0] = 58, ++ [0][0][2][0][2][1] = 66, ++ [0][0][2][0][1][1] = 58, ++ [0][0][2][0][3][1] = 76, ++ [0][0][2][0][5][1] = 66, ++ [0][0][2][0][6][1] = 58, ++ [0][0][2][0][9][1] = 58, ++ [0][0][2][0][8][1] = 60, ++ [0][0][2][0][11][1] = 58, ++ [0][0][2][0][2][2] = 70, ++ [0][0][2][0][1][2] = 58, ++ [0][0][2][0][3][2] = 76, ++ [0][0][2][0][5][2] = 70, ++ [0][0][2][0][6][2] = 58, ++ [0][0][2][0][9][2] = 58, ++ [0][0][2][0][8][2] = 60, ++ [0][0][2][0][11][2] = 58, ++ [0][0][2][0][2][3] = 74, ++ [0][0][2][0][1][3] = 58, ++ [0][0][2][0][3][3] = 76, ++ [0][0][2][0][5][3] = 74, ++ [0][0][2][0][6][3] = 58, ++ [0][0][2][0][9][3] = 58, ++ [0][0][2][0][8][3] = 60, ++ [0][0][2][0][11][3] = 58, ++ [0][0][2][0][2][4] = 76, ++ [0][0][2][0][1][4] = 58, ++ [0][0][2][0][3][4] = 76, ++ [0][0][2][0][5][4] = 76, ++ [0][0][2][0][6][4] = 58, ++ [0][0][2][0][9][4] = 58, ++ [0][0][2][0][8][4] = 60, ++ [0][0][2][0][11][4] = 58, ++ [0][0][2][0][2][5] = 76, ++ [0][0][2][0][1][5] = 58, ++ [0][0][2][0][3][5] = 76, ++ [0][0][2][0][5][5] = 76, ++ [0][0][2][0][6][5] = 58, ++ [0][0][2][0][9][5] = 58, ++ [0][0][2][0][8][5] = 60, ++ [0][0][2][0][11][5] = 58, ++ [0][0][2][0][2][6] = 76, ++ [0][0][2][0][1][6] = 58, ++ [0][0][2][0][3][6] = 76, ++ [0][0][2][0][5][6] = 76, ++ [0][0][2][0][6][6] = 58, ++ [0][0][2][0][9][6] = 58, ++ [0][0][2][0][8][6] = 60, ++ [0][0][2][0][11][6] = 58, ++ [0][0][2][0][2][7] = 74, ++ [0][0][2][0][1][7] = 58, ++ [0][0][2][0][3][7] = 76, ++ [0][0][2][0][5][7] = 74, ++ [0][0][2][0][6][7] = 58, ++ [0][0][2][0][9][7] = 58, ++ [0][0][2][0][8][7] = 60, ++ [0][0][2][0][11][7] = 58, ++ [0][0][2][0][2][8] = 70, ++ [0][0][2][0][1][8] = 58, ++ [0][0][2][0][3][8] = 76, ++ [0][0][2][0][5][8] = 70, ++ [0][0][2][0][6][8] = 58, ++ [0][0][2][0][9][8] = 58, ++ [0][0][2][0][8][8] = 60, ++ [0][0][2][0][11][8] = 58, ++ [0][0][2][0][2][9] = 66, ++ [0][0][2][0][1][9] = 58, ++ [0][0][2][0][3][9] = 76, ++ [0][0][2][0][5][9] = 66, ++ [0][0][2][0][6][9] = 58, ++ [0][0][2][0][9][9] = 58, ++ [0][0][2][0][8][9] = 60, ++ [0][0][2][0][11][9] = 58, ++ [0][0][2][0][2][10] = 66, ++ [0][0][2][0][1][10] = 58, ++ [0][0][2][0][3][10] = 76, ++ [0][0][2][0][5][10] = 66, ++ [0][0][2][0][6][10] = 58, ++ [0][0][2][0][9][10] = 58, ++ [0][0][2][0][8][10] = 60, ++ [0][0][2][0][11][10] = 58, ++ [0][0][2][0][2][11] = 54, ++ [0][0][2][0][1][11] = 58, ++ [0][0][2][0][3][11] = 76, ++ [0][0][2][0][5][11] = 54, ++ [0][0][2][0][6][11] = 58, ++ [0][0][2][0][9][11] = 58, ++ [0][0][2][0][8][11] = 60, ++ [0][0][2][0][11][11] = 58, ++ [0][0][2][0][2][12] = 50, ++ [0][0][2][0][1][12] = 58, ++ [0][0][2][0][3][12] = 76, ++ [0][0][2][0][5][12] = 50, ++ [0][0][2][0][6][12] = 58, ++ [0][0][2][0][9][12] = 58, ++ [0][0][2][0][8][12] = 60, ++ [0][0][2][0][11][12] = 58, ++ [0][0][2][0][2][13] = 127, ++ [0][0][2][0][1][13] = 127, ++ [0][0][2][0][3][13] = 127, ++ [0][0][2][0][5][13] = 127, ++ [0][0][2][0][6][13] = 127, ++ [0][0][2][0][9][13] = 127, ++ [0][0][2][0][8][13] = 127, ++ [0][0][2][0][11][13] = 127, ++ [0][1][2][0][2][0] = 62, ++ [0][1][2][0][1][0] = 46, ++ [0][1][2][0][3][0] = 64, ++ [0][1][2][0][5][0] = 62, ++ [0][1][2][0][6][0] = 46, ++ [0][1][2][0][9][0] = 46, ++ [0][1][2][0][8][0] = 48, ++ [0][1][2][0][11][0] = 46, ++ [0][1][2][0][2][1] = 62, ++ [0][1][2][0][1][1] = 46, ++ [0][1][2][0][3][1] = 64, ++ [0][1][2][0][5][1] = 62, ++ [0][1][2][0][6][1] = 46, ++ [0][1][2][0][9][1] = 46, ++ [0][1][2][0][8][1] = 48, ++ [0][1][2][0][11][1] = 46, ++ [0][1][2][0][2][2] = 66, ++ [0][1][2][0][1][2] = 46, ++ [0][1][2][0][3][2] = 64, ++ [0][1][2][0][5][2] = 66, ++ [0][1][2][0][6][2] = 46, ++ [0][1][2][0][9][2] = 46, ++ [0][1][2][0][8][2] = 48, ++ [0][1][2][0][11][2] = 46, ++ [0][1][2][0][2][3] = 70, ++ [0][1][2][0][1][3] = 46, ++ [0][1][2][0][3][3] = 64, ++ [0][1][2][0][5][3] = 70, ++ [0][1][2][0][6][3] = 46, ++ [0][1][2][0][9][3] = 46, ++ [0][1][2][0][8][3] = 48, ++ [0][1][2][0][11][3] = 46, ++ [0][1][2][0][2][4] = 76, ++ [0][1][2][0][1][4] = 46, ++ [0][1][2][0][3][4] = 64, ++ [0][1][2][0][5][4] = 76, ++ [0][1][2][0][6][4] = 46, ++ [0][1][2][0][9][4] = 46, ++ [0][1][2][0][8][4] = 48, ++ [0][1][2][0][11][4] = 46, ++ [0][1][2][0][2][5] = 76, ++ [0][1][2][0][1][5] = 46, ++ [0][1][2][0][3][5] = 64, ++ [0][1][2][0][5][5] = 76, ++ [0][1][2][0][6][5] = 46, ++ [0][1][2][0][9][5] = 46, ++ [0][1][2][0][8][5] = 48, ++ [0][1][2][0][11][5] = 46, ++ [0][1][2][0][2][6] = 76, ++ [0][1][2][0][1][6] = 46, ++ [0][1][2][0][3][6] = 64, ++ [0][1][2][0][5][6] = 76, ++ [0][1][2][0][6][6] = 46, ++ [0][1][2][0][9][6] = 46, ++ [0][1][2][0][8][6] = 48, ++ [0][1][2][0][11][6] = 46, ++ [0][1][2][0][2][7] = 68, ++ [0][1][2][0][1][7] = 46, ++ [0][1][2][0][3][7] = 64, ++ [0][1][2][0][5][7] = 68, ++ [0][1][2][0][6][7] = 46, ++ [0][1][2][0][9][7] = 46, ++ [0][1][2][0][8][7] = 48, ++ [0][1][2][0][11][7] = 46, ++ [0][1][2][0][2][8] = 64, ++ [0][1][2][0][1][8] = 46, ++ [0][1][2][0][3][8] = 64, ++ [0][1][2][0][5][8] = 64, ++ [0][1][2][0][6][8] = 46, ++ [0][1][2][0][9][8] = 46, ++ [0][1][2][0][8][8] = 48, ++ [0][1][2][0][11][8] = 46, ++ [0][1][2][0][2][9] = 60, ++ [0][1][2][0][1][9] = 46, ++ [0][1][2][0][3][9] = 64, ++ [0][1][2][0][5][9] = 60, ++ [0][1][2][0][6][9] = 46, ++ [0][1][2][0][9][9] = 46, ++ [0][1][2][0][8][9] = 48, ++ [0][1][2][0][11][9] = 46, ++ [0][1][2][0][2][10] = 60, ++ [0][1][2][0][1][10] = 46, ++ [0][1][2][0][3][10] = 64, ++ [0][1][2][0][5][10] = 60, ++ [0][1][2][0][6][10] = 46, ++ [0][1][2][0][9][10] = 46, ++ [0][1][2][0][8][10] = 48, ++ [0][1][2][0][11][10] = 46, ++ [0][1][2][0][2][11] = 42, ++ [0][1][2][0][1][11] = 46, ++ [0][1][2][0][3][11] = 64, ++ [0][1][2][0][5][11] = 42, ++ [0][1][2][0][6][11] = 46, ++ [0][1][2][0][9][11] = 46, ++ [0][1][2][0][8][11] = 48, ++ [0][1][2][0][11][11] = 46, ++ [0][1][2][0][2][12] = 40, ++ [0][1][2][0][1][12] = 46, ++ [0][1][2][0][3][12] = 64, ++ [0][1][2][0][5][12] = 40, ++ [0][1][2][0][6][12] = 46, ++ [0][1][2][0][9][12] = 46, ++ [0][1][2][0][8][12] = 48, ++ [0][1][2][0][11][12] = 46, ++ [0][1][2][0][2][13] = 127, ++ [0][1][2][0][1][13] = 127, ++ [0][1][2][0][3][13] = 127, ++ [0][1][2][0][5][13] = 127, ++ [0][1][2][0][6][13] = 127, ++ [0][1][2][0][9][13] = 127, ++ [0][1][2][0][8][13] = 127, ++ [0][1][2][0][11][13] = 127, ++ [0][1][2][1][2][0] = 62, ++ [0][1][2][1][1][0] = 34, ++ [0][1][2][1][3][0] = 64, ++ [0][1][2][1][5][0] = 62, ++ [0][1][2][1][6][0] = 34, ++ [0][1][2][1][9][0] = 34, ++ [0][1][2][1][8][0] = 36, ++ [0][1][2][1][11][0] = 34, ++ [0][1][2][1][2][1] = 62, ++ [0][1][2][1][1][1] = 34, ++ [0][1][2][1][3][1] = 64, ++ [0][1][2][1][5][1] = 62, ++ [0][1][2][1][6][1] = 34, ++ [0][1][2][1][9][1] = 34, ++ [0][1][2][1][8][1] = 36, ++ [0][1][2][1][11][1] = 34, ++ [0][1][2][1][2][2] = 66, ++ [0][1][2][1][1][2] = 34, ++ [0][1][2][1][3][2] = 64, ++ [0][1][2][1][5][2] = 66, ++ [0][1][2][1][6][2] = 34, ++ [0][1][2][1][9][2] = 34, ++ [0][1][2][1][8][2] = 36, ++ [0][1][2][1][11][2] = 34, ++ [0][1][2][1][2][3] = 70, ++ [0][1][2][1][1][3] = 34, ++ [0][1][2][1][3][3] = 64, ++ [0][1][2][1][5][3] = 70, ++ [0][1][2][1][6][3] = 34, ++ [0][1][2][1][9][3] = 34, ++ [0][1][2][1][8][3] = 36, ++ [0][1][2][1][11][3] = 34, ++ [0][1][2][1][2][4] = 76, ++ [0][1][2][1][1][4] = 34, ++ [0][1][2][1][3][4] = 64, ++ [0][1][2][1][5][4] = 76, ++ [0][1][2][1][6][4] = 34, ++ [0][1][2][1][9][4] = 34, ++ [0][1][2][1][8][4] = 36, ++ [0][1][2][1][11][4] = 34, ++ [0][1][2][1][2][5] = 76, ++ [0][1][2][1][1][5] = 34, ++ [0][1][2][1][3][5] = 64, ++ [0][1][2][1][5][5] = 76, ++ [0][1][2][1][6][5] = 34, ++ [0][1][2][1][9][5] = 34, ++ [0][1][2][1][8][5] = 36, ++ [0][1][2][1][11][5] = 34, ++ [0][1][2][1][2][6] = 76, ++ [0][1][2][1][1][6] = 34, ++ [0][1][2][1][3][6] = 64, ++ [0][1][2][1][5][6] = 76, ++ [0][1][2][1][6][6] = 34, ++ [0][1][2][1][9][6] = 34, ++ [0][1][2][1][8][6] = 36, ++ [0][1][2][1][11][6] = 34, ++ [0][1][2][1][2][7] = 68, ++ [0][1][2][1][1][7] = 34, ++ [0][1][2][1][3][7] = 64, ++ [0][1][2][1][5][7] = 68, ++ [0][1][2][1][6][7] = 34, ++ [0][1][2][1][9][7] = 34, ++ [0][1][2][1][8][7] = 36, ++ [0][1][2][1][11][7] = 34, ++ [0][1][2][1][2][8] = 64, ++ [0][1][2][1][1][8] = 34, ++ [0][1][2][1][3][8] = 64, ++ [0][1][2][1][5][8] = 64, ++ [0][1][2][1][6][8] = 34, ++ [0][1][2][1][9][8] = 34, ++ [0][1][2][1][8][8] = 36, ++ [0][1][2][1][11][8] = 34, ++ [0][1][2][1][2][9] = 60, ++ [0][1][2][1][1][9] = 34, ++ [0][1][2][1][3][9] = 64, ++ [0][1][2][1][5][9] = 60, ++ [0][1][2][1][6][9] = 34, ++ [0][1][2][1][9][9] = 34, ++ [0][1][2][1][8][9] = 36, ++ [0][1][2][1][11][9] = 34, ++ [0][1][2][1][2][10] = 60, ++ [0][1][2][1][1][10] = 34, ++ [0][1][2][1][3][10] = 64, ++ [0][1][2][1][5][10] = 60, ++ [0][1][2][1][6][10] = 34, ++ [0][1][2][1][9][10] = 34, ++ [0][1][2][1][8][10] = 36, ++ [0][1][2][1][11][10] = 34, ++ [0][1][2][1][2][11] = 42, ++ [0][1][2][1][1][11] = 34, ++ [0][1][2][1][3][11] = 64, ++ [0][1][2][1][5][11] = 42, ++ [0][1][2][1][6][11] = 34, ++ [0][1][2][1][9][11] = 34, ++ [0][1][2][1][8][11] = 36, ++ [0][1][2][1][11][11] = 34, ++ [0][1][2][1][2][12] = 40, ++ [0][1][2][1][1][12] = 34, ++ [0][1][2][1][3][12] = 64, ++ [0][1][2][1][5][12] = 40, ++ [0][1][2][1][6][12] = 34, ++ [0][1][2][1][9][12] = 34, ++ [0][1][2][1][8][12] = 36, ++ [0][1][2][1][11][12] = 34, ++ [0][1][2][1][2][13] = 127, ++ [0][1][2][1][1][13] = 127, ++ [0][1][2][1][3][13] = 127, ++ [0][1][2][1][5][13] = 127, ++ [0][1][2][1][6][13] = 127, ++ [0][1][2][1][9][13] = 127, ++ [0][1][2][1][8][13] = 127, ++ [0][1][2][1][11][13] = 127, ++ [1][0][2][0][2][0] = 127, ++ [1][0][2][0][1][0] = 127, ++ [1][0][2][0][3][0] = 127, ++ [1][0][2][0][5][0] = 127, ++ [1][0][2][0][6][0] = 127, ++ [1][0][2][0][9][0] = 127, ++ [1][0][2][0][8][0] = 127, ++ [1][0][2][0][11][0] = 127, ++ [1][0][2][0][2][1] = 127, ++ [1][0][2][0][1][1] = 127, ++ [1][0][2][0][3][1] = 127, ++ [1][0][2][0][5][1] = 127, ++ [1][0][2][0][6][1] = 127, ++ [1][0][2][0][9][1] = 127, ++ [1][0][2][0][8][1] = 127, ++ [1][0][2][0][11][1] = 127, ++ [1][0][2][0][2][2] = 56, ++ [1][0][2][0][1][2] = 58, ++ [1][0][2][0][3][2] = 76, ++ [1][0][2][0][5][2] = 56, ++ [1][0][2][0][6][2] = 58, ++ [1][0][2][0][9][2] = 58, ++ [1][0][2][0][8][2] = 60, ++ [1][0][2][0][11][2] = 58, ++ [1][0][2][0][2][3] = 56, ++ [1][0][2][0][1][3] = 58, ++ [1][0][2][0][3][3] = 76, ++ [1][0][2][0][5][3] = 56, ++ [1][0][2][0][6][3] = 58, ++ [1][0][2][0][9][3] = 58, ++ [1][0][2][0][8][3] = 60, ++ [1][0][2][0][11][3] = 58, ++ [1][0][2][0][2][4] = 60, ++ [1][0][2][0][1][4] = 58, ++ [1][0][2][0][3][4] = 76, ++ [1][0][2][0][5][4] = 60, ++ [1][0][2][0][6][4] = 58, ++ [1][0][2][0][9][4] = 58, ++ [1][0][2][0][8][4] = 60, ++ [1][0][2][0][11][4] = 58, ++ [1][0][2][0][2][5] = 64, ++ [1][0][2][0][1][5] = 58, ++ [1][0][2][0][3][5] = 76, ++ [1][0][2][0][5][5] = 64, ++ [1][0][2][0][6][5] = 58, ++ [1][0][2][0][9][5] = 58, ++ [1][0][2][0][8][5] = 60, ++ [1][0][2][0][11][5] = 58, ++ [1][0][2][0][2][6] = 54, ++ [1][0][2][0][1][6] = 58, ++ [1][0][2][0][3][6] = 76, ++ [1][0][2][0][5][6] = 54, ++ [1][0][2][0][6][6] = 58, ++ [1][0][2][0][9][6] = 58, ++ [1][0][2][0][8][6] = 60, ++ [1][0][2][0][11][6] = 58, ++ [1][0][2][0][2][7] = 50, ++ [1][0][2][0][1][7] = 58, ++ [1][0][2][0][3][7] = 76, ++ [1][0][2][0][5][7] = 50, ++ [1][0][2][0][6][7] = 58, ++ [1][0][2][0][9][7] = 58, ++ [1][0][2][0][8][7] = 60, ++ [1][0][2][0][11][7] = 58, ++ [1][0][2][0][2][8] = 50, ++ [1][0][2][0][1][8] = 58, ++ [1][0][2][0][3][8] = 76, ++ [1][0][2][0][5][8] = 50, ++ [1][0][2][0][6][8] = 58, ++ [1][0][2][0][9][8] = 58, ++ [1][0][2][0][8][8] = 60, ++ [1][0][2][0][11][8] = 58, ++ [1][0][2][0][2][9] = 42, ++ [1][0][2][0][1][9] = 58, ++ [1][0][2][0][3][9] = 76, ++ [1][0][2][0][5][9] = 42, ++ [1][0][2][0][6][9] = 58, ++ [1][0][2][0][9][9] = 58, ++ [1][0][2][0][8][9] = 60, ++ [1][0][2][0][11][9] = 58, ++ [1][0][2][0][2][10] = 40, ++ [1][0][2][0][1][10] = 58, ++ [1][0][2][0][3][10] = 76, ++ [1][0][2][0][5][10] = 40, ++ [1][0][2][0][6][10] = 58, ++ [1][0][2][0][9][10] = 58, ++ [1][0][2][0][8][10] = 60, ++ [1][0][2][0][11][10] = 58, ++ [1][0][2][0][2][11] = 127, ++ [1][0][2][0][1][11] = 127, ++ [1][0][2][0][3][11] = 127, ++ [1][0][2][0][5][11] = 127, ++ [1][0][2][0][6][11] = 127, ++ [1][0][2][0][9][11] = 127, ++ [1][0][2][0][8][11] = 127, ++ [1][0][2][0][11][11] = 127, ++ [1][0][2][0][2][12] = 127, ++ [1][0][2][0][1][12] = 127, ++ [1][0][2][0][3][12] = 127, ++ [1][0][2][0][5][12] = 127, ++ [1][0][2][0][6][12] = 127, ++ [1][0][2][0][9][12] = 127, ++ [1][0][2][0][8][12] = 127, ++ [1][0][2][0][11][12] = 127, ++ [1][0][2][0][2][13] = 127, ++ [1][0][2][0][1][13] = 127, ++ [1][0][2][0][3][13] = 127, ++ [1][0][2][0][5][13] = 127, ++ [1][0][2][0][6][13] = 127, ++ [1][0][2][0][9][13] = 127, ++ [1][0][2][0][8][13] = 127, ++ [1][0][2][0][11][13] = 127, ++ [1][1][2][0][2][0] = 127, ++ [1][1][2][0][1][0] = 127, ++ [1][1][2][0][3][0] = 127, ++ [1][1][2][0][5][0] = 127, ++ [1][1][2][0][6][0] = 127, ++ [1][1][2][0][9][0] = 127, ++ [1][1][2][0][8][0] = 127, ++ [1][1][2][0][11][0] = 127, ++ [1][1][2][0][2][1] = 127, ++ [1][1][2][0][1][1] = 127, ++ [1][1][2][0][3][1] = 127, ++ [1][1][2][0][5][1] = 127, ++ [1][1][2][0][6][1] = 127, ++ [1][1][2][0][9][1] = 127, ++ [1][1][2][0][8][1] = 127, ++ [1][1][2][0][11][1] = 127, ++ [1][1][2][0][2][2] = 52, ++ [1][1][2][0][1][2] = 46, ++ [1][1][2][0][3][2] = 64, ++ [1][1][2][0][5][2] = 52, ++ [1][1][2][0][6][2] = 46, ++ [1][1][2][0][9][2] = 46, ++ [1][1][2][0][8][2] = 48, ++ [1][1][2][0][11][2] = 46, ++ [1][1][2][0][2][3] = 52, ++ [1][1][2][0][1][3] = 46, ++ [1][1][2][0][3][3] = 64, ++ [1][1][2][0][5][3] = 52, ++ [1][1][2][0][6][3] = 46, ++ [1][1][2][0][9][3] = 46, ++ [1][1][2][0][8][3] = 48, ++ [1][1][2][0][11][3] = 46, ++ [1][1][2][0][2][4] = 56, ++ [1][1][2][0][1][4] = 46, ++ [1][1][2][0][3][4] = 64, ++ [1][1][2][0][5][4] = 56, ++ [1][1][2][0][6][4] = 46, ++ [1][1][2][0][9][4] = 46, ++ [1][1][2][0][8][4] = 48, ++ [1][1][2][0][11][4] = 46, ++ [1][1][2][0][2][5] = 60, ++ [1][1][2][0][1][5] = 46, ++ [1][1][2][0][3][5] = 64, ++ [1][1][2][0][5][5] = 60, ++ [1][1][2][0][6][5] = 46, ++ [1][1][2][0][9][5] = 46, ++ [1][1][2][0][8][5] = 48, ++ [1][1][2][0][11][5] = 46, ++ [1][1][2][0][2][6] = 54, ++ [1][1][2][0][1][6] = 46, ++ [1][1][2][0][3][6] = 64, ++ [1][1][2][0][5][6] = 52, ++ [1][1][2][0][6][6] = 46, ++ [1][1][2][0][9][6] = 46, ++ [1][1][2][0][8][6] = 48, ++ [1][1][2][0][11][6] = 46, ++ [1][1][2][0][2][7] = 50, ++ [1][1][2][0][1][7] = 46, ++ [1][1][2][0][3][7] = 64, ++ [1][1][2][0][5][7] = 48, ++ [1][1][2][0][6][7] = 46, ++ [1][1][2][0][9][7] = 46, ++ [1][1][2][0][8][7] = 48, ++ [1][1][2][0][11][7] = 46, ++ [1][1][2][0][2][8] = 50, ++ [1][1][2][0][1][8] = 46, ++ [1][1][2][0][3][8] = 64, ++ [1][1][2][0][5][8] = 48, ++ [1][1][2][0][6][8] = 46, ++ [1][1][2][0][9][8] = 46, ++ [1][1][2][0][8][8] = 48, ++ [1][1][2][0][11][8] = 46, ++ [1][1][2][0][2][9] = 38, ++ [1][1][2][0][1][9] = 46, ++ [1][1][2][0][3][9] = 64, ++ [1][1][2][0][5][9] = 38, ++ [1][1][2][0][6][9] = 46, ++ [1][1][2][0][9][9] = 46, ++ [1][1][2][0][8][9] = 48, ++ [1][1][2][0][11][9] = 46, ++ [1][1][2][0][2][10] = 36, ++ [1][1][2][0][1][10] = 46, ++ [1][1][2][0][3][10] = 64, ++ [1][1][2][0][5][10] = 36, ++ [1][1][2][0][6][10] = 46, ++ [1][1][2][0][9][10] = 46, ++ [1][1][2][0][8][10] = 48, ++ [1][1][2][0][11][10] = 46, ++ [1][1][2][0][2][11] = 127, ++ [1][1][2][0][1][11] = 127, ++ [1][1][2][0][3][11] = 127, ++ [1][1][2][0][5][11] = 127, ++ [1][1][2][0][6][11] = 127, ++ [1][1][2][0][9][11] = 127, ++ [1][1][2][0][8][11] = 127, ++ [1][1][2][0][11][11] = 127, ++ [1][1][2][0][2][12] = 127, ++ [1][1][2][0][1][12] = 127, ++ [1][1][2][0][3][12] = 127, ++ [1][1][2][0][5][12] = 127, ++ [1][1][2][0][6][12] = 127, ++ [1][1][2][0][9][12] = 127, ++ [1][1][2][0][8][12] = 127, ++ [1][1][2][0][11][12] = 127, ++ [1][1][2][0][2][13] = 127, ++ [1][1][2][0][1][13] = 127, ++ [1][1][2][0][3][13] = 127, ++ [1][1][2][0][5][13] = 127, ++ [1][1][2][0][6][13] = 127, ++ [1][1][2][0][9][13] = 127, ++ [1][1][2][0][8][13] = 127, ++ [1][1][2][0][11][13] = 127, ++ [1][1][2][1][2][0] = 127, ++ [1][1][2][1][1][0] = 127, ++ [1][1][2][1][3][0] = 127, ++ [1][1][2][1][5][0] = 127, ++ [1][1][2][1][6][0] = 127, ++ [1][1][2][1][9][0] = 127, ++ [1][1][2][1][8][0] = 127, ++ [1][1][2][1][11][0] = 127, ++ [1][1][2][1][2][1] = 127, ++ [1][1][2][1][1][1] = 127, ++ [1][1][2][1][3][1] = 127, ++ [1][1][2][1][5][1] = 127, ++ [1][1][2][1][6][1] = 127, ++ [1][1][2][1][9][1] = 127, ++ [1][1][2][1][8][1] = 127, ++ [1][1][2][1][11][1] = 127, ++ [1][1][2][1][2][2] = 52, ++ [1][1][2][1][1][2] = 34, ++ [1][1][2][1][3][2] = 64, ++ [1][1][2][1][5][2] = 52, ++ [1][1][2][1][6][2] = 34, ++ [1][1][2][1][9][2] = 34, ++ [1][1][2][1][8][2] = 36, ++ [1][1][2][1][11][2] = 34, ++ [1][1][2][1][2][3] = 52, ++ [1][1][2][1][1][3] = 34, ++ [1][1][2][1][3][3] = 64, ++ [1][1][2][1][5][3] = 52, ++ [1][1][2][1][6][3] = 34, ++ [1][1][2][1][9][3] = 34, ++ [1][1][2][1][8][3] = 36, ++ [1][1][2][1][11][3] = 34, ++ [1][1][2][1][2][4] = 56, ++ [1][1][2][1][1][4] = 34, ++ [1][1][2][1][3][4] = 64, ++ [1][1][2][1][5][4] = 56, ++ [1][1][2][1][6][4] = 34, ++ [1][1][2][1][9][4] = 34, ++ [1][1][2][1][8][4] = 36, ++ [1][1][2][1][11][4] = 34, ++ [1][1][2][1][2][5] = 60, ++ [1][1][2][1][1][5] = 34, ++ [1][1][2][1][3][5] = 64, ++ [1][1][2][1][5][5] = 60, ++ [1][1][2][1][6][5] = 34, ++ [1][1][2][1][9][5] = 34, ++ [1][1][2][1][8][5] = 36, ++ [1][1][2][1][11][5] = 34, ++ [1][1][2][1][2][6] = 54, ++ [1][1][2][1][1][6] = 34, ++ [1][1][2][1][3][6] = 64, ++ [1][1][2][1][5][6] = 52, ++ [1][1][2][1][6][6] = 34, ++ [1][1][2][1][9][6] = 34, ++ [1][1][2][1][8][6] = 36, ++ [1][1][2][1][11][6] = 34, ++ [1][1][2][1][2][7] = 50, ++ [1][1][2][1][1][7] = 34, ++ [1][1][2][1][3][7] = 64, ++ [1][1][2][1][5][7] = 48, ++ [1][1][2][1][6][7] = 34, ++ [1][1][2][1][9][7] = 34, ++ [1][1][2][1][8][7] = 36, ++ [1][1][2][1][11][7] = 34, ++ [1][1][2][1][2][8] = 50, ++ [1][1][2][1][1][8] = 34, ++ [1][1][2][1][3][8] = 64, ++ [1][1][2][1][5][8] = 48, ++ [1][1][2][1][6][8] = 34, ++ [1][1][2][1][9][8] = 34, ++ [1][1][2][1][8][8] = 36, ++ [1][1][2][1][11][8] = 34, ++ [1][1][2][1][2][9] = 38, ++ [1][1][2][1][1][9] = 34, ++ [1][1][2][1][3][9] = 64, ++ [1][1][2][1][5][9] = 38, ++ [1][1][2][1][6][9] = 34, ++ [1][1][2][1][9][9] = 34, ++ [1][1][2][1][8][9] = 36, ++ [1][1][2][1][11][9] = 34, ++ [1][1][2][1][2][10] = 36, ++ [1][1][2][1][1][10] = 34, ++ [1][1][2][1][3][10] = 64, ++ [1][1][2][1][5][10] = 36, ++ [1][1][2][1][6][10] = 34, ++ [1][1][2][1][9][10] = 34, ++ [1][1][2][1][8][10] = 36, ++ [1][1][2][1][11][10] = 34, ++ [1][1][2][1][2][11] = 127, ++ [1][1][2][1][1][11] = 127, ++ [1][1][2][1][3][11] = 127, ++ [1][1][2][1][5][11] = 127, ++ [1][1][2][1][6][11] = 127, ++ [1][1][2][1][9][11] = 127, ++ [1][1][2][1][8][11] = 127, ++ [1][1][2][1][11][11] = 127, ++ [1][1][2][1][2][12] = 127, ++ [1][1][2][1][1][12] = 127, ++ [1][1][2][1][3][12] = 127, ++ [1][1][2][1][5][12] = 127, ++ [1][1][2][1][6][12] = 127, ++ [1][1][2][1][9][12] = 127, ++ [1][1][2][1][8][12] = 127, ++ [1][1][2][1][11][12] = 127, ++ [1][1][2][1][2][13] = 127, ++ [1][1][2][1][1][13] = 127, ++ [1][1][2][1][3][13] = 127, ++ [1][1][2][1][5][13] = 127, ++ [1][1][2][1][6][13] = 127, ++ [1][1][2][1][9][13] = 127, ++ [1][1][2][1][8][13] = 127, ++ [1][1][2][1][11][13] = 127, ++}; ++ ++const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] ++ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] ++ [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { ++ [0][0][1][0][0][0] = 30, ++ [0][0][1][0][0][2] = 30, ++ [0][0][1][0][0][4] = 30, ++ [0][0][1][0][0][6] = 30, ++ [0][0][1][0][0][8] = 52, ++ [0][0][1][0][0][10] = 52, ++ [0][0][1][0][0][12] = 52, ++ [0][0][1][0][0][14] = 52, ++ [0][0][1][0][0][15] = 52, ++ [0][0][1][0][0][17] = 52, ++ [0][0][1][0][0][19] = 52, ++ [0][0][1][0][0][21] = 52, ++ [0][0][1][0][0][23] = 52, ++ [0][0][1][0][0][25] = 52, ++ [0][0][1][0][0][27] = 52, ++ [0][0][1][0][0][29] = 52, ++ [0][0][1][0][0][31] = 52, ++ [0][0][1][0][0][33] = 52, ++ [0][0][1][0][0][35] = 52, ++ [0][0][1][0][0][37] = 54, ++ [0][0][1][0][0][38] = 28, ++ [0][0][1][0][0][40] = 28, ++ [0][0][1][0][0][42] = 28, ++ [0][0][1][0][0][44] = 28, ++ [0][0][1][0][0][46] = 28, ++ [0][1][1][0][0][0] = 18, ++ [0][1][1][0][0][2] = 18, ++ [0][1][1][0][0][4] = 18, ++ [0][1][1][0][0][6] = 18, ++ [0][1][1][0][0][8] = 40, ++ [0][1][1][0][0][10] = 40, ++ [0][1][1][0][0][12] = 40, ++ [0][1][1][0][0][14] = 40, ++ [0][1][1][0][0][15] = 40, ++ [0][1][1][0][0][17] = 40, ++ [0][1][1][0][0][19] = 40, ++ [0][1][1][0][0][21] = 40, ++ [0][1][1][0][0][23] = 40, ++ [0][1][1][0][0][25] = 40, ++ [0][1][1][0][0][27] = 40, ++ [0][1][1][0][0][29] = 40, ++ [0][1][1][0][0][31] = 40, ++ [0][1][1][0][0][33] = 40, ++ [0][1][1][0][0][35] = 40, ++ [0][1][1][0][0][37] = 42, ++ [0][1][1][0][0][38] = 16, ++ [0][1][1][0][0][40] = 16, ++ [0][1][1][0][0][42] = 16, ++ [0][1][1][0][0][44] = 16, ++ [0][1][1][0][0][46] = 16, ++ [0][0][2][0][0][0] = 30, ++ [0][0][2][0][0][2] = 30, ++ [0][0][2][0][0][4] = 30, ++ [0][0][2][0][0][6] = 30, ++ [0][0][2][0][0][8] = 52, ++ [0][0][2][0][0][10] = 52, ++ [0][0][2][0][0][12] = 52, ++ [0][0][2][0][0][14] = 52, ++ [0][0][2][0][0][15] = 52, ++ [0][0][2][0][0][17] = 52, ++ [0][0][2][0][0][19] = 52, ++ [0][0][2][0][0][21] = 52, ++ [0][0][2][0][0][23] = 52, ++ [0][0][2][0][0][25] = 52, ++ [0][0][2][0][0][27] = 52, ++ [0][0][2][0][0][29] = 52, ++ [0][0][2][0][0][31] = 52, ++ [0][0][2][0][0][33] = 52, ++ [0][0][2][0][0][35] = 52, ++ [0][0][2][0][0][37] = 54, ++ [0][0][2][0][0][38] = 28, ++ [0][0][2][0][0][40] = 28, ++ [0][0][2][0][0][42] = 28, ++ [0][0][2][0][0][44] = 28, ++ [0][0][2][0][0][46] = 28, ++ [0][1][2][0][0][0] = 18, ++ [0][1][2][0][0][2] = 18, ++ [0][1][2][0][0][4] = 18, ++ [0][1][2][0][0][6] = 18, ++ [0][1][2][0][0][8] = 40, ++ [0][1][2][0][0][10] = 40, ++ [0][1][2][0][0][12] = 40, ++ [0][1][2][0][0][14] = 40, ++ [0][1][2][0][0][15] = 40, ++ [0][1][2][0][0][17] = 40, ++ [0][1][2][0][0][19] = 40, ++ [0][1][2][0][0][21] = 40, ++ [0][1][2][0][0][23] = 40, ++ [0][1][2][0][0][25] = 40, ++ [0][1][2][0][0][27] = 40, ++ [0][1][2][0][0][29] = 40, ++ [0][1][2][0][0][31] = 40, ++ [0][1][2][0][0][33] = 40, ++ [0][1][2][0][0][35] = 40, ++ [0][1][2][0][0][37] = 42, ++ [0][1][2][0][0][38] = 16, ++ [0][1][2][0][0][40] = 16, ++ [0][1][2][0][0][42] = 16, ++ [0][1][2][0][0][44] = 16, ++ [0][1][2][0][0][46] = 16, ++ [0][1][2][1][0][0] = 6, ++ [0][1][2][1][0][2] = 6, ++ [0][1][2][1][0][4] = 6, ++ [0][1][2][1][0][6] = 6, ++ [0][1][2][1][0][8] = 28, ++ [0][1][2][1][0][10] = 28, ++ [0][1][2][1][0][12] = 28, ++ [0][1][2][1][0][14] = 28, ++ [0][1][2][1][0][15] = 28, ++ [0][1][2][1][0][17] = 28, ++ [0][1][2][1][0][19] = 28, ++ [0][1][2][1][0][21] = 28, ++ [0][1][2][1][0][23] = 28, ++ [0][1][2][1][0][25] = 28, ++ [0][1][2][1][0][27] = 28, ++ [0][1][2][1][0][29] = 28, ++ [0][1][2][1][0][31] = 28, ++ [0][1][2][1][0][33] = 28, ++ [0][1][2][1][0][35] = 28, ++ [0][1][2][1][0][37] = 30, ++ [0][1][2][1][0][38] = 4, ++ [0][1][2][1][0][40] = 4, ++ [0][1][2][1][0][42] = 4, ++ [0][1][2][1][0][44] = 4, ++ [0][1][2][1][0][46] = 4, ++ [1][0][2][0][0][1] = 30, ++ [1][0][2][0][0][5] = 30, ++ [1][0][2][0][0][9] = 52, ++ [1][0][2][0][0][13] = 52, ++ [1][0][2][0][0][16] = 52, ++ [1][0][2][0][0][20] = 52, ++ [1][0][2][0][0][24] = 52, ++ [1][0][2][0][0][28] = 52, ++ [1][0][2][0][0][32] = 52, ++ [1][0][2][0][0][36] = 54, ++ [1][0][2][0][0][39] = 28, ++ [1][0][2][0][0][43] = 28, ++ [1][1][2][0][0][1] = 18, ++ [1][1][2][0][0][5] = 18, ++ [1][1][2][0][0][9] = 40, ++ [1][1][2][0][0][13] = 40, ++ [1][1][2][0][0][16] = 40, ++ [1][1][2][0][0][20] = 40, ++ [1][1][2][0][0][24] = 40, ++ [1][1][2][0][0][28] = 40, ++ [1][1][2][0][0][32] = 40, ++ [1][1][2][0][0][36] = 42, ++ [1][1][2][0][0][39] = 16, ++ [1][1][2][0][0][43] = 16, ++ [1][1][2][1][0][1] = 6, ++ [1][1][2][1][0][5] = 6, ++ [1][1][2][1][0][9] = 28, ++ [1][1][2][1][0][13] = 28, ++ [1][1][2][1][0][16] = 28, ++ [1][1][2][1][0][20] = 28, ++ [1][1][2][1][0][24] = 28, ++ [1][1][2][1][0][28] = 28, ++ [1][1][2][1][0][32] = 28, ++ [1][1][2][1][0][36] = 30, ++ [1][1][2][1][0][39] = 4, ++ [1][1][2][1][0][43] = 4, ++ [2][0][2][0][0][3] = 30, ++ [2][0][2][0][0][11] = 52, ++ [2][0][2][0][0][18] = 52, ++ [2][0][2][0][0][26] = 52, ++ [2][0][2][0][0][34] = 54, ++ [2][0][2][0][0][41] = 28, ++ [2][1][2][0][0][3] = 18, ++ [2][1][2][0][0][11] = 40, ++ [2][1][2][0][0][18] = 40, ++ [2][1][2][0][0][26] = 40, ++ [2][1][2][0][0][34] = 42, ++ [2][1][2][0][0][41] = 16, ++ [2][1][2][1][0][3] = 6, ++ [2][1][2][1][0][11] = 28, ++ [2][1][2][1][0][18] = 28, ++ [2][1][2][1][0][26] = 28, ++ [2][1][2][1][0][34] = 30, ++ [2][1][2][1][0][41] = 4, ++ [0][0][1][0][2][0] = 76, ++ [0][0][1][0][1][0] = 58, ++ [0][0][1][0][3][0] = 62, ++ [0][0][1][0][5][0] = 62, ++ [0][0][1][0][6][0] = 58, ++ [0][0][1][0][9][0] = 58, ++ [0][0][1][0][8][0] = 30, ++ [0][0][1][0][11][0] = 52, ++ [0][0][1][0][2][2] = 76, ++ [0][0][1][0][1][2] = 58, ++ [0][0][1][0][3][2] = 62, ++ [0][0][1][0][5][2] = 62, ++ [0][0][1][0][6][2] = 58, ++ [0][0][1][0][9][2] = 58, ++ [0][0][1][0][8][2] = 30, ++ [0][0][1][0][11][2] = 52, ++ [0][0][1][0][2][4] = 76, ++ [0][0][1][0][1][4] = 58, ++ [0][0][1][0][3][4] = 62, ++ [0][0][1][0][5][4] = 62, ++ [0][0][1][0][6][4] = 58, ++ [0][0][1][0][9][4] = 58, ++ [0][0][1][0][8][4] = 30, ++ [0][0][1][0][11][4] = 52, ++ [0][0][1][0][2][6] = 76, ++ [0][0][1][0][1][6] = 58, ++ [0][0][1][0][3][6] = 62, ++ [0][0][1][0][5][6] = 62, ++ [0][0][1][0][6][6] = 54, ++ [0][0][1][0][9][6] = 58, ++ [0][0][1][0][8][6] = 30, ++ [0][0][1][0][11][6] = 52, ++ [0][0][1][0][2][8] = 76, ++ [0][0][1][0][1][8] = 58, ++ [0][0][1][0][3][8] = 62, ++ [0][0][1][0][5][8] = 64, ++ [0][0][1][0][6][8] = 58, ++ [0][0][1][0][9][8] = 58, ++ [0][0][1][0][8][8] = 54, ++ [0][0][1][0][11][8] = 52, ++ [0][0][1][0][2][10] = 76, ++ [0][0][1][0][1][10] = 58, ++ [0][0][1][0][3][10] = 62, ++ [0][0][1][0][5][10] = 64, ++ [0][0][1][0][6][10] = 58, ++ [0][0][1][0][9][10] = 58, ++ [0][0][1][0][8][10] = 54, ++ [0][0][1][0][11][10] = 52, ++ [0][0][1][0][2][12] = 76, ++ [0][0][1][0][1][12] = 58, ++ [0][0][1][0][3][12] = 62, ++ [0][0][1][0][5][12] = 64, ++ [0][0][1][0][6][12] = 58, ++ [0][0][1][0][9][12] = 58, ++ [0][0][1][0][8][12] = 54, ++ [0][0][1][0][11][12] = 52, ++ [0][0][1][0][2][14] = 76, ++ [0][0][1][0][1][14] = 58, ++ [0][0][1][0][3][14] = 62, ++ [0][0][1][0][5][14] = 64, ++ [0][0][1][0][6][14] = 58, ++ [0][0][1][0][9][14] = 58, ++ [0][0][1][0][8][14] = 54, ++ [0][0][1][0][11][14] = 52, ++ [0][0][1][0][2][15] = 76, ++ [0][0][1][0][1][15] = 58, ++ [0][0][1][0][3][15] = 76, ++ [0][0][1][0][5][15] = 76, ++ [0][0][1][0][6][15] = 58, ++ [0][0][1][0][9][15] = 58, ++ [0][0][1][0][8][15] = 54, ++ [0][0][1][0][11][15] = 52, ++ [0][0][1][0][2][17] = 76, ++ [0][0][1][0][1][17] = 58, ++ [0][0][1][0][3][17] = 76, ++ [0][0][1][0][5][17] = 76, ++ [0][0][1][0][6][17] = 58, ++ [0][0][1][0][9][17] = 58, ++ [0][0][1][0][8][17] = 54, ++ [0][0][1][0][11][17] = 52, ++ [0][0][1][0][2][19] = 76, ++ [0][0][1][0][1][19] = 58, ++ [0][0][1][0][3][19] = 76, ++ [0][0][1][0][5][19] = 76, ++ [0][0][1][0][6][19] = 58, ++ [0][0][1][0][9][19] = 58, ++ [0][0][1][0][8][19] = 54, ++ [0][0][1][0][11][19] = 52, ++ [0][0][1][0][2][21] = 76, ++ [0][0][1][0][1][21] = 58, ++ [0][0][1][0][3][21] = 76, ++ [0][0][1][0][5][21] = 76, ++ [0][0][1][0][6][21] = 58, ++ [0][0][1][0][9][21] = 58, ++ [0][0][1][0][8][21] = 54, ++ [0][0][1][0][11][21] = 52, ++ [0][0][1][0][2][23] = 76, ++ [0][0][1][0][1][23] = 58, ++ [0][0][1][0][3][23] = 76, ++ [0][0][1][0][5][23] = 76, ++ [0][0][1][0][6][23] = 58, ++ [0][0][1][0][9][23] = 58, ++ [0][0][1][0][8][23] = 54, ++ [0][0][1][0][11][23] = 52, ++ [0][0][1][0][2][25] = 76, ++ [0][0][1][0][1][25] = 58, ++ [0][0][1][0][3][25] = 76, ++ [0][0][1][0][5][25] = 127, ++ [0][0][1][0][6][25] = 58, ++ [0][0][1][0][9][25] = 127, ++ [0][0][1][0][8][25] = 54, ++ [0][0][1][0][11][25] = 52, ++ [0][0][1][0][2][27] = 76, ++ [0][0][1][0][1][27] = 58, ++ [0][0][1][0][3][27] = 76, ++ [0][0][1][0][5][27] = 127, ++ [0][0][1][0][6][27] = 58, ++ [0][0][1][0][9][27] = 127, ++ [0][0][1][0][8][27] = 54, ++ [0][0][1][0][11][27] = 52, ++ [0][0][1][0][2][29] = 76, ++ [0][0][1][0][1][29] = 58, ++ [0][0][1][0][3][29] = 76, ++ [0][0][1][0][5][29] = 127, ++ [0][0][1][0][6][29] = 58, ++ [0][0][1][0][9][29] = 127, ++ [0][0][1][0][8][29] = 54, ++ [0][0][1][0][11][29] = 52, ++ [0][0][1][0][2][31] = 76, ++ [0][0][1][0][1][31] = 58, ++ [0][0][1][0][3][31] = 76, ++ [0][0][1][0][5][31] = 76, ++ [0][0][1][0][6][31] = 58, ++ [0][0][1][0][9][31] = 58, ++ [0][0][1][0][8][31] = 54, ++ [0][0][1][0][11][31] = 52, ++ [0][0][1][0][2][33] = 76, ++ [0][0][1][0][1][33] = 58, ++ [0][0][1][0][3][33] = 76, ++ [0][0][1][0][5][33] = 76, ++ [0][0][1][0][6][33] = 58, ++ [0][0][1][0][9][33] = 58, ++ [0][0][1][0][8][33] = 54, ++ [0][0][1][0][11][33] = 52, ++ [0][0][1][0][2][35] = 74, ++ [0][0][1][0][1][35] = 58, ++ [0][0][1][0][3][35] = 76, ++ [0][0][1][0][5][35] = 74, ++ [0][0][1][0][6][35] = 58, ++ [0][0][1][0][9][35] = 58, ++ [0][0][1][0][8][35] = 54, ++ [0][0][1][0][11][35] = 52, ++ [0][0][1][0][2][37] = 76, ++ [0][0][1][0][1][37] = 127, ++ [0][0][1][0][3][37] = 76, ++ [0][0][1][0][5][37] = 76, ++ [0][0][1][0][6][37] = 58, ++ [0][0][1][0][9][37] = 76, ++ [0][0][1][0][8][37] = 54, ++ [0][0][1][0][11][37] = 127, ++ [0][0][1][0][2][38] = 76, ++ [0][0][1][0][1][38] = 28, ++ [0][0][1][0][3][38] = 127, ++ [0][0][1][0][5][38] = 76, ++ [0][0][1][0][6][38] = 28, ++ [0][0][1][0][9][38] = 76, ++ [0][0][1][0][8][38] = 54, ++ [0][0][1][0][11][38] = 52, ++ [0][0][1][0][2][40] = 76, ++ [0][0][1][0][1][40] = 28, ++ [0][0][1][0][3][40] = 127, ++ [0][0][1][0][5][40] = 76, ++ [0][0][1][0][6][40] = 28, ++ [0][0][1][0][9][40] = 76, ++ [0][0][1][0][8][40] = 54, ++ [0][0][1][0][11][40] = 52, ++ [0][0][1][0][2][42] = 76, ++ [0][0][1][0][1][42] = 28, ++ [0][0][1][0][3][42] = 127, ++ [0][0][1][0][5][42] = 76, ++ [0][0][1][0][6][42] = 28, ++ [0][0][1][0][9][42] = 76, ++ [0][0][1][0][8][42] = 54, ++ [0][0][1][0][11][42] = 52, ++ [0][0][1][0][2][44] = 76, ++ [0][0][1][0][1][44] = 28, ++ [0][0][1][0][3][44] = 127, ++ [0][0][1][0][5][44] = 76, ++ [0][0][1][0][6][44] = 28, ++ [0][0][1][0][9][44] = 76, ++ [0][0][1][0][8][44] = 54, ++ [0][0][1][0][11][44] = 52, ++ [0][0][1][0][2][46] = 76, ++ [0][0][1][0][1][46] = 28, ++ [0][0][1][0][3][46] = 127, ++ [0][0][1][0][5][46] = 76, ++ [0][0][1][0][6][46] = 28, ++ [0][0][1][0][9][46] = 76, ++ [0][0][1][0][8][46] = 54, ++ [0][0][1][0][11][46] = 52, ++ [0][1][1][0][2][0] = 68, ++ [0][1][1][0][1][0] = 46, ++ [0][1][1][0][3][0] = 50, ++ [0][1][1][0][5][0] = 40, ++ [0][1][1][0][6][0] = 46, ++ [0][1][1][0][9][0] = 46, ++ [0][1][1][0][8][0] = 18, ++ [0][1][1][0][11][0] = 40, ++ [0][1][1][0][2][2] = 68, ++ [0][1][1][0][1][2] = 46, ++ [0][1][1][0][3][2] = 50, ++ [0][1][1][0][5][2] = 40, ++ [0][1][1][0][6][2] = 46, ++ [0][1][1][0][9][2] = 46, ++ [0][1][1][0][8][2] = 18, ++ [0][1][1][0][11][2] = 40, ++ [0][1][1][0][2][4] = 68, ++ [0][1][1][0][1][4] = 46, ++ [0][1][1][0][3][4] = 50, ++ [0][1][1][0][5][4] = 40, ++ [0][1][1][0][6][4] = 46, ++ [0][1][1][0][9][4] = 46, ++ [0][1][1][0][8][4] = 18, ++ [0][1][1][0][11][4] = 40, ++ [0][1][1][0][2][6] = 68, ++ [0][1][1][0][1][6] = 46, ++ [0][1][1][0][3][6] = 50, ++ [0][1][1][0][5][6] = 40, ++ [0][1][1][0][6][6] = 36, ++ [0][1][1][0][9][6] = 46, ++ [0][1][1][0][8][6] = 18, ++ [0][1][1][0][11][6] = 40, ++ [0][1][1][0][2][8] = 68, ++ [0][1][1][0][1][8] = 46, ++ [0][1][1][0][3][8] = 50, ++ [0][1][1][0][5][8] = 52, ++ [0][1][1][0][6][8] = 46, ++ [0][1][1][0][9][8] = 46, ++ [0][1][1][0][8][8] = 42, ++ [0][1][1][0][11][8] = 40, ++ [0][1][1][0][2][10] = 68, ++ [0][1][1][0][1][10] = 46, ++ [0][1][1][0][3][10] = 50, ++ [0][1][1][0][5][10] = 52, ++ [0][1][1][0][6][10] = 46, ++ [0][1][1][0][9][10] = 46, ++ [0][1][1][0][8][10] = 42, ++ [0][1][1][0][11][10] = 40, ++ [0][1][1][0][2][12] = 68, ++ [0][1][1][0][1][12] = 46, ++ [0][1][1][0][3][12] = 50, ++ [0][1][1][0][5][12] = 52, ++ [0][1][1][0][6][12] = 46, ++ [0][1][1][0][9][12] = 46, ++ [0][1][1][0][8][12] = 42, ++ [0][1][1][0][11][12] = 40, ++ [0][1][1][0][2][14] = 68, ++ [0][1][1][0][1][14] = 46, ++ [0][1][1][0][3][14] = 50, ++ [0][1][1][0][5][14] = 52, ++ [0][1][1][0][6][14] = 46, ++ [0][1][1][0][9][14] = 46, ++ [0][1][1][0][8][14] = 42, ++ [0][1][1][0][11][14] = 40, ++ [0][1][1][0][2][15] = 68, ++ [0][1][1][0][1][15] = 46, ++ [0][1][1][0][3][15] = 70, ++ [0][1][1][0][5][15] = 68, ++ [0][1][1][0][6][15] = 46, ++ [0][1][1][0][9][15] = 46, ++ [0][1][1][0][8][15] = 42, ++ [0][1][1][0][11][15] = 40, ++ [0][1][1][0][2][17] = 68, ++ [0][1][1][0][1][17] = 46, ++ [0][1][1][0][3][17] = 70, ++ [0][1][1][0][5][17] = 68, ++ [0][1][1][0][6][17] = 46, ++ [0][1][1][0][9][17] = 46, ++ [0][1][1][0][8][17] = 42, ++ [0][1][1][0][11][17] = 40, ++ [0][1][1][0][2][19] = 68, ++ [0][1][1][0][1][19] = 46, ++ [0][1][1][0][3][19] = 70, ++ [0][1][1][0][5][19] = 68, ++ [0][1][1][0][6][19] = 46, ++ [0][1][1][0][9][19] = 46, ++ [0][1][1][0][8][19] = 42, ++ [0][1][1][0][11][19] = 40, ++ [0][1][1][0][2][21] = 68, ++ [0][1][1][0][1][21] = 46, ++ [0][1][1][0][3][21] = 70, ++ [0][1][1][0][5][21] = 68, ++ [0][1][1][0][6][21] = 46, ++ [0][1][1][0][9][21] = 46, ++ [0][1][1][0][8][21] = 42, ++ [0][1][1][0][11][21] = 40, ++ [0][1][1][0][2][23] = 68, ++ [0][1][1][0][1][23] = 46, ++ [0][1][1][0][3][23] = 70, ++ [0][1][1][0][5][23] = 68, ++ [0][1][1][0][6][23] = 46, ++ [0][1][1][0][9][23] = 46, ++ [0][1][1][0][8][23] = 42, ++ [0][1][1][0][11][23] = 40, ++ [0][1][1][0][2][25] = 68, ++ [0][1][1][0][1][25] = 46, ++ [0][1][1][0][3][25] = 70, ++ [0][1][1][0][5][25] = 127, ++ [0][1][1][0][6][25] = 46, ++ [0][1][1][0][9][25] = 127, ++ [0][1][1][0][8][25] = 42, ++ [0][1][1][0][11][25] = 40, ++ [0][1][1][0][2][27] = 68, ++ [0][1][1][0][1][27] = 46, ++ [0][1][1][0][3][27] = 70, ++ [0][1][1][0][5][27] = 127, ++ [0][1][1][0][6][27] = 46, ++ [0][1][1][0][9][27] = 127, ++ [0][1][1][0][8][27] = 42, ++ [0][1][1][0][11][27] = 40, ++ [0][1][1][0][2][29] = 68, ++ [0][1][1][0][1][29] = 46, ++ [0][1][1][0][3][29] = 70, ++ [0][1][1][0][5][29] = 127, ++ [0][1][1][0][6][29] = 46, ++ [0][1][1][0][9][29] = 127, ++ [0][1][1][0][8][29] = 42, ++ [0][1][1][0][11][29] = 40, ++ [0][1][1][0][2][31] = 68, ++ [0][1][1][0][1][31] = 46, ++ [0][1][1][0][3][31] = 70, ++ [0][1][1][0][5][31] = 68, ++ [0][1][1][0][6][31] = 46, ++ [0][1][1][0][9][31] = 46, ++ [0][1][1][0][8][31] = 42, ++ [0][1][1][0][11][31] = 40, ++ [0][1][1][0][2][33] = 68, ++ [0][1][1][0][1][33] = 46, ++ [0][1][1][0][3][33] = 70, ++ [0][1][1][0][5][33] = 68, ++ [0][1][1][0][6][33] = 46, ++ [0][1][1][0][9][33] = 46, ++ [0][1][1][0][8][33] = 42, ++ [0][1][1][0][11][33] = 40, ++ [0][1][1][0][2][35] = 66, ++ [0][1][1][0][1][35] = 46, ++ [0][1][1][0][3][35] = 70, ++ [0][1][1][0][5][35] = 66, ++ [0][1][1][0][6][35] = 46, ++ [0][1][1][0][9][35] = 46, ++ [0][1][1][0][8][35] = 42, ++ [0][1][1][0][11][35] = 40, ++ [0][1][1][0][2][37] = 68, ++ [0][1][1][0][1][37] = 127, ++ [0][1][1][0][3][37] = 70, ++ [0][1][1][0][5][37] = 68, ++ [0][1][1][0][6][37] = 46, ++ [0][1][1][0][9][37] = 68, ++ [0][1][1][0][8][37] = 42, ++ [0][1][1][0][11][37] = 127, ++ [0][1][1][0][2][38] = 76, ++ [0][1][1][0][1][38] = 16, ++ [0][1][1][0][3][38] = 127, ++ [0][1][1][0][5][38] = 76, ++ [0][1][1][0][6][38] = 16, ++ [0][1][1][0][9][38] = 76, ++ [0][1][1][0][8][38] = 42, ++ [0][1][1][0][11][38] = 40, ++ [0][1][1][0][2][40] = 76, ++ [0][1][1][0][1][40] = 16, ++ [0][1][1][0][3][40] = 127, ++ [0][1][1][0][5][40] = 76, ++ [0][1][1][0][6][40] = 16, ++ [0][1][1][0][9][40] = 76, ++ [0][1][1][0][8][40] = 42, ++ [0][1][1][0][11][40] = 40, ++ [0][1][1][0][2][42] = 76, ++ [0][1][1][0][1][42] = 16, ++ [0][1][1][0][3][42] = 127, ++ [0][1][1][0][5][42] = 76, ++ [0][1][1][0][6][42] = 16, ++ [0][1][1][0][9][42] = 76, ++ [0][1][1][0][8][42] = 42, ++ [0][1][1][0][11][42] = 40, ++ [0][1][1][0][2][44] = 76, ++ [0][1][1][0][1][44] = 16, ++ [0][1][1][0][3][44] = 127, ++ [0][1][1][0][5][44] = 76, ++ [0][1][1][0][6][44] = 16, ++ [0][1][1][0][9][44] = 76, ++ [0][1][1][0][8][44] = 42, ++ [0][1][1][0][11][44] = 40, ++ [0][1][1][0][2][46] = 76, ++ [0][1][1][0][1][46] = 16, ++ [0][1][1][0][3][46] = 127, ++ [0][1][1][0][5][46] = 76, ++ [0][1][1][0][6][46] = 16, ++ [0][1][1][0][9][46] = 76, ++ [0][1][1][0][8][46] = 42, ++ [0][1][1][0][11][46] = 40, ++ [0][0][2][0][2][0] = 76, ++ [0][0][2][0][1][0] = 58, ++ [0][0][2][0][3][0] = 62, ++ [0][0][2][0][5][0] = 62, ++ [0][0][2][0][6][0] = 58, ++ [0][0][2][0][9][0] = 58, ++ [0][0][2][0][8][0] = 30, ++ [0][0][2][0][11][0] = 52, ++ [0][0][2][0][2][2] = 76, ++ [0][0][2][0][1][2] = 58, ++ [0][0][2][0][3][2] = 62, ++ [0][0][2][0][5][2] = 62, ++ [0][0][2][0][6][2] = 58, ++ [0][0][2][0][9][2] = 58, ++ [0][0][2][0][8][2] = 30, ++ [0][0][2][0][11][2] = 52, ++ [0][0][2][0][2][4] = 76, ++ [0][0][2][0][1][4] = 58, ++ [0][0][2][0][3][4] = 62, ++ [0][0][2][0][5][4] = 62, ++ [0][0][2][0][6][4] = 58, ++ [0][0][2][0][9][4] = 58, ++ [0][0][2][0][8][4] = 30, ++ [0][0][2][0][11][4] = 52, ++ [0][0][2][0][2][6] = 76, ++ [0][0][2][0][1][6] = 58, ++ [0][0][2][0][3][6] = 62, ++ [0][0][2][0][5][6] = 62, ++ [0][0][2][0][6][6] = 54, ++ [0][0][2][0][9][6] = 58, ++ [0][0][2][0][8][6] = 30, ++ [0][0][2][0][11][6] = 52, ++ [0][0][2][0][2][8] = 76, ++ [0][0][2][0][1][8] = 58, ++ [0][0][2][0][3][8] = 62, ++ [0][0][2][0][5][8] = 64, ++ [0][0][2][0][6][8] = 58, ++ [0][0][2][0][9][8] = 58, ++ [0][0][2][0][8][8] = 54, ++ [0][0][2][0][11][8] = 52, ++ [0][0][2][0][2][10] = 76, ++ [0][0][2][0][1][10] = 58, ++ [0][0][2][0][3][10] = 62, ++ [0][0][2][0][5][10] = 64, ++ [0][0][2][0][6][10] = 58, ++ [0][0][2][0][9][10] = 58, ++ [0][0][2][0][8][10] = 54, ++ [0][0][2][0][11][10] = 52, ++ [0][0][2][0][2][12] = 76, ++ [0][0][2][0][1][12] = 58, ++ [0][0][2][0][3][12] = 62, ++ [0][0][2][0][5][12] = 64, ++ [0][0][2][0][6][12] = 58, ++ [0][0][2][0][9][12] = 58, ++ [0][0][2][0][8][12] = 54, ++ [0][0][2][0][11][12] = 52, ++ [0][0][2][0][2][14] = 76, ++ [0][0][2][0][1][14] = 58, ++ [0][0][2][0][3][14] = 62, ++ [0][0][2][0][5][14] = 64, ++ [0][0][2][0][6][14] = 58, ++ [0][0][2][0][9][14] = 58, ++ [0][0][2][0][8][14] = 54, ++ [0][0][2][0][11][14] = 52, ++ [0][0][2][0][2][15] = 74, ++ [0][0][2][0][1][15] = 58, ++ [0][0][2][0][3][15] = 76, ++ [0][0][2][0][5][15] = 74, ++ [0][0][2][0][6][15] = 58, ++ [0][0][2][0][9][15] = 58, ++ [0][0][2][0][8][15] = 54, ++ [0][0][2][0][11][15] = 52, ++ [0][0][2][0][2][17] = 76, ++ [0][0][2][0][1][17] = 58, ++ [0][0][2][0][3][17] = 76, ++ [0][0][2][0][5][17] = 76, ++ [0][0][2][0][6][17] = 58, ++ [0][0][2][0][9][17] = 58, ++ [0][0][2][0][8][17] = 54, ++ [0][0][2][0][11][17] = 52, ++ [0][0][2][0][2][19] = 76, ++ [0][0][2][0][1][19] = 58, ++ [0][0][2][0][3][19] = 76, ++ [0][0][2][0][5][19] = 76, ++ [0][0][2][0][6][19] = 58, ++ [0][0][2][0][9][19] = 58, ++ [0][0][2][0][8][19] = 54, ++ [0][0][2][0][11][19] = 52, ++ [0][0][2][0][2][21] = 76, ++ [0][0][2][0][1][21] = 58, ++ [0][0][2][0][3][21] = 76, ++ [0][0][2][0][5][21] = 76, ++ [0][0][2][0][6][21] = 58, ++ [0][0][2][0][9][21] = 58, ++ [0][0][2][0][8][21] = 54, ++ [0][0][2][0][11][21] = 52, ++ [0][0][2][0][2][23] = 76, ++ [0][0][2][0][1][23] = 58, ++ [0][0][2][0][3][23] = 76, ++ [0][0][2][0][5][23] = 76, ++ [0][0][2][0][6][23] = 58, ++ [0][0][2][0][9][23] = 58, ++ [0][0][2][0][8][23] = 54, ++ [0][0][2][0][11][23] = 52, ++ [0][0][2][0][2][25] = 76, ++ [0][0][2][0][1][25] = 58, ++ [0][0][2][0][3][25] = 76, ++ [0][0][2][0][5][25] = 127, ++ [0][0][2][0][6][25] = 58, ++ [0][0][2][0][9][25] = 127, ++ [0][0][2][0][8][25] = 54, ++ [0][0][2][0][11][25] = 52, ++ [0][0][2][0][2][27] = 76, ++ [0][0][2][0][1][27] = 58, ++ [0][0][2][0][3][27] = 76, ++ [0][0][2][0][5][27] = 127, ++ [0][0][2][0][6][27] = 58, ++ [0][0][2][0][9][27] = 127, ++ [0][0][2][0][8][27] = 54, ++ [0][0][2][0][11][27] = 52, ++ [0][0][2][0][2][29] = 76, ++ [0][0][2][0][1][29] = 58, ++ [0][0][2][0][3][29] = 76, ++ [0][0][2][0][5][29] = 127, ++ [0][0][2][0][6][29] = 58, ++ [0][0][2][0][9][29] = 127, ++ [0][0][2][0][8][29] = 54, ++ [0][0][2][0][11][29] = 52, ++ [0][0][2][0][2][31] = 76, ++ [0][0][2][0][1][31] = 58, ++ [0][0][2][0][3][31] = 76, ++ [0][0][2][0][5][31] = 76, ++ [0][0][2][0][6][31] = 58, ++ [0][0][2][0][9][31] = 58, ++ [0][0][2][0][8][31] = 54, ++ [0][0][2][0][11][31] = 52, ++ [0][0][2][0][2][33] = 76, ++ [0][0][2][0][1][33] = 58, ++ [0][0][2][0][3][33] = 76, ++ [0][0][2][0][5][33] = 76, ++ [0][0][2][0][6][33] = 58, ++ [0][0][2][0][9][33] = 58, ++ [0][0][2][0][8][33] = 54, ++ [0][0][2][0][11][33] = 52, ++ [0][0][2][0][2][35] = 70, ++ [0][0][2][0][1][35] = 58, ++ [0][0][2][0][3][35] = 76, ++ [0][0][2][0][5][35] = 70, ++ [0][0][2][0][6][35] = 58, ++ [0][0][2][0][9][35] = 58, ++ [0][0][2][0][8][35] = 54, ++ [0][0][2][0][11][35] = 52, ++ [0][0][2][0][2][37] = 76, ++ [0][0][2][0][1][37] = 127, ++ [0][0][2][0][3][37] = 76, ++ [0][0][2][0][5][37] = 76, ++ [0][0][2][0][6][37] = 58, ++ [0][0][2][0][9][37] = 76, ++ [0][0][2][0][8][37] = 54, ++ [0][0][2][0][11][37] = 127, ++ [0][0][2][0][2][38] = 76, ++ [0][0][2][0][1][38] = 28, ++ [0][0][2][0][3][38] = 127, ++ [0][0][2][0][5][38] = 76, ++ [0][0][2][0][6][38] = 28, ++ [0][0][2][0][9][38] = 76, ++ [0][0][2][0][8][38] = 54, ++ [0][0][2][0][11][38] = 52, ++ [0][0][2][0][2][40] = 76, ++ [0][0][2][0][1][40] = 28, ++ [0][0][2][0][3][40] = 127, ++ [0][0][2][0][5][40] = 76, ++ [0][0][2][0][6][40] = 28, ++ [0][0][2][0][9][40] = 76, ++ [0][0][2][0][8][40] = 54, ++ [0][0][2][0][11][40] = 52, ++ [0][0][2][0][2][42] = 76, ++ [0][0][2][0][1][42] = 28, ++ [0][0][2][0][3][42] = 127, ++ [0][0][2][0][5][42] = 76, ++ [0][0][2][0][6][42] = 28, ++ [0][0][2][0][9][42] = 76, ++ [0][0][2][0][8][42] = 54, ++ [0][0][2][0][11][42] = 52, ++ [0][0][2][0][2][44] = 76, ++ [0][0][2][0][1][44] = 28, ++ [0][0][2][0][3][44] = 127, ++ [0][0][2][0][5][44] = 76, ++ [0][0][2][0][6][44] = 28, ++ [0][0][2][0][9][44] = 76, ++ [0][0][2][0][8][44] = 54, ++ [0][0][2][0][11][44] = 52, ++ [0][0][2][0][2][46] = 76, ++ [0][0][2][0][1][46] = 28, ++ [0][0][2][0][3][46] = 127, ++ [0][0][2][0][5][46] = 76, ++ [0][0][2][0][6][46] = 28, ++ [0][0][2][0][9][46] = 76, ++ [0][0][2][0][8][46] = 54, ++ [0][0][2][0][11][46] = 52, ++ [0][1][2][0][2][0] = 68, ++ [0][1][2][0][1][0] = 46, ++ [0][1][2][0][3][0] = 50, ++ [0][1][2][0][5][0] = 40, ++ [0][1][2][0][6][0] = 46, ++ [0][1][2][0][9][0] = 46, ++ [0][1][2][0][8][0] = 18, ++ [0][1][2][0][11][0] = 40, ++ [0][1][2][0][2][2] = 68, ++ [0][1][2][0][1][2] = 46, ++ [0][1][2][0][3][2] = 50, ++ [0][1][2][0][5][2] = 40, ++ [0][1][2][0][6][2] = 46, ++ [0][1][2][0][9][2] = 46, ++ [0][1][2][0][8][2] = 18, ++ [0][1][2][0][11][2] = 40, ++ [0][1][2][0][2][4] = 68, ++ [0][1][2][0][1][4] = 46, ++ [0][1][2][0][3][4] = 50, ++ [0][1][2][0][5][4] = 40, ++ [0][1][2][0][6][4] = 46, ++ [0][1][2][0][9][4] = 46, ++ [0][1][2][0][8][4] = 18, ++ [0][1][2][0][11][4] = 40, ++ [0][1][2][0][2][6] = 68, ++ [0][1][2][0][1][6] = 46, ++ [0][1][2][0][3][6] = 50, ++ [0][1][2][0][5][6] = 40, ++ [0][1][2][0][6][6] = 36, ++ [0][1][2][0][9][6] = 46, ++ [0][1][2][0][8][6] = 18, ++ [0][1][2][0][11][6] = 40, ++ [0][1][2][0][2][8] = 68, ++ [0][1][2][0][1][8] = 46, ++ [0][1][2][0][3][8] = 50, ++ [0][1][2][0][5][8] = 52, ++ [0][1][2][0][6][8] = 46, ++ [0][1][2][0][9][8] = 46, ++ [0][1][2][0][8][8] = 42, ++ [0][1][2][0][11][8] = 40, ++ [0][1][2][0][2][10] = 68, ++ [0][1][2][0][1][10] = 46, ++ [0][1][2][0][3][10] = 50, ++ [0][1][2][0][5][10] = 52, ++ [0][1][2][0][6][10] = 46, ++ [0][1][2][0][9][10] = 46, ++ [0][1][2][0][8][10] = 42, ++ [0][1][2][0][11][10] = 40, ++ [0][1][2][0][2][12] = 68, ++ [0][1][2][0][1][12] = 46, ++ [0][1][2][0][3][12] = 50, ++ [0][1][2][0][5][12] = 52, ++ [0][1][2][0][6][12] = 46, ++ [0][1][2][0][9][12] = 46, ++ [0][1][2][0][8][12] = 42, ++ [0][1][2][0][11][12] = 40, ++ [0][1][2][0][2][14] = 68, ++ [0][1][2][0][1][14] = 46, ++ [0][1][2][0][3][14] = 50, ++ [0][1][2][0][5][14] = 52, ++ [0][1][2][0][6][14] = 46, ++ [0][1][2][0][9][14] = 46, ++ [0][1][2][0][8][14] = 42, ++ [0][1][2][0][11][14] = 40, ++ [0][1][2][0][2][15] = 68, ++ [0][1][2][0][1][15] = 46, ++ [0][1][2][0][3][15] = 70, ++ [0][1][2][0][5][15] = 68, ++ [0][1][2][0][6][15] = 46, ++ [0][1][2][0][9][15] = 46, ++ [0][1][2][0][8][15] = 42, ++ [0][1][2][0][11][15] = 40, ++ [0][1][2][0][2][17] = 68, ++ [0][1][2][0][1][17] = 46, ++ [0][1][2][0][3][17] = 70, ++ [0][1][2][0][5][17] = 68, ++ [0][1][2][0][6][17] = 46, ++ [0][1][2][0][9][17] = 46, ++ [0][1][2][0][8][17] = 42, ++ [0][1][2][0][11][17] = 40, ++ [0][1][2][0][2][19] = 68, ++ [0][1][2][0][1][19] = 46, ++ [0][1][2][0][3][19] = 70, ++ [0][1][2][0][5][19] = 68, ++ [0][1][2][0][6][19] = 46, ++ [0][1][2][0][9][19] = 46, ++ [0][1][2][0][8][19] = 42, ++ [0][1][2][0][11][19] = 40, ++ [0][1][2][0][2][21] = 68, ++ [0][1][2][0][1][21] = 46, ++ [0][1][2][0][3][21] = 70, ++ [0][1][2][0][5][21] = 68, ++ [0][1][2][0][6][21] = 46, ++ [0][1][2][0][9][21] = 46, ++ [0][1][2][0][8][21] = 42, ++ [0][1][2][0][11][21] = 40, ++ [0][1][2][0][2][23] = 68, ++ [0][1][2][0][1][23] = 46, ++ [0][1][2][0][3][23] = 70, ++ [0][1][2][0][5][23] = 68, ++ [0][1][2][0][6][23] = 46, ++ [0][1][2][0][9][23] = 46, ++ [0][1][2][0][8][23] = 42, ++ [0][1][2][0][11][23] = 40, ++ [0][1][2][0][2][25] = 68, ++ [0][1][2][0][1][25] = 46, ++ [0][1][2][0][3][25] = 70, ++ [0][1][2][0][5][25] = 127, ++ [0][1][2][0][6][25] = 46, ++ [0][1][2][0][9][25] = 127, ++ [0][1][2][0][8][25] = 42, ++ [0][1][2][0][11][25] = 40, ++ [0][1][2][0][2][27] = 68, ++ [0][1][2][0][1][27] = 46, ++ [0][1][2][0][3][27] = 70, ++ [0][1][2][0][5][27] = 127, ++ [0][1][2][0][6][27] = 46, ++ [0][1][2][0][9][27] = 127, ++ [0][1][2][0][8][27] = 42, ++ [0][1][2][0][11][27] = 40, ++ [0][1][2][0][2][29] = 68, ++ [0][1][2][0][1][29] = 46, ++ [0][1][2][0][3][29] = 70, ++ [0][1][2][0][5][29] = 127, ++ [0][1][2][0][6][29] = 46, ++ [0][1][2][0][9][29] = 127, ++ [0][1][2][0][8][29] = 42, ++ [0][1][2][0][11][29] = 40, ++ [0][1][2][0][2][31] = 68, ++ [0][1][2][0][1][31] = 46, ++ [0][1][2][0][3][31] = 70, ++ [0][1][2][0][5][31] = 68, ++ [0][1][2][0][6][31] = 46, ++ [0][1][2][0][9][31] = 46, ++ [0][1][2][0][8][31] = 42, ++ [0][1][2][0][11][31] = 40, ++ [0][1][2][0][2][33] = 68, ++ [0][1][2][0][1][33] = 46, ++ [0][1][2][0][3][33] = 70, ++ [0][1][2][0][5][33] = 68, ++ [0][1][2][0][6][33] = 46, ++ [0][1][2][0][9][33] = 46, ++ [0][1][2][0][8][33] = 42, ++ [0][1][2][0][11][33] = 40, ++ [0][1][2][0][2][35] = 64, ++ [0][1][2][0][1][35] = 46, ++ [0][1][2][0][3][35] = 70, ++ [0][1][2][0][5][35] = 64, ++ [0][1][2][0][6][35] = 46, ++ [0][1][2][0][9][35] = 46, ++ [0][1][2][0][8][35] = 42, ++ [0][1][2][0][11][35] = 40, ++ [0][1][2][0][2][37] = 68, ++ [0][1][2][0][1][37] = 127, ++ [0][1][2][0][3][37] = 70, ++ [0][1][2][0][5][37] = 68, ++ [0][1][2][0][6][37] = 46, ++ [0][1][2][0][9][37] = 68, ++ [0][1][2][0][8][37] = 42, ++ [0][1][2][0][11][37] = 127, ++ [0][1][2][0][2][38] = 76, ++ [0][1][2][0][1][38] = 16, ++ [0][1][2][0][3][38] = 127, ++ [0][1][2][0][5][38] = 76, ++ [0][1][2][0][6][38] = 16, ++ [0][1][2][0][9][38] = 76, ++ [0][1][2][0][8][38] = 42, ++ [0][1][2][0][11][38] = 40, ++ [0][1][2][0][2][40] = 76, ++ [0][1][2][0][1][40] = 16, ++ [0][1][2][0][3][40] = 127, ++ [0][1][2][0][5][40] = 76, ++ [0][1][2][0][6][40] = 16, ++ [0][1][2][0][9][40] = 76, ++ [0][1][2][0][8][40] = 42, ++ [0][1][2][0][11][40] = 40, ++ [0][1][2][0][2][42] = 76, ++ [0][1][2][0][1][42] = 16, ++ [0][1][2][0][3][42] = 127, ++ [0][1][2][0][5][42] = 76, ++ [0][1][2][0][6][42] = 16, ++ [0][1][2][0][9][42] = 76, ++ [0][1][2][0][8][42] = 42, ++ [0][1][2][0][11][42] = 40, ++ [0][1][2][0][2][44] = 76, ++ [0][1][2][0][1][44] = 16, ++ [0][1][2][0][3][44] = 127, ++ [0][1][2][0][5][44] = 76, ++ [0][1][2][0][6][44] = 16, ++ [0][1][2][0][9][44] = 76, ++ [0][1][2][0][8][44] = 42, ++ [0][1][2][0][11][44] = 40, ++ [0][1][2][0][2][46] = 76, ++ [0][1][2][0][1][46] = 16, ++ [0][1][2][0][3][46] = 127, ++ [0][1][2][0][5][46] = 76, ++ [0][1][2][0][6][46] = 16, ++ [0][1][2][0][9][46] = 76, ++ [0][1][2][0][8][46] = 42, ++ [0][1][2][0][11][46] = 40, ++ [0][1][2][1][2][0] = 68, ++ [0][1][2][1][1][0] = 34, ++ [0][1][2][1][3][0] = 50, ++ [0][1][2][1][5][0] = 38, ++ [0][1][2][1][6][0] = 34, ++ [0][1][2][1][9][0] = 34, ++ [0][1][2][1][8][0] = 6, ++ [0][1][2][1][11][0] = 28, ++ [0][1][2][1][2][2] = 68, ++ [0][1][2][1][1][2] = 34, ++ [0][1][2][1][3][2] = 50, ++ [0][1][2][1][5][2] = 38, ++ [0][1][2][1][6][2] = 34, ++ [0][1][2][1][9][2] = 34, ++ [0][1][2][1][8][2] = 6, ++ [0][1][2][1][11][2] = 28, ++ [0][1][2][1][2][4] = 68, ++ [0][1][2][1][1][4] = 34, ++ [0][1][2][1][3][4] = 50, ++ [0][1][2][1][5][4] = 38, ++ [0][1][2][1][6][4] = 34, ++ [0][1][2][1][9][4] = 34, ++ [0][1][2][1][8][4] = 6, ++ [0][1][2][1][11][4] = 28, ++ [0][1][2][1][2][6] = 68, ++ [0][1][2][1][1][6] = 34, ++ [0][1][2][1][3][6] = 50, ++ [0][1][2][1][5][6] = 38, ++ [0][1][2][1][6][6] = 34, ++ [0][1][2][1][9][6] = 34, ++ [0][1][2][1][8][6] = 6, ++ [0][1][2][1][11][6] = 28, ++ [0][1][2][1][2][8] = 68, ++ [0][1][2][1][1][8] = 34, ++ [0][1][2][1][3][8] = 50, ++ [0][1][2][1][5][8] = 38, ++ [0][1][2][1][6][8] = 34, ++ [0][1][2][1][9][8] = 34, ++ [0][1][2][1][8][8] = 30, ++ [0][1][2][1][11][8] = 28, ++ [0][1][2][1][2][10] = 68, ++ [0][1][2][1][1][10] = 34, ++ [0][1][2][1][3][10] = 50, ++ [0][1][2][1][5][10] = 38, ++ [0][1][2][1][6][10] = 34, ++ [0][1][2][1][9][10] = 34, ++ [0][1][2][1][8][10] = 30, ++ [0][1][2][1][11][10] = 28, ++ [0][1][2][1][2][12] = 68, ++ [0][1][2][1][1][12] = 34, ++ [0][1][2][1][3][12] = 50, ++ [0][1][2][1][5][12] = 38, ++ [0][1][2][1][6][12] = 34, ++ [0][1][2][1][9][12] = 34, ++ [0][1][2][1][8][12] = 30, ++ [0][1][2][1][11][12] = 28, ++ [0][1][2][1][2][14] = 68, ++ [0][1][2][1][1][14] = 34, ++ [0][1][2][1][3][14] = 50, ++ [0][1][2][1][5][14] = 38, ++ [0][1][2][1][6][14] = 34, ++ [0][1][2][1][9][14] = 34, ++ [0][1][2][1][8][14] = 30, ++ [0][1][2][1][11][14] = 28, ++ [0][1][2][1][2][15] = 68, ++ [0][1][2][1][1][15] = 34, ++ [0][1][2][1][3][15] = 70, ++ [0][1][2][1][5][15] = 62, ++ [0][1][2][1][6][15] = 34, ++ [0][1][2][1][9][15] = 34, ++ [0][1][2][1][8][15] = 30, ++ [0][1][2][1][11][15] = 28, ++ [0][1][2][1][2][17] = 68, ++ [0][1][2][1][1][17] = 34, ++ [0][1][2][1][3][17] = 70, ++ [0][1][2][1][5][17] = 62, ++ [0][1][2][1][6][17] = 34, ++ [0][1][2][1][9][17] = 34, ++ [0][1][2][1][8][17] = 30, ++ [0][1][2][1][11][17] = 28, ++ [0][1][2][1][2][19] = 68, ++ [0][1][2][1][1][19] = 34, ++ [0][1][2][1][3][19] = 70, ++ [0][1][2][1][5][19] = 62, ++ [0][1][2][1][6][19] = 34, ++ [0][1][2][1][9][19] = 34, ++ [0][1][2][1][8][19] = 30, ++ [0][1][2][1][11][19] = 28, ++ [0][1][2][1][2][21] = 68, ++ [0][1][2][1][1][21] = 34, ++ [0][1][2][1][3][21] = 70, ++ [0][1][2][1][5][21] = 62, ++ [0][1][2][1][6][21] = 34, ++ [0][1][2][1][9][21] = 34, ++ [0][1][2][1][8][21] = 30, ++ [0][1][2][1][11][21] = 28, ++ [0][1][2][1][2][23] = 68, ++ [0][1][2][1][1][23] = 34, ++ [0][1][2][1][3][23] = 70, ++ [0][1][2][1][5][23] = 62, ++ [0][1][2][1][6][23] = 34, ++ [0][1][2][1][9][23] = 34, ++ [0][1][2][1][8][23] = 30, ++ [0][1][2][1][11][23] = 28, ++ [0][1][2][1][2][25] = 68, ++ [0][1][2][1][1][25] = 34, ++ [0][1][2][1][3][25] = 70, ++ [0][1][2][1][5][25] = 127, ++ [0][1][2][1][6][25] = 34, ++ [0][1][2][1][9][25] = 127, ++ [0][1][2][1][8][25] = 30, ++ [0][1][2][1][11][25] = 28, ++ [0][1][2][1][2][27] = 68, ++ [0][1][2][1][1][27] = 34, ++ [0][1][2][1][3][27] = 70, ++ [0][1][2][1][5][27] = 127, ++ [0][1][2][1][6][27] = 34, ++ [0][1][2][1][9][27] = 127, ++ [0][1][2][1][8][27] = 30, ++ [0][1][2][1][11][27] = 28, ++ [0][1][2][1][2][29] = 68, ++ [0][1][2][1][1][29] = 34, ++ [0][1][2][1][3][29] = 70, ++ [0][1][2][1][5][29] = 127, ++ [0][1][2][1][6][29] = 34, ++ [0][1][2][1][9][29] = 127, ++ [0][1][2][1][8][29] = 30, ++ [0][1][2][1][11][29] = 28, ++ [0][1][2][1][2][31] = 68, ++ [0][1][2][1][1][31] = 34, ++ [0][1][2][1][3][31] = 70, ++ [0][1][2][1][5][31] = 62, ++ [0][1][2][1][6][31] = 34, ++ [0][1][2][1][9][31] = 34, ++ [0][1][2][1][8][31] = 30, ++ [0][1][2][1][11][31] = 28, ++ [0][1][2][1][2][33] = 68, ++ [0][1][2][1][1][33] = 34, ++ [0][1][2][1][3][33] = 70, ++ [0][1][2][1][5][33] = 62, ++ [0][1][2][1][6][33] = 34, ++ [0][1][2][1][9][33] = 34, ++ [0][1][2][1][8][33] = 30, ++ [0][1][2][1][11][33] = 28, ++ [0][1][2][1][2][35] = 64, ++ [0][1][2][1][1][35] = 34, ++ [0][1][2][1][3][35] = 70, ++ [0][1][2][1][5][35] = 62, ++ [0][1][2][1][6][35] = 34, ++ [0][1][2][1][9][35] = 34, ++ [0][1][2][1][8][35] = 30, ++ [0][1][2][1][11][35] = 28, ++ [0][1][2][1][2][37] = 68, ++ [0][1][2][1][1][37] = 127, ++ [0][1][2][1][3][37] = 70, ++ [0][1][2][1][5][37] = 62, ++ [0][1][2][1][6][37] = 34, ++ [0][1][2][1][9][37] = 68, ++ [0][1][2][1][8][37] = 30, ++ [0][1][2][1][11][37] = 127, ++ [0][1][2][1][2][38] = 76, ++ [0][1][2][1][1][38] = 4, ++ [0][1][2][1][3][38] = 127, ++ [0][1][2][1][5][38] = 76, ++ [0][1][2][1][6][38] = 4, ++ [0][1][2][1][9][38] = 76, ++ [0][1][2][1][8][38] = 30, ++ [0][1][2][1][11][38] = 28, ++ [0][1][2][1][2][40] = 76, ++ [0][1][2][1][1][40] = 4, ++ [0][1][2][1][3][40] = 127, ++ [0][1][2][1][5][40] = 76, ++ [0][1][2][1][6][40] = 4, ++ [0][1][2][1][9][40] = 76, ++ [0][1][2][1][8][40] = 30, ++ [0][1][2][1][11][40] = 28, ++ [0][1][2][1][2][42] = 76, ++ [0][1][2][1][1][42] = 4, ++ [0][1][2][1][3][42] = 127, ++ [0][1][2][1][5][42] = 76, ++ [0][1][2][1][6][42] = 4, ++ [0][1][2][1][9][42] = 76, ++ [0][1][2][1][8][42] = 30, ++ [0][1][2][1][11][42] = 28, ++ [0][1][2][1][2][44] = 76, ++ [0][1][2][1][1][44] = 4, ++ [0][1][2][1][3][44] = 127, ++ [0][1][2][1][5][44] = 76, ++ [0][1][2][1][6][44] = 4, ++ [0][1][2][1][9][44] = 76, ++ [0][1][2][1][8][44] = 30, ++ [0][1][2][1][11][44] = 28, ++ [0][1][2][1][2][46] = 76, ++ [0][1][2][1][1][46] = 4, ++ [0][1][2][1][3][46] = 127, ++ [0][1][2][1][5][46] = 76, ++ [0][1][2][1][6][46] = 4, ++ [0][1][2][1][9][46] = 76, ++ [0][1][2][1][8][46] = 30, ++ [0][1][2][1][11][46] = 28, ++ [1][0][2][0][2][1] = 68, ++ [1][0][2][0][1][1] = 64, ++ [1][0][2][0][3][1] = 62, ++ [1][0][2][0][5][1] = 64, ++ [1][0][2][0][6][1] = 64, ++ [1][0][2][0][9][1] = 64, ++ [1][0][2][0][8][1] = 30, ++ [1][0][2][0][11][1] = 52, ++ [1][0][2][0][2][5] = 72, ++ [1][0][2][0][1][5] = 64, ++ [1][0][2][0][3][5] = 62, ++ [1][0][2][0][5][5] = 64, ++ [1][0][2][0][6][5] = 60, ++ [1][0][2][0][9][5] = 64, ++ [1][0][2][0][8][5] = 30, ++ [1][0][2][0][11][5] = 52, ++ [1][0][2][0][2][9] = 72, ++ [1][0][2][0][1][9] = 64, ++ [1][0][2][0][3][9] = 62, ++ [1][0][2][0][5][9] = 64, ++ [1][0][2][0][6][9] = 64, ++ [1][0][2][0][9][9] = 64, ++ [1][0][2][0][8][9] = 54, ++ [1][0][2][0][11][9] = 52, ++ [1][0][2][0][2][13] = 66, ++ [1][0][2][0][1][13] = 64, ++ [1][0][2][0][3][13] = 62, ++ [1][0][2][0][5][13] = 64, ++ [1][0][2][0][6][13] = 64, ++ [1][0][2][0][9][13] = 64, ++ [1][0][2][0][8][13] = 54, ++ [1][0][2][0][11][13] = 52, ++ [1][0][2][0][2][16] = 62, ++ [1][0][2][0][1][16] = 64, ++ [1][0][2][0][3][16] = 72, ++ [1][0][2][0][5][16] = 62, ++ [1][0][2][0][6][16] = 64, ++ [1][0][2][0][9][16] = 64, ++ [1][0][2][0][8][16] = 54, ++ [1][0][2][0][11][16] = 52, ++ [1][0][2][0][2][20] = 72, ++ [1][0][2][0][1][20] = 64, ++ [1][0][2][0][3][20] = 72, ++ [1][0][2][0][5][20] = 72, ++ [1][0][2][0][6][20] = 64, ++ [1][0][2][0][9][20] = 64, ++ [1][0][2][0][8][20] = 54, ++ [1][0][2][0][11][20] = 52, ++ [1][0][2][0][2][24] = 72, ++ [1][0][2][0][1][24] = 64, ++ [1][0][2][0][3][24] = 72, ++ [1][0][2][0][5][24] = 127, ++ [1][0][2][0][6][24] = 64, ++ [1][0][2][0][9][24] = 127, ++ [1][0][2][0][8][24] = 54, ++ [1][0][2][0][11][24] = 52, ++ [1][0][2][0][2][28] = 72, ++ [1][0][2][0][1][28] = 64, ++ [1][0][2][0][3][28] = 72, ++ [1][0][2][0][5][28] = 127, ++ [1][0][2][0][6][28] = 64, ++ [1][0][2][0][9][28] = 127, ++ [1][0][2][0][8][28] = 54, ++ [1][0][2][0][11][28] = 52, ++ [1][0][2][0][2][32] = 72, ++ [1][0][2][0][1][32] = 64, ++ [1][0][2][0][3][32] = 72, ++ [1][0][2][0][5][32] = 72, ++ [1][0][2][0][6][32] = 64, ++ [1][0][2][0][9][32] = 64, ++ [1][0][2][0][8][32] = 54, ++ [1][0][2][0][11][32] = 52, ++ [1][0][2][0][2][36] = 72, ++ [1][0][2][0][1][36] = 127, ++ [1][0][2][0][3][36] = 72, ++ [1][0][2][0][5][36] = 72, ++ [1][0][2][0][6][36] = 64, ++ [1][0][2][0][9][36] = 72, ++ [1][0][2][0][8][36] = 54, ++ [1][0][2][0][11][36] = 127, ++ [1][0][2][0][2][39] = 72, ++ [1][0][2][0][1][39] = 28, ++ [1][0][2][0][3][39] = 127, ++ [1][0][2][0][5][39] = 72, ++ [1][0][2][0][6][39] = 28, ++ [1][0][2][0][9][39] = 72, ++ [1][0][2][0][8][39] = 54, ++ [1][0][2][0][11][39] = 52, ++ [1][0][2][0][2][43] = 72, ++ [1][0][2][0][1][43] = 28, ++ [1][0][2][0][3][43] = 127, ++ [1][0][2][0][5][43] = 72, ++ [1][0][2][0][6][43] = 28, ++ [1][0][2][0][9][43] = 72, ++ [1][0][2][0][8][43] = 54, ++ [1][0][2][0][11][43] = 52, ++ [1][1][2][0][2][1] = 58, ++ [1][1][2][0][1][1] = 52, ++ [1][1][2][0][3][1] = 50, ++ [1][1][2][0][5][1] = 52, ++ [1][1][2][0][6][1] = 52, ++ [1][1][2][0][9][1] = 52, ++ [1][1][2][0][8][1] = 18, ++ [1][1][2][0][11][1] = 40, ++ [1][1][2][0][2][5] = 72, ++ [1][1][2][0][1][5] = 52, ++ [1][1][2][0][3][5] = 50, ++ [1][1][2][0][5][5] = 52, ++ [1][1][2][0][6][5] = 46, ++ [1][1][2][0][9][5] = 52, ++ [1][1][2][0][8][5] = 18, ++ [1][1][2][0][11][5] = 40, ++ [1][1][2][0][2][9] = 72, ++ [1][1][2][0][1][9] = 52, ++ [1][1][2][0][3][9] = 50, ++ [1][1][2][0][5][9] = 52, ++ [1][1][2][0][6][9] = 52, ++ [1][1][2][0][9][9] = 52, ++ [1][1][2][0][8][9] = 42, ++ [1][1][2][0][11][9] = 40, ++ [1][1][2][0][2][13] = 58, ++ [1][1][2][0][1][13] = 52, ++ [1][1][2][0][3][13] = 50, ++ [1][1][2][0][5][13] = 52, ++ [1][1][2][0][6][13] = 52, ++ [1][1][2][0][9][13] = 52, ++ [1][1][2][0][8][13] = 42, ++ [1][1][2][0][11][13] = 40, ++ [1][1][2][0][2][16] = 56, ++ [1][1][2][0][1][16] = 52, ++ [1][1][2][0][3][16] = 72, ++ [1][1][2][0][5][16] = 56, ++ [1][1][2][0][6][16] = 52, ++ [1][1][2][0][9][16] = 52, ++ [1][1][2][0][8][16] = 42, ++ [1][1][2][0][11][16] = 40, ++ [1][1][2][0][2][20] = 72, ++ [1][1][2][0][1][20] = 52, ++ [1][1][2][0][3][20] = 72, ++ [1][1][2][0][5][20] = 72, ++ [1][1][2][0][6][20] = 52, ++ [1][1][2][0][9][20] = 52, ++ [1][1][2][0][8][20] = 42, ++ [1][1][2][0][11][20] = 40, ++ [1][1][2][0][2][24] = 72, ++ [1][1][2][0][1][24] = 52, ++ [1][1][2][0][3][24] = 72, ++ [1][1][2][0][5][24] = 127, ++ [1][1][2][0][6][24] = 52, ++ [1][1][2][0][9][24] = 127, ++ [1][1][2][0][8][24] = 42, ++ [1][1][2][0][11][24] = 40, ++ [1][1][2][0][2][28] = 72, ++ [1][1][2][0][1][28] = 52, ++ [1][1][2][0][3][28] = 72, ++ [1][1][2][0][5][28] = 127, ++ [1][1][2][0][6][28] = 52, ++ [1][1][2][0][9][28] = 127, ++ [1][1][2][0][8][28] = 42, ++ [1][1][2][0][11][28] = 40, ++ [1][1][2][0][2][32] = 68, ++ [1][1][2][0][1][32] = 52, ++ [1][1][2][0][3][32] = 72, ++ [1][1][2][0][5][32] = 68, ++ [1][1][2][0][6][32] = 52, ++ [1][1][2][0][9][32] = 52, ++ [1][1][2][0][8][32] = 42, ++ [1][1][2][0][11][32] = 40, ++ [1][1][2][0][2][36] = 72, ++ [1][1][2][0][1][36] = 127, ++ [1][1][2][0][3][36] = 72, ++ [1][1][2][0][5][36] = 72, ++ [1][1][2][0][6][36] = 52, ++ [1][1][2][0][9][36] = 72, ++ [1][1][2][0][8][36] = 42, ++ [1][1][2][0][11][36] = 127, ++ [1][1][2][0][2][39] = 72, ++ [1][1][2][0][1][39] = 16, ++ [1][1][2][0][3][39] = 127, ++ [1][1][2][0][5][39] = 72, ++ [1][1][2][0][6][39] = 16, ++ [1][1][2][0][9][39] = 72, ++ [1][1][2][0][8][39] = 42, ++ [1][1][2][0][11][39] = 40, ++ [1][1][2][0][2][43] = 72, ++ [1][1][2][0][1][43] = 16, ++ [1][1][2][0][3][43] = 127, ++ [1][1][2][0][5][43] = 72, ++ [1][1][2][0][6][43] = 16, ++ [1][1][2][0][9][43] = 72, ++ [1][1][2][0][8][43] = 42, ++ [1][1][2][0][11][43] = 40, ++ [1][1][2][1][2][1] = 58, ++ [1][1][2][1][1][1] = 40, ++ [1][1][2][1][3][1] = 50, ++ [1][1][2][1][5][1] = 40, ++ [1][1][2][1][6][1] = 40, ++ [1][1][2][1][9][1] = 40, ++ [1][1][2][1][8][1] = 6, ++ [1][1][2][1][11][1] = 28, ++ [1][1][2][1][2][5] = 68, ++ [1][1][2][1][1][5] = 40, ++ [1][1][2][1][3][5] = 50, ++ [1][1][2][1][5][5] = 40, ++ [1][1][2][1][6][5] = 40, ++ [1][1][2][1][9][5] = 40, ++ [1][1][2][1][8][5] = 6, ++ [1][1][2][1][11][5] = 28, ++ [1][1][2][1][2][9] = 68, ++ [1][1][2][1][1][9] = 40, ++ [1][1][2][1][3][9] = 50, ++ [1][1][2][1][5][9] = 40, ++ [1][1][2][1][6][9] = 40, ++ [1][1][2][1][9][9] = 40, ++ [1][1][2][1][8][9] = 30, ++ [1][1][2][1][11][9] = 28, ++ [1][1][2][1][2][13] = 58, ++ [1][1][2][1][1][13] = 40, ++ [1][1][2][1][3][13] = 50, ++ [1][1][2][1][5][13] = 40, ++ [1][1][2][1][6][13] = 40, ++ [1][1][2][1][9][13] = 40, ++ [1][1][2][1][8][13] = 30, ++ [1][1][2][1][11][13] = 28, ++ [1][1][2][1][2][16] = 56, ++ [1][1][2][1][1][16] = 40, ++ [1][1][2][1][3][16] = 72, ++ [1][1][2][1][5][16] = 56, ++ [1][1][2][1][6][16] = 40, ++ [1][1][2][1][9][16] = 40, ++ [1][1][2][1][8][16] = 30, ++ [1][1][2][1][11][16] = 28, ++ [1][1][2][1][2][20] = 68, ++ [1][1][2][1][1][20] = 40, ++ [1][1][2][1][3][20] = 72, ++ [1][1][2][1][5][20] = 68, ++ [1][1][2][1][6][20] = 40, ++ [1][1][2][1][9][20] = 40, ++ [1][1][2][1][8][20] = 30, ++ [1][1][2][1][11][20] = 28, ++ [1][1][2][1][2][24] = 68, ++ [1][1][2][1][1][24] = 40, ++ [1][1][2][1][3][24] = 72, ++ [1][1][2][1][5][24] = 127, ++ [1][1][2][1][6][24] = 40, ++ [1][1][2][1][9][24] = 127, ++ [1][1][2][1][8][24] = 30, ++ [1][1][2][1][11][24] = 28, ++ [1][1][2][1][2][28] = 68, ++ [1][1][2][1][1][28] = 40, ++ [1][1][2][1][3][28] = 72, ++ [1][1][2][1][5][28] = 127, ++ [1][1][2][1][6][28] = 40, ++ [1][1][2][1][9][28] = 127, ++ [1][1][2][1][8][28] = 30, ++ [1][1][2][1][11][28] = 28, ++ [1][1][2][1][2][32] = 68, ++ [1][1][2][1][1][32] = 40, ++ [1][1][2][1][3][32] = 72, ++ [1][1][2][1][5][32] = 68, ++ [1][1][2][1][6][32] = 40, ++ [1][1][2][1][9][32] = 40, ++ [1][1][2][1][8][32] = 30, ++ [1][1][2][1][11][32] = 28, ++ [1][1][2][1][2][36] = 68, ++ [1][1][2][1][1][36] = 127, ++ [1][1][2][1][3][36] = 72, ++ [1][1][2][1][5][36] = 68, ++ [1][1][2][1][6][36] = 40, ++ [1][1][2][1][9][36] = 68, ++ [1][1][2][1][8][36] = 30, ++ [1][1][2][1][11][36] = 127, ++ [1][1][2][1][2][39] = 72, ++ [1][1][2][1][1][39] = 4, ++ [1][1][2][1][3][39] = 127, ++ [1][1][2][1][5][39] = 72, ++ [1][1][2][1][6][39] = 4, ++ [1][1][2][1][9][39] = 72, ++ [1][1][2][1][8][39] = 30, ++ [1][1][2][1][11][39] = 28, ++ [1][1][2][1][2][43] = 72, ++ [1][1][2][1][1][43] = 4, ++ [1][1][2][1][3][43] = 127, ++ [1][1][2][1][5][43] = 72, ++ [1][1][2][1][6][43] = 4, ++ [1][1][2][1][9][43] = 72, ++ [1][1][2][1][8][43] = 30, ++ [1][1][2][1][11][43] = 28, ++ [2][0][2][0][2][3] = 64, ++ [2][0][2][0][1][3] = 64, ++ [2][0][2][0][3][3] = 64, ++ [2][0][2][0][5][3] = 62, ++ [2][0][2][0][6][3] = 64, ++ [2][0][2][0][9][3] = 64, ++ [2][0][2][0][8][3] = 30, ++ [2][0][2][0][11][3] = 52, ++ [2][0][2][0][2][11] = 64, ++ [2][0][2][0][1][11] = 64, ++ [2][0][2][0][3][11] = 64, ++ [2][0][2][0][5][11] = 62, ++ [2][0][2][0][6][11] = 64, ++ [2][0][2][0][9][11] = 64, ++ [2][0][2][0][8][11] = 54, ++ [2][0][2][0][11][11] = 52, ++ [2][0][2][0][2][18] = 62, ++ [2][0][2][0][1][18] = 64, ++ [2][0][2][0][3][18] = 72, ++ [2][0][2][0][5][18] = 66, ++ [2][0][2][0][6][18] = 64, ++ [2][0][2][0][9][18] = 64, ++ [2][0][2][0][8][18] = 54, ++ [2][0][2][0][11][18] = 52, ++ [2][0][2][0][2][26] = 72, ++ [2][0][2][0][1][26] = 64, ++ [2][0][2][0][3][26] = 72, ++ [2][0][2][0][5][26] = 127, ++ [2][0][2][0][6][26] = 64, ++ [2][0][2][0][9][26] = 127, ++ [2][0][2][0][8][26] = 54, ++ [2][0][2][0][11][26] = 52, ++ [2][0][2][0][2][34] = 72, ++ [2][0][2][0][1][34] = 127, ++ [2][0][2][0][3][34] = 72, ++ [2][0][2][0][5][34] = 72, ++ [2][0][2][0][6][34] = 64, ++ [2][0][2][0][9][34] = 72, ++ [2][0][2][0][8][34] = 54, ++ [2][0][2][0][11][34] = 127, ++ [2][0][2][0][2][41] = 72, ++ [2][0][2][0][1][41] = 28, ++ [2][0][2][0][3][41] = 127, ++ [2][0][2][0][5][41] = 72, ++ [2][0][2][0][6][41] = 28, ++ [2][0][2][0][9][41] = 72, ++ [2][0][2][0][8][41] = 54, ++ [2][0][2][0][11][41] = 52, ++ [2][1][2][0][2][3] = 56, ++ [2][1][2][0][1][3] = 52, ++ [2][1][2][0][3][3] = 52, ++ [2][1][2][0][5][3] = 52, ++ [2][1][2][0][6][3] = 52, ++ [2][1][2][0][9][3] = 52, ++ [2][1][2][0][8][3] = 18, ++ [2][1][2][0][11][3] = 40, ++ [2][1][2][0][2][11] = 56, ++ [2][1][2][0][1][11] = 52, ++ [2][1][2][0][3][11] = 52, ++ [2][1][2][0][5][11] = 52, ++ [2][1][2][0][6][11] = 52, ++ [2][1][2][0][9][11] = 52, ++ [2][1][2][0][8][11] = 42, ++ [2][1][2][0][11][11] = 40, ++ [2][1][2][0][2][18] = 56, ++ [2][1][2][0][1][18] = 52, ++ [2][1][2][0][3][18] = 72, ++ [2][1][2][0][5][18] = 56, ++ [2][1][2][0][6][18] = 52, ++ [2][1][2][0][9][18] = 52, ++ [2][1][2][0][8][18] = 42, ++ [2][1][2][0][11][18] = 40, ++ [2][1][2][0][2][26] = 72, ++ [2][1][2][0][1][26] = 52, ++ [2][1][2][0][3][26] = 72, ++ [2][1][2][0][5][26] = 127, ++ [2][1][2][0][6][26] = 52, ++ [2][1][2][0][9][26] = 127, ++ [2][1][2][0][8][26] = 42, ++ [2][1][2][0][11][26] = 40, ++ [2][1][2][0][2][34] = 72, ++ [2][1][2][0][1][34] = 127, ++ [2][1][2][0][3][34] = 72, ++ [2][1][2][0][5][34] = 72, ++ [2][1][2][0][6][34] = 52, ++ [2][1][2][0][9][34] = 72, ++ [2][1][2][0][8][34] = 42, ++ [2][1][2][0][11][34] = 127, ++ [2][1][2][0][2][41] = 72, ++ [2][1][2][0][1][41] = 16, ++ [2][1][2][0][3][41] = 127, ++ [2][1][2][0][5][41] = 72, ++ [2][1][2][0][6][41] = 16, ++ [2][1][2][0][9][41] = 72, ++ [2][1][2][0][8][41] = 42, ++ [2][1][2][0][11][41] = 40, ++ [2][1][2][1][2][3] = 56, ++ [2][1][2][1][1][3] = 40, ++ [2][1][2][1][3][3] = 52, ++ [2][1][2][1][5][3] = 40, ++ [2][1][2][1][6][3] = 40, ++ [2][1][2][1][9][3] = 40, ++ [2][1][2][1][8][3] = 6, ++ [2][1][2][1][11][3] = 28, ++ [2][1][2][1][2][11] = 56, ++ [2][1][2][1][1][11] = 40, ++ [2][1][2][1][3][11] = 52, ++ [2][1][2][1][5][11] = 40, ++ [2][1][2][1][6][11] = 40, ++ [2][1][2][1][9][11] = 40, ++ [2][1][2][1][8][11] = 30, ++ [2][1][2][1][11][11] = 28, ++ [2][1][2][1][2][18] = 56, ++ [2][1][2][1][1][18] = 40, ++ [2][1][2][1][3][18] = 72, ++ [2][1][2][1][5][18] = 56, ++ [2][1][2][1][6][18] = 40, ++ [2][1][2][1][9][18] = 40, ++ [2][1][2][1][8][18] = 30, ++ [2][1][2][1][11][18] = 28, ++ [2][1][2][1][2][26] = 68, ++ [2][1][2][1][1][26] = 40, ++ [2][1][2][1][3][26] = 72, ++ [2][1][2][1][5][26] = 127, ++ [2][1][2][1][6][26] = 40, ++ [2][1][2][1][9][26] = 127, ++ [2][1][2][1][8][26] = 30, ++ [2][1][2][1][11][26] = 28, ++ [2][1][2][1][2][34] = 68, ++ [2][1][2][1][1][34] = 127, ++ [2][1][2][1][3][34] = 72, ++ [2][1][2][1][5][34] = 68, ++ [2][1][2][1][6][34] = 40, ++ [2][1][2][1][9][34] = 68, ++ [2][1][2][1][8][34] = 30, ++ [2][1][2][1][11][34] = 127, ++ [2][1][2][1][2][41] = 72, ++ [2][1][2][1][1][41] = 4, ++ [2][1][2][1][3][41] = 127, ++ [2][1][2][1][5][41] = 72, ++ [2][1][2][1][6][41] = 4, ++ [2][1][2][1][9][41] = 72, ++ [2][1][2][1][8][41] = 30, ++ [2][1][2][1][11][41] = 28, ++}; ++ ++const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] ++ [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { ++ [0][0][0][0] = 32, ++ [0][0][0][1] = 32, ++ [0][0][0][2] = 32, ++ [0][0][0][3] = 32, ++ [0][0][0][4] = 32, ++ [0][0][0][5] = 32, ++ [0][0][0][6] = 32, ++ [0][0][0][7] = 32, ++ [0][0][0][8] = 32, ++ [0][0][0][9] = 32, ++ [0][0][0][10] = 32, ++ [0][0][0][11] = 32, ++ [0][0][0][12] = 32, ++ [0][0][0][13] = 0, ++ [0][1][0][0] = 20, ++ [0][1][0][1] = 20, ++ [0][1][0][2] = 20, ++ [0][1][0][3] = 20, ++ [0][1][0][4] = 20, ++ [0][1][0][5] = 20, ++ [0][1][0][6] = 20, ++ [0][1][0][7] = 20, ++ [0][1][0][8] = 20, ++ [0][1][0][9] = 20, ++ [0][1][0][10] = 20, ++ [0][1][0][11] = 20, ++ [0][1][0][12] = 20, ++ [0][1][0][13] = 0, ++ [1][0][0][0] = 42, ++ [1][0][0][1] = 42, ++ [1][0][0][2] = 42, ++ [1][0][0][3] = 42, ++ [1][0][0][4] = 42, ++ [1][0][0][5] = 42, ++ [1][0][0][6] = 42, ++ [1][0][0][7] = 42, ++ [1][0][0][8] = 42, ++ [1][0][0][9] = 42, ++ [1][0][0][10] = 42, ++ [1][0][0][11] = 42, ++ [1][0][0][12] = 36, ++ [1][0][0][13] = 0, ++ [1][1][0][0] = 30, ++ [1][1][0][1] = 30, ++ [1][1][0][2] = 30, ++ [1][1][0][3] = 30, ++ [1][1][0][4] = 30, ++ [1][1][0][5] = 30, ++ [1][1][0][6] = 30, ++ [1][1][0][7] = 30, ++ [1][1][0][8] = 30, ++ [1][1][0][9] = 30, ++ [1][1][0][10] = 30, ++ [1][1][0][11] = 30, ++ [1][1][0][12] = 30, ++ [1][1][0][13] = 0, ++ [2][0][0][0] = 52, ++ [2][0][0][1] = 52, ++ [2][0][0][2] = 52, ++ [2][0][0][3] = 52, ++ [2][0][0][4] = 52, ++ [2][0][0][5] = 52, ++ [2][0][0][6] = 52, ++ [2][0][0][7] = 52, ++ [2][0][0][8] = 52, ++ [2][0][0][9] = 52, ++ [2][0][0][10] = 52, ++ [2][0][0][11] = 52, ++ [2][0][0][12] = 40, ++ [2][0][0][13] = 0, ++ [2][1][0][0] = 40, ++ [2][1][0][1] = 40, ++ [2][1][0][2] = 40, ++ [2][1][0][3] = 40, ++ [2][1][0][4] = 40, ++ [2][1][0][5] = 40, ++ [2][1][0][6] = 40, ++ [2][1][0][7] = 40, ++ [2][1][0][8] = 40, ++ [2][1][0][9] = 40, ++ [2][1][0][10] = 40, ++ [2][1][0][11] = 40, ++ [2][1][0][12] = 26, ++ [2][1][0][13] = 0, ++ [0][0][2][0] = 70, ++ [0][0][1][0] = 32, ++ [0][0][3][0] = 40, ++ [0][0][5][0] = 70, ++ [0][0][6][0] = 32, ++ [0][0][9][0] = 32, ++ [0][0][8][0] = 60, ++ [0][0][11][0] = 32, ++ [0][0][2][1] = 70, ++ [0][0][1][1] = 32, ++ [0][0][3][1] = 40, ++ [0][0][5][1] = 70, ++ [0][0][6][1] = 32, ++ [0][0][9][1] = 32, ++ [0][0][8][1] = 60, ++ [0][0][11][1] = 32, ++ [0][0][2][2] = 74, ++ [0][0][1][2] = 32, ++ [0][0][3][2] = 40, ++ [0][0][5][2] = 74, ++ [0][0][6][2] = 32, ++ [0][0][9][2] = 32, ++ [0][0][8][2] = 60, ++ [0][0][11][2] = 32, ++ [0][0][2][3] = 78, ++ [0][0][1][3] = 32, ++ [0][0][3][3] = 40, ++ [0][0][5][3] = 78, ++ [0][0][6][3] = 32, ++ [0][0][9][3] = 32, ++ [0][0][8][3] = 60, ++ [0][0][11][3] = 32, ++ [0][0][2][4] = 78, ++ [0][0][1][4] = 32, ++ [0][0][3][4] = 40, ++ [0][0][5][4] = 78, ++ [0][0][6][4] = 32, ++ [0][0][9][4] = 32, ++ [0][0][8][4] = 60, ++ [0][0][11][4] = 32, ++ [0][0][2][5] = 78, ++ [0][0][1][5] = 32, ++ [0][0][3][5] = 40, ++ [0][0][5][5] = 78, ++ [0][0][6][5] = 32, ++ [0][0][9][5] = 32, ++ [0][0][8][5] = 60, ++ [0][0][11][5] = 32, ++ [0][0][2][6] = 78, ++ [0][0][1][6] = 32, ++ [0][0][3][6] = 40, ++ [0][0][5][6] = 78, ++ [0][0][6][6] = 32, ++ [0][0][9][6] = 32, ++ [0][0][8][6] = 60, ++ [0][0][11][6] = 32, ++ [0][0][2][7] = 78, ++ [0][0][1][7] = 32, ++ [0][0][3][7] = 40, ++ [0][0][5][7] = 78, ++ [0][0][6][7] = 32, ++ [0][0][9][7] = 32, ++ [0][0][8][7] = 60, ++ [0][0][11][7] = 32, ++ [0][0][2][8] = 74, ++ [0][0][1][8] = 32, ++ [0][0][3][8] = 40, ++ [0][0][5][8] = 74, ++ [0][0][6][8] = 32, ++ [0][0][9][8] = 32, ++ [0][0][8][8] = 60, ++ [0][0][11][8] = 32, ++ [0][0][2][9] = 70, ++ [0][0][1][9] = 32, ++ [0][0][3][9] = 40, ++ [0][0][5][9] = 70, ++ [0][0][6][9] = 32, ++ [0][0][9][9] = 32, ++ [0][0][8][9] = 60, ++ [0][0][11][9] = 32, ++ [0][0][2][10] = 70, ++ [0][0][1][10] = 32, ++ [0][0][3][10] = 40, ++ [0][0][5][10] = 70, ++ [0][0][6][10] = 32, ++ [0][0][9][10] = 32, ++ [0][0][8][10] = 60, ++ [0][0][11][10] = 32, ++ [0][0][2][11] = 58, ++ [0][0][1][11] = 32, ++ [0][0][3][11] = 40, ++ [0][0][5][11] = 58, ++ [0][0][6][11] = 32, ++ [0][0][9][11] = 32, ++ [0][0][8][11] = 60, ++ [0][0][11][11] = 32, ++ [0][0][2][12] = 34, ++ [0][0][1][12] = 32, ++ [0][0][3][12] = 40, ++ [0][0][5][12] = 34, ++ [0][0][6][12] = 32, ++ [0][0][9][12] = 32, ++ [0][0][8][12] = 60, ++ [0][0][11][12] = 32, ++ [0][0][2][13] = 127, ++ [0][0][1][13] = 127, ++ [0][0][3][13] = 127, ++ [0][0][5][13] = 127, ++ [0][0][6][13] = 127, ++ [0][0][9][13] = 127, ++ [0][0][8][13] = 127, ++ [0][0][11][13] = 127, ++ [0][1][2][0] = 64, ++ [0][1][1][0] = 20, ++ [0][1][3][0] = 28, ++ [0][1][5][0] = 64, ++ [0][1][6][0] = 20, ++ [0][1][9][0] = 20, ++ [0][1][8][0] = 48, ++ [0][1][11][0] = 20, ++ [0][1][2][1] = 64, ++ [0][1][1][1] = 20, ++ [0][1][3][1] = 28, ++ [0][1][5][1] = 64, ++ [0][1][6][1] = 20, ++ [0][1][9][1] = 20, ++ [0][1][8][1] = 48, ++ [0][1][11][1] = 20, ++ [0][1][2][2] = 68, ++ [0][1][1][2] = 20, ++ [0][1][3][2] = 28, ++ [0][1][5][2] = 68, ++ [0][1][6][2] = 20, ++ [0][1][9][2] = 20, ++ [0][1][8][2] = 48, ++ [0][1][11][2] = 20, ++ [0][1][2][3] = 72, ++ [0][1][1][3] = 20, ++ [0][1][3][3] = 28, ++ [0][1][5][3] = 72, ++ [0][1][6][3] = 20, ++ [0][1][9][3] = 20, ++ [0][1][8][3] = 48, ++ [0][1][11][3] = 20, ++ [0][1][2][4] = 76, ++ [0][1][1][4] = 20, ++ [0][1][3][4] = 28, ++ [0][1][5][4] = 76, ++ [0][1][6][4] = 20, ++ [0][1][9][4] = 20, ++ [0][1][8][4] = 48, ++ [0][1][11][4] = 20, ++ [0][1][2][5] = 78, ++ [0][1][1][5] = 20, ++ [0][1][3][5] = 28, ++ [0][1][5][5] = 78, ++ [0][1][6][5] = 20, ++ [0][1][9][5] = 20, ++ [0][1][8][5] = 48, ++ [0][1][11][5] = 20, ++ [0][1][2][6] = 76, ++ [0][1][1][6] = 20, ++ [0][1][3][6] = 28, ++ [0][1][5][6] = 76, ++ [0][1][6][6] = 20, ++ [0][1][9][6] = 20, ++ [0][1][8][6] = 48, ++ [0][1][11][6] = 20, ++ [0][1][2][7] = 72, ++ [0][1][1][7] = 20, ++ [0][1][3][7] = 28, ++ [0][1][5][7] = 72, ++ [0][1][6][7] = 20, ++ [0][1][9][7] = 20, ++ [0][1][8][7] = 48, ++ [0][1][11][7] = 20, ++ [0][1][2][8] = 68, ++ [0][1][1][8] = 20, ++ [0][1][3][8] = 28, ++ [0][1][5][8] = 68, ++ [0][1][6][8] = 20, ++ [0][1][9][8] = 20, ++ [0][1][8][8] = 48, ++ [0][1][11][8] = 20, ++ [0][1][2][9] = 64, ++ [0][1][1][9] = 20, ++ [0][1][3][9] = 28, ++ [0][1][5][9] = 64, ++ [0][1][6][9] = 20, ++ [0][1][9][9] = 20, ++ [0][1][8][9] = 48, ++ [0][1][11][9] = 20, ++ [0][1][2][10] = 64, ++ [0][1][1][10] = 20, ++ [0][1][3][10] = 28, ++ [0][1][5][10] = 64, ++ [0][1][6][10] = 20, ++ [0][1][9][10] = 20, ++ [0][1][8][10] = 48, ++ [0][1][11][10] = 20, ++ [0][1][2][11] = 54, ++ [0][1][1][11] = 20, ++ [0][1][3][11] = 28, ++ [0][1][5][11] = 54, ++ [0][1][6][11] = 20, ++ [0][1][9][11] = 20, ++ [0][1][8][11] = 48, ++ [0][1][11][11] = 20, ++ [0][1][2][12] = 32, ++ [0][1][1][12] = 20, ++ [0][1][3][12] = 28, ++ [0][1][5][12] = 32, ++ [0][1][6][12] = 20, ++ [0][1][9][12] = 20, ++ [0][1][8][12] = 48, ++ [0][1][11][12] = 20, ++ [0][1][2][13] = 127, ++ [0][1][1][13] = 127, ++ [0][1][3][13] = 127, ++ [0][1][5][13] = 127, ++ [0][1][6][13] = 127, ++ [0][1][9][13] = 127, ++ [0][1][8][13] = 127, ++ [0][1][11][13] = 127, ++ [1][0][2][0] = 72, ++ [1][0][1][0] = 42, ++ [1][0][3][0] = 50, ++ [1][0][5][0] = 72, ++ [1][0][6][0] = 42, ++ [1][0][9][0] = 42, ++ [1][0][8][0] = 60, ++ [1][0][11][0] = 42, ++ [1][0][2][1] = 72, ++ [1][0][1][1] = 42, ++ [1][0][3][1] = 50, ++ [1][0][5][1] = 72, ++ [1][0][6][1] = 42, ++ [1][0][9][1] = 42, ++ [1][0][8][1] = 60, ++ [1][0][11][1] = 42, ++ [1][0][2][2] = 76, ++ [1][0][1][2] = 42, ++ [1][0][3][2] = 50, ++ [1][0][5][2] = 76, ++ [1][0][6][2] = 42, ++ [1][0][9][2] = 42, ++ [1][0][8][2] = 60, ++ [1][0][11][2] = 42, ++ [1][0][2][3] = 78, ++ [1][0][1][3] = 42, ++ [1][0][3][3] = 50, ++ [1][0][5][3] = 78, ++ [1][0][6][3] = 42, ++ [1][0][9][3] = 42, ++ [1][0][8][3] = 60, ++ [1][0][11][3] = 42, ++ [1][0][2][4] = 78, ++ [1][0][1][4] = 42, ++ [1][0][3][4] = 50, ++ [1][0][5][4] = 78, ++ [1][0][6][4] = 42, ++ [1][0][9][4] = 42, ++ [1][0][8][4] = 60, ++ [1][0][11][4] = 42, ++ [1][0][2][5] = 78, ++ [1][0][1][5] = 42, ++ [1][0][3][5] = 50, ++ [1][0][5][5] = 78, ++ [1][0][6][5] = 42, ++ [1][0][9][5] = 42, ++ [1][0][8][5] = 60, ++ [1][0][11][5] = 42, ++ [1][0][2][6] = 78, ++ [1][0][1][6] = 42, ++ [1][0][3][6] = 50, ++ [1][0][5][6] = 78, ++ [1][0][6][6] = 42, ++ [1][0][9][6] = 42, ++ [1][0][8][6] = 60, ++ [1][0][11][6] = 42, ++ [1][0][2][7] = 78, ++ [1][0][1][7] = 42, ++ [1][0][3][7] = 50, ++ [1][0][5][7] = 78, ++ [1][0][6][7] = 42, ++ [1][0][9][7] = 42, ++ [1][0][8][7] = 60, ++ [1][0][11][7] = 42, ++ [1][0][2][8] = 78, ++ [1][0][1][8] = 42, ++ [1][0][3][8] = 50, ++ [1][0][5][8] = 78, ++ [1][0][6][8] = 42, ++ [1][0][9][8] = 42, ++ [1][0][8][8] = 60, ++ [1][0][11][8] = 42, ++ [1][0][2][9] = 74, ++ [1][0][1][9] = 42, ++ [1][0][3][9] = 50, ++ [1][0][5][9] = 74, ++ [1][0][6][9] = 42, ++ [1][0][9][9] = 42, ++ [1][0][8][9] = 60, ++ [1][0][11][9] = 42, ++ [1][0][2][10] = 74, ++ [1][0][1][10] = 42, ++ [1][0][3][10] = 50, ++ [1][0][5][10] = 74, ++ [1][0][6][10] = 42, ++ [1][0][9][10] = 42, ++ [1][0][8][10] = 60, ++ [1][0][11][10] = 42, ++ [1][0][2][11] = 64, ++ [1][0][1][11] = 42, ++ [1][0][3][11] = 50, ++ [1][0][5][11] = 64, ++ [1][0][6][11] = 42, ++ [1][0][9][11] = 42, ++ [1][0][8][11] = 60, ++ [1][0][11][11] = 42, ++ [1][0][2][12] = 36, ++ [1][0][1][12] = 42, ++ [1][0][3][12] = 50, ++ [1][0][5][12] = 36, ++ [1][0][6][12] = 42, ++ [1][0][9][12] = 42, ++ [1][0][8][12] = 60, ++ [1][0][11][12] = 42, ++ [1][0][2][13] = 127, ++ [1][0][1][13] = 127, ++ [1][0][3][13] = 127, ++ [1][0][5][13] = 127, ++ [1][0][6][13] = 127, ++ [1][0][9][13] = 127, ++ [1][0][8][13] = 127, ++ [1][0][11][13] = 127, ++ [1][1][2][0] = 66, ++ [1][1][1][0] = 30, ++ [1][1][3][0] = 38, ++ [1][1][5][0] = 66, ++ [1][1][6][0] = 30, ++ [1][1][9][0] = 30, ++ [1][1][8][0] = 48, ++ [1][1][11][0] = 30, ++ [1][1][2][1] = 66, ++ [1][1][1][1] = 30, ++ [1][1][3][1] = 38, ++ [1][1][5][1] = 66, ++ [1][1][6][1] = 30, ++ [1][1][9][1] = 30, ++ [1][1][8][1] = 48, ++ [1][1][11][1] = 30, ++ [1][1][2][2] = 70, ++ [1][1][1][2] = 30, ++ [1][1][3][2] = 38, ++ [1][1][5][2] = 70, ++ [1][1][6][2] = 30, ++ [1][1][9][2] = 30, ++ [1][1][8][2] = 48, ++ [1][1][11][2] = 30, ++ [1][1][2][3] = 74, ++ [1][1][1][3] = 30, ++ [1][1][3][3] = 38, ++ [1][1][5][3] = 74, ++ [1][1][6][3] = 30, ++ [1][1][9][3] = 30, ++ [1][1][8][3] = 48, ++ [1][1][11][3] = 30, ++ [1][1][2][4] = 78, ++ [1][1][1][4] = 30, ++ [1][1][3][4] = 38, ++ [1][1][5][4] = 78, ++ [1][1][6][4] = 30, ++ [1][1][9][4] = 30, ++ [1][1][8][4] = 48, ++ [1][1][11][4] = 30, ++ [1][1][2][5] = 78, ++ [1][1][1][5] = 30, ++ [1][1][3][5] = 38, ++ [1][1][5][5] = 78, ++ [1][1][6][5] = 30, ++ [1][1][9][5] = 30, ++ [1][1][8][5] = 48, ++ [1][1][11][5] = 30, ++ [1][1][2][6] = 78, ++ [1][1][1][6] = 30, ++ [1][1][3][6] = 38, ++ [1][1][5][6] = 78, ++ [1][1][6][6] = 30, ++ [1][1][9][6] = 30, ++ [1][1][8][6] = 48, ++ [1][1][11][6] = 30, ++ [1][1][2][7] = 74, ++ [1][1][1][7] = 30, ++ [1][1][3][7] = 38, ++ [1][1][5][7] = 74, ++ [1][1][6][7] = 30, ++ [1][1][9][7] = 30, ++ [1][1][8][7] = 48, ++ [1][1][11][7] = 30, ++ [1][1][2][8] = 70, ++ [1][1][1][8] = 30, ++ [1][1][3][8] = 38, ++ [1][1][5][8] = 70, ++ [1][1][6][8] = 30, ++ [1][1][9][8] = 30, ++ [1][1][8][8] = 48, ++ [1][1][11][8] = 30, ++ [1][1][2][9] = 66, ++ [1][1][1][9] = 30, ++ [1][1][3][9] = 38, ++ [1][1][5][9] = 66, ++ [1][1][6][9] = 30, ++ [1][1][9][9] = 30, ++ [1][1][8][9] = 48, ++ [1][1][11][9] = 30, ++ [1][1][2][10] = 66, ++ [1][1][1][10] = 30, ++ [1][1][3][10] = 38, ++ [1][1][5][10] = 66, ++ [1][1][6][10] = 30, ++ [1][1][9][10] = 30, ++ [1][1][8][10] = 48, ++ [1][1][11][10] = 30, ++ [1][1][2][11] = 60, ++ [1][1][1][11] = 30, ++ [1][1][3][11] = 38, ++ [1][1][5][11] = 60, ++ [1][1][6][11] = 30, ++ [1][1][9][11] = 30, ++ [1][1][8][11] = 48, ++ [1][1][11][11] = 30, ++ [1][1][2][12] = 32, ++ [1][1][1][12] = 30, ++ [1][1][3][12] = 38, ++ [1][1][5][12] = 32, ++ [1][1][6][12] = 30, ++ [1][1][9][12] = 30, ++ [1][1][8][12] = 48, ++ [1][1][11][12] = 30, ++ [1][1][2][13] = 127, ++ [1][1][1][13] = 127, ++ [1][1][3][13] = 127, ++ [1][1][5][13] = 127, ++ [1][1][6][13] = 127, ++ [1][1][9][13] = 127, ++ [1][1][8][13] = 127, ++ [1][1][11][13] = 127, ++ [2][0][2][0] = 76, ++ [2][0][1][0] = 52, ++ [2][0][3][0] = 64, ++ [2][0][5][0] = 76, ++ [2][0][6][0] = 52, ++ [2][0][9][0] = 52, ++ [2][0][8][0] = 60, ++ [2][0][11][0] = 52, ++ [2][0][2][1] = 76, ++ [2][0][1][1] = 52, ++ [2][0][3][1] = 64, ++ [2][0][5][1] = 76, ++ [2][0][6][1] = 52, ++ [2][0][9][1] = 52, ++ [2][0][8][1] = 60, ++ [2][0][11][1] = 52, ++ [2][0][2][2] = 78, ++ [2][0][1][2] = 52, ++ [2][0][3][2] = 64, ++ [2][0][5][2] = 78, ++ [2][0][6][2] = 52, ++ [2][0][9][2] = 52, ++ [2][0][8][2] = 60, ++ [2][0][11][2] = 52, ++ [2][0][2][3] = 78, ++ [2][0][1][3] = 52, ++ [2][0][3][3] = 64, ++ [2][0][5][3] = 78, ++ [2][0][6][3] = 52, ++ [2][0][9][3] = 52, ++ [2][0][8][3] = 60, ++ [2][0][11][3] = 52, ++ [2][0][2][4] = 78, ++ [2][0][1][4] = 52, ++ [2][0][3][4] = 64, ++ [2][0][5][4] = 78, ++ [2][0][6][4] = 52, ++ [2][0][9][4] = 52, ++ [2][0][8][4] = 60, ++ [2][0][11][4] = 52, ++ [2][0][2][5] = 78, ++ [2][0][1][5] = 52, ++ [2][0][3][5] = 64, ++ [2][0][5][5] = 78, ++ [2][0][6][5] = 52, ++ [2][0][9][5] = 52, ++ [2][0][8][5] = 60, ++ [2][0][11][5] = 52, ++ [2][0][2][6] = 78, ++ [2][0][1][6] = 52, ++ [2][0][3][6] = 64, ++ [2][0][5][6] = 78, ++ [2][0][6][6] = 52, ++ [2][0][9][6] = 52, ++ [2][0][8][6] = 60, ++ [2][0][11][6] = 52, ++ [2][0][2][7] = 78, ++ [2][0][1][7] = 52, ++ [2][0][3][7] = 64, ++ [2][0][5][7] = 78, ++ [2][0][6][7] = 52, ++ [2][0][9][7] = 52, ++ [2][0][8][7] = 60, ++ [2][0][11][7] = 52, ++ [2][0][2][8] = 78, ++ [2][0][1][8] = 52, ++ [2][0][3][8] = 64, ++ [2][0][5][8] = 78, ++ [2][0][6][8] = 52, ++ [2][0][9][8] = 52, ++ [2][0][8][8] = 60, ++ [2][0][11][8] = 52, ++ [2][0][2][9] = 76, ++ [2][0][1][9] = 52, ++ [2][0][3][9] = 64, ++ [2][0][5][9] = 76, ++ [2][0][6][9] = 52, ++ [2][0][9][9] = 52, ++ [2][0][8][9] = 60, ++ [2][0][11][9] = 52, ++ [2][0][2][10] = 76, ++ [2][0][1][10] = 52, ++ [2][0][3][10] = 64, ++ [2][0][5][10] = 76, ++ [2][0][6][10] = 52, ++ [2][0][9][10] = 52, ++ [2][0][8][10] = 60, ++ [2][0][11][10] = 52, ++ [2][0][2][11] = 68, ++ [2][0][1][11] = 52, ++ [2][0][3][11] = 64, ++ [2][0][5][11] = 68, ++ [2][0][6][11] = 52, ++ [2][0][9][11] = 52, ++ [2][0][8][11] = 60, ++ [2][0][11][11] = 52, ++ [2][0][2][12] = 40, ++ [2][0][1][12] = 52, ++ [2][0][3][12] = 64, ++ [2][0][5][12] = 40, ++ [2][0][6][12] = 52, ++ [2][0][9][12] = 52, ++ [2][0][8][12] = 60, ++ [2][0][11][12] = 52, ++ [2][0][2][13] = 127, ++ [2][0][1][13] = 127, ++ [2][0][3][13] = 127, ++ [2][0][5][13] = 127, ++ [2][0][6][13] = 127, ++ [2][0][9][13] = 127, ++ [2][0][8][13] = 127, ++ [2][0][11][13] = 127, ++ [2][1][2][0] = 68, ++ [2][1][1][0] = 40, ++ [2][1][3][0] = 52, ++ [2][1][5][0] = 68, ++ [2][1][6][0] = 40, ++ [2][1][9][0] = 40, ++ [2][1][8][0] = 48, ++ [2][1][11][0] = 40, ++ [2][1][2][1] = 68, ++ [2][1][1][1] = 40, ++ [2][1][3][1] = 52, ++ [2][1][5][1] = 68, ++ [2][1][6][1] = 40, ++ [2][1][9][1] = 40, ++ [2][1][8][1] = 48, ++ [2][1][11][1] = 40, ++ [2][1][2][2] = 72, ++ [2][1][1][2] = 40, ++ [2][1][3][2] = 52, ++ [2][1][5][2] = 72, ++ [2][1][6][2] = 40, ++ [2][1][9][2] = 40, ++ [2][1][8][2] = 48, ++ [2][1][11][2] = 40, ++ [2][1][2][3] = 76, ++ [2][1][1][3] = 40, ++ [2][1][3][3] = 52, ++ [2][1][5][3] = 76, ++ [2][1][6][3] = 40, ++ [2][1][9][3] = 40, ++ [2][1][8][3] = 48, ++ [2][1][11][3] = 40, ++ [2][1][2][4] = 78, ++ [2][1][1][4] = 40, ++ [2][1][3][4] = 52, ++ [2][1][5][4] = 78, ++ [2][1][6][4] = 40, ++ [2][1][9][4] = 40, ++ [2][1][8][4] = 48, ++ [2][1][11][4] = 40, ++ [2][1][2][5] = 78, ++ [2][1][1][5] = 40, ++ [2][1][3][5] = 52, ++ [2][1][5][5] = 78, ++ [2][1][6][5] = 40, ++ [2][1][9][5] = 40, ++ [2][1][8][5] = 48, ++ [2][1][11][5] = 40, ++ [2][1][2][6] = 78, ++ [2][1][1][6] = 40, ++ [2][1][3][6] = 52, ++ [2][1][5][6] = 78, ++ [2][1][6][6] = 40, ++ [2][1][9][6] = 40, ++ [2][1][8][6] = 48, ++ [2][1][11][6] = 40, ++ [2][1][2][7] = 78, ++ [2][1][1][7] = 40, ++ [2][1][3][7] = 52, ++ [2][1][5][7] = 78, ++ [2][1][6][7] = 40, ++ [2][1][9][7] = 40, ++ [2][1][8][7] = 48, ++ [2][1][11][7] = 40, ++ [2][1][2][8] = 74, ++ [2][1][1][8] = 40, ++ [2][1][3][8] = 52, ++ [2][1][5][8] = 74, ++ [2][1][6][8] = 40, ++ [2][1][9][8] = 40, ++ [2][1][8][8] = 48, ++ [2][1][11][8] = 40, ++ [2][1][2][9] = 70, ++ [2][1][1][9] = 40, ++ [2][1][3][9] = 52, ++ [2][1][5][9] = 70, ++ [2][1][6][9] = 40, ++ [2][1][9][9] = 40, ++ [2][1][8][9] = 48, ++ [2][1][11][9] = 40, ++ [2][1][2][10] = 70, ++ [2][1][1][10] = 40, ++ [2][1][3][10] = 52, ++ [2][1][5][10] = 70, ++ [2][1][6][10] = 40, ++ [2][1][9][10] = 40, ++ [2][1][8][10] = 48, ++ [2][1][11][10] = 40, ++ [2][1][2][11] = 48, ++ [2][1][1][11] = 40, ++ [2][1][3][11] = 52, ++ [2][1][5][11] = 48, ++ [2][1][6][11] = 40, ++ [2][1][9][11] = 40, ++ [2][1][8][11] = 48, ++ [2][1][11][11] = 40, ++ [2][1][2][12] = 26, ++ [2][1][1][12] = 40, ++ [2][1][3][12] = 52, ++ [2][1][5][12] = 26, ++ [2][1][6][12] = 40, ++ [2][1][9][12] = 40, ++ [2][1][8][12] = 48, ++ [2][1][11][12] = 40, ++ [2][1][2][13] = 127, ++ [2][1][1][13] = 127, ++ [2][1][3][13] = 127, ++ [2][1][5][13] = 127, ++ [2][1][6][13] = 127, ++ [2][1][9][13] = 127, ++ [2][1][8][13] = 127, ++ [2][1][11][13] = 127, ++}; ++ ++const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] ++ [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { ++ [0][0][0][0] = 22, ++ [0][0][0][2] = 22, ++ [0][0][0][4] = 22, ++ [0][0][0][6] = 22, ++ [0][0][0][8] = 24, ++ [0][0][0][10] = 24, ++ [0][0][0][12] = 24, ++ [0][0][0][14] = 24, ++ [0][0][0][15] = 24, ++ [0][0][0][17] = 24, ++ [0][0][0][19] = 24, ++ [0][0][0][21] = 24, ++ [0][0][0][23] = 24, ++ [0][0][0][25] = 24, ++ [0][0][0][27] = 24, ++ [0][0][0][29] = 24, ++ [0][0][0][31] = 24, ++ [0][0][0][33] = 24, ++ [0][0][0][35] = 24, ++ [0][0][0][37] = 24, ++ [0][0][0][38] = 28, ++ [0][0][0][40] = 28, ++ [0][0][0][42] = 28, ++ [0][0][0][44] = 28, ++ [0][0][0][46] = 28, ++ [0][1][0][0] = 8, ++ [0][1][0][2] = 8, ++ [0][1][0][4] = 8, ++ [0][1][0][6] = 8, ++ [0][1][0][8] = 12, ++ [0][1][0][10] = 12, ++ [0][1][0][12] = 12, ++ [0][1][0][14] = 12, ++ [0][1][0][15] = 12, ++ [0][1][0][17] = 12, ++ [0][1][0][19] = 12, ++ [0][1][0][21] = 12, ++ [0][1][0][23] = 12, ++ [0][1][0][25] = 12, ++ [0][1][0][27] = 12, ++ [0][1][0][29] = 12, ++ [0][1][0][31] = 12, ++ [0][1][0][33] = 12, ++ [0][1][0][35] = 12, ++ [0][1][0][37] = 12, ++ [0][1][0][38] = 16, ++ [0][1][0][40] = 16, ++ [0][1][0][42] = 16, ++ [0][1][0][44] = 16, ++ [0][1][0][46] = 16, ++ [1][0][0][0] = 30, ++ [1][0][0][2] = 30, ++ [1][0][0][4] = 30, ++ [1][0][0][6] = 30, ++ [1][0][0][8] = 36, ++ [1][0][0][10] = 36, ++ [1][0][0][12] = 36, ++ [1][0][0][14] = 36, ++ [1][0][0][15] = 36, ++ [1][0][0][17] = 36, ++ [1][0][0][19] = 36, ++ [1][0][0][21] = 36, ++ [1][0][0][23] = 36, ++ [1][0][0][25] = 36, ++ [1][0][0][27] = 36, ++ [1][0][0][29] = 36, ++ [1][0][0][31] = 36, ++ [1][0][0][33] = 36, ++ [1][0][0][35] = 36, ++ [1][0][0][37] = 36, ++ [1][0][0][38] = 28, ++ [1][0][0][40] = 28, ++ [1][0][0][42] = 28, ++ [1][0][0][44] = 28, ++ [1][0][0][46] = 28, ++ [1][1][0][0] = 18, ++ [1][1][0][2] = 18, ++ [1][1][0][4] = 18, ++ [1][1][0][6] = 18, ++ [1][1][0][8] = 22, ++ [1][1][0][10] = 22, ++ [1][1][0][12] = 22, ++ [1][1][0][14] = 22, ++ [1][1][0][15] = 22, ++ [1][1][0][17] = 22, ++ [1][1][0][19] = 22, ++ [1][1][0][21] = 22, ++ [1][1][0][23] = 22, ++ [1][1][0][25] = 22, ++ [1][1][0][27] = 22, ++ [1][1][0][29] = 22, ++ [1][1][0][31] = 22, ++ [1][1][0][33] = 22, ++ [1][1][0][35] = 22, ++ [1][1][0][37] = 22, ++ [1][1][0][38] = 16, ++ [1][1][0][40] = 16, ++ [1][1][0][42] = 16, ++ [1][1][0][44] = 16, ++ [1][1][0][46] = 16, ++ [2][0][0][0] = 30, ++ [2][0][0][2] = 30, ++ [2][0][0][4] = 30, ++ [2][0][0][6] = 30, ++ [2][0][0][8] = 46, ++ [2][0][0][10] = 46, ++ [2][0][0][12] = 46, ++ [2][0][0][14] = 46, ++ [2][0][0][15] = 46, ++ [2][0][0][17] = 46, ++ [2][0][0][19] = 46, ++ [2][0][0][21] = 46, ++ [2][0][0][23] = 46, ++ [2][0][0][25] = 46, ++ [2][0][0][27] = 46, ++ [2][0][0][29] = 46, ++ [2][0][0][31] = 46, ++ [2][0][0][33] = 46, ++ [2][0][0][35] = 46, ++ [2][0][0][37] = 46, ++ [2][0][0][38] = 28, ++ [2][0][0][40] = 28, ++ [2][0][0][42] = 28, ++ [2][0][0][44] = 28, ++ [2][0][0][46] = 28, ++ [2][1][0][0] = 18, ++ [2][1][0][2] = 18, ++ [2][1][0][4] = 18, ++ [2][1][0][6] = 18, ++ [2][1][0][8] = 32, ++ [2][1][0][10] = 32, ++ [2][1][0][12] = 32, ++ [2][1][0][14] = 32, ++ [2][1][0][15] = 32, ++ [2][1][0][17] = 32, ++ [2][1][0][19] = 32, ++ [2][1][0][21] = 32, ++ [2][1][0][23] = 32, ++ [2][1][0][25] = 32, ++ [2][1][0][27] = 32, ++ [2][1][0][29] = 32, ++ [2][1][0][31] = 32, ++ [2][1][0][33] = 32, ++ [2][1][0][35] = 32, ++ [2][1][0][37] = 32, ++ [2][1][0][38] = 16, ++ [2][1][0][40] = 16, ++ [2][1][0][42] = 16, ++ [2][1][0][44] = 16, ++ [2][1][0][46] = 16, ++ [0][0][2][0] = 48, ++ [0][0][1][0] = 24, ++ [0][0][3][0] = 26, ++ [0][0][5][0] = 22, ++ [0][0][6][0] = 24, ++ [0][0][9][0] = 24, ++ [0][0][8][0] = 30, ++ [0][0][11][0] = 24, ++ [0][0][2][2] = 48, ++ [0][0][1][2] = 24, ++ [0][0][3][2] = 26, ++ [0][0][5][2] = 22, ++ [0][0][6][2] = 24, ++ [0][0][9][2] = 24, ++ [0][0][8][2] = 30, ++ [0][0][11][2] = 24, ++ [0][0][2][4] = 48, ++ [0][0][1][4] = 24, ++ [0][0][3][4] = 26, ++ [0][0][5][4] = 22, ++ [0][0][6][4] = 24, ++ [0][0][9][4] = 24, ++ [0][0][8][4] = 30, ++ [0][0][11][4] = 24, ++ [0][0][2][6] = 48, ++ [0][0][1][6] = 24, ++ [0][0][3][6] = 26, ++ [0][0][5][6] = 22, ++ [0][0][6][6] = 24, ++ [0][0][9][6] = 24, ++ [0][0][8][6] = 30, ++ [0][0][11][6] = 24, ++ [0][0][2][8] = 48, ++ [0][0][1][8] = 24, ++ [0][0][3][8] = 26, ++ [0][0][5][8] = 48, ++ [0][0][6][8] = 24, ++ [0][0][9][8] = 24, ++ [0][0][8][8] = 54, ++ [0][0][11][8] = 24, ++ [0][0][2][10] = 48, ++ [0][0][1][10] = 24, ++ [0][0][3][10] = 26, ++ [0][0][5][10] = 48, ++ [0][0][6][10] = 24, ++ [0][0][9][10] = 24, ++ [0][0][8][10] = 54, ++ [0][0][11][10] = 24, ++ [0][0][2][12] = 48, ++ [0][0][1][12] = 24, ++ [0][0][3][12] = 26, ++ [0][0][5][12] = 48, ++ [0][0][6][12] = 24, ++ [0][0][9][12] = 24, ++ [0][0][8][12] = 54, ++ [0][0][11][12] = 24, ++ [0][0][2][14] = 48, ++ [0][0][1][14] = 24, ++ [0][0][3][14] = 26, ++ [0][0][5][14] = 48, ++ [0][0][6][14] = 24, ++ [0][0][9][14] = 24, ++ [0][0][8][14] = 54, ++ [0][0][11][14] = 24, ++ [0][0][2][15] = 48, ++ [0][0][1][15] = 24, ++ [0][0][3][15] = 44, ++ [0][0][5][15] = 48, ++ [0][0][6][15] = 24, ++ [0][0][9][15] = 24, ++ [0][0][8][15] = 54, ++ [0][0][11][15] = 24, ++ [0][0][2][17] = 48, ++ [0][0][1][17] = 24, ++ [0][0][3][17] = 44, ++ [0][0][5][17] = 48, ++ [0][0][6][17] = 24, ++ [0][0][9][17] = 24, ++ [0][0][8][17] = 54, ++ [0][0][11][17] = 24, ++ [0][0][2][19] = 48, ++ [0][0][1][19] = 24, ++ [0][0][3][19] = 44, ++ [0][0][5][19] = 48, ++ [0][0][6][19] = 24, ++ [0][0][9][19] = 24, ++ [0][0][8][19] = 54, ++ [0][0][11][19] = 24, ++ [0][0][2][21] = 48, ++ [0][0][1][21] = 24, ++ [0][0][3][21] = 44, ++ [0][0][5][21] = 48, ++ [0][0][6][21] = 24, ++ [0][0][9][21] = 24, ++ [0][0][8][21] = 54, ++ [0][0][11][21] = 24, ++ [0][0][2][23] = 48, ++ [0][0][1][23] = 24, ++ [0][0][3][23] = 44, ++ [0][0][5][23] = 48, ++ [0][0][6][23] = 24, ++ [0][0][9][23] = 24, ++ [0][0][8][23] = 54, ++ [0][0][11][23] = 24, ++ [0][0][2][25] = 48, ++ [0][0][1][25] = 24, ++ [0][0][3][25] = 44, ++ [0][0][5][25] = 127, ++ [0][0][6][25] = 24, ++ [0][0][9][25] = 127, ++ [0][0][8][25] = 54, ++ [0][0][11][25] = 24, ++ [0][0][2][27] = 48, ++ [0][0][1][27] = 24, ++ [0][0][3][27] = 44, ++ [0][0][5][27] = 127, ++ [0][0][6][27] = 24, ++ [0][0][9][27] = 127, ++ [0][0][8][27] = 54, ++ [0][0][11][27] = 24, ++ [0][0][2][29] = 48, ++ [0][0][1][29] = 24, ++ [0][0][3][29] = 44, ++ [0][0][5][29] = 127, ++ [0][0][6][29] = 24, ++ [0][0][9][29] = 127, ++ [0][0][8][29] = 54, ++ [0][0][11][29] = 24, ++ [0][0][2][31] = 48, ++ [0][0][1][31] = 24, ++ [0][0][3][31] = 44, ++ [0][0][5][31] = 48, ++ [0][0][6][31] = 24, ++ [0][0][9][31] = 24, ++ [0][0][8][31] = 54, ++ [0][0][11][31] = 24, ++ [0][0][2][33] = 48, ++ [0][0][1][33] = 24, ++ [0][0][3][33] = 44, ++ [0][0][5][33] = 48, ++ [0][0][6][33] = 24, ++ [0][0][9][33] = 24, ++ [0][0][8][33] = 54, ++ [0][0][11][33] = 24, ++ [0][0][2][35] = 48, ++ [0][0][1][35] = 24, ++ [0][0][3][35] = 44, ++ [0][0][5][35] = 48, ++ [0][0][6][35] = 24, ++ [0][0][9][35] = 24, ++ [0][0][8][35] = 54, ++ [0][0][11][35] = 24, ++ [0][0][2][37] = 48, ++ [0][0][1][37] = 127, ++ [0][0][3][37] = 44, ++ [0][0][5][37] = 48, ++ [0][0][6][37] = 24, ++ [0][0][9][37] = 48, ++ [0][0][8][37] = 54, ++ [0][0][11][37] = 127, ++ [0][0][2][38] = 76, ++ [0][0][1][38] = 28, ++ [0][0][3][38] = 127, ++ [0][0][5][38] = 76, ++ [0][0][6][38] = 28, ++ [0][0][9][38] = 76, ++ [0][0][8][38] = 54, ++ [0][0][11][38] = 28, ++ [0][0][2][40] = 76, ++ [0][0][1][40] = 28, ++ [0][0][3][40] = 127, ++ [0][0][5][40] = 76, ++ [0][0][6][40] = 28, ++ [0][0][9][40] = 76, ++ [0][0][8][40] = 54, ++ [0][0][11][40] = 28, ++ [0][0][2][42] = 76, ++ [0][0][1][42] = 28, ++ [0][0][3][42] = 127, ++ [0][0][5][42] = 76, ++ [0][0][6][42] = 28, ++ [0][0][9][42] = 76, ++ [0][0][8][42] = 54, ++ [0][0][11][42] = 28, ++ [0][0][2][44] = 76, ++ [0][0][1][44] = 28, ++ [0][0][3][44] = 127, ++ [0][0][5][44] = 76, ++ [0][0][6][44] = 28, ++ [0][0][9][44] = 76, ++ [0][0][8][44] = 54, ++ [0][0][11][44] = 28, ++ [0][0][2][46] = 76, ++ [0][0][1][46] = 28, ++ [0][0][3][46] = 127, ++ [0][0][5][46] = 76, ++ [0][0][6][46] = 28, ++ [0][0][9][46] = 76, ++ [0][0][8][46] = 54, ++ [0][0][11][46] = 28, ++ [0][1][2][0] = 36, ++ [0][1][1][0] = 12, ++ [0][1][3][0] = 14, ++ [0][1][5][0] = 8, ++ [0][1][6][0] = 12, ++ [0][1][9][0] = 12, ++ [0][1][8][0] = 18, ++ [0][1][11][0] = 12, ++ [0][1][2][2] = 36, ++ [0][1][1][2] = 12, ++ [0][1][3][2] = 14, ++ [0][1][5][2] = 8, ++ [0][1][6][2] = 12, ++ [0][1][9][2] = 12, ++ [0][1][8][2] = 18, ++ [0][1][11][2] = 12, ++ [0][1][2][4] = 36, ++ [0][1][1][4] = 12, ++ [0][1][3][4] = 14, ++ [0][1][5][4] = 8, ++ [0][1][6][4] = 12, ++ [0][1][9][4] = 12, ++ [0][1][8][4] = 18, ++ [0][1][11][4] = 12, ++ [0][1][2][6] = 36, ++ [0][1][1][6] = 12, ++ [0][1][3][6] = 14, ++ [0][1][5][6] = 8, ++ [0][1][6][6] = 12, ++ [0][1][9][6] = 12, ++ [0][1][8][6] = 18, ++ [0][1][11][6] = 12, ++ [0][1][2][8] = 36, ++ [0][1][1][8] = 12, ++ [0][1][3][8] = 14, ++ [0][1][5][8] = 36, ++ [0][1][6][8] = 12, ++ [0][1][9][8] = 12, ++ [0][1][8][8] = 42, ++ [0][1][11][8] = 12, ++ [0][1][2][10] = 36, ++ [0][1][1][10] = 12, ++ [0][1][3][10] = 14, ++ [0][1][5][10] = 36, ++ [0][1][6][10] = 12, ++ [0][1][9][10] = 12, ++ [0][1][8][10] = 42, ++ [0][1][11][10] = 12, ++ [0][1][2][12] = 36, ++ [0][1][1][12] = 12, ++ [0][1][3][12] = 14, ++ [0][1][5][12] = 36, ++ [0][1][6][12] = 12, ++ [0][1][9][12] = 12, ++ [0][1][8][12] = 42, ++ [0][1][11][12] = 12, ++ [0][1][2][14] = 36, ++ [0][1][1][14] = 12, ++ [0][1][3][14] = 14, ++ [0][1][5][14] = 36, ++ [0][1][6][14] = 12, ++ [0][1][9][14] = 12, ++ [0][1][8][14] = 42, ++ [0][1][11][14] = 12, ++ [0][1][2][15] = 36, ++ [0][1][1][15] = 12, ++ [0][1][3][15] = 32, ++ [0][1][5][15] = 36, ++ [0][1][6][15] = 12, ++ [0][1][9][15] = 12, ++ [0][1][8][15] = 42, ++ [0][1][11][15] = 12, ++ [0][1][2][17] = 36, ++ [0][1][1][17] = 12, ++ [0][1][3][17] = 32, ++ [0][1][5][17] = 36, ++ [0][1][6][17] = 12, ++ [0][1][9][17] = 12, ++ [0][1][8][17] = 42, ++ [0][1][11][17] = 12, ++ [0][1][2][19] = 36, ++ [0][1][1][19] = 12, ++ [0][1][3][19] = 32, ++ [0][1][5][19] = 36, ++ [0][1][6][19] = 12, ++ [0][1][9][19] = 12, ++ [0][1][8][19] = 42, ++ [0][1][11][19] = 12, ++ [0][1][2][21] = 36, ++ [0][1][1][21] = 12, ++ [0][1][3][21] = 32, ++ [0][1][5][21] = 36, ++ [0][1][6][21] = 12, ++ [0][1][9][21] = 12, ++ [0][1][8][21] = 42, ++ [0][1][11][21] = 12, ++ [0][1][2][23] = 36, ++ [0][1][1][23] = 12, ++ [0][1][3][23] = 32, ++ [0][1][5][23] = 36, ++ [0][1][6][23] = 12, ++ [0][1][9][23] = 12, ++ [0][1][8][23] = 42, ++ [0][1][11][23] = 12, ++ [0][1][2][25] = 36, ++ [0][1][1][25] = 12, ++ [0][1][3][25] = 32, ++ [0][1][5][25] = 127, ++ [0][1][6][25] = 12, ++ [0][1][9][25] = 127, ++ [0][1][8][25] = 42, ++ [0][1][11][25] = 12, ++ [0][1][2][27] = 36, ++ [0][1][1][27] = 12, ++ [0][1][3][27] = 32, ++ [0][1][5][27] = 127, ++ [0][1][6][27] = 12, ++ [0][1][9][27] = 127, ++ [0][1][8][27] = 42, ++ [0][1][11][27] = 12, ++ [0][1][2][29] = 36, ++ [0][1][1][29] = 12, ++ [0][1][3][29] = 32, ++ [0][1][5][29] = 127, ++ [0][1][6][29] = 12, ++ [0][1][9][29] = 127, ++ [0][1][8][29] = 42, ++ [0][1][11][29] = 12, ++ [0][1][2][31] = 36, ++ [0][1][1][31] = 12, ++ [0][1][3][31] = 32, ++ [0][1][5][31] = 36, ++ [0][1][6][31] = 12, ++ [0][1][9][31] = 12, ++ [0][1][8][31] = 42, ++ [0][1][11][31] = 12, ++ [0][1][2][33] = 36, ++ [0][1][1][33] = 12, ++ [0][1][3][33] = 32, ++ [0][1][5][33] = 36, ++ [0][1][6][33] = 12, ++ [0][1][9][33] = 12, ++ [0][1][8][33] = 42, ++ [0][1][11][33] = 12, ++ [0][1][2][35] = 36, ++ [0][1][1][35] = 12, ++ [0][1][3][35] = 32, ++ [0][1][5][35] = 36, ++ [0][1][6][35] = 12, ++ [0][1][9][35] = 12, ++ [0][1][8][35] = 42, ++ [0][1][11][35] = 12, ++ [0][1][2][37] = 36, ++ [0][1][1][37] = 127, ++ [0][1][3][37] = 32, ++ [0][1][5][37] = 36, ++ [0][1][6][37] = 12, ++ [0][1][9][37] = 36, ++ [0][1][8][37] = 42, ++ [0][1][11][37] = 127, ++ [0][1][2][38] = 72, ++ [0][1][1][38] = 16, ++ [0][1][3][38] = 127, ++ [0][1][5][38] = 72, ++ [0][1][6][38] = 16, ++ [0][1][9][38] = 76, ++ [0][1][8][38] = 42, ++ [0][1][11][38] = 16, ++ [0][1][2][40] = 76, ++ [0][1][1][40] = 16, ++ [0][1][3][40] = 127, ++ [0][1][5][40] = 76, ++ [0][1][6][40] = 16, ++ [0][1][9][40] = 76, ++ [0][1][8][40] = 42, ++ [0][1][11][40] = 16, ++ [0][1][2][42] = 76, ++ [0][1][1][42] = 16, ++ [0][1][3][42] = 127, ++ [0][1][5][42] = 76, ++ [0][1][6][42] = 16, ++ [0][1][9][42] = 76, ++ [0][1][8][42] = 42, ++ [0][1][11][42] = 16, ++ [0][1][2][44] = 76, ++ [0][1][1][44] = 16, ++ [0][1][3][44] = 127, ++ [0][1][5][44] = 76, ++ [0][1][6][44] = 16, ++ [0][1][9][44] = 76, ++ [0][1][8][44] = 42, ++ [0][1][11][44] = 16, ++ [0][1][2][46] = 76, ++ [0][1][1][46] = 16, ++ [0][1][3][46] = 127, ++ [0][1][5][46] = 76, ++ [0][1][6][46] = 16, ++ [0][1][9][46] = 76, ++ [0][1][8][46] = 42, ++ [0][1][11][46] = 16, ++ [1][0][2][0] = 62, ++ [1][0][1][0] = 36, ++ [1][0][3][0] = 36, ++ [1][0][5][0] = 34, ++ [1][0][6][0] = 36, ++ [1][0][9][0] = 36, ++ [1][0][8][0] = 30, ++ [1][0][11][0] = 36, ++ [1][0][2][2] = 62, ++ [1][0][1][2] = 36, ++ [1][0][3][2] = 36, ++ [1][0][5][2] = 34, ++ [1][0][6][2] = 36, ++ [1][0][9][2] = 36, ++ [1][0][8][2] = 30, ++ [1][0][11][2] = 36, ++ [1][0][2][4] = 62, ++ [1][0][1][4] = 36, ++ [1][0][3][4] = 36, ++ [1][0][5][4] = 34, ++ [1][0][6][4] = 36, ++ [1][0][9][4] = 36, ++ [1][0][8][4] = 30, ++ [1][0][11][4] = 36, ++ [1][0][2][6] = 62, ++ [1][0][1][6] = 36, ++ [1][0][3][6] = 36, ++ [1][0][5][6] = 34, ++ [1][0][6][6] = 36, ++ [1][0][9][6] = 36, ++ [1][0][8][6] = 30, ++ [1][0][11][6] = 36, ++ [1][0][2][8] = 62, ++ [1][0][1][8] = 36, ++ [1][0][3][8] = 36, ++ [1][0][5][8] = 62, ++ [1][0][6][8] = 36, ++ [1][0][9][8] = 36, ++ [1][0][8][8] = 54, ++ [1][0][11][8] = 36, ++ [1][0][2][10] = 62, ++ [1][0][1][10] = 36, ++ [1][0][3][10] = 36, ++ [1][0][5][10] = 62, ++ [1][0][6][10] = 36, ++ [1][0][9][10] = 36, ++ [1][0][8][10] = 54, ++ [1][0][11][10] = 36, ++ [1][0][2][12] = 62, ++ [1][0][1][12] = 36, ++ [1][0][3][12] = 36, ++ [1][0][5][12] = 62, ++ [1][0][6][12] = 36, ++ [1][0][9][12] = 36, ++ [1][0][8][12] = 54, ++ [1][0][11][12] = 36, ++ [1][0][2][14] = 62, ++ [1][0][1][14] = 36, ++ [1][0][3][14] = 36, ++ [1][0][5][14] = 62, ++ [1][0][6][14] = 36, ++ [1][0][9][14] = 36, ++ [1][0][8][14] = 54, ++ [1][0][11][14] = 36, ++ [1][0][2][15] = 62, ++ [1][0][1][15] = 36, ++ [1][0][3][15] = 58, ++ [1][0][5][15] = 62, ++ [1][0][6][15] = 36, ++ [1][0][9][15] = 36, ++ [1][0][8][15] = 54, ++ [1][0][11][15] = 36, ++ [1][0][2][17] = 62, ++ [1][0][1][17] = 36, ++ [1][0][3][17] = 58, ++ [1][0][5][17] = 62, ++ [1][0][6][17] = 36, ++ [1][0][9][17] = 36, ++ [1][0][8][17] = 54, ++ [1][0][11][17] = 36, ++ [1][0][2][19] = 62, ++ [1][0][1][19] = 36, ++ [1][0][3][19] = 58, ++ [1][0][5][19] = 62, ++ [1][0][6][19] = 36, ++ [1][0][9][19] = 36, ++ [1][0][8][19] = 54, ++ [1][0][11][19] = 36, ++ [1][0][2][21] = 62, ++ [1][0][1][21] = 36, ++ [1][0][3][21] = 58, ++ [1][0][5][21] = 62, ++ [1][0][6][21] = 36, ++ [1][0][9][21] = 36, ++ [1][0][8][21] = 54, ++ [1][0][11][21] = 36, ++ [1][0][2][23] = 62, ++ [1][0][1][23] = 36, ++ [1][0][3][23] = 58, ++ [1][0][5][23] = 62, ++ [1][0][6][23] = 36, ++ [1][0][9][23] = 36, ++ [1][0][8][23] = 54, ++ [1][0][11][23] = 36, ++ [1][0][2][25] = 62, ++ [1][0][1][25] = 36, ++ [1][0][3][25] = 58, ++ [1][0][5][25] = 127, ++ [1][0][6][25] = 36, ++ [1][0][9][25] = 127, ++ [1][0][8][25] = 54, ++ [1][0][11][25] = 36, ++ [1][0][2][27] = 62, ++ [1][0][1][27] = 36, ++ [1][0][3][27] = 58, ++ [1][0][5][27] = 127, ++ [1][0][6][27] = 36, ++ [1][0][9][27] = 127, ++ [1][0][8][27] = 54, ++ [1][0][11][27] = 36, ++ [1][0][2][29] = 62, ++ [1][0][1][29] = 36, ++ [1][0][3][29] = 58, ++ [1][0][5][29] = 127, ++ [1][0][6][29] = 36, ++ [1][0][9][29] = 127, ++ [1][0][8][29] = 54, ++ [1][0][11][29] = 36, ++ [1][0][2][31] = 62, ++ [1][0][1][31] = 36, ++ [1][0][3][31] = 58, ++ [1][0][5][31] = 62, ++ [1][0][6][31] = 36, ++ [1][0][9][31] = 36, ++ [1][0][8][31] = 54, ++ [1][0][11][31] = 36, ++ [1][0][2][33] = 62, ++ [1][0][1][33] = 36, ++ [1][0][3][33] = 58, ++ [1][0][5][33] = 62, ++ [1][0][6][33] = 36, ++ [1][0][9][33] = 36, ++ [1][0][8][33] = 54, ++ [1][0][11][33] = 36, ++ [1][0][2][35] = 62, ++ [1][0][1][35] = 36, ++ [1][0][3][35] = 58, ++ [1][0][5][35] = 62, ++ [1][0][6][35] = 36, ++ [1][0][9][35] = 36, ++ [1][0][8][35] = 54, ++ [1][0][11][35] = 36, ++ [1][0][2][37] = 56, ++ [1][0][1][37] = 62, ++ [1][0][3][37] = 127, ++ [1][0][5][37] = 58, ++ [1][0][6][37] = 62, ++ [1][0][9][37] = 36, ++ [1][0][8][37] = 62, ++ [1][0][11][37] = 54, ++ [1][0][2][38] = 76, ++ [1][0][1][38] = 28, ++ [1][0][3][38] = 127, ++ [1][0][5][38] = 76, ++ [1][0][6][38] = 28, ++ [1][0][9][38] = 76, ++ [1][0][8][38] = 54, ++ [1][0][11][38] = 28, ++ [1][0][2][40] = 76, ++ [1][0][1][40] = 28, ++ [1][0][3][40] = 127, ++ [1][0][5][40] = 76, ++ [1][0][6][40] = 28, ++ [1][0][9][40] = 76, ++ [1][0][8][40] = 54, ++ [1][0][11][40] = 28, ++ [1][0][2][42] = 76, ++ [1][0][1][42] = 28, ++ [1][0][3][42] = 127, ++ [1][0][5][42] = 76, ++ [1][0][6][42] = 28, ++ [1][0][9][42] = 76, ++ [1][0][8][42] = 54, ++ [1][0][11][42] = 28, ++ [1][0][2][44] = 76, ++ [1][0][1][44] = 28, ++ [1][0][3][44] = 127, ++ [1][0][5][44] = 76, ++ [1][0][6][44] = 28, ++ [1][0][9][44] = 76, ++ [1][0][8][44] = 54, ++ [1][0][11][44] = 28, ++ [1][0][2][46] = 76, ++ [1][0][1][46] = 28, ++ [1][0][3][46] = 127, ++ [1][0][5][46] = 76, ++ [1][0][6][46] = 28, ++ [1][0][9][46] = 76, ++ [1][0][8][46] = 54, ++ [1][0][11][46] = 28, ++ [1][1][2][0] = 46, ++ [1][1][1][0] = 22, ++ [1][1][3][0] = 24, ++ [1][1][5][0] = 18, ++ [1][1][6][0] = 22, ++ [1][1][9][0] = 22, ++ [1][1][8][0] = 18, ++ [1][1][11][0] = 22, ++ [1][1][2][2] = 46, ++ [1][1][1][2] = 22, ++ [1][1][3][2] = 24, ++ [1][1][5][2] = 18, ++ [1][1][6][2] = 22, ++ [1][1][9][2] = 22, ++ [1][1][8][2] = 18, ++ [1][1][11][2] = 22, ++ [1][1][2][4] = 46, ++ [1][1][1][4] = 22, ++ [1][1][3][4] = 24, ++ [1][1][5][4] = 18, ++ [1][1][6][4] = 22, ++ [1][1][9][4] = 22, ++ [1][1][8][4] = 18, ++ [1][1][11][4] = 22, ++ [1][1][2][6] = 46, ++ [1][1][1][6] = 22, ++ [1][1][3][6] = 24, ++ [1][1][5][6] = 18, ++ [1][1][6][6] = 22, ++ [1][1][9][6] = 22, ++ [1][1][8][6] = 18, ++ [1][1][11][6] = 22, ++ [1][1][2][8] = 46, ++ [1][1][1][8] = 22, ++ [1][1][3][8] = 24, ++ [1][1][5][8] = 46, ++ [1][1][6][8] = 22, ++ [1][1][9][8] = 22, ++ [1][1][8][8] = 42, ++ [1][1][11][8] = 22, ++ [1][1][2][10] = 46, ++ [1][1][1][10] = 22, ++ [1][1][3][10] = 24, ++ [1][1][5][10] = 46, ++ [1][1][6][10] = 22, ++ [1][1][9][10] = 22, ++ [1][1][8][10] = 42, ++ [1][1][11][10] = 22, ++ [1][1][2][12] = 46, ++ [1][1][1][12] = 22, ++ [1][1][3][12] = 24, ++ [1][1][5][12] = 46, ++ [1][1][6][12] = 22, ++ [1][1][9][12] = 22, ++ [1][1][8][12] = 42, ++ [1][1][11][12] = 22, ++ [1][1][2][14] = 46, ++ [1][1][1][14] = 22, ++ [1][1][3][14] = 24, ++ [1][1][5][14] = 46, ++ [1][1][6][14] = 22, ++ [1][1][9][14] = 22, ++ [1][1][8][14] = 42, ++ [1][1][11][14] = 22, ++ [1][1][2][15] = 46, ++ [1][1][1][15] = 22, ++ [1][1][3][15] = 46, ++ [1][1][5][15] = 46, ++ [1][1][6][15] = 22, ++ [1][1][9][15] = 22, ++ [1][1][8][15] = 42, ++ [1][1][11][15] = 22, ++ [1][1][2][17] = 46, ++ [1][1][1][17] = 22, ++ [1][1][3][17] = 46, ++ [1][1][5][17] = 46, ++ [1][1][6][17] = 22, ++ [1][1][9][17] = 22, ++ [1][1][8][17] = 42, ++ [1][1][11][17] = 22, ++ [1][1][2][19] = 46, ++ [1][1][1][19] = 22, ++ [1][1][3][19] = 46, ++ [1][1][5][19] = 46, ++ [1][1][6][19] = 22, ++ [1][1][9][19] = 22, ++ [1][1][8][19] = 42, ++ [1][1][11][19] = 22, ++ [1][1][2][21] = 46, ++ [1][1][1][21] = 22, ++ [1][1][3][21] = 46, ++ [1][1][5][21] = 46, ++ [1][1][6][21] = 22, ++ [1][1][9][21] = 22, ++ [1][1][8][21] = 42, ++ [1][1][11][21] = 22, ++ [1][1][2][23] = 46, ++ [1][1][1][23] = 22, ++ [1][1][3][23] = 46, ++ [1][1][5][23] = 46, ++ [1][1][6][23] = 22, ++ [1][1][9][23] = 22, ++ [1][1][8][23] = 42, ++ [1][1][11][23] = 22, ++ [1][1][2][25] = 46, ++ [1][1][1][25] = 22, ++ [1][1][3][25] = 46, ++ [1][1][5][25] = 127, ++ [1][1][6][25] = 22, ++ [1][1][9][25] = 127, ++ [1][1][8][25] = 42, ++ [1][1][11][25] = 22, ++ [1][1][2][27] = 46, ++ [1][1][1][27] = 22, ++ [1][1][3][27] = 46, ++ [1][1][5][27] = 127, ++ [1][1][6][27] = 22, ++ [1][1][9][27] = 127, ++ [1][1][8][27] = 42, ++ [1][1][11][27] = 22, ++ [1][1][2][29] = 46, ++ [1][1][1][29] = 22, ++ [1][1][3][29] = 46, ++ [1][1][5][29] = 127, ++ [1][1][6][29] = 22, ++ [1][1][9][29] = 127, ++ [1][1][8][29] = 42, ++ [1][1][11][29] = 22, ++ [1][1][2][31] = 46, ++ [1][1][1][31] = 22, ++ [1][1][3][31] = 46, ++ [1][1][5][31] = 46, ++ [1][1][6][31] = 22, ++ [1][1][9][31] = 22, ++ [1][1][8][31] = 42, ++ [1][1][11][31] = 22, ++ [1][1][2][33] = 46, ++ [1][1][1][33] = 22, ++ [1][1][3][33] = 46, ++ [1][1][5][33] = 46, ++ [1][1][6][33] = 22, ++ [1][1][9][33] = 22, ++ [1][1][8][33] = 42, ++ [1][1][11][33] = 22, ++ [1][1][2][35] = 46, ++ [1][1][1][35] = 22, ++ [1][1][3][35] = 46, ++ [1][1][5][35] = 46, ++ [1][1][6][35] = 22, ++ [1][1][9][35] = 22, ++ [1][1][8][35] = 42, ++ [1][1][11][35] = 22, ++ [1][1][2][37] = 46, ++ [1][1][1][37] = 127, ++ [1][1][3][37] = 46, ++ [1][1][5][37] = 46, ++ [1][1][6][37] = 22, ++ [1][1][9][37] = 50, ++ [1][1][8][37] = 42, ++ [1][1][11][37] = 127, ++ [1][1][2][38] = 74, ++ [1][1][1][38] = 16, ++ [1][1][3][38] = 127, ++ [1][1][5][38] = 74, ++ [1][1][6][38] = 16, ++ [1][1][9][38] = 76, ++ [1][1][8][38] = 42, ++ [1][1][11][38] = 16, ++ [1][1][2][40] = 76, ++ [1][1][1][40] = 16, ++ [1][1][3][40] = 127, ++ [1][1][5][40] = 76, ++ [1][1][6][40] = 16, ++ [1][1][9][40] = 76, ++ [1][1][8][40] = 42, ++ [1][1][11][40] = 16, ++ [1][1][2][42] = 76, ++ [1][1][1][42] = 16, ++ [1][1][3][42] = 127, ++ [1][1][5][42] = 76, ++ [1][1][6][42] = 16, ++ [1][1][9][42] = 76, ++ [1][1][8][42] = 42, ++ [1][1][11][42] = 16, ++ [1][1][2][44] = 76, ++ [1][1][1][44] = 16, ++ [1][1][3][44] = 127, ++ [1][1][5][44] = 76, ++ [1][1][6][44] = 16, ++ [1][1][9][44] = 76, ++ [1][1][8][44] = 42, ++ [1][1][11][44] = 16, ++ [1][1][2][46] = 76, ++ [1][1][1][46] = 16, ++ [1][1][3][46] = 127, ++ [1][1][5][46] = 76, ++ [1][1][6][46] = 16, ++ [1][1][9][46] = 76, ++ [1][1][8][46] = 42, ++ [1][1][11][46] = 16, ++ [2][0][2][0] = 74, ++ [2][0][1][0] = 46, ++ [2][0][3][0] = 50, ++ [2][0][5][0] = 46, ++ [2][0][6][0] = 46, ++ [2][0][9][0] = 46, ++ [2][0][8][0] = 30, ++ [2][0][11][0] = 46, ++ [2][0][2][2] = 74, ++ [2][0][1][2] = 46, ++ [2][0][3][2] = 50, ++ [2][0][5][2] = 46, ++ [2][0][6][2] = 46, ++ [2][0][9][2] = 46, ++ [2][0][8][2] = 30, ++ [2][0][11][2] = 46, ++ [2][0][2][4] = 74, ++ [2][0][1][4] = 46, ++ [2][0][3][4] = 50, ++ [2][0][5][4] = 46, ++ [2][0][6][4] = 46, ++ [2][0][9][4] = 46, ++ [2][0][8][4] = 30, ++ [2][0][11][4] = 46, ++ [2][0][2][6] = 74, ++ [2][0][1][6] = 46, ++ [2][0][3][6] = 50, ++ [2][0][5][6] = 46, ++ [2][0][6][6] = 46, ++ [2][0][9][6] = 46, ++ [2][0][8][6] = 30, ++ [2][0][11][6] = 46, ++ [2][0][2][8] = 74, ++ [2][0][1][8] = 46, ++ [2][0][3][8] = 50, ++ [2][0][5][8] = 66, ++ [2][0][6][8] = 46, ++ [2][0][9][8] = 46, ++ [2][0][8][8] = 54, ++ [2][0][11][8] = 46, ++ [2][0][2][10] = 74, ++ [2][0][1][10] = 46, ++ [2][0][3][10] = 50, ++ [2][0][5][10] = 66, ++ [2][0][6][10] = 46, ++ [2][0][9][10] = 46, ++ [2][0][8][10] = 54, ++ [2][0][11][10] = 46, ++ [2][0][2][12] = 74, ++ [2][0][1][12] = 46, ++ [2][0][3][12] = 50, ++ [2][0][5][12] = 66, ++ [2][0][6][12] = 46, ++ [2][0][9][12] = 46, ++ [2][0][8][12] = 54, ++ [2][0][11][12] = 46, ++ [2][0][2][14] = 74, ++ [2][0][1][14] = 46, ++ [2][0][3][14] = 50, ++ [2][0][5][14] = 66, ++ [2][0][6][14] = 46, ++ [2][0][9][14] = 46, ++ [2][0][8][14] = 54, ++ [2][0][11][14] = 46, ++ [2][0][2][15] = 74, ++ [2][0][1][15] = 46, ++ [2][0][3][15] = 70, ++ [2][0][5][15] = 74, ++ [2][0][6][15] = 46, ++ [2][0][9][15] = 46, ++ [2][0][8][15] = 54, ++ [2][0][11][15] = 46, ++ [2][0][2][17] = 74, ++ [2][0][1][17] = 46, ++ [2][0][3][17] = 70, ++ [2][0][5][17] = 74, ++ [2][0][6][17] = 46, ++ [2][0][9][17] = 46, ++ [2][0][8][17] = 54, ++ [2][0][11][17] = 46, ++ [2][0][2][19] = 74, ++ [2][0][1][19] = 46, ++ [2][0][3][19] = 70, ++ [2][0][5][19] = 74, ++ [2][0][6][19] = 46, ++ [2][0][9][19] = 46, ++ [2][0][8][19] = 54, ++ [2][0][11][19] = 46, ++ [2][0][2][21] = 74, ++ [2][0][1][21] = 46, ++ [2][0][3][21] = 70, ++ [2][0][5][21] = 74, ++ [2][0][6][21] = 46, ++ [2][0][9][21] = 46, ++ [2][0][8][21] = 54, ++ [2][0][11][21] = 46, ++ [2][0][2][23] = 74, ++ [2][0][1][23] = 46, ++ [2][0][3][23] = 70, ++ [2][0][5][23] = 74, ++ [2][0][6][23] = 46, ++ [2][0][9][23] = 46, ++ [2][0][8][23] = 54, ++ [2][0][11][23] = 46, ++ [2][0][2][25] = 74, ++ [2][0][1][25] = 46, ++ [2][0][3][25] = 70, ++ [2][0][5][25] = 127, ++ [2][0][6][25] = 46, ++ [2][0][9][25] = 127, ++ [2][0][8][25] = 54, ++ [2][0][11][25] = 46, ++ [2][0][2][27] = 74, ++ [2][0][1][27] = 46, ++ [2][0][3][27] = 70, ++ [2][0][5][27] = 127, ++ [2][0][6][27] = 46, ++ [2][0][9][27] = 127, ++ [2][0][8][27] = 54, ++ [2][0][11][27] = 46, ++ [2][0][2][29] = 74, ++ [2][0][1][29] = 46, ++ [2][0][3][29] = 70, ++ [2][0][5][29] = 127, ++ [2][0][6][29] = 46, ++ [2][0][9][29] = 127, ++ [2][0][8][29] = 54, ++ [2][0][11][29] = 46, ++ [2][0][2][31] = 74, ++ [2][0][1][31] = 46, ++ [2][0][3][31] = 70, ++ [2][0][5][31] = 74, ++ [2][0][6][31] = 46, ++ [2][0][9][31] = 46, ++ [2][0][8][31] = 54, ++ [2][0][11][31] = 46, ++ [2][0][2][33] = 74, ++ [2][0][1][33] = 46, ++ [2][0][3][33] = 70, ++ [2][0][5][33] = 74, ++ [2][0][6][33] = 46, ++ [2][0][9][33] = 46, ++ [2][0][8][33] = 54, ++ [2][0][11][33] = 46, ++ [2][0][2][35] = 74, ++ [2][0][1][35] = 46, ++ [2][0][3][35] = 70, ++ [2][0][5][35] = 74, ++ [2][0][6][35] = 46, ++ [2][0][9][35] = 46, ++ [2][0][8][35] = 54, ++ [2][0][11][35] = 46, ++ [2][0][2][37] = 74, ++ [2][0][1][37] = 127, ++ [2][0][3][37] = 70, ++ [2][0][5][37] = 74, ++ [2][0][6][37] = 46, ++ [2][0][9][37] = 74, ++ [2][0][8][37] = 54, ++ [2][0][11][37] = 127, ++ [2][0][2][38] = 76, ++ [2][0][1][38] = 28, ++ [2][0][3][38] = 127, ++ [2][0][5][38] = 76, ++ [2][0][6][38] = 28, ++ [2][0][9][38] = 76, ++ [2][0][8][38] = 54, ++ [2][0][11][38] = 28, ++ [2][0][2][40] = 76, ++ [2][0][1][40] = 28, ++ [2][0][3][40] = 127, ++ [2][0][5][40] = 76, ++ [2][0][6][40] = 28, ++ [2][0][9][40] = 76, ++ [2][0][8][40] = 54, ++ [2][0][11][40] = 28, ++ [2][0][2][42] = 76, ++ [2][0][1][42] = 28, ++ [2][0][3][42] = 127, ++ [2][0][5][42] = 76, ++ [2][0][6][42] = 28, ++ [2][0][9][42] = 76, ++ [2][0][8][42] = 54, ++ [2][0][11][42] = 28, ++ [2][0][2][44] = 76, ++ [2][0][1][44] = 28, ++ [2][0][3][44] = 127, ++ [2][0][5][44] = 76, ++ [2][0][6][44] = 28, ++ [2][0][9][44] = 76, ++ [2][0][8][44] = 54, ++ [2][0][11][44] = 28, ++ [2][0][2][46] = 76, ++ [2][0][1][46] = 28, ++ [2][0][3][46] = 127, ++ [2][0][5][46] = 76, ++ [2][0][6][46] = 28, ++ [2][0][9][46] = 76, ++ [2][0][8][46] = 54, ++ [2][0][11][46] = 28, ++ [2][1][2][0] = 58, ++ [2][1][1][0] = 32, ++ [2][1][3][0] = 38, ++ [2][1][5][0] = 30, ++ [2][1][6][0] = 32, ++ [2][1][9][0] = 32, ++ [2][1][8][0] = 18, ++ [2][1][11][0] = 32, ++ [2][1][2][2] = 58, ++ [2][1][1][2] = 32, ++ [2][1][3][2] = 38, ++ [2][1][5][2] = 30, ++ [2][1][6][2] = 32, ++ [2][1][9][2] = 32, ++ [2][1][8][2] = 18, ++ [2][1][11][2] = 32, ++ [2][1][2][4] = 58, ++ [2][1][1][4] = 32, ++ [2][1][3][4] = 38, ++ [2][1][5][4] = 30, ++ [2][1][6][4] = 32, ++ [2][1][9][4] = 32, ++ [2][1][8][4] = 18, ++ [2][1][11][4] = 32, ++ [2][1][2][6] = 58, ++ [2][1][1][6] = 32, ++ [2][1][3][6] = 38, ++ [2][1][5][6] = 30, ++ [2][1][6][6] = 32, ++ [2][1][9][6] = 32, ++ [2][1][8][6] = 18, ++ [2][1][11][6] = 32, ++ [2][1][2][8] = 58, ++ [2][1][1][8] = 32, ++ [2][1][3][8] = 38, ++ [2][1][5][8] = 52, ++ [2][1][6][8] = 32, ++ [2][1][9][8] = 32, ++ [2][1][8][8] = 42, ++ [2][1][11][8] = 32, ++ [2][1][2][10] = 58, ++ [2][1][1][10] = 32, ++ [2][1][3][10] = 38, ++ [2][1][5][10] = 52, ++ [2][1][6][10] = 32, ++ [2][1][9][10] = 32, ++ [2][1][8][10] = 42, ++ [2][1][11][10] = 32, ++ [2][1][2][12] = 58, ++ [2][1][1][12] = 32, ++ [2][1][3][12] = 38, ++ [2][1][5][12] = 52, ++ [2][1][6][12] = 32, ++ [2][1][9][12] = 32, ++ [2][1][8][12] = 42, ++ [2][1][11][12] = 32, ++ [2][1][2][14] = 58, ++ [2][1][1][14] = 32, ++ [2][1][3][14] = 38, ++ [2][1][5][14] = 52, ++ [2][1][6][14] = 32, ++ [2][1][9][14] = 32, ++ [2][1][8][14] = 42, ++ [2][1][11][14] = 32, ++ [2][1][2][15] = 58, ++ [2][1][1][15] = 32, ++ [2][1][3][15] = 58, ++ [2][1][5][15] = 58, ++ [2][1][6][15] = 32, ++ [2][1][9][15] = 32, ++ [2][1][8][15] = 42, ++ [2][1][11][15] = 32, ++ [2][1][2][17] = 58, ++ [2][1][1][17] = 32, ++ [2][1][3][17] = 58, ++ [2][1][5][17] = 58, ++ [2][1][6][17] = 32, ++ [2][1][9][17] = 32, ++ [2][1][8][17] = 42, ++ [2][1][11][17] = 32, ++ [2][1][2][19] = 58, ++ [2][1][1][19] = 32, ++ [2][1][3][19] = 58, ++ [2][1][5][19] = 58, ++ [2][1][6][19] = 32, ++ [2][1][9][19] = 32, ++ [2][1][8][19] = 42, ++ [2][1][11][19] = 32, ++ [2][1][2][21] = 58, ++ [2][1][1][21] = 32, ++ [2][1][3][21] = 58, ++ [2][1][5][21] = 58, ++ [2][1][6][21] = 32, ++ [2][1][9][21] = 32, ++ [2][1][8][21] = 42, ++ [2][1][11][21] = 32, ++ [2][1][2][23] = 58, ++ [2][1][1][23] = 32, ++ [2][1][3][23] = 58, ++ [2][1][5][23] = 58, ++ [2][1][6][23] = 32, ++ [2][1][9][23] = 32, ++ [2][1][8][23] = 42, ++ [2][1][11][23] = 32, ++ [2][1][2][25] = 58, ++ [2][1][1][25] = 32, ++ [2][1][3][25] = 58, ++ [2][1][5][25] = 127, ++ [2][1][6][25] = 32, ++ [2][1][9][25] = 127, ++ [2][1][8][25] = 42, ++ [2][1][11][25] = 32, ++ [2][1][2][27] = 58, ++ [2][1][1][27] = 32, ++ [2][1][3][27] = 58, ++ [2][1][5][27] = 127, ++ [2][1][6][27] = 32, ++ [2][1][9][27] = 127, ++ [2][1][8][27] = 42, ++ [2][1][11][27] = 32, ++ [2][1][2][29] = 58, ++ [2][1][1][29] = 32, ++ [2][1][3][29] = 58, ++ [2][1][5][29] = 127, ++ [2][1][6][29] = 32, ++ [2][1][9][29] = 127, ++ [2][1][8][29] = 42, ++ [2][1][11][29] = 32, ++ [2][1][2][31] = 58, ++ [2][1][1][31] = 32, ++ [2][1][3][31] = 58, ++ [2][1][5][31] = 58, ++ [2][1][6][31] = 32, ++ [2][1][9][31] = 32, ++ [2][1][8][31] = 42, ++ [2][1][11][31] = 32, ++ [2][1][2][33] = 58, ++ [2][1][1][33] = 32, ++ [2][1][3][33] = 58, ++ [2][1][5][33] = 58, ++ [2][1][6][33] = 32, ++ [2][1][9][33] = 32, ++ [2][1][8][33] = 42, ++ [2][1][11][33] = 32, ++ [2][1][2][35] = 58, ++ [2][1][1][35] = 32, ++ [2][1][3][35] = 58, ++ [2][1][5][35] = 58, ++ [2][1][6][35] = 32, ++ [2][1][9][35] = 32, ++ [2][1][8][35] = 42, ++ [2][1][11][35] = 32, ++ [2][1][2][37] = 58, ++ [2][1][1][37] = 127, ++ [2][1][3][37] = 58, ++ [2][1][5][37] = 58, ++ [2][1][6][37] = 32, ++ [2][1][9][37] = 62, ++ [2][1][8][37] = 42, ++ [2][1][11][37] = 127, ++ [2][1][2][38] = 76, ++ [2][1][1][38] = 16, ++ [2][1][3][38] = 127, ++ [2][1][5][38] = 76, ++ [2][1][6][38] = 16, ++ [2][1][9][38] = 76, ++ [2][1][8][38] = 42, ++ [2][1][11][38] = 16, ++ [2][1][2][40] = 76, ++ [2][1][1][40] = 16, ++ [2][1][3][40] = 127, ++ [2][1][5][40] = 76, ++ [2][1][6][40] = 16, ++ [2][1][9][40] = 76, ++ [2][1][8][40] = 42, ++ [2][1][11][40] = 16, ++ [2][1][2][42] = 76, ++ [2][1][1][42] = 16, ++ [2][1][3][42] = 127, ++ [2][1][5][42] = 76, ++ [2][1][6][42] = 16, ++ [2][1][9][42] = 76, ++ [2][1][8][42] = 42, ++ [2][1][11][42] = 16, ++ [2][1][2][44] = 76, ++ [2][1][1][44] = 16, ++ [2][1][3][44] = 127, ++ [2][1][5][44] = 76, ++ [2][1][6][44] = 16, ++ [2][1][9][44] = 76, ++ [2][1][8][44] = 42, ++ [2][1][11][44] = 16, ++ [2][1][2][46] = 76, ++ [2][1][1][46] = 16, ++ [2][1][3][46] = 127, ++ [2][1][5][46] = 76, ++ [2][1][6][46] = 16, ++ [2][1][9][46] = 76, ++ [2][1][8][46] = 42, ++ [2][1][11][46] = 16, ++}; ++ ++#define DECLARE_DIG_TABLE(name) \ ++static const struct rtw89_phy_dig_gain_cfg name##_table = { \ ++ .table = name, \ ++ .size = ARRAY_SIZE(name) \ ++} ++ ++static const struct rtw89_reg_def rtw89_8852a_lna_gain_g[] = { ++ {R_PATH0_LNA_ERR1, B_PATH0_LNA_ERR_G0_G_MSK}, ++ {R_PATH0_LNA_ERR2, B_PATH0_LNA_ERR_G1_G_MSK}, ++ {R_PATH0_LNA_ERR2, B_PATH0_LNA_ERR_G2_G_MSK}, ++ {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G3_G_MSK}, ++ {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G4_G_MSK}, ++ {R_PATH0_LNA_ERR4, B_PATH0_LNA_ERR_G5_G_MSK}, ++ {R_PATH0_LNA_ERR5, B_PATH0_LNA_ERR_G6_G_MSK}, ++}; ++ ++DECLARE_DIG_TABLE(rtw89_8852a_lna_gain_g); ++ ++static const struct rtw89_reg_def rtw89_8852a_tia_gain_g[] = { ++ {R_PATH0_TIA_ERR_G0, B_PATH0_TIA_ERR_G0_G_MSK}, ++ {R_PATH0_TIA_ERR_G1, B_PATH0_TIA_ERR_G1_G_MSK}, ++}; ++ ++DECLARE_DIG_TABLE(rtw89_8852a_tia_gain_g); ++ ++static const struct rtw89_reg_def rtw89_8852a_lna_gain_a[] = { ++ {R_PATH0_LNA_ERR1, B_PATH0_LNA_ERR_G0_A_MSK}, ++ {R_PATH0_LNA_ERR1, B_PATH0_LNA_ERR_G1_A_MSK}, ++ {R_PATH0_LNA_ERR2, B_PATH0_LNA_ERR_G2_A_MSK}, ++ {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G3_A_MSK}, ++ {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G4_A_MSK}, ++ {R_PATH0_LNA_ERR4, B_PATH0_LNA_ERR_G5_A_MSK}, ++ {R_PATH0_LNA_ERR4, B_PATH0_LNA_ERR_G6_A_MSK}, ++}; ++ ++DECLARE_DIG_TABLE(rtw89_8852a_lna_gain_a); ++ ++static const struct rtw89_reg_def rtw89_8852a_tia_gain_a[] = { ++ {R_PATH0_TIA_ERR_G0, B_PATH0_TIA_ERR_G0_A_MSK}, ++ {R_PATH0_TIA_ERR_G1, B_PATH0_TIA_ERR_G1_A_MSK}, ++}; ++ ++DECLARE_DIG_TABLE(rtw89_8852a_tia_gain_a); ++ ++const struct rtw89_phy_table rtw89_8852a_phy_bb_table = { ++ .regs = rtw89_8852a_phy_bb_regs, ++ .n_regs = ARRAY_SIZE(rtw89_8852a_phy_bb_regs), ++ .rf_path = 0, /* don't care */ ++}; ++ ++const struct rtw89_phy_table rtw89_8852a_phy_radioa_table = { ++ .regs = rtw89_8852a_phy_radioa_regs, ++ .n_regs = ARRAY_SIZE(rtw89_8852a_phy_radioa_regs), ++ .rf_path = RF_PATH_A, ++}; ++ ++const struct rtw89_phy_table rtw89_8852a_phy_radiob_table = { ++ .regs = rtw89_8852a_phy_radiob_regs, ++ .n_regs = ARRAY_SIZE(rtw89_8852a_phy_radiob_regs), ++ .rf_path = RF_PATH_B, ++}; ++ ++const struct rtw89_phy_table rtw89_8852a_phy_nctl_table = { ++ .regs = rtw89_8852a_phy_nctl_regs, ++ .n_regs = ARRAY_SIZE(rtw89_8852a_phy_nctl_regs), ++ .rf_path = 0, /* don't care */ ++}; ++ ++const struct rtw89_txpwr_table rtw89_8852a_byr_table = { ++ .data = rtw89_8852a_txpwr_byrate, ++ .size = ARRAY_SIZE(rtw89_8852a_txpwr_byrate), ++ .load = rtw89_phy_load_txpwr_byrate, ++}; ++ ++const struct rtw89_txpwr_track_cfg rtw89_8852a_trk_cfg = { ++ .delta_swingidx_5gb_n = _txpwr_track_delta_swingidx_5gb_n, ++ .delta_swingidx_5gb_p = _txpwr_track_delta_swingidx_5gb_p, ++ .delta_swingidx_5ga_n = _txpwr_track_delta_swingidx_5ga_n, ++ .delta_swingidx_5ga_p = _txpwr_track_delta_swingidx_5ga_p, ++ .delta_swingidx_2gb_n = _txpwr_track_delta_swingidx_2gb_n, ++ .delta_swingidx_2gb_p = _txpwr_track_delta_swingidx_2gb_p, ++ .delta_swingidx_2ga_n = _txpwr_track_delta_swingidx_2ga_n, ++ .delta_swingidx_2ga_p = _txpwr_track_delta_swingidx_2ga_p, ++ .delta_swingidx_2g_cck_b_n = _txpwr_track_delta_swingidx_2g_cck_b_n, ++ .delta_swingidx_2g_cck_b_p = _txpwr_track_delta_swingidx_2g_cck_b_p, ++ .delta_swingidx_2g_cck_a_n = _txpwr_track_delta_swingidx_2g_cck_a_n, ++ .delta_swingidx_2g_cck_a_p = _txpwr_track_delta_swingidx_2g_cck_a_p, ++}; ++ ++const struct rtw89_phy_dig_gain_table rtw89_8852a_phy_dig_table = { ++ .cfg_lna_g = &rtw89_8852a_lna_gain_g_table, ++ .cfg_tia_g = &rtw89_8852a_tia_gain_g_table, ++ .cfg_lna_a = &rtw89_8852a_lna_gain_a_table, ++ .cfg_tia_a = &rtw89_8852a_tia_gain_a_table ++}; +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.h +new file mode 100644 +index 000000000000..913796506286 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.h +@@ -0,0 +1,28 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_8852A_TABLE_H__ ++#define __RTW89_8852A_TABLE_H__ ++ ++#include "core.h" ++ ++extern const struct rtw89_phy_table rtw89_8852a_phy_bb_table; ++extern const struct rtw89_phy_table rtw89_8852a_phy_radioa_table; ++extern const struct rtw89_phy_table rtw89_8852a_phy_radiob_table; ++extern const struct rtw89_phy_table rtw89_8852a_phy_nctl_table; ++extern const struct rtw89_txpwr_table rtw89_8852a_byr_table; ++extern const struct rtw89_phy_dig_gain_table rtw89_8852a_phy_dig_table; ++extern const struct rtw89_txpwr_track_cfg rtw89_8852a_trk_cfg; ++extern const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] ++ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] ++ [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; ++extern const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] ++ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] ++ [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; ++extern const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] ++ [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; ++extern const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] ++ [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/sar.c b/drivers/net/wireless/realtek/rtw89/sar.c +new file mode 100644 +index 000000000000..097c87899cea +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/sar.c +@@ -0,0 +1,190 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "debug.h" ++#include "sar.h" ++ ++static int rtw89_query_sar_config_common(struct rtw89_dev *rtwdev, s32 *cfg) ++{ ++ struct rtw89_sar_cfg_common *rtwsar = &rtwdev->sar.cfg_common; ++ enum rtw89_subband subband = rtwdev->hal.current_subband; ++ ++ if (!rtwsar->set[subband]) ++ return -ENODATA; ++ ++ *cfg = rtwsar->cfg[subband]; ++ return 0; ++} ++ ++static const ++struct rtw89_sar_handler rtw89_sar_handlers[RTW89_SAR_SOURCE_NR] = { ++ [RTW89_SAR_SOURCE_COMMON] = { ++ .descr_sar_source = "RTW89_SAR_SOURCE_COMMON", ++ .txpwr_factor_sar = 2, ++ .query_sar_config = rtw89_query_sar_config_common, ++ }, ++}; ++ ++#define rtw89_sar_set_src(_dev, _src, _cfg_name, _cfg_data) \ ++ do { \ ++ typeof(_src) _s = (_src); \ ++ typeof(_dev) _d = (_dev); \ ++ BUILD_BUG_ON(!rtw89_sar_handlers[_s].descr_sar_source); \ ++ BUILD_BUG_ON(!rtw89_sar_handlers[_s].query_sar_config); \ ++ lockdep_assert_held(&_d->mutex); \ ++ _d->sar._cfg_name = *(_cfg_data); \ ++ _d->sar.src = _s; \ ++ } while (0) ++ ++static s8 rtw89_txpwr_sar_to_mac(struct rtw89_dev *rtwdev, u8 fct, s32 cfg) ++{ ++ const u8 fct_mac = rtwdev->chip->txpwr_factor_mac; ++ s32 cfg_mac; ++ ++ cfg_mac = fct > fct_mac ? ++ cfg >> (fct - fct_mac) : cfg << (fct_mac - fct); ++ ++ return (s8)clamp_t(s32, cfg_mac, ++ RTW89_SAR_TXPWR_MAC_MIN, ++ RTW89_SAR_TXPWR_MAC_MAX); ++} ++ ++s8 rtw89_query_sar(struct rtw89_dev *rtwdev) ++{ ++ const enum rtw89_sar_sources src = rtwdev->sar.src; ++ /* its members are protected by rtw89_sar_set_src() */ ++ const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src]; ++ int ret; ++ s32 cfg; ++ u8 fct; ++ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ if (src == RTW89_SAR_SOURCE_NONE) ++ return RTW89_SAR_TXPWR_MAC_MAX; ++ ++ ret = sar_hdl->query_sar_config(rtwdev, &cfg); ++ if (ret) ++ return RTW89_SAR_TXPWR_MAC_MAX; ++ ++ fct = sar_hdl->txpwr_factor_sar; ++ ++ return rtw89_txpwr_sar_to_mac(rtwdev, fct, cfg); ++} ++ ++void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev) ++{ ++ const enum rtw89_sar_sources src = rtwdev->sar.src; ++ /* its members are protected by rtw89_sar_set_src() */ ++ const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src]; ++ const u8 fct_mac = rtwdev->chip->txpwr_factor_mac; ++ int ret; ++ s32 cfg; ++ u8 fct; ++ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ if (src == RTW89_SAR_SOURCE_NONE) { ++ seq_puts(m, "no SAR is applied\n"); ++ return; ++ } ++ ++ seq_printf(m, "source: %d (%s)\n", src, sar_hdl->descr_sar_source); ++ ++ ret = sar_hdl->query_sar_config(rtwdev, &cfg); ++ if (ret) { ++ seq_printf(m, "config: return code: %d\n", ret); ++ seq_printf(m, "assign: max setting: %d (unit: 1/%lu dBm)\n", ++ RTW89_SAR_TXPWR_MAC_MAX, BIT(fct_mac)); ++ return; ++ } ++ ++ fct = sar_hdl->txpwr_factor_sar; ++ ++ seq_printf(m, "config: %d (unit: 1/%lu dBm)\n", cfg, BIT(fct)); ++} ++ ++static int rtw89_apply_sar_common(struct rtw89_dev *rtwdev, ++ const struct rtw89_sar_cfg_common *sar) ++{ ++ enum rtw89_sar_sources src; ++ int ret = 0; ++ ++ mutex_lock(&rtwdev->mutex); ++ ++ src = rtwdev->sar.src; ++ if (src != RTW89_SAR_SOURCE_NONE && src != RTW89_SAR_SOURCE_COMMON) { ++ rtw89_warn(rtwdev, "SAR source: %d is in use", src); ++ ret = -EBUSY; ++ goto exit; ++ } ++ ++ rtw89_sar_set_src(rtwdev, RTW89_SAR_SOURCE_COMMON, cfg_common, sar); ++ rtw89_chip_set_txpwr(rtwdev); ++ ++exit: ++ mutex_unlock(&rtwdev->mutex); ++ return ret; ++} ++ ++static const u8 rtw89_common_sar_subband_map[] = { ++ RTW89_CH_2G, ++ RTW89_CH_5G_BAND_1, ++ RTW89_CH_5G_BAND_3, ++ RTW89_CH_5G_BAND_4, ++}; ++ ++static const struct cfg80211_sar_freq_ranges rtw89_common_sar_freq_ranges[] = { ++ { .start_freq = 2412, .end_freq = 2484, }, ++ { .start_freq = 5180, .end_freq = 5320, }, ++ { .start_freq = 5500, .end_freq = 5720, }, ++ { .start_freq = 5745, .end_freq = 5825, }, ++}; ++ ++static_assert(ARRAY_SIZE(rtw89_common_sar_subband_map) == ++ ARRAY_SIZE(rtw89_common_sar_freq_ranges)); ++ ++const struct cfg80211_sar_capa rtw89_sar_capa = { ++ .type = NL80211_SAR_TYPE_POWER, ++ .num_freq_ranges = ARRAY_SIZE(rtw89_common_sar_freq_ranges), ++ .freq_ranges = rtw89_common_sar_freq_ranges, ++}; ++ ++int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw, ++ const struct cfg80211_sar_specs *sar) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_sar_cfg_common sar_common = {0}; ++ u8 fct; ++ u32 freq_start; ++ u32 freq_end; ++ u32 band; ++ s32 power; ++ u32 i, idx; ++ ++ if (sar->type != NL80211_SAR_TYPE_POWER) ++ return -EINVAL; ++ ++ fct = rtw89_sar_handlers[RTW89_SAR_SOURCE_COMMON].txpwr_factor_sar; ++ ++ for (i = 0; i < sar->num_sub_specs; i++) { ++ idx = sar->sub_specs[i].freq_range_index; ++ if (idx >= ARRAY_SIZE(rtw89_common_sar_freq_ranges)) ++ return -EINVAL; ++ ++ freq_start = rtw89_common_sar_freq_ranges[idx].start_freq; ++ freq_end = rtw89_common_sar_freq_ranges[idx].end_freq; ++ band = rtw89_common_sar_subband_map[idx]; ++ power = sar->sub_specs[i].power; ++ ++ rtw89_info(rtwdev, "On freq %u to %u, ", freq_start, freq_end); ++ rtw89_info(rtwdev, "set SAR power limit %d (unit: 1/%lu dBm)\n", ++ power, BIT(fct)); ++ ++ sar_common.set[band] = true; ++ sar_common.cfg[band] = power; ++ } ++ ++ return rtw89_apply_sar_common(rtwdev, &sar_common); ++} +diff --git a/drivers/net/wireless/realtek/rtw89/sar.h b/drivers/net/wireless/realtek/rtw89/sar.h +new file mode 100644 +index 000000000000..7b5484c84eb1 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/sar.h +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_SAR_H__ ++#define __RTW89_SAR_H__ ++ ++#include "core.h" ++ ++#define RTW89_SAR_TXPWR_MAC_MAX S8_MAX ++#define RTW89_SAR_TXPWR_MAC_MIN S8_MIN ++ ++struct rtw89_sar_handler { ++ const char *descr_sar_source; ++ u8 txpwr_factor_sar; ++ int (*query_sar_config)(struct rtw89_dev *rtwdev, s32 *cfg); ++}; ++ ++extern const struct cfg80211_sar_capa rtw89_sar_capa; ++ ++s8 rtw89_query_sar(struct rtw89_dev *rtwdev); ++void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev); ++int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw, ++ const struct cfg80211_sar_specs *sar); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c +new file mode 100644 +index 000000000000..837cdc366a61 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/ser.c +@@ -0,0 +1,491 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "cam.h" ++#include "debug.h" ++#include "mac.h" ++#include "ps.h" ++#include "ser.h" ++#include "util.h" ++ ++#define SER_RECFG_TIMEOUT 1000 ++ ++enum ser_evt { ++ SER_EV_NONE, ++ SER_EV_STATE_IN, ++ SER_EV_STATE_OUT, ++ SER_EV_L1_RESET, /* M1 */ ++ SER_EV_DO_RECOVERY, /* M3 */ ++ SER_EV_MAC_RESET_DONE, /* M5 */ ++ SER_EV_L2_RESET, ++ SER_EV_L2_RECFG_DONE, ++ SER_EV_L2_RECFG_TIMEOUT, ++ SER_EV_M3_TIMEOUT, ++ SER_EV_FW_M5_TIMEOUT, ++ SER_EV_L0_RESET, ++ SER_EV_MAXX ++}; ++ ++enum ser_state { ++ SER_IDLE_ST, ++ SER_RESET_TRX_ST, ++ SER_DO_HCI_ST, ++ SER_L2_RESET_ST, ++ SER_ST_MAX_ST ++}; ++ ++struct ser_msg { ++ struct list_head list; ++ u8 event; ++}; ++ ++struct state_ent { ++ u8 state; ++ char *name; ++ void (*st_func)(struct rtw89_ser *ser, u8 event); ++}; ++ ++struct event_ent { ++ u8 event; ++ char *name; ++}; ++ ++static char *ser_ev_name(struct rtw89_ser *ser, u8 event) ++{ ++ if (event < SER_EV_MAXX) ++ return ser->ev_tbl[event].name; ++ ++ return "err_ev_name"; ++} ++ ++static char *ser_st_name(struct rtw89_ser *ser) ++{ ++ if (ser->state < SER_ST_MAX_ST) ++ return ser->st_tbl[ser->state].name; ++ ++ return "err_st_name"; ++} ++ ++static void ser_state_run(struct rtw89_ser *ser, u8 evt) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s receive %s\n", ++ ser_st_name(ser), ser_ev_name(ser, evt)); ++ ++ rtw89_leave_lps(rtwdev); ++ ser->st_tbl[ser->state].st_func(ser, evt); ++} ++ ++static void ser_state_goto(struct rtw89_ser *ser, u8 new_state) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ if (ser->state == new_state || new_state >= SER_ST_MAX_ST) ++ return; ++ ser_state_run(ser, SER_EV_STATE_OUT); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s goto -> %s\n", ++ ser_st_name(ser), ser->st_tbl[new_state].name); ++ ++ ser->state = new_state; ++ ser_state_run(ser, SER_EV_STATE_IN); ++} ++ ++static struct ser_msg *__rtw89_ser_dequeue_msg(struct rtw89_ser *ser) ++{ ++ struct ser_msg *msg; ++ ++ spin_lock_irq(&ser->msg_q_lock); ++ msg = list_first_entry_or_null(&ser->msg_q, struct ser_msg, list); ++ if (msg) ++ list_del(&msg->list); ++ spin_unlock_irq(&ser->msg_q_lock); ++ ++ return msg; ++} ++ ++static void rtw89_ser_hdl_work(struct work_struct *work) ++{ ++ struct ser_msg *msg; ++ struct rtw89_ser *ser = container_of(work, struct rtw89_ser, ++ ser_hdl_work); ++ ++ while ((msg = __rtw89_ser_dequeue_msg(ser))) { ++ ser_state_run(ser, msg->event); ++ kfree(msg); ++ } ++} ++ ++static int ser_send_msg(struct rtw89_ser *ser, u8 event) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ struct ser_msg *msg = NULL; ++ ++ if (test_bit(RTW89_SER_DRV_STOP_RUN, ser->flags)) ++ return -EIO; ++ ++ msg = kmalloc(sizeof(*msg), GFP_ATOMIC); ++ if (!msg) ++ return -ENOMEM; ++ ++ msg->event = event; ++ ++ spin_lock_irq(&ser->msg_q_lock); ++ list_add(&msg->list, &ser->msg_q); ++ spin_unlock_irq(&ser->msg_q_lock); ++ ++ ieee80211_queue_work(rtwdev->hw, &ser->ser_hdl_work); ++ return 0; ++} ++ ++static void rtw89_ser_alarm_work(struct work_struct *work) ++{ ++ struct rtw89_ser *ser = container_of(work, struct rtw89_ser, ++ ser_alarm_work.work); ++ ++ ser_send_msg(ser, ser->alarm_event); ++ ser->alarm_event = SER_EV_NONE; ++} ++ ++static void ser_set_alarm(struct rtw89_ser *ser, u32 ms, u8 event) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ if (test_bit(RTW89_SER_DRV_STOP_RUN, ser->flags)) ++ return; ++ ++ ser->alarm_event = event; ++ ieee80211_queue_delayed_work(rtwdev->hw, &ser->ser_alarm_work, ++ msecs_to_jiffies(ms)); ++} ++ ++static void ser_del_alarm(struct rtw89_ser *ser) ++{ ++ cancel_delayed_work(&ser->ser_alarm_work); ++ ser->alarm_event = SER_EV_NONE; ++} ++ ++/* driver function */ ++static void drv_stop_tx(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ ieee80211_stop_queues(rtwdev->hw); ++ set_bit(RTW89_SER_DRV_STOP_TX, ser->flags); ++} ++ ++static void drv_stop_rx(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ clear_bit(RTW89_FLAG_RUNNING, rtwdev->flags); ++ set_bit(RTW89_SER_DRV_STOP_RX, ser->flags); ++} ++ ++static void drv_trx_reset(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ rtw89_hci_reset(rtwdev); ++} ++ ++static void drv_resume_tx(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ if (!test_bit(RTW89_SER_DRV_STOP_TX, ser->flags)) ++ return; ++ ++ ieee80211_wake_queues(rtwdev->hw); ++ clear_bit(RTW89_SER_DRV_STOP_TX, ser->flags); ++} ++ ++static void drv_resume_rx(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ if (!test_bit(RTW89_SER_DRV_STOP_RX, ser->flags)) ++ return; ++ ++ set_bit(RTW89_FLAG_RUNNING, rtwdev->flags); ++ clear_bit(RTW89_SER_DRV_STOP_RX, ser->flags); ++} ++ ++static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port); ++ rtwvif->net_type = RTW89_NET_TYPE_NO_LINK; ++ rtwvif->trigger = false; ++} ++ ++static void ser_reset_mac_binding(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_vif *rtwvif; ++ ++ rtw89_cam_reset_keys(rtwdev); ++ rtw89_core_release_all_bits_map(rtwdev->mac_id_map, RTW89_MAX_MAC_ID_NUM); ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ ser_reset_vif(rtwdev, rtwvif); ++} ++ ++/* hal function */ ++static int hal_enable_dma(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ int ret; ++ ++ if (!test_bit(RTW89_SER_HAL_STOP_DMA, ser->flags)) ++ return 0; ++ ++ if (!rtwdev->hci.ops->mac_lv1_rcvy) ++ return -EIO; ++ ++ ret = rtwdev->hci.ops->mac_lv1_rcvy(rtwdev, RTW89_LV1_RCVY_STEP_2); ++ if (!ret) ++ clear_bit(RTW89_SER_HAL_STOP_DMA, ser->flags); ++ ++ return ret; ++} ++ ++static int hal_stop_dma(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ int ret; ++ ++ if (!rtwdev->hci.ops->mac_lv1_rcvy) ++ return -EIO; ++ ++ ret = rtwdev->hci.ops->mac_lv1_rcvy(rtwdev, RTW89_LV1_RCVY_STEP_1); ++ if (!ret) ++ set_bit(RTW89_SER_HAL_STOP_DMA, ser->flags); ++ ++ return ret; ++} ++ ++static void hal_send_m2_event(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_DISABLE_EN); ++} ++ ++static void hal_send_m4_event(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_RCVY_EN); ++} ++ ++/* state handler */ ++static void ser_idle_st_hdl(struct rtw89_ser *ser, u8 evt) ++{ ++ switch (evt) { ++ case SER_EV_STATE_IN: ++ break; ++ case SER_EV_L1_RESET: ++ ser_state_goto(ser, SER_RESET_TRX_ST); ++ break; ++ case SER_EV_L2_RESET: ++ ser_state_goto(ser, SER_L2_RESET_ST); ++ break; ++ case SER_EV_STATE_OUT: ++ default: ++ break; ++ } ++} ++ ++static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt) ++{ ++ switch (evt) { ++ case SER_EV_STATE_IN: ++ drv_stop_tx(ser); ++ ++ if (hal_stop_dma(ser)) { ++ ser_state_goto(ser, SER_L2_RESET_ST); ++ break; ++ } ++ ++ drv_stop_rx(ser); ++ drv_trx_reset(ser); ++ ++ /* wait m3 */ ++ hal_send_m2_event(ser); ++ ++ /* set alarm to prevent FW response timeout */ ++ ser_set_alarm(ser, 1000, SER_EV_M3_TIMEOUT); ++ break; ++ ++ case SER_EV_DO_RECOVERY: ++ ser_state_goto(ser, SER_DO_HCI_ST); ++ break; ++ ++ case SER_EV_M3_TIMEOUT: ++ ser_state_goto(ser, SER_L2_RESET_ST); ++ break; ++ ++ case SER_EV_STATE_OUT: ++ ser_del_alarm(ser); ++ hal_enable_dma(ser); ++ drv_resume_rx(ser); ++ drv_resume_tx(ser); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++static void ser_do_hci_st_hdl(struct rtw89_ser *ser, u8 evt) ++{ ++ switch (evt) { ++ case SER_EV_STATE_IN: ++ /* wait m5 */ ++ hal_send_m4_event(ser); ++ ++ /* prevent FW response timeout */ ++ ser_set_alarm(ser, 1000, SER_EV_FW_M5_TIMEOUT); ++ break; ++ ++ case SER_EV_FW_M5_TIMEOUT: ++ ser_state_goto(ser, SER_L2_RESET_ST); ++ break; ++ ++ case SER_EV_MAC_RESET_DONE: ++ ser_state_goto(ser, SER_IDLE_ST); ++ break; ++ ++ case SER_EV_STATE_OUT: ++ ser_del_alarm(ser); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++static void ser_l2_reset_st_hdl(struct rtw89_ser *ser, u8 evt) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ switch (evt) { ++ case SER_EV_STATE_IN: ++ mutex_lock(&rtwdev->mutex); ++ ser_reset_mac_binding(rtwdev); ++ rtw89_core_stop(rtwdev); ++ mutex_unlock(&rtwdev->mutex); ++ ++ ieee80211_restart_hw(rtwdev->hw); ++ ser_set_alarm(ser, SER_RECFG_TIMEOUT, SER_EV_L2_RECFG_TIMEOUT); ++ break; ++ ++ case SER_EV_L2_RECFG_TIMEOUT: ++ rtw89_info(rtwdev, "Err: ser L2 re-config timeout\n"); ++ fallthrough; ++ case SER_EV_L2_RECFG_DONE: ++ ser_state_goto(ser, SER_IDLE_ST); ++ break; ++ ++ case SER_EV_STATE_OUT: ++ ser_del_alarm(ser); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++static struct event_ent ser_ev_tbl[] = { ++ {SER_EV_NONE, "SER_EV_NONE"}, ++ {SER_EV_STATE_IN, "SER_EV_STATE_IN"}, ++ {SER_EV_STATE_OUT, "SER_EV_STATE_OUT"}, ++ {SER_EV_L1_RESET, "SER_EV_L1_RESET"}, ++ {SER_EV_DO_RECOVERY, "SER_EV_DO_RECOVERY m3"}, ++ {SER_EV_MAC_RESET_DONE, "SER_EV_MAC_RESET_DONE m5"}, ++ {SER_EV_L2_RESET, "SER_EV_L2_RESET"}, ++ {SER_EV_L2_RECFG_DONE, "SER_EV_L2_RECFG_DONE"}, ++ {SER_EV_L2_RECFG_TIMEOUT, "SER_EV_L2_RECFG_TIMEOUT"}, ++ {SER_EV_M3_TIMEOUT, "SER_EV_M3_TIMEOUT"}, ++ {SER_EV_FW_M5_TIMEOUT, "SER_EV_FW_M5_TIMEOUT"}, ++ {SER_EV_L0_RESET, "SER_EV_L0_RESET"}, ++ {SER_EV_MAXX, "SER_EV_MAX"} ++}; ++ ++static struct state_ent ser_st_tbl[] = { ++ {SER_IDLE_ST, "SER_IDLE_ST", ser_idle_st_hdl}, ++ {SER_RESET_TRX_ST, "SER_RESET_TRX_ST", ser_reset_trx_st_hdl}, ++ {SER_DO_HCI_ST, "SER_DO_HCI_ST", ser_do_hci_st_hdl}, ++ {SER_L2_RESET_ST, "SER_L2_RESET_ST", ser_l2_reset_st_hdl} ++}; ++ ++int rtw89_ser_init(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_ser *ser = &rtwdev->ser; ++ ++ memset(ser, 0, sizeof(*ser)); ++ INIT_LIST_HEAD(&ser->msg_q); ++ ser->state = SER_IDLE_ST; ++ ser->st_tbl = ser_st_tbl; ++ ser->ev_tbl = ser_ev_tbl; ++ ++ bitmap_zero(ser->flags, RTW89_NUM_OF_SER_FLAGS); ++ spin_lock_init(&ser->msg_q_lock); ++ INIT_WORK(&ser->ser_hdl_work, rtw89_ser_hdl_work); ++ INIT_DELAYED_WORK(&ser->ser_alarm_work, rtw89_ser_alarm_work); ++ return 0; ++} ++ ++int rtw89_ser_deinit(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_ser *ser = (struct rtw89_ser *)&rtwdev->ser; ++ ++ set_bit(RTW89_SER_DRV_STOP_RUN, ser->flags); ++ cancel_delayed_work_sync(&ser->ser_alarm_work); ++ cancel_work_sync(&ser->ser_hdl_work); ++ clear_bit(RTW89_SER_DRV_STOP_RUN, ser->flags); ++ return 0; ++} ++ ++void rtw89_ser_recfg_done(struct rtw89_dev *rtwdev) ++{ ++ ser_send_msg(&rtwdev->ser, SER_EV_L2_RECFG_DONE); ++} ++ ++int rtw89_ser_notify(struct rtw89_dev *rtwdev, u32 err) ++{ ++ u8 event = SER_EV_NONE; ++ ++ rtw89_info(rtwdev, "ser event = 0x%04x\n", err); ++ ++ switch (err) { ++ case MAC_AX_ERR_L1_ERR_DMAC: ++ case MAC_AX_ERR_L0_PROMOTE_TO_L1: ++ event = SER_EV_L1_RESET; /* M1 */ ++ break; ++ case MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE: ++ event = SER_EV_DO_RECOVERY; /* M3 */ ++ break; ++ case MAC_AX_ERR_L1_RESET_RECOVERY_DONE: ++ event = SER_EV_MAC_RESET_DONE; /* M5 */ ++ break; ++ case MAC_AX_ERR_L0_ERR_CMAC0: ++ case MAC_AX_ERR_L0_ERR_CMAC1: ++ case MAC_AX_ERR_L0_RESET_DONE: ++ event = SER_EV_L0_RESET; ++ break; ++ default: ++ if (err == MAC_AX_ERR_L1_PROMOTE_TO_L2 || ++ (err >= MAC_AX_ERR_L2_ERR_AH_DMA && ++ err <= MAC_AX_GET_ERR_MAX)) ++ event = SER_EV_L2_RESET; ++ break; ++ } ++ ++ if (event == SER_EV_NONE) ++ return -EINVAL; ++ ++ ser_send_msg(&rtwdev->ser, event); ++ return 0; ++} ++EXPORT_SYMBOL(rtw89_ser_notify); +diff --git a/drivers/net/wireless/realtek/rtw89/ser.h b/drivers/net/wireless/realtek/rtw89/ser.h +new file mode 100644 +index 000000000000..6b8e62019942 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/ser.h +@@ -0,0 +1,15 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++ * Copyright(c) 2019-2020 Realtek Corporation ++ */ ++#ifndef __SER_H__ ++#define __SER_H__ ++ ++#include "core.h" ++ ++int rtw89_ser_init(struct rtw89_dev *rtwdev); ++int rtw89_ser_deinit(struct rtw89_dev *rtwdev); ++int rtw89_ser_notify(struct rtw89_dev *rtwdev, u32 err); ++void rtw89_ser_recfg_done(struct rtw89_dev *rtwdev); ++ ++#endif /* __SER_H__*/ ++ +diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h +new file mode 100644 +index 000000000000..f1e0fe36107d +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/txrx.h +@@ -0,0 +1,358 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_TXRX_H__ ++#define __RTW89_TXRX_H__ ++ ++#include "debug.h" ++ ++#define DATA_RATE_MODE_CTRL_MASK GENMASK(8, 7) ++#define DATA_RATE_NOT_HT_IDX_MASK GENMASK(3, 0) ++#define DATA_RATE_MODE_NON_HT 0x0 ++#define DATA_RATE_HT_IDX_MASK GENMASK(4, 0) ++#define DATA_RATE_MODE_HT 0x1 ++#define DATA_RATE_VHT_HE_NSS_MASK GENMASK(6, 4) ++#define DATA_RATE_VHT_HE_IDX_MASK GENMASK(3, 0) ++#define DATA_RATE_MODE_VHT 0x2 ++#define DATA_RATE_MODE_HE 0x3 ++#define GET_DATA_RATE_MODE(r) FIELD_GET(DATA_RATE_MODE_CTRL_MASK, r) ++#define GET_DATA_RATE_NOT_HT_IDX(r) FIELD_GET(DATA_RATE_NOT_HT_IDX_MASK, r) ++#define GET_DATA_RATE_HT_IDX(r) FIELD_GET(DATA_RATE_HT_IDX_MASK, r) ++#define GET_DATA_RATE_VHT_HE_IDX(r) FIELD_GET(DATA_RATE_VHT_HE_IDX_MASK, r) ++#define GET_DATA_RATE_NSS(r) FIELD_GET(DATA_RATE_VHT_HE_NSS_MASK, r) ++ ++/* TX WD BODY DWORD 0 */ ++#define RTW89_TXWD_BODY0_WP_OFFSET GENMASK(31, 24) ++#define RTW89_TXWD_BODY0_MORE_DATA BIT(23) ++#define RTW89_TXWD_BODY0_WD_INFO_EN BIT(22) ++#define RTW89_TXWD_BODY0_FW_DL BIT(20) ++#define RTW89_TXWD_BODY0_CHANNEL_DMA GENMASK(19, 16) ++#define RTW89_TXWD_BODY0_HDR_LLC_LEN GENMASK(15, 11) ++#define RTW89_TXWD_BODY0_WD_PAGE BIT(7) ++#define RTW89_TXWD_BODY0_HW_AMSDU BIT(5) ++ ++/* TX WD BODY DWORD 1 */ ++#define RTW89_TXWD_BODY1_PAYLOAD_ID GENMASK(31, 16) ++ ++/* TX WD BODY DWORD 2 */ ++#define RTW89_TXWD_BODY2_MACID GENMASK(30, 24) ++#define RTW89_TXWD_BODY2_TID_INDICATE BIT(23) ++#define RTW89_TXWD_BODY2_QSEL GENMASK(22, 17) ++#define RTW89_TXWD_BODY2_TXPKT_SIZE GENMASK(13, 0) ++ ++/* TX WD BODY DWORD 3 */ ++#define RTW89_TXWD_BODY3_BK BIT(13) ++#define RTW89_TXWD_BODY3_AGG_EN BIT(12) ++#define RTW89_TXWD_BODY3_SW_SEQ GENMASK(11, 0) ++ ++/* TX WD BODY DWORD 4 */ ++ ++/* TX WD BODY DWORD 5 */ ++ ++/* TX WD INFO DWORD 0 */ ++#define RTW89_TXWD_INFO0_USE_RATE BIT(30) ++#define RTW89_TXWD_INFO0_DATA_BW GENMASK(29, 28) ++#define RTW89_TXWD_INFO0_GI_LTF GENMASK(27, 25) ++#define RTW89_TXWD_INFO0_DATA_RATE GENMASK(24, 16) ++#define RTW89_TXWD_INFO0_DISDATAFB BIT(10) ++ ++/* TX WD INFO DWORD 1 */ ++#define RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE GENMASK(24, 16) ++#define RTW89_TXWD_INFO1_A_CTRL_BSR BIT(14) ++#define RTW89_TXWD_INFO1_MAX_AGGNUM GENMASK(7, 0) ++ ++/* TX WD INFO DWORD 2 */ ++#define RTW89_TXWD_INFO2_AMPDU_DENSITY GENMASK(20, 18) ++#define RTW89_TXWD_INFO2_SEC_TYPE GENMASK(12, 9) ++#define RTW89_TXWD_INFO2_SEC_HW_ENC BIT(8) ++#define RTW89_TXWD_INFO2_SEC_CAM_IDX GENMASK(7, 0) ++ ++/* TX WD INFO DWORD 3 */ ++ ++/* TX WD INFO DWORD 4 */ ++#define RTW89_TXWD_INFO4_RTS_EN BIT(27) ++#define RTW89_TXWD_INFO4_HW_RTS_EN BIT(31) ++ ++/* TX WD INFO DWORD 5 */ ++ ++/* RX DESC helpers */ ++/* Short Descriptor */ ++#define RTW89_GET_RXWD_LONG_RXD(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, BIT(31)) ++#define RTW89_GET_RXWD_DRV_INFO_SIZE(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, GENMASK(30, 28)) ++#define RTW89_GET_RXWD_RPKT_TYPE(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, GENMASK(27, 24)) ++#define RTW89_GET_RXWD_MAC_INFO_VALID(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, BIT(23)) ++#define RTW89_GET_RXWD_BB_SEL(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, BIT(22)) ++#define RTW89_GET_RXWD_HD_IV_LEN(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, GENMASK(21, 16)) ++#define RTW89_GET_RXWD_SHIFT(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, GENMASK(15, 14)) ++#define RTW89_GET_RXWD_PKT_SIZE(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, GENMASK(13, 0)) ++#define RTW89_GET_RXWD_BW(rxdesc) \ ++ le32_get_bits((rxdesc)->dword1, GENMASK(31, 30)) ++#define RTW89_GET_RXWD_GI_LTF(rxdesc) \ ++ le32_get_bits((rxdesc)->dword1, GENMASK(27, 25)) ++#define RTW89_GET_RXWD_DATA_RATE(rxdesc) \ ++ le32_get_bits((rxdesc)->dword1, GENMASK(24, 16)) ++#define RTW89_GET_RXWD_USER_ID(rxdesc) \ ++ le32_get_bits((rxdesc)->dword1, GENMASK(15, 8)) ++#define RTW89_GET_RXWD_SR_EN(rxdesc) \ ++ le32_get_bits((rxdesc)->dword1, BIT(7)) ++#define RTW89_GET_RXWD_PPDU_CNT(rxdesc) \ ++ le32_get_bits((rxdesc)->dword1, GENMASK(6, 4)) ++#define RTW89_GET_RXWD_PPDU_TYPE(rxdesc) \ ++ le32_get_bits((rxdesc)->dword1, GENMASK(3, 0)) ++#define RTW89_GET_RXWD_FREE_RUN_CNT(rxdesc) \ ++ le32_get_bits((rxdesc)->dword2, GENMASK(31, 0)) ++#define RTW89_GET_RXWD_ICV_ERR(rxdesc) \ ++ le32_get_bits((rxdesc)->dword3, BIT(10)) ++#define RTW89_GET_RXWD_CRC32_ERR(rxdesc) \ ++ le32_get_bits((rxdesc)->dword3, BIT(9)) ++#define RTW89_GET_RXWD_HW_DEC(rxdesc) \ ++ le32_get_bits((rxdesc)->dword3, BIT(2)) ++#define RTW89_GET_RXWD_SW_DEC(rxdesc) \ ++ le32_get_bits((rxdesc)->dword3, BIT(1)) ++#define RTW89_GET_RXWD_A1_MATCH(rxdesc) \ ++ le32_get_bits((rxdesc)->dword3, BIT(0)) ++ ++/* Long Descriptor */ ++#define RTW89_GET_RXWD_FRAG(rxdesc) \ ++ le32_get_bits((rxdesc)->dword4, GENMASK(31, 28)) ++#define RTW89_GET_RXWD_SEQ(rxdesc) \ ++ le32_get_bits((rxdesc)->dword4, GENMASK(27, 16)) ++#define RTW89_GET_RXWD_TYPE(rxdesc) \ ++ le32_get_bits((rxdesc)->dword4, GENMASK(1, 0)) ++#define RTW89_GET_RXWD_ADDR_CAM_VLD(rxdesc) \ ++ le32_get_bits((rxdesc)->dword5, BIT(28)) ++#define RTW89_GET_RXWD_RX_PL_ID(rxdesc) \ ++ le32_get_bits((rxdesc)->dword5, GENMASK(27, 24)) ++#define RTW89_GET_RXWD_MAC_ID(rxdesc) \ ++ le32_get_bits((rxdesc)->dword5, GENMASK(23, 16)) ++#define RTW89_GET_RXWD_ADDR_CAM_ID(rxdesc) \ ++ le32_get_bits((rxdesc)->dword5, GENMASK(15, 8)) ++#define RTW89_GET_RXWD_SEC_CAM_ID(rxdesc) \ ++ le32_get_bits((rxdesc)->dword5, GENMASK(7, 0)) ++ ++#define RTW89_GET_RXINFO_USR_NUM(rpt) \ ++ le32_get_bits(*((__le32 *)rpt), GENMASK(3, 0)) ++#define RTW89_GET_RXINFO_FW_DEFINE(rpt) \ ++ le32_get_bits(*((__le32 *)rpt), GENMASK(15, 8)) ++#define RTW89_GET_RXINFO_LSIG_LEN(rpt) \ ++ le32_get_bits(*((__le32 *)rpt), GENMASK(27, 16)) ++#define RTW89_GET_RXINFO_IS_TO_SELF(rpt) \ ++ le32_get_bits(*((__le32 *)rpt), BIT(28)) ++#define RTW89_GET_RXINFO_RX_CNT_VLD(rpt) \ ++ le32_get_bits(*((__le32 *)rpt), BIT(29)) ++#define RTW89_GET_RXINFO_LONG_RXD(rpt) \ ++ le32_get_bits(*((__le32 *)rpt), GENMASK(31, 30)) ++#define RTW89_GET_RXINFO_SERVICE(rpt) \ ++ le32_get_bits(*((__le32 *)(rpt) + 1), GENMASK(15, 0)) ++#define RTW89_GET_RXINFO_PLCP_LEN(rpt) \ ++ le32_get_bits(*((__le32 *)(rpt) + 1), GENMASK(23, 16)) ++#define RTW89_GET_RXINFO_MAC_ID_VALID(rpt, usr) \ ++ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(0)) ++#define RTW89_GET_RXINFO_DATA(rpt, usr) \ ++ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(1)) ++#define RTW89_GET_RXINFO_CTRL(rpt, usr) \ ++ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(2)) ++#define RTW89_GET_RXINFO_MGMT(rpt, usr) \ ++ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(3)) ++#define RTW89_GET_RXINFO_BCM(rpt, usr) \ ++ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(4)) ++#define RTW89_GET_RXINFO_MACID(rpt, usr) \ ++ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), GENMASK(15, 8)) ++ ++#define RTW89_GET_PHY_STS_RSSI_A(sts) \ ++ le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(7, 0)) ++#define RTW89_GET_PHY_STS_RSSI_B(sts) \ ++ le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(15, 8)) ++#define RTW89_GET_PHY_STS_RSSI_C(sts) \ ++ le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(23, 16)) ++#define RTW89_GET_PHY_STS_RSSI_D(sts) \ ++ le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(31, 24)) ++#define RTW89_GET_PHY_STS_LEN(sts) \ ++ le32_get_bits(*((__le32 *)sts), GENMASK(15, 8)) ++#define RTW89_GET_PHY_STS_RSSI_AVG(sts) \ ++ le32_get_bits(*((__le32 *)sts), GENMASK(31, 24)) ++#define RTW89_GET_PHY_STS_IE_TYPE(ie) \ ++ le32_get_bits(*((__le32 *)ie), GENMASK(4, 0)) ++#define RTW89_GET_PHY_STS_IE_LEN(ie) \ ++ le32_get_bits(*((__le32 *)ie), GENMASK(11, 5)) ++#define RTW89_GET_PHY_STS_IE0_CFO(ie) \ ++ le32_get_bits(*((__le32 *)(ie) + 1), GENMASK(31, 20)) ++ ++enum rtw89_tx_channel { ++ RTW89_TXCH_ACH0 = 0, ++ RTW89_TXCH_ACH1 = 1, ++ RTW89_TXCH_ACH2 = 2, ++ RTW89_TXCH_ACH3 = 3, ++ RTW89_TXCH_ACH4 = 4, ++ RTW89_TXCH_ACH5 = 5, ++ RTW89_TXCH_ACH6 = 6, ++ RTW89_TXCH_ACH7 = 7, ++ RTW89_TXCH_CH8 = 8, /* MGMT Band 0 */ ++ RTW89_TXCH_CH9 = 9, /* HI Band 0 */ ++ RTW89_TXCH_CH10 = 10, /* MGMT Band 1 */ ++ RTW89_TXCH_CH11 = 11, /* HI Band 1 */ ++ RTW89_TXCH_CH12 = 12, /* FW CMD */ ++ ++ /* keep last */ ++ RTW89_TXCH_NUM, ++ RTW89_TXCH_MAX = RTW89_TXCH_NUM - 1 ++}; ++ ++enum rtw89_rx_channel { ++ RTW89_RXCH_RXQ = 0, ++ RTW89_RXCH_RPQ = 1, ++ ++ /* keep last */ ++ RTW89_RXCH_NUM, ++ RTW89_RXCH_MAX = RTW89_RXCH_NUM - 1 ++}; ++ ++enum rtw89_tx_qsel { ++ RTW89_TX_QSEL_BE_0 = 0x00, ++ RTW89_TX_QSEL_BK_0 = 0x01, ++ RTW89_TX_QSEL_VI_0 = 0x02, ++ RTW89_TX_QSEL_VO_0 = 0x03, ++ RTW89_TX_QSEL_BE_1 = 0x04, ++ RTW89_TX_QSEL_BK_1 = 0x05, ++ RTW89_TX_QSEL_VI_1 = 0x06, ++ RTW89_TX_QSEL_VO_1 = 0x07, ++ RTW89_TX_QSEL_BE_2 = 0x08, ++ RTW89_TX_QSEL_BK_2 = 0x09, ++ RTW89_TX_QSEL_VI_2 = 0x0a, ++ RTW89_TX_QSEL_VO_2 = 0x0b, ++ RTW89_TX_QSEL_BE_3 = 0x0c, ++ RTW89_TX_QSEL_BK_3 = 0x0d, ++ RTW89_TX_QSEL_VI_3 = 0x0e, ++ RTW89_TX_QSEL_VO_3 = 0x0f, ++ RTW89_TX_QSEL_B0_BCN = 0x10, ++ RTW89_TX_QSEL_B0_HI = 0x11, ++ RTW89_TX_QSEL_B0_MGMT = 0x12, ++ RTW89_TX_QSEL_B0_NOPS = 0x13, ++ RTW89_TX_QSEL_B0_MGMT_FAST = 0x14, ++ /* reserved */ ++ /* reserved */ ++ /* reserved */ ++ RTW89_TX_QSEL_B1_BCN = 0x18, ++ RTW89_TX_QSEL_B1_HI = 0x19, ++ RTW89_TX_QSEL_B1_MGMT = 0x1a, ++ RTW89_TX_QSEL_B1_NOPS = 0x1b, ++ RTW89_TX_QSEL_B1_MGMT_FAST = 0x1c, ++ /* reserved */ ++ /* reserved */ ++ /* reserved */ ++}; ++ ++enum rtw89_phy_status_ie_type { ++ RTW89_PHYSTS_IE00_CMN_CCK = 0, ++ RTW89_PHYSTS_IE01_CMN_OFDM = 1, ++ RTW89_PHYSTS_IE02_CMN_EXT_AX = 2, ++ RTW89_PHYSTS_IE03_CMN_EXT_SEG_1 = 3, ++ RTW89_PHYSTS_IE04_CMN_EXT_PATH_A = 4, ++ RTW89_PHYSTS_IE05_CMN_EXT_PATH_B = 5, ++ RTW89_PHYSTS_IE06_CMN_EXT_PATH_C = 6, ++ RTW89_PHYSTS_IE07_CMN_EXT_PATH_D = 7, ++ RTW89_PHYSTS_IE08_FTR_CH = 8, ++ RTW89_PHYSTS_IE09_FTR_PLCP_0 = 9, ++ RTW89_PHYSTS_IE10_FTR_PLCP_EXT = 10, ++ RTW89_PHYSTS_IE11_FTR_PLCP_HISTOGRAM = 11, ++ RTW89_PHYSTS_IE12_MU_EIGEN_INFO = 12, ++ RTW89_PHYSTS_IE13_DL_MU_DEF = 13, ++ RTW89_PHYSTS_IE14_TB_UL_CQI = 14, ++ RTW89_PHYSTS_IE15_TB_UL_DEF = 15, ++ RTW89_PHYSTS_IE16_RSVD16 = 16, ++ RTW89_PHYSTS_IE17_TB_UL_CTRL = 17, ++ RTW89_PHYSTS_IE18_DBG_OFDM_FD_CMN = 18, ++ RTW89_PHYSTS_IE19_DBG_OFDM_TD_CMN = 19, ++ RTW89_PHYSTS_IE20_DBG_OFDM_FD_USER_SEG_0 = 20, ++ RTW89_PHYSTS_IE21_DBG_OFDM_FD_USER_SEG_1 = 21, ++ RTW89_PHYSTS_IE22_DBG_OFDM_FD_USER_AGC = 22, ++ RTW89_PHYSTS_IE23_RSVD23 = 23, ++ RTW89_PHYSTS_IE24_DBG_OFDM_TD_PATH_A = 24, ++ RTW89_PHYSTS_IE25_DBG_OFDM_TD_PATH_B = 25, ++ RTW89_PHYSTS_IE26_DBG_OFDM_TD_PATH_C = 26, ++ RTW89_PHYSTS_IE27_DBG_OFDM_TD_PATH_D = 27, ++ RTW89_PHYSTS_IE28_DBG_CCK_PATH_A = 28, ++ RTW89_PHYSTS_IE29_DBG_CCK_PATH_B = 29, ++ RTW89_PHYSTS_IE30_DBG_CCK_PATH_C = 30, ++ RTW89_PHYSTS_IE31_DBG_CCK_PATH_D = 31, ++ ++ /* keep last */ ++ RTW89_PHYSTS_IE_NUM, ++ RTW89_PHYSTS_IE_MAX = RTW89_PHYSTS_IE_NUM - 1 ++}; ++ ++static inline u8 rtw89_core_get_qsel(struct rtw89_dev *rtwdev, u8 tid) ++{ ++ switch (tid) { ++ default: ++ rtw89_warn(rtwdev, "Should use tag 1d: %d\n", tid); ++ fallthrough; ++ case 0: ++ case 3: ++ return RTW89_TX_QSEL_BE_0; ++ case 1: ++ case 2: ++ return RTW89_TX_QSEL_BK_0; ++ case 4: ++ case 5: ++ return RTW89_TX_QSEL_VI_0; ++ case 6: ++ case 7: ++ return RTW89_TX_QSEL_VO_0; ++ } ++} ++ ++static inline u8 rtw89_core_get_ch_dma(struct rtw89_dev *rtwdev, u8 qsel) ++{ ++ switch (qsel) { ++ default: ++ rtw89_warn(rtwdev, "Cannot map qsel to dma: %d\n", qsel); ++ fallthrough; ++ case RTW89_TX_QSEL_BE_0: ++ return RTW89_TXCH_ACH0; ++ case RTW89_TX_QSEL_BK_0: ++ return RTW89_TXCH_ACH1; ++ case RTW89_TX_QSEL_VI_0: ++ return RTW89_TXCH_ACH2; ++ case RTW89_TX_QSEL_VO_0: ++ return RTW89_TXCH_ACH3; ++ case RTW89_TX_QSEL_B0_MGMT: ++ return RTW89_TXCH_CH8; ++ case RTW89_TX_QSEL_B0_HI: ++ return RTW89_TXCH_CH9; ++ case RTW89_TX_QSEL_B1_MGMT: ++ return RTW89_TXCH_CH10; ++ case RTW89_TX_QSEL_B1_HI: ++ return RTW89_TXCH_CH11; ++ } ++} ++ ++static inline u8 rtw89_core_get_tid_indicate(struct rtw89_dev *rtwdev, u8 tid) ++{ ++ switch (tid) { ++ case 3: ++ case 2: ++ case 5: ++ case 7: ++ return 1; ++ default: ++ rtw89_warn(rtwdev, "Should use tag 1d: %d\n", tid); ++ fallthrough; ++ case 0: ++ case 1: ++ case 4: ++ case 6: ++ return 0; ++ } ++} ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/util.h b/drivers/net/wireless/realtek/rtw89/util.h +new file mode 100644 +index 000000000000..229e81009de6 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/util.h +@@ -0,0 +1,17 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++ * Copyright(c) 2019-2020 Realtek Corporation ++ */ ++#ifndef __RTW89_UTIL_H__ ++#define __RTW89_UTIL_H__ ++ ++#include "core.h" ++ ++#define rtw89_iterate_vifs_bh(rtwdev, iterator, data) \ ++ ieee80211_iterate_active_interfaces_atomic((rtwdev)->hw, \ ++ IEEE80211_IFACE_ITER_NORMAL, iterator, data) ++ ++/* call this function with rtwdev->mutex is held */ ++#define rtw89_for_each_rtwvif(rtwdev, rtwvif) \ ++ list_for_each_entry(rtwvif, &(rtwdev)->rtwvifs_list, list) ++ ++#endif +-- +2.34.0 + diff --git a/kernel/kernel/files/patches/mageia/staging-add-r8188eu.patch b/kernel/kernel/files/patches/mageia/staging-add-r8188eu.patch new file mode 100644 index 00000000..d1c75633 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/staging-add-r8188eu.patch @@ -0,0 +1,81013 @@ +diff --git a/drivers/staging/r8188eu/Kconfig b/drivers/staging/r8188eu/Kconfig +new file mode 100644 +index 000000000000..dc1719d3f2e4 +--- /dev/null ++++ b/drivers/staging/r8188eu/Kconfig +@@ -0,0 +1,26 @@ ++# SPDX-License-Identifier: GPL-2.0 ++config R8188EU ++ tristate "Realtek RTL8188EU Wireless LAN NIC driver" ++ depends on WLAN && USB && CFG80211 ++ depends on m ++ select WIRELESS_EXT ++ select WEXT_PRIV ++ select LIB80211 ++ select LIB80211_CRYPT_WEP ++ select LIB80211_CRYPT_CCMP ++ help ++ This option adds support for the Realtek RTL8188EU chipset, used in USB ++ devices such as the ASUS USB-N10 Nano. This newer driver is based on GitHub ++ sources for version v4.1.4_6773.20130222, and contains modifications for ++ newer kernel features. If built as a module, it will be called r8188eu. ++ ++if R8188EU ++ ++config 88EU_AP_MODE ++ bool "Realtek RTL8188EU AP mode" ++ help ++ This option enables Access Point mode. Unless you know that your system ++ will never be used as an AP, or the target system has limited memory, ++ "Y" should be selected. ++ ++endif +diff --git a/drivers/staging/r8188eu/Makefile b/drivers/staging/r8188eu/Makefile +new file mode 100644 +index 000000000000..aebaf29990fd +--- /dev/null ++++ b/drivers/staging/r8188eu/Makefile +@@ -0,0 +1,105 @@ ++SHELL := /bin/bash ++EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS) ++EXTRA_CFLAGS += -O1 ++ ++ccflags-y += -D__CHECK_ENDIAN__ ++ ++CONFIG_BT_COEXIST = n ++CONFIG_WOWLAN = n ++ ++OUTSRC_FILES := \ ++ hal/HalHWImg8188E_MAC.o \ ++ hal/HalHWImg8188E_BB.o \ ++ hal/HalHWImg8188E_RF.o \ ++ hal/HalPhyRf_8188e.o \ ++ hal/HalPwrSeqCmd.o \ ++ hal/Hal8188EPwrSeq.o \ ++ hal/Hal8188ERateAdaptive.o\ ++ hal/hal_intf.o \ ++ hal/hal_com.o \ ++ hal/odm.o \ ++ hal/odm_debug.o \ ++ hal/odm_interface.o \ ++ hal/odm_HWConfig.o \ ++ hal/odm_RegConfig8188E.o\ ++ hal/odm_RTL8188E.o \ ++ hal/rtl8188e_cmd.o \ ++ hal/rtl8188e_dm.o \ ++ hal/rtl8188e_hal_init.o \ ++ hal/rtl8188e_mp.o \ ++ hal/rtl8188e_phycfg.o \ ++ hal/rtl8188e_rf6052.o \ ++ hal/rtl8188e_rxdesc.o \ ++ hal/rtl8188e_sreset.o \ ++ hal/rtl8188e_xmit.o \ ++ hal/rtl8188eu_led.o \ ++ hal/rtl8188eu_recv.o \ ++ hal/rtl8188eu_xmit.o \ ++ hal/usb_halinit.o \ ++ hal/usb_ops_linux.o ++ ++RTL871X = rtl8188e ++ ++HCI_NAME = usb ++ ++_OS_INTFS_FILES := \ ++ os_dep/ioctl_linux.o \ ++ os_dep/mlme_linux.o \ ++ os_dep/os_intfs.o \ ++ os_dep/osdep_service.o \ ++ os_dep/recv_linux.o \ ++ os_dep/usb_intf.o \ ++ os_dep/usb_ops_linux.o \ ++ os_dep/xmit_linux.o ++ ++_HAL_INTFS_FILES += $(OUTSRC_FILES) ++ ++ifeq ($(CONFIG_BT_COEXIST), y) ++EXTRA_CFLAGS += -DCONFIG_BT_COEXIST ++endif ++ ++ifeq ($(CONFIG_WOWLAN), y) ++EXTRA_CFLAGS += -DCONFIG_WOWLAN ++endif ++ ++SUBARCH := $(shell uname -m | sed -e "s/i.86/i386/; s/ppc.*/powerpc/; s/armv.l/arm/; s/aarch64/arm64/;") ++ ++ARCH ?= $(SUBARCH) ++CROSS_COMPILE ?= ++KVER ?= $(if $(KERNELRELEASE),$(KERNELRELEASE),$(shell uname -r)) ++KSRC ?= $(if $(KERNEL_SRC),$(KERNEL_SRC),/lib/modules/$(KVER)/build) ++MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless ++INSTALL_PREFIX := ++ ++rtk_core := \ ++ core/rtw_ap.o \ ++ core/rtw_br_ext.o \ ++ core/rtw_cmd.o \ ++ core/rtw_debug.o \ ++ core/rtw_efuse.o \ ++ core/rtw_ieee80211.o \ ++ core/rtw_io.o \ ++ core/rtw_ioctl_set.o \ ++ core/rtw_iol.o \ ++ core/rtw_led.o \ ++ core/rtw_mlme.o \ ++ core/rtw_mlme_ext.o \ ++ core/rtw_mp.o \ ++ core/rtw_mp_ioctl.o \ ++ core/rtw_pwrctrl.o \ ++ core/rtw_p2p.o \ ++ core/rtw_recv.o \ ++ core/rtw_rf.o \ ++ core/rtw_security.o \ ++ core/rtw_sreset.o \ ++ core/rtw_sta_mgt.o \ ++ core/rtw_wlan_util.o \ ++ core/rtw_xmit.o ++ ++r8188eu-y += $(rtk_core) ++ ++r8188eu-y += $(_HAL_INTFS_FILES) ++ ++r8188eu-y += $(_OS_INTFS_FILES) ++ ++obj-$(CONFIG_R8188EU) := r8188eu.o +diff --git a/drivers/staging/r8188eu/TODO b/drivers/staging/r8188eu/TODO +new file mode 100644 +index 000000000000..ab9d5d145b3b +--- /dev/null ++++ b/drivers/staging/r8188eu/TODO +@@ -0,0 +1,16 @@ ++To-do list: ++ ++* Correct the coding style according to Linux guidelines; please read the document ++ at https://www.kernel.org/doc/html/latest/process/coding-style.html. ++* Remove unnecessary debugging/printing macros; for those that are still needed ++ use the proper kernel API (pr_debug(), dev_dbg(), netdev_dbg()). ++* Remove dead code such as unusued functions, variables, fields, etc.. ++* Use in-kernel API and remove unnecessary wrappers where possible. ++* Fix bugs due to code that sleeps in atomic context. ++* Remove the HAL layer and migrate its functionality into the relevant parts of ++ the driver. ++* Switch to use LIB80211. ++* Switch to use MAC80211. ++* Switch to use CFG80211. ++* Improve the error handling of various functions, particularly those that use ++ existing kernel APIs. +diff --git a/drivers/staging/r8188eu/core/rtw_ap.c b/drivers/staging/r8188eu/core/rtw_ap.c +new file mode 100644 +index 000000000000..1c07ad28b242 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_ap.c +@@ -0,0 +1,1850 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_AP_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wifi.h" ++#include "../include/ieee80211.h" ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++void init_mlme_ap_info(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; ++ ++ spin_lock_init(&pmlmepriv->bcn_update_lock); ++ ++ /* for ACL */ ++ _rtw_init_queue(&pacl_list->acl_node_q); ++ ++ start_ap_mode(padapter); ++} ++ ++void free_mlme_ap_info(struct adapter *padapter) ++{ ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ pmlmepriv->update_bcn = false; ++ pmlmeext->bstart_bss = false; ++ ++ rtw_sta_flush(padapter); ++ ++ pmlmeinfo->state = _HW_STATE_NOLINK_; ++ ++ /* free_assoc_sta_resources */ ++ rtw_free_all_stainfo(padapter); ++ ++ /* free bc/mc sta_info */ ++ psta = rtw_get_bcmc_stainfo(padapter); ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(padapter, psta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++} ++ ++static void update_BCNTIM(struct adapter *padapter) ++{ ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network; ++ unsigned char *pie = pnetwork_mlmeext->IEs; ++ ++ /* update TIM IE */ ++ if (true) { ++ u8 *p, *dst_ie, *premainder_ie = NULL; ++ u8 *pbackup_remainder_ie = NULL; ++ __le16 tim_bitmap_le; ++ uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen; ++ ++ tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap); ++ ++ p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen, pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_); ++ if (p && tim_ielen > 0) { ++ tim_ielen += 2; ++ premainder_ie = p + tim_ielen; ++ tim_ie_offset = (int)(p - pie); ++ remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen; ++ /* append TIM IE from dst_ie offset */ ++ dst_ie = p; ++ } else { ++ tim_ielen = 0; ++ ++ /* calculate head_len */ ++ offset = _FIXED_IE_LENGTH_; ++ offset += pnetwork_mlmeext->Ssid.SsidLength + 2; ++ ++ /* get supported rates len */ ++ p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_)); ++ if (p) ++ offset += tmp_len + 2; ++ ++ /* DS Parameter Set IE, len = 3 */ ++ offset += 3; ++ ++ premainder_ie = pie + offset; ++ ++ remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen; ++ ++ /* append TIM IE from offset */ ++ dst_ie = pie + offset; ++ } ++ ++ if (remainder_ielen > 0) { ++ pbackup_remainder_ie = kmalloc(remainder_ielen, GFP_ATOMIC); ++ if (pbackup_remainder_ie && premainder_ie) ++ memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); ++ } ++ *dst_ie++ = _TIM_IE_; ++ ++ if ((pstapriv->tim_bitmap & 0xff00) && (pstapriv->tim_bitmap & 0x00fc)) ++ tim_ielen = 5; ++ else ++ tim_ielen = 4; ++ ++ *dst_ie++ = tim_ielen; ++ ++ *dst_ie++ = 0;/* DTIM count */ ++ *dst_ie++ = 1;/* DTIM period */ ++ ++ if (pstapriv->tim_bitmap & BIT(0))/* for bc/mc frames */ ++ *dst_ie++ = BIT(0);/* bitmap ctrl */ ++ else ++ *dst_ie++ = 0; ++ ++ if (tim_ielen == 4) { ++ *dst_ie++ = *(u8 *)&tim_bitmap_le; ++ } else if (tim_ielen == 5) { ++ memcpy(dst_ie, &tim_bitmap_le, 2); ++ dst_ie += 2; ++ } ++ ++ /* copy remainder IE */ ++ if (pbackup_remainder_ie) { ++ memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen); ++ ++ kfree(pbackup_remainder_ie); ++ } ++ offset = (uint)(dst_ie - pie); ++ pnetwork_mlmeext->IELength = offset + remainder_ielen; ++ } ++ ++ set_tx_beacon_cmd(padapter); ++} ++ ++static u8 chk_sta_is_alive(struct sta_info *psta) ++{ ++ u8 ret = false; ++ ++ if ((psta->sta_stats.last_rx_data_pkts + psta->sta_stats.last_rx_ctrl_pkts) == ++ (psta->sta_stats.rx_data_pkts + psta->sta_stats.rx_ctrl_pkts)) ++ ; ++ else ++ ret = true; ++ ++ sta_update_last_rx_pkts(psta); ++ ++ return ret; ++} ++ ++void expire_timeout_chk(struct adapter *padapter) ++{ ++ struct list_head *phead, *plist; ++ u8 updated = 0; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 chk_alive_num = 0; ++ char chk_alive_list[NUM_STA]; ++ int i; ++ ++ spin_lock_bh(&pstapriv->auth_list_lock); ++ ++ phead = &pstapriv->auth_list; ++ plist = phead->next; ++ ++ /* check auth_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, auth_list); ++ plist = plist->next; ++ ++ if (psta->expire_to > 0) { ++ psta->expire_to--; ++ if (psta->expire_to == 0) { ++ list_del_init(&psta->auth_list); ++ pstapriv->auth_list_cnt--; ++ ++ DBG_88E("auth expire %6ph\n", ++ psta->hwaddr); ++ ++ spin_unlock_bh(&pstapriv->auth_list_lock); ++ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(padapter, psta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++ spin_lock_bh(&pstapriv->auth_list_lock); ++ } ++ } ++ ++ } ++ spin_unlock_bh(&pstapriv->auth_list_lock); ++ ++ psta = NULL; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ ++ phead = &pstapriv->asoc_list; ++ plist = phead->next; ++ ++ /* check asoc_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, asoc_list); ++ plist = plist->next; ++ ++ if (chk_sta_is_alive(psta) || !psta->expire_to) { ++ psta->expire_to = pstapriv->expire_to; ++ psta->keep_alive_trycnt = 0; ++ psta->under_exist_checking = 0; ++ } else { ++ psta->expire_to--; ++ } ++ ++ if (psta->expire_to <= 0) { ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ if (padapter->registrypriv.wifi_spec == 1) { ++ psta->expire_to = pstapriv->expire_to; ++ continue; ++ } ++ ++ if (psta->state & WIFI_SLEEP_STATE) { ++ if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) { ++ /* to check if alive by another methods if station is at ps mode. */ ++ psta->expire_to = pstapriv->expire_to; ++ psta->state |= WIFI_STA_ALIVE_CHK_STATE; ++ ++ /* to update bcn with tim_bitmap for this station */ ++ pstapriv->tim_bitmap |= BIT(psta->aid); ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++ ++ if (!pmlmeext->active_keep_alive_check) ++ continue; ++ } ++ } ++ if (pmlmeext->active_keep_alive_check) { ++ int stainfo_offset; ++ ++ stainfo_offset = rtw_stainfo_offset(pstapriv, psta); ++ if (stainfo_offset_valid(stainfo_offset)) ++ chk_alive_list[chk_alive_num++] = stainfo_offset; ++ continue; ++ } ++ ++ list_del_init(&psta->asoc_list); ++ pstapriv->asoc_list_cnt--; ++ ++ DBG_88E("asoc expire %pM, state = 0x%x\n", (psta->hwaddr), psta->state); ++ updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING); ++ } else { ++ /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */ ++ if (psta->sleepq_len > (NR_XMITFRAME / pstapriv->asoc_list_cnt) && ++ padapter->xmitpriv.free_xmitframe_cnt < (NR_XMITFRAME / pstapriv->asoc_list_cnt / 2)) { ++ DBG_88E("%s sta:%pM, sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n", __func__, ++ (psta->hwaddr), psta->sleepq_len, ++ padapter->xmitpriv.free_xmitframe_cnt, ++ pstapriv->asoc_list_cnt); ++ wakeup_sta_to_xmit(padapter, psta); ++ } ++ } ++ } ++ ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ if (chk_alive_num) { ++ u8 backup_oper_channel = 0; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ /* switch to correct channel of current network before issue keep-alive frames */ ++ if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) { ++ backup_oper_channel = rtw_get_oper_ch(padapter); ++ SelectChannel(padapter, pmlmeext->cur_channel); ++ } ++ ++ /* issue null data to check sta alive*/ ++ for (i = 0; i < chk_alive_num; i++) { ++ int ret = _FAIL; ++ ++ psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]); ++ ++ if (psta->state & WIFI_SLEEP_STATE) ++ ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50); ++ else ++ ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50); ++ ++ psta->keep_alive_trycnt++; ++ if (ret == _SUCCESS) { ++ DBG_88E("asoc check, sta(%pM) is alive\n", (psta->hwaddr)); ++ psta->expire_to = pstapriv->expire_to; ++ psta->keep_alive_trycnt = 0; ++ continue; ++ } else if (psta->keep_alive_trycnt <= 3) { ++ DBG_88E("ack check for asoc expire, keep_alive_trycnt =%d\n", psta->keep_alive_trycnt); ++ psta->expire_to = 1; ++ continue; ++ } ++ ++ psta->keep_alive_trycnt = 0; ++ ++ DBG_88E("asoc expire %pM, state = 0x%x\n", (psta->hwaddr), psta->state); ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ list_del_init(&psta->asoc_list); ++ pstapriv->asoc_list_cnt--; ++ updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING); ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ } ++ ++ if (backup_oper_channel > 0) /* back to the original operation channel */ ++ SelectChannel(padapter, backup_oper_channel); ++ } ++ ++ associated_clients_update(padapter, updated); ++} ++ ++void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level) ++{ ++ int i; ++ u8 rf_type; ++ u32 init_rate = 0; ++ unsigned char sta_band = 0, raid, shortGIrate = false; ++ unsigned char limit; ++ unsigned int tx_ra_bitmap = 0; ++ struct ht_priv *psta_ht = NULL; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; ++ ++ if (psta) ++ psta_ht = &psta->htpriv; ++ else ++ return; ++ ++ if (!(psta->state & _FW_LINKED)) ++ return; ++ ++ /* b/g mode ra_bitmap */ ++ for (i = 0; i < sizeof(psta->bssrateset); i++) { ++ if (psta->bssrateset[i]) ++ tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f); ++ } ++ /* n mode ra_bitmap */ ++ if (psta_ht->ht_option) { ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ if (rf_type == RF_2T2R) ++ limit = 16;/* 2R */ ++ else ++ limit = 8;/* 1R */ ++ ++ for (i = 0; i < limit; i++) { ++ if (psta_ht->ht_cap.mcs.rx_mask[i / 8] & BIT(i % 8)) ++ tx_ra_bitmap |= BIT(i + 12); ++ } ++ ++ /* max short GI rate */ ++ shortGIrate = psta_ht->sgi; ++ } ++ ++ if (pcur_network->Configuration.DSConfig > 14) { ++ sta_band |= WIRELESS_INVALID; ++ } else { ++ if (tx_ra_bitmap & 0xffff000) ++ sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B; ++ else if (tx_ra_bitmap & 0xff0) ++ sta_band |= WIRELESS_11G | WIRELESS_11B; ++ else ++ sta_band |= WIRELESS_11B; ++ } ++ ++ psta->wireless_mode = sta_band; ++ ++ raid = networktype_to_raid(sta_band); ++ init_rate = get_highest_rate_idx(tx_ra_bitmap & 0x0fffffff) & 0x3f; ++ ++ if (psta->aid < NUM_STA) { ++ u8 arg = 0; ++ ++ arg = psta->mac_id & 0x1f; ++ ++ arg |= BIT(7);/* support entry 2~31 */ ++ ++ if (shortGIrate) ++ arg |= BIT(5); ++ ++ tx_ra_bitmap |= ((raid << 28) & 0xf0000000); ++ ++ DBG_88E("%s => mac_id:%d , raid:%d , bitmap = 0x%x, arg = 0x%x\n", ++ __func__, psta->mac_id, raid, tx_ra_bitmap, arg); ++ ++ /* bitmap[0:27] = tx_rate_bitmap */ ++ /* bitmap[28:31]= Rate Adaptive id */ ++ /* arg[0:4] = macid */ ++ /* arg[5] = Short GI */ ++ rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, rssi_level); ++ ++ if (shortGIrate) ++ init_rate |= BIT(6); ++ ++ /* set ra_id, init_rate */ ++ psta->raid = raid; ++ psta->init_rate = init_rate; ++ ++ } else { ++ DBG_88E("station aid %d exceed the max number\n", psta->aid); ++ } ++} ++ ++void update_bmc_sta(struct adapter *padapter) ++{ ++ u32 init_rate = 0; ++ unsigned char network_type, raid; ++ int i, supportRateNum = 0; ++ unsigned int tx_ra_bitmap = 0; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; ++ struct sta_info *psta = rtw_get_bcmc_stainfo(padapter); ++ ++ if (psta) { ++ psta->aid = 0;/* default set to 0 */ ++ psta->mac_id = psta->aid + 1; ++ ++ psta->qos_option = 0; ++ psta->htpriv.ht_option = false; ++ ++ psta->ieee8021x_blocked = 0; ++ ++ memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats)); ++ ++ /* prepare for add_RATid */ ++ supportRateNum = rtw_get_rateset_len((u8 *)&pcur_network->SupportedRates); ++ network_type = rtw_check_network_type((u8 *)&pcur_network->SupportedRates, supportRateNum, 1); ++ ++ memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum); ++ psta->bssratelen = supportRateNum; ++ ++ /* b/g mode ra_bitmap */ ++ for (i = 0; i < supportRateNum; i++) { ++ if (psta->bssrateset[i]) ++ tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f); ++ } ++ ++ if (pcur_network->Configuration.DSConfig > 14) { ++ network_type = WIRELESS_INVALID; ++ } else { ++ /* force to b mode */ ++ network_type = WIRELESS_11B; ++ tx_ra_bitmap = 0xf; ++ } ++ ++ raid = networktype_to_raid(network_type); ++ init_rate = get_highest_rate_idx(tx_ra_bitmap & 0x0fffffff) & 0x3f; ++ ++ /* ap mode */ ++ rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true); ++ ++ { ++ u8 arg = 0; ++ ++ arg = psta->mac_id & 0x1f; ++ arg |= BIT(7); ++ tx_ra_bitmap |= ((raid << 28) & 0xf0000000); ++ DBG_88E("update_bmc_sta, mask = 0x%x, arg = 0x%x\n", tx_ra_bitmap, arg); ++ ++ /* bitmap[0:27] = tx_rate_bitmap */ ++ /* bitmap[28:31]= Rate Adaptive id */ ++ /* arg[0:4] = macid */ ++ /* arg[5] = Short GI */ ++ rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, 0); ++ } ++ /* set ra_id, init_rate */ ++ psta->raid = raid; ++ psta->init_rate = init_rate; ++ ++ rtw_sta_media_status_rpt(padapter, psta, 1); ++ ++ spin_lock_bh(&psta->lock); ++ psta->state = _FW_LINKED; ++ spin_unlock_bh(&psta->lock); ++ ++ } else { ++ DBG_88E("add_RATid_bmc_sta error!\n"); ++ } ++} ++ ++/* notes: */ ++/* AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode */ ++/* MAC_ID = AID+1 for sta in ap/adhoc mode */ ++/* MAC_ID = 1 for bc/mc for sta/ap/adhoc */ ++/* MAC_ID = 0 for bssid for sta/ap/adhoc */ ++/* CAM_ID = 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */ ++ ++void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv; ++ struct ht_priv *phtpriv_sta = &psta->htpriv; ++ u16 sta_cap_info; ++ u16 ap_cap_info; ++ ++ psta->mac_id = psta->aid + 1; ++ DBG_88E("%s\n", __func__); ++ ++ /* ap mode */ ++ rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true); ++ ++ if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ++ psta->ieee8021x_blocked = true; ++ else ++ psta->ieee8021x_blocked = false; ++ ++ /* update sta's cap */ ++ ++ /* ERP */ ++ VCS_update(padapter, psta); ++ /* HT related cap */ ++ if (phtpriv_sta->ht_option) { ++ /* check if sta supports rx ampdu */ ++ phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable; ++ sta_cap_info = le16_to_cpu(phtpriv_sta->ht_cap.cap_info); ++ ap_cap_info = le16_to_cpu(phtpriv_ap->ht_cap.cap_info); ++ ++ /* check if sta support s Short GI */ ++ if ((sta_cap_info & ap_cap_info) & ++ (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ++ phtpriv_sta->sgi = true; ++ ++ /* bwmode */ ++ if ((sta_cap_info & ap_cap_info) & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { ++ phtpriv_sta->bwmode = pmlmeext->cur_bwmode; ++ phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset; ++ } ++ psta->qos_option = true; ++ } else { ++ phtpriv_sta->ampdu_enable = false; ++ phtpriv_sta->sgi = false; ++ phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20; ++ phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ } ++ ++ /* Rx AMPDU */ ++ send_delba(padapter, 0, psta->hwaddr);/* recipient */ ++ ++ /* TX AMPDU */ ++ send_delba(padapter, 1, psta->hwaddr);/* originator */ ++ phtpriv_sta->agg_enable_bitmap = 0x0;/* reset */ ++ phtpriv_sta->candidate_tid_bitmap = 0x0;/* reset */ ++ ++ /* todo: init other variables */ ++ ++ memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats)); ++ ++ spin_lock_bh(&psta->lock); ++ psta->state |= _FW_LINKED; ++ spin_unlock_bh(&psta->lock); ++} ++ ++static void update_hw_ht_param(struct adapter *padapter) ++{ ++ unsigned char max_AMPDU_len; ++ unsigned char min_MPDU_spacing; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ DBG_88E("%s\n", __func__); ++ ++ /* handle A-MPDU parameter field */ ++ /* ++ AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k ++ AMPDU_para [4:2]:Min MPDU Start Spacing ++ */ ++ max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03; ++ ++ min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing)); ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len)); ++ ++ /* */ ++ /* Config SM Power Save setting */ ++ /* */ ++ pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & 0x0C) >> 2; ++ if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) ++ DBG_88E("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__); ++} ++ ++static void start_bss_network(struct adapter *padapter, u8 *pbuf) ++{ ++ u8 *p; ++ u8 val8, cur_channel, cur_bwmode, cur_ch_offset; ++ u16 bcn_interval; ++ u32 acparm; ++ int ie_len; ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network; ++ struct HT_info_element *pht_info = NULL; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod; ++ cur_channel = pnetwork->Configuration.DSConfig; ++ cur_bwmode = HT_CHANNEL_WIDTH_20; ++ cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ ++ /* check if there is wps ie, */ ++ /* if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd, */ ++ /* and at first time the security ie (RSN/WPA IE) will not include in beacon. */ ++ if (!rtw_get_wps_ie(pnetwork->IEs + _FIXED_IE_LENGTH_, pnetwork->IELength - _FIXED_IE_LENGTH_, NULL, NULL)) ++ pmlmeext->bstart_bss = true; ++ ++ /* todo: update wmm, ht cap */ ++ if (pmlmepriv->qospriv.qos_option) ++ pmlmeinfo->WMM_enable = true; ++ if (pmlmepriv->htpriv.ht_option) { ++ pmlmeinfo->WMM_enable = true; ++ pmlmeinfo->HT_enable = true; ++ ++ update_hw_ht_param(padapter); ++ } ++ ++ if (pmlmepriv->cur_network.join_res != true) { /* setting only at first time */ ++ /* WEP Key will be set before this function, do not clear CAM. */ ++ if ((psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) && ++ (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)) ++ flush_all_cam_entry(padapter); /* clear CAM */ ++ } ++ ++ /* set MSR to AP_Mode */ ++ Set_MSR(padapter, _HW_STATE_AP_); ++ ++ /* Set BSSID REG */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress); ++ ++ /* Set EDCA param reg */ ++ acparm = 0x002F3217; /* VO */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm)); ++ acparm = 0x005E4317; /* VI */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm)); ++ acparm = 0x005ea42b; ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm)); ++ acparm = 0x0000A444; /* BK */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm)); ++ ++ /* Set Security */ ++ val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf; ++ rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); ++ ++ /* Beacon Control related register */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval)); ++ ++ UpdateBrateTbl(padapter, pnetwork->SupportedRates); ++ rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates); ++ ++ if (!pmlmepriv->cur_network.join_res) { /* setting only at first time */ ++ /* turn on all dynamic functions */ ++ Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); ++ } ++ /* set channel, bwmode */ ++ p = rtw_get_ie((pnetwork->IEs + sizeof(struct ndis_802_11_fixed_ie)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - sizeof(struct ndis_802_11_fixed_ie))); ++ if (p && ie_len) { ++ pht_info = (struct HT_info_element *)(p + 2); ++ ++ if ((pregpriv->cbw40_enable) && (pht_info->infos[0] & BIT(2))) { ++ /* switch to the 40M Hz mode */ ++ cur_bwmode = HT_CHANNEL_WIDTH_40; ++ switch (pht_info->infos[0] & 0x3) { ++ case 1: ++ cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; ++ break; ++ case 3: ++ cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; ++ break; ++ default: ++ cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ break; ++ } ++ } ++ } ++ /* TODO: need to judge the phy parameters on concurrent mode for single phy */ ++ set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode); ++ ++ DBG_88E("CH =%d, BW =%d, offset =%d\n", cur_channel, cur_bwmode, cur_ch_offset); ++ ++ /* */ ++ pmlmeext->cur_channel = cur_channel; ++ pmlmeext->cur_bwmode = cur_bwmode; ++ pmlmeext->cur_ch_offset = cur_ch_offset; ++ pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type; ++ ++ /* update cur_wireless_mode */ ++ update_wireless_mode(padapter); ++ ++ /* udpate capability after cur_wireless_mode updated */ ++ update_capinfo(padapter, rtw_get_capability((struct wlan_bssid_ex *)pnetwork)); ++ ++ /* let pnetwork_mlmeext == pnetwork_mlme. */ ++ memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length); ++ ++#ifdef CONFIG_88EU_P2P ++ memcpy(pwdinfo->p2p_group_ssid, pnetwork->Ssid.Ssid, pnetwork->Ssid.SsidLength); ++ pwdinfo->p2p_group_ssid_len = pnetwork->Ssid.SsidLength; ++#endif /* CONFIG_88EU_P2P */ ++ ++ if (pmlmeext->bstart_bss) { ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++ ++ /* issue beacon frame */ ++ if (send_beacon(padapter) == _FAIL) ++ DBG_88E("issue_beacon, fail!\n"); ++ } ++ ++ /* update bc/mc sta_info */ ++ update_bmc_sta(padapter); ++} ++ ++int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) ++{ ++ int ret = _SUCCESS; ++ u8 *p; ++ u8 *pHT_caps_ie = NULL; ++ u8 *pHT_info_ie = NULL; ++ struct sta_info *psta = NULL; ++ u16 cap, ht_cap = false; ++ uint ie_len = 0; ++ int group_cipher, pairwise_cipher; ++ u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX]; ++ int supportRateNum = 0; ++ u8 OUI1[] = {0x00, 0x50, 0xf2, 0x01}; ++ u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pbss_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; ++ u8 *ie = pbss_network->IEs; ++ ++ /* SSID */ ++ /* Supported rates */ ++ /* DS Params */ ++ /* WLAN_EID_COUNTRY */ ++ /* ERP Information element */ ++ /* Extended supported rates */ ++ /* WPA/WPA2 */ ++ /* Wi-Fi Wireless Multimedia Extensions */ ++ /* ht_capab, ht_oper */ ++ /* WPS IE */ ++ ++ DBG_88E("%s, len =%d\n", __func__, len); ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) ++ return _FAIL; ++ ++ if (len > MAX_IE_SZ) ++ return _FAIL; ++ ++ pbss_network->IELength = len; ++ ++ memset(ie, 0, MAX_IE_SZ); ++ ++ memcpy(ie, pbuf, pbss_network->IELength); ++ ++ if (pbss_network->InfrastructureMode != Ndis802_11APMode) ++ return _FAIL; ++ ++ pbss_network->Rssi = 0; ++ ++ memcpy(pbss_network->MacAddress, myid(&padapter->eeprompriv), ETH_ALEN); ++ ++ /* beacon interval */ ++ p = rtw_get_beacon_interval_from_ie(ie);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */ ++ pbss_network->Configuration.BeaconPeriod = get_unaligned_le16(p); ++ ++ /* capability */ ++ cap = get_unaligned_le16(ie); ++ ++ /* SSID */ ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); ++ if (p && ie_len > 0) { ++ memset(&pbss_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); ++ memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len); ++ pbss_network->Ssid.SsidLength = ie_len; ++ } ++ ++ /* channel */ ++ channel = 0; ++ pbss_network->Configuration.Length = 0; ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); ++ if (p && ie_len > 0) ++ channel = *(p + 2); ++ ++ pbss_network->Configuration.DSConfig = channel; ++ ++ memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX); ++ /* get supported rates */ ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); ++ if (p) { ++ memcpy(supportRate, p + 2, ie_len); ++ supportRateNum = ie_len; ++ } ++ ++ /* get ext_supported rates */ ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_); ++ if (p) { ++ memcpy(supportRate + supportRateNum, p + 2, ie_len); ++ supportRateNum += ie_len; ++ } ++ ++ network_type = rtw_check_network_type(supportRate, supportRateNum, channel); ++ ++ rtw_set_supported_rate(pbss_network->SupportedRates, network_type); ++ ++ /* parsing ERP_IE */ ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); ++ if (p && ie_len > 0) ++ ERP_IE_handler(padapter, (struct ndis_802_11_var_ie *)p); ++ ++ /* update privacy/security */ ++ if (cap & BIT(4)) ++ pbss_network->Privacy = 1; ++ else ++ pbss_network->Privacy = 0; ++ ++ psecuritypriv->wpa_psk = 0; ++ ++ /* wpa2 */ ++ group_cipher = 0; ++ pairwise_cipher = 0; ++ psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_; ++ psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_; ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); ++ if (p && ie_len > 0) { ++ if (rtw_parse_wpa2_ie(p, ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { ++ psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; ++ ++ psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */ ++ psecuritypriv->wpa_psk |= BIT(1); ++ ++ psecuritypriv->wpa2_group_cipher = group_cipher; ++ psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher; ++ } ++ } ++ /* wpa */ ++ ie_len = 0; ++ group_cipher = 0; ++ pairwise_cipher = 0; ++ psecuritypriv->wpa_group_cipher = _NO_PRIVACY_; ++ psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_; ++ for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) { ++ p = rtw_get_ie(p, _SSN_IE_1_, &ie_len, ++ (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))); ++ if ((p) && (!memcmp(p + 2, OUI1, 4))) { ++ if (rtw_parse_wpa_ie(p, ie_len + 2, &group_cipher, ++ &pairwise_cipher, NULL) == _SUCCESS) { ++ psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; ++ ++ psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */ ++ ++ psecuritypriv->wpa_psk |= BIT(0); ++ ++ psecuritypriv->wpa_group_cipher = group_cipher; ++ psecuritypriv->wpa_pairwise_cipher = pairwise_cipher; ++ } ++ break; ++ } ++ if (!p || ie_len == 0) ++ break; ++ } ++ ++ /* wmm */ ++ ie_len = 0; ++ pmlmepriv->qospriv.qos_option = 0; ++ if (pregistrypriv->wmm_enable) { ++ for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) { ++ p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, ++ (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))); ++ if ((p) && !memcmp(p + 2, WMM_PARA_IE, 6)) { ++ pmlmepriv->qospriv.qos_option = 1; ++ ++ *(p + 8) |= BIT(7);/* QoS Info, support U-APSD */ ++ ++ /* disable all ACM bits since the WMM admission control is not supported */ ++ *(p + 10) &= ~BIT(4); /* BE */ ++ *(p + 14) &= ~BIT(4); /* BK */ ++ *(p + 18) &= ~BIT(4); /* VI */ ++ *(p + 22) &= ~BIT(4); /* VO */ ++ break; ++ } ++ ++ if (!p || ie_len == 0) ++ break; ++ } ++ } ++ /* parsing HT_CAP_IE */ ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, ++ (pbss_network->IELength - _BEACON_IE_OFFSET_)); ++ if (p && ie_len > 0) { ++ u8 rf_type; ++ struct ieee80211_ht_cap *pht_cap = (struct ieee80211_ht_cap *)(p + 2); ++ ++ pHT_caps_ie = p; ++ ht_cap = true; ++ network_type |= WIRELESS_11_24N; ++ ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ ++ if ((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) || ++ (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP)) ++ pht_cap->ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY & (0x07 << 2)); ++ else ++ pht_cap->ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00); ++ ++ /* set Max Rx AMPDU size to 64K */ ++ pht_cap->ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_FACTOR & 0x03); ++ ++ if (rf_type == RF_1T1R) { ++ pht_cap->mcs.rx_mask[0] = 0xff; ++ pht_cap->mcs.rx_mask[1] = 0x0; ++ } ++ memcpy(&pmlmepriv->htpriv.ht_cap, p + 2, ie_len); ++ } ++ ++ /* parsing HT_INFO_IE */ ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, ++ (pbss_network->IELength - _BEACON_IE_OFFSET_)); ++ if (p && ie_len > 0) ++ pHT_info_ie = p; ++ switch (network_type) { ++ case WIRELESS_11B: ++ pbss_network->NetworkTypeInUse = Ndis802_11DS; ++ break; ++ case WIRELESS_11G: ++ case WIRELESS_11BG: ++ case WIRELESS_11G_24N: ++ case WIRELESS_11BG_24N: ++ pbss_network->NetworkTypeInUse = Ndis802_11OFDM24; ++ break; ++ default: ++ pbss_network->NetworkTypeInUse = Ndis802_11OFDM24; ++ break; ++ } ++ ++ pmlmepriv->cur_network.network_type = network_type; ++ ++ pmlmepriv->htpriv.ht_option = false; ++ ++ if ((psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) || ++ (psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) { ++ /* todo: */ ++ /* ht_cap = false; */ ++ } ++ ++ /* ht_cap */ ++ if (pregistrypriv->ht_enable && ht_cap) { ++ pmlmepriv->htpriv.ht_option = true; ++ pmlmepriv->qospriv.qos_option = 1; ++ ++ if (pregistrypriv->ampdu_enable == 1) ++ pmlmepriv->htpriv.ampdu_enable = true; ++ HT_caps_handler(padapter, (struct ndis_802_11_var_ie *)pHT_caps_ie); ++ ++ HT_info_handler(padapter, (struct ndis_802_11_var_ie *)pHT_info_ie); ++ } ++ ++ pbss_network->Length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pbss_network); ++ ++ /* issue beacon to start bss network */ ++ start_bss_network(padapter, (u8 *)pbss_network); ++ ++ /* alloc sta_info for ap itself */ ++ psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress); ++ if (!psta) { ++ psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress); ++ if (!psta) ++ return _FAIL; ++ } ++ ++ /* fix bug of flush_cam_entry at STOP AP mode */ ++ psta->state |= WIFI_AP_STATE; ++ rtw_indicate_connect(padapter); ++ pmlmepriv->cur_network.join_res = true;/* for check if already set beacon */ ++ return ret; ++} ++ ++void rtw_set_macaddr_acl(struct adapter *padapter, int mode) ++{ ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; ++ ++ DBG_88E("%s, mode =%d\n", __func__, mode); ++ ++ pacl_list->mode = mode; ++} ++ ++int rtw_acl_add_sta(struct adapter *padapter, u8 *addr) ++{ ++ struct list_head *plist, *phead; ++ u8 added = false; ++ int i, ret = 0; ++ struct rtw_wlan_acl_node *paclnode; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; ++ struct __queue *pacl_node_q = &pacl_list->acl_node_q; ++ ++ DBG_88E("%s(acl_num =%d) =%pM\n", __func__, pacl_list->num, (addr)); ++ ++ if ((NUM_ACL - 1) < pacl_list->num) ++ return -1; ++ ++ spin_lock_bh(&pacl_node_q->lock); ++ ++ phead = get_list_head(pacl_node_q); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ paclnode = container_of(plist, struct rtw_wlan_acl_node, list); ++ plist = plist->next; ++ ++ if (!memcmp(paclnode->addr, addr, ETH_ALEN)) { ++ if (paclnode->valid) { ++ added = true; ++ DBG_88E("%s, sta has been added\n", __func__); ++ break; ++ } ++ } ++ } ++ ++ spin_unlock_bh(&pacl_node_q->lock); ++ ++ if (added) ++ return ret; ++ ++ spin_lock_bh(&pacl_node_q->lock); ++ ++ for (i = 0; i < NUM_ACL; i++) { ++ paclnode = &pacl_list->aclnode[i]; ++ ++ if (!paclnode->valid) { ++ INIT_LIST_HEAD(&paclnode->list); ++ ++ memcpy(paclnode->addr, addr, ETH_ALEN); ++ ++ paclnode->valid = true; ++ ++ list_add_tail(&paclnode->list, get_list_head(pacl_node_q)); ++ ++ pacl_list->num++; ++ ++ break; ++ } ++ } ++ ++ DBG_88E("%s, acl_num =%d\n", __func__, pacl_list->num); ++ ++ spin_unlock_bh(&pacl_node_q->lock); ++ ++ return ret; ++} ++ ++int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr) ++{ ++ struct list_head *plist, *phead; ++ int ret = 0; ++ struct rtw_wlan_acl_node *paclnode; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; ++ struct __queue *pacl_node_q = &pacl_list->acl_node_q; ++ ++ DBG_88E("%s(acl_num =%d) =%pM\n", __func__, pacl_list->num, (addr)); ++ ++ spin_lock_bh(&pacl_node_q->lock); ++ ++ phead = get_list_head(pacl_node_q); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ paclnode = container_of(plist, struct rtw_wlan_acl_node, list); ++ plist = plist->next; ++ ++ if (!memcmp(paclnode->addr, addr, ETH_ALEN)) { ++ if (paclnode->valid) { ++ paclnode->valid = false; ++ ++ list_del_init(&paclnode->list); ++ ++ pacl_list->num--; ++ } ++ } ++ } ++ ++ spin_unlock_bh(&pacl_node_q->lock); ++ ++ DBG_88E("%s, acl_num =%d\n", __func__, pacl_list->num); ++ return ret; ++} ++ ++static void update_bcn_fixed_ie(struct adapter *padapter) ++{ ++ DBG_88E("%s\n", __func__); ++} ++ ++static void update_bcn_erpinfo_ie(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; ++ unsigned char *p, *ie = pnetwork->IEs; ++ u32 len = 0; ++ ++ DBG_88E("%s, ERP_enable =%d\n", __func__, pmlmeinfo->ERP_enable); ++ ++ if (!pmlmeinfo->ERP_enable) ++ return; ++ ++ /* parsing ERP_IE */ ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len, ++ (pnetwork->IELength - _BEACON_IE_OFFSET_)); ++ if (p && len > 0) { ++ struct ndis_802_11_var_ie *pIE = (struct ndis_802_11_var_ie *)p; ++ ++ if (pmlmepriv->num_sta_non_erp == 1) ++ pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT | RTW_ERP_INFO_USE_PROTECTION; ++ else ++ pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT | RTW_ERP_INFO_USE_PROTECTION); ++ ++ if (pmlmepriv->num_sta_no_short_preamble > 0) ++ pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE; ++ else ++ pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE); ++ ++ ERP_IE_handler(padapter, pIE); ++ } ++} ++ ++static void update_bcn_htcap_ie(struct adapter *padapter) ++{ ++ DBG_88E("%s\n", __func__); ++} ++ ++static void update_bcn_htinfo_ie(struct adapter *padapter) ++{ ++ DBG_88E("%s\n", __func__); ++} ++ ++static void update_bcn_rsn_ie(struct adapter *padapter) ++{ ++ DBG_88E("%s\n", __func__); ++} ++ ++static void update_bcn_wpa_ie(struct adapter *padapter) ++{ ++ DBG_88E("%s\n", __func__); ++} ++ ++static void update_bcn_wmm_ie(struct adapter *padapter) ++{ ++ DBG_88E("%s\n", __func__); ++} ++ ++static void update_bcn_wps_ie(struct adapter *padapter) ++{ ++ u8 *pwps_ie = NULL, *pwps_ie_src; ++ u8 *premainder_ie, *pbackup_remainder_ie = NULL; ++ uint wps_ielen = 0, wps_offset, remainder_ielen; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; ++ unsigned char *ie = pnetwork->IEs; ++ u32 ielen = pnetwork->IELength; ++ ++ DBG_88E("%s\n", __func__); ++ ++ pwps_ie = rtw_get_wps_ie(ie + _FIXED_IE_LENGTH_, ielen - _FIXED_IE_LENGTH_, NULL, &wps_ielen); ++ ++ if (!pwps_ie || wps_ielen == 0) ++ return; ++ ++ wps_offset = (uint)(pwps_ie - ie); ++ ++ premainder_ie = pwps_ie + wps_ielen; ++ ++ remainder_ielen = ielen - wps_offset - wps_ielen; ++ ++ if (remainder_ielen > 0) { ++ pbackup_remainder_ie = kmalloc(remainder_ielen, GFP_ATOMIC); ++ if (pbackup_remainder_ie) ++ memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); ++ } ++ ++ pwps_ie_src = pmlmepriv->wps_beacon_ie; ++ if (!pwps_ie_src) ++ goto exit; ++ ++ wps_ielen = (uint)pwps_ie_src[1];/* to get ie data len */ ++ if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) { ++ memcpy(pwps_ie, pwps_ie_src, wps_ielen + 2); ++ pwps_ie += (wps_ielen + 2); ++ ++ if (pbackup_remainder_ie) ++ memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen); ++ ++ /* update IELength */ ++ pnetwork->IELength = wps_offset + (wps_ielen + 2) + remainder_ielen; ++ } ++ ++exit: ++ kfree(pbackup_remainder_ie); ++} ++ ++static void update_bcn_p2p_ie(struct adapter *padapter) ++{ ++} ++ ++static void update_bcn_vendor_spec_ie(struct adapter *padapter, u8 *oui) ++{ ++ DBG_88E("%s\n", __func__); ++ ++ if (!memcmp(RTW_WPA_OUI, oui, 4)) ++ update_bcn_wpa_ie(padapter); ++ else if (!memcmp(WMM_OUI, oui, 4)) ++ update_bcn_wmm_ie(padapter); ++ else if (!memcmp(WPS_OUI, oui, 4)) ++ update_bcn_wps_ie(padapter); ++ else if (!memcmp(P2P_OUI, oui, 4)) ++ update_bcn_p2p_ie(padapter); ++ else ++ DBG_88E("unknown OUI type!\n"); ++} ++ ++void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx) ++{ ++ struct mlme_priv *pmlmepriv; ++ struct mlme_ext_priv *pmlmeext; ++ ++ if (!padapter) ++ return; ++ ++ pmlmepriv = &padapter->mlmepriv; ++ pmlmeext = &padapter->mlmeextpriv; ++ ++ if (!pmlmeext->bstart_bss) ++ return; ++ ++ spin_lock_bh(&pmlmepriv->bcn_update_lock); ++ ++ switch (ie_id) { ++ case 0xFF: ++ update_bcn_fixed_ie(padapter);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */ ++ break; ++ case _TIM_IE_: ++ update_BCNTIM(padapter); ++ break; ++ case _ERPINFO_IE_: ++ update_bcn_erpinfo_ie(padapter); ++ break; ++ case _HT_CAPABILITY_IE_: ++ update_bcn_htcap_ie(padapter); ++ break; ++ case _RSN_IE_2_: ++ update_bcn_rsn_ie(padapter); ++ break; ++ case _HT_ADD_INFO_IE_: ++ update_bcn_htinfo_ie(padapter); ++ break; ++ case _VENDOR_SPECIFIC_IE_: ++ update_bcn_vendor_spec_ie(padapter, oui); ++ break; ++ default: ++ break; ++ } ++ ++ pmlmepriv->update_bcn = true; ++ ++ spin_unlock_bh(&pmlmepriv->bcn_update_lock); ++ ++ if (tx) ++ set_tx_beacon_cmd(padapter); ++} ++ ++/* ++op_mode ++Set to 0 (HT pure) under the followign conditions ++ - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or ++ - all STAs in the BSS are 20 MHz HT in 20 MHz BSS ++Set to 1 (HT non-member protection) if there may be non-HT STAs ++ in both the primary and the secondary channel ++Set to 2 if only HT STAs are associated in BSS, ++ however and at least one 20 MHz HT STA is associated ++Set to 3 (HT mixed mode) when one or more non-HT STAs are associated ++ (currently non-GF HT station is considered as non-HT STA also) ++*/ ++static int rtw_ht_operation_update(struct adapter *padapter) ++{ ++ u16 cur_op_mode, new_op_mode; ++ int op_mode_changes = 0; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv; ++ ++ if (pmlmepriv->htpriv.ht_option) ++ return 0; ++ ++ DBG_88E("%s current operation mode = 0x%X\n", ++ __func__, pmlmepriv->ht_op_mode); ++ ++ if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) && ++ pmlmepriv->num_sta_ht_no_gf) { ++ pmlmepriv->ht_op_mode |= ++ HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT; ++ op_mode_changes++; ++ } else if ((pmlmepriv->ht_op_mode & ++ HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) && ++ pmlmepriv->num_sta_ht_no_gf == 0) { ++ pmlmepriv->ht_op_mode &= ++ ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT; ++ op_mode_changes++; ++ } ++ ++ if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) && ++ (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) { ++ pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT; ++ op_mode_changes++; ++ } else if ((pmlmepriv->ht_op_mode & ++ HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) && ++ (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) { ++ pmlmepriv->ht_op_mode &= ++ ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT; ++ op_mode_changes++; ++ } ++ ++ /* Note: currently we switch to the MIXED op mode if HT non-greenfield ++ * station is associated. Probably it's a theoretical case, since ++ * it looks like all known HT STAs support greenfield. ++ */ ++ new_op_mode = 0; ++ if (pmlmepriv->num_sta_no_ht || ++ (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)) ++ new_op_mode = OP_MODE_MIXED; ++ else if ((le16_to_cpu(phtpriv_ap->ht_cap.cap_info) & ++ IEEE80211_HT_CAP_SUP_WIDTH_20_40) && ++ pmlmepriv->num_sta_ht_20mhz) ++ new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED; ++ else if (pmlmepriv->olbc_ht) ++ new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS; ++ else ++ new_op_mode = OP_MODE_PURE; ++ ++ cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK; ++ if (cur_op_mode != new_op_mode) { ++ pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK; ++ pmlmepriv->ht_op_mode |= new_op_mode; ++ op_mode_changes++; ++ } ++ ++ DBG_88E("%s new operation mode = 0x%X changes =%d\n", ++ __func__, pmlmepriv->ht_op_mode, op_mode_changes); ++ ++ return op_mode_changes; ++} ++ ++void associated_clients_update(struct adapter *padapter, u8 updated) ++{ ++ /* update associcated stations cap. */ ++ if (updated) { ++ struct list_head *phead, *plist; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ ++ phead = &pstapriv->asoc_list; ++ plist = phead->next; ++ ++ /* check asoc_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, asoc_list); ++ ++ plist = plist->next; ++ ++ VCS_update(padapter, psta); ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ } ++} ++ ++/* called > TSR LEVEL for USB or SDIO Interface*/ ++void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta) ++{ ++ u8 beacon_updated = false; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) { ++ if (!psta->no_short_preamble_set) { ++ psta->no_short_preamble_set = 1; ++ ++ pmlmepriv->num_sta_no_short_preamble++; ++ ++ if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && ++ (pmlmepriv->num_sta_no_short_preamble == 1)) { ++ beacon_updated = true; ++ update_beacon(padapter, 0xFF, NULL, true); ++ } ++ } ++ } else { ++ if (psta->no_short_preamble_set) { ++ psta->no_short_preamble_set = 0; ++ ++ pmlmepriv->num_sta_no_short_preamble--; ++ ++ if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && ++ (pmlmepriv->num_sta_no_short_preamble == 0)) { ++ beacon_updated = true; ++ update_beacon(padapter, 0xFF, NULL, true); ++ } ++ } ++ } ++ ++ if (psta->flags & WLAN_STA_NONERP) { ++ if (!psta->nonerp_set) { ++ psta->nonerp_set = 1; ++ ++ pmlmepriv->num_sta_non_erp++; ++ ++ if (pmlmepriv->num_sta_non_erp == 1) { ++ beacon_updated = true; ++ update_beacon(padapter, _ERPINFO_IE_, NULL, true); ++ } ++ } ++ } else { ++ if (psta->nonerp_set) { ++ psta->nonerp_set = 0; ++ ++ pmlmepriv->num_sta_non_erp--; ++ ++ if (pmlmepriv->num_sta_non_erp == 0) { ++ beacon_updated = true; ++ update_beacon(padapter, _ERPINFO_IE_, NULL, true); ++ } ++ } ++ } ++ ++ if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT)) { ++ if (!psta->no_short_slot_time_set) { ++ psta->no_short_slot_time_set = 1; ++ ++ pmlmepriv->num_sta_no_short_slot_time++; ++ ++ if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && ++ (pmlmepriv->num_sta_no_short_slot_time == 1)) { ++ beacon_updated = true; ++ update_beacon(padapter, 0xFF, NULL, true); ++ } ++ } ++ } else { ++ if (psta->no_short_slot_time_set) { ++ psta->no_short_slot_time_set = 0; ++ ++ pmlmepriv->num_sta_no_short_slot_time--; ++ ++ if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && ++ (pmlmepriv->num_sta_no_short_slot_time == 0)) { ++ beacon_updated = true; ++ update_beacon(padapter, 0xFF, NULL, true); ++ } ++ } ++ } ++ ++ if (psta->flags & WLAN_STA_HT) { ++ u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info); ++ ++ DBG_88E("HT: STA %pM HT Capabilities Info: 0x%04x\n", ++ (psta->hwaddr), ht_capab); ++ ++ if (psta->no_ht_set) { ++ psta->no_ht_set = 0; ++ pmlmepriv->num_sta_no_ht--; ++ } ++ ++ if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) { ++ if (!psta->no_ht_gf_set) { ++ psta->no_ht_gf_set = 1; ++ pmlmepriv->num_sta_ht_no_gf++; ++ } ++ DBG_88E("%s STA %pM - no greenfield, num of non-gf stations %d\n", ++ __func__, (psta->hwaddr), ++ pmlmepriv->num_sta_ht_no_gf); ++ } ++ ++ if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH_20_40) == 0) { ++ if (!psta->ht_20mhz_set) { ++ psta->ht_20mhz_set = 1; ++ pmlmepriv->num_sta_ht_20mhz++; ++ } ++ DBG_88E("%s STA %pM - 20 MHz HT, num of 20MHz HT STAs %d\n", ++ __func__, (psta->hwaddr), ++ pmlmepriv->num_sta_ht_20mhz); ++ } ++ } else { ++ if (!psta->no_ht_set) { ++ psta->no_ht_set = 1; ++ pmlmepriv->num_sta_no_ht++; ++ } ++ if (pmlmepriv->htpriv.ht_option) { ++ DBG_88E("%s STA %pM - no HT, num of non-HT stations %d\n", ++ __func__, (psta->hwaddr), ++ pmlmepriv->num_sta_no_ht); ++ } ++ } ++ ++ if (rtw_ht_operation_update(padapter) > 0) { ++ update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, false); ++ update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, true); ++ } ++ ++ /* update associcated stations cap. */ ++ associated_clients_update(padapter, beacon_updated); ++ ++ DBG_88E("%s, updated =%d\n", __func__, beacon_updated); ++} ++ ++u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta) ++{ ++ u8 beacon_updated = false; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ if (!psta) ++ return beacon_updated; ++ ++ if (psta->no_short_preamble_set) { ++ psta->no_short_preamble_set = 0; ++ pmlmepriv->num_sta_no_short_preamble--; ++ if (pmlmeext->cur_wireless_mode > WIRELESS_11B && ++ pmlmepriv->num_sta_no_short_preamble == 0) { ++ beacon_updated = true; ++ update_beacon(padapter, 0xFF, NULL, true); ++ } ++ } ++ ++ if (psta->nonerp_set) { ++ psta->nonerp_set = 0; ++ pmlmepriv->num_sta_non_erp--; ++ if (pmlmepriv->num_sta_non_erp == 0) { ++ beacon_updated = true; ++ update_beacon(padapter, _ERPINFO_IE_, NULL, true); ++ } ++ } ++ ++ if (psta->no_short_slot_time_set) { ++ psta->no_short_slot_time_set = 0; ++ pmlmepriv->num_sta_no_short_slot_time--; ++ if (pmlmeext->cur_wireless_mode > WIRELESS_11B && ++ pmlmepriv->num_sta_no_short_slot_time == 0) { ++ beacon_updated = true; ++ update_beacon(padapter, 0xFF, NULL, true); ++ } ++ } ++ ++ if (psta->no_ht_gf_set) { ++ psta->no_ht_gf_set = 0; ++ pmlmepriv->num_sta_ht_no_gf--; ++ } ++ ++ if (psta->no_ht_set) { ++ psta->no_ht_set = 0; ++ pmlmepriv->num_sta_no_ht--; ++ } ++ ++ if (psta->ht_20mhz_set) { ++ psta->ht_20mhz_set = 0; ++ pmlmepriv->num_sta_ht_20mhz--; ++ } ++ ++ if (rtw_ht_operation_update(padapter) > 0) { ++ update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, false); ++ update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, true); ++ } ++ ++ /* update associcated stations cap. */ ++ ++ DBG_88E("%s, updated =%d\n", __func__, beacon_updated); ++ ++ return beacon_updated; ++} ++ ++u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta, ++ bool active, u16 reason) ++{ ++ u8 beacon_updated = false; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ if (!psta) ++ return beacon_updated; ++ ++ /* tear down Rx AMPDU */ ++ send_delba(padapter, 0, psta->hwaddr);/* recipient */ ++ ++ /* tear down TX AMPDU */ ++ send_delba(padapter, 1, psta->hwaddr);/* originator */ ++ psta->htpriv.agg_enable_bitmap = 0x0;/* reset */ ++ psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */ ++ ++ if (active) ++ issue_deauth(padapter, psta->hwaddr, reason); ++ ++ /* clear cam entry / key */ ++ rtw_clearstakey_cmd(padapter, (u8 *)psta, (u8)(psta->mac_id + 3), true); ++ ++ spin_lock_bh(&psta->lock); ++ psta->state &= ~_FW_LINKED; ++ spin_unlock_bh(&psta->lock); ++ ++ rtw_indicate_sta_disassoc_event(padapter, psta); ++ ++ report_del_sta_event(padapter, psta->hwaddr, reason); ++ ++ beacon_updated = bss_cap_update_on_sta_leave(padapter, psta); ++ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(padapter, psta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++ return beacon_updated; ++} ++ ++int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset) ++{ ++ struct list_head *phead, *plist; ++ int ret = 0; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ ++ if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) ++ return ret; ++ ++ DBG_88E(FUNC_NDEV_FMT" with ch:%u, offset:%u\n", ++ FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset); ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ phead = &pstapriv->asoc_list; ++ plist = phead->next; ++ ++ /* for each sta in asoc_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, asoc_list); ++ plist = plist->next; ++ ++ issue_action_spct_ch_switch(padapter, psta->hwaddr, new_ch, ch_offset); ++ psta->expire_to = ((pstapriv->expire_to * 2) > 5) ? 5 : (pstapriv->expire_to * 2); ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset); ++ ++ return ret; ++} ++ ++int rtw_sta_flush(struct adapter *padapter) ++{ ++ struct list_head *phead, *plist; ++ int ret = 0; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ ++ DBG_88E(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); ++ ++ if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) ++ return ret; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ phead = &pstapriv->asoc_list; ++ plist = phead->next; ++ ++ /* free sta asoc_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, asoc_list); ++ ++ plist = plist->next; ++ ++ list_del_init(&psta->asoc_list); ++ pstapriv->asoc_list_cnt--; ++ ++ ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING); ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING); ++ ++ associated_clients_update(padapter, true); ++ ++ return ret; ++} ++ ++/* called > TSR LEVEL for USB or SDIO Interface*/ ++void sta_info_update(struct adapter *padapter, struct sta_info *psta) ++{ ++ int flags = psta->flags; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ /* update wmm cap. */ ++ if (WLAN_STA_WME & flags) ++ psta->qos_option = 1; ++ else ++ psta->qos_option = 0; ++ ++ if (pmlmepriv->qospriv.qos_option == 0) ++ psta->qos_option = 0; ++ ++ /* update 802.11n ht cap. */ ++ if (WLAN_STA_HT & flags) { ++ psta->htpriv.ht_option = true; ++ psta->qos_option = 1; ++ } else { ++ psta->htpriv.ht_option = false; ++ } ++ ++ if (!pmlmepriv->htpriv.ht_option) ++ psta->htpriv.ht_option = false; ++ ++ update_sta_info_apmode(padapter, psta); ++} ++ ++/* called >= TSR LEVEL for USB or SDIO Interface*/ ++void ap_sta_info_defer_update(struct adapter *padapter, struct sta_info *psta) ++{ ++ if (psta->state & _FW_LINKED) { ++ /* add ratid */ ++ add_RATid(padapter, psta, 0);/* DM_RATR_STA_INIT */ ++ } ++} ++ ++void start_ap_mode(struct adapter *padapter) ++{ ++ int i; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; ++ ++ pmlmepriv->update_bcn = false; ++ ++ pmlmeext->bstart_bss = false; ++ ++ pmlmepriv->num_sta_non_erp = 0; ++ ++ pmlmepriv->num_sta_no_short_slot_time = 0; ++ ++ pmlmepriv->num_sta_no_short_preamble = 0; ++ ++ pmlmepriv->num_sta_ht_no_gf = 0; ++ pmlmepriv->num_sta_no_ht = 0; ++ pmlmepriv->num_sta_ht_20mhz = 0; ++ ++ pmlmepriv->olbc = false; ++ ++ pmlmepriv->olbc_ht = false; ++ ++ pmlmepriv->ht_op_mode = 0; ++ ++ for (i = 0; i < NUM_STA; i++) ++ pstapriv->sta_aid[i] = NULL; ++ ++ pmlmepriv->wps_beacon_ie = NULL; ++ pmlmepriv->wps_probe_resp_ie = NULL; ++ pmlmepriv->wps_assoc_resp_ie = NULL; ++ ++ pmlmepriv->p2p_beacon_ie = NULL; ++ pmlmepriv->p2p_probe_resp_ie = NULL; ++ ++ /* for ACL */ ++ INIT_LIST_HEAD(&pacl_list->acl_node_q.queue); ++ pacl_list->num = 0; ++ pacl_list->mode = 0; ++ for (i = 0; i < NUM_ACL; i++) { ++ INIT_LIST_HEAD(&pacl_list->aclnode[i].list); ++ pacl_list->aclnode[i].valid = false; ++ } ++} ++ ++void stop_ap_mode(struct adapter *padapter) ++{ ++ struct list_head *phead, *plist; ++ struct rtw_wlan_acl_node *paclnode; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; ++ struct __queue *pacl_node_q = &pacl_list->acl_node_q; ++ ++ pmlmepriv->update_bcn = false; ++ pmlmeext->bstart_bss = false; ++ ++ /* reset and init security priv , this can refine with rtw_reset_securitypriv */ ++ memset((unsigned char *)&padapter->securitypriv, 0, sizeof(struct security_priv)); ++ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled; ++ ++ /* for ACL */ ++ spin_lock_bh(&pacl_node_q->lock); ++ phead = get_list_head(pacl_node_q); ++ plist = phead->next; ++ while (phead != plist) { ++ paclnode = container_of(plist, struct rtw_wlan_acl_node, list); ++ plist = plist->next; ++ ++ if (paclnode->valid) { ++ paclnode->valid = false; ++ ++ list_del_init(&paclnode->list); ++ ++ pacl_list->num--; ++ } ++ } ++ spin_unlock_bh(&pacl_node_q->lock); ++ ++ DBG_88E("%s, free acl_node_queue, num =%d\n", __func__, pacl_list->num); ++ ++ rtw_sta_flush(padapter); ++ ++ /* free_assoc_sta_resources */ ++ rtw_free_all_stainfo(padapter); ++ ++ psta = rtw_get_bcmc_stainfo(padapter); ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(padapter, psta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++ rtw_init_bcmc_stainfo(padapter); ++ ++ rtw_free_mlme_priv_ie_data(pmlmepriv); ++} ++ ++#endif /* CONFIG_88EU_AP_MODE */ +diff --git a/drivers/staging/r8188eu/core/rtw_br_ext.c b/drivers/staging/r8188eu/core/rtw_br_ext.c +new file mode 100644 +index 000000000000..62a672243696 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_br_ext.c +@@ -0,0 +1,717 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. i*/ ++ ++#define _RTW_BR_EXT_C_ ++ ++#include "../include/linux/if_arp.h" ++#include "../include/net/ip.h" ++#include "../include/linux/atalk.h" ++#include "../include/linux/udp.h" ++#include "../include/linux/if_pppox.h" ++ ++#include "../include/drv_types.h" ++#include "../include/rtw_br_ext.h" ++#include "../include/usb_osintf.h" ++#include "../include/recv_osdep.h" ++ ++#ifndef csum_ipv6_magic ++#include "../include/net/ip6_checksum.h" ++#endif ++ ++#include "../include/linux/ipv6.h" ++#include "../include/linux/icmpv6.h" ++#include "../include/net/ndisc.h" ++#include "../include/net/checksum.h" ++ ++#define NAT25_IPV4 01 ++#define NAT25_IPV6 02 ++#define NAT25_IPX 03 ++#define NAT25_APPLE 04 ++#define NAT25_PPPOE 05 ++ ++#define RTL_RELAY_TAG_LEN (ETH_ALEN) ++#define TAG_HDR_LEN 4 ++ ++#define MAGIC_CODE 0x8186 ++#define MAGIC_CODE_LEN 2 ++#define WAIT_TIME_PPPOE 5 /* waiting time for pppoe server in sec */ ++ ++/*----------------------------------------------------------------- ++ How database records network address: ++ 0 1 2 3 4 5 6 7 8 9 10 ++ |----|----|----|----|----|----|----|----|----|----|----| ++ IPv4 |type| | IP addr | ++ IPX |type| Net addr | Node addr | ++ IPX |type| Net addr |Sckt addr| ++ Apple |type| Network |node| ++ PPPoE |type| SID | AC MAC | ++-----------------------------------------------------------------*/ ++ ++/* Find a tag in pppoe frame and return the pointer */ ++static unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, unsigned short type) ++{ ++ unsigned char *cur_ptr, *start_ptr; ++ unsigned short tagLen, tagType; ++ ++ start_ptr = cur_ptr = (unsigned char *)ph->tag; ++ while ((cur_ptr - start_ptr) < ntohs(ph->length)) { ++ /* prevent un-alignment access */ ++ tagType = (unsigned short)((cur_ptr[0] << 8) + cur_ptr[1]); ++ tagLen = (unsigned short)((cur_ptr[2] << 8) + cur_ptr[3]); ++ if (tagType == type) ++ return cur_ptr; ++ cur_ptr = cur_ptr + TAG_HDR_LEN + tagLen; ++ } ++ return NULL; ++} ++ ++static int __nat25_add_pppoe_tag(struct sk_buff *skb, struct pppoe_tag *tag) ++{ ++ struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN); ++ int data_len; ++ ++ data_len = tag->tag_len + TAG_HDR_LEN; ++ if (skb_tailroom(skb) < data_len) { ++ _DEBUG_ERR("skb_tailroom() failed in add SID tag!\n"); ++ return -1; ++ } ++ ++ skb_put(skb, data_len); ++ /* have a room for new tag */ ++ memmove(((unsigned char *)ph->tag + data_len), (unsigned char *)ph->tag, ntohs(ph->length)); ++ ph->length = htons(ntohs(ph->length) + data_len); ++ memcpy((unsigned char *)ph->tag, tag, data_len); ++ return data_len; ++} ++ ++static int skb_pull_and_merge(struct sk_buff *skb, unsigned char *src, int len) ++{ ++ int tail_len; ++ unsigned long end, tail; ++ ++ if ((src+len) > skb_tail_pointer(skb) || skb->len < len) ++ return -1; ++ ++ tail = (unsigned long)skb_tail_pointer(skb); ++ end = (unsigned long)src+len; ++ if (tail < end) ++ return -1; ++ ++ tail_len = (int)(tail-end); ++ if (tail_len > 0) ++ memmove(src, src+len, tail_len); ++ ++ skb_trim(skb, skb->len-len); ++ return 0; ++} ++ ++static unsigned long __nat25_timeout(struct adapter *priv) ++{ ++ unsigned long timeout; ++ ++ timeout = jiffies - NAT25_AGEING_TIME*HZ; ++ ++ return timeout; ++} ++ ++static int __nat25_has_expired(struct adapter *priv, ++ struct nat25_network_db_entry *fdb) ++{ ++ if (time_before_eq(fdb->ageing_timer, __nat25_timeout(priv))) ++ return 1; ++ ++ return 0; ++} ++ ++static void __nat25_generate_ipv4_network_addr(unsigned char *networkAddr, ++ unsigned int *ipAddr) ++{ ++ memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); ++ ++ networkAddr[0] = NAT25_IPV4; ++ memcpy(networkAddr+7, (unsigned char *)ipAddr, 4); ++} ++ ++static void __nat25_generate_pppoe_network_addr(unsigned char *networkAddr, ++ unsigned char *ac_mac, __be16 *sid) ++{ ++ memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); ++ ++ networkAddr[0] = NAT25_PPPOE; ++ memcpy(networkAddr+1, (unsigned char *)sid, 2); ++ memcpy(networkAddr+3, (unsigned char *)ac_mac, 6); ++} ++ ++static void __nat25_generate_ipv6_network_addr(unsigned char *networkAddr, ++ unsigned int *ipAddr) ++{ ++ memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); ++ ++ networkAddr[0] = NAT25_IPV6; ++ memcpy(networkAddr+1, (unsigned char *)ipAddr, 16); ++} ++ ++static unsigned char *scan_tlv(unsigned char *data, int len, unsigned char tag, unsigned char len8b) ++{ ++ while (len > 0) { ++ if (*data == tag && *(data+1) == len8b && len >= len8b*8) ++ return data+2; ++ ++ len -= (*(data+1))*8; ++ data += (*(data+1))*8; ++ } ++ return NULL; ++} ++ ++static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char *replace_mac) ++{ ++ struct icmp6hdr *icmphdr = (struct icmp6hdr *)data; ++ unsigned char *mac; ++ ++ if (icmphdr->icmp6_type == NDISC_ROUTER_SOLICITATION) { ++ if (len >= 8) { ++ mac = scan_tlv(&data[8], len-8, 1, 1); ++ if (mac) { ++ _DEBUG_INFO("Router Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], ++ replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); ++ memcpy(mac, replace_mac, 6); ++ return 1; ++ } ++ } ++ } else if (icmphdr->icmp6_type == NDISC_ROUTER_ADVERTISEMENT) { ++ if (len >= 16) { ++ mac = scan_tlv(&data[16], len-16, 1, 1); ++ if (mac) { ++ _DEBUG_INFO("Router Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], ++ replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); ++ memcpy(mac, replace_mac, 6); ++ return 1; ++ } ++ } ++ } else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) { ++ if (len >= 24) { ++ mac = scan_tlv(&data[24], len-24, 1, 1); ++ if (mac) { ++ _DEBUG_INFO("Neighbor Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], ++ replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); ++ memcpy(mac, replace_mac, 6); ++ return 1; ++ } ++ } ++ } else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) { ++ if (len >= 24) { ++ mac = scan_tlv(&data[24], len-24, 2, 1); ++ if (mac) { ++ _DEBUG_INFO("Neighbor Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], ++ replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); ++ memcpy(mac, replace_mac, 6); ++ return 1; ++ } ++ } ++ } else if (icmphdr->icmp6_type == NDISC_REDIRECT) { ++ if (len >= 40) { ++ mac = scan_tlv(&data[40], len-40, 2, 1); ++ if (mac) { ++ _DEBUG_INFO("Redirect, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], ++ replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); ++ memcpy(mac, replace_mac, 6); ++ return 1; ++ } ++ } ++ } ++ return 0; ++} ++ ++static int __nat25_network_hash(unsigned char *networkAddr) ++{ ++ if (networkAddr[0] == NAT25_IPV4) { ++ unsigned long x; ++ ++ x = networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; ++ ++ return x & (NAT25_HASH_SIZE - 1); ++ } else if (networkAddr[0] == NAT25_IPX) { ++ unsigned long x; ++ ++ x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ ++ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; ++ ++ return x & (NAT25_HASH_SIZE - 1); ++ } else if (networkAddr[0] == NAT25_APPLE) { ++ unsigned long x; ++ ++ x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3]; ++ ++ return x & (NAT25_HASH_SIZE - 1); ++ } else if (networkAddr[0] == NAT25_PPPOE) { ++ unsigned long x; ++ ++ x = networkAddr[0] ^ networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8]; ++ ++ return x & (NAT25_HASH_SIZE - 1); ++ } else if (networkAddr[0] == NAT25_IPV6) { ++ unsigned long x; ++ ++ x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ ++ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10] ^ ++ networkAddr[11] ^ networkAddr[12] ^ networkAddr[13] ^ networkAddr[14] ^ networkAddr[15] ^ ++ networkAddr[16]; ++ ++ return x & (NAT25_HASH_SIZE - 1); ++ } else { ++ unsigned long x = 0; ++ int i; ++ ++ for (i = 0; i < MAX_NETWORK_ADDR_LEN; i++) ++ x ^= networkAddr[i]; ++ ++ return x & (NAT25_HASH_SIZE - 1); ++ } ++} ++ ++static void __network_hash_link(struct adapter *priv, ++ struct nat25_network_db_entry *ent, int hash) ++{ ++ /* Caller must spin_lock already! */ ++ ent->next_hash = priv->nethash[hash]; ++ if (ent->next_hash) ++ ent->next_hash->pprev_hash = &ent->next_hash; ++ priv->nethash[hash] = ent; ++ ent->pprev_hash = &priv->nethash[hash]; ++} ++ ++static void __network_hash_unlink(struct nat25_network_db_entry *ent) ++{ ++ /* Caller must spin_lock already! */ ++ *ent->pprev_hash = ent->next_hash; ++ if (ent->next_hash) ++ ent->next_hash->pprev_hash = ent->pprev_hash; ++ ent->next_hash = NULL; ++ ent->pprev_hash = NULL; ++} ++ ++static void __nat25_db_network_insert(struct adapter *priv, ++ unsigned char *macAddr, unsigned char *networkAddr) ++{ ++ struct nat25_network_db_entry *db; ++ int hash; ++ ++ spin_lock_bh(&priv->br_ext_lock); ++ hash = __nat25_network_hash(networkAddr); ++ db = priv->nethash[hash]; ++ while (db) { ++ if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) { ++ memcpy(db->macAddr, macAddr, ETH_ALEN); ++ db->ageing_timer = jiffies; ++ spin_unlock_bh(&priv->br_ext_lock); ++ return; ++ } ++ db = db->next_hash; ++ } ++ db = kmalloc(sizeof(*db), GFP_ATOMIC); ++ if (!db) { ++ spin_unlock_bh(&priv->br_ext_lock); ++ return; ++ } ++ memcpy(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN); ++ memcpy(db->macAddr, macAddr, ETH_ALEN); ++ atomic_set(&db->use_count, 1); ++ db->ageing_timer = jiffies; ++ ++ __network_hash_link(priv, db, hash); ++ ++ spin_unlock_bh(&priv->br_ext_lock); ++} ++ ++static void __nat25_db_print(struct adapter *priv) ++{ ++} ++ ++/* ++ * NAT2.5 interface ++ */ ++ ++void nat25_db_cleanup(struct adapter *priv) ++{ ++ int i; ++ ++ spin_lock_bh(&priv->br_ext_lock); ++ ++ for (i = 0; i < NAT25_HASH_SIZE; i++) { ++ struct nat25_network_db_entry *f; ++ f = priv->nethash[i]; ++ while (f) { ++ struct nat25_network_db_entry *g; ++ ++ g = f->next_hash; ++ if (priv->scdb_entry == f) { ++ memset(priv->scdb_mac, 0, ETH_ALEN); ++ memset(priv->scdb_ip, 0, 4); ++ priv->scdb_entry = NULL; ++ } ++ __network_hash_unlink(f); ++ kfree(f); ++ f = g; ++ } ++ } ++ spin_unlock_bh(&priv->br_ext_lock); ++} ++ ++void nat25_db_expire(struct adapter *priv) ++{ ++ int i; ++ ++ spin_lock_bh(&priv->br_ext_lock); ++ ++ for (i = 0; i < NAT25_HASH_SIZE; i++) { ++ struct nat25_network_db_entry *f; ++ f = priv->nethash[i]; ++ ++ while (f) { ++ struct nat25_network_db_entry *g; ++ g = f->next_hash; ++ ++ if (__nat25_has_expired(priv, f)) { ++ if (atomic_dec_and_test(&f->use_count)) { ++ if (priv->scdb_entry == f) { ++ memset(priv->scdb_mac, 0, ETH_ALEN); ++ memset(priv->scdb_ip, 0, 4); ++ priv->scdb_entry = NULL; ++ } ++ __network_hash_unlink(f); ++ kfree(f); ++ } ++ } ++ f = g; ++ } ++ } ++ spin_unlock_bh(&priv->br_ext_lock); ++} ++ ++int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method) ++{ ++ unsigned short protocol; ++ unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; ++ unsigned int tmp; ++ ++ if (!skb) ++ return -1; ++ ++ if ((method <= NAT25_MIN) || (method >= NAT25_MAX)) ++ return -1; ++ ++ protocol = be16_to_cpu(*((__be16 *)(skb->data + 2 * ETH_ALEN))); ++ ++ /*---------------------------------------------------*/ ++ /* Handle IP frame */ ++ /*---------------------------------------------------*/ ++ if (protocol == ETH_P_IP) { ++ struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN); ++ ++ if (((unsigned char *)(iph) + (iph->ihl<<2)) >= (skb->data + ETH_HLEN + skb->len)) { ++ DEBUG_WARN("NAT25: malformed IP packet !\n"); ++ return -1; ++ } ++ ++ switch (method) { ++ case NAT25_CHECK: ++ return -1; ++ case NAT25_INSERT: ++ /* some multicast with source IP is all zero, maybe other case is illegal */ ++ /* in class A, B, C, host address is all zero or all one is illegal */ ++ if (iph->saddr == 0) ++ return 0; ++ tmp = be32_to_cpu(iph->saddr); ++ DEBUG_INFO("NAT25: Insert IP, SA =%08x, DA =%08x\n", tmp, iph->daddr); ++ __nat25_generate_ipv4_network_addr(networkAddr, &tmp); ++ /* record source IP address and , source mac address into db */ ++ __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); ++ ++ __nat25_db_print(priv); ++ return 0; ++ default: ++ return -1; ++ } ++ } else if (protocol == ETH_P_ARP) { ++ /*---------------------------------------------------*/ ++ /* Handle ARP frame */ ++ /*---------------------------------------------------*/ ++ struct arphdr *arp = (struct arphdr *)(skb->data + ETH_HLEN); ++ unsigned char *arp_ptr = (unsigned char *)(arp + 1); ++ unsigned int *sender; ++ ++ if (arp->ar_pro != __constant_htons(ETH_P_IP)) { ++ DEBUG_WARN("NAT25: arp protocol unknown (%4x)!\n", be16_to_cpu(arp->ar_pro)); ++ return -1; ++ } ++ ++ switch (method) { ++ case NAT25_CHECK: ++ return 0; /* skb_copy for all ARP frame */ ++ case NAT25_INSERT: ++ DEBUG_INFO("NAT25: Insert ARP, MAC =%02x%02x%02x%02x%02x%02x\n", arp_ptr[0], ++ arp_ptr[1], arp_ptr[2], arp_ptr[3], arp_ptr[4], arp_ptr[5]); ++ ++ /* change to ARP sender mac address to wlan STA address */ ++ memcpy(arp_ptr, GET_MY_HWADDR(priv), ETH_ALEN); ++ arp_ptr += arp->ar_hln; ++ sender = (unsigned int *)arp_ptr; ++ __nat25_generate_ipv4_network_addr(networkAddr, sender); ++ __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); ++ __nat25_db_print(priv); ++ return 0; ++ default: ++ return -1; ++ } ++ } else if ((protocol == ETH_P_PPP_DISC) || ++ (protocol == ETH_P_PPP_SES)) { ++ /*---------------------------------------------------*/ ++ /* Handle PPPoE frame */ ++ /*---------------------------------------------------*/ ++ struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN); ++ unsigned short *pMagic; ++ ++ switch (method) { ++ case NAT25_CHECK: ++ if (ph->sid == 0) ++ return 0; ++ return 1; ++ case NAT25_INSERT: ++ if (ph->sid == 0) { /* Discovery phase according to tag */ ++ if (ph->code == PADI_CODE || ph->code == PADR_CODE) { ++ if (priv->ethBrExtInfo.addPPPoETag) { ++ struct pppoe_tag *tag, *pOldTag; ++ unsigned char tag_buf[40]; ++ int old_tag_len = 0; ++ ++ tag = (struct pppoe_tag *)tag_buf; ++ pOldTag = (struct pppoe_tag *)__nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID)); ++ if (pOldTag) { /* if SID existed, copy old value and delete it */ ++ old_tag_len = ntohs(pOldTag->tag_len); ++ if (old_tag_len+TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN > sizeof(tag_buf)) { ++ DEBUG_ERR("SID tag length too long!\n"); ++ return -1; ++ } ++ ++ memcpy(tag->tag_data+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN, ++ pOldTag->tag_data, old_tag_len); ++ ++ if (skb_pull_and_merge(skb, (unsigned char *)pOldTag, TAG_HDR_LEN+old_tag_len) < 0) { ++ DEBUG_ERR("call skb_pull_and_merge() failed in PADI/R packet!\n"); ++ return -1; ++ } ++ ph->length = htons(ntohs(ph->length)-TAG_HDR_LEN-old_tag_len); ++ } ++ ++ tag->tag_type = PTT_RELAY_SID; ++ tag->tag_len = htons(MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN+old_tag_len); ++ ++ /* insert the magic_code+client mac in relay tag */ ++ pMagic = (unsigned short *)tag->tag_data; ++ *pMagic = htons(MAGIC_CODE); ++ memcpy(tag->tag_data+MAGIC_CODE_LEN, skb->data+ETH_ALEN, ETH_ALEN); ++ ++ /* Add relay tag */ ++ if (__nat25_add_pppoe_tag(skb, tag) < 0) ++ return -1; ++ ++ DEBUG_INFO("NAT25: Insert PPPoE, forward %s packet\n", ++ (ph->code == PADI_CODE ? "PADI" : "PADR")); ++ } else { /* not add relay tag */ ++ if (priv->pppoe_connection_in_progress && ++ memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) { ++ DEBUG_ERR("Discard PPPoE packet due to another PPPoE connection is in progress!\n"); ++ return -2; ++ } ++ ++ if (priv->pppoe_connection_in_progress == 0) ++ memcpy(priv->pppoe_addr, skb->data+ETH_ALEN, ETH_ALEN); ++ ++ priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE; ++ } ++ } else { ++ return -1; ++ } ++ } else { /* session phase */ ++ DEBUG_INFO("NAT25: Insert PPPoE, insert session packet to %s\n", skb->dev->name); ++ ++ __nat25_generate_pppoe_network_addr(networkAddr, skb->data, &ph->sid); ++ ++ __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); ++ ++ __nat25_db_print(priv); ++ ++ if (!priv->ethBrExtInfo.addPPPoETag && ++ priv->pppoe_connection_in_progress && ++ !memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) ++ priv->pppoe_connection_in_progress = 0; ++ } ++ return 0; ++ default: ++ return -1; ++ } ++ } else if (protocol == 0x888e) { ++ /*---------------------------------------------------*/ ++ /* Handle EAP frame */ ++ /*---------------------------------------------------*/ ++ switch (method) { ++ case NAT25_CHECK: ++ return -1; ++ case NAT25_INSERT: ++ return 0; ++ default: ++ return -1; ++ } ++ } else if ((protocol == 0xe2ae) || (protocol == 0xe2af)) { ++ /*---------------------------------------------------*/ ++ /* Handle C-Media proprietary frame */ ++ /*---------------------------------------------------*/ ++ switch (method) { ++ case NAT25_CHECK: ++ return -1; ++ case NAT25_INSERT: ++ return 0; ++ default: ++ return -1; ++ } ++ } else if (protocol == ETH_P_IPV6) { ++ /*------------------------------------------------*/ ++ /* Handle IPV6 frame */ ++ /*------------------------------------------------*/ ++ struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN); ++ ++ if (sizeof(*iph) >= (skb->len - ETH_HLEN)) { ++ DEBUG_WARN("NAT25: malformed IPv6 packet !\n"); ++ return -1; ++ } ++ ++ switch (method) { ++ case NAT25_CHECK: ++ if (skb->data[0] & 1) ++ return 0; ++ return -1; ++ case NAT25_INSERT: ++ DEBUG_INFO("NAT25: Insert IP, SA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x," ++ " DA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n", ++ iph->saddr.s6_addr16[0], iph->saddr.s6_addr16[1], iph->saddr.s6_addr16[2], iph->saddr.s6_addr16[3], ++ iph->saddr.s6_addr16[4], iph->saddr.s6_addr16[5], iph->saddr.s6_addr16[6], iph->saddr.s6_addr16[7], ++ iph->daddr.s6_addr16[0], iph->daddr.s6_addr16[1], iph->daddr.s6_addr16[2], iph->daddr.s6_addr16[3], ++ iph->daddr.s6_addr16[4], iph->daddr.s6_addr16[5], iph->daddr.s6_addr16[6], iph->daddr.s6_addr16[7]); ++ ++ if (memcmp(&iph->saddr, "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16)) { ++ __nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->saddr); ++ __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); ++ __nat25_db_print(priv); ++ ++ if (iph->nexthdr == IPPROTO_ICMPV6 && ++ skb->len > (ETH_HLEN + sizeof(*iph) + 4)) { ++ if (update_nd_link_layer_addr(skb->data + ETH_HLEN + sizeof(*iph), ++ skb->len - ETH_HLEN - sizeof(*iph), GET_MY_HWADDR(priv))) { ++ struct icmp6hdr *hdr = (struct icmp6hdr *)(skb->data + ETH_HLEN + sizeof(*iph)); ++ hdr->icmp6_cksum = 0; ++ hdr->icmp6_cksum = csum_ipv6_magic(&iph->saddr, &iph->daddr, ++ iph->payload_len, ++ IPPROTO_ICMPV6, ++ csum_partial((__u8 *)hdr, iph->payload_len, 0)); ++ } ++ } ++ } ++ return 0; ++ default: ++ return -1; ++ } ++ } ++ return -1; ++} ++ ++#define SERVER_PORT 67 ++#define CLIENT_PORT 68 ++#define DHCP_MAGIC 0x63825363 ++#define BROADCAST_FLAG 0x8000 ++ ++struct dhcpMessage { ++ u_int8_t op; ++ u_int8_t htype; ++ u_int8_t hlen; ++ u_int8_t hops; ++ u_int32_t xid; ++ __be16 secs; ++ __be16 flags; ++ __be32 ciaddr; ++ __be32 yiaddr; ++ __be32 siaddr; ++ __be32 giaddr; ++ u_int8_t chaddr[16]; ++ u_int8_t sname[64]; ++ u_int8_t file[128]; ++ __be32 cookie; ++ u_int8_t options[308]; /* 312 - cookie */ ++}; ++ ++void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb) ++{ ++ if (!skb) ++ return; ++ ++ if (!priv->ethBrExtInfo.dhcp_bcst_disable) { ++ __be16 protocol = *((__be16 *)(skb->data + 2 * ETH_ALEN)); ++ ++ if (protocol == __constant_htons(ETH_P_IP)) { /* IP */ ++ struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN); ++ ++ if (iph->protocol == IPPROTO_UDP) { /* UDP */ ++ struct udphdr *udph = (struct udphdr *)((size_t)iph + (iph->ihl << 2)); ++ ++ if ((udph->source == __constant_htons(CLIENT_PORT)) && ++ (udph->dest == __constant_htons(SERVER_PORT))) { /* DHCP request */ ++ struct dhcpMessage *dhcph = ++ (struct dhcpMessage *)((size_t)udph + sizeof(struct udphdr)); ++ u32 cookie = be32_to_cpu((__be32)dhcph->cookie); ++ ++ if (cookie == DHCP_MAGIC) { /* match magic word */ ++ if (!(dhcph->flags & htons(BROADCAST_FLAG))) { ++ /* if not broadcast */ ++ register int sum = 0; ++ ++ DEBUG_INFO("DHCP: change flag of DHCP request to broadcast.\n"); ++ /* or BROADCAST flag */ ++ dhcph->flags |= htons(BROADCAST_FLAG); ++ /* recalculate checksum */ ++ sum = ~(udph->check) & 0xffff; ++ sum += be16_to_cpu(dhcph->flags); ++ while (sum >> 16) ++ sum = (sum & 0xffff) + (sum >> 16); ++ udph->check = ~sum; ++ } ++ } ++ } ++ } ++ } ++ } ++} ++ ++void *scdb_findEntry(struct adapter *priv, unsigned char *macAddr, ++ unsigned char *ipAddr) ++{ ++ unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; ++ struct nat25_network_db_entry *db; ++ int hash; ++ ++ __nat25_generate_ipv4_network_addr(networkAddr, (unsigned int *)ipAddr); ++ hash = __nat25_network_hash(networkAddr); ++ db = priv->nethash[hash]; ++ while (db) { ++ if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) { ++ return (void *)db; ++ } ++ ++ db = db->next_hash; ++ } ++ ++ return NULL; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_cmd.c b/drivers/staging/r8188eu/core/rtw_cmd.c +new file mode 100644 +index 000000000000..ce73ac7cf973 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_cmd.c +@@ -0,0 +1,2128 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_CMD_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/mlme_osdep.h" ++#include "../include/rtw_br_ext.h" ++#include "../include/rtw_mlme_ext.h" ++ ++/* ++Caller and the rtw_cmd_thread can protect cmd_q by spin_lock. ++No irqsave is necessary. ++*/ ++ ++static int _rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) ++{ ++ int res = _SUCCESS; ++ ++ sema_init(&pcmdpriv->cmd_queue_sema, 0); ++ /* sema_init(&(pcmdpriv->cmd_done_sema), 0); */ ++ sema_init(&pcmdpriv->terminate_cmdthread_sema, 0); ++ ++ _rtw_init_queue(&pcmdpriv->cmd_queue); ++ ++ /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ ++ ++ pcmdpriv->cmd_seq = 1; ++ ++ pcmdpriv->cmd_allocated_buf = kzalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ, ++ GFP_KERNEL); ++ ++ if (!pcmdpriv->cmd_allocated_buf) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ - ((size_t)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ - 1)); ++ ++ pcmdpriv->rsp_allocated_buf = kzalloc(MAX_RSPSZ + 4, GFP_KERNEL); ++ ++ if (!pcmdpriv->rsp_allocated_buf) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - ((size_t)(pcmdpriv->rsp_allocated_buf) & 3); ++ ++ pcmdpriv->cmd_issued_cnt = 0; ++ pcmdpriv->cmd_done_cnt = 0; ++ pcmdpriv->rsp_cnt = 0; ++exit: ++ ++ return res; ++} ++ ++static void c2h_wk_callback(struct work_struct *work); ++ ++static int _rtw_init_evt_priv(struct evt_priv *pevtpriv) ++{ ++ int res = _SUCCESS; ++ ++ /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ ++ atomic_set(&pevtpriv->event_seq, 0); ++ pevtpriv->evt_done_cnt = 0; ++ ++ _init_workitem(&pevtpriv->c2h_wk, c2h_wk_callback, NULL); ++ pevtpriv->c2h_wk_alive = false; ++ pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN + 1); ++ ++ return res; ++} ++ ++void rtw_free_evt_priv(struct evt_priv *pevtpriv) ++{ ++ _cancel_workitem_sync(&pevtpriv->c2h_wk); ++ while (pevtpriv->c2h_wk_alive) ++ msleep(10); ++ ++ while (!rtw_cbuf_empty(pevtpriv->c2h_queue)) { ++ void *c2h = rtw_cbuf_pop(pevtpriv->c2h_queue); ++ if (c2h && c2h != (void *)pevtpriv) ++ kfree(c2h); ++ } ++} ++ ++static void _rtw_free_cmd_priv(struct cmd_priv *pcmdpriv) ++{ ++ if (pcmdpriv) { ++ kfree(pcmdpriv->cmd_allocated_buf); ++ kfree(pcmdpriv->rsp_allocated_buf); ++ } ++} ++ ++/* ++Calling Context: ++ ++rtw_enqueue_cmd can only be called between kernel thread, ++since only spin_lock is used. ++ ++ISR/Call-Back functions can't call this sub-function. ++ ++*/ ++ ++static int _rtw_enqueue_cmd(struct __queue *queue, struct cmd_obj *obj) ++{ ++ unsigned long flags; ++ ++ if (!obj) ++ goto exit; ++ ++ spin_lock_irqsave(&queue->lock, flags); ++ ++ list_add_tail(&obj->list, &queue->queue); ++ ++ spin_unlock_irqrestore(&queue->lock, flags); ++ ++exit: ++ ++ return _SUCCESS; ++} ++ ++static struct cmd_obj *_rtw_dequeue_cmd(struct __queue *queue) ++{ ++ struct cmd_obj *obj; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&queue->lock, flags); ++ if (list_empty(&queue->queue)) { ++ obj = NULL; ++ } else { ++ obj = container_of((&queue->queue)->next, struct cmd_obj, list); ++ rtw_list_delete(&obj->list); ++ } ++ ++ spin_unlock_irqrestore(&queue->lock, flags); ++ ++ return obj; ++} ++ ++u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) ++{ ++ u32 res; ++ ++ res = _rtw_init_cmd_priv(pcmdpriv); ++ ++ return res; ++} ++ ++u32 rtw_init_evt_priv(struct evt_priv *pevtpriv) ++{ ++ int res; ++ ++ res = _rtw_init_evt_priv(pevtpriv); ++ ++ return res; ++} ++ ++void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv) ++{ ++ _rtw_free_cmd_priv(pcmdpriv); ++} ++ ++static int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) ++{ ++ u8 bAllow = false; /* set to true to allow enqueuing cmd when hw_init_completed is false */ ++ ++ /* To decide allow or not */ ++ if ((pcmdpriv->padapter->pwrctrlpriv.bHWPwrPindetect) && ++ (!pcmdpriv->padapter->registrypriv.usbss_enable)) { ++ if (cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)cmd_obj->parmbuf; ++ if (pdrvextra_cmd_parm->ec_id == POWER_SAVING_CTRL_WK_CID) ++ bAllow = true; ++ } ++ } ++ ++ if (cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan)) ++ bAllow = true; ++ ++ if ((!pcmdpriv->padapter->hw_init_completed && !bAllow) || ++ !pcmdpriv->cmdthd_running) /* com_thread not running */ ++ return _FAIL; ++ return _SUCCESS; ++} ++ ++u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) ++{ ++ int res = _FAIL; ++ struct adapter *padapter = pcmdpriv->padapter; ++ ++ if (!cmd_obj) ++ goto exit; ++ ++ cmd_obj->padapter = padapter; ++ ++ res = rtw_cmd_filter(pcmdpriv, cmd_obj); ++ if (_FAIL == res) { ++ rtw_free_cmd_obj(cmd_obj); ++ goto exit; ++ } ++ ++ res = _rtw_enqueue_cmd(&pcmdpriv->cmd_queue, cmd_obj); ++ ++ if (res == _SUCCESS) ++ up(&pcmdpriv->cmd_queue_sema); ++ ++exit: ++ ++ return res; ++} ++ ++struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv) ++{ ++ struct cmd_obj *cmd_obj; ++ ++ cmd_obj = _rtw_dequeue_cmd(&pcmdpriv->cmd_queue); ++ ++ return cmd_obj; ++} ++ ++void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv) ++{ ++ ++ pcmdpriv->cmd_done_cnt++; ++ /* up(&(pcmdpriv->cmd_done_sema)); */ ++ ++} ++ ++void rtw_free_cmd_obj(struct cmd_obj *pcmd) ++{ ++ ++ if ((pcmd->cmdcode != _JoinBss_CMD_) && (pcmd->cmdcode != _CreateBss_CMD_)) { ++ /* free parmbuf in cmd_obj */ ++ kfree(pcmd->parmbuf); ++ } ++ ++ if (pcmd->rsp) { ++ if (pcmd->rspsz != 0) { ++ /* free rsp in cmd_obj */ ++ kfree(pcmd->rsp); ++ } ++ } ++ ++ /* free cmd_obj */ ++ kfree(pcmd); ++ ++} ++ ++int rtw_cmd_thread(void *context) ++{ ++ u8 ret; ++ struct cmd_obj *pcmd; ++ u8 *pcmdbuf; ++ u8 (*cmd_hdl)(struct adapter *padapter, u8 *pbuf); ++ void (*pcmd_callback)(struct adapter *dev, struct cmd_obj *pcmd); ++ struct adapter *padapter = (struct adapter *)context; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ thread_enter("RTW_CMD_THREAD"); ++ ++ pcmdbuf = pcmdpriv->cmd_buf; ++ ++ pcmdpriv->cmdthd_running = true; ++ up(&pcmdpriv->terminate_cmdthread_sema); ++ ++ while (1) { ++ if (_rtw_down_sema(&pcmdpriv->cmd_queue_sema) == _FAIL) ++ break; ++ ++ if (padapter->bDriverStopped || ++ padapter->bSurpriseRemoved) { ++ DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n", ++ __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__); ++ break; ++ } ++_next: ++ if (padapter->bDriverStopped || ++ padapter->bSurpriseRemoved) { ++ DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n", ++ __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__); ++ break; ++ } ++ ++ pcmd = rtw_dequeue_cmd(pcmdpriv); ++ if (!pcmd) ++ continue; ++ ++ if (_FAIL == rtw_cmd_filter(pcmdpriv, pcmd)) { ++ pcmd->res = H2C_DROPPED; ++ goto post_process; ++ } ++ ++ pcmdpriv->cmd_issued_cnt++; ++ ++ pcmd->cmdsz = _RND4((pcmd->cmdsz));/* _RND4 */ ++ ++ memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz); ++ ++ if (pcmd->cmdcode < ARRAY_SIZE(wlancmds)) { ++ cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns; ++ ++ if (cmd_hdl) { ++ ret = cmd_hdl(pcmd->padapter, pcmdbuf); ++ pcmd->res = ret; ++ } ++ ++ pcmdpriv->cmd_seq++; ++ } else { ++ pcmd->res = H2C_PARAMETERS_ERROR; ++ } ++ ++ cmd_hdl = NULL; ++ ++post_process: ++ ++ /* call callback function for post-processed */ ++ if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) { ++ pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback; ++ if (!pcmd_callback) ++ rtw_free_cmd_obj(pcmd); ++ else ++ /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!= NULL) */ ++ pcmd_callback(pcmd->padapter, pcmd);/* need conider that free cmd_obj in rtw_cmd_callback */ ++ } else { ++ rtw_free_cmd_obj(pcmd); ++ } ++ ++ flush_signals_thread(); ++ ++ goto _next; ++ } ++ pcmdpriv->cmdthd_running = false; ++ ++ /* free all cmd_obj resources */ ++ do { ++ pcmd = rtw_dequeue_cmd(pcmdpriv); ++ if (!pcmd) ++ break; ++ ++ /* DBG_88E("%s: leaving... drop cmdcode:%u\n", __func__, pcmd->cmdcode); */ ++ ++ rtw_free_cmd_obj(pcmd); ++ } while (1); ++ ++ up(&pcmdpriv->terminate_cmdthread_sema); ++ ++ thread_exit(); ++} ++ ++u8 rtw_setstandby_cmd(struct adapter *padapter, uint action) ++{ ++ struct cmd_obj *ph2c; ++ struct usb_suspend_parm *psetusbsuspend; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ u8 ret = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ psetusbsuspend = kzalloc(sizeof(struct usb_suspend_parm), GFP_ATOMIC); ++ if (!psetusbsuspend) { ++ kfree(ph2c); ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ psetusbsuspend->action = action; ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psetusbsuspend, GEN_CMD_CODE(_SetUsbSuspend)); ++ ++ ret = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return ret; ++} ++ ++/* ++rtw_sitesurvey_cmd(~) ++ ### NOTE:#### (!!!!) ++ MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock ++*/ ++u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, int ssid_num, ++ struct rtw_ieee80211_channel *ch, int ch_num) ++{ ++ u8 res = _FAIL; ++ struct cmd_obj *ph2c; ++ struct sitesurvey_parm *psurveyPara; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1); ++ } ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ p2p_ps_wk_cmd(padapter, P2P_PS_SCAN, 1); ++ } ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) ++ return _FAIL; ++ ++ psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC); ++ if (!psurveyPara) { ++ kfree(ph2c); ++ return _FAIL; ++ } ++ ++ rtw_free_network_queue(padapter, false); ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey)); ++ ++ /* psurveyPara->bsslimit = 48; */ ++ psurveyPara->scan_mode = pmlmepriv->scan_mode; ++ ++ /* prepare ssid list */ ++ if (ssid) { ++ int i; ++ for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) { ++ if (ssid[i].SsidLength) { ++ memcpy(&psurveyPara->ssid[i], &ssid[i], sizeof(struct ndis_802_11_ssid)); ++ psurveyPara->ssid_num++; ++ } ++ } ++ } ++ ++ /* prepare channel list */ ++ if (ch) { ++ int i; ++ for (i = 0; i < ch_num && i < RTW_CHANNEL_SCAN_AMOUNT; i++) { ++ if (ch[i].hw_value && !(ch[i].flags & RTW_IEEE80211_CHAN_DISABLED)) { ++ memcpy(&psurveyPara->ch[i], &ch[i], sizeof(struct rtw_ieee80211_channel)); ++ psurveyPara->ch_num++; ++ } ++ } ++ } ++ ++ set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++ if (res == _SUCCESS) { ++ pmlmepriv->scan_start_time = jiffies; ++ ++ _set_timer(&pmlmepriv->scan_to_timer, SCANNING_TIMEOUT); ++ ++ rtw_led_control(padapter, LED_CTL_SITE_SURVEY); ++ ++ pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */ ++ } else { ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); ++ } ++ ++ return res; ++} ++ ++u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset) ++{ ++ struct cmd_obj *ph2c; ++ struct setdatarate_parm *pbsetdataratepara; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pbsetdataratepara = kzalloc(sizeof(struct setdatarate_parm), GFP_ATOMIC); ++ if (!pbsetdataratepara) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate)); ++ pbsetdataratepara->mac_id = 5; ++ memcpy(pbsetdataratepara->datarates, rateset, NumRates); ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_setbasicrate_cmd(struct adapter *padapter, u8 *rateset) ++{ ++ struct cmd_obj *ph2c; ++ struct setbasicrate_parm *pssetbasicratepara; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ pssetbasicratepara = kzalloc(sizeof(struct setbasicrate_parm), GFP_ATOMIC); ++ ++ if (!pssetbasicratepara) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pssetbasicratepara, _SetBasicRate_CMD_); ++ ++ memcpy(pssetbasicratepara->basicrates, rateset, NumRates); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++/* ++unsigned char rtw_setphy_cmd(unsigned char *adapter) ++ ++1. be called only after rtw_update_registrypriv_dev_network(~) or mp testing program ++2. for AdHoc/Ap mode or mp mode? ++ ++*/ ++u8 rtw_setphy_cmd(struct adapter *padapter, u8 modem, u8 ch) ++{ ++ struct cmd_obj *ph2c; ++ struct setphy_parm *psetphypara; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ psetphypara = kzalloc(sizeof(struct setphy_parm), GFP_ATOMIC); ++ ++ if (!psetphypara) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psetphypara, _SetPhy_CMD_); ++ ++ psetphypara->modem = modem; ++ psetphypara->rfchannel = ch; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_setbbreg_cmd(struct adapter *padapter, u8 offset, u8 val) ++{ ++ struct cmd_obj *ph2c; ++ struct writeBB_parm *pwritebbparm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ pwritebbparm = kzalloc(sizeof(struct writeBB_parm), GFP_ATOMIC); ++ ++ if (!pwritebbparm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pwritebbparm, GEN_CMD_CODE(_SetBBReg)); ++ ++ pwritebbparm->offset = offset; ++ pwritebbparm->value = val; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_getbbreg_cmd(struct adapter *padapter, u8 offset, u8 *pval) ++{ ++ struct cmd_obj *ph2c; ++ struct readBB_parm *prdbbparm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ prdbbparm = kzalloc(sizeof(struct readBB_parm), GFP_ATOMIC); ++ ++ if (!prdbbparm) { ++ kfree(ph2c); ++ return _FAIL; ++ } ++ ++ INIT_LIST_HEAD(&ph2c->list); ++ ph2c->cmdcode = GEN_CMD_CODE(_GetBBReg); ++ ph2c->parmbuf = (unsigned char *)prdbbparm; ++ ph2c->cmdsz = sizeof(struct readBB_parm); ++ ph2c->rsp = pval; ++ ph2c->rspsz = sizeof(struct readBB_rsp); ++ ++ prdbbparm->offset = offset; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_setrfreg_cmd(struct adapter *padapter, u8 offset, u32 val) ++{ ++ struct cmd_obj *ph2c; ++ struct writeRF_parm *pwriterfparm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ pwriterfparm = kzalloc(sizeof(struct writeRF_parm), GFP_ATOMIC); ++ ++ if (!pwriterfparm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg)); ++ ++ pwriterfparm->offset = offset; ++ pwriterfparm->value = val; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_getrfreg_cmd(struct adapter *padapter, u8 offset, u8 *pval) ++{ ++ struct cmd_obj *ph2c; ++ struct readRF_parm *prdrfparm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ prdrfparm = kzalloc(sizeof(struct readRF_parm), GFP_ATOMIC); ++ if (!prdrfparm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ INIT_LIST_HEAD(&ph2c->list); ++ ph2c->cmdcode = GEN_CMD_CODE(_GetRFReg); ++ ph2c->parmbuf = (unsigned char *)prdrfparm; ++ ph2c->cmdsz = sizeof(struct readRF_parm); ++ ph2c->rsp = pval; ++ ph2c->rspsz = sizeof(struct readRF_rsp); ++ ++ prdrfparm->offset = offset; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++} ++ ++void rtw_getbbrfreg_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ ++ ++ kfree(pcmd->parmbuf); ++ kfree(pcmd); ++ ++ if (padapter->registrypriv.mp_mode == 1) ++ padapter->mppriv.workparam.bcompleted = true; ++ ++} ++ ++void rtw_readtssi_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ ++ ++ kfree(pcmd->parmbuf); ++ kfree(pcmd); ++ ++ if (padapter->registrypriv.mp_mode == 1) ++ padapter->mppriv.workparam.bcompleted = true; ++ ++} ++ ++u8 rtw_createbss_cmd(struct adapter *padapter) ++{ ++ struct cmd_obj *pcmd; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct wlan_bssid_ex *pdev_network = &padapter->registrypriv.dev_network; ++ u8 res = _SUCCESS; ++ ++ rtw_led_control(padapter, LED_CTL_START_TO_LINK); ++ ++ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmd) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ INIT_LIST_HEAD(&pcmd->list); ++ pcmd->cmdcode = _CreateBss_CMD_; ++ pcmd->parmbuf = (unsigned char *)pdev_network; ++ pcmd->cmdsz = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network); ++ pcmd->rsp = NULL; ++ pcmd->rspsz = 0; ++ pdev_network->Length = pcmd->cmdsz; ++ res = rtw_enqueue_cmd(pcmdpriv, pcmd); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_createbss_cmd_ex(struct adapter *padapter, unsigned char *pbss, unsigned int sz) ++{ ++ struct cmd_obj *pcmd; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmd) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ INIT_LIST_HEAD(&pcmd->list); ++ pcmd->cmdcode = GEN_CMD_CODE(_CreateBss); ++ pcmd->parmbuf = pbss; ++ pcmd->cmdsz = sz; ++ pcmd->rsp = NULL; ++ pcmd->rspsz = 0; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, pcmd); ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) ++{ ++ u8 res = _SUCCESS; ++ uint t_len = 0; ++ struct wlan_bssid_ex *psecnetwork; ++ struct cmd_obj *pcmd; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct qos_priv *pqospriv = &pmlmepriv->qospriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ enum ndis_802_11_network_infra ndis_network_mode = pnetwork->network.InfrastructureMode; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ rtw_led_control(padapter, LED_CTL_START_TO_LINK); ++ ++ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmd) { ++ res = _FAIL; ++ goto exit; ++ } ++ /* for IEs is fix buf size */ ++ t_len = sizeof(struct wlan_bssid_ex); ++ ++ /* for hidden ap to set fw_state here */ ++ if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE)) { ++ switch (ndis_network_mode) { ++ case Ndis802_11IBSS: ++ set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); ++ break; ++ case Ndis802_11Infrastructure: ++ set_fwstate(pmlmepriv, WIFI_STATION_STATE); ++ break; ++ case Ndis802_11APMode: ++ case Ndis802_11AutoUnknown: ++ case Ndis802_11InfrastructureMax: ++ break; ++ } ++ } ++ ++ psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss; ++ if (!psecnetwork) { ++ kfree(pcmd); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ memset(psecnetwork, 0, t_len); ++ ++ memcpy(psecnetwork, &pnetwork->network, get_wlan_bssid_ex_sz(&pnetwork->network)); ++ ++ psecuritypriv->authenticator_ie[0] = (unsigned char)psecnetwork->IELength; ++ ++ if (psecnetwork->IELength - 12 < 255) { ++ memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], psecnetwork->IELength - 12); ++ } else { ++ memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], 255); ++ } ++ ++ psecnetwork->IELength = 0; ++ /* Added by Albert 2009/02/18 */ ++ /* If the the driver wants to use the bssid to create the connection. */ ++ /* If not, we have to copy the connecting AP's MAC address to it so that */ ++ /* the driver just has the bssid information for PMKIDList searching. */ ++ ++ if (!pmlmepriv->assoc_by_bssid) ++ memcpy(&pmlmepriv->assoc_bssid[0], &pnetwork->network.MacAddress[0], ETH_ALEN); ++ ++ psecnetwork->IELength = rtw_restruct_sec_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength); ++ ++ pqospriv->qos_option = 0; ++ ++ if (pregistrypriv->wmm_enable) { ++ u32 tmp_len; ++ ++ tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength, psecnetwork->IELength); ++ ++ if (psecnetwork->IELength != tmp_len) { ++ psecnetwork->IELength = tmp_len; ++ pqospriv->qos_option = 1; /* There is WMM IE in this corresp. beacon */ ++ } else { ++ pqospriv->qos_option = 0;/* There is no WMM IE in this corresp. beacon */ ++ } ++ } ++ ++ phtpriv->ht_option = false; ++ if (pregistrypriv->ht_enable) { ++ /* Added by Albert 2010/06/23 */ ++ /* For the WEP mode, we will use the bg mode to do the connection to avoid some IOT issue. */ ++ /* Especially for Realtek 8192u SoftAP. */ ++ if ((padapter->securitypriv.dot11PrivacyAlgrthm != _WEP40_) && ++ (padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_) && ++ (padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_)) { ++ /* rtw_restructure_ht_ie */ ++ rtw_restructure_ht_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], ++ pnetwork->network.IELength, &psecnetwork->IELength); ++ } ++ } ++ ++ pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.IEs, pnetwork->network.IELength); ++ ++ if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_TENDA) ++ padapter->pwrctrlpriv.smart_ps = 0; ++ else ++ padapter->pwrctrlpriv.smart_ps = padapter->registrypriv.smart_ps; ++ ++ DBG_88E("%s: smart_ps =%d\n", __func__, padapter->pwrctrlpriv.smart_ps); ++ ++ pcmd->cmdsz = get_wlan_bssid_ex_sz(psecnetwork);/* get cmdsz before endian conversion */ ++ ++ INIT_LIST_HEAD(&pcmd->list); ++ pcmd->cmdcode = _JoinBss_CMD_;/* GEN_CMD_CODE(_JoinBss) */ ++ pcmd->parmbuf = (unsigned char *)psecnetwork; ++ pcmd->rsp = NULL; ++ pcmd->rspsz = 0; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, pcmd); ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueue) /* for sta_mode */ ++{ ++ struct cmd_obj *cmdobj = NULL; ++ struct disconnect_parm *param = NULL; ++ struct cmd_priv *cmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ /* prepare cmd parameter */ ++ param = kzalloc(sizeof(*param), GFP_ATOMIC); ++ if (!param) { ++ res = _FAIL; ++ goto exit; ++ } ++ param->deauth_timeout_ms = deauth_timeout_ms; ++ ++ if (enqueue) { ++ /* need enqueue, prepare cmd_obj and enqueue */ ++ cmdobj = kzalloc(sizeof(*cmdobj), GFP_ATOMIC); ++ if (!cmdobj) { ++ res = _FAIL; ++ kfree(param); ++ goto exit; ++ } ++ init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_); ++ res = rtw_enqueue_cmd(cmdpriv, cmdobj); ++ } else { ++ /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ ++ if (H2C_SUCCESS != disconnect_hdl(padapter, (u8 *)param)) ++ res = _FAIL; ++ kfree(param); ++ } ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_setopmode_cmd(struct adapter *padapter, enum ndis_802_11_network_infra networktype) ++{ ++ struct cmd_obj *ph2c; ++ struct setopmode_parm *psetop; ++ ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!ph2c) { ++ res = false; ++ goto exit; ++ } ++ psetop = kzalloc(sizeof(struct setopmode_parm), GFP_KERNEL); ++ ++ if (!psetop) { ++ kfree(ph2c); ++ res = false; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_); ++ psetop->mode = (u8)networktype; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key) ++{ ++ struct cmd_obj *ph2c; ++ struct set_stakey_parm *psetstakey_para; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct set_stakey_rsp *psetstakey_rsp = NULL; ++ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct sta_info *sta = (struct sta_info *)psta; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL); ++ if (!psetstakey_para) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), GFP_KERNEL); ++ if (!psetstakey_rsp) { ++ kfree(ph2c); ++ kfree(psetstakey_para); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); ++ ph2c->rsp = (u8 *)psetstakey_rsp; ++ ph2c->rspsz = sizeof(struct set_stakey_rsp); ++ ++ memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN); ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) ++ psetstakey_para->algorithm = (unsigned char)psecuritypriv->dot11PrivacyAlgrthm; ++ else ++ GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, false); ++ ++ if (unicast_key) ++ memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16); ++ else ++ memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16); ++ ++ /* jeff: set this because at least sw key is ready */ ++ padapter->securitypriv.busetkipkey = true; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry, u8 enqueue) ++{ ++ struct cmd_obj *ph2c; ++ struct set_stakey_parm *psetstakey_para; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct set_stakey_rsp *psetstakey_rsp = NULL; ++ struct sta_info *sta = (struct sta_info *)psta; ++ u8 res = _SUCCESS; ++ ++ if (!enqueue) { ++ clear_cam_entry(padapter, entry); ++ } else { ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), ++ GFP_ATOMIC); ++ if (!psetstakey_para) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), ++ GFP_ATOMIC); ++ if (!psetstakey_rsp) { ++ kfree(ph2c); ++ kfree(psetstakey_para); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); ++ ph2c->rsp = (u8 *)psetstakey_rsp; ++ ph2c->rspsz = sizeof(struct set_stakey_rsp); ++ ++ memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN); ++ ++ psetstakey_para->algorithm = _NO_PRIVACY_; ++ ++ psetstakey_para->id = entry; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ } ++exit: ++ ++ return res; ++} ++ ++u8 rtw_setrttbl_cmd(struct adapter *padapter, struct setratable_parm *prate_table) ++{ ++ struct cmd_obj *ph2c; ++ struct setratable_parm *psetrttblparm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ psetrttblparm = kzalloc(sizeof(struct setratable_parm), GFP_KERNEL); ++ ++ if (!psetrttblparm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable)); ++ ++ memcpy(psetrttblparm, prate_table, sizeof(struct setratable_parm)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_getrttbl_cmd(struct adapter *padapter, struct getratable_rsp *pval) ++{ ++ struct cmd_obj *ph2c; ++ struct getratable_parm *pgetrttblparm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ pgetrttblparm = kzalloc(sizeof(struct getratable_parm), GFP_KERNEL); ++ ++ if (!pgetrttblparm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++/* init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable)); */ ++ ++ INIT_LIST_HEAD(&ph2c->list); ++ ph2c->cmdcode = GEN_CMD_CODE(_GetRaTable); ++ ph2c->parmbuf = (unsigned char *)pgetrttblparm; ++ ph2c->cmdsz = sizeof(struct getratable_parm); ++ ph2c->rsp = (u8 *)pval; ++ ph2c->rspsz = sizeof(struct getratable_rsp); ++ ++ pgetrttblparm->rsvd = 0x0; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_setassocsta_cmd(struct adapter *padapter, u8 *mac_addr) ++{ ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct cmd_obj *ph2c; ++ struct set_assocsta_parm *psetassocsta_para; ++ struct set_stakey_rsp *psetassocsta_rsp = NULL; ++ ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ psetassocsta_para = kzalloc(sizeof(struct set_assocsta_parm), GFP_ATOMIC); ++ if (!psetassocsta_para) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ psetassocsta_rsp = kzalloc(sizeof(struct set_assocsta_rsp), GFP_ATOMIC); ++ if (!psetassocsta_rsp) { ++ kfree(ph2c); ++ kfree(psetassocsta_para); ++ return _FAIL; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_); ++ ph2c->rsp = (u8 *)psetassocsta_rsp; ++ ph2c->rspsz = sizeof(struct set_assocsta_rsp); ++ ++ memcpy(psetassocsta_para->addr, mac_addr, ETH_ALEN); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++ } ++ ++u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr) ++{ ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct cmd_obj *ph2c; ++ struct addBaReq_parm *paddbareq_parm; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_ATOMIC); ++ if (!paddbareq_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ paddbareq_parm->tid = tid; ++ memcpy(paddbareq_parm->addr, addr, ETH_ALEN); ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq)); ++ ++ /* DBG_88E("rtw_addbareq_cmd, tid =%d\n", tid); */ ++ ++ /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = DYNAMIC_CHK_WK_CID; ++ pdrvextra_cmd_parm->type_size = 0; ++ pdrvextra_cmd_parm->pbuf = (u8 *)padapter; ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_set_ch_cmd(struct adapter *padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue) ++{ ++ struct cmd_obj *pcmdobj; ++ struct set_ch_parm *set_ch_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ u8 res = _SUCCESS; ++ ++ DBG_88E(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n", ++ FUNC_NDEV_ARG(padapter->pnetdev), ch, bw, ch_offset); ++ ++ /* check input parameter */ ++ ++ /* prepare cmd parameter */ ++ set_ch_parm = kzalloc(sizeof(*set_ch_parm), GFP_ATOMIC); ++ if (!set_ch_parm) { ++ res = _FAIL; ++ goto exit; ++ } ++ set_ch_parm->ch = ch; ++ set_ch_parm->bw = bw; ++ set_ch_parm->ch_offset = ch_offset; ++ ++ if (enqueue) { ++ /* need enqueue, prepare cmd_obj and enqueue */ ++ pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmdobj) { ++ kfree(set_ch_parm); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm, GEN_CMD_CODE(_SetChannel)); ++ res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); ++ } else { ++ /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ ++ if (H2C_SUCCESS != set_ch_hdl(padapter, (u8 *)set_ch_parm)) ++ res = _FAIL; ++ ++ kfree(set_ch_parm); ++ } ++ ++ /* do something based on res... */ ++ ++exit: ++ ++ DBG_88E(FUNC_NDEV_FMT" res:%u\n", FUNC_NDEV_ARG(padapter->pnetdev), res); ++ ++ return res; ++} ++ ++u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue) ++{ ++ struct cmd_obj *pcmdobj; ++ struct SetChannelPlan_param *setChannelPlan_param; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ u8 res = _SUCCESS; ++ ++ /* check input parameter */ ++ if (!rtw_is_channel_plan_valid(chplan)) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ /* prepare cmd parameter */ ++ setChannelPlan_param = kzalloc(sizeof(struct SetChannelPlan_param), ++ GFP_KERNEL); ++ if (!setChannelPlan_param) { ++ res = _FAIL; ++ goto exit; ++ } ++ setChannelPlan_param->channel_plan = chplan; ++ ++ if (enqueue) { ++ /* need enqueue, prepare cmd_obj and enqueue */ ++ pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!pcmdobj) { ++ kfree(setChannelPlan_param); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelPlan_param, GEN_CMD_CODE(_SetChannelPlan)); ++ res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); ++ } else { ++ /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ ++ if (H2C_SUCCESS != set_chplan_hdl(padapter, (unsigned char *)setChannelPlan_param)) ++ res = _FAIL; ++ ++ kfree(setChannelPlan_param); ++ } ++ ++ /* do something based on res... */ ++ if (res == _SUCCESS) ++ padapter->mlmepriv.ChannelPlan = chplan; ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_led_blink_cmd(struct adapter *padapter, struct LED_871x *pLed) ++{ ++ struct cmd_obj *pcmdobj; ++ struct LedBlink_param *ledBlink_param; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ u8 res = _SUCCESS; ++ ++ pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmdobj) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ ledBlink_param = kzalloc(sizeof(struct LedBlink_param), GFP_ATOMIC); ++ if (!ledBlink_param) { ++ kfree(pcmdobj); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ ledBlink_param->pLed = pLed; ++ ++ init_h2fwcmd_w_parm_no_rsp(pcmdobj, ledBlink_param, GEN_CMD_CODE(_LedBlink)); ++ res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_set_csa_cmd(struct adapter *padapter, u8 new_ch_no) ++{ ++ struct cmd_obj *pcmdobj; ++ struct SetChannelSwitch_param *setChannelSwitch_param; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ u8 res = _SUCCESS; ++ ++ pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmdobj) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ setChannelSwitch_param = kzalloc(sizeof(struct SetChannelSwitch_param), ++ GFP_ATOMIC); ++ if (!setChannelSwitch_param) { ++ kfree(pcmdobj); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ setChannelSwitch_param->new_ch_no = new_ch_no; ++ ++ init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelSwitch_param, GEN_CMD_CODE(_SetChannelSwitch)); ++ res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_tdls_cmd(struct adapter *padapter, u8 *addr, u8 option) ++{ ++ return _SUCCESS; ++} ++ ++static void traffic_status_watchdog(struct adapter *padapter) ++{ ++ u8 bEnterPS; ++ u8 bBusyTraffic = false, bTxBusyTraffic = false, bRxBusyTraffic = false; ++ u8 bHigherBusyTraffic = false, bHigherBusyRxTraffic = false, bHigherBusyTxTraffic = false; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ /* */ ++ /* Determine if our traffic is busy now */ ++ /* */ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 100 || ++ pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 100) { ++ bBusyTraffic = true; ++ ++ if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) ++ bRxBusyTraffic = true; ++ else ++ bTxBusyTraffic = true; ++ } ++ ++ /* Higher Tx/Rx data. */ ++ if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 || ++ pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000) { ++ bHigherBusyTraffic = true; ++ ++ if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) ++ bHigherBusyRxTraffic = true; ++ else ++ bHigherBusyTxTraffic = true; ++ } ++ ++ /* check traffic for powersaving. */ ++ if (((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8) || ++ (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2)) ++ bEnterPS = false; ++ else ++ bEnterPS = true; ++ ++ /* LeisurePS only work in infra mode. */ ++ if (bEnterPS) ++ LPS_Enter(padapter); ++ else ++ LPS_Leave(padapter); ++ } else { ++ LPS_Leave(padapter); ++ } ++ ++ pmlmepriv->LinkDetectInfo.NumRxOkInPeriod = 0; ++ pmlmepriv->LinkDetectInfo.NumTxOkInPeriod = 0; ++ pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod = 0; ++ pmlmepriv->LinkDetectInfo.bBusyTraffic = bBusyTraffic; ++ pmlmepriv->LinkDetectInfo.bTxBusyTraffic = bTxBusyTraffic; ++ pmlmepriv->LinkDetectInfo.bRxBusyTraffic = bRxBusyTraffic; ++ pmlmepriv->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic; ++ pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic; ++ pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic; ++} ++ ++static void dynamic_chk_wk_hdl(struct adapter *padapter, u8 *pbuf, int sz) ++{ ++ struct mlme_priv *pmlmepriv; ++ ++ padapter = (struct adapter *)pbuf; ++ pmlmepriv = &padapter->mlmepriv; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ expire_timeout_chk(padapter); ++#endif ++ ++ rtw_hal_sreset_xmit_status_check(padapter); ++ ++ linked_status_chk(padapter); ++ traffic_status_watchdog(padapter); ++ ++ rtw_hal_dm_watchdog(padapter); ++} ++ ++static void lps_ctrl_wk_hdl(struct adapter *padapter, u8 lps_ctrl_type) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 mstatus; ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) ++ return; ++ ++ switch (lps_ctrl_type) { ++ case LPS_CTRL_SCAN: ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ /* connect */ ++ LPS_Leave(padapter); ++ } ++ break; ++ case LPS_CTRL_JOINBSS: ++ LPS_Leave(padapter); ++ break; ++ case LPS_CTRL_CONNECT: ++ mstatus = 1;/* connect */ ++ /* Reset LPS Setting */ ++ padapter->pwrctrlpriv.LpsIdleCount = 0; ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); ++ break; ++ case LPS_CTRL_DISCONNECT: ++ mstatus = 0;/* disconnect */ ++ LPS_Leave(padapter); ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); ++ break; ++ case LPS_CTRL_SPECIAL_PACKET: ++ /* DBG_88E("LPS_CTRL_SPECIAL_PACKET\n"); */ ++ pwrpriv->DelayLPSLastTimeStamp = jiffies; ++ LPS_Leave(padapter); ++ break; ++ case LPS_CTRL_LEAVE: ++ LPS_Leave(padapter); ++ break; ++ default: ++ break; ++ } ++ ++} ++ ++u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ /* struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; */ ++ u8 res = _SUCCESS; ++ ++ /* if (!pwrctrlpriv->bLeisurePs) */ ++ /* return res; */ ++ ++ if (enqueue) { ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), ++ GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = LPS_CTRL_WK_CID; ++ pdrvextra_cmd_parm->type_size = lps_ctrl_type; ++ pdrvextra_cmd_parm->pbuf = NULL; ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ } else { ++ lps_ctrl_wk_hdl(padapter, lps_ctrl_type); ++ } ++ ++exit: ++ ++ return res; ++} ++ ++static void rpt_timer_setting_wk_hdl(struct adapter *padapter, u16 min_time) ++{ ++ rtw_hal_set_hwreg(padapter, HW_VAR_RPT_TIMER_SETTING, (u8 *)(&min_time)); ++} ++ ++u8 rtw_rpt_timer_cfg_cmd(struct adapter *padapter, u16 min_time) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), ++ GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = RTP_TIMER_CFG_WK_CID; ++ pdrvextra_cmd_parm->type_size = min_time; ++ pdrvextra_cmd_parm->pbuf = NULL; ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++static void antenna_select_wk_hdl(struct adapter *padapter, u8 antenna) ++{ ++ rtw_hal_set_hwreg(padapter, HW_VAR_ANTENNA_DIVERSITY_SELECT, (u8 *)(&antenna)); ++} ++ ++u8 rtw_antenna_select_cmd(struct adapter *padapter, u8 antenna, u8 enqueue) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 support_ant_div; ++ u8 res = _SUCCESS; ++ ++ rtw_hal_get_def_var(padapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &support_ant_div); ++ if (!support_ant_div) ++ return res; ++ ++ if (enqueue) { ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), ++ GFP_KERNEL); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = ANT_SELECT_WK_CID; ++ pdrvextra_cmd_parm->type_size = antenna; ++ pdrvextra_cmd_parm->pbuf = NULL; ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ } else { ++ antenna_select_wk_hdl(padapter, antenna); ++ } ++exit: ++ ++ return res; ++} ++ ++static void power_saving_wk_hdl(struct adapter *padapter, u8 *pbuf, int sz) ++{ ++ rtw_ps_processor(padapter); ++} ++ ++#ifdef CONFIG_88EU_P2P ++u8 p2p_protocol_wk_cmd(struct adapter *padapter, int intCmdType) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return res; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = P2P_PROTO_WK_CID; ++ pdrvextra_cmd_parm->type_size = intCmdType; /* As the command tppe. */ ++ pdrvextra_cmd_parm->pbuf = NULL; /* Must be NULL here */ ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++} ++#endif /* CONFIG_88EU_P2P */ ++ ++u8 rtw_ps_cmd(struct adapter *padapter) ++{ ++ struct cmd_obj *ppscmd; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ u8 res = _SUCCESS; ++ ++ ppscmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ppscmd) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ppscmd); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID; ++ pdrvextra_cmd_parm->pbuf = NULL; ++ init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ppscmd); ++ ++exit: ++ ++ return res; ++} ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++static void rtw_chk_hi_queue_hdl(struct adapter *padapter) ++{ ++ int cnt = 0; ++ struct sta_info *psta_bmc; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ psta_bmc = rtw_get_bcmc_stainfo(padapter); ++ if (!psta_bmc) ++ return; ++ ++ if (psta_bmc->sleepq_len == 0) { ++ u8 val = 0; ++ ++ /* while ((rtw_read32(padapter, 0x414)&0x00ffff00)!= 0) */ ++ /* while ((rtw_read32(padapter, 0x414)&0x0000ff00)!= 0) */ ++ ++ rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &val); ++ ++ while (!val) { ++ msleep(100); ++ ++ cnt++; ++ ++ if (cnt > 10) ++ break; ++ ++ rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &val); ++ } ++ ++ if (cnt <= 10) { ++ pstapriv->tim_bitmap &= ~BIT(0); ++ pstapriv->sta_dz_bitmap &= ~BIT(0); ++ ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++ } else { /* re check again */ ++ rtw_chk_hi_queue_cmd(padapter); ++ } ++ } ++} ++ ++u8 rtw_chk_hi_queue_cmd(struct adapter *padapter) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = CHECK_HIQ_WK_CID; ++ pdrvextra_cmd_parm->type_size = 0; ++ pdrvextra_cmd_parm->pbuf = NULL; ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ return res; ++} ++#endif ++ ++u8 rtw_c2h_wk_cmd(struct adapter *padapter, u8 *c2h_evt) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = C2H_WK_CID; ++ pdrvextra_cmd_parm->type_size = c2h_evt ? 16 : 0; ++ pdrvextra_cmd_parm->pbuf = c2h_evt; ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++} ++ ++static s32 c2h_evt_hdl(struct adapter *adapter, struct c2h_evt_hdr *c2h_evt, c2h_id_filter filter) ++{ ++ s32 ret = _FAIL; ++ u8 buf[16]; ++ ++ if (!c2h_evt) { ++ /* No c2h event in cmd_obj, read c2h event before handling*/ ++ if (c2h_evt_read(adapter, buf) == _SUCCESS) { ++ c2h_evt = (struct c2h_evt_hdr *)buf; ++ ++ if (filter && !filter(c2h_evt->id)) ++ goto exit; ++ ++ ret = rtw_hal_c2h_handler(adapter, c2h_evt); ++ } ++ } else { ++ if (filter && !filter(c2h_evt->id)) ++ goto exit; ++ ++ ret = rtw_hal_c2h_handler(adapter, c2h_evt); ++ } ++exit: ++ return ret; ++} ++ ++static void c2h_wk_callback(struct work_struct *work) ++{ ++ struct evt_priv *evtpriv = container_of(work, struct evt_priv, c2h_wk); ++ struct adapter *adapter = container_of(evtpriv, struct adapter, evtpriv); ++ struct c2h_evt_hdr *c2h_evt; ++ c2h_id_filter ccx_id_filter = rtw_hal_c2h_id_filter_ccx(adapter); ++ ++ evtpriv->c2h_wk_alive = true; ++ ++ while (!rtw_cbuf_empty(evtpriv->c2h_queue)) { ++ if ((c2h_evt = (struct c2h_evt_hdr *)rtw_cbuf_pop(evtpriv->c2h_queue)) != NULL) { ++ /* This C2H event is read, clear it */ ++ c2h_evt_clear(adapter); ++ } else { ++ c2h_evt = kmalloc(16, GFP_KERNEL); ++ if (c2h_evt) { ++ /* This C2H event is not read, read & clear now */ ++ if (c2h_evt_read(adapter, (u8 *)c2h_evt) != _SUCCESS) { ++ kfree(c2h_evt); ++ continue; ++ } ++ } else { ++ return; ++ } ++ } ++ ++ /* Special pointer to trigger c2h_evt_clear only */ ++ if ((void *)c2h_evt == (void *)evtpriv) ++ continue; ++ ++ if (!c2h_evt_exist(c2h_evt)) { ++ kfree(c2h_evt); ++ continue; ++ } ++ ++ if (ccx_id_filter(c2h_evt->id)) { ++ /* Handle CCX report here */ ++ rtw_hal_c2h_handler(adapter, c2h_evt); ++ kfree(c2h_evt); ++ } else { ++#ifdef CONFIG_88EU_P2P ++ /* Enqueue into cmd_thread for others */ ++ rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt); ++#endif ++ } ++ } ++ ++ evtpriv->c2h_wk_alive = false; ++} ++ ++u8 rtw_drvextra_cmd_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ struct drvextra_cmd_parm *pdrvextra_cmd; ++ ++ if (!pbuf) ++ return H2C_PARAMETERS_ERROR; ++ ++ pdrvextra_cmd = (struct drvextra_cmd_parm *)pbuf; ++ ++ switch (pdrvextra_cmd->ec_id) { ++ case DYNAMIC_CHK_WK_CID: ++ dynamic_chk_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size); ++ break; ++ case POWER_SAVING_CTRL_WK_CID: ++ power_saving_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size); ++ break; ++ case LPS_CTRL_WK_CID: ++ lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type_size); ++ break; ++ case RTP_TIMER_CFG_WK_CID: ++ rpt_timer_setting_wk_hdl(padapter, pdrvextra_cmd->type_size); ++ break; ++ case ANT_SELECT_WK_CID: ++ antenna_select_wk_hdl(padapter, pdrvextra_cmd->type_size); ++ break; ++#ifdef CONFIG_88EU_P2P ++ case P2P_PS_WK_CID: ++ p2p_ps_wk_hdl(padapter, pdrvextra_cmd->type_size); ++ break; ++ case P2P_PROTO_WK_CID: ++ /* Commented by Albert 2011/07/01 */ ++ /* I used the type_size as the type command */ ++ p2p_protocol_wk_hdl(padapter, pdrvextra_cmd->type_size); ++ break; ++#endif ++#ifdef CONFIG_88EU_AP_MODE ++ case CHECK_HIQ_WK_CID: ++ rtw_chk_hi_queue_hdl(padapter); ++ break; ++#endif /* CONFIG_88EU_AP_MODE */ ++ case C2H_WK_CID: ++ c2h_evt_hdl(padapter, (struct c2h_evt_hdr *)pdrvextra_cmd->pbuf, NULL); ++ break; ++ default: ++ break; ++ } ++ ++ if (pdrvextra_cmd->pbuf && pdrvextra_cmd->type_size > 0) ++ kfree(pdrvextra_cmd->pbuf); ++ ++ return H2C_SUCCESS; ++} ++ ++void rtw_survey_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if (pcmd->res == H2C_DROPPED) { ++ /* TODO: cancel timer and do timeout handler directly... */ ++ /* need to make timeout handlerOS independent */ ++ _set_timer(&pmlmepriv->scan_to_timer, 1); ++ } else if (pcmd->res != H2C_SUCCESS) { ++ _set_timer(&pmlmepriv->scan_to_timer, 1); ++ } ++ ++ /* free cmd */ ++ rtw_free_cmd_obj(pcmd); ++ ++} ++void rtw_disassoc_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if (pcmd->res != H2C_SUCCESS) { ++ spin_lock_bh(&pmlmepriv->lock); ++ set_fwstate(pmlmepriv, _FW_LINKED); ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++ return; ++ } else /* clear bridge database */ ++ nat25_db_cleanup(padapter); ++ ++ /* free cmd */ ++ rtw_free_cmd_obj(pcmd); ++} ++ ++void rtw_joinbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if (pcmd->res == H2C_DROPPED) { ++ /* TODO: cancel timer and do timeout handler directly... */ ++ /* need to make timeout handlerOS independent */ ++ _set_timer(&pmlmepriv->assoc_timer, 1); ++ } else if (pcmd->res != H2C_SUCCESS) { ++ _set_timer(&pmlmepriv->assoc_timer, 1); ++ } ++ ++ rtw_free_cmd_obj(pcmd); ++} ++ ++void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ u8 timer_cancelled; ++ struct sta_info *psta = NULL; ++ struct wlan_network *pwlan = NULL; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf; ++ struct wlan_network *tgt_network = &pmlmepriv->cur_network; ++ ++ if (pcmd->res != H2C_SUCCESS) ++ _set_timer(&pmlmepriv->assoc_timer, 1); ++ ++ _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled); ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ psta = rtw_get_stainfo(&padapter->stapriv, pnetwork->MacAddress); ++ if (!psta) { ++ psta = rtw_alloc_stainfo(&padapter->stapriv, pnetwork->MacAddress); ++ if (!psta) ++ goto createbss_cmd_fail; ++ } ++ ++ rtw_indicate_connect(padapter); ++ } else { ++ ++ pwlan = _rtw_alloc_network(pmlmepriv); ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ if (!pwlan) { ++ pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue); ++ if (!pwlan) { ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ goto createbss_cmd_fail; ++ } ++ pwlan->last_scanned = jiffies; ++ } else { ++ list_add_tail(&pwlan->list, &pmlmepriv->scanned_queue.queue); ++ } ++ ++ pnetwork->Length = get_wlan_bssid_ex_sz(pnetwork); ++ memcpy(&pwlan->network, pnetwork, pnetwork->Length); ++ ++ memcpy(&tgt_network->network, pnetwork, (get_wlan_bssid_ex_sz(pnetwork))); ++ ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ /* we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) */ ++ } ++ ++createbss_cmd_fail: ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++ rtw_free_cmd_obj(pcmd); ++ ++} ++ ++void rtw_setstaKey_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct set_stakey_rsp *psetstakey_rsp = (struct set_stakey_rsp *)(pcmd->rsp); ++ struct sta_info *psta = rtw_get_stainfo(pstapriv, psetstakey_rsp->addr); ++ ++ if (!psta) ++ goto exit; ++exit: ++ rtw_free_cmd_obj(pcmd); ++ ++} ++ ++void rtw_setassocsta_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct set_assocsta_parm *passocsta_parm = (struct set_assocsta_parm *)(pcmd->parmbuf); ++ struct set_assocsta_rsp *passocsta_rsp = (struct set_assocsta_rsp *)(pcmd->rsp); ++ struct sta_info *psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr); ++ ++ if (!psta) ++ goto exit; ++ ++ psta->aid = passocsta_rsp->cam_id; ++ psta->mac_id = passocsta_rsp->cam_id; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (check_fwstate(pmlmepriv, WIFI_MP_STATE) && check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ ++ set_fwstate(pmlmepriv, _FW_LINKED); ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++exit: ++ rtw_free_cmd_obj(pcmd); ++ ++} +diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c +new file mode 100644 +index 000000000000..2ee64cef73f7 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_debug.c +@@ -0,0 +1,904 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_DEBUG_C_ ++ ++#include "../include/rtw_debug.h" ++#include "../include/drv_types.h" ++ ++int proc_get_drv_version(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "%s\n", DRIVERVERSION); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_write_reg(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ *eof = 1; ++ return 0; ++} ++ ++int proc_set_write_reg(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ char tmp[32]; ++ u32 addr, val, len; ++ ++ if (count < 3) { ++ DBG_88E("argument size is less than 3\n"); ++ return -EFAULT; ++ } ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ int num = sscanf(tmp, "%x %x %x", &addr, &val, &len); ++ ++ if (num != 3) { ++ DBG_88E("invalid write_reg parameter!\n"); ++ return count; ++ } ++ switch (len) { ++ case 1: ++ rtw_write8(padapter, addr, (u8)val); ++ break; ++ case 2: ++ rtw_write16(padapter, addr, (u16)val); ++ break; ++ case 4: ++ rtw_write32(padapter, addr, val); ++ break; ++ default: ++ DBG_88E("error write length =%d", len); ++ break; ++ } ++ } ++ return count; ++} ++ ++static u32 proc_get_read_addr = 0xeeeeeeee; ++static u32 proc_get_read_len = 0x4; ++ ++int proc_get_read_reg(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ int len = 0; ++ ++ if (proc_get_read_addr == 0xeeeeeeee) { ++ *eof = 1; ++ return len; ++ } ++ ++ switch (proc_get_read_len) { ++ case 1: ++ len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n", proc_get_read_addr, rtw_read8(padapter, proc_get_read_addr)); ++ break; ++ case 2: ++ len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr)); ++ break; ++ case 4: ++ len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr)); ++ break; ++ default: ++ len += snprintf(page + len, count - len, "error read length=%d\n", proc_get_read_len); ++ break; ++ } ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_set_read_reg(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ char tmp[16]; ++ u32 addr, len; ++ ++ if (count < 2) { ++ DBG_88E("argument size is less than 2\n"); ++ return -EFAULT; ++ } ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ int num = sscanf(tmp, "%x %x", &addr, &len); ++ ++ if (num != 2) { ++ DBG_88E("invalid read_reg parameter!\n"); ++ return count; ++ } ++ ++ proc_get_read_addr = addr; ++ ++ proc_get_read_len = len; ++ } ++ ++ return count; ++} ++ ++int proc_get_fwstate(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "fwstate=0x%x\n", get_fwstate(pmlmepriv)); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_sec_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", ++ psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, ++ psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_mlmext_state(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "pmlmeinfo->state=0x%x\n", pmlmeinfo->state); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_qos_option(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "qos_option=%d\n", pmlmepriv->qospriv.qos_option); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_ht_option(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ int len = 0; ++ len += snprintf(page + len, count - len, "ht_option=%d\n", pmlmepriv->htpriv.ht_option); ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_rf_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "cur_ch=%d, cur_bw=%d, cur_ch_offet=%d\n", ++ pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_ap_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct sta_info *psta; ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wlan_network *cur_network = &pmlmepriv->cur_network; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ int len = 0; ++ ++ psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress); ++ if (psta) { ++ int i; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ ++ len += snprintf(page + len, count - len, "SSID=%s\n", cur_network->network.Ssid.Ssid); ++ len += snprintf(page + len, count - len, "sta's macaddr:%pM\n", psta->hwaddr); ++ len += snprintf(page + len, count - len, "cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); ++ len += snprintf(page + len, count - len, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self); ++ len += snprintf(page + len, count - len, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); ++ len += snprintf(page + len, count - len, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); ++ len += snprintf(page + len, count - len, "bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi); ++ len += snprintf(page + len, count - len, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable); ++ len += snprintf(page + len, count - len, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); ++ ++ for (i = 0; i < 16; i++) { ++ preorder_ctrl = &psta->recvreorder_ctrl[i]; ++ if (preorder_ctrl->enable) ++ len += snprintf(page + len, count - len, "tid=%d, indicate_seq=%d\n", i, preorder_ctrl->indicate_seq); ++ } ++ } else { ++ len += snprintf(page + len, count - len, "can't get sta's macaddr, cur_network's macaddr: %pM\n", cur_network->network.MacAddress); ++ } ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_adapter_state(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "bSurpriseRemoved=%d, bDriverStopped=%d\n", ++ padapter->bSurpriseRemoved, padapter->bDriverStopped); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_trx_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d, free_ext_xmitbuf_cnt=%d, free_recvframe_cnt=%d\n", ++ pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmit_extbuf_cnt, precvpriv->free_recvframe_cnt); ++ len += snprintf(page + len, count - len, "rx_urb_pending_cn=%d\n", precvpriv->rx_pending_cnt); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_mac_reg_dump1(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1; ++ ++ len += snprintf(page + len, count - len, "\n======= MAC REG =======\n"); ++ ++ for (i = 0x0; i < 0x300; i += 4) { ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_mac_reg_dump2(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1; ++ ++ len += snprintf(page + len, count - len, "\n======= MAC REG =======\n"); ++ memset(page, 0, count); ++ for (i = 0x300; i < 0x600; i += 4) { ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_mac_reg_dump3(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1; ++ ++ len += snprintf(page + len, count - len, "\n======= MAC REG =======\n"); ++ ++ for (i = 0x600; i < 0x800; i += 4) { ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_bb_reg_dump1(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1; ++ ++ len += snprintf(page + len, count - len, "\n======= BB REG =======\n"); ++ for (i = 0x800; i < 0xB00; i += 4) { ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_bb_reg_dump2(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1; ++ ++ len += snprintf(page + len, count - len, "\n======= BB REG =======\n"); ++ for (i = 0xB00; i < 0xE00; i += 4) { ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_bb_reg_dump3(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1; ++ ++ len += snprintf(page + len, count - len, "\n======= BB REG =======\n"); ++ for (i = 0xE00; i < 0x1000; i += 4) { ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_rf_reg_dump1(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1, path; ++ u32 value; ++ ++ len += snprintf(page + len, count - len, "\n======= RF REG =======\n"); ++ path = 1; ++ len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path); ++ for (i = 0; i < 0xC0; i++) { ++ value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x ", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", value); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_rf_reg_dump2(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1, path; ++ u32 value; ++ ++ len += snprintf(page + len, count - len, "\n======= RF REG =======\n"); ++ path = 1; ++ len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path); ++ for (i = 0xC0; i < 0x100; i++) { ++ value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x ", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", value); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_rf_reg_dump3(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1, path; ++ u32 value; ++ ++ len += snprintf(page + len, count - len, "\n======= RF REG =======\n"); ++ path = 2; ++ len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path); ++ for (i = 0; i < 0xC0; i++) { ++ value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x ", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", value); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_rf_reg_dump4(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1, path; ++ u32 value; ++ ++ len += snprintf(page + len, count - len, "\n======= RF REG =======\n"); ++ path = 2; ++ len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path); ++ for (i = 0xC0; i < 0x100; i++) { ++ value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x ", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", value); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_rx_signal(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ ++ len = snprintf(page + len, count, ++ "rssi:%d\n" ++ "rxpwdb:%d\n" ++ "signal_strength:%u\n" ++ "signal_qual:%u\n" ++ "noise:%u\n", ++ padapter->recvpriv.rssi, ++ padapter->recvpriv.rxpwdb, ++ padapter->recvpriv.signal_strength, ++ padapter->recvpriv.signal_qual, ++ padapter->recvpriv.noise ++ ); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_set_rx_signal(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ char tmp[32]; ++ u32 is_signal_dbg; ++ s32 signal_strength; ++ ++ if (count < 1) ++ return -EFAULT; ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ int num = sscanf(tmp, "%u %u", &is_signal_dbg, &signal_strength); ++ is_signal_dbg = is_signal_dbg == 0 ? 0 : 1; ++ if (is_signal_dbg && num != 2) ++ return count; ++ ++ signal_strength = signal_strength > 100 ? 100 : signal_strength; ++ signal_strength = signal_strength < 0 ? 0 : signal_strength; ++ ++ padapter->recvpriv.is_signal_dbg = is_signal_dbg; ++ padapter->recvpriv.signal_strength_dbg = signal_strength; ++ ++ if (is_signal_dbg) ++ DBG_88E("set %s %u\n", "DBG_SIGNAL_STRENGTH", signal_strength); ++ else ++ DBG_88E("set %s\n", "HW_SIGNAL_STRENGTH"); ++ } ++ return count; ++} ++ ++int proc_get_ht_enable(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ int len = 0; ++ ++ if (pregpriv) ++ len += snprintf(page + len, count - len, ++ "%d\n", ++ pregpriv->ht_enable ++ ); ++ *eof = 1; ++ return len; ++} ++ ++int proc_set_ht_enable(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ char tmp[32]; ++ s32 mode = 0; ++ ++ if (count < 1) ++ return -EFAULT; ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ if (pregpriv) { ++ pregpriv->ht_enable = mode; ++ pr_info("ht_enable=%d\n", pregpriv->ht_enable); ++ } ++ } ++ ++ return count; ++} ++ ++int proc_get_cbw40_enable(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ ++ int len = 0; ++ ++ if (pregpriv) ++ len += snprintf(page + len, count - len, ++ "%d\n", ++ pregpriv->cbw40_enable ++ ); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_set_cbw40_enable(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ char tmp[32]; ++ s32 mode = 0; ++ ++ if (count < 1) ++ return -EFAULT; ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ if (pregpriv) { ++ pregpriv->cbw40_enable = mode; ++ pr_info("cbw40_enable=%d\n", mode); ++ } ++ } ++ return count; ++} ++ ++int proc_get_ampdu_enable(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ ++ int len = 0; ++ ++ if (pregpriv) ++ len += snprintf(page + len, count - len, ++ "%d\n", ++ pregpriv->ampdu_enable ++ ); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_set_ampdu_enable(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ char tmp[32]; ++ s32 mode = 0; ++ ++ if (count < 1) ++ return -EFAULT; ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ if (pregpriv) { ++ pregpriv->ampdu_enable = mode; ++ pr_info("ampdu_enable=%d\n", mode); ++ } ++ } ++ return count; ++} ++ ++int proc_get_two_path_rssi(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ int len = 0; ++ ++ if (padapter) ++ len += snprintf(page + len, count - len, ++ "%d %d\n", ++ padapter->recvpriv.RxRssi[0], ++ padapter->recvpriv.RxRssi[1] ++ ); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_rx_stbc(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ ++ int len = 0; ++ ++ if (pregpriv) ++ len += snprintf(page + len, count - len, ++ "%d\n", ++ pregpriv->rx_stbc ++ ); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_set_rx_stbc(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ char tmp[32]; ++ u32 mode = 0; ++ ++ if (count < 1) ++ return -EFAULT; ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ if (pregpriv) { ++ pregpriv->rx_stbc = mode; ++ printk("rx_stbc=%d\n", mode); ++ } ++ } ++ return count; ++} ++ ++int proc_get_rssi_disp(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ *eof = 1; ++ return 0; ++} ++ ++int proc_set_rssi_disp(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ char tmp[32]; ++ u32 enable = 0; ++ ++ if (count < 1) { ++ DBG_88E("argument size is less than 1\n"); ++ return -EFAULT; ++ } ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ int num = sscanf(tmp, "%x", &enable); ++ ++ if (num != 1) { ++ DBG_88E("invalid set_rssi_disp parameter!\n"); ++ return count; ++ } ++ ++ if (enable) { ++ DBG_88E("Turn On Rx RSSI Display Function\n"); ++ padapter->bRxRSSIDisplay = enable; ++ } else { ++ DBG_88E("Turn Off Rx RSSI Display Function\n"); ++ padapter->bRxRSSIDisplay = 0; ++ } ++ } ++ return count; ++} ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++int proc_get_all_sta_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct sta_info *psta; ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ int i, j; ++ struct list_head *plist, *phead; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap); ++ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ ++ for (i = 0; i < NUM_STA; i++) { ++ phead = &pstapriv->sta_hash[i]; ++ plist = phead->next; ++ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, hash_list); ++ ++ plist = plist->next; ++ ++ len += snprintf(page + len, count - len, "sta's macaddr: %pM\n", psta->hwaddr); ++ len += snprintf(page + len, count - len, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self); ++ len += snprintf(page + len, count - len, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); ++ len += snprintf(page + len, count - len, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); ++ len += snprintf(page + len, count - len, "bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi); ++ len += snprintf(page + len, count - len, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable); ++ len += snprintf(page + len, count - len, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); ++ len += snprintf(page + len, count - len, "sleepq_len=%d\n", psta->sleepq_len); ++ len += snprintf(page + len, count - len, "capability=0x%x\n", psta->capability); ++ len += snprintf(page + len, count - len, "flags=0x%x\n", psta->flags); ++ len += snprintf(page + len, count - len, "wpa_psk=0x%x\n", psta->wpa_psk); ++ len += snprintf(page + len, count - len, "wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher); ++ len += snprintf(page + len, count - len, "wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher); ++ len += snprintf(page + len, count - len, "qos_info=0x%x\n", psta->qos_info); ++ len += snprintf(page + len, count - len, "dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy); ++ ++ for (j = 0; j < 16; j++) { ++ preorder_ctrl = &psta->recvreorder_ctrl[j]; ++ if (preorder_ctrl->enable) ++ len += snprintf(page + len, count - len, "tid=%d, indicate_seq=%d\n", j, preorder_ctrl->indicate_seq); ++ } ++ } ++ } ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++ *eof = 1; ++ return len; ++} ++#endif ++ ++int proc_get_best_channel(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ int len = 0; ++ u32 i, best_channel_24G = 1, index_24G = 0; ++ ++ for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) { ++ if (pmlmeext->channel_set[i].ChannelNum == 1) ++ index_24G = i; ++ } ++ ++ for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) { ++ /* 2.4G */ ++ if (pmlmeext->channel_set[i].ChannelNum == 6) { ++ if (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_24G].rx_count) { ++ index_24G = i; ++ best_channel_24G = pmlmeext->channel_set[i].ChannelNum; ++ } ++ } ++ ++ /* debug */ ++ len += snprintf(page + len, count - len, "The rx cnt of channel %3d = %d\n", ++ pmlmeext->channel_set[i].ChannelNum, pmlmeext->channel_set[i].rx_count); ++ } ++ ++ len += snprintf(page + len, count - len, "best_channel_24G = %d\n", best_channel_24G); ++ ++ *eof = 1; ++ return len; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c +new file mode 100644 +index 000000000000..c1c70648f5bc +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_efuse.c +@@ -0,0 +1,848 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_EFUSE_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtw_efuse.h" ++ ++/*------------------------Define local variable------------------------------*/ ++u8 fakeEfuseBank; ++u32 fakeEfuseUsedBytes; ++u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE] = {0}; ++u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN] = {0}; ++u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN] = {0}; ++ ++u32 BTEfuseUsedBytes; ++u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; ++u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0}; ++u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0}; ++ ++u32 fakeBTEfuseUsedBytes; ++u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; ++u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0}; ++u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0}; ++/*------------------------Define local variable------------------------------*/ ++ ++/* */ ++#define REG_EFUSE_CTRL 0x0030 ++#define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */ ++/* */ ++static bool Efuse_Read1ByteFromFakeContent(struct adapter *pAdapter, ++ u16 Offset, ++ u8 *Value) ++{ ++ if (Offset >= EFUSE_MAX_HW_SIZE) ++ return false; ++ if (fakeEfuseBank == 0) ++ *Value = fakeEfuseContent[Offset]; ++ else ++ *Value = fakeBTEfuseContent[fakeEfuseBank - 1][Offset]; ++ return true; ++} ++ ++static bool ++Efuse_Write1ByteToFakeContent( ++ struct adapter *pAdapter, ++ u16 Offset, ++ u8 Value) ++{ ++ if (Offset >= EFUSE_MAX_HW_SIZE) ++ return false; ++ if (fakeEfuseBank == 0) { ++ fakeEfuseContent[Offset] = Value; ++ } else { ++ fakeBTEfuseContent[fakeEfuseBank - 1][Offset] = Value; ++ } ++ return true; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: Efuse_PowerSwitch ++ * ++ * Overview: When we want to enable write operation, we should change to ++ * pwr on state. When we stop write, we should switch to 500k mode ++ * and disable LDO 2.5V. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/17/2008 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++void ++Efuse_PowerSwitch( ++ struct adapter *pAdapter, ++ u8 write, ++ u8 PwrState) ++{ ++ pAdapter->HalFunc.EfusePowerSwitch(pAdapter, write, PwrState); ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: efuse_GetCurrentSize ++ * ++ * Overview: Get current efuse size!!! ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/16/2008 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++u16 ++Efuse_GetCurrentSize( ++ struct adapter *pAdapter, ++ u8 efuseType, ++ bool pseudo) ++{ ++ u16 ret = 0; ++ ++ ret = pAdapter->HalFunc.EfuseGetCurrentSize(pAdapter, efuseType, pseudo); ++ ++ return ret; ++} ++ ++/* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */ ++u8 ++Efuse_CalculateWordCnts(u8 word_en) ++{ ++ u8 word_cnts = 0; ++ if (!(word_en & BIT(0))) ++ word_cnts++; /* 0 : write enable */ ++ if (!(word_en & BIT(1))) ++ word_cnts++; ++ if (!(word_en & BIT(2))) ++ word_cnts++; ++ if (!(word_en & BIT(3))) ++ word_cnts++; ++ return word_cnts; ++} ++ ++/* */ ++/* Description: */ ++/* Execute E-Fuse read byte operation. */ ++/* Referred from SD1 Richard. */ ++/* */ ++/* Assumption: */ ++/* 1. Boot from E-Fuse and successfully auto-load. */ ++/* 2. PASSIVE_LEVEL (USB interface) */ ++/* */ ++/* Created by Roger, 2008.10.21. */ ++/* */ ++void ++ReadEFuseByte( ++ struct adapter *Adapter, ++ u16 _offset, ++ u8 *pbuf, ++ bool pseudo) ++{ ++ u32 value32; ++ u8 readbyte; ++ u16 retry; ++ ++ if (pseudo) { ++ Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf); ++ return; ++ } ++ ++ /* Write Address */ ++ rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff)); ++ readbyte = rtw_read8(Adapter, EFUSE_CTRL + 2); ++ rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc)); ++ ++ /* Write bit 32 0 */ ++ readbyte = rtw_read8(Adapter, EFUSE_CTRL + 3); ++ rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f)); ++ ++ /* Check bit 32 read-ready */ ++ retry = 0; ++ value32 = rtw_read32(Adapter, EFUSE_CTRL); ++ while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) { ++ value32 = rtw_read32(Adapter, EFUSE_CTRL); ++ retry++; ++ } ++ ++ /* 20100205 Joseph: Add delay suggested by SD1 Victor. */ ++ /* This fix the problem that Efuse read error in high temperature condition. */ ++ /* Designer says that there shall be some delay after ready bit is set, or the */ ++ /* result will always stay on last data we read. */ ++ udelay(50); ++ value32 = rtw_read32(Adapter, EFUSE_CTRL); ++ ++ *pbuf = (u8)(value32 & 0xff); ++} ++ ++/* */ ++/* Description: */ ++/* 1. Execute E-Fuse read byte operation according as map offset and */ ++/* save to E-Fuse table. */ ++/* 2. Referred from SD1 Richard. */ ++/* */ ++/* Assumption: */ ++/* 1. Boot from E-Fuse and successfully auto-load. */ ++/* 2. PASSIVE_LEVEL (USB interface) */ ++/* */ ++/* Created by Roger, 2008.10.21. */ ++/* */ ++/* 2008/12/12 MH 1. Reorganize code flow and reserve bytes. and add description. */ ++/* 2. Add efuse utilization collect. */ ++/* 2008/12/22 MH Read Efuse must check if we write section 1 data again!!! Sec1 */ ++/* write addr must be after sec5. */ ++/* */ ++ ++static void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo) ++{ ++ Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo); ++} ++ ++void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool pseudo ++ ) ++{ ++ pAdapter->HalFunc.EFUSEGetEfuseDefinition(pAdapter, efuseType, type, pOut, pseudo); ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: EFUSE_Read1Byte ++ * ++ * Overview: Copy from WMAC fot EFUSE read 1 byte. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 09/23/2008 MHC Copy from WMAC. ++ * ++ *---------------------------------------------------------------------------*/ ++u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address) ++{ ++ u8 data; ++ u8 Bytetemp = {0x00}; ++ u8 temp = {0x00}; ++ u32 k = 0; ++ u16 contentLen = 0; ++ ++ EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, false); ++ ++ if (Address < contentLen) { /* E-fuse 512Byte */ ++ /* Write E-fuse Register address bit0~7 */ ++ temp = Address & 0xFF; ++ rtw_write8(Adapter, EFUSE_CTRL + 1, temp); ++ Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 2); ++ /* Write E-fuse Register address bit8~9 */ ++ temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC); ++ rtw_write8(Adapter, EFUSE_CTRL + 2, temp); ++ ++ /* Write 0x30[31]= 0 */ ++ Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3); ++ temp = Bytetemp & 0x7F; ++ rtw_write8(Adapter, EFUSE_CTRL + 3, temp); ++ ++ /* Wait Write-ready (0x30[31]= 1) */ ++ Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3); ++ while (!(Bytetemp & 0x80)) { ++ Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3); ++ k++; ++ if (k == 1000) { ++ k = 0; ++ break; ++ } ++ } ++ data = rtw_read8(Adapter, EFUSE_CTRL); ++ return data; ++ } else { ++ return 0xFF; ++ } ++ ++} /* EFUSE_Read1Byte */ ++ ++/* 11/16/2008 MH Read one byte from real Efuse. */ ++u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data, bool pseudo) ++{ ++ u8 tmpidx = 0; ++ u8 result; ++ ++ if (pseudo) { ++ result = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data); ++ return result; ++ } ++ /* -----------------e-fuse reg ctrl --------------------------------- */ ++ /* address */ ++ rtw_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff)); ++ rtw_write8(pAdapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) | ++ (rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC)); ++ ++ rtw_write8(pAdapter, EFUSE_CTRL + 3, 0x72);/* read cmd */ ++ ++ while (!(0x80 & rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100)) ++ tmpidx++; ++ if (tmpidx < 100) { ++ *data = rtw_read8(pAdapter, EFUSE_CTRL); ++ result = true; ++ } else { ++ *data = 0xff; ++ result = false; ++ } ++ return result; ++} ++ ++/* 11/16/2008 MH Write one byte to reald Efuse. */ ++u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data, bool pseudo) ++{ ++ u8 tmpidx = 0; ++ u8 result; ++ ++ if (pseudo) { ++ result = Efuse_Write1ByteToFakeContent(pAdapter, addr, data); ++ return result; ++ } ++ ++ /* -----------------e-fuse reg ctrl --------------------------------- */ ++ /* address */ ++ rtw_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff)); ++ rtw_write8(pAdapter, EFUSE_CTRL + 2, ++ (rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC) | ++ (u8)((addr >> 8) & 0x03)); ++ rtw_write8(pAdapter, EFUSE_CTRL, data);/* data */ ++ ++ rtw_write8(pAdapter, EFUSE_CTRL + 3, 0xF2);/* write cmd */ ++ ++ while ((0x80 & rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100)) ++ tmpidx++; ++ ++ if (tmpidx < 100) ++ result = true; ++ else ++ result = false; ++ ++ return result; ++} ++ ++int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool pseudo) ++{ ++ int ret = 0; ++ ++ ret = pAdapter->HalFunc.Efuse_PgPacketRead(pAdapter, offset, data, pseudo); ++ ++ return ret; ++} ++ ++int Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool pseudo) ++{ ++ int ret; ++ ++ ret = pAdapter->HalFunc.Efuse_PgPacketWrite(pAdapter, offset, word_en, data, pseudo); ++ ++ return ret; ++} ++ ++static int Efuse_PgPacketWrite_BT(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool pseudo) ++{ ++ int ret; ++ ++ ret = pAdapter->HalFunc.Efuse_PgPacketWrite_BT(pAdapter, offset, word_en, data, pseudo); ++ ++ return ret; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: efuse_WordEnableDataRead ++ * ++ * Overview: Read allowed word in current efuse section data. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/16/2008 MHC Create Version 0. ++ * 11/21/2008 MHC Fix Write bug when we only enable late word. ++ * ++ *---------------------------------------------------------------------------*/ ++void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata) ++{ ++ if (!(word_en & BIT(0))) { ++ targetdata[0] = sourdata[0]; ++ targetdata[1] = sourdata[1]; ++ } ++ if (!(word_en & BIT(1))) { ++ targetdata[2] = sourdata[2]; ++ targetdata[3] = sourdata[3]; ++ } ++ if (!(word_en & BIT(2))) { ++ targetdata[4] = sourdata[4]; ++ targetdata[5] = sourdata[5]; ++ } ++ if (!(word_en & BIT(3))) { ++ targetdata[6] = sourdata[6]; ++ targetdata[7] = sourdata[7]; ++ } ++} ++ ++u8 Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool pseudo) ++{ ++ u8 ret = 0; ++ ++ ret = pAdapter->HalFunc.Efuse_WordEnableDataWrite(pAdapter, efuse_addr, word_en, data, pseudo); ++ ++ return ret; ++} ++ ++static u8 efuse_read8(struct adapter *padapter, u16 address, u8 *value) ++{ ++ return efuse_OneByteRead(padapter, address, value, false); ++} ++ ++static u8 efuse_write8(struct adapter *padapter, u16 address, u8 *value) ++{ ++ return efuse_OneByteWrite(padapter, address, *value, false); ++} ++ ++/* ++ * read/wirte raw efuse data ++ */ ++u8 rtw_efuse_access(struct adapter *padapter, u8 write, u16 start_addr, u16 cnts, u8 *data) ++{ ++ int i = 0; ++ u16 real_content_len = 0, max_available_size = 0; ++ u8 res = _FAIL; ++ u8 (*rw8)(struct adapter *, u16, u8*); ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&real_content_len, false); ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ ++ if (start_addr > real_content_len) ++ return _FAIL; ++ ++ if (write) { ++ if ((start_addr + cnts) > max_available_size) ++ return _FAIL; ++ rw8 = &efuse_write8; ++ } else { ++ rw8 = &efuse_read8; ++ } ++ ++ Efuse_PowerSwitch(padapter, write, true); ++ ++ /* e-fuse one byte read / write */ ++ for (i = 0; i < cnts; i++) { ++ if (start_addr >= real_content_len) { ++ res = _FAIL; ++ break; ++ } ++ ++ res = rw8(padapter, start_addr++, data++); ++ if (_FAIL == res) ++ break; ++ } ++ ++ Efuse_PowerSwitch(padapter, write, false); ++ ++ return res; ++} ++/* */ ++u16 efuse_GetMaxSize(struct adapter *padapter) ++{ ++ u16 max_size; ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_size, false); ++ return max_size; ++} ++/* */ ++u8 efuse_GetCurrentSize(struct adapter *padapter, u16 *size) ++{ ++ Efuse_PowerSwitch(padapter, false, true); ++ *size = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, false); ++ Efuse_PowerSwitch(padapter, false, false); ++ ++ return _SUCCESS; ++} ++/* */ ++u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data) ++{ ++ u16 mapLen = 0; ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false); ++ ++ if ((addr + cnts) > mapLen) ++ return _FAIL; ++ ++ Efuse_PowerSwitch(padapter, false, true); ++ ++ efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false); ++ ++ Efuse_PowerSwitch(padapter, false, false); ++ ++ return _SUCCESS; ++} ++ ++u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data) ++{ ++ u16 mapLen = 0; ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false); ++ ++ if ((addr + cnts) > mapLen) ++ return _FAIL; ++ ++ Efuse_PowerSwitch(padapter, false, true); ++ ++ efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false); ++ ++ Efuse_PowerSwitch(padapter, false, false); ++ ++ return _SUCCESS; ++} ++/* */ ++u8 rtw_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data) ++{ ++ u8 offset, word_en; ++ u8 *map; ++ u8 newdata[PGPKT_DATA_SIZE + 1]; ++ s32 i, idx; ++ u8 ret = _SUCCESS; ++ u16 mapLen = 0; ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false); ++ ++ if ((addr + cnts) > mapLen) ++ return _FAIL; ++ ++ map = kzalloc(mapLen, GFP_KERNEL); ++ if (!map) ++ return _FAIL; ++ ++ ret = rtw_efuse_map_read(padapter, 0, mapLen, map); ++ if (ret == _FAIL) ++ goto exit; ++ ++ Efuse_PowerSwitch(padapter, true, true); ++ ++ offset = (addr >> 3); ++ word_en = 0xF; ++ memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1); ++ i = addr & 0x7; /* index of one package */ ++ idx = 0; /* data index */ ++ ++ if (i & 0x1) { ++ /* odd start */ ++ if (data[idx] != map[addr + idx]) { ++ word_en &= ~BIT(i >> 1); ++ newdata[i - 1] = map[addr + idx - 1]; ++ newdata[i] = data[idx]; ++ } ++ i++; ++ idx++; ++ } ++ do { ++ for (; i < PGPKT_DATA_SIZE; i += 2) { ++ if (cnts == idx) ++ break; ++ if ((cnts - idx) == 1) { ++ if (data[idx] != map[addr + idx]) { ++ word_en &= ~BIT(i >> 1); ++ newdata[i] = data[idx]; ++ newdata[i + 1] = map[addr + idx + 1]; ++ } ++ idx++; ++ break; ++ } else { ++ if ((data[idx] != map[addr + idx]) || ++ (data[idx + 1] != map[addr + idx + 1])) { ++ word_en &= ~BIT(i >> 1); ++ newdata[i] = data[idx]; ++ newdata[i + 1] = data[idx + 1]; ++ } ++ idx += 2; ++ } ++ if (idx == cnts) ++ break; ++ } ++ ++ if (word_en != 0xF) { ++ ret = Efuse_PgPacketWrite(padapter, offset, word_en, newdata, false); ++ DBG_88E("offset=%x\n", offset); ++ DBG_88E("word_en=%x\n", word_en); ++ ++ for (i = 0; i < PGPKT_DATA_SIZE; i++) ++ DBG_88E("data=%x \t", newdata[i]); ++ if (ret == _FAIL) ++ break; ++ } ++ ++ if (idx == cnts) ++ break; ++ ++ offset++; ++ i = 0; ++ word_en = 0xF; ++ memset(newdata, 0xFF, PGPKT_DATA_SIZE); ++ } while (1); ++ ++ Efuse_PowerSwitch(padapter, true, false); ++exit: ++ kfree(map); ++ return ret; ++} ++ ++/* */ ++u8 rtw_BT_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data) ++{ ++ u8 offset, word_en; ++ u8 *map; ++ u8 newdata[PGPKT_DATA_SIZE + 1]; ++ s32 i, idx; ++ u8 ret = _SUCCESS; ++ u16 mapLen = 0; ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false); ++ ++ if ((addr + cnts) > mapLen) ++ return _FAIL; ++ ++ map = kzalloc(mapLen, GFP_KERNEL); ++ if (!map) ++ return _FAIL; ++ ++ ret = rtw_BT_efuse_map_read(padapter, 0, mapLen, map); ++ if (ret == _FAIL) ++ goto exit; ++ ++ Efuse_PowerSwitch(padapter, true, true); ++ ++ offset = (addr >> 3); ++ word_en = 0xF; ++ memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1); ++ i = addr & 0x7; /* index of one package */ ++ idx = 0; /* data index */ ++ ++ if (i & 0x1) { ++ /* odd start */ ++ if (data[idx] != map[addr + idx]) { ++ word_en &= ~BIT(i >> 1); ++ newdata[i - 1] = map[addr + idx - 1]; ++ newdata[i] = data[idx]; ++ } ++ i++; ++ idx++; ++ } ++ do { ++ for (; i < PGPKT_DATA_SIZE; i += 2) { ++ if (cnts == idx) ++ break; ++ if ((cnts - idx) == 1) { ++ if (data[idx] != map[addr + idx]) { ++ word_en &= ~BIT(i >> 1); ++ newdata[i] = data[idx]; ++ newdata[i + 1] = map[addr + idx + 1]; ++ } ++ idx++; ++ break; ++ } else { ++ if ((data[idx] != map[addr + idx]) || ++ (data[idx + 1] != map[addr + idx + 1])) { ++ word_en &= ~BIT(i >> 1); ++ newdata[i] = data[idx]; ++ newdata[i + 1] = data[idx + 1]; ++ } ++ idx += 2; ++ } ++ if (idx == cnts) ++ break; ++ } ++ ++ if (word_en != 0xF) { ++ DBG_88E("%s: offset=%#X\n", __func__, offset); ++ DBG_88E("%s: word_en=%#X\n", __func__, word_en); ++ DBG_88E("%s: data=", __func__); ++ for (i = 0; i < PGPKT_DATA_SIZE; i++) ++ DBG_88E("0x%02X ", newdata[i]); ++ DBG_88E("\n"); ++ ++ ret = Efuse_PgPacketWrite_BT(padapter, offset, word_en, newdata, false); ++ if (ret == _FAIL) ++ break; ++ } ++ ++ if (idx == cnts) ++ break; ++ ++ offset++; ++ i = 0; ++ word_en = 0xF; ++ memset(newdata, 0xFF, PGPKT_DATA_SIZE); ++ } while (1); ++ ++ Efuse_PowerSwitch(padapter, true, false); ++ ++exit: ++ ++ kfree(map); ++ ++ return ret; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: efuse_ShadowRead1Byte ++ * efuse_ShadowRead2Byte ++ * efuse_ShadowRead4Byte ++ * ++ * Overview: Read from efuse init map by one/two/four bytes !!!!! ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/12/2008 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++static void ++efuse_ShadowRead1Byte( ++ struct adapter *pAdapter, ++ u16 Offset, ++ u8 *Value) ++{ ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); ++ ++ *Value = pEEPROM->efuse_eeprom_data[Offset]; ++ ++} /* EFUSE_ShadowRead1Byte */ ++ ++/* Read Two Bytes */ ++static void ++efuse_ShadowRead2Byte( ++ struct adapter *pAdapter, ++ u16 Offset, ++ u16 *Value) ++{ ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); ++ ++ *Value = pEEPROM->efuse_eeprom_data[Offset]; ++ *Value |= pEEPROM->efuse_eeprom_data[Offset + 1] << 8; ++ ++} /* EFUSE_ShadowRead2Byte */ ++ ++/* Read Four Bytes */ ++static void ++efuse_ShadowRead4Byte( ++ struct adapter *pAdapter, ++ u16 Offset, ++ u32 *Value) ++{ ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); ++ ++ *Value = pEEPROM->efuse_eeprom_data[Offset]; ++ *Value |= pEEPROM->efuse_eeprom_data[Offset + 1] << 8; ++ *Value |= pEEPROM->efuse_eeprom_data[Offset + 2] << 16; ++ *Value |= pEEPROM->efuse_eeprom_data[Offset + 3] << 24; ++ ++} /* efuse_ShadowRead4Byte */ ++ ++/*----------------------------------------------------------------------------- ++ * Function: Efuse_ReadAllMap ++ * ++ * Overview: Read All Efuse content ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/11/2008 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo) ++{ ++ u16 mapLen = 0; ++ ++ Efuse_PowerSwitch(pAdapter, false, true); ++ ++ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo); ++ ++ efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo); ++ ++ Efuse_PowerSwitch(pAdapter, false, false); ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: EFUSE_ShadowMapUpdate ++ * ++ * Overview: Transfer current EFUSE content to shadow init and modify map. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/13/2008 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++void EFUSE_ShadowMapUpdate( ++ struct adapter *pAdapter, ++ u8 efuseType, ++ bool pseudo) ++{ ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); ++ u16 mapLen = 0; ++ ++ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo); ++ ++ if (pEEPROM->bautoload_fail_flag) ++ memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen); ++ else ++ Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo); ++} /* EFUSE_ShadowMapUpdate */ ++ ++/*----------------------------------------------------------------------------- ++ * Function: EFUSE_ShadowRead ++ * ++ * Overview: Read from efuse init map !!!!! ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/12/2008 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++void EFUSE_ShadowRead(struct adapter *pAdapter, u8 Type, u16 Offset, u32 *Value) ++{ ++ if (Type == 1) ++ efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value); ++ else if (Type == 2) ++ efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value); ++ else if (Type == 4) ++ efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value); ++ ++} /* EFUSE_ShadowRead */ +diff --git a/drivers/staging/r8188eu/core/rtw_ieee80211.c b/drivers/staging/r8188eu/core/rtw_ieee80211.c +new file mode 100644 +index 000000000000..b3a74198596a +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_ieee80211.c +@@ -0,0 +1,1539 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _IEEE80211_C ++ ++#include "../include/drv_types.h" ++#include "../include/ieee80211.h" ++#include "../include/wifi.h" ++#include "../include/osdep_service.h" ++#include "../include/wlan_bssdef.h" ++#include "../include/usb_osintf.h" ++ ++u8 RTW_WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 }; ++u16 RTW_WPA_VERSION = 1; ++u8 WPA_AUTH_KEY_MGMT_NONE[] = { 0x00, 0x50, 0xf2, 0 }; ++u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x50, 0xf2, 1 }; ++u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x50, 0xf2, 2 }; ++u8 WPA_CIPHER_SUITE_NONE[] = { 0x00, 0x50, 0xf2, 0 }; ++u8 WPA_CIPHER_SUITE_WEP40[] = { 0x00, 0x50, 0xf2, 1 }; ++u8 WPA_CIPHER_SUITE_TKIP[] = { 0x00, 0x50, 0xf2, 2 }; ++u8 WPA_CIPHER_SUITE_WRAP[] = { 0x00, 0x50, 0xf2, 3 }; ++u8 WPA_CIPHER_SUITE_CCMP[] = { 0x00, 0x50, 0xf2, 4 }; ++u8 WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 }; ++ ++u16 RSN_VERSION_BSD = 1; ++u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x0f, 0xac, 1 }; ++u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x0f, 0xac, 2 }; ++u8 RSN_CIPHER_SUITE_NONE[] = { 0x00, 0x0f, 0xac, 0 }; ++u8 RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 }; ++u8 RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 }; ++u8 RSN_CIPHER_SUITE_WRAP[] = { 0x00, 0x0f, 0xac, 3 }; ++u8 RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 }; ++u8 RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 }; ++/* */ ++/* for adhoc-master to generate ie and provide supported-rate to fw */ ++/* */ ++ ++static u8 WIFI_CCKRATES[] = { ++ (IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK), ++ (IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK), ++ (IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK), ++ (IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK) ++ }; ++ ++static u8 WIFI_OFDMRATES[] = { ++ (IEEE80211_OFDM_RATE_6MB), ++ (IEEE80211_OFDM_RATE_9MB), ++ (IEEE80211_OFDM_RATE_12MB), ++ (IEEE80211_OFDM_RATE_18MB), ++ (IEEE80211_OFDM_RATE_24MB), ++ IEEE80211_OFDM_RATE_36MB, ++ IEEE80211_OFDM_RATE_48MB, ++ IEEE80211_OFDM_RATE_54MB ++ }; ++ ++int rtw_get_bit_value_from_ieee_value(u8 val) ++{ ++ unsigned char dot11_rate_table[] = { ++ 2, 4, 11, 22, 12, 18, 24, 36, 48, ++ 72, 96, 108, 0}; /* last element must be zero!! */ ++ ++ int i = 0; ++ while (dot11_rate_table[i] != 0) { ++ if (dot11_rate_table[i] == val) ++ return BIT(i); ++ i++; ++ } ++ return 0; ++} ++ ++uint rtw_is_cckrates_included(u8 *rate) ++{ ++ u32 i = 0; ++ ++ while (rate[i] != 0) { ++ if ((((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) || ++ (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22)) ++ return true; ++ i++; ++ } ++ return false; ++} ++ ++uint rtw_is_cckratesonly_included(u8 *rate) ++{ ++ u32 i = 0; ++ ++ while (rate[i] != 0) { ++ if ((((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && ++ (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22)) ++ return false; ++ i++; ++ } ++ ++ return true; ++} ++ ++int rtw_check_network_type(unsigned char *rate, int ratelen, int channel) ++{ ++ if (channel > 14) { ++ return WIRELESS_INVALID; ++ } else { /* could be pure B, pure G, or B/G */ ++ if (rtw_is_cckratesonly_included(rate)) ++ return WIRELESS_11B; ++ else if (rtw_is_cckrates_included(rate)) ++ return WIRELESS_11BG; ++ else ++ return WIRELESS_11G; ++ } ++} ++ ++u8 *rtw_set_fixed_ie(unsigned char *pbuf, unsigned int len, unsigned char *source, ++ unsigned int *frlen) ++{ ++ memcpy((void *)pbuf, (void *)source, len); ++ *frlen = *frlen + len; ++ return pbuf + len; ++} ++ ++/* rtw_set_ie will update frame length */ ++u8 *rtw_set_ie ++( ++ u8 *pbuf, ++ int index, ++ uint len, ++ u8 *source, ++ uint *frlen /* frame length */ ++) ++{ ++ ++ *pbuf = (u8)index; ++ ++ *(pbuf + 1) = (u8)len; ++ ++ if (len > 0) ++ memcpy((void *)(pbuf + 2), (void *)source, len); ++ ++ *frlen = *frlen + (len + 2); ++ ++ return pbuf + len + 2; ++} ++ ++inline u8 *rtw_set_ie_ch_switch(u8 *buf, u32 *buf_len, u8 ch_switch_mode, ++ u8 new_ch, u8 ch_switch_cnt) ++{ ++ u8 ie_data[3]; ++ ++ ie_data[0] = ch_switch_mode; ++ ie_data[1] = new_ch; ++ ie_data[2] = ch_switch_cnt; ++ return rtw_set_ie(buf, WLAN_EID_CHANNEL_SWITCH, 3, ie_data, buf_len); ++} ++ ++inline u8 secondary_ch_offset_to_hal_ch_offset(u8 ch_offset) ++{ ++ if (ch_offset == SCN) ++ return HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ else if (ch_offset == SCA) ++ return HAL_PRIME_CHNL_OFFSET_UPPER; ++ else if (ch_offset == SCB) ++ return HAL_PRIME_CHNL_OFFSET_LOWER; ++ ++ return HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++} ++ ++inline u8 hal_ch_offset_to_secondary_ch_offset(u8 ch_offset) ++{ ++ if (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ++ return SCN; ++ else if (ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) ++ return SCB; ++ else if (ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER) ++ return SCA; ++ ++ return SCN; ++} ++ ++inline u8 *rtw_set_ie_secondary_ch_offset(u8 *buf, u32 *buf_len, u8 secondary_ch_offset) ++{ ++ return rtw_set_ie(buf, WLAN_EID_SECONDARY_CHANNEL_OFFSET, 1, &secondary_ch_offset, buf_len); ++} ++ ++inline u8 *rtw_set_ie_mesh_ch_switch_parm(u8 *buf, u32 *buf_len, u8 ttl, ++ u8 flags, u16 reason, u16 precedence) ++{ ++ u8 ie_data[6]; ++ ++ ie_data[0] = ttl; ++ ie_data[1] = flags; ++ *(u16 *)(ie_data + 2) = cpu_to_le16(reason); ++ *(u16 *)(ie_data + 4) = cpu_to_le16(precedence); ++ ++ return rtw_set_ie(buf, 0x118, 6, ie_data, buf_len); ++} ++ ++/*---------------------------------------------------------------------------- ++index: the information element id index, limit is the limit for search ++-----------------------------------------------------------------------------*/ ++u8 *rtw_get_ie(u8 *pbuf, int index, int *len, int limit) ++{ ++ int tmp, i; ++ u8 *p; ++ ++ if (limit < 1) { ++ ++ return NULL; ++ } ++ ++ p = pbuf; ++ i = 0; ++ *len = 0; ++ while (1) { ++ if (*p == index) { ++ *len = *(p + 1); ++ return p; ++ } else { ++ tmp = *(p + 1); ++ p += (tmp + 2); ++ i += (tmp + 2); ++ } ++ if (i >= limit) ++ break; ++ } ++ ++ return NULL; ++} ++ ++/** ++ * rtw_get_ie_ex - Search specific IE from a series of IEs ++ * @in_ie: Address of IEs to search ++ * @in_len: Length limit from in_ie ++ * @eid: Element ID to match ++ * @oui: OUI to match ++ * @oui_len: OUI length ++ * @ie: If not NULL and the specific IE is found, the IE will be copied to the buf starting from the specific IE ++ * @ielen: If not NULL and the specific IE is found, will set to the length of the entire IE ++ * ++ * Returns: The address of the specific IE found, or NULL ++ */ ++u8 *rtw_get_ie_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, u8 oui_len, u8 *ie, uint *ielen) ++{ ++ uint cnt; ++ u8 *target_ie = NULL; ++ ++ if (ielen) ++ *ielen = 0; ++ ++ if (!in_ie || in_len <= 0) ++ return target_ie; ++ ++ cnt = 0; ++ ++ while (cnt < in_len) { ++ if (eid == in_ie[cnt] && (!oui || !memcmp(&in_ie[cnt + 2], oui, oui_len))) { ++ target_ie = &in_ie[cnt]; ++ ++ if (ie) ++ memcpy(ie, &in_ie[cnt], in_ie[cnt + 1] + 2); ++ ++ if (ielen) ++ *ielen = in_ie[cnt + 1] + 2; ++ ++ break; ++ } else { ++ cnt += in_ie[cnt + 1] + 2; /* goto next */ ++ } ++ } ++ return target_ie; ++} ++ ++/** ++ * rtw_ies_remove_ie - Find matching IEs and remove ++ * @ies: Address of IEs to search ++ * @ies_len: Pointer of length of ies, will update to new length ++ * @offset: The offset to start scarch ++ * @eid: Element ID to match ++ * @oui: OUI to match ++ * @oui_len: OUI length ++ * ++ * Returns: _SUCCESS: ies is updated, _FAIL: not updated ++ */ ++int rtw_ies_remove_ie(u8 *ies, uint *ies_len, uint offset, u8 eid, u8 *oui, u8 oui_len) ++{ ++ int ret = _FAIL; ++ u8 *target_ie; ++ u32 target_ielen; ++ u8 *start; ++ uint search_len; ++ ++ if (!ies || !ies_len || *ies_len <= offset) ++ goto exit; ++ ++ start = ies + offset; ++ search_len = *ies_len - offset; ++ ++ while (1) { ++ target_ie = rtw_get_ie_ex(start, search_len, eid, oui, oui_len, NULL, &target_ielen); ++ if (target_ie && target_ielen) { ++ u8 buf[MAX_IE_SZ] = {0}; ++ u8 *remain_ies = target_ie + target_ielen; ++ uint remain_len = search_len - (remain_ies - start); ++ ++ memcpy(buf, remain_ies, remain_len); ++ memcpy(target_ie, buf, remain_len); ++ *ies_len = *ies_len - target_ielen; ++ ret = _SUCCESS; ++ ++ start = target_ie; ++ search_len = remain_len; ++ } else { ++ break; ++ } ++ } ++exit: ++ return ret; ++} ++ ++void rtw_set_supported_rate(u8 *SupportedRates, uint mode) ++{ ++ ++ memset(SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX); ++ ++ switch (mode) { ++ case WIRELESS_11B: ++ memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN); ++ break; ++ case WIRELESS_11G: ++ memcpy(SupportedRates, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN); ++ break; ++ case WIRELESS_11BG: ++ case WIRELESS_11G_24N: ++ case WIRELESS_11_24N: ++ case WIRELESS_11BG_24N: ++ memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN); ++ memcpy(SupportedRates + IEEE80211_CCK_RATE_LEN, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN); ++ break; ++ } ++ ++} ++ ++uint rtw_get_rateset_len(u8 *rateset) ++{ ++ uint i = 0; ++ ++ while (1) { ++ if ((rateset[i]) == 0) ++ break; ++ if (i > 12) ++ break; ++ i++; ++ } ++ ++ return i; ++} ++ ++int rtw_generate_ie(struct registry_priv *pregistrypriv) ++{ ++ u8 wireless_mode; ++ int sz = 0, rateLen; ++ struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; ++ u8 *ie = pdev_network->IEs; ++ ++ /* timestamp will be inserted by hardware */ ++ sz += 8; ++ ie += sz; ++ ++ /* beacon interval : 2bytes */ ++ *(__le16 *)ie = cpu_to_le16((u16)pdev_network->Configuration.BeaconPeriod);/* BCN_INTERVAL; */ ++ sz += 2; ++ ie += 2; ++ ++ /* capability info */ ++ *(u16 *)ie = 0; ++ ++ *(__le16 *)ie |= cpu_to_le16(cap_IBSS); ++ ++ if (pregistrypriv->preamble == PREAMBLE_SHORT) ++ *(__le16 *)ie |= cpu_to_le16(cap_ShortPremble); ++ ++ if (pdev_network->Privacy) ++ *(__le16 *)ie |= cpu_to_le16(cap_Privacy); ++ ++ sz += 2; ++ ie += 2; ++ ++ /* SSID */ ++ ie = rtw_set_ie(ie, _SSID_IE_, pdev_network->Ssid.SsidLength, pdev_network->Ssid.Ssid, &sz); ++ ++ /* supported rates */ ++ wireless_mode = pregistrypriv->wireless_mode; ++ ++ rtw_set_supported_rate(pdev_network->SupportedRates, wireless_mode); ++ ++ rateLen = rtw_get_rateset_len(pdev_network->SupportedRates); ++ ++ if (rateLen > 8) { ++ ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, pdev_network->SupportedRates, &sz); ++ /* ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz); */ ++ } else { ++ ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, pdev_network->SupportedRates, &sz); ++ } ++ ++ /* DS parameter set */ ++ ie = rtw_set_ie(ie, _DSSET_IE_, 1, (u8 *)&pdev_network->Configuration.DSConfig, &sz); ++ ++ /* IBSS Parameter Set */ ++ ++ ie = rtw_set_ie(ie, _IBSS_PARA_IE_, 2, (u8 *)&pdev_network->Configuration.ATIMWindow, &sz); ++ ++ if (rateLen > 8) ++ ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz); ++ ++ return sz; ++} ++ ++unsigned char *rtw_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit) ++{ ++ int len; ++ u16 val16; ++ __le16 le_tmp; ++ unsigned char wpa_oui_type[] = {0x00, 0x50, 0xf2, 0x01}; ++ u8 *pbuf = pie; ++ int limit_new = limit; ++ ++ while (1) { ++ pbuf = rtw_get_ie(pbuf, _WPA_IE_ID_, &len, limit_new); ++ ++ if (pbuf) { ++ /* check if oui matches... */ ++ if (memcmp((pbuf + 2), wpa_oui_type, sizeof(wpa_oui_type))) ++ goto check_next_ie; ++ ++ /* check version... */ ++ memcpy((u8 *)&le_tmp, (pbuf + 6), sizeof(val16)); ++ ++ val16 = le16_to_cpu(le_tmp); ++ if (val16 != 0x0001) ++ goto check_next_ie; ++ *wpa_ie_len = *(pbuf + 1); ++ return pbuf; ++ } else { ++ *wpa_ie_len = 0; ++ return NULL; ++ } ++ ++check_next_ie: ++ limit_new = limit - (pbuf - pie) - 2 - len; ++ if (limit_new <= 0) ++ break; ++ pbuf += (2 + len); ++ } ++ *wpa_ie_len = 0; ++ return NULL; ++} ++ ++unsigned char *rtw_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit) ++{ ++ ++ return rtw_get_ie(pie, _WPA2_IE_ID_, rsn_ie_len, limit); ++} ++ ++int rtw_get_wpa_cipher_suite(u8 *s) ++{ ++ if (!memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN)) ++ return WPA_CIPHER_NONE; ++ if (!memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN)) ++ return WPA_CIPHER_WEP40; ++ if (!memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN)) ++ return WPA_CIPHER_TKIP; ++ if (!memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN)) ++ return WPA_CIPHER_CCMP; ++ if (!memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN)) ++ return WPA_CIPHER_WEP104; ++ ++ return 0; ++} ++ ++int rtw_get_wpa2_cipher_suite(u8 *s) ++{ ++ if (!memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN)) ++ return WPA_CIPHER_NONE; ++ if (!memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN)) ++ return WPA_CIPHER_WEP40; ++ if (!memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN)) ++ return WPA_CIPHER_TKIP; ++ if (!memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN)) ++ return WPA_CIPHER_CCMP; ++ if (!memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN)) ++ return WPA_CIPHER_WEP104; ++ ++ return 0; ++} ++ ++int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x) ++{ ++ int i, ret = _SUCCESS; ++ int left, count; ++ u8 *pos; ++ u8 SUITE_1X[4] = {0x00, 0x50, 0xf2, 1}; ++ ++ if (wpa_ie_len <= 0) { ++ /* No WPA IE - fail silently */ ++ return _FAIL; ++ } ++ ++ if ((*wpa_ie != _WPA_IE_ID_) || (*(wpa_ie + 1) != (u8)(wpa_ie_len - 2)) || ++ (memcmp(wpa_ie + 2, RTW_WPA_OUI_TYPE, WPA_SELECTOR_LEN))) ++ return _FAIL; ++ ++ pos = wpa_ie; ++ ++ pos += 8; ++ left = wpa_ie_len - 8; ++ ++ /* group_cipher */ ++ if (left >= WPA_SELECTOR_LEN) { ++ *group_cipher = rtw_get_wpa_cipher_suite(pos); ++ pos += WPA_SELECTOR_LEN; ++ left -= WPA_SELECTOR_LEN; ++ } else if (left > 0) { ++ return _FAIL; ++ } ++ ++ /* pairwise_cipher */ ++ if (left >= 2) { ++ count = get_unaligned_le16(pos); ++ pos += 2; ++ left -= 2; ++ ++ if (count == 0 || left < count * WPA_SELECTOR_LEN) ++ return _FAIL; ++ ++ for (i = 0; i < count; i++) { ++ *pairwise_cipher |= rtw_get_wpa_cipher_suite(pos); ++ ++ pos += WPA_SELECTOR_LEN; ++ left -= WPA_SELECTOR_LEN; ++ } ++ } else if (left == 1) { ++ return _FAIL; ++ } ++ ++ if (is_8021x) { ++ if (left >= 6) { ++ pos += 2; ++ if (!memcmp(pos, SUITE_1X, 4)) ++ *is_8021x = 1; ++ } ++ } ++ ++ return ret; ++} ++ ++int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x) ++{ ++ int i, ret = _SUCCESS; ++ int left, count; ++ u8 *pos; ++ u8 SUITE_1X[4] = {0x00, 0x0f, 0xac, 0x01}; ++ ++ if (rsn_ie_len <= 0) { ++ /* No RSN IE - fail silently */ ++ return _FAIL; ++ } ++ ++ if ((*rsn_ie != _WPA2_IE_ID_) || (*(rsn_ie + 1) != (u8)(rsn_ie_len - 2))) ++ return _FAIL; ++ ++ pos = rsn_ie; ++ pos += 4; ++ left = rsn_ie_len - 4; ++ ++ /* group_cipher */ ++ if (left >= RSN_SELECTOR_LEN) { ++ *group_cipher = rtw_get_wpa2_cipher_suite(pos); ++ ++ pos += RSN_SELECTOR_LEN; ++ left -= RSN_SELECTOR_LEN; ++ ++ } else if (left > 0) { ++ return _FAIL; ++ } ++ ++ /* pairwise_cipher */ ++ if (left >= 2) { ++ count = get_unaligned_le16(pos); ++ pos += 2; ++ left -= 2; ++ ++ if (count == 0 || left < count * RSN_SELECTOR_LEN) ++ return _FAIL; ++ ++ for (i = 0; i < count; i++) { ++ *pairwise_cipher |= rtw_get_wpa2_cipher_suite(pos); ++ ++ pos += RSN_SELECTOR_LEN; ++ left -= RSN_SELECTOR_LEN; ++ } ++ ++ } else if (left == 1) { ++ return _FAIL; ++ } ++ ++ if (is_8021x) { ++ if (left >= 6) { ++ pos += 2; ++ if (!memcmp(pos, SUITE_1X, 4)) ++ *is_8021x = 1; ++ } ++ } ++ return ret; ++} ++ ++int rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie, u16 *wpa_len) ++{ ++ u8 authmode; ++ u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01}; ++ uint cnt; ++ ++ /* Search required WPA or WPA2 IE and copy to sec_ie[] */ ++ ++ cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_); ++ ++ while (cnt < in_len) { ++ authmode = in_ie[cnt]; ++ ++ if ((authmode == _WPA_IE_ID_) && (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) { ++ if (wpa_ie) ++ memcpy(wpa_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); ++ ++ *wpa_len = in_ie[cnt + 1] + 2; ++ cnt += in_ie[cnt + 1] + 2; /* get next */ ++ } else { ++ if (authmode == _WPA2_IE_ID_) { ++ if (rsn_ie) ++ memcpy(rsn_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); ++ ++ *rsn_len = in_ie[cnt + 1] + 2; ++ cnt += in_ie[cnt + 1] + 2; /* get next */ ++ } else { ++ cnt += in_ie[cnt + 1] + 2; /* get next */ ++ } ++ } ++ } ++ ++ return *rsn_len + *wpa_len; ++} ++ ++u8 rtw_is_wps_ie(u8 *ie_ptr, uint *wps_ielen) ++{ ++ u8 match = false; ++ u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; ++ ++ if (!ie_ptr) ++ return match; ++ ++ eid = ie_ptr[0]; ++ ++ if ((eid == _WPA_IE_ID_) && (!memcmp(&ie_ptr[2], wps_oui, 4))) { ++ *wps_ielen = ie_ptr[1] + 2; ++ match = true; ++ } ++ return match; ++} ++ ++/** ++ * rtw_get_wps_ie - Search WPS IE from a series of IEs ++ * @in_ie: Address of IEs to search ++ * @in_len: Length limit from in_ie ++ * @wps_ie: If not NULL and WPS IE is found, WPS IE will be copied to the buf starting from wps_ie ++ * @wps_ielen: If not NULL and WPS IE is found, will set to the length of the entire WPS IE ++ * ++ * Returns: The address of the WPS IE found, or NULL ++ */ ++u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen) ++{ ++ uint cnt; ++ u8 *wpsie_ptr = NULL; ++ u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; ++ ++ if (wps_ielen) ++ *wps_ielen = 0; ++ ++ if (!in_ie || in_len <= 0) ++ return wpsie_ptr; ++ ++ cnt = 0; ++ ++ while (cnt < in_len) { ++ eid = in_ie[cnt]; ++ ++ if ((eid == _WPA_IE_ID_) && (!memcmp(&in_ie[cnt + 2], wps_oui, 4))) { ++ wpsie_ptr = &in_ie[cnt]; ++ ++ if (wps_ie) ++ memcpy(wps_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); ++ ++ if (wps_ielen) ++ *wps_ielen = in_ie[cnt + 1] + 2; ++ ++ cnt += in_ie[cnt + 1] + 2; ++ ++ break; ++ } else { ++ cnt += in_ie[cnt + 1] + 2; /* goto next */ ++ } ++ } ++ return wpsie_ptr; ++} ++ ++/** ++ * rtw_get_wps_attr - Search a specific WPS attribute from a given WPS IE ++ * @wps_ie: Address of WPS IE to search ++ * @wps_ielen: Length limit from wps_ie ++ * @target_attr_id: The attribute ID of WPS attribute to search ++ * @buf_attr: If not NULL and the WPS attribute is found, WPS attribute will be copied to the buf starting from buf_attr ++ * @len_attr: If not NULL and the WPS attribute is found, will set to the length of the entire WPS attribute ++ * ++ * Returns: the address of the specific WPS attribute found, or NULL ++ */ ++u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_attr, u32 *len_attr) ++{ ++ u8 *attr_ptr = NULL; ++ u8 *target_attr_ptr = NULL; ++ u8 wps_oui[4] = {0x00, 0x50, 0xF2, 0x04}; ++ ++ if (len_attr) ++ *len_attr = 0; ++ ++ if ((wps_ie[0] != _VENDOR_SPECIFIC_IE_) || ++ (memcmp(wps_ie + 2, wps_oui, 4))) ++ return attr_ptr; ++ ++ /* 6 = 1(Element ID) + 1(Length) + 4(WPS OUI) */ ++ attr_ptr = wps_ie + 6; /* goto first attr */ ++ ++ while (attr_ptr - wps_ie < wps_ielen) { ++ /* 4 = 2(Attribute ID) + 2(Length) */ ++ u16 attr_id = RTW_GET_BE16(attr_ptr); ++ u16 attr_data_len = RTW_GET_BE16(attr_ptr + 2); ++ u16 attr_len = attr_data_len + 4; ++ ++ if (attr_id == target_attr_id) { ++ target_attr_ptr = attr_ptr; ++ if (buf_attr) ++ memcpy(buf_attr, attr_ptr, attr_len); ++ if (len_attr) ++ *len_attr = attr_len; ++ break; ++ } else { ++ attr_ptr += attr_len; /* goto next */ ++ } ++ } ++ return target_attr_ptr; ++} ++ ++/** ++ * rtw_get_wps_attr_content - Search a specific WPS attribute content from a given WPS IE ++ * @wps_ie: Address of WPS IE to search ++ * @wps_ielen: Length limit from wps_ie ++ * @target_attr_id: The attribute ID of WPS attribute to search ++ * @buf_content: If not NULL and the WPS attribute is found, WPS attribute content will be copied to the buf starting from buf_content ++ * @len_content: If not NULL and the WPS attribute is found, will set to the length of the WPS attribute content ++ * ++ * Returns: the address of the specific WPS attribute content found, or NULL ++ */ ++u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_content, uint *len_content) ++{ ++ u8 *attr_ptr; ++ u32 attr_len; ++ ++ if (len_content) ++ *len_content = 0; ++ ++ attr_ptr = rtw_get_wps_attr(wps_ie, wps_ielen, target_attr_id, NULL, &attr_len); ++ ++ if (attr_ptr && attr_len) { ++ if (buf_content) ++ memcpy(buf_content, attr_ptr + 4, attr_len - 4); ++ ++ if (len_content) ++ *len_content = attr_len - 4; ++ ++ return attr_ptr + 4; ++ } ++ ++ return NULL; ++} ++ ++static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, ++ struct rtw_ieee802_11_elems *elems, ++ int show_errors) ++{ ++ unsigned int oui; ++ ++ /* first 3 bytes in vendor specific information element are the IEEE ++ * OUI of the vendor. The following byte is used a vendor specific ++ * sub-type. */ ++ if (elen < 4) { ++ if (show_errors) { ++ DBG_88E("short vendor specific information element ignored (len=%lu)\n", ++ (unsigned long)elen); ++ } ++ return -1; ++ } ++ ++ oui = RTW_GET_BE24(pos); ++ switch (oui) { ++ case OUI_MICROSOFT: ++ /* Microsoft/Wi-Fi information elements are further typed and ++ * subtyped */ ++ switch (pos[3]) { ++ case 1: ++ /* Microsoft OUI (00:50:F2) with OUI Type 1: ++ * real WPA information element */ ++ elems->wpa_ie = pos; ++ elems->wpa_ie_len = elen; ++ break; ++ case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */ ++ if (elen < 5) { ++ DBG_88E("short WME information element ignored (len=%lu)\n", ++ (unsigned long)elen); ++ return -1; ++ } ++ switch (pos[4]) { ++ case WME_OUI_SUBTYPE_INFORMATION_ELEMENT: ++ case WME_OUI_SUBTYPE_PARAMETER_ELEMENT: ++ elems->wme = pos; ++ elems->wme_len = elen; ++ break; ++ case WME_OUI_SUBTYPE_TSPEC_ELEMENT: ++ elems->wme_tspec = pos; ++ elems->wme_tspec_len = elen; ++ break; ++ default: ++ DBG_88E("unknown WME information element ignored (subtype=%d len=%lu)\n", ++ pos[4], (unsigned long)elen); ++ return -1; ++ } ++ break; ++ case 4: ++ /* Wi-Fi Protected Setup (WPS) IE */ ++ elems->wps_ie = pos; ++ elems->wps_ie_len = elen; ++ break; ++ default: ++ DBG_88E("Unknown Microsoft information element ignored (type=%d len=%lu)\n", ++ pos[3], (unsigned long)elen); ++ return -1; ++ } ++ break; ++ ++ case OUI_BROADCOM: ++ switch (pos[3]) { ++ case VENDOR_HT_CAPAB_OUI_TYPE: ++ elems->vendor_ht_cap = pos; ++ elems->vendor_ht_cap_len = elen; ++ break; ++ default: ++ DBG_88E("Unknown Broadcom information element ignored (type=%d len=%lu)\n", ++ pos[3], (unsigned long)elen); ++ return -1; ++ } ++ break; ++ default: ++ DBG_88E("unknown vendor specific information element ignored (vendor OUI %02x:%02x:%02x len=%lu)\n", ++ pos[0], pos[1], pos[2], (unsigned long)elen); ++ return -1; ++ } ++ return 0; ++} ++ ++/** ++ * ieee802_11_parse_elems - Parse information elements in management frames ++ * @start: Pointer to the start of IEs ++ * @len: Length of IE buffer in octets ++ * @elems: Data structure for parsed elements ++ * @show_errors: Whether to show parsing errors in debug log ++ * Returns: Parsing result ++ */ ++enum parse_res rtw_ieee802_11_parse_elems(u8 *start, uint len, ++ struct rtw_ieee802_11_elems *elems, ++ int show_errors) ++{ ++ uint left = len; ++ u8 *pos = start; ++ int unknown = 0; ++ ++ memset(elems, 0, sizeof(*elems)); ++ ++ while (left >= 2) { ++ u8 id, elen; ++ ++ id = *pos++; ++ elen = *pos++; ++ left -= 2; ++ ++ if (elen > left) { ++ if (show_errors) { ++ DBG_88E("IEEE 802.11 element parse failed (id=%d elen=%d left=%lu)\n", ++ id, elen, (unsigned long)left); ++ } ++ return ParseFailed; ++ } ++ ++ switch (id) { ++ case WLAN_EID_SSID: ++ elems->ssid = pos; ++ elems->ssid_len = elen; ++ break; ++ case WLAN_EID_SUPP_RATES: ++ elems->supp_rates = pos; ++ elems->supp_rates_len = elen; ++ break; ++ case WLAN_EID_FH_PARAMS: ++ elems->fh_params = pos; ++ elems->fh_params_len = elen; ++ break; ++ case WLAN_EID_DS_PARAMS: ++ elems->ds_params = pos; ++ elems->ds_params_len = elen; ++ break; ++ case WLAN_EID_CF_PARAMS: ++ elems->cf_params = pos; ++ elems->cf_params_len = elen; ++ break; ++ case WLAN_EID_TIM: ++ elems->tim = pos; ++ elems->tim_len = elen; ++ break; ++ case WLAN_EID_IBSS_PARAMS: ++ elems->ibss_params = pos; ++ elems->ibss_params_len = elen; ++ break; ++ case WLAN_EID_CHALLENGE: ++ elems->challenge = pos; ++ elems->challenge_len = elen; ++ break; ++ case WLAN_EID_ERP_INFO: ++ elems->erp_info = pos; ++ elems->erp_info_len = elen; ++ break; ++ case WLAN_EID_EXT_SUPP_RATES: ++ elems->ext_supp_rates = pos; ++ elems->ext_supp_rates_len = elen; ++ break; ++ case WLAN_EID_VENDOR_SPECIFIC: ++ if (rtw_ieee802_11_parse_vendor_specific(pos, elen, elems, show_errors)) ++ unknown++; ++ break; ++ case WLAN_EID_RSN: ++ elems->rsn_ie = pos; ++ elems->rsn_ie_len = elen; ++ break; ++ case WLAN_EID_PWR_CAPABILITY: ++ elems->power_cap = pos; ++ elems->power_cap_len = elen; ++ break; ++ case WLAN_EID_SUPPORTED_CHANNELS: ++ elems->supp_channels = pos; ++ elems->supp_channels_len = elen; ++ break; ++ case WLAN_EID_MOBILITY_DOMAIN: ++ elems->mdie = pos; ++ elems->mdie_len = elen; ++ break; ++ case WLAN_EID_FAST_BSS_TRANSITION: ++ elems->ftie = pos; ++ elems->ftie_len = elen; ++ break; ++ case WLAN_EID_TIMEOUT_INTERVAL: ++ elems->timeout_int = pos; ++ elems->timeout_int_len = elen; ++ break; ++ case WLAN_EID_HT_CAP: ++ elems->ht_capabilities = pos; ++ elems->ht_capabilities_len = elen; ++ break; ++ case WLAN_EID_HT_OPERATION: ++ elems->ht_operation = pos; ++ elems->ht_operation_len = elen; ++ break; ++ default: ++ unknown++; ++ if (!show_errors) ++ break; ++ DBG_88E("IEEE 802.11 element parse ignored unknown element (id=%d elen=%d)\n", ++ id, elen); ++ break; ++ } ++ left -= elen; ++ pos += elen; ++ } ++ if (left) ++ return ParseFailed; ++ return unknown ? ParseUnknown : ParseOK; ++} ++ ++u8 key_char2num(u8 ch) ++{ ++ if ((ch >= '0') && (ch <= '9')) ++ return ch - '0'; ++ else if ((ch >= 'a') && (ch <= 'f')) ++ return ch - 'a' + 10; ++ else if ((ch >= 'A') && (ch <= 'F')) ++ return ch - 'A' + 10; ++ else ++ return 0xff; ++} ++ ++u8 str_2char2num(u8 hch, u8 lch) ++{ ++ return (key_char2num(hch) * 10) + key_char2num(lch); ++} ++ ++u8 key_2char2num(u8 hch, u8 lch) ++{ ++ return (key_char2num(hch) << 4) | key_char2num(lch); ++} ++ ++void rtw_macaddr_cfg(u8 *mac_addr) ++{ ++ u8 mac[ETH_ALEN]; ++ if (!mac_addr) ++ return; ++ ++ if (rtw_initmac) { /* Users specify the mac address */ ++ int jj, kk; ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ mac[jj] = key_2char2num(rtw_initmac[kk], rtw_initmac[kk + 1]); ++ memcpy(mac_addr, mac, ETH_ALEN); ++ } else { /* Use the mac address stored in the Efuse */ ++ memcpy(mac, mac_addr, ETH_ALEN); ++ } ++ ++ if (((mac[0] == 0xff) && (mac[1] == 0xff) && (mac[2] == 0xff) && ++ (mac[3] == 0xff) && (mac[4] == 0xff) && (mac[5] == 0xff)) || ++ ((mac[0] == 0x0) && (mac[1] == 0x0) && (mac[2] == 0x0) && ++ (mac[3] == 0x0) && (mac[4] == 0x0) && (mac[5] == 0x0))) { ++ mac[0] = 0x00; ++ mac[1] = 0xe0; ++ mac[2] = 0x4c; ++ mac[3] = 0x87; ++ mac[4] = 0x00; ++ mac[5] = 0x00; ++ /* use default mac addresss */ ++ memcpy(mac_addr, mac, ETH_ALEN); ++ DBG_88E("MAC Address from efuse error, assign default one !!!\n"); ++ } ++ ++ DBG_88E("rtw_macaddr_cfg MAC Address = %pM\n", (mac_addr)); ++} ++ ++void dump_ies(u8 *buf, u32 buf_len) ++{ ++ u8 *pos = (u8 *)buf; ++ u8 id, len; ++ ++ while (pos - buf <= buf_len) { ++ id = *pos; ++ len = *(pos + 1); ++ ++ DBG_88E("%s ID:%u, LEN:%u\n", __func__, id, len); ++ #ifdef CONFIG_88EU_P2P ++ dump_p2p_ie(pos, len); ++ #endif ++ dump_wps_ie(pos, len); ++ ++ pos += (2 + len); ++ } ++} ++ ++void dump_wps_ie(u8 *ie, u32 ie_len) ++{ ++ u8 *pos = (u8 *)ie; ++ u16 id; ++ u16 len; ++ u8 *wps_ie; ++ uint wps_ielen; ++ ++ wps_ie = rtw_get_wps_ie(ie, ie_len, NULL, &wps_ielen); ++ if (wps_ie != ie || wps_ielen == 0) ++ return; ++ ++ pos += 6; ++ while (pos - ie < ie_len) { ++ id = RTW_GET_BE16(pos); ++ len = RTW_GET_BE16(pos + 2); ++ DBG_88E("%s ID:0x%04x, LEN:%u\n", __func__, id, len); ++ pos += (4 + len); ++ } ++} ++ ++#ifdef CONFIG_88EU_P2P ++void dump_p2p_ie(u8 *ie, u32 ie_len) ++{ ++ u8 *pos = (u8 *)ie; ++ u8 id; ++ u16 len; ++ u8 *p2p_ie; ++ uint p2p_ielen; ++ ++ p2p_ie = rtw_get_p2p_ie(ie, ie_len, NULL, &p2p_ielen); ++ if (p2p_ie != ie || p2p_ielen == 0) ++ return; ++ ++ pos += 6; ++ while (pos - ie < ie_len) { ++ id = *pos; ++ len = get_unaligned_le16(pos + 1); ++ DBG_88E("%s ID:%u, LEN:%u\n", __func__, id, len); ++ pos += (3 + len); ++ } ++} ++ ++/** ++ * rtw_get_p2p_ie - Search P2P IE from a series of IEs ++ * @in_ie: Address of IEs to search ++ * @in_len: Length limit from in_ie ++ * @p2p_ie: If not NULL and P2P IE is found, P2P IE will be copied to the buf starting from p2p_ie ++ * @p2p_ielen: If not NULL and P2P IE is found, will set to the length of the entire P2P IE ++ * ++ * Returns: The address of the P2P IE found, or NULL ++ */ ++u8 *rtw_get_p2p_ie(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen) ++{ ++ uint cnt = 0; ++ u8 *p2p_ie_ptr; ++ u8 eid, p2p_oui[4] = {0x50, 0x6F, 0x9A, 0x09}; ++ ++ if (p2p_ielen) ++ *p2p_ielen = 0; ++ ++ while (cnt < in_len) { ++ eid = in_ie[cnt]; ++ if ((in_len < 0) || (cnt > MAX_IE_SZ)) { ++ dump_stack(); ++ return NULL; ++ } ++ if ((eid == _VENDOR_SPECIFIC_IE_) && !memcmp(&in_ie[cnt + 2], p2p_oui, 4)) { ++ p2p_ie_ptr = in_ie + cnt; ++ ++ if (p2p_ie) ++ memcpy(p2p_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); ++ if (p2p_ielen) ++ *p2p_ielen = in_ie[cnt + 1] + 2; ++ return p2p_ie_ptr; ++ } else { ++ cnt += in_ie[cnt + 1] + 2; /* goto next */ ++ } ++ } ++ return NULL; ++} ++ ++/** ++ * rtw_get_p2p_attr - Search a specific P2P attribute from a given P2P IE ++ * @p2p_ie: Address of P2P IE to search ++ * @p2p_ielen: Length limit from p2p_ie ++ * @target_attr_id: The attribute ID of P2P attribute to search ++ * @buf_attr: If not NULL and the P2P attribute is found, P2P attribute will be copied to the buf starting from buf_attr ++ * @len_attr: If not NULL and the P2P attribute is found, will set to the length of the entire P2P attribute ++ * ++ * Returns: the address of the specific WPS attribute found, or NULL ++ */ ++u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id, u8 *buf_attr, u32 *len_attr) ++{ ++ u8 *attr_ptr = NULL; ++ u8 *target_attr_ptr = NULL; ++ u8 p2p_oui[4] = {0x50, 0x6F, 0x9A, 0x09}; ++ ++ if (len_attr) ++ *len_attr = 0; ++ ++ if (!p2p_ie || (p2p_ie[0] != _VENDOR_SPECIFIC_IE_) || ++ memcmp(p2p_ie + 2, p2p_oui, 4)) ++ return attr_ptr; ++ ++ /* 6 = 1(Element ID) + 1(Length) + 3 (OUI) + 1(OUI Type) */ ++ attr_ptr = p2p_ie + 6; /* goto first attr */ ++ ++ while (attr_ptr - p2p_ie < p2p_ielen) { ++ /* 3 = 1(Attribute ID) + 2(Length) */ ++ u8 attr_id = *attr_ptr; ++ u16 attr_data_len = get_unaligned_le16(attr_ptr + 1); ++ u16 attr_len = attr_data_len + 3; ++ ++ if (attr_id == target_attr_id) { ++ target_attr_ptr = attr_ptr; ++ ++ if (buf_attr) ++ memcpy(buf_attr, attr_ptr, attr_len); ++ if (len_attr) ++ *len_attr = attr_len; ++ break; ++ } else { ++ attr_ptr += attr_len; /* goto next */ ++ } ++ } ++ return target_attr_ptr; ++} ++ ++/** ++ * rtw_get_p2p_attr_content - Search a specific P2P attribute content from a given P2P IE ++ * @p2p_ie: Address of P2P IE to search ++ * @p2p_ielen: Length limit from p2p_ie ++ * @target_attr_id: The attribute ID of P2P attribute to search ++ * @buf_content: If not NULL and the P2P attribute is found, P2P attribute content will be copied to the buf starting from buf_content ++ * @len_content: If not NULL and the P2P attribute is found, will set to the length of the P2P attribute content ++ * ++ * Returns: the address of the specific P2P attribute content found, or NULL ++ */ ++u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id, u8 *buf_content, uint *len_content) ++{ ++ u8 *attr_ptr; ++ u32 attr_len; ++ ++ if (len_content) ++ *len_content = 0; ++ ++ attr_ptr = rtw_get_p2p_attr(p2p_ie, p2p_ielen, target_attr_id, NULL, &attr_len); ++ ++ if (attr_ptr && attr_len) { ++ if (buf_content) ++ memcpy(buf_content, attr_ptr + 3, attr_len - 3); ++ ++ if (len_content) ++ *len_content = attr_len - 3; ++ ++ return attr_ptr + 3; ++ } ++ ++ return NULL; ++} ++ ++u32 rtw_set_p2p_attr_content(u8 *pbuf, u8 attr_id, u16 attr_len, u8 *pdata_attr) ++{ ++ u32 a_len; ++ ++ *pbuf = attr_id; ++ ++ /* u16*)(pbuf + 1) = cpu_to_le16(attr_len); */ ++ RTW_PUT_LE16(pbuf + 1, attr_len); ++ ++ if (pdata_attr) ++ memcpy(pbuf + 3, pdata_attr, attr_len); ++ ++ a_len = attr_len + 3; ++ ++ return a_len; ++} ++ ++static uint rtw_p2p_attr_remove(u8 *ie, uint ielen_ori, u8 attr_id) ++{ ++ u8 *target_attr; ++ u32 target_attr_len; ++ uint ielen = ielen_ori; ++ ++ while (1) { ++ target_attr = rtw_get_p2p_attr(ie, ielen, attr_id, NULL, &target_attr_len); ++ if (target_attr && target_attr_len) { ++ u8 *next_attr = target_attr + target_attr_len; ++ uint remain_len = ielen - (next_attr - ie); ++ ++ memset(target_attr, 0, target_attr_len); ++ memcpy(target_attr, next_attr, remain_len); ++ memset(target_attr + remain_len, 0, target_attr_len); ++ *(ie + 1) -= target_attr_len; ++ ielen -= target_attr_len; ++ } else { ++ break; ++ } ++ } ++ return ielen; ++} ++ ++void rtw_wlan_bssid_ex_remove_p2p_attr(struct wlan_bssid_ex *bss_ex, u8 attr_id) ++{ ++ u8 *p2p_ie; ++ uint p2p_ielen, p2p_ielen_ori; ++ ++ p2p_ie = rtw_get_p2p_ie(bss_ex->IEs + _FIXED_IE_LENGTH_, bss_ex->IELength - _FIXED_IE_LENGTH_, NULL, &p2p_ielen_ori); ++ if (p2p_ie) { ++ p2p_ielen = rtw_p2p_attr_remove(p2p_ie, p2p_ielen_ori, attr_id); ++ if (p2p_ielen != p2p_ielen_ori) { ++ u8 *next_ie_ori = p2p_ie + p2p_ielen_ori; ++ u8 *next_ie = p2p_ie + p2p_ielen; ++ uint remain_len = bss_ex->IELength - (next_ie_ori - bss_ex->IEs); ++ ++ memcpy(next_ie, next_ie_ori, remain_len); ++ memset(next_ie + remain_len, 0, p2p_ielen_ori - p2p_ielen); ++ bss_ex->IELength -= p2p_ielen_ori - p2p_ielen; ++ } ++ } ++} ++ ++#endif /* CONFIG_88EU_P2P */ ++ ++/* Baron adds to avoid FreeBSD warning */ ++int ieee80211_is_empty_essid(const char *essid, int essid_len) ++{ ++ /* Single white space is for Linksys APs */ ++ if (essid_len == 1 && essid[0] == ' ') ++ return 1; ++ ++ /* Otherwise, if the entire essid is 0, we assume it is hidden */ ++ while (essid_len) { ++ essid_len--; ++ if (essid[essid_len] != '\0') ++ return 0; ++ } ++ ++ return 1; ++} ++ ++int ieee80211_get_hdrlen(u16 fc) ++{ ++ int hdrlen = 24; ++ ++ switch (WLAN_FC_GET_TYPE(fc)) { ++ case RTW_IEEE80211_FTYPE_DATA: ++ if (fc & RTW_IEEE80211_STYPE_QOS_DATA) ++ hdrlen += 2; ++ if ((fc & RTW_IEEE80211_FCTL_FROMDS) && (fc & RTW_IEEE80211_FCTL_TODS)) ++ hdrlen += 6; /* Addr4 */ ++ break; ++ case RTW_IEEE80211_FTYPE_CTL: ++ switch (WLAN_FC_GET_STYPE(fc)) { ++ case RTW_IEEE80211_STYPE_CTS: ++ case RTW_IEEE80211_STYPE_ACK: ++ hdrlen = 10; ++ break; ++ default: ++ hdrlen = 16; ++ break; ++ } ++ break; ++ } ++ ++ return hdrlen; ++} ++ ++static int rtw_get_cipher_info(struct wlan_network *pnetwork) ++{ ++ u32 wpa_ielen; ++ unsigned char *pbuf; ++ int group_cipher = 0, pairwise_cipher = 0, is8021x = 0; ++ int ret = _FAIL; ++ pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12); ++ ++ if (pbuf && (wpa_ielen > 0)) { ++ if (_SUCCESS == rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x)) { ++ pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher; ++ pnetwork->BcnInfo.group_cipher = group_cipher; ++ pnetwork->BcnInfo.is_8021x = is8021x; ++ ret = _SUCCESS; ++ } ++ } else { ++ pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12); ++ ++ if (pbuf && (wpa_ielen > 0)) { ++ if (_SUCCESS == rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x)) { ++ pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher; ++ pnetwork->BcnInfo.group_cipher = group_cipher; ++ pnetwork->BcnInfo.is_8021x = is8021x; ++ ret = _SUCCESS; ++ } ++ } ++ } ++ ++ return ret; ++} ++ ++void rtw_get_bcn_info(struct wlan_network *pnetwork) ++{ ++ unsigned short cap = 0; ++ u8 bencrypt = 0; ++ __le16 le_tmp; ++ u16 wpa_len = 0, rsn_len = 0; ++ struct HT_info_element *pht_info = NULL; ++ struct ieee80211_ht_cap *pht_cap = NULL; ++ unsigned int len; ++ unsigned char *p; ++ ++ memcpy(&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2); ++ cap = le16_to_cpu(le_tmp); ++ if (cap & WLAN_CAPABILITY_PRIVACY) { ++ bencrypt = 1; ++ pnetwork->network.Privacy = 1; ++ } else { ++ pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_OPENSYS; ++ } ++ rtw_get_sec_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &rsn_len, NULL, &wpa_len); ++ ++ if (rsn_len > 0) { ++ pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA2; ++ } else if (wpa_len > 0) { ++ pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA; ++ } else { ++ if (bencrypt) ++ pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WEP; ++ } ++ rtw_get_cipher_info(pnetwork); ++ ++ /* get bwmode and ch_offset */ ++ /* parsing HT_CAP_IE */ ++ p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_); ++ if (p && len > 0) { ++ pht_cap = (struct ieee80211_ht_cap *)(p + 2); ++ pnetwork->BcnInfo.ht_cap_info = le16_to_cpu(pht_cap->cap_info); ++ } else { ++ pnetwork->BcnInfo.ht_cap_info = 0; ++ } ++ /* parsing HT_INFO_IE */ ++ p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_); ++ if (p && len > 0) { ++ pht_info = (struct HT_info_element *)(p + 2); ++ pnetwork->BcnInfo.ht_info_infos_0 = pht_info->infos[0]; ++ } else { ++ pnetwork->BcnInfo.ht_info_infos_0 = 0; ++ } ++} ++ ++/* show MCS rate, unit: 100Kbps */ ++u16 rtw_mcs_rate(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40, unsigned char *MCS_rate) ++{ ++ u16 max_rate = 0; ++ ++ if (rf_type == RF_1T1R) { ++ if (MCS_rate[0] & BIT(7)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1500 : 1350) : ((short_GI_20) ? 722 : 650); ++ else if (MCS_rate[0] & BIT(6)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1350 : 1215) : ((short_GI_20) ? 650 : 585); ++ else if (MCS_rate[0] & BIT(5)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1200 : 1080) : ((short_GI_20) ? 578 : 520); ++ else if (MCS_rate[0] & BIT(4)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 900 : 810) : ((short_GI_20) ? 433 : 390); ++ else if (MCS_rate[0] & BIT(3)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 600 : 540) : ((short_GI_20) ? 289 : 260); ++ else if (MCS_rate[0] & BIT(2)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 450 : 405) : ((short_GI_20) ? 217 : 195); ++ else if (MCS_rate[0] & BIT(1)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 300 : 270) : ((short_GI_20) ? 144 : 130); ++ else if (MCS_rate[0] & BIT(0)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 150 : 135) : ((short_GI_20) ? 72 : 65); ++ } else { ++ if (MCS_rate[1]) { ++ if (MCS_rate[1] & BIT(7)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 3000 : 2700) : ((short_GI_20) ? 1444 : 1300); ++ else if (MCS_rate[1] & BIT(6)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 2700 : 2430) : ((short_GI_20) ? 1300 : 1170); ++ else if (MCS_rate[1] & BIT(5)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 2400 : 2160) : ((short_GI_20) ? 1156 : 1040); ++ else if (MCS_rate[1] & BIT(4)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1800 : 1620) : ((short_GI_20) ? 867 : 780); ++ else if (MCS_rate[1] & BIT(3)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1200 : 1080) : ((short_GI_20) ? 578 : 520); ++ else if (MCS_rate[1] & BIT(2)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 900 : 810) : ((short_GI_20) ? 433 : 390); ++ else if (MCS_rate[1] & BIT(1)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 600 : 540) : ((short_GI_20) ? 289 : 260); ++ else if (MCS_rate[1] & BIT(0)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 300 : 270) : ((short_GI_20) ? 144 : 130); ++ } else { ++ if (MCS_rate[0] & BIT(7)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1500 : 1350) : ((short_GI_20) ? 722 : 650); ++ else if (MCS_rate[0] & BIT(6)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1350 : 1215) : ((short_GI_20) ? 650 : 585); ++ else if (MCS_rate[0] & BIT(5)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1200 : 1080) : ((short_GI_20) ? 578 : 520); ++ else if (MCS_rate[0] & BIT(4)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 900 : 810) : ((short_GI_20) ? 433 : 390); ++ else if (MCS_rate[0] & BIT(3)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 600 : 540) : ((short_GI_20) ? 289 : 260); ++ else if (MCS_rate[0] & BIT(2)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 450 : 405) : ((short_GI_20) ? 217 : 195); ++ else if (MCS_rate[0] & BIT(1)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 300 : 270) : ((short_GI_20) ? 144 : 130); ++ else if (MCS_rate[0] & BIT(0)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 150 : 135) : ((short_GI_20) ? 72 : 65); ++ } ++ } ++ return max_rate; ++} ++ ++int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category, u8 *action) ++{ ++ const u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr); ++ u16 fc; ++ u8 c, a = 0; ++ ++ fc = le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)frame)->frame_ctl); ++ ++ if ((fc & (RTW_IEEE80211_FCTL_FTYPE | RTW_IEEE80211_FCTL_STYPE)) != ++ (RTW_IEEE80211_FTYPE_MGMT | RTW_IEEE80211_STYPE_ACTION)) ++ return false; ++ ++ c = frame_body[0]; ++ ++ switch (c) { ++ case RTW_WLAN_CATEGORY_P2P: /* vendor-specific */ ++ break; ++ default: ++ a = frame_body[1]; ++ } ++ ++ if (category) ++ *category = c; ++ if (action) ++ *action = a; ++ ++ return true; ++} ++ ++static const char *_action_public_str[] = { ++ "ACT_PUB_BSSCOEXIST", ++ "ACT_PUB_DSE_ENABLE", ++ "ACT_PUB_DSE_DEENABLE", ++ "ACT_PUB_DSE_REG_LOCATION", ++ "ACT_PUB_EXT_CHL_SWITCH", ++ "ACT_PUB_DSE_MSR_REQ", ++ "ACT_PUB_DSE_MSR_RPRT", ++ "ACT_PUB_MP", ++ "ACT_PUB_DSE_PWR_CONSTRAINT", ++ "ACT_PUB_VENDOR", ++ "ACT_PUB_GAS_INITIAL_REQ", ++ "ACT_PUB_GAS_INITIAL_RSP", ++ "ACT_PUB_GAS_COMEBACK_REQ", ++ "ACT_PUB_GAS_COMEBACK_RSP", ++ "ACT_PUB_TDLS_DISCOVERY_RSP", ++ "ACT_PUB_LOCATION_TRACK", ++ "ACT_PUB_RSVD", ++}; ++ ++const char *action_public_str(u8 action) ++{ ++ action = (action >= ACT_PUBLIC_MAX) ? ACT_PUBLIC_MAX : action; ++ return _action_public_str[action]; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c +new file mode 100644 +index 000000000000..cde0205816b1 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_io.c +@@ -0,0 +1,299 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++/* ++ ++The purpose of rtw_io.c ++ ++a. provides the API ++ ++b. provides the protocol engine ++ ++c. provides the software interface between caller and the hardware interface ++ ++Compiler Flag Option: ++ ++USB: ++ a. USE_ASYNC_IRP: Both sync/async operations are provided. ++ ++Only sync read/rtw_write_mem operations are provided. ++ ++jackson@realtek.com.tw ++ ++*/ ++ ++#define _RTW_IO_C_ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtw_io.h" ++#include "../include/osdep_intf.h" ++#include "../include/usb_ops.h" ++ ++#define rtw_le16_to_cpu(val) le16_to_cpu(val) ++#define rtw_le32_to_cpu(val) le32_to_cpu(val) ++#define rtw_cpu_to_le16(val) cpu_to_le16(val) ++#define rtw_cpu_to_le32(val) cpu_to_le32(val) ++ ++u8 _rtw_read8(struct adapter *adapter, u32 addr) ++{ ++ u8 r_val; ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr); ++ ++ ++ _read8 = pintfhdl->io_ops._read8; ++ r_val = _read8(pintfhdl, addr); ++ ++ return r_val; ++} ++ ++u16 _rtw_read16(struct adapter *adapter, u32 addr) ++{ ++ u16 r_val; ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr); ++ ++ _read16 = pintfhdl->io_ops._read16; ++ ++ r_val = _read16(pintfhdl, addr); ++ ++ return r_val; ++} ++ ++u32 _rtw_read32(struct adapter *adapter, u32 addr) ++{ ++ u32 r_val; ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr); ++ ++ _read32 = pintfhdl->io_ops._read32; ++ ++ r_val = _read32(pintfhdl, addr); ++ ++ return r_val; ++} ++ ++int _rtw_write8(struct adapter *adapter, u32 addr, u8 val) ++{ ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); ++ int ret; ++ ++ _write8 = pintfhdl->io_ops._write8; ++ ++ ret = _write8(pintfhdl, addr, val); ++ ++ ++ return RTW_STATUS_CODE(ret); ++} ++ ++int _rtw_write16(struct adapter *adapter, u32 addr, u16 val) ++{ ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val); ++ int ret; ++ ++ _write16 = pintfhdl->io_ops._write16; ++ ++ ret = _write16(pintfhdl, addr, val); ++ ++ ++ return RTW_STATUS_CODE(ret); ++} ++int _rtw_write32(struct adapter *adapter, u32 addr, u32 val) ++{ ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val); ++ int ret; ++ ++ _write32 = pintfhdl->io_ops._write32; ++ ++ ret = _write32(pintfhdl, addr, val); ++ ++ ++ return RTW_STATUS_CODE(ret); ++} ++ ++int _rtw_writeN(struct adapter *adapter, u32 addr, u32 length, u8 *pdata) ++{ ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = (struct intf_hdl *)(&pio_priv->intf); ++ int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata); ++ int ret; ++ ++ _writeN = pintfhdl->io_ops._writeN; ++ ++ ret = _writeN(pintfhdl, addr, length, pdata); ++ ++ ++ return RTW_STATUS_CODE(ret); ++} ++int _rtw_write8_async(struct adapter *adapter, u32 addr, u8 val) ++{ ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val); ++ int ret; ++ ++ _write8_async = pintfhdl->io_ops._write8_async; ++ ++ ret = _write8_async(pintfhdl, addr, val); ++ ++ ++ return RTW_STATUS_CODE(ret); ++} ++ ++int _rtw_write16_async(struct adapter *adapter, u32 addr, u16 val) ++{ ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val); ++ int ret; ++ ++ _write16_async = pintfhdl->io_ops._write16_async; ++ ret = _write16_async(pintfhdl, addr, val); ++ ++ return RTW_STATUS_CODE(ret); ++} ++ ++int _rtw_write32_async(struct adapter *adapter, u32 addr, u32 val) ++{ ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val); ++ int ret; ++ ++ _write32_async = pintfhdl->io_ops._write32_async; ++ ret = _write32_async(pintfhdl, addr, val); ++ ++ return RTW_STATUS_CODE(ret); ++} ++ ++void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) ++{ ++ void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ ++ ++ if (adapter->bDriverStopped || adapter->bSurpriseRemoved) ++ return; ++ _read_mem = pintfhdl->io_ops._read_mem; ++ _read_mem(pintfhdl, addr, cnt, pmem); ++ ++} ++ ++void _rtw_write_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) ++{ ++ void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ ++ ++ ++ _write_mem = pintfhdl->io_ops._write_mem; ++ ++ _write_mem(pintfhdl, addr, cnt, pmem); ++ ++ ++} ++ ++void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) ++{ ++ u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ ++ ++ ++ if (adapter->bDriverStopped || adapter->bSurpriseRemoved) ++ return; ++ ++ _read_port = pintfhdl->io_ops._read_port; ++ ++ _read_port(pintfhdl, addr, cnt, pmem); ++ ++ ++} ++ ++void _rtw_read_port_cancel(struct adapter *adapter) ++{ ++ void (*_read_port_cancel)(struct intf_hdl *pintfhdl); ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ ++ _read_port_cancel = pintfhdl->io_ops._read_port_cancel; ++ ++ if (_read_port_cancel) ++ _read_port_cancel(pintfhdl); ++} ++ ++u32 _rtw_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) ++{ ++ u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ u32 ret = _SUCCESS; ++ ++ ++ ++ _write_port = pintfhdl->io_ops._write_port; ++ ++ ret = _write_port(pintfhdl, addr, cnt, pmem); ++ ++ ++ ++ return ret; ++} ++ ++u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms) ++{ ++ int ret = _SUCCESS; ++ struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem; ++ struct submit_ctx sctx; ++ ++ rtw_sctx_init(&sctx, timeout_ms); ++ pxmitbuf->sctx = &sctx; ++ ++ ret = _rtw_write_port(adapter, addr, cnt, pmem); ++ ++ if (ret == _SUCCESS) ++ ret = rtw_sctx_wait(&sctx); ++ ++ return ret; ++} ++ ++void _rtw_write_port_cancel(struct adapter *adapter) ++{ ++ void (*_write_port_cancel)(struct intf_hdl *pintfhdl); ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ ++ _write_port_cancel = pintfhdl->io_ops._write_port_cancel; ++ ++ if (_write_port_cancel) ++ _write_port_cancel(pintfhdl); ++} ++ ++int rtw_init_io_priv(struct adapter *padapter, void (*set_intf_ops)(struct _io_ops *pops)) ++{ ++ struct io_priv *piopriv = &padapter->iopriv; ++ struct intf_hdl *pintf = &piopriv->intf; ++ ++ if (!set_intf_ops) ++ return _FAIL; ++ ++ piopriv->padapter = padapter; ++ pintf->padapter = padapter; ++ pintf->pintf_dev = adapter_to_dvobj(padapter); ++ ++ set_intf_ops(&pintf->io_ops); ++ ++ return _SUCCESS; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_ioctl_set.c b/drivers/staging/r8188eu/core/rtw_ioctl_set.c +new file mode 100644 +index 000000000000..c187de78b4ac +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_ioctl_set.c +@@ -0,0 +1,891 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_IOCTL_SET_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtw_ioctl_set.h" ++#include "../include/hal_intf.h" ++ ++#include "../include/usb_osintf.h" ++#include "../include/usb_ops.h" ++ ++extern void indicate_wx_scan_complete_event(struct adapter *padapter); ++ ++u8 rtw_validate_ssid(struct ndis_802_11_ssid *ssid) ++{ ++ u8 i; ++ u8 ret = true; ++ ++ if (ssid->SsidLength > 32) { ++ ret = false; ++ goto exit; ++ } ++ ++ for (i = 0; i < ssid->SsidLength; i++) { ++ /* wifi, printable ascii code must be supported */ ++ if (!((ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e))) { ++ ret = false; ++ break; ++ } ++ } ++ ++exit: ++ ++ return ret; ++} ++ ++u8 rtw_do_join(struct adapter *padapter) ++{ ++ struct list_head *plist, *phead; ++ u8 *pibss = NULL; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ u8 ret = _SUCCESS; ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ pmlmepriv->cur_network.join_res = -2; ++ ++ set_fwstate(pmlmepriv, _FW_UNDER_LINKING); ++ ++ pmlmepriv->pscanned = plist; ++ ++ pmlmepriv->to_join = true; ++ ++ if (list_empty(&queue->queue)) { ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ ++ /* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */ ++ /* we try to issue sitesurvey firstly */ ++ ++ if (!pmlmepriv->LinkDetectInfo.bBusyTraffic || ++ pmlmepriv->to_roaming > 0) { ++ /* submit site_survey_cmd */ ++ ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0); ++ if (_SUCCESS != ret) ++ pmlmepriv->to_join = false; ++ } else { ++ pmlmepriv->to_join = false; ++ ret = _FAIL; ++ } ++ ++ goto exit; ++ } else { ++ int select_ret; ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv); ++ if (select_ret == _SUCCESS) { ++ pmlmepriv->to_join = false; ++ _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); ++ } else { ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { ++ /* submit createbss_cmd to change to a ADHOC_MASTER */ ++ ++ /* pmlmepriv->lock has been acquired by caller... */ ++ struct wlan_bssid_ex *pdev_network = &padapter->registrypriv.dev_network; ++ ++ pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; ++ ++ pibss = padapter->registrypriv.dev_network.MacAddress; ++ ++ memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); ++ memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); ++ ++ rtw_update_registrypriv_dev_network(padapter); ++ ++ rtw_generate_random_ibss(pibss); ++ ++ if (rtw_createbss_cmd(padapter) != _SUCCESS) { ++ ret = false; ++ goto exit; ++ } ++ pmlmepriv->to_join = false; ++ } else { ++ /* can't associate ; reset under-linking */ ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ ++ /* when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue */ ++ /* we try to issue sitesurvey firstly */ ++ if (!pmlmepriv->LinkDetectInfo.bBusyTraffic || ++ pmlmepriv->to_roaming > 0) { ++ ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0); ++ if (_SUCCESS != ret) ++ pmlmepriv->to_join = false; ++ } else { ++ ret = _FAIL; ++ pmlmepriv->to_join = false; ++ } ++ } ++ } ++ } ++ ++exit: ++ ++ return ret; ++} ++ ++u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid) ++{ ++ u8 status = _SUCCESS; ++ u32 cur_time = 0; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ DBG_88E_LEVEL(_drv_info_, "set bssid:%pM\n", bssid); ++ ++ if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 && ++ bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) || ++ (bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF && ++ bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) { ++ status = _FAIL; ++ goto exit; ++ } ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ DBG_88E("Set BSSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv)); ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) ++ goto handle_tkip_countermeasure; ++ else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) ++ goto release_mlme_lock; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) { ++ if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN)) { ++ if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) ++ goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */ ++ } else { ++ rtw_disassoc_cmd(padapter, 0, true); ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ rtw_indicate_disconnect(padapter); ++ ++ rtw_free_assoc_resources(padapter, 1); ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); ++ set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); ++ } ++ } ++ } ++ ++handle_tkip_countermeasure: ++ /* should we add something here...? */ ++ ++ if (padapter->securitypriv.btkip_countermeasure) { ++ cur_time = jiffies; ++ ++ if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) { ++ padapter->securitypriv.btkip_countermeasure = false; ++ padapter->securitypriv.btkip_countermeasure_time = 0; ++ } else { ++ status = _FAIL; ++ goto release_mlme_lock; ++ } ++ } ++ ++ memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN); ++ pmlmepriv->assoc_by_bssid = true; ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) ++ pmlmepriv->to_join = true; ++ else ++ status = rtw_do_join(padapter); ++ ++release_mlme_lock: ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++exit: ++ return status; ++} ++ ++u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) ++{ ++ u8 status = _SUCCESS; ++ u32 cur_time = 0; ++ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_network *pnetwork = &pmlmepriv->cur_network; ++ ++ DBG_88E_LEVEL(_drv_info_, "set ssid [%s] fw_state=0x%08x\n", ++ ssid->Ssid, get_fwstate(pmlmepriv)); ++ ++ if (!padapter->hw_init_completed) { ++ status = _FAIL; ++ goto exit; ++ } ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ DBG_88E("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv)); ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { ++ goto handle_tkip_countermeasure; ++ } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { ++ goto release_mlme_lock; ++ } ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) { ++ if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && ++ (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength))) { ++ if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ if (!rtw_is_same_ibss(padapter, pnetwork)) { ++ /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */ ++ rtw_disassoc_cmd(padapter, 0, true); ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ rtw_indicate_disconnect(padapter); ++ ++ rtw_free_assoc_resources(padapter, 1); ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); ++ set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); ++ } ++ } else { ++ goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */ ++ } ++ } else { ++ rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1); ++ } ++ } else { ++ rtw_disassoc_cmd(padapter, 0, true); ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ rtw_indicate_disconnect(padapter); ++ ++ rtw_free_assoc_resources(padapter, 1); ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); ++ set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); ++ } ++ } ++ } ++ ++handle_tkip_countermeasure: ++ ++ if (padapter->securitypriv.btkip_countermeasure) { ++ cur_time = jiffies; ++ ++ if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) { ++ padapter->securitypriv.btkip_countermeasure = false; ++ padapter->securitypriv.btkip_countermeasure_time = 0; ++ } else { ++ status = _FAIL; ++ goto release_mlme_lock; ++ } ++ } ++ ++ memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid)); ++ pmlmepriv->assoc_by_bssid = false; ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { ++ pmlmepriv->to_join = true; ++ } else { ++ status = rtw_do_join(padapter); ++ } ++ ++release_mlme_lock: ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++exit: ++ return status; ++} ++ ++u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter, ++ enum ndis_802_11_network_infra networktype) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_network *cur_network = &pmlmepriv->cur_network; ++ enum ndis_802_11_network_infra *pold_state = &cur_network->network.InfrastructureMode; ++ ++ if (*pold_state != networktype) { ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ /* DBG_88E("change mode, old_mode =%d, new_mode =%d, fw_state = 0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); */ ++ ++ if (*pold_state == Ndis802_11APMode) { ++ /* change to other mode from Ndis802_11APMode */ ++ cur_network->join_res = -1; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ stop_ap_mode(padapter); ++#endif ++ } ++ ++ if ((check_fwstate(pmlmepriv, _FW_LINKED)) || ++ (*pold_state == Ndis802_11IBSS)) ++ rtw_disassoc_cmd(padapter, 0, true); ++ ++ if ((check_fwstate(pmlmepriv, _FW_LINKED)) || ++ (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) ++ rtw_free_assoc_resources(padapter, 1); ++ ++ if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) { ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ rtw_indicate_disconnect(padapter); /* will clr Linked_state; before this function, we must have chked whether issue dis-assoc_cmd or not */ ++ } ++ ++ *pold_state = networktype; ++ ++ _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE); ++ ++ switch (networktype) { ++ case Ndis802_11IBSS: ++ set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); ++ break; ++ case Ndis802_11Infrastructure: ++ set_fwstate(pmlmepriv, WIFI_STATION_STATE); ++ break; ++ case Ndis802_11APMode: ++ set_fwstate(pmlmepriv, WIFI_AP_STATE); ++#ifdef CONFIG_88EU_AP_MODE ++ start_ap_mode(padapter); ++#endif ++ break; ++ case Ndis802_11AutoUnknown: ++ case Ndis802_11InfrastructureMax: ++ break; ++ } ++ spin_unlock_bh(&pmlmepriv->lock); ++ } ++ ++ return true; ++} ++ ++u8 rtw_set_802_11_disassociate(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ rtw_disassoc_cmd(padapter, 0, true); ++ rtw_indicate_disconnect(padapter); ++ rtw_free_assoc_resources(padapter, 1); ++ rtw_pwr_wakeup(padapter); ++ } ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++ return true; ++} ++ ++u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_ssid *pssid, int ssid_max_num) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 res = true; ++ ++ if (!padapter) { ++ res = false; ++ goto exit; ++ } ++ if (!padapter->hw_init_completed) { ++ res = false; ++ goto exit; ++ } ++ ++ if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) || ++ (pmlmepriv->LinkDetectInfo.bBusyTraffic)) { ++ /* Scan or linking is in progress, do nothing. */ ++ res = true; ++ } else { ++ if (rtw_is_scan_deny(padapter)) { ++ DBG_88E(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter)); ++ indicate_wx_scan_complete_event(padapter); ++ return _SUCCESS; ++ } ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, NULL, 0); ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ } ++exit: ++ ++ return res; ++} ++ ++u8 rtw_set_802_11_authentication_mode(struct adapter *padapter, enum ndis_802_11_auth_mode authmode) ++{ ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ int res; ++ u8 ret; ++ ++ psecuritypriv->ndisauthtype = authmode; ++ ++ if (psecuritypriv->ndisauthtype > 3) ++ psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; ++ ++ res = rtw_set_auth(padapter, psecuritypriv); ++ ++ if (res == _SUCCESS) ++ ret = true; ++ else ++ ret = false; ++ ++ return ret; ++} ++ ++u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep) ++{ ++ int keyid, res; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ u8 ret = _SUCCESS; ++ ++ keyid = wep->KeyIndex & 0x3fffffff; ++ ++ if (keyid >= 4) { ++ ret = false; ++ goto exit; ++ } ++ ++ switch (wep->KeyLength) { ++ case 5: ++ psecuritypriv->dot11PrivacyAlgrthm = _WEP40_; ++ break; ++ case 13: ++ psecuritypriv->dot11PrivacyAlgrthm = _WEP104_; ++ break; ++ default: ++ psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ break; ++ } ++ ++ memcpy(&psecuritypriv->dot11DefKey[keyid].skey[0], &wep->KeyMaterial, wep->KeyLength); ++ ++ psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength; ++ ++ psecuritypriv->dot11PrivacyKeyIndex = keyid; ++ ++ res = rtw_set_key(padapter, psecuritypriv, keyid, 1); ++ ++ if (res == _FAIL) ++ ret = false; ++exit: ++ ++ return ret; ++} ++ ++u8 rtw_set_802_11_remove_wep(struct adapter *padapter, u32 keyindex) ++{ ++ u8 ret = _SUCCESS; ++ ++ if (keyindex >= 0x80000000 || !padapter) { ++ ret = false; ++ goto exit; ++ } else { ++ int res; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ if (keyindex < 4) { ++ memset(&psecuritypriv->dot11DefKey[keyindex], 0, 16); ++ res = rtw_set_key(padapter, psecuritypriv, keyindex, 0); ++ psecuritypriv->dot11DefKeylen[keyindex] = 0; ++ if (res == _FAIL) ++ ret = _FAIL; ++ } else { ++ ret = _FAIL; ++ } ++ } ++exit: ++ ++ return ret; ++} ++ ++u8 rtw_set_802_11_add_key(struct adapter *padapter, struct ndis_802_11_key *key) ++{ ++ uint encryptionalgo; ++ u8 *pbssid; ++ struct sta_info *stainfo; ++ u8 bgroup = false; ++ u8 bgrouptkey = false;/* can be removed later */ ++ u8 ret = _SUCCESS; ++ ++ if (((key->KeyIndex & 0x80000000) == 0) && ((key->KeyIndex & 0x40000000) > 0)) { ++ /* It is invalid to clear bit 31 and set bit 30. If the miniport driver encounters this combination, */ ++ /* it must fail the request and return NDIS_STATUS_INVALID_DATA. */ ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ if (key->KeyIndex & 0x40000000) { ++ /* Pairwise key */ ++ ++ pbssid = get_bssid(&padapter->mlmepriv); ++ stainfo = rtw_get_stainfo(&padapter->stapriv, pbssid); ++ ++ if (stainfo && padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ++ encryptionalgo = stainfo->dot118021XPrivacy; ++ else ++ encryptionalgo = padapter->securitypriv.dot11PrivacyAlgrthm; ++ ++ if (key->KeyIndex & 0x000000FF) { ++ /* The key index is specified in the lower 8 bits by values of zero to 255. */ ++ /* The key index should be set to zero for a Pairwise key, and the driver should fail with */ ++ /* NDIS_STATUS_INVALID_DATA if the lower 8 bits is not zero */ ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* check BSSID */ ++ if (is_broadcast_ether_addr(key->BSSID)) { ++ ret = false; ++ goto exit; ++ } ++ ++ /* Check key length for TKIP. */ ++ if ((encryptionalgo == _TKIP_) && (key->KeyLength != 32)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* Check key length for AES. */ ++ if ((encryptionalgo == _AES_) && (key->KeyLength != 16)) { ++ /* For our supplicant, EAPPkt9x.vxd, cannot differentiate TKIP and AES case. */ ++ if (key->KeyLength == 32) { ++ key->KeyLength = 16; ++ } else { ++ ret = _FAIL; ++ goto exit; ++ } ++ } ++ ++ /* Check key length for WEP. For NDTEST, 2005.01.27, by rcnjko. */ ++ if ((encryptionalgo == _WEP40_ || encryptionalgo == _WEP104_) && ++ (key->KeyLength != 5 && key->KeyLength != 13)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ bgroup = false; ++ } else { ++ /* Group key - KeyIndex(BIT(30) == 0) */ ++ /* when add wep key through add key and didn't assigned encryption type before */ ++ if ((padapter->securitypriv.ndisauthtype <= 3) && ++ (padapter->securitypriv.dot118021XGrpPrivacy == 0)) { ++ switch (key->KeyLength) { ++ case 5: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; ++ break; ++ case 13: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; ++ break; ++ default: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ break; ++ } ++ ++ encryptionalgo = padapter->securitypriv.dot11PrivacyAlgrthm; ++ } else { ++ encryptionalgo = padapter->securitypriv.dot118021XGrpPrivacy; ++ } ++ ++ if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE) && !is_broadcast_ether_addr(key->BSSID)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* Check key length for TKIP */ ++ if ((encryptionalgo == _TKIP_) && (key->KeyLength != 32)) { ++ ret = _FAIL; ++ goto exit; ++ } else if (encryptionalgo == _AES_ && (key->KeyLength != 16 && key->KeyLength != 32)) { ++ /* Check key length for AES */ ++ /* For NDTEST, we allow keylen = 32 in this case. 2005.01.27, by rcnjko. */ ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* Change the key length for EAPPkt9x.vxd. Added by Annie, 2005-11-03. */ ++ if ((encryptionalgo == _AES_) && (key->KeyLength == 32)) ++ key->KeyLength = 16; ++ ++ if (key->KeyIndex & 0x8000000) {/* error ??? 0x8000_0000 */ ++ bgrouptkey = true; ++ } ++ ++ if ((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)) && ++ (check_fwstate(&padapter->mlmepriv, _FW_LINKED))) ++ bgrouptkey = true; ++ bgroup = true; ++ } ++ ++ /* If WEP encryption algorithm, just call rtw_set_802_11_add_wep(). */ ++ if ((padapter->securitypriv.dot11AuthAlgrthm != dot11AuthAlgrthm_8021X) && ++ (encryptionalgo == _WEP40_ || encryptionalgo == _WEP104_)) { ++ u32 keyindex; ++ u32 len = FIELD_OFFSET(struct ndis_802_11_key, KeyMaterial) + key->KeyLength; ++ struct ndis_802_11_wep *wep = &padapter->securitypriv.ndiswep; ++ ++ wep->Length = len; ++ keyindex = key->KeyIndex & 0x7fffffff; ++ wep->KeyIndex = keyindex; ++ wep->KeyLength = key->KeyLength; ++ ++ memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength); ++ memcpy(&padapter->securitypriv.dot11DefKey[keyindex].skey[0], key->KeyMaterial, key->KeyLength); ++ ++ padapter->securitypriv.dot11DefKeylen[keyindex] = key->KeyLength; ++ padapter->securitypriv.dot11PrivacyKeyIndex = keyindex; ++ ++ ret = rtw_set_802_11_add_wep(padapter, wep); ++ goto exit; ++ } ++ if (key->KeyIndex & 0x20000000) { ++ /* SetRSC */ ++ if (bgroup) { ++ unsigned long long keysrc = key->KeyRSC & 0x00FFFFFFFFFFFFULL; ++ memcpy(&padapter->securitypriv.dot11Grprxpn, &keysrc, 8); ++ } else { ++ unsigned long long keysrc = key->KeyRSC & 0x00FFFFFFFFFFFFULL; ++ memcpy(&padapter->securitypriv.dot11Grptxpn, &keysrc, 8); ++ } ++ } ++ ++ /* Indicate this key idx is used for TX */ ++ /* Save the key in KeyMaterial */ ++ if (bgroup) { /* Group transmit key */ ++ int res; ++ ++ if (bgrouptkey) ++ padapter->securitypriv.dot118021XGrpKeyid = (u8)key->KeyIndex; ++ if ((key->KeyIndex & 0x3) == 0) { ++ ret = _FAIL; ++ goto exit; ++ } ++ memset(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], 0, 16); ++ memset(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16); ++ memset(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16); ++ ++ if ((key->KeyIndex & 0x10000000)) { ++ memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); ++ memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); ++ } else { ++ memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); ++ memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); ++ } ++ ++ /* set group key by index */ ++ memcpy(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial, key->KeyLength); ++ ++ key->KeyIndex = key->KeyIndex & 0x03; ++ ++ padapter->securitypriv.binstallGrpkey = true; ++ ++ padapter->securitypriv.bcheck_grpkey = false; ++ ++ res = rtw_set_key(padapter, &padapter->securitypriv, key->KeyIndex, 1); ++ ++ if (res == _FAIL) ++ ret = _FAIL; ++ ++ goto exit; ++ ++ } else { /* Pairwise Key */ ++ u8 res; ++ ++ pbssid = get_bssid(&padapter->mlmepriv); ++ stainfo = rtw_get_stainfo(&padapter->stapriv, pbssid); ++ ++ if (stainfo) { ++ memset(&stainfo->dot118021x_UncstKey, 0, 16);/* clear keybuffer */ ++ ++ memcpy(&stainfo->dot118021x_UncstKey, key->KeyMaterial, 16); ++ ++ if (encryptionalgo == _TKIP_) { ++ padapter->securitypriv.busetkipkey = false; ++ ++ /* _set_timer(&padapter->securitypriv.tkip_timer, 50); */ ++ ++ /* if TKIP, save the Receive/Transmit MIC key in KeyMaterial[128-255] */ ++ if ((key->KeyIndex & 0x10000000)) { ++ memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 16, 8); ++ memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 24, 8); ++ ++ } else { ++ memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 24, 8); ++ memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 16, 8); ++ } ++ } ++ ++ /* Set key to CAM through H2C command */ ++ if (bgrouptkey) /* never go to here */ ++ res = rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, false); ++ else ++ res = rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, true); ++ if (!res) ++ ret = _FAIL; ++ } ++ } ++exit: ++ ++ return ret; ++} ++ ++u8 rtw_set_802_11_remove_key(struct adapter *padapter, struct ndis_802_11_remove_key *key) ++{ ++ u8 *pbssid; ++ struct sta_info *stainfo; ++ u8 bgroup = (key->KeyIndex & 0x4000000) > 0 ? false : true; ++ u8 keyIndex = (u8)key->KeyIndex & 0x03; ++ u8 ret = _SUCCESS; ++ ++ if ((key->KeyIndex & 0xbffffffc) > 0) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ if (bgroup) { ++ /* clear group key by index */ ++ ++ memset(&padapter->securitypriv.dot118021XGrpKey[keyIndex], 0, 16); ++ ++ /* \todo Send a H2C Command to Firmware for removing this Key in CAM Entry. */ ++ } else { ++ pbssid = get_bssid(&padapter->mlmepriv); ++ stainfo = rtw_get_stainfo(&padapter->stapriv, pbssid); ++ if (stainfo) { ++ /* clear key by BSSID */ ++ memset(&stainfo->dot118021x_UncstKey, 0, 16); ++ ++ /* \todo Send a H2C Command to Firmware for disable this Key in CAM Entry. */ ++ } else { ++ ret = _FAIL; ++ goto exit; ++ } ++ } ++exit: ++ ++ return ret; ++} ++ ++/* ++* rtw_get_cur_max_rate - ++* @adapter: pointer to struct adapter structure ++* ++* Return 0 or 100Kbps ++*/ ++u16 rtw_get_cur_max_rate(struct adapter *adapter) ++{ ++ int i = 0; ++ u8 *p; ++ u16 rate = 0, max_rate = 0; ++ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct registry_priv *pregistrypriv = &adapter->registrypriv; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; ++ struct ieee80211_ht_cap *pht_capie; ++ u8 rf_type = 0; ++ u8 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0; ++ u16 mcs_rate = 0; ++ u32 ht_ielen = 0; ++ ++ if (adapter->registrypriv.mp_mode == 1) { ++ if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) ++ return 0; ++ } ++ ++ if ((!check_fwstate(pmlmepriv, _FW_LINKED)) && ++ (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) ++ return 0; ++ ++ if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N)) { ++ p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength - 12); ++ if (p && ht_ielen > 0) { ++ pht_capie = (struct ieee80211_ht_cap *)(p + 2); ++ ++ memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2); ++ ++ /* cur_bwmod is updated by beacon, pmlmeinfo is updated by association response */ ++ bw_40MHz = (pmlmeext->cur_bwmode && (HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH & pmlmeinfo->HT_info.infos[0])) ? 1 : 0; ++ ++ short_GI_20 = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; ++ short_GI_40 = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; ++ ++ rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ max_rate = rtw_mcs_rate( ++ rf_type, ++ bw_40MHz & (pregistrypriv->cbw40_enable), ++ short_GI_20, ++ short_GI_40, ++ pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate ++ ); ++ } ++ } else { ++ while ((pcur_bss->SupportedRates[i] != 0) && (pcur_bss->SupportedRates[i] != 0xFF)) { ++ rate = pcur_bss->SupportedRates[i] & 0x7F; ++ if (rate > max_rate) ++ max_rate = rate; ++ i++; ++ } ++ ++ max_rate *= 5; ++ } ++ ++ return max_rate; ++} ++ ++/* ++* rtw_set_scan_mode - ++* @adapter: pointer to struct adapter structure ++* @scan_mode: ++* ++* Return _SUCCESS or _FAIL ++*/ ++int rtw_set_scan_mode(struct adapter *adapter, enum rt_scan_type scan_mode) ++{ ++ if (scan_mode != SCAN_ACTIVE && scan_mode != SCAN_PASSIVE) ++ return _FAIL; ++ ++ adapter->mlmepriv.scan_mode = scan_mode; ++ ++ return _SUCCESS; ++} ++ ++/* ++* rtw_set_channel_plan - ++* @adapter: pointer to struct adapter structure ++* @channel_plan: ++* ++* Return _SUCCESS or _FAIL ++*/ ++int rtw_set_channel_plan(struct adapter *adapter, u8 channel_plan) ++{ ++ /* handle by cmd_thread to sync with scan operation */ ++ return rtw_set_chplan_cmd(adapter, channel_plan, 1); ++} ++ ++/* ++* rtw_set_country - ++* @adapter: pointer to struct adapter structure ++* @country_code: string of country code ++* ++* Return _SUCCESS or _FAIL ++*/ ++int rtw_set_country(struct adapter *adapter, const char *country_code) ++{ ++ int channel_plan = RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G; ++ ++ DBG_88E("%s country_code:%s\n", __func__, country_code); ++ ++ /* TODO: should have a table to match country code and RT_CHANNEL_DOMAIN */ ++ /* TODO: should consider 2-character and 3-character country code */ ++ if (0 == strcmp(country_code, "US")) ++ channel_plan = RT_CHANNEL_DOMAIN_FCC; ++ else if (0 == strcmp(country_code, "EU")) ++ channel_plan = RT_CHANNEL_DOMAIN_ETSI; ++ else if (0 == strcmp(country_code, "JP")) ++ channel_plan = RT_CHANNEL_DOMAIN_MKK; ++ else if (0 == strcmp(country_code, "CN")) ++ channel_plan = RT_CHANNEL_DOMAIN_CHINA; ++ else ++ DBG_88E("%s unknown country_code:%s\n", __func__, country_code); ++ ++ return rtw_set_channel_plan(adapter, channel_plan); ++} +diff --git a/drivers/staging/r8188eu/core/rtw_iol.c b/drivers/staging/r8188eu/core/rtw_iol.c +new file mode 100644 +index 000000000000..5c1b19679cad +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_iol.c +@@ -0,0 +1,192 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/rtw_iol.h" ++ ++struct xmit_frame *rtw_IOL_accquire_xmit_frame(struct adapter *adapter) ++{ ++ struct xmit_frame *xmit_frame; ++ struct xmit_buf *xmitbuf; ++ struct pkt_attrib *pattrib; ++ struct xmit_priv *pxmitpriv = &adapter->xmitpriv; ++ ++ xmit_frame = rtw_alloc_xmitframe(pxmitpriv); ++ if (!xmit_frame) { ++ DBG_88E("%s rtw_alloc_xmitframe return null\n", __func__); ++ goto exit; ++ } ++ ++ xmitbuf = rtw_alloc_xmitbuf(pxmitpriv); ++ if (!xmitbuf) { ++ DBG_88E("%s rtw_alloc_xmitbuf return null\n", __func__); ++ rtw_free_xmitframe(pxmitpriv, xmit_frame); ++ xmit_frame = NULL; ++ goto exit; ++ } ++ ++ xmit_frame->frame_tag = MGNT_FRAMETAG; ++ xmit_frame->pxmitbuf = xmitbuf; ++ xmit_frame->buf_addr = xmitbuf->pbuf; ++ xmitbuf->priv_data = xmit_frame; ++ ++ pattrib = &xmit_frame->attrib; ++ update_mgntframe_attrib(adapter, pattrib); ++ pattrib->qsel = 0x10;/* Beacon */ ++ pattrib->subtype = WIFI_BEACON; ++ pattrib->pktlen = 0; ++ pattrib->last_txcmdsz = 0; ++exit: ++ return xmit_frame; ++} ++ ++int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len) ++{ ++ struct pkt_attrib *pattrib = &xmit_frame->attrib; ++ u16 buf_offset; ++ u32 ori_len; ++ ++ buf_offset = TXDESC_OFFSET; ++ ori_len = buf_offset + pattrib->pktlen; ++ ++ /* check if the io_buf can accommodate new cmds */ ++ if (ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) { ++ DBG_88E("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n", ++ __func__, ori_len + cmd_len + 8, MAX_XMITBUF_SZ); ++ return _FAIL; ++ } ++ ++ memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len); ++ pattrib->pktlen += cmd_len; ++ pattrib->last_txcmdsz += cmd_len; ++ ++ return _SUCCESS; ++} ++ ++bool rtw_IOL_applied(struct adapter *adapter) ++{ ++ if (1 == adapter->registrypriv.fw_iol) ++ return true; ++ ++ if ((2 == adapter->registrypriv.fw_iol) && (!adapter_to_dvobj(adapter)->ishighspeed)) ++ return true; ++ return false; ++} ++ ++int rtw_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt) ++{ ++ return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms, bndy_cnt); ++} ++ ++int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary) ++{ ++ return _SUCCESS; ++} ++ ++int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask) ++{ ++ struct ioreg_cfg cmd = {8, IOREG_CMD_WB_REG, 0x0, 0x0, 0x0}; ++ ++ cmd.address = cpu_to_le16(addr); ++ cmd.data = cpu_to_le32(value); ++ ++ if (mask != 0xFF) { ++ cmd.length = 12; ++ cmd.mask = cpu_to_le32(mask); ++ } ++ return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length); ++} ++ ++int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask) ++{ ++ struct ioreg_cfg cmd = {8, IOREG_CMD_WW_REG, 0x0, 0x0, 0x0}; ++ ++ cmd.address = cpu_to_le16(addr); ++ cmd.data = cpu_to_le32(value); ++ ++ if (mask != 0xFFFF) { ++ cmd.length = 12; ++ cmd.mask = cpu_to_le32(mask); ++ } ++ return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length); ++} ++ ++int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask) ++{ ++ struct ioreg_cfg cmd = {8, IOREG_CMD_WD_REG, 0x0, 0x0, 0x0}; ++ ++ cmd.address = cpu_to_le16(addr); ++ cmd.data = cpu_to_le32(value); ++ ++ if (mask != 0xFFFFFFFF) { ++ cmd.length = 12; ++ cmd.mask = cpu_to_le32(mask); ++ } ++ return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length); ++} ++ ++int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask) ++{ ++ struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0}; ++ ++ cmd.address = cpu_to_le16((rf_path << 8) | ((addr) & 0xFF)); ++ cmd.data = cpu_to_le32(value); ++ ++ if (mask != 0x000FFFFF) { ++ cmd.length = 12; ++ cmd.mask = cpu_to_le32(mask); ++ } ++ return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length); ++} ++ ++int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us) ++{ ++ struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0}; ++ cmd.address = cpu_to_le16(us); ++ ++ return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4); ++} ++ ++int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms) ++{ ++ struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0}; ++ ++ cmd.address = cpu_to_le16(ms); ++ return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4); ++} ++ ++int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame) ++{ ++ struct ioreg_cfg cmd = {4, IOREG_CMD_END, cpu_to_le16(0xFFFF), cpu_to_le32(0xFF), 0x0}; ++ ++ return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4); ++} ++ ++u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame) ++{ ++ u8 is_cmd_bndy = false; ++ if (((pxmit_frame->attrib.pktlen + 32) % 256) + 8 >= 256) { ++ rtw_IOL_append_END_cmd(pxmit_frame); ++ pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen + 32) / 256) + 1) * 256); ++ ++ pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen; ++ is_cmd_bndy = true; ++ } ++ return is_cmd_bndy; ++} ++ ++void rtw_IOL_cmd_buf_dump(struct adapter *Adapter, int buf_len, u8 *pbuf) ++{ ++ int i; ++ int j = 1; ++ ++ pr_info("###### %s ######\n", __func__); ++ for (i = 0; i < buf_len; i++) { ++ printk("%02x-", *(pbuf + i)); ++ ++ if (j % 32 == 0) ++ printk("\n"); ++ j++; ++ } ++ printk("\n"); ++ pr_info("=============ioreg_cmd len=%d===============\n", buf_len); ++} +diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c +new file mode 100644 +index 000000000000..b33e34cce12e +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_led.c +@@ -0,0 +1,1612 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#include "../include/drv_types.h" ++#include "../include/rtw_led.h" ++ ++/* */ ++/* Description: */ ++/* Callback function of LED BlinkTimer, */ ++/* it just schedules to corresponding BlinkWorkItem/led_blink_hdl */ ++/* */ ++void BlinkTimerCallback(struct timer_list *t) ++{ ++ struct LED_871x *pLed = from_timer(pLed, t, BlinkTimer); ++ struct adapter *padapter = pLed->padapter; ++ ++ if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped)) ++ return; ++ ++ _set_workitem(&pLed->BlinkWorkItem); ++} ++ ++/* */ ++/* Description: */ ++/* Callback function of LED BlinkWorkItem. */ ++/* We dispatch acture LED blink action according to LedStrategy. */ ++/* */ ++void BlinkWorkItemCallback(struct work_struct *work) ++{ ++ struct LED_871x *pLed = container_of(work, struct LED_871x, BlinkWorkItem); ++ BlinkHandler(pLed); ++} ++ ++/* */ ++/* Description: */ ++/* Reset status of LED_871x object. */ ++/* */ ++void ResetLedStatus(struct LED_871x *pLed) ++{ ++ pLed->CurrLedState = RTW_LED_OFF; /* Current LED state. */ ++ pLed->bLedOn = false; /* true if LED is ON, false if LED is OFF. */ ++ ++ pLed->bLedBlinkInProgress = false; /* true if it is blinking, false o.w.. */ ++ pLed->bLedWPSBlinkInProgress = false; ++ ++ pLed->BlinkTimes = 0; /* Number of times to toggle led state for blinking. */ ++ pLed->BlinkingLedState = LED_UNKNOWN; /* Next state for blinking, either RTW_LED_ON or RTW_LED_OFF are. */ ++ ++ pLed->bLedNoLinkBlinkInProgress = false; ++ pLed->bLedLinkBlinkInProgress = false; ++ pLed->bLedStartToLinkBlinkInProgress = false; ++ pLed->bLedScanBlinkInProgress = false; ++} ++ ++/*Description: */ ++/* Initialize an LED_871x object. */ ++void InitLed871x(struct adapter *padapter, struct LED_871x *pLed, enum LED_PIN_871x LedPin) ++{ ++ pLed->padapter = padapter; ++ pLed->LedPin = LedPin; ++ ++ ResetLedStatus(pLed); ++ ++ timer_setup(&pLed->BlinkTimer, BlinkTimerCallback, 0); ++ _init_workitem(&pLed->BlinkWorkItem, BlinkWorkItemCallback, pLed); ++} ++ ++/* */ ++/* Description: */ ++/* DeInitialize an LED_871x object. */ ++/* */ ++void DeInitLed871x(struct LED_871x *pLed) ++{ ++ _cancel_workitem_sync(&pLed->BlinkWorkItem); ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ ResetLedStatus(pLed); ++} ++ ++/* */ ++/* Description: */ ++/* Implementation of LED blinking behavior. */ ++/* It toggle off LED and schedule corresponding timer if necessary. */ ++/* */ ++ ++static void SwLedBlink(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 bStopBlinking = false; ++ ++ /* Change LED according to BlinkingLedState specified. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ SwLedOn(padapter, pLed); ++ else ++ SwLedOff(padapter, pLed); ++ ++ /* Determine if we shall change LED state again. */ ++ pLed->BlinkTimes--; ++ switch (pLed->CurrLedState) { ++ case LED_BLINK_NORMAL: ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ break; ++ case LED_BLINK_StartToBlink: ++ if (check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE)) ++ bStopBlinking = true; ++ if (check_fwstate(pmlmepriv, _FW_LINKED) && ++ (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) ++ bStopBlinking = true; ++ else if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ break; ++ case LED_BLINK_WPS: ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ break; ++ default: ++ bStopBlinking = true; ++ break; ++ } ++ ++ if (bStopBlinking) { ++ if (check_fwstate(pmlmepriv, _FW_LINKED) && !pLed->bLedOn) { ++ SwLedOn(padapter, pLed); ++ } else if (check_fwstate(pmlmepriv, _FW_LINKED) && pLed->bLedOn) { ++ SwLedOff(padapter, pLed); ++ } ++ pLed->BlinkTimes = 0; ++ pLed->bLedBlinkInProgress = false; ++ } else { ++ /* Assign LED state to toggle. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ ++ /* Schedule a timer to toggle LED state. */ ++ switch (pLed->CurrLedState) { ++ case LED_BLINK_NORMAL: ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ break; ++ case LED_BLINK_SLOWLY: ++ case LED_BLINK_StartToBlink: ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SLOWLY_INTERVAL); ++ break; ++ case LED_BLINK_WPS: ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_LONG_INTERVAL); ++ break; ++ default: ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SLOWLY_INTERVAL); ++ break; ++ } ++ } ++} ++ ++static void SwLedBlink1(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 bStopBlinking = false; ++ ++ /* Change LED according to BlinkingLedState specified. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ SwLedOn(padapter, pLed); ++ else ++ SwLedOff(padapter, pLed); ++ ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ ResetLedStatus(pLed); ++ return; ++ } ++ ++ switch (pLed->CurrLedState) { ++ case LED_BLINK_SLOWLY: ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ break; ++ case LED_BLINK_NORMAL: ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA); ++ break; ++ case LED_BLINK_SCAN: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ if (bStopBlinking) { ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->bLedLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_NORMAL; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA); ++ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ } ++ pLed->bLedScanBlinkInProgress = false; ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_BLINK_TXRX: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ if (bStopBlinking) { ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->bLedLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_NORMAL; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA); ++ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ } ++ pLed->BlinkTimes = 0; ++ pLed->bLedBlinkInProgress = false; ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_BLINK_WPS: ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ break; ++ case LED_BLINK_WPS_STOP: /* WPS success */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ bStopBlinking = false; ++ else ++ bStopBlinking = true; ++ ++ if (bStopBlinking) { ++ pLed->bLedLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_NORMAL; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA); ++ ++ pLed->bLedWPSBlinkInProgress = false; ++ } else { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++static void SwLedBlink2(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 bStopBlinking = false; ++ ++ /* Change LED according to BlinkingLedState specified. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ SwLedOn(padapter, pLed); ++ else ++ SwLedOff(padapter, pLed); ++ ++ switch (pLed->CurrLedState) { ++ case LED_BLINK_SCAN: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ SwLedOn(padapter, pLed); ++ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ SwLedOff(padapter, pLed); ++ } ++ pLed->bLedScanBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ case LED_BLINK_TXRX: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ SwLedOn(padapter, pLed); ++ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ SwLedOff(padapter, pLed); ++ } ++ pLed->bLedBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++static void SwLedBlink3(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 bStopBlinking = false; ++ ++ /* Change LED according to BlinkingLedState specified. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) { ++ SwLedOn(padapter, pLed); ++ } else { ++ if (pLed->CurrLedState != LED_BLINK_WPS_STOP) ++ SwLedOff(padapter, pLed); ++ } ++ ++ switch (pLed->CurrLedState) { ++ case LED_BLINK_SCAN: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ if (!pLed->bLedOn) ++ SwLedOn(padapter, pLed); ++ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ if (pLed->bLedOn) ++ SwLedOff(padapter, pLed); ++ } ++ pLed->bLedScanBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ case LED_BLINK_TXRX: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ if (!pLed->bLedOn) ++ SwLedOn(padapter, pLed); ++ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ ++ if (pLed->bLedOn) ++ SwLedOff(padapter, pLed); ++ } ++ pLed->bLedBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ case LED_BLINK_WPS: ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ break; ++ case LED_BLINK_WPS_STOP: /* WPS success */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); ++ bStopBlinking = false; ++ } else { ++ bStopBlinking = true; ++ } ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ SwLedOn(padapter, pLed); ++ } ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++static void SwLedBlink4(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct LED_871x *pLed1 = &ledpriv->SwLed1; ++ u8 bStopBlinking = false; ++ ++ /* Change LED according to BlinkingLedState specified. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ SwLedOn(padapter, pLed); ++ else ++ SwLedOff(padapter, pLed); ++ ++ if (!pLed1->bLedWPSBlinkInProgress && pLed1->BlinkingLedState == LED_UNKNOWN) { ++ pLed1->BlinkingLedState = RTW_LED_OFF; ++ pLed1->CurrLedState = RTW_LED_OFF; ++ SwLedOff(padapter, pLed1); ++ } ++ ++ switch (pLed->CurrLedState) { ++ case LED_BLINK_SLOWLY: ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ break; ++ case LED_BLINK_StartToBlink: ++ if (pLed->bLedOn) { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SLOWLY_INTERVAL); ++ } else { ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ } ++ break; ++ case LED_BLINK_SCAN: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = false; ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ SwLedOff(padapter, pLed); ++ } else { ++ pLed->bLedNoLinkBlinkInProgress = false; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ } ++ pLed->bLedScanBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ case LED_BLINK_TXRX: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ SwLedOff(padapter, pLed); ++ } else { ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ } ++ pLed->bLedBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ case LED_BLINK_WPS: ++ if (pLed->bLedOn) { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SLOWLY_INTERVAL); ++ } else { ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ } ++ break; ++ case LED_BLINK_WPS_STOP: /* WPS authentication fail */ ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ break; ++ case LED_BLINK_WPS_STOP_OVERLAP: /* WPS session overlap */ ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) { ++ if (pLed->bLedOn) ++ pLed->BlinkTimes = 1; ++ else ++ bStopBlinking = true; ++ } ++ ++ if (bStopBlinking) { ++ pLed->BlinkTimes = 10; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++static void SwLedBlink5(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ u8 bStopBlinking = false; ++ ++ /* Change LED according to BlinkingLedState specified. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ SwLedOn(padapter, pLed); ++ else ++ SwLedOff(padapter, pLed); ++ ++ switch (pLed->CurrLedState) { ++ case LED_BLINK_SCAN: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ if (pLed->bLedOn) ++ SwLedOff(padapter, pLed); ++ } else { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ if (!pLed->bLedOn) ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ ++ pLed->bLedScanBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ case LED_BLINK_TXRX: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ if (pLed->bLedOn) ++ SwLedOff(padapter, pLed); ++ } else { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ if (!pLed->bLedOn) ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ ++ pLed->bLedBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++static void SwLedBlink6(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ ++ /* Change LED according to BlinkingLedState specified. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ SwLedOn(padapter, pLed); ++ else ++ SwLedOff(padapter, pLed); ++} ++ ++ /* ALPHA, added by chiyoko, 20090106 */ ++static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAction) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct LED_871x *pLed = &ledpriv->SwLed0; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ switch (LedAction) { ++ case LED_CTL_POWER_ON: ++ case LED_CTL_START_TO_LINK: ++ case LED_CTL_NO_LINK: ++ if (!pLed->bLedNoLinkBlinkInProgress) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ if (pLed->bLedLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_LINK: ++ if (!pLed->bLedLinkBlinkInProgress) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ pLed->bLedLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_NORMAL; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_SITE_SURVEY: ++ if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED))) { ++ ; ++ } else if (!pLed->bLedScanBlinkInProgress) { ++ if (IS_LED_WPS_BLINKING(pLed)) ++ return; ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ pLed->bLedScanBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SCAN; ++ pLed->BlinkTimes = 24; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_TX: ++ case LED_CTL_RX: ++ if (!pLed->bLedBlinkInProgress) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedLinkBlinkInProgress = false; ++ } ++ pLed->bLedBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_TXRX; ++ pLed->BlinkTimes = 2; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_START_WPS: /* wait until xinpin finish */ ++ case LED_CTL_START_WPS_BOTTON: ++ if (!pLed->bLedWPSBlinkInProgress) { ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ pLed->bLedWPSBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_WPS; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_STOP_WPS: ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ if (pLed->bLedWPSBlinkInProgress) ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ else ++ pLed->bLedWPSBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_WPS_STOP; ++ if (pLed->bLedOn) { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); ++ } else { ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ break; ++ case LED_CTL_STOP_WPS_FAIL: ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ break; ++ case LED_CTL_POWER_OFF: ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ SwLedOff(padapter, pLed); ++ break; ++ default: ++ break; ++ } ++} ++ ++ /* Arcadyan/Sitecom , added by chiyoko, 20090216 */ ++static void SwLedControlMode2(struct adapter *padapter, enum LED_CTL_MODE LedAction) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct LED_871x *pLed = &ledpriv->SwLed0; ++ ++ switch (LedAction) { ++ case LED_CTL_SITE_SURVEY: ++ if (pmlmepriv->LinkDetectInfo.bBusyTraffic) { ++ } else if (!pLed->bLedScanBlinkInProgress) { ++ if (IS_LED_WPS_BLINKING(pLed)) ++ return; ++ ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ pLed->bLedScanBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SCAN; ++ pLed->BlinkTimes = 24; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_TX: ++ case LED_CTL_RX: ++ if ((!pLed->bLedBlinkInProgress) && (check_fwstate(pmlmepriv, _FW_LINKED))) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ pLed->bLedBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_TXRX; ++ pLed->BlinkTimes = 2; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_LINK: ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ _set_timer(&pLed->BlinkTimer, 0); ++ break; ++ case LED_CTL_START_WPS: /* wait until xinpin finish */ ++ case LED_CTL_START_WPS_BOTTON: ++ if (!pLed->bLedWPSBlinkInProgress) { ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ pLed->bLedWPSBlinkInProgress = true; ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ break; ++ case LED_CTL_STOP_WPS: ++ pLed->bLedWPSBlinkInProgress = false; ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ break; ++ case LED_CTL_STOP_WPS_FAIL: ++ pLed->bLedWPSBlinkInProgress = false; ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ break; ++ case LED_CTL_START_TO_LINK: ++ case LED_CTL_NO_LINK: ++ if (!IS_LED_BLINKING(pLed)) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ break; ++ case LED_CTL_POWER_OFF: ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ ++ _set_timer(&pLed->BlinkTimer, 0); ++ break; ++ default: ++ break; ++ } ++} ++ ++ /* COREGA, added by chiyoko, 20090316 */ ++ static void SwLedControlMode3(struct adapter *padapter, enum LED_CTL_MODE LedAction) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct LED_871x *pLed = &ledpriv->SwLed0; ++ ++ switch (LedAction) { ++ case LED_CTL_SITE_SURVEY: ++ if (pmlmepriv->LinkDetectInfo.bBusyTraffic) { ++ } else if (!pLed->bLedScanBlinkInProgress) { ++ if (IS_LED_WPS_BLINKING(pLed)) ++ return; ++ ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ pLed->bLedScanBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SCAN; ++ pLed->BlinkTimes = 24; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_TX: ++ case LED_CTL_RX: ++ if ((!pLed->bLedBlinkInProgress) && (check_fwstate(pmlmepriv, _FW_LINKED))) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ pLed->bLedBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_TXRX; ++ pLed->BlinkTimes = 2; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_LINK: ++ if (IS_LED_WPS_BLINKING(pLed)) ++ return; ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ ++ _set_timer(&pLed->BlinkTimer, 0); ++ break; ++ case LED_CTL_START_WPS: /* wait until xinpin finish */ ++ case LED_CTL_START_WPS_BOTTON: ++ if (!pLed->bLedWPSBlinkInProgress) { ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ pLed->bLedWPSBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_WPS; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_STOP_WPS: ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } else { ++ pLed->bLedWPSBlinkInProgress = true; ++ } ++ ++ pLed->CurrLedState = LED_BLINK_WPS_STOP; ++ if (pLed->bLedOn) { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); ++ } else { ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ break; ++ case LED_CTL_STOP_WPS_FAIL: ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, 0); ++ break; ++ case LED_CTL_START_TO_LINK: ++ case LED_CTL_NO_LINK: ++ if (!IS_LED_BLINKING(pLed)) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ break; ++ case LED_CTL_POWER_OFF: ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ ++ _set_timer(&pLed->BlinkTimer, 0); ++ break; ++ default: ++ break; ++ } ++} ++ ++ /* Edimax-Belkin, added by chiyoko, 20090413 */ ++static void SwLedControlMode4(struct adapter *padapter, enum LED_CTL_MODE LedAction) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct LED_871x *pLed = &ledpriv->SwLed0; ++ struct LED_871x *pLed1 = &ledpriv->SwLed1; ++ ++ switch (LedAction) { ++ case LED_CTL_START_TO_LINK: ++ if (pLed1->bLedWPSBlinkInProgress) { ++ pLed1->bLedWPSBlinkInProgress = false; ++ _cancel_timer_ex(&pLed1->BlinkTimer); ++ ++ pLed1->BlinkingLedState = RTW_LED_OFF; ++ pLed1->CurrLedState = RTW_LED_OFF; ++ ++ if (pLed1->bLedOn) ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ ++ if (!pLed->bLedStartToLinkBlinkInProgress) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ ++ pLed->bLedStartToLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_StartToBlink; ++ if (pLed->bLedOn) { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SLOWLY_INTERVAL); ++ } else { ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ } ++ } ++ break; ++ case LED_CTL_LINK: ++ case LED_CTL_NO_LINK: ++ /* LED1 settings */ ++ if (LedAction == LED_CTL_LINK) { ++ if (pLed1->bLedWPSBlinkInProgress) { ++ pLed1->bLedWPSBlinkInProgress = false; ++ _cancel_timer_ex(&pLed1->BlinkTimer); ++ ++ pLed1->BlinkingLedState = RTW_LED_OFF; ++ pLed1->CurrLedState = RTW_LED_OFF; ++ ++ if (pLed1->bLedOn) ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ } ++ ++ if (!pLed->bLedNoLinkBlinkInProgress) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_SITE_SURVEY: ++ if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED))) { ++ } else if (!pLed->bLedScanBlinkInProgress) { ++ if (IS_LED_WPS_BLINKING(pLed)) ++ return; ++ ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ pLed->bLedScanBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SCAN; ++ pLed->BlinkTimes = 24; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_TX: ++ case LED_CTL_RX: ++ if (!pLed->bLedBlinkInProgress) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ pLed->bLedBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_TXRX; ++ pLed->BlinkTimes = 2; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_START_WPS: /* wait until xinpin finish */ ++ case LED_CTL_START_WPS_BOTTON: ++ if (pLed1->bLedWPSBlinkInProgress) { ++ pLed1->bLedWPSBlinkInProgress = false; ++ _cancel_timer_ex(&pLed1->BlinkTimer); ++ ++ pLed1->BlinkingLedState = RTW_LED_OFF; ++ pLed1->CurrLedState = RTW_LED_OFF; ++ ++ if (pLed1->bLedOn) ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ ++ if (!pLed->bLedWPSBlinkInProgress) { ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ pLed->bLedWPSBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_WPS; ++ if (pLed->bLedOn) { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SLOWLY_INTERVAL); ++ } else { ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ } ++ } ++ break; ++ case LED_CTL_STOP_WPS: /* WPS connect success */ ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ ++ break; ++ case LED_CTL_STOP_WPS_FAIL: /* WPS authentication fail */ ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ ++ /* LED1 settings */ ++ if (pLed1->bLedWPSBlinkInProgress) ++ _cancel_timer_ex(&pLed1->BlinkTimer); ++ else ++ pLed1->bLedWPSBlinkInProgress = true; ++ pLed1->CurrLedState = LED_BLINK_WPS_STOP; ++ if (pLed1->bLedOn) ++ pLed1->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed1->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ break; ++ case LED_CTL_STOP_WPS_FAIL_OVERLAP: /* WPS session overlap */ ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ ++ /* LED1 settings */ ++ if (pLed1->bLedWPSBlinkInProgress) ++ _cancel_timer_ex(&pLed1->BlinkTimer); ++ else ++ pLed1->bLedWPSBlinkInProgress = true; ++ pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP; ++ pLed1->BlinkTimes = 10; ++ if (pLed1->bLedOn) ++ pLed1->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed1->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ break; ++ case LED_CTL_POWER_OFF: ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ if (pLed->bLedStartToLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedStartToLinkBlinkInProgress = false; ++ } ++ if (pLed1->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed1->BlinkTimer); ++ pLed1->bLedWPSBlinkInProgress = false; ++ } ++ pLed1->BlinkingLedState = LED_UNKNOWN; ++ SwLedOff(padapter, pLed); ++ SwLedOff(padapter, pLed1); ++ break; ++ default: ++ break; ++ } ++} ++ ++ /* Sercomm-Belkin, added by chiyoko, 20090415 */ ++static void ++SwLedControlMode5( ++ struct adapter *padapter, ++ enum LED_CTL_MODE LedAction ++) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct LED_871x *pLed = &ledpriv->SwLed0; ++ ++ switch (LedAction) { ++ case LED_CTL_POWER_ON: ++ case LED_CTL_NO_LINK: ++ case LED_CTL_LINK: /* solid blue */ ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ ++ _set_timer(&pLed->BlinkTimer, 0); ++ break; ++ case LED_CTL_SITE_SURVEY: ++ if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED))) { ++ } else if (!pLed->bLedScanBlinkInProgress) { ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ pLed->bLedScanBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SCAN; ++ pLed->BlinkTimes = 24; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_TX: ++ case LED_CTL_RX: ++ if (!pLed->bLedBlinkInProgress) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN) ++ return; ++ pLed->bLedBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_TXRX; ++ pLed->BlinkTimes = 2; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_POWER_OFF: ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ SwLedOff(padapter, pLed); ++ break; ++ default: ++ break; ++ } ++} ++ ++ /* WNC-Corega, added by chiyoko, 20090902 */ ++static void ++SwLedControlMode6( ++ struct adapter *padapter, ++ enum LED_CTL_MODE LedAction ++) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct LED_871x *pLed0 = &ledpriv->SwLed0; ++ ++ switch (LedAction) { ++ case LED_CTL_POWER_ON: ++ case LED_CTL_LINK: ++ case LED_CTL_NO_LINK: ++ _cancel_timer_ex(&pLed0->BlinkTimer); ++ pLed0->CurrLedState = RTW_LED_ON; ++ pLed0->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed0->BlinkTimer, 0); ++ break; ++ case LED_CTL_POWER_OFF: ++ SwLedOff(padapter, pLed0); ++ break; ++ default: ++ break; ++ } ++} ++ ++/* */ ++/* Description: */ ++/* Handler function of LED Blinking. */ ++/* We dispatch acture LED blink action according to LedStrategy. */ ++/* */ ++void BlinkHandler(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ ++ if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped)) ++ return; ++ ++ switch (ledpriv->LedStrategy) { ++ case SW_LED_MODE0: ++ SwLedBlink(pLed); ++ break; ++ case SW_LED_MODE1: ++ SwLedBlink1(pLed); ++ break; ++ case SW_LED_MODE2: ++ SwLedBlink2(pLed); ++ break; ++ case SW_LED_MODE3: ++ SwLedBlink3(pLed); ++ break; ++ case SW_LED_MODE4: ++ SwLedBlink4(pLed); ++ break; ++ case SW_LED_MODE5: ++ SwLedBlink5(pLed); ++ break; ++ case SW_LED_MODE6: ++ SwLedBlink6(pLed); ++ break; ++ default: ++ break; ++ } ++} ++ ++void LedControl8188eu(struct adapter *padapter, enum LED_CTL_MODE LedAction) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct registry_priv *registry_par; ++ ++ if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped) || ++ (!padapter->hw_init_completed)) ++ return; ++ ++ if (!ledpriv->bRegUseLed) ++ return; ++ ++ registry_par = &padapter->registrypriv; ++ if (!registry_par->led_enable) ++ return; ++ ++ if ((padapter->pwrctrlpriv.rf_pwrstate != rf_on && ++ padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) && ++ (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX || ++ LedAction == LED_CTL_SITE_SURVEY || ++ LedAction == LED_CTL_LINK || ++ LedAction == LED_CTL_NO_LINK || ++ LedAction == LED_CTL_POWER_ON)) ++ return; ++ ++ switch (ledpriv->LedStrategy) { ++ case SW_LED_MODE0: ++ break; ++ case SW_LED_MODE1: ++ SwLedControlMode1(padapter, LedAction); ++ break; ++ case SW_LED_MODE2: ++ SwLedControlMode2(padapter, LedAction); ++ break; ++ case SW_LED_MODE3: ++ SwLedControlMode3(padapter, LedAction); ++ break; ++ case SW_LED_MODE4: ++ SwLedControlMode4(padapter, LedAction); ++ break; ++ case SW_LED_MODE5: ++ SwLedControlMode5(padapter, LedAction); ++ break; ++ case SW_LED_MODE6: ++ SwLedControlMode6(padapter, LedAction); ++ break; ++ default: ++ break; ++ } ++} +diff --git a/drivers/staging/r8188eu/core/rtw_mlme.c b/drivers/staging/r8188eu/core/rtw_mlme.c +new file mode 100644 +index 000000000000..1115ff5d865a +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_mlme.c +@@ -0,0 +1,2199 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_MLME_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/xmit_osdep.h" ++#include "../include/hal_intf.h" ++#include "../include/mlme_osdep.h" ++#include "../include/sta_info.h" ++#include "../include/wifi.h" ++#include "../include/wlan_bssdef.h" ++#include "../include/rtw_ioctl_set.h" ++#include "../include/usb_osintf.h" ++ ++extern unsigned char MCS_rate_2R[16]; ++extern unsigned char MCS_rate_1R[16]; ++ ++void rtw_set_roaming(struct adapter *adapter, u8 to_roaming) ++{ ++ if (to_roaming == 0) ++ adapter->mlmepriv.to_join = false; ++ adapter->mlmepriv.to_roaming = to_roaming; ++} ++ ++u8 rtw_to_roaming(struct adapter *adapter) ++{ ++ return adapter->mlmepriv.to_roaming; ++} ++ ++int _rtw_init_mlme_priv(struct adapter *padapter) ++{ ++ int i; ++ u8 *pbuf; ++ struct wlan_network *pnetwork; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ int res = _SUCCESS; ++ ++ /* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */ ++ ++ pmlmepriv->nic_hdl = (u8 *)padapter; ++ ++ pmlmepriv->pscanned = NULL; ++ pmlmepriv->fw_state = 0; ++ pmlmepriv->cur_network.network.InfrastructureMode = Ndis802_11AutoUnknown; ++ pmlmepriv->scan_mode = SCAN_ACTIVE;/* 1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff) */ ++ ++ spin_lock_init(&pmlmepriv->lock); ++ _rtw_init_queue(&pmlmepriv->free_bss_pool); ++ _rtw_init_queue(&pmlmepriv->scanned_queue); ++ ++ set_scanned_network_val(pmlmepriv, 0); ++ ++ memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid)); ++ ++ pbuf = vzalloc(MAX_BSS_CNT * (sizeof(struct wlan_network))); ++ ++ if (!pbuf) { ++ res = _FAIL; ++ goto exit; ++ } ++ pmlmepriv->free_bss_buf = pbuf; ++ ++ pnetwork = (struct wlan_network *)pbuf; ++ ++ for (i = 0; i < MAX_BSS_CNT; i++) { ++ INIT_LIST_HEAD(&pnetwork->list); ++ ++ list_add_tail(&pnetwork->list, &pmlmepriv->free_bss_pool.queue); ++ ++ pnetwork++; ++ } ++ ++ /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ ++ ++ rtw_clear_scan_deny(padapter); ++ ++ rtw_init_mlme_timer(padapter); ++ ++exit: ++ ++ return res; ++} ++ ++static void rtw_mfree_mlme_priv_lock(struct mlme_priv *pmlmepriv) ++{ ++} ++ ++#if defined(CONFIG_88EU_AP_MODE) ++static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen) ++{ ++ kfree(*ppie); ++ *plen = 0; ++ *ppie = NULL; ++} ++ ++void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv) ++{ ++ kfree(pmlmepriv->assoc_req); ++ kfree(pmlmepriv->assoc_rsp); ++ rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len); ++ rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len); ++ rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len); ++ rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len); ++ ++ rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len); ++ rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len); ++ rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len); ++ rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len); ++ rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len); ++} ++#else ++void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv) ++{ ++} ++#endif ++ ++void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) ++{ ++ ++ rtw_free_mlme_priv_ie_data(pmlmepriv); ++ ++ if (pmlmepriv) { ++ rtw_mfree_mlme_priv_lock(pmlmepriv); ++ ++ vfree(pmlmepriv->free_bss_buf); ++ } ++ ++} ++ ++int _rtw_enqueue_network(struct __queue *queue, struct wlan_network *pnetwork) ++{ ++ ++ if (!pnetwork) ++ goto exit; ++ ++ spin_lock_bh(&queue->lock); ++ ++ list_add_tail(&pnetwork->list, &queue->queue); ++ ++ spin_unlock_bh(&queue->lock); ++ ++exit: ++ ++ return _SUCCESS; ++} ++ ++struct wlan_network *_rtw_dequeue_network(struct __queue *queue) ++{ ++ struct wlan_network *pnetwork; ++ ++ spin_lock_bh(&queue->lock); ++ ++ if (list_empty(&queue->queue)) { ++ pnetwork = NULL; ++ } else { ++ pnetwork = container_of((&queue->queue)->next, struct wlan_network, list); ++ ++ list_del_init(&pnetwork->list); ++ } ++ ++ spin_unlock_bh(&queue->lock); ++ ++ return pnetwork; ++} ++ ++struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv)/* _queue *free_queue) */ ++{ ++ struct wlan_network *pnetwork; ++ struct __queue *free_queue = &pmlmepriv->free_bss_pool; ++ struct list_head *plist = NULL; ++ ++ spin_lock_bh(&free_queue->lock); ++ ++ if (list_empty(&free_queue->queue)) { ++ pnetwork = NULL; ++ goto exit; ++ } ++ plist = (&free_queue->queue)->next; ++ ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ list_del_init(&pnetwork->list); ++ ++ pnetwork->network_type = 0; ++ pnetwork->fixed = false; ++ pnetwork->last_scanned = jiffies; ++ pnetwork->aid = 0; ++ pnetwork->join_res = 0; ++ ++ pmlmepriv->num_of_scanned++; ++ ++exit: ++ spin_unlock_bh(&free_queue->lock); ++ ++ return pnetwork; ++} ++ ++void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 isfreeall) ++{ ++ u32 curr_time, delta_time; ++ u32 lifetime = SCANQUEUE_LIFETIME; ++ struct __queue *free_queue = &pmlmepriv->free_bss_pool; ++ ++ if (!pnetwork) ++ return; ++ ++ if (pnetwork->fixed) ++ return; ++ curr_time = jiffies; ++ if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) || ++ (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))) ++ lifetime = 1; ++ if (!isfreeall) { ++ delta_time = (curr_time - pnetwork->last_scanned) / HZ; ++ if (delta_time < lifetime)/* unit:sec */ ++ return; ++ } ++ spin_lock_bh(&free_queue->lock); ++ list_del_init(&pnetwork->list); ++ list_add_tail(&pnetwork->list, &free_queue->queue); ++ pmlmepriv->num_of_scanned--; ++ spin_unlock_bh(&free_queue->lock); ++} ++ ++void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork) ++{ ++ struct __queue *free_queue = &pmlmepriv->free_bss_pool; ++ ++ if (!pnetwork) ++ return; ++ if (pnetwork->fixed) ++ return; ++ list_del_init(&pnetwork->list); ++ list_add_tail(&pnetwork->list, get_list_head(free_queue)); ++ pmlmepriv->num_of_scanned--; ++} ++ ++/* ++ return the wlan_network with the matching addr ++ ++ Shall be calle under atomic context... to avoid possible racing condition... ++*/ ++struct wlan_network *_rtw_find_network(struct __queue *scanned_queue, u8 *addr) ++{ ++ struct list_head *phead, *plist; ++ struct wlan_network *pnetwork = NULL; ++ u8 zero_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; ++ ++ if (!memcmp(zero_addr, addr, ETH_ALEN)) { ++ pnetwork = NULL; ++ goto exit; ++ } ++ phead = get_list_head(scanned_queue); ++ plist = phead->next; ++ ++ while (plist != phead) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN)) ++ break; ++ plist = plist->next; ++ } ++ if (plist == phead) ++ pnetwork = NULL; ++exit: ++ ++ return pnetwork; ++} ++ ++void _rtw_free_network_queue(struct adapter *padapter, u8 isfreeall) ++{ ++ struct list_head *phead, *plist; ++ struct wlan_network *pnetwork; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct __queue *scanned_queue = &pmlmepriv->scanned_queue; ++ ++ spin_lock_bh(&scanned_queue->lock); ++ ++ phead = get_list_head(scanned_queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ plist = plist->next; ++ ++ _rtw_free_network(pmlmepriv, pnetwork, isfreeall); ++ } ++ spin_unlock_bh(&scanned_queue->lock); ++ ++} ++ ++int rtw_if_up(struct adapter *padapter) ++{ ++ int res; ++ ++ if (padapter->bDriverStopped || padapter->bSurpriseRemoved || ++ !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) ++ res = false; ++ else ++ res = true; ++ ++ return res; ++} ++ ++void rtw_generate_random_ibss(u8 *pibss) ++{ ++ u32 curtime = jiffies; ++ ++ pibss[0] = 0x02; /* in ad-hoc mode bit1 must set to 1 */ ++ pibss[1] = 0x11; ++ pibss[2] = 0x87; ++ pibss[3] = (u8)(curtime & 0xff);/* p[0]; */ ++ pibss[4] = (u8)((curtime >> 8) & 0xff);/* p[1]; */ ++ pibss[5] = (u8)((curtime >> 16) & 0xff);/* p[2]; */ ++} ++ ++u8 *rtw_get_capability_from_ie(u8 *ie) ++{ ++ return ie + 8 + 2; ++} ++ ++u16 rtw_get_capability(struct wlan_bssid_ex *bss) ++{ ++ __le16 val; ++ ++ memcpy((u8 *)&val, rtw_get_capability_from_ie(bss->IEs), 2); ++ ++ return le16_to_cpu(val); ++} ++ ++u8 *rtw_get_timestampe_from_ie(u8 *ie) ++{ ++ return ie + 0; ++} ++ ++u8 *rtw_get_beacon_interval_from_ie(u8 *ie) ++{ ++ return ie + 8; ++} ++ ++int rtw_init_mlme_priv(struct adapter *padapter)/* struct mlme_priv *pmlmepriv) */ ++{ ++ int res; ++ ++ res = _rtw_init_mlme_priv(padapter);/* (pmlmepriv); */ ++ ++ return res; ++} ++ ++void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) ++{ ++ _rtw_free_mlme_priv(pmlmepriv); ++} ++ ++static struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv) ++{ ++ struct wlan_network *pnetwork; ++ ++ pnetwork = _rtw_alloc_network(pmlmepriv); ++ ++ return pnetwork; ++} ++ ++static void rtw_free_network_nolock(struct mlme_priv *pmlmepriv, ++ struct wlan_network *pnetwork) ++{ ++ ++ _rtw_free_network_nolock(pmlmepriv, pnetwork); ++ ++} ++ ++void rtw_free_network_queue(struct adapter *dev, u8 isfreeall) ++{ ++ ++ _rtw_free_network_queue(dev, isfreeall); ++ ++} ++ ++/* ++ return the wlan_network with the matching addr ++ ++ Shall be calle under atomic context... to avoid possible racing condition... ++*/ ++struct wlan_network *rtw_find_network(struct __queue *scanned_queue, u8 *addr) ++{ ++ struct wlan_network *pnetwork = _rtw_find_network(scanned_queue, addr); ++ ++ return pnetwork; ++} ++ ++int rtw_is_same_ibss(struct adapter *adapter, struct wlan_network *pnetwork) ++{ ++ int ret = true; ++ struct security_priv *psecuritypriv = &adapter->securitypriv; ++ ++ if ((psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_) && ++ (pnetwork->network.Privacy == 0)) ++ ret = false; ++ else if ((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_) && ++ (pnetwork->network.Privacy == 1)) ++ ret = false; ++ else ++ ret = true; ++ return ret; ++} ++ ++static int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b) ++{ ++ return (a->Ssid.SsidLength == b->Ssid.SsidLength) && ++ !memcmp(a->Ssid.Ssid, b->Ssid.Ssid, a->Ssid.SsidLength); ++} ++ ++int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst) ++{ ++ u16 s_cap, d_cap; ++ __le16 le_scap, le_dcap; ++ ++ memcpy((u8 *)&le_scap, rtw_get_capability_from_ie(src->IEs), 2); ++ memcpy((u8 *)&le_dcap, rtw_get_capability_from_ie(dst->IEs), 2); ++ ++ s_cap = le16_to_cpu(le_scap); ++ d_cap = le16_to_cpu(le_dcap); ++ ++ return ((src->Ssid.SsidLength == dst->Ssid.SsidLength) && ++ ((!memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN))) && ++ ((!memcmp(src->Ssid.Ssid, dst->Ssid.Ssid, src->Ssid.SsidLength))) && ++ ((s_cap & WLAN_CAPABILITY_IBSS) == ++ (d_cap & WLAN_CAPABILITY_IBSS)) && ++ ((s_cap & WLAN_CAPABILITY_BSS) == ++ (d_cap & WLAN_CAPABILITY_BSS))); ++} ++ ++struct wlan_network *rtw_get_oldest_wlan_network(struct __queue *scanned_queue) ++{ ++ struct list_head *plist, *phead; ++ struct wlan_network *pwlan = NULL; ++ struct wlan_network *oldest = NULL; ++ ++ phead = get_list_head(scanned_queue); ++ ++ plist = phead->next; ++ ++ while (1) { ++ if (phead == plist) ++ break; ++ ++ pwlan = container_of(plist, struct wlan_network, list); ++ ++ if (!pwlan->fixed) { ++ if (!oldest || time_after(oldest->last_scanned, pwlan->last_scanned)) ++ oldest = pwlan; ++ } ++ ++ plist = plist->next; ++ } ++ ++ return oldest; ++} ++ ++void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, ++ struct adapter *padapter, bool update_ie) ++{ ++ long rssi_ori = dst->Rssi; ++ u8 sq_smp = src->PhyInfo.SignalQuality; ++ u8 ss_final; ++ u8 sq_final; ++ long rssi_final; ++ ++ rtw_hal_antdiv_rssi_compared(padapter, dst, src); /* this will update src.Rssi, need consider again */ ++ ++ /* The rule below is 1/5 for sample value, 4/5 for history value */ ++ if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&padapter->mlmepriv.cur_network.network, src)) { ++ /* Take the recvpriv's value for the connected AP*/ ++ ss_final = padapter->recvpriv.signal_strength; ++ sq_final = padapter->recvpriv.signal_qual; ++ /* the rssi value here is undecorated, and will be used for antenna diversity */ ++ if (sq_smp != 101) /* from the right channel */ ++ rssi_final = dst->Rssi; //(src->Rssi+dst->Rssi*4)/5; ++ else ++ rssi_final = rssi_ori; ++ } else { ++// if (sq_smp != 101) { /* from the right channel */ ++ ss_final = (u32)dst->PhyInfo.SignalStrength; //((u32)(src->PhyInfo.SignalStrength)+(u32)(dst->PhyInfo.SignalStrength)*4)/5; ++ sq_final = (u32)dst->PhyInfo.SignalQuality; //((u32)(src->PhyInfo.SignalQuality)+(u32)(dst->PhyInfo.SignalQuality)*4)/5; ++ rssi_final = dst->Rssi; //(src->Rssi+dst->Rssi*4)/5; ++// } else { ++// /* bss info not receiving from the right channel, use the original RX signal infos */ ++// ss_final = dst->PhyInfo.SignalStrength; ++// sq_final = dst->PhyInfo.SignalQuality; ++// rssi_final = dst->Rssi; ++// } ++ } ++ if (update_ie) { ++ dst->Reserved[0] = src->Reserved[0]; ++ dst->Reserved[1] = src->Reserved[1]; ++ memcpy((u8 *)dst, (u8 *)src, get_wlan_bssid_ex_sz(src)); ++ } ++ dst->PhyInfo.SignalStrength = ss_final; ++ dst->PhyInfo.SignalQuality = sq_final; ++ dst->Rssi = rssi_final; ++ ++} ++ ++static void update_current_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork) ++{ ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED) && ++ is_same_network(&pmlmepriv->cur_network.network, pnetwork)) { ++ update_network(&pmlmepriv->cur_network.network, pnetwork, adapter, true); ++ rtw_update_protection(adapter, (pmlmepriv->cur_network.network.IEs) + sizeof(struct ndis_802_11_fixed_ie), ++ pmlmepriv->cur_network.network.IELength); ++ } ++ ++} ++ ++/* ++Caller must hold pmlmepriv->lock first. ++*/ ++void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *target) ++{ ++ struct list_head *plist, *phead; ++ u32 bssid_ex_sz; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ struct wlan_network *oldest = NULL; ++ ++ spin_lock_bh(&queue->lock); ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ if (is_same_network(&pnetwork->network, target)) ++ break; ++ if ((oldest == ((struct wlan_network *)0)) || ++ time_after(oldest->last_scanned, pnetwork->last_scanned)) ++ oldest = pnetwork; ++ plist = plist->next; ++ } ++ /* If we didn't find a match, then get a new network slot to initialize ++ * with this beacon's information */ ++ if (phead == plist) { ++ if (list_empty(&pmlmepriv->free_bss_pool.queue)) { ++ /* If there are no more slots, expire the oldest */ ++ pnetwork = oldest; ++ ++ rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &target->PhyInfo.Optimum_antenna); ++ memcpy(&pnetwork->network, target, get_wlan_bssid_ex_sz(target)); ++ /* variable initialize */ ++ pnetwork->fixed = false; ++ pnetwork->last_scanned = jiffies; ++ ++ pnetwork->network_type = 0; ++ pnetwork->aid = 0; ++ pnetwork->join_res = 0; ++ ++ /* bss info not receiving from the right channel */ ++ if (pnetwork->network.PhyInfo.SignalQuality == 101) ++ pnetwork->network.PhyInfo.SignalQuality = 0; ++ } else { ++ /* Otherwise just pull from the free list */ ++ ++ pnetwork = rtw_alloc_network(pmlmepriv); /* will update scan_time */ ++ ++ if (!pnetwork) ++ goto exit; ++ ++ bssid_ex_sz = get_wlan_bssid_ex_sz(target); ++ target->Length = bssid_ex_sz; ++ rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &target->PhyInfo.Optimum_antenna); ++ memcpy(&pnetwork->network, target, bssid_ex_sz); ++ ++ pnetwork->last_scanned = jiffies; ++ ++ /* bss info not receiving from the right channel */ ++ if (pnetwork->network.PhyInfo.SignalQuality == 101) ++ pnetwork->network.PhyInfo.SignalQuality = 0; ++ list_add_tail(&pnetwork->list, &queue->queue); ++ } ++ } else { ++ /* we have an entry and we are going to update it. But this entry may ++ * be already expired. In this case we do the same as we found a new ++ * net and call the new_net handler ++ */ ++ bool update_ie = true; ++ ++ pnetwork->last_scanned = jiffies; ++ ++ /* target.Reserved[0]== 1, means that scanned network is a bcn frame. */ ++ /* probe resp(3) > beacon(1) > probe req(2) */ ++ if ((target->Reserved[0] != 2) && ++ (target->Reserved[0] >= pnetwork->network.Reserved[0])) ++ update_ie = true; ++ else ++ update_ie = false; ++ update_network(&pnetwork->network, target, adapter, update_ie); ++ } ++ ++exit: ++ spin_unlock_bh(&queue->lock); ++ ++} ++ ++static void rtw_add_network(struct adapter *adapter, ++ struct wlan_bssid_ex *pnetwork) ++{ ++ ++#if defined(CONFIG_88EU_P2P) ++ rtw_wlan_bssid_ex_remove_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO); ++#endif ++ update_current_network(adapter, pnetwork); ++ rtw_update_scanned_network(adapter, pnetwork); ++ ++} ++ ++/* select the desired network based on the capability of the (i)bss. */ ++/* check items: (1) security */ ++/* (2) network_type */ ++/* (3) WMM */ ++/* (4) HT */ ++/* (5) others */ ++static int rtw_is_desired_network(struct adapter *adapter, struct wlan_network *pnetwork) ++{ ++ struct security_priv *psecuritypriv = &adapter->securitypriv; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ u32 desired_encmode; ++ u32 privacy; ++ ++ /* u8 wps_ie[512]; */ ++ uint wps_ielen; ++ ++ int bselected = true; ++ ++ desired_encmode = psecuritypriv->ndisencryptstatus; ++ privacy = pnetwork->network.Privacy; ++ ++ if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) { ++ if (rtw_get_wps_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, pnetwork->network.IELength - _FIXED_IE_LENGTH_, NULL, &wps_ielen)) ++ return true; ++ else ++ return false; ++ } ++ if (adapter->registrypriv.wifi_spec == 1) { /* for correct flow of 8021X to do.... */ ++ u8 *p = NULL; ++ uint ie_len = 0; ++ ++ if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0)) ++ bselected = false; ++ if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) { ++ p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, ++ _RSN_IE_2_, &ie_len, ++ (pnetwork->network.IELength - ++ _BEACON_IE_OFFSET_)); ++ if (p && ie_len > 0) ++ bselected = true; ++ else ++ bselected = false; ++ } ++ } ++ ++ if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0)) { ++ DBG_88E("desired_encmode: %d, privacy: %d\n", desired_encmode, privacy); ++ bselected = false; ++ } ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { ++ if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode) ++ bselected = false; ++ } ++ ++ return bselected; ++} ++ ++void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf) ++{ ++ u32 len; ++ struct wlan_bssid_ex *pnetwork; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ ++ pnetwork = (struct wlan_bssid_ex *)pbuf; ++ ++ len = get_wlan_bssid_ex_sz(pnetwork); ++ if (len > (sizeof(struct wlan_bssid_ex))) ++ return; ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ /* update IBSS_network 's timestamp */ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, pnetwork->MacAddress, ETH_ALEN)) { ++ struct wlan_network *ibss_wlan = NULL; ++ ++ memcpy(pmlmepriv->cur_network.network.IEs, pnetwork->IEs, 8); ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ibss_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->MacAddress); ++ if (ibss_wlan) { ++ memcpy(ibss_wlan->network.IEs, pnetwork->IEs, 8); ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ goto exit; ++ } ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ } ++ } ++ ++ /* lock pmlmepriv->lock when you accessing network_q */ ++ if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { ++ if (pnetwork->Ssid.Ssid[0] == 0) ++ pnetwork->Ssid.SsidLength = 0; ++ rtw_add_network(adapter, pnetwork); ++ } ++ ++exit: ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) ++{ ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ u8 timer_cancelled = 0; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (pmlmepriv->wps_probe_req_ie) { ++ pmlmepriv->wps_probe_req_ie_len = 0; ++ kfree(pmlmepriv->wps_probe_req_ie); ++ pmlmepriv->wps_probe_req_ie = NULL; ++ } ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { ++ timer_cancelled = 1; ++ ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); ++ } ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++ if (timer_cancelled) ++ _cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled); ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ rtw_set_signal_stat_timer(&adapter->recvpriv); ++ ++ if (pmlmepriv->to_join) { ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { ++ if (!check_fwstate(pmlmepriv, _FW_LINKED)) { ++ set_fwstate(pmlmepriv, _FW_UNDER_LINKING); ++ ++ if (rtw_select_and_join_from_scanned_queue(pmlmepriv) == _SUCCESS) { ++ _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); ++ } else { ++ struct wlan_bssid_ex *pdev_network = &adapter->registrypriv.dev_network; ++ u8 *pibss = adapter->registrypriv.dev_network.MacAddress; ++ ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); ++ ++ memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); ++ memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); ++ ++ rtw_update_registrypriv_dev_network(adapter); ++ rtw_generate_random_ibss(pibss); ++ ++ pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; ++ ++ rtw_createbss_cmd(adapter); ++ pmlmepriv->to_join = false; ++ } ++ } ++ } else { ++ int s_ret; ++ set_fwstate(pmlmepriv, _FW_UNDER_LINKING); ++ pmlmepriv->to_join = false; ++ s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv); ++ if (_SUCCESS == s_ret) { ++ _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); ++ } else if (s_ret == 2) { /* there is no need to wait for join */ ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ rtw_indicate_connect(adapter); ++ } else { ++ DBG_88E("try_to_join, but select scanning queue fail, to_roaming:%d\n", ++ pmlmepriv->to_roaming); ++ if (rtw_to_roaming(adapter) != 0) { ++ if (--pmlmepriv->to_roaming == 0 || ++ _SUCCESS != rtw_sitesurvey_cmd(adapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)) { ++ rtw_set_roaming(adapter, 0); ++ rtw_free_assoc_resources(adapter, 1); ++ rtw_indicate_disconnect(adapter); ++ } else { ++ pmlmepriv->to_join = true; ++ } ++ } else { ++ rtw_indicate_disconnect(adapter); ++ } ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ } ++ } ++ } ++ ++ indicate_wx_scan_complete_event(adapter); ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ p2p_ps_wk_cmd(adapter, P2P_PS_SCAN_DONE, 0); ++ ++ rtw_os_xmit_schedule(adapter); ++} ++ ++void rtw_dummy_event_callback(struct adapter *adapter, u8 *pbuf) ++{ ++} ++ ++void rtw_fwdbg_event_callback(struct adapter *adapter, u8 *pbuf) ++{ ++} ++ ++static void free_scanqueue(struct mlme_priv *pmlmepriv) ++{ ++ struct __queue *free_queue = &pmlmepriv->free_bss_pool; ++ struct __queue *scan_queue = &pmlmepriv->scanned_queue; ++ struct list_head *plist, *phead, *ptemp; ++ ++ spin_lock_bh(&scan_queue->lock); ++ spin_lock_bh(&free_queue->lock); ++ ++ phead = get_list_head(scan_queue); ++ plist = phead->next; ++ ++ while (plist != phead) { ++ ptemp = plist->next; ++ list_del_init(plist); ++ list_add_tail(plist, &free_queue->queue); ++ plist = ptemp; ++ pmlmepriv->num_of_scanned--; ++ } ++ ++ spin_unlock_bh(&free_queue->lock); ++ spin_unlock_bh(&scan_queue->lock); ++} ++ ++/* ++*rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock ++*/ ++void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue) ++{ ++ struct wlan_network *pwlan = NULL; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct sta_priv *pstapriv = &adapter->stapriv; ++ struct wlan_network *tgt_network = &pmlmepriv->cur_network; ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) { ++ struct sta_info *psta; ++ ++ psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.MacAddress); ++ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(adapter, psta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ } ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) { ++ struct sta_info *psta; ++ ++ rtw_free_all_stainfo(adapter); ++ ++ psta = rtw_get_bcmc_stainfo(adapter); ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(adapter, psta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++ rtw_init_bcmc_stainfo(adapter); ++ } ++ ++ if (lock_scanned_queue) ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress); ++ if (pwlan) ++ pwlan->fixed = false; ++ ++ if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) && (adapter->stapriv.asoc_sta_count == 1))) ++ rtw_free_network_nolock(pmlmepriv, pwlan); ++ ++ if (lock_scanned_queue) ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ pmlmepriv->key_mask = 0; ++ ++} ++ ++/* ++*rtw_indicate_connect: the caller has to lock pmlmepriv->lock ++*/ ++void rtw_indicate_connect(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ pmlmepriv->to_join = false; ++ ++ if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { ++ set_fwstate(pmlmepriv, _FW_LINKED); ++ ++ rtw_led_control(padapter, LED_CTL_LINK); ++ ++ rtw_os_indicate_connect(padapter); ++ } ++ ++ pmlmepriv->to_roaming = 0; ++ ++ rtw_set_scan_deny(padapter, 3000); ++} ++ ++/* ++*rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock ++*/ ++void rtw_indicate_disconnect(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING | WIFI_UNDER_WPS); ++ ++ if (pmlmepriv->to_roaming > 0) ++ _clr_fwstate_(pmlmepriv, _FW_LINKED); ++ ++ if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) || ++ (pmlmepriv->to_roaming <= 0)) { ++ rtw_os_indicate_disconnect(padapter); ++ ++ _clr_fwstate_(pmlmepriv, _FW_LINKED); ++ rtw_led_control(padapter, LED_CTL_NO_LINK); ++ rtw_clear_scan_deny(padapter); ++ } ++ p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1); ++ ++ rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1); ++ ++} ++ ++inline void rtw_indicate_scan_done(struct adapter *padapter, bool aborted) ++{ ++ rtw_os_indicate_scan_done(padapter, aborted); ++} ++ ++void rtw_scan_abort(struct adapter *adapter) ++{ ++ u32 start; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; ++ ++ start = jiffies; ++ pmlmeext->scan_abort = true; ++ while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) && ++ rtw_get_passing_time_ms(start) <= 200) { ++ if (adapter->bDriverStopped || adapter->bSurpriseRemoved) ++ break; ++ DBG_88E(FUNC_NDEV_FMT"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev)); ++ msleep(20); ++ } ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { ++ if (!adapter->bDriverStopped && !adapter->bSurpriseRemoved) ++ DBG_88E(FUNC_NDEV_FMT"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter->pnetdev)); ++ rtw_indicate_scan_done(adapter, true); ++ } ++ pmlmeext->scan_abort = false; ++} ++ ++static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, struct wlan_network *pnetwork) ++{ ++ int i; ++ struct sta_info *bmc_sta, *psta = NULL; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ psta = rtw_get_stainfo(pstapriv, pnetwork->network.MacAddress); ++ if (!psta) ++ psta = rtw_alloc_stainfo(pstapriv, pnetwork->network.MacAddress); ++ ++ if (psta) { /* update ptarget_sta */ ++ DBG_88E("%s\n", __func__); ++ psta->aid = pnetwork->join_res; ++ psta->mac_id = 0; ++ /* sta mode */ ++ rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true); ++ /* security related */ ++ if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { ++ padapter->securitypriv.binstallGrpkey = false; ++ padapter->securitypriv.busetkipkey = false; ++ padapter->securitypriv.bgrpkey_handshake = false; ++ psta->ieee8021x_blocked = true; ++ psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; ++ memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype)); ++ memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype)); ++ memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype)); ++ memset((u8 *)&psta->dot11txpn, 0, sizeof(union pn48)); ++ memset((u8 *)&psta->dot11rxpn, 0, sizeof(union pn48)); ++ } ++ /* Commented by Albert 2012/07/21 */ ++ /* When doing the WPS, the wps_ie_len won't equal to 0 */ ++ /* And the Wi-Fi driver shouldn't allow the data packet to be tramsmitted. */ ++ if (padapter->securitypriv.wps_ie_len != 0) { ++ psta->ieee8021x_blocked = true; ++ padapter->securitypriv.wps_ie_len = 0; ++ } ++ /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */ ++ /* if A-MPDU Rx is enabled, resetting rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */ ++ /* todo: check if AP can send A-MPDU packets */ ++ for (i = 0; i < 16; i++) { ++ /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */ ++ preorder_ctrl = &psta->recvreorder_ctrl[i]; ++ preorder_ctrl->enable = false; ++ preorder_ctrl->indicate_seq = 0xffff; ++ preorder_ctrl->wend_b = 0xffff; ++ preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */ ++ } ++ bmc_sta = rtw_get_bcmc_stainfo(padapter); ++ if (bmc_sta) { ++ for (i = 0; i < 16; i++) { ++ /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */ ++ preorder_ctrl = &bmc_sta->recvreorder_ctrl[i]; ++ preorder_ctrl->enable = false; ++ preorder_ctrl->indicate_seq = 0xffff; ++ preorder_ctrl->wend_b = 0xffff; ++ preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */ ++ } ++ } ++ /* misc. */ ++ update_sta_info(padapter, psta); ++ } ++ return psta; ++} ++ ++/* pnetwork: returns from rtw_joinbss_event_callback */ ++/* ptarget_wlan: found from scanned_queue */ ++static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network *pnetwork) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_network *cur_network = &pmlmepriv->cur_network; ++ ++ DBG_88E("%s\n", __func__); ++ ++ /* why not use ptarget_wlan?? */ ++ memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.Length); ++ /* some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */ ++ cur_network->network.IELength = ptarget_wlan->network.IELength; ++ memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0], MAX_IE_SZ); ++ ++ cur_network->aid = pnetwork->join_res; ++ ++ rtw_set_signal_stat_timer(&padapter->recvpriv); ++ padapter->recvpriv.signal_strength = ptarget_wlan->network.PhyInfo.SignalStrength; ++ padapter->recvpriv.signal_qual = ptarget_wlan->network.PhyInfo.SignalQuality; ++ /* the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) */ ++ padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.PhyInfo.SignalStrength); ++ rtw_set_signal_stat_timer(&padapter->recvpriv); ++ ++ /* update fw_state will clr _FW_UNDER_LINKING here indirectly */ ++ switch (pnetwork->network.InfrastructureMode) { ++ case Ndis802_11Infrastructure: ++ if (pmlmepriv->fw_state & WIFI_UNDER_WPS) ++ pmlmepriv->fw_state = WIFI_STATION_STATE | WIFI_UNDER_WPS; ++ else ++ pmlmepriv->fw_state = WIFI_STATION_STATE; ++ break; ++ case Ndis802_11IBSS: ++ pmlmepriv->fw_state = WIFI_ADHOC_STATE; ++ break; ++ default: ++ pmlmepriv->fw_state = WIFI_NULL_STATE; ++ break; ++ } ++ ++ rtw_update_protection(padapter, (cur_network->network.IEs) + ++ sizeof(struct ndis_802_11_fixed_ie), ++ (cur_network->network.IELength)); ++ rtw_update_ht_cap(padapter, cur_network->network.IEs, cur_network->network.IELength); ++} ++ ++/* Notes: the function could be > passive_level (the same context as Rx tasklet) */ ++/* pnetwork: returns from rtw_joinbss_event_callback */ ++/* ptarget_wlan: found from scanned_queue */ ++/* if join_res > 0, for (fw_state == WIFI_STATION_STATE), we check if "ptarget_sta" & "ptarget_wlan" exist. */ ++/* if join_res > 0, for (fw_state == WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. */ ++/* if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan != NULL). */ ++ ++void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) ++{ ++ u8 timer_cancelled; ++ struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL; ++ struct sta_priv *pstapriv = &adapter->stapriv; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct wlan_network *pnetwork = (struct wlan_network *)pbuf; ++ struct wlan_network *cur_network = &pmlmepriv->cur_network; ++ struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL; ++ unsigned int the_same_macaddr = false; ++ ++ rtw_get_encrypt_decrypt_from_registrypriv(adapter); ++ ++ the_same_macaddr = !memcmp(pnetwork->network.MacAddress, cur_network->network.MacAddress, ETH_ALEN); ++ ++ pnetwork->network.Length = get_wlan_bssid_ex_sz(&pnetwork->network); ++ if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex)) ++ return; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (pnetwork->join_res > 0) { ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { ++ /* s1. find ptarget_wlan */ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ if (the_same_macaddr) { ++ ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); ++ } else { ++ pcur_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); ++ if (pcur_wlan) ++ pcur_wlan->fixed = false; ++ ++ pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress); ++ if (pcur_sta) { ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(adapter, pcur_sta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ } ++ ++ ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress); ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ if (ptarget_wlan) ++ ptarget_wlan->fixed = true; ++ } ++ } ++ } else { ++ ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress); ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ if (ptarget_wlan) ++ ptarget_wlan->fixed = true; ++ } ++ } ++ ++ /* s2. update cur_network */ ++ if (ptarget_wlan) { ++ rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork); ++ } else { ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ goto ignore_joinbss_callback; ++ } ++ ++ /* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork); ++ if (!ptarget_sta) { ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ goto ignore_joinbss_callback; ++ } ++ } ++ ++ /* s4. indicate connect */ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ pmlmepriv->cur_network_scanned = ptarget_wlan; ++ rtw_indicate_connect(adapter); ++ } ++ ++ /* s5. Cancle assoc_timer */ ++ _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled); ++ } else { ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ goto ignore_joinbss_callback; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ } else if (pnetwork->join_res == -4) { ++ rtw_reset_securitypriv(adapter); ++ _set_timer(&pmlmepriv->assoc_timer, 1); ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ } else { /* if join_res < 0 (join fails), then try again */ ++ _set_timer(&pmlmepriv->assoc_timer, 1); ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ } ++ ++ignore_joinbss_callback: ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++void rtw_joinbss_event_callback(struct adapter *adapter, u8 *pbuf) ++{ ++ struct wlan_network *pnetwork = (struct wlan_network *)pbuf; ++ ++ mlmeext_joinbss_event_callback(adapter, pnetwork->join_res); ++ ++ rtw_os_xmit_schedule(adapter); ++ ++} ++ ++static u8 search_max_mac_id(struct adapter *padapter) ++{ ++ u8 mac_id; ++#if defined(CONFIG_88EU_AP_MODE) ++ u8 aid; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++#endif ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++#if defined(CONFIG_88EU_AP_MODE) ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ for (aid = (pstapriv->max_num_sta); aid > 0; aid--) { ++ if (pstapriv->sta_aid[aid - 1]) ++ break; ++ } ++ mac_id = aid + 1; ++ } else ++#endif ++ {/* adhoc id = 31~2 */ ++ for (mac_id = (NUM_STA - 1); mac_id >= IBSS_START_MAC_ID; mac_id--) { ++ if (pmlmeinfo->FW_sta_info[mac_id].status == 1) ++ break; ++ } ++ } ++ return mac_id; ++} ++ ++/* FOR AP , AD-HOC mode */ ++void rtw_sta_media_status_rpt(struct adapter *adapter, struct sta_info *psta, ++ u32 mstatus) ++{ ++ u16 media_status_rpt; ++ u8 macid; ++ ++ if (!psta) ++ return; ++ ++ macid = search_max_mac_id(adapter); ++ rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, (u8 *)&macid); ++ /* MACID|OPMODE:1 connect */ ++ media_status_rpt = (u16)((psta->mac_id << 8) | mstatus); ++ rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, ++ (u8 *)&media_status_rpt); ++} ++ ++void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf) ++{ ++ struct sta_info *psta; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf; ++ struct wlan_network *cur_network = &pmlmepriv->cur_network; ++ struct wlan_network *ptarget_wlan = NULL; ++ ++ if (!rtw_access_ctrl(adapter, pstassoc->macaddr)) ++ return; ++ ++#if defined(CONFIG_88EU_AP_MODE) ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr); ++ if (psta) ++ rtw_indicate_sta_assoc_event(adapter, psta); ++ return; ++ } ++#endif ++ /* for AD-HOC mode */ ++ psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr); ++ if (psta) ++ /* the sta have been in sta_info_queue => do nothing */ ++ return; /* between drv has received this event before and fw have not yet to set key to CAM_ENTRY) */ ++ psta = rtw_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr); ++ if (!psta) ++ return; ++ /* to do: init sta_info variable */ ++ psta->qos_option = 0; ++ psta->mac_id = (uint)pstassoc->cam_id; ++ DBG_88E("%s\n", __func__); ++ /* for ad-hoc mode */ ++ rtw_hal_set_odm_var(adapter, HAL_ODM_STA_INFO, psta, true); ++ rtw_sta_media_status_rpt(adapter, psta, 1); ++ if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ++ psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm; ++ psta->ieee8021x_blocked = false; ++ spin_lock_bh(&pmlmepriv->lock); ++ if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) || ++ (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))) { ++ if (adapter->stapriv.asoc_sta_count == 2) { ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); ++ pmlmepriv->cur_network_scanned = ptarget_wlan; ++ if (ptarget_wlan) ++ ptarget_wlan->fixed = true; ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ /* a sta + bc/mc_stainfo (not Ibss_stainfo) */ ++ rtw_indicate_connect(adapter); ++ } ++ } ++ spin_unlock_bh(&pmlmepriv->lock); ++ mlmeext_sta_add_event_callback(adapter, psta); ++} ++ ++void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf) ++{ ++ int mac_id = -1; ++ struct sta_info *psta; ++ struct wlan_network *pwlan = NULL; ++ struct wlan_bssid_ex *pdev_network = NULL; ++ u8 *pibss = NULL; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct stadel_event *pstadel = (struct stadel_event *)pbuf; ++ struct sta_priv *pstapriv = &adapter->stapriv; ++ struct wlan_network *tgt_network = &pmlmepriv->cur_network; ++ ++ psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr); ++ if (psta) ++ mac_id = psta->mac_id; ++ else ++ mac_id = pstadel->mac_id; ++ ++ DBG_88E("%s(mac_id=%d)=%pM\n", __func__, mac_id, pstadel->macaddr); ++ ++ if (mac_id >= 0) { ++ u16 media_status; ++ media_status = (mac_id << 8) | 0; /* MACID|OPMODE:0 means disconnect */ ++ /* for STA, AP, ADHOC mode, report disconnect stauts to FW */ ++ rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status); ++ } ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ return; ++ ++ mlmeext_sta_del_event_callback(adapter); ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ if (adapter->registrypriv.wifi_spec == 1) ++ rtw_set_roaming(adapter, 0); /* don't roam */ ++ else if (rtw_to_roaming(adapter) > 0) ++ pmlmepriv->to_roaming--; /* this stadel_event is caused by roaming, decrease to_roaming */ ++ else if (rtw_to_roaming(adapter) == 0) ++ rtw_set_roaming(adapter, ++ adapter->registrypriv.max_roaming_times); ++ ++ if (*((unsigned short *)(pstadel->rsvd)) != WLAN_REASON_EXPIRATION_CHK) ++ rtw_set_roaming(adapter, 0); /* don't roam */ ++ ++ rtw_free_uc_swdec_pending_queue(adapter); ++ ++ rtw_free_assoc_resources(adapter, 1); ++ rtw_indicate_disconnect(adapter); ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ /* remove the network entry in scanned_queue */ ++ pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress); ++ if (pwlan) { ++ pwlan->fixed = false; ++ rtw_free_network_nolock(pmlmepriv, pwlan); ++ } ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ _rtw_roaming(adapter, tgt_network); ++ } ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(adapter, psta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++ if (adapter->stapriv.asoc_sta_count == 1) { /* a sta + bc/mc_stainfo (not Ibss_stainfo) */ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ /* free old ibss network */ ++ pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress); ++ if (pwlan) { ++ pwlan->fixed = false; ++ rtw_free_network_nolock(pmlmepriv, pwlan); ++ } ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ /* re-create ibss */ ++ pdev_network = &adapter->registrypriv.dev_network; ++ pibss = adapter->registrypriv.dev_network.MacAddress; ++ ++ memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network)); ++ ++ memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); ++ memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); ++ ++ rtw_update_registrypriv_dev_network(adapter); ++ ++ rtw_generate_random_ibss(pibss); ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { ++ set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE); ++ _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE); ++ } ++ ++ rtw_createbss_cmd(adapter); ++ } ++ } ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++} ++ ++/* ++* _rtw_join_timeout_handler - Timeout/faliure handler for CMD JoinBss ++* @adapter: pointer to struct adapter structure ++*/ ++void _rtw_join_timeout_handler (struct adapter *adapter) ++{ ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ int do_join_r; ++ ++ DBG_88E("%s, fw_state=%x\n", __func__, get_fwstate(pmlmepriv)); ++ ++ if (adapter->bDriverStopped || adapter->bSurpriseRemoved) ++ return; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (rtw_to_roaming(adapter) > 0) { /* join timeout caused by roaming */ ++ while (1) { ++ pmlmepriv->to_roaming--; ++ if (rtw_to_roaming(adapter) != 0) { /* try another */ ++ DBG_88E("%s try another roaming\n", __func__); ++ do_join_r = rtw_do_join(adapter); ++ if (_SUCCESS != do_join_r) { ++ DBG_88E("%s roaming do_join return %d\n", __func__, do_join_r); ++ continue; ++ } ++ break; ++ } else { ++ DBG_88E("%s We've try roaming but fail\n", __func__); ++ rtw_indicate_disconnect(adapter); ++ break; ++ } ++ } ++ } else { ++ rtw_indicate_disconnect(adapter); ++ free_scanqueue(pmlmepriv);/* */ ++ } ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++} ++ ++/* ++* rtw_scan_timeout_handler - Timeout/Faliure handler for CMD SiteSurvey ++* @adapter: pointer to struct adapter structure ++*/ ++void rtw_scan_timeout_handler (struct adapter *adapter) ++{ ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ ++ DBG_88E(FUNC_ADPT_FMT" fw_state=%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv)); ++ spin_lock_bh(&pmlmepriv->lock); ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); ++ spin_unlock_bh(&pmlmepriv->lock); ++ rtw_indicate_scan_done(adapter, true); ++} ++ ++static void rtw_auto_scan_handler(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ /* auto site survey per 60sec */ ++ if (pmlmepriv->scan_interval > 0) { ++ pmlmepriv->scan_interval--; ++ if (pmlmepriv->scan_interval == 0) { ++ DBG_88E("%s\n", __func__); ++ rtw_set_802_11_bssid_list_scan(padapter, NULL, 0); ++ pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */ ++ } ++ } ++} ++ ++void rtw_dynamic_check_timer_handlder(struct adapter *adapter) ++{ ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct registry_priv *pregistrypriv = &adapter->registrypriv; ++ ++ if (!adapter) ++ return; ++ if (!adapter->hw_init_completed) ++ return; ++ if ((adapter->bDriverStopped) || (adapter->bSurpriseRemoved)) ++ return; ++ if (adapter->net_closed) ++ return; ++ rtw_dynamic_chk_wk_cmd(adapter); ++ ++ if (pregistrypriv->wifi_spec == 1) { ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &adapter->wdinfo; ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++#endif ++ { ++ /* auto site survey */ ++ rtw_auto_scan_handler(adapter); ++ } ++ } ++ ++ rcu_read_lock(); ++ ++ if (rcu_dereference(adapter->pnetdev->rx_handler_data) && ++ check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE)) { ++ /* expire NAT2.5 entry */ ++ nat25_db_expire(adapter); ++ ++ if (adapter->pppoe_connection_in_progress > 0) { ++ adapter->pppoe_connection_in_progress--; ++ } ++ ++ /* due to rtw_dynamic_check_timer_handlder() is called every 2 seconds */ ++ if (adapter->pppoe_connection_in_progress > 0) { ++ adapter->pppoe_connection_in_progress--; ++ } ++ } ++ ++ rcu_read_unlock(); ++} ++ ++#define RTW_SCAN_RESULT_EXPIRE 2000 ++ ++/* ++* Select a new join candidate from the original @param candidate and @param competitor ++* @return true: candidate is updated ++* @return false: candidate is not updated ++*/ ++static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv ++ , struct wlan_network **candidate, struct wlan_network *competitor) ++{ ++ int updated = false; ++ struct adapter *adapter = container_of(pmlmepriv, struct adapter, mlmepriv); ++ ++ /* check bssid, if needed */ ++ if (pmlmepriv->assoc_by_bssid) { ++ if (memcmp(competitor->network.MacAddress, pmlmepriv->assoc_bssid, ETH_ALEN)) ++ goto exit; ++ } ++ ++ /* check ssid, if needed */ ++ if (pmlmepriv->assoc_ssid.SsidLength) { ++ if (competitor->network.Ssid.SsidLength != pmlmepriv->assoc_ssid.SsidLength || ++ memcmp(competitor->network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength)) ++ goto exit; ++ } ++ ++ if (!rtw_is_desired_network(adapter, competitor)) ++ goto exit; ++ ++ if (rtw_to_roaming(adapter) > 0) { ++ if (rtw_get_passing_time_ms((u32)competitor->last_scanned) >= RTW_SCAN_RESULT_EXPIRE || ++ !is_same_ess(&competitor->network, &pmlmepriv->cur_network.network)) ++ goto exit; ++ } ++ ++ if (!*candidate || (*candidate)->network.Rssi < competitor->network.Rssi) { ++ *candidate = competitor; ++ updated = true; ++ } ++ if (updated) { ++ DBG_88E("[by_bssid:%u][assoc_ssid:%s]new candidate: %s(%pM rssi:%d\n", ++ pmlmepriv->assoc_by_bssid, ++ pmlmepriv->assoc_ssid.Ssid, ++ (*candidate)->network.Ssid.Ssid, ++ (*candidate)->network.MacAddress, ++ (int)(*candidate)->network.Rssi); ++ DBG_88E("[to_roaming:%u]\n", rtw_to_roaming(adapter)); ++ } ++ ++exit: ++ return updated; ++} ++ ++/* ++Calling context: ++The caller of the sub-routine will be in critical section... ++The caller must hold the following spinlock ++pmlmepriv->lock ++*/ ++ ++int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv) ++{ ++ int ret; ++ struct list_head *phead; ++ struct adapter *adapter; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ struct wlan_network *candidate = NULL; ++ u8 supp_ant_div = false; ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ phead = get_list_head(queue); ++ adapter = (struct adapter *)pmlmepriv->nic_hdl; ++ pmlmepriv->pscanned = phead->next; ++ while (phead != pmlmepriv->pscanned) { ++ pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list); ++ if (!pnetwork) { ++ ret = _FAIL; ++ goto exit; ++ } ++ pmlmepriv->pscanned = pmlmepriv->pscanned->next; ++ rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork); ++ } ++ if (!candidate) { ++ DBG_88E("%s: return _FAIL(candidate==NULL)\n", __func__); ++ ret = _FAIL; ++ goto exit; ++ } else { ++ DBG_88E("%s: candidate: %s(%pM ch:%u)\n", __func__, ++ candidate->network.Ssid.Ssid, candidate->network.MacAddress, ++ candidate->network.Configuration.DSConfig); ++ } ++ ++ /* check for situation of _FW_LINKED */ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ DBG_88E("%s: _FW_LINKED while ask_for_joinbss!!!\n", __func__); ++ ++ rtw_disassoc_cmd(adapter, 0, true); ++ rtw_indicate_disconnect(adapter); ++ rtw_free_assoc_resources(adapter, 0); ++ } ++ ++ rtw_hal_get_def_var(adapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(supp_ant_div)); ++ if (supp_ant_div) { ++ u8 cur_ant; ++ rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(cur_ant)); ++ DBG_88E("#### Opt_Ant_(%s), cur_Ant(%s)\n", ++ (2 == candidate->network.PhyInfo.Optimum_antenna) ? "A" : "B", ++ (2 == cur_ant) ? "A" : "B" ++ ); ++ } ++ ++ ret = rtw_joinbss_cmd(adapter, candidate); ++ ++exit: ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ return ret; ++} ++ ++int rtw_set_auth(struct adapter *adapter, struct security_priv *psecuritypriv) ++{ ++ struct cmd_obj *pcmd; ++ struct setauth_parm *psetauthparm; ++ struct cmd_priv *pcmdpriv = &adapter->cmdpriv; ++ int res = _SUCCESS; ++ ++ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!pcmd) { ++ res = _FAIL; /* try again */ ++ goto exit; ++ } ++ ++ psetauthparm = kzalloc(sizeof(struct setauth_parm), GFP_KERNEL); ++ if (!psetauthparm) { ++ kfree(pcmd); ++ res = _FAIL; ++ goto exit; ++ } ++ memset(psetauthparm, 0, sizeof(struct setauth_parm)); ++ psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm; ++ pcmd->cmdcode = _SetAuth_CMD_; ++ pcmd->parmbuf = (unsigned char *)psetauthparm; ++ pcmd->cmdsz = (sizeof(struct setauth_parm)); ++ pcmd->rsp = NULL; ++ pcmd->rspsz = 0; ++ INIT_LIST_HEAD(&pcmd->list); ++ res = rtw_enqueue_cmd(pcmdpriv, pcmd); ++exit: ++ ++ return res; ++} ++ ++int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, int keyid, u8 set_tx) ++{ ++ u8 keylen; ++ struct cmd_obj *pcmd; ++ struct setkey_parm *psetkeyparm; ++ struct cmd_priv *pcmdpriv = &adapter->cmdpriv; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ int res = _SUCCESS; ++ ++ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!pcmd) { ++ res = _FAIL; /* try again */ ++ goto exit; ++ } ++ psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL); ++ if (!psetkeyparm) { ++ kfree(pcmd); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ memset(psetkeyparm, 0, sizeof(struct setkey_parm)); ++ ++ if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ++ psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy; ++ else ++ psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm; ++ psetkeyparm->keyid = (u8)keyid;/* 0~3 */ ++ psetkeyparm->set_tx = set_tx; ++ pmlmepriv->key_mask |= BIT(psetkeyparm->keyid); ++ DBG_88E("==> rtw_set_key algorithm(%x), keyid(%x), key_mask(%x)\n", ++ psetkeyparm->algorithm, psetkeyparm->keyid, pmlmepriv->key_mask); ++ ++ switch (psetkeyparm->algorithm) { ++ case _WEP40_: ++ keylen = 5; ++ memcpy(&psetkeyparm->key[0], &psecuritypriv->dot11DefKey[keyid].skey[0], keylen); ++ break; ++ case _WEP104_: ++ keylen = 13; ++ memcpy(&psetkeyparm->key[0], &psecuritypriv->dot11DefKey[keyid].skey[0], keylen); ++ break; ++ case _TKIP_: ++ keylen = 16; ++ memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen); ++ psetkeyparm->grpkey = 1; ++ break; ++ case _AES_: ++ keylen = 16; ++ memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen); ++ psetkeyparm->grpkey = 1; ++ break; ++ default: ++ res = _FAIL; ++ goto exit; ++ } ++ pcmd->cmdcode = _SetKey_CMD_; ++ pcmd->parmbuf = (u8 *)psetkeyparm; ++ pcmd->cmdsz = (sizeof(struct setkey_parm)); ++ pcmd->rsp = NULL; ++ pcmd->rspsz = 0; ++ INIT_LIST_HEAD(&pcmd->list); ++ res = rtw_enqueue_cmd(pcmdpriv, pcmd); ++exit: ++ return res; ++} ++ ++/* adjust IEs for rtw_joinbss_cmd in WMM */ ++int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len) ++{ ++ unsigned int ielength = 0; ++ unsigned int i, j; ++ ++ i = 12; /* after the fixed IE */ ++ while (i < in_len) { ++ ielength = initial_out_len; ++ ++ if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 && in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 && in_ie[i + 5] == 0x02 && i + 5 < in_len) { ++ /* WMM element ID and OUI */ ++ /* Append WMM IE to the last index of out_ie */ ++ ++ for (j = i; j < i + 9; j++) { ++ out_ie[ielength] = in_ie[j]; ++ ielength++; ++ } ++ out_ie[initial_out_len + 1] = 0x07; ++ out_ie[initial_out_len + 6] = 0x00; ++ out_ie[initial_out_len + 8] = 0x00; ++ break; ++ } ++ i += (in_ie[i + 1] + 2); /* to the next IE element */ ++ } ++ return ielength; ++} ++ ++/* */ ++/* Ported from 8185: IsInPreAuthKeyList(). (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.) */ ++/* Added by Annie, 2006-05-07. */ ++/* */ ++/* Search by BSSID, */ ++/* Return Value: */ ++/* -1 :if there is no pre-auth key in the table */ ++/* >= 0 :if there is pre-auth key, and return the entry id */ ++/* */ ++/* */ ++ ++static int SecIsInPMKIDList(struct adapter *Adapter, u8 *bssid) ++{ ++ struct security_priv *psecuritypriv = &Adapter->securitypriv; ++ int i = 0; ++ ++ do { ++ if ((psecuritypriv->PMKIDList[i].bUsed) && ++ (!memcmp(psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN))) { ++ break; ++ } else { ++ i++; ++ /* continue; */ ++ } ++ ++ } while (i < NUM_PMKID_CACHE); ++ ++ if (i == NUM_PMKID_CACHE) { ++ i = -1;/* Could not find. */ ++ } else { ++ /* There is one Pre-Authentication Key for the specific BSSID. */ ++ } ++ return i; ++} ++ ++/* */ ++/* Check the RSN IE length */ ++/* If the RSN IE length <= 20, the RSN IE didn't include the PMKID information */ ++/* 0-11th element in the array are the fixed IE */ ++/* 12th element in the array is the IE */ ++/* 13th element in the array is the IE length */ ++/* */ ++ ++static int rtw_append_pmkid(struct adapter *Adapter, int iEntry, u8 *ie, uint ie_len) ++{ ++ struct security_priv *psecuritypriv = &Adapter->securitypriv; ++ ++ if (ie[13] <= 20) { ++ /* The RSN IE didn't include the PMK ID, append the PMK information */ ++ ie[ie_len] = 1; ++ ie_len++; ++ ie[ie_len] = 0; /* PMKID count = 0x0100 */ ++ ie_len++; ++ memcpy(&ie[ie_len], &psecuritypriv->PMKIDList[iEntry].PMKID, 16); ++ ++ ie_len += 16; ++ ie[13] += 18;/* PMKID length = 2+16 */ ++ } ++ return ie_len; ++} ++ ++int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len) ++{ ++ u8 authmode = 0; ++ uint ielength; ++ int iEntry; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct security_priv *psecuritypriv = &adapter->securitypriv; ++ uint ndisauthmode = psecuritypriv->ndisauthtype; ++ ++ /* copy fixed ie only */ ++ memcpy(out_ie, in_ie, 12); ++ ielength = 12; ++ if ((ndisauthmode == Ndis802_11AuthModeWPA) || ++ (ndisauthmode == Ndis802_11AuthModeWPAPSK)) ++ authmode = _WPA_IE_ID_; ++ if ((ndisauthmode == Ndis802_11AuthModeWPA2) || ++ (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) ++ authmode = _WPA2_IE_ID_; ++ ++ if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) { ++ memcpy(out_ie + ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len); ++ ++ ielength += psecuritypriv->wps_ie_len; ++ } else if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) { ++ /* copy RSN or SSN */ ++ memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1] + 2); ++ ielength += psecuritypriv->supplicant_ie[1] + 2; ++ rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie); ++ } ++ ++ iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid); ++ if (iEntry < 0) { ++ return ielength; ++ } else { ++ if (authmode == _WPA2_IE_ID_) ++ ielength = rtw_append_pmkid(adapter, iEntry, out_ie, ielength); ++ } ++ ++ return ielength; ++} ++ ++void rtw_init_registrypriv_dev_network(struct adapter *adapter) ++{ ++ struct registry_priv *pregistrypriv = &adapter->registrypriv; ++ struct eeprom_priv *peepriv = &adapter->eeprompriv; ++ struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; ++ u8 *myhwaddr = myid(peepriv); ++ ++ memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN); ++ ++ memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, sizeof(struct ndis_802_11_ssid)); ++ ++ pdev_network->Configuration.Length = sizeof(struct ndis_802_11_config); ++ pdev_network->Configuration.BeaconPeriod = 100; ++ pdev_network->Configuration.FHConfig.Length = 0; ++ pdev_network->Configuration.FHConfig.HopPattern = 0; ++ pdev_network->Configuration.FHConfig.HopSet = 0; ++ pdev_network->Configuration.FHConfig.DwellTime = 0; ++ ++} ++ ++void rtw_update_registrypriv_dev_network(struct adapter *adapter) ++{ ++ int sz = 0; ++ struct registry_priv *pregistrypriv = &adapter->registrypriv; ++ struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; ++ struct security_priv *psecuritypriv = &adapter->securitypriv; ++ struct wlan_network *cur_network = &adapter->mlmepriv.cur_network; ++ ++ pdev_network->Privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0); /* adhoc no 802.1x */ ++ ++ pdev_network->Rssi = 0; ++ ++ switch (pregistrypriv->wireless_mode) { ++ case WIRELESS_11B: ++ pdev_network->NetworkTypeInUse = (Ndis802_11DS); ++ break; ++ case WIRELESS_11G: ++ case WIRELESS_11BG: ++ case WIRELESS_11_24N: ++ case WIRELESS_11G_24N: ++ case WIRELESS_11BG_24N: ++ pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24); ++ break; ++ default: ++ /* TODO */ ++ break; ++ } ++ ++ pdev_network->Configuration.DSConfig = (pregistrypriv->channel); ++ ++ if (cur_network->network.InfrastructureMode == Ndis802_11IBSS) ++ pdev_network->Configuration.ATIMWindow = (0); ++ ++ pdev_network->InfrastructureMode = (cur_network->network.InfrastructureMode); ++ ++ /* 1. Supported rates */ ++ /* 2. IE */ ++ ++ sz = rtw_generate_ie(pregistrypriv); ++ pdev_network->IELength = sz; ++ pdev_network->Length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network); ++ ++ /* notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd(); */ ++ /* pdev_network->IELength = cpu_to_le32(sz); */ ++ ++} ++ ++void rtw_get_encrypt_decrypt_from_registrypriv(struct adapter *adapter) ++{ ++ ++} ++ ++/* the function is at passive_level */ ++void rtw_joinbss_reset(struct adapter *padapter) ++{ ++ u8 threshold; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ ++ /* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */ ++ pmlmepriv->num_FortyMHzIntolerant = 0; ++ ++ pmlmepriv->num_sta_no_ht = 0; ++ ++ phtpriv->ampdu_enable = false;/* reset to disabled */ ++ ++ /* TH = 1 => means that invalidate usb rx aggregation */ ++ /* TH = 0 => means that validate usb rx aggregation, use init value. */ ++ if (phtpriv->ht_option) { ++ if (padapter->registrypriv.wifi_spec == 1) ++ threshold = 1; ++ else ++ threshold = 0; ++ rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); ++ } else { ++ threshold = 1; ++ rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); ++ } ++} ++ ++/* the function is >= passive_level */ ++unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len) ++{ ++ u32 ielen, out_len; ++ enum ht_cap_ampdu_factor max_rx_ampdu_factor; ++ unsigned char *p; ++ struct ieee80211_ht_cap ht_capie; ++ unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct qos_priv *pqospriv = &pmlmepriv->qospriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ u32 rx_packet_offset, max_recvbuf_sz; ++ ++ phtpriv->ht_option = false; ++ ++ p = rtw_get_ie(in_ie + 12, _HT_CAPABILITY_IE_, &ielen, in_len - 12); ++ ++ if (p && ielen > 0) { ++ if (pqospriv->qos_option == 0) { ++ out_len = *pout_len; ++ rtw_set_ie(out_ie + out_len, _VENDOR_SPECIFIC_IE_, ++ _WMM_IE_Length_, WMM_IE, pout_len); ++ ++ pqospriv->qos_option = 1; ++ } ++ ++ out_len = *pout_len; ++ ++ memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap)); ++ ++ ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 | ++ IEEE80211_HT_CAP_SGI_20 | ++ IEEE80211_HT_CAP_SGI_40 | ++ IEEE80211_HT_CAP_TX_STBC | ++ IEEE80211_HT_CAP_DSSSCCK40); ++ ++ rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset); ++ rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz); ++ ++ /* ++ AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k ++ AMPDU_para [4:2]:Min MPDU Start Spacing ++ */ ++ ++ rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); ++ ht_capie.ampdu_params_info = (max_rx_ampdu_factor & 0x03); ++ ++ if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) ++ ht_capie.ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY & (0x07 << 2)); ++ else ++ ht_capie.ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00); ++ ++ rtw_set_ie(out_ie + out_len, _HT_CAPABILITY_IE_, ++ sizeof(struct ieee80211_ht_cap), (unsigned char *)&ht_capie, pout_len); ++ ++ phtpriv->ht_option = true; ++ ++ p = rtw_get_ie(in_ie + 12, _HT_ADD_INFO_IE_, &ielen, in_len - 12); ++ if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) { ++ out_len = *pout_len; ++ rtw_set_ie(out_ie + out_len, _HT_ADD_INFO_IE_, ielen, p + 2, pout_len); ++ } ++ } ++ return phtpriv->ht_option; ++} ++ ++/* the function is > passive_level (in critical_section) */ ++void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len) ++{ ++ u8 *p, max_ampdu_sz; ++ int len; ++ struct ieee80211_ht_cap *pht_capie; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (!phtpriv->ht_option) ++ return; ++ ++ if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable)) ++ return; ++ ++ DBG_88E("+rtw_update_ht_cap()\n"); ++ ++ /* maybe needs check if ap supports rx ampdu. */ ++ if ((!phtpriv->ampdu_enable) && (pregistrypriv->ampdu_enable == 1)) { ++ if (pregistrypriv->wifi_spec == 1) ++ phtpriv->ampdu_enable = false; ++ else ++ phtpriv->ampdu_enable = true; ++ } else if (pregistrypriv->ampdu_enable == 2) { ++ phtpriv->ampdu_enable = true; ++ } ++ ++ /* check Max Rx A-MPDU Size */ ++ len = 0; ++ p = rtw_get_ie(pie + sizeof(struct ndis_802_11_fixed_ie), _HT_CAPABILITY_IE_, &len, ie_len - sizeof(struct ndis_802_11_fixed_ie)); ++ if (p && len > 0) { ++ pht_capie = (struct ieee80211_ht_cap *)(p + 2); ++ max_ampdu_sz = (pht_capie->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_FACTOR); ++ max_ampdu_sz = 1 << (max_ampdu_sz + 3); /* max_ampdu_sz (kbytes); */ ++ phtpriv->rx_ampdu_maxlen = max_ampdu_sz; ++ } ++ len = 0; ++ p = rtw_get_ie(pie + sizeof(struct ndis_802_11_fixed_ie), _HT_ADD_INFO_IE_, &len, ie_len - sizeof(struct ndis_802_11_fixed_ie)); ++ ++ /* update cur_bwmode & cur_ch_offset */ ++ if ((pregistrypriv->cbw40_enable) && ++ (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & BIT(1)) && ++ (pmlmeinfo->HT_info.infos[0] & BIT(2))) { ++ int i; ++ u8 rf_type; ++ ++ padapter->HalFunc.GetHwRegHandler(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ ++ /* update the MCS rates */ ++ for (i = 0; i < 16; i++) { ++ if ((rf_type == RF_1T1R) || (rf_type == RF_1T2R)) ++ pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; ++ else ++ pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i]; ++ } ++ /* switch to the 40M Hz mode according to the AP */ ++ pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40; ++ switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) { ++ case HT_EXTCHNL_OFFSET_UPPER: ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; ++ break; ++ case HT_EXTCHNL_OFFSET_LOWER: ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; ++ break; ++ default: ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ break; ++ } ++ } ++ ++ /* Config SM Power Save setting */ ++ pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & 0x0C) >> 2; ++ if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) ++ DBG_88E("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__); ++ ++ /* Config current HT Protection mode. */ ++ pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3; ++} ++ ++void rtw_issue_addbareq_cmd(struct adapter *padapter, struct xmit_frame *pxmitframe) ++{ ++ u8 issued; ++ int priority; ++ struct sta_info *psta = NULL; ++ struct ht_priv *phtpriv; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ ++ if (is_multicast_ether_addr(pattrib->ra) || ++ padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod < 100) ++ return; ++ ++ priority = pattrib->priority; ++ ++ if (pattrib->psta) ++ psta = pattrib->psta; ++ else ++ psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); ++ ++ if (!psta) ++ return; ++ ++ phtpriv = &psta->htpriv; ++ ++ if ((phtpriv->ht_option) && (phtpriv->ampdu_enable)) { ++ issued = (phtpriv->agg_enable_bitmap >> priority) & 0x1; ++ issued |= (phtpriv->candidate_tid_bitmap >> priority) & 0x1; ++ ++ if (0 == issued) { ++ DBG_88E("rtw_issue_addbareq_cmd, p=%d\n", priority); ++ psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority); ++ rtw_addbareq_cmd(padapter, (u8)priority, pattrib->ra); ++ } ++ } ++} ++ ++void rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ _rtw_roaming(padapter, tgt_network); ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++void _rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ int do_join_r; ++ ++ struct wlan_network *pnetwork; ++ ++ if (tgt_network) ++ pnetwork = tgt_network; ++ else ++ pnetwork = &pmlmepriv->cur_network; ++ ++ if (0 < rtw_to_roaming(padapter)) { ++ DBG_88E("roaming from %s(%pM length:%d\n", ++ pnetwork->network.Ssid.Ssid, pnetwork->network.MacAddress, ++ pnetwork->network.Ssid.SsidLength); ++ memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.Ssid, sizeof(struct ndis_802_11_ssid)); ++ ++ pmlmepriv->assoc_by_bssid = false; ++ ++ while (1) { ++ do_join_r = rtw_do_join(padapter); ++ if (_SUCCESS == do_join_r) { ++ break; ++ } else { ++ DBG_88E("roaming do_join return %d\n", do_join_r); ++ pmlmepriv->to_roaming--; ++ ++ if (0 < pmlmepriv->to_roaming) { ++ continue; ++ } else { ++ DBG_88E("%s(%d) -to roaming fail, indicate_disconnect\n", __func__, __LINE__); ++ rtw_indicate_disconnect(padapter); ++ break; ++ } ++ } ++ } ++ } ++} +diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c +new file mode 100644 +index 000000000000..5a472a4954b0 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c +@@ -0,0 +1,8327 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_MLME_EXT_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wifi.h" ++#include "../include/rtw_mlme_ext.h" ++#include "../include/wlan_bssdef.h" ++#include "../include/mlme_osdep.h" ++#include "../include/recv_osdep.h" ++ ++static struct mlme_handler mlme_sta_tbl[] = { ++ {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq}, ++ {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp}, ++ {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq}, ++ {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp}, ++ {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq}, ++ {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp}, ++ ++ /*---------------------------------------------------------- ++ below 2 are reserved ++ -----------------------------------------------------------*/ ++ {0, "DoReserved", &DoReserved}, ++ {0, "DoReserved", &DoReserved}, ++ {WIFI_BEACON, "OnBeacon", &OnBeacon}, ++ {WIFI_ATIM, "OnATIM", &OnAtim}, ++ {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc}, ++ {WIFI_AUTH, "OnAuth", &OnAuthClient}, ++ {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth}, ++ {WIFI_ACTION, "OnAction", &OnAction}, ++}; ++ ++static struct action_handler OnAction_tbl[] = { ++ {RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct}, ++ {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos}, ++ {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls}, ++ {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back}, ++ {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public}, ++ {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved}, ++ {RTW_WLAN_CATEGORY_FT, "ACTION_FT", &DoReserved}, ++ {RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht}, ++ {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved}, ++ {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm}, ++ {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p}, ++}; ++ ++static u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; ++ ++/************************************************** ++OUI definitions for the vendor specific IE ++***************************************************/ ++unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01}; ++unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02}; ++unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04}; ++unsigned char P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09}; ++unsigned char WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A}; ++ ++unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; ++unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; ++ ++unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02}; ++unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02}; ++ ++extern unsigned char REALTEK_96B_IE[]; ++ ++/******************************************************** ++MCS rate definitions ++*********************************************************/ ++unsigned char MCS_rate_2R[16] = {0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; ++unsigned char MCS_rate_1R[16] = {0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; ++ ++/******************************************************** ++ChannelPlan definitions ++*********************************************************/ ++static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = { ++ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */ ++ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */ ++ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */ ++ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */ ++ {{10, 11, 12, 13}, 4}, /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */ ++ {{}, 0}, /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */ ++}; ++ ++static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = { ++ /* 0x00 ~ 0x1F , Old Define ===== */ ++ {0x02}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */ ++ {0x02}, /* 0x01, RT_CHANNEL_DOMAIN_IC */ ++ {0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */ ++ {0x01}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */ ++ {0x01}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */ ++ {0x03}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */ ++ {0x03}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */ ++ {0x01}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */ ++ {0x03}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */ ++ {0x03}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */ ++ {0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */ ++ {0x02}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */ ++ {0x01}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */ ++ {0x02}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */ ++ {0x02}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */ ++ {0x02}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */ ++ {0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */ ++ {0x02}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */ ++ {0x01}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */ ++ {0x02}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */ ++ {0x00}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */ ++ {0x00}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */ ++ {0x03}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */ ++ {0x05}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */ ++ {0x02}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */ ++ {0x00}, /* 0x1A, */ ++ {0x00}, /* 0x1B, */ ++ {0x00}, /* 0x1C, */ ++ {0x00}, /* 0x1D, */ ++ {0x00}, /* 0x1E, */ ++ /* 0x20 ~ 0x7F , New Define ===== */ ++ {0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */ ++ {0x01}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */ ++ {0x02}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */ ++ {0x03}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */ ++ {0x04}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */ ++ {0x02}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */ ++ {0x00}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */ ++ {0x03}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */ ++ {0x00}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */ ++ {0x00}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */ ++ {0x00}, /* 0x2A, */ ++ {0x00}, /* 0x2B, */ ++ {0x00}, /* 0x2C, */ ++ {0x00}, /* 0x2D, */ ++ {0x00}, /* 0x2E, */ ++ {0x00}, /* 0x2F, */ ++ {0x00}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */ ++ {0x00}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */ ++ {0x00}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */ ++ {0x00}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */ ++ {0x02}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */ ++ {0x00}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */ ++ {0x00}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */ ++ {0x03}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */ ++ {0x03}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */ ++ {0x02}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */ ++ {0x00}, /* 0x3A, */ ++ {0x00}, /* 0x3B, */ ++ {0x00}, /* 0x3C, */ ++ {0x00}, /* 0x3D, */ ++ {0x00}, /* 0x3E, */ ++ {0x00}, /* 0x3F, */ ++ {0x02}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */ ++ {0x03}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */ ++}; ++ ++static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03}; /* use the conbination for max channel numbers */ ++ ++/* ++ * Search the @param channel_num in given @param channel_set ++ * @ch_set: the given channel set ++ * @ch: the given channel number ++ * ++ * return the index of channel_num in channel_set, -1 if not found ++ */ ++int rtw_ch_set_search_ch(struct rt_channel_info *ch_set, const u32 ch) ++{ ++ int i; ++ for (i = 0; ch_set[i].ChannelNum != 0; i++) { ++ if (ch == ch_set[i].ChannelNum) ++ break; ++ } ++ ++ if (i >= ch_set[i].ChannelNum) ++ return -1; ++ return i; ++} ++ ++/**************************************************************************** ++ ++Following are the initialization functions for WiFi MLME ++ ++*****************************************************************************/ ++ ++int init_hw_mlme_ext(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); ++ return _SUCCESS; ++} ++ ++static void init_mlme_ext_priv_value(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ unsigned char mixed_datarate[NumRates] = { ++ _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, ++ _9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_, ++ _48M_RATE_, _54M_RATE_, 0xff ++ }; ++ unsigned char mixed_basicrate[NumRates] = { ++ _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, ++ _12M_RATE_, _24M_RATE_, 0xff, ++ }; ++ ++ atomic_set(&pmlmeext->event_seq, 0); ++ pmlmeext->mgnt_seq = 0;/* reset to zero when disconnect at client mode */ ++ ++ pmlmeext->cur_channel = padapter->registrypriv.channel; ++ pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ pmlmeext->retry = 0; ++ ++ pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode; ++ ++ memcpy(pmlmeext->datarate, mixed_datarate, NumRates); ++ memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates); ++ ++ pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB; ++ ++ pmlmeext->sitesurvey_res.state = SCAN_DISABLE; ++ pmlmeext->sitesurvey_res.channel_idx = 0; ++ pmlmeext->sitesurvey_res.bss_cnt = 0; ++ pmlmeext->scan_abort = false; ++ ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ pmlmeinfo->reauth_count = 0; ++ pmlmeinfo->reassoc_count = 0; ++ pmlmeinfo->link_count = 0; ++ pmlmeinfo->auth_seq = 0; ++ pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open; ++ pmlmeinfo->key_index = 0; ++ pmlmeinfo->iv = 0; ++ ++ pmlmeinfo->enc_algo = _NO_PRIVACY_; ++ pmlmeinfo->authModeToggle = 0; ++ ++ memset(pmlmeinfo->chg_txt, 0, 128); ++ ++ pmlmeinfo->slotTime = SHORT_SLOT_TIME; ++ pmlmeinfo->preamble_mode = PREAMBLE_AUTO; ++ ++ pmlmeinfo->dialogToken = 0; ++ ++ pmlmeext->action_public_rxseq = 0xffff; ++ pmlmeext->action_public_dialog_token = 0xff; ++} ++ ++static int has_channel(struct rt_channel_info *channel_set, ++ u8 chanset_size, ++ u8 chan) { ++ int i; ++ ++ for (i = 0; i < chanset_size; i++) { ++ if (channel_set[i].ChannelNum == chan) ++ return 1; ++ } ++ return 0; ++} ++ ++static void init_channel_list(struct adapter *padapter, struct rt_channel_info *channel_set, ++ u8 chanset_size, ++ struct p2p_channels *channel_list) { ++ struct p2p_oper_class_map op_class[] = { ++ { IEEE80211G, 81, 1, 13, 1, BW20 }, ++ { IEEE80211G, 82, 14, 14, 1, BW20 }, ++ { -1, 0, 0, 0, 0, BW20 } ++ }; ++ ++ int cla, op; ++ ++ cla = 0; ++ ++ for (op = 0; op_class[op].op_class; op++) { ++ u8 ch; ++ struct p2p_oper_class_map *o = &op_class[op]; ++ struct p2p_reg_class *reg = NULL; ++ ++ for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) { ++ if (!has_channel(channel_set, chanset_size, ch)) { ++ continue; ++ } ++ ++ if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc)) ++ continue; ++ ++ if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) && ++ ((BW40MINUS == o->bw) || (BW40PLUS == o->bw))) ++ continue; ++ ++ if (!reg) { ++ reg = &channel_list->reg_class[cla]; ++ cla++; ++ reg->reg_class = o->op_class; ++ reg->channels = 0; ++ } ++ reg->channel[reg->channels] = ch; ++ reg->channels++; ++ } ++ } ++ channel_list->reg_classes = cla; ++} ++ ++static u8 init_channel_set(struct adapter *padapter, u8 ChannelPlan, struct rt_channel_info *channel_set) ++{ ++ u8 index, chanset_size = 0; ++ u8 b2_4GBand = false; ++ u8 Index2G = 0; ++ ++ memset(channel_set, 0, sizeof(struct rt_channel_info) * MAX_CHANNEL_NUM); ++ ++ if (ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) { ++ DBG_88E("ChannelPlan ID %x error !!!!!\n", ChannelPlan); ++ return chanset_size; ++ } ++ ++ if (padapter->registrypriv.wireless_mode & WIRELESS_11G) { ++ b2_4GBand = true; ++ if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan) ++ Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G; ++ else ++ Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G; ++ } ++ ++ if (b2_4GBand) { ++ for (index = 0; index < RTW_ChannelPlan2G[Index2G].Len; index++) { ++ channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index]; ++ ++ if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) ||/* Channel 1~11 is active, and 12~14 is passive */ ++ (RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G == ChannelPlan)) { ++ if (channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11) ++ channel_set[chanset_size].ScanType = SCAN_ACTIVE; ++ else if ((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14)) ++ channel_set[chanset_size].ScanType = SCAN_PASSIVE; ++ } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan || ++ RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) {/* channel 12~13, passive scan */ ++ if (channel_set[chanset_size].ChannelNum <= 11) ++ channel_set[chanset_size].ScanType = SCAN_ACTIVE; ++ else ++ channel_set[chanset_size].ScanType = SCAN_PASSIVE; ++ } else { ++ channel_set[chanset_size].ScanType = SCAN_ACTIVE; ++ } ++ ++ chanset_size++; ++ } ++ } ++ return chanset_size; ++} ++ ++int init_mlme_ext_priv(struct adapter *padapter) ++{ ++ int res = _SUCCESS; ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ pmlmeext->padapter = padapter; ++ ++ init_mlme_ext_priv_value(padapter); ++ pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq; ++ ++ init_mlme_ext_timer(padapter); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ init_mlme_ap_info(padapter); ++#endif ++ ++ pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan, pmlmeext->channel_set); ++ init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list); ++ ++ pmlmeext->chan_scan_time = SURVEY_TO; ++ pmlmeext->mlmeext_init = true; ++ ++ pmlmeext->active_keep_alive_check = true; ++ ++ return res; ++} ++ ++void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext) ++{ ++ struct adapter *padapter = pmlmeext->padapter; ++ ++ if (!padapter) ++ return; ++ ++ if (padapter->bDriverStopped) { ++ _cancel_timer_ex(&pmlmeext->survey_timer); ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ /* _cancel_timer_ex(&pmlmeext->ADDBA_timer); */ ++ } ++} ++ ++static void _mgt_dispatcher(struct adapter *padapter, struct mlme_handler *ptable, struct recv_frame *precv_frame) ++{ ++ u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ u8 *pframe = precv_frame->rx_data; ++ ++ if (ptable->func) { ++ /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ ++ if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) && ++ memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) ++ return; ++ ptable->func(padapter, precv_frame); ++ } ++} ++ ++void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ int index; ++ struct mlme_handler *ptable; ++#ifdef CONFIG_88EU_AP_MODE ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++#endif /* CONFIG_88EU_AP_MODE */ ++ u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ u8 *pframe = precv_frame->rx_data; ++ struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe)); ++ ++ if (GetFrameType(pframe) != WIFI_MGT_TYPE) ++ return; ++ ++ /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ ++ if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) && ++ memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) ++ return; ++ ++ ptable = mlme_sta_tbl; ++ ++ index = GetFrameSubType(pframe) >> 4; ++ ++ if (index > 13) ++ return; ++ ptable += index; ++ ++ if (psta) { ++ if (GetRetry(pframe)) { ++ if (precv_frame->attrib.seq_num == psta->RxMgmtFrameSeqNum) { ++ /* drop the duplicate management frame */ ++ DBG_88E("Drop duplicate management frame with seq_num=%d.\n", precv_frame->attrib.seq_num); ++ return; ++ } ++ } ++ psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num; ++ } ++ ++#ifdef CONFIG_88EU_AP_MODE ++ switch (GetFrameSubType(pframe)) { ++ case WIFI_AUTH: ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ ptable->func = &OnAuth; ++ else ++ ptable->func = &OnAuthClient; ++ fallthrough; ++ case WIFI_ASSOCREQ: ++ case WIFI_REASSOCREQ: ++ _mgt_dispatcher(padapter, ptable, precv_frame); ++ break; ++ case WIFI_PROBEREQ: ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ _mgt_dispatcher(padapter, ptable, precv_frame); ++ else ++ _mgt_dispatcher(padapter, ptable, precv_frame); ++ break; ++ case WIFI_BEACON: ++ _mgt_dispatcher(padapter, ptable, precv_frame); ++ break; ++ case WIFI_ACTION: ++ _mgt_dispatcher(padapter, ptable, precv_frame); ++ break; ++ default: ++ _mgt_dispatcher(padapter, ptable, precv_frame); ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ rtw_hostapd_mlme_rx(padapter, precv_frame); ++ break; ++ } ++#else ++ _mgt_dispatcher(padapter, ptable, precv_frame); ++#endif ++} ++ ++#ifdef CONFIG_88EU_P2P ++static u32 p2p_listen_state_process(struct adapter *padapter, unsigned char *da) ++{ ++ bool response = true; ++ ++ /* do nothing if the device name is empty */ ++ if (!padapter->wdinfo.device_name_len) ++ response = false; ++ ++ if (response) ++ issue_probersp_p2p(padapter, da); ++ ++ return _SUCCESS; ++} ++#endif /* CONFIG_88EU_P2P */ ++ ++/**************************************************************************** ++ ++Following are the callback functions for each subtype of the management frames ++ ++*****************************************************************************/ ++ ++unsigned int OnProbeReq(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ unsigned int ielen; ++ unsigned char *p; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur = &pmlmeinfo->network; ++ u8 *pframe = precv_frame->rx_data; ++ uint len = precv_frame->len; ++ u8 is_valid_p2p_probereq = false; ++ ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 wifi_test_chk_rate = 1; ++ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && ++ !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) && ++ !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && ++ !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) && ++ !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)) { ++ /* mcs_rate = 0 -> CCK 1M rate */ ++ /* mcs_rate = 1 -> CCK 2M rate */ ++ /* mcs_rate = 2 -> CCK 5.5M rate */ ++ /* mcs_rate = 3 -> CCK 11M rate */ ++ /* In the P2P mode, the driver should not support the CCK rate */ ++ ++ /* Commented by Kurt 2012/10/16 */ ++ /* IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client */ ++ if (wifi_test_chk_rate == 1) { ++ is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len); ++ if (is_valid_p2p_probereq) { ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) { ++ /* FIXME */ ++ report_survey_event(padapter, precv_frame); ++ p2p_listen_state_process(padapter, get_sa(pframe)); ++ ++ return _SUCCESS; ++ } ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) ++ goto _continue; ++ } ++ } ++ } ++ ++_continue: ++#endif /* CONFIG_88EU_P2P */ ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) ++ return _SUCCESS; ++ ++ if (!check_fwstate(pmlmepriv, _FW_LINKED) && ++ !check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) ++ return _SUCCESS; ++ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen, ++ len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); ++ ++ /* check (wildcard) SSID */ ++ if (p) { ++ if (is_valid_p2p_probereq) ++ goto _issue_probersp; ++ ++ if ((ielen != 0 && memcmp((void *)(p + 2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength)) || ++ (ielen == 0 && pmlmeinfo->hidden_ssid_mode)) ++ return _SUCCESS; ++ ++_issue_probersp: ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED) && ++ (pmlmepriv->cur_network.join_res || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) ++ issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq); ++ } ++ return _SUCCESS; ++} ++ ++unsigned int OnProbeRsp(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 *pframe = precv_frame->rx_data; ++#endif ++ ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) { ++ if (pwdinfo->tx_prov_disc_info.benable) { ++ if (!memcmp(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN)) { ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) { ++ pwdinfo->tx_prov_disc_info.benable = false; ++ issue_p2p_provision_request(padapter, ++ pwdinfo->tx_prov_disc_info.ssid.Ssid, ++ pwdinfo->tx_prov_disc_info.ssid.SsidLength, ++ pwdinfo->tx_prov_disc_info.peerDevAddr); ++ } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ pwdinfo->tx_prov_disc_info.benable = false; ++ issue_p2p_provision_request(padapter, NULL, 0, ++ pwdinfo->tx_prov_disc_info.peerDevAddr); ++ } ++ } ++ } ++ return _SUCCESS; ++ } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) { ++ if (pwdinfo->nego_req_info.benable) { ++ DBG_88E("[%s] P2P State is GONEGO ING!\n", __func__); ++ if (!memcmp(pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN)) { ++ pwdinfo->nego_req_info.benable = false; ++ issue_p2p_GO_request(padapter, pwdinfo->nego_req_info.peerDevAddr); ++ } ++ } ++ } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) { ++ if (pwdinfo->invitereq_info.benable) { ++ DBG_88E("[%s] P2P_STATE_TX_INVITE_REQ!\n", __func__); ++ if (!memcmp(pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN)) { ++ pwdinfo->invitereq_info.benable = false; ++ issue_p2p_invitation_request(padapter, pwdinfo->invitereq_info.peer_macaddr); ++ } ++ } ++ } ++#endif ++ ++ if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { ++ report_survey_event(padapter, precv_frame); ++ return _SUCCESS; ++ } ++ ++ return _SUCCESS; ++} ++ ++unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ int cam_idx; ++ struct sta_info *psta; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 *pframe = precv_frame->rx_data; ++ uint len = precv_frame->len; ++ struct wlan_bssid_ex *pbss; ++ int ret = _SUCCESS; ++ ++ if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { ++ report_survey_event(padapter, precv_frame); ++ return _SUCCESS; ++ } ++ ++ if (!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) { ++ if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) { ++ /* we should update current network before auth, or some IE is wrong */ ++ pbss = kmalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC); ++ if (pbss) { ++ if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) { ++ update_network(&pmlmepriv->cur_network.network, pbss, padapter, true); ++ rtw_get_bcn_info(&pmlmepriv->cur_network); ++ } ++ kfree(pbss); ++ } ++ ++ /* check the vendor of the assoc AP */ ++ pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe + sizeof(struct rtw_ieee80211_hdr_3addr), len - sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ /* update TSF Value */ ++ update_TSF(pmlmeext, pframe, len); ++ ++ /* start auth */ ++ start_clnt_auth(padapter); ++ ++ return _SUCCESS; ++ } ++ ++ if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) { ++ psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); ++ if (psta) { ++ ret = rtw_check_bcn_info(padapter, pframe, len); ++ if (!ret) { ++ DBG_88E_LEVEL(_drv_info_, "ap has changed, disconnect now\n "); ++ receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0); ++ return _SUCCESS; ++ } ++ /* update WMM, ERP in the beacon */ ++ /* todo: the timer is used instead of the number of the beacon received */ ++ if ((sta_rx_pkts(psta) & 0xf) == 0) ++ update_beacon_info(padapter, pframe, len, psta); ++ process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)); ++ } ++ } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { ++ psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); ++ if (psta) { ++ /* update WMM, ERP in the beacon */ ++ /* todo: the timer is used instead of the number of the beacon received */ ++ if ((sta_rx_pkts(psta) & 0xf) == 0) ++ update_beacon_info(padapter, pframe, len, psta); ++ } else { ++ /* allocate a new CAM entry for IBSS station */ ++ cam_idx = allocate_fw_sta_entry(padapter); ++ if (cam_idx == NUM_STA) ++ goto _END_ONBEACON_; ++ ++ /* get supported rate */ ++ if (update_sta_support_rate(padapter, (pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_), (len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_), cam_idx) == _FAIL) { ++ pmlmeinfo->FW_sta_info[cam_idx].status = 0; ++ goto _END_ONBEACON_; ++ } ++ ++ /* update TSF Value */ ++ update_TSF(pmlmeext, pframe, len); ++ ++ /* report sta add event */ ++ report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx); ++ } ++ } ++ } ++ ++_END_ONBEACON_: ++ ++ return _SUCCESS; ++} ++ ++unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++#ifdef CONFIG_88EU_AP_MODE ++ unsigned int auth_mode, ie_len; ++ u16 seq; ++ unsigned char *sa, *p; ++ u16 algorithm; ++ int status; ++ static struct sta_info stat; ++ struct sta_info *pstat = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 *pframe = precv_frame->rx_data; ++ uint len = precv_frame->len; ++ ++ if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) ++ return _FAIL; ++ ++ DBG_88E("+OnAuth\n"); ++ ++ sa = GetAddr2Ptr(pframe); ++ ++ auth_mode = psecuritypriv->dot11AuthAlgrthm; ++ seq = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + 2)); ++ algorithm = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN)); ++ ++ DBG_88E("auth alg=%x, seq=%X\n", algorithm, seq); ++ ++ if (auth_mode == 2 && psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ && ++ psecuritypriv->dot11PrivacyAlgrthm != _WEP104_) ++ auth_mode = 0; ++ ++ if ((algorithm > 0 && auth_mode == 0) || /* rx a shared-key auth but shared not enabled */ ++ (algorithm == 0 && auth_mode == 1)) { /* rx a open-system auth but shared-key is enabled */ ++ DBG_88E("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n", ++ algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]); ++ ++ status = _STATS_NO_SUPP_ALG_; ++ ++ goto auth_fail; ++ } ++ ++ if (!rtw_access_ctrl(padapter, sa)) { ++ status = _STATS_UNABLE_HANDLE_STA_; ++ goto auth_fail; ++ } ++ ++ pstat = rtw_get_stainfo(pstapriv, sa); ++ if (!pstat) { ++ /* allocate a new one */ ++ DBG_88E("going to alloc stainfo for sa=%pM\n", sa); ++ pstat = rtw_alloc_stainfo(pstapriv, sa); ++ if (!pstat) { ++ DBG_88E(" Exceed the upper limit of supported clients...\n"); ++ status = _STATS_UNABLE_HANDLE_STA_; ++ goto auth_fail; ++ } ++ ++ pstat->state = WIFI_FW_AUTH_NULL; ++ pstat->auth_seq = 0; ++ } else { ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ if (!list_empty(&pstat->asoc_list)) { ++ list_del_init(&pstat->asoc_list); ++ pstapriv->asoc_list_cnt--; ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ if (seq == 1) { ++ /* TODO: STA re_auth and auth timeout */ ++ } ++ } ++ ++ spin_lock_bh(&pstapriv->auth_list_lock); ++ if (list_empty(&pstat->auth_list)) { ++ list_add_tail(&pstat->auth_list, &pstapriv->auth_list); ++ pstapriv->auth_list_cnt++; ++ } ++ spin_unlock_bh(&pstapriv->auth_list_lock); ++ ++ if (pstat->auth_seq == 0) ++ pstat->expire_to = pstapriv->auth_to; ++ ++ if ((pstat->auth_seq + 1) != seq) { ++ DBG_88E("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n", ++ seq, pstat->auth_seq + 1); ++ status = _STATS_OUT_OF_AUTH_SEQ_; ++ goto auth_fail; ++ } ++ ++ if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2)) { ++ if (seq == 1) { ++ pstat->state &= ~WIFI_FW_AUTH_NULL; ++ pstat->state |= WIFI_FW_AUTH_SUCCESS; ++ pstat->expire_to = pstapriv->assoc_to; ++ pstat->authalg = algorithm; ++ } else { ++ DBG_88E("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n", ++ seq, pstat->auth_seq + 1); ++ status = _STATS_OUT_OF_AUTH_SEQ_; ++ goto auth_fail; ++ } ++ } else { /* shared system or auto authentication */ ++ if (seq == 1) { ++ /* prepare for the challenging txt... */ ++ ++ pstat->state &= ~WIFI_FW_AUTH_NULL; ++ pstat->state |= WIFI_FW_AUTH_STATE; ++ pstat->authalg = algorithm; ++ pstat->auth_seq = 2; ++ } else if (seq == 3) { ++ /* checking for challenging txt... */ ++ DBG_88E("checking for challenging txt...\n"); ++ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&ie_len, ++ len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4); ++ ++ if (!p || ie_len <= 0) { ++ DBG_88E("auth rejected because challenge failure!(1)\n"); ++ status = _STATS_CHALLENGE_FAIL_; ++ goto auth_fail; ++ } ++ ++ if (!memcmp((void *)(p + 2), pstat->chg_txt, 128)) { ++ pstat->state &= (~WIFI_FW_AUTH_STATE); ++ pstat->state |= WIFI_FW_AUTH_SUCCESS; ++ /* challenging txt is correct... */ ++ pstat->expire_to = pstapriv->assoc_to; ++ } else { ++ DBG_88E("auth rejected because challenge failure!\n"); ++ status = _STATS_CHALLENGE_FAIL_; ++ goto auth_fail; ++ } ++ } else { ++ DBG_88E("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n", ++ seq, pstat->auth_seq + 1); ++ status = _STATS_OUT_OF_AUTH_SEQ_; ++ goto auth_fail; ++ } ++ } ++ ++ /* Now, we are going to issue_auth... */ ++ pstat->auth_seq = seq + 1; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_)); ++#endif ++ ++ if (pstat->state & WIFI_FW_AUTH_SUCCESS) ++ pstat->auth_seq = 0; ++ ++ return _SUCCESS; ++ ++auth_fail: ++ ++ if (pstat) ++ rtw_free_stainfo(padapter, pstat); ++ ++ pstat = &stat; ++ memset((char *)pstat, '\0', sizeof(stat)); ++ pstat->auth_seq = 2; ++ memcpy(pstat->hwaddr, sa, 6); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ issue_auth(padapter, pstat, (unsigned short)status); ++#endif ++ ++#endif ++ return _FAIL; ++} ++ ++unsigned int OnAuthClient(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ unsigned int seq, len, status, offset; ++ unsigned char *p; ++ unsigned int go2asoc = 0; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 *pframe = precv_frame->rx_data; ++ uint pkt_len = precv_frame->len; ++ ++ DBG_88E("%s\n", __func__); ++ ++ /* check A1 matches or not */ ++ if (memcmp(myid(&padapter->eeprompriv), get_da(pframe), ETH_ALEN)) ++ return _SUCCESS; ++ ++ if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE)) ++ return _SUCCESS; ++ ++ offset = (GetPrivacy(pframe)) ? 4 : 0; ++ ++ seq = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + offset + 2)); ++ status = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + offset + 4)); ++ ++ if (status != 0) { ++ DBG_88E("clnt auth fail, status: %d\n", status); ++ if (status == 13) { /* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */ ++ if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ++ pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open; ++ else ++ pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; ++ } ++ ++ set_link_timer(pmlmeext, 1); ++ goto authclnt_fail; ++ } ++ ++ if (seq == 2) { ++ if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) { ++ /* legendary shared system */ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len, ++ pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_); ++ ++ if (!p) ++ goto authclnt_fail; ++ ++ memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len); ++ pmlmeinfo->auth_seq = 3; ++ issue_auth(padapter, NULL, 0); ++ set_link_timer(pmlmeext, REAUTH_TO); ++ ++ return _SUCCESS; ++ } else { ++ /* open system */ ++ go2asoc = 1; ++ } ++ } else if (seq == 4) { ++ if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ++ go2asoc = 1; ++ else ++ goto authclnt_fail; ++ } else { ++ /* this is also illegal */ ++ goto authclnt_fail; ++ } ++ ++ if (go2asoc) { ++ DBG_88E_LEVEL(_drv_info_, "auth success, start assoc\n"); ++ start_clnt_assoc(padapter); ++ return _SUCCESS; ++ } ++authclnt_fail: ++ return _FAIL; ++} ++ ++unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++#ifdef CONFIG_88EU_AP_MODE ++ u16 capab_info; ++ struct rtw_ieee802_11_elems elems; ++ struct sta_info *pstat; ++ unsigned char reassoc, *p, *pos, *wpa_ie; ++ unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; ++ int i, ie_len, wpa_ie_len, left; ++ unsigned char supportRate[16]; ++ int supportRateNum; ++ unsigned short status = _STATS_SUCCESSFUL_; ++ unsigned short frame_type, ie_offset = 0; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur = &pmlmeinfo->network; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 *pframe = precv_frame->rx_data; ++ uint pkt_len = precv_frame->len; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 p2p_status_code = P2P_STATUS_SUCCESS; ++ u8 *p2pie; ++ u32 p2pielen = 0; ++#endif /* CONFIG_88EU_P2P */ ++ ++ if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) ++ return _FAIL; ++ ++ frame_type = GetFrameSubType(pframe); ++ if (frame_type == WIFI_ASSOCREQ) { ++ reassoc = 0; ++ ie_offset = _ASOCREQ_IE_OFFSET_; ++ } else { /* WIFI_REASSOCREQ */ ++ reassoc = 1; ++ ie_offset = _REASOCREQ_IE_OFFSET_; ++ } ++ ++ if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) { ++ DBG_88E("handle_assoc(reassoc=%d) - too short payload (len=%lu)" ++ "\n", reassoc, (unsigned long)pkt_len); ++ return _FAIL; ++ } ++ ++ pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); ++ if (pstat == (struct sta_info *)NULL) { ++ status = _RSON_CLS2_; ++ goto asoc_class2_error; ++ } ++ ++ capab_info = get_unaligned_le16(pframe + WLAN_HDR_A3_LEN); ++ ++ left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset); ++ pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset); ++ ++ DBG_88E("%s\n", __func__); ++ ++ /* check if this stat has been successfully authenticated/assocated */ ++ if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) { ++ if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) { ++ status = _RSON_CLS2_; ++ goto asoc_class2_error; ++ } else { ++ pstat->state &= (~WIFI_FW_ASSOC_SUCCESS); ++ pstat->state |= WIFI_FW_ASSOC_STATE; ++ } ++ } else { ++ pstat->state &= (~WIFI_FW_AUTH_SUCCESS); ++ pstat->state |= WIFI_FW_ASSOC_STATE; ++ } ++ pstat->capability = capab_info; ++ /* now parse all ieee802_11 ie to point to elems */ ++ if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed || ++ !elems.ssid) { ++ DBG_88E("STA %pM sent invalid association request\n", ++ pstat->hwaddr); ++ status = _STATS_FAILURE_; ++ goto OnAssocReqFail; ++ } ++ ++ /* now we should check all the fields... */ ++ /* checking SSID */ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len, ++ pkt_len - WLAN_HDR_A3_LEN - ie_offset); ++ if (!p) ++ status = _STATS_FAILURE_; ++ ++ if (ie_len == 0) { /* broadcast ssid, however it is not allowed in assocreq */ ++ status = _STATS_FAILURE_; ++ } else { ++ /* check if ssid match */ ++ if (memcmp((void *)(p + 2), cur->Ssid.Ssid, cur->Ssid.SsidLength)) ++ status = _STATS_FAILURE_; ++ ++ if (ie_len != cur->Ssid.SsidLength) ++ status = _STATS_FAILURE_; ++ } ++ ++ if (_STATS_SUCCESSFUL_ != status) ++ goto OnAssocReqFail; ++ ++ /* check if the supported rate is ok */ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset); ++ if (!p) { ++ DBG_88E("Rx a sta assoc-req which supported rate is empty!\n"); ++ /* use our own rate set as statoin used */ ++ /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */ ++ /* supportRateNum = AP_BSSRATE_LEN; */ ++ ++ status = _STATS_FAILURE_; ++ goto OnAssocReqFail; ++ } else { ++ memcpy(supportRate, p + 2, ie_len); ++ supportRateNum = ie_len; ++ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_, &ie_len, ++ pkt_len - WLAN_HDR_A3_LEN - ie_offset); ++ if (p) { ++ if (supportRateNum <= sizeof(supportRate)) { ++ memcpy(supportRate + supportRateNum, p + 2, ie_len); ++ supportRateNum += ie_len; ++ } ++ } ++ } ++ ++ /* todo: mask supportRate between AP & STA -> move to update raid */ ++ /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */ ++ ++ /* update station supportRate */ ++ pstat->bssratelen = supportRateNum; ++ memcpy(pstat->bssrateset, supportRate, supportRateNum); ++ UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen); ++ ++ /* check RSN/WPA/WPS */ ++ pstat->dot8021xalg = 0; ++ pstat->wpa_psk = 0; ++ pstat->wpa_group_cipher = 0; ++ pstat->wpa2_group_cipher = 0; ++ pstat->wpa_pairwise_cipher = 0; ++ pstat->wpa2_pairwise_cipher = 0; ++ memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie)); ++ if ((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) { ++ int group_cipher = 0, pairwise_cipher = 0; ++ ++ wpa_ie = elems.rsn_ie; ++ wpa_ie_len = elems.rsn_ie_len; ++ ++ if (rtw_parse_wpa2_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { ++ pstat->dot8021xalg = 1;/* psk, todo:802.1x */ ++ pstat->wpa_psk |= BIT(1); ++ ++ pstat->wpa2_group_cipher = group_cipher & psecuritypriv->wpa2_group_cipher; ++ pstat->wpa2_pairwise_cipher = pairwise_cipher & psecuritypriv->wpa2_pairwise_cipher; ++ ++ if (!pstat->wpa2_group_cipher) ++ status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; ++ ++ if (!pstat->wpa2_pairwise_cipher) ++ status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; ++ } else { ++ status = WLAN_STATUS_INVALID_IE; ++ } ++ } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) { ++ int group_cipher = 0, pairwise_cipher = 0; ++ ++ wpa_ie = elems.wpa_ie; ++ wpa_ie_len = elems.wpa_ie_len; ++ ++ if (rtw_parse_wpa_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { ++ pstat->dot8021xalg = 1;/* psk, todo:802.1x */ ++ pstat->wpa_psk |= BIT(0); ++ ++ pstat->wpa_group_cipher = group_cipher & psecuritypriv->wpa_group_cipher; ++ pstat->wpa_pairwise_cipher = pairwise_cipher & psecuritypriv->wpa_pairwise_cipher; ++ ++ if (!pstat->wpa_group_cipher) ++ status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; ++ ++ if (!pstat->wpa_pairwise_cipher) ++ status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; ++ } else { ++ status = WLAN_STATUS_INVALID_IE; ++ } ++ } else { ++ wpa_ie = NULL; ++ wpa_ie_len = 0; ++ } ++ ++ if (_STATS_SUCCESSFUL_ != status) ++ goto OnAssocReqFail; ++ ++ pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); ++ if (!wpa_ie) { ++ if (elems.wps_ie) { ++ DBG_88E("STA included WPS IE in " ++ "(Re)Association Request - assume WPS is " ++ "used\n"); ++ pstat->flags |= WLAN_STA_WPS; ++ /* wpabuf_free(sta->wps_ie); */ ++ /* sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4, */ ++ /* elems.wps_ie_len - 4); */ ++ } else { ++ DBG_88E("STA did not include WPA/RSN IE " ++ "in (Re)Association Request - possible WPS " ++ "use\n"); ++ pstat->flags |= WLAN_STA_MAYBE_WPS; ++ } ++ ++ /* AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */ ++ /* that the selected registrar of AP is _FLASE */ ++ if ((psecuritypriv->wpa_psk > 0) && (pstat->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) { ++ if (pmlmepriv->wps_beacon_ie) { ++ u8 selected_registrar = 0; ++ ++ rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR, &selected_registrar, NULL); ++ ++ if (!selected_registrar) { ++ DBG_88E("selected_registrar is false , or AP is not ready to do WPS\n"); ++ ++ status = _STATS_UNABLE_HANDLE_STA_; ++ ++ goto OnAssocReqFail; ++ } ++ } ++ } ++ } else { ++ int copy_len; ++ ++ if (psecuritypriv->wpa_psk == 0) { ++ DBG_88E("STA %pM: WPA/RSN IE in association " ++ "request, but AP don't support WPA/RSN\n", pstat->hwaddr); ++ ++ status = WLAN_STATUS_INVALID_IE; ++ ++ goto OnAssocReqFail; ++ } ++ ++ if (elems.wps_ie) { ++ DBG_88E("STA included WPS IE in " ++ "(Re)Association Request - WPS is " ++ "used\n"); ++ pstat->flags |= WLAN_STA_WPS; ++ copy_len = 0; ++ } else { ++ copy_len = ((wpa_ie_len + 2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)) : (wpa_ie_len + 2); ++ } ++ if (copy_len > 0) ++ memcpy(pstat->wpa_ie, wpa_ie - 2, copy_len); ++ } ++ /* check if there is WMM IE & support WWM-PS */ ++ pstat->flags &= ~WLAN_STA_WME; ++ pstat->qos_option = 0; ++ pstat->qos_info = 0; ++ pstat->has_legacy_ac = true; ++ pstat->uapsd_vo = 0; ++ pstat->uapsd_vi = 0; ++ pstat->uapsd_be = 0; ++ pstat->uapsd_bk = 0; ++ if (pmlmepriv->qospriv.qos_option) { ++ p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0; ++ for (;;) { ++ p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset); ++ if (p) { ++ if (!memcmp(p + 2, WMM_IE, 6)) { ++ pstat->flags |= WLAN_STA_WME; ++ ++ pstat->qos_option = 1; ++ pstat->qos_info = *(p + 8); ++ ++ pstat->max_sp_len = (pstat->qos_info >> 5) & 0x3; ++ ++ if ((pstat->qos_info & 0xf) != 0xf) ++ pstat->has_legacy_ac = true; ++ else ++ pstat->has_legacy_ac = false; ++ ++ if (pstat->qos_info & 0xf) { ++ if (pstat->qos_info & BIT(0)) ++ pstat->uapsd_vo = BIT(0) | BIT(1); ++ else ++ pstat->uapsd_vo = 0; ++ ++ if (pstat->qos_info & BIT(1)) ++ pstat->uapsd_vi = BIT(0) | BIT(1); ++ else ++ pstat->uapsd_vi = 0; ++ ++ if (pstat->qos_info & BIT(2)) ++ pstat->uapsd_bk = BIT(0) | BIT(1); ++ else ++ pstat->uapsd_bk = 0; ++ ++ if (pstat->qos_info & BIT(3)) ++ pstat->uapsd_be = BIT(0) | BIT(1); ++ else ++ pstat->uapsd_be = 0; ++ } ++ break; ++ } ++ } else { ++ break; ++ } ++ p = p + ie_len + 2; ++ } ++ } ++ ++ /* save HT capabilities in the sta object */ ++ memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap)); ++ if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct ieee80211_ht_cap)) { ++ pstat->flags |= WLAN_STA_HT; ++ ++ pstat->flags |= WLAN_STA_WME; ++ ++ memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct ieee80211_ht_cap)); ++ } else { ++ pstat->flags &= ~WLAN_STA_HT; ++ } ++ if ((!pmlmepriv->htpriv.ht_option) && (pstat->flags & WLAN_STA_HT)) { ++ status = _STATS_FAILURE_; ++ goto OnAssocReqFail; ++ } ++ ++ if ((pstat->flags & WLAN_STA_HT) && ++ ((pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) || ++ (pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP))) { ++ DBG_88E("HT: %pM tried to " ++ "use TKIP with HT association\n", pstat->hwaddr); ++ ++ /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */ ++ /* goto OnAssocReqFail; */ ++ } ++ ++ pstat->flags |= WLAN_STA_NONERP; ++ for (i = 0; i < pstat->bssratelen; i++) { ++ if ((pstat->bssrateset[i] & 0x7f) > 22) { ++ pstat->flags &= ~WLAN_STA_NONERP; ++ break; ++ } ++ } ++ ++ if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) ++ pstat->flags |= WLAN_STA_SHORT_PREAMBLE; ++ else ++ pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE; ++ ++ if (status != _STATS_SUCCESSFUL_) ++ goto OnAssocReqFail; ++ ++#ifdef CONFIG_88EU_P2P ++ pstat->is_p2p_device = false; ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, NULL, &p2pielen); ++ if (p2pie) { ++ pstat->is_p2p_device = true; ++ p2p_status_code = (u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat); ++ if (p2p_status_code > 0) { ++ pstat->p2p_status_code = p2p_status_code; ++ status = _STATS_CAP_FAIL_; ++ goto OnAssocReqFail; ++ } ++ } ++ } ++ pstat->p2p_status_code = p2p_status_code; ++#endif /* CONFIG_88EU_P2P */ ++ ++ /* TODO: identify_proprietary_vendor_ie(); */ ++ /* Realtek proprietary IE */ ++ /* identify if this is Broadcom sta */ ++ /* identify if this is ralink sta */ ++ /* Customer proprietary IE */ ++ ++ /* get a unique AID */ ++ if (pstat->aid > 0) { ++ DBG_88E(" old AID %d\n", pstat->aid); ++ } else { ++ for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) ++ if (!pstapriv->sta_aid[pstat->aid - 1]) ++ break; ++ ++ /* if (pstat->aid > NUM_STA) { */ ++ if (pstat->aid > pstapriv->max_num_sta) { ++ pstat->aid = 0; ++ ++ DBG_88E(" no room for more AIDs\n"); ++ ++ status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; ++ ++ goto OnAssocReqFail; ++ } else { ++ pstapriv->sta_aid[pstat->aid - 1] = pstat; ++ DBG_88E("allocate new AID=(%d)\n", pstat->aid); ++ } ++ } ++ ++ pstat->state &= (~WIFI_FW_ASSOC_STATE); ++ pstat->state |= WIFI_FW_ASSOC_SUCCESS; ++ ++ spin_lock_bh(&pstapriv->auth_list_lock); ++ if (!list_empty(&pstat->auth_list)) { ++ list_del_init(&pstat->auth_list); ++ pstapriv->auth_list_cnt--; ++ } ++ spin_unlock_bh(&pstapriv->auth_list_lock); ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ if (list_empty(&pstat->asoc_list)) { ++ pstat->expire_to = pstapriv->expire_to; ++ list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list); ++ pstapriv->asoc_list_cnt++; ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ /* now the station is qualified to join our BSS... */ ++ if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_ == status)) { ++#ifdef CONFIG_88EU_AP_MODE ++ /* 1 bss_cap_update & sta_info_update */ ++ bss_cap_update_on_sta_join(padapter, pstat); ++ sta_info_update(padapter, pstat); ++ ++ /* issue assoc rsp before notify station join event. */ ++ if (frame_type == WIFI_ASSOCREQ) ++ issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); ++ else ++ issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); ++ ++ /* 2 - report to upper layer */ ++ DBG_88E("indicate_sta_join_event to upper layer - hostapd\n"); ++ rtw_indicate_sta_assoc_event(padapter, pstat); ++ ++ /* 3-(1) report sta add event */ ++ report_add_sta_event(padapter, pstat->hwaddr, pstat->aid); ++#endif ++ } ++ ++ return _SUCCESS; ++ ++asoc_class2_error: ++ ++#ifdef CONFIG_88EU_AP_MODE ++ issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status); ++#endif ++ ++ return _FAIL; ++ ++OnAssocReqFail: ++ ++#ifdef CONFIG_88EU_AP_MODE ++ pstat->aid = 0; ++ if (frame_type == WIFI_ASSOCREQ) ++ issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); ++ else ++ issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); ++#endif ++ ++#endif /* CONFIG_88EU_AP_MODE */ ++ ++ return _FAIL; ++} ++ ++unsigned int OnAssocRsp(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ uint i; ++ int res; ++ unsigned short status; ++ struct ndis_802_11_var_ie *pIE; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ /* struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); */ ++ u8 *pframe = precv_frame->rx_data; ++ uint pkt_len = precv_frame->len; ++ ++ DBG_88E("%s\n", __func__); ++ ++ /* check A1 matches or not */ ++ if (memcmp(myid(&padapter->eeprompriv), get_da(pframe), ETH_ALEN)) ++ return _SUCCESS; ++ ++ if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE))) ++ return _SUCCESS; ++ ++ if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) ++ return _SUCCESS; ++ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ ++ /* status */ ++ status = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 2)); ++ if (status > 0) { ++ DBG_88E("assoc reject, status code: %d\n", status); ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ res = -4; ++ goto report_assoc_result; ++ } ++ ++ /* get capabilities */ ++ pmlmeinfo->capability = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); ++ ++ /* set slot time */ ++ pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10)) ? 9 : 20; ++ ++ /* AID */ ++ pmlmeinfo->aid = (int)(le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 4)) & 0x3fff); ++ res = pmlmeinfo->aid; ++ ++ /* following are moved to join event callback function */ ++ /* to handle HT, WMM, rate adaptive, update MAC reg */ ++ /* for not to handle the synchronous IO in the tasklet */ ++ for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) { ++ pIE = (struct ndis_802_11_var_ie *)(pframe + i); ++ ++ switch (pIE->ElementID) { ++ case _VENDOR_SPECIFIC_IE_: ++ if (!memcmp(pIE->data, WMM_PARA_OUI, 6)) /* WMM */ ++ WMM_param_handler(padapter, pIE); ++ break; ++ case _HT_CAPABILITY_IE_: /* HT caps */ ++ HT_caps_handler(padapter, pIE); ++ break; ++ case _HT_EXTRA_INFO_IE_: /* HT info */ ++ HT_info_handler(padapter, pIE); ++ break; ++ case _ERPINFO_IE_: ++ ERP_IE_handler(padapter, pIE); ++ break; ++ default: ++ break; ++ } ++ ++ i += (pIE->Length + 2); ++ } ++ ++ pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE); ++ pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; ++ ++ /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */ ++ UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates); ++ ++report_assoc_result: ++ if (res > 0) ++ rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len); ++ else ++ kfree(pmlmepriv->assoc_rsp); ++ ++ report_join_res(padapter, res); ++ ++ return _SUCCESS; ++} ++ ++unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ unsigned short reason; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 *pframe = precv_frame->rx_data; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ /* check A3 */ ++ if (!(!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) ++ return _SUCCESS; ++ ++#ifdef CONFIG_88EU_P2P ++ if (pwdinfo->rx_invitereq_info.scan_op_ch_only) { ++ _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey); ++ _set_timer(&pwdinfo->reset_ch_sitesurvey, 10); ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); ++ ++ DBG_88E("%s Reason code(%d)\n", __func__, reason); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ struct sta_info *psta; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ DBG_88E_LEVEL(_drv_always_, "ap recv deauth reason code(%d) sta:%pM\n", ++ reason, GetAddr2Ptr(pframe)); ++ ++ psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); ++ if (psta) { ++ u8 updated = 0; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ if (!list_empty(&psta->asoc_list)) { ++ list_del_init(&psta->asoc_list); ++ pstapriv->asoc_list_cnt--; ++ updated = ap_free_sta(padapter, psta, false, reason); ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ associated_clients_update(padapter, updated); ++ } ++ ++ return _SUCCESS; ++ } else ++#endif ++ { ++ int ignore_received_deauth = 0; ++ ++ /* Before sending the auth frame to start the STA/GC mode connection with AP/GO, ++ * we will send the deauth first. ++ * However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth. ++ * Added the following code to avoid this case. ++ */ ++ if ((pmlmeinfo->state & WIFI_FW_AUTH_STATE) || ++ (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)) { ++ if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA) { ++ ignore_received_deauth = 1; ++ } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) { ++ // TODO: 802.11r ++ ignore_received_deauth = 1; ++ } ++ } ++ ++ DBG_88E_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM, ignore = %d\n", ++ reason, GetAddr3Ptr(pframe), ignore_received_deauth); ++ ++ if (!ignore_received_deauth) ++ receive_disconnect(padapter, GetAddr3Ptr(pframe), reason); ++ } ++ pmlmepriv->LinkDetectInfo.bBusyTraffic = false; ++ return _SUCCESS; ++} ++ ++unsigned int OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ u16 reason; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 *pframe = precv_frame->rx_data; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ /* check A3 */ ++ if (!(!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) ++ return _SUCCESS; ++ ++#ifdef CONFIG_88EU_P2P ++ if (pwdinfo->rx_invitereq_info.scan_op_ch_only) { ++ _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey); ++ _set_timer(&pwdinfo->reset_ch_sitesurvey, 10); ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); ++ ++ DBG_88E("%s Reason code(%d)\n", __func__, reason); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ struct sta_info *psta; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ DBG_88E_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n", ++ reason, GetAddr2Ptr(pframe)); ++ ++ psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); ++ if (psta) { ++ u8 updated = 0; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ if (!list_empty(&psta->asoc_list)) { ++ list_del_init(&psta->asoc_list); ++ pstapriv->asoc_list_cnt--; ++ updated = ap_free_sta(padapter, psta, false, reason); ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ associated_clients_update(padapter, updated); ++ } ++ ++ return _SUCCESS; ++ } else ++#endif ++ { ++ DBG_88E_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n", ++ reason, GetAddr3Ptr(pframe)); ++ ++ receive_disconnect(padapter, GetAddr3Ptr(pframe), reason); ++ } ++ pmlmepriv->LinkDetectInfo.bBusyTraffic = false; ++ return _SUCCESS; ++} ++ ++unsigned int OnAtim(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ DBG_88E("%s\n", __func__); ++ return _SUCCESS; ++} ++ ++unsigned int on_action_spct(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ unsigned int ret = _FAIL; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 *pframe = precv_frame->rx_data; ++ u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ u8 category; ++ u8 action; ++ ++ DBG_88E(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); ++ ++ psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); ++ ++ if (!psta) ++ goto exit; ++ ++ category = frame_body[0]; ++ if (category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT) ++ goto exit; ++ ++ action = frame_body[1]; ++ switch (action) { ++ case RTW_WLAN_ACTION_SPCT_MSR_REQ: ++ case RTW_WLAN_ACTION_SPCT_MSR_RPRT: ++ case RTW_WLAN_ACTION_SPCT_TPC_REQ: ++ case RTW_WLAN_ACTION_SPCT_TPC_RPRT: ++ break; ++ case RTW_WLAN_ACTION_SPCT_CHL_SWITCH: ++ break; ++ default: ++ break; ++ } ++ ++exit: ++ return ret; ++} ++ ++unsigned int OnAction_qos(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ return _SUCCESS; ++} ++ ++unsigned int OnAction_dls(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ return _SUCCESS; ++} ++ ++unsigned int OnAction_back(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ u8 *addr; ++ struct sta_info *psta = NULL; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ unsigned char *frame_body; ++ unsigned char category, action; ++ unsigned short tid, status, reason_code = 0; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 *pframe = precv_frame->rx_data; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ /* check RA matches or not */ ++ if (memcmp(myid(&padapter->eeprompriv), GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */ ++ return _SUCCESS; ++ ++ DBG_88E("%s\n", __func__); ++ ++ if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) ++ if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) ++ return _SUCCESS; ++ ++ addr = GetAddr2Ptr(pframe); ++ psta = rtw_get_stainfo(pstapriv, addr); ++ ++ if (!psta) ++ return _SUCCESS; ++ ++ frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ category = frame_body[0]; ++ if (category == RTW_WLAN_CATEGORY_BACK) { /* representing Block Ack */ ++ if (!pmlmeinfo->HT_enable) ++ return _SUCCESS; ++ action = frame_body[1]; ++ DBG_88E("%s, action=%d\n", __func__, action); ++ switch (action) { ++ case RTW_WLAN_ACTION_ADDBA_REQ: /* ADDBA request */ ++ memcpy(&pmlmeinfo->ADDBA_req, &frame_body[2], sizeof(struct ADDBA_request)); ++ process_addba_req(padapter, (u8 *)&pmlmeinfo->ADDBA_req, addr); ++ ++ if (pmlmeinfo->bAcceptAddbaReq) ++ issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 0); ++ else ++ issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 37);/* reject ADDBA Req */ ++ break; ++ case RTW_WLAN_ACTION_ADDBA_RESP: /* ADDBA response */ ++ status = get_unaligned_le16(&frame_body[3]); ++ tid = ((frame_body[5] >> 2) & 0x7); ++ if (status == 0) { /* successful */ ++ DBG_88E("agg_enable for TID=%d\n", tid); ++ psta->htpriv.agg_enable_bitmap |= 1 << tid; ++ psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); ++ } else { ++ psta->htpriv.agg_enable_bitmap &= ~BIT(tid); ++ } ++ break; ++ case RTW_WLAN_ACTION_DELBA: /* DELBA */ ++ if ((frame_body[3] & BIT(3)) == 0) { ++ psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf)); ++ psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf)); ++ reason_code = get_unaligned_le16(&frame_body[4]); ++ } else if ((frame_body[3] & BIT(3)) == BIT(3)) { ++ tid = (frame_body[3] >> 4) & 0x0F; ++ preorder_ctrl = &psta->recvreorder_ctrl[tid]; ++ preorder_ctrl->enable = false; ++ preorder_ctrl->indicate_seq = 0xffff; ++ } ++ DBG_88E("%s(): DELBA: %x(%x)\n", __func__, pmlmeinfo->agg_enable_bitmap, reason_code); ++ /* todo: how to notify the host while receiving DELETE BA */ ++ break; ++ default: ++ break; ++ } ++ } ++ return _SUCCESS; ++} ++ ++#ifdef CONFIG_88EU_P2P ++ ++static int get_reg_classes_full_count(struct p2p_channels *channel_list) ++{ ++ int cnt = 0; ++ int i; ++ ++ for (i = 0; i < channel_list->reg_classes; i++) { ++ cnt += channel_list->reg_class[i].channels; ++ } ++ ++ return cnt; ++} ++ ++void issue_p2p_GO_request(struct adapter *padapter, u8 *raddr) ++{ ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_GO_NEGO_REQ; ++ u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 }; ++ u8 wpsielen = 0, p2pielen = 0; ++ u16 len_channellist_attr = 0; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ DBG_88E("[%s] In\n", __func__); ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pwdinfo->negotiation_dialog_token = 1; /* Initialize the dialog value */ ++ pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &pattrib->pktlen); ++ ++ /* WPS Section */ ++ wpsielen = 0; ++ /* WPS OUI */ ++ *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI); ++ wpsielen += 4; ++ ++ /* WPS version */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */ ++ ++ /* Device Password ID */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002); ++ wpsielen += 2; ++ ++ /* Value: */ ++ ++ if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN) ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC); ++ else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN) ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC); ++ else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC) ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC); ++ ++ wpsielen += 2; ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen); ++ ++ /* P2P IE Section. */ ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20110306 */ ++ /* According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes */ ++ /* 1. P2P Capability */ ++ /* 2. Group Owner Intent */ ++ /* 3. Configuration Timeout */ ++ /* 4. Listen Channel */ ++ /* 5. Extended Listen Timing */ ++ /* 6. Intended P2P Interface Address */ ++ /* 7. Channel List */ ++ /* 8. P2P Device Info */ ++ /* 9. Operating Channel */ ++ ++ /* P2P Capability */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CAPABILITY; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT; ++ ++ /* Group Capability Bitmap, 1 byte */ ++ if (pwdinfo->persistent_supported) ++ p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP; ++ else ++ p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN; ++ ++ /* Group Owner Intent */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GO_INTENT; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Todo the tie breaker bit. */ ++ p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0)); ++ ++ /* Configuration Timeout */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */ ++ ++ /* Listen Channel */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; /* Copy from SD7 */ ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->listen_channel; /* listening channel number */ ++ ++ /* Extended Listen Timing ATTR */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Availability Period */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF); ++ p2pielen += 2; ++ ++ /* Availability Interval */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF); ++ p2pielen += 2; ++ ++ /* Intended P2P Interface Address */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Channel List */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CH_LIST; ++ ++ /* Length: */ ++ /* Country String(3) */ ++ /* + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */ ++ /* + number of channels in all classes */ ++ len_channellist_attr = 3 ++ + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes) ++ + get_reg_classes_full_count(&pmlmeext->channel_list); ++ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Channel Entry List */ ++ ++ { ++ int i, j; ++ for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) { ++ /* Operating Class */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class; ++ ++ /* Number of Channels */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels; ++ ++ /* Channel List */ ++ for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) { ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i]; ++ } ++ } ++ } ++ ++ /* Device Info */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO; ++ ++ /* Length: */ ++ /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */ ++ /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address */ ++ memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Config Method */ ++ /* This field should be big endian. Noted by P2P specification. */ ++ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm); ++ ++ p2pielen += 2; ++ ++ /* Primary Device Type */ ++ /* Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); ++ p2pielen += 2; ++ ++ /* OUI */ ++ *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI); ++ p2pielen += 4; ++ ++ /* Sub Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); ++ p2pielen += 2; ++ ++ /* Number of Secondary Device Types */ ++ p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */ ++ ++ /* Device Name */ ++ /* Type: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); ++ p2pielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ p2pielen += pwdinfo->device_name_len; ++ ++ /* Operating Channel */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */ ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static void issue_p2p_GO_response(struct adapter *padapter, u8 *raddr, u8 *frame_body, uint len, u8 result) ++{ ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_GO_NEGO_RESP; ++ u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 }; ++ u8 p2pielen = 0; ++ uint wpsielen = 0; ++ u16 wps_devicepassword_id = 0x0000; ++ __be16 be_tmp; ++ uint wps_devicepassword_id_len = 0; ++ u16 len_channellist_attr = 0; ++ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ DBG_88E("[%s] In, result=%d\n", __func__, result); ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pwdinfo->negotiation_dialog_token = frame_body[7]; /* The Dialog Token of provisioning discovery request frame. */ ++ pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &pattrib->pktlen); ++ ++ /* Commented by Albert 20110328 */ ++ /* Try to get the device password ID from the WPS IE of group negotiation request frame */ ++ /* WiFi Direct test plan 5.1.15 */ ++ rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen); ++ rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8 *)&be_tmp, &wps_devicepassword_id_len); ++ wps_devicepassword_id = be16_to_cpu(be_tmp); ++ ++ memset(wpsie, 0x00, 255); ++ wpsielen = 0; ++ ++ /* WPS Section */ ++ wpsielen = 0; ++ /* WPS OUI */ ++ *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI); ++ wpsielen += 4; ++ ++ /* WPS version */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */ ++ ++ /* Device Password ID */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002); ++ wpsielen += 2; ++ ++ /* Value: */ ++ if (wps_devicepassword_id == WPS_DPID_USER_SPEC) ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC); ++ else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC) ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC); ++ else ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC); ++ wpsielen += 2; ++ ++ /* Commented by Kurt 20120113 */ ++ /* If some device wants to do p2p handshake without sending prov_disc_req */ ++ /* We have to get peer_req_cm from here. */ ++ if (!memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) { ++ if (wps_devicepassword_id == WPS_DPID_USER_SPEC) ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3); ++ else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC) ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3); ++ else ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3); ++ } ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen); ++ ++ /* P2P IE Section. */ ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20100908 */ ++ /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */ ++ /* 1. Status */ ++ /* 2. P2P Capability */ ++ /* 3. Group Owner Intent */ ++ /* 4. Configuration Timeout */ ++ /* 5. Operating Channel */ ++ /* 6. Intended P2P Interface Address */ ++ /* 7. Channel List */ ++ /* 8. Device Info */ ++ /* 9. Group ID (Only GO) */ ++ ++ /* ToDo: */ ++ ++ /* P2P Status */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_STATUS; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001); ++ p2pielen += 2; ++ ++ /* Value: */ ++ p2pie[p2pielen++] = result; ++ ++ /* P2P Capability */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CAPABILITY; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) { ++ /* Commented by Albert 2011/03/08 */ ++ /* According to the P2P specification */ ++ /* if the sending device will be client, the P2P Capability should be reserved of group negotiation response frame */ ++ p2pie[p2pielen++] = 0; ++ } else { ++ /* Be group owner or meet the error case */ ++ p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT; ++ } ++ ++ /* Group Capability Bitmap, 1 byte */ ++ if (pwdinfo->persistent_supported) { ++ p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP; ++ } else { ++ p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN; ++ } ++ ++ /* Group Owner Intent */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GO_INTENT; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001); ++ p2pielen += 2; ++ ++ /* Value: */ ++ if (pwdinfo->peer_intent & 0x01) { ++ /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */ ++ p2pie[p2pielen++] = (pwdinfo->intent << 1); ++ } else { ++ /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */ ++ p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0)); ++ } ++ ++ /* Configuration Timeout */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */ ++ ++ /* Operating Channel */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */ ++ ++ /* Intended P2P Interface Address */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Channel List */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CH_LIST; ++ ++ /* Country String(3) */ ++ /* + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */ ++ /* + number of channels in all classes */ ++ len_channellist_attr = 3 ++ + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes ++ + get_reg_classes_full_count(&pmlmeext->channel_list); ++ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr); ++ ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Channel Entry List */ ++ ++ { ++ int i, j; ++ for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) { ++ /* Operating Class */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class; ++ ++ /* Number of Channels */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels; ++ ++ /* Channel List */ ++ for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) { ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i]; ++ } ++ } ++ } ++ ++ /* Device Info */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO; ++ ++ /* Length: */ ++ /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */ ++ /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address */ ++ memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Config Method */ ++ /* This field should be big endian. Noted by P2P specification. */ ++ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm); ++ ++ p2pielen += 2; ++ ++ /* Primary Device Type */ ++ /* Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); ++ p2pielen += 2; ++ ++ /* OUI */ ++ *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI); ++ p2pielen += 4; ++ ++ /* Sub Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); ++ p2pielen += 2; ++ ++ /* Number of Secondary Device Types */ ++ p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */ ++ ++ /* Device Name */ ++ /* Type: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); ++ p2pielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ p2pielen += pwdinfo->device_name_len; ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ /* Group ID Attribute */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GROUP_ID; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* p2P Device Address */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* SSID */ ++ memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen); ++ p2pielen += pwdinfo->nego_ssidlen; ++ } ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static void issue_p2p_GO_confirm(struct adapter *padapter, u8 *raddr, u8 result) ++{ ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_GO_NEGO_CONF; ++ u8 p2pie[255] = { 0x00 }; ++ u8 p2pielen = 0; ++ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ DBG_88E("[%s] In\n", __func__); ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &pattrib->pktlen); ++ ++ /* P2P IE Section. */ ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20110306 */ ++ /* According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes */ ++ /* 1. Status */ ++ /* 2. P2P Capability */ ++ /* 3. Operating Channel */ ++ /* 4. Channel List */ ++ /* 5. Group ID (if this WiFi is GO) */ ++ ++ /* P2P Status */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_STATUS; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001); ++ p2pielen += 2; ++ ++ /* Value: */ ++ p2pie[p2pielen++] = result; ++ ++ /* P2P Capability */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CAPABILITY; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT; ++ ++ /* Group Capability Bitmap, 1 byte */ ++ if (pwdinfo->persistent_supported) ++ p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP; ++ else ++ p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN; ++ ++ /* Operating Channel */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) { ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; ++ p2pie[p2pielen++] = pwdinfo->peer_operating_ch; ++ } else { ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->operating_channel; /* Use the listen channel as the operating channel */ ++ } ++ ++ /* Channel List */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CH_LIST; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(pwdinfo->channel_list_attr_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len); ++ p2pielen += pwdinfo->channel_list_attr_len; ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ /* Group ID Attribute */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GROUP_ID; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* p2P Device Address */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* SSID */ ++ memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen); ++ p2pielen += pwdinfo->nego_ssidlen; ++ } ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen); ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++void issue_p2p_invitation_request(struct adapter *padapter, u8 *raddr) ++{ ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_INVIT_REQ; ++ u8 p2pie[255] = { 0x00 }; ++ u8 p2pielen = 0; ++ u8 dialogToken = 3; ++ u16 len_channellist_attr = 0; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, raddr, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen); ++ ++ /* P2P IE Section. */ ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20101011 */ ++ /* According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes */ ++ /* 1. Configuration Timeout */ ++ /* 2. Invitation Flags */ ++ /* 3. Operating Channel (Only GO) */ ++ /* 4. P2P Group BSSID (Should be included if I am the GO) */ ++ /* 5. Channel List */ ++ /* 6. P2P Group ID */ ++ /* 7. P2P Device Info */ ++ ++ /* Configuration Timeout */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */ ++ ++ /* Invitation Flags */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_INVITATION_FLAGS; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001); ++ p2pielen += 2; ++ ++ /* Value: */ ++ p2pie[p2pielen++] = P2P_INVITATION_FLAGS_PERSISTENT; ++ ++ /* Operating Channel */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->invitereq_info.operating_ch; /* operating channel number */ ++ ++ if (!memcmp(myid(&padapter->eeprompriv), pwdinfo->invitereq_info.go_bssid, ETH_ALEN)) { ++ /* P2P Group BSSID */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address for GO */ ++ memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ } ++ ++ /* Channel List */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CH_LIST; ++ ++ /* Length: */ ++ /* Country String(3) */ ++ /* + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */ ++ /* + number of channels in all classes */ ++ len_channellist_attr = 3 ++ + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes ++ + get_reg_classes_full_count(&pmlmeext->channel_list); ++ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr); ++ ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Channel Entry List */ ++ { ++ int i, j; ++ for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) { ++ /* Operating Class */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class; ++ ++ /* Number of Channels */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels; ++ ++ /* Channel List */ ++ for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) { ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i]; ++ } ++ } ++ } ++ ++ /* P2P Group ID */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GROUP_ID; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(6 + pwdinfo->invitereq_info.ssidlen); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address for GO */ ++ memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* SSID */ ++ memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen); ++ p2pielen += pwdinfo->invitereq_info.ssidlen; ++ ++ /* Device Info */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO; ++ ++ /* Length: */ ++ /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */ ++ /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address */ ++ memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Config Method */ ++ /* This field should be big endian. Noted by P2P specification. */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY); ++ p2pielen += 2; ++ ++ /* Primary Device Type */ ++ /* Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); ++ p2pielen += 2; ++ ++ /* OUI */ ++ *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI); ++ p2pielen += 4; ++ ++ /* Sub Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); ++ p2pielen += 2; ++ ++ /* Number of Secondary Device Types */ ++ p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */ ++ ++ /* Device Name */ ++ /* Type: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); ++ p2pielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ p2pielen += pwdinfo->device_name_len; ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++void issue_p2p_invitation_response(struct adapter *padapter, u8 *raddr, u8 dialogToken, u8 status_code) ++{ ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_INVIT_RESP; ++ u8 p2pie[255] = { 0x00 }; ++ u8 p2pielen = 0; ++ u16 len_channellist_attr = 0; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, raddr, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen); ++ ++ /* P2P IE Section. */ ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20101005 */ ++ /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */ ++ /* 1. Status */ ++ /* 2. Configuration Timeout */ ++ /* 3. Operating Channel (Only GO) */ ++ /* 4. P2P Group BSSID (Only GO) */ ++ /* 5. Channel List */ ++ ++ /* P2P Status */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_STATUS; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. */ ++ /* Sent the event receiving the P2P Invitation Req frame to DMP UI. */ ++ /* DMP had to compare the MAC address to find out the profile. */ ++ /* So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. */ ++ /* If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req */ ++ /* to NB to rebuild the persistent group. */ ++ p2pie[p2pielen++] = status_code; ++ ++ /* Configuration Timeout */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */ ++ ++ if (status_code == P2P_STATUS_SUCCESS) { ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */ ++ /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */ ++ /* First one is operating channel attribute. */ ++ /* Second one is P2P Group BSSID attribute. */ ++ ++ /* Operating Channel */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; /* Copy from SD7 */ ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */ ++ ++ /* P2P Group BSSID */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address for GO */ ++ memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ } ++ ++ /* Channel List */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CH_LIST; ++ ++ /* Length: */ ++ /* Country String(3) */ ++ /* + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */ ++ /* + number of channels in all classes */ ++ len_channellist_attr = 3 ++ + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes ++ + get_reg_classes_full_count(&pmlmeext->channel_list); ++ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Channel Entry List */ ++ { ++ int i, j; ++ for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) { ++ /* Operating Class */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class; ++ ++ /* Number of Channels */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels; ++ ++ /* Channel List */ ++ for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) { ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i]; ++ } ++ } ++ } ++ } ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++void issue_p2p_provision_request(struct adapter *padapter, u8 *pssid, u8 ussidlen, u8 *pdev_raddr) ++{ ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ u8 dialogToken = 1; ++ u8 oui_subtype = P2P_PROVISION_DISC_REQ; ++ u8 wpsie[100] = { 0x00 }; ++ u8 wpsielen = 0; ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u32 p2pielen = 0; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ DBG_88E("[%s] In\n", __func__); ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen); ++ ++ p2pielen = build_prov_disc_request_p2p_ie(pwdinfo, pframe, pssid, ussidlen, pdev_raddr); ++ ++ pframe += p2pielen; ++ pattrib->pktlen += p2pielen; ++ ++ wpsielen = 0; ++ /* WPS OUI */ ++ *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI); ++ wpsielen += 4; ++ ++ /* WPS version */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */ ++ ++ /* Config Method */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002); ++ wpsielen += 2; ++ ++ /* Value: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request); ++ wpsielen += 2; ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static u8 is_matched_in_profilelist(u8 *peermacaddr, struct profile_info *profileinfo) ++{ ++ u8 i, match_result = 0; ++ ++ DBG_88E("[%s] peermac=%.2X %.2X %.2X %.2X %.2X %.2X\n", __func__, ++ peermacaddr[0], peermacaddr[1], peermacaddr[2], peermacaddr[3], peermacaddr[4], peermacaddr[5]); ++ ++ for (i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++) { ++ DBG_88E("[%s] profileinfo_mac=%.2X %.2X %.2X %.2X %.2X %.2X\n", __func__, ++ profileinfo->peermac[0], profileinfo->peermac[1], profileinfo->peermac[2], ++ profileinfo->peermac[3], profileinfo->peermac[4], profileinfo->peermac[5]); ++ if (!memcmp(peermacaddr, profileinfo->peermac, ETH_ALEN)) { ++ match_result = 1; ++ DBG_88E("[%s] Match!\n", __func__); ++ break; ++ } ++ } ++ return match_result; ++} ++ ++void issue_probersp_p2p(struct adapter *padapter, unsigned char *da) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ unsigned char *mac; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ u16 beacon_interval = 100; ++ u16 capInfo = 0; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 wpsie[255] = { 0x00 }; ++ u32 wpsielen = 0, p2pielen = 0; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ mac = myid(&padapter->eeprompriv); ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, mac, ETH_ALEN); ++ ++ /* Use the device address for BSSID field. */ ++ memcpy(pwlanhdr->addr3, mac, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(fctrl, WIFI_PROBERSP); ++ ++ pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = pattrib->hdrlen; ++ pframe += pattrib->hdrlen; ++ ++ /* timestamp will be inserted by hardware */ ++ pframe += 8; ++ pattrib->pktlen += 8; ++ ++ /* beacon interval: 2 bytes */ ++ memcpy(pframe, (unsigned char *)&beacon_interval, 2); ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* capability info: 2 bytes */ ++ /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */ ++ capInfo |= cap_ShortPremble; ++ capInfo |= cap_ShortSlot; ++ ++ memcpy(pframe, (unsigned char *)&capInfo, 2); ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* SSID */ ++ pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen); ++ ++ /* supported rates... */ ++ /* Use the OFDM rate in the P2P probe response frame. (6(B), 9(B), 12, 18, 24, 36, 48, 54) */ ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen); ++ ++ /* DS parameter set */ ++ pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen); ++ ++ /* Todo: WPS IE */ ++ /* Noted by Albert 20100907 */ ++ /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */ ++ ++ wpsielen = 0; ++ /* WPS OUI */ ++ *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI); ++ wpsielen += 4; ++ ++ /* WPS version */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */ ++ ++ /* WiFi Simple Config State */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */ ++ ++ /* Response Type */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X; ++ ++ /* UUID-E */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010); ++ wpsielen += 2; ++ ++ /* Value: */ ++ memcpy(wpsie + wpsielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ wpsielen += 0x10; ++ ++ /* Manufacturer */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007); ++ wpsielen += 2; ++ ++ /* Value: */ ++ memcpy(wpsie + wpsielen, "Realtek", 7); ++ wpsielen += 7; ++ ++ /* Model Name */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006); ++ wpsielen += 2; ++ ++ /* Value: */ ++ memcpy(wpsie + wpsielen, "8188EU", 6); ++ wpsielen += 6; ++ ++ /* Model Number */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = 0x31; /* character 1 */ ++ ++ /* Serial Number */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN); ++ wpsielen += 2; ++ ++ /* Value: */ ++ memcpy(wpsie + wpsielen, "123456", ETH_ALEN); ++ wpsielen += ETH_ALEN; ++ ++ /* Primary Device Type */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008); ++ wpsielen += 2; ++ ++ /* Value: */ ++ /* Category ID */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); ++ wpsielen += 2; ++ ++ /* OUI */ ++ *(__be32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI); ++ wpsielen += 4; ++ ++ /* Sub Category ID */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); ++ wpsielen += 2; ++ ++ /* Device Name */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len); ++ wpsielen += 2; ++ ++ /* Value: */ ++ if (pwdinfo->device_name_len) { ++ memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ wpsielen += pwdinfo->device_name_len; ++ } ++ ++ /* Config Method */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002); ++ wpsielen += 2; ++ ++ /* Value: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm); ++ wpsielen += 2; ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen); ++ ++ p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe); ++ pframe += p2pielen; ++ pattrib->pktlen += p2pielen; ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static int _issue_probereq_p2p(struct adapter *padapter, u8 *da, int wait_ack) ++{ ++ int ret = _FAIL; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ unsigned char *mac; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 }; ++ u16 wpsielen = 0, p2pielen = 0; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ goto exit; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ mac = myid(&padapter->eeprompriv); ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ if (da) { ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, da, ETH_ALEN); ++ } else { ++ if ((pwdinfo->p2p_info.scan_op_ch_only) || (pwdinfo->rx_invitereq_info.scan_op_ch_only)) { ++ /* This two flags will be set when this is only the P2P client mode. */ ++ memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN); ++ } else { ++ /* broadcast probe request frame */ ++ memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN); ++ } ++ } ++ memcpy(pwlanhdr->addr2, mac, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_PROBEREQ); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) ++ pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &pattrib->pktlen); ++ else ++ pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen); ++ ++ /* Use the OFDM rate in the P2P probe request frame. (6(B), 9(B), 12(B), 24(B), 36, 48, 54) */ ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen); ++ ++ /* WPS IE */ ++ /* Noted by Albert 20110221 */ ++ /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */ ++ ++ wpsielen = 0; ++ /* WPS OUI */ ++ *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI); ++ wpsielen += 4; ++ ++ /* WPS version */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */ ++ ++ if (!pmlmepriv->wps_probe_req_ie) { ++ /* UUID-E */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010); ++ wpsielen += 2; ++ ++ /* Value: */ ++ memcpy(wpsie + wpsielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ wpsielen += 0x10; ++ ++ /* Config Method */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002); ++ wpsielen += 2; ++ ++ /* Value: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm); ++ wpsielen += 2; ++ } ++ ++ /* Device Name */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len); ++ wpsielen += 2; ++ ++ /* Value: */ ++ memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ wpsielen += pwdinfo->device_name_len; ++ ++ /* Primary Device Type */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008); ++ wpsielen += 2; ++ ++ /* Value: */ ++ /* Category ID */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_RTK_WIDI); ++ wpsielen += 2; ++ ++ /* OUI */ ++ *(__be32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI); ++ wpsielen += 4; ++ ++ /* Sub Category ID */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_RTK_DMP); ++ wpsielen += 2; ++ ++ /* Device Password ID */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002); ++ wpsielen += 2; ++ ++ /* Value: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC); /* Registrar-specified */ ++ wpsielen += 2; ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen); ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20110221 */ ++ /* According to the P2P Specification, the probe request frame should contain 5 P2P attributes */ ++ /* 1. P2P Capability */ ++ /* 2. P2P Device ID if this probe request wants to find the specific P2P device */ ++ /* 3. Listen Channel */ ++ /* 4. Extended Listen Timing */ ++ /* 5. Operating Channel if this WiFi is working as the group owner now */ ++ ++ /* P2P Capability */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CAPABILITY; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT; ++ ++ /* Group Capability Bitmap, 1 byte */ ++ if (pwdinfo->persistent_supported) ++ p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; ++ else ++ p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT; ++ ++ /* Listen Channel */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; /* Copy from SD7 */ ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->listen_channel; /* listen channel */ ++ ++ /* Extended Listen Timing */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Availability Period */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF); ++ p2pielen += 2; ++ ++ /* Availability Interval */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF); ++ p2pielen += 2; ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ /* Operating Channel (if this WiFi is working as the group owner now) */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; /* Copy from SD7 */ ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */ ++ } ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen); ++ ++ if (pmlmepriv->wps_probe_req_ie) { ++ /* WPS IE */ ++ memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len); ++ pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len; ++ pframe += pmlmepriv->wps_probe_req_ie_len; ++ } ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ if (wait_ack) { ++ ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); ++ } else { ++ dump_mgntframe(padapter, pmgntframe); ++ ret = _SUCCESS; ++ } ++ ++exit: ++ return ret; ++} ++ ++inline void issue_probereq_p2p(struct adapter *adapter, u8 *da) ++{ ++ _issue_probereq_p2p(adapter, da, false); ++} ++ ++int issue_probereq_p2p_ex(struct adapter *adapter, u8 *da, int try_cnt, int wait_ms) ++{ ++ int ret; ++ int i = 0; ++ u32 start = jiffies; ++ ++ do { ++ ret = _issue_probereq_p2p(adapter, da, wait_ms > 0); ++ ++ i++; ++ ++ if (adapter->bDriverStopped || adapter->bSurpriseRemoved) ++ break; ++ ++ if (i < try_cnt && wait_ms > 0 && ret == _FAIL) ++ msleep(wait_ms); ++ } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); ++ ++ if (ret != _FAIL) { ++ ret = _SUCCESS; ++ goto exit; ++ } ++ ++ if (try_cnt && wait_ms) { ++ if (da) ++ DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(adapter), da, rtw_get_oper_ch(adapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ else ++ DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ } ++exit: ++ return ret; ++} ++ ++#endif /* CONFIG_88EU_P2P */ ++ ++static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token) ++{ ++ struct adapter *adapter = recv_frame->adapter; ++ struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; ++ u8 *frame = recv_frame->rx_data; ++ u16 seq_ctrl = ((recv_frame->attrib.seq_num & 0xffff) << 4) | ++ (recv_frame->attrib.frag_num & 0xf); ++ ++ if (GetRetry(frame)) { ++ if (token >= 0) { ++ if ((seq_ctrl == mlmeext->action_public_rxseq) && (token == mlmeext->action_public_dialog_token)) { ++ DBG_88E(FUNC_ADPT_FMT" seq_ctrl = 0x%x, rxseq = 0x%x, token:%d\n", ++ FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token); ++ return _FAIL; ++ } ++ } else { ++ if (seq_ctrl == mlmeext->action_public_rxseq) { ++ DBG_88E(FUNC_ADPT_FMT" seq_ctrl = 0x%x, rxseq = 0x%x\n", ++ FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq); ++ return _FAIL; ++ } ++ } ++ } ++ ++ mlmeext->action_public_rxseq = seq_ctrl; ++ ++ if (token >= 0) ++ mlmeext->action_public_dialog_token = token; ++ ++ return _SUCCESS; ++} ++ ++static unsigned int on_action_public_p2p(struct recv_frame *precv_frame) ++{ ++ u8 *pframe = precv_frame->rx_data; ++ u8 *frame_body; ++ u8 dialogToken = 0; ++#ifdef CONFIG_88EU_P2P ++ struct adapter *padapter = precv_frame->adapter; ++ uint len = precv_frame->len; ++ u8 *p2p_ie; ++ u32 p2p_ielen; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 result = P2P_STATUS_SUCCESS; ++ u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++#endif /* CONFIG_88EU_P2P */ ++ ++ frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ dialogToken = frame_body[7]; ++ ++ if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL) ++ return _FAIL; ++ ++#ifdef CONFIG_88EU_P2P ++ _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey); ++ /* Do nothing if the driver doesn't enable the P2P function. */ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) ++ return _SUCCESS; ++ ++ len -= sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ switch (frame_body[6]) { /* OUI Subtype */ ++ case P2P_GO_NEGO_REQ: ++ DBG_88E("[%s] Got GO Nego Req Frame\n", __func__); ++ memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info)); ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ)) ++ rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) { ++ /* Commented by Albert 20110526 */ ++ /* In this case, this means the previous nego fail doesn't be reset yet. */ ++ _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); ++ /* Restore the previous p2p state */ ++ rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); ++ DBG_88E("[%s] Restore the previous p2p state to %d\n", __func__, rtw_p2p_state(pwdinfo)); ++ } ++ ++ /* Commented by Kurt 20110902 */ ++ /* Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) ++ rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); ++ ++ /* Commented by Kurt 20120113 */ ++ /* Get peer_dev_addr here if peer doesn't issue prov_disc frame. */ ++ if (!memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN)) ++ memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN); ++ ++ result = process_p2p_group_negotation_req(pwdinfo, frame_body, len); ++ issue_p2p_GO_response(padapter, GetAddr2Ptr(pframe), frame_body, len, result); ++ ++ /* Commented by Albert 20110718 */ ++ /* No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. */ ++ _set_timer(&pwdinfo->restore_p2p_state_timer, 5000); ++ break; ++ case P2P_GO_NEGO_RESP: ++ DBG_88E("[%s] Got GO Nego Resp Frame\n", __func__); ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) { ++ /* Commented by Albert 20110425 */ ++ /* The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. */ ++ _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); ++ pwdinfo->nego_req_info.benable = false; ++ result = process_p2p_group_negotation_resp(pwdinfo, frame_body, len); ++ issue_p2p_GO_confirm(pwdinfo->padapter, GetAddr2Ptr(pframe), result); ++ if (P2P_STATUS_SUCCESS == result) { ++ if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) { ++ pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch; ++ pwdinfo->p2p_info.scan_op_ch_only = 1; ++ _set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH); ++ } ++ } ++ /* Reset the dialog token for group negotiation frames. */ ++ pwdinfo->negotiation_dialog_token = 1; ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) ++ _set_timer(&pwdinfo->restore_p2p_state_timer, 5000); ++ } else { ++ DBG_88E("[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __func__); ++ } ++ break; ++ case P2P_GO_NEGO_CONF: ++ DBG_88E("[%s] Got GO Nego Confirm Frame\n", __func__); ++ result = process_p2p_group_negotation_confirm(pwdinfo, frame_body, len); ++ if (P2P_STATUS_SUCCESS == result) { ++ if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) { ++ pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch; ++ pwdinfo->p2p_info.scan_op_ch_only = 1; ++ _set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH); ++ } ++ } ++ break; ++ case P2P_INVIT_REQ: ++ /* Added by Albert 2010/10/05 */ ++ /* Received the P2P Invite Request frame. */ ++ ++ DBG_88E("[%s] Got invite request frame!\n", __func__); ++ p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen); ++ if (p2p_ie) { ++ /* Parse the necessary information from the P2P Invitation Request frame. */ ++ /* For example: The MAC address of sending this P2P Invitation Request frame. */ ++ u32 attr_contentlen = 0; ++ u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; ++ struct group_id_info group_id; ++ u8 invitation_flag = 0; ++ ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen); ++ if (attr_contentlen) { ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen); ++ /* Commented by Albert 20120510 */ ++ /* Copy to the pwdinfo->p2p_peer_interface_addr. */ ++ /* So that the WFD UI (or Sigma) can get the peer interface address by using the following command. */ ++ /* #> iwpriv wlan0 p2p_get peer_ifa */ ++ /* After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. */ ++ ++ if (attr_contentlen) { ++ DBG_88E("[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __func__, ++ pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], ++ pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3], ++ pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]); ++ } ++ ++ if (invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT) { ++ /* Re-invoke the persistent group. */ ++ ++ memset(&group_id, 0x00, sizeof(struct group_id_info)); ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *)&group_id, &attr_contentlen); ++ if (attr_contentlen) { ++ if (!memcmp(group_id.go_device_addr, myid(&padapter->eeprompriv), ETH_ALEN)) { ++ /* The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. */ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ status_code = P2P_STATUS_SUCCESS; ++ } else { ++ /* The p2p device sending this p2p invitation request wants to be the persistent GO. */ ++ if (is_matched_in_profilelist(pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[0])) { ++ u8 operatingch_info[5] = { 0x00 }; ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) { ++ if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4])) { ++ /* The operating channel is acceptable for this device. */ ++ pwdinfo->rx_invitereq_info.operation_ch[0] = operatingch_info[4]; ++ pwdinfo->rx_invitereq_info.scan_op_ch_only = 1; ++ _set_timer(&pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ status_code = P2P_STATUS_SUCCESS; ++ } else { ++ /* The operating channel isn't supported by this device. */ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ status_code = P2P_STATUS_FAIL_NO_COMMON_CH; ++ _set_timer(&pwdinfo->restore_p2p_state_timer, 3000); ++ } ++ } else { ++ /* Commented by Albert 20121130 */ ++ /* Intel will use the different P2P IE to store the operating channel information */ ++ /* Workaround for Intel WiDi 3.5 */ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ status_code = P2P_STATUS_SUCCESS; ++ } ++ } else { ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH); ++ status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP; ++ } ++ } ++ } else { ++ DBG_88E("[%s] P2P Group ID Attribute NOT FOUND!\n", __func__); ++ status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; ++ } ++ } else { ++ /* Received the invitation to join a P2P group. */ ++ ++ memset(&group_id, 0x00, sizeof(struct group_id_info)); ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *)&group_id, &attr_contentlen); ++ if (attr_contentlen) { ++ if (!memcmp(group_id.go_device_addr, myid(&padapter->eeprompriv), ETH_ALEN)) { ++ /* In this case, the GO can't be myself. */ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH); ++ status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; ++ } else { ++ /* The p2p device sending this p2p invitation request wants to join an existing P2P group */ ++ /* Commented by Albert 2012/06/28 */ ++ /* In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. */ ++ /* The peer device address should be the destination address for the provisioning discovery request. */ ++ /* Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. */ ++ /* The peer interface address should be the address for WPS mac address */ ++ memcpy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr, ETH_ALEN); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN); ++ status_code = P2P_STATUS_SUCCESS; ++ } ++ } else { ++ DBG_88E("[%s] P2P Group ID Attribute NOT FOUND!\n", __func__); ++ status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; ++ } ++ } ++ } else { ++ DBG_88E("[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __func__); ++ status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; ++ } ++ ++ DBG_88E("[%s] status_code = %d\n", __func__, status_code); ++ ++ pwdinfo->inviteresp_info.token = frame_body[7]; ++ issue_p2p_invitation_response(padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code); ++ } ++ break; ++ case P2P_INVIT_RESP: { ++ u8 attr_content = 0x00; ++ u32 attr_contentlen = 0; ++ ++ DBG_88E("[%s] Got invite response frame!\n", __func__); ++ _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); ++ p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen); ++ if (p2p_ie) { ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen); ++ ++ if (attr_contentlen == 1) { ++ DBG_88E("[%s] Status = %d\n", __func__, attr_content); ++ pwdinfo->invitereq_info.benable = false; ++ ++ if (attr_content == P2P_STATUS_SUCCESS) { ++ if (!memcmp(pwdinfo->invitereq_info.go_bssid, myid(&padapter->eeprompriv), ETH_ALEN)) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ } else { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ } ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_OK); ++ } else { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL); ++ } ++ } else { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL); ++ } ++ } else { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL); ++ } ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL)) ++ _set_timer(&pwdinfo->restore_p2p_state_timer, 5000); ++ break; ++ } ++ case P2P_DEVDISC_REQ: ++ process_p2p_devdisc_req(pwdinfo, pframe, len); ++ break; ++ case P2P_DEVDISC_RESP: ++ process_p2p_devdisc_resp(pwdinfo, pframe, len); ++ break; ++ case P2P_PROVISION_DISC_REQ: ++ DBG_88E("[%s] Got Provisioning Discovery Request Frame\n", __func__); ++ process_p2p_provdisc_req(pwdinfo, pframe, len); ++ memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN); ++ ++ /* 20110902 Kurt */ ++ /* Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ)) ++ rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); ++ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ); ++ _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT); ++ break; ++ case P2P_PROVISION_DISC_RESP: ++ /* Commented by Albert 20110707 */ ++ /* Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? */ ++ DBG_88E("[%s] Got Provisioning Discovery Response Frame\n", __func__); ++ /* Commented by Albert 20110426 */ ++ /* The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. */ ++ _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP); ++ process_p2p_provdisc_resp(pwdinfo, pframe); ++ _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT); ++ break; ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ return _SUCCESS; ++} ++ ++static unsigned int on_action_public_vendor(struct recv_frame *precv_frame) ++{ ++ unsigned int ret = _FAIL; ++ u8 *pframe = precv_frame->rx_data; ++ u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ if (!memcmp(frame_body + 2, P2P_OUI, 4)) { ++ ret = on_action_public_p2p(precv_frame); ++ } ++ ++ return ret; ++} ++ ++static unsigned int on_action_public_default(struct recv_frame *precv_frame, u8 action) ++{ ++ unsigned int ret = _FAIL; ++ u8 *pframe = precv_frame->rx_data; ++ u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); ++ u8 token; ++ ++ token = frame_body[2]; ++ ++ if (rtw_action_public_decache(precv_frame, token) == _FAIL) ++ goto exit; ++ ++ ret = _SUCCESS; ++ ++exit: ++ return ret; ++} ++ ++unsigned int on_action_public(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ unsigned int ret = _FAIL; ++ u8 *pframe = precv_frame->rx_data; ++ u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); ++ u8 category, action; ++ ++ /* check RA matches or not */ ++ if (memcmp(myid(&padapter->eeprompriv), GetAddr1Ptr(pframe), ETH_ALEN)) ++ goto exit; ++ ++ category = frame_body[0]; ++ if (category != RTW_WLAN_CATEGORY_PUBLIC) ++ goto exit; ++ ++ action = frame_body[1]; ++ switch (action) { ++ case ACT_PUBLIC_VENDOR: ++ ret = on_action_public_vendor(precv_frame); ++ break; ++ default: ++ ret = on_action_public_default(precv_frame, action); ++ break; ++ } ++ ++exit: ++ return ret; ++} ++ ++unsigned int OnAction_ht(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ return _SUCCESS; ++} ++ ++unsigned int OnAction_wmm(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ return _SUCCESS; ++} ++ ++unsigned int OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++#ifdef CONFIG_88EU_P2P ++ u8 *frame_body; ++ u8 category, OUI_Subtype; ++ u8 *pframe = precv_frame->rx_data; ++ uint len = precv_frame->len; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("%s\n", __func__); ++ ++ /* check RA matches or not */ ++ if (memcmp(myid(&padapter->eeprompriv), GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */ ++ return _SUCCESS; ++ ++ frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ category = frame_body[0]; ++ if (category != RTW_WLAN_CATEGORY_P2P) ++ return _SUCCESS; ++ ++ if (be32_to_cpu(*((__be32 *)(frame_body + 1))) != P2POUI) ++ return _SUCCESS; ++ ++ len -= sizeof(struct rtw_ieee80211_hdr_3addr); ++ OUI_Subtype = frame_body[5]; ++ ++ switch (OUI_Subtype) { ++ case P2P_NOTICE_OF_ABSENCE: ++ break; ++ case P2P_PRESENCE_REQUEST: ++ process_p2p_presence_req(pwdinfo, pframe, len); ++ break; ++ case P2P_PRESENCE_RESPONSE: ++ break; ++ case P2P_GO_DISC_REQUEST: ++ break; ++ default: ++ break; ++ } ++#endif /* CONFIG_88EU_P2P */ ++ return _SUCCESS; ++} ++ ++unsigned int OnAction(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ int i; ++ unsigned char category; ++ struct action_handler *ptable; ++ unsigned char *frame_body; ++ u8 *pframe = precv_frame->rx_data; ++ ++ frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ category = frame_body[0]; ++ ++ for (i = 0; i < sizeof(OnAction_tbl) / sizeof(struct action_handler); i++) { ++ ptable = &OnAction_tbl[i]; ++ if (category == ptable->num) ++ ptable->func(padapter, precv_frame); ++ } ++ return _SUCCESS; ++} ++ ++unsigned int DoReserved(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ return _SUCCESS; ++} ++ ++struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv) ++{ ++ struct xmit_frame *pmgntframe; ++ struct xmit_buf *pxmitbuf; ++ ++ pmgntframe = rtw_alloc_xmitframe(pxmitpriv); ++ if (!pmgntframe) { ++ DBG_88E("%s, alloc xmitframe fail\n", __func__); ++ return NULL; ++ } ++ ++ pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv); ++ if (!pxmitbuf) { ++ DBG_88E("%s, alloc xmitbuf fail\n", __func__); ++ rtw_free_xmitframe(pxmitpriv, pmgntframe); ++ return NULL; ++ } ++ pmgntframe->frame_tag = MGNT_FRAMETAG; ++ pmgntframe->pxmitbuf = pxmitbuf; ++ pmgntframe->buf_addr = pxmitbuf->pbuf; ++ pxmitbuf->priv_data = pmgntframe; ++ return pmgntframe; ++} ++ ++/**************************************************************************** ++ ++Following are some TX fuctions for WiFi MLME ++ ++*****************************************************************************/ ++ ++void update_mgnt_tx_rate(struct adapter *padapter, u8 rate) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ pmlmeext->tx_rate = rate; ++ DBG_88E("%s(): rate = %x\n", __func__, rate); ++} ++ ++void update_mgntframe_attrib(struct adapter *padapter, struct pkt_attrib *pattrib) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib)); ++ ++ pattrib->hdrlen = 24; ++ pattrib->nr_frags = 1; ++ pattrib->priority = 7; ++ pattrib->mac_id = 0; ++ pattrib->qsel = 0x12; ++ ++ pattrib->pktlen = 0; ++ ++ if (pmlmeext->cur_wireless_mode & WIRELESS_11B) ++ pattrib->raid = 6;/* b mode */ ++ else ++ pattrib->raid = 5;/* a/g mode */ ++ ++ pattrib->encrypt = _NO_PRIVACY_; ++ pattrib->bswenc = false; ++ ++ pattrib->qos_en = false; ++ pattrib->ht_en = false; ++ pattrib->bwmode = HT_CHANNEL_WIDTH_20; ++ pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ pattrib->sgi = false; ++ ++ pattrib->seqnum = pmlmeext->mgnt_seq; ++ ++ pattrib->retry_ctrl = true; ++} ++ ++void dump_mgntframe(struct adapter *padapter, struct xmit_frame *pmgntframe) ++{ ++ if (padapter->bSurpriseRemoved || padapter->bDriverStopped) ++ return; ++ ++ rtw_hal_mgnt_xmit(padapter, pmgntframe); ++} ++ ++s32 dump_mgntframe_and_wait(struct adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms) ++{ ++ s32 ret = _FAIL; ++ struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf; ++ struct submit_ctx sctx; ++ ++ if (padapter->bSurpriseRemoved || padapter->bDriverStopped) ++ return ret; ++ ++ rtw_sctx_init(&sctx, timeout_ms); ++ pxmitbuf->sctx = &sctx; ++ ++ ret = rtw_hal_mgnt_xmit(padapter, pmgntframe); ++ ++ if (ret == _SUCCESS) ++ ret = rtw_sctx_wait(&sctx); ++ ++ return ret; ++} ++ ++s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmgntframe) ++{ ++ s32 ret = _FAIL; ++ u32 timeout_ms = 500;/* 500ms */ ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ if (padapter->bSurpriseRemoved || padapter->bDriverStopped) ++ return -1; ++ ++ _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL); ++ pxmitpriv->ack_tx = true; ++ ++ pmgntframe->ack_report = 1; ++ if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) { ++ ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms); ++ } ++ ++ pxmitpriv->ack_tx = false; ++ _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL); ++ ++ return ret; ++} ++ ++static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode) ++{ ++ u8 *ssid_ie; ++ int ssid_len_ori; ++ int len_diff = 0; ++ ++ ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len); ++ ++ if (ssid_ie && ssid_len_ori > 0) { ++ switch (hidden_ssid_mode) { ++ case 1: { ++ u8 *next_ie = ssid_ie + 2 + ssid_len_ori; ++ u32 remain_len = 0; ++ ++ remain_len = ies_len - (next_ie - ies); ++ ++ ssid_ie[1] = 0; ++ memcpy(ssid_ie + 2, next_ie, remain_len); ++ len_diff -= ssid_len_ori; ++ ++ break; ++ } ++ case 2: ++ memset(&ssid_ie[2], 0, ssid_len_ori); ++ break; ++ default: ++ break; ++ } ++ } ++ ++ return len_diff; ++} ++ ++void issue_beacon(struct adapter *padapter, int timeout_ms) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ unsigned int rate_len; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) { ++ DBG_88E("%s, alloc mgnt frame fail\n", __func__); ++ return; ++ } ++#if defined(CONFIG_88EU_AP_MODE) ++ spin_lock_bh(&pmlmepriv->bcn_update_lock); ++#endif /* if defined (CONFIG_88EU_AP_MODE) */ ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ pattrib->qsel = 0x10; ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); ++ /* pmlmeext->mgnt_seq++; */ ++ SetFrameSubType(pframe, WIFI_BEACON); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { ++#ifdef CONFIG_88EU_P2P ++ /* for P2P : Primary Device Type & Device Name */ ++ u32 wpsielen = 0, insert_len = 0; ++ u8 *wpsie = NULL; ++ wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen); ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) { ++ uint wps_offset, remainder_ielen; ++ u8 *premainder_ie, *pframe_wscie; ++ ++ wps_offset = (uint)(wpsie - cur_network->IEs); ++ premainder_ie = wpsie + wpsielen; ++ remainder_ielen = cur_network->IELength - wps_offset - wpsielen; ++ pframe_wscie = pframe + wps_offset; ++ memcpy(pframe, cur_network->IEs, wps_offset + wpsielen); ++ pframe += (wps_offset + wpsielen); ++ pattrib->pktlen += (wps_offset + wpsielen); ++ ++ /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */ ++ /* Primary Device Type */ ++ /* Type: */ ++ *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE); ++ insert_len += 2; ++ ++ /* Length: */ ++ *(__be16 *)(pframe + insert_len) = cpu_to_be16(0x0008); ++ insert_len += 2; ++ ++ /* Value: */ ++ /* Category ID */ ++ *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); ++ insert_len += 2; ++ ++ /* OUI */ ++ *(__be32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI); ++ insert_len += 4; ++ ++ /* Sub Category ID */ ++ *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); ++ insert_len += 2; ++ ++ /* Device Name */ ++ /* Type: */ ++ *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); ++ insert_len += 2; ++ ++ /* Length: */ ++ *(__be16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len); ++ insert_len += 2; ++ ++ /* Value: */ ++ memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len); ++ insert_len += pwdinfo->device_name_len; ++ ++ /* update wsc ie length */ ++ *(pframe_wscie + 1) = (wpsielen - 2) + insert_len; ++ ++ /* pframe move to end */ ++ pframe += insert_len; ++ pattrib->pktlen += insert_len; ++ ++ /* copy remainder_ie to pframe */ ++ memcpy(pframe, premainder_ie, remainder_ielen); ++ pframe += remainder_ielen; ++ pattrib->pktlen += remainder_ielen; ++ } else ++#endif /* CONFIG_88EU_P2P */ ++ { ++ int len_diff; ++ memcpy(pframe, cur_network->IEs, cur_network->IELength); ++ len_diff = update_hidden_ssid( ++ pframe + _BEACON_IE_OFFSET_ ++ , cur_network->IELength - _BEACON_IE_OFFSET_ ++ , pmlmeinfo->hidden_ssid_mode ++ ); ++ pframe += (cur_network->IELength + len_diff); ++ pattrib->pktlen += (cur_network->IELength + len_diff); ++ } ++ ++ { ++ u8 *wps_ie; ++ uint wps_ielen; ++ u8 sr = 0; ++ wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, ++ pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen); ++ if (wps_ie && wps_ielen > 0) ++ rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL); ++ if (sr != 0) ++ set_fwstate(pmlmepriv, WIFI_UNDER_WPS); ++ else ++ _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS); ++ } ++ ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ u32 len; ++ len = build_beacon_p2p_ie(pwdinfo, pframe); ++ ++ pframe += len; ++ pattrib->pktlen += len; ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ goto _issue_bcn; ++ } ++ ++ /* below for ad-hoc mode */ ++ ++ /* timestamp will be inserted by hardware */ ++ pframe += 8; ++ pattrib->pktlen += 8; ++ ++ /* beacon interval: 2 bytes */ ++ ++ memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); ++ ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* capability info: 2 bytes */ ++ ++ memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); ++ ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* SSID */ ++ pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen); ++ ++ /* supported rates... */ ++ rate_len = rtw_get_rateset_len(cur_network->SupportedRates); ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen); ++ ++ /* DS parameter set */ ++ pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&cur_network->Configuration.DSConfig, &pattrib->pktlen); ++ ++ { ++ u8 erpinfo = 0; ++ u32 ATIMWindow; ++ /* IBSS Parameter Set... */ ++ ATIMWindow = 0; ++ pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen); ++ ++ /* ERP IE */ ++ pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen); ++ } ++ ++ /* EXTERNDED SUPPORTED RATE */ ++ if (rate_len > 8) ++ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen); ++ /* todo:HT for adhoc */ ++_issue_bcn: ++ ++#if defined(CONFIG_88EU_AP_MODE) ++ pmlmepriv->update_bcn = false; ++ ++ spin_unlock_bh(&pmlmepriv->bcn_update_lock); ++#endif /* if defined (CONFIG_88EU_AP_MODE) */ ++ ++ if ((pattrib->pktlen + TXDESC_SIZE) > 512) { ++ DBG_88E("beacon frame too large\n"); ++ return; ++ } ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ /* DBG_88E("issue bcn_sz=%d\n", pattrib->last_txcmdsz); */ ++ if (timeout_ms > 0) ++ dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms); ++ else ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ unsigned char *mac, *bssid; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++#if defined(CONFIG_88EU_AP_MODE) ++ u8 *pwps_ie; ++ uint wps_ielen; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++#endif /* if defined (CONFIG_88EU_AP_MODE) */ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ unsigned int rate_len; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) { ++ DBG_88E("%s, alloc mgnt frame fail\n", __func__); ++ return; ++ } ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ mac = myid(&padapter->eeprompriv); ++ bssid = cur_network->MacAddress; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, mac, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, bssid, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(fctrl, WIFI_PROBERSP); ++ ++ pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = pattrib->hdrlen; ++ pframe += pattrib->hdrlen; ++ ++ if (cur_network->IELength > MAX_IE_SZ) ++ return; ++ ++#if defined(CONFIG_88EU_AP_MODE) ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { ++ pwps_ie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wps_ielen); ++ ++ /* inerset & update wps_probe_resp_ie */ ++ if (pmlmepriv->wps_probe_resp_ie && pwps_ie && wps_ielen > 0) { ++ uint wps_offset, remainder_ielen; ++ u8 *premainder_ie; ++ ++ wps_offset = (uint)(pwps_ie - cur_network->IEs); ++ ++ premainder_ie = pwps_ie + wps_ielen; ++ ++ remainder_ielen = cur_network->IELength - wps_offset - wps_ielen; ++ ++ memcpy(pframe, cur_network->IEs, wps_offset); ++ pframe += wps_offset; ++ pattrib->pktlen += wps_offset; ++ ++ wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];/* to get ie data len */ ++ if ((wps_offset + wps_ielen + 2) <= MAX_IE_SZ) { ++ memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen + 2); ++ pframe += wps_ielen + 2; ++ pattrib->pktlen += wps_ielen + 2; ++ } ++ ++ if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) { ++ memcpy(pframe, premainder_ie, remainder_ielen); ++ pframe += remainder_ielen; ++ pattrib->pktlen += remainder_ielen; ++ } ++ } else { ++ memcpy(pframe, cur_network->IEs, cur_network->IELength); ++ pframe += cur_network->IELength; ++ pattrib->pktlen += cur_network->IELength; ++ } ++ } else ++#endif ++ { ++ /* timestamp will be inserted by hardware */ ++ pframe += 8; ++ pattrib->pktlen += 8; ++ ++ /* beacon interval: 2 bytes */ ++ ++ memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); ++ ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* capability info: 2 bytes */ ++ ++ memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); ++ ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* below for ad-hoc mode */ ++ ++ /* SSID */ ++ pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen); ++ ++ /* supported rates... */ ++ rate_len = rtw_get_rateset_len(cur_network->SupportedRates); ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen); ++ ++ /* DS parameter set */ ++ pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&cur_network->Configuration.DSConfig, &pattrib->pktlen); ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { ++ u8 erpinfo = 0; ++ u32 ATIMWindow; ++ /* IBSS Parameter Set... */ ++ /* ATIMWindow = cur->Configuration.ATIMWindow; */ ++ ATIMWindow = 0; ++ pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen); ++ ++ /* ERP IE */ ++ pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen); ++ } ++ ++ /* EXTERNDED SUPPORTED RATE */ ++ if (rate_len > 8) ++ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen); ++ /* todo:HT for adhoc */ ++ } ++ ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && is_valid_p2p_probereq) { ++ u32 len; ++ len = build_probe_resp_p2p_ie(pwdinfo, pframe); ++ ++ pframe += len; ++ pattrib->pktlen += len; ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static int _issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, int wait_ack) ++{ ++ int ret = _FAIL; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ unsigned char *mac; ++ unsigned char bssrate[NumRates]; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ int bssrate_len = 0; ++ u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ goto exit; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ mac = myid(&padapter->eeprompriv); ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ if (da) { ++ /* unicast probe request frame */ ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, da, ETH_ALEN); ++ } else { ++ /* broadcast probe request frame */ ++ memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN); ++ } ++ ++ memcpy(pwlanhdr->addr2, mac, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_PROBEREQ); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ if (pssid) ++ pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &pattrib->pktlen); ++ else ++ pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pattrib->pktlen); ++ ++ get_rate_set(padapter, bssrate, &bssrate_len); ++ ++ if (bssrate_len > 8) { ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &pattrib->pktlen); ++ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, bssrate_len - 8, bssrate + 8, &pattrib->pktlen); ++ } else { ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &pattrib->pktlen); ++ } ++ ++ /* add wps_ie for wps2.0 */ ++ if (pmlmepriv->wps_probe_req_ie_len > 0 && pmlmepriv->wps_probe_req_ie) { ++ memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len); ++ pframe += pmlmepriv->wps_probe_req_ie_len; ++ pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len; ++ } ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ if (wait_ack) { ++ ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); ++ } else { ++ dump_mgntframe(padapter, pmgntframe); ++ ret = _SUCCESS; ++ } ++ ++exit: ++ return ret; ++} ++ ++inline void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da) ++{ ++ _issue_probereq(padapter, pssid, da, false); ++} ++ ++int issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, ++ int try_cnt, int wait_ms) ++{ ++ int ret; ++ int i = 0; ++ u32 start = jiffies; ++ ++ do { ++ ret = _issue_probereq(padapter, pssid, da, wait_ms > 0); ++ ++ i++; ++ ++ if (padapter->bDriverStopped || padapter->bSurpriseRemoved) ++ break; ++ ++ if (i < try_cnt && wait_ms > 0 && ret == _FAIL) ++ msleep(wait_ms); ++ ++ } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); ++ ++ if (ret != _FAIL) { ++ ret = _SUCCESS; ++ goto exit; ++ } ++ ++ if (try_cnt && wait_ms) { ++ if (da) ++ DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ else ++ DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ } ++exit: ++ return ret; ++} ++ ++/* if psta == NULL, indiate we are station(client) now... */ ++void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short status) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ unsigned int val32; ++ u16 val16; ++#ifdef CONFIG_88EU_AP_MODE ++ __le16 le_val16; ++#endif ++ int use_shared_key = 0; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_AUTH); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ if (psta) {/* for AP mode */ ++#ifdef CONFIG_88EU_AP_MODE ++ ++ memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN); ++ ++ /* setting auth algo number */ ++ val16 = (u16)psta->authalg; ++ ++ if (status != _STATS_SUCCESSFUL_) ++ val16 = 0; ++ ++ if (val16) { ++ le_val16 = cpu_to_le16(val16); ++ use_shared_key = 1; ++ } else { ++ le_val16 = 0; ++ } ++ ++ pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_val16, &pattrib->pktlen); ++ ++ /* setting auth seq number */ ++ val16 = (u16)psta->auth_seq; ++ le_val16 = cpu_to_le16(val16); ++ pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_val16, &pattrib->pktlen); ++ ++ /* setting status code... */ ++ val16 = status; ++ le_val16 = cpu_to_le16(val16); ++ pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_val16, &pattrib->pktlen); ++ ++ /* added challenging text... */ ++ if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) ++ pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &pattrib->pktlen); ++#endif ++ } else { ++ __le32 le_tmp32; ++ __le16 le_tmp16; ++ memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ /* setting auth algo number */ ++ val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0;/* 0:OPEN System, 1:Shared key */ ++ if (val16) ++ use_shared_key = 1; ++ ++ /* setting IV for auth seq #3 */ ++ if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) { ++ val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30)); ++ le_tmp32 = cpu_to_le32(val32); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&le_tmp32, &pattrib->pktlen); ++ ++ pattrib->iv_len = 4; ++ } ++ ++ le_tmp16 = cpu_to_le16(val16); ++ pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_tmp16, &pattrib->pktlen); ++ ++ /* setting auth seq number */ ++ val16 = pmlmeinfo->auth_seq; ++ le_tmp16 = cpu_to_le16(val16); ++ pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_tmp16, &pattrib->pktlen); ++ ++ /* setting status code... */ ++ le_tmp16 = cpu_to_le16(status); ++ pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_tmp16, &pattrib->pktlen); ++ ++ /* then checking to see if sending challenging text... */ ++ if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) { ++ pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &pattrib->pktlen); ++ ++ SetPrivacy(fctrl); ++ ++ pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pattrib->encrypt = _WEP40_; ++ ++ pattrib->icv_len = 4; ++ ++ pattrib->pktlen += pattrib->icv_len; ++ } ++ } ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ rtw_wep_encrypt(padapter, (u8 *)pmgntframe); ++ DBG_88E("%s\n", __func__); ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type) ++{ ++#ifdef CONFIG_88EU_AP_MODE ++ struct xmit_frame *pmgntframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ struct pkt_attrib *pattrib; ++ unsigned char *pbuf, *pframe; ++ unsigned short val; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; ++ u8 *ie = pnetwork->IEs; ++ __le16 lestatus, leval; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ DBG_88E("%s\n", __func__); ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN); ++ memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP)) ++ SetFrameSubType(pwlanhdr, pkt_type); ++ else ++ return; ++ ++ pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen += pattrib->hdrlen; ++ pframe += pattrib->hdrlen; ++ ++ /* capability */ ++ val = *(unsigned short *)rtw_get_capability_from_ie(ie); ++ ++ pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_, (unsigned char *)&val, &pattrib->pktlen); ++ ++ lestatus = cpu_to_le16(status); ++ pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&lestatus, &pattrib->pktlen); ++ ++ leval = cpu_to_le16(pstat->aid | BIT(14) | BIT(15)); ++ pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_, (unsigned char *)&leval, &pattrib->pktlen); ++ ++ if (pstat->bssratelen <= 8) { ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &pattrib->pktlen); ++ } else { ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &pattrib->pktlen); ++ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, pstat->bssratelen - 8, pstat->bssrateset + 8, &pattrib->pktlen); ++ } ++ ++ if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) { ++ uint ie_len = 0; ++ ++ /* FILL HT CAP INFO IE */ ++ pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); ++ if (pbuf && ie_len > 0) { ++ memcpy(pframe, pbuf, ie_len + 2); ++ pframe += (ie_len + 2); ++ pattrib->pktlen += (ie_len + 2); ++ } ++ ++ /* FILL HT ADD INFO IE */ ++ pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); ++ if (pbuf && ie_len > 0) { ++ memcpy(pframe, pbuf, ie_len + 2); ++ pframe += (ie_len + 2); ++ pattrib->pktlen += (ie_len + 2); ++ } ++ } ++ ++ /* FILL WMM IE */ ++ if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) { ++ uint ie_len = 0; ++ unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; ++ ++ for (pbuf = ie + _BEACON_IE_OFFSET_;; pbuf += (ie_len + 2)) { ++ pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))); ++ if (pbuf && !memcmp(pbuf + 2, WMM_PARA_IE, 6)) { ++ memcpy(pframe, pbuf, ie_len + 2); ++ pframe += (ie_len + 2); ++ pattrib->pktlen += (ie_len + 2); ++ break; ++ } ++ ++ if (!pbuf || ie_len == 0) ++ break; ++ } ++ } ++ ++ if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &pattrib->pktlen); ++ ++ /* add WPS IE ie for wps 2.0 */ ++ if (pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len > 0) { ++ memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len); ++ ++ pframe += pmlmepriv->wps_assoc_resp_ie_len; ++ pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len; ++ } ++ ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device)) { ++ u32 len; ++ ++ len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code); ++ ++ pframe += len; ++ pattrib->pktlen += len; ++ } ++#endif /* CONFIG_88EU_P2P */ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ dump_mgntframe(padapter, pmgntframe); ++#endif ++} ++ ++void issue_assocreq(struct adapter *padapter) ++{ ++ int ret = _FAIL; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe, *p; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ __le16 le_tmp; ++ unsigned int i, j, ie_len, index = 0; ++ unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates]; ++ struct ndis_802_11_var_ie *pIE; ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ int bssrate_len = 0, sta_bssrate_len = 0; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 p2pie[255] = { 0x00 }; ++ u16 p2pielen = 0; ++#endif /* CONFIG_88EU_P2P */ ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ goto exit; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ASSOCREQ); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ /* caps */ ++ ++ memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); ++ ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* listen interval */ ++ /* todo: listen interval for power saving */ ++ le_tmp = cpu_to_le16(3); ++ memcpy(pframe, (unsigned char *)&le_tmp, 2); ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* SSID */ ++ pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &pattrib->pktlen); ++ ++ /* supported rate & extended supported rate */ ++ ++ /* Check if the AP's supported rates are also supported by STA. */ ++ get_rate_set(padapter, sta_bssrate, &sta_bssrate_len); ++ ++ if (pmlmeext->cur_channel == 14)/* for JAPAN, channel 14 can only uses B Mode(CCK) */ ++ sta_bssrate_len = 4; ++ ++ for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { ++ if (pmlmeinfo->network.SupportedRates[i] == 0) ++ break; ++ DBG_88E("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]); ++ } ++ ++ for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { ++ if (pmlmeinfo->network.SupportedRates[i] == 0) ++ break; ++ ++ /* Check if the AP's supported rates are also supported by STA. */ ++ for (j = 0; j < sta_bssrate_len; j++) { ++ /* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */ ++ if ((pmlmeinfo->network.SupportedRates[i] | IEEE80211_BASIC_RATE_MASK) ++ == (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) ++ break; ++ } ++ ++ if (j == sta_bssrate_len) { ++ /* the rate is not supported by STA */ ++ DBG_88E("%s(): the rate[%d]=%02X is not supported by STA!\n", __func__, i, pmlmeinfo->network.SupportedRates[i]); ++ } else { ++ /* the rate is supported by STA */ ++ bssrate[index++] = pmlmeinfo->network.SupportedRates[i]; ++ } ++ } ++ ++ bssrate_len = index; ++ DBG_88E("bssrate_len=%d\n", bssrate_len); ++ ++ if (bssrate_len == 0) { ++ rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); ++ rtw_free_xmitframe(pxmitpriv, pmgntframe); ++ goto exit; /* don't connect to AP if no joint supported rate */ ++ } ++ ++ if (bssrate_len > 8) { ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &pattrib->pktlen); ++ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, bssrate_len - 8, bssrate + 8, &pattrib->pktlen); ++ } else { ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &pattrib->pktlen); ++ } ++ ++ /* RSN */ ++ p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(struct ndis_802_11_fixed_ie)), _RSN_IE_2_, &ie_len, (pmlmeinfo->network.IELength - sizeof(struct ndis_802_11_fixed_ie))); ++ if (p) ++ pframe = rtw_set_ie(pframe, _RSN_IE_2_, ie_len, p + 2, &pattrib->pktlen); ++ ++ /* HT caps */ ++ if (padapter->mlmepriv.htpriv.ht_option) { ++ p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(struct ndis_802_11_fixed_ie)), _HT_CAPABILITY_IE_, &ie_len, (pmlmeinfo->network.IELength - sizeof(struct ndis_802_11_fixed_ie))); ++ if (p && !is_ap_in_tkip(padapter)) { ++ memcpy(&pmlmeinfo->HT_caps, p + 2, sizeof(struct HT_caps_element)); ++ ++ /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */ ++ if (pregpriv->cbw40_enable == 0) ++ pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= cpu_to_le16(~(BIT(6) | BIT(1))); ++ else ++ pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(BIT(1)); ++ ++ /* todo: disable SM power save mode */ ++ pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x000c); ++ ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ switch (rf_type) { ++ case RF_1T1R: ++ if (pregpriv->rx_stbc) ++ pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);/* RX STBC One spatial stream */ ++ memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16); ++ break; ++ case RF_2T2R: ++ case RF_1T2R: ++ default: ++ if ((pregpriv->rx_stbc == 0x3) ||/* enable for 2.4/5 GHz */ ++ ((pmlmeext->cur_wireless_mode & WIRELESS_11_24N) && (pregpriv->rx_stbc == 0x1)) || /* enable for 2.4GHz */ ++ (pregpriv->wifi_spec == 1)) { ++ DBG_88E("declare supporting RX STBC\n"); ++ pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);/* RX STBC two spatial stream */ ++ } ++ memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16); ++ break; ++ } ++ pframe = rtw_set_ie(pframe, _HT_CAPABILITY_IE_, ie_len, (u8 *)(&pmlmeinfo->HT_caps), &pattrib->pktlen); ++ } ++ } ++ ++ /* vendor specific IE, such as WPA, WMM, WPS */ ++ for (i = sizeof(struct ndis_802_11_fixed_ie); i < pmlmeinfo->network.IELength;) { ++ pIE = (struct ndis_802_11_var_ie *)(pmlmeinfo->network.IEs + i); ++ ++ switch (pIE->ElementID) { ++ case _VENDOR_SPECIFIC_IE_: ++ if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) || ++ (!memcmp(pIE->data, WMM_OUI, 4)) || ++ (!memcmp(pIE->data, WPS_OUI, 4))) { ++ if (!padapter->registrypriv.wifi_spec) { ++ /* Commented by Kurt 20110629 */ ++ /* In some older APs, WPS handshake */ ++ /* would be fail if we append vender extensions informations to AP */ ++ if (!memcmp(pIE->data, WPS_OUI, 4)) ++ pIE->Length = 14; ++ } ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, pIE->Length, pIE->data, &pattrib->pktlen); ++ } ++ break; ++ default: ++ break; ++ } ++ i += (pIE->Length + 2); ++ } ++ ++ if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &pattrib->pktlen); ++ ++#ifdef CONFIG_88EU_P2P ++ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) { ++ /* Should add the P2P IE in the association request frame. */ ++ /* P2P OUI */ ++ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20101109 */ ++ /* According to the P2P Specification, the association request frame should contain 3 P2P attributes */ ++ /* 1. P2P Capability */ ++ /* 2. Extended Listen Timing */ ++ /* 3. Device Info */ ++ /* Commented by Albert 20110516 */ ++ /* 4. P2P Interface */ ++ ++ /* P2P Capability */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CAPABILITY; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT; ++ ++ /* Group Capability Bitmap, 1 byte */ ++ if (pwdinfo->persistent_supported) ++ p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; ++ else ++ p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT; ++ ++ /* Extended Listen Timing */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Availability Period */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF); ++ p2pielen += 2; ++ ++ /* Availability Interval */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF); ++ p2pielen += 2; ++ ++ /* Device Info */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO; ++ ++ /* Length: */ ++ /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */ ++ /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address */ ++ memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Config Method */ ++ /* This field should be big endian. Noted by P2P specification. */ ++ if ((pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN) || ++ (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN)) ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY); ++ else ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_PBC); ++ ++ p2pielen += 2; ++ ++ /* Primary Device Type */ ++ /* Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); ++ p2pielen += 2; ++ ++ /* OUI */ ++ *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI); ++ p2pielen += 4; ++ ++ /* Sub Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); ++ p2pielen += 2; ++ ++ /* Number of Secondary Device Types */ ++ p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */ ++ ++ /* Device Name */ ++ /* Type: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); ++ p2pielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ p2pielen += pwdinfo->device_name_len; ++ ++ /* P2P Interface */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_INTERFACE; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x000D); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); /* P2P Device Address */ ++ p2pielen += ETH_ALEN; ++ ++ p2pie[p2pielen++] = 1; /* P2P Interface Address Count */ ++ ++ memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); /* P2P Interface Address List */ ++ p2pielen += ETH_ALEN; ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen); ++ } ++ ++#endif /* CONFIG_88EU_P2P */ ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ dump_mgntframe(padapter, pmgntframe); ++ ++ ret = _SUCCESS; ++ ++exit: ++ if (ret == _SUCCESS) ++ rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen); ++ else ++ kfree(pmlmepriv->assoc_req); ++} ++ ++/* when wait_ack is ture, this function shoule be called at process context */ ++static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack) ++{ ++ int ret = _FAIL; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv; ++ struct mlme_ext_priv *pmlmeext; ++ struct mlme_ext_info *pmlmeinfo; ++ ++ if (!padapter) ++ goto exit; ++ ++ pxmitpriv = &padapter->xmitpriv; ++ pmlmeext = &padapter->mlmeextpriv; ++ pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ goto exit; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ pattrib->retry_ctrl = false; ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) ++ SetFrDs(fctrl); ++ else if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) ++ SetToDs(fctrl); ++ ++ if (power_mode) ++ SetPwrMgt(fctrl); ++ ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_DATA_NULL); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ if (wait_ack) { ++ ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); ++ } else { ++ dump_mgntframe(padapter, pmgntframe); ++ ret = _SUCCESS; ++ } ++ ++exit: ++ return ret; ++} ++ ++/* when wait_ms > 0 , this function shoule be called at process context */ ++/* da == NULL for station mode */ ++int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms) ++{ ++ int ret; ++ int i = 0; ++ u32 start = jiffies; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ /* da == NULL, assum it's null data for sta to ap*/ ++ if (!da) ++ da = get_my_bssid(&pmlmeinfo->network); ++ ++ do { ++ ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0); ++ ++ i++; ++ ++ if (padapter->bDriverStopped || padapter->bSurpriseRemoved) ++ break; ++ ++ if (i < try_cnt && wait_ms > 0 && ret == _FAIL) ++ msleep(wait_ms); ++ } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); ++ ++ if (ret != _FAIL) { ++ ret = _SUCCESS; ++ goto exit; ++ } ++ ++ if (try_cnt && wait_ms) { ++ if (da) ++ DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ else ++ DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ } ++exit: ++ return ret; ++} ++ ++/* when wait_ack is ture, this function shoule be called at process context */ ++static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int wait_ack) ++{ ++ int ret = _FAIL; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ unsigned short *qc; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ DBG_88E("%s\n", __func__); ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ goto exit; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ pattrib->hdrlen += 2; ++ pattrib->qos_en = true; ++ pattrib->eosp = 1; ++ pattrib->ack_policy = 0; ++ pattrib->mdata = 0; ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) ++ SetFrDs(fctrl); ++ else if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) ++ SetToDs(fctrl); ++ ++ if (pattrib->mdata) ++ SetMData(fctrl); ++ ++ qc = (unsigned short *)(pframe + pattrib->hdrlen - 2); ++ ++ SetPriority(qc, tid); ++ ++ SetEOSP(qc, pattrib->eosp); ++ ++ SetAckpolicy(qc, pattrib->ack_policy); ++ ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_QOS_DATA_NULL); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ if (wait_ack) { ++ ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); ++ } else { ++ dump_mgntframe(padapter, pmgntframe); ++ ret = _SUCCESS; ++ } ++ ++exit: ++ return ret; ++} ++ ++/* when wait_ms > 0 , this function shoule be called at process context */ ++/* da == NULL for station mode */ ++int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms) ++{ ++ int ret; ++ int i = 0; ++ u32 start = jiffies; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ /* da == NULL, assum it's null data for sta to ap*/ ++ if (!da) ++ da = get_my_bssid(&pmlmeinfo->network); ++ ++ do { ++ ret = _issue_qos_nulldata(padapter, da, tid, wait_ms > 0); ++ ++ i++; ++ ++ if (padapter->bDriverStopped || padapter->bSurpriseRemoved) ++ break; ++ ++ if (i < try_cnt && wait_ms > 0 && ret == _FAIL) ++ msleep(wait_ms); ++ } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); ++ ++ if (ret != _FAIL) { ++ ret = _SUCCESS; ++ goto exit; ++ } ++ ++ if (try_cnt && wait_ms) { ++ if (da) ++ DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ else ++ DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ } ++exit: ++ return ret; ++} ++ ++static int _issue_deauth(struct adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ int ret = _FAIL; ++ __le16 le_tmp; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++#ifdef CONFIG_88EU_P2P ++ if (!(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) && (pwdinfo->rx_invitereq_info.scan_op_ch_only)) { ++ _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey); ++ _set_timer(&pwdinfo->reset_ch_sitesurvey, 10); ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ goto exit; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ pattrib->retry_ctrl = false; ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_DEAUTH); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ le_tmp = cpu_to_le16(reason); ++ pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_, (unsigned char *)&le_tmp, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ if (wait_ack) { ++ ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); ++ } else { ++ dump_mgntframe(padapter, pmgntframe); ++ ret = _SUCCESS; ++ } ++ ++exit: ++ return ret; ++} ++ ++int issue_deauth(struct adapter *padapter, unsigned char *da, unsigned short reason) ++{ ++ DBG_88E("%s to %pM\n", __func__, da); ++ return _issue_deauth(padapter, da, reason, false); ++} ++ ++int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason, int try_cnt, ++ int wait_ms) ++{ ++ int ret; ++ int i = 0; ++ u32 start = jiffies; ++ ++ do { ++ ret = _issue_deauth(padapter, da, reason, wait_ms > 0); ++ ++ i++; ++ ++ if (padapter->bDriverStopped || padapter->bSurpriseRemoved) ++ break; ++ ++ if (i < try_cnt && wait_ms > 0 && ret == _FAIL) ++ msleep(wait_ms); ++ } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); ++ ++ if (ret != _FAIL) { ++ ret = _SUCCESS; ++ goto exit; ++ } ++ ++ if (try_cnt && wait_ms) { ++ if (da) ++ DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ else ++ DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ } ++exit: ++ return ret; ++} ++ ++void issue_action_spct_ch_switch(struct adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ DBG_88E(FUNC_NDEV_FMT" ra =%pM, ch:%u, offset:%u\n", ++ FUNC_NDEV_ARG(padapter->pnetdev), ra, new_ch, ch_offset); ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */ ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); /* TA */ ++ memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */ ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ /* category, action */ ++ { ++ u8 category, action; ++ category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT; ++ action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH; ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ } ++ ++ pframe = rtw_set_ie_ch_switch(pframe, &pattrib->pktlen, 0, new_ch, 0); ++ pframe = rtw_set_ie_secondary_ch_offset(pframe, &pattrib->pktlen, ++ hal_ch_offset_to_secondary_ch_offset(ch_offset)); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status) ++{ ++ u8 category = RTW_WLAN_CATEGORY_BACK; ++ u16 start_seq; ++ u16 BA_para_set; ++ u16 reason_code; ++ u16 BA_timeout_value; ++ __le16 le_tmp; ++ u16 BA_starting_seqctrl = 0; ++ enum ht_cap_ampdu_factor max_rx_ampdu_factor; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ u8 *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct sta_info *psta; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ ++ DBG_88E("%s, category=%d, action=%d, status=%d\n", __func__, category, action, status); ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ /* memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */ ++ memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &(action), &pattrib->pktlen); ++ ++ if (category == 3) { ++ switch (action) { ++ case 0: /* ADDBA req */ ++ do { ++ pmlmeinfo->dialogToken++; ++ } while (pmlmeinfo->dialogToken == 0); ++ pframe = rtw_set_fixed_ie(pframe, 1, &pmlmeinfo->dialogToken, &pattrib->pktlen); ++ ++ BA_para_set = (0x1002 | ((status & 0xf) << 2)); /* immediate ack & 64 buffer size */ ++ le_tmp = cpu_to_le16(BA_para_set); ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen); ++ ++ BA_timeout_value = 5000;/* 5ms */ ++ le_tmp = cpu_to_le16(BA_timeout_value); ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen); ++ ++ psta = rtw_get_stainfo(pstapriv, raddr); ++ if (psta) { ++ start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07] & 0xfff) + 1; ++ ++ DBG_88E("BA_starting_seqctrl=%d for TID=%d\n", start_seq, status & 0x07); ++ ++ psta->BA_starting_seqctrl[status & 0x07] = start_seq; ++ ++ BA_starting_seqctrl = start_seq << 4; ++ } ++ le_tmp = cpu_to_le16(BA_starting_seqctrl); ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen); ++ break; ++ case 1: /* ADDBA rsp */ ++ pframe = rtw_set_fixed_ie(pframe, 1, &pmlmeinfo->ADDBA_req.dialog_token, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&status, &pattrib->pktlen); ++ BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f; ++ rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); ++ switch (max_rx_ampdu_factor) { ++ case MAX_AMPDU_FACTOR_64K: ++ BA_para_set |= 0x1000; /* 64 buffer size */ ++ break; ++ case MAX_AMPDU_FACTOR_32K: ++ BA_para_set |= 0x0800; /* 32 buffer size */ ++ break; ++ case MAX_AMPDU_FACTOR_16K: ++ BA_para_set |= 0x0400; /* 16 buffer size */ ++ break; ++ case MAX_AMPDU_FACTOR_8K: ++ BA_para_set |= 0x0200; /* 8 buffer size */ ++ break; ++ default: ++ BA_para_set |= 0x1000; /* 64 buffer size */ ++ break; ++ } ++ ++ if (pregpriv->ampdu_amsdu == 0)/* disabled */ ++ BA_para_set = BA_para_set & ~BIT(0); ++ else if (pregpriv->ampdu_amsdu == 1)/* enabled */ ++ BA_para_set = BA_para_set | BIT(0); ++ le_tmp = cpu_to_le16(BA_para_set); ++ ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeinfo->ADDBA_req.BA_timeout_value, &pattrib->pktlen); ++ break; ++ case 2:/* DELBA */ ++ BA_para_set = (status & 0x1F) << 3; ++ le_tmp = cpu_to_le16(BA_para_set); ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen); ++ ++ reason_code = 37;/* Requested from peer STA as it does not want to use the mechanism */ ++ le_tmp = cpu_to_le16(reason_code); ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen); ++ break; ++ default: ++ break; ++ } ++ } ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static void issue_action_BSSCoexistPacket(struct adapter *padapter) ++{ ++ struct list_head *plist, *phead; ++ unsigned char category, action; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct wlan_network *pnetwork = NULL; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ u8 InfoContent[16] = {0}; ++ u8 ICS[8][15]; ++ if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0)) ++ return; ++ ++ if (pmlmeinfo->bwmode_updated) ++ return; ++ ++ DBG_88E("%s\n", __func__); ++ ++ category = RTW_WLAN_CATEGORY_PUBLIC; ++ action = ACT_PUBLIC_BSSCOEXIST; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ ++ /* */ ++ if (pmlmepriv->num_FortyMHzIntolerant > 0) { ++ u8 iedata = 0; ++ ++ iedata |= BIT(2);/* 20 MHz BSS Width Request */ ++ ++ pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &pattrib->pktlen); ++ } ++ ++ /* */ ++ memset(ICS, 0, sizeof(ICS)); ++ if (pmlmepriv->num_sta_no_ht > 0) { ++ int i; ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ int len; ++ u8 *p; ++ struct wlan_bssid_ex *pbss_network; ++ ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ plist = plist->next; ++ ++ pbss_network = (struct wlan_bssid_ex *)&pnetwork->network; ++ ++ p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_); ++ if (!p || len == 0) { /* non-HT */ ++ if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14)) ++ continue; ++ ++ ICS[0][pbss_network->Configuration.DSConfig] = 1; ++ ++ if (ICS[0][0] == 0) ++ ICS[0][0] = 1; ++ } ++ } ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ for (i = 0; i < 8; i++) { ++ if (ICS[i][0] == 1) { ++ int j, k = 0; ++ ++ InfoContent[k] = i; ++ /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */ ++ k++; ++ ++ for (j = 1; j <= 14; j++) { ++ if (ICS[i][j] == 1) { ++ if (k < 16) { ++ InfoContent[k] = j; /* channel number */ ++ /* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */ ++ k++; ++ } ++ } ++ } ++ ++ pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &pattrib->pktlen); ++ } ++ } ++ } ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr) ++{ ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct sta_info *psta = NULL; ++ /* struct recv_reorder_ctrl *preorder_ctrl; */ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u16 tid; ++ ++ if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) ++ if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) ++ return _SUCCESS; ++ ++ psta = rtw_get_stainfo(pstapriv, addr); ++ if (!psta) ++ return _SUCCESS; ++ ++ if (initiator == 0) { /* recipient */ ++ for (tid = 0; tid < MAXTID; tid++) { ++ if (psta->recvreorder_ctrl[tid].enable) { ++ DBG_88E("rx agg disable tid(%d)\n", tid); ++ issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator) & 0x1F)); ++ psta->recvreorder_ctrl[tid].enable = false; ++ psta->recvreorder_ctrl[tid].indicate_seq = 0xffff; ++ } ++ } ++ } else if (initiator == 1) { /* originator */ ++ for (tid = 0; tid < MAXTID; tid++) { ++ if (psta->htpriv.agg_enable_bitmap & BIT(tid)) { ++ DBG_88E("tx agg disable tid(%d)\n", tid); ++ issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator) & 0x1F)); ++ psta->htpriv.agg_enable_bitmap &= ~BIT(tid); ++ psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); ++ } ++ } ++ } ++ ++ return _SUCCESS; ++} ++ ++unsigned int send_beacon(struct adapter *padapter) ++{ ++ u8 bxmitok = false; ++ int issue = 0; ++ int poll = 0; ++ ++ u32 start = jiffies; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL); ++ do { ++ issue_beacon(padapter, 100); ++ issue++; ++ do { ++ yield(); ++ rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok)); ++ poll++; ++ } while ((poll % 10) != 0 && !bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); ++ } while (!bxmitok && issue < 100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); ++ ++ if (padapter->bSurpriseRemoved || padapter->bDriverStopped) ++ return _FAIL; ++ if (!bxmitok) { ++ DBG_88E("%s fail! %u ms\n", __func__, rtw_get_passing_time_ms(start)); ++ return _FAIL; ++ } else { ++ u32 passing_time = rtw_get_passing_time_ms(start); ++ ++ if (passing_time > 100 || issue > 3) ++ DBG_88E("%s success, issue:%d, poll:%d, %u ms\n", __func__, issue, poll, rtw_get_passing_time_ms(start)); ++ return _SUCCESS; ++ } ++} ++ ++/**************************************************************************** ++ ++Following are some utitity fuctions for WiFi MLME ++ ++*****************************************************************************/ ++ ++void site_survey(struct adapter *padapter) ++{ ++ unsigned char survey_channel = 0, val8; ++ enum rt_scan_type ScanType = SCAN_PASSIVE; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u32 initialgain = 0; ++ ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ if ((pwdinfo->rx_invitereq_info.scan_op_ch_only) || (pwdinfo->p2p_info.scan_op_ch_only)) { ++ if (pwdinfo->rx_invitereq_info.scan_op_ch_only) { ++ survey_channel = pwdinfo->rx_invitereq_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx]; ++ } else { ++ survey_channel = pwdinfo->p2p_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx]; ++ } ++ ScanType = SCAN_ACTIVE; ++ } else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) { ++ /* Commented by Albert 2011/06/03 */ ++ /* The driver is in the find phase, it should go through the social channel. */ ++ int ch_set_idx; ++ survey_channel = pwdinfo->social_chan[pmlmeext->sitesurvey_res.channel_idx]; ++ ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, survey_channel); ++ if (ch_set_idx >= 0) ++ ScanType = pmlmeext->channel_set[ch_set_idx].ScanType; ++ else ++ ScanType = SCAN_ACTIVE; ++ } else ++#endif /* CONFIG_88EU_P2P */ ++ { ++ struct rtw_ieee80211_channel *ch; ++ if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) { ++ ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx]; ++ survey_channel = ch->hw_value; ++ ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE; ++ } ++ } ++ ++ if (survey_channel != 0) { ++ /* PAUSE 4-AC Queue when site_survey */ ++ /* rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */ ++ /* val8 |= 0x0f; */ ++ /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */ ++ if (pmlmeext->sitesurvey_res.channel_idx == 0) ++ set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ else ++ SelectChannel(padapter, survey_channel); ++ ++ if (ScanType == SCAN_ACTIVE) { /* obey the channel plan setting... */ ++ #ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || ++ rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) { ++ issue_probereq_p2p(padapter, NULL); ++ issue_probereq_p2p(padapter, NULL); ++ issue_probereq_p2p(padapter, NULL); ++ } else ++ #endif /* CONFIG_88EU_P2P */ ++ { ++ int i; ++ for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { ++ if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) { ++ /* todo: to issue two probe req??? */ ++ issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL); ++ /* msleep(SURVEY_TO>>1); */ ++ issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL); ++ } ++ } ++ ++ if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) { ++ /* todo: to issue two probe req??? */ ++ issue_probereq(padapter, NULL, NULL); ++ /* msleep(SURVEY_TO>>1); */ ++ issue_probereq(padapter, NULL, NULL); ++ } ++ } ++ } ++ ++ set_survey_timer(pmlmeext, pmlmeext->chan_scan_time); ++ } else { ++ /* channel number is 0 or this channel is not valid. */ ++ ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) { ++ if ((pwdinfo->rx_invitereq_info.scan_op_ch_only) || (pwdinfo->p2p_info.scan_op_ch_only)) { ++ /* Set the find_phase_state_exchange_cnt to P2P_FINDPHASE_EX_CNT. */ ++ /* This will let the following flow to run the scanning end. */ ++ rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX); ++ } ++ } ++ ++ if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) { ++ /* Set the P2P State to the listen state of find phase and set the current channel to the listen channel */ ++ set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN); ++ pmlmeext->sitesurvey_res.state = SCAN_DISABLE; ++ ++ initialgain = 0xff; /* restore RX GAIN */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); ++ /* turn on dynamic functions */ ++ Restore_DM_Func_Flag(padapter); ++ /* Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, true); */ ++ ++ _set_timer(&pwdinfo->find_phase_timer, (u32)((u32)(pwdinfo->listen_dwell) * 100)); ++ } else ++#endif /* CONFIG_88EU_P2P */ ++ { ++ /* 20100721:Interrupt scan operation here. */ ++ /* For SW antenna diversity before link, it needs to switch to another antenna and scan again. */ ++ /* It compares the scan result and select beter one to do connection. */ ++ if (rtw_hal_antdiv_before_linked(padapter)) { ++ pmlmeext->sitesurvey_res.bss_cnt = 0; ++ pmlmeext->sitesurvey_res.channel_idx = -1; ++ pmlmeext->chan_scan_time = SURVEY_TO / 2; ++ set_survey_timer(pmlmeext, pmlmeext->chan_scan_time); ++ return; ++ } ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) ++ rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); ++ rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE); ++#endif /* CONFIG_88EU_P2P */ ++ ++ pmlmeext->sitesurvey_res.state = SCAN_COMPLETE; ++ ++ /* switch back to the original channel */ ++ ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) ++ set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ else ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); ++#endif /* CONFIG_88EU_P2P */ ++ ++ /* flush 4-AC Queue after site_survey */ ++ /* val8 = 0; */ ++ /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */ ++ ++ /* config MSR */ ++ Set_MSR(padapter, (pmlmeinfo->state & 0x3)); ++ ++ initialgain = 0xff; /* restore RX GAIN */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); ++ /* turn on dynamic functions */ ++ Restore_DM_Func_Flag(padapter); ++ /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); */ ++ ++ if (is_client_associated_to_ap(padapter)) ++ issue_nulldata(padapter, NULL, 0, 3, 500); ++ ++ val8 = 0; /* survey done */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); ++ ++ report_surveydone_event(padapter); ++ ++ pmlmeext->chan_scan_time = SURVEY_TO; ++ pmlmeext->sitesurvey_res.state = SCAN_DISABLE; ++ ++ issue_action_BSSCoexistPacket(padapter); ++ issue_action_BSSCoexistPacket(padapter); ++ issue_action_BSSCoexistPacket(padapter); ++ } ++ } ++} ++ ++/* collect bss info from Beacon and Probe request/response frames. */ ++u8 collect_bss_info(struct adapter *padapter, struct recv_frame *precv_frame, struct wlan_bssid_ex *bssid) ++{ ++ int i; ++ u32 len; ++ u8 *p; ++ u16 val16, subtype; ++ u8 *pframe = precv_frame->rx_data; ++ u32 packet_len = precv_frame->len; ++ u8 ie_offset; ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ __le32 le32_tmp; ++ ++ len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ if (len > MAX_IE_SZ) ++ return _FAIL; ++ ++ memset(bssid, 0, sizeof(struct wlan_bssid_ex)); ++ ++ subtype = GetFrameSubType(pframe); ++ ++ if (subtype == WIFI_BEACON) { ++ bssid->Reserved[0] = 1; ++ ie_offset = _BEACON_IE_OFFSET_; ++ } else { ++ /* FIXME : more type */ ++ if (subtype == WIFI_PROBEREQ) { ++ ie_offset = _PROBEREQ_IE_OFFSET_; ++ bssid->Reserved[0] = 2; ++ } else if (subtype == WIFI_PROBERSP) { ++ ie_offset = _PROBERSP_IE_OFFSET_; ++ bssid->Reserved[0] = 3; ++ } else { ++ bssid->Reserved[0] = 0; ++ ie_offset = _FIXED_IE_LENGTH_; ++ } ++ } ++ ++ bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len; ++ ++ /* below is to copy the information element */ ++ bssid->IELength = len; ++ memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength); ++ ++ /* get the signal strength */ ++ bssid->Rssi = precv_frame->attrib.phy_info.recvpower; /* in dBM.raw data */ ++ bssid->PhyInfo.SignalQuality = precv_frame->attrib.phy_info.SignalQuality;/* in percentage */ ++ bssid->PhyInfo.SignalStrength = precv_frame->attrib.phy_info.SignalStrength;/* in percentage */ ++ rtw_hal_get_def_var(padapter, HAL_DEF_CURRENT_ANTENNA, &bssid->PhyInfo.Optimum_antenna); ++ ++ /* checking SSID */ ++ p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset); ++ if (!p) { ++ DBG_88E("marc: cannot find SSID for survey event\n"); ++ return _FAIL; ++ } ++ ++ if (*(p + 1)) { ++ if (len > NDIS_802_11_LENGTH_SSID) { ++ DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len); ++ return _FAIL; ++ } ++ memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1)); ++ bssid->Ssid.SsidLength = *(p + 1); ++ } else { ++ bssid->Ssid.SsidLength = 0; ++ } ++ ++ memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX); ++ ++ /* checking rate info... */ ++ i = 0; ++ p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset); ++ if (p) { ++ if (len > NDIS_802_11_LENGTH_RATES_EX) { ++ DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len); ++ return _FAIL; ++ } ++ memcpy(bssid->SupportedRates, (p + 2), len); ++ i = len; ++ } ++ ++ p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset); ++ if (p) { ++ if (len > (NDIS_802_11_LENGTH_RATES_EX - i)) { ++ DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len); ++ return _FAIL; ++ } ++ memcpy(bssid->SupportedRates + i, (p + 2), len); ++ } ++ ++ /* todo: */ ++ bssid->NetworkTypeInUse = Ndis802_11OFDM24; ++ ++ if (bssid->IELength < 12) ++ return _FAIL; ++ ++ /* Checking for DSConfig */ ++ p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset); ++ ++ bssid->Configuration.DSConfig = 0; ++ bssid->Configuration.Length = 0; ++ ++ if (p) { ++ bssid->Configuration.DSConfig = *(p + 2); ++ } else {/* In 5G, some ap do not have DSSET IE */ ++ /* checking HT info for channel */ ++ p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset); ++ if (p) { ++ struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2); ++ bssid->Configuration.DSConfig = HT_info->primary_channel; ++ } else { /* use current channel */ ++ bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter); ++ } ++ } ++ ++ memcpy(&le32_tmp, rtw_get_beacon_interval_from_ie(bssid->IEs), 2); ++ bssid->Configuration.BeaconPeriod = le32_to_cpu(le32_tmp); ++ ++ val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid); ++ ++ if (val16 & BIT(0)) { ++ bssid->InfrastructureMode = Ndis802_11Infrastructure; ++ memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN); ++ } else { ++ bssid->InfrastructureMode = Ndis802_11IBSS; ++ memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN); ++ } ++ ++ if (val16 & BIT(4)) ++ bssid->Privacy = 1; ++ else ++ bssid->Privacy = 0; ++ ++ bssid->Configuration.ATIMWindow = 0; ++ ++ /* 20/40 BSS Coexistence check */ ++ if ((pregistrypriv->wifi_spec == 1) && (!pmlmeinfo->bwmode_updated)) { ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset); ++ if (p && len > 0) { ++ struct HT_caps_element *pHT_caps; ++ pHT_caps = (struct HT_caps_element *)(p + 2); ++ ++ if (le16_to_cpu(pHT_caps->u.HT_cap_element.HT_caps_info) & BIT(14)) ++ pmlmepriv->num_FortyMHzIntolerant++; ++ } else { ++ pmlmepriv->num_sta_no_ht++; ++ } ++ } ++ ++ /* mark bss info receiving from nearby channel as SignalQuality 101 */ ++ if (bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter)) ++ bssid->PhyInfo.SignalQuality = 101; ++ return _SUCCESS; ++} ++ ++void start_create_ibss(struct adapter *padapter) ++{ ++ unsigned short caps; ++ u8 val8; ++ u8 join_type; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); ++ pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; ++ pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork); ++ ++ /* update wireless mode */ ++ update_wireless_mode(padapter); ++ ++ /* udpate capability */ ++ caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); ++ update_capinfo(padapter, caps); ++ if (caps & cap_IBSS) {/* adhoc master */ ++ val8 = 0xcf; ++ rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); ++ ++ /* switch channel */ ++ /* SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */ ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ ++ beacon_timing_control(padapter); ++ ++ /* set msr to WIFI_FW_ADHOC_STATE */ ++ pmlmeinfo->state = WIFI_FW_ADHOC_STATE; ++ Set_MSR(padapter, (pmlmeinfo->state & 0x3)); ++ ++ /* issue beacon */ ++ if (send_beacon(padapter) == _FAIL) { ++ report_join_res(padapter, -1); ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ } else { ++ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress); ++ join_type = 0; ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); ++ ++ report_join_res(padapter, 1); ++ pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; ++ rtw_indicate_connect(padapter); ++ } ++ } else { ++ DBG_88E("start_create_ibss, invalid cap:%x\n", caps); ++ return; ++ } ++ /* update bc/mc sta_info */ ++ update_bmc_sta(padapter); ++} ++ ++void start_clnt_join(struct adapter *padapter) ++{ ++ unsigned short caps; ++ u8 val8; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); ++ int beacon_timeout; ++ ++ pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; ++ pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork); ++ ++ /* update wireless mode */ ++ update_wireless_mode(padapter); ++ ++ /* udpate capability */ ++ caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); ++ update_capinfo(padapter, caps); ++ if (caps & cap_ESS) { ++ Set_MSR(padapter, WIFI_FW_STATION_STATE); ++ ++ val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); ++ ++ /* switch channel */ ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); ++ ++ /* here wait for receiving the beacon to start auth */ ++ /* and enable a timer */ ++ beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval); ++ set_link_timer(pmlmeext, beacon_timeout); ++ _set_timer(&padapter->mlmepriv.assoc_timer, ++ (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO * REASSOC_LIMIT) + beacon_timeout); ++ ++ pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE; ++ } else if (caps & cap_IBSS) { /* adhoc client */ ++ Set_MSR(padapter, WIFI_FW_ADHOC_STATE); ++ ++ val8 = 0xcf; ++ rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); ++ ++ /* switch channel */ ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); ++ ++ beacon_timing_control(padapter); ++ ++ pmlmeinfo->state = WIFI_FW_ADHOC_STATE; ++ ++ report_join_res(padapter, 1); ++ } else { ++ return; ++ } ++} ++ ++void start_clnt_auth(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ ++ pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL); ++ pmlmeinfo->state |= WIFI_FW_AUTH_STATE; ++ ++ pmlmeinfo->auth_seq = 1; ++ pmlmeinfo->reauth_count = 0; ++ pmlmeinfo->reassoc_count = 0; ++ pmlmeinfo->link_count = 0; ++ pmlmeext->retry = 0; ++ ++ /* Because of AP's not receiving deauth before */ ++ /* AP may: 1)not response auth or 2)deauth us after link is complete */ ++ /* issue deauth before issuing auth to deal with the situation */ ++ /* Commented by Albert 2012/07/21 */ ++ /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */ ++ issue_deauth(padapter, (&pmlmeinfo->network)->MacAddress, WLAN_REASON_DEAUTH_LEAVING); ++ ++ DBG_88E_LEVEL(_drv_info_, "start auth\n"); ++ issue_auth(padapter, NULL, 0); ++ ++ set_link_timer(pmlmeext, REAUTH_TO); ++} ++ ++void start_clnt_assoc(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ ++ pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE)); ++ pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE); ++ ++ issue_assocreq(padapter); ++ ++ set_link_timer(pmlmeext, REASSOC_TO); ++} ++ ++unsigned int receive_disconnect(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ /* check A3 */ ++ if (!(!memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) ++ return _SUCCESS; ++ ++ DBG_88E("%s\n", __func__); ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) { ++ if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ report_del_sta_event(padapter, MacAddr, reason); ++ } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) { ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ report_join_res(padapter, -2); ++ } ++ } ++ return _SUCCESS; ++} ++ ++static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid) ++{ ++ struct registry_priv *pregistrypriv; ++ struct mlme_ext_priv *pmlmeext; ++ struct rt_channel_info *chplan_new; ++ u8 channel; ++ u8 i; ++ ++ pregistrypriv = &padapter->registrypriv; ++ pmlmeext = &padapter->mlmeextpriv; ++ ++ /* Adjust channel plan by AP Country IE */ ++ if (pregistrypriv->enable80211d && ++ (!pmlmeext->update_channel_plan_by_ap_done)) { ++ u8 *ie, *p; ++ u32 len; ++ struct rt_channel_plan chplan_ap; ++ struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM]; ++ u8 country[4]; ++ u8 fcn; /* first channel number */ ++ u8 noc; /* number of channel */ ++ u8 j, k; ++ ++ ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); ++ if (!ie) ++ return; ++ if (len < 6) ++ return; ++ ie += 2; ++ p = ie; ++ ie += len; ++ ++ memset(country, 0, 4); ++ memcpy(country, p, 3); ++ p += 3; ++ ++ i = 0; ++ while ((ie - p) >= 3) { ++ fcn = *(p++); ++ noc = *(p++); ++ p++; ++ ++ for (j = 0; j < noc; j++) { ++ channel = fcn + j; ++ chplan_ap.Channel[i++] = channel; ++ } ++ } ++ chplan_ap.Len = i; ++ ++ memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta)); ++ ++ memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set)); ++ chplan_new = pmlmeext->channel_set; ++ ++ i = 0; ++ j = 0; ++ k = 0; ++ if (pregistrypriv->wireless_mode & WIRELESS_11G) { ++ do { ++ if ((i == MAX_CHANNEL_NUM) || ++ (chplan_sta[i].ChannelNum == 0)) ++ break; ++ ++ if (j == chplan_ap.Len) ++ break; ++ ++ if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) { ++ chplan_new[k].ChannelNum = chplan_ap.Channel[j]; ++ chplan_new[k].ScanType = SCAN_ACTIVE; ++ i++; ++ j++; ++ k++; ++ } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) { ++ chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; ++ chplan_new[k].ScanType = SCAN_PASSIVE; ++ i++; ++ k++; ++ } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) { ++ chplan_new[k].ChannelNum = chplan_ap.Channel[j]; ++ chplan_new[k].ScanType = SCAN_ACTIVE; ++ j++; ++ k++; ++ } ++ } while (1); ++ ++ /* change AP not support channel to Passive scan */ ++ while ((i < MAX_CHANNEL_NUM) && ++ (chplan_sta[i].ChannelNum != 0) && ++ (chplan_sta[i].ChannelNum <= 14)) { ++ chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; ++ chplan_new[k].ScanType = SCAN_PASSIVE; ++ i++; ++ k++; ++ } ++ ++ /* add channel AP supported */ ++ while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) { ++ chplan_new[k].ChannelNum = chplan_ap.Channel[j]; ++ chplan_new[k].ScanType = SCAN_ACTIVE; ++ j++; ++ k++; ++ } ++ } else { ++ /* keep original STA 2.4G channel plan */ ++ while ((i < MAX_CHANNEL_NUM) && ++ (chplan_sta[i].ChannelNum != 0) && ++ (chplan_sta[i].ChannelNum <= 14)) { ++ chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; ++ chplan_new[k].ScanType = chplan_sta[i].ScanType; ++ i++; ++ k++; ++ } ++ ++ /* skip AP 2.4G channel plan */ ++ while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) ++ j++; ++ } ++ ++ /* keep original STA 5G channel plan */ ++ while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) { ++ chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; ++ chplan_new[k].ScanType = chplan_sta[i].ScanType; ++ i++; ++ k++; ++ } ++ ++ pmlmeext->update_channel_plan_by_ap_done = 1; ++ } ++ ++ /* If channel is used by AP, set channel scan type to active */ ++ channel = bssid->Configuration.DSConfig; ++ chplan_new = pmlmeext->channel_set; ++ i = 0; ++ while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) { ++ if (chplan_new[i].ChannelNum == channel) { ++ if (chplan_new[i].ScanType == SCAN_PASSIVE) ++ chplan_new[i].ScanType = SCAN_ACTIVE; ++ break; ++ } ++ i++; ++ } ++} ++ ++/**************************************************************************** ++ ++Following are the functions to report events ++ ++*****************************************************************************/ ++ ++void report_survey_event(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ struct cmd_obj *pcmd_obj; ++ u8 *pevtcmd; ++ u32 cmdsz; ++ struct survey_event *psurvey_evt; ++ struct C2HEvent_Header *pc2h_evt_hdr; ++ struct mlme_ext_priv *pmlmeext; ++ struct cmd_priv *pcmdpriv; ++ /* u8 *pframe = precv_frame->rx_data; */ ++ /* uint len = precv_frame->len; */ ++ ++ if (!padapter) ++ return; ++ ++ pmlmeext = &padapter->mlmeextpriv; ++ pcmdpriv = &padapter->cmdpriv; ++ ++ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmd_obj) ++ return; ++ ++ cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header)); ++ pevtcmd = kzalloc(cmdsz, GFP_ATOMIC); ++ if (!pevtcmd) { ++ kfree(pcmd_obj); ++ return; ++ } ++ ++ INIT_LIST_HEAD(&pcmd_obj->list); ++ ++ pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); ++ pcmd_obj->cmdsz = cmdsz; ++ pcmd_obj->parmbuf = pevtcmd; ++ ++ pcmd_obj->rsp = NULL; ++ pcmd_obj->rspsz = 0; ++ ++ pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); ++ pc2h_evt_hdr->len = sizeof(struct survey_event); ++ pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey); ++ pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); ++ ++ psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); ++ ++ if (collect_bss_info(padapter, precv_frame, (struct wlan_bssid_ex *)&psurvey_evt->bss) == _FAIL) { ++ kfree(pcmd_obj); ++ kfree(pevtcmd); ++ return; ++ } ++ ++ process_80211d(padapter, &psurvey_evt->bss); ++ ++ rtw_enqueue_cmd(pcmdpriv, pcmd_obj); ++ ++ pmlmeext->sitesurvey_res.bss_cnt++; ++} ++ ++void report_surveydone_event(struct adapter *padapter) ++{ ++ struct cmd_obj *pcmd_obj; ++ u8 *pevtcmd; ++ u32 cmdsz; ++ struct surveydone_event *psurveydone_evt; ++ struct C2HEvent_Header *pc2h_evt_hdr; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!pcmd_obj) ++ return; ++ ++ cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header)); ++ pevtcmd = kzalloc(cmdsz, GFP_KERNEL); ++ if (!pevtcmd) { ++ kfree(pcmd_obj); ++ return; ++ } ++ ++ INIT_LIST_HEAD(&pcmd_obj->list); ++ ++ pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); ++ pcmd_obj->cmdsz = cmdsz; ++ pcmd_obj->parmbuf = pevtcmd; ++ ++ pcmd_obj->rsp = NULL; ++ pcmd_obj->rspsz = 0; ++ ++ pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); ++ pc2h_evt_hdr->len = sizeof(struct surveydone_event); ++ pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone); ++ pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); ++ ++ psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); ++ psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt; ++ ++ DBG_88E("survey done event(%x)\n", psurveydone_evt->bss_cnt); ++ ++ rtw_enqueue_cmd(pcmdpriv, pcmd_obj); ++} ++ ++void report_join_res(struct adapter *padapter, int res) ++{ ++ struct cmd_obj *pcmd_obj; ++ u8 *pevtcmd; ++ u32 cmdsz; ++ struct joinbss_event *pjoinbss_evt; ++ struct C2HEvent_Header *pc2h_evt_hdr; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmd_obj) ++ return; ++ ++ cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header)); ++ pevtcmd = kzalloc(cmdsz, GFP_ATOMIC); ++ if (!pevtcmd) { ++ kfree(pcmd_obj); ++ return; ++ } ++ ++ INIT_LIST_HEAD(&pcmd_obj->list); ++ ++ pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); ++ pcmd_obj->cmdsz = cmdsz; ++ pcmd_obj->parmbuf = pevtcmd; ++ ++ pcmd_obj->rsp = NULL; ++ pcmd_obj->rspsz = 0; ++ ++ pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); ++ pc2h_evt_hdr->len = sizeof(struct joinbss_event); ++ pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss); ++ pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); ++ ++ pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); ++ memcpy((unsigned char *)(&pjoinbss_evt->network.network), &pmlmeinfo->network, sizeof(struct wlan_bssid_ex)); ++ pjoinbss_evt->network.join_res = res; ++ pjoinbss_evt->network.aid = res; ++ ++ DBG_88E("report_join_res(%d)\n", res); ++ ++ rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network); ++ ++ rtw_enqueue_cmd(pcmdpriv, pcmd_obj); ++} ++ ++void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason) ++{ ++ struct cmd_obj *pcmd_obj; ++ u8 *pevtcmd; ++ u32 cmdsz; ++ struct sta_info *psta; ++ int mac_id; ++ struct stadel_event *pdel_sta_evt; ++ struct C2HEvent_Header *pc2h_evt_hdr; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!pcmd_obj) ++ return; ++ ++ cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header)); ++ pevtcmd = kzalloc(cmdsz, GFP_KERNEL); ++ if (!pevtcmd) { ++ kfree(pcmd_obj); ++ return; ++ } ++ ++ INIT_LIST_HEAD(&pcmd_obj->list); ++ ++ pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); ++ pcmd_obj->cmdsz = cmdsz; ++ pcmd_obj->parmbuf = pevtcmd; ++ ++ pcmd_obj->rsp = NULL; ++ pcmd_obj->rspsz = 0; ++ ++ pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); ++ pc2h_evt_hdr->len = sizeof(struct stadel_event); ++ pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA); ++ pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); ++ ++ pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); ++ memcpy((unsigned char *)(&pdel_sta_evt->macaddr), MacAddr, ETH_ALEN); ++ memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2); ++ ++ psta = rtw_get_stainfo(&padapter->stapriv, MacAddr); ++ if (psta) ++ mac_id = (int)psta->mac_id; ++ else ++ mac_id = (-1); ++ ++ pdel_sta_evt->mac_id = mac_id; ++ ++ DBG_88E("report_del_sta_event: delete STA, mac_id =%d\n", mac_id); ++ ++ rtw_enqueue_cmd(pcmdpriv, pcmd_obj); ++} ++ ++void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int cam_idx) ++{ ++ struct cmd_obj *pcmd_obj; ++ u8 *pevtcmd; ++ u32 cmdsz; ++ struct stassoc_event *padd_sta_evt; ++ struct C2HEvent_Header *pc2h_evt_hdr; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!pcmd_obj) ++ return; ++ ++ cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header)); ++ pevtcmd = kzalloc(cmdsz, GFP_KERNEL); ++ if (!pevtcmd) { ++ kfree(pcmd_obj); ++ return; ++ } ++ ++ INIT_LIST_HEAD(&pcmd_obj->list); ++ ++ pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); ++ pcmd_obj->cmdsz = cmdsz; ++ pcmd_obj->parmbuf = pevtcmd; ++ ++ pcmd_obj->rsp = NULL; ++ pcmd_obj->rspsz = 0; ++ ++ pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); ++ pc2h_evt_hdr->len = sizeof(struct stassoc_event); ++ pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA); ++ pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); ++ ++ padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); ++ memcpy((unsigned char *)(&padd_sta_evt->macaddr), MacAddr, ETH_ALEN); ++ padd_sta_evt->cam_id = cam_idx; ++ ++ DBG_88E("report_add_sta_event: add STA\n"); ++ ++ rtw_enqueue_cmd(pcmdpriv, pcmd_obj); ++} ++ ++/**************************************************************************** ++ ++Following are the event callback functions ++ ++*****************************************************************************/ ++ ++/* for sta/adhoc mode */ ++void update_sta_info(struct adapter *padapter, struct sta_info *psta) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ /* ERP */ ++ VCS_update(padapter, psta); ++ ++ /* HT */ ++ if (pmlmepriv->htpriv.ht_option) { ++ psta->htpriv.ht_option = true; ++ ++ psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable; ++ ++ if (support_short_GI(padapter, &pmlmeinfo->HT_caps)) ++ psta->htpriv.sgi = true; ++ ++ psta->qos_option = true; ++ } else { ++ psta->htpriv.ht_option = false; ++ ++ psta->htpriv.ampdu_enable = false; ++ ++ psta->htpriv.sgi = false; ++ psta->qos_option = false; ++ } ++ psta->htpriv.bwmode = pmlmeext->cur_bwmode; ++ psta->htpriv.ch_offset = pmlmeext->cur_ch_offset; ++ ++ psta->htpriv.agg_enable_bitmap = 0x0;/* reset */ ++ psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */ ++ ++ /* QoS */ ++ if (pmlmepriv->qospriv.qos_option) ++ psta->qos_option = true; ++ ++ psta->state = _FW_LINKED; ++} ++ ++void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res) ++{ ++ struct sta_info *psta, *psta_bmc; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 join_type; ++ u16 media_status; ++ ++ if (join_res < 0) { ++ join_type = 1; ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); ++ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); ++ ++ /* restore to initial setting. */ ++ update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); ++ ++ goto exit_mlmeext_joinbss_event_callback; ++ } ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { ++ /* for bc/mc */ ++ psta_bmc = rtw_get_bcmc_stainfo(padapter); ++ if (psta_bmc) { ++ pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc; ++ update_bmc_sta_support_rate(padapter, psta_bmc->mac_id); ++ Update_RA_Entry(padapter, psta_bmc->mac_id); ++ } ++ } ++ ++ /* turn on dynamic functions */ ++ Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); ++ ++ /* update IOT-releated issue */ ++ update_IOT_info(padapter); ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates); ++ ++ /* BCN interval */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval)); ++ ++ /* udpate capability */ ++ update_capinfo(padapter, pmlmeinfo->capability); ++ ++ /* WMM, Update EDCA param */ ++ WMMOnAssocRsp(padapter); ++ ++ /* HT */ ++ HTOnAssocRsp(padapter); ++ ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); ++ ++ psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress); ++ if (psta) { /* only for infra. mode */ ++ pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta; ++ ++ psta->wireless_mode = pmlmeext->cur_wireless_mode; ++ ++ /* set per sta rate after updating HT cap. */ ++ set_sta_rate(padapter, psta); ++ rtw_hal_set_hwreg(padapter, HW_VAR_TX_RPT_MAX_MACID, (u8 *)&psta->mac_id); ++ media_status = (psta->mac_id << 8) | 1; /* MACID|OPMODE: 1 means connect */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status); ++ } ++ ++ join_type = 2; ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) { ++ /* correcting TSF */ ++ correct_TSF(padapter, pmlmeext); ++ } ++ rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0); ++ ++exit_mlmeext_joinbss_event_callback: ++ ++ DBG_88E("=>%s\n", __func__); ++} ++ ++void mlmeext_sta_add_event_callback(struct adapter *padapter, struct sta_info *psta) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 join_type; ++ ++ DBG_88E("%s\n", __func__); ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { ++ if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {/* adhoc master or sta_count>1 */ ++ /* nothing to do */ ++ } else { /* adhoc client */ ++ /* correcting TSF */ ++ correct_TSF(padapter, pmlmeext); ++ ++ /* start beacon */ ++ if (send_beacon(padapter) == _FAIL) { ++ pmlmeinfo->FW_sta_info[psta->mac_id].status = 0; ++ pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE; ++ return; ++ } ++ pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; ++ } ++ ++ join_type = 2; ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); ++ } ++ ++ pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta; ++ ++ /* rate radaptive */ ++ Update_RA_Entry(padapter, psta->mac_id); ++ ++ /* update adhoc sta_info */ ++ update_sta_info(padapter, psta); ++} ++ ++void mlmeext_sta_del_event_callback(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter)) { ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL); ++ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); ++ ++ /* restore to initial setting. */ ++ update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); ++ ++ /* switch to the 20M Hz mode after disconnect */ ++ pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ ++ /* SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */ ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); ++ ++ flush_all_cam_entry(padapter); ++ ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ ++ /* set MSR to no link state -> infra. mode */ ++ Set_MSR(padapter, _HW_STATE_STATION_); ++ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ } ++} ++ ++/**************************************************************************** ++ ++Following are the functions for the timer handlers ++ ++*****************************************************************************/ ++void _linked_rx_signal_strehgth_display(struct adapter *padapter); ++void _linked_rx_signal_strehgth_display(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 mac_id; ++ int UndecoratedSmoothedPWDB; ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) ++ mac_id = 0; ++ else if ((pmlmeinfo->state & 0x03) == _HW_STATE_AP_) ++ mac_id = 2; ++ ++ rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, &mac_id); ++ ++ rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB); ++ DBG_88E("UndecoratedSmoothedPWDB:%d\n", UndecoratedSmoothedPWDB); ++} ++ ++static u8 chk_ap_is_alive(struct adapter *padapter, struct sta_info *psta) ++{ ++ u8 ret = false; ++ ++ if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)) && ++ sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) && ++ sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)) ++ ret = false; ++ else ++ ret = true; ++ ++ sta_update_last_rx_pkts(psta); ++ ++ return ret; ++} ++ ++void linked_status_chk(struct adapter *padapter) ++{ ++ u32 i; ++ struct sta_info *psta; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ if (padapter->bRxRSSIDisplay) ++ _linked_rx_signal_strehgth_display(padapter); ++ ++ rtw_hal_sreset_linked_status_check(padapter); ++ ++ if (is_client_associated_to_ap(padapter)) { ++ /* linked infrastructure client mode */ ++ ++ int tx_chk = _SUCCESS, rx_chk = _SUCCESS; ++ int rx_chk_limit; ++ ++ rx_chk_limit = 4; ++ psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress); ++ if (psta) { ++ bool is_p2p_enable = false; ++ #ifdef CONFIG_88EU_P2P ++ is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE); ++ #endif ++ ++ if (!chk_ap_is_alive(padapter, psta)) ++ rx_chk = _FAIL; ++ ++ if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts) ++ tx_chk = _FAIL; ++ ++ if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) { ++ u8 backup_oper_channel = 0; ++ ++ /* switch to correct channel of current network before issue keep-alive frames */ ++ if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) { ++ backup_oper_channel = rtw_get_oper_ch(padapter); ++ SelectChannel(padapter, pmlmeext->cur_channel); ++ } ++ ++ if (rx_chk != _SUCCESS) ++ issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1); ++ ++ if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) { ++ tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1); ++ /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */ ++ if (tx_chk == _SUCCESS && !is_p2p_enable) ++ rx_chk = _SUCCESS; ++ } ++ ++ /* back to the original operation channel */ ++ if (backup_oper_channel > 0) ++ SelectChannel(padapter, backup_oper_channel); ++ } else { ++ if (rx_chk != _SUCCESS) { ++ if (pmlmeext->retry == 0) { ++ issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress); ++ issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress); ++ issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress); ++ } ++ } ++ ++ if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) { ++ tx_chk = issue_nulldata(padapter, NULL, 0, 1, 0); ++ } ++ } ++ ++ if (rx_chk == _FAIL) { ++ pmlmeext->retry++; ++ if (pmlmeext->retry > rx_chk_limit) { ++ DBG_88E_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n", ++ FUNC_ADPT_ARG(padapter)); ++ receive_disconnect(padapter, pmlmeinfo->network.MacAddress, ++ WLAN_REASON_EXPIRATION_CHK); ++ return; ++ } ++ } else { ++ pmlmeext->retry = 0; ++ } ++ ++ if (tx_chk == _FAIL) { ++ pmlmeinfo->link_count &= 0xf; ++ } else { ++ pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts; ++ pmlmeinfo->link_count = 0; ++ } ++ } /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */ ++ } else if (is_client_associated_to_ibss(padapter)) { ++ /* linked IBSS mode */ ++ /* for each assoc list entry to check the rx pkt counter */ ++ for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) { ++ if (pmlmeinfo->FW_sta_info[i].status == 1) { ++ psta = pmlmeinfo->FW_sta_info[i].psta; ++ ++ if (NULL == psta) ++ continue; ++ if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta)) { ++ if (pmlmeinfo->FW_sta_info[i].retry < 3) { ++ pmlmeinfo->FW_sta_info[i].retry++; ++ } else { ++ pmlmeinfo->FW_sta_info[i].retry = 0; ++ pmlmeinfo->FW_sta_info[i].status = 0; ++ report_del_sta_event(padapter, psta->hwaddr ++ , 65535/* indicate disconnect caused by no rx */ ++ ); ++ } ++ } else { ++ pmlmeinfo->FW_sta_info[i].retry = 0; ++ pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta); ++ } ++ } ++ } ++ } ++} ++ ++void survey_timer_hdl(struct adapter *padapter) ++{ ++ struct cmd_obj *ph2c; ++ struct sitesurvey_parm *psurveyPara; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif ++ ++ /* issue rtw_sitesurvey_cmd */ ++ if (pmlmeext->sitesurvey_res.state > SCAN_START) { ++ if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) ++ pmlmeext->sitesurvey_res.channel_idx++; ++ ++ if (pmlmeext->scan_abort) { ++ #ifdef CONFIG_88EU_P2P ++ if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) { ++ rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX); ++ pmlmeext->sitesurvey_res.channel_idx = 3; ++ DBG_88E("%s idx:%d, cnt:%u\n", __func__ ++ , pmlmeext->sitesurvey_res.channel_idx ++ , pwdinfo->find_phase_state_exchange_cnt ++ ); ++ } else ++ #endif ++ { ++ pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num; ++ DBG_88E("%s idx:%d\n", __func__ ++ , pmlmeext->sitesurvey_res.channel_idx ++ ); ++ } ++ ++ pmlmeext->scan_abort = false;/* reset */ ++ } ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) ++ goto exit_survey_timer_hdl; ++ ++ psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC); ++ if (!psurveyPara) { ++ kfree(ph2c); ++ goto exit_survey_timer_hdl; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey)); ++ rtw_enqueue_cmd(pcmdpriv, ph2c); ++ } ++ ++exit_survey_timer_hdl: ++ return; ++} ++ ++void link_timer_hdl(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) { ++ DBG_88E("link_timer_hdl:no beacon while connecting\n"); ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ report_join_res(padapter, -3); ++ } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) { ++ /* re-auth timer */ ++ if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) { ++ pmlmeinfo->state = 0; ++ report_join_res(padapter, -1); ++ return; ++ } ++ ++ DBG_88E("link_timer_hdl: auth timeout and try again\n"); ++ pmlmeinfo->auth_seq = 1; ++ issue_auth(padapter, NULL, 0); ++ set_link_timer(pmlmeext, REAUTH_TO); ++ } else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) { ++ /* re-assoc timer */ ++ if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) { ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ report_join_res(padapter, -2); ++ return; ++ } ++ ++ DBG_88E("link_timer_hdl: assoc timeout and try again\n"); ++ issue_assocreq(padapter); ++ set_link_timer(pmlmeext, REASSOC_TO); ++ } ++} ++ ++void addba_timer_hdl(struct sta_info *psta) ++{ ++ struct ht_priv *phtpriv; ++ ++ if (!psta) ++ return; ++ ++ phtpriv = &psta->htpriv; ++ ++ if ((phtpriv->ht_option) && (phtpriv->ampdu_enable)) { ++ if (phtpriv->candidate_tid_bitmap) ++ phtpriv->candidate_tid_bitmap = 0x0; ++ } ++} ++ ++u8 NULL_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ return H2C_SUCCESS; ++} ++ ++u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ u8 type; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf; ++ ++ if (psetop->mode == Ndis802_11APMode) { ++ pmlmeinfo->state = WIFI_FW_AP_STATE; ++ type = _HW_STATE_AP_; ++ } else if (psetop->mode == Ndis802_11Infrastructure) { ++ pmlmeinfo->state &= ~(BIT(0) | BIT(1));/* clear state */ ++ pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */ ++ type = _HW_STATE_STATION_; ++ } else if (psetop->mode == Ndis802_11IBSS) { ++ type = _HW_STATE_ADHOC_; ++ } else { ++ type = _HW_STATE_NOLINK_; ++ } ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type)); ++ /* Set_NETYPE0_MSR(padapter, type); */ ++ ++ return H2C_SUCCESS; ++} ++ ++u8 createbss_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); ++ struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf; ++ /* u32 initialgain; */ ++ ++ if (pparm->network.InfrastructureMode == Ndis802_11APMode) { ++#ifdef CONFIG_88EU_AP_MODE ++ ++ if (pmlmeinfo->state == WIFI_FW_AP_STATE) { ++ /* todo: */ ++ return H2C_SUCCESS; ++ } ++#endif ++ } ++ ++ /* below is for ad-hoc master */ ++ if (pparm->network.InfrastructureMode == Ndis802_11IBSS) { ++ rtw_joinbss_reset(padapter); ++ ++ pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ pmlmeinfo->ERP_enable = 0; ++ pmlmeinfo->WMM_enable = 0; ++ pmlmeinfo->HT_enable = 0; ++ pmlmeinfo->HT_caps_enable = 0; ++ pmlmeinfo->HT_info_enable = 0; ++ pmlmeinfo->agg_enable_bitmap = 0; ++ pmlmeinfo->candidate_tid_bitmap = 0; ++ ++ /* disable dynamic functions, such as high power, DIG */ ++ Save_DM_Func_Flag(padapter); ++ Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); ++ ++ /* config the initial gain under linking, need to write the BB registers */ ++ /* initialgain = 0x1E; */ ++ /* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */ ++ ++ /* cancel link timer */ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ ++ /* clear CAM */ ++ flush_all_cam_entry(padapter); ++ ++ memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength)); ++ pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength; ++ ++ if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */ ++ return H2C_PARAMETERS_ERROR; ++ ++ memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength); ++ ++ start_create_ibss(padapter); ++ } ++ ++ return H2C_SUCCESS; ++} ++ ++u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ u8 join_type; ++ struct ndis_802_11_var_ie *pIE; ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); ++ struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf; ++ u32 i; ++ ++ /* check already connecting to AP or not */ ++ if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { ++ if (pmlmeinfo->state & WIFI_FW_STATION_STATE) ++ issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 5, 100); ++ ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ ++ /* clear CAM */ ++ flush_all_cam_entry(padapter); ++ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ ++ /* set MSR to nolink -> infra. mode */ ++ Set_MSR(padapter, _HW_STATE_STATION_); ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL); ++ } ++ ++ rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, false); ++ ++ rtw_joinbss_reset(padapter); ++ ++ pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ pmlmeinfo->ERP_enable = 0; ++ pmlmeinfo->WMM_enable = 0; ++ pmlmeinfo->HT_enable = 0; ++ pmlmeinfo->HT_caps_enable = 0; ++ pmlmeinfo->HT_info_enable = 0; ++ pmlmeinfo->agg_enable_bitmap = 0; ++ pmlmeinfo->candidate_tid_bitmap = 0; ++ pmlmeinfo->bwmode_updated = false; ++ ++ memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength)); ++ pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength; ++ ++ if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */ ++ return H2C_PARAMETERS_ERROR; ++ ++ memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength); ++ ++ /* Check AP vendor to move rtw_joinbss_cmd() */ ++ ++ for (i = sizeof(struct ndis_802_11_fixed_ie); i < pnetwork->IELength;) { ++ pIE = (struct ndis_802_11_var_ie *)(pnetwork->IEs + i); ++ ++ switch (pIE->ElementID) { ++ case _VENDOR_SPECIFIC_IE_:/* Get WMM IE. */ ++ if (!memcmp(pIE->data, WMM_OUI, 4)) ++ pmlmeinfo->WMM_enable = 1; ++ break; ++ case _HT_CAPABILITY_IE_: /* Get HT Cap IE. */ ++ pmlmeinfo->HT_caps_enable = 1; ++ break; ++ case _HT_EXTRA_INFO_IE_: /* Get HT Info IE. */ ++ pmlmeinfo->HT_info_enable = 1; ++ ++ /* spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz */ ++ { ++ struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data); ++ ++ if ((pregpriv->cbw40_enable) && (pht_info->infos[0] & BIT(2))) { ++ /* switch to the 40M Hz mode according to the AP */ ++ pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40; ++ switch (pht_info->infos[0] & 0x3) { ++ case 1: ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; ++ break; ++ case 3: ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; ++ break; ++ default: ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ break; ++ } ++ ++ DBG_88E("set ch/bw before connected\n"); ++ } ++ } ++ break; ++ default: ++ break; ++ } ++ ++ i += (pIE->Length + 2); ++ } ++ /* disable dynamic functions, such as high power, DIG */ ++ ++ /* config the initial gain under linking, need to write the BB registers */ ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress); ++ join_type = 0; ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); ++ ++ /* cancel link timer */ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ ++ start_clnt_join(padapter); ++ ++ return H2C_SUCCESS; ++} ++ ++u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ struct disconnect_parm *param = (struct disconnect_parm *)pbuf; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); ++ u8 val8; ++ ++ if (is_client_associated_to_ap(padapter)) ++ issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms / 100, 100); ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL); ++ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); ++ ++ /* restore to initial setting. */ ++ update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); ++ ++ if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) { ++ /* Stop BCN */ ++ val8 = 0; ++ rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8)); ++ } ++ ++ /* set MSR to no link state -> infra. mode */ ++ Set_MSR(padapter, _HW_STATE_STATION_); ++ ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ ++ /* switch to the 20M Hz mode after disconnect */ ++ pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); ++ ++ flush_all_cam_entry(padapter); ++ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ ++ rtw_free_uc_swdec_pending_queue(padapter); ++ ++ return H2C_SUCCESS; ++} ++ ++static int rtw_scan_ch_decision(struct adapter *padapter, struct rtw_ieee80211_channel *out, ++ u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num) ++{ ++ int i, j; ++ int set_idx; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ /* clear out first */ ++ memset(out, 0, sizeof(struct rtw_ieee80211_channel) * out_num); ++ ++ /* acquire channels from in */ ++ j = 0; ++ for (i = 0; i < in_num; i++) { ++ set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value); ++ if (in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED) && ++ set_idx >= 0) { ++ memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel)); ++ ++ if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE) ++ out[j].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN; ++ ++ j++; ++ } ++ if (j >= out_num) ++ break; ++ } ++ ++ /* if out is empty, use channel_set as default */ ++ if (j == 0) { ++ for (i = 0; i < pmlmeext->max_chan_nums; i++) { ++ out[i].hw_value = pmlmeext->channel_set[i].ChannelNum; ++ ++ if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE) ++ out[i].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN; ++ ++ j++; ++ } ++ } ++ ++ return j; ++} ++ ++u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf; ++ u8 bdelayscan = false; ++ u8 val8; ++ u32 initialgain; ++ u32 i; ++ ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif ++ ++ if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) { ++ /* for first time sitesurvey_cmd */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, NULL); ++ ++ pmlmeext->sitesurvey_res.state = SCAN_START; ++ pmlmeext->sitesurvey_res.bss_cnt = 0; ++ pmlmeext->sitesurvey_res.channel_idx = 0; ++ ++ for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { ++ if (pparm->ssid[i].SsidLength) { ++ memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE); ++ pmlmeext->sitesurvey_res.ssid[i].SsidLength = pparm->ssid[i].SsidLength; ++ } else { ++ pmlmeext->sitesurvey_res.ssid[i].SsidLength = 0; ++ } ++ } ++ ++ pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter ++ , pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT ++ , pparm->ch, pparm->ch_num ++ ); ++ ++ pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode; ++ ++ /* issue null data if associating to the AP */ ++ if (is_client_associated_to_ap(padapter)) { ++ pmlmeext->sitesurvey_res.state = SCAN_TXNULL; ++ ++ issue_nulldata(padapter, NULL, 1, 3, 500); ++ ++ bdelayscan = true; ++ } ++ if (bdelayscan) { ++ /* delay 50ms to protect nulldata(1). */ ++ set_survey_timer(pmlmeext, 50); ++ return H2C_SUCCESS; ++ } ++ } ++ ++ if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) { ++ /* disable dynamic functions, such as high power, DIG */ ++ Save_DM_Func_Flag(padapter); ++ Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); ++ ++ /* config the initial gain under scanning, need to write the BB registers */ ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ initialgain = 0x1E; ++ else ++ initialgain = 0x28; ++#else /* CONFIG_88EU_P2P */ ++ initialgain = 0x1E; ++#endif /* CONFIG_88EU_P2P */ ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); ++ ++ /* set MSR to no link state */ ++ Set_MSR(padapter, _HW_STATE_NOLINK_); ++ ++ val8 = 1; /* under site survey */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); ++ ++ pmlmeext->sitesurvey_res.state = SCAN_PROCESS; ++ } ++ ++ site_survey(padapter); ++ ++ return H2C_SUCCESS; ++} ++ ++u8 setauth_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ struct setauth_parm *pparm = (struct setauth_parm *)pbuf; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pparm->mode < 4) ++ pmlmeinfo->auth_algo = pparm->mode; ++ return H2C_SUCCESS; ++} ++ ++u8 setkey_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ unsigned short ctrl; ++ struct setkey_parm *pparm = (struct setkey_parm *)pbuf; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; ++ ++ /* main tx key for wep. */ ++ if (pparm->set_tx) ++ pmlmeinfo->key_index = pparm->keyid; ++ ++ /* write cam */ ++ ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid; ++ ++ DBG_88E_LEVEL(_drv_info_, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) " ++ "keyid:%d\n", pparm->algorithm, pparm->keyid); ++ write_cam(padapter, pparm->keyid, ctrl, null_sta, pparm->key); ++ ++ return H2C_SUCCESS; ++} ++ ++u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ u16 ctrl = 0; ++ u8 cam_id;/* cam_entry */ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf; ++ ++ /* cam_entry: */ ++ /* 0~3 for default key */ ++ ++ /* for concurrent mode (ap+sta): */ ++ /* default key is disable, using sw encrypt/decrypt */ ++ /* cam_entry = 4 for sta mode (macid = 0) */ ++ /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */ ++ ++ /* for concurrent mode (sta+sta): */ ++ /* default key is disable, using sw encrypt/decrypt */ ++ /* cam_entry = 4 mapping to macid = 0 */ ++ /* cam_entry = 5 mapping to macid = 2 */ ++ ++ cam_id = 4; ++ ++ DBG_88E_LEVEL(_drv_info_, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n", ++ pparm->algorithm, cam_id); ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { ++ struct sta_info *psta; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ if (pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */ { ++ clear_cam_entry(padapter, pparm->id); ++ return H2C_SUCCESS_RSP; ++ } ++ ++ psta = rtw_get_stainfo(pstapriv, pparm->addr); ++ if (psta) { ++ ctrl = (BIT(15) | ((pparm->algorithm) << 2)); ++ ++ DBG_88E("r871x_set_stakey_hdl(): enc_algorithm=%d\n", pparm->algorithm); ++ ++ if ((psta->mac_id < 1) || (psta->mac_id > (NUM_STA - 4))) { ++ DBG_88E("r871x_set_stakey_hdl():set_stakey failed, mac_id(aid)=%d\n", psta->mac_id); ++ return H2C_REJECTED; ++ } ++ ++ cam_id = (psta->mac_id + 3);/* 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */ ++ ++ DBG_88E("Write CAM, mac_addr =%x:%x:%x:%x:%x:%x, cam_entry=%d\n", pparm->addr[0], ++ pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4], ++ pparm->addr[5], cam_id); ++ ++ write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key); ++ ++ return H2C_SUCCESS_RSP; ++ } else { ++ DBG_88E("r871x_set_stakey_hdl(): sta has been free\n"); ++ return H2C_REJECTED; ++ } ++ } ++ ++ /* below for sta mode */ ++ ++ if (pparm->algorithm == _NO_PRIVACY_) { /* clear cam entry */ ++ clear_cam_entry(padapter, pparm->id); ++ return H2C_SUCCESS; ++ } ++ ctrl = BIT(15) | ((pparm->algorithm) << 2); ++ write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key); ++ pmlmeinfo->enc_algo = pparm->algorithm; ++ return H2C_SUCCESS; ++} ++ ++u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr); ++ ++ if (!psta) ++ return H2C_SUCCESS; ++ ++ if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) || ++ ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) { ++ issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid); ++ _set_timer(&psta->addba_retry_timer, ADDBA_TO); ++ } else { ++ psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid); ++ } ++ return H2C_SUCCESS; ++} ++ ++u8 set_tx_beacon_cmd(struct adapter *padapter) ++{ ++ struct cmd_obj *ph2c; ++ struct Tx_Beacon_param *ptxBeacon_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 res = _SUCCESS; ++ int len_diff = 0; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ ptxBeacon_parm = kzalloc(sizeof(struct Tx_Beacon_param), GFP_ATOMIC); ++ if (!ptxBeacon_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ memcpy(&ptxBeacon_parm->network, &pmlmeinfo->network, sizeof(struct wlan_bssid_ex)); ++ ++ len_diff = update_hidden_ssid(ptxBeacon_parm->network.IEs + _BEACON_IE_OFFSET_, ++ ptxBeacon_parm->network.IELength - _BEACON_IE_OFFSET_, ++ pmlmeinfo->hidden_ssid_mode); ++ ptxBeacon_parm->network.IELength += len_diff; ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++} ++ ++u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ u8 evt_code; ++ u16 evt_sz; ++ uint *peventbuf; ++ void (*event_callback)(struct adapter *dev, u8 *pbuf); ++ struct evt_priv *pevt_priv = &padapter->evtpriv; ++ ++ peventbuf = (uint *)pbuf; ++ evt_sz = (u16)(*peventbuf & 0xffff); ++ evt_code = (u8)((*peventbuf >> 16) & 0xff); ++ ++ /* checking if event code is valid */ ++ if (evt_code >= MAX_C2HEVT) ++ goto _abort_event_; ++ ++ /* checking if event size match the event parm size */ ++ if ((wlanevents[evt_code].parmsize != 0) && ++ (wlanevents[evt_code].parmsize != evt_sz)) ++ goto _abort_event_; ++ ++ atomic_inc(&pevt_priv->event_seq); ++ ++ peventbuf += 2; ++ ++ if (peventbuf) { ++ event_callback = wlanevents[evt_code].event_callback; ++ event_callback(padapter, (u8 *)peventbuf); ++ ++ pevt_priv->evt_done_cnt++; ++ } ++ ++_abort_event_: ++ return H2C_SUCCESS; ++} ++ ++u8 h2c_msg_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ if (!pbuf) ++ return H2C_PARAMETERS_ERROR; ++ ++ return H2C_SUCCESS; ++} ++ ++u8 tx_beacon_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ if (send_beacon(padapter) == _FAIL) { ++ DBG_88E("issue_beacon, fail!\n"); ++ return H2C_PARAMETERS_ERROR; ++ } ++#ifdef CONFIG_88EU_AP_MODE ++ else { /* tx bc/mc frames after update TIM */ ++ struct sta_info *psta_bmc; ++ struct list_head *xmitframe_plist, *xmitframe_phead; ++ struct xmit_frame *pxmitframe = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ /* for BC/MC Frames */ ++ psta_bmc = rtw_get_bcmc_stainfo(padapter); ++ if (!psta_bmc) ++ return H2C_SUCCESS; ++ ++ if ((pstapriv->tim_bitmap & BIT(0)) && (psta_bmc->sleepq_len > 0)) { ++ msleep(10);/* 10ms, ATIM(HIQ) Windows */ ++ spin_lock_bh(&psta_bmc->sleep_q.lock); ++ ++ xmitframe_phead = get_list_head(&psta_bmc->sleep_q); ++ xmitframe_plist = xmitframe_phead->next; ++ ++ while (xmitframe_phead != xmitframe_plist) { ++ pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); ++ ++ xmitframe_plist = xmitframe_plist->next; ++ ++ list_del_init(&pxmitframe->list); ++ ++ psta_bmc->sleepq_len--; ++ if (psta_bmc->sleepq_len > 0) ++ pxmitframe->attrib.mdata = 1; ++ else ++ pxmitframe->attrib.mdata = 0; ++ ++ pxmitframe->attrib.triggered = 1; ++ ++ pxmitframe->attrib.qsel = 0x11;/* HIQ */ ++ ++ spin_unlock_bh(&psta_bmc->sleep_q.lock); ++ if (rtw_hal_xmit(padapter, pxmitframe)) ++ rtw_os_xmit_complete(padapter, pxmitframe); ++ spin_lock_bh(&psta_bmc->sleep_q.lock); ++ } ++ spin_unlock_bh(&psta_bmc->sleep_q.lock); ++ } ++ } ++#endif ++ return H2C_SUCCESS; ++} ++ ++u8 set_ch_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ struct set_ch_parm *set_ch_parm; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ if (!pbuf) ++ return H2C_PARAMETERS_ERROR; ++ ++ set_ch_parm = (struct set_ch_parm *)pbuf; ++ ++ DBG_88E(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n", ++ FUNC_NDEV_ARG(padapter->pnetdev), ++ set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset); ++ ++ pmlmeext->cur_channel = set_ch_parm->ch; ++ pmlmeext->cur_ch_offset = set_ch_parm->ch_offset; ++ pmlmeext->cur_bwmode = set_ch_parm->bw; ++ ++ set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw); ++ ++ return H2C_SUCCESS; ++} ++ ++u8 set_chplan_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ struct SetChannelPlan_param *setChannelPlan_param; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ if (!pbuf) ++ return H2C_PARAMETERS_ERROR; ++ ++ setChannelPlan_param = (struct SetChannelPlan_param *)pbuf; ++ ++ pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set); ++ init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list); ++ ++ return H2C_SUCCESS; ++} ++ ++u8 led_blink_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ if (!pbuf) ++ return H2C_PARAMETERS_ERROR; ++ return H2C_SUCCESS; ++} ++ ++u8 set_csa_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ return H2C_REJECTED; ++} ++ ++/* TDLS_WRCR : write RCR DATA BIT */ ++/* TDLS_SD_PTI : issue peer traffic indication */ ++/* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */ ++/* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */ ++/* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */ ++/* TDLS_OFF_CH : first time set channel to off channel */ ++/* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */ ++/* TDLS_P_OFF_CH : periodically go to off channel */ ++/* TDLS_P_BASE_CH : periodically go back to base channel */ ++/* TDLS_RS_RCR : restore RCR */ ++/* TDLS_CKALV_PH1 : check alive timer phase1 */ ++/* TDLS_CKALV_PH2 : check alive timer phase2 */ ++/* TDLS_FREE_STA : free tdls sta */ ++u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ return H2C_REJECTED; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c +new file mode 100644 +index 000000000000..dabdd0406f30 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_mp.c +@@ -0,0 +1,935 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_MP_C_ ++ ++#include "../include/drv_types.h" ++#include "../include/odm_precomp.h" ++#include "../include/rtl8188e_hal.h" ++ ++u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask) ++{ ++ return rtw_hal_read_bbreg(padapter, addr, bitmask); ++} ++ ++void write_bbreg(struct adapter *padapter, u32 addr, u32 bitmask, u32 val) ++{ ++ rtw_hal_write_bbreg(padapter, addr, bitmask, val); ++} ++ ++u32 _read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask) ++{ ++ return rtw_hal_read_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bitmask); ++} ++ ++void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val) ++{ ++ rtw_hal_write_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bitmask, val); ++} ++ ++u32 read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr) ++{ ++ return _read_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bRFRegOffsetMask); ++} ++ ++void write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 val) ++{ ++ _write_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bRFRegOffsetMask, val); ++} ++ ++static void _init_mp_priv_(struct mp_priv *pmp_priv) ++{ ++ struct wlan_bssid_ex *pnetwork; ++ ++ memset(pmp_priv, 0, sizeof(struct mp_priv)); ++ ++ pmp_priv->mode = MP_OFF; ++ ++ pmp_priv->channel = 1; ++ pmp_priv->bandwidth = HT_CHANNEL_WIDTH_20; ++ pmp_priv->prime_channel_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ pmp_priv->rateidx = MPT_RATE_1M; ++ pmp_priv->txpoweridx = 0x2A; ++ ++ pmp_priv->antenna_tx = ANTENNA_A; ++ pmp_priv->antenna_rx = ANTENNA_AB; ++ ++ pmp_priv->check_mp_pkt = 0; ++ ++ pmp_priv->tx_pktcount = 0; ++ ++ pmp_priv->rx_pktcount = 0; ++ pmp_priv->rx_crcerrpktcount = 0; ++ ++ pmp_priv->network_macaddr[0] = 0x00; ++ pmp_priv->network_macaddr[1] = 0xE0; ++ pmp_priv->network_macaddr[2] = 0x4C; ++ pmp_priv->network_macaddr[3] = 0x87; ++ pmp_priv->network_macaddr[4] = 0x66; ++ pmp_priv->network_macaddr[5] = 0x55; ++ ++ pnetwork = &pmp_priv->mp_network.network; ++ memcpy(pnetwork->MacAddress, pmp_priv->network_macaddr, ETH_ALEN); ++ ++ pnetwork->Ssid.SsidLength = 8; ++ memcpy(pnetwork->Ssid.Ssid, "mp_871x", pnetwork->Ssid.SsidLength); ++} ++ ++static void mp_init_xmit_attrib(struct mp_tx *pmptx, struct adapter *padapter) ++{ ++ struct pkt_attrib *pattrib; ++ struct tx_desc *desc; ++ ++ /* init xmitframe attribute */ ++ pattrib = &pmptx->attrib; ++ memset(pattrib, 0, sizeof(struct pkt_attrib)); ++ desc = &pmptx->desc; ++ memset(desc, 0, TXDESC_SIZE); ++ ++ pattrib->ether_type = 0x8712; ++ memset(pattrib->dst, 0xFF, ETH_ALEN); ++ pattrib->ack_policy = 0; ++ pattrib->hdrlen = WLAN_HDR_A3_LEN; ++ pattrib->subtype = WIFI_DATA; ++ pattrib->priority = 0; ++ pattrib->qsel = pattrib->priority; ++ pattrib->nr_frags = 1; ++ pattrib->encrypt = 0; ++ pattrib->bswenc = false; ++ pattrib->qos_en = false; ++} ++ ++s32 init_mp_priv(struct adapter *padapter) ++{ ++ struct mp_priv *pmppriv = &padapter->mppriv; ++ ++ _init_mp_priv_(pmppriv); ++ pmppriv->papdater = padapter; ++ ++ pmppriv->tx.stop = 1; ++ mp_init_xmit_attrib(&pmppriv->tx, padapter); ++ ++ switch (padapter->registrypriv.rf_config) { ++ case RF_1T1R: ++ pmppriv->antenna_tx = ANTENNA_A; ++ pmppriv->antenna_rx = ANTENNA_A; ++ break; ++ case RF_1T2R: ++ default: ++ pmppriv->antenna_tx = ANTENNA_A; ++ pmppriv->antenna_rx = ANTENNA_AB; ++ break; ++ case RF_2T2R: ++ case RF_2T2R_GREEN: ++ pmppriv->antenna_tx = ANTENNA_AB; ++ pmppriv->antenna_rx = ANTENNA_AB; ++ break; ++ case RF_2T4R: ++ pmppriv->antenna_tx = ANTENNA_AB; ++ pmppriv->antenna_rx = ANTENNA_ABCD; ++ break; ++ } ++ ++ return _SUCCESS; ++} ++ ++void free_mp_priv(struct mp_priv *pmp_priv) ++{ ++ kfree(pmp_priv->pallocated_mp_xmitframe_buf); ++ pmp_priv->pallocated_mp_xmitframe_buf = NULL; ++ pmp_priv->pmp_xmtframe_buf = NULL; ++} ++ ++#define PHY_IQCalibrate(a, b) PHY_IQCalibrate_8188E(a, b) ++#define PHY_LCCalibrate(a) PHY_LCCalibrate_8188E(a) ++#define PHY_SetRFPathSwitch(a, b) PHY_SetRFPathSwitch_8188E(a, b) ++ ++s32 MPT_InitializeAdapter(struct adapter *pAdapter, u8 Channel) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ s32 rtStatus = _SUCCESS; ++ struct mpt_context *pMptCtx = &pAdapter->mppriv.MptCtx; ++ struct mlme_priv *pmlmepriv = &pAdapter->mlmepriv; ++ ++ /* HW Initialization for 8190 MPT. */ ++ /* SW Initialization for 8190 MP. */ ++ pMptCtx->bMptDrvUnload = false; ++ pMptCtx->bMassProdTest = false; ++ pMptCtx->bMptIndexEven = true; /* default gain index is -6.0db */ ++ pMptCtx->h2cReqNum = 0x0; ++ /* Init mpt event. */ ++ /* init for BT MP */ ++ ++ pMptCtx->bMptWorkItemInProgress = false; ++ pMptCtx->CurrMptAct = NULL; ++ /* */ ++ ++ /* Don't accept any packets */ ++ rtw_write32(pAdapter, REG_RCR, 0); ++ ++ PHY_IQCalibrate(pAdapter, false); ++ dm_CheckTXPowerTracking(&pHalData->odmpriv); /* trigger thermal meter */ ++ PHY_LCCalibrate(pAdapter); ++ ++ pMptCtx->backup0xc50 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0); ++ pMptCtx->backup0xc58 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_XBAGCCore1, bMaskByte0); ++ pMptCtx->backup0xc30 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_RxDetector1, bMaskByte0); ++ pMptCtx->backup0x52_RF_A = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0); ++ pMptCtx->backup0x52_RF_B = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0); ++ ++ /* set ant to wifi side in mp mode */ ++ rtw_write16(pAdapter, 0x870, 0x300); ++ rtw_write16(pAdapter, 0x860, 0x110); ++ ++ if (pAdapter->registrypriv.mp_mode == 1) ++ pmlmepriv->fw_state = WIFI_MP_STATE; ++ ++ return rtStatus; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: MPT_DeInitAdapter() ++ * ++ * Overview: Extra DeInitialization for Mass Production Test. ++ * ++ * Input: struct adapter * pAdapter ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 05/08/2007 MHC Create Version 0. ++ * 05/18/2007 MHC Add normal driver MPHalt code. ++ * ++ *---------------------------------------------------------------------------*/ ++void MPT_DeInitAdapter(struct adapter *pAdapter) ++{ ++ struct mpt_context *pMptCtx = &pAdapter->mppriv.MptCtx; ++ ++ pMptCtx->bMptDrvUnload = true; ++} ++ ++static u8 mpt_ProStartTest(struct adapter *padapter) ++{ ++ struct mpt_context *pMptCtx = &padapter->mppriv.MptCtx; ++ ++ pMptCtx->bMassProdTest = true; ++ pMptCtx->bStartContTx = false; ++ pMptCtx->bCckContTx = false; ++ pMptCtx->bOfdmContTx = false; ++ pMptCtx->bSingleCarrier = false; ++ pMptCtx->bCarrierSuppression = false; ++ pMptCtx->bSingleTone = false; ++ ++ return _SUCCESS; ++} ++ ++/* ++ * General use ++ */ ++s32 SetPowerTracking(struct adapter *padapter, u8 enable) ++{ ++ Hal_SetPowerTracking(padapter, enable); ++ return 0; ++} ++ ++void GetPowerTracking(struct adapter *padapter, u8 *enable) ++{ ++ Hal_GetPowerTracking(padapter, enable); ++} ++ ++static void disable_dm(struct adapter *padapter) ++{ ++ u8 v8; ++ ++ /* 3 1. disable firmware dynamic mechanism */ ++ /* disable Power Training, Rate Adaptive */ ++ v8 = rtw_read8(padapter, REG_BCN_CTRL); ++ v8 &= ~EN_BCN_FUNCTION; ++ rtw_write8(padapter, REG_BCN_CTRL, v8); ++ ++ /* 3 2. disable driver dynamic mechanism */ ++ /* disable Dynamic Initial Gain */ ++ /* disable High Power */ ++ /* disable Power Tracking */ ++ Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); ++ ++ /* enable APK, LCK and IQK but disable power tracking */ ++ Switch_DM_Func(padapter, DYNAMIC_RF_CALIBRATION, true); ++} ++ ++/* This function initializes the DUT to the MP test mode */ ++s32 mp_start_test(struct adapter *padapter) ++{ ++ struct wlan_bssid_ex bssid; ++ struct sta_info *psta; ++ u32 length; ++ u8 val8; ++ s32 res = _SUCCESS; ++ struct mp_priv *pmppriv = &padapter->mppriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_network *tgt_network = &pmlmepriv->cur_network; ++ ++ padapter->registrypriv.mp_mode = 1; ++ pmppriv->bSetTxPower = 0; /* for manually set tx power */ ++ ++ /* 3 disable dynamic mechanism */ ++ disable_dm(padapter); ++ ++ /* 3 0. update mp_priv */ ++ ++ if (padapter->registrypriv.rf_config == RF_819X_MAX_TYPE) { ++ switch (GET_RF_TYPE(padapter)) { ++ case RF_1T1R: ++ pmppriv->antenna_tx = ANTENNA_A; ++ pmppriv->antenna_rx = ANTENNA_A; ++ break; ++ case RF_1T2R: ++ default: ++ pmppriv->antenna_tx = ANTENNA_A; ++ pmppriv->antenna_rx = ANTENNA_AB; ++ break; ++ case RF_2T2R: ++ case RF_2T2R_GREEN: ++ pmppriv->antenna_tx = ANTENNA_AB; ++ pmppriv->antenna_rx = ANTENNA_AB; ++ break; ++ case RF_2T4R: ++ pmppriv->antenna_tx = ANTENNA_AB; ++ pmppriv->antenna_rx = ANTENNA_ABCD; ++ break; ++ } ++ } ++ ++ mpt_ProStartTest(padapter); ++ ++ /* 3 1. initialize a new struct wlan_bssid_ex */ ++/* memset(&bssid, 0, sizeof(struct wlan_bssid_ex)); */ ++ memcpy(bssid.MacAddress, pmppriv->network_macaddr, ETH_ALEN); ++ bssid.Ssid.SsidLength = strlen("mp_pseudo_adhoc"); ++ memcpy(bssid.Ssid.Ssid, (u8 *)"mp_pseudo_adhoc", bssid.Ssid.SsidLength); ++ bssid.InfrastructureMode = Ndis802_11IBSS; ++ bssid.NetworkTypeInUse = Ndis802_11DS; ++ bssid.IELength = 0; ++ ++ length = get_wlan_bssid_ex_sz(&bssid); ++ if (length % 4) ++ bssid.Length = ((length >> 2) + 1) << 2; /* round up to multiple of 4 bytes. */ ++ else ++ bssid.Length = length; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) ++ goto end_of_mp_start_test; ++ ++ /* init mp_start_test status */ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ rtw_disassoc_cmd(padapter, 500, true); ++ rtw_indicate_disconnect(padapter); ++ rtw_free_assoc_resources(padapter, 1); ++ } ++ pmppriv->prev_fw_state = get_fwstate(pmlmepriv); ++ if (padapter->registrypriv.mp_mode == 1) ++ pmlmepriv->fw_state = WIFI_MP_STATE; ++ set_fwstate(pmlmepriv, _FW_UNDER_LINKING); ++ ++ /* 3 2. create a new psta for mp driver */ ++ /* clear psta in the cur_network, if any */ ++ psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress); ++ if (psta) ++ rtw_free_stainfo(padapter, psta); ++ ++ psta = rtw_alloc_stainfo(&padapter->stapriv, bssid.MacAddress); ++ if (!psta) { ++ pmlmepriv->fw_state = pmppriv->prev_fw_state; ++ res = _FAIL; ++ goto end_of_mp_start_test; ++ } ++ ++ /* 3 3. join psudo AdHoc */ ++ tgt_network->join_res = 1; ++ tgt_network->aid = 1; ++ psta->aid = 1; ++ memcpy(&tgt_network->network, &bssid, length); ++ ++ rtw_indicate_connect(padapter); ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ ++end_of_mp_start_test: ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++ if (res == _SUCCESS) { ++ /* set MSR to WIFI_FW_ADHOC_STATE */ ++ val8 = rtw_read8(padapter, MSR) & 0xFC; /* 0x0102 */ ++ val8 |= WIFI_FW_ADHOC_STATE; ++ rtw_write8(padapter, MSR, val8); /* Link in ad hoc network */ ++ } ++ return res; ++} ++/* */ ++/* This function change the DUT from the MP test mode into normal mode */ ++void mp_stop_test(struct adapter *padapter) ++{ ++ struct mp_priv *pmppriv = &padapter->mppriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_network *tgt_network = &pmlmepriv->cur_network; ++ struct sta_info *psta; ++ ++ if (pmppriv->mode == MP_ON) { ++ pmppriv->bSetTxPower = 0; ++ spin_lock_bh(&pmlmepriv->lock); ++ if (!check_fwstate(pmlmepriv, WIFI_MP_STATE)) ++ goto end_of_mp_stop_test; ++ ++ /* 3 1. disconnect psudo AdHoc */ ++ rtw_indicate_disconnect(padapter); ++ ++ /* 3 2. clear psta used in mp test mode. */ ++ psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress); ++ if (psta) ++ rtw_free_stainfo(padapter, psta); ++ ++ /* 3 3. return to normal state (default:station mode) */ ++ pmlmepriv->fw_state = pmppriv->prev_fw_state; /* WIFI_STATION_STATE; */ ++ ++ /* flush the cur_network */ ++ memset(tgt_network, 0, sizeof(struct wlan_network)); ++ ++ _clr_fwstate_(pmlmepriv, WIFI_MP_STATE); ++ ++end_of_mp_stop_test: ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ } ++} ++ ++/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/ ++/* ++ * SetChannel ++ * Description ++ * Use H2C command to change channel, ++ * not only modify rf register, but also other setting need to be done. ++ */ ++void SetChannel(struct adapter *pAdapter) ++{ ++ Hal_SetChannel(pAdapter); ++} ++ ++/* ++ * Notice ++ * Switch bandwitdth may change center frequency(channel) ++ */ ++void SetBandwidth(struct adapter *pAdapter) ++{ ++ Hal_SetBandwidth(pAdapter); ++} ++ ++void SetAntenna(struct adapter *pAdapter) ++{ ++ Hal_SetAntenna(pAdapter); ++} ++ ++void SetAntennaPathPower(struct adapter *pAdapter) ++{ ++ Hal_SetAntennaPathPower(pAdapter); ++} ++ ++void SetTxPower(struct adapter *pAdapter) ++{ ++ Hal_SetTxPower(pAdapter); ++ } ++ ++void SetDataRate(struct adapter *pAdapter) ++{ ++ Hal_SetDataRate(pAdapter); ++} ++ ++void MP_PHY_SetRFPathSwitch(struct adapter *pAdapter, bool bMain) ++{ ++ PHY_SetRFPathSwitch(pAdapter, bMain); ++} ++ ++s32 SetThermalMeter(struct adapter *pAdapter, u8 target_ther) ++{ ++ return Hal_SetThermalMeter(pAdapter, target_ther); ++} ++ ++void GetThermalMeter(struct adapter *pAdapter, u8 *value) ++{ ++ Hal_GetThermalMeter(pAdapter, value); ++} ++ ++void SetSingleCarrierTx(struct adapter *pAdapter, u8 bStart) ++{ ++ PhySetTxPowerLevel(pAdapter); ++ Hal_SetSingleCarrierTx(pAdapter, bStart); ++} ++ ++void SetSingleToneTx(struct adapter *pAdapter, u8 bStart) ++{ ++ PhySetTxPowerLevel(pAdapter); ++ Hal_SetSingleToneTx(pAdapter, bStart); ++} ++ ++void SetCarrierSuppressionTx(struct adapter *pAdapter, u8 bStart) ++{ ++ PhySetTxPowerLevel(pAdapter); ++ Hal_SetCarrierSuppressionTx(pAdapter, bStart); ++} ++ ++void SetContinuousTx(struct adapter *pAdapter, u8 bStart) ++{ ++ PhySetTxPowerLevel(pAdapter); ++ Hal_SetContinuousTx(pAdapter, bStart); ++} ++ ++void PhySetTxPowerLevel(struct adapter *pAdapter) ++{ ++ struct mp_priv *pmp_priv = &pAdapter->mppriv; ++ ++ if (pmp_priv->bSetTxPower == 0) /* for NO manually set power index */ ++ PHY_SetTxPowerLevel8188E(pAdapter, pmp_priv->channel); ++} ++ ++/* */ ++static void dump_mpframe(struct adapter *padapter, struct xmit_frame *pmpframe) ++{ ++ rtw_hal_mgnt_xmit(padapter, pmpframe); ++} ++ ++static struct xmit_frame *alloc_mp_xmitframe(struct xmit_priv *pxmitpriv) ++{ ++ struct xmit_frame *pmpframe; ++ struct xmit_buf *pxmitbuf; ++ ++ pmpframe = rtw_alloc_xmitframe(pxmitpriv); ++ if (!pmpframe) ++ return NULL; ++ ++ pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); ++ if (!pxmitbuf) { ++ rtw_free_xmitframe(pxmitpriv, pmpframe); ++ return NULL; ++ } ++ ++ pmpframe->frame_tag = MP_FRAMETAG; ++ ++ pmpframe->pxmitbuf = pxmitbuf; ++ ++ pmpframe->buf_addr = pxmitbuf->pbuf; ++ ++ pxmitbuf->priv_data = pmpframe; ++ ++ return pmpframe; ++} ++ ++static int mp_xmit_packet_thread(void *context) ++{ ++ struct xmit_frame *pxmitframe; ++ struct mp_tx *pmptx; ++ struct mp_priv *pmp_priv; ++ struct xmit_priv *pxmitpriv; ++ struct adapter *padapter; ++ ++ pmp_priv = (struct mp_priv *)context; ++ pmptx = &pmp_priv->tx; ++ padapter = pmp_priv->papdater; ++ pxmitpriv = &padapter->xmitpriv; ++ ++ thread_enter("RTW_MP_THREAD"); ++ ++ /* DBG_88E("%s:pkTx Start\n", __func__); */ ++ while (1) { ++ pxmitframe = alloc_mp_xmitframe(pxmitpriv); ++ if (!pxmitframe) { ++ if (pmptx->stop || ++ padapter->bSurpriseRemoved || ++ padapter->bDriverStopped) { ++ goto exit; ++ } else { ++ msleep(1); ++ continue; ++ } ++ } ++ ++ memcpy((u8 *)(pxmitframe->buf_addr + TXDESC_OFFSET), pmptx->buf, pmptx->write_size); ++ memcpy(&pxmitframe->attrib, &pmptx->attrib, sizeof(struct pkt_attrib)); ++ ++ dump_mpframe(padapter, pxmitframe); ++ ++ pmptx->sended++; ++ pmp_priv->tx_pktcount++; ++ ++ if (pmptx->stop || ++ padapter->bSurpriseRemoved || ++ padapter->bDriverStopped) ++ goto exit; ++ if ((pmptx->count != 0) && ++ (pmptx->count == pmptx->sended)) ++ goto exit; ++ ++ flush_signals_thread(); ++ } ++ ++exit: ++ kfree(pmptx->pallocated_buf); ++ pmptx->pallocated_buf = NULL; ++ pmptx->stop = 1; ++ ++ thread_exit(); ++} ++ ++void fill_txdesc_for_mp(struct adapter *padapter, struct tx_desc *ptxdesc) ++{ ++ struct mp_priv *pmp_priv = &padapter->mppriv; ++ memcpy(ptxdesc, &pmp_priv->tx.desc, TXDESC_SIZE); ++} ++ ++void SetPacketTx(struct adapter *padapter) ++{ ++ u8 *ptr, *pkt_start, *pkt_end; ++ u32 pkt_size; ++ struct tx_desc *desc; ++ struct rtw_ieee80211_hdr *hdr; ++ u8 payload; ++ bool bmcast; ++ struct pkt_attrib *pattrib; ++ struct mp_priv *pmp_priv; ++ ++ pmp_priv = &padapter->mppriv; ++ if (pmp_priv->tx.stop) ++ return; ++ pmp_priv->tx.sended = 0; ++ pmp_priv->tx.stop = 0; ++ pmp_priv->tx_pktcount = 0; ++ ++ /* 3 1. update_attrib() */ ++ pattrib = &pmp_priv->tx.attrib; ++ memcpy(pattrib->src, padapter->eeprompriv.mac_addr, ETH_ALEN); ++ memcpy(pattrib->ta, pattrib->src, ETH_ALEN); ++ memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); ++ bmcast = is_multicast_ether_addr(pattrib->ra); ++ if (bmcast) { ++ pattrib->mac_id = 1; ++ pattrib->psta = rtw_get_bcmc_stainfo(padapter); ++ } else { ++ pattrib->mac_id = 0; ++ pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv)); ++ } ++ ++ pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen; ++ ++ /* 3 2. allocate xmit buffer */ ++ pkt_size = pattrib->last_txcmdsz; ++ ++ kfree(pmp_priv->tx.pallocated_buf); ++ pmp_priv->tx.write_size = pkt_size; ++ pmp_priv->tx.buf_size = pkt_size + XMITBUF_ALIGN_SZ; ++ pmp_priv->tx.pallocated_buf = kzalloc(pmp_priv->tx.buf_size, GFP_KERNEL); ++ if (!pmp_priv->tx.pallocated_buf) { ++ DBG_88E("%s: malloc(%d) fail!!\n", __func__, pmp_priv->tx.buf_size); ++ return; ++ } ++ pmp_priv->tx.buf = (u8 *)N_BYTE_ALIGMENT((size_t)(pmp_priv->tx.pallocated_buf), XMITBUF_ALIGN_SZ); ++ ptr = pmp_priv->tx.buf; ++ ++ desc = &pmp_priv->tx.desc; ++ memset(desc, 0, TXDESC_SIZE); ++ pkt_start = ptr; ++ pkt_end = pkt_start + pkt_size; ++ ++ /* 3 3. init TX descriptor */ ++ /* offset 0 */ ++ desc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); ++ desc->txdw0 |= cpu_to_le32(pkt_size & 0x0000FFFF); /* packet size */ ++ desc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00FF0000); /* 32 bytes for TX Desc */ ++ if (bmcast) ++ desc->txdw0 |= cpu_to_le32(BMC); /* broadcast packet */ ++ ++ desc->txdw1 |= cpu_to_le32((0x01 << 26) & 0xff000000); ++ /* offset 4 */ ++ desc->txdw1 |= cpu_to_le32((pattrib->mac_id) & 0x3F); /* CAM_ID(MAC_ID) */ ++ desc->txdw1 |= cpu_to_le32((pattrib->qsel << QSEL_SHT) & 0x00001F00); /* Queue Select, TID */ ++ ++ desc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000F0000); /* Rate Adaptive ID */ ++ /* offset 8 */ ++ /* offset 12 */ ++ ++ desc->txdw3 |= cpu_to_le32((pattrib->seqnum << 16) & 0x0fff0000); ++ ++ /* offset 16 */ ++ desc->txdw4 |= cpu_to_le32(HW_SSN); ++ desc->txdw4 |= cpu_to_le32(USERATE); ++ desc->txdw4 |= cpu_to_le32(DISDATAFB); ++ ++ if (pmp_priv->preamble) { ++ if (pmp_priv->rateidx <= MPT_RATE_54M) ++ desc->txdw4 |= cpu_to_le32(DATA_SHORT); /* CCK Short Preamble */ ++ } ++ if (pmp_priv->bandwidth == HT_CHANNEL_WIDTH_40) ++ desc->txdw4 |= cpu_to_le32(DATA_BW); ++ ++ /* offset 20 */ ++ desc->txdw5 |= cpu_to_le32(pmp_priv->rateidx & 0x0000001F); ++ ++ if (pmp_priv->preamble) { ++ if (pmp_priv->rateidx > MPT_RATE_54M) ++ desc->txdw5 |= cpu_to_le32(SGI); /* MCS Short Guard Interval */ ++ } ++ desc->txdw5 |= cpu_to_le32(RTY_LMT_EN); /* retry limit enable */ ++ desc->txdw5 |= cpu_to_le32(0x00180000); /* DATA/RTS Rate Fallback Limit */ ++ ++ /* 3 4. make wlan header, make_wlanhdr() */ ++ hdr = (struct rtw_ieee80211_hdr *)pkt_start; ++ SetFrameSubType(&hdr->frame_ctl, pattrib->subtype); ++ memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); /* DA */ ++ memcpy(hdr->addr2, pattrib->src, ETH_ALEN); /* SA */ ++ memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); /* RA, BSSID */ ++ ++ /* 3 5. make payload */ ++ ptr = pkt_start + pattrib->hdrlen; ++ ++ switch (pmp_priv->tx.payload) { ++ case 0: ++ payload = 0x00; ++ break; ++ case 1: ++ payload = 0x5a; ++ break; ++ case 2: ++ payload = 0xa5; ++ break; ++ case 3: ++ payload = 0xff; ++ break; ++ default: ++ payload = 0x00; ++ break; ++ } ++ ++ memset(ptr, payload, pkt_end - ptr); ++ ++ /* 3 6. start thread */ ++ pmp_priv->tx.PktTxThread = kthread_run(mp_xmit_packet_thread, pmp_priv, "RTW_MP_THREAD"); ++ if (IS_ERR(pmp_priv->tx.PktTxThread)) ++ DBG_88E("Create PktTx Thread Fail !!!!!\n"); ++} ++ ++void SetPacketRx(struct adapter *pAdapter, u8 bStartRx) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ ++ if (bStartRx) { ++ /* Accept CRC error and destination address */ ++ pHalData->ReceiveConfig = AAP | APM | AM | AB | APP_ICV | ++ AMF | ADF | APP_FCS | HTC_LOC_CTRL | ++ APP_MIC | APP_PHYSTS; ++ ++ pHalData->ReceiveConfig |= (RCR_ACRC32 | RCR_AAP); ++ ++ rtw_write32(pAdapter, REG_RCR, pHalData->ReceiveConfig); ++ ++ /* Accept all data frames */ ++ rtw_write16(pAdapter, REG_RXFLTMAP2, 0xFFFF); ++ } else { ++ rtw_write32(pAdapter, REG_RCR, 0); ++ } ++} ++ ++void ResetPhyRxPktCount(struct adapter *pAdapter) ++{ ++ u32 i, phyrx_set = 0; ++ ++ for (i = 0; i <= 0xF; i++) { ++ phyrx_set = 0; ++ phyrx_set |= _RXERR_RPT_SEL(i); /* select */ ++ phyrx_set |= RXERR_RPT_RST; /* set counter to zero */ ++ rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set); ++ } ++} ++ ++static u32 GetPhyRxPktCounts(struct adapter *pAdapter, u32 selbit) ++{ ++ /* selection */ ++ u32 phyrx_set = 0, count = 0; ++ ++ phyrx_set = _RXERR_RPT_SEL(selbit & 0xF); ++ rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set); ++ ++ /* Read packet count */ ++ count = rtw_read32(pAdapter, REG_RXERR_RPT) & RXERR_COUNTER_MASK; ++ ++ return count; ++} ++ ++u32 GetPhyRxPktReceived(struct adapter *pAdapter) ++{ ++ u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0; ++ ++ OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_OK); ++ CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_OK); ++ HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_OK); ++ ++ return OFDM_cnt + CCK_cnt + HT_cnt; ++} ++ ++u32 GetPhyRxPktCRC32Error(struct adapter *pAdapter) ++{ ++ u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0; ++ ++ OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_FAIL); ++ CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_FAIL); ++ HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_FAIL); ++ ++ return OFDM_cnt + CCK_cnt + HT_cnt; ++} ++ ++/* reg 0x808[9:0]: FFT data x */ ++/* reg 0x808[22]: 0 --> 1 to get 1 FFT data y */ ++/* reg 0x8B4[15:0]: FFT data y report */ ++static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point) ++{ ++ int psd_val; ++ ++ psd_val = rtw_read32(pAdapter, 0x808); ++ psd_val &= 0xFFBFFC00; ++ psd_val |= point; ++ ++ rtw_write32(pAdapter, 0x808, psd_val); ++ mdelay(1); ++ psd_val |= 0x00400000; ++ ++ rtw_write32(pAdapter, 0x808, psd_val); ++ mdelay(1); ++ psd_val = rtw_read32(pAdapter, 0x8B4); ++ ++ psd_val &= 0x0000FFFF; ++ ++ return psd_val; ++} ++ ++/* ++ *pts start_point_min stop_point_max ++ * 128 64 64 + 128 = 192 ++ * 256 128 128 + 256 = 384 ++ * 512 256 256 + 512 = 768 ++ * 1024 512 512 + 1024 = 1536 ++ */ ++u32 mp_query_psd(struct adapter *pAdapter, u8 *data) ++{ ++ u32 i, psd_pts = 0, psd_start = 0, psd_stop = 0; ++ u32 psd_data = 0; ++ ++ if (!netif_running(pAdapter->pnetdev)) ++ return 0; ++ ++ if (!check_fwstate(&pAdapter->mlmepriv, WIFI_MP_STATE)) ++ return 0; ++ ++ if (strlen(data) == 0) { /* default value */ ++ psd_pts = 128; ++ psd_start = 64; ++ psd_stop = 128; ++ } else { ++ sscanf(data, "pts =%d, start =%d, stop =%d", &psd_pts, &psd_start, &psd_stop); ++ } ++ ++ memset(data, '\0', sizeof(*data)); ++ ++ i = psd_start; ++ while (i < psd_stop) { ++ if (i >= psd_pts) { ++ psd_data = rtw_GetPSDData(pAdapter, i - psd_pts); ++ } else { ++ psd_data = rtw_GetPSDData(pAdapter, i); ++ } ++ sprintf(data + strlen(data), "%x ", psd_data); ++ i++; ++ } ++ ++ msleep(100); ++ return strlen(data) + 1; ++} ++ ++void _rtw_mp_xmit_priv(struct xmit_priv *pxmitpriv) ++{ ++ int i, res; ++ struct adapter *padapter = pxmitpriv->adapter; ++ struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; ++ u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; ++ u32 num_xmit_extbuf = NR_XMIT_EXTBUFF; ++ ++ if (padapter->registrypriv.mp_mode == 0) { ++ max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; ++ num_xmit_extbuf = NR_XMIT_EXTBUFF; ++ } else { ++ max_xmit_extbuf_size = 6000; ++ num_xmit_extbuf = 8; ++ } ++ ++ pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; ++ for (i = 0; i < num_xmit_extbuf; i++) { ++ rtw_os_xmit_resource_free(padapter, pxmitbuf, (max_xmit_extbuf_size + XMITBUF_ALIGN_SZ)); ++ ++ pxmitbuf++; ++ } ++ ++ vfree(pxmitpriv->pallocated_xmit_extbuf); ++ ++ if (padapter->registrypriv.mp_mode == 0) { ++ max_xmit_extbuf_size = 6000; ++ num_xmit_extbuf = 8; ++ } else { ++ max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; ++ num_xmit_extbuf = NR_XMIT_EXTBUFF; ++ } ++ ++ /* Init xmit extension buff */ ++ _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue); ++ ++ pxmitpriv->pallocated_xmit_extbuf = vzalloc(num_xmit_extbuf * sizeof(struct xmit_buf) + 4); ++ ++ if (!pxmitpriv->pallocated_xmit_extbuf) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_xmit_extbuf), 4); ++ ++ pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; ++ ++ for (i = 0; i < num_xmit_extbuf; i++) { ++ INIT_LIST_HEAD(&pxmitbuf->list); ++ ++ pxmitbuf->priv_data = NULL; ++ pxmitbuf->padapter = padapter; ++ pxmitbuf->ext_tag = true; ++ ++ res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ); ++ if (res == _FAIL) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmit_extbuf_queue.queue); ++ pxmitbuf++; ++ } ++ ++ pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf; ++ ++exit: ++ ; ++} ++ ++void Hal_ProSetCrystalCap(struct adapter *pAdapter, u32 CrystalCapVal) ++{ ++ CrystalCapVal = CrystalCapVal & 0x3F; ++ ++ // write 0x24[16:11] = 0x24[22:17] = CrystalCap ++ PHY_SetBBReg(pAdapter, REG_AFE_XTAL_CTRL, 0x7FF800, ++ (CrystalCapVal | (CrystalCapVal << 6))); ++} +diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c +new file mode 100644 +index 000000000000..c85f8e467337 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c +@@ -0,0 +1,1170 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_MP_IOCTL_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/mlme_osdep.h" ++#include "../include/rtw_mp_ioctl.h" ++ ++/* rtl8188eu_oid_rtl_seg_81_85 section start **************** */ ++int rtl8188eu_oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->information_buf_len < sizeof(u8)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ if (poid_par_priv->type_of_oid == SET_OID) { ++ Adapter->registrypriv.wireless_mode = *(u8 *)poid_par_priv->information_buf; ++ } else if (poid_par_priv->type_of_oid == QUERY_OID) { ++ *(u8 *)poid_par_priv->information_buf = Adapter->registrypriv.wireless_mode; ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ } else { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ } ++ ++ return status; ++} ++/* rtl8188eu_oid_rtl_seg_81_87_80 section start **************** */ ++int rtl8188eu_oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct bb_reg_param *pbbreg; ++ u16 offset; ++ u32 value; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf); ++ ++ offset = (u16)(pbbreg->offset) & 0xFFF; /* 0ffset :0x800~0xfff */ ++ if (offset < BB_REG_BASE_ADDR) ++ offset |= BB_REG_BASE_ADDR; ++ ++ value = pbbreg->value; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ write_bbreg(Adapter, offset, 0xFFFFFFFF, value); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct bb_reg_param *pbbreg; ++ u16 offset; ++ u32 value; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf); ++ ++ offset = (u16)(pbbreg->offset) & 0xFFF; /* 0ffset :0x800~0xfff */ ++ if (offset < BB_REG_BASE_ADDR) ++ offset |= BB_REG_BASE_ADDR; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ value = read_bbreg(Adapter, offset, 0xFFFFFFFF); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ pbbreg->value = value; ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct rf_reg_param *pbbreg; ++ u8 path; ++ u8 offset; ++ u32 value; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf); ++ ++ if (pbbreg->path >= RF_PATH_MAX) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ if (pbbreg->offset > 0xFF) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ if (pbbreg->value > 0xFFFFF) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ path = (u8)pbbreg->path; ++ offset = (u8)pbbreg->offset; ++ value = pbbreg->value; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ write_rfreg(Adapter, path, offset, value); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct rf_reg_param *pbbreg; ++ u8 path; ++ u8 offset; ++ u32 value; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ int status = NDIS_STATUS_SUCCESS; ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf); ++ ++ if (pbbreg->path >= RF_PATH_MAX) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ if (pbbreg->offset > 0xFF) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ path = (u8)pbbreg->path; ++ offset = (u8)pbbreg->offset; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ value = read_rfreg(Adapter, path, offset); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ pbbreg->value = value; ++ ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ ++ return status; ++} ++/* rtl8188eu_oid_rtl_seg_81_87_00 section end**************** */ ++/* */ ++ ++/* rtl8188eu_oid_rtl_seg_81_80_00 section start **************** */ ++/* */ ++int rtl8188eu_oid_rt_pro_set_data_rate_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 ratevalue;/* 4 */ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len != sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ ratevalue = *((u32 *)poid_par_priv->information_buf);/* 4 */ ++ if (ratevalue >= MPT_RATE_LAST) ++ return NDIS_STATUS_INVALID_DATA; ++ ++ Adapter->mppriv.rateidx = ratevalue; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetDataRate(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 mode; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (Adapter->registrypriv.mp_mode == 0) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ++ /* IQCalibrateBcut(Adapter); */ ++ ++ mode = *((u32 *)poid_par_priv->information_buf); ++ Adapter->mppriv.mode = mode;/* 1 for loopback */ ++ ++ if (mp_start_test(Adapter) == _FAIL) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ goto exit; ++ } ++ ++exit: ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ mp_stop_test(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 Channel; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->information_buf_len != sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ if (poid_par_priv->type_of_oid == QUERY_OID) { ++ *((u32 *)poid_par_priv->information_buf) = Adapter->mppriv.channel; ++ return NDIS_STATUS_SUCCESS; ++ } ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ Channel = *((u32 *)poid_par_priv->information_buf); ++ if (Channel > 14) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ Adapter->mppriv.channel = Channel; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetChannel(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u16 bandwidth; ++ u16 channel_offset; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *padapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ bandwidth = *((u32 *)poid_par_priv->information_buf);/* 4 */ ++ channel_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ ++ if (bandwidth != HT_CHANNEL_WIDTH_40) ++ bandwidth = HT_CHANNEL_WIDTH_20; ++ padapter->mppriv.bandwidth = (u8)bandwidth; ++ padapter->mppriv.prime_channel_offset = (u8)channel_offset; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetBandwidth(padapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 antenna; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->information_buf_len != sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ if (poid_par_priv->type_of_oid == SET_OID) { ++ antenna = *(u32 *)poid_par_priv->information_buf; ++ ++ Adapter->mppriv.antenna_tx = (u16)((antenna & 0xFFFF0000) >> 16); ++ Adapter->mppriv.antenna_rx = (u16)(antenna & 0x0000FFFF); ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetAntenna(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ } else { ++ antenna = (Adapter->mppriv.antenna_tx << 16) | Adapter->mppriv.antenna_rx; ++ *(u32 *)poid_par_priv->information_buf = antenna; ++ } ++ ++ return status; ++} ++ ++int rtl8188eu_oid_rt_pro_set_tx_power_control_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 tx_pwr_idx; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len != sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ tx_pwr_idx = *((u32 *)poid_par_priv->information_buf); ++ if (tx_pwr_idx > MAX_TX_PWR_INDEX_N_MODE) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ Adapter->mppriv.txpoweridx = (u8)tx_pwr_idx; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetTxPower(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++ ++/* */ ++/* rtl8188eu_oid_rtl_seg_81_80_20 section start **************** */ ++/* */ ++int rtl8188eu_oid_rt_pro_query_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ return status; ++ } ++ ++ if (poid_par_priv->information_buf_len == sizeof(u32)) { ++ *(u32 *)poid_par_priv->information_buf = Adapter->mppriv.tx_pktcount; ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ } else { ++ status = NDIS_STATUS_INVALID_LENGTH; ++ } ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_query_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ return status; ++ } ++ if (poid_par_priv->information_buf_len == sizeof(u32)) { ++ *(u32 *)poid_par_priv->information_buf = Adapter->mppriv.rx_pktcount; ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ } else { ++ status = NDIS_STATUS_INVALID_LENGTH; ++ } ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_query_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ return status; ++ } ++ if (poid_par_priv->information_buf_len == sizeof(u32)) { ++ *(u32 *)poid_par_priv->information_buf = Adapter->mppriv.rx_crcerrpktcount; ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ } else { ++ status = NDIS_STATUS_INVALID_LENGTH; ++ } ++ ++ return status; ++} ++/* */ ++ ++int rtl8188eu_oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ return status; ++ } ++ ++ Adapter->mppriv.tx_pktcount = 0; ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ return status; ++ } ++ ++ if (poid_par_priv->information_buf_len == sizeof(u32)) { ++ Adapter->mppriv.rx_pktcount = 0; ++ Adapter->mppriv.rx_crcerrpktcount = 0; ++ } else { ++ status = NDIS_STATUS_INVALID_LENGTH; ++ } ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ return status; ++ } ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ResetPhyRxPktCount(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len != sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ *(u32 *)poid_par_priv->information_buf = GetPhyRxPktReceived(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len != sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ *(u32 *)poid_par_priv->information_buf = GetPhyRxPktCRC32Error(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ ++ return status; ++} ++/* rtl8188eu_oid_rtl_seg_81_80_20 section end **************** */ ++int rtl8188eu_oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 bStartTest; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ bStartTest = *((u32 *)poid_par_priv->information_buf); ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetContinuousTx(Adapter, (u8)bStartTest); ++ if (bStartTest) { ++ struct mp_priv *pmp_priv = &Adapter->mppriv; ++ if (pmp_priv->tx.stop == 0) { ++ pmp_priv->tx.stop = 1; ++ DBG_88E("%s: pkt tx is running...\n", __func__); ++ msleep(5); ++ } ++ pmp_priv->tx.stop = 0; ++ pmp_priv->tx.count = 1; ++ SetPacketTx(Adapter); ++ } ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++ ++int rtl8188eu_oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 bStartTest; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ bStartTest = *((u32 *)poid_par_priv->information_buf); ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetSingleCarrierTx(Adapter, (u8)bStartTest); ++ if (bStartTest) { ++ struct mp_priv *pmp_priv = &Adapter->mppriv; ++ if (pmp_priv->tx.stop == 0) { ++ pmp_priv->tx.stop = 1; ++ DBG_88E("%s: pkt tx is running...\n", __func__); ++ msleep(5); ++ } ++ pmp_priv->tx.stop = 0; ++ pmp_priv->tx.count = 1; ++ SetPacketTx(Adapter); ++ } ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++ ++int rtl8188eu_oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 bStartTest; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ bStartTest = *((u32 *)poid_par_priv->information_buf); ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetCarrierSuppressionTx(Adapter, (u8)bStartTest); ++ if (bStartTest) { ++ struct mp_priv *pmp_priv = &Adapter->mppriv; ++ if (pmp_priv->tx.stop == 0) { ++ pmp_priv->tx.stop = 1; ++ DBG_88E("%s: pkt tx is running...\n", __func__); ++ msleep(5); ++ } ++ pmp_priv->tx.stop = 0; ++ pmp_priv->tx.count = 1; ++ SetPacketTx(Adapter); ++ } ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++ ++int rtl8188eu_oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 bStartTest; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ bStartTest = *((u32 *)poid_par_priv->information_buf); ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetSingleToneTx(Adapter, (u8)bStartTest); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++ ++int rtl8188eu_oid_rt_pro_set_modulation_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++int rtl8188eu_oid_rt_pro_trigger_gpio_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ int status = NDIS_STATUS_SUCCESS; ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ rtw_hal_set_hwreg(Adapter, HW_VAR_TRIGGER_GPIO_0, NULL); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* rtl8188eu_oid_rtl_seg_81_80_00 section end **************** */ ++/* */ ++int rtl8188eu_oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct mp_rw_reg *RegRWStruct; ++ u32 offset, width; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf; ++ offset = RegRWStruct->offset; ++ width = RegRWStruct->width; ++ ++ if (offset > 0xFFF) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ++ switch (width) { ++ case 1: ++ RegRWStruct->value = rtw_read8(Adapter, offset); ++ break; ++ case 2: ++ RegRWStruct->value = rtw_read16(Adapter, offset); ++ break; ++ default: ++ width = 4; ++ RegRWStruct->value = rtw_read32(Adapter, offset); ++ break; ++ } ++ ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ *poid_par_priv->bytes_rw = width; ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct mp_rw_reg *RegRWStruct; ++ u32 offset, value; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *padapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf; ++ offset = RegRWStruct->offset; ++ value = RegRWStruct->value; ++ ++ if (offset > 0xFFF) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ++ switch (RegRWStruct->width) { ++ case 1: ++ if (value > 0xFF) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ break; ++ } ++ rtw_write8(padapter, offset, (u8)value); ++ break; ++ case 2: ++ if (value > 0xFFFF) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ break; ++ } ++ rtw_write16(padapter, offset, (u16)value); ++ break; ++ case 4: ++ rtw_write32(padapter, offset, value); ++ break; ++ default: ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ break; ++ } ++ ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_burst_read_register_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_burst_write_register_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++/* */ ++int rtl8188eu_oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++/* */ ++int rtl8188eu_oid_rt_pro_write16_eeprom_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_wr_attrib_mem_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_cfg_debug_message_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_set_data_rate_ex_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ int status = NDIS_STATUS_SUCCESS; ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ++ if (rtw_setdatarate_cmd(Adapter, poid_par_priv->information_buf) != _SUCCESS) ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ u8 thermal = 0; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ GetThermalMeter(Adapter, &thermal); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ *(u32 *)poid_par_priv->information_buf = (u32)thermal; ++ *poid_par_priv->bytes_rw = sizeof(u32); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_read_tssi_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_set_power_tracking_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->information_buf_len < sizeof(u8)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ if (poid_par_priv->type_of_oid == SET_OID) { ++ u8 enable; ++ ++ enable = *(u8 *)poid_par_priv->information_buf; ++ ++ SetPowerTracking(Adapter, enable); ++ } else { ++ GetPowerTracking(Adapter, (u8 *)poid_par_priv->information_buf); ++ } ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_set_basic_rate_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_qry_pwrstate_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_set_pwrstate_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_h2c_set_rate_table_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_h2c_get_rate_table_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++/* rtl8188eu_oid_rtl_seg_87_12_00 section start **************** */ ++int rtl8188eu_oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++int rtl8188eu_oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++int rtl8188eu_oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++int rtl8188eu_oid_rt_pro_query_dr_variable_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++int rtl8188eu_oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return NDIS_STATUS_SUCCESS; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct efuse_access_struct *pefuse; ++ u8 *data; ++ u16 addr = 0, cnts = 0, max_available_size = 0; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(struct efuse_access_struct)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ pefuse = (struct efuse_access_struct *)poid_par_priv->information_buf; ++ addr = pefuse->start_addr; ++ cnts = pefuse->cnts; ++ data = pefuse->data; ++ ++ EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ ++ if ((addr + cnts) > max_available_size) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ if (rtw_efuse_access(Adapter, false, addr, cnts, data) == _FAIL) ++ status = NDIS_STATUS_FAILURE; ++ else ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct efuse_access_struct *pefuse; ++ u8 *data; ++ u16 addr = 0, cnts = 0, max_available_size = 0; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ pefuse = (struct efuse_access_struct *)poid_par_priv->information_buf; ++ addr = pefuse->start_addr; ++ cnts = pefuse->cnts; ++ data = pefuse->data; ++ ++ EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ ++ if ((addr + cnts) > max_available_size) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ if (rtw_efuse_access(Adapter, true, addr, cnts, data) == _FAIL) ++ status = NDIS_STATUS_FAILURE; ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct pgpkt *ppgpkt; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ *poid_par_priv->bytes_rw = 0; ++ ++ if (poid_par_priv->information_buf_len < sizeof(struct pgpkt *)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ ppgpkt = (struct pgpkt *)poid_par_priv->information_buf; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ++ if (poid_par_priv->type_of_oid == QUERY_OID) { ++ Efuse_PowerSwitch(Adapter, false, true); ++ if (Efuse_PgPacketRead(Adapter, ppgpkt->offset, ppgpkt->data, false)) ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ else ++ status = NDIS_STATUS_FAILURE; ++ Efuse_PowerSwitch(Adapter, false, false); ++ } else { ++ Efuse_PowerSwitch(Adapter, true, true); ++ if (Efuse_PgPacketWrite(Adapter, ppgpkt->offset, ppgpkt->word_en, ppgpkt->data, false)) ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ else ++ status = NDIS_STATUS_FAILURE; ++ Efuse_PowerSwitch(Adapter, true, false); ++ } ++ ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_get_efuse_current_size_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u16 size; ++ u8 ret; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ret = efuse_GetCurrentSize(Adapter, &size); ++ _irqlevel_changed_(&oldirql, RAISE); ++ if (ret == _SUCCESS) { ++ *(u32 *)poid_par_priv->information_buf = size; ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ } else { ++ status = NDIS_STATUS_FAILURE; ++ } ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ *(u32 *)poid_par_priv->information_buf = efuse_GetMaxSize(Adapter); ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status; ++ ++ if (poid_par_priv->type_of_oid == QUERY_OID) ++ status = rtl8188eu_oid_rt_pro_read_efuse_hdl(poid_par_priv); ++ else ++ status = rtl8188eu_oid_rt_pro_write_efuse_hdl(poid_par_priv); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u8 *data; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ u16 maplen = 0; ++ ++ EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&maplen, false); ++ ++ *poid_par_priv->bytes_rw = 0; ++ ++ if (poid_par_priv->information_buf_len < maplen) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ data = (u8 *)poid_par_priv->information_buf; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ++ if (poid_par_priv->type_of_oid == QUERY_OID) { ++ if (rtw_efuse_map_read(Adapter, 0, maplen, data) == _SUCCESS) ++ *poid_par_priv->bytes_rw = maplen; ++ else ++ status = NDIS_STATUS_FAILURE; ++ } else { ++ /* SET_OID */ ++ if (rtw_efuse_map_write(Adapter, 0, maplen, data) == _SUCCESS) ++ *poid_par_priv->bytes_rw = maplen; ++ else ++ status = NDIS_STATUS_FAILURE; ++ } ++ ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++ ++int rtl8188eu_oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ return status; ++} ++ ++int rtl8188eu_oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(u8)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ return status; ++} ++ ++int rtl8188eu_oid_rt_pro_set_tx_agc_offset_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++int rtl8188eu_oid_rt_pro_set_pkt_test_mode_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++int rtl8188eu_mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct mp_xmit_parm *pparm; ++ struct adapter *padapter; ++ struct mp_priv *pmp_priv; ++ struct pkt_attrib *pattrib; ++ ++ pparm = (struct mp_xmit_parm *)poid_par_priv->information_buf; ++ padapter = (struct adapter *)poid_par_priv->adapter_context; ++ pmp_priv = &padapter->mppriv; ++ ++ if (poid_par_priv->type_of_oid == QUERY_OID) { ++ pparm->enable = !pmp_priv->tx.stop; ++ pparm->count = pmp_priv->tx.sended; ++ } else { ++ if (pparm->enable == 0) { ++ pmp_priv->tx.stop = 1; ++ } else if (pmp_priv->tx.stop == 1) { ++ pmp_priv->tx.stop = 0; ++ pmp_priv->tx.count = pparm->count; ++ pmp_priv->tx.payload = pparm->payload_type; ++ pattrib = &pmp_priv->tx.attrib; ++ pattrib->pktlen = pparm->length; ++ memcpy(pattrib->dst, pparm->da, ETH_ALEN); ++ SetPacketTx(padapter); ++ } else { ++ return NDIS_STATUS_FAILURE; ++ } ++ } ++ ++ return NDIS_STATUS_SUCCESS; ++} ++ ++/* */ ++int rtl8188eu_oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ ++ if (poid_par_priv->type_of_oid != SET_OID) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ return status; ++ } ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ++ /* CALL the power_down function */ ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_get_power_mode_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_p2p.c b/drivers/staging/r8188eu/core/rtw_p2p.c +new file mode 100644 +index 000000000000..e2b6cf2386e0 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_p2p.c +@@ -0,0 +1,1997 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_P2P_C_ ++ ++#include "../include/drv_types.h" ++#include "../include/rtw_p2p.h" ++#include "../include/wifi.h" ++ ++#ifdef CONFIG_88EU_P2P ++ ++static int rtw_p2p_is_channel_list_ok(u8 desired_ch, u8 *ch_list, u8 ch_cnt) ++{ ++ int found = 0, i = 0; ++ ++ for (i = 0; i < ch_cnt; i++) { ++ if (ch_list[i] == desired_ch) { ++ found = 1; ++ break; ++ } ++ } ++ return found; ++} ++ ++static u32 go_add_group_info_attr(struct wifidirect_info *pwdinfo, u8 *pbuf) ++{ ++ struct list_head *phead, *plist; ++ u32 len = 0; ++ u16 attr_len = 0; ++ u8 tmplen, *pdata_attr, *pstart, *pcur; ++ struct sta_info *psta = NULL; ++ struct adapter *padapter = pwdinfo->padapter; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ DBG_88E("%s\n", __func__); ++ ++ pdata_attr = kzalloc(MAX_P2P_IE_LEN, GFP_KERNEL); ++ ++ pstart = pdata_attr; ++ pcur = pdata_attr; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ phead = &pstapriv->asoc_list; ++ plist = phead->next; ++ ++ /* look up sta asoc_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, asoc_list); ++ ++ plist = plist->next; ++ ++ if (psta->is_p2p_device) { ++ tmplen = 0; ++ ++ pcur++; ++ ++ /* P2P device address */ ++ memcpy(pcur, psta->dev_addr, ETH_ALEN); ++ pcur += ETH_ALEN; ++ ++ /* P2P interface address */ ++ memcpy(pcur, psta->hwaddr, ETH_ALEN); ++ pcur += ETH_ALEN; ++ ++ *pcur = psta->dev_cap; ++ pcur++; ++ ++ /* u16*)(pcur) = cpu_to_be16(psta->config_methods); */ ++ RTW_PUT_BE16(pcur, psta->config_methods); ++ pcur += 2; ++ ++ memcpy(pcur, psta->primary_dev_type, 8); ++ pcur += 8; ++ ++ *pcur = psta->num_of_secdev_type; ++ pcur++; ++ ++ memcpy(pcur, psta->secdev_types_list, psta->num_of_secdev_type * 8); ++ pcur += psta->num_of_secdev_type * 8; ++ ++ if (psta->dev_name_len > 0) { ++ /* u16*)(pcur) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */ ++ RTW_PUT_BE16(pcur, WPS_ATTR_DEVICE_NAME); ++ pcur += 2; ++ ++ /* u16*)(pcur) = cpu_to_be16(psta->dev_name_len); */ ++ RTW_PUT_BE16(pcur, psta->dev_name_len); ++ pcur += 2; ++ ++ memcpy(pcur, psta->dev_name, psta->dev_name_len); ++ pcur += psta->dev_name_len; ++ } ++ ++ tmplen = (u8)(pcur - pstart); ++ ++ *pstart = (tmplen - 1); ++ ++ attr_len += tmplen; ++ ++ /* pstart += tmplen; */ ++ pstart = pcur; ++ } ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ if (attr_len > 0) ++ len = rtw_set_p2p_attr_content(pbuf, P2P_ATTR_GROUP_INFO, attr_len, pdata_attr); ++ ++ kfree(pdata_attr); ++ return len; ++} ++ ++static void issue_group_disc_req(struct wifidirect_info *pwdinfo, u8 *da) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct adapter *padapter = pwdinfo->padapter; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ unsigned char category = RTW_WLAN_CATEGORY_P2P;/* P2P action frame */ ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_GO_DISC_REQUEST; ++ u8 dialogToken = 0; ++ ++ DBG_88E("[%s]\n", __func__); ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ /* Build P2P action frame header */ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen); ++ ++ /* there is no IE in this P2P action frame */ ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct adapter *padapter = pwdinfo->padapter; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_DEVDISC_RESP; ++ u8 p2pie[8] = { 0x00 }; ++ u32 p2pielen = 0; ++ ++ DBG_88E("[%s]\n", __func__); ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, pwdinfo->device_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, pwdinfo->device_addr, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ /* Build P2P public action frame header */ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen); ++ ++ /* Build P2P IE */ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* P2P_ATTR_STATUS */ ++ p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status); ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8 *raddr, u8 *frame_body, u16 config_method) ++{ ++ struct adapter *padapter = pwdinfo->padapter; ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ u8 dialogToken = frame_body[7]; /* The Dialog Token of provisioning discovery request frame. */ ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_PROVISION_DISC_RESP; ++ u8 wpsie[100] = { 0x00 }; ++ u8 wpsielen = 0; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen); ++ ++ wpsielen = 0; ++ /* WPS OUI */ ++ RTW_PUT_BE32(wpsie, WPSOUI); ++ wpsielen += 4; ++ ++ /* Config Method */ ++ /* Type: */ ++ RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD); ++ wpsielen += 2; ++ ++ /* Length: */ ++ RTW_PUT_BE16(wpsie + wpsielen, 0x0002); ++ wpsielen += 2; ++ ++ /* Value: */ ++ RTW_PUT_BE16(wpsie + wpsielen, config_method); ++ wpsielen += 2; ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct adapter *padapter = pwdinfo->padapter; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ unsigned char category = RTW_WLAN_CATEGORY_P2P;/* P2P action frame */ ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_PRESENCE_RESPONSE; ++ u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 }; ++ u8 noa_attr_content[32] = { 0x00 }; ++ u32 p2pielen = 0; ++ ++ DBG_88E("[%s]\n", __func__); ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ /* Build P2P action frame header */ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen); ++ ++ /* Add P2P IE header */ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Add Status attribute in P2P IE */ ++ p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status); ++ ++ /* Add NoA attribute in P2P IE */ ++ noa_attr_content[0] = 0x1;/* index */ ++ noa_attr_content[1] = 0x0;/* CTWindow and OppPS Parameters */ ++ ++ /* todo: Notice of Absence Descriptor(s) */ ++ ++ p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_NOA, 2, noa_attr_content); ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) ++{ ++ u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 }; ++ u16 capability = 0; ++ u32 len = 0, p2pielen = 0; ++ __le16 le_tmp; ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* According to the P2P Specification, the beacon frame should contain 3 P2P attributes */ ++ /* 1. P2P Capability */ ++ /* 2. P2P Device ID */ ++ /* 3. Notice of Absence (NOA) */ ++ ++ /* P2P Capability ATTR */ ++ /* Type: */ ++ /* Length: */ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ /* Be able to participate in additional P2P Groups and */ ++ /* support the P2P Invitation Procedure */ ++ /* Group Capability Bitmap, 1 byte */ ++ capability = P2P_DEVCAP_INVITATION_PROC | P2P_DEVCAP_CLIENT_DISCOVERABILITY; ++ capability |= ((P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS) << 8); ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) ++ capability |= (P2P_GRPCAP_GROUP_FORMATION << 8); ++ ++ le_tmp = cpu_to_le16(capability); ++ p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_CAPABILITY, 2, (u8 *)&le_tmp); ++ ++ /* P2P Device ID ATTR */ ++ p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_DEVICE_ID, ETH_ALEN, pwdinfo->device_addr); ++ ++ /* Notice of Absence ATTR */ ++ /* Type: */ ++ /* Length: */ ++ /* Value: */ ++ ++ pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len); ++ return len; ++} ++ ++u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) ++{ ++ u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 }; ++ u32 len = 0, p2pielen = 0; ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20100907 */ ++ /* According to the P2P Specification, the probe response frame should contain 5 P2P attributes */ ++ /* 1. P2P Capability */ ++ /* 2. Extended Listen Timing */ ++ /* 3. Notice of Absence (NOA) (Only GO needs this) */ ++ /* 4. Device Info */ ++ /* 5. Group Info (Only GO need this) */ ++ ++ /* P2P Capability ATTR */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CAPABILITY; ++ ++ /* Length: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002); */ ++ RTW_PUT_LE16(p2pie + p2pielen, 0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT; ++ ++ /* Group Capability Bitmap, 1 byte */ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ p2pie[p2pielen] = (P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS); ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) ++ p2pie[p2pielen] |= P2P_GRPCAP_GROUP_FORMATION; ++ ++ p2pielen++; ++ } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) { ++ /* Group Capability Bitmap, 1 byte */ ++ if (pwdinfo->persistent_supported) ++ p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; ++ else ++ p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT; ++ } ++ ++ /* Extended Listen Timing ATTR */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING; ++ ++ /* Length: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0004); */ ++ RTW_PUT_LE16(p2pie + p2pielen, 0x0004); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Availability Period */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF); */ ++ RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF); ++ p2pielen += 2; ++ ++ /* Availability Interval */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF); */ ++ RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF); ++ p2pielen += 2; ++ ++ /* Notice of Absence ATTR */ ++ /* Type: */ ++ /* Length: */ ++ /* Value: */ ++ ++ /* Device Info ATTR */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO; ++ ++ /* Length: */ ++ /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */ ++ /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); */ ++ RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Config Method */ ++ /* This field should be big endian. Noted by P2P specification. */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm); */ ++ RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->supported_wps_cm); ++ p2pielen += 2; ++ ++ /* Primary Device Type */ ++ /* Category ID */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA); ++ p2pielen += 2; ++ ++ /* OUI */ ++ /* u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI); */ ++ RTW_PUT_BE32(p2pie + p2pielen, WPSOUI); ++ p2pielen += 4; ++ ++ /* Sub Category ID */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER); ++ p2pielen += 2; ++ ++ /* Number of Secondary Device Types */ ++ p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */ ++ ++ /* Device Name */ ++ /* Type: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME); ++ p2pielen += 2; ++ ++ /* Length: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); */ ++ RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ p2pielen += pwdinfo->device_name_len; ++ ++ /* Group Info ATTR */ ++ /* Type: */ ++ /* Length: */ ++ /* Value: */ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) ++ p2pielen += go_add_group_info_attr(pwdinfo, p2pie + p2pielen); ++ ++ pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len); ++ ++ return len; ++} ++ ++u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 *pssid, u8 ussidlen, u8 *pdev_raddr) ++{ ++ u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 }; ++ u32 len = 0, p2pielen = 0; ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20110301 */ ++ /* According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes */ ++ /* 1. P2P Capability */ ++ /* 2. Device Info */ ++ /* 3. Group ID (When joining an operating P2P Group) */ ++ ++ /* P2P Capability ATTR */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CAPABILITY; ++ ++ /* Length: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002); */ ++ RTW_PUT_LE16(p2pie + p2pielen, 0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT; ++ ++ /* Group Capability Bitmap, 1 byte */ ++ if (pwdinfo->persistent_supported) ++ p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; ++ else ++ p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT; ++ ++ /* Device Info ATTR */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO; ++ ++ /* Length: */ ++ /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */ ++ /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); */ ++ RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Config Method */ ++ /* This field should be big endian. Noted by P2P specification. */ ++ if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC) { ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_PBC); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_PBC); ++ } else { ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_DISPLAY); ++ } ++ ++ p2pielen += 2; ++ ++ /* Primary Device Type */ ++ /* Category ID */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA); ++ p2pielen += 2; ++ ++ /* OUI */ ++ /* u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI); */ ++ RTW_PUT_BE32(p2pie + p2pielen, WPSOUI); ++ p2pielen += 4; ++ ++ /* Sub Category ID */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER); ++ p2pielen += 2; ++ ++ /* Number of Secondary Device Types */ ++ p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */ ++ ++ /* Device Name */ ++ /* Type: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME); ++ p2pielen += 2; ++ ++ /* Length: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); */ ++ RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ p2pielen += pwdinfo->device_name_len; ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) { ++ /* Added by Albert 2011/05/19 */ ++ /* In this case, the pdev_raddr is the device address of the group owner. */ ++ ++ /* P2P Group ID ATTR */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GROUP_ID; ++ ++ /* Length: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + ussidlen); */ ++ RTW_PUT_LE16(p2pie + p2pielen, ETH_ALEN + ussidlen); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pdev_raddr, ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ memcpy(p2pie + p2pielen, pssid, ussidlen); ++ p2pielen += ussidlen; ++ } ++ ++ pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len); ++ ++ return len; ++} ++ ++u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 status_code) ++{ ++ u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 }; ++ u32 len = 0, p2pielen = 0; ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* According to the P2P Specification, the Association response frame should contain 2 P2P attributes */ ++ /* 1. Status */ ++ /* 2. Extended Listen Timing (optional) */ ++ ++ /* Status ATTR */ ++ p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status_code); ++ ++ /* Extended Listen Timing ATTR */ ++ /* Type: */ ++ /* Length: */ ++ /* Value: */ ++ ++ pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len); ++ ++ return len; ++} ++ ++u32 build_deauth_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) ++{ ++ u32 len = 0; ++ ++ return len; ++} ++ ++u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ u8 *p; ++ u32 ret = false; ++ u8 *p2pie; ++ u32 p2pielen = 0; ++ int ssid_len = 0, rate_cnt = 0; ++ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SUPPORTEDRATES_IE_, (int *)&rate_cnt, ++ len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); ++ ++ if (rate_cnt <= 4) { ++ int i, g_rate = 0; ++ ++ for (i = 0; i < rate_cnt; i++) { ++ if (((*(p + 2 + i) & 0xff) != 0x02) && ++ ((*(p + 2 + i) & 0xff) != 0x04) && ++ ((*(p + 2 + i) & 0xff) != 0x0B) && ++ ((*(p + 2 + i) & 0xff) != 0x16)) ++ g_rate = 1; ++ } ++ ++ if (g_rate == 0) { ++ /* There is no OFDM rate included in SupportedRates IE of this probe request frame */ ++ /* The driver should response this probe request. */ ++ return ret; ++ } ++ } else { ++ /* rate_cnt > 4 means the SupportRates IE contains the OFDM rate because the count of CCK rates are 4. */ ++ /* We should proceed the following check for this probe request. */ ++ } ++ ++ /* Added comments by Albert 20100906 */ ++ /* There are several items we should check here. */ ++ /* 1. This probe request frame must contain the P2P IE. (Done) */ ++ /* 2. This probe request frame must contain the wildcard SSID. (Done) */ ++ /* 3. Wildcard BSSID. (Todo) */ ++ /* 4. Destination Address. (Done in mgt_dispatcher function) */ ++ /* 5. Requested Device Type in WSC IE. (Todo) */ ++ /* 6. Device ID attribute in P2P IE. (Todo) */ ++ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ssid_len, ++ len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); ++ ++ ssid_len &= 0xff; /* Just last 1 byte is valid for ssid len of the probe request */ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_, NULL, &p2pielen); ++ if (p2pie) { ++ if (p && !memcmp((void *)(p + 2), (void *)pwdinfo->p2p_wildcard_ssid, 7)) { ++ /* todo: */ ++ /* Check Requested Device Type attributes in WSC IE. */ ++ /* Check Device ID attribute in P2P IE */ ++ ++ ret = true; ++ } else if (p && ssid_len == 0) { ++ ret = true; ++ } ++ } else { ++ /* non -p2p device */ ++ } ++ } ++ ++ return ret; ++} ++ ++u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len, struct sta_info *psta) ++{ ++ u8 status_code = P2P_STATUS_SUCCESS; ++ u8 *pbuf, *pattr_content = NULL; ++ u32 attr_contentlen = 0; ++ u16 cap_attr = 0; ++ unsigned short frame_type, ie_offset = 0; ++ u8 *ies; ++ u32 ies_len; ++ u8 *p2p_ie; ++ u32 p2p_ielen = 0; ++ __be16 be_tmp; ++ __le16 le_tmp; ++ ++ if (!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) ++ return P2P_STATUS_FAIL_REQUEST_UNABLE; ++ ++ frame_type = GetFrameSubType(pframe); ++ if (frame_type == WIFI_ASSOCREQ) ++ ie_offset = _ASOCREQ_IE_OFFSET_; ++ else /* WIFI_REASSOCREQ */ ++ ie_offset = _REASOCREQ_IE_OFFSET_; ++ ++ ies = pframe + WLAN_HDR_A3_LEN + ie_offset; ++ ies_len = len - WLAN_HDR_A3_LEN - ie_offset; ++ ++ p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen); ++ ++ if (!p2p_ie) { ++ DBG_88E("[%s] P2P IE not Found!!\n", __func__); ++ status_code = P2P_STATUS_FAIL_INVALID_PARAM; ++ } else { ++ DBG_88E("[%s] P2P IE Found!!\n", __func__); ++ } ++ ++ while (p2p_ie) { ++ /* Check P2P Capability ATTR */ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&le_tmp, (uint *)&attr_contentlen)) { ++ DBG_88E("[%s] Got P2P Capability Attr!!\n", __func__); ++ cap_attr = le16_to_cpu(le_tmp); ++ psta->dev_cap = cap_attr & 0xff; ++ } ++ ++ /* Check Extended Listen Timing ATTR */ ++ ++ /* Check P2P Device Info ATTR */ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, NULL, (uint *)&attr_contentlen)) { ++ DBG_88E("[%s] Got P2P DEVICE INFO Attr!!\n", __func__); ++ pattr_content = kzalloc(attr_contentlen, GFP_KERNEL); ++ pbuf = pattr_content; ++ if (pattr_content) { ++ u8 num_of_secdev_type; ++ u16 dev_name_len; ++ ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, pattr_content, (uint *)&attr_contentlen); ++ ++ memcpy(psta->dev_addr, pattr_content, ETH_ALEN);/* P2P Device Address */ ++ ++ pattr_content += ETH_ALEN; ++ ++ memcpy(&be_tmp, pattr_content, 2);/* Config Methods */ ++ psta->config_methods = be16_to_cpu(be_tmp); ++ ++ pattr_content += 2; ++ ++ memcpy(psta->primary_dev_type, pattr_content, 8); ++ ++ pattr_content += 8; ++ ++ num_of_secdev_type = *pattr_content; ++ pattr_content += 1; ++ ++ if (num_of_secdev_type == 0) { ++ psta->num_of_secdev_type = 0; ++ } else { ++ u32 len; ++ ++ psta->num_of_secdev_type = num_of_secdev_type; ++ ++ len = (sizeof(psta->secdev_types_list) < (num_of_secdev_type * 8)) ? ++ (sizeof(psta->secdev_types_list)) : (num_of_secdev_type * 8); ++ ++ memcpy(psta->secdev_types_list, pattr_content, len); ++ ++ pattr_content += (num_of_secdev_type * 8); ++ } ++ ++ psta->dev_name_len = 0; ++ if (WPS_ATTR_DEVICE_NAME == be16_to_cpu(*(__be16 *)pattr_content)) { ++ dev_name_len = be16_to_cpu(*(__be16 *)(pattr_content + 2)); ++ ++ psta->dev_name_len = (sizeof(psta->dev_name) < dev_name_len) ? sizeof(psta->dev_name) : dev_name_len; ++ ++ memcpy(psta->dev_name, pattr_content + 4, psta->dev_name_len); ++ } ++ kfree(pbuf); ++ } ++ } ++ ++ /* Get the next P2P IE */ ++ p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen); ++ } ++ ++ return status_code; ++} ++ ++u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ u8 *frame_body; ++ u8 status, dialogToken; ++ struct sta_info *psta = NULL; ++ struct adapter *padapter = pwdinfo->padapter; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 *p2p_ie; ++ u32 p2p_ielen = 0; ++ ++ frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ dialogToken = frame_body[7]; ++ status = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP; ++ ++ p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen); ++ if (p2p_ie) { ++ u8 groupid[38] = { 0x00 }; ++ u8 dev_addr[ETH_ALEN] = { 0x00 }; ++ u32 attr_contentlen = 0; ++ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) { ++ if (!memcmp(pwdinfo->device_addr, groupid, ETH_ALEN) && ++ !memcmp(pwdinfo->p2p_group_ssid, groupid + ETH_ALEN, pwdinfo->p2p_group_ssid_len)) { ++ attr_contentlen = 0; ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_ID, dev_addr, &attr_contentlen)) { ++ struct list_head *phead, *plist; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ phead = &pstapriv->asoc_list; ++ plist = phead->next; ++ ++ /* look up sta asoc_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, asoc_list); ++ ++ plist = plist->next; ++ ++ if (psta->is_p2p_device && (psta->dev_cap & P2P_DEVCAP_CLIENT_DISCOVERABILITY) && ++ !memcmp(psta->dev_addr, dev_addr, ETH_ALEN)) { ++ /* issue GO Discoverability Request */ ++ issue_group_disc_req(pwdinfo, psta->hwaddr); ++ status = P2P_STATUS_SUCCESS; ++ break; ++ } else { ++ status = P2P_STATUS_FAIL_INFO_UNAVAILABLE; ++ } ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ } else { ++ status = P2P_STATUS_FAIL_INVALID_PARAM; ++ } ++ } else { ++ status = P2P_STATUS_FAIL_INVALID_PARAM; ++ } ++ } ++ } ++ ++ /* issue Device Discoverability Response */ ++ issue_p2p_devdisc_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken); ++ ++ return (status == P2P_STATUS_SUCCESS) ? true : false; ++} ++ ++u32 process_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ return true; ++} ++ ++u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ u8 *frame_body; ++ u8 *wpsie; ++ uint wps_ielen = 0, attr_contentlen = 0; ++ u16 uconfig_method = 0; ++ __be16 be_tmp; ++ ++ frame_body = (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ wpsie = rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen); ++ if (wpsie) { ++ if (rtw_get_wps_attr_content(wpsie, wps_ielen, WPS_ATTR_CONF_METHOD, (u8 *)&be_tmp, &attr_contentlen)) { ++ uconfig_method = be16_to_cpu(be_tmp); ++ switch (uconfig_method) { ++ case WPS_CM_DISPLYA: ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3); ++ break; ++ case WPS_CM_LABEL: ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "lab", 3); ++ break; ++ case WPS_CM_PUSH_BUTTON: ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3); ++ break; ++ case WPS_CM_KEYPAD: ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3); ++ break; ++ } ++ issue_p2p_provision_resp(pwdinfo, GetAddr2Ptr(pframe), frame_body, uconfig_method); ++ } ++ } ++ DBG_88E("[%s] config method = %s\n", __func__, pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req); ++ return true; ++} ++ ++u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe) ++{ ++ return true; ++} ++ ++static u8 rtw_p2p_get_peer_ch_list(struct wifidirect_info *pwdinfo, u8 *ch_content, u8 ch_cnt, u8 *peer_ch_list) ++{ ++ u8 i = 0, j = 0; ++ u8 temp = 0; ++ u8 ch_no = 0; ++ ch_content += 3; ++ ch_cnt -= 3; ++ ++ while (ch_cnt > 0) { ++ ch_content += 1; ++ ch_cnt -= 1; ++ temp = *ch_content; ++ for (i = 0 ; i < temp ; i++, j++) ++ peer_ch_list[j] = *(ch_content + 1 + i); ++ ch_content += (temp + 1); ++ ch_cnt -= (temp + 1); ++ ch_no += temp; ++ } ++ ++ return ch_no; ++} ++ ++static u8 rtw_p2p_ch_inclusion(struct mlme_ext_priv *pmlmeext, u8 *peer_ch_list, u8 peer_ch_num, u8 *ch_list_inclusioned) ++{ ++ int i = 0, j = 0, temp = 0; ++ u8 ch_no = 0; ++ ++ for (i = 0; i < peer_ch_num; i++) { ++ for (j = temp; j < pmlmeext->max_chan_nums; j++) { ++ if (*(peer_ch_list + i) == pmlmeext->channel_set[j].ChannelNum) { ++ ch_list_inclusioned[ch_no++] = *(peer_ch_list + i); ++ temp = j; ++ break; ++ } ++ } ++ } ++ ++ return ch_no; ++} ++ ++u8 process_p2p_group_negotation_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ struct adapter *padapter = pwdinfo->padapter; ++ u8 result = P2P_STATUS_SUCCESS; ++ u32 p2p_ielen = 0, wps_ielen = 0; ++ u8 *ies; ++ u32 ies_len; ++ u8 *p2p_ie; ++ u8 *wpsie; ++ u16 wps_devicepassword_id = 0x0000; ++ uint wps_devicepassword_id_len = 0; ++ __be16 be_tmp; ++ ++ wpsie = rtw_get_wps_ie(pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen); ++ if (wpsie) { ++ /* Commented by Kurt 20120113 */ ++ /* If some device wants to do p2p handshake without sending prov_disc_req */ ++ /* We have to get peer_req_cm from here. */ ++ if (!memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) { ++ rtw_get_wps_attr_content(wpsie, wps_ielen, WPS_ATTR_DEVICE_PWID, (u8 *)&be_tmp, &wps_devicepassword_id_len); ++ wps_devicepassword_id = be16_to_cpu(be_tmp); ++ ++ if (wps_devicepassword_id == WPS_DPID_USER_SPEC) ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3); ++ else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC) ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3); ++ else ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3); ++ } ++ } else { ++ DBG_88E("[%s] WPS IE not Found!!\n", __func__); ++ result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ return result; ++ } ++ ++ if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO) { ++ result = P2P_STATUS_FAIL_INFO_UNAVAILABLE; ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INFOR_NOREADY); ++ return result; ++ } ++ ++ ies = pframe + _PUBLIC_ACTION_IE_OFFSET_; ++ ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; ++ ++ p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen); ++ ++ if (!p2p_ie) { ++ DBG_88E("[%s] P2P IE not Found!!\n", __func__); ++ result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ } ++ ++ while (p2p_ie) { ++ u8 attr_content = 0x00; ++ u32 attr_contentlen = 0; ++ u8 ch_content[50] = { 0x00 }; ++ uint ch_cnt = 0; ++ u8 peer_ch_list[50] = { 0x00 }; ++ u8 peer_ch_num = 0; ++ u8 ch_list_inclusioned[50] = { 0x00 }; ++ u8 ch_num_inclusioned = 0; ++ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING); ++ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, &attr_content, &attr_contentlen)) { ++ DBG_88E("[%s] GO Intent = %d, tie = %d\n", __func__, attr_content >> 1, attr_content & 0x01); ++ pwdinfo->peer_intent = attr_content; /* include both intent and tie breaker values. */ ++ ++ if (pwdinfo->intent == (pwdinfo->peer_intent >> 1)) { ++ /* Try to match the tie breaker value */ ++ if (pwdinfo->intent == P2P_MAX_INTENT) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ result = P2P_STATUS_FAIL_BOTH_GOINTENT_15; ++ } else { ++ if (attr_content & 0x01) ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ else ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ } ++ } else if (pwdinfo->intent > (pwdinfo->peer_intent >> 1)) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ } else { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ } ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ /* Store the group id information. */ ++ memcpy(pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN); ++ memcpy(pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen); ++ } ++ } ++ ++ attr_contentlen = 0; ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen)) { ++ if (attr_contentlen != ETH_ALEN) ++ memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN); ++ } ++ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, ch_content, &ch_cnt)) { ++ peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, ch_content, ch_cnt, peer_ch_list); ++ ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned); ++ ++ if (ch_num_inclusioned == 0) { ++ DBG_88E("[%s] No common channel in channel list!\n", __func__); ++ result = P2P_STATUS_FAIL_NO_COMMON_CH; ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ break; ++ } ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ if (!rtw_p2p_is_channel_list_ok(pwdinfo->operating_channel, ++ ch_list_inclusioned, ch_num_inclusioned)) { ++ u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0; ++ attr_contentlen = 0; ++ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) ++ peer_operating_ch = operatingch_info[4]; ++ ++ if (rtw_p2p_is_channel_list_ok(peer_operating_ch, ++ ch_list_inclusioned, ch_num_inclusioned)) { ++ /** ++ * Change our operating channel as peer's for compatibility. ++ */ ++ pwdinfo->operating_channel = peer_operating_ch; ++ DBG_88E("[%s] Change op ch to %02x as peer's\n", __func__, pwdinfo->operating_channel); ++ } else { ++ /* Take first channel of ch_list_inclusioned as operating channel */ ++ pwdinfo->operating_channel = ch_list_inclusioned[0]; ++ DBG_88E("[%s] Change op ch to %02x\n", __func__, pwdinfo->operating_channel); ++ } ++ } ++ } ++ } ++ ++ /* Get the next P2P IE */ ++ p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen); ++ } ++ return result; ++} ++ ++u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ struct adapter *padapter = pwdinfo->padapter; ++ u8 result = P2P_STATUS_SUCCESS; ++ u32 p2p_ielen, wps_ielen; ++ u8 *ies; ++ u32 ies_len; ++ u8 *p2p_ie; ++ ++ ies = pframe + _PUBLIC_ACTION_IE_OFFSET_; ++ ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; ++ ++ /* Be able to know which one is the P2P GO and which one is P2P client. */ ++ ++ if (rtw_get_wps_ie(ies, ies_len, NULL, &wps_ielen)) { ++ } else { ++ DBG_88E("[%s] WPS IE not Found!!\n", __func__); ++ result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ } ++ ++ p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen); ++ if (!p2p_ie) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; ++ } else { ++ u8 attr_content = 0x00; ++ u32 attr_contentlen = 0; ++ u8 operatingch_info[5] = { 0x00 }; ++ u8 groupid[38]; ++ u8 peer_ch_list[50] = { 0x00 }; ++ u8 peer_ch_num = 0; ++ u8 ch_list_inclusioned[50] = { 0x00 }; ++ u8 ch_num_inclusioned = 0; ++ ++ while (p2p_ie) { /* Found the P2P IE. */ ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen); ++ if (attr_contentlen == 1) { ++ DBG_88E("[%s] Status = %d\n", __func__, attr_content); ++ if (attr_content == P2P_STATUS_SUCCESS) { ++ /* Do nothing. */ ++ } else { ++ if (P2P_STATUS_FAIL_INFO_UNAVAILABLE == attr_content) { ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INFOR_NOREADY); ++ } else { ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ } ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ result = attr_content; ++ break; ++ } ++ } ++ ++ /* Try to get the peer's interface address */ ++ attr_contentlen = 0; ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen)) { ++ if (attr_contentlen != ETH_ALEN) ++ memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN); ++ } ++ ++ /* Try to get the peer's intent and tie breaker value. */ ++ attr_content = 0x00; ++ attr_contentlen = 0; ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, &attr_content, &attr_contentlen)) { ++ DBG_88E("[%s] GO Intent = %d, tie = %d\n", __func__, attr_content >> 1, attr_content & 0x01); ++ pwdinfo->peer_intent = attr_content; /* include both intent and tie breaker values. */ ++ ++ if (pwdinfo->intent == (pwdinfo->peer_intent >> 1)) { ++ /* Try to match the tie breaker value */ ++ if (pwdinfo->intent == P2P_MAX_INTENT) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ result = P2P_STATUS_FAIL_BOTH_GOINTENT_15; ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ } else { ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ if (attr_content & 0x01) ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ else ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ } ++ } else if (pwdinfo->intent > (pwdinfo->peer_intent >> 1)) { ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ } else { ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ } ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ /* Store the group id information. */ ++ memcpy(pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN); ++ memcpy(pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen); ++ } ++ } ++ ++ /* Try to get the operation channel information */ ++ ++ attr_contentlen = 0; ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) { ++ DBG_88E("[%s] Peer's operating channel = %d\n", __func__, operatingch_info[4]); ++ pwdinfo->peer_operating_ch = operatingch_info[4]; ++ } ++ ++ /* Try to get the channel list information */ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, pwdinfo->channel_list_attr, &pwdinfo->channel_list_attr_len)) { ++ DBG_88E("[%s] channel list attribute found, len = %d\n", __func__, pwdinfo->channel_list_attr_len); ++ ++ peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len, peer_ch_list); ++ ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned); ++ ++ if (ch_num_inclusioned == 0) { ++ DBG_88E("[%s] No common channel in channel list!\n", __func__); ++ result = P2P_STATUS_FAIL_NO_COMMON_CH; ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ break; ++ } ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ if (!rtw_p2p_is_channel_list_ok(pwdinfo->operating_channel, ++ ch_list_inclusioned, ch_num_inclusioned)) { ++ u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0; ++ attr_contentlen = 0; ++ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) ++ peer_operating_ch = operatingch_info[4]; ++ ++ if (rtw_p2p_is_channel_list_ok(peer_operating_ch, ++ ch_list_inclusioned, ch_num_inclusioned)) { ++ /** ++ * Change our operating channel as peer's for compatibility. ++ */ ++ pwdinfo->operating_channel = peer_operating_ch; ++ DBG_88E("[%s] Change op ch to %02x as peer's\n", __func__, pwdinfo->operating_channel); ++ } else { ++ /* Take first channel of ch_list_inclusioned as operating channel */ ++ pwdinfo->operating_channel = ch_list_inclusioned[0]; ++ DBG_88E("[%s] Change op ch to %02x\n", __func__, pwdinfo->operating_channel); ++ } ++ } ++ } ++ } else { ++ DBG_88E("[%s] channel list attribute not found!\n", __func__); ++ } ++ ++ /* Try to get the group id information if peer is GO */ ++ attr_contentlen = 0; ++ memset(groupid, 0x00, 38); ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) { ++ memcpy(pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN); ++ memcpy(pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN); ++ } ++ ++ /* Get the next P2P IE */ ++ p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen); ++ } ++ } ++ return result; ++} ++ ++u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ u8 *ies; ++ u32 ies_len; ++ u8 *p2p_ie; ++ u32 p2p_ielen = 0; ++ u8 result = P2P_STATUS_SUCCESS; ++ ies = pframe + _PUBLIC_ACTION_IE_OFFSET_; ++ ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; ++ ++ p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen); ++ while (p2p_ie) { /* Found the P2P IE. */ ++ u8 attr_content = 0x00, operatingch_info[5] = { 0x00 }; ++ u8 groupid[38] = { 0x00 }; ++ u32 attr_contentlen = 0; ++ ++ pwdinfo->negotiation_dialog_token = 1; ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen); ++ if (attr_contentlen == 1) { ++ DBG_88E("[%s] Status = %d\n", __func__, attr_content); ++ result = attr_content; ++ ++ if (attr_content == P2P_STATUS_SUCCESS) { ++ u8 bcancelled = 0; ++ ++ _cancel_timer(&pwdinfo->restore_p2p_state_timer, &bcancelled); ++ ++ /* Commented by Albert 20100911 */ ++ /* Todo: Need to handle the case which both Intents are the same. */ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ if ((pwdinfo->intent) > (pwdinfo->peer_intent >> 1)) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ } else if ((pwdinfo->intent) < (pwdinfo->peer_intent >> 1)) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ } else { ++ /* Have to compare the Tie Breaker */ ++ if (pwdinfo->peer_intent & 0x01) ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ else ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ } ++ } else { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ break; ++ } ++ } ++ ++ /* Try to get the group id information */ ++ attr_contentlen = 0; ++ memset(groupid, 0x00, 38); ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) { ++ DBG_88E("[%s] Ssid = %s, ssidlen = %zu\n", __func__, &groupid[ETH_ALEN], strlen(&groupid[ETH_ALEN])); ++ memcpy(pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN); ++ memcpy(pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN); ++ } ++ ++ attr_contentlen = 0; ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) { ++ DBG_88E("[%s] Peer's operating channel = %d\n", __func__, operatingch_info[4]); ++ pwdinfo->peer_operating_ch = operatingch_info[4]; ++ } ++ ++ /* Get the next P2P IE */ ++ p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen); ++ } ++ return result; ++} ++ ++u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ u8 *frame_body; ++ u8 dialogToken = 0; ++ u8 status = P2P_STATUS_SUCCESS; ++ ++ frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ dialogToken = frame_body[6]; ++ ++ /* todo: check NoA attribute */ ++ ++ issue_p2p_presence_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken); ++ ++ return true; ++} ++ ++static void find_phase_handler(struct adapter *padapter) ++{ ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ndis_802_11_ssid ssid; ++ ++ memset((unsigned char *)&ssid, 0, sizeof(struct ndis_802_11_ssid)); ++ memcpy(ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN); ++ ssid.SsidLength = P2P_WILDCARD_SSID_LEN; ++ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH); ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++} ++ ++void p2p_concurrent_handler(struct adapter *padapter); ++ ++static void restore_p2p_state_handler(struct adapter *padapter) ++{ ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) { ++ /* In the P2P client mode, the driver should not switch back to its listen channel */ ++ /* because this P2P client should stay at the operating channel of P2P GO. */ ++ set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ } ++ ++} ++ ++static void pre_tx_invitereq_handler(struct adapter *padapter) ++{ ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 val8 = 1; ++ ++ set_channel_bwmode(padapter, pwdinfo->invitereq_info.peer_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); ++ issue_probereq_p2p(padapter, NULL); ++ _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); ++ ++} ++ ++static void pre_tx_provdisc_handler(struct adapter *padapter) ++{ ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 val8 = 1; ++ ++ set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); ++ issue_probereq_p2p(padapter, NULL); ++ _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); ++ ++} ++ ++static void pre_tx_negoreq_handler(struct adapter *padapter) ++{ ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 val8 = 1; ++ ++ set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); ++ issue_probereq_p2p(padapter, NULL); ++ _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); ++ ++} ++ ++void p2p_protocol_wk_hdl(struct adapter *padapter, int intCmdType) ++{ ++ ++ switch (intCmdType) { ++ case P2P_FIND_PHASE_WK: ++ find_phase_handler(padapter); ++ break; ++ case P2P_RESTORE_STATE_WK: ++ restore_p2p_state_handler(padapter); ++ break; ++ case P2P_PRE_TX_PROVDISC_PROCESS_WK: ++ pre_tx_provdisc_handler(padapter); ++ break; ++ case P2P_PRE_TX_INVITEREQ_PROCESS_WK: ++ pre_tx_invitereq_handler(padapter); ++ break; ++ case P2P_PRE_TX_NEGOREQ_PROCESS_WK: ++ pre_tx_negoreq_handler(padapter); ++ break; ++ } ++ ++} ++ ++void process_p2p_ps_ie(struct adapter *padapter, u8 *IEs, u32 IELength) ++{ ++ u8 *ies; ++ u32 ies_len; ++ u8 *p2p_ie; ++ u32 p2p_ielen = 0; ++ u8 noa_attr[MAX_P2P_IE_LEN] = { 0x00 };/* NoA length should be n*(13) + 2 */ ++ u32 attr_contentlen = 0; ++ ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 find_p2p = false, find_p2p_ps = false; ++ u8 noa_offset, noa_num, noa_index; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return; ++ if (IELength <= _BEACON_IE_OFFSET_) ++ return; ++ ++ ies = IEs + _BEACON_IE_OFFSET_; ++ ies_len = IELength - _BEACON_IE_OFFSET_; ++ ++ p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen); ++ ++ while (p2p_ie) { ++ find_p2p = true; ++ /* Get Notice of Absence IE. */ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_NOA, noa_attr, &attr_contentlen)) { ++ find_p2p_ps = true; ++ noa_index = noa_attr[0]; ++ ++ if ((pwdinfo->p2p_ps_mode == P2P_PS_NONE) || ++ (noa_index != pwdinfo->noa_index)) { /* if index change, driver should reconfigure related setting. */ ++ pwdinfo->noa_index = noa_index; ++ pwdinfo->opp_ps = noa_attr[1] >> 7; ++ pwdinfo->ctwindow = noa_attr[1] & 0x7F; ++ ++ noa_offset = 2; ++ noa_num = 0; ++ /* NoA length should be n*(13) + 2 */ ++ if (attr_contentlen > 2) { ++ while (noa_offset < attr_contentlen) { ++ /* memcpy(&wifidirect_info->noa_count[noa_num], &noa_attr[noa_offset], 1); */ ++ pwdinfo->noa_count[noa_num] = noa_attr[noa_offset]; ++ noa_offset += 1; ++ ++ memcpy(&pwdinfo->noa_duration[noa_num], &noa_attr[noa_offset], 4); ++ noa_offset += 4; ++ ++ memcpy(&pwdinfo->noa_interval[noa_num], &noa_attr[noa_offset], 4); ++ noa_offset += 4; ++ ++ memcpy(&pwdinfo->noa_start_time[noa_num], &noa_attr[noa_offset], 4); ++ noa_offset += 4; ++ ++ noa_num++; ++ } ++ } ++ pwdinfo->noa_num = noa_num; ++ ++ if (pwdinfo->opp_ps == 1) { ++ pwdinfo->p2p_ps_mode = P2P_PS_CTWINDOW; ++ /* driver should wait LPS for entering CTWindow */ ++ if (padapter->pwrctrlpriv.bFwCurrentInPSMode) ++ p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1); ++ } else if (pwdinfo->noa_num > 0) { ++ pwdinfo->p2p_ps_mode = P2P_PS_NOA; ++ p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1); ++ } else if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) { ++ p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1); ++ } ++ } ++ ++ break; /* find target, just break. */ ++ } ++ ++ /* Get the next P2P IE */ ++ p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen); ++ } ++ ++ if (find_p2p) { ++ if ((pwdinfo->p2p_ps_mode > P2P_PS_NONE) && !find_p2p_ps) ++ p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1); ++ } ++ ++} ++ ++void p2p_ps_wk_hdl(struct adapter *padapter, u8 p2p_ps_state) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ /* Pre action for p2p state */ ++ switch (p2p_ps_state) { ++ case P2P_PS_DISABLE: ++ pwdinfo->p2p_ps_state = p2p_ps_state; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); ++ ++ pwdinfo->noa_index = 0; ++ pwdinfo->ctwindow = 0; ++ pwdinfo->opp_ps = 0; ++ pwdinfo->noa_num = 0; ++ pwdinfo->p2p_ps_mode = P2P_PS_NONE; ++ if (padapter->pwrctrlpriv.bFwCurrentInPSMode) { ++ if (pwrpriv->smart_ps == 0) { ++ pwrpriv->smart_ps = 2; ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&padapter->pwrctrlpriv.pwr_mode)); ++ } ++ } ++ break; ++ case P2P_PS_ENABLE: ++ if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) { ++ pwdinfo->p2p_ps_state = p2p_ps_state; ++ ++ if (pwdinfo->ctwindow > 0) { ++ if (pwrpriv->smart_ps != 0) { ++ pwrpriv->smart_ps = 0; ++ DBG_88E("%s(): Enter CTW, change SmartPS\n", __func__); ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&padapter->pwrctrlpriv.pwr_mode)); ++ } ++ } ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); ++ } ++ break; ++ case P2P_PS_SCAN: ++ case P2P_PS_SCAN_DONE: ++ case P2P_PS_ALLSTASLEEP: ++ if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) { ++ pwdinfo->p2p_ps_state = p2p_ps_state; ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); ++ } ++ break; ++ default: ++ break; ++ } ++ ++} ++ ++u8 p2p_ps_wk_cmd(struct adapter *padapter, u8 p2p_ps_state, u8 enqueue) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return res; ++ ++ if (enqueue) { ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = P2P_PS_WK_CID; ++ pdrvextra_cmd_parm->type_size = p2p_ps_state; ++ pdrvextra_cmd_parm->pbuf = NULL; ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ } else { ++ p2p_ps_wk_hdl(padapter, p2p_ps_state); ++ } ++ ++exit: ++ ++ return res; ++} ++ ++static void reset_ch_sitesurvey_timer_process(struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, pwrctrlpriv.pwr_state_check_timer); ++ struct wifidirect_info *pwdinfo = &adapter->wdinfo; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return; ++ ++ DBG_88E("[%s] In\n", __func__); ++ /* Reset the operation channel information */ ++ pwdinfo->rx_invitereq_info.operation_ch[0] = 0; ++ pwdinfo->rx_invitereq_info.scan_op_ch_only = 0; ++} ++ ++static void reset_ch_sitesurvey_timer_process2(struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, pwrctrlpriv.pwr_state_check_timer); ++ struct wifidirect_info *pwdinfo = &adapter->wdinfo; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return; ++ ++ DBG_88E("[%s] In\n", __func__); ++ /* Reset the operation channel information */ ++ pwdinfo->p2p_info.operation_ch[0] = 0; ++ pwdinfo->p2p_info.scan_op_ch_only = 0; ++} ++ ++static void restore_p2p_state_timer_process(struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, wdinfo.restore_p2p_state_timer); ++ struct wifidirect_info *pwdinfo = &adapter->wdinfo; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return; ++ ++ p2p_protocol_wk_cmd(adapter, P2P_RESTORE_STATE_WK); ++} ++ ++static void pre_tx_scan_timer_process(struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, wdinfo.pre_tx_scan_timer); ++ struct wifidirect_info *pwdinfo = &adapter->wdinfo; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) { ++ if (pwdinfo->tx_prov_disc_info.benable) { /* the provision discovery request frame is trigger to send or not */ ++ p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_PROVDISC_PROCESS_WK); ++ /* issue_probereq_p2p(adapter, NULL); */ ++ /* _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); */ ++ } ++ } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) { ++ if (pwdinfo->nego_req_info.benable) ++ p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_NEGOREQ_PROCESS_WK); ++ } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) { ++ if (pwdinfo->invitereq_info.benable) ++ p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_INVITEREQ_PROCESS_WK); ++ } else { ++ DBG_88E("[%s] p2p_state is %d, ignore!!\n", __func__, rtw_p2p_state(pwdinfo)); ++ } ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++static void find_phase_timer_process(struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, wdinfo.find_phase_timer); ++ struct wifidirect_info *pwdinfo = &adapter->wdinfo; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return; ++ ++ adapter->wdinfo.find_phase_state_exchange_cnt++; ++ ++ p2p_protocol_wk_cmd(adapter, P2P_FIND_PHASE_WK); ++} ++ ++void reset_global_wifidirect_info(struct adapter *padapter) ++{ ++ struct wifidirect_info *pwdinfo; ++ ++ pwdinfo = &padapter->wdinfo; ++ pwdinfo->persistent_supported = 0; ++ pwdinfo->session_available = true; ++ pwdinfo->wfd_tdls_enable = 0; ++ pwdinfo->wfd_tdls_weaksec = 0; ++} ++ ++void rtw_init_wifidirect_timers(struct adapter *padapter) ++{ ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ timer_setup(&pwdinfo->find_phase_timer, find_phase_timer_process, 0); ++ timer_setup(&pwdinfo->restore_p2p_state_timer, restore_p2p_state_timer_process, 0); ++ timer_setup(&pwdinfo->pre_tx_scan_timer, pre_tx_scan_timer_process, 0); ++ timer_setup(&pwdinfo->reset_ch_sitesurvey, reset_ch_sitesurvey_timer_process, 0); ++ timer_setup(&pwdinfo->reset_ch_sitesurvey2, reset_ch_sitesurvey_timer_process2, 0); ++} ++ ++void rtw_init_wifidirect_addrs(struct adapter *padapter, u8 *dev_addr, u8 *iface_addr) ++{ ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ /*init device&interface address */ ++ if (dev_addr) ++ memcpy(pwdinfo->device_addr, dev_addr, ETH_ALEN); ++ if (iface_addr) ++ memcpy(pwdinfo->interface_addr, iface_addr, ETH_ALEN); ++#endif ++} ++ ++void init_wifidirect_info(struct adapter *padapter, enum P2P_ROLE role) ++{ ++ struct wifidirect_info *pwdinfo; ++ ++ pwdinfo = &padapter->wdinfo; ++ pwdinfo->padapter = padapter; ++ ++ /* 1, 6, 11 are the social channel defined in the WiFi Direct specification. */ ++ pwdinfo->social_chan[0] = 1; ++ pwdinfo->social_chan[1] = 6; ++ pwdinfo->social_chan[2] = 11; ++ pwdinfo->social_chan[3] = 0; /* channel 0 for scanning ending in site survey function. */ ++ ++ /* Use the channel 11 as the listen channel */ ++ pwdinfo->listen_channel = 11; ++ ++ if (role == P2P_ROLE_DEVICE) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); ++ pwdinfo->intent = 1; ++ rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_LISTEN); ++ } else if (role == P2P_ROLE_CLIENT) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ pwdinfo->intent = 1; ++ rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ } else if (role == P2P_ROLE_GO) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ pwdinfo->intent = 15; ++ rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ } ++ ++/* Use the OFDM rate in the P2P probe response frame. (6(B), 9(B), 12, 18, 24, 36, 48, 54) */ ++ pwdinfo->support_rate[0] = 0x8c; /* 6(B) */ ++ pwdinfo->support_rate[1] = 0x92; /* 9(B) */ ++ pwdinfo->support_rate[2] = 0x18; /* 12 */ ++ pwdinfo->support_rate[3] = 0x24; /* 18 */ ++ pwdinfo->support_rate[4] = 0x30; /* 24 */ ++ pwdinfo->support_rate[5] = 0x48; /* 36 */ ++ pwdinfo->support_rate[6] = 0x60; /* 48 */ ++ pwdinfo->support_rate[7] = 0x6c; /* 54 */ ++ ++ memcpy(pwdinfo->p2p_wildcard_ssid, "DIRECT-", 7); ++ ++ memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN); ++ pwdinfo->device_name_len = 0; ++ ++ memset(&pwdinfo->invitereq_info, 0x00, sizeof(struct tx_invite_req_info)); ++ pwdinfo->invitereq_info.token = 3; /* Token used for P2P invitation request frame. */ ++ ++ memset(&pwdinfo->inviteresp_info, 0x00, sizeof(struct tx_invite_resp_info)); ++ pwdinfo->inviteresp_info.token = 0; ++ ++ pwdinfo->profileindex = 0; ++ memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM); ++ ++ rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE); ++ ++ pwdinfo->listen_dwell = (u8)((jiffies % 3) + 1); ++ ++ memset(&pwdinfo->tx_prov_disc_info, 0x00, sizeof(struct tx_provdisc_req_info)); ++ pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_NONE; ++ ++ memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info)); ++ ++ pwdinfo->device_password_id_for_nego = WPS_DPID_PBC; ++ pwdinfo->negotiation_dialog_token = 1; ++ ++ memset(pwdinfo->nego_ssid, 0x00, WLAN_SSID_MAXLEN); ++ pwdinfo->nego_ssidlen = 0; ++ ++ pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO; ++ pwdinfo->supported_wps_cm = WPS_CONFIG_METHOD_DISPLAY | WPS_CONFIG_METHOD_PBC | WPS_CONFIG_METHOD_KEYPAD; ++ pwdinfo->channel_list_attr_len = 0; ++ memset(pwdinfo->channel_list_attr, 0x00, 100); ++ ++ memset(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, 0x00, 4); ++ memset(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, '0', 3); ++ memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info)); ++ pwdinfo->wfd_tdls_enable = 0; ++ memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN); ++ memset(pwdinfo->p2p_peer_device_addr, 0x00, ETH_ALEN); ++ ++ pwdinfo->rx_invitereq_info.operation_ch[0] = 0; ++ pwdinfo->rx_invitereq_info.operation_ch[1] = 0; /* Used to indicate the scan end in site survey function */ ++ pwdinfo->rx_invitereq_info.scan_op_ch_only = 0; ++ pwdinfo->p2p_info.operation_ch[0] = 0; ++ pwdinfo->p2p_info.operation_ch[1] = 0; /* Used to indicate the scan end in site survey function */ ++ pwdinfo->p2p_info.scan_op_ch_only = 0; ++} ++ ++int rtw_p2p_enable(struct adapter *padapter, enum P2P_ROLE role) ++{ ++ int ret = _SUCCESS; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT || role == P2P_ROLE_GO) { ++ /* leave IPS/Autosuspend */ ++ if (_FAIL == rtw_pwr_wakeup(padapter)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* Added by Albert 2011/03/22 */ ++ /* In the P2P mode, the driver should not support the b mode. */ ++ /* So, the Tx packet shouldn't use the CCK rate */ ++ update_tx_basic_rate(padapter, (WIRELESS_11G | WIRELESS_11_24N)); ++ ++ /* Enable P2P function */ ++ init_wifidirect_info(padapter, role); ++ ++ rtw_hal_set_odm_var(padapter, HAL_ODM_P2P_STATE, NULL, true); ++ } else if (role == P2P_ROLE_DISABLE) { ++ if (_FAIL == rtw_pwr_wakeup(padapter)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* Disable P2P function */ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ++ _cancel_timer_ex(&pwdinfo->find_phase_timer); ++ _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); ++ _cancel_timer_ex(&pwdinfo->pre_tx_scan_timer); ++ _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey); ++ _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey2); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DISABLE); ++ memset(&pwdinfo->rx_prov_disc_info, 0x00, sizeof(struct rx_provdisc_req_info)); ++ } ++ ++ rtw_hal_set_odm_var(padapter, HAL_ODM_P2P_STATE, NULL, false); ++ ++ /* Restore to initial setting. */ ++ update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); ++ } ++ ++exit: ++ return ret; ++} ++ ++#else ++u8 p2p_ps_wk_cmd(struct adapter *padapter, u8 p2p_ps_state, u8 enqueue) ++{ ++ return _FAIL; ++} ++ ++void process_p2p_ps_ie(struct adapter *padapter, u8 *IEs, u32 IELength) ++{ ++} ++ ++#endif /* CONFIG_88EU_P2P */ +diff --git a/drivers/staging/r8188eu/core/rtw_pwrctrl.c b/drivers/staging/r8188eu/core/rtw_pwrctrl.c +new file mode 100644 +index 000000000000..c3897b29121c +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_pwrctrl.c +@@ -0,0 +1,605 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_PWRCTRL_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/osdep_intf.h" ++#include "../include/linux/usb.h" ++ ++void ips_enter(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct xmit_priv *pxmit_priv = &padapter->xmitpriv; ++ ++ if (padapter->registrypriv.mp_mode == 1) ++ return; ++ ++ if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF || ++ pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) { ++ DBG_88E_LEVEL(_drv_info_, "There are some pkts to transmit\n"); ++ DBG_88E_LEVEL(_drv_info_, "free_xmitbuf_cnt: %d, free_xmit_extbuf_cnt: %d\n", ++ pxmit_priv->free_xmitbuf_cnt, pxmit_priv->free_xmit_extbuf_cnt); ++ return; ++ } ++ ++ _enter_pwrlock(&pwrpriv->lock); ++ ++ pwrpriv->bips_processing = true; ++ ++ /* syn ips_mode with request */ ++ pwrpriv->ips_mode = pwrpriv->ips_mode_req; ++ ++ pwrpriv->ips_enter_cnts++; ++ DBG_88E("==>ips_enter cnts:%d\n", pwrpriv->ips_enter_cnts); ++ if (rf_off == pwrpriv->change_rfpwrstate) { ++ pwrpriv->bpower_saving = true; ++ DBG_88E_LEVEL(_drv_info_, "nolinked power save enter\n"); ++ ++ if (pwrpriv->ips_mode == IPS_LEVEL_2) ++ pwrpriv->bkeepfwalive = true; ++ ++ rtw_ips_pwr_down(padapter); ++ pwrpriv->rf_pwrstate = rf_off; ++ } ++ pwrpriv->bips_processing = false; ++ ++ _exit_pwrlock(&pwrpriv->lock); ++} ++ ++int ips_leave(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ int result = _SUCCESS; ++ int keyid; ++ ++ _enter_pwrlock(&pwrpriv->lock); ++ ++ if ((pwrpriv->rf_pwrstate == rf_off) && (!pwrpriv->bips_processing)) { ++ pwrpriv->bips_processing = true; ++ pwrpriv->change_rfpwrstate = rf_on; ++ pwrpriv->ips_leave_cnts++; ++ DBG_88E("==>ips_leave cnts:%d\n", pwrpriv->ips_leave_cnts); ++ ++ result = rtw_ips_pwr_up(padapter); ++ if (result == _SUCCESS) { ++ pwrpriv->rf_pwrstate = rf_on; ++ } ++ DBG_88E_LEVEL(_drv_info_, "nolinked power save leave\n"); ++ ++ if ((_WEP40_ == psecuritypriv->dot11PrivacyAlgrthm) || (_WEP104_ == psecuritypriv->dot11PrivacyAlgrthm)) { ++ DBG_88E("==>%s, channel(%d), processing(%x)\n", __func__, padapter->mlmeextpriv.cur_channel, pwrpriv->bips_processing); ++ set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ for (keyid = 0; keyid < 4; keyid++) { ++ if (pmlmepriv->key_mask & BIT(keyid)) { ++ if (keyid == psecuritypriv->dot11PrivacyKeyIndex) ++ result = rtw_set_key(padapter, psecuritypriv, keyid, 1); ++ else ++ result = rtw_set_key(padapter, psecuritypriv, keyid, 0); ++ } ++ } ++ } ++ ++ DBG_88E("==> ips_leave.....LED(0x%08x)...\n", rtw_read32(padapter, 0x4c)); ++ pwrpriv->bips_processing = false; ++ ++ pwrpriv->bkeepfwalive = false; ++ pwrpriv->bpower_saving = false; ++ } ++ ++ _exit_pwrlock(&pwrpriv->lock); ++ ++ return result; ++} ++ ++static bool rtw_pwr_unassociated_idle(struct adapter *adapter) ++{ ++ struct adapter *buddy = adapter->pbuddy_adapter; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &adapter->wdinfo; ++#endif ++ ++ bool ret = false; ++ ++ if (adapter->pwrctrlpriv.ips_deny_time >= jiffies) ++ goto exit; ++ ++ if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_SITE_MONITOR) || ++ check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS) || ++ check_fwstate(pmlmepriv, WIFI_UNDER_WPS) || ++ check_fwstate(pmlmepriv, WIFI_AP_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) || ++#if defined(CONFIG_88EU_P2P) ++ !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++#else ++ 0) ++#endif ++ goto exit; ++ ++ /* consider buddy, if exist */ ++ if (buddy) { ++ struct mlme_priv *b_pmlmepriv = &buddy->mlmepriv; ++ #ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *b_pwdinfo = &buddy->wdinfo; ++ #endif ++ ++ if (check_fwstate(b_pmlmepriv, WIFI_ASOC_STATE | WIFI_SITE_MONITOR) || ++ check_fwstate(b_pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS) || ++ check_fwstate(b_pmlmepriv, WIFI_AP_STATE) || ++ check_fwstate(b_pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) || ++#if defined(CONFIG_88EU_P2P) ++ !rtw_p2p_chk_state(b_pwdinfo, P2P_STATE_NONE)) ++#else ++ 0) ++#endif ++ goto exit; ++ } ++ ret = true; ++ ++exit: ++ return ret; ++} ++ ++void rtw_ps_processor(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ enum rt_rf_power_state rfpwrstate; ++ ++ pwrpriv->ps_processing = true; ++ ++ if (pwrpriv->bips_processing) ++ goto exit; ++ ++ if (padapter->pwrctrlpriv.bHWPwrPindetect) { ++ rfpwrstate = RfOnOffDetect(padapter); ++ DBG_88E("@@@@- #2 %s==> rfstate:%s\n", __func__, (rfpwrstate == rf_on) ? "rf_on" : "rf_off"); ++ ++ if (rfpwrstate != pwrpriv->rf_pwrstate) { ++ if (rfpwrstate == rf_off) { ++ pwrpriv->change_rfpwrstate = rf_off; ++ pwrpriv->brfoffbyhw = true; ++ padapter->bCardDisableWOHSM = true; ++ rtw_hw_suspend(padapter); ++ } else { ++ pwrpriv->change_rfpwrstate = rf_on; ++ rtw_hw_resume(padapter); ++ } ++ DBG_88E("current rf_pwrstate(%s)\n", (pwrpriv->rf_pwrstate == rf_off) ? "rf_off" : "rf_on"); ++ } ++ pwrpriv->pwr_state_check_cnts++; ++ } ++ ++ if (pwrpriv->ips_mode_req == IPS_NONE) ++ goto exit; ++ ++ if (!rtw_pwr_unassociated_idle(padapter)) ++ goto exit; ++ ++ if ((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts % 4) == 0)) { ++ DBG_88E("==>%s .fw_state(%x)\n", __func__, get_fwstate(pmlmepriv)); ++ pwrpriv->change_rfpwrstate = rf_off; ++ ++ ips_enter(padapter); ++ } ++exit: ++ rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); ++ pwrpriv->ps_processing = false; ++} ++ ++static void pwr_state_check_handler(struct timer_list *t) ++{ ++ struct adapter *padapter = ++ from_timer(padapter, t, ++ pwrctrlpriv.pwr_state_check_timer); ++ rtw_ps_cmd(padapter); ++} ++ ++/* ++ * ++ * Parameters ++ * padapter ++ * pslv power state level, only could be PS_STATE_S0 ~ PS_STATE_S4 ++ * ++ */ ++void rtw_set_rpwm(struct adapter *padapter, u8 pslv) ++{ ++ u8 rpwm; ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ ++ pslv = PS_STATE(pslv); ++ ++ if (pwrpriv->btcoex_rfon) { ++ if (pslv < PS_STATE_S4) ++ pslv = PS_STATE_S3; ++ } ++ ++ if (pwrpriv->rpwm == pslv) ++ return; ++ ++ if ((padapter->bSurpriseRemoved) || ++ (!padapter->hw_init_completed)) { ++ pwrpriv->cpwm = PS_STATE_S4; ++ ++ return; ++ } ++ ++ if (padapter->bDriverStopped) { ++ if (pslv < PS_STATE_S2) ++ return; ++ } ++ ++ rpwm = pslv | pwrpriv->tog; ++ ++ pwrpriv->rpwm = pslv; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm)); ++ ++ pwrpriv->tog += 0x80; ++ pwrpriv->cpwm = pslv; ++ ++} ++ ++static u8 PS_RDY_CHECK(struct adapter *padapter) ++{ ++ u32 curr_time, delta_time; ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ curr_time = jiffies; ++ delta_time = curr_time - pwrpriv->DelayLPSLastTimeStamp; ++ ++ if (delta_time < LPS_DELAY_TIME) ++ return false; ++ ++ if (!check_fwstate(pmlmepriv, _FW_LINKED) || ++ check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) || ++ check_fwstate(pmlmepriv, WIFI_AP_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) ++ return false; ++ if (pwrpriv->bInSuspend) ++ return false; ++ if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && !padapter->securitypriv.binstallGrpkey) { ++ DBG_88E("Group handshake still in progress !!!\n"); ++ return false; ++ } ++ return true; ++} ++ ++void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ if (ps_mode > PM_Card_Disable) ++ return; ++ ++ if (pwrpriv->pwr_mode == ps_mode) { ++ if (PS_MODE_ACTIVE == ps_mode) ++ return; ++ ++ if ((pwrpriv->smart_ps == smart_ps) && ++ (pwrpriv->bcn_ant_mode == bcn_ant_mode)) ++ return; ++ } ++ ++ /* if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) */ ++ if (ps_mode == PS_MODE_ACTIVE) { ++#ifdef CONFIG_88EU_P2P ++ if (pwdinfo->opp_ps == 0) { ++ DBG_88E("rtw_set_ps_mode: Leave 802.11 power save\n"); ++ pwrpriv->pwr_mode = ps_mode; ++ rtw_set_rpwm(padapter, PS_STATE_S4); ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); ++ pwrpriv->bFwCurrentInPSMode = false; ++ } ++ } else { ++#endif /* CONFIG_88EU_P2P */ ++ if (PS_RDY_CHECK(padapter)) { ++ DBG_88E("%s: Enter 802.11 power save\n", __func__); ++ pwrpriv->bFwCurrentInPSMode = true; ++ pwrpriv->pwr_mode = ps_mode; ++ pwrpriv->smart_ps = smart_ps; ++ pwrpriv->bcn_ant_mode = bcn_ant_mode; ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); ++ ++#ifdef CONFIG_88EU_P2P ++ /* Set CTWindow after LPS */ ++ if (pwdinfo->opp_ps == 1) ++ p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 0); ++#endif /* CONFIG_88EU_P2P */ ++ ++ rtw_set_rpwm(padapter, PS_STATE_S2); ++ } ++ } ++ ++} ++ ++/* ++ * Return: ++ * 0: Leave OK ++ * -1: Timeout ++ * -2: Other error ++ */ ++s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms) ++{ ++ u32 start_time; ++ u8 bAwake = false; ++ s32 err = 0; ++ ++ start_time = jiffies; ++ while (1) { ++ rtw_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, &bAwake); ++ if (bAwake) ++ break; ++ ++ if (padapter->bSurpriseRemoved) { ++ err = -2; ++ DBG_88E("%s: device surprise removed!!\n", __func__); ++ break; ++ } ++ ++ if (rtw_get_passing_time_ms(start_time) > delay_ms) { ++ err = -1; ++ DBG_88E("%s: Wait for FW LPS leave more than %u ms!!!\n", __func__, delay_ms); ++ break; ++ } ++ rtw_usleep_os(100); ++ } ++ ++ return err; ++} ++ ++/* */ ++/* Description: */ ++/* Enter the leisure power save mode. */ ++/* */ ++void LPS_Enter(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ ++ if (!PS_RDY_CHECK(padapter)) ++ return; ++ ++ if (pwrpriv->bLeisurePs) { ++ /* Idle for a while if we connect to AP a while ago. */ ++ if (pwrpriv->LpsIdleCount >= 2) { /* 4 Sec */ ++ if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) { ++ pwrpriv->bpower_saving = true; ++ DBG_88E("%s smart_ps:%d\n", __func__, pwrpriv->smart_ps); ++ /* For Tenda W311R IOT issue */ ++ rtw_set_ps_mode(padapter, pwrpriv->power_mgnt, ++ pwrpriv->smart_ps, 0x40); ++ } ++ } else { ++ pwrpriv->LpsIdleCount++; ++ } ++ } ++ ++} ++ ++#define LPS_LEAVE_TIMEOUT_MS 100 ++ ++/* Description: */ ++/* Leave the leisure power save mode. */ ++void LPS_Leave(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ ++ if (pwrpriv->bLeisurePs) { ++ if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) { ++ rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0x40); ++ ++ if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) ++ LPS_RF_ON_check(padapter, LPS_LEAVE_TIMEOUT_MS); ++ } ++ } ++ ++ pwrpriv->bpower_saving = false; ++ ++} ++ ++/* */ ++/* Description: Leave all power save mode: LPS, FwLPS, IPS if needed. */ ++/* Move code to function by tynli. 2010.03.26. */ ++/* */ ++void LeaveAllPowerSaveMode(struct adapter *Adapter) ++{ ++ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; ++ u8 enqueue = 0; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { /* connect */ ++ p2p_ps_wk_cmd(Adapter, P2P_PS_DISABLE, enqueue); ++ ++ rtw_lps_ctrl_wk_cmd(Adapter, LPS_CTRL_LEAVE, enqueue); ++ } ++ ++} ++ ++void rtw_init_pwrctrl_priv(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; ++ ++ _init_pwrlock(&pwrctrlpriv->lock); ++ pwrctrlpriv->rf_pwrstate = rf_on; ++ pwrctrlpriv->ips_enter_cnts = 0; ++ pwrctrlpriv->ips_leave_cnts = 0; ++ pwrctrlpriv->bips_processing = false; ++ ++ pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode; ++ pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode; ++ ++ pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL; ++ pwrctrlpriv->pwr_state_check_cnts = 0; ++ pwrctrlpriv->bInternalAutoSuspend = false; ++ pwrctrlpriv->bInSuspend = false; ++ pwrctrlpriv->bkeepfwalive = false; ++ ++ pwrctrlpriv->LpsIdleCount = 0; ++ if (padapter->registrypriv.mp_mode == 1) ++ pwrctrlpriv->power_mgnt = PS_MODE_ACTIVE; ++ else ++ pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;/* PS_MODE_MIN; */ ++ pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? true : false; ++ ++ pwrctrlpriv->bFwCurrentInPSMode = false; ++ ++ pwrctrlpriv->rpwm = 0; ++ pwrctrlpriv->cpwm = PS_STATE_S4; ++ ++ pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE; ++ pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps; ++ pwrctrlpriv->bcn_ant_mode = 0; ++ ++ pwrctrlpriv->tog = 0x80; ++ ++ pwrctrlpriv->btcoex_rfon = false; ++ ++ timer_setup(&pwrctrlpriv->pwr_state_check_timer, pwr_state_check_handler, 0); ++} ++ ++void rtw_free_pwrctrl_priv(struct adapter *adapter) ++{ ++ struct pwrctrl_priv *pwrctrlpriv = &adapter->pwrctrlpriv; ++ ++ _free_pwrlock(&pwrctrlpriv->lock); ++ ++} ++ ++u8 rtw_interface_ps_func(struct adapter *padapter, enum hal_intf_ps_func efunc_id, u8 *val) ++{ ++ u8 bResult = true; ++ rtw_hal_intf_ps_func(padapter, efunc_id, val); ++ ++ return bResult; ++} ++ ++inline void rtw_set_ips_deny(struct adapter *padapter, u32 ms) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ms); ++} ++ ++/* ++* rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend ++* @adapter: pointer to struct adapter structure ++* @ips_deffer_ms: the ms wiil prevent from falling into IPS after wakeup ++* Return _SUCCESS or _FAIL ++*/ ++ ++int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *caller) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ int ret = _SUCCESS; ++ u32 start = jiffies; ++ ++ if (pwrpriv->ips_deny_time < jiffies + rtw_ms_to_systime(ips_deffer_ms)) ++ pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ips_deffer_ms); ++ ++ if (pwrpriv->ps_processing) { ++ DBG_88E("%s wait ps_processing...\n", __func__); ++ while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000) ++ msleep(10); ++ if (pwrpriv->ps_processing) ++ DBG_88E("%s wait ps_processing timeout\n", __func__); ++ else ++ DBG_88E("%s wait ps_processing done\n", __func__); ++ } ++ ++ /* System suspend is not allowed to wakeup */ ++ if ((!pwrpriv->bInternalAutoSuspend) && pwrpriv->bInSuspend) { ++ while (pwrpriv->bInSuspend && ++ (rtw_get_passing_time_ms(start) <= 3000 || ++ (rtw_get_passing_time_ms(start) <= 500))) ++ msleep(10); ++ if (pwrpriv->bInSuspend) ++ DBG_88E("%s wait bInSuspend timeout\n", __func__); ++ else ++ DBG_88E("%s wait bInSuspend done\n", __func__); ++ } ++ ++ /* block??? */ ++ if ((pwrpriv->bInternalAutoSuspend) && (padapter->net_closed)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* I think this should be check in IPS, LPS, autosuspend functions... */ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ ret = _SUCCESS; ++ goto exit; ++ } ++ if (rf_off == pwrpriv->rf_pwrstate) { ++ DBG_88E("%s call ips_leave....\n", __func__); ++ if (_FAIL == ips_leave(padapter)) { ++ DBG_88E("======> ips_leave fail.............\n"); ++ ret = _FAIL; ++ goto exit; ++ } ++ } ++ ++ /* TODO: the following checking need to be merged... */ ++ if (padapter->bDriverStopped || !padapter->bup || ++ !padapter->hw_init_completed) { ++ DBG_88E("%s: bDriverStopped=%d, bup=%d, hw_init_completed =%u\n" ++ , caller ++ , padapter->bDriverStopped ++ , padapter->bup ++ , padapter->hw_init_completed); ++ ret = false; ++ goto exit; ++ } ++ ++exit: ++ if (pwrpriv->ips_deny_time < jiffies + rtw_ms_to_systime(ips_deffer_ms)) ++ pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ips_deffer_ms); ++ return ret; ++} ++ ++int rtw_pm_set_lps(struct adapter *padapter, u8 mode) ++{ ++ int ret = 0; ++ struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; ++ ++ if (mode < PS_MODE_NUM) { ++ if (pwrctrlpriv->power_mgnt != mode) { ++ if (PS_MODE_ACTIVE == mode) ++ LeaveAllPowerSaveMode(padapter); ++ else ++ pwrctrlpriv->LpsIdleCount = 2; ++ pwrctrlpriv->power_mgnt = mode; ++ pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? true : false; ++ } ++ } else { ++ ret = -EINVAL; ++ } ++ ++ return ret; ++} ++ ++int rtw_pm_set_ips(struct adapter *padapter, u8 mode) ++{ ++ struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; ++ ++ if (mode == IPS_NORMAL || mode == IPS_LEVEL_2) { ++ rtw_ips_mode_req(pwrctrlpriv, mode); ++ DBG_88E("%s %s\n", __func__, mode == IPS_NORMAL ? "IPS_NORMAL" : "IPS_LEVEL_2"); ++ return 0; ++ } else if (mode == IPS_NONE) { ++ rtw_ips_mode_req(pwrctrlpriv, mode); ++ DBG_88E("%s %s\n", __func__, "IPS_NONE"); ++ if ((padapter->bSurpriseRemoved == 0) && (_FAIL == rtw_pwr_wakeup(padapter))) ++ return -EFAULT; ++ } else { ++ return -EINVAL; ++ } ++ return 0; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_recv.c b/drivers/staging/r8188eu/core/rtw_recv.c +new file mode 100644 +index 000000000000..e082edfbaad8 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_recv.c +@@ -0,0 +1,2058 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_RECV_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/mlme_osdep.h" ++#include "../include/usb_ops.h" ++#include "../include/wifi.h" ++ ++static u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37}; ++static u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3}; ++ ++/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ ++static u8 rtw_bridge_tunnel_header[] = { ++ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 ++}; ++ ++static u8 rtw_rfc1042_header[] = { ++ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 ++}; ++ ++void rtw_signal_stat_timer_hdl(struct timer_list *); ++ ++void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv) ++{ ++ ++ memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv)); ++ ++ spin_lock_init(&psta_recvpriv->lock); ++ ++ _rtw_init_queue(&psta_recvpriv->defrag_q); ++ ++} ++ ++int _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter) ++{ ++ int i; ++ ++ struct recv_frame *precvframe; ++ ++ int res = _SUCCESS; ++ ++ spin_lock_init(&precvpriv->lock); ++ ++ _rtw_init_queue(&precvpriv->free_recv_queue); ++ _rtw_init_queue(&precvpriv->recv_pending_queue); ++ _rtw_init_queue(&precvpriv->uc_swdec_pending_queue); ++ ++ precvpriv->adapter = padapter; ++ ++ precvpriv->free_recvframe_cnt = NR_RECVFRAME; ++ ++ rtw_os_recv_resource_init(precvpriv, padapter); ++ ++ precvpriv->pallocated_frame_buf = vzalloc(NR_RECVFRAME * sizeof(struct recv_frame) + RXFRAME_ALIGN_SZ); ++ ++ if (!precvpriv->pallocated_frame_buf) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ precvpriv->precv_frame_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ); ++ ++ precvframe = (struct recv_frame *)precvpriv->precv_frame_buf; ++ ++ for (i = 0; i < NR_RECVFRAME; i++) { ++ INIT_LIST_HEAD(&precvframe->list); ++ ++ list_add_tail(&precvframe->list, &precvpriv->free_recv_queue.queue); ++ ++ res = rtw_os_recv_resource_alloc(padapter, precvframe); ++ ++ precvframe->len = 0; ++ ++ precvframe->adapter = padapter; ++ precvframe++; ++ } ++ precvpriv->rx_pending_cnt = 1; ++ ++ sema_init(&precvpriv->allrxreturnevt, 0); ++ ++ res = rtw_hal_init_recv_priv(padapter); ++ ++ timer_setup(&precvpriv->signal_stat_timer, rtw_signal_stat_timer_hdl, 0); ++ precvpriv->signal_stat_sampling_interval = 1000; /* ms */ ++ ++ rtw_set_signal_stat_timer(precvpriv); ++exit: ++ ++ return res; ++} ++ ++void _rtw_free_recv_priv(struct recv_priv *precvpriv) ++{ ++ struct adapter *padapter = precvpriv->adapter; ++ ++ rtw_free_uc_swdec_pending_queue(padapter); ++ ++ rtw_os_recv_resource_free(precvpriv); ++ ++ vfree(precvpriv->pallocated_frame_buf); ++ ++ rtw_hal_free_recv_priv(padapter); ++} ++ ++struct recv_frame *_rtw_alloc_recvframe(struct __queue *pfree_recv_queue) ++{ ++ struct recv_frame *hdr; ++ struct list_head *plist, *phead; ++ struct adapter *padapter; ++ struct recv_priv *precvpriv; ++ ++ if (list_empty(&pfree_recv_queue->queue)) { ++ hdr = NULL; ++ } else { ++ phead = get_list_head(pfree_recv_queue); ++ ++ plist = phead->next; ++ ++ hdr = container_of(plist, struct recv_frame, list); ++ ++ list_del_init(&hdr->list); ++ padapter = hdr->adapter; ++ if (padapter) { ++ precvpriv = &padapter->recvpriv; ++ if (pfree_recv_queue == &precvpriv->free_recv_queue) ++ precvpriv->free_recvframe_cnt--; ++ } ++ } ++ ++ return (struct recv_frame *)hdr; ++} ++ ++struct recv_frame *rtw_alloc_recvframe(struct __queue *pfree_recv_queue) ++{ ++ struct recv_frame *precvframe; ++ ++ spin_lock_bh(&pfree_recv_queue->lock); ++ ++ precvframe = _rtw_alloc_recvframe(pfree_recv_queue); ++ ++ spin_unlock_bh(&pfree_recv_queue->lock); ++ ++ return precvframe; ++} ++ ++void rtw_init_recvframe(struct recv_frame *precvframe, struct recv_priv *precvpriv) ++{ ++ /* Perry: This can be removed */ ++ INIT_LIST_HEAD(&precvframe->list); ++ ++ precvframe->len = 0; ++} ++ ++int rtw_free_recvframe(struct recv_frame *precvframe, struct __queue *pfree_recv_queue) ++{ ++ struct adapter *padapter; ++ struct recv_priv *precvpriv; ++ ++ if (!precvframe) ++ return _FAIL; ++ padapter = precvframe->adapter; ++ precvpriv = &padapter->recvpriv; ++ if (precvframe->pkt) { ++ dev_kfree_skb_any(precvframe->pkt);/* free skb by driver */ ++ precvframe->pkt = NULL; ++ } ++ ++ spin_lock_bh(&pfree_recv_queue->lock); ++ ++ list_del_init(&precvframe->list); ++ ++ precvframe->len = 0; ++ ++ list_add_tail(&precvframe->list, get_list_head(pfree_recv_queue)); ++ ++ if (padapter) { ++ if (pfree_recv_queue == &precvpriv->free_recv_queue) ++ precvpriv->free_recvframe_cnt++; ++ } ++ ++ spin_unlock_bh(&pfree_recv_queue->lock); ++ ++ return _SUCCESS; ++} ++ ++int _rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue) ++{ ++ struct adapter *padapter = precvframe->adapter; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ ++ list_del_init(&precvframe->list); ++ list_add_tail(&precvframe->list, get_list_head(queue)); ++ ++ if (padapter) { ++ if (queue == &precvpriv->free_recv_queue) ++ precvpriv->free_recvframe_cnt++; ++ } ++ ++ return _SUCCESS; ++} ++ ++int rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue) ++{ ++ int ret; ++ ++ spin_lock_bh(&queue->lock); ++ ret = _rtw_enqueue_recvframe(precvframe, queue); ++ spin_unlock_bh(&queue->lock); ++ ++ return ret; ++} ++ ++/* ++caller : defrag ; recvframe_chk_defrag in recv_thread (passive) ++pframequeue: defrag_queue : will be accessed in recv_thread (passive) ++ ++using spinlock to protect ++ ++*/ ++ ++void rtw_free_recvframe_queue(struct __queue *pframequeue, struct __queue *pfree_recv_queue) ++{ ++ struct recv_frame *hdr; ++ struct list_head *plist, *phead; ++ ++ spin_lock(&pframequeue->lock); ++ ++ phead = get_list_head(pframequeue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ hdr = container_of(plist, struct recv_frame, list); ++ ++ plist = plist->next; ++ ++ rtw_free_recvframe((struct recv_frame *)hdr, pfree_recv_queue); ++ } ++ ++ spin_unlock(&pframequeue->lock); ++ ++} ++ ++u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter) ++{ ++ u32 cnt = 0; ++ struct recv_frame *pending_frame; ++ while ((pending_frame = rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) { ++ rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue); ++ DBG_88E("%s: dequeue uc_swdec_pending_queue\n", __func__); ++ cnt++; ++ } ++ ++ return cnt; ++} ++ ++int rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, struct __queue *queue) ++{ ++ spin_lock_bh(&queue->lock); ++ ++ list_del_init(&precvbuf->list); ++ list_add(&precvbuf->list, get_list_head(queue)); ++ ++ spin_unlock_bh(&queue->lock); ++ ++ return _SUCCESS; ++} ++ ++int rtw_enqueue_recvbuf(struct recv_buf *precvbuf, struct __queue *queue) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&queue->lock, flags); ++ ++ list_del_init(&precvbuf->list); ++ ++ list_add_tail(&precvbuf->list, get_list_head(queue)); ++ spin_unlock_irqrestore(&queue->lock, flags); ++ return _SUCCESS; ++} ++ ++struct recv_buf *rtw_dequeue_recvbuf(struct __queue *queue) ++{ ++ struct recv_buf *precvbuf; ++ struct list_head *plist, *phead; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&queue->lock, flags); ++ ++ if (list_empty(&queue->queue)) { ++ precvbuf = NULL; ++ } else { ++ phead = get_list_head(queue); ++ ++ plist = phead->next; ++ ++ precvbuf = container_of(plist, struct recv_buf, list); ++ ++ list_del_init(&precvbuf->list); ++ } ++ ++ spin_unlock_irqrestore(&queue->lock, flags); ++ ++ return precvbuf; ++} ++ ++static int recvframe_chkmic(struct adapter *adapter, struct recv_frame *precvframe) ++{ ++ int i, res = _SUCCESS; ++ u32 datalen; ++ u8 miccode[8]; ++ u8 bmic_err = false, brpt_micerror = true; ++ u8 *pframe, *payload, *pframemic; ++ u8 *mickey; ++ struct sta_info *stainfo; ++ struct rx_pkt_attrib *prxattrib = &precvframe->attrib; ++ struct security_priv *psecuritypriv = &adapter->securitypriv; ++ ++ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ stainfo = rtw_get_stainfo(&adapter->stapriv, &prxattrib->ta[0]); ++ ++ if (prxattrib->encrypt == _TKIP_) { ++ /* calculate mic code */ ++ if (stainfo) { ++ if (is_multicast_ether_addr(prxattrib->ra)) { ++ mickey = &psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0]; ++ ++ if (!psecuritypriv) { ++ res = _FAIL; ++ DBG_88E("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n"); ++ goto exit; ++ } ++ } else { ++ mickey = &stainfo->dot11tkiprxmickey.skey[0]; ++ } ++ ++ datalen = precvframe->len - prxattrib->hdrlen - prxattrib->iv_len - prxattrib->icv_len - 8;/* icv_len included the mic code */ ++ pframe = precvframe->rx_data; ++ payload = pframe + prxattrib->hdrlen + prxattrib->iv_len; ++ ++ rtw_seccalctkipmic(mickey, pframe, payload, datalen, &miccode[0], ++ (unsigned char)prxattrib->priority); /* care the length of the data */ ++ ++ pframemic = payload + datalen; ++ ++ bmic_err = false; ++ ++ for (i = 0; i < 8; i++) { ++ if (miccode[i] != *(pframemic + i)) ++ bmic_err = true; ++ } ++ ++ if (bmic_err) { ++ /* double check key_index for some timing issue , */ ++ /* cannot compare with psecuritypriv->dot118021XGrpKeyid also cause timing issue */ ++ if (is_multicast_ether_addr(prxattrib->ra) && prxattrib->key_index != pmlmeinfo->key_index) ++ brpt_micerror = false; ++ ++ if ((prxattrib->bdecrypted) && (brpt_micerror)) { ++ rtw_handle_tkip_mic_err(adapter, (u8)is_multicast_ether_addr(prxattrib->ra)); ++ DBG_88E(" mic error :prxattrib->bdecrypted=%d\n", prxattrib->bdecrypted); ++ } else { ++ DBG_88E(" mic error :prxattrib->bdecrypted=%d\n", prxattrib->bdecrypted); ++ } ++ res = _FAIL; ++ } else { ++ /* mic checked ok */ ++ if (!psecuritypriv->bcheck_grpkey && is_multicast_ether_addr(prxattrib->ra)) ++ psecuritypriv->bcheck_grpkey = true; ++ } ++ } ++ ++ recvframe_pull_tail(precvframe, 8); ++ } ++ ++exit: ++ ++ return res; ++} ++ ++/* decrypt and set the ivlen, icvlen of the recv_frame */ ++static struct recv_frame *decryptor(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ struct rx_pkt_attrib *prxattrib = &precv_frame->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct recv_frame *return_packet = precv_frame; ++ u32 res = _SUCCESS; ++ ++ if (prxattrib->encrypt > 0) { ++ u8 *iv = precv_frame->rx_data + prxattrib->hdrlen; ++ prxattrib->key_index = (((iv[3]) >> 6) & 0x3); ++ ++ if (prxattrib->key_index > WEP_KEYS) { ++ DBG_88E("prxattrib->key_index(%d)>WEP_KEYS\n", prxattrib->key_index); ++ ++ switch (prxattrib->encrypt) { ++ case _WEP40_: ++ case _WEP104_: ++ prxattrib->key_index = psecuritypriv->dot11PrivacyKeyIndex; ++ break; ++ case _TKIP_: ++ case _AES_: ++ default: ++ prxattrib->key_index = psecuritypriv->dot118021XGrpKeyid; ++ break; ++ } ++ } ++ } ++ ++ if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0) || (psecuritypriv->sw_decrypt))) { ++ psecuritypriv->hw_decrypted = false; ++ ++ switch (prxattrib->encrypt) { ++ case _WEP40_: ++ case _WEP104_: ++ rtw_wep_decrypt(padapter, (u8 *)precv_frame); ++ break; ++ case _TKIP_: ++ res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame); ++ break; ++ case _AES_: ++ res = rtw_aes_decrypt(padapter, (u8 *)precv_frame); ++ break; ++ default: ++ break; ++ } ++ } else if (prxattrib->bdecrypted == 1 && prxattrib->encrypt > 0 && ++ (psecuritypriv->busetkipkey == 1 || prxattrib->encrypt != _TKIP_)) ++ psecuritypriv->hw_decrypted = true; ++ ++ if (res == _FAIL) { ++ rtw_free_recvframe(return_packet, &padapter->recvpriv.free_recv_queue); ++ return_packet = NULL; ++ } else { ++ prxattrib->bdecrypted = true; ++ } ++ ++ return return_packet; ++} ++ ++/* set the security information in the recv_frame */ ++static struct recv_frame *portctrl(struct adapter *adapter, struct recv_frame *precv_frame) ++{ ++ u8 *psta_addr, *ptr; ++ uint auth_alg; ++ struct recv_frame *pfhdr; ++ struct sta_info *psta; ++ struct sta_priv *pstapriv; ++ struct recv_frame *prtnframe; ++ u16 ether_type = 0; ++ u16 eapol_type = 0x888e;/* for Funia BD's WPA issue */ ++ struct rx_pkt_attrib *pattrib; ++ __be16 be_tmp; ++ ++ pstapriv = &adapter->stapriv; ++ ++ auth_alg = adapter->securitypriv.dot11AuthAlgrthm; ++ ++ ptr = precv_frame->rx_data; ++ pfhdr = precv_frame; ++ pattrib = &pfhdr->attrib; ++ psta_addr = pattrib->ta; ++ ++ prtnframe = NULL; ++ ++ psta = rtw_get_stainfo(pstapriv, psta_addr); ++ ++ if (auth_alg == 2) { ++ if (psta && psta->ieee8021x_blocked) { ++ /* blocked */ ++ /* only accept EAPOL frame */ ++ prtnframe = precv_frame; ++ ++ /* get ether_type */ ++ ptr = ptr + pfhdr->attrib.hdrlen + pfhdr->attrib.iv_len + LLC_HEADER_SIZE; ++ memcpy(&be_tmp, ptr, 2); ++ ether_type = ntohs(be_tmp); ++ ++ if (ether_type == eapol_type) { ++ prtnframe = precv_frame; ++ } else { ++ /* free this frame */ ++ rtw_free_recvframe(precv_frame, &adapter->recvpriv.free_recv_queue); ++ prtnframe = NULL; ++ } ++ } else { ++ /* allowed */ ++ /* check decryption status, and decrypt the frame if needed */ ++ prtnframe = precv_frame; ++ } ++ } else { ++ prtnframe = precv_frame; ++ } ++ ++ return prtnframe; ++} ++ ++static int recv_decache(struct recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache) ++{ ++ int tid = precv_frame->attrib.priority; ++ ++ u16 seq_ctrl = ((precv_frame->attrib.seq_num & 0xffff) << 4) | ++ (precv_frame->attrib.frag_num & 0xf); ++ ++ if (tid > 15) ++ return _FAIL; ++ ++ if (1) {/* if (bretry) */ ++ if (seq_ctrl == prxcache->tid_rxseq[tid]) ++ return _FAIL; ++ } ++ ++ prxcache->tid_rxseq[tid] = seq_ctrl; ++ ++ return _SUCCESS; ++} ++ ++void process_pwrbit_data(struct adapter *padapter, struct recv_frame *precv_frame); ++void process_pwrbit_data(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++#ifdef CONFIG_88EU_AP_MODE ++ unsigned char pwrbit; ++ u8 *ptr = precv_frame->rx_data; ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct sta_info *psta = NULL; ++ ++ psta = rtw_get_stainfo(pstapriv, pattrib->src); ++ ++ pwrbit = GetPwrMgt(ptr); ++ ++ if (psta) { ++ if (pwrbit) { ++ if (!(psta->state & WIFI_SLEEP_STATE)) ++ stop_sta_xmit(padapter, psta); ++ } else { ++ if (psta->state & WIFI_SLEEP_STATE) ++ wakeup_sta_to_xmit(padapter, psta); ++ } ++ } ++ ++#endif ++} ++ ++static void process_wmmps_data(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++#ifdef CONFIG_88EU_AP_MODE ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct sta_info *psta = NULL; ++ ++ psta = rtw_get_stainfo(pstapriv, pattrib->src); ++ ++ if (!psta) ++ return; ++ ++ if (!psta->qos_option) ++ return; ++ ++ if (!(psta->qos_info & 0xf)) ++ return; ++ ++ if (psta->state & WIFI_SLEEP_STATE) { ++ u8 wmmps_ac = 0; ++ ++ switch (pattrib->priority) { ++ case 1: ++ case 2: ++ wmmps_ac = psta->uapsd_bk & BIT(1); ++ break; ++ case 4: ++ case 5: ++ wmmps_ac = psta->uapsd_vi & BIT(1); ++ break; ++ case 6: ++ case 7: ++ wmmps_ac = psta->uapsd_vo & BIT(1); ++ break; ++ case 0: ++ case 3: ++ default: ++ wmmps_ac = psta->uapsd_be & BIT(1); ++ break; ++ } ++ ++ if (wmmps_ac) { ++ if (psta->sleepq_ac_len > 0) { ++ /* process received triggered frame */ ++ xmit_delivery_enabled_frames(padapter, psta); ++ } else { ++ /* issue one qos null frame with More data bit = 0 and the EOSP bit set (= 1) */ ++ issue_qos_nulldata(padapter, psta->hwaddr, (u16)pattrib->priority, 0, 0); ++ } ++ } ++ } ++ ++#endif ++} ++ ++static void count_rx_stats(struct adapter *padapter, struct recv_frame *prframe, struct sta_info *sta) ++{ ++ int sz; ++ struct sta_info *psta = NULL; ++ struct stainfo_stats *pstats = NULL; ++ struct rx_pkt_attrib *pattrib = &prframe->attrib; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ ++ sz = get_recvframe_len(prframe); ++ precvpriv->rx_bytes += sz; ++ ++ padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++; ++ ++ if (!is_broadcast_ether_addr(pattrib->dst) && !is_multicast_ether_addr(pattrib->dst)) ++ padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++; ++ ++ if (sta) ++ psta = sta; ++ else ++ psta = prframe->psta; ++ ++ if (psta) { ++ pstats = &psta->sta_stats; ++ ++ pstats->rx_data_pkts++; ++ pstats->rx_bytes += sz; ++ } ++} ++ ++int sta2sta_data_frame( ++ struct adapter *adapter, ++ struct recv_frame *precv_frame, ++ struct sta_info **psta ++); ++ ++int sta2sta_data_frame(struct adapter *adapter, struct recv_frame *precv_frame, struct sta_info **psta) ++{ ++ u8 *ptr = precv_frame->rx_data; ++ int ret = _SUCCESS; ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ struct sta_priv *pstapriv = &adapter->stapriv; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ u8 *mybssid = get_bssid(pmlmepriv); ++ u8 *myhwaddr = myid(&adapter->eeprompriv); ++ u8 *sta_addr = NULL; ++ bool bmcast = is_multicast_ether_addr(pattrib->dst); ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ /* filter packets that SA is myself or multicast or broadcast */ ++ if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || ++ !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || ++ memcmp(pattrib->bssid, mybssid, ETH_ALEN)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ sta_addr = pattrib->src; ++ } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ /* For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */ ++ if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ sta_addr = pattrib->bssid; ++ } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ if (bmcast) { ++ /* For AP mode, if DA == MCAST, then BSSID should be also MCAST */ ++ if (!is_multicast_ether_addr(pattrib->bssid)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ } else { /* not mc-frame */ ++ /* For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID */ ++ if (memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ sta_addr = pattrib->src; ++ } ++ } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { ++ memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); ++ memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN); ++ memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); ++ memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); ++ memcpy(pattrib->ta, pattrib->src, ETH_ALEN); ++ ++ sta_addr = mybssid; ++ } else { ++ ret = _FAIL; ++ } ++ ++ if (bmcast) ++ *psta = rtw_get_bcmc_stainfo(adapter); ++ else ++ *psta = rtw_get_stainfo(pstapriv, sta_addr); /* get ap_info */ ++ ++ if (!*psta) { ++ if (adapter->registrypriv.mp_mode == 1) { ++ if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) ++ adapter->mppriv.rx_pktloss++; ++ } ++ ret = _FAIL; ++ goto exit; ++ } ++ ++exit: ++ ++ return ret; ++} ++ ++static int ap2sta_data_frame( ++ struct adapter *adapter, ++ struct recv_frame *precv_frame, ++ struct sta_info **psta) ++{ ++ u8 *ptr = precv_frame->rx_data; ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ int ret = _SUCCESS; ++ struct sta_priv *pstapriv = &adapter->stapriv; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ u8 *mybssid = get_bssid(pmlmepriv); ++ u8 *myhwaddr = myid(&adapter->eeprompriv); ++ bool bmcast = is_multicast_ether_addr(pattrib->dst); ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && ++ (check_fwstate(pmlmepriv, _FW_LINKED) || ++ check_fwstate(pmlmepriv, _FW_UNDER_LINKING))) { ++ /* filter packets that SA is myself or multicast or broadcast */ ++ if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* da should be for me */ ++ if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* check BSSID */ ++ if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || ++ !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || ++ (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) { ++ if (!bmcast) { ++ DBG_88E("issue_deauth to the nonassociated ap=%pM for the reason(7)\n", (pattrib->bssid)); ++ issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); ++ } ++ ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ if (bmcast) ++ *psta = rtw_get_bcmc_stainfo(adapter); ++ else ++ *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get ap_info */ ++ ++ if (!*psta) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { */ ++ /* */ ++ ++ if (GetFrameSubType(ptr) & BIT(6)) { ++ /* No data, will not indicate to upper layer, temporily count it here */ ++ count_rx_stats(adapter, precv_frame, *psta); ++ ret = RTW_RX_HANDLED; ++ goto exit; ++ } ++ } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) && ++ check_fwstate(pmlmepriv, _FW_LINKED)) { ++ memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); ++ memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN); ++ memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); ++ memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); ++ memcpy(pattrib->ta, pattrib->src, ETH_ALEN); ++ ++ /* */ ++ memcpy(pattrib->bssid, mybssid, ETH_ALEN); ++ ++ *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */ ++ if (!*psta) { ++ ret = _FAIL; ++ goto exit; ++ } ++ } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ /* Special case */ ++ ret = RTW_RX_HANDLED; ++ goto exit; ++ } else { ++ if (!memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && (!bmcast)) { ++ *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */ ++ if (!*psta) { ++ DBG_88E("issue_deauth to the ap =%pM for the reason(7)\n", (pattrib->bssid)); ++ ++ issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); ++ } ++ } ++ ++ ret = _FAIL; ++ } ++ ++exit: ++ ++ return ret; ++} ++ ++static int sta2ap_data_frame(struct adapter *adapter, ++ struct recv_frame *precv_frame, ++ struct sta_info **psta) ++{ ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ struct sta_priv *pstapriv = &adapter->stapriv; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ u8 *ptr = precv_frame->rx_data; ++ unsigned char *mybssid = get_bssid(pmlmepriv); ++ int ret = _SUCCESS; ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ /* For AP mode, RA = BSSID, TX = STA(SRC_ADDR), A3 = DST_ADDR */ ++ if (memcmp(pattrib->bssid, mybssid, ETH_ALEN)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ *psta = rtw_get_stainfo(pstapriv, pattrib->src); ++ if (!*psta) { ++ DBG_88E("issue_deauth to sta=%pM for the reason(7)\n", (pattrib->src)); ++ ++ issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); ++ ++ ret = RTW_RX_HANDLED; ++ goto exit; ++ } ++ ++ process_pwrbit_data(adapter, precv_frame); ++ ++ if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { ++ process_wmmps_data(adapter, precv_frame); ++ } ++ ++ if (GetFrameSubType(ptr) & BIT(6)) { ++ /* No data, will not indicate to upper layer, temporily count it here */ ++ count_rx_stats(adapter, precv_frame, *psta); ++ ret = RTW_RX_HANDLED; ++ goto exit; ++ } ++ } else { ++ u8 *myhwaddr = myid(&adapter->eeprompriv); ++ if (memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) { ++ ret = RTW_RX_HANDLED; ++ goto exit; ++ } ++ DBG_88E("issue_deauth to sta=%pM for the reason(7)\n", (pattrib->src)); ++ issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); ++ ret = RTW_RX_HANDLED; ++ goto exit; ++ } ++ ++exit: ++ ++ return ret; ++} ++ ++static int validate_recv_ctrl_frame(struct adapter *padapter, ++ struct recv_frame *precv_frame) ++{ ++#ifdef CONFIG_88EU_AP_MODE ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 *pframe = precv_frame->rx_data; ++ /* uint len = precv_frame->len; */ ++ ++ if (GetFrameType(pframe) != WIFI_CTRL_TYPE) ++ return _FAIL; ++ ++ /* receive the frames that ra(a1) is my address */ ++ if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN)) ++ return _FAIL; ++ ++ /* only handle ps-poll */ ++ if (GetFrameSubType(pframe) == WIFI_PSPOLL) { ++ u16 aid; ++ u8 wmmps_ac = 0; ++ struct sta_info *psta = NULL; ++ ++ aid = GetAid(pframe); ++ psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); ++ ++ if (!psta || psta->aid != aid) ++ return _FAIL; ++ ++ /* for rx pkt statistics */ ++ psta->sta_stats.rx_ctrl_pkts++; ++ ++ switch (pattrib->priority) { ++ case 1: ++ case 2: ++ wmmps_ac = psta->uapsd_bk & BIT(0); ++ break; ++ case 4: ++ case 5: ++ wmmps_ac = psta->uapsd_vi & BIT(0); ++ break; ++ case 6: ++ case 7: ++ wmmps_ac = psta->uapsd_vo & BIT(0); ++ break; ++ case 0: ++ case 3: ++ default: ++ wmmps_ac = psta->uapsd_be & BIT(0); ++ break; ++ } ++ ++ if (wmmps_ac) ++ return _FAIL; ++ ++ if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { ++ DBG_88E("%s alive check-rx ps-poll\n", __func__); ++ psta->expire_to = pstapriv->expire_to; ++ psta->state ^= WIFI_STA_ALIVE_CHK_STATE; ++ } ++ ++ if ((psta->state & WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap & BIT(psta->aid))) { ++ struct list_head *xmitframe_plist, *xmitframe_phead; ++ struct xmit_frame *pxmitframe = NULL; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ spin_lock_bh(&pxmitpriv->lock); ++ ++ xmitframe_phead = get_list_head(&psta->sleep_q); ++ xmitframe_plist = xmitframe_phead->next; ++ ++ if (xmitframe_phead != xmitframe_plist) { ++ pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); ++ ++ xmitframe_plist = xmitframe_plist->next; ++ ++ list_del_init(&pxmitframe->list); ++ ++ psta->sleepq_len--; ++ ++ if (psta->sleepq_len > 0) ++ pxmitframe->attrib.mdata = 1; ++ else ++ pxmitframe->attrib.mdata = 0; ++ ++ pxmitframe->attrib.triggered = 1; ++ ++ rtw_hal_xmitframe_enqueue(padapter, pxmitframe); ++ ++ if (psta->sleepq_len == 0) { ++ pstapriv->tim_bitmap &= ~BIT(psta->aid); ++ ++ /* upate BCN for TIM IE */ ++ /* update_BCNTIM(padapter); */ ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++ } ++ } else { ++ if (pstapriv->tim_bitmap & BIT(psta->aid)) { ++ if (psta->sleepq_len == 0) { ++ DBG_88E("no buffered packets to xmit\n"); ++ ++ /* issue nulldata with More data bit = 0 to indicate we have no buffered packets */ ++ issue_nulldata(padapter, psta->hwaddr, 0, 0, 0); ++ } else { ++ DBG_88E("error!psta->sleepq_len=%d\n", psta->sleepq_len); ++ psta->sleepq_len = 0; ++ } ++ ++ pstapriv->tim_bitmap &= ~BIT(psta->aid); ++ ++ /* upate BCN for TIM IE */ ++ /* update_BCNTIM(padapter); */ ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++ } ++ } ++ spin_unlock_bh(&pxmitpriv->lock); ++ } ++ } ++ ++#endif ++ ++ return _FAIL; ++} ++ ++struct recv_frame *recvframe_chk_defrag(struct adapter *padapter, struct recv_frame *precv_frame); ++ ++static int validate_recv_mgnt_frame(struct adapter *padapter, ++ struct recv_frame *precv_frame) ++{ ++ struct sta_info *psta; ++ ++ precv_frame = recvframe_chk_defrag(padapter, precv_frame); ++ if (!precv_frame) ++ return _SUCCESS; ++ ++ /* for rx pkt statistics */ ++ psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(precv_frame->rx_data)); ++ if (psta) { ++ psta->sta_stats.rx_mgnt_pkts++; ++ if (GetFrameSubType(precv_frame->rx_data) == WIFI_BEACON) { ++ psta->sta_stats.rx_beacon_pkts++; ++ } else if (GetFrameSubType(precv_frame->rx_data) == WIFI_PROBEREQ) { ++ psta->sta_stats.rx_probereq_pkts++; ++ } else if (GetFrameSubType(precv_frame->rx_data) == WIFI_PROBERSP) { ++ if (!memcmp(padapter->eeprompriv.mac_addr, GetAddr1Ptr(precv_frame->rx_data), ETH_ALEN)) ++ psta->sta_stats.rx_probersp_pkts++; ++ else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->rx_data)) || ++ is_multicast_mac_addr(GetAddr1Ptr(precv_frame->rx_data))) ++ psta->sta_stats.rx_probersp_bm_pkts++; ++ else ++ psta->sta_stats.rx_probersp_uo_pkts++; ++ } ++ } ++ ++ mgt_dispatcher(padapter, precv_frame); ++ ++ return _SUCCESS; ++} ++ ++static int validate_recv_data_frame(struct adapter *adapter, ++ struct recv_frame *precv_frame) ++{ ++ u8 bretry; ++ u8 *psa, *pda, *pbssid; ++ struct sta_info *psta = NULL; ++ u8 *ptr = precv_frame->rx_data; ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ struct security_priv *psecuritypriv = &adapter->securitypriv; ++ int ret = _SUCCESS; ++ ++ bretry = GetRetry(ptr); ++ pda = get_da(ptr); ++ psa = get_sa(ptr); ++ pbssid = get_hdr_bssid(ptr); ++ ++ if (!pbssid) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ memcpy(pattrib->dst, pda, ETH_ALEN); ++ memcpy(pattrib->src, psa, ETH_ALEN); ++ ++ memcpy(pattrib->bssid, pbssid, ETH_ALEN); ++ ++ switch (pattrib->to_fr_ds) { ++ case 0: ++ memcpy(pattrib->ra, pda, ETH_ALEN); ++ memcpy(pattrib->ta, psa, ETH_ALEN); ++ ret = sta2sta_data_frame(adapter, precv_frame, &psta); ++ break; ++ case 1: ++ memcpy(pattrib->ra, pda, ETH_ALEN); ++ memcpy(pattrib->ta, pbssid, ETH_ALEN); ++ ret = ap2sta_data_frame(adapter, precv_frame, &psta); ++ break; ++ case 2: ++ memcpy(pattrib->ra, pbssid, ETH_ALEN); ++ memcpy(pattrib->ta, psa, ETH_ALEN); ++ ret = sta2ap_data_frame(adapter, precv_frame, &psta); ++ break; ++ case 3: ++ memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); ++ memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN); ++ ret = _FAIL; ++ break; ++ default: ++ ret = _FAIL; ++ break; ++ } ++ ++ if (ret == _FAIL) { ++ goto exit; ++ } else if (ret == RTW_RX_HANDLED) { ++ goto exit; ++ } ++ ++ if (!psta) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* psta->rssi = prxcmd->rssi; */ ++ /* psta->signal_quality = prxcmd->sq; */ ++ precv_frame->psta = psta; ++ ++ pattrib->amsdu = 0; ++ pattrib->ack_policy = 0; ++ /* parsing QC field */ ++ if (pattrib->qos == 1) { ++ pattrib->priority = GetPriority((ptr + 24)); ++ pattrib->ack_policy = GetAckpolicy((ptr + 24)); ++ pattrib->amsdu = GetAMsdu((ptr + 24)); ++ pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 32 : 26; ++ ++ if (pattrib->priority != 0 && pattrib->priority != 3) ++ adapter->recvpriv.bIsAnyNonBEPkts = true; ++ } else { ++ pattrib->priority = 0; ++ pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 30 : 24; ++ } ++ ++ if (pattrib->order)/* HT-CTRL 11n */ ++ pattrib->hdrlen += 4; ++ ++ precv_frame->preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority]; ++ ++ /* decache, drop duplicate recv packets */ ++ if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) == _FAIL) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ if (pattrib->privacy) { ++ GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, is_multicast_ether_addr(pattrib->ra)); ++ ++ SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt); ++ } else { ++ pattrib->encrypt = 0; ++ pattrib->iv_len = 0; ++ pattrib->icv_len = 0; ++ } ++ ++exit: ++ ++ return ret; ++} ++ ++static int validate_recv_frame(struct adapter *adapter, struct recv_frame *precv_frame) ++{ ++ /* shall check frame subtype, to / from ds, da, bssid */ ++ ++ /* then call check if rx seq/frag. duplicated. */ ++ ++ u8 type; ++ u8 subtype; ++ int retval = _SUCCESS; ++ u8 bDumpRxPkt; ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ u8 *ptr = precv_frame->rx_data; ++ u8 ver = (unsigned char)(*ptr) & 0x3; ++ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; ++ ++ if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { ++ int ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, rtw_get_oper_ch(adapter)); ++ if (ch_set_idx >= 0) ++ pmlmeext->channel_set[ch_set_idx].rx_count++; ++ } ++ ++ /* add version chk */ ++ if (ver != 0) { ++ retval = _FAIL; ++ goto exit; ++ } ++ ++ type = GetFrameType(ptr); ++ subtype = GetFrameSubType(ptr); /* bit(7)~bit(2) */ ++ ++ pattrib->to_fr_ds = get_tofr_ds(ptr); ++ ++ pattrib->frag_num = GetFragNum(ptr); ++ pattrib->seq_num = GetSequence(ptr); ++ ++ pattrib->pw_save = GetPwrMgt(ptr); ++ pattrib->mfrag = GetMFrag(ptr); ++ pattrib->mdata = GetMData(ptr); ++ pattrib->privacy = GetPrivacy(ptr); ++ pattrib->order = GetOrder(ptr); ++ ++ /* Dump rx packets */ ++ rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt)); ++ if (bDumpRxPkt == 1) {/* dump all rx packets */ ++ int i; ++ DBG_88E("#############################\n"); ++ ++ for (i = 0; i < 64; i = i + 8) ++ DBG_88E("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr + i), ++ *(ptr + i + 1), *(ptr + i + 2), *(ptr + i + 3), *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7)); ++ DBG_88E("#############################\n"); ++ } else if (bDumpRxPkt == 2) { ++ if (type == WIFI_MGT_TYPE) { ++ int i; ++ DBG_88E("#############################\n"); ++ ++ for (i = 0; i < 64; i = i + 8) ++ DBG_88E("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr + i), ++ *(ptr + i + 1), *(ptr + i + 2), *(ptr + i + 3), *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7)); ++ DBG_88E("#############################\n"); ++ } ++ } else if (bDumpRxPkt == 3) { ++ if (type == WIFI_DATA_TYPE) { ++ int i; ++ DBG_88E("#############################\n"); ++ ++ for (i = 0; i < 64; i = i + 8) ++ DBG_88E("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr + i), ++ *(ptr + i + 1), *(ptr + i + 2), *(ptr + i + 3), *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7)); ++ DBG_88E("#############################\n"); ++ } ++ } ++ switch (type) { ++ case WIFI_MGT_TYPE: /* mgnt */ ++ validate_recv_mgnt_frame(adapter, precv_frame); ++ retval = _FAIL; /* only data frame return _SUCCESS */ ++ break; ++ case WIFI_CTRL_TYPE: /* ctrl */ ++ validate_recv_ctrl_frame(adapter, precv_frame); ++ retval = _FAIL; /* only data frame return _SUCCESS */ ++ break; ++ case WIFI_DATA_TYPE: /* data */ ++ rtw_led_control(adapter, LED_CTL_RX); ++ pattrib->qos = (subtype & BIT(7)) ? 1 : 0; ++ retval = validate_recv_data_frame(adapter, precv_frame); ++ if (retval == _FAIL) { ++ struct recv_priv *precvpriv = &adapter->recvpriv; ++ precvpriv->rx_drop++; ++ } ++ break; ++ default: ++ retval = _FAIL; ++ break; ++ } ++ ++exit: ++ ++ return retval; ++} ++ ++/* remove the wlanhdr and add the eth_hdr */ ++ ++static int wlanhdr_to_ethhdr(struct recv_frame *precvframe) ++{ ++ int rmv_len; ++ u16 eth_type, len; ++ __be16 be_tmp; ++ u8 bsnaphdr; ++ u8 *psnap_type; ++ struct ieee80211_snap_hdr *psnap; ++ ++ int ret = _SUCCESS; ++ struct adapter *adapter = precvframe->adapter; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ ++ u8 *ptr = get_recvframe_data(precvframe); /* point to frame_ctrl field */ ++ struct rx_pkt_attrib *pattrib = &precvframe->attrib; ++ ++ if (pattrib->encrypt) ++ recvframe_pull_tail(precvframe, pattrib->icv_len); ++ ++ psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len); ++ psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE; ++ /* convert hdr + possible LLC headers into Ethernet header */ ++ if ((!memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) && ++ memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) && ++ memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2)) || ++ !memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) { ++ /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ ++ bsnaphdr = true; ++ } else { ++ /* Leave Ethernet header part of hdr and full payload */ ++ bsnaphdr = false; ++ } ++ ++ rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr ? SNAP_SIZE : 0); ++ len = precvframe->len - rmv_len; ++ ++ memcpy(&be_tmp, ptr + rmv_len, 2); ++ eth_type = ntohs(be_tmp); /* pattrib->ether_type */ ++ pattrib->eth_type = eth_type; ++ ++ if ((check_fwstate(pmlmepriv, WIFI_MP_STATE))) { ++ ptr += rmv_len; ++ *ptr = 0x87; ++ *(ptr + 1) = 0x12; ++ ++ eth_type = 0x8712; ++ /* append rx status for mp test packets */ ++ ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2) - 24); ++ memcpy(ptr, get_rxmem(precvframe), 24); ++ ptr += 24; ++ } else { ++ ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0))); ++ } ++ ++ memcpy(ptr, pattrib->dst, ETH_ALEN); ++ memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN); ++ ++ if (!bsnaphdr) { ++ be_tmp = htons(len); ++ memcpy(ptr + 12, &be_tmp, 2); ++ } ++ ++ return ret; ++} ++ ++/* perform defrag */ ++static struct recv_frame *recvframe_defrag(struct adapter *adapter, struct __queue *defrag_q) ++{ ++ struct list_head *plist, *phead; ++ u8 wlanhdr_offset; ++ u8 curfragnum; ++ struct recv_frame *pfhdr, *pnfhdr; ++ struct recv_frame *prframe, *pnextrframe; ++ struct __queue *pfree_recv_queue; ++ ++ curfragnum = 0; ++ pfree_recv_queue = &adapter->recvpriv.free_recv_queue; ++ ++ phead = get_list_head(defrag_q); ++ plist = phead->next; ++ pfhdr = container_of(plist, struct recv_frame, list); ++ prframe = (struct recv_frame *)pfhdr; ++ list_del_init(&prframe->list); ++ ++ if (curfragnum != pfhdr->attrib.frag_num) { ++ /* the first fragment number must be 0 */ ++ /* free the whole queue */ ++ rtw_free_recvframe(prframe, pfree_recv_queue); ++ rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); ++ ++ return NULL; ++ } ++ ++ curfragnum++; ++ ++ plist = get_list_head(defrag_q); ++ plist = phead->next; ++ pfhdr = container_of(plist, struct recv_frame, list); ++ prframe = (struct recv_frame *)pfhdr; ++ list_del_init(&prframe->list); ++ ++ plist = plist->next; ++ ++ while (phead != plist) { ++ pnfhdr = container_of(plist, struct recv_frame, list); ++ pnextrframe = (struct recv_frame *)pnfhdr; ++ ++ /* check the fragment sequence (2nd ~n fragment frame) */ ++ ++ if (curfragnum != pnfhdr->attrib.frag_num) { ++ /* the fragment number must be increasing (after decache) */ ++ /* release the defrag_q & prframe */ ++ rtw_free_recvframe(prframe, pfree_recv_queue); ++ rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); ++ return NULL; ++ } ++ ++ curfragnum++; ++ ++ /* copy the 2nd~n fragment frame's payload to the first fragment */ ++ /* get the 2nd~last fragment frame's payload */ ++ ++ wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len; ++ ++ recvframe_pull(pnextrframe, wlanhdr_offset); ++ ++ /* append to first fragment frame's tail (if privacy frame, pull the ICV) */ ++ recvframe_pull_tail(prframe, pfhdr->attrib.icv_len); ++ ++ /* memcpy */ ++ memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len); ++ ++ recvframe_put(prframe, pnfhdr->len); ++ ++ pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len; ++ plist = plist->next; ++ } ++ ++ /* free the defrag_q queue and return the prframe */ ++ rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); ++ ++ return prframe; ++} ++ ++/* check if need to defrag, if needed queue the frame to defrag_q */ ++struct recv_frame *recvframe_chk_defrag(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ u8 ismfrag; ++ u8 fragnum; ++ u8 *psta_addr; ++ struct recv_frame *pfhdr; ++ struct sta_info *psta; ++ struct sta_priv *pstapriv; ++ struct list_head *phead; ++ struct recv_frame *prtnframe = NULL; ++ struct __queue *pfree_recv_queue, *pdefrag_q; ++ ++ pstapriv = &padapter->stapriv; ++ ++ pfhdr = precv_frame; ++ ++ pfree_recv_queue = &padapter->recvpriv.free_recv_queue; ++ ++ /* need to define struct of wlan header frame ctrl */ ++ ismfrag = pfhdr->attrib.mfrag; ++ fragnum = pfhdr->attrib.frag_num; ++ ++ psta_addr = pfhdr->attrib.ta; ++ psta = rtw_get_stainfo(pstapriv, psta_addr); ++ if (!psta) { ++ u8 type = GetFrameType(pfhdr->rx_data); ++ if (type != WIFI_DATA_TYPE) { ++ psta = rtw_get_bcmc_stainfo(padapter); ++ pdefrag_q = &psta->sta_recvpriv.defrag_q; ++ } else { ++ pdefrag_q = NULL; ++ } ++ } else { ++ pdefrag_q = &psta->sta_recvpriv.defrag_q; ++ } ++ ++ if ((ismfrag == 0) && (fragnum == 0)) ++ prtnframe = precv_frame;/* isn't a fragment frame */ ++ ++ if (ismfrag == 1) { ++ /* 0~(n-1) fragment frame */ ++ /* enqueue to defraf_g */ ++ if (pdefrag_q) { ++ if (fragnum == 0) { ++ /* the first fragment */ ++ if (!list_empty(&pdefrag_q->queue)) { ++ /* free current defrag_q */ ++ rtw_free_recvframe_queue(pdefrag_q, pfree_recv_queue); ++ } ++ } ++ ++ /* Then enqueue the 0~(n-1) fragment into the defrag_q */ ++ ++ phead = get_list_head(pdefrag_q); ++ list_add_tail(&pfhdr->list, phead); ++ ++ prtnframe = NULL; ++ } else { ++ /* can't find this ta's defrag_queue, so free this recv_frame */ ++ if (precv_frame && pfree_recv_queue) ++ rtw_free_recvframe(precv_frame, pfree_recv_queue); ++ prtnframe = NULL; ++ } ++ } ++ ++ if ((ismfrag == 0) && (fragnum != 0)) { ++ /* the last fragment frame */ ++ /* enqueue the last fragment */ ++ if (pdefrag_q) { ++ phead = get_list_head(pdefrag_q); ++ list_add_tail(&pfhdr->list, phead); ++ ++ /* call recvframe_defrag to defrag */ ++ precv_frame = recvframe_defrag(padapter, pdefrag_q); ++ prtnframe = precv_frame; ++ } else { ++ /* can't find this ta's defrag_queue, so free this recv_frame */ ++ if (precv_frame && pfree_recv_queue) ++ rtw_free_recvframe(precv_frame, pfree_recv_queue); ++ prtnframe = NULL; ++ } ++ } ++ ++ if (prtnframe && prtnframe->attrib.privacy) { ++ /* after defrag we must check tkip mic code */ ++ if (recvframe_chkmic(padapter, prtnframe) == _FAIL) { ++ if (precv_frame && pfree_recv_queue) ++ rtw_free_recvframe(prtnframe, pfree_recv_queue); ++ prtnframe = NULL; ++ } ++ } ++ ++ return prtnframe; ++} ++ ++static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe) ++{ ++ int a_len, padding_len; ++ u16 eth_type, nSubframe_Length; ++ u8 nr_subframes, i; ++ unsigned char *pdata; ++ struct rx_pkt_attrib *pattrib; ++ unsigned char *data_ptr; ++ struct sk_buff *sub_skb, *subframes[MAX_SUBFRAME_COUNT]; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue; ++ int ret = _SUCCESS; ++ nr_subframes = 0; ++ ++ pattrib = &prframe->attrib; ++ ++ recvframe_pull(prframe, prframe->attrib.hdrlen); ++ ++ if (prframe->attrib.iv_len > 0) ++ recvframe_pull(prframe, prframe->attrib.iv_len); ++ ++ a_len = prframe->len; ++ ++ pdata = prframe->rx_data; ++ ++ while (a_len > ETH_HLEN) { ++ /* Offset 12 denote 2 mac address */ ++ nSubframe_Length = RTW_GET_BE16(pdata + 12); ++ ++ if (a_len < ETH_HLEN + nSubframe_Length) { ++ DBG_88E("nRemain_Length is %d and nSubframe_Length is : %d\n", a_len, nSubframe_Length); ++ goto exit; ++ } ++ ++ /* move the data point to data content */ ++ pdata += ETH_HLEN; ++ a_len -= ETH_HLEN; ++ ++ /* Allocate new skb for releasing to upper layer */ ++ sub_skb = dev_alloc_skb(nSubframe_Length + 12); ++ if (sub_skb) { ++ skb_reserve(sub_skb, 12); ++ data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length); ++ memcpy(data_ptr, pdata, nSubframe_Length); ++ } else { ++ sub_skb = skb_clone(prframe->pkt, GFP_ATOMIC); ++ if (sub_skb) { ++ sub_skb->data = pdata; ++ sub_skb->len = nSubframe_Length; ++ skb_set_tail_pointer(sub_skb, nSubframe_Length); ++ } else { ++ DBG_88E("skb_clone() Fail!!! , nr_subframes=%d\n", nr_subframes); ++ break; ++ } ++ } ++ ++ subframes[nr_subframes++] = sub_skb; ++ ++ if (nr_subframes >= MAX_SUBFRAME_COUNT) { ++ DBG_88E("ParseSubframe(): Too many Subframes! Packets dropped!\n"); ++ break; ++ } ++ ++ pdata += nSubframe_Length; ++ a_len -= nSubframe_Length; ++ if (a_len != 0) { ++ padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & (4 - 1)); ++ if (padding_len == 4) { ++ padding_len = 0; ++ } ++ ++ if (a_len < padding_len) { ++ goto exit; ++ } ++ pdata += padding_len; ++ a_len -= padding_len; ++ } ++ } ++ ++ for (i = 0; i < nr_subframes; i++) { ++ sub_skb = subframes[i]; ++ /* convert hdr + possible LLC headers into Ethernet header */ ++ eth_type = RTW_GET_BE16(&sub_skb->data[6]); ++ if (sub_skb->len >= 8 && ++ ((!memcmp(sub_skb->data, rtw_rfc1042_header, SNAP_SIZE) && ++ eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || ++ !memcmp(sub_skb->data, rtw_bridge_tunnel_header, SNAP_SIZE))) { ++ /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ ++ skb_pull(sub_skb, SNAP_SIZE); ++ memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN); ++ memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN); ++ } else { ++ __be16 len; ++ /* Leave Ethernet header part of hdr and full payload */ ++ len = htons(sub_skb->len); ++ memcpy(skb_push(sub_skb, 2), &len, 2); ++ memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN); ++ memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN); ++ } ++ ++ /* Indicate the packets to upper layer */ ++ /* Insert NAT2.5 RX here! */ ++ sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev); ++ sub_skb->dev = padapter->pnetdev; ++ ++ sub_skb->ip_summed = CHECKSUM_NONE; ++ ++ netif_rx(sub_skb); ++ } ++ ++exit: ++ ++ prframe->len = 0; ++ rtw_free_recvframe(prframe, pfree_recv_queue);/* free this recv_frame */ ++ ++ return ret; ++} ++ ++static int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num) ++{ ++ u8 wsize = preorder_ctrl->wsize_b; ++ u16 wend = (preorder_ctrl->indicate_seq + wsize - 1) & 0xFFF;/* 4096; */ ++ ++ /* Rx Reorder initialize condition. */ ++ if (preorder_ctrl->indicate_seq == 0xFFFF) ++ preorder_ctrl->indicate_seq = seq_num; ++ ++ /* Drop out the packet which SeqNum is smaller than WinStart */ ++ if (SN_LESS(seq_num, preorder_ctrl->indicate_seq)) ++ return false; ++ ++ /* */ ++ /* Sliding window manipulation. Conditions includes: */ ++ /* 1. Incoming SeqNum is equal to WinStart =>Window shift 1 */ ++ /* 2. Incoming SeqNum is larger than the WinEnd => Window shift N */ ++ /* */ ++ if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) { ++ preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF; ++ } else if (SN_LESS(wend, seq_num)) { ++ if (seq_num >= (wsize - 1)) ++ preorder_ctrl->indicate_seq = seq_num + 1 - wsize; ++ else ++ preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1; ++ } ++ ++ return true; ++} ++ ++int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, struct recv_frame *prframe); ++int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, struct recv_frame *prframe) ++{ ++ struct rx_pkt_attrib *pattrib = &prframe->attrib; ++ struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; ++ struct list_head *phead, *plist; ++ struct recv_frame *hdr; ++ struct rx_pkt_attrib *pnextattrib; ++ ++ phead = get_list_head(ppending_recvframe_queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ hdr = container_of(plist, struct recv_frame, list); ++ pnextattrib = &hdr->attrib; ++ ++ if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num)) ++ plist = plist->next; ++ else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) ++ return false; ++ else ++ break; ++ } ++ ++ list_del_init(&prframe->list); ++ ++ list_add_tail(&prframe->list, plist); ++ return true; ++} ++ ++static int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced) ++{ ++ struct list_head *phead, *plist; ++ struct recv_frame *prframe; ++ struct rx_pkt_attrib *pattrib; ++ int bPktInBuf = false; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; ++ ++ phead = get_list_head(ppending_recvframe_queue); ++ plist = phead->next; ++ ++ /* Handling some condition for forced indicate case. */ ++ if (bforced) { ++ if (list_empty(phead)) ++ return true; ++ ++ prframe = container_of(plist, struct recv_frame, list); ++ pattrib = &prframe->attrib; ++ preorder_ctrl->indicate_seq = pattrib->seq_num; ++ } ++ ++ /* Prepare indication list and indication. */ ++ /* Check if there is any packet need indicate. */ ++ while (!list_empty(phead)) { ++ prframe = container_of(plist, struct recv_frame, list); ++ pattrib = &prframe->attrib; ++ ++ if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) { ++ plist = plist->next; ++ list_del_init(&prframe->list); ++ ++ if (SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num)) ++ preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF; ++ ++ /* Set this as a lock to make sure that only one thread is indicating packet. */ ++ ++ /* indicate this recv_frame */ ++ if (!pattrib->amsdu) { ++ if ((!padapter->bDriverStopped) && ++ (!padapter->bSurpriseRemoved)) ++ rtw_recv_indicatepkt(padapter, prframe);/* indicate this recv_frame */ ++ } else if (pattrib->amsdu == 1) { ++ if (amsdu_to_msdu(padapter, prframe) != _SUCCESS) ++ rtw_free_recvframe(prframe, &precvpriv->free_recv_queue); ++ } else { ++ /* error condition; */ ++ } ++ ++ /* Update local variables. */ ++ bPktInBuf = false; ++ } else { ++ bPktInBuf = true; ++ break; ++ } ++ } ++ return bPktInBuf; ++} ++ ++static int recv_indicatepkt_reorder(struct adapter *padapter, struct recv_frame *prframe) ++{ ++ int retval = _SUCCESS; ++ struct rx_pkt_attrib *pattrib = &prframe->attrib; ++ struct recv_reorder_ctrl *preorder_ctrl = prframe->preorder_ctrl; ++ struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; ++ ++ if (!pattrib->amsdu) { ++ /* s1. */ ++ wlanhdr_to_ethhdr(prframe); ++ ++ if (pattrib->qos != 1) { ++ if (!padapter->bDriverStopped && ++ !padapter->bSurpriseRemoved) { ++ rtw_recv_indicatepkt(padapter, prframe); ++ return _SUCCESS; ++ } ++ ++ return _FAIL; ++ } ++ ++ if (!preorder_ctrl->enable) { ++ /* indicate this recv_frame */ ++ preorder_ctrl->indicate_seq = pattrib->seq_num; ++ rtw_recv_indicatepkt(padapter, prframe); ++ ++ preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) % 4096; ++ return _SUCCESS; ++ } ++ } else if (pattrib->amsdu == 1) { /* temp filter -> means didn't support A-MSDUs in a A-MPDU */ ++ if (!preorder_ctrl->enable) { ++ preorder_ctrl->indicate_seq = pattrib->seq_num; ++ retval = amsdu_to_msdu(padapter, prframe); ++ ++ preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) % 4096; ++ return retval; ++ } ++ } ++ ++ spin_lock_bh(&ppending_recvframe_queue->lock); ++ ++ /* s2. check if winstart_b(indicate_seq) needs to been updated */ ++ if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) ++ goto _err_exit; ++ ++ /* s3. Insert all packet into Reorder Queue to maintain its ordering. */ ++ if (!enqueue_reorder_recvframe(preorder_ctrl, prframe)) ++ goto _err_exit; ++ ++ /* s4. */ ++ /* Indication process. */ ++ /* After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets */ ++ /* with the SeqNum smaller than latest WinStart and buffer other packets. */ ++ /* */ ++ /* For Rx Reorder condition: */ ++ /* 1. All packets with SeqNum smaller than WinStart => Indicate */ ++ /* 2. All packets with SeqNum larger than or equal to WinStart => Buffer it. */ ++ /* */ ++ ++ /* recv_indicatepkts_in_order(padapter, preorder_ctrl, true); */ ++ if (recv_indicatepkts_in_order(padapter, preorder_ctrl, false)) { ++ _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME); ++ spin_unlock_bh(&ppending_recvframe_queue->lock); ++ } else { ++ spin_unlock_bh(&ppending_recvframe_queue->lock); ++ _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer); ++ } ++ ++ return _SUCCESS; ++ ++_err_exit: ++ ++ spin_unlock_bh(&ppending_recvframe_queue->lock); ++ ++ return _FAIL; ++} ++ ++void rtw_reordering_ctrl_timeout_handler(void *pcontext) ++{ ++ struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)pcontext; ++ struct adapter *padapter = preorder_ctrl->padapter; ++ struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; ++ ++ if (padapter->bDriverStopped || padapter->bSurpriseRemoved) ++ return; ++ ++ spin_lock_bh(&ppending_recvframe_queue->lock); ++ ++ if (recv_indicatepkts_in_order(padapter, preorder_ctrl, true)) ++ _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME); ++ ++ spin_unlock_bh(&ppending_recvframe_queue->lock); ++} ++ ++static int process_recv_indicatepkts(struct adapter *padapter, struct recv_frame *prframe) ++{ ++ int retval = _SUCCESS; ++ /* struct recv_priv *precvpriv = &padapter->recvpriv; */ ++ /* struct rx_pkt_attrib *pattrib = &prframe->attrib; */ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ ++ if (phtpriv->ht_option) { /* B/G/N Mode */ ++ /* prframe->preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority]; */ ++ ++ if (recv_indicatepkt_reorder(padapter, prframe) != _SUCCESS) { ++ /* including perform A-MPDU Rx Ordering Buffer Control */ ++ if ((!padapter->bDriverStopped) && ++ (!padapter->bSurpriseRemoved)) { ++ retval = _FAIL; ++ return retval; ++ } ++ } ++ } else { /* B/G mode */ ++ retval = wlanhdr_to_ethhdr(prframe); ++ if (retval != _SUCCESS) ++ return retval; ++ ++ if ((!padapter->bDriverStopped) && ++ (!padapter->bSurpriseRemoved)) { ++ /* indicate this recv_frame */ ++ rtw_recv_indicatepkt(padapter, prframe); ++ } else { ++ retval = _FAIL; ++ return retval; ++ } ++ } ++ ++ return retval; ++} ++ ++static int recv_func_prehandle(struct adapter *padapter, struct recv_frame *rframe) ++{ ++ int ret = _SUCCESS; ++ struct rx_pkt_attrib *pattrib = &rframe->attrib; ++ struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if (padapter->registrypriv.mp_mode == 1) { ++ if (pattrib->crc_err == 1) ++ padapter->mppriv.rx_crcerrpktcount++; ++ else ++ padapter->mppriv.rx_pktcount++; ++ ++ if (!check_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE)) { ++ ret = _FAIL; ++ rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */ ++ goto exit; ++ } ++ } ++ ++ /* check the frame crtl field and decache */ ++ ret = validate_recv_frame(padapter, rframe); ++ if (ret != _SUCCESS) { ++ rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */ ++ goto exit; ++ } ++ ++exit: ++ return ret; ++} ++ ++static int recv_func_posthandle(struct adapter *padapter, struct recv_frame *prframe) ++{ ++ int ret = _SUCCESS; ++ struct recv_frame *orig_prframe = prframe; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; ++ ++ /* DATA FRAME */ ++ rtw_led_control(padapter, LED_CTL_RX); ++ ++ prframe = decryptor(padapter, prframe); ++ if (!prframe) { ++ ret = _FAIL; ++ goto _recv_data_drop; ++ } ++ ++ prframe = recvframe_chk_defrag(padapter, prframe); ++ if (!prframe) ++ goto _recv_data_drop; ++ ++ prframe = portctrl(padapter, prframe); ++ if (!prframe) { ++ ret = _FAIL; ++ goto _recv_data_drop; ++ } ++ ++ count_rx_stats(padapter, prframe, NULL); ++ ++ ret = process_recv_indicatepkts(padapter, prframe); ++ if (ret != _SUCCESS) { ++ rtw_free_recvframe(orig_prframe, pfree_recv_queue);/* free this recv_frame */ ++ goto _recv_data_drop; ++ } ++ return ret; ++ ++_recv_data_drop: ++ precvpriv->rx_drop++; ++ return ret; ++} ++ ++static int recv_func(struct adapter *padapter, struct recv_frame *rframe) ++{ ++ int ret; ++ struct rx_pkt_attrib *prxattrib = &rframe->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct mlme_priv *mlmepriv = &padapter->mlmepriv; ++ struct recv_priv *recvpriv = &padapter->recvpriv; ++ ++ /* check if need to handle uc_swdec_pending_queue*/ ++ if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && ++ psecuritypriv->busetkipkey) { ++ struct recv_frame *pending_frame; ++ int cnt = 0; ++ ++ pending_frame = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue); ++ while (pending_frame) { ++ cnt++; ++ recv_func_posthandle(padapter, pending_frame); ++ } ++ } ++ ++ ret = recv_func_prehandle(padapter, rframe); ++ ++ if (ret == _SUCCESS) { ++ /* check if need to enqueue into uc_swdec_pending_queue*/ ++ if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && ++ !is_multicast_ether_addr(prxattrib->ra) && prxattrib->encrypt > 0 && ++ (prxattrib->bdecrypted == 0 || psecuritypriv->sw_decrypt) && ++ psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK && ++ !psecuritypriv->busetkipkey) { ++ rtw_enqueue_recvframe(rframe, &padapter->recvpriv.uc_swdec_pending_queue); ++ DBG_88E("%s: no key, enqueue uc_swdec_pending_queue\n", __func__); ++ if (recvpriv->free_recvframe_cnt < NR_RECVFRAME / 4) { ++ /* to prevent from recvframe starvation, ++ * get recvframe from uc_swdec_pending_queue to ++ * free_recvframe_cnt */ ++ rframe = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue); ++ if (rframe) ++ goto do_posthandle; ++ } ++ goto exit; ++ } ++do_posthandle: ++ ret = recv_func_posthandle(padapter, rframe); ++ } ++ ++exit: ++ return ret; ++} ++ ++s32 rtw_recv_entry(struct recv_frame *precvframe) ++{ ++ struct adapter *padapter; ++ struct recv_priv *precvpriv; ++ s32 ret = _SUCCESS; ++ ++ padapter = precvframe->adapter; ++ ++ precvpriv = &padapter->recvpriv; ++ ++ ret = recv_func(padapter, precvframe); ++ if (ret == _FAIL) ++ goto _recv_entry_drop; ++ ++ precvpriv->rx_pkts++; ++ ++ return ret; ++ ++_recv_entry_drop: ++ ++ if (padapter->registrypriv.mp_mode == 1) ++ padapter->mppriv.rx_pktloss = precvpriv->rx_drop; ++ ++ return ret; ++} ++ ++void rtw_signal_stat_timer_hdl(struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, recvpriv.signal_stat_timer); ++ struct recv_priv *recvpriv = &adapter->recvpriv; ++ ++ u32 tmp_s, tmp_q; ++ u8 avg_signal_strength = 0; ++ u8 avg_signal_qual = 0; ++ u8 _alpha = 3; /* this value is based on converging_constant = 5000 and sampling_interval = 1000 */ ++ ++ if (adapter->recvpriv.is_signal_dbg) { ++ /* update the user specific value, signal_strength_dbg, to signal_strength, rssi */ ++ adapter->recvpriv.signal_strength = adapter->recvpriv.signal_strength_dbg; ++ adapter->recvpriv.rssi = (s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg); ++ } else { ++ if (recvpriv->signal_strength_data.update_req == 0) {/* update_req is clear, means we got rx */ ++ avg_signal_strength = recvpriv->signal_strength_data.avg_val; ++ /* after avg_vals are accquired, we can re-stat the signal values */ ++ recvpriv->signal_strength_data.update_req = 1; ++ } ++ ++ if (recvpriv->signal_qual_data.update_req == 0) {/* update_req is clear, means we got rx */ ++ avg_signal_qual = recvpriv->signal_qual_data.avg_val; ++ /* after avg_vals are accquired, we can re-stat the signal values */ ++ recvpriv->signal_qual_data.update_req = 1; ++ } ++ ++ /* update value of signal_strength, rssi, signal_qual */ ++ if (!check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY)) { ++ tmp_s = (avg_signal_strength + (_alpha - 1) * recvpriv->signal_strength); ++ if (tmp_s % _alpha) ++ tmp_s = tmp_s / _alpha + 1; ++ else ++ tmp_s = tmp_s / _alpha; ++ if (tmp_s > 100) ++ tmp_s = 100; ++ ++ tmp_q = (avg_signal_qual + (_alpha - 1) * recvpriv->signal_qual); ++ if (tmp_q % _alpha) ++ tmp_q = tmp_q / _alpha + 1; ++ else ++ tmp_q = tmp_q / _alpha; ++ if (tmp_q > 100) ++ tmp_q = 100; ++ ++ recvpriv->signal_strength = tmp_s; ++ recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s); ++ recvpriv->signal_qual = tmp_q; ++ } ++ } ++ rtw_set_signal_stat_timer(recvpriv); ++} +diff --git a/drivers/staging/r8188eu/core/rtw_rf.c b/drivers/staging/r8188eu/core/rtw_rf.c +new file mode 100644 +index 000000000000..321546c40446 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_rf.c +@@ -0,0 +1,72 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_RF_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/xmit_osdep.h" ++ ++struct ch_freq { ++ u32 channel; ++ u32 frequency; ++}; ++ ++static struct ch_freq ch_freq_map[] = { ++ {1, 2412}, {2, 2417}, {3, 2422}, {4, 2427}, {5, 2432}, ++ {6, 2437}, {7, 2442}, {8, 2447}, {9, 2452}, {10, 2457}, ++ {11, 2462}, {12, 2467}, {13, 2472}, {14, 2484}, ++ /* UNII */ ++ {36, 5180}, {40, 5200}, {44, 5220}, {48, 5240}, {52, 5260}, ++ {56, 5280}, {60, 5300}, {64, 5320}, {149, 5745}, {153, 5765}, ++ {157, 5785}, {161, 5805}, {165, 5825}, {167, 5835}, {169, 5845}, ++ {171, 5855}, {173, 5865}, ++ /* HiperLAN2 */ ++ {100, 5500}, {104, 5520}, {108, 5540}, {112, 5560}, {116, 5580}, ++ {120, 5600}, {124, 5620}, {128, 5640}, {132, 5660}, {136, 5680}, ++ {140, 5700}, ++ /* Japan MMAC */ ++ {34, 5170}, {38, 5190}, {42, 5210}, {46, 5230}, ++ /* Japan */ ++ {184, 4920}, {188, 4940}, {192, 4960}, {196, 4980}, ++ {208, 5040},/* Japan, means J08 */ ++ {212, 5060},/* Japan, means J12 */ ++ {216, 5080},/* Japan, means J16 */ ++}; ++ ++static int ch_freq_map_num = (sizeof(ch_freq_map) / sizeof(struct ch_freq)); ++ ++u32 rtw_ch2freq(u32 channel) ++{ ++ u8 i; ++ u32 freq = 0; ++ ++ for (i = 0; i < ch_freq_map_num; i++) { ++ if (channel == ch_freq_map[i].channel) { ++ freq = ch_freq_map[i].frequency; ++ break; ++ } ++ } ++ if (i == ch_freq_map_num) ++ freq = 2412; ++ ++ return freq; ++} ++ ++u32 rtw_freq2ch(u32 freq) ++{ ++ u8 i; ++ u32 ch = 0; ++ ++ for (i = 0; i < ch_freq_map_num; i++) { ++ if (freq == ch_freq_map[i].frequency) { ++ ch = ch_freq_map[i].channel; ++ break; ++ } ++ } ++ if (i == ch_freq_map_num) ++ ch = 1; ++ ++ return ch; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_security.c b/drivers/staging/r8188eu/core/rtw_security.c +new file mode 100644 +index 000000000000..5aa893ab46e9 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_security.c +@@ -0,0 +1,1656 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_SECURITY_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wifi.h" ++#include "../include/osdep_intf.h" ++ ++/* WEP related ===== */ ++ ++#define CRC32_POLY 0x04c11db7 ++ ++struct arc4context { ++ u32 x; ++ u32 y; ++ u8 state[256]; ++}; ++ ++static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len) ++{ ++ u32 t, u; ++ u32 keyindex; ++ u32 stateindex; ++ u8 *state; ++ u32 counter; ++ ++ state = parc4ctx->state; ++ parc4ctx->x = 0; ++ parc4ctx->y = 0; ++ for (counter = 0; counter < 256; counter++) ++ state[counter] = (u8)counter; ++ keyindex = 0; ++ stateindex = 0; ++ for (counter = 0; counter < 256; counter++) { ++ t = state[counter]; ++ stateindex = (stateindex + key[keyindex] + t) & 0xff; ++ u = state[stateindex]; ++ state[stateindex] = (u8)t; ++ state[counter] = (u8)u; ++ if (++keyindex >= key_len) ++ keyindex = 0; ++ } ++ ++} ++ ++static u32 arcfour_byte(struct arc4context *parc4ctx) ++{ ++ u32 x; ++ u32 y; ++ u32 sx, sy; ++ u8 *state; ++ ++ state = parc4ctx->state; ++ x = (parc4ctx->x + 1) & 0xff; ++ sx = state[x]; ++ y = (sx + parc4ctx->y) & 0xff; ++ sy = state[y]; ++ parc4ctx->x = x; ++ parc4ctx->y = y; ++ state[y] = (u8)sx; ++ state[x] = (u8)sy; ++ ++ return state[(sx + sy) & 0xff]; ++} ++ ++static void arcfour_encrypt(struct arc4context *parc4ctx, u8 *dest, u8 *src, u32 len) ++{ ++ u32 i; ++ ++ for (i = 0; i < len; i++) ++ dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx); ++ ++} ++ ++/* ++ Need to consider the fragment situation ++*/ ++void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe) ++{ /* exclude ICV */ ++ union { ++ __le32 f0; ++ u8 f1[4]; ++ } crc; ++ struct arc4context mycontext; ++ ++ int curfragnum, length; ++ u32 keylength; ++ ++ u8 *pframe, *payload, *iv; /* wepkey */ ++ u8 wepkey[16]; ++ u8 hw_hdr_offset = 0; ++ struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ if (!((struct xmit_frame *)pxmitframe)->buf_addr) ++ return; ++ ++ hw_hdr_offset = TXDESC_SIZE + ++ (((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ); ++ ++ pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset; ++ ++ /* start to encrypt each fragment */ ++ if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) { ++ keylength = psecuritypriv->dot11DefKeylen[psecuritypriv->dot11PrivacyKeyIndex]; ++ ++ for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { ++ iv = pframe + pattrib->hdrlen; ++ memcpy(&wepkey[0], iv, 3); ++ memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength); ++ payload = pframe + pattrib->iv_len + pattrib->hdrlen; ++ ++ if ((curfragnum + 1) == pattrib->nr_frags) { /* the last fragment */ ++ length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; ++ ++ crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length)); ++ ++ arcfour_init(&mycontext, wepkey, 3 + keylength); ++ arcfour_encrypt(&mycontext, payload, payload, length); ++ arcfour_encrypt(&mycontext, payload + length, crc.f1, 4); ++ } else { ++ length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; ++ crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length)); ++ arcfour_init(&mycontext, wepkey, 3 + keylength); ++ arcfour_encrypt(&mycontext, payload, payload, length); ++ arcfour_encrypt(&mycontext, payload + length, crc.f1, 4); ++ ++ pframe += pxmitpriv->frag_len; ++ pframe = (u8 *)RND4((size_t)(pframe)); ++ } ++ } ++ } ++ ++} ++ ++void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe) ++{ ++ /* exclude ICV */ ++ struct arc4context mycontext; ++ int length; ++ u32 keylength; ++ u8 *pframe, *payload, *iv, wepkey[16]; ++ u8 keyindex; ++ struct rx_pkt_attrib *prxattrib = &(((struct recv_frame *)precvframe)->attrib); ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ ++ pframe = (unsigned char *)((struct recv_frame *)precvframe)->rx_data; ++ ++ /* start to decrypt recvframe */ ++ if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) { ++ iv = pframe + prxattrib->hdrlen; ++ keyindex = prxattrib->key_index; ++ keylength = psecuritypriv->dot11DefKeylen[keyindex]; ++ memcpy(&wepkey[0], iv, 3); ++ memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength); ++ length = ((struct recv_frame *)precvframe)->len - prxattrib->hdrlen - prxattrib->iv_len; ++ ++ payload = pframe + prxattrib->iv_len + prxattrib->hdrlen; ++ ++ /* decrypt payload include icv */ ++ arcfour_init(&mycontext, wepkey, 3 + keylength); ++ arcfour_encrypt(&mycontext, payload, payload, length); ++ } ++} ++ ++/* 3 ===== TKIP related ===== */ ++ ++static u32 secmicgetuint32(u8 *p) ++/* Convert from Byte[] to Us3232 in a portable way */ ++{ ++ s32 i; ++ u32 res = 0; ++ ++ for (i = 0; i < 4; i++) ++ res |= ((u32)(*p++)) << (8 * i); ++ ++ return res; ++} ++ ++static void secmicputuint32(u8 *p, u32 val) ++/* Convert from Us3232 to Byte[] in a portable way */ ++{ ++ long i; ++ ++ for (i = 0; i < 4; i++) { ++ *p++ = (u8)(val & 0xff); ++ val >>= 8; ++ } ++ ++} ++ ++static void secmicclear(struct mic_data *pmicdata) ++{ ++/* Reset the state to the empty message. */ ++ ++ pmicdata->L = pmicdata->K0; ++ pmicdata->R = pmicdata->K1; ++ pmicdata->nBytesInM = 0; ++ pmicdata->M = 0; ++ ++} ++ ++void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key) ++{ ++ /* Set the key */ ++ ++ pmicdata->K0 = secmicgetuint32(key); ++ pmicdata->K1 = secmicgetuint32(key + 4); ++ /* and reset the message */ ++ secmicclear(pmicdata); ++ ++} ++ ++void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b) ++{ ++ ++ /* Append the byte to our word-sized buffer */ ++ pmicdata->M |= ((unsigned long)b) << (8 * pmicdata->nBytesInM); ++ pmicdata->nBytesInM++; ++ /* Process the word if it is full. */ ++ if (pmicdata->nBytesInM >= 4) { ++ pmicdata->L ^= pmicdata->M; ++ pmicdata->R ^= ROL32(pmicdata->L, 17); ++ pmicdata->L += pmicdata->R; ++ pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | ((pmicdata->L & 0x00ff00ff) << 8); ++ pmicdata->L += pmicdata->R; ++ pmicdata->R ^= ROL32(pmicdata->L, 3); ++ pmicdata->L += pmicdata->R; ++ pmicdata->R ^= ROR32(pmicdata->L, 2); ++ pmicdata->L += pmicdata->R; ++ /* Clear the buffer */ ++ pmicdata->M = 0; ++ pmicdata->nBytesInM = 0; ++ } ++ ++} ++ ++void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes) ++{ ++ ++ /* This is simple */ ++ while (nbytes > 0) { ++ rtw_secmicappendbyte(pmicdata, *src++); ++ nbytes--; ++ } ++ ++} ++ ++void rtw_secgetmic(struct mic_data *pmicdata, u8 *dst) ++{ ++ ++ /* Append the minimum padding */ ++ rtw_secmicappendbyte(pmicdata, 0x5a); ++ rtw_secmicappendbyte(pmicdata, 0); ++ rtw_secmicappendbyte(pmicdata, 0); ++ rtw_secmicappendbyte(pmicdata, 0); ++ rtw_secmicappendbyte(pmicdata, 0); ++ /* and then zeroes until the length is a multiple of 4 */ ++ while (pmicdata->nBytesInM != 0) ++ rtw_secmicappendbyte(pmicdata, 0); ++ /* The appendByte function has already computed the result. */ ++ secmicputuint32(dst, pmicdata->L); ++ secmicputuint32(dst + 4, pmicdata->R); ++ /* Reset to the empty message. */ ++ secmicclear(pmicdata); ++ ++} ++ ++void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, u8 pri) ++{ ++ struct mic_data micdata; ++ u8 priority[4] = {0x0, 0x0, 0x0, 0x0}; ++ ++ rtw_secmicsetkey(&micdata, key); ++ priority[0] = pri; ++ ++ /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */ ++ if (header[1] & 1) { /* ToDS == 1 */ ++ rtw_secmicappend(&micdata, &header[16], 6); /* DA */ ++ if (header[1] & 2) /* From Ds == 1 */ ++ rtw_secmicappend(&micdata, &header[24], 6); ++ else ++ rtw_secmicappend(&micdata, &header[10], 6); ++ } else { /* ToDS == 0 */ ++ rtw_secmicappend(&micdata, &header[4], 6); /* DA */ ++ if (header[1] & 2) /* From Ds == 1 */ ++ rtw_secmicappend(&micdata, &header[16], 6); ++ else ++ rtw_secmicappend(&micdata, &header[10], 6); ++ } ++ rtw_secmicappend(&micdata, &priority[0], 4); ++ ++ rtw_secmicappend(&micdata, data, data_len); ++ ++ rtw_secgetmic(&micdata, mic_code); ++ ++} ++ ++/* macros for extraction/creation of unsigned char/unsigned short values */ ++#define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15)) ++#define Lo8(v16) ((u8)((v16) & 0x00FF)) ++#define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF)) ++#define Lo16(v32) ((u16)((v32) & 0xFFFF)) ++#define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF)) ++#define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8)) ++ ++/* select the Nth 16-bit word of the temporal key unsigned char array TK[] */ ++#define TK16(N) Mk16(tk[2 * (N) + 1], tk[2 * (N)]) ++ ++/* S-box lookup: 16 bits --> 16 bits */ ++#define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)]) ++ ++/* fixed algorithm "parameters" */ ++#define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */ ++#define TA_SIZE 6 /* 48-bit transmitter address */ ++#define TK_SIZE 16 /* 128-bit temporal key */ ++#define P1K_SIZE 10 /* 80-bit Phase1 key */ ++#define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */ ++ ++/* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */ ++static const unsigned short Sbox1[2][256] = { /* Sbox for hash (can be in ROM) */ ++{ ++ 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, ++ 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, ++ 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, ++ 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, ++ 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, ++ 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, ++ 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, ++ 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, ++ 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, ++ 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, ++ 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, ++ 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, ++ 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, ++ 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, ++ 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, ++ 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, ++ 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, ++ 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, ++ 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, ++ 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, ++ 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, ++ 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, ++ 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, ++ 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, ++ 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, ++ 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, ++ 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, ++ 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, ++ 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, ++ 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, ++ 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, ++ 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, ++ }, ++ ++ { /* second half of table is unsigned char-reversed version of first! */ ++ 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491, ++ 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC, ++ 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB, ++ 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B, ++ 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83, ++ 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A, ++ 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F, ++ 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA, ++ 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B, ++ 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713, ++ 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6, ++ 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85, ++ 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411, ++ 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B, ++ 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1, ++ 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF, ++ 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E, ++ 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6, ++ 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B, ++ 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD, ++ 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8, ++ 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2, ++ 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049, ++ 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810, ++ 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197, ++ 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F, ++ 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C, ++ 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927, ++ 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733, ++ 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5, ++ 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0, ++ 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C, ++ } ++}; ++ ++ /* ++********************************************************************** ++* Routine: Phase 1 -- generate P1K, given TA, TK, IV32 ++* ++* Inputs: ++* tk[] = temporal key [128 bits] ++* ta[] = transmitter's MAC address [ 48 bits] ++* iv32 = upper 32 bits of IV [ 32 bits] ++* Output: ++* p1k[] = Phase 1 key [ 80 bits] ++* ++* Note: ++* This function only needs to be called every 2**16 packets, ++* although in theory it could be called every packet. ++* ++********************************************************************** ++*/ ++static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32) ++{ ++ int i; ++ ++ /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */ ++ p1k[0] = Lo16(iv32); ++ p1k[1] = Hi16(iv32); ++ p1k[2] = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */ ++ p1k[3] = Mk16(ta[3], ta[2]); ++ p1k[4] = Mk16(ta[5], ta[4]); ++ ++ /* Now compute an unbalanced Feistel cipher with 80-bit block */ ++ /* size on the 80-bit block P1K[], using the 128-bit key TK[] */ ++ for (i = 0; i < PHASE1_LOOP_CNT; i++) { /* Each add operation here is mod 2**16 */ ++ p1k[0] += _S_(p1k[4] ^ TK16((i & 1) + 0)); ++ p1k[1] += _S_(p1k[0] ^ TK16((i & 1) + 2)); ++ p1k[2] += _S_(p1k[1] ^ TK16((i & 1) + 4)); ++ p1k[3] += _S_(p1k[2] ^ TK16((i & 1) + 6)); ++ p1k[4] += _S_(p1k[3] ^ TK16((i & 1) + 0)); ++ p1k[4] += (unsigned short)i; /* avoid "slide attacks" */ ++ } ++ ++} ++ ++/* ++********************************************************************** ++* Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16 ++* ++* Inputs: ++* tk[] = Temporal key [128 bits] ++* p1k[] = Phase 1 output key [ 80 bits] ++* iv16 = low 16 bits of IV counter [ 16 bits] ++* Output: ++* rc4key[] = the key used to encrypt the packet [128 bits] ++* ++* Note: ++* The value {TA, IV32, IV16} for Phase1/Phase2 must be unique ++* across all packets using the same key TK value. Then, for a ++* given value of TK[], this TKIP48 construction guarantees that ++* the final RC4KEY value is unique across all packets. ++* ++* Suggested implementation optimization: if PPK[] is "overlaid" ++* appropriately on RC4KEY[], there is no need for the final ++* for loop below that copies the PPK[] result into RC4KEY[]. ++* ++********************************************************************** ++*/ ++static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16) ++{ ++ int i; ++ u16 PPK[6]; /* temporary key for mixing */ ++ ++ /* Note: all adds in the PPK[] equations below are mod 2**16 */ ++ for (i = 0; i < 5; i++) ++ PPK[i] = p1k[i]; /* first, copy P1K to PPK */ ++ PPK[5] = p1k[4] + iv16; /* next, add in IV16 */ ++ ++ /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */ ++ PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */ ++ PPK[1] += _S_(PPK[0] ^ TK16(1)); ++ PPK[2] += _S_(PPK[1] ^ TK16(2)); ++ PPK[3] += _S_(PPK[2] ^ TK16(3)); ++ PPK[4] += _S_(PPK[3] ^ TK16(4)); ++ PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */ ++ ++ /* Final sweep: bijective, "linear". Rotates kill LSB correlations */ ++ PPK[0] += RotR1(PPK[5] ^ TK16(6)); ++ PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */ ++ PPK[2] += RotR1(PPK[1]); ++ PPK[3] += RotR1(PPK[2]); ++ PPK[4] += RotR1(PPK[3]); ++ PPK[5] += RotR1(PPK[4]); ++ /* Note: At this point, for a given key TK[0..15], the 96-bit output */ ++ /* value PPK[0..5] is guaranteed to be unique, as a function */ ++ /* of the 96-bit "input" value {TA, IV32, IV16}. That is, P1K */ ++ /* is now a keyed permutation of {TA, IV32, IV16}. */ ++ ++ /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */ ++ rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV */ ++ rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */ ++ rc4key[2] = Lo8(iv16); ++ rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1); ++ ++ /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */ ++ for (i = 0; i < 6; i++) { ++ rc4key[4 + 2 * i] = Lo8(PPK[i]); ++ rc4key[5 + 2 * i] = Hi8(PPK[i]); ++ } ++ ++} ++ ++/* The hlen isn't include the IV */ ++u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe) ++{ /* exclude ICV */ ++ u16 pnl; ++ u32 pnh; ++ u8 rc4key[16]; ++ u8 ttkey[16]; ++ union { ++ __le32 f0; ++ u8 f1[4]; ++ } crc; ++ u8 hw_hdr_offset = 0; ++ struct arc4context mycontext; ++ int curfragnum, length; ++ ++ u8 *pframe, *payload, *iv, *prwskey; ++ union pn48 dot11txpn; ++ struct sta_info *stainfo; ++ struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ u32 res = _SUCCESS; ++ ++ if (!((struct xmit_frame *)pxmitframe)->buf_addr) ++ return _FAIL; ++ ++ hw_hdr_offset = TXDESC_SIZE + ++ (((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ); ++ pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset; ++ /* 4 start to encrypt each fragment */ ++ if (pattrib->encrypt == _TKIP_) { ++ if (pattrib->psta) ++ stainfo = pattrib->psta; ++ else ++ stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]); ++ ++ if (stainfo) { ++ if (is_multicast_ether_addr(pattrib->ra)) ++ prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; ++ else ++ prwskey = &stainfo->dot118021x_UncstKey.skey[0]; ++ ++ for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { ++ iv = pframe + pattrib->hdrlen; ++ payload = pframe + pattrib->iv_len + pattrib->hdrlen; ++ ++ GET_TKIP_PN(iv, dot11txpn); ++ ++ pnl = (u16)(dot11txpn.val); ++ pnh = (u32)(dot11txpn.val >> 16); ++ phase1((u16 *)&ttkey[0], prwskey, &pattrib->ta[0], pnh); ++ phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], pnl); ++ ++ if ((curfragnum + 1) == pattrib->nr_frags) { /* 4 the last fragment */ ++ length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; ++ crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length)); ++ ++ arcfour_init(&mycontext, rc4key, 16); ++ arcfour_encrypt(&mycontext, payload, payload, length); ++ arcfour_encrypt(&mycontext, payload + length, crc.f1, 4); ++ } else { ++ length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; ++ crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length)); ++ ++ arcfour_init(&mycontext, rc4key, 16); ++ arcfour_encrypt(&mycontext, payload, payload, length); ++ arcfour_encrypt(&mycontext, payload + length, crc.f1, 4); ++ ++ pframe += pxmitpriv->frag_len; ++ pframe = (u8 *)RND4((size_t)(pframe)); ++ } ++ } ++ } else { ++ res = _FAIL; ++ } ++ } ++ ++ return res; ++} ++ ++/* The hlen isn't include the IV */ ++u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe) ++{ /* exclude ICV */ ++ u16 pnl; ++ u32 pnh; ++ u8 rc4key[16]; ++ u8 ttkey[16]; ++ union { ++ __le32 f0; ++ u8 f1[4]; ++ } crc; ++ struct arc4context mycontext; ++ int length; ++ ++ u8 *pframe, *payload, *iv, *prwskey; ++ union pn48 dot11txpn; ++ struct sta_info *stainfo; ++ struct rx_pkt_attrib *prxattrib = &((struct recv_frame *)precvframe)->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ u32 res = _SUCCESS; ++ ++ pframe = (unsigned char *)((struct recv_frame *)precvframe)->rx_data; ++ ++ /* 4 start to decrypt recvframe */ ++ if (prxattrib->encrypt == _TKIP_) { ++ stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]); ++ if (stainfo) { ++ if (is_multicast_ether_addr(prxattrib->ra)) { ++ if (!psecuritypriv->binstallGrpkey) { ++ res = _FAIL; ++ DBG_88E("%s:rx bc/mc packets, but didn't install group key!!!!!!!!!!\n", __func__); ++ goto exit; ++ } ++ prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey; ++ } else { ++ prwskey = &stainfo->dot118021x_UncstKey.skey[0]; ++ } ++ ++ iv = pframe + prxattrib->hdrlen; ++ payload = pframe + prxattrib->iv_len + prxattrib->hdrlen; ++ length = ((struct recv_frame *)precvframe)->len - prxattrib->hdrlen - prxattrib->iv_len; ++ ++ GET_TKIP_PN(iv, dot11txpn); ++ ++ pnl = (u16)(dot11txpn.val); ++ pnh = (u32)(dot11txpn.val >> 16); ++ ++ phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], pnh); ++ phase2(&rc4key[0], prwskey, (unsigned short *)&ttkey[0], pnl); ++ ++ /* 4 decrypt payload include icv */ ++ ++ arcfour_init(&mycontext, rc4key, 16); ++ arcfour_encrypt(&mycontext, payload, payload, length); ++ ++ crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length)); ++ ++ if (crc.f1[3] != payload[length - 1] || ++ crc.f1[2] != payload[length - 2] || ++ crc.f1[1] != payload[length - 3] || ++ crc.f1[0] != payload[length - 4]) ++ res = _FAIL; ++ } else { ++ res = _FAIL; ++ } ++ } ++ ++exit: ++ return res; ++} ++ ++/* 3 ===== AES related ===== */ ++ ++#define MAX_MSG_SIZE 2048 ++/*****************************/ ++/******** SBOX Table *********/ ++/*****************************/ ++ ++static u8 sbox_table[256] = { ++ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, ++ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, ++ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, ++ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, ++ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, ++ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, ++ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, ++ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, ++ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, ++ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, ++ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, ++ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, ++ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, ++ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, ++ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, ++ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, ++ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, ++ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, ++ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, ++ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, ++ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, ++ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, ++ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, ++ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, ++ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, ++ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, ++ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, ++ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, ++ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, ++ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, ++ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, ++ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ++}; ++ ++/*****************************/ ++/**** Function Prototypes ****/ ++/*****************************/ ++ ++static void bitwise_xor(u8 *ina, u8 *inb, u8 *out); ++static void construct_mic_iv(u8 *mic_header1, int qc_exists, int a4_exists, u8 *mpdu, uint payload_length, u8 *pn_vector); ++static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu); ++static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int qc_exists); ++static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, u8 *mpdu, u8 *pn_vector, int c); ++static void xor_128(u8 *a, u8 *b, u8 *out); ++static void xor_32(u8 *a, u8 *b, u8 *out); ++static u8 sbox(u8 a); ++static void next_key(u8 *key, int round); ++static void byte_sub(u8 *in, u8 *out); ++static void shift_row(u8 *in, u8 *out); ++static void mix_column(u8 *in, u8 *out); ++static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext); ++ ++/****************************************/ ++/* aes128k128d() */ ++/* Performs a 128 bit AES encrypt with */ ++/* 128 bit data. */ ++/****************************************/ ++static void xor_128(u8 *a, u8 *b, u8 *out) ++{ ++ int i; ++ ++ for (i = 0; i < 16; i++) ++ out[i] = a[i] ^ b[i]; ++ ++} ++ ++static void xor_32(u8 *a, u8 *b, u8 *out) ++{ ++ int i; ++ ++ for (i = 0; i < 4; i++) ++ out[i] = a[i] ^ b[i]; ++ ++} ++ ++static u8 sbox(u8 a) ++{ ++ return sbox_table[(int)a]; ++} ++ ++static void next_key(u8 *key, int round) ++{ ++ u8 rcon; ++ u8 sbox_key[4]; ++ u8 rcon_table[12] = { ++ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, ++ 0x1b, 0x36, 0x36, 0x36 ++ }; ++ ++ sbox_key[0] = sbox(key[13]); ++ sbox_key[1] = sbox(key[14]); ++ sbox_key[2] = sbox(key[15]); ++ sbox_key[3] = sbox(key[12]); ++ ++ rcon = rcon_table[round]; ++ ++ xor_32(&key[0], sbox_key, &key[0]); ++ key[0] = key[0] ^ rcon; ++ ++ xor_32(&key[4], &key[0], &key[4]); ++ xor_32(&key[8], &key[4], &key[8]); ++ xor_32(&key[12], &key[8], &key[12]); ++ ++} ++ ++static void byte_sub(u8 *in, u8 *out) ++{ ++ int i; ++ ++ for (i = 0; i < 16; i++) ++ out[i] = sbox(in[i]); ++ ++} ++ ++static void shift_row(u8 *in, u8 *out) ++{ ++ ++ out[0] = in[0]; ++ out[1] = in[5]; ++ out[2] = in[10]; ++ out[3] = in[15]; ++ out[4] = in[4]; ++ out[5] = in[9]; ++ out[6] = in[14]; ++ out[7] = in[3]; ++ out[8] = in[8]; ++ out[9] = in[13]; ++ out[10] = in[2]; ++ out[11] = in[7]; ++ out[12] = in[12]; ++ out[13] = in[1]; ++ out[14] = in[6]; ++ out[15] = in[11]; ++ ++} ++ ++static void mix_column(u8 *in, u8 *out) ++{ ++ int i; ++ u8 add1b[4]; ++ u8 add1bf7[4]; ++ u8 rotl[4]; ++ u8 swap_halfs[4]; ++ u8 andf7[4]; ++ u8 rotr[4]; ++ u8 temp[4]; ++ u8 tempb[4]; ++ ++ for (i = 0 ; i < 4; i++) { ++ if ((in[i] & 0x80) == 0x80) ++ add1b[i] = 0x1b; ++ else ++ add1b[i] = 0x00; ++ } ++ ++ swap_halfs[0] = in[2]; /* Swap halves */ ++ swap_halfs[1] = in[3]; ++ swap_halfs[2] = in[0]; ++ swap_halfs[3] = in[1]; ++ ++ rotl[0] = in[3]; /* Rotate left 8 bits */ ++ rotl[1] = in[0]; ++ rotl[2] = in[1]; ++ rotl[3] = in[2]; ++ ++ andf7[0] = in[0] & 0x7f; ++ andf7[1] = in[1] & 0x7f; ++ andf7[2] = in[2] & 0x7f; ++ andf7[3] = in[3] & 0x7f; ++ ++ for (i = 3; i > 0; i--) { /* logical shift left 1 bit */ ++ andf7[i] = andf7[i] << 1; ++ if ((andf7[i - 1] & 0x80) == 0x80) ++ andf7[i] = (andf7[i] | 0x01); ++ } ++ andf7[0] = andf7[0] << 1; ++ andf7[0] = andf7[0] & 0xfe; ++ ++ xor_32(add1b, andf7, add1bf7); ++ ++ xor_32(in, add1bf7, rotr); ++ ++ temp[0] = rotr[0]; /* Rotate right 8 bits */ ++ rotr[0] = rotr[1]; ++ rotr[1] = rotr[2]; ++ rotr[2] = rotr[3]; ++ rotr[3] = temp[0]; ++ ++ xor_32(add1bf7, rotr, temp); ++ xor_32(swap_halfs, rotl, tempb); ++ xor_32(temp, tempb, out); ++ ++} ++ ++static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext) ++{ ++ int round; ++ int i; ++ u8 intermediatea[16]; ++ u8 intermediateb[16]; ++ u8 round_key[16]; ++ ++ for (i = 0; i < 16; i++) ++ round_key[i] = key[i]; ++ for (round = 0; round < 11; round++) { ++ if (round == 0) { ++ xor_128(round_key, data, ciphertext); ++ next_key(round_key, round); ++ } else if (round == 10) { ++ byte_sub(ciphertext, intermediatea); ++ shift_row(intermediatea, intermediateb); ++ xor_128(intermediateb, round_key, ciphertext); ++ } else { /* 1 - 9 */ ++ byte_sub(ciphertext, intermediatea); ++ shift_row(intermediatea, intermediateb); ++ mix_column(&intermediateb[0], &intermediatea[0]); ++ mix_column(&intermediateb[4], &intermediatea[4]); ++ mix_column(&intermediateb[8], &intermediatea[8]); ++ mix_column(&intermediateb[12], &intermediatea[12]); ++ xor_128(intermediatea, round_key, ciphertext); ++ next_key(round_key, round); ++ } ++ } ++ ++} ++ ++/************************************************/ ++/* construct_mic_iv() */ ++/* Builds the MIC IV from header fields and PN */ ++/************************************************/ ++static void construct_mic_iv(u8 *mic_iv, int qc_exists, int a4_exists, u8 *mpdu, ++ uint payload_length, u8 *pn_vector) ++{ ++ int i; ++ ++ mic_iv[0] = 0x59; ++ if (qc_exists && a4_exists) ++ mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */ ++ if (qc_exists && !a4_exists) ++ mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */ ++ if (!qc_exists) ++ mic_iv[1] = 0x00; ++ for (i = 2; i < 8; i++) ++ mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */ ++ for (i = 8; i < 14; i++) ++ mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */ ++ mic_iv[14] = (unsigned char)(payload_length / 256); ++ mic_iv[15] = (unsigned char)(payload_length % 256); ++ ++} ++ ++/************************************************/ ++/* construct_mic_header1() */ ++/* Builds the first MIC header block from */ ++/* header fields. */ ++/************************************************/ ++static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu) ++{ ++ ++ mic_header1[0] = (u8)((header_length - 2) / 256); ++ mic_header1[1] = (u8)((header_length - 2) % 256); ++ mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */ ++ mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */ ++ mic_header1[4] = mpdu[4]; /* A1 */ ++ mic_header1[5] = mpdu[5]; ++ mic_header1[6] = mpdu[6]; ++ mic_header1[7] = mpdu[7]; ++ mic_header1[8] = mpdu[8]; ++ mic_header1[9] = mpdu[9]; ++ mic_header1[10] = mpdu[10]; /* A2 */ ++ mic_header1[11] = mpdu[11]; ++ mic_header1[12] = mpdu[12]; ++ mic_header1[13] = mpdu[13]; ++ mic_header1[14] = mpdu[14]; ++ mic_header1[15] = mpdu[15]; ++ ++} ++ ++/************************************************/ ++/* construct_mic_header2() */ ++/* Builds the last MIC header block from */ ++/* header fields. */ ++/************************************************/ ++static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int qc_exists) ++{ ++ int i; ++ ++ for (i = 0; i < 16; i++) ++ mic_header2[i] = 0x00; ++ ++ mic_header2[0] = mpdu[16]; /* A3 */ ++ mic_header2[1] = mpdu[17]; ++ mic_header2[2] = mpdu[18]; ++ mic_header2[3] = mpdu[19]; ++ mic_header2[4] = mpdu[20]; ++ mic_header2[5] = mpdu[21]; ++ ++ mic_header2[6] = 0x00; ++ mic_header2[7] = 0x00; /* mpdu[23]; */ ++ ++ if (!qc_exists && a4_exists) { ++ for (i = 0; i < 6; i++) ++ mic_header2[8 + i] = mpdu[24 + i]; /* A4 */ ++ } ++ ++ if (qc_exists && !a4_exists) { ++ mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */ ++ mic_header2[9] = mpdu[25] & 0x00; ++ } ++ ++ if (qc_exists && a4_exists) { ++ for (i = 0; i < 6; i++) ++ mic_header2[8 + i] = mpdu[24 + i]; /* A4 */ ++ ++ mic_header2[14] = mpdu[30] & 0x0f; ++ mic_header2[15] = mpdu[31] & 0x00; ++ } ++ ++} ++ ++/************************************************/ ++/* construct_mic_header2() */ ++/* Builds the last MIC header block from */ ++/* header fields. */ ++/************************************************/ ++static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, u8 *mpdu, u8 *pn_vector, int c) ++{ ++ int i; ++ ++ for (i = 0; i < 16; i++) ++ ctr_preload[i] = 0x00; ++ i = 0; ++ ++ ctr_preload[0] = 0x01; /* flag */ ++ if (qc_exists && a4_exists) ++ ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */ ++ if (qc_exists && !a4_exists) ++ ctr_preload[1] = mpdu[24] & 0x0f; ++ ++ for (i = 2; i < 8; i++) ++ ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */ ++ for (i = 8; i < 14; i++) ++ ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */ ++ ctr_preload[14] = (unsigned char)(c / 256); /* Ctr */ ++ ctr_preload[15] = (unsigned char)(c % 256); ++ ++} ++ ++/************************************/ ++/* bitwise_xor() */ ++/* A 128 bit, bitwise exclusive or */ ++/************************************/ ++static void bitwise_xor(u8 *ina, u8 *inb, u8 *out) ++{ ++ int i; ++ ++ for (i = 0; i < 16; i++) ++ out[i] = ina[i] ^ inb[i]; ++ ++} ++ ++static int aes_cipher(u8 *key, uint hdrlen, u8 *pframe, uint plen) ++{ ++ uint qc_exists, a4_exists, i, j, payload_remainder, ++ num_blocks, payload_index; ++ ++ u8 pn_vector[6]; ++ u8 mic_iv[16]; ++ u8 mic_header1[16]; ++ u8 mic_header2[16]; ++ u8 ctr_preload[16]; ++ ++ /* Intermediate Buffers */ ++ u8 chain_buffer[16]; ++ u8 aes_out[16]; ++ u8 padded_buffer[16]; ++ u8 mic[8]; ++ uint frtype = GetFrameType(pframe); ++ uint frsubtype = GetFrameSubType(pframe); ++ ++ frsubtype = frsubtype >> 4; ++ ++ memset((void *)mic_iv, 0, 16); ++ memset((void *)mic_header1, 0, 16); ++ memset((void *)mic_header2, 0, 16); ++ memset((void *)ctr_preload, 0, 16); ++ memset((void *)chain_buffer, 0, 16); ++ memset((void *)aes_out, 0, 16); ++ memset((void *)padded_buffer, 0, 16); ++ ++ if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN)) ++ a4_exists = 0; ++ else ++ a4_exists = 1; ++ ++ if ((frtype == WIFI_DATA_CFACK) || (frtype == WIFI_DATA_CFPOLL) || (frtype == WIFI_DATA_CFACKPOLL)) { ++ qc_exists = 1; ++ if (hdrlen != WLAN_HDR_A3_QOS_LEN) ++ hdrlen += 2; ++ } else if ((frsubtype == 0x08) || (frsubtype == 0x09) || (frsubtype == 0x0a) || (frsubtype == 0x0b)) { ++ if (hdrlen != WLAN_HDR_A3_QOS_LEN) ++ hdrlen += 2; ++ qc_exists = 1; ++ } else { ++ qc_exists = 0; ++ } ++ ++ pn_vector[0] = pframe[hdrlen]; ++ pn_vector[1] = pframe[hdrlen + 1]; ++ pn_vector[2] = pframe[hdrlen + 4]; ++ pn_vector[3] = pframe[hdrlen + 5]; ++ pn_vector[4] = pframe[hdrlen + 6]; ++ pn_vector[5] = pframe[hdrlen + 7]; ++ ++ construct_mic_iv(mic_iv, qc_exists, a4_exists, pframe, plen, pn_vector); ++ ++ construct_mic_header1(mic_header1, hdrlen, pframe); ++ construct_mic_header2(mic_header2, pframe, a4_exists, qc_exists); ++ ++ payload_remainder = plen % 16; ++ num_blocks = plen / 16; ++ ++ /* Find start of payload */ ++ payload_index = (hdrlen + 8); ++ ++ /* Calculate MIC */ ++ aes128k128d(key, mic_iv, aes_out); ++ bitwise_xor(aes_out, mic_header1, chain_buffer); ++ aes128k128d(key, chain_buffer, aes_out); ++ bitwise_xor(aes_out, mic_header2, chain_buffer); ++ aes128k128d(key, chain_buffer, aes_out); ++ ++ for (i = 0; i < num_blocks; i++) { ++ bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);/* bitwise_xor(aes_out, &message[payload_index], chain_buffer); */ ++ ++ payload_index += 16; ++ aes128k128d(key, chain_buffer, aes_out); ++ } ++ ++ /* Add on the final payload block if it needs padding */ ++ if (payload_remainder > 0) { ++ for (j = 0; j < 16; j++) ++ padded_buffer[j] = 0x00; ++ for (j = 0; j < payload_remainder; j++) ++ padded_buffer[j] = pframe[payload_index++];/* padded_buffer[j] = message[payload_index++]; */ ++ bitwise_xor(aes_out, padded_buffer, chain_buffer); ++ aes128k128d(key, chain_buffer, aes_out); ++ } ++ ++ for (j = 0; j < 8; j++) ++ mic[j] = aes_out[j]; ++ ++ /* Insert MIC into payload */ ++ for (j = 0; j < 8; j++) ++ pframe[payload_index + j] = mic[j]; /* message[payload_index+j] = mic[j]; */ ++ ++ payload_index = hdrlen + 8; ++ for (i = 0; i < num_blocks; i++) { ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, i + 1); ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, &pframe[payload_index], chain_buffer); ++ for (j = 0; j < 16; j++) ++ pframe[payload_index++] = chain_buffer[j]; ++ } ++ ++ if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/ ++ /* encrypt it and copy the unpadded part back */ ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, num_blocks + 1); ++ ++ for (j = 0; j < 16; j++) ++ padded_buffer[j] = 0x00; ++ for (j = 0; j < payload_remainder; j++) ++ padded_buffer[j] = pframe[payload_index + j]; ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, padded_buffer, chain_buffer); ++ for (j = 0; j < payload_remainder; j++) ++ pframe[payload_index++] = chain_buffer[j]; ++ } ++ /* Encrypt the MIC */ ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, 0); ++ ++ for (j = 0; j < 16; j++) ++ padded_buffer[j] = 0x00; ++ for (j = 0; j < 8; j++) ++ padded_buffer[j] = pframe[j + hdrlen + 8 + plen]; ++ ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, padded_buffer, chain_buffer); ++ for (j = 0; j < 8; j++) ++ pframe[payload_index++] = chain_buffer[j]; ++ ++ return _SUCCESS; ++} ++ ++u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe) ++{ /* exclude ICV */ ++ ++ /*static*/ ++/* unsigned char message[MAX_MSG_SIZE]; */ ++ ++ /* Intermediate Buffers */ ++ int curfragnum, length; ++ u8 *pframe, *prwskey; /* *payload,*iv */ ++ u8 hw_hdr_offset = 0; ++ struct sta_info *stainfo; ++ struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++/* uint offset = 0; */ ++ u32 res = _SUCCESS; ++ ++ if (!((struct xmit_frame *)pxmitframe)->buf_addr) ++ return _FAIL; ++ ++ hw_hdr_offset = TXDESC_SIZE + ++ (((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ); ++ ++ pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset; ++ ++ /* 4 start to encrypt each fragment */ ++ if (pattrib->encrypt == _AES_) { ++ if (pattrib->psta) ++ stainfo = pattrib->psta; ++ else ++ stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]); ++ ++ if (stainfo) { ++ if (is_multicast_ether_addr(pattrib->ra)) ++ prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; ++ else ++ prwskey = &stainfo->dot118021x_UncstKey.skey[0]; ++ for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { ++ if ((curfragnum + 1) == pattrib->nr_frags) { /* 4 the last fragment */ ++ length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; ++ ++ aes_cipher(prwskey, pattrib->hdrlen, pframe, length); ++ } else { ++ length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; ++ ++ aes_cipher(prwskey, pattrib->hdrlen, pframe, length); ++ pframe += pxmitpriv->frag_len; ++ pframe = (u8 *)RND4((size_t)(pframe)); ++ } ++ } ++ } else { ++ res = _FAIL; ++ } ++ } ++ ++ return res; ++} ++ ++static int aes_decipher(u8 *key, uint hdrlen, ++ u8 *pframe, uint plen) ++{ ++ static u8 message[MAX_MSG_SIZE]; ++ uint qc_exists, a4_exists, i, j, payload_remainder, ++ num_blocks, payload_index; ++ int res = _SUCCESS; ++ u8 pn_vector[6]; ++ u8 mic_iv[16]; ++ u8 mic_header1[16]; ++ u8 mic_header2[16]; ++ u8 ctr_preload[16]; ++ ++ /* Intermediate Buffers */ ++ u8 chain_buffer[16]; ++ u8 aes_out[16]; ++ u8 padded_buffer[16]; ++ u8 mic[8]; ++ ++/* uint offset = 0; */ ++ uint frtype = GetFrameType(pframe); ++ uint frsubtype = GetFrameSubType(pframe); ++ ++ frsubtype = frsubtype >> 4; ++ ++ memset((void *)mic_iv, 0, 16); ++ memset((void *)mic_header1, 0, 16); ++ memset((void *)mic_header2, 0, 16); ++ memset((void *)ctr_preload, 0, 16); ++ memset((void *)chain_buffer, 0, 16); ++ memset((void *)aes_out, 0, 16); ++ memset((void *)padded_buffer, 0, 16); ++ ++ /* start to decrypt the payload */ ++ ++ num_blocks = (plen - 8) / 16; /* plen including llc, payload_length and mic) */ ++ ++ payload_remainder = (plen - 8) % 16; ++ ++ pn_vector[0] = pframe[hdrlen]; ++ pn_vector[1] = pframe[hdrlen + 1]; ++ pn_vector[2] = pframe[hdrlen + 4]; ++ pn_vector[3] = pframe[hdrlen + 5]; ++ pn_vector[4] = pframe[hdrlen + 6]; ++ pn_vector[5] = pframe[hdrlen + 7]; ++ ++ if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN)) ++ a4_exists = 0; ++ else ++ a4_exists = 1; ++ ++ if ((frtype == WIFI_DATA_CFACK) || (frtype == WIFI_DATA_CFPOLL) || ++ (frtype == WIFI_DATA_CFACKPOLL)) { ++ qc_exists = 1; ++ if (hdrlen != WLAN_HDR_A3_QOS_LEN) ++ hdrlen += 2; ++ } else if ((frsubtype == 0x08) || (frsubtype == 0x09) || ++ (frsubtype == 0x0a) || (frsubtype == 0x0b)) { ++ if (hdrlen != WLAN_HDR_A3_QOS_LEN) ++ hdrlen += 2; ++ qc_exists = 1; ++ } else { ++ qc_exists = 0; ++ } ++ ++ /* now, decrypt pframe with hdrlen offset and plen long */ ++ ++ payload_index = hdrlen + 8; /* 8 is for extiv */ ++ ++ for (i = 0; i < num_blocks; i++) { ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, i + 1); ++ ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, &pframe[payload_index], chain_buffer); ++ ++ for (j = 0; j < 16; j++) ++ pframe[payload_index++] = chain_buffer[j]; ++ } ++ ++ if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/ ++ /* encrypt it and copy the unpadded part back */ ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, num_blocks + 1); ++ ++ for (j = 0; j < 16; j++) ++ padded_buffer[j] = 0x00; ++ for (j = 0; j < payload_remainder; j++) ++ padded_buffer[j] = pframe[payload_index + j]; ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, padded_buffer, chain_buffer); ++ for (j = 0; j < payload_remainder; j++) ++ pframe[payload_index++] = chain_buffer[j]; ++ } ++ ++ /* start to calculate the mic */ ++ if ((hdrlen + plen + 8) <= MAX_MSG_SIZE) ++ memcpy(message, pframe, (hdrlen + plen + 8)); /* 8 is for ext iv len */ ++ ++ pn_vector[0] = pframe[hdrlen]; ++ pn_vector[1] = pframe[hdrlen + 1]; ++ pn_vector[2] = pframe[hdrlen + 4]; ++ pn_vector[3] = pframe[hdrlen + 5]; ++ pn_vector[4] = pframe[hdrlen + 6]; ++ pn_vector[5] = pframe[hdrlen + 7]; ++ construct_mic_iv(mic_iv, qc_exists, a4_exists, message, plen - 8, pn_vector); ++ ++ construct_mic_header1(mic_header1, hdrlen, message); ++ construct_mic_header2(mic_header2, message, a4_exists, qc_exists); ++ ++ payload_remainder = (plen - 8) % 16; ++ num_blocks = (plen - 8) / 16; ++ ++ /* Find start of payload */ ++ payload_index = (hdrlen + 8); ++ ++ /* Calculate MIC */ ++ aes128k128d(key, mic_iv, aes_out); ++ bitwise_xor(aes_out, mic_header1, chain_buffer); ++ aes128k128d(key, chain_buffer, aes_out); ++ bitwise_xor(aes_out, mic_header2, chain_buffer); ++ aes128k128d(key, chain_buffer, aes_out); ++ ++ for (i = 0; i < num_blocks; i++) { ++ bitwise_xor(aes_out, &message[payload_index], chain_buffer); ++ ++ payload_index += 16; ++ aes128k128d(key, chain_buffer, aes_out); ++ } ++ ++ /* Add on the final payload block if it needs padding */ ++ if (payload_remainder > 0) { ++ for (j = 0; j < 16; j++) ++ padded_buffer[j] = 0x00; ++ for (j = 0; j < payload_remainder; j++) ++ padded_buffer[j] = message[payload_index++]; ++ bitwise_xor(aes_out, padded_buffer, chain_buffer); ++ aes128k128d(key, chain_buffer, aes_out); ++ } ++ ++ for (j = 0 ; j < 8; j++) ++ mic[j] = aes_out[j]; ++ ++ /* Insert MIC into payload */ ++ for (j = 0; j < 8; j++) ++ message[payload_index + j] = mic[j]; ++ ++ payload_index = hdrlen + 8; ++ for (i = 0; i < num_blocks; i++) { ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, i + 1); ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, &message[payload_index], chain_buffer); ++ for (j = 0; j < 16; j++) ++ message[payload_index++] = chain_buffer[j]; ++ } ++ ++ if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/ ++ /* encrypt it and copy the unpadded part back */ ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, num_blocks + 1); ++ ++ for (j = 0; j < 16; j++) ++ padded_buffer[j] = 0x00; ++ for (j = 0; j < payload_remainder; j++) ++ padded_buffer[j] = message[payload_index + j]; ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, padded_buffer, chain_buffer); ++ for (j = 0; j < payload_remainder; j++) ++ message[payload_index++] = chain_buffer[j]; ++ } ++ ++ /* Encrypt the MIC */ ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, 0); ++ ++ for (j = 0; j < 16; j++) ++ padded_buffer[j] = 0x00; ++ for (j = 0; j < 8; j++) ++ padded_buffer[j] = message[j + hdrlen + 8 + plen - 8]; ++ ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, padded_buffer, chain_buffer); ++ for (j = 0; j < 8; j++) ++ message[payload_index++] = chain_buffer[j]; ++ ++ /* compare the mic */ ++ for (i = 0; i < 8; i++) { ++ if (pframe[hdrlen + 8 + plen - 8 + i] != message[hdrlen + 8 + plen - 8 + i]) { ++ DBG_88E("aes_decipher:mic check error mic[%d]: pframe(%x)!=message(%x)\n", ++ i, pframe[hdrlen + 8 + plen - 8 + i], message[hdrlen + 8 + plen - 8 + i]); ++ res = _FAIL; ++ } ++ } ++ ++ return res; ++} ++ ++u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe) ++{ /* exclude ICV */ ++ /* Intermediate Buffers */ ++ int length; ++ u8 *pframe, *prwskey; /* *payload,*iv */ ++ struct sta_info *stainfo; ++ struct rx_pkt_attrib *prxattrib = &((struct recv_frame *)precvframe)->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ u32 res = _SUCCESS; ++ ++ pframe = (unsigned char *)((struct recv_frame *)precvframe)->rx_data; ++ /* 4 start to encrypt each fragment */ ++ if (prxattrib->encrypt == _AES_) { ++ stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]); ++ if (stainfo) { ++ if (is_multicast_ether_addr(prxattrib->ra)) { ++ /* in concurrent we should use sw descrypt in group key, so we remove this message */ ++ if (!psecuritypriv->binstallGrpkey) { ++ res = _FAIL; ++ DBG_88E("%s:rx bc/mc packets, but didn't install group key!!!!!!!!!!\n", __func__); ++ goto exit; ++ } ++ prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey; ++ if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) { ++ DBG_88E("not match packet_index=%d, install_index=%d\n", ++ prxattrib->key_index, psecuritypriv->dot118021XGrpKeyid); ++ res = _FAIL; ++ goto exit; ++ } ++ } else { ++ prwskey = &stainfo->dot118021x_UncstKey.skey[0]; ++ } ++ length = ((struct recv_frame *)precvframe)->len - prxattrib->hdrlen - prxattrib->iv_len; ++ res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length); ++ } else { ++ res = _FAIL; ++ } ++ } ++ ++exit: ++ return res; ++} ++ ++/* AES tables*/ ++const u32 Te0[256] = { ++ 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, ++ 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, ++ 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, ++ 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, ++ 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, ++ 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, ++ 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, ++ 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, ++ 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, ++ 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, ++ 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, ++ 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, ++ 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, ++ 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, ++ 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, ++ 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, ++ 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, ++ 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, ++ 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, ++ 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, ++ 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, ++ 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, ++ 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, ++ 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, ++ 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, ++ 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, ++ 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, ++ 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, ++ 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, ++ 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, ++ 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, ++ 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, ++ 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, ++ 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, ++ 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, ++ 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, ++ 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, ++ 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, ++ 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, ++ 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, ++ 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, ++ 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, ++ 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, ++ 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, ++ 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, ++ 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, ++ 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, ++ 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, ++ 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, ++ 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, ++ 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, ++ 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, ++ 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, ++ 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, ++ 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, ++ 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, ++ 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, ++ 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, ++ 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, ++ 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, ++ 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, ++ 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, ++ 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, ++ 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, ++}; ++ ++const u32 Td0[256] = { ++ 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, ++ 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, ++ 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, ++ 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, ++ 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, ++ 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, ++ 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, ++ 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, ++ 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, ++ 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, ++ 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, ++ 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, ++ 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, ++ 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, ++ 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, ++ 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, ++ 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, ++ 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, ++ 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, ++ 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, ++ 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, ++ 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, ++ 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, ++ 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, ++ 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, ++ 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, ++ 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, ++ 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, ++ 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, ++ 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, ++ 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, ++ 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, ++ 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, ++ 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, ++ 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, ++ 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, ++ 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, ++ 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, ++ 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, ++ 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, ++ 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, ++ 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, ++ 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, ++ 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, ++ 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, ++ 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, ++ 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, ++ 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, ++ 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, ++ 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, ++ 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, ++ 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, ++ 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, ++ 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, ++ 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, ++ 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, ++ 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, ++ 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, ++ 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, ++ 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, ++ 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, ++ 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, ++ 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, ++ 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, ++}; ++ ++const u8 Td4s[256] = { ++ 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, ++ 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, ++ 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, ++ 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, ++ 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, ++ 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, ++ 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, ++ 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, ++ 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, ++ 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, ++ 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, ++ 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, ++ 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, ++ 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, ++ 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, ++ 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, ++ 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, ++ 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, ++ 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, ++ 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, ++ 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, ++ 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, ++ 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, ++ 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, ++ 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, ++ 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, ++ 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, ++ 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, ++ 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, ++ 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, ++ 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, ++ 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, ++}; ++const u8 rcons[] = { ++ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 ++ /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ ++}; ++ ++/** ++ * Expand the cipher key into the encryption key schedule. ++ * ++ * @return the number of rounds for the given cipher key size. ++ */ ++#define ROUND(i, d, s) \ ++do { \ ++ d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \ ++ d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \ ++ d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \ ++ d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]; \ ++} while (0); ++ ++/** ++ * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC) ++ * @key: 128-bit key for the hash operation ++ * @data: Data buffer for which a MAC is determined ++ * @data_len: Length of data buffer in bytes ++ * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) ++ * Returns: 0 on success, -1 on failure ++ * ++ * This is a mode for using block cipher (AES in this case) for authentication. ++ * OMAC1 was standardized with the name CMAC by NIST in a Special Publication ++ * (SP) 800-38B. ++ */ ++void rtw_use_tkipkey_handler(void *FunctionContext) ++{ ++ struct adapter *padapter = (struct adapter *)FunctionContext; ++ ++ padapter->securitypriv.busetkipkey = true; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_sreset.c b/drivers/staging/r8188eu/core/rtw_sreset.c +new file mode 100644 +index 000000000000..c831033d20a9 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_sreset.c +@@ -0,0 +1,62 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#include "../include/rtw_sreset.h" ++ ++void sreset_init_value(struct adapter *padapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct sreset_priv *psrtpriv = &pHalData->srestpriv; ++ ++ _rtw_mutex_init(&psrtpriv->silentreset_mutex); ++ psrtpriv->silent_reset_inprogress = false; ++ psrtpriv->wifi_error_status = WIFI_STATUS_SUCCESS; ++ psrtpriv->last_tx_time = 0; ++ psrtpriv->last_tx_complete_time = 0; ++} ++void sreset_reset_value(struct adapter *padapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct sreset_priv *psrtpriv = &pHalData->srestpriv; ++ ++ psrtpriv->silent_reset_inprogress = false; ++ psrtpriv->wifi_error_status = WIFI_STATUS_SUCCESS; ++ psrtpriv->last_tx_time = 0; ++ psrtpriv->last_tx_complete_time = 0; ++} ++ ++u8 sreset_get_wifi_status(struct adapter *padapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct sreset_priv *psrtpriv = &pHalData->srestpriv; ++ ++ u8 status = WIFI_STATUS_SUCCESS; ++ u32 val32 = 0; ++ ++ if (psrtpriv->silent_reset_inprogress) ++ return status; ++ val32 = rtw_read32(padapter, REG_TXDMA_STATUS); ++ if (val32 == 0xeaeaeaea) { ++ psrtpriv->wifi_error_status = WIFI_IF_NOT_EXIST; ++ } else if (val32 != 0) { ++ DBG_88E("txdmastatu(%x)\n", val32); ++ psrtpriv->wifi_error_status = WIFI_MAC_TXDMA_ERROR; ++ } ++ ++ if (WIFI_STATUS_SUCCESS != psrtpriv->wifi_error_status) { ++ DBG_88E("==>%s error_status(0x%x)\n", __func__, psrtpriv->wifi_error_status); ++ status = (psrtpriv->wifi_error_status & (~(USB_READ_PORT_FAIL | USB_WRITE_PORT_FAIL))); ++ } ++ DBG_88E("==> %s wifi_status(0x%x)\n", __func__, status); ++ ++ /* status restore */ ++ psrtpriv->wifi_error_status = WIFI_STATUS_SUCCESS; ++ ++ return status; ++} ++ ++void sreset_set_wifi_error_status(struct adapter *padapter, u32 status) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ pHalData->srestpriv.wifi_error_status = status; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_sta_mgt.c b/drivers/staging/r8188eu/core/rtw_sta_mgt.c +new file mode 100644 +index 000000000000..f6dffed53a60 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_sta_mgt.c +@@ -0,0 +1,508 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_STA_MGT_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/xmit_osdep.h" ++#include "../include/mlme_osdep.h" ++#include "../include/sta_info.h" ++ ++static void _rtw_init_stainfo(struct sta_info *psta) ++{ ++ ++ memset((u8 *)psta, 0, sizeof(struct sta_info)); ++ ++ spin_lock_init(&psta->lock); ++ INIT_LIST_HEAD(&psta->list); ++ INIT_LIST_HEAD(&psta->hash_list); ++ _rtw_init_queue(&psta->sleep_q); ++ psta->sleepq_len = 0; ++ ++ _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv); ++ _rtw_init_sta_recv_priv(&psta->sta_recvpriv); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++ INIT_LIST_HEAD(&psta->asoc_list); ++ ++ INIT_LIST_HEAD(&psta->auth_list); ++ ++ psta->expire_to = 0; ++ ++ psta->flags = 0; ++ ++ psta->capability = 0; ++ ++ psta->bpairwise_key_installed = false; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ psta->nonerp_set = 0; ++ psta->no_short_slot_time_set = 0; ++ psta->no_short_preamble_set = 0; ++ psta->no_ht_gf_set = 0; ++ psta->no_ht_set = 0; ++ psta->ht_20mhz_set = 0; ++#endif ++ ++ psta->under_exist_checking = 0; ++ ++ psta->keep_alive_trycnt = 0; ++ ++#endif /* CONFIG_88EU_AP_MODE */ ++ ++} ++ ++u32 _rtw_init_sta_priv(struct sta_priv *pstapriv) ++{ ++ struct sta_info *psta; ++ s32 i; ++ ++ pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * NUM_STA + 4); ++ ++ if (!pstapriv->pallocated_stainfo_buf) ++ return _FAIL; ++ ++ pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 - ++ ((size_t)(pstapriv->pallocated_stainfo_buf) & 3); ++ ++ _rtw_init_queue(&pstapriv->free_sta_queue); ++ ++ spin_lock_init(&pstapriv->sta_hash_lock); ++ ++ pstapriv->asoc_sta_count = 0; ++ _rtw_init_queue(&pstapriv->sleep_q); ++ _rtw_init_queue(&pstapriv->wakeup_q); ++ ++ psta = (struct sta_info *)(pstapriv->pstainfo_buf); ++ ++ for (i = 0; i < NUM_STA; i++) { ++ _rtw_init_stainfo(psta); ++ ++ INIT_LIST_HEAD(&pstapriv->sta_hash[i]); ++ ++ list_add_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue)); ++ ++ psta++; ++ } ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++ pstapriv->sta_dz_bitmap = 0; ++ pstapriv->tim_bitmap = 0; ++ ++ INIT_LIST_HEAD(&pstapriv->asoc_list); ++ INIT_LIST_HEAD(&pstapriv->auth_list); ++ spin_lock_init(&pstapriv->asoc_list_lock); ++ spin_lock_init(&pstapriv->auth_list_lock); ++ pstapriv->asoc_list_cnt = 0; ++ pstapriv->auth_list_cnt = 0; ++ ++ pstapriv->auth_to = 3; /* 3*2 = 6 sec */ ++ pstapriv->assoc_to = 3; ++ pstapriv->expire_to = 3; /* 3*2 = 6 sec */ ++ pstapriv->max_num_sta = NUM_STA; ++#endif ++ ++ return _SUCCESS; ++} ++ ++inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta) ++{ ++ int offset = (((u8 *)sta) - stapriv->pstainfo_buf) / sizeof(struct sta_info); ++ ++ if (!stainfo_offset_valid(offset)) ++ DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset); ++ ++ return offset; ++} ++ ++inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset) ++{ ++ if (!stainfo_offset_valid(offset)) ++ DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset); ++ ++ return (struct sta_info *)(stapriv->pstainfo_buf + offset * sizeof(struct sta_info)); ++} ++ ++u32 _rtw_free_sta_priv(struct sta_priv *pstapriv) ++{ ++ struct list_head *phead, *plist; ++ struct sta_info *psta = NULL; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ int index; ++ ++ if (pstapriv) { ++ /* delete all reordering_ctrl_timer */ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ for (index = 0; index < NUM_STA; index++) { ++ phead = &pstapriv->sta_hash[index]; ++ plist = phead->next; ++ ++ while (phead != plist) { ++ int i; ++ psta = container_of(plist, struct sta_info, hash_list); ++ plist = plist->next; ++ ++ for (i = 0; i < 16; i++) { ++ preorder_ctrl = &psta->recvreorder_ctrl[i]; ++ _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer); ++ } ++ } ++ } ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ /*===============================*/ ++ ++ if (pstapriv->pallocated_stainfo_buf) ++ vfree(pstapriv->pallocated_stainfo_buf); ++ } ++ ++ return _SUCCESS; ++} ++ ++struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) ++{ ++ s32 index; ++ struct list_head *phash_list; ++ struct sta_info *psta; ++ struct __queue *pfree_sta_queue; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ int i = 0; ++ u16 wRxSeqInitialValue = 0xffff; ++ ++ pfree_sta_queue = &pstapriv->free_sta_queue; ++ ++ spin_lock_bh(&pfree_sta_queue->lock); ++ ++ if (list_empty(&pfree_sta_queue->queue)) { ++ spin_unlock_bh(&pfree_sta_queue->lock); ++ psta = NULL; ++ } else { ++ psta = container_of((&pfree_sta_queue->queue)->next, struct sta_info, list); ++ list_del_init(&psta->list); ++ spin_unlock_bh(&pfree_sta_queue->lock); ++ _rtw_init_stainfo(psta); ++ memcpy(psta->hwaddr, hwaddr, ETH_ALEN); ++ index = wifi_mac_hash(hwaddr); ++ if (index >= NUM_STA) { ++ psta = NULL; ++ goto exit; ++ } ++ phash_list = &pstapriv->sta_hash[index]; ++ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ ++ list_add_tail(&psta->hash_list, phash_list); ++ ++ pstapriv->asoc_sta_count++; ++ ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++/* Commented by Albert 2009/08/13 */ ++/* For the SMC router, the sequence number of first packet of WPS handshake will be 0. */ ++/* In this case, this packet will be dropped by recv_decache function if we use the 0x00 as the default value for tid_rxseq variable. */ ++/* So, we initialize the tid_rxseq variable as the 0xffff. */ ++ ++ for (i = 0; i < 16; i++) ++ memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2); ++ ++ init_addba_retry_timer(pstapriv->padapter, psta); ++ ++ /* for A-MPDU Rx reordering buffer control */ ++ for (i = 0; i < 16; i++) { ++ preorder_ctrl = &psta->recvreorder_ctrl[i]; ++ ++ preorder_ctrl->padapter = pstapriv->padapter; ++ ++ preorder_ctrl->enable = false; ++ ++ preorder_ctrl->indicate_seq = 0xffff; ++ preorder_ctrl->wend_b = 0xffff; ++ preorder_ctrl->wsize_b = 64;/* 64; */ ++ ++ _rtw_init_queue(&preorder_ctrl->pending_recvframe_queue); ++ ++ rtw_init_recv_timer(preorder_ctrl); ++ } ++ ++ /* init for DM */ ++ psta->rssi_stat.UndecoratedSmoothedPWDB = (-1); ++ psta->rssi_stat.UndecoratedSmoothedCCK = (-1); ++ ++ /* init for the sequence number of received management frame */ ++ psta->RxMgmtFrameSeqNum = 0xffff; ++ } ++ ++exit: ++ ++ return psta; ++} ++ ++/* using pstapriv->sta_hash_lock to protect */ ++u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta) ++{ ++ int i; ++ struct __queue *pfree_sta_queue; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ struct sta_xmit_priv *pstaxmitpriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ if (!psta) ++ goto exit; ++ ++ pfree_sta_queue = &pstapriv->free_sta_queue; ++ ++ pstaxmitpriv = &psta->sta_xmitpriv; ++ ++ spin_lock_bh(&pxmitpriv->lock); ++ ++ rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q); ++ psta->sleepq_len = 0; ++ ++ rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending); ++ ++ list_del_init(&pstaxmitpriv->vo_q.tx_pending); ++ ++ rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending); ++ ++ list_del_init(&pstaxmitpriv->vi_q.tx_pending); ++ ++ rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending); ++ ++ list_del_init(&pstaxmitpriv->bk_q.tx_pending); ++ ++ rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending); ++ ++ list_del_init(&pstaxmitpriv->be_q.tx_pending); ++ ++ spin_unlock_bh(&pxmitpriv->lock); ++ ++ list_del_init(&psta->hash_list); ++ pstapriv->asoc_sta_count--; ++ ++ /* re-init sta_info; 20061114 */ ++ _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv); ++ _rtw_init_sta_recv_priv(&psta->sta_recvpriv); ++ ++ _cancel_timer_ex(&psta->addba_retry_timer); ++ ++ /* for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer */ ++ for (i = 0; i < 16 ; i++) { ++ struct list_head *phead, *plist; ++ struct recv_frame *prframe; ++ struct __queue *ppending_recvframe_queue; ++ struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; ++ ++ preorder_ctrl = &psta->recvreorder_ctrl[i]; ++ ++ _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer); ++ ++ ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; ++ ++ spin_lock_bh(&ppending_recvframe_queue->lock); ++ ++ phead = get_list_head(ppending_recvframe_queue); ++ plist = phead->next; ++ ++ while (!list_empty(phead)) { ++ prframe = container_of(plist, struct recv_frame, list); ++ ++ plist = plist->next; ++ ++ list_del_init(&prframe->list); ++ ++ rtw_free_recvframe(prframe, pfree_recv_queue); ++ } ++ ++ spin_unlock_bh(&ppending_recvframe_queue->lock); ++ } ++ ++ if (!(psta->state & WIFI_AP_STATE)) ++ rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, false); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++ spin_lock_bh(&pstapriv->auth_list_lock); ++ if (!list_empty(&psta->auth_list)) { ++ list_del_init(&psta->auth_list); ++ pstapriv->auth_list_cnt--; ++ } ++ spin_unlock_bh(&pstapriv->auth_list_lock); ++ ++ psta->expire_to = 0; ++ ++ psta->sleepq_ac_len = 0; ++ psta->qos_info = 0; ++ ++ psta->max_sp_len = 0; ++ psta->uapsd_bk = 0; ++ psta->uapsd_be = 0; ++ psta->uapsd_vi = 0; ++ psta->uapsd_vo = 0; ++ psta->has_legacy_ac = 0; ++ ++ pstapriv->sta_dz_bitmap &= ~BIT(psta->aid); ++ pstapriv->tim_bitmap &= ~BIT(psta->aid); ++ ++ if ((psta->aid > 0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) { ++ pstapriv->sta_aid[psta->aid - 1] = NULL; ++ psta->aid = 0; ++ } ++ ++ psta->under_exist_checking = 0; ++ ++#endif /* CONFIG_88EU_AP_MODE */ ++ ++ spin_lock_bh(&pfree_sta_queue->lock); ++ list_add_tail(&psta->list, get_list_head(pfree_sta_queue)); ++ spin_unlock_bh(&pfree_sta_queue->lock); ++ ++exit: ++ ++ return _SUCCESS; ++} ++ ++/* free all stainfo which in sta_hash[all] */ ++void rtw_free_all_stainfo(struct adapter *padapter) ++{ ++ struct list_head *plist, *phead; ++ s32 index; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo(padapter); ++ ++ if (pstapriv->asoc_sta_count == 1) ++ return; ++ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ ++ for (index = 0; index < NUM_STA; index++) { ++ phead = &pstapriv->sta_hash[index]; ++ plist = phead->next; ++ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, hash_list); ++ ++ plist = plist->next; ++ ++ if (pbcmc_stainfo != psta) ++ rtw_free_stainfo(padapter, psta); ++ } ++ } ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++} ++ ++/* any station allocated can be searched by hash list */ ++struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) ++{ ++ struct list_head *plist, *phead; ++ struct sta_info *psta = NULL; ++ u32 index; ++ u8 *addr; ++ u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ ++ if (!hwaddr) ++ return NULL; ++ ++ if (IS_MCAST(hwaddr)) ++ addr = bc_addr; ++ else ++ addr = hwaddr; ++ ++ index = wifi_mac_hash(addr); ++ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ ++ phead = &pstapriv->sta_hash[index]; ++ plist = phead->next; ++ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, hash_list); ++ ++ if ((!memcmp(psta->hwaddr, addr, ETH_ALEN))) { ++ /* if found the matched address */ ++ break; ++ } ++ psta = NULL; ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++ return psta; ++} ++ ++u32 rtw_init_bcmc_stainfo(struct adapter *padapter) ++{ ++ struct sta_info *psta; ++ u32 res = _SUCCESS; ++ unsigned char bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ psta = rtw_alloc_stainfo(pstapriv, bcast_addr); ++ ++ if (!psta) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ /* default broadcast & multicast use macid 1 */ ++ psta->mac_id = 1; ++ ++exit: ++ ++ return res; ++} ++ ++struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter) ++{ ++ struct sta_info *psta; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ ++ psta = rtw_get_stainfo(pstapriv, bc_addr); ++ ++ return psta; ++} ++ ++u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr) ++{ ++ u8 res = true; ++#ifdef CONFIG_88EU_AP_MODE ++ struct list_head *plist, *phead; ++ struct rtw_wlan_acl_node *paclnode; ++ u8 match = false; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; ++ struct __queue *pacl_node_q = &pacl_list->acl_node_q; ++ ++ spin_lock_bh(&pacl_node_q->lock); ++ phead = get_list_head(pacl_node_q); ++ plist = phead->next; ++ while (phead != plist) { ++ paclnode = container_of(plist, struct rtw_wlan_acl_node, list); ++ plist = plist->next; ++ ++ if (!memcmp(paclnode->addr, mac_addr, ETH_ALEN)) { ++ if (paclnode->valid) { ++ match = true; ++ break; ++ } ++ } ++ } ++ spin_unlock_bh(&pacl_node_q->lock); ++ ++ if (pacl_list->mode == 1)/* accept unless in deny list */ ++ res = (match) ? false : true; ++ else if (pacl_list->mode == 2)/* deny unless in accept list */ ++ res = (match) ? true : false; ++ else ++ res = true; ++ ++#endif ++ ++ return res; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_wlan_util.c b/drivers/staging/r8188eu/core/rtw_wlan_util.c +new file mode 100644 +index 000000000000..a3a5e1c64c4a +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_wlan_util.c +@@ -0,0 +1,1643 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_WLAN_UTIL_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wifi.h" ++ ++static unsigned char ARTHEROS_OUI1[] = {0x00, 0x03, 0x7f}; ++static unsigned char ARTHEROS_OUI2[] = {0x00, 0x13, 0x74}; ++ ++static unsigned char BROADCOM_OUI1[] = {0x00, 0x10, 0x18}; ++static unsigned char BROADCOM_OUI2[] = {0x00, 0x0a, 0xf7}; ++ ++static unsigned char CISCO_OUI[] = {0x00, 0x40, 0x96}; ++static unsigned char MARVELL_OUI[] = {0x00, 0x50, 0x43}; ++static unsigned char RALINK_OUI[] = {0x00, 0x0c, 0x43}; ++static unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c}; ++static unsigned char AIRGOCAP_OUI[] = {0x00, 0x0a, 0xf5}; ++static unsigned char EPIGRAM_OUI[] = {0x00, 0x90, 0x4c}; ++ ++unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20}; ++ ++#define R2T_PHY_DELAY (0) ++ ++/* define WAIT_FOR_BCN_TO_M (3000) */ ++#define WAIT_FOR_BCN_TO_MIN (6000) ++#define WAIT_FOR_BCN_TO_MAX (20000) ++ ++static u8 rtw_basic_rate_cck[4] = { ++ IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK, ++ IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK ++}; ++ ++static u8 rtw_basic_rate_ofdm[3] = { ++ IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK, ++ IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK ++}; ++ ++static u8 rtw_basic_rate_mix[7] = { ++ IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK, ++ IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK, ++ IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK, ++ IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK ++}; ++ ++int cckrates_included(unsigned char *rate, int ratelen) ++{ ++ int i; ++ ++ for (i = 0; i < ratelen; i++) { ++ if ((((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) || ++ (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22)) ++ return true; ++ } ++ return false; ++} ++ ++int cckratesonly_included(unsigned char *rate, int ratelen) ++{ ++ int i; ++ ++ for (i = 0; i < ratelen; i++) { ++ if ((((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && ++ (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22)) ++ return false; ++ } ++ ++ return true; ++} ++ ++unsigned char networktype_to_raid(unsigned char network_type) ++{ ++ unsigned char raid; ++ ++ switch (network_type) { ++ case WIRELESS_11B: ++ raid = RATR_INX_WIRELESS_B; ++ break; ++ case WIRELESS_11G: ++ raid = RATR_INX_WIRELESS_G; ++ break; ++ case WIRELESS_11BG: ++ raid = RATR_INX_WIRELESS_GB; ++ break; ++ case WIRELESS_11_24N: ++ raid = RATR_INX_WIRELESS_N; ++ break; ++ case WIRELESS_11G_24N: ++ raid = RATR_INX_WIRELESS_NG; ++ break; ++ case WIRELESS_11BG_24N: ++ raid = RATR_INX_WIRELESS_NGB; ++ break; ++ default: ++ raid = RATR_INX_WIRELESS_GB; ++ break; ++ } ++ return raid; ++} ++ ++u8 judge_network_type(struct adapter *padapter, unsigned char *rate, int ratelen) ++{ ++ u8 network_type = 0; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pmlmeext->cur_channel > 14) { ++ network_type |= WIRELESS_INVALID; ++ } else { ++ if (pmlmeinfo->HT_enable) ++ network_type = WIRELESS_11_24N; ++ ++ if (cckratesonly_included(rate, ratelen)) ++ network_type |= WIRELESS_11B; ++ else if (cckrates_included(rate, ratelen)) ++ network_type |= WIRELESS_11BG; ++ else ++ network_type |= WIRELESS_11G; ++ } ++ return network_type; ++} ++ ++static unsigned char ratetbl_val_2wifirate(unsigned char rate) ++{ ++ unsigned char val = 0; ++ ++ switch (rate & 0x7f) { ++ case 0: ++ val = IEEE80211_CCK_RATE_1MB; ++ break; ++ case 1: ++ val = IEEE80211_CCK_RATE_2MB; ++ break; ++ case 2: ++ val = IEEE80211_CCK_RATE_5MB; ++ break; ++ case 3: ++ val = IEEE80211_CCK_RATE_11MB; ++ break; ++ case 4: ++ val = IEEE80211_OFDM_RATE_6MB; ++ break; ++ case 5: ++ val = IEEE80211_OFDM_RATE_9MB; ++ break; ++ case 6: ++ val = IEEE80211_OFDM_RATE_12MB; ++ break; ++ case 7: ++ val = IEEE80211_OFDM_RATE_18MB; ++ break; ++ case 8: ++ val = IEEE80211_OFDM_RATE_24MB; ++ break; ++ case 9: ++ val = IEEE80211_OFDM_RATE_36MB; ++ break; ++ case 10: ++ val = IEEE80211_OFDM_RATE_48MB; ++ break; ++ case 11: ++ val = IEEE80211_OFDM_RATE_54MB; ++ break; ++ } ++ return val; ++} ++ ++static int is_basicrate(struct adapter *padapter, unsigned char rate) ++{ ++ int i; ++ unsigned char val; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ for (i = 0; i < NumRates; i++) { ++ val = pmlmeext->basicrate[i]; ++ ++ if ((val != 0xff) && (val != 0xfe)) { ++ if (rate == ratetbl_val_2wifirate(val)) ++ return true; ++ } ++ } ++ return false; ++} ++ ++static unsigned int ratetbl2rateset(struct adapter *padapter, unsigned char *rateset) ++{ ++ int i; ++ unsigned char rate; ++ unsigned int len = 0; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ for (i = 0; i < NumRates; i++) { ++ rate = pmlmeext->datarate[i]; ++ ++ switch (rate) { ++ case 0xff: ++ return len; ++ case 0xfe: ++ continue; ++ default: ++ rate = ratetbl_val_2wifirate(rate); ++ ++ if (is_basicrate(padapter, rate)) ++ rate |= IEEE80211_BASIC_RATE_MASK; ++ ++ rateset[len] = rate; ++ len++; ++ break; ++ } ++ } ++ return len; ++} ++ ++void get_rate_set(struct adapter *padapter, unsigned char *pbssrate, int *bssrate_len) ++{ ++ unsigned char supportedrates[NumRates]; ++ ++ memset(supportedrates, 0, NumRates); ++ *bssrate_len = ratetbl2rateset(padapter, supportedrates); ++ memcpy(pbssrate, supportedrates, *bssrate_len); ++} ++ ++void UpdateBrateTbl(struct adapter *Adapter, u8 *mbrate) ++{ ++ u8 i; ++ u8 rate; ++ ++ /* 1M, 2M, 5.5M, 11M, 6M, 12M, 24M are mandatory. */ ++ for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { ++ rate = mbrate[i] & 0x7f; ++ switch (rate) { ++ case IEEE80211_CCK_RATE_1MB: ++ case IEEE80211_CCK_RATE_2MB: ++ case IEEE80211_CCK_RATE_5MB: ++ case IEEE80211_CCK_RATE_11MB: ++ case IEEE80211_OFDM_RATE_6MB: ++ case IEEE80211_OFDM_RATE_12MB: ++ case IEEE80211_OFDM_RATE_24MB: ++ mbrate[i] |= IEEE80211_BASIC_RATE_MASK; ++ break; ++ } ++ } ++} ++ ++void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen) ++{ ++ u8 i; ++ u8 rate; ++ ++ for (i = 0; i < bssratelen; i++) { ++ rate = bssrateset[i] & 0x7f; ++ switch (rate) { ++ case IEEE80211_CCK_RATE_1MB: ++ case IEEE80211_CCK_RATE_2MB: ++ case IEEE80211_CCK_RATE_5MB: ++ case IEEE80211_CCK_RATE_11MB: ++ bssrateset[i] |= IEEE80211_BASIC_RATE_MASK; ++ break; ++ } ++ } ++} ++ ++void Save_DM_Func_Flag(struct adapter *padapter) ++{ ++ u8 saveflag = true; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&saveflag)); ++} ++ ++void Restore_DM_Func_Flag(struct adapter *padapter) ++{ ++ u8 saveflag = false; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&saveflag)); ++} ++ ++void Switch_DM_Func(struct adapter *padapter, u32 mode, u8 enable) ++{ ++ if (enable) ++ rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_SET, (u8 *)(&mode)); ++ else ++ rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_CLR, (u8 *)(&mode)); ++} ++ ++static void Set_NETYPE0_MSR(struct adapter *padapter, u8 type) ++{ ++ rtw_hal_set_hwreg(padapter, HW_VAR_MEDIA_STATUS, (u8 *)(&type)); ++} ++ ++void Set_MSR(struct adapter *padapter, u8 type) ++{ ++ Set_NETYPE0_MSR(padapter, type); ++} ++ ++inline u8 rtw_get_oper_ch(struct adapter *adapter) ++{ ++ return adapter->mlmeextpriv.oper_channel; ++} ++ ++inline void rtw_set_oper_ch(struct adapter *adapter, u8 ch) ++{ ++ adapter->mlmeextpriv.oper_channel = ch; ++} ++ ++inline u8 rtw_get_oper_bw(struct adapter *adapter) ++{ ++ return adapter->mlmeextpriv.oper_bwmode; ++} ++ ++inline void rtw_set_oper_bw(struct adapter *adapter, u8 bw) ++{ ++ adapter->mlmeextpriv.oper_bwmode = bw; ++} ++ ++inline u8 rtw_get_oper_choffset(struct adapter *adapter) ++{ ++ return adapter->mlmeextpriv.oper_ch_offset; ++} ++ ++inline void rtw_set_oper_choffset(struct adapter *adapter, u8 offset) ++{ ++ adapter->mlmeextpriv.oper_ch_offset = offset; ++} ++ ++void SelectChannel(struct adapter *padapter, unsigned char channel) ++{ ++ /* saved channel info */ ++ rtw_set_oper_ch(padapter, channel); ++ rtw_hal_set_chan(padapter, channel); ++} ++ ++void SetBWMode(struct adapter *padapter, unsigned short bwmode, ++ unsigned char channel_offset) ++{ ++ /* saved bw info */ ++ rtw_set_oper_bw(padapter, bwmode); ++ rtw_set_oper_choffset(padapter, channel_offset); ++ ++ rtw_hal_set_bwmode(padapter, (enum ht_channel_width)bwmode, channel_offset); ++} ++ ++void set_channel_bwmode(struct adapter *padapter, unsigned char channel, unsigned char channel_offset, unsigned short bwmode) ++{ ++ u8 center_ch; ++ ++ if (padapter->bNotifyChannelChange) ++ DBG_88E("[%s] ch = %d, offset = %d, bwmode = %d\n", __func__, channel, channel_offset, bwmode); ++ ++ if ((bwmode == HT_CHANNEL_WIDTH_20) || ++ (channel_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)) { ++ /* SelectChannel(padapter, channel); */ ++ center_ch = channel; ++ } else { ++ /* switch to the proper channel */ ++ if (channel_offset == HAL_PRIME_CHNL_OFFSET_LOWER) { ++ /* SelectChannel(padapter, channel + 2); */ ++ center_ch = channel + 2; ++ } else { ++ /* SelectChannel(padapter, channel - 2); */ ++ center_ch = channel - 2; ++ } ++ } ++ ++ /* set Channel */ ++ /* saved channel/bw info */ ++ rtw_set_oper_ch(padapter, channel); ++ rtw_set_oper_bw(padapter, bwmode); ++ rtw_set_oper_choffset(padapter, channel_offset); ++ ++ rtw_hal_set_chan(padapter, center_ch); /* set center channel */ ++ SetBWMode(padapter, bwmode, channel_offset); ++} ++ ++int get_bsstype(unsigned short capability) ++{ ++ if (capability & BIT(0)) ++ return WIFI_FW_AP_STATE; ++ else if (capability & BIT(1)) ++ return WIFI_FW_ADHOC_STATE; ++ else ++ return 0; ++} ++ ++__inline u8 *get_my_bssid(struct wlan_bssid_ex *pnetwork) ++{ ++ return pnetwork->MacAddress; ++} ++ ++u16 get_beacon_interval(struct wlan_bssid_ex *bss) ++{ ++ __le16 val; ++ memcpy((unsigned char *)&val, rtw_get_beacon_interval_from_ie(bss->IEs), 2); ++ ++ return le16_to_cpu(val); ++} ++ ++int is_client_associated_to_ap(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext; ++ struct mlme_ext_info *pmlmeinfo; ++ ++ if (!padapter) ++ return _FAIL; ++ ++ pmlmeext = &padapter->mlmeextpriv; ++ pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)) ++ return true; ++ else ++ return _FAIL; ++} ++ ++int is_client_associated_to_ibss(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) ++ return true; ++ else ++ return _FAIL; ++} ++ ++int is_IBSS_empty(struct adapter *padapter) ++{ ++ unsigned int i; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) { ++ if (pmlmeinfo->FW_sta_info[i].status == 1) ++ return _FAIL; ++ } ++ return true; ++} ++ ++unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval) ++{ ++ if ((bcn_interval << 2) < WAIT_FOR_BCN_TO_MIN) ++ return WAIT_FOR_BCN_TO_MIN; ++ else if ((bcn_interval << 2) > WAIT_FOR_BCN_TO_MAX) ++ return WAIT_FOR_BCN_TO_MAX; ++ else ++ return bcn_interval << 2; ++} ++ ++void CAM_empty_entry(struct adapter *Adapter, u8 ucIndex) ++{ ++ rtw_hal_set_hwreg(Adapter, HW_VAR_CAM_EMPTY_ENTRY, (u8 *)(&ucIndex)); ++} ++ ++void invalidate_cam_all(struct adapter *padapter) ++{ ++ rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, NULL); ++} ++ ++void write_cam(struct adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key) ++{ ++ unsigned int i, val, addr; ++ int j; ++ u32 cam_val[2]; ++ ++ addr = entry << 3; ++ ++ for (j = 5; j >= 0; j--) { ++ switch (j) { ++ case 0: ++ val = (ctrl | (mac[0] << 16) | (mac[1] << 24)); ++ break; ++ case 1: ++ val = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24)); ++ break; ++ default: ++ i = (j - 2) << 2; ++ val = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24)); ++ break; ++ } ++ ++ cam_val[0] = val; ++ cam_val[1] = addr + (unsigned int)j; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_CAM_WRITE, (u8 *)cam_val); ++ } ++} ++ ++void clear_cam_entry(struct adapter *padapter, u8 entry) ++{ ++ unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; ++ unsigned char null_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; ++ ++ write_cam(padapter, entry, 0, null_sta, null_key); ++} ++ ++int allocate_fw_sta_entry(struct adapter *padapter) ++{ ++ unsigned int mac_id; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ for (mac_id = IBSS_START_MAC_ID; mac_id < NUM_STA; mac_id++) { ++ if (pmlmeinfo->FW_sta_info[mac_id].status == 0) { ++ pmlmeinfo->FW_sta_info[mac_id].status = 1; ++ pmlmeinfo->FW_sta_info[mac_id].retry = 0; ++ break; ++ } ++ } ++ ++ return mac_id; ++} ++ ++void flush_all_cam_entry(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, NULL); ++ ++ memset((u8 *)(pmlmeinfo->FW_sta_info), 0, sizeof(pmlmeinfo->FW_sta_info)); ++} ++ ++int WMM_param_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE) ++{ ++ /* struct registry_priv *pregpriv = &padapter->registrypriv; */ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pmlmepriv->qospriv.qos_option == 0) { ++ pmlmeinfo->WMM_enable = 0; ++ return _FAIL; ++ } ++ ++ pmlmeinfo->WMM_enable = 1; ++ memcpy(&pmlmeinfo->WMM_param, pIE->data + 6, sizeof(struct WMM_para_element)); ++ return true; ++} ++ ++void WMMOnAssocRsp(struct adapter *padapter) ++{ ++ u8 ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime; ++ u8 acm_mask; ++ u16 TXOP; ++ u32 acParm, i; ++ u32 edca[4], inx[4]; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ ++ if (pmlmeinfo->WMM_enable == 0) { ++ padapter->mlmepriv.acm_mask = 0; ++ return; ++ } ++ ++ acm_mask = 0; ++ ++ if (pmlmeext->cur_wireless_mode == WIRELESS_11B) ++ aSifsTime = 10; ++ else ++ aSifsTime = 16; ++ ++ for (i = 0; i < 4; i++) { ++ ACI = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 5) & 0x03; ++ ACM = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 4) & 0x01; ++ ++ /* AIFS = AIFSN * slot time + SIFS - r2t phy delay */ ++ AIFS = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN & 0x0f) * pmlmeinfo->slotTime + aSifsTime; ++ ++ ECWMin = (pmlmeinfo->WMM_param.ac_param[i].CW & 0x0f); ++ ECWMax = (pmlmeinfo->WMM_param.ac_param[i].CW & 0xf0) >> 4; ++ TXOP = le16_to_cpu(pmlmeinfo->WMM_param.ac_param[i].TXOP_limit); ++ ++ acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16); ++ ++ switch (ACI) { ++ case 0x0: ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm)); ++ acm_mask |= (ACM ? BIT(1) : 0); ++ edca[XMIT_BE_QUEUE] = acParm; ++ break; ++ case 0x1: ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm)); ++ edca[XMIT_BK_QUEUE] = acParm; ++ break; ++ case 0x2: ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm)); ++ acm_mask |= (ACM ? BIT(2) : 0); ++ edca[XMIT_VI_QUEUE] = acParm; ++ break; ++ case 0x3: ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm)); ++ acm_mask |= (ACM ? BIT(3) : 0); ++ edca[XMIT_VO_QUEUE] = acParm; ++ break; ++ } ++ ++ DBG_88E("WMM(%x): %x, %x\n", ACI, ACM, acParm); ++ } ++ ++ if (padapter->registrypriv.acm_method == 1) ++ rtw_hal_set_hwreg(padapter, HW_VAR_ACM_CTRL, (u8 *)(&acm_mask)); ++ else ++ padapter->mlmepriv.acm_mask = acm_mask; ++ ++ inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3; ++ ++ if (pregpriv->wifi_spec == 1) { ++ u32 j, tmp, change_inx = false; ++ ++ /* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */ ++ for (i = 0; i < 4; i++) { ++ for (j = i + 1; j < 4; j++) { ++ /* compare CW and AIFS */ ++ if ((edca[j] & 0xFFFF) < (edca[i] & 0xFFFF)) { ++ change_inx = true; ++ } else if ((edca[j] & 0xFFFF) == (edca[i] & 0xFFFF)) { ++ /* compare TXOP */ ++ if ((edca[j] >> 16) > (edca[i] >> 16)) ++ change_inx = true; ++ } ++ ++ if (change_inx) { ++ tmp = edca[i]; ++ edca[i] = edca[j]; ++ edca[j] = tmp; ++ ++ tmp = inx[i]; ++ inx[i] = inx[j]; ++ inx[j] = tmp; ++ ++ change_inx = false; ++ } ++ } ++ } ++ } ++ ++ for (i = 0; i < 4; i++) { ++ pxmitpriv->wmm_para_seq[i] = inx[i]; ++ DBG_88E("wmm_para_seq(%d): %d\n", i, pxmitpriv->wmm_para_seq[i]); ++ } ++} ++ ++static void bwmode_update_check(struct adapter *padapter, struct ndis_802_11_var_ie *pIE) ++{ ++ unsigned char new_bwmode; ++ unsigned char new_ch_offset; ++ struct HT_info_element *pHT_info; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ ++ if (!pIE) ++ return; ++ ++ if (!phtpriv) ++ return; ++ ++ if (pIE->Length > sizeof(struct HT_info_element)) ++ return; ++ ++ pHT_info = (struct HT_info_element *)pIE->data; ++ ++ if ((pHT_info->infos[0] & BIT(2)) && pregistrypriv->cbw40_enable) { ++ new_bwmode = HT_CHANNEL_WIDTH_40; ++ ++ switch (pHT_info->infos[0] & 0x3) { ++ case 1: ++ new_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; ++ break; ++ case 3: ++ new_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; ++ break; ++ default: ++ new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ break; ++ } ++ } else { ++ new_bwmode = HT_CHANNEL_WIDTH_20; ++ new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ } ++ ++ if ((new_bwmode != pmlmeext->cur_bwmode) || ++ (new_ch_offset != pmlmeext->cur_ch_offset)) { ++ pmlmeinfo->bwmode_updated = true; ++ ++ pmlmeext->cur_bwmode = new_bwmode; ++ pmlmeext->cur_ch_offset = new_ch_offset; ++ ++ /* update HT info also */ ++ HT_info_handler(padapter, pIE); ++ } else { ++ pmlmeinfo->bwmode_updated = false; ++ } ++ ++ if (pmlmeinfo->bwmode_updated) { ++ struct sta_info *psta; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ /* set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */ ++ ++ /* update ap's stainfo */ ++ psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress); ++ if (psta) { ++ struct ht_priv *phtpriv_sta = &psta->htpriv; ++ ++ if (phtpriv_sta->ht_option) { ++ /* bwmode */ ++ phtpriv_sta->bwmode = pmlmeext->cur_bwmode; ++ phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset; ++ } else { ++ phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20; ++ phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ } ++ } ++ } ++} ++ ++void HT_caps_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE) ++{ ++ unsigned int i; ++ u8 rf_type; ++ u8 max_AMPDU_len, min_MPDU_spacing; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ ++ if (!pIE) ++ return; ++ ++ if (!phtpriv->ht_option) ++ return; ++ ++ pmlmeinfo->HT_caps_enable = 1; ++ ++ for (i = 0; i < (pIE->Length); i++) { ++ if (i != 2) { ++ /* Got the endian issue here. */ ++ pmlmeinfo->HT_caps.u.HT_cap[i] &= (pIE->data[i]); ++ } else { ++ /* modify from fw by Thomas 2010/11/17 */ ++ if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3) > (pIE->data[i] & 0x3)) ++ max_AMPDU_len = (pIE->data[i] & 0x3); ++ else ++ max_AMPDU_len = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3); ++ ++ if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) > (pIE->data[i] & 0x1c)) ++ min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c); ++ else ++ min_MPDU_spacing = (pIE->data[i] & 0x1c); ++ ++ pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para = max_AMPDU_len | min_MPDU_spacing; ++ } ++ } ++ ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ ++ /* update the MCS rates */ ++ for (i = 0; i < 16; i++) { ++ if ((rf_type == RF_1T1R) || (rf_type == RF_1T2R)) ++ pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; ++ else ++ pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i]; ++ } ++} ++ ++void HT_info_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ ++ if (!pIE) ++ return; ++ ++ if (!phtpriv->ht_option) ++ return; ++ ++ if (pIE->Length > sizeof(struct HT_info_element)) ++ return; ++ ++ pmlmeinfo->HT_info_enable = 1; ++ memcpy(&pmlmeinfo->HT_info, pIE->data, pIE->Length); ++} ++ ++void HTOnAssocRsp(struct adapter *padapter) ++{ ++ unsigned char max_AMPDU_len; ++ unsigned char min_MPDU_spacing; ++ /* struct registry_priv *pregpriv = &padapter->registrypriv; */ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ DBG_88E("%s\n", __func__); ++ ++ if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable)) { ++ pmlmeinfo->HT_enable = 1; ++ } else { ++ pmlmeinfo->HT_enable = 0; ++ return; ++ } ++ ++ /* handle A-MPDU parameter field */ ++ /* ++ AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k ++ AMPDU_para [4:2]:Min MPDU Start Spacing ++ */ ++ max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03; ++ ++ min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing)); ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len)); ++} ++ ++void ERP_IE_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pIE->Length > 1) ++ return; ++ ++ pmlmeinfo->ERP_enable = 1; ++ memcpy(&pmlmeinfo->ERP_IE, pIE->data, pIE->Length); ++} ++ ++void VCS_update(struct adapter *padapter, struct sta_info *psta) ++{ ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ switch (pregpriv->vrtl_carrier_sense) { /* 0:off 1:on 2:auto */ ++ case 0: /* off */ ++ psta->rtsen = 0; ++ psta->cts2self = 0; ++ break; ++ case 1: /* on */ ++ if (pregpriv->vcs_type == 1) { /* 1:RTS/CTS 2:CTS to self */ ++ psta->rtsen = 1; ++ psta->cts2self = 0; ++ } else { ++ psta->rtsen = 0; ++ psta->cts2self = 1; ++ } ++ break; ++ case 2: /* auto */ ++ default: ++ if ((pmlmeinfo->ERP_enable) && (pmlmeinfo->ERP_IE & BIT(1))) { ++ if (pregpriv->vcs_type == 1) { ++ psta->rtsen = 1; ++ psta->cts2self = 0; ++ } else { ++ psta->rtsen = 0; ++ psta->cts2self = 1; ++ } ++ } else { ++ psta->rtsen = 0; ++ psta->cts2self = 0; ++ } ++ break; ++ } ++} ++ ++int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len) ++{ ++ unsigned int len; ++ unsigned char *p; ++ unsigned short val16, subtype; ++ struct wlan_network *cur_network = &Adapter->mlmepriv.cur_network; ++ /* u8 wpa_ie[255], rsn_ie[255]; */ ++ u16 wpa_len = 0, rsn_len = 0; ++ u8 encryp_protocol = 0; ++ struct wlan_bssid_ex *bssid; ++ int group_cipher = 0, pairwise_cipher = 0, is_8021x = 0; ++ unsigned char *pbuf; ++ u32 wpa_ielen = 0; ++ u8 *pbssid = GetAddr3Ptr(pframe); ++ u32 hidden_ssid = 0; ++ struct HT_info_element *pht_info = NULL; ++ struct ieee80211_ht_cap *pht_cap = NULL; ++ u32 bcn_channel; ++ unsigned short ht_cap_info; ++ unsigned char ht_info_infos_0; ++ ++ if (!is_client_associated_to_ap(Adapter)) ++ return true; ++ ++ len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ if (len > MAX_IE_SZ) { ++ DBG_88E("%s IE too long for survey event\n", __func__); ++ return _FAIL; ++ } ++ ++ if (memcmp(cur_network->network.MacAddress, pbssid, 6)) { ++ DBG_88E("Oops: rtw_check_network_encrypt linked but recv other bssid bcn\n%pM %pM\n", ++ (pbssid), (cur_network->network.MacAddress)); ++ return true; ++ } ++ ++ bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC); ++ if (!bssid) ++ return _FAIL; ++ ++ subtype = GetFrameSubType(pframe) >> 4; ++ ++ if (subtype == WIFI_BEACON) ++ bssid->Reserved[0] = 1; ++ ++ bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len; ++ ++ /* below is to copy the information element */ ++ bssid->IELength = len; ++ memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength); ++ ++ /* check bw and channel offset */ ++ /* parsing HT_CAP_IE */ ++ p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); ++ if (p && len > 0) { ++ pht_cap = (struct ieee80211_ht_cap *)(p + 2); ++ ht_cap_info = le16_to_cpu(pht_cap->cap_info); ++ } else { ++ ht_cap_info = 0; ++ } ++ /* parsing HT_INFO_IE */ ++ p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); ++ if (p && len > 0) { ++ pht_info = (struct HT_info_element *)(p + 2); ++ ht_info_infos_0 = pht_info->infos[0]; ++ } else { ++ ht_info_infos_0 = 0; ++ } ++ if (ht_cap_info != cur_network->BcnInfo.ht_cap_info || ++ ((ht_info_infos_0 & 0x03) != (cur_network->BcnInfo.ht_info_infos_0 & 0x03))) { ++ DBG_88E("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n", __func__, ++ ht_cap_info, ht_info_infos_0); ++ DBG_88E("%s bcn link: ht_cap_info:%x ht_info_infos_0:%x\n", __func__, ++ cur_network->BcnInfo.ht_cap_info, cur_network->BcnInfo.ht_info_infos_0); ++ DBG_88E("%s bw mode change, disconnect\n", __func__); ++ /* bcn_info_update */ ++ cur_network->BcnInfo.ht_cap_info = ht_cap_info; ++ cur_network->BcnInfo.ht_info_infos_0 = ht_info_infos_0; ++ /* to do : need to check that whether modify related register of BB or not */ ++ /* goto _mismatch; */ ++ } ++ ++ /* Checking for channel */ ++ p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _DSSET_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); ++ if (p) { ++ bcn_channel = *(p + 2); ++ } else {/* In 5G, some ap do not have DSSET IE checking HT info for channel */ ++ p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); ++ if (pht_info) { ++ bcn_channel = pht_info->primary_channel; ++ } else { /* we don't find channel IE, so don't check it */ ++ DBG_88E("Oops: %s we don't find channel IE, so don't check it\n", __func__); ++ bcn_channel = Adapter->mlmeextpriv.cur_channel; ++ } ++ } ++ if (bcn_channel != Adapter->mlmeextpriv.cur_channel) { ++ DBG_88E("%s beacon channel:%d cur channel:%d disconnect\n", __func__, ++ bcn_channel, Adapter->mlmeextpriv.cur_channel); ++ goto _mismatch; ++ } ++ ++ /* checking SSID */ ++ p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SSID_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); ++ if (!p) { ++ DBG_88E("%s marc: cannot find SSID for survey event\n", __func__); ++ hidden_ssid = true; ++ } else { ++ hidden_ssid = false; ++ } ++ ++ if ((NULL != p) && (false == hidden_ssid && (*(p + 1)))) { ++ memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1)); ++ bssid->Ssid.SsidLength = *(p + 1); ++ } else { ++ bssid->Ssid.SsidLength = 0; ++ bssid->Ssid.Ssid[0] = '\0'; ++ } ++ ++ if (memcmp(bssid->Ssid.Ssid, cur_network->network.Ssid.Ssid, 32) || ++ bssid->Ssid.SsidLength != cur_network->network.Ssid.SsidLength) { ++ if (bssid->Ssid.Ssid[0] != '\0' && bssid->Ssid.SsidLength != 0) { /* not hidden ssid */ ++ DBG_88E("%s(), SSID is not match return FAIL\n", __func__); ++ goto _mismatch; ++ } ++ } ++ ++ /* check encryption info */ ++ val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid); ++ ++ if (val16 & BIT(4)) ++ bssid->Privacy = 1; ++ else ++ bssid->Privacy = 0; ++ ++ if (cur_network->network.Privacy != bssid->Privacy) { ++ DBG_88E("%s(), privacy is not match return FAIL\n", __func__); ++ goto _mismatch; ++ } ++ ++ rtw_get_sec_ie(bssid->IEs, bssid->IELength, NULL, &rsn_len, NULL, &wpa_len); ++ ++ if (rsn_len > 0) { ++ encryp_protocol = ENCRYP_PROTOCOL_WPA2; ++ } else if (wpa_len > 0) { ++ encryp_protocol = ENCRYP_PROTOCOL_WPA; ++ } else { ++ if (bssid->Privacy) ++ encryp_protocol = ENCRYP_PROTOCOL_WEP; ++ } ++ ++ if (cur_network->BcnInfo.encryp_protocol != encryp_protocol) { ++ DBG_88E("%s(): enctyp is not match , return FAIL\n", __func__); ++ goto _mismatch; ++ } ++ ++ if (encryp_protocol == ENCRYP_PROTOCOL_WPA || encryp_protocol == ENCRYP_PROTOCOL_WPA2) { ++ pbuf = rtw_get_wpa_ie(&bssid->IEs[12], &wpa_ielen, bssid->IELength - 12); ++ if (pbuf && (wpa_ielen > 0)) { ++ rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is_8021x); ++ } else { ++ pbuf = rtw_get_wpa2_ie(&bssid->IEs[12], &wpa_ielen, bssid->IELength - 12); ++ ++ if (pbuf && (wpa_ielen > 0)) ++ rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is_8021x); ++ } ++ ++ if (pairwise_cipher != cur_network->BcnInfo.pairwise_cipher || group_cipher != cur_network->BcnInfo.group_cipher) { ++ DBG_88E("%s pairwise_cipher(%x:%x) or group_cipher(%x:%x) is not match , return FAIL\n", __func__, ++ pairwise_cipher, cur_network->BcnInfo.pairwise_cipher, ++ group_cipher, cur_network->BcnInfo.group_cipher); ++ goto _mismatch; ++ } ++ ++ if (is_8021x != cur_network->BcnInfo.is_8021x) { ++ DBG_88E("%s authentication is not match , return FAIL\n", __func__); ++ goto _mismatch; ++ } ++ } ++ ++ kfree(bssid); ++ ++ return _SUCCESS; ++ ++_mismatch: ++ kfree(bssid); ++ ++ return _FAIL; ++} ++ ++void update_beacon_info(struct adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta) ++{ ++ unsigned int i; ++ unsigned int len; ++ struct ndis_802_11_var_ie *pIE; ++ ++ len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN); ++ ++ for (i = 0; i < len;) { ++ pIE = (struct ndis_802_11_var_ie *)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i); ++ ++ switch (pIE->ElementID) { ++ case _HT_EXTRA_INFO_IE_: /* HT info */ ++ /* HT_info_handler(padapter, pIE); */ ++ bwmode_update_check(padapter, pIE); ++ break; ++ case _ERPINFO_IE_: ++ ERP_IE_handler(padapter, pIE); ++ VCS_update(padapter, psta); ++ break; ++ default: ++ break; ++ } ++ ++ i += (pIE->Length + 2); ++ } ++} ++ ++unsigned int is_ap_in_tkip(struct adapter *padapter) ++{ ++ u32 i; ++ struct ndis_802_11_var_ie *pIE; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ ++ if (rtw_get_capability((struct wlan_bssid_ex *)cur_network) & WLAN_CAPABILITY_PRIVACY) { ++ for (i = sizeof(struct ndis_802_11_fixed_ie); i < pmlmeinfo->network.IELength;) { ++ pIE = (struct ndis_802_11_var_ie *)(pmlmeinfo->network.IEs + i); ++ ++ switch (pIE->ElementID) { ++ case _VENDOR_SPECIFIC_IE_: ++ if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) && (!memcmp((pIE->data + 12), WPA_TKIP_CIPHER, 4))) ++ return true; ++ break; ++ case _RSN_IE_2_: ++ if (!memcmp((pIE->data + 8), RSN_TKIP_CIPHER, 4)) ++ return true; ++ break; ++ default: ++ break; ++ } ++ ++ i += (pIE->Length + 2); ++ } ++ return false; ++ } else { ++ return false; ++ } ++} ++ ++unsigned int should_forbid_n_rate(struct adapter *padapter) ++{ ++ u32 i; ++ struct ndis_802_11_var_ie *pIE; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *cur_network = &pmlmepriv->cur_network.network; ++ ++ if (rtw_get_capability((struct wlan_bssid_ex *)cur_network) & WLAN_CAPABILITY_PRIVACY) { ++ for (i = sizeof(struct ndis_802_11_fixed_ie); i < cur_network->IELength;) { ++ pIE = (struct ndis_802_11_var_ie *)(cur_network->IEs + i); ++ ++ switch (pIE->ElementID) { ++ case _VENDOR_SPECIFIC_IE_: ++ if (!memcmp(pIE->data, RTW_WPA_OUI, 4) && ++ ((!memcmp((pIE->data + 12), WPA_CIPHER_SUITE_CCMP, 4)) || ++ (!memcmp((pIE->data + 16), WPA_CIPHER_SUITE_CCMP, 4)))) ++ return false; ++ break; ++ case _RSN_IE_2_: ++ if ((!memcmp((pIE->data + 8), RSN_CIPHER_SUITE_CCMP, 4)) || ++ (!memcmp((pIE->data + 12), RSN_CIPHER_SUITE_CCMP, 4))) ++ return false; ++ break; ++ default: ++ break; ++ } ++ ++ i += (pIE->Length + 2); ++ } ++ ++ return true; ++ } else { ++ return false; ++ } ++} ++ ++unsigned int is_ap_in_wep(struct adapter *padapter) ++{ ++ u32 i; ++ struct ndis_802_11_var_ie *pIE; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ ++ if (rtw_get_capability((struct wlan_bssid_ex *)cur_network) & WLAN_CAPABILITY_PRIVACY) { ++ for (i = sizeof(struct ndis_802_11_fixed_ie); i < pmlmeinfo->network.IELength;) { ++ pIE = (struct ndis_802_11_var_ie *)(pmlmeinfo->network.IEs + i); ++ ++ switch (pIE->ElementID) { ++ case _VENDOR_SPECIFIC_IE_: ++ if (!memcmp(pIE->data, RTW_WPA_OUI, 4)) ++ return false; ++ break; ++ case _RSN_IE_2_: ++ return false; ++ default: ++ break; ++ } ++ i += (pIE->Length + 2); ++ } ++ return true; ++ } else { ++ return false; ++ } ++} ++ ++int wifirate2_ratetbl_inx(unsigned char rate) ++{ ++ int inx = 0; ++ rate = rate & 0x7f; ++ ++ switch (rate) { ++ case 54 * 2: ++ inx = 11; ++ break; ++ case 48 * 2: ++ inx = 10; ++ break; ++ case 36 * 2: ++ inx = 9; ++ break; ++ case 24 * 2: ++ inx = 8; ++ break; ++ case 18 * 2: ++ inx = 7; ++ break; ++ case 12 * 2: ++ inx = 6; ++ break; ++ case 9 * 2: ++ inx = 5; ++ break; ++ case 6 * 2: ++ inx = 4; ++ break; ++ case 11 * 2: ++ inx = 3; ++ break; ++ case 11: ++ inx = 2; ++ break; ++ case 2 * 2: ++ inx = 1; ++ break; ++ case 1 * 2: ++ inx = 0; ++ break; ++ } ++ return inx; ++} ++ ++unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz) ++{ ++ unsigned int i, num_of_rate; ++ unsigned int mask = 0; ++ ++ num_of_rate = (ptn_sz > NumRates) ? NumRates : ptn_sz; ++ ++ for (i = 0; i < num_of_rate; i++) { ++ if ((*(ptn + i)) & 0x80) ++ mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i)); ++ } ++ return mask; ++} ++ ++unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz) ++{ ++ unsigned int i, num_of_rate; ++ unsigned int mask = 0; ++ ++ num_of_rate = (ptn_sz > NumRates) ? NumRates : ptn_sz; ++ ++ for (i = 0; i < num_of_rate; i++) ++ mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i)); ++ return mask; ++} ++ ++unsigned int update_MSC_rate(struct HT_caps_element *pHT_caps) ++{ ++ unsigned int mask = 0; ++ ++ mask = ((pHT_caps->u.HT_cap_element.MCS_rate[0] << 12) | (pHT_caps->u.HT_cap_element.MCS_rate[1] << 20)); ++ ++ return mask; ++} ++ ++int support_short_GI(struct adapter *padapter, struct HT_caps_element *pHT_caps) ++{ ++ unsigned char bit_offset; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (!(pmlmeinfo->HT_enable)) ++ return _FAIL; ++ ++ if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_RALINK) ++ return _FAIL; ++ ++ bit_offset = (pmlmeext->cur_bwmode & HT_CHANNEL_WIDTH_40) ? 6 : 5; ++ ++ if (__le16_to_cpu(pHT_caps->u.HT_cap_element.HT_caps_info) & (0x1 << bit_offset)) ++ return _SUCCESS; ++ else ++ return _FAIL; ++} ++ ++unsigned char get_highest_rate_idx(u32 mask) ++{ ++ int i; ++ unsigned char rate_idx = 0; ++ ++ for (i = 27; i >= 0; i--) { ++ if (mask & BIT(i)) { ++ rate_idx = i; ++ break; ++ } ++ } ++ return rate_idx; ++} ++ ++void Update_RA_Entry(struct adapter *padapter, u32 mac_id) ++{ ++ rtw_hal_update_ra_mask(padapter, mac_id, 0); ++} ++ ++static void enable_rate_adaptive(struct adapter *padapter, u32 mac_id) ++{ ++ Update_RA_Entry(padapter, mac_id); ++} ++ ++void set_sta_rate(struct adapter *padapter, struct sta_info *psta) ++{ ++ /* rate adaptive */ ++ enable_rate_adaptive(padapter, psta->mac_id); ++} ++ ++/* Update RRSR and Rate for USERATE */ ++void update_tx_basic_rate(struct adapter *padapter, u8 wirelessmode) ++{ ++ unsigned char supported_rates[NDIS_802_11_LENGTH_RATES_EX]; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ /* Added by Albert 2011/03/22 */ ++ /* In the P2P mode, the driver should not support the b mode. */ ++ /* So, the Tx packet shouldn't use the CCK rate */ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return; ++#endif /* CONFIG_88EU_P2P */ ++ memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX); ++ ++ if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B)) ++ memcpy(supported_rates, rtw_basic_rate_cck, 4); ++ else if (wirelessmode & WIRELESS_11B) ++ memcpy(supported_rates, rtw_basic_rate_mix, 7); ++ else ++ memcpy(supported_rates, rtw_basic_rate_ofdm, 3); ++ ++ if (wirelessmode & WIRELESS_11B) ++ update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB); ++ else ++ update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB); ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, supported_rates); ++} ++ ++unsigned char check_assoc_AP(u8 *pframe, uint len) ++{ ++ unsigned int i; ++ struct ndis_802_11_var_ie *pIE; ++ u8 epigram_vendor_flag; ++ u8 ralink_vendor_flag; ++ epigram_vendor_flag = 0; ++ ralink_vendor_flag = 0; ++ ++ for (i = sizeof(struct ndis_802_11_fixed_ie); i < len;) { ++ pIE = (struct ndis_802_11_var_ie *)(pframe + i); ++ ++ switch (pIE->ElementID) { ++ case _VENDOR_SPECIFIC_IE_: ++ if ((!memcmp(pIE->data, ARTHEROS_OUI1, 3)) || ++ (!memcmp(pIE->data, ARTHEROS_OUI2, 3))) { ++ DBG_88E("link to Artheros AP\n"); ++ return HT_IOT_PEER_ATHEROS; ++ } else if ((!memcmp(pIE->data, BROADCOM_OUI1, 3)) || ++ (!memcmp(pIE->data, BROADCOM_OUI2, 3)) || ++ (!memcmp(pIE->data, BROADCOM_OUI2, 3))) { ++ DBG_88E("link to Broadcom AP\n"); ++ return HT_IOT_PEER_BROADCOM; ++ } else if (!memcmp(pIE->data, MARVELL_OUI, 3)) { ++ DBG_88E("link to Marvell AP\n"); ++ return HT_IOT_PEER_MARVELL; ++ } else if (!memcmp(pIE->data, RALINK_OUI, 3)) { ++ if (!ralink_vendor_flag) { ++ ralink_vendor_flag = 1; ++ } else { ++ DBG_88E("link to Ralink AP\n"); ++ return HT_IOT_PEER_RALINK; ++ } ++ } else if (!memcmp(pIE->data, CISCO_OUI, 3)) { ++ DBG_88E("link to Cisco AP\n"); ++ return HT_IOT_PEER_CISCO; ++ } else if (!memcmp(pIE->data, REALTEK_OUI, 3)) { ++ DBG_88E("link to Realtek 96B\n"); ++ return HT_IOT_PEER_REALTEK; ++ } else if (!memcmp(pIE->data, AIRGOCAP_OUI, 3)) { ++ DBG_88E("link to Airgo Cap\n"); ++ return HT_IOT_PEER_AIRGO; ++ } else if (!memcmp(pIE->data, EPIGRAM_OUI, 3)) { ++ epigram_vendor_flag = 1; ++ if (ralink_vendor_flag) { ++ DBG_88E("link to Tenda W311R AP\n"); ++ return HT_IOT_PEER_TENDA; ++ } else { ++ DBG_88E("Capture EPIGRAM_OUI\n"); ++ } ++ } else { ++ break; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ i += (pIE->Length + 2); ++ } ++ ++ if (ralink_vendor_flag && !epigram_vendor_flag) { ++ DBG_88E("link to Ralink AP\n"); ++ return HT_IOT_PEER_RALINK; ++ } else if (ralink_vendor_flag && epigram_vendor_flag) { ++ DBG_88E("link to Tenda W311R AP\n"); ++ return HT_IOT_PEER_TENDA; ++ } else { ++ DBG_88E("link to new AP\n"); ++ return HT_IOT_PEER_UNKNOWN; ++ } ++} ++ ++void update_IOT_info(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ switch (pmlmeinfo->assoc_AP_vendor) { ++ case HT_IOT_PEER_MARVELL: ++ pmlmeinfo->turboMode_cts2self = 1; ++ pmlmeinfo->turboMode_rtsen = 0; ++ break; ++ case HT_IOT_PEER_RALINK: ++ pmlmeinfo->turboMode_cts2self = 0; ++ pmlmeinfo->turboMode_rtsen = 1; ++ /* disable high power */ ++ Switch_DM_Func(padapter, (~DYNAMIC_BB_DYNAMIC_TXPWR), false); ++ break; ++ case HT_IOT_PEER_REALTEK: ++ /* rtw_write16(padapter, 0x4cc, 0xffff); */ ++ /* rtw_write16(padapter, 0x546, 0x01c0); */ ++ /* disable high power */ ++ Switch_DM_Func(padapter, (~DYNAMIC_BB_DYNAMIC_TXPWR), false); ++ break; ++ default: ++ pmlmeinfo->turboMode_cts2self = 0; ++ pmlmeinfo->turboMode_rtsen = 1; ++ break; ++ } ++} ++ ++void update_capinfo(struct adapter *Adapter, u16 updateCap) ++{ ++ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ bool ShortPreamble; ++ ++ /* Check preamble mode, 2005.01.06, by rcnjko. */ ++ /* Mark to update preamble value forever, 2008.03.18 by lanhsin */ ++ ++ if (updateCap & cShortPreamble) { /* Short Preamble */ ++ if (pmlmeinfo->preamble_mode != PREAMBLE_SHORT) { /* PREAMBLE_LONG or PREAMBLE_AUTO */ ++ ShortPreamble = true; ++ pmlmeinfo->preamble_mode = PREAMBLE_SHORT; ++ rtw_hal_set_hwreg(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble); ++ } ++ } else { /* Long Preamble */ ++ if (pmlmeinfo->preamble_mode != PREAMBLE_LONG) { /* PREAMBLE_SHORT or PREAMBLE_AUTO */ ++ ShortPreamble = false; ++ pmlmeinfo->preamble_mode = PREAMBLE_LONG; ++ rtw_hal_set_hwreg(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble); ++ } ++ } ++ ++ if (updateCap & cIBSS) { ++ /* Filen: See 802.11-2007 p.91 */ ++ pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME; ++ } else { /* Filen: See 802.11-2007 p.90 */ ++ if (pmlmeext->cur_wireless_mode & (WIRELESS_11G | WIRELESS_11_24N)) { ++ if (updateCap & cShortSlotTime) { /* Short Slot Time */ ++ if (pmlmeinfo->slotTime != SHORT_SLOT_TIME) ++ pmlmeinfo->slotTime = SHORT_SLOT_TIME; ++ } else { /* Long Slot Time */ ++ if (pmlmeinfo->slotTime != NON_SHORT_SLOT_TIME) ++ pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME; ++ } ++ } else { ++ /* B Mode */ ++ pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME; ++ } ++ } ++ ++ rtw_hal_set_hwreg(Adapter, HW_VAR_SLOT_TIME, &pmlmeinfo->slotTime); ++} ++ ++void update_wireless_mode(struct adapter *padapter) ++{ ++ int ratelen, network_type = 0; ++ u32 SIFS_Timer; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ unsigned char *rate = cur_network->SupportedRates; ++ ++ ratelen = rtw_get_rateset_len(cur_network->SupportedRates); ++ ++ if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable)) ++ pmlmeinfo->HT_enable = 1; ++ ++ if (pmlmeext->cur_channel > 14) { ++ network_type |= WIRELESS_INVALID; ++ } else { ++ if (pmlmeinfo->HT_enable) ++ network_type = WIRELESS_11_24N; ++ ++ if (cckratesonly_included(rate, ratelen)) ++ network_type |= WIRELESS_11B; ++ else if (cckrates_included(rate, ratelen)) ++ network_type |= WIRELESS_11BG; ++ else ++ network_type |= WIRELESS_11G; ++ } ++ ++ pmlmeext->cur_wireless_mode = network_type & padapter->registrypriv.wireless_mode; ++ ++ SIFS_Timer = 0x0a0a0808;/* 0x0808 -> for CCK, 0x0a0a -> for OFDM */ ++ /* change this value if having IOT issues. */ ++ ++ padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_RESP_SIFS, (u8 *)&SIFS_Timer); ++ ++ if (pmlmeext->cur_wireless_mode & WIRELESS_11B) ++ update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB); ++ else ++ update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB); ++} ++ ++void update_bmc_sta_support_rate(struct adapter *padapter, u32 mac_id) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pmlmeext->cur_wireless_mode & WIRELESS_11B) { ++ /* Only B, B/G, and B/G/N AP could use CCK rate */ ++ memcpy((pmlmeinfo->FW_sta_info[mac_id].SupportedRates), rtw_basic_rate_cck, 4); ++ } else { ++ memcpy((pmlmeinfo->FW_sta_info[mac_id].SupportedRates), rtw_basic_rate_ofdm, 3); ++ } ++} ++ ++int update_sta_support_rate(struct adapter *padapter, u8 *pvar_ie, uint var_ie_len, int cam_idx) ++{ ++ unsigned int ie_len; ++ struct ndis_802_11_var_ie *pIE; ++ int supportRateNum = 0; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ pIE = (struct ndis_802_11_var_ie *)rtw_get_ie(pvar_ie, _SUPPORTEDRATES_IE_, &ie_len, var_ie_len); ++ if (!pIE) ++ return _FAIL; ++ ++ memcpy(pmlmeinfo->FW_sta_info[cam_idx].SupportedRates, pIE->data, ie_len); ++ supportRateNum = ie_len; ++ ++ pIE = (struct ndis_802_11_var_ie *)rtw_get_ie(pvar_ie, _EXT_SUPPORTEDRATES_IE_, &ie_len, var_ie_len); ++ if (pIE) ++ memcpy((pmlmeinfo->FW_sta_info[cam_idx].SupportedRates + supportRateNum), pIE->data, ie_len); ++ ++ return _SUCCESS; ++} ++ ++void process_addba_req(struct adapter *padapter, u8 *paddba_req, u8 *addr) ++{ ++ struct sta_info *psta; ++ u16 tid; ++ u16 param; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct ADDBA_request *preq = (struct ADDBA_request *)paddba_req; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ psta = rtw_get_stainfo(pstapriv, addr); ++ ++ if (psta) { ++ param = le16_to_cpu(preq->BA_para_set); ++ tid = (param >> 2) & 0x0f; ++ preorder_ctrl = &psta->recvreorder_ctrl[tid]; ++ preorder_ctrl->indicate_seq = 0xffff; ++ preorder_ctrl->enable = (pmlmeinfo->bAcceptAddbaReq) ? true : false; ++ } ++} ++ ++void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len) ++{ ++ u8 *pIE; ++ __le32 *pbuf; ++ ++ pIE = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); ++ pbuf = (__le32 *)pIE; ++ ++ pmlmeext->TSFValue = le32_to_cpu(*(pbuf + 1)); ++ ++ pmlmeext->TSFValue = pmlmeext->TSFValue << 32; ++ ++ pmlmeext->TSFValue |= le32_to_cpu(*pbuf); ++} ++ ++void correct_TSF(struct adapter *padapter, struct mlme_ext_priv *pmlmeext) ++{ ++ rtw_hal_set_hwreg(padapter, HW_VAR_CORRECT_TSF, NULL); ++} ++ ++void beacon_timing_control(struct adapter *padapter) ++{ ++ rtw_hal_bcn_related_reg_setting(padapter); ++} ++ ++static struct adapter *pbuddy_padapter; ++ ++int rtw_handle_dualmac(struct adapter *adapter, bool init) ++{ ++ int status = _SUCCESS; ++ ++ if (init) { ++ if (!pbuddy_padapter) { ++ pbuddy_padapter = adapter; ++ DBG_88E("%s(): pbuddy_padapter == NULL, Set pbuddy_padapter\n", __func__); ++ } else { ++ adapter->pbuddy_adapter = pbuddy_padapter; ++ pbuddy_padapter->pbuddy_adapter = adapter; ++ /* clear global value */ ++ pbuddy_padapter = NULL; ++ DBG_88E("%s(): pbuddy_padapter exist, Exchange Information\n", __func__); ++ } ++ } else { ++ pbuddy_padapter = NULL; ++ } ++ return status; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_xmit.c b/drivers/staging/r8188eu/core/rtw_xmit.c +new file mode 100644 +index 000000000000..46fe62c7c32c +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_xmit.c +@@ -0,0 +1,2240 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_XMIT_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wifi.h" ++#include "../include/osdep_intf.h" ++#include "../include/usb_ops.h" ++#include "../include/usb_osintf.h" ++ ++static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; ++static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; ++ ++static void _init_txservq(struct tx_servq *ptxservq) ++{ ++ ++ INIT_LIST_HEAD(&ptxservq->tx_pending); ++ _rtw_init_queue(&ptxservq->sta_pending); ++ ptxservq->qcnt = 0; ++ ++} ++ ++void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv) ++{ ++ ++ memset((unsigned char *)psta_xmitpriv, 0, sizeof(struct sta_xmit_priv)); ++ spin_lock_init(&psta_xmitpriv->lock); ++ _init_txservq(&psta_xmitpriv->be_q); ++ _init_txservq(&psta_xmitpriv->bk_q); ++ _init_txservq(&psta_xmitpriv->vi_q); ++ _init_txservq(&psta_xmitpriv->vo_q); ++ INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz); ++ INIT_LIST_HEAD(&psta_xmitpriv->apsd); ++ ++} ++ ++s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) ++{ ++ int i; ++ struct xmit_buf *pxmitbuf; ++ struct xmit_frame *pxframe; ++ int res = _SUCCESS; ++ u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; ++ u32 num_xmit_extbuf = NR_XMIT_EXTBUFF; ++ ++ /* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */ ++ ++ spin_lock_init(&pxmitpriv->lock); ++ sema_init(&pxmitpriv->xmit_sema, 0); ++ sema_init(&pxmitpriv->terminate_xmitthread_sema, 0); ++ ++ /* ++ Please insert all the queue initializaiton using _rtw_init_queue below ++ */ ++ ++ pxmitpriv->adapter = padapter; ++ ++ _rtw_init_queue(&pxmitpriv->be_pending); ++ _rtw_init_queue(&pxmitpriv->bk_pending); ++ _rtw_init_queue(&pxmitpriv->vi_pending); ++ _rtw_init_queue(&pxmitpriv->vo_pending); ++ _rtw_init_queue(&pxmitpriv->bm_pending); ++ ++ _rtw_init_queue(&pxmitpriv->free_xmit_queue); ++ ++ /* ++ Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME, ++ and initialize free_xmit_frame below. ++ Please also apply free_txobj to link_up all the xmit_frames... ++ */ ++ ++ pxmitpriv->pallocated_frame_buf = vzalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4); ++ ++ if (!pxmitpriv->pallocated_frame_buf) { ++ pxmitpriv->pxmit_frame_buf = NULL; ++ res = _FAIL; ++ goto exit; ++ } ++ pxmitpriv->pxmit_frame_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_frame_buf), 4); ++ /* pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 - */ ++ /* ((size_t) (pxmitpriv->pallocated_frame_buf) &3); */ ++ ++ pxframe = (struct xmit_frame *)pxmitpriv->pxmit_frame_buf; ++ ++ for (i = 0; i < NR_XMITFRAME; i++) { ++ INIT_LIST_HEAD(&pxframe->list); ++ ++ pxframe->padapter = padapter; ++ pxframe->frame_tag = NULL_FRAMETAG; ++ ++ pxframe->pkt = NULL; ++ ++ pxframe->buf_addr = NULL; ++ pxframe->pxmitbuf = NULL; ++ ++ list_add_tail(&pxframe->list, &pxmitpriv->free_xmit_queue.queue); ++ ++ pxframe++; ++ } ++ ++ pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME; ++ ++ pxmitpriv->frag_len = MAX_FRAG_THRESHOLD; ++ ++ /* init xmit_buf */ ++ _rtw_init_queue(&pxmitpriv->free_xmitbuf_queue); ++ _rtw_init_queue(&pxmitpriv->pending_xmitbuf_queue); ++ ++ pxmitpriv->pallocated_xmitbuf = vzalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4); ++ ++ if (!pxmitpriv->pallocated_xmitbuf) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pxmitpriv->pxmitbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_xmitbuf), 4); ++ /* pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - */ ++ /* ((size_t) (pxmitpriv->pallocated_xmitbuf) &3); */ ++ ++ pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; ++ ++ for (i = 0; i < NR_XMITBUFF; i++) { ++ INIT_LIST_HEAD(&pxmitbuf->list); ++ ++ pxmitbuf->priv_data = NULL; ++ pxmitbuf->padapter = padapter; ++ pxmitbuf->ext_tag = false; ++ ++ /* Tx buf allocation may fail sometimes, so sleep and retry. */ ++ res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ)); ++ if (res == _FAIL) { ++ msleep(10); ++ res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ)); ++ if (res == _FAIL) { ++ goto exit; ++ } ++ } ++ ++ pxmitbuf->flags = XMIT_VO_QUEUE; ++ ++ list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmitbuf_queue.queue); ++ pxmitbuf++; ++ } ++ ++ pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF; ++ ++ /* Init xmit extension buff */ ++ _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue); ++ ++ pxmitpriv->pallocated_xmit_extbuf = vzalloc(num_xmit_extbuf * sizeof(struct xmit_buf) + 4); ++ ++ if (!pxmitpriv->pallocated_xmit_extbuf) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_xmit_extbuf), 4); ++ ++ pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; ++ ++ for (i = 0; i < num_xmit_extbuf; i++) { ++ INIT_LIST_HEAD(&pxmitbuf->list); ++ ++ pxmitbuf->priv_data = NULL; ++ pxmitbuf->padapter = padapter; ++ pxmitbuf->ext_tag = true; ++ ++ res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ); ++ if (res == _FAIL) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmit_extbuf_queue.queue); ++ pxmitbuf++; ++ } ++ ++ pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf; ++ ++ rtw_alloc_hwxmits(padapter); ++ rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); ++ ++ for (i = 0; i < 4; i++) ++ pxmitpriv->wmm_para_seq[i] = i; ++ ++ pxmitpriv->txirp_cnt = 1; ++ ++ sema_init(&pxmitpriv->tx_retevt, 0); ++ ++ /* per AC pending irp */ ++ pxmitpriv->beq_cnt = 0; ++ pxmitpriv->bkq_cnt = 0; ++ pxmitpriv->viq_cnt = 0; ++ pxmitpriv->voq_cnt = 0; ++ ++ pxmitpriv->ack_tx = false; ++ _rtw_mutex_init(&pxmitpriv->ack_tx_mutex); ++ rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0); ++ ++ rtw_hal_init_xmit_priv(padapter); ++ ++exit: ++ ++ return res; ++} ++ ++void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv) ++{ ++ int i; ++ struct adapter *padapter = pxmitpriv->adapter; ++ struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitpriv->pxmit_frame_buf; ++ struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; ++ u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; ++ u32 num_xmit_extbuf = NR_XMIT_EXTBUFF; ++ ++ if (!pxmitpriv->pxmit_frame_buf) ++ return; ++ ++ for (i = 0; i < NR_XMITFRAME; i++) { ++ rtw_os_xmit_complete(padapter, pxmitframe); ++ ++ pxmitframe++; ++ } ++ ++ for (i = 0; i < NR_XMITBUFF; i++) { ++ rtw_os_xmit_resource_free(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ)); ++ pxmitbuf++; ++ } ++ ++ vfree(pxmitpriv->pallocated_frame_buf); ++ ++ vfree(pxmitpriv->pallocated_xmitbuf); ++ ++ pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; ++ for (i = 0; i < num_xmit_extbuf; i++) { ++ rtw_os_xmit_resource_free(padapter, pxmitbuf, (max_xmit_extbuf_size + XMITBUF_ALIGN_SZ)); ++ pxmitbuf++; ++ } ++ ++ vfree(pxmitpriv->pallocated_xmit_extbuf); ++ ++ rtw_free_hwxmits(padapter); ++ ++ _rtw_mutex_free(&pxmitpriv->ack_tx_mutex); ++} ++ ++static void update_attrib_vcs_info(struct adapter *padapter, struct xmit_frame *pxmitframe) ++{ ++ u32 sz; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ struct sta_info *psta = pattrib->psta; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pattrib->nr_frags != 1) ++ sz = padapter->xmitpriv.frag_len; ++ else /* no frag */ ++ sz = pattrib->last_txcmdsz; ++ ++ /* (1) RTS_Threshold is compared to the MPDU, not MSDU. */ ++ /* (2) If there are more than one frag in this MSDU, only the first frag uses protection frame. */ ++ /* Other fragments are protected by previous fragment. */ ++ /* So we only need to check the length of first fragment. */ ++ if (pmlmeext->cur_wireless_mode < WIRELESS_11_24N || padapter->registrypriv.wifi_spec) { ++ if (sz > padapter->registrypriv.rts_thresh) { ++ pattrib->vcs_mode = RTS_CTS; ++ } else { ++ if (psta->rtsen) ++ pattrib->vcs_mode = RTS_CTS; ++ else if (psta->cts2self) ++ pattrib->vcs_mode = CTS_TO_SELF; ++ else ++ pattrib->vcs_mode = NONE_VCS; ++ } ++ } else { ++ while (true) { ++ /* IOT action */ ++ if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS) && pattrib->ampdu_en && ++ (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) { ++ pattrib->vcs_mode = CTS_TO_SELF; ++ break; ++ } ++ ++ /* check ERP protection */ ++ if (psta->rtsen || psta->cts2self) { ++ if (psta->rtsen) ++ pattrib->vcs_mode = RTS_CTS; ++ else if (psta->cts2self) ++ pattrib->vcs_mode = CTS_TO_SELF; ++ ++ break; ++ } ++ ++ /* check HT op mode */ ++ if (pattrib->ht_en) { ++ u8 htopmode = pmlmeinfo->HT_protection; ++ if ((pmlmeext->cur_bwmode && (htopmode == 2 || htopmode == 3)) || ++ (!pmlmeext->cur_bwmode && htopmode == 3)) { ++ pattrib->vcs_mode = RTS_CTS; ++ break; ++ } ++ } ++ ++ /* check rts */ ++ if (sz > padapter->registrypriv.rts_thresh) { ++ pattrib->vcs_mode = RTS_CTS; ++ break; ++ } ++ ++ /* to do list: check MIMO power save condition. */ ++ ++ /* check AMPDU aggregation for TXOP */ ++ if (pattrib->ampdu_en) { ++ pattrib->vcs_mode = RTS_CTS; ++ break; ++ } ++ ++ pattrib->vcs_mode = NONE_VCS; ++ break; ++ } ++ } ++} ++ ++static void update_attrib_phy_info(struct pkt_attrib *pattrib, struct sta_info *psta) ++{ ++ /*if (psta->rtsen) ++ pattrib->vcs_mode = RTS_CTS; ++ else if (psta->cts2self) ++ pattrib->vcs_mode = CTS_TO_SELF; ++ else ++ pattrib->vcs_mode = NONE_VCS;*/ ++ ++ pattrib->mdata = 0; ++ pattrib->eosp = 0; ++ pattrib->triggered = 0; ++ ++ /* qos_en, ht_en, init rate, , bw, ch_offset, sgi */ ++ pattrib->qos_en = psta->qos_option; ++ ++ pattrib->raid = psta->raid; ++ pattrib->ht_en = psta->htpriv.ht_option; ++ pattrib->bwmode = psta->htpriv.bwmode; ++ pattrib->ch_offset = psta->htpriv.ch_offset; ++ pattrib->sgi = psta->htpriv.sgi; ++ pattrib->ampdu_en = false; ++ pattrib->retry_ctrl = false; ++} ++ ++u8 qos_acm(u8 acm_mask, u8 priority) ++{ ++ u8 change_priority = priority; ++ ++ switch (priority) { ++ case 0: ++ case 3: ++ if (acm_mask & BIT(1)) ++ change_priority = 1; ++ break; ++ case 1: ++ case 2: ++ break; ++ case 4: ++ case 5: ++ if (acm_mask & BIT(2)) ++ change_priority = 0; ++ break; ++ case 6: ++ case 7: ++ if (acm_mask & BIT(3)) ++ change_priority = 5; ++ break; ++ default: ++ DBG_88E("qos_acm(): invalid pattrib->priority: %d!!!\n", priority); ++ break; ++ } ++ ++ return change_priority; ++} ++ ++static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib) ++{ ++ struct ethhdr etherhdr; ++ struct iphdr ip_hdr; ++ s32 user_prio = 0; ++ ++ _rtw_open_pktfile(ppktfile->pkt, ppktfile); ++ _rtw_pktfile_read(ppktfile, (unsigned char *)ðerhdr, ETH_HLEN); ++ ++ /* get user_prio from IP hdr */ ++ if (pattrib->ether_type == 0x0800) { ++ _rtw_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr)); ++/* user_prio = (ntohs(ip_hdr.tos) >> 5) & 0x3; */ ++ user_prio = ip_hdr.tos >> 5; ++ } else if (pattrib->ether_type == 0x888e) { ++ /* "When priority processing of data frames is supported, */ ++ /* a STA's SME should send EAPOL-Key frames at the highest priority." */ ++ user_prio = 7; ++ } ++ ++ pattrib->priority = user_prio; ++ pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN; ++ pattrib->subtype = WIFI_QOS_DATA_TYPE; ++} ++ ++static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct pkt_attrib *pattrib) ++{ ++ struct pkt_file pktfile; ++ struct sta_info *psta = NULL; ++ struct ethhdr etherhdr; ++ ++ bool bmcast; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct qos_priv *pqospriv = &pmlmepriv->qospriv; ++ int res = _SUCCESS; ++ ++ ++ ++ _rtw_open_pktfile(pkt, &pktfile); ++ _rtw_pktfile_read(&pktfile, (u8 *)ðerhdr, ETH_HLEN); ++ ++ pattrib->ether_type = ntohs(etherhdr.h_proto); ++ ++ memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN); ++ memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN); ++ ++ pattrib->pctrl = 0; ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); ++ memcpy(pattrib->ta, pattrib->src, ETH_ALEN); ++ } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); ++ memcpy(pattrib->ta, pattrib->src, ETH_ALEN); ++ } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); ++ memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN); ++ } ++ ++ pattrib->pktlen = pktfile.pkt_len; ++ ++ if (ETH_P_IP == pattrib->ether_type) { ++ /* The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time */ ++ /* to prevent DHCP protocol fail */ ++ u8 tmp[24]; ++ _rtw_pktfile_read(&pktfile, &tmp[0], 24); ++ pattrib->dhcp_pkt = 0; ++ if (pktfile.pkt_len > 282) {/* MINIMUM_DHCP_PACKET_SIZE) { */ ++ if (ETH_P_IP == pattrib->ether_type) {/* IP header */ ++ if (((tmp[21] == 68) && (tmp[23] == 67)) || ++ ((tmp[21] == 67) && (tmp[23] == 68))) { ++ /* 68 : UDP BOOTP client */ ++ /* 67 : UDP BOOTP server */ ++ /* Use low rate to send DHCP packet. */ ++ pattrib->dhcp_pkt = 1; ++ } ++ } ++ } ++ } else if (0x888e == pattrib->ether_type) { ++ DBG_88E_LEVEL(_drv_info_, "send eapol packet\n"); ++ } ++ ++ if ((pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1)) ++ rtw_set_scan_deny(padapter, 3000); ++ ++ /* If EAPOL , ARP , OR DHCP packet, driver must be in active mode. */ ++ if ((pattrib->ether_type == 0x0806) || (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1)) ++ rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1); ++ ++ bmcast = is_multicast_ether_addr(pattrib->ra); ++ ++ /* get sta_info */ ++ if (bmcast) { ++ psta = rtw_get_bcmc_stainfo(padapter); ++ } else { ++ psta = rtw_get_stainfo(pstapriv, pattrib->ra); ++ if (!psta) { /* if we cannot get psta => drrp the pkt */ ++ res = _FAIL; ++ goto exit; ++ } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) && !(psta->state & _FW_LINKED)) { ++ res = _FAIL; ++ goto exit; ++ } ++ } ++ ++ if (psta) { ++ pattrib->mac_id = psta->mac_id; ++ /* DBG_88E("%s ==> mac_id(%d)\n", __func__, pattrib->mac_id); */ ++ pattrib->psta = psta; ++ } else { ++ /* if we cannot get psta => drop the pkt */ ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pattrib->ack_policy = 0; ++ /* get ether_hdr_len */ ++ pattrib->pkt_hdrlen = ETH_HLEN;/* pattrib->ether_type == 0x8100) ? (14 + 4): 14; vlan tag */ ++ ++ pattrib->hdrlen = WLAN_HDR_A3_LEN; ++ pattrib->subtype = WIFI_DATA_TYPE; ++ pattrib->priority = 0; ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) { ++ if (psta->qos_option) ++ set_qos(&pktfile, pattrib); ++ } else { ++ if (pqospriv->qos_option) { ++ set_qos(&pktfile, pattrib); ++ ++ if (pmlmepriv->acm_mask != 0) ++ pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority); ++ } ++ } ++ ++ if (psta->ieee8021x_blocked) { ++ pattrib->encrypt = 0; ++ ++ if ((pattrib->ether_type != 0x888e) && !check_fwstate(pmlmepriv, WIFI_MP_STATE)) { ++ res = _FAIL; ++ goto exit; ++ } ++ } else { ++ GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast); ++ ++ switch (psecuritypriv->dot11AuthAlgrthm) { ++ case dot11AuthAlgrthm_Open: ++ case dot11AuthAlgrthm_Shared: ++ case dot11AuthAlgrthm_Auto: ++ pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex; ++ break; ++ case dot11AuthAlgrthm_8021X: ++ if (bmcast) ++ pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid; ++ else ++ pattrib->key_idx = 0; ++ break; ++ default: ++ pattrib->key_idx = 0; ++ break; ++ } ++ } ++ ++ switch (pattrib->encrypt) { ++ case _WEP40_: ++ case _WEP104_: ++ pattrib->iv_len = 4; ++ pattrib->icv_len = 4; ++ break; ++ case _TKIP_: ++ pattrib->iv_len = 8; ++ pattrib->icv_len = 4; ++ ++ if (padapter->securitypriv.busetkipkey == _FAIL) { ++ res = _FAIL; ++ goto exit; ++ } ++ break; ++ case _AES_: ++ pattrib->iv_len = 8; ++ pattrib->icv_len = 8; ++ break; ++ default: ++ pattrib->iv_len = 0; ++ pattrib->icv_len = 0; ++ break; ++ } ++ ++ if (pattrib->encrypt && ++ (padapter->securitypriv.sw_encrypt || !psecuritypriv->hw_decrypted)) ++ pattrib->bswenc = true; ++ else ++ pattrib->bswenc = false; ++ ++ rtw_set_tx_chksum_offload(pkt, pattrib); ++ ++ update_attrib_phy_info(pattrib, psta); ++ ++exit: ++ ++ return res; ++} ++ ++static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitframe) ++{ ++ int curfragnum, length; ++ u8 *pframe, *payload, mic[8]; ++ struct mic_data micdata; ++ struct sta_info *stainfo; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ u8 priority[4] = {0x0, 0x0, 0x0, 0x0}; ++ u8 hw_hdr_offset = 0; ++ ++ if (pattrib->psta) ++ stainfo = pattrib->psta; ++ else ++ stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]); ++ ++ hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ); ++ ++ if (pattrib->encrypt == _TKIP_) {/* if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_PRIVACY_) */ ++ /* encode mic code */ ++ if (stainfo) { ++ u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0}; ++ ++ pframe = pxmitframe->buf_addr + hw_hdr_offset; ++ ++ if (is_multicast_ether_addr(pattrib->ra)) { ++ if (!memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16)) ++ return _FAIL; ++ /* start to calculate the mic code */ ++ rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey); ++ } else { ++ if (!memcmp(&stainfo->dot11tkiptxmickey.skey[0], null_key, 16)) { ++ /* msleep(10); */ ++ return _FAIL; ++ } ++ /* start to calculate the mic code */ ++ rtw_secmicsetkey(&micdata, &stainfo->dot11tkiptxmickey.skey[0]); ++ } ++ ++ if (pframe[1] & 1) { /* ToDS == 1 */ ++ rtw_secmicappend(&micdata, &pframe[16], 6); /* DA */ ++ if (pframe[1] & 2) /* From Ds == 1 */ ++ rtw_secmicappend(&micdata, &pframe[24], 6); ++ else ++ rtw_secmicappend(&micdata, &pframe[10], 6); ++ } else { /* ToDS == 0 */ ++ rtw_secmicappend(&micdata, &pframe[4], 6); /* DA */ ++ if (pframe[1] & 2) /* From Ds == 1 */ ++ rtw_secmicappend(&micdata, &pframe[16], 6); ++ else ++ rtw_secmicappend(&micdata, &pframe[10], 6); ++ } ++ ++ if (pattrib->qos_en) ++ priority[0] = (u8)pxmitframe->attrib.priority; ++ ++ rtw_secmicappend(&micdata, &priority[0], 4); ++ ++ payload = pframe; ++ ++ for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { ++ payload = (u8 *)RND4((size_t)(payload)); ++ ++ payload = payload + pattrib->hdrlen + pattrib->iv_len; ++ if ((curfragnum + 1) == pattrib->nr_frags) { ++ length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - ((pattrib->bswenc) ? pattrib->icv_len : 0); ++ rtw_secmicappend(&micdata, payload, length); ++ payload = payload + length; ++ } else { ++ length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - ((pattrib->bswenc) ? pattrib->icv_len : 0); ++ rtw_secmicappend(&micdata, payload, length); ++ payload = payload + length + pattrib->icv_len; ++ } ++ } ++ rtw_secgetmic(&micdata, &mic[0]); ++ /* add mic code and add the mic code length in last_txcmdsz */ ++ ++ memcpy(payload, &mic[0], 8); ++ pattrib->last_txcmdsz += 8; ++ ++ payload = payload - pattrib->last_txcmdsz + 8; ++ } ++ } ++ ++ return _SUCCESS; ++} ++ ++static s32 xmitframe_swencrypt(struct adapter *padapter, struct xmit_frame *pxmitframe) ++{ ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ ++ if (pattrib->bswenc) { ++ switch (pattrib->encrypt) { ++ case _WEP40_: ++ case _WEP104_: ++ rtw_wep_encrypt(padapter, (u8 *)pxmitframe); ++ break; ++ case _TKIP_: ++ rtw_tkip_encrypt(padapter, (u8 *)pxmitframe); ++ break; ++ case _AES_: ++ rtw_aes_encrypt(padapter, (u8 *)pxmitframe); ++ break; ++ default: ++ break; ++ } ++ } ++ ++ return _SUCCESS; ++} ++ ++s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib) ++{ ++ u16 *qc; ++ ++ struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct qos_priv *pqospriv = &pmlmepriv->qospriv; ++ u8 qos_option = false; ++ ++ int res = _SUCCESS; ++ __le16 *fctrl = &pwlanhdr->frame_ctl; ++ ++ struct sta_info *psta; ++ ++ if (pattrib->psta) { ++ psta = pattrib->psta; ++ } else { ++ if (is_multicast_ether_addr(pattrib->ra)) { ++ psta = rtw_get_bcmc_stainfo(padapter); ++ } else { ++ psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); ++ } ++ } ++ ++ memset(hdr, 0, WLANHDR_OFFSET); ++ ++ SetFrameSubType(fctrl, pattrib->subtype); ++ ++ if (pattrib->subtype & WIFI_DATA_TYPE) { ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ /* to_ds = 1, fr_ds = 0; */ ++ /* Data transfer to AP */ ++ SetToDs(fctrl); ++ memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); ++ ++ if (pqospriv->qos_option) ++ qos_option = true; ++ } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ /* to_ds = 0, fr_ds = 1; */ ++ SetFrDs(fctrl); ++ memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN); ++ ++ if (psta->qos_option) ++ qos_option = true; ++ } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN); ++ ++ if (psta->qos_option) ++ qos_option = true; ++ } else { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ if (pattrib->mdata) ++ SetMData(fctrl); ++ ++ if (pattrib->encrypt) ++ SetPrivacy(fctrl); ++ ++ if (qos_option) { ++ qc = (unsigned short *)(hdr + pattrib->hdrlen - 2); ++ ++ if (pattrib->priority) ++ SetPriority(qc, pattrib->priority); ++ ++ SetEOSP(qc, pattrib->eosp); ++ ++ SetAckpolicy(qc, pattrib->ack_policy); ++ } ++ ++ /* TODO: fill HT Control Field */ ++ ++ /* Update Seq Num will be handled by f/w */ ++ if (psta) { ++ psta->sta_xmitpriv.txseq_tid[pattrib->priority]++; ++ psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF; ++ ++ pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority]; ++ ++ SetSeqNum(hdr, pattrib->seqnum); ++ ++ /* check if enable ampdu */ ++ if (pattrib->ht_en && psta->htpriv.ampdu_enable) { ++ if (psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority)) ++ pattrib->ampdu_en = true; ++ } ++ ++ /* re-check if enable ampdu by BA_starting_seqctrl */ ++ if (pattrib->ampdu_en) { ++ u16 tx_seq; ++ ++ tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f]; ++ ++ /* check BA_starting_seqctrl */ ++ if (SN_LESS(pattrib->seqnum, tx_seq)) { ++ pattrib->ampdu_en = false;/* AGG BK */ ++ } else if (SN_EQUAL(pattrib->seqnum, tx_seq)) { ++ psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq + 1) & 0xfff; ++ ++ pattrib->ampdu_en = true;/* AGG EN */ ++ } else { ++ psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum + 1) & 0xfff; ++ pattrib->ampdu_en = true;/* AGG EN */ ++ } ++ } ++ } ++ } ++exit: ++ ++ return res; ++} ++ ++s32 rtw_txframes_pending(struct adapter *padapter) ++{ ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ return (!list_empty(&pxmitpriv->be_pending.queue) || ++ !list_empty(&pxmitpriv->bk_pending.queue) || ++ !list_empty(&pxmitpriv->vi_pending.queue) || ++ !list_empty(&pxmitpriv->vo_pending.queue)); ++} ++ ++s32 rtw_txframes_sta_ac_pending(struct adapter *padapter, struct pkt_attrib *pattrib) ++{ ++ struct sta_info *psta; ++ struct tx_servq *ptxservq; ++ int priority = pattrib->priority; ++ ++ psta = pattrib->psta; ++ ++ switch (priority) { ++ case 1: ++ case 2: ++ ptxservq = &psta->sta_xmitpriv.bk_q; ++ break; ++ case 4: ++ case 5: ++ ptxservq = &psta->sta_xmitpriv.vi_q; ++ break; ++ case 6: ++ case 7: ++ ptxservq = &psta->sta_xmitpriv.vo_q; ++ break; ++ case 0: ++ case 3: ++ default: ++ ptxservq = &psta->sta_xmitpriv.be_q; ++ break; ++ } ++ ++ if (ptxservq) ++ return ptxservq->qcnt; ++ return 0; ++} ++ ++/* ++ * Calculate wlan 802.11 packet MAX size from pkt_attrib ++ * This function doesn't consider fragment case ++ */ ++u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib) ++{ ++ u32 len = 0; ++ ++ len = pattrib->hdrlen + pattrib->iv_len; /* WLAN Header and IV */ ++ len += SNAP_SIZE + sizeof(u16); /* LLC */ ++ len += pattrib->pktlen; ++ if (pattrib->encrypt == _TKIP_) ++ len += 8; /* MIC */ ++ len += ((pattrib->bswenc) ? pattrib->icv_len : 0); /* ICV */ ++ ++ return len; ++} ++ ++/* ++ ++This sub-routine will perform all the following: ++ ++1. remove 802.3 header. ++2. create wlan_header, based on the info in pxmitframe ++3. append sta's iv/ext-iv ++4. append LLC ++5. move frag chunk from pframe to pxmitframe->mem ++6. apply sw-encrypt, if necessary. ++ ++*/ ++s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct xmit_frame *pxmitframe) ++{ ++ struct pkt_file pktfile; ++ s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz; ++ size_t addr; ++ u8 *pframe, *mem_start; ++ u8 hw_hdr_offset; ++ struct sta_info *psta; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ u8 *pbuf_start; ++ bool bmcst = is_multicast_ether_addr(pattrib->ra); ++ s32 res = _SUCCESS; ++ ++ if (!pkt) ++ return _FAIL; ++ ++ psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); ++ ++ if (!psta) ++ return _FAIL; ++ ++ if (!pxmitframe->buf_addr) { ++ DBG_88E("==> %s buf_addr == NULL\n", __func__); ++ return _FAIL; ++ } ++ ++ pbuf_start = pxmitframe->buf_addr; ++ ++ hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ); ++ ++ mem_start = pbuf_start + hw_hdr_offset; ++ ++ if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) { ++ DBG_88E("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n"); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ _rtw_open_pktfile(pkt, &pktfile); ++ _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen); ++ ++ frg_inx = 0; ++ frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */ ++ ++ while (1) { ++ llc_sz = 0; ++ ++ mpdu_len = frg_len; ++ ++ pframe = mem_start; ++ ++ SetMFrag(mem_start); ++ ++ pframe += pattrib->hdrlen; ++ mpdu_len -= pattrib->hdrlen; ++ ++ /* adding icv, if necessary... */ ++ if (pattrib->iv_len) { ++ if (psta) { ++ switch (pattrib->encrypt) { ++ case _WEP40_: ++ case _WEP104_: ++ WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); ++ break; ++ case _TKIP_: ++ if (bmcst) ++ TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); ++ else ++ TKIP_IV(pattrib->iv, psta->dot11txpn, 0); ++ break; ++ case _AES_: ++ if (bmcst) ++ AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); ++ else ++ AES_IV(pattrib->iv, psta->dot11txpn, 0); ++ break; ++ } ++ } ++ ++ memcpy(pframe, pattrib->iv, pattrib->iv_len); ++ ++ pframe += pattrib->iv_len; ++ ++ mpdu_len -= pattrib->iv_len; ++ } ++ ++ if (frg_inx == 0) { ++ llc_sz = rtw_put_snap(pframe, pattrib->ether_type); ++ pframe += llc_sz; ++ mpdu_len -= llc_sz; ++ } ++ ++ if ((pattrib->icv_len > 0) && (pattrib->bswenc)) { ++ mpdu_len -= pattrib->icv_len; ++ } ++ ++ if (bmcst) { ++ /* don't do fragment to broadcat/multicast packets */ ++ mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen); ++ } else { ++ mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len); ++ } ++ ++ pframe += mem_sz; ++ ++ if ((pattrib->icv_len > 0) && (pattrib->bswenc)) { ++ memcpy(pframe, pattrib->icv, pattrib->icv_len); ++ pframe += pattrib->icv_len; ++ } ++ ++ frg_inx++; ++ ++ if (bmcst || rtw_endofpktfile(&pktfile)) { ++ pattrib->nr_frags = frg_inx; ++ ++ pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + ((pattrib->nr_frags == 1) ? llc_sz : 0) + ++ ((pattrib->bswenc) ? pattrib->icv_len : 0) + mem_sz; ++ ++ ClearMFrag(mem_start); ++ ++ break; ++ } ++ ++ addr = (size_t)(pframe); ++ ++ mem_start = (unsigned char *)RND4(addr) + hw_hdr_offset; ++ memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen); ++ } ++ ++ if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) { ++ DBG_88E("xmitframe_addmic(padapter, pxmitframe) == _FAIL\n"); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ xmitframe_swencrypt(padapter, pxmitframe); ++ ++ if (!bmcst) ++ update_attrib_vcs_info(padapter, pxmitframe); ++ else ++ pattrib->vcs_mode = NONE_VCS; ++ ++exit: ++ ++ return res; ++} ++ ++/* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header ++ * IEEE LLC/SNAP header contains 8 octets ++ * First 3 octets comprise the LLC portion ++ * SNAP portion, 5 octets, is divided into two fields: ++ * Organizationally Unique Identifier(OUI), 3 octets, ++ * type, defined by that organization, 2 octets. ++ */ ++s32 rtw_put_snap(u8 *data, u16 h_proto) ++{ ++ struct ieee80211_snap_hdr *snap; ++ u8 *oui; ++ ++ snap = (struct ieee80211_snap_hdr *)data; ++ snap->dsap = 0xaa; ++ snap->ssap = 0xaa; ++ snap->ctrl = 0x03; ++ ++ if (h_proto == 0x8137 || h_proto == 0x80f3) ++ oui = P802_1H_OUI; ++ else ++ oui = RFC1042_OUI; ++ ++ snap->oui[0] = oui[0]; ++ snap->oui[1] = oui[1]; ++ snap->oui[2] = oui[2]; ++ ++ *(__be16 *)(data + SNAP_SIZE) = htons(h_proto); ++ ++ return SNAP_SIZE + sizeof(u16); ++} ++ ++void rtw_update_protection(struct adapter *padapter, u8 *ie, uint ie_len) ++{ ++ uint protection; ++ u8 *perp; ++ int erp_len; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ ++ switch (pxmitpriv->vcs_setting) { ++ case DISABLE_VCS: ++ pxmitpriv->vcs = NONE_VCS; ++ break; ++ case ENABLE_VCS: ++ break; ++ case AUTO_VCS: ++ default: ++ perp = rtw_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len); ++ if (!perp) { ++ pxmitpriv->vcs = NONE_VCS; ++ } else { ++ protection = (*(perp + 2)) & BIT(1); ++ if (protection) { ++ if (pregistrypriv->vcs_type == RTS_CTS) ++ pxmitpriv->vcs = RTS_CTS; ++ else ++ pxmitpriv->vcs = CTS_TO_SELF; ++ } else { ++ pxmitpriv->vcs = NONE_VCS; ++ } ++ } ++ break; ++ } ++ ++} ++ ++void rtw_count_tx_stats(struct adapter *padapter, struct xmit_frame *pxmitframe, int sz) ++{ ++ struct sta_info *psta = NULL; ++ struct stainfo_stats *pstats = NULL; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) { ++ pxmitpriv->tx_bytes += sz; ++ pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pxmitframe->agg_num; ++ ++ psta = pxmitframe->attrib.psta; ++ if (psta) { ++ pstats = &psta->sta_stats; ++ pstats->tx_pkts += pxmitframe->agg_num; ++ pstats->tx_bytes += sz; ++ } ++ } ++} ++ ++struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv) ++{ ++ struct xmit_buf *pxmitbuf = NULL; ++ struct list_head *plist, *phead; ++ struct __queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&pfree_queue->lock, flags); ++ ++ if (list_empty(&pfree_queue->queue)) { ++ pxmitbuf = NULL; ++ } else { ++ phead = get_list_head(pfree_queue); ++ ++ plist = phead->next; ++ ++ pxmitbuf = container_of(plist, struct xmit_buf, list); ++ ++ list_del_init(&pxmitbuf->list); ++ } ++ ++ if (pxmitbuf) { ++ pxmitpriv->free_xmit_extbuf_cnt--; ++ ++ pxmitbuf->priv_data = NULL; ++ /* pxmitbuf->ext_tag = true; */ ++ ++ if (pxmitbuf->sctx) { ++ DBG_88E("%s pxmitbuf->sctx is not NULL\n", __func__); ++ rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC); ++ } ++ } ++ ++ spin_unlock_irqrestore(&pfree_queue->lock, flags); ++ ++ return pxmitbuf; ++} ++ ++s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) ++{ ++ struct __queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue; ++ unsigned long flags; ++ ++ if (!pxmitbuf) ++ return _FAIL; ++ ++ spin_lock_irqsave(&pfree_queue->lock, flags); ++ ++ list_del_init(&pxmitbuf->list); ++ ++ list_add_tail(&pxmitbuf->list, get_list_head(pfree_queue)); ++ pxmitpriv->free_xmit_extbuf_cnt++; ++ ++ spin_unlock_irqrestore(&pfree_queue->lock, flags); ++ ++ return _SUCCESS; ++} ++ ++struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv) ++{ ++ struct xmit_buf *pxmitbuf = NULL; ++ struct list_head *plist, *phead; ++ struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; ++ unsigned long flags; ++ ++ /* DBG_88E("+rtw_alloc_xmitbuf\n"); */ ++ ++ spin_lock_irqsave(&pfree_xmitbuf_queue->lock, flags); ++ ++ if (list_empty(&pfree_xmitbuf_queue->queue)) { ++ pxmitbuf = NULL; ++ } else { ++ phead = get_list_head(pfree_xmitbuf_queue); ++ ++ plist = phead->next; ++ ++ pxmitbuf = container_of(plist, struct xmit_buf, list); ++ ++ list_del_init(&pxmitbuf->list); ++ } ++ ++ if (pxmitbuf) { ++ pxmitpriv->free_xmitbuf_cnt--; ++ pxmitbuf->priv_data = NULL; ++ if (pxmitbuf->sctx) { ++ DBG_88E("%s pxmitbuf->sctx is not NULL\n", __func__); ++ rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC); ++ } ++ } ++ spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, flags); ++ ++ return pxmitbuf; ++} ++ ++s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) ++{ ++ struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; ++ unsigned long flags; ++ ++ if (!pxmitbuf) ++ return _FAIL; ++ ++ if (pxmitbuf->sctx) { ++ DBG_88E("%s pxmitbuf->sctx is not NULL\n", __func__); ++ rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE); ++ } ++ ++ if (pxmitbuf->ext_tag) { ++ rtw_free_xmitbuf_ext(pxmitpriv, pxmitbuf); ++ } else { ++ spin_lock_irqsave(&pfree_xmitbuf_queue->lock, flags); ++ ++ list_del_init(&pxmitbuf->list); ++ ++ list_add_tail(&pxmitbuf->list, get_list_head(pfree_xmitbuf_queue)); ++ ++ pxmitpriv->free_xmitbuf_cnt++; ++ spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, flags); ++ } ++ ++ return _SUCCESS; ++} ++ ++/* ++Calling context: ++1. OS_TXENTRY ++2. RXENTRY (rx_thread or RX_ISR/RX_CallBack) ++ ++If we turn on USE_RXTHREAD, then, no need for critical section. ++Otherwise, we must use _enter/_exit critical to protect free_xmit_queue... ++ ++Must be very very cautious... ++ ++*/ ++ ++struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* _queue *pfree_xmit_queue) */ ++{ ++ /* ++ Please remember to use all the osdep_service api, ++ and lock/unlock or _enter/_exit critical to protect ++ pfree_xmit_queue ++ */ ++ ++ struct xmit_frame *pxframe = NULL; ++ struct list_head *plist, *phead; ++ struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; ++ ++ spin_lock_bh(&pfree_xmit_queue->lock); ++ ++ if (list_empty(&pfree_xmit_queue->queue)) { ++ pxframe = NULL; ++ } else { ++ phead = get_list_head(pfree_xmit_queue); ++ ++ plist = phead->next; ++ ++ pxframe = container_of(plist, struct xmit_frame, list); ++ ++ list_del_init(&pxframe->list); ++ } ++ ++ if (pxframe) { /* default value setting */ ++ pxmitpriv->free_xmitframe_cnt--; ++ ++ pxframe->buf_addr = NULL; ++ pxframe->pxmitbuf = NULL; ++ ++ memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib)); ++ /* pxframe->attrib.psta = NULL; */ ++ ++ pxframe->frame_tag = DATA_FRAMETAG; ++ ++ pxframe->pkt = NULL; ++ pxframe->pkt_offset = 1;/* default use pkt_offset to fill tx desc */ ++ ++ pxframe->agg_num = 1; ++ pxframe->ack_report = 0; ++ } ++ ++ spin_unlock_bh(&pfree_xmit_queue->lock); ++ ++ return pxframe; ++} ++ ++s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe) ++{ ++ struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; ++ struct adapter *padapter = pxmitpriv->adapter; ++ struct sk_buff *pndis_pkt = NULL; ++ ++ if (!pxmitframe) ++ goto exit; ++ ++ spin_lock_bh(&pfree_xmit_queue->lock); ++ ++ list_del_init(&pxmitframe->list); ++ ++ if (pxmitframe->pkt) { ++ pndis_pkt = pxmitframe->pkt; ++ pxmitframe->pkt = NULL; ++ } ++ ++ list_add_tail(&pxmitframe->list, get_list_head(pfree_xmit_queue)); ++ ++ pxmitpriv->free_xmitframe_cnt++; ++ ++ spin_unlock_bh(&pfree_xmit_queue->lock); ++ ++ if (pndis_pkt) ++ rtw_os_pkt_complete(padapter, pndis_pkt); ++ ++exit: ++ ++ return _SUCCESS; ++} ++ ++void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, struct __queue *pframequeue) ++{ ++ struct list_head *plist, *phead; ++ struct xmit_frame *pxmitframe; ++ ++ spin_lock_bh(&pframequeue->lock); ++ ++ phead = get_list_head(pframequeue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pxmitframe = container_of(plist, struct xmit_frame, list); ++ ++ plist = plist->next; ++ ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ } ++ spin_unlock_bh(&pframequeue->lock); ++ ++} ++ ++s32 rtw_xmitframe_enqueue(struct adapter *padapter, struct xmit_frame *pxmitframe) ++{ ++ if (rtw_xmit_classifier(padapter, pxmitframe) == _FAIL) { ++/* pxmitframe->pkt = NULL; */ ++ return _FAIL; ++ } ++ ++ return _SUCCESS; ++} ++ ++static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, struct __queue *pframe_queue) ++{ ++ struct list_head *xmitframe_plist, *xmitframe_phead; ++ struct xmit_frame *pxmitframe = NULL; ++ ++ xmitframe_phead = get_list_head(pframe_queue); ++ xmitframe_plist = xmitframe_phead->next; ++ ++ if (xmitframe_phead != xmitframe_plist) { ++ pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); ++ ++ xmitframe_plist = xmitframe_plist->next; ++ ++ list_del_init(&pxmitframe->list); ++ ++ ptxservq->qcnt--; ++ } ++ return pxmitframe; ++} ++ ++struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, int entry) ++{ ++ struct list_head *sta_plist, *sta_phead; ++ struct hw_xmit *phwxmit; ++ struct tx_servq *ptxservq = NULL; ++ struct __queue *pframe_queue = NULL; ++ struct xmit_frame *pxmitframe = NULL; ++ struct adapter *padapter = pxmitpriv->adapter; ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ int i, inx[4]; ++ ++ inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3; ++ ++ if (pregpriv->wifi_spec == 1) { ++ int j; ++ ++ for (j = 0; j < 4; j++) ++ inx[j] = pxmitpriv->wmm_para_seq[j]; ++ } ++ ++ spin_lock_bh(&pxmitpriv->lock); ++ ++ for (i = 0; i < entry; i++) { ++ phwxmit = phwxmit_i + inx[i]; ++ ++ sta_phead = get_list_head(phwxmit->sta_queue); ++ sta_plist = sta_phead->next; ++ ++ while (sta_phead != sta_plist) { ++ ptxservq = container_of(sta_plist, struct tx_servq, tx_pending); ++ ++ pframe_queue = &ptxservq->sta_pending; ++ ++ pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue); ++ ++ if (pxmitframe) { ++ phwxmit->accnt--; ++ ++ /* Remove sta node when there are no pending packets. */ ++ if (list_empty(&pframe_queue->queue)) /* must be done after get_next and before break */ ++ list_del_init(&ptxservq->tx_pending); ++ goto exit; ++ } ++ ++ sta_plist = sta_plist->next; ++ } ++ } ++exit: ++ spin_unlock_bh(&pxmitpriv->lock); ++ ++ return pxmitframe; ++} ++ ++struct tx_servq *rtw_get_sta_pending(struct adapter *padapter, struct sta_info *psta, int up, u8 *ac) ++{ ++ struct tx_servq *ptxservq; ++ ++ switch (up) { ++ case 1: ++ case 2: ++ ptxservq = &psta->sta_xmitpriv.bk_q; ++ *(ac) = 3; ++ break; ++ case 4: ++ case 5: ++ ptxservq = &psta->sta_xmitpriv.vi_q; ++ *(ac) = 1; ++ break; ++ case 6: ++ case 7: ++ ptxservq = &psta->sta_xmitpriv.vo_q; ++ *(ac) = 0; ++ break; ++ case 0: ++ case 3: ++ default: ++ ptxservq = &psta->sta_xmitpriv.be_q; ++ *(ac) = 2; ++ break; ++ } ++ ++ return ptxservq; ++} ++ ++/* ++ * Will enqueue pxmitframe to the proper queue, ++ * and indicate it to xx_pending list..... ++ */ ++s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe) ++{ ++ u8 ac_index; ++ struct sta_info *psta; ++ struct tx_servq *ptxservq; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; ++ int res = _SUCCESS; ++ ++ if (pattrib->psta) { ++ psta = pattrib->psta; ++ } else { ++ psta = rtw_get_stainfo(pstapriv, pattrib->ra); ++ } ++ ++ if (!psta) { ++ res = _FAIL; ++ DBG_88E("rtw_xmit_classifier: psta == NULL\n"); ++ goto exit; ++ } ++ ++ ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index)); ++ ++ if (list_empty(&ptxservq->tx_pending)) ++ list_add_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue)); ++ ++ list_add_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending)); ++ ptxservq->qcnt++; ++ phwxmits[ac_index].accnt++; ++exit: ++ ++ return res; ++} ++ ++void rtw_alloc_hwxmits(struct adapter *padapter) ++{ ++ struct hw_xmit *hwxmits; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ pxmitpriv->hwxmit_entry = HWXMIT_ENTRY; ++ ++ pxmitpriv->hwxmits = kzalloc(sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry, GFP_KERNEL); ++ ++ hwxmits = pxmitpriv->hwxmits; ++ ++ if (pxmitpriv->hwxmit_entry == 5) { ++ hwxmits[0] .sta_queue = &pxmitpriv->bm_pending; ++ hwxmits[1] .sta_queue = &pxmitpriv->vo_pending; ++ hwxmits[2] .sta_queue = &pxmitpriv->vi_pending; ++ hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; ++ hwxmits[4] .sta_queue = &pxmitpriv->be_pending; ++ } else if (pxmitpriv->hwxmit_entry == 4) { ++ hwxmits[0] .sta_queue = &pxmitpriv->vo_pending; ++ hwxmits[1] .sta_queue = &pxmitpriv->vi_pending; ++ hwxmits[2] .sta_queue = &pxmitpriv->be_pending; ++ hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; ++ } else { ++ } ++} ++ ++void rtw_free_hwxmits(struct adapter *padapter) ++{ ++ struct hw_xmit *hwxmits; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ hwxmits = pxmitpriv->hwxmits; ++ kfree(hwxmits); ++} ++ ++void rtw_init_hwxmits(struct hw_xmit *phwxmit, int entry) ++{ ++ int i; ++ ++ for (i = 0; i < entry; i++, phwxmit++) ++ phwxmit->accnt = 0; ++ ++} ++ ++static int rtw_br_client_tx(struct adapter *padapter, struct sk_buff **pskb) ++{ ++ struct sk_buff *skb = *pskb; ++ int res, is_vlan_tag = 0, i, do_nat25 = 1; ++ unsigned short vlan_hdr = 0; ++ void *br_port = NULL; ++ ++ rcu_read_lock(); ++ br_port = rcu_dereference(padapter->pnetdev->rx_handler_data); ++ rcu_read_unlock(); ++ spin_lock_bh(&padapter->br_ext_lock); ++ if (!(skb->data[0] & 1) && br_port && ++ memcmp(skb->data + MACADDRLEN, padapter->br_mac, MACADDRLEN) && ++ *((__be16 *)(skb->data + MACADDRLEN * 2)) != __constant_htons(ETH_P_8021Q) && ++ *((__be16 *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP) && ++ !memcmp(padapter->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN) && padapter->scdb_entry) { ++ memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN); ++ padapter->scdb_entry->ageing_timer = jiffies; ++ spin_unlock_bh(&padapter->br_ext_lock); ++ } else { ++ if (*((__be16 *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_8021Q)) { ++ is_vlan_tag = 1; ++ vlan_hdr = *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)); ++ for (i = 0; i < 6; i++) ++ *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + MACADDRLEN * 2 - 2 - i * 2)); ++ skb_pull(skb, 4); ++ } ++ if (!memcmp(skb->data + MACADDRLEN, padapter->br_mac, MACADDRLEN) && ++ (*((__be16 *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP))) ++ memcpy(padapter->br_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4); ++ ++ if (*((__be16 *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP)) { ++ if (memcmp(padapter->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN)) { ++ padapter->scdb_entry = (struct nat25_network_db_entry *)scdb_findEntry(padapter, ++ skb->data + MACADDRLEN, skb->data + WLAN_ETHHDR_LEN + 12); ++ if (padapter->scdb_entry) { ++ memcpy(padapter->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN); ++ memcpy(padapter->scdb_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4); ++ padapter->scdb_entry->ageing_timer = jiffies; ++ do_nat25 = 0; ++ } ++ } else { ++ if (padapter->scdb_entry) { ++ padapter->scdb_entry->ageing_timer = jiffies; ++ do_nat25 = 0; ++ } else { ++ memset(padapter->scdb_mac, 0, MACADDRLEN); ++ memset(padapter->scdb_ip, 0, 4); ++ } ++ } ++ } ++ spin_unlock_bh(&padapter->br_ext_lock); ++ if (do_nat25) { ++ if (nat25_db_handle(padapter, skb, NAT25_CHECK) == 0) { ++ struct sk_buff *newskb; ++ ++ if (is_vlan_tag) { ++ skb_push(skb, 4); ++ for (i = 0; i < 6; i++) ++ *((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2)); ++ *((__be16 *)(skb->data + MACADDRLEN * 2)) = __constant_htons(ETH_P_8021Q); ++ *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)) = vlan_hdr; ++ } ++ ++ newskb = skb_copy(skb, GFP_ATOMIC); ++ if (!newskb) { ++ DEBUG_ERR("TX DROP: skb_copy fail!\n"); ++ return -1; ++ } ++ dev_kfree_skb_any(skb); ++ ++ *pskb = skb = newskb; ++ if (is_vlan_tag) { ++ vlan_hdr = *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)); ++ for (i = 0; i < 6; i++) ++ *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + MACADDRLEN * 2 - 2 - i * 2)); ++ skb_pull(skb, 4); ++ } ++ } ++ ++ if (skb_is_nonlinear(skb)) ++ DEBUG_ERR("%s(): skb_is_nonlinear!!\n", __func__); ++ ++ res = skb_linearize(skb); ++ if (res < 0) { ++ DEBUG_ERR("TX DROP: skb_linearize fail!\n"); ++ return -1; ++ } ++ ++ res = nat25_db_handle(padapter, skb, NAT25_INSERT); ++ if (res < 0) { ++ if (res == -2) { ++ DEBUG_ERR("TX DROP: nat25_db_handle fail!\n"); ++ return -1; ++ } ++ return 0; ++ } ++ } ++ ++ memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN); ++ ++ dhcp_flag_bcast(padapter, skb); ++ ++ if (is_vlan_tag) { ++ skb_push(skb, 4); ++ for (i = 0; i < 6; i++) ++ *((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2)); ++ *((__be16 *)(skb->data + MACADDRLEN * 2)) = __constant_htons(ETH_P_8021Q); ++ *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)) = vlan_hdr; ++ } ++ } ++ ++ /* check if SA is equal to our MAC */ ++ if (memcmp(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN)) { ++ DEBUG_ERR("TX DROP: untransformed frame SA:%02X%02X%02X%02X%02X%02X!\n", ++ skb->data[6], skb->data[7], skb->data[8], skb->data[9], skb->data[10], skb->data[11]); ++ return -1; ++ } ++ return 0; ++} ++ ++u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe) ++{ ++ u32 addr; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ ++ switch (pattrib->qsel) { ++ case 0: ++ case 3: ++ addr = BE_QUEUE_INX; ++ break; ++ case 1: ++ case 2: ++ addr = BK_QUEUE_INX; ++ break; ++ case 4: ++ case 5: ++ addr = VI_QUEUE_INX; ++ break; ++ case 6: ++ case 7: ++ addr = VO_QUEUE_INX; ++ break; ++ case 0x10: ++ addr = BCN_QUEUE_INX; ++ break; ++ case 0x11:/* BC/MC in PS (HIQ) */ ++ addr = HIGH_QUEUE_INX; ++ break; ++ case 0x12: ++ default: ++ addr = MGT_QUEUE_INX; ++ break; ++ } ++ ++ return addr; ++} ++ ++static void do_queue_select(struct adapter *padapter, struct pkt_attrib *pattrib) ++{ ++ u8 qsel; ++ ++ qsel = pattrib->priority; ++ ++ pattrib->qsel = qsel; ++} ++ ++/* ++ * The main transmit(tx) entry ++ * ++ * Return ++ * 1 enqueue ++ * 0 success, hardware will handle this xmit frame(packet) ++ * <0 fail ++ */ ++s32 rtw_xmit(struct adapter *padapter, struct sk_buff **ppkt) ++{ ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct xmit_frame *pxmitframe = NULL; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ void *br_port = NULL; ++ s32 res; ++ ++ pxmitframe = rtw_alloc_xmitframe(pxmitpriv); ++ if (!pxmitframe) { ++ DBG_88E("DBG_TX_DROP_FRAME %s no more pxmitframe\n", __func__); ++ return -1; ++ } ++ ++ rcu_read_lock(); ++ br_port = rcu_dereference(padapter->pnetdev->rx_handler_data); ++ rcu_read_unlock(); ++ ++ if (br_port && check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE)) { ++ res = rtw_br_client_tx(padapter, ppkt); ++ if (res == -1) { ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ return -1; ++ } ++ } ++ ++ res = update_attrib(padapter, *ppkt, &pxmitframe->attrib); ++ ++ if (res == _FAIL) { ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ return -1; ++ } ++ pxmitframe->pkt = *ppkt; ++ ++ rtw_led_control(padapter, LED_CTL_TX); ++ ++ do_queue_select(padapter, &pxmitframe->attrib); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ spin_lock_bh(&pxmitpriv->lock); ++ if (xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe)) { ++ spin_unlock_bh(&pxmitpriv->lock); ++ return 1; ++ } ++ spin_unlock_bh(&pxmitpriv->lock); ++#endif ++ ++ if (!rtw_hal_xmit(padapter, pxmitframe)) ++ return 1; ++ ++ return 0; ++} ++ ++#if defined(CONFIG_88EU_AP_MODE) ++ ++int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_frame *pxmitframe) ++{ ++ int ret = false; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ bool bmcst = is_multicast_ether_addr(pattrib->ra); ++ ++ if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ return ret; ++ ++ if (pattrib->psta) ++ psta = pattrib->psta; ++ else ++ psta = rtw_get_stainfo(pstapriv, pattrib->ra); ++ ++ if (!psta) ++ return ret; ++ ++ if (pattrib->triggered == 1) { ++ if (bmcst) ++ pattrib->qsel = 0x11;/* HIQ */ ++ return ret; ++ } ++ ++ if (bmcst) { ++ spin_lock_bh(&psta->sleep_q.lock); ++ ++ if (pstapriv->sta_dz_bitmap) {/* if any one sta is in ps mode */ ++ list_del_init(&pxmitframe->list); ++ ++ list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q)); ++ ++ psta->sleepq_len++; ++ ++ pstapriv->tim_bitmap |= BIT(0);/* */ ++ pstapriv->sta_dz_bitmap |= BIT(0); ++ ++ update_beacon(padapter, _TIM_IE_, NULL, false);/* tx bc/mc packets after upate bcn */ ++ ++ ret = true; ++ } ++ ++ spin_unlock_bh(&psta->sleep_q.lock); ++ ++ return ret; ++ } ++ ++ spin_lock_bh(&psta->sleep_q.lock); ++ ++ if (psta->state & WIFI_SLEEP_STATE) { ++ u8 wmmps_ac = 0; ++ ++ if (pstapriv->sta_dz_bitmap & BIT(psta->aid)) { ++ list_del_init(&pxmitframe->list); ++ ++ list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q)); ++ ++ psta->sleepq_len++; ++ ++ switch (pattrib->priority) { ++ case 1: ++ case 2: ++ wmmps_ac = psta->uapsd_bk & BIT(0); ++ break; ++ case 4: ++ case 5: ++ wmmps_ac = psta->uapsd_vi & BIT(0); ++ break; ++ case 6: ++ case 7: ++ wmmps_ac = psta->uapsd_vo & BIT(0); ++ break; ++ case 0: ++ case 3: ++ default: ++ wmmps_ac = psta->uapsd_be & BIT(0); ++ break; ++ } ++ ++ if (wmmps_ac) ++ psta->sleepq_ac_len++; ++ ++ if (((psta->has_legacy_ac) && (!wmmps_ac)) || ++ ((!psta->has_legacy_ac) && (wmmps_ac))) { ++ pstapriv->tim_bitmap |= BIT(psta->aid); ++ ++ if (psta->sleepq_len == 1) { ++ /* upate BCN for TIM IE */ ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++ } ++ } ++ ret = true; ++ } ++ } ++ ++ spin_unlock_bh(&psta->sleep_q.lock); ++ ++ return ret; ++} ++ ++static void dequeue_xmitframes_to_sleeping_queue(struct adapter *padapter, struct sta_info *psta, struct __queue *pframequeue) ++{ ++ struct list_head *plist, *phead; ++ u8 ac_index; ++ struct tx_servq *ptxservq; ++ struct pkt_attrib *pattrib; ++ struct xmit_frame *pxmitframe; ++ struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; ++ ++ phead = get_list_head(pframequeue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pxmitframe = container_of(plist, struct xmit_frame, list); ++ ++ plist = plist->next; ++ ++ xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe); ++ ++ pattrib = &pxmitframe->attrib; ++ ++ ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index)); ++ ++ ptxservq->qcnt--; ++ phwxmits[ac_index].accnt--; ++ } ++} ++ ++void stop_sta_xmit(struct adapter *padapter, struct sta_info *psta) ++{ ++ struct sta_info *psta_bmc; ++ struct sta_xmit_priv *pstaxmitpriv; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ pstaxmitpriv = &psta->sta_xmitpriv; ++ ++ /* for BC/MC Frames */ ++ psta_bmc = rtw_get_bcmc_stainfo(padapter); ++ ++ spin_lock_bh(&pxmitpriv->lock); ++ ++ psta->state |= WIFI_SLEEP_STATE; ++ ++ pstapriv->sta_dz_bitmap |= BIT(psta->aid); ++ ++ dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending); ++ list_del_init(&pstaxmitpriv->vo_q.tx_pending); ++ ++ dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending); ++ list_del_init(&pstaxmitpriv->vi_q.tx_pending); ++ ++ dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending); ++ list_del_init(&pstaxmitpriv->be_q.tx_pending); ++ ++ dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending); ++ list_del_init(&pstaxmitpriv->bk_q.tx_pending); ++ ++ /* for BC/MC Frames */ ++ pstaxmitpriv = &psta_bmc->sta_xmitpriv; ++ dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->be_q.sta_pending); ++ list_del_init(&pstaxmitpriv->be_q.tx_pending); ++ ++ spin_unlock_bh(&pxmitpriv->lock); ++} ++ ++void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta) ++{ ++ u8 update_mask = 0, wmmps_ac = 0; ++ struct sta_info *psta_bmc; ++ struct list_head *xmitframe_plist, *xmitframe_phead; ++ struct xmit_frame *pxmitframe = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ spin_lock_bh(&psta->sleep_q.lock); ++ ++ xmitframe_phead = get_list_head(&psta->sleep_q); ++ xmitframe_plist = xmitframe_phead->next; ++ ++ while (xmitframe_phead != xmitframe_plist) { ++ pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); ++ ++ xmitframe_plist = xmitframe_plist->next; ++ ++ list_del_init(&pxmitframe->list); ++ ++ switch (pxmitframe->attrib.priority) { ++ case 1: ++ case 2: ++ wmmps_ac = psta->uapsd_bk & BIT(1); ++ break; ++ case 4: ++ case 5: ++ wmmps_ac = psta->uapsd_vi & BIT(1); ++ break; ++ case 6: ++ case 7: ++ wmmps_ac = psta->uapsd_vo & BIT(1); ++ break; ++ case 0: ++ case 3: ++ default: ++ wmmps_ac = psta->uapsd_be & BIT(1); ++ break; ++ } ++ ++ psta->sleepq_len--; ++ if (psta->sleepq_len > 0) ++ pxmitframe->attrib.mdata = 1; ++ else ++ pxmitframe->attrib.mdata = 0; ++ ++ if (wmmps_ac) { ++ psta->sleepq_ac_len--; ++ if (psta->sleepq_ac_len > 0) { ++ pxmitframe->attrib.mdata = 1; ++ pxmitframe->attrib.eosp = 0; ++ } else { ++ pxmitframe->attrib.mdata = 0; ++ pxmitframe->attrib.eosp = 1; ++ } ++ } ++ ++ pxmitframe->attrib.triggered = 1; ++ ++ spin_unlock_bh(&psta->sleep_q.lock); ++ if (rtw_hal_xmit(padapter, pxmitframe)) ++ rtw_os_xmit_complete(padapter, pxmitframe); ++ spin_lock_bh(&psta->sleep_q.lock); ++ } ++ ++ if (psta->sleepq_len == 0) { ++ pstapriv->tim_bitmap &= ~BIT(psta->aid); ++ ++ update_mask = BIT(0); ++ ++ if (psta->state & WIFI_SLEEP_STATE) ++ psta->state ^= WIFI_SLEEP_STATE; ++ ++ if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { ++ psta->expire_to = pstapriv->expire_to; ++ psta->state ^= WIFI_STA_ALIVE_CHK_STATE; ++ } ++ ++ pstapriv->sta_dz_bitmap &= ~BIT(psta->aid); ++ } ++ ++ spin_unlock_bh(&psta->sleep_q.lock); ++ ++ /* for BC/MC Frames */ ++ psta_bmc = rtw_get_bcmc_stainfo(padapter); ++ if (!psta_bmc) ++ return; ++ ++ if ((pstapriv->sta_dz_bitmap & 0xfffe) == 0x0) { /* no any sta in ps mode */ ++ spin_lock_bh(&psta_bmc->sleep_q.lock); ++ ++ xmitframe_phead = get_list_head(&psta_bmc->sleep_q); ++ xmitframe_plist = xmitframe_phead->next; ++ ++ while (xmitframe_phead != xmitframe_plist) { ++ pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); ++ ++ xmitframe_plist = xmitframe_plist->next; ++ ++ list_del_init(&pxmitframe->list); ++ ++ psta_bmc->sleepq_len--; ++ if (psta_bmc->sleepq_len > 0) ++ pxmitframe->attrib.mdata = 1; ++ else ++ pxmitframe->attrib.mdata = 0; ++ ++ pxmitframe->attrib.triggered = 1; ++ ++ spin_unlock_bh(&psta_bmc->sleep_q.lock); ++ if (rtw_hal_xmit(padapter, pxmitframe)) ++ rtw_os_xmit_complete(padapter, pxmitframe); ++ spin_lock_bh(&psta_bmc->sleep_q.lock); ++ } ++ ++ if (psta_bmc->sleepq_len == 0) { ++ pstapriv->tim_bitmap &= ~BIT(0); ++ pstapriv->sta_dz_bitmap &= ~BIT(0); ++ ++ update_mask |= BIT(1); ++ } ++ ++ spin_unlock_bh(&psta_bmc->sleep_q.lock); ++ } ++ ++ if (update_mask) ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++} ++ ++void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *psta) ++{ ++ u8 wmmps_ac = 0; ++ struct list_head *xmitframe_plist, *xmitframe_phead; ++ struct xmit_frame *pxmitframe = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ spin_lock_bh(&psta->sleep_q.lock); ++ ++ xmitframe_phead = get_list_head(&psta->sleep_q); ++ xmitframe_plist = xmitframe_phead->next; ++ ++ while (xmitframe_phead != xmitframe_plist) { ++ pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); ++ ++ xmitframe_plist = xmitframe_plist->next; ++ ++ switch (pxmitframe->attrib.priority) { ++ case 1: ++ case 2: ++ wmmps_ac = psta->uapsd_bk & BIT(1); ++ break; ++ case 4: ++ case 5: ++ wmmps_ac = psta->uapsd_vi & BIT(1); ++ break; ++ case 6: ++ case 7: ++ wmmps_ac = psta->uapsd_vo & BIT(1); ++ break; ++ case 0: ++ case 3: ++ default: ++ wmmps_ac = psta->uapsd_be & BIT(1); ++ break; ++ } ++ ++ if (!wmmps_ac) ++ continue; ++ ++ list_del_init(&pxmitframe->list); ++ ++ psta->sleepq_len--; ++ psta->sleepq_ac_len--; ++ ++ if (psta->sleepq_ac_len > 0) { ++ pxmitframe->attrib.mdata = 1; ++ pxmitframe->attrib.eosp = 0; ++ } else { ++ pxmitframe->attrib.mdata = 0; ++ pxmitframe->attrib.eosp = 1; ++ } ++ ++ pxmitframe->attrib.triggered = 1; ++ ++ if (rtw_hal_xmit(padapter, pxmitframe)) ++ rtw_os_xmit_complete(padapter, pxmitframe); ++ ++ if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) && (wmmps_ac)) { ++ pstapriv->tim_bitmap &= ~BIT(psta->aid); ++ ++ /* upate BCN for TIM IE */ ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++ } ++ } ++ ++ spin_unlock_bh(&psta->sleep_q.lock); ++} ++ ++#endif ++ ++void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms) ++{ ++ sctx->timeout_ms = timeout_ms; ++ sctx->submit_time = jiffies; ++ init_completion(&sctx->done); ++ sctx->status = RTW_SCTX_SUBMITTED; ++} ++ ++int rtw_sctx_wait(struct submit_ctx *sctx) ++{ ++ int ret = _FAIL; ++ unsigned long expire; ++ int status = 0; ++ ++ expire = sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) : MAX_SCHEDULE_TIMEOUT; ++ if (!wait_for_completion_timeout(&sctx->done, expire)) { ++ /* timeout, do something?? */ ++ status = RTW_SCTX_DONE_TIMEOUT; ++ DBG_88E("%s timeout\n", __func__); ++ } else { ++ status = sctx->status; ++ } ++ ++ if (status == RTW_SCTX_DONE_SUCCESS) ++ ret = _SUCCESS; ++ ++ return ret; ++} ++ ++static bool rtw_sctx_chk_waring_status(int status) ++{ ++ switch (status) { ++ case RTW_SCTX_DONE_UNKNOWN: ++ case RTW_SCTX_DONE_BUF_ALLOC: ++ case RTW_SCTX_DONE_BUF_FREE: ++ ++ case RTW_SCTX_DONE_DRV_STOP: ++ case RTW_SCTX_DONE_DEV_REMOVE: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++void rtw_sctx_done_err(struct submit_ctx **sctx, int status) ++{ ++ if (*sctx) { ++ if (rtw_sctx_chk_waring_status(status)) ++ DBG_88E("%s status:%d\n", __func__, status); ++ (*sctx)->status = status; ++ complete(&((*sctx)->done)); ++ *sctx = NULL; ++ } ++} ++ ++void rtw_sctx_done(struct submit_ctx **sctx) ++{ ++ rtw_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS); ++} ++ ++int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms) ++{ ++ struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops; ++ ++ pack_tx_ops->submit_time = jiffies; ++ pack_tx_ops->timeout_ms = timeout_ms; ++ pack_tx_ops->status = RTW_SCTX_SUBMITTED; ++ ++ return rtw_sctx_wait(pack_tx_ops); ++} ++ ++void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status) ++{ ++ struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops; ++ ++ if (pxmitpriv->ack_tx) ++ rtw_sctx_done_err(&pack_tx_ops, status); ++ else ++ DBG_88E("%s ack_tx not set\n", __func__); ++} +diff --git a/drivers/staging/r8188eu/hal/Hal8188EPwrSeq.c b/drivers/staging/r8188eu/hal/Hal8188EPwrSeq.c +new file mode 100644 +index 000000000000..48ede610cd28 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/Hal8188EPwrSeq.c +@@ -0,0 +1,69 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/Hal8188EPwrSeq.h" ++#include "../include/rtl8188e_hal.h" ++ ++/* ++ drivers should parse below arrays and do the corresponding actions ++*/ ++/* 3 Power on Array */ ++struct wl_pwr_cfg rtl8188E_power_on_flow[RTL8188E_TRANS_CARDEMU_TO_ACT_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ RTL8188E_TRANS_CARDEMU_TO_ACT ++ RTL8188E_TRANS_END ++}; ++ ++/* 3Radio off Array */ ++struct wl_pwr_cfg rtl8188E_radio_off_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ RTL8188E_TRANS_ACT_TO_CARDEMU ++ RTL8188E_TRANS_END ++}; ++ ++/* 3Card Disable Array */ ++struct wl_pwr_cfg rtl8188E_card_disable_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ RTL8188E_TRANS_ACT_TO_CARDEMU ++ RTL8188E_TRANS_CARDEMU_TO_CARDDIS ++ RTL8188E_TRANS_END ++}; ++ ++/* 3 Card Enable Array */ ++struct wl_pwr_cfg rtl8188E_card_enable_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ RTL8188E_TRANS_CARDDIS_TO_CARDEMU ++ RTL8188E_TRANS_CARDEMU_TO_ACT ++ RTL8188E_TRANS_END ++}; ++ ++/* 3Suspend Array */ ++struct wl_pwr_cfg rtl8188E_suspend_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ RTL8188E_TRANS_ACT_TO_CARDEMU ++ RTL8188E_TRANS_CARDEMU_TO_SUS ++ RTL8188E_TRANS_END ++}; ++ ++/* 3 Resume Array */ ++struct wl_pwr_cfg rtl8188E_resume_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ RTL8188E_TRANS_SUS_TO_CARDEMU ++ RTL8188E_TRANS_CARDEMU_TO_ACT ++ RTL8188E_TRANS_END ++}; ++ ++/* 3HWPDN Array */ ++struct wl_pwr_cfg rtl8188E_hwpdn_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ RTL8188E_TRANS_ACT_TO_CARDEMU ++ RTL8188E_TRANS_CARDEMU_TO_PDN ++ RTL8188E_TRANS_END ++}; ++ ++/* 3 Enter LPS */ ++struct wl_pwr_cfg rtl8188E_enter_lps_flow[RTL8188E_TRANS_ACT_TO_LPS_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ /* FW behavior */ ++ RTL8188E_TRANS_ACT_TO_LPS ++ RTL8188E_TRANS_END ++}; ++ ++/* 3 Leave LPS */ ++struct wl_pwr_cfg rtl8188E_leave_lps_flow[RTL8188E_TRANS_LPS_TO_ACT_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ /* FW behavior */ ++ RTL8188E_TRANS_LPS_TO_ACT ++ RTL8188E_TRANS_END ++}; +diff --git a/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c +new file mode 100644 +index 000000000000..d873672feb27 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c +@@ -0,0 +1,664 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright (c) Realtek Semiconductor Corp. ++Module Name: ++ RateAdaptive.c ++ ++Abstract: ++ Implement Rate Adaptive functions for common operations. ++ ++Major Change History: ++ When Who What ++ ---------- --------------- ------------------------------- ++ 2011-08-12 Page Create. ++ ++--*/ ++#include "../include/odm_precomp.h" ++ ++/* Rate adaptive parameters */ ++ ++static u8 RETRY_PENALTY[PERENTRY][RETRYSIZE + 1] = { ++ {5, 4, 3, 2, 0, 3}, /* 92 , idx = 0 */ ++ {6, 5, 4, 3, 0, 4}, /* 86 , idx = 1 */ ++ {6, 5, 4, 2, 0, 4}, /* 81 , idx = 2 */ ++ {8, 7, 6, 4, 0, 6}, /* 75 , idx = 3 */ ++ {10, 9, 8, 6, 0, 8}, /* 71 , idx = 4 */ ++ {10, 9, 8, 4, 0, 8}, /* 66 , idx = 5 */ ++ {10, 9, 8, 2, 0, 8}, /* 62 , idx = 6 */ ++ {10, 9, 8, 0, 0, 8}, /* 59 , idx = 7 */ ++ {18, 17, 16, 8, 0, 16}, /* 53 , idx = 8 */ ++ {26, 25, 24, 16, 0, 24}, /* 50 , idx = 9 */ ++ {34, 33, 32, 24, 0, 32}, /* 47 , idx = 0x0a */ ++ {34, 31, 28, 20, 0, 32}, /* 43 , idx = 0x0b */ ++ {34, 31, 27, 18, 0, 32}, /* 40 , idx = 0x0c */ ++ {34, 31, 26, 16, 0, 32}, /* 37 , idx = 0x0d */ ++ {34, 30, 22, 16, 0, 32}, /* 32 , idx = 0x0e */ ++ {34, 30, 24, 16, 0, 32}, /* 26 , idx = 0x0f */ ++ {49, 46, 40, 16, 0, 48}, /* 20 , idx = 0x10 */ ++ {49, 45, 32, 0, 0, 48}, /* 17 , idx = 0x11 */ ++ {49, 45, 22, 18, 0, 48}, /* 15 , idx = 0x12 */ ++ {49, 40, 24, 16, 0, 48}, /* 12 , idx = 0x13 */ ++ {49, 32, 18, 12, 0, 48}, /* 9 , idx = 0x14 */ ++ {49, 22, 18, 14, 0, 48}, /* 6 , idx = 0x15 */ ++ {49, 16, 16, 0, 0, 48} ++ }; /* 3, idx = 0x16 */ ++ ++static u8 PT_PENALTY[RETRYSIZE + 1] = {34, 31, 30, 24, 0, 32}; ++ ++/* wilson modify */ ++static u8 RETRY_PENALTY_IDX[2][RATESIZE] = { ++ {4, 4, 4, 5, 4, 4, 5, 7, 7, 7, 8, 0x0a, /* SS>TH */ ++ 4, 4, 4, 4, 6, 0x0a, 0x0b, 0x0d, ++ 5, 5, 7, 7, 8, 0x0b, 0x0d, 0x0f}, /* 0329 R01 */ ++ {0x0a, 0x0a, 0x0b, 0x0c, 0x0a, ++ 0x0a, 0x0b, 0x0c, 0x0d, 0x10, 0x13, 0x14, /* SSTH */ ++ 0x0f, 0x10, 0x10, 0x12, 0x12, 0x13, 0x14, 0x15, ++ 0x11, 0x11, 0x12, 0x13, 0x13, 0x13, 0x14, 0x15}; ++ ++static u8 RSSI_THRESHOLD[RATESIZE] = { ++ 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0x24, 0x26, 0x2a, ++ 0x18, 0x1a, 0x1d, 0x1f, 0x21, 0x27, 0x29, 0x2a, ++ 0, 0, 0, 0x1f, 0x23, 0x28, 0x2a, 0x2c}; ++ ++static u16 N_THRESHOLD_HIGH[RATESIZE] = { ++ 4, 4, 8, 16, ++ 24, 36, 48, 72, 96, 144, 192, 216, ++ 60, 80, 100, 160, 240, 400, 560, 640, ++ 300, 320, 480, 720, 1000, 1200, 1600, 2000}; ++static u16 N_THRESHOLD_LOW[RATESIZE] = { ++ 2, 2, 4, 8, ++ 12, 18, 24, 36, 48, 72, 96, 108, ++ 30, 40, 50, 80, 120, 200, 280, 320, ++ 150, 160, 240, 360, 500, 600, 800, 1000}; ++ ++static u8 DROPING_NECESSARY[RATESIZE] = { ++ 1, 1, 1, 1, ++ 1, 2, 3, 4, 5, 6, 7, 8, ++ 1, 2, 3, 4, 5, 6, 7, 8, ++ 5, 6, 7, 8, 9, 10, 11, 12}; ++ ++static u8 PendingForRateUpFail[5] = {2, 10, 24, 40, 60}; ++static u16 DynamicTxRPTTiming[6] = { ++ 0x186a, 0x30d4, 0x493e, 0x61a8, 0x7a12, 0x927c}; /* 200ms-1200ms */ ++ ++/* End Rate adaptive parameters */ ++ ++static void odm_SetTxRPTTiming_8188E( ++ struct odm_dm_struct *dm_odm, ++ struct odm_ra_info *pRaInfo, ++ u8 extend ++ ) ++{ ++ u8 idx = 0; ++ ++ for (idx = 0; idx < 5; idx++) ++ if (DynamicTxRPTTiming[idx] == pRaInfo->RptTime) ++ break; ++ ++ if (extend == 0) { /* back to default timing */ ++ idx = 0; /* 200ms */ ++ } else if (extend == 1) {/* increase the timing */ ++ idx += 1; ++ if (idx > 5) ++ idx = 5; ++ } else if (extend == 2) {/* decrease the timing */ ++ if (idx != 0) ++ idx -= 1; ++ } ++ pRaInfo->RptTime = DynamicTxRPTTiming[idx]; ++} ++ ++static int odm_RateDown_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_info *pRaInfo) ++{ ++ u8 RateID, LowestRate, HighestRate; ++ u8 i; ++ ++ if (NULL == pRaInfo) ++ return -1; ++ RateID = pRaInfo->PreRate; ++ LowestRate = pRaInfo->LowestRate; ++ HighestRate = pRaInfo->HighestRate; ++ ++ if (RateID > HighestRate) { ++ RateID = HighestRate; ++ } else if (pRaInfo->RateSGI) { ++ pRaInfo->RateSGI = 0; ++ } else if (RateID > LowestRate) { ++ if (RateID > 0) { ++ for (i = RateID - 1; i > LowestRate; i--) { ++ if (pRaInfo->RAUseRate & BIT(i)) { ++ RateID = i; ++ goto RateDownFinish; ++ } ++ } ++ } ++ } else if (RateID <= LowestRate) { ++ RateID = LowestRate; ++ } ++RateDownFinish: ++ if (pRaInfo->RAWaitingCounter == 1) { ++ pRaInfo->RAWaitingCounter += 1; ++ pRaInfo->RAPendingCounter += 1; ++ } else if (pRaInfo->RAWaitingCounter == 0) { ++ ; ++ } else { ++ pRaInfo->RAWaitingCounter = 0; ++ pRaInfo->RAPendingCounter = 0; ++ } ++ ++ if (pRaInfo->RAPendingCounter >= 4) ++ pRaInfo->RAPendingCounter = 4; ++ ++ pRaInfo->DecisionRate = RateID; ++ odm_SetTxRPTTiming_8188E(dm_odm, pRaInfo, 2); ++ return 0; ++} ++ ++static int odm_RateUp_8188E( ++ struct odm_dm_struct *dm_odm, ++ struct odm_ra_info *pRaInfo ++ ) ++{ ++ u8 RateID, HighestRate; ++ u8 i; ++ ++ if (NULL == pRaInfo) ++ return -1; ++ RateID = pRaInfo->PreRate; ++ HighestRate = pRaInfo->HighestRate; ++ if (pRaInfo->RAWaitingCounter == 1) { ++ pRaInfo->RAWaitingCounter = 0; ++ pRaInfo->RAPendingCounter = 0; ++ } else if (pRaInfo->RAWaitingCounter > 1) { ++ pRaInfo->PreRssiStaRA = pRaInfo->RssiStaRA; ++ goto RateUpfinish; ++ } ++ odm_SetTxRPTTiming_8188E(dm_odm, pRaInfo, 0); ++ ++ if (RateID < HighestRate) { ++ for (i = RateID + 1; i <= HighestRate; i++) { ++ if (pRaInfo->RAUseRate & BIT(i)) { ++ RateID = i; ++ goto RateUpfinish; ++ } ++ } ++ } else if (RateID == HighestRate) { ++ if (pRaInfo->SGIEnable && (pRaInfo->RateSGI != 1)) ++ pRaInfo->RateSGI = 1; ++ else if ((pRaInfo->SGIEnable) != 1) ++ pRaInfo->RateSGI = 0; ++ } else { ++ RateID = HighestRate; ++ } ++RateUpfinish: ++ if (pRaInfo->RAWaitingCounter == (4 + PendingForRateUpFail[pRaInfo->RAPendingCounter])) ++ pRaInfo->RAWaitingCounter = 0; ++ else ++ pRaInfo->RAWaitingCounter++; ++ ++ pRaInfo->DecisionRate = RateID; ++ return 0; ++} ++ ++static void odm_ResetRaCounter_8188E(struct odm_ra_info *pRaInfo) ++{ ++ u8 RateID; ++ ++ RateID = pRaInfo->DecisionRate; ++ pRaInfo->NscUp = (N_THRESHOLD_HIGH[RateID] + N_THRESHOLD_LOW[RateID]) >> 1; ++ pRaInfo->NscDown = (N_THRESHOLD_HIGH[RateID] + N_THRESHOLD_LOW[RateID]) >> 1; ++} ++ ++static void odm_RateDecision_8188E(struct odm_dm_struct *dm_odm, ++ struct odm_ra_info *pRaInfo ++ ) ++{ ++ u8 RateID = 0, RtyPtID = 0, PenaltyID1 = 0, PenaltyID2 = 0; ++ /* u32 pool_retry; */ ++ static u8 DynamicTxRPTTimingCounter; ++ ++ if (pRaInfo->Active && (pRaInfo->TOTAL > 0)) { /* STA used and data packet exits */ ++ if ((pRaInfo->RssiStaRA < (pRaInfo->PreRssiStaRA - 3)) || ++ (pRaInfo->RssiStaRA > (pRaInfo->PreRssiStaRA + 3))) { ++ pRaInfo->RAWaitingCounter = 0; ++ pRaInfo->RAPendingCounter = 0; ++ } ++ /* Start RA decision */ ++ if (pRaInfo->PreRate > pRaInfo->HighestRate) ++ RateID = pRaInfo->HighestRate; ++ else ++ RateID = pRaInfo->PreRate; ++ if (pRaInfo->RssiStaRA > RSSI_THRESHOLD[RateID]) ++ RtyPtID = 0; ++ else ++ RtyPtID = 1; ++ PenaltyID1 = RETRY_PENALTY_IDX[RtyPtID][RateID]; /* TODO by page */ ++ ++ pRaInfo->NscDown += pRaInfo->RTY[0] * RETRY_PENALTY[PenaltyID1][0]; ++ pRaInfo->NscDown += pRaInfo->RTY[1] * RETRY_PENALTY[PenaltyID1][1]; ++ pRaInfo->NscDown += pRaInfo->RTY[2] * RETRY_PENALTY[PenaltyID1][2]; ++ pRaInfo->NscDown += pRaInfo->RTY[3] * RETRY_PENALTY[PenaltyID1][3]; ++ pRaInfo->NscDown += pRaInfo->RTY[4] * RETRY_PENALTY[PenaltyID1][4]; ++ if (pRaInfo->NscDown > (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5])) ++ pRaInfo->NscDown -= pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5]; ++ else ++ pRaInfo->NscDown = 0; ++ ++ /* rate up */ ++ PenaltyID2 = RETRY_PENALTY_UP_IDX[RateID]; ++ pRaInfo->NscUp += pRaInfo->RTY[0] * RETRY_PENALTY[PenaltyID2][0]; ++ pRaInfo->NscUp += pRaInfo->RTY[1] * RETRY_PENALTY[PenaltyID2][1]; ++ pRaInfo->NscUp += pRaInfo->RTY[2] * RETRY_PENALTY[PenaltyID2][2]; ++ pRaInfo->NscUp += pRaInfo->RTY[3] * RETRY_PENALTY[PenaltyID2][3]; ++ pRaInfo->NscUp += pRaInfo->RTY[4] * RETRY_PENALTY[PenaltyID2][4]; ++ if (pRaInfo->NscUp > (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID2][5])) ++ pRaInfo->NscUp -= pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID2][5]; ++ else ++ pRaInfo->NscUp = 0; ++ ++ if ((pRaInfo->NscDown < N_THRESHOLD_LOW[RateID]) || ++ (pRaInfo->DROP > DROPING_NECESSARY[RateID])) ++ odm_RateDown_8188E(dm_odm, pRaInfo); ++ else if (pRaInfo->NscUp > N_THRESHOLD_HIGH[RateID]) ++ odm_RateUp_8188E(dm_odm, pRaInfo); ++ ++ if (pRaInfo->DecisionRate > pRaInfo->HighestRate) ++ pRaInfo->DecisionRate = pRaInfo->HighestRate; ++ ++ if ((pRaInfo->DecisionRate) == (pRaInfo->PreRate)) ++ DynamicTxRPTTimingCounter += 1; ++ else ++ DynamicTxRPTTimingCounter = 0; ++ ++ if (DynamicTxRPTTimingCounter >= 4) { ++ odm_SetTxRPTTiming_8188E(dm_odm, pRaInfo, 1); ++ DynamicTxRPTTimingCounter = 0; ++ } ++ ++ pRaInfo->PreRate = pRaInfo->DecisionRate; /* YJ, add, 120120 */ ++ ++ odm_ResetRaCounter_8188E(pRaInfo); ++ } ++} ++ ++static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_info *pRaInfo) ++{ /* Wilson 2011/10/26 */ ++ u32 MaskFromReg; ++ s8 i; ++ ++ switch (pRaInfo->RateID) { ++ case RATR_INX_WIRELESS_NGB: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0f8ff015; ++ break; ++ case RATR_INX_WIRELESS_NG: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0f8ff010; ++ break; ++ case RATR_INX_WIRELESS_NB: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0f8ff005; ++ break; ++ case RATR_INX_WIRELESS_N: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0f8ff000; ++ break; ++ case RATR_INX_WIRELESS_GB: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x00000ff5; ++ break; ++ case RATR_INX_WIRELESS_G: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x00000ff0; ++ break; ++ case RATR_INX_WIRELESS_B: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0000000d; ++ break; ++ case 12: ++ MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR0); ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg; ++ break; ++ case 13: ++ MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR1); ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg; ++ break; ++ case 14: ++ MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR2); ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg; ++ break; ++ case 15: ++ MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR3); ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg; ++ break; ++ default: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask); ++ break; ++ } ++ /* Highest rate */ ++ if (pRaInfo->RAUseRate) { ++ for (i = RATESIZE; i >= 0; i--) { ++ if ((pRaInfo->RAUseRate) & BIT(i)) { ++ pRaInfo->HighestRate = i; ++ break; ++ } ++ } ++ } else { ++ pRaInfo->HighestRate = 0; ++ } ++ /* Lowest rate */ ++ if (pRaInfo->RAUseRate) { ++ for (i = 0; i < RATESIZE; i++) { ++ if ((pRaInfo->RAUseRate) & BIT(i)) { ++ pRaInfo->LowestRate = i; ++ break; ++ } ++ } ++ } else { ++ pRaInfo->LowestRate = 0; ++ } ++ if (pRaInfo->HighestRate > 0x13) ++ pRaInfo->PTModeSS = 3; ++ else if (pRaInfo->HighestRate > 0x0b) ++ pRaInfo->PTModeSS = 2; ++ else if (pRaInfo->HighestRate > 0x03) ++ pRaInfo->PTModeSS = 1; ++ else ++ pRaInfo->PTModeSS = 0; ++ ++ if (pRaInfo->DecisionRate > pRaInfo->HighestRate) ++ pRaInfo->DecisionRate = pRaInfo->HighestRate; ++ ++ return 0; ++} ++ ++static void odm_PTTryState_8188E(struct odm_ra_info *pRaInfo) ++{ ++ pRaInfo->PTTryState = 0; ++ switch (pRaInfo->PTModeSS) { ++ case 3: ++ if (pRaInfo->DecisionRate >= 0x19) ++ pRaInfo->PTTryState = 1; ++ break; ++ case 2: ++ if (pRaInfo->DecisionRate >= 0x11) ++ pRaInfo->PTTryState = 1; ++ break; ++ case 1: ++ if (pRaInfo->DecisionRate >= 0x0a) ++ pRaInfo->PTTryState = 1; ++ break; ++ case 0: ++ if (pRaInfo->DecisionRate >= 0x03) ++ pRaInfo->PTTryState = 1; ++ break; ++ default: ++ pRaInfo->PTTryState = 0; ++ break; ++ } ++ ++ if (pRaInfo->RssiStaRA < 48) { ++ pRaInfo->PTStage = 0; ++ } else if (pRaInfo->PTTryState == 1) { ++ if ((pRaInfo->PTStopCount >= 10) || ++ (pRaInfo->PTPreRssi > pRaInfo->RssiStaRA + 5) || ++ (pRaInfo->PTPreRssi < pRaInfo->RssiStaRA - 5) || ++ (pRaInfo->DecisionRate != pRaInfo->PTPreRate)) { ++ if (pRaInfo->PTStage == 0) ++ pRaInfo->PTStage = 1; ++ else if (pRaInfo->PTStage == 1) ++ pRaInfo->PTStage = 3; ++ else ++ pRaInfo->PTStage = 5; ++ ++ pRaInfo->PTPreRssi = pRaInfo->RssiStaRA; ++ pRaInfo->PTStopCount = 0; ++ } else { ++ pRaInfo->RAstage = 0; ++ pRaInfo->PTStopCount++; ++ } ++ } else { ++ pRaInfo->PTStage = 0; ++ pRaInfo->RAstage = 0; ++ } ++ pRaInfo->PTPreRate = pRaInfo->DecisionRate; ++} ++ ++static void odm_PTDecision_8188E(struct odm_ra_info *pRaInfo) ++{ ++ u8 j; ++ u8 temp_stage; ++ u32 numsc; ++ u32 num_total; ++ u8 stage_id; ++ ++ numsc = 0; ++ num_total = pRaInfo->TOTAL * PT_PENALTY[5]; ++ for (j = 0; j <= 4; j++) { ++ numsc += pRaInfo->RTY[j] * PT_PENALTY[j]; ++ if (numsc > num_total) ++ break; ++ } ++ ++ j = j >> 1; ++ temp_stage = (pRaInfo->PTStage + 1) >> 1; ++ if (temp_stage > j) ++ stage_id = temp_stage - j; ++ else ++ stage_id = 0; ++ ++ pRaInfo->PTSmoothFactor = (pRaInfo->PTSmoothFactor >> 1) + (pRaInfo->PTSmoothFactor >> 2) + stage_id * 16 + 2; ++ if (pRaInfo->PTSmoothFactor > 192) ++ pRaInfo->PTSmoothFactor = 192; ++ stage_id = pRaInfo->PTSmoothFactor >> 6; ++ temp_stage = stage_id * 2; ++ if (temp_stage != 0) ++ temp_stage -= 1; ++ if (pRaInfo->DROP > 3) ++ temp_stage = 0; ++ pRaInfo->PTStage = temp_stage; ++} ++ ++static void ++odm_RATxRPTTimerSetting( ++ struct odm_dm_struct *dm_odm, ++ u16 minRptTime ++) ++{ ++ if (dm_odm->CurrminRptTime != minRptTime) { ++ rtw_rpt_timer_cfg_cmd(dm_odm->Adapter, minRptTime); ++ dm_odm->CurrminRptTime = minRptTime; ++ } ++} ++ ++void ++ODM_RASupport_Init( ++ struct odm_dm_struct *dm_odm ++ ) ++{ ++ /* 2012/02/14 MH Be noticed, the init must be after IC type is recognized!!!!! */ ++ if (dm_odm->SupportICType == ODM_RTL8188E) ++ dm_odm->RaSupport88E = true; ++} ++ ++int ODM_RAInfo_Init(struct odm_dm_struct *dm_odm, u8 macid) ++{ ++ struct odm_ra_info *pRaInfo = &dm_odm->RAInfo[macid]; ++ u8 WirelessMode = 0xFF; /* invalid value */ ++ u8 max_rate_idx = 0x13; /* MCS7 */ ++ if (dm_odm->pWirelessMode) ++ WirelessMode = *dm_odm->pWirelessMode; ++ ++ if (WirelessMode != 0xFF) { ++ if (WirelessMode & ODM_WM_N24G) ++ max_rate_idx = 0x13; ++ else if (WirelessMode & ODM_WM_G) ++ max_rate_idx = 0x0b; ++ else if (WirelessMode & ODM_WM_B) ++ max_rate_idx = 0x03; ++ } ++ ++ pRaInfo->DecisionRate = max_rate_idx; ++ pRaInfo->PreRate = max_rate_idx; ++ pRaInfo->HighestRate = max_rate_idx; ++ pRaInfo->LowestRate = 0; ++ pRaInfo->RateID = 0; ++ pRaInfo->RateMask = 0xffffffff; ++ pRaInfo->RssiStaRA = 0; ++ pRaInfo->PreRssiStaRA = 0; ++ pRaInfo->SGIEnable = 0; ++ pRaInfo->RAUseRate = 0xffffffff; ++ pRaInfo->NscDown = (N_THRESHOLD_HIGH[0x13] + N_THRESHOLD_LOW[0x13]) / 2; ++ pRaInfo->NscUp = (N_THRESHOLD_HIGH[0x13] + N_THRESHOLD_LOW[0x13]) / 2; ++ pRaInfo->RateSGI = 0; ++ pRaInfo->Active = 1; /* Active is not used at present. by page, 110819 */ ++ pRaInfo->RptTime = 0x927c; ++ pRaInfo->DROP = 0; ++ pRaInfo->RTY[0] = 0; ++ pRaInfo->RTY[1] = 0; ++ pRaInfo->RTY[2] = 0; ++ pRaInfo->RTY[3] = 0; ++ pRaInfo->RTY[4] = 0; ++ pRaInfo->TOTAL = 0; ++ pRaInfo->RAWaitingCounter = 0; ++ pRaInfo->RAPendingCounter = 0; ++ pRaInfo->PTActive = 1; /* Active when this STA is use */ ++ pRaInfo->PTTryState = 0; ++ pRaInfo->PTStage = 5; /* Need to fill into HW_PWR_STATUS */ ++ pRaInfo->PTSmoothFactor = 192; ++ pRaInfo->PTStopCount = 0; ++ pRaInfo->PTPreRate = 0; ++ pRaInfo->PTPreRssi = 0; ++ pRaInfo->PTModeSS = 0; ++ pRaInfo->RAstage = 0; ++ return 0; ++} ++ ++int ODM_RAInfo_Init_all(struct odm_dm_struct *dm_odm) ++{ ++ u8 macid = 0; ++ ++ dm_odm->CurrminRptTime = 0; ++ ++ for (macid = 0; macid < ODM_ASSOCIATE_ENTRY_NUM; macid++) ++ ODM_RAInfo_Init(dm_odm, macid); ++ ++ return 0; ++} ++ ++u8 ODM_RA_GetShortGI_8188E(struct odm_dm_struct *dm_odm, u8 macid) ++{ ++ if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) ++ return 0; ++ return dm_odm->RAInfo[macid].RateSGI; ++} ++ ++u8 ODM_RA_GetDecisionRate_8188E(struct odm_dm_struct *dm_odm, u8 macid) ++{ ++ u8 DecisionRate = 0; ++ ++ if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) ++ return 0; ++ DecisionRate = (dm_odm->RAInfo[macid].DecisionRate); ++ return DecisionRate; ++} ++ ++u8 ODM_RA_GetHwPwrStatus_8188E(struct odm_dm_struct *dm_odm, u8 macid) ++{ ++ u8 PTStage = 5; ++ ++ if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) ++ return 0; ++ PTStage = (dm_odm->RAInfo[macid].PTStage); ++ return PTStage; ++} ++ ++void ODM_RA_UpdateRateInfo_8188E(struct odm_dm_struct *dm_odm, u8 macid, u8 RateID, u32 RateMask, u8 SGIEnable) ++{ ++ struct odm_ra_info *pRaInfo = NULL; ++ ++ if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) ++ return; ++ ++ pRaInfo = &dm_odm->RAInfo[macid]; ++ pRaInfo->RateID = RateID; ++ pRaInfo->RateMask = RateMask; ++ pRaInfo->SGIEnable = SGIEnable; ++ odm_ARFBRefresh_8188E(dm_odm, pRaInfo); ++} ++ ++void ODM_RA_SetRSSI_8188E(struct odm_dm_struct *dm_odm, u8 macid, u8 Rssi) ++{ ++ struct odm_ra_info *pRaInfo = NULL; ++ ++ if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) ++ return; ++ ++ pRaInfo = &dm_odm->RAInfo[macid]; ++ pRaInfo->RssiStaRA = Rssi; ++} ++ ++void ODM_RA_Set_TxRPT_Time(struct odm_dm_struct *dm_odm, u16 minRptTime) ++{ ++ ODM_Write2Byte(dm_odm, REG_TX_RPT_TIME, minRptTime); ++} ++ ++void ODM_RA_TxRPT2Handle_8188E(struct odm_dm_struct *dm_odm, u8 *TxRPT_Buf, u16 TxRPT_Len, u32 macid_entry0, u32 macid_entry1) ++{ ++ struct odm_ra_info *pRAInfo = NULL; ++ u8 MacId = 0; ++ u8 *pBuffer = NULL; ++ u32 valid = 0, ItemNum = 0; ++ u16 minRptTime = 0x927c; ++ ++ ItemNum = TxRPT_Len >> 3; ++ pBuffer = TxRPT_Buf; ++ ++ do { ++ if (MacId >= ASSOCIATE_ENTRY_NUM) ++ valid = 0; ++ else if (MacId >= 32) ++ valid = (1 << (MacId - 32)) & macid_entry1; ++ else ++ valid = (1 << MacId) & macid_entry0; ++ ++ pRAInfo = &dm_odm->RAInfo[MacId]; ++ if (valid) { ++ pRAInfo->RTY[0] = (u16)GET_TX_REPORT_TYPE1_RERTY_0(pBuffer); ++ pRAInfo->RTY[1] = (u16)GET_TX_REPORT_TYPE1_RERTY_1(pBuffer); ++ pRAInfo->RTY[2] = (u16)GET_TX_REPORT_TYPE1_RERTY_2((u8 *)pBuffer); ++ pRAInfo->RTY[3] = (u16)GET_TX_REPORT_TYPE1_RERTY_3(pBuffer); ++ pRAInfo->RTY[4] = (u16)GET_TX_REPORT_TYPE1_RERTY_4(pBuffer); ++ pRAInfo->DROP = (u16)GET_TX_REPORT_TYPE1_DROP_0(pBuffer); ++ pRAInfo->TOTAL = pRAInfo->RTY[0] + pRAInfo->RTY[1] + ++ pRAInfo->RTY[2] + pRAInfo->RTY[3] + ++ pRAInfo->RTY[4] + pRAInfo->DROP; ++ if (pRAInfo->TOTAL != 0) { ++ if (pRAInfo->PTActive) { ++ if (pRAInfo->RAstage < 5) ++ odm_RateDecision_8188E(dm_odm, pRAInfo); ++ else if (pRAInfo->RAstage == 5) /* Power training try state */ ++ odm_PTTryState_8188E(pRAInfo); ++ else /* RAstage == 6 */ ++ odm_PTDecision_8188E(pRAInfo); ++ ++ /* Stage_RA counter */ ++ if (pRAInfo->RAstage <= 5) ++ pRAInfo->RAstage++; ++ else ++ pRAInfo->RAstage = 0; ++ } else { ++ odm_RateDecision_8188E(dm_odm, pRAInfo); ++ } ++ } ++ } ++ ++ if (minRptTime > pRAInfo->RptTime) ++ minRptTime = pRAInfo->RptTime; ++ ++ pBuffer += TX_RPT2_ITEM_SIZE; ++ MacId++; ++ } while (MacId < ItemNum); ++ ++ odm_RATxRPTTimerSetting(dm_odm, minRptTime); ++} +diff --git a/drivers/staging/r8188eu/hal/HalHWImg8188E_BB.c b/drivers/staging/r8188eu/hal/HalHWImg8188E_BB.c +new file mode 100644 +index 000000000000..55aa20a30342 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/HalHWImg8188E_BB.c +@@ -0,0 +1,702 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++#include "../include/rtw_iol.h" ++ ++#define read_next_pair(array, v1, v2, i) \ ++ do { \ ++ i += 2; \ ++ v1 = array[i]; \ ++ v2 = array[i + 1]; \ ++ } while (0) ++ ++static bool CheckCondition(const u32 condition, const u32 hex) ++{ ++ u32 _board = (hex & 0x000000FF); ++ u32 _interface = (hex & 0x0000FF00) >> 8; ++ u32 _platform = (hex & 0x00FF0000) >> 16; ++ u32 cond = condition; ++ ++ if (condition == 0xCDCDCDCD) ++ return true; ++ ++ cond = condition & 0x000000FF; ++ if ((_board == cond) && cond != 0x00) ++ return false; ++ ++ cond = condition & 0x0000FF00; ++ cond = cond >> 8; ++ if ((_interface & cond) == 0 && cond != 0x07) ++ return false; ++ ++ cond = condition & 0x00FF0000; ++ cond = cond >> 16; ++ if ((_platform & cond) == 0 && cond != 0x0F) ++ return false; ++ return true; ++} ++ ++/****************************************************************************** ++* AGC_TAB_1T.TXT ++******************************************************************************/ ++ ++static u32 array_agc_tab_1t_8188e[] = { ++ 0xC78, 0xFB000001, ++ 0xC78, 0xFB010001, ++ 0xC78, 0xFB020001, ++ 0xC78, 0xFB030001, ++ 0xC78, 0xFB040001, ++ 0xC78, 0xFB050001, ++ 0xC78, 0xFA060001, ++ 0xC78, 0xF9070001, ++ 0xC78, 0xF8080001, ++ 0xC78, 0xF7090001, ++ 0xC78, 0xF60A0001, ++ 0xC78, 0xF50B0001, ++ 0xC78, 0xF40C0001, ++ 0xC78, 0xF30D0001, ++ 0xC78, 0xF20E0001, ++ 0xC78, 0xF10F0001, ++ 0xC78, 0xF0100001, ++ 0xC78, 0xEF110001, ++ 0xC78, 0xEE120001, ++ 0xC78, 0xED130001, ++ 0xC78, 0xEC140001, ++ 0xC78, 0xEB150001, ++ 0xC78, 0xEA160001, ++ 0xC78, 0xE9170001, ++ 0xC78, 0xE8180001, ++ 0xC78, 0xE7190001, ++ 0xC78, 0xE61A0001, ++ 0xC78, 0xE51B0001, ++ 0xC78, 0xE41C0001, ++ 0xC78, 0xE31D0001, ++ 0xC78, 0xE21E0001, ++ 0xC78, 0xE11F0001, ++ 0xC78, 0x8A200001, ++ 0xC78, 0x89210001, ++ 0xC78, 0x88220001, ++ 0xC78, 0x87230001, ++ 0xC78, 0x86240001, ++ 0xC78, 0x85250001, ++ 0xC78, 0x84260001, ++ 0xC78, 0x83270001, ++ 0xC78, 0x82280001, ++ 0xC78, 0x6B290001, ++ 0xC78, 0x6A2A0001, ++ 0xC78, 0x692B0001, ++ 0xC78, 0x682C0001, ++ 0xC78, 0x672D0001, ++ 0xC78, 0x662E0001, ++ 0xC78, 0x652F0001, ++ 0xC78, 0x64300001, ++ 0xC78, 0x63310001, ++ 0xC78, 0x62320001, ++ 0xC78, 0x61330001, ++ 0xC78, 0x46340001, ++ 0xC78, 0x45350001, ++ 0xC78, 0x44360001, ++ 0xC78, 0x43370001, ++ 0xC78, 0x42380001, ++ 0xC78, 0x41390001, ++ 0xC78, 0x403A0001, ++ 0xC78, 0x403B0001, ++ 0xC78, 0x403C0001, ++ 0xC78, 0x403D0001, ++ 0xC78, 0x403E0001, ++ 0xC78, 0x403F0001, ++ 0xC78, 0xFB400001, ++ 0xC78, 0xFB410001, ++ 0xC78, 0xFB420001, ++ 0xC78, 0xFB430001, ++ 0xC78, 0xFB440001, ++ 0xC78, 0xFB450001, ++ 0xC78, 0xFB460001, ++ 0xC78, 0xFB470001, ++ 0xC78, 0xFB480001, ++ 0xC78, 0xFA490001, ++ 0xC78, 0xF94A0001, ++ 0xC78, 0xF84B0001, ++ 0xC78, 0xF74C0001, ++ 0xC78, 0xF64D0001, ++ 0xC78, 0xF54E0001, ++ 0xC78, 0xF44F0001, ++ 0xC78, 0xF3500001, ++ 0xC78, 0xF2510001, ++ 0xC78, 0xF1520001, ++ 0xC78, 0xF0530001, ++ 0xC78, 0xEF540001, ++ 0xC78, 0xEE550001, ++ 0xC78, 0xED560001, ++ 0xC78, 0xEC570001, ++ 0xC78, 0xEB580001, ++ 0xC78, 0xEA590001, ++ 0xC78, 0xE95A0001, ++ 0xC78, 0xE85B0001, ++ 0xC78, 0xE75C0001, ++ 0xC78, 0xE65D0001, ++ 0xC78, 0xE55E0001, ++ 0xC78, 0xE45F0001, ++ 0xC78, 0xE3600001, ++ 0xC78, 0xE2610001, ++ 0xC78, 0xC3620001, ++ 0xC78, 0xC2630001, ++ 0xC78, 0xC1640001, ++ 0xC78, 0x8B650001, ++ 0xC78, 0x8A660001, ++ 0xC78, 0x89670001, ++ 0xC78, 0x88680001, ++ 0xC78, 0x87690001, ++ 0xC78, 0x866A0001, ++ 0xC78, 0x856B0001, ++ 0xC78, 0x846C0001, ++ 0xC78, 0x676D0001, ++ 0xC78, 0x666E0001, ++ 0xC78, 0x656F0001, ++ 0xC78, 0x64700001, ++ 0xC78, 0x63710001, ++ 0xC78, 0x62720001, ++ 0xC78, 0x61730001, ++ 0xC78, 0x60740001, ++ 0xC78, 0x46750001, ++ 0xC78, 0x45760001, ++ 0xC78, 0x44770001, ++ 0xC78, 0x43780001, ++ 0xC78, 0x42790001, ++ 0xC78, 0x417A0001, ++ 0xC78, 0x407B0001, ++ 0xC78, 0x407C0001, ++ 0xC78, 0x407D0001, ++ 0xC78, 0x407E0001, ++ 0xC78, 0x407F0001, ++}; ++ ++enum HAL_STATUS ODM_ReadAndConfig_AGC_TAB_1T_8188E(struct odm_dm_struct *dm_odm) ++{ ++ u32 hex = 0; ++ u32 i = 0; ++ u8 platform = dm_odm->SupportPlatform; ++ u8 interfaceValue = dm_odm->SupportInterface; ++ u8 board = dm_odm->BoardType; ++ u32 arraylen = sizeof(array_agc_tab_1t_8188e) / sizeof(u32); ++ u32 *array = array_agc_tab_1t_8188e; ++ bool biol = false; ++ struct adapter *adapter = dm_odm->Adapter; ++ struct xmit_frame *pxmit_frame = NULL; ++ u8 bndy_cnt = 1; ++ enum HAL_STATUS rst = HAL_STATUS_SUCCESS; ++ ++ hex += board; ++ hex += interfaceValue << 8; ++ hex += platform << 16; ++ hex += 0xFF000000; ++ biol = rtw_IOL_applied(adapter); ++ ++ if (biol) { ++ pxmit_frame = rtw_IOL_accquire_xmit_frame(adapter); ++ if (!pxmit_frame) { ++ pr_info("rtw_IOL_accquire_xmit_frame failed\n"); ++ return HAL_STATUS_FAILURE; ++ } ++ } ++ ++ for (i = 0; i < arraylen; i += 2) { ++ u32 v1 = array[i]; ++ u32 v2 = array[i + 1]; ++ ++ /* This (offset, data) pair meets the condition. */ ++ if (v1 < 0xCDCDCDCD) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord); ++ } else { ++ odm_ConfigBB_AGC_8188E(dm_odm, v1, bMaskDWord, v2); ++ } ++ continue; ++ } else { ++ /* This line is the start line of branch. */ ++ if (!CheckCondition(array[i], hex)) { ++ /* Discard the following (offset, data) pairs. */ ++ read_next_pair(array, v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < arraylen - 2) ++ read_next_pair(array, v1, v2, i); ++ i -= 2; /* prevent from for-loop += 2 */ ++ } else { /* Configure matched pairs and skip to end of if-else. */ ++ read_next_pair(array, v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < arraylen - 2) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord); ++ } else { ++ odm_ConfigBB_AGC_8188E(dm_odm, v1, bMaskDWord, v2); ++ } ++ read_next_pair(array, v1, v2, i); ++ } ++ ++ while (v2 != 0xDEAD && i < arraylen - 2) ++ read_next_pair(array, v1, v2, i); ++ } ++ } ++ } ++ if (biol) { ++ if (!rtw_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { ++ printk("~~~ %s IOL_exec_cmds Failed !!!\n", __func__); ++ rst = HAL_STATUS_FAILURE; ++ } ++ } ++ return rst; ++} ++ ++/****************************************************************************** ++* PHY_REG_1T.TXT ++******************************************************************************/ ++ ++static u32 array_phy_reg_1t_8188e[] = { ++ 0x800, 0x80040000, ++ 0x804, 0x00000003, ++ 0x808, 0x0000FC00, ++ 0x80C, 0x0000000A, ++ 0x810, 0x10001331, ++ 0x814, 0x020C3D10, ++ 0x818, 0x02200385, ++ 0x81C, 0x00000000, ++ 0x820, 0x01000100, ++ 0x824, 0x00390204, ++ 0x828, 0x00000000, ++ 0x82C, 0x00000000, ++ 0x830, 0x00000000, ++ 0x834, 0x00000000, ++ 0x838, 0x00000000, ++ 0x83C, 0x00000000, ++ 0x840, 0x00010000, ++ 0x844, 0x00000000, ++ 0x848, 0x00000000, ++ 0x84C, 0x00000000, ++ 0x850, 0x00000000, ++ 0x854, 0x00000000, ++ 0x858, 0x569A11A9, ++ 0x85C, 0x01000014, ++ 0x860, 0x66F60110, ++ 0x864, 0x061F0649, ++ 0x868, 0x00000000, ++ 0x86C, 0x27272700, ++ 0x870, 0x07000760, ++ 0x874, 0x25004000, ++ 0x878, 0x00000808, ++ 0x87C, 0x00000000, ++ 0x880, 0xB0000C1C, ++ 0x884, 0x00000001, ++ 0x888, 0x00000000, ++ 0x88C, 0xCCC000C0, ++ 0x890, 0x00000800, ++ 0x894, 0xFFFFFFFE, ++ 0x898, 0x40302010, ++ 0x89C, 0x00706050, ++ 0x900, 0x00000000, ++ 0x904, 0x00000023, ++ 0x908, 0x00000000, ++ 0x90C, 0x81121111, ++ 0x910, 0x00000002, ++ 0x914, 0x00000201, ++ 0xA00, 0x00D047C8, ++ 0xA04, 0x80FF000C, ++ 0xA08, 0x8C838300, ++ 0xA0C, 0x2E7F120F, ++ 0xA10, 0x9500BB78, ++ 0xA14, 0x1114D028, ++ 0xA18, 0x00881117, ++ 0xA1C, 0x89140F00, ++ 0xA20, 0x1A1B0000, ++ 0xA24, 0x090E1317, ++ 0xA28, 0x00000204, ++ 0xA2C, 0x00D30000, ++ 0xA70, 0x101FBF00, ++ 0xA74, 0x00000007, ++ 0xA78, 0x00000900, ++ 0xA7C, 0x225B0606, ++ 0xA80, 0x218075B1, ++ 0xB2C, 0x80000000, ++ 0xC00, 0x48071D40, ++ 0xC04, 0x03A05611, ++ 0xC08, 0x000000E4, ++ 0xC0C, 0x6C6C6C6C, ++ 0xC10, 0x08800000, ++ 0xC14, 0x40000100, ++ 0xC18, 0x08800000, ++ 0xC1C, 0x40000100, ++ 0xC20, 0x00000000, ++ 0xC24, 0x00000000, ++ 0xC28, 0x00000000, ++ 0xC2C, 0x00000000, ++ 0xC30, 0x69E9AC47, ++ 0xC34, 0x469652AF, ++ 0xC38, 0x49795994, ++ 0xC3C, 0x0A97971C, ++ 0xC40, 0x1F7C403F, ++ 0xC44, 0x000100B7, ++ 0xC48, 0xEC020107, ++ 0xC4C, 0x007F037F, ++ 0xC50, 0x69553420, ++ 0xC54, 0x43BC0094, ++ 0xC58, 0x00013169, ++ 0xC5C, 0x00250492, ++ 0xC60, 0x00000000, ++ 0xC64, 0x7112848B, ++ 0xC68, 0x47C00BFF, ++ 0xC6C, 0x00000036, ++ 0xC70, 0x2C7F000D, ++ 0xC74, 0x020610DB, ++ 0xC78, 0x0000001F, ++ 0xC7C, 0x00B91612, ++ 0xC80, 0x390000E4, ++ 0xC84, 0x20F60000, ++ 0xC88, 0x40000100, ++ 0xC8C, 0x20200000, ++ 0xC90, 0x00091521, ++ 0xC94, 0x00000000, ++ 0xC98, 0x00121820, ++ 0xC9C, 0x00007F7F, ++ 0xCA0, 0x00000000, ++ 0xCA4, 0x000300A0, ++ 0xCA8, 0x00000000, ++ 0xCAC, 0x00000000, ++ 0xCB0, 0x00000000, ++ 0xCB4, 0x00000000, ++ 0xCB8, 0x00000000, ++ 0xCBC, 0x28000000, ++ 0xCC0, 0x00000000, ++ 0xCC4, 0x00000000, ++ 0xCC8, 0x00000000, ++ 0xCCC, 0x00000000, ++ 0xCD0, 0x00000000, ++ 0xCD4, 0x00000000, ++ 0xCD8, 0x64B22427, ++ 0xCDC, 0x00766932, ++ 0xCE0, 0x00222222, ++ 0xCE4, 0x00000000, ++ 0xCE8, 0x37644302, ++ 0xCEC, 0x2F97D40C, ++ 0xD00, 0x00000740, ++ 0xD04, 0x00020401, ++ 0xD08, 0x0000907F, ++ 0xD0C, 0x20010201, ++ 0xD10, 0xA0633333, ++ 0xD14, 0x3333BC43, ++ 0xD18, 0x7A8F5B6F, ++ 0xD2C, 0xCC979975, ++ 0xD30, 0x00000000, ++ 0xD34, 0x80608000, ++ 0xD38, 0x00000000, ++ 0xD3C, 0x00127353, ++ 0xD40, 0x00000000, ++ 0xD44, 0x00000000, ++ 0xD48, 0x00000000, ++ 0xD4C, 0x00000000, ++ 0xD50, 0x6437140A, ++ 0xD54, 0x00000000, ++ 0xD58, 0x00000282, ++ 0xD5C, 0x30032064, ++ 0xD60, 0x4653DE68, ++ 0xD64, 0x04518A3C, ++ 0xD68, 0x00002101, ++ 0xD6C, 0x2A201C16, ++ 0xD70, 0x1812362E, ++ 0xD74, 0x322C2220, ++ 0xD78, 0x000E3C24, ++ 0xE00, 0x2D2D2D2D, ++ 0xE04, 0x2D2D2D2D, ++ 0xE08, 0x0390272D, ++ 0xE10, 0x2D2D2D2D, ++ 0xE14, 0x2D2D2D2D, ++ 0xE18, 0x2D2D2D2D, ++ 0xE1C, 0x2D2D2D2D, ++ 0xE28, 0x00000000, ++ 0xE30, 0x1000DC1F, ++ 0xE34, 0x10008C1F, ++ 0xE38, 0x02140102, ++ 0xE3C, 0x681604C2, ++ 0xE40, 0x01007C00, ++ 0xE44, 0x01004800, ++ 0xE48, 0xFB000000, ++ 0xE4C, 0x000028D1, ++ 0xE50, 0x1000DC1F, ++ 0xE54, 0x10008C1F, ++ 0xE58, 0x02140102, ++ 0xE5C, 0x28160D05, ++ 0xE60, 0x00000008, ++ 0xE68, 0x001B25A4, ++ 0xE6C, 0x00C00014, ++ 0xE70, 0x00C00014, ++ 0xE74, 0x01000014, ++ 0xE78, 0x01000014, ++ 0xE7C, 0x01000014, ++ 0xE80, 0x01000014, ++ 0xE84, 0x00C00014, ++ 0xE88, 0x01000014, ++ 0xE8C, 0x00C00014, ++ 0xED0, 0x00C00014, ++ 0xED4, 0x00C00014, ++ 0xED8, 0x00C00014, ++ 0xEDC, 0x00000014, ++ 0xEE0, 0x00000014, ++ 0xEEC, 0x01C00014, ++ 0xF14, 0x00000003, ++ 0xF4C, 0x00000000, ++ 0xF00, 0x00000300, ++}; ++ ++enum HAL_STATUS ODM_ReadAndConfig_PHY_REG_1T_8188E(struct odm_dm_struct *dm_odm) ++{ ++ u32 hex = 0; ++ u32 i = 0; ++ u8 platform = dm_odm->SupportPlatform; ++ u8 interfaceValue = dm_odm->SupportInterface; ++ u8 board = dm_odm->BoardType; ++ u32 arraylen = sizeof(array_phy_reg_1t_8188e) / sizeof(u32); ++ u32 *array = array_phy_reg_1t_8188e; ++ bool biol = false; ++ struct adapter *adapter = dm_odm->Adapter; ++ struct xmit_frame *pxmit_frame = NULL; ++ u8 bndy_cnt = 1; ++ enum HAL_STATUS rst = HAL_STATUS_SUCCESS; ++ hex += board; ++ hex += interfaceValue << 8; ++ hex += platform << 16; ++ hex += 0xFF000000; ++ biol = rtw_IOL_applied(adapter); ++ ++ if (biol) { ++ pxmit_frame = rtw_IOL_accquire_xmit_frame(adapter); ++ if (!pxmit_frame) { ++ pr_info("rtw_IOL_accquire_xmit_frame failed\n"); ++ return HAL_STATUS_FAILURE; ++ } ++ } ++ ++ for (i = 0; i < arraylen; i += 2) { ++ u32 v1 = array[i]; ++ u32 v2 = array[i + 1]; ++ ++ /* This (offset, data) pair meets the condition. */ ++ if (v1 < 0xCDCDCDCD) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ if (v1 == 0xfe) { ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50); ++ } else if (v1 == 0xfd) { ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5); ++ } else if (v1 == 0xfc) { ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1); ++ } else if (v1 == 0xfb) { ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50); ++ } else if (v1 == 0xfa) { ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5); ++ } else if (v1 == 0xf9) { ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1); ++ } else { ++ if (v1 == 0xa24) ++ dm_odm->RFCalibrateInfo.RegA24 = v2; ++ rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord); ++ } ++ } else { ++ odm_ConfigBB_PHY_8188E(dm_odm, v1, bMaskDWord, v2); ++ } ++ continue; ++ } else { /* This line is the start line of branch. */ ++ if (!CheckCondition(array[i], hex)) { ++ /* Discard the following (offset, data) pairs. */ ++ read_next_pair(array, v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < arraylen - 2) ++ read_next_pair(array, v1, v2, i); ++ i -= 2; /* prevent from for-loop += 2 */ ++ } else { /* Configure matched pairs and skip to end of if-else. */ ++ read_next_pair(array, v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < arraylen - 2) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ if (v1 == 0xfe) { ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50); ++ } else if (v1 == 0xfd) { ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5); ++ } else if (v1 == 0xfc) { ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1); ++ } else if (v1 == 0xfb) { ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50); ++ } else if (v1 == 0xfa) { ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5); ++ } else if (v1 == 0xf9) { ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1); ++ } else { ++ if (v1 == 0xa24) ++ dm_odm->RFCalibrateInfo.RegA24 = v2; ++ ++ rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord); ++ } ++ } else { ++ odm_ConfigBB_PHY_8188E(dm_odm, v1, bMaskDWord, v2); ++ } ++ read_next_pair(array, v1, v2, i); ++ } ++ ++ while (v2 != 0xDEAD && i < arraylen - 2) ++ read_next_pair(array, v1, v2, i); ++ } ++ } ++ } ++ if (biol) { ++ if (!rtw_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { ++ rst = HAL_STATUS_FAILURE; ++ pr_info("~~~ IOL Config %s Failed !!!\n", __func__); ++ } ++ } ++ return rst; ++} ++ ++/****************************************************************************** ++* PHY_REG_PG.TXT ++******************************************************************************/ ++ ++static u32 array_phy_reg_pg_8188e[] = { ++ 0xE00, 0xFFFFFFFF, 0x06070809, ++ 0xE04, 0xFFFFFFFF, 0x02020405, ++ 0xE08, 0x0000FF00, 0x00000006, ++ 0x86C, 0xFFFFFF00, 0x00020400, ++ 0xE10, 0xFFFFFFFF, 0x08090A0B, ++ 0xE14, 0xFFFFFFFF, 0x01030607, ++ 0xE18, 0xFFFFFFFF, 0x08090A0B, ++ 0xE1C, 0xFFFFFFFF, 0x01030607, ++ 0xE00, 0xFFFFFFFF, 0x00000000, ++ 0xE04, 0xFFFFFFFF, 0x00000000, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x00000000, ++ 0xE14, 0xFFFFFFFF, 0x00000000, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x02020202, ++ 0xE04, 0xFFFFFFFF, 0x00020202, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x04040404, ++ 0xE14, 0xFFFFFFFF, 0x00020404, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x02020202, ++ 0xE04, 0xFFFFFFFF, 0x00020202, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x04040404, ++ 0xE14, 0xFFFFFFFF, 0x00020404, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x00000000, ++ 0xE04, 0xFFFFFFFF, 0x00000000, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x00000000, ++ 0xE14, 0xFFFFFFFF, 0x00000000, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x02020202, ++ 0xE04, 0xFFFFFFFF, 0x00020202, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x04040404, ++ 0xE14, 0xFFFFFFFF, 0x00020404, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x00000000, ++ 0xE04, 0xFFFFFFFF, 0x00000000, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x00000000, ++ 0xE14, 0xFFFFFFFF, 0x00000000, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x00000000, ++ 0xE04, 0xFFFFFFFF, 0x00000000, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x00000000, ++ 0xE14, 0xFFFFFFFF, 0x00000000, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x00000000, ++ 0xE04, 0xFFFFFFFF, 0x00000000, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x00000000, ++ 0xE14, 0xFFFFFFFF, 0x00000000, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x00000000, ++ 0xE04, 0xFFFFFFFF, 0x00000000, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x00000000, ++ 0xE14, 0xFFFFFFFF, 0x00000000, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x00000000, ++ 0xE04, 0xFFFFFFFF, 0x00000000, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x00000000, ++ 0xE14, 0xFFFFFFFF, 0x00000000, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ ++}; ++ ++void ODM_ReadAndConfig_PHY_REG_PG_8188E(struct odm_dm_struct *dm_odm) ++{ ++ u32 hex; ++ u32 i = 0; ++ u8 platform = dm_odm->SupportPlatform; ++ u8 interfaceValue = dm_odm->SupportInterface; ++ u8 board = dm_odm->BoardType; ++ u32 arraylen = sizeof(array_phy_reg_pg_8188e) / sizeof(u32); ++ u32 *array = array_phy_reg_pg_8188e; ++ ++ hex = board + (interfaceValue << 8); ++ hex += (platform << 16) + 0xFF000000; ++ ++ for (i = 0; i < arraylen; i += 3) { ++ u32 v1 = array[i]; ++ u32 v2 = array[i + 1]; ++ u32 v3 = array[i + 2]; ++ ++ /* this line is a line of pure_body */ ++ if (v1 < 0xCDCDCDCD) { ++ odm_ConfigBB_PHY_REG_PG_8188E(dm_odm, v1, v2, v3); ++ continue; ++ } else { /* this line is the start of branch */ ++ if (!CheckCondition(array[i], hex)) { ++ /* don't need the hw_body */ ++ i += 2; /* skip the pair of expression */ ++ v1 = array[i]; ++ v2 = array[i + 1]; ++ v3 = array[i + 2]; ++ while (v2 != 0xDEAD) { ++ i += 3; ++ v1 = array[i]; ++ v2 = array[i + 1]; ++ v3 = array[i + 1]; ++ } ++ } ++ } ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/HalHWImg8188E_MAC.c b/drivers/staging/r8188eu/hal/HalHWImg8188E_MAC.c +new file mode 100644 +index 000000000000..0ff2609c26bb +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/HalHWImg8188E_MAC.c +@@ -0,0 +1,213 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++#include "../include/rtw_iol.h" ++ ++static bool Checkcondition(const u32 condition, const u32 hex) ++{ ++ u32 _board = (hex & 0x000000FF); ++ u32 _interface = (hex & 0x0000FF00) >> 8; ++ u32 _platform = (hex & 0x00FF0000) >> 16; ++ u32 cond = condition; ++ ++ if (condition == 0xCDCDCDCD) ++ return true; ++ ++ cond = condition & 0x000000FF; ++ if ((_board == cond) && cond != 0x00) ++ return false; ++ ++ cond = condition & 0x0000FF00; ++ cond = cond >> 8; ++ if ((_interface & cond) == 0 && cond != 0x07) ++ return false; ++ ++ cond = condition & 0x00FF0000; ++ cond = cond >> 16; ++ if ((_platform & cond) == 0 && cond != 0x0F) ++ return false; ++ return true; ++} ++ ++/****************************************************************************** ++* MAC_REG.TXT ++******************************************************************************/ ++ ++static u32 array_MAC_REG_8188E[] = { ++ 0x026, 0x00000041, ++ 0x027, 0x00000035, ++ 0x428, 0x0000000A, ++ 0x429, 0x00000010, ++ 0x430, 0x00000000, ++ 0x431, 0x00000001, ++ 0x432, 0x00000002, ++ 0x433, 0x00000004, ++ 0x434, 0x00000005, ++ 0x435, 0x00000006, ++ 0x436, 0x00000007, ++ 0x437, 0x00000008, ++ 0x438, 0x00000000, ++ 0x439, 0x00000000, ++ 0x43A, 0x00000001, ++ 0x43B, 0x00000002, ++ 0x43C, 0x00000004, ++ 0x43D, 0x00000005, ++ 0x43E, 0x00000006, ++ 0x43F, 0x00000007, ++ 0x440, 0x0000005D, ++ 0x441, 0x00000001, ++ 0x442, 0x00000000, ++ 0x444, 0x00000015, ++ 0x445, 0x000000F0, ++ 0x446, 0x0000000F, ++ 0x447, 0x00000000, ++ 0x458, 0x00000041, ++ 0x459, 0x000000A8, ++ 0x45A, 0x00000072, ++ 0x45B, 0x000000B9, ++ 0x460, 0x00000066, ++ 0x461, 0x00000066, ++ 0x480, 0x00000008, ++ 0x4C8, 0x000000FF, ++ 0x4C9, 0x00000008, ++ 0x4CC, 0x000000FF, ++ 0x4CD, 0x000000FF, ++ 0x4CE, 0x00000001, ++ 0x4D3, 0x00000001, ++ 0x500, 0x00000026, ++ 0x501, 0x000000A2, ++ 0x502, 0x0000002F, ++ 0x503, 0x00000000, ++ 0x504, 0x00000028, ++ 0x505, 0x000000A3, ++ 0x506, 0x0000005E, ++ 0x507, 0x00000000, ++ 0x508, 0x0000002B, ++ 0x509, 0x000000A4, ++ 0x50A, 0x0000005E, ++ 0x50B, 0x00000000, ++ 0x50C, 0x0000004F, ++ 0x50D, 0x000000A4, ++ 0x50E, 0x00000000, ++ 0x50F, 0x00000000, ++ 0x512, 0x0000001C, ++ 0x514, 0x0000000A, ++ 0x516, 0x0000000A, ++ 0x525, 0x0000004F, ++ 0x550, 0x00000010, ++ 0x551, 0x00000010, ++ 0x559, 0x00000002, ++ 0x55D, 0x000000FF, ++ 0x605, 0x00000030, ++ 0x608, 0x0000000E, ++ 0x609, 0x0000002A, ++ 0x620, 0x000000FF, ++ 0x621, 0x000000FF, ++ 0x622, 0x000000FF, ++ 0x623, 0x000000FF, ++ 0x624, 0x000000FF, ++ 0x625, 0x000000FF, ++ 0x626, 0x000000FF, ++ 0x627, 0x000000FF, ++ 0x652, 0x00000020, ++ 0x63C, 0x0000000A, ++ 0x63D, 0x0000000A, ++ 0x63E, 0x0000000E, ++ 0x63F, 0x0000000E, ++ 0x640, 0x00000040, ++ 0x66E, 0x00000005, ++ 0x700, 0x00000021, ++ 0x701, 0x00000043, ++ 0x702, 0x00000065, ++ 0x703, 0x00000087, ++ 0x708, 0x00000021, ++ 0x709, 0x00000043, ++ 0x70A, 0x00000065, ++ 0x70B, 0x00000087, ++}; ++ ++enum HAL_STATUS ODM_ReadAndConfig_MAC_REG_8188E(struct odm_dm_struct *dm_odm) ++{ ++ #define READ_NEXT_PAIR(v1, v2, i) do { i += 2; v1 = array[i]; v2 = array[i + 1]; } while (0) ++ ++ u32 hex = 0; ++ u32 i; ++ u8 platform = dm_odm->SupportPlatform; ++ u8 interface_val = dm_odm->SupportInterface; ++ u8 board = dm_odm->BoardType; ++ u32 array_len = sizeof(array_MAC_REG_8188E) / sizeof(u32); ++ u32 *array = array_MAC_REG_8188E; ++ bool biol = false; ++ ++ struct adapter *adapt = dm_odm->Adapter; ++ struct xmit_frame *pxmit_frame = NULL; ++ u8 bndy_cnt = 1; ++ enum HAL_STATUS rst = HAL_STATUS_SUCCESS; ++ hex += board; ++ hex += interface_val << 8; ++ hex += platform << 16; ++ hex += 0xFF000000; ++ ++ biol = rtw_IOL_applied(adapt); ++ ++ if (biol) { ++ pxmit_frame = rtw_IOL_accquire_xmit_frame(adapt); ++ if (!pxmit_frame) { ++ pr_info("rtw_IOL_accquire_xmit_frame failed\n"); ++ return HAL_STATUS_FAILURE; ++ } ++ } ++ ++ for (i = 0; i < array_len; i += 2) { ++ u32 v1 = array[i]; ++ u32 v2 = array[i + 1]; ++ ++ /* This (offset, data) pair meets the condition. */ ++ if (v1 < 0xCDCDCDCD) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ rtw_IOL_append_WB_cmd(pxmit_frame, (u16)v1, (u8)v2, 0xFF); ++ } else { ++ odm_ConfigMAC_8188E(dm_odm, v1, (u8)v2); ++ } ++ continue; ++ } else { /* This line is the start line of branch. */ ++ if (!Checkcondition(array[i], hex)) { ++ /* Discard the following (offset, data) pairs. */ ++ READ_NEXT_PAIR(v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < array_len - 2) { ++ READ_NEXT_PAIR(v1, v2, i); ++ } ++ i -= 2; /* prevent from for-loop += 2 */ ++ } else { /* Configure matched pairs and skip to end of if-else. */ ++ READ_NEXT_PAIR(v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < array_len - 2) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ rtw_IOL_append_WB_cmd(pxmit_frame, (u16)v1, (u8)v2, 0xFF); ++ } else { ++ odm_ConfigMAC_8188E(dm_odm, v1, (u8)v2); ++ } ++ ++ READ_NEXT_PAIR(v1, v2, i); ++ } ++ while (v2 != 0xDEAD && i < array_len - 2) ++ READ_NEXT_PAIR(v1, v2, i); ++ } ++ } ++ } ++ if (biol) { ++ if (!rtw_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { ++ pr_info("~~~ MAC IOL_exec_cmds Failed !!!\n"); ++ rst = HAL_STATUS_FAILURE; ++ } ++ } ++ return rst; ++} +diff --git a/drivers/staging/r8188eu/hal/HalHWImg8188E_RF.c b/drivers/staging/r8188eu/hal/HalHWImg8188E_RF.c +new file mode 100644 +index 000000000000..55e4b4a877a4 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/HalHWImg8188E_RF.c +@@ -0,0 +1,250 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++#include "../include/rtw_iol.h" ++ ++static bool CheckCondition(const u32 Condition, const u32 Hex) ++{ ++ u32 _board = (Hex & 0x000000FF); ++ u32 _interface = (Hex & 0x0000FF00) >> 8; ++ u32 _platform = (Hex & 0x00FF0000) >> 16; ++ u32 cond = Condition; ++ ++ if (Condition == 0xCDCDCDCD) ++ return true; ++ ++ cond = Condition & 0x000000FF; ++ if ((_board == cond) && cond != 0x00) ++ return false; ++ ++ cond = Condition & 0x0000FF00; ++ cond = cond >> 8; ++ if ((_interface & cond) == 0 && cond != 0x07) ++ return false; ++ ++ cond = Condition & 0x00FF0000; ++ cond = cond >> 16; ++ if ((_platform & cond) == 0 && cond != 0x0F) ++ return false; ++ return true; ++} ++ ++/****************************************************************************** ++* RadioA_1T.TXT ++******************************************************************************/ ++ ++static u32 Array_RadioA_1T_8188E[] = { ++ 0x000, 0x00030000, ++ 0x008, 0x00084000, ++ 0x018, 0x00000407, ++ 0x019, 0x00000012, ++ 0x01E, 0x00080009, ++ 0x01F, 0x00000880, ++ 0x02F, 0x0001A060, ++ 0x03F, 0x00000000, ++ 0x042, 0x000060C0, ++ 0x057, 0x000D0000, ++ 0x058, 0x000BE180, ++ 0x067, 0x00001552, ++ 0x083, 0x00000000, ++ 0x0B0, 0x000FF8FC, ++ 0x0B1, 0x00054400, ++ 0x0B2, 0x000CCC19, ++ 0x0B4, 0x00043003, ++ 0x0B6, 0x0004953E, ++ 0x0B7, 0x0001C718, ++ 0x0B8, 0x000060FF, ++ 0x0B9, 0x00080001, ++ 0x0BA, 0x00040000, ++ 0x0BB, 0x00000400, ++ 0x0BF, 0x000C0000, ++ 0x0C2, 0x00002400, ++ 0x0C3, 0x00000009, ++ 0x0C4, 0x00040C91, ++ 0x0C5, 0x00099999, ++ 0x0C6, 0x000000A3, ++ 0x0C7, 0x00088820, ++ 0x0C8, 0x00076C06, ++ 0x0C9, 0x00000000, ++ 0x0CA, 0x00080000, ++ 0x0DF, 0x00000180, ++ 0x0EF, 0x000001A0, ++ 0x051, 0x0006B27D, ++ 0xFF0F041F, 0xABCD, ++ 0x052, 0x0007E4DD, ++ 0xCDCDCDCD, 0xCDCD, ++ 0x052, 0x0007E49D, ++ 0xFF0F041F, 0xDEAD, ++ 0x053, 0x00000073, ++ 0x056, 0x00051FF3, ++ 0x035, 0x00000086, ++ 0x035, 0x00000186, ++ 0x035, 0x00000286, ++ 0x036, 0x00001C25, ++ 0x036, 0x00009C25, ++ 0x036, 0x00011C25, ++ 0x036, 0x00019C25, ++ 0x0B6, 0x00048538, ++ 0x018, 0x00000C07, ++ 0x05A, 0x0004BD00, ++ 0x019, 0x000739D0, ++ 0x034, 0x0000ADF3, ++ 0x034, 0x00009DF0, ++ 0x034, 0x00008DED, ++ 0x034, 0x00007DEA, ++ 0x034, 0x00006DE7, ++ 0x034, 0x000054EE, ++ 0x034, 0x000044EB, ++ 0x034, 0x000034E8, ++ 0x034, 0x0000246B, ++ 0x034, 0x00001468, ++ 0x034, 0x0000006D, ++ 0x000, 0x00030159, ++ 0x084, 0x00068200, ++ 0x086, 0x000000CE, ++ 0x087, 0x00048A00, ++ 0x08E, 0x00065540, ++ 0x08F, 0x00088000, ++ 0x0EF, 0x000020A0, ++ 0x03B, 0x000F02B0, ++ 0x03B, 0x000EF7B0, ++ 0x03B, 0x000D4FB0, ++ 0x03B, 0x000CF060, ++ 0x03B, 0x000B0090, ++ 0x03B, 0x000A0080, ++ 0x03B, 0x00090080, ++ 0x03B, 0x0008F780, ++ 0x03B, 0x000722B0, ++ 0x03B, 0x0006F7B0, ++ 0x03B, 0x00054FB0, ++ 0x03B, 0x0004F060, ++ 0x03B, 0x00030090, ++ 0x03B, 0x00020080, ++ 0x03B, 0x00010080, ++ 0x03B, 0x0000F780, ++ 0x0EF, 0x000000A0, ++ 0x000, 0x00010159, ++ 0x018, 0x0000F407, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0x01F, 0x00080003, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0x01E, 0x00000001, ++ 0x01F, 0x00080000, ++ 0x000, 0x00033E60, ++}; ++ ++enum HAL_STATUS ODM_ReadAndConfig_RadioA_1T_8188E(struct odm_dm_struct *pDM_Odm) ++{ ++ #define READ_NEXT_PAIR(v1, v2, i) do \ ++ { i += 2; v1 = Array[i]; \ ++ v2 = Array[i + 1]; } while (0) ++ ++ u32 hex = 0; ++ u32 i = 0; ++ u8 platform = pDM_Odm->SupportPlatform; ++ u8 interfaceValue = pDM_Odm->SupportInterface; ++ u8 board = pDM_Odm->BoardType; ++ u32 ArrayLen = sizeof(Array_RadioA_1T_8188E) / sizeof(u32); ++ u32 *Array = Array_RadioA_1T_8188E; ++ bool biol = false; ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ struct xmit_frame *pxmit_frame = NULL; ++ u8 bndy_cnt = 1; ++ enum HAL_STATUS rst = HAL_STATUS_SUCCESS; ++ ++ hex += board; ++ hex += interfaceValue << 8; ++ hex += platform << 16; ++ hex += 0xFF000000; ++ biol = rtw_IOL_applied(Adapter); ++ ++ if (biol) { ++ pxmit_frame = rtw_IOL_accquire_xmit_frame(Adapter); ++ if (!pxmit_frame) { ++ pr_info("rtw_IOL_accquire_xmit_frame failed\n"); ++ return HAL_STATUS_FAILURE; ++ } ++ } ++ ++ for (i = 0; i < ArrayLen; i += 2) { ++ u32 v1 = Array[i]; ++ u32 v2 = Array[i + 1]; ++ ++ /* This (offset, data) pair meets the condition. */ ++ if (v1 < 0xCDCDCDCD) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ ++ if (v1 == 0xffe) ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50); ++ else if (v1 == 0xfd) ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5); ++ else if (v1 == 0xfc) ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1); ++ else if (v1 == 0xfb) ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50); ++ else if (v1 == 0xfa) ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5); ++ else if (v1 == 0xf9) ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1); ++ else ++ rtw_IOL_append_WRF_cmd(pxmit_frame, RF_PATH_A, (u16)v1, v2, bRFRegOffsetMask); ++ } else { ++ odm_ConfigRF_RadioA_8188E(pDM_Odm, v1, v2); ++ } ++ continue; ++ } else { /* This line is the start line of branch. */ ++ if (!CheckCondition(Array[i], hex)) { ++ /* Discard the following (offset, data) pairs. */ ++ READ_NEXT_PAIR(v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < ArrayLen - 2) ++ READ_NEXT_PAIR(v1, v2, i); ++ i -= 2; /* prevent from for-loop += 2 */ ++ } else { /* Configure matched pairs and skip to end of if-else. */ ++ READ_NEXT_PAIR(v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < ArrayLen - 2) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ ++ if (v1 == 0xffe) ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50); ++ else if (v1 == 0xfd) ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5); ++ else if (v1 == 0xfc) ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1); ++ else if (v1 == 0xfb) ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50); ++ else if (v1 == 0xfa) ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5); ++ else if (v1 == 0xf9) ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1); ++ else ++ rtw_IOL_append_WRF_cmd(pxmit_frame, RF_PATH_A, (u16)v1, v2, bRFRegOffsetMask); ++ } else { ++ odm_ConfigRF_RadioA_8188E(pDM_Odm, v1, v2); ++ } ++ READ_NEXT_PAIR(v1, v2, i); ++ } ++ ++ while (v2 != 0xDEAD && i < ArrayLen - 2) ++ READ_NEXT_PAIR(v1, v2, i); ++ } ++ } ++ } ++ if (biol) { ++ if (!rtw_IOL_exec_cmds_sync(pDM_Odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { ++ rst = HAL_STATUS_FAILURE; ++ pr_info("~~~ IOL Config %s Failed !!!\n", __func__); ++ } ++ } ++ return rst; ++} +diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c +new file mode 100644 +index 000000000000..356885e27edd +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c +@@ -0,0 +1,1264 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++ ++/*---------------------------Define Local Constant---------------------------*/ ++/* 2010/04/25 MH Define the max tx power tracking tx agc power. */ ++#define ODM_TXPWRTRACK_MAX_IDX_88E 6 ++ ++/*---------------------------Define Local Constant---------------------------*/ ++ ++/* 3============================================================ */ ++/* 3 Tx Power Tracking */ ++/* 3============================================================ */ ++/*----------------------------------------------------------------------------- ++ * Function: ODM_TxPwrTrackAdjust88E() ++ * ++ * Overview: 88E we can not write 0xc80/c94/c4c/ 0xa2x. Instead of write TX agc. ++ * No matter OFDM & CCK use the same method. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 04/23/2012 MHC Create Version 0. ++ * 04/23/2012 MHC Adjust TX agc directly not throughput BB digital. ++ * ++ *---------------------------------------------------------------------------*/ ++void ODM_TxPwrTrackAdjust88E(struct odm_dm_struct *dm_odm, u8 Type,/* 0 = OFDM, 1 = CCK */ ++ u8 *pDirection, /* 1 = +(increase) 2 = -(decrease) */ ++ u32 *pOutWriteVal /* Tx tracking CCK/OFDM BB swing index adjust */ ++ ) ++{ ++ u8 pwr_value = 0; ++ /* Tx power tracking BB swing table. */ ++ /* The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */ ++ if (Type == 0) { /* For OFDM afjust */ ++ if (dm_odm->BbSwingIdxOfdm <= dm_odm->BbSwingIdxOfdmBase) { ++ *pDirection = 1; ++ pwr_value = (dm_odm->BbSwingIdxOfdmBase - dm_odm->BbSwingIdxOfdm); ++ } else { ++ *pDirection = 2; ++ pwr_value = (dm_odm->BbSwingIdxOfdm - dm_odm->BbSwingIdxOfdmBase); ++ } ++ } else if (Type == 1) { /* For CCK adjust. */ ++ if (dm_odm->BbSwingIdxCck <= dm_odm->BbSwingIdxCckBase) { ++ *pDirection = 1; ++ pwr_value = (dm_odm->BbSwingIdxCckBase - dm_odm->BbSwingIdxCck); ++ } else { ++ *pDirection = 2; ++ pwr_value = (dm_odm->BbSwingIdxCck - dm_odm->BbSwingIdxCckBase); ++ } ++ } ++ ++ /* */ ++ /* 2012/04/25 MH According to Ed/Luke.Lees estimate for EVM the max tx power tracking */ ++ /* need to be less than 6 power index for 88E. */ ++ /* */ ++ if (pwr_value >= ODM_TXPWRTRACK_MAX_IDX_88E && *pDirection == 1) ++ pwr_value = ODM_TXPWRTRACK_MAX_IDX_88E; ++ ++ *pOutWriteVal = pwr_value | (pwr_value << 8) | (pwr_value << 16) | (pwr_value << 24); ++} /* ODM_TxPwrTrackAdjust88E */ ++ ++/*----------------------------------------------------------------------------- ++ * Function: odm_TxPwrTrackSetPwr88E() ++ * ++ * Overview: 88E change all channel tx power accordign to flag. ++ * OFDM & CCK are all different. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 04/23/2012 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++static void odm_TxPwrTrackSetPwr88E(struct odm_dm_struct *dm_odm) ++{ ++ if (dm_odm->BbSwingFlagOfdm || dm_odm->BbSwingFlagCck) { ++ PHY_SetTxPowerLevel8188E(dm_odm->Adapter, *dm_odm->pChannel); ++ dm_odm->BbSwingFlagOfdm = false; ++ dm_odm->BbSwingFlagCck = false; ++ } ++} /* odm_TxPwrTrackSetPwr88E */ ++ ++/* 091212 chiyokolin */ ++void ++odm_TXPowerTrackingCallback_ThermalMeter_8188E( ++ struct adapter *Adapter ++ ) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u8 ThermalValue = 0, delta, delta_LCK, delta_IQK, offset; ++ u8 ThermalValue_AVG_count = 0; ++ u32 ThermalValue_AVG = 0; ++ s32 ele_A = 0, ele_D, TempCCk, X, value32; ++ s32 Y, ele_C = 0; ++ s8 OFDM_index[2], CCK_index = 0; ++ s8 OFDM_index_old[2] = {0, 0}, CCK_index_old = 0; ++ u32 i = 0, j = 0; ++ bool is2t = false; ++ ++ u8 OFDM_min_index = 6, rf; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */ ++ u8 Indexforchannel = 0/*GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/; ++ s8 OFDM_index_mapping[2][index_mapping_NUM_88E] = { ++ {0, 0, 2, 3, 4, 4, /* 2.4G, decrease power */ ++ 5, 6, 7, 7, 8, 9, ++ 10, 10, 11}, /* For lower temperature, 20120220 updated on 20120220. */ ++ {0, 0, -1, -2, -3, -4, /* 2.4G, increase power */ ++ -4, -4, -4, -5, -7, -8, ++ -9, -9, -10}, ++ }; ++ u8 Thermal_mapping[2][index_mapping_NUM_88E] = { ++ {0, 2, 4, 6, 8, 10, /* 2.4G, decrease power */ ++ 12, 14, 16, 18, 20, 22, ++ 24, 26, 27}, ++ {0, 2, 4, 6, 8, 10, /* 2.4G,, increase power */ ++ 12, 14, 16, 18, 20, 22, ++ 25, 25, 25}, ++ }; ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ /* 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */ ++ odm_TxPwrTrackSetPwr88E(dm_odm); ++ ++ dm_odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++; /* cosa add for debug */ ++ dm_odm->RFCalibrateInfo.bTXPowerTrackingInit = true; ++ ++ /* RFCalibrateInfo.RegA24 will be initialized when ODM HW configuring, but MP configures with para files. */ ++ dm_odm->RFCalibrateInfo.RegA24 = 0x090e1317; ++ ++ ThermalValue = (u8)ODM_GetRFReg(dm_odm, RF_PATH_A, RF_T_METER_88E, 0xfc00); /* 0x42: RF Reg[15:10] 88E */ ++ ++ if (is2t) ++ rf = 2; ++ else ++ rf = 1; ++ ++ if (ThermalValue) { ++ /* Query OFDM path A default setting */ ++ ele_D = ODM_GetBBReg(dm_odm, rOFDM0_XATxIQImbalance, bMaskDWord) & bMaskOFDM_D; ++ for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) { /* find the index */ ++ if (ele_D == (OFDMSwingTable[i] & bMaskOFDM_D)) { ++ OFDM_index_old[0] = (u8)i; ++ dm_odm->BbSwingIdxOfdmBase = (u8)i; ++ break; ++ } ++ } ++ ++ /* Query OFDM path B default setting */ ++ if (is2t) { ++ ele_D = ODM_GetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord) & bMaskOFDM_D; ++ for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) { /* find the index */ ++ if (ele_D == (OFDMSwingTable[i] & bMaskOFDM_D)) { ++ OFDM_index_old[1] = (u8)i; ++ break; ++ } ++ } ++ } ++ ++ /* Query CCK default setting From 0xa24 */ ++ TempCCk = dm_odm->RFCalibrateInfo.RegA24; ++ ++ for (i = 0; i < CCK_TABLE_SIZE; i++) { ++ if (dm_odm->RFCalibrateInfo.bCCKinCH14) { ++ if (ODM_CompareMemory(dm_odm, (void *)&TempCCk, (void *)&CCKSwingTable_Ch14[i][2], 4) == 0) { ++ CCK_index_old = (u8)i; ++ dm_odm->BbSwingIdxCckBase = (u8)i; ++ break; ++ } ++ } else { ++ if (ODM_CompareMemory(dm_odm, (void *)&TempCCk, (void *)&CCKSwingTable_Ch1_Ch13[i][2], 4) == 0) { ++ CCK_index_old = (u8)i; ++ dm_odm->BbSwingIdxCckBase = (u8)i; ++ break; ++ } ++ } ++ } ++ ++ if (!dm_odm->RFCalibrateInfo.ThermalValue) { ++ dm_odm->RFCalibrateInfo.ThermalValue = pHalData->EEPROMThermalMeter; ++ dm_odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue; ++ dm_odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue; ++ ++ for (i = 0; i < rf; i++) ++ dm_odm->RFCalibrateInfo.OFDM_index[i] = OFDM_index_old[i]; ++ dm_odm->RFCalibrateInfo.CCK_index = CCK_index_old; ++ } ++ ++ /* calculate average thermal meter */ ++ dm_odm->RFCalibrateInfo.ThermalValue_AVG[dm_odm->RFCalibrateInfo.ThermalValue_AVG_index] = ThermalValue; ++ dm_odm->RFCalibrateInfo.ThermalValue_AVG_index++; ++ if (dm_odm->RFCalibrateInfo.ThermalValue_AVG_index == AVG_THERMAL_NUM_88E) ++ dm_odm->RFCalibrateInfo.ThermalValue_AVG_index = 0; ++ ++ for (i = 0; i < AVG_THERMAL_NUM_88E; i++) { ++ if (dm_odm->RFCalibrateInfo.ThermalValue_AVG[i]) { ++ ThermalValue_AVG += dm_odm->RFCalibrateInfo.ThermalValue_AVG[i]; ++ ThermalValue_AVG_count++; ++ } ++ } ++ ++ if (ThermalValue_AVG_count) ++ ThermalValue = (u8)(ThermalValue_AVG / ThermalValue_AVG_count); ++ ++ if (dm_odm->RFCalibrateInfo.bReloadtxpowerindex) { ++ delta = ThermalValue > pHalData->EEPROMThermalMeter ? ++ (ThermalValue - pHalData->EEPROMThermalMeter) : ++ (pHalData->EEPROMThermalMeter - ThermalValue); ++ dm_odm->RFCalibrateInfo.bReloadtxpowerindex = false; ++ dm_odm->RFCalibrateInfo.bDoneTxpower = false; ++ } else if (dm_odm->RFCalibrateInfo.bDoneTxpower) { ++ delta = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue) ? ++ (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue) : ++ (dm_odm->RFCalibrateInfo.ThermalValue - ThermalValue); ++ } else { ++ delta = ThermalValue > pHalData->EEPROMThermalMeter ? ++ (ThermalValue - pHalData->EEPROMThermalMeter) : ++ (pHalData->EEPROMThermalMeter - ThermalValue); ++ } ++ delta_LCK = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue_LCK) ? ++ (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue_LCK) : ++ (dm_odm->RFCalibrateInfo.ThermalValue_LCK - ThermalValue); ++ delta_IQK = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue_IQK) ? ++ (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue_IQK) : ++ (dm_odm->RFCalibrateInfo.ThermalValue_IQK - ThermalValue); ++ ++ if ((delta_LCK >= 8)) { /* Delta temperature is equal to or larger than 20 centigrade. */ ++ dm_odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue; ++ PHY_LCCalibrate_8188E(Adapter); ++ } ++ ++ if (delta > 0 && dm_odm->RFCalibrateInfo.TxPowerTrackControl) { ++ delta = ThermalValue > pHalData->EEPROMThermalMeter ? ++ (ThermalValue - pHalData->EEPROMThermalMeter) : ++ (pHalData->EEPROMThermalMeter - ThermalValue); ++ /* calculate new OFDM / CCK offset */ ++ if (ThermalValue > pHalData->EEPROMThermalMeter) ++ j = 1; ++ else ++ j = 0; ++ for (offset = 0; offset < index_mapping_NUM_88E; offset++) { ++ if (delta < Thermal_mapping[j][offset]) { ++ if (offset != 0) ++ offset--; ++ break; ++ } ++ } ++ if (offset >= index_mapping_NUM_88E) ++ offset = index_mapping_NUM_88E - 1; ++ for (i = 0; i < rf; i++) ++ OFDM_index[i] = dm_odm->RFCalibrateInfo.OFDM_index[i] + OFDM_index_mapping[j][offset]; ++ CCK_index = dm_odm->RFCalibrateInfo.CCK_index + OFDM_index_mapping[j][offset]; ++ ++ for (i = 0; i < rf; i++) { ++ if (OFDM_index[i] > OFDM_TABLE_SIZE_92D - 1) ++ OFDM_index[i] = OFDM_TABLE_SIZE_92D - 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; ++ ++ /* 2 temporarily remove bNOPG */ ++ /* Config by SwingTable */ ++ if (dm_odm->RFCalibrateInfo.TxPowerTrackControl) { ++ dm_odm->RFCalibrateInfo.bDoneTxpower = true; ++ ++ /* Adujst OFDM Ant_A according to IQK result */ ++ ele_D = (OFDMSwingTable[(u8)OFDM_index[0]] & 0xFFC00000) >> 22; ++ X = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][0]; ++ Y = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][1]; ++ ++ /* Revse TX power table. */ ++ dm_odm->BbSwingIdxOfdm = (u8)OFDM_index[0]; ++ dm_odm->BbSwingIdxCck = (u8)CCK_index; ++ ++ if (dm_odm->BbSwingIdxOfdmCurrent != dm_odm->BbSwingIdxOfdm) { ++ dm_odm->BbSwingIdxOfdmCurrent = dm_odm->BbSwingIdxOfdm; ++ dm_odm->BbSwingFlagOfdm = true; ++ } ++ ++ if (dm_odm->BbSwingIdxCckCurrent != dm_odm->BbSwingIdxCck) { ++ dm_odm->BbSwingIdxCckCurrent = dm_odm->BbSwingIdxCck; ++ dm_odm->BbSwingFlagCck = true; ++ } ++ ++ if (X != 0) { ++ if ((X & 0x00000200) != 0) ++ X = X | 0xFFFFFC00; ++ ele_A = ((X * ele_D) >> 8) & 0x000003FF; ++ ++ /* new element C = element D x Y */ ++ if ((Y & 0x00000200) != 0) ++ Y = Y | 0xFFFFFC00; ++ ele_C = ((Y * ele_D) >> 8) & 0x000003FF; ++ ++ /* 2012/04/23 MH According to Luke's suggestion, we can not write BB digital */ ++ /* to increase TX power. Otherwise, EVM will be bad. */ ++ } ++ ++ if (is2t) { ++ ele_D = (OFDMSwingTable[(u8)OFDM_index[1]] & 0xFFC00000) >> 22; ++ ++ /* new element A = element D x X */ ++ X = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][4]; ++ Y = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][5]; ++ ++ if ((X != 0) && (*dm_odm->pBandType == ODM_BAND_2_4G)) { ++ if ((X & 0x00000200) != 0) /* consider minus */ ++ X = X | 0xFFFFFC00; ++ ele_A = ((X * ele_D) >> 8) & 0x000003FF; ++ ++ /* new element C = element D x Y */ ++ if ((Y & 0x00000200) != 0) ++ Y = Y | 0xFFFFFC00; ++ ele_C = ((Y * ele_D) >> 8) & 0x00003FF; ++ ++ /* wtite new elements A, C, D to regC88 and regC9C, element B is always 0 */ ++ value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A; ++ ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord, value32); ++ ++ value32 = (ele_C & 0x000003C0) >> 6; ++ ODM_SetBBReg(dm_odm, rOFDM0_XDTxAFE, bMaskH4Bits, value32); ++ ++ value32 = ((X * ele_D) >> 7) & 0x01; ++ ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(28), value32); ++ } else { ++ ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable[(u8)OFDM_index[1]]); ++ ODM_SetBBReg(dm_odm, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00); ++ ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(28), 0x00); ++ } ++ } ++ } ++ } ++ ++ if (delta_IQK >= 8) { /* Delta temperature is equal to or larger than 20 centigrade. */ ++ dm_odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue; ++ PHY_IQCalibrate_8188E(Adapter, false); ++ } ++ /* update thermal meter value */ ++ if (dm_odm->RFCalibrateInfo.TxPowerTrackControl) ++ dm_odm->RFCalibrateInfo.ThermalValue = ThermalValue; ++ } ++ dm_odm->RFCalibrateInfo.TXPowercount = 0; ++} ++ ++/* 1 7. IQK */ ++#define MAX_TOLERANCE 5 ++#define IQK_DELAY_TIME 1 /* ms */ ++ ++static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ ++phy_PathA_IQK_8188E(struct adapter *adapt, bool configPathB) ++{ ++ u32 regeac, regE94, regE9C; ++ u8 result = 0x00; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ /* 1 Tx IQK */ ++ /* path-A IQK setting */ ++ ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c); ++ ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c); ++ ODM_SetBBReg(dm_odm, rTx_IQK_PI_A, bMaskDWord, 0x8214032a); ++ ODM_SetBBReg(dm_odm, rRx_IQK_PI_A, bMaskDWord, 0x28160000); ++ ++ /* LO calibration setting */ ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Rsp, bMaskDWord, 0x00462911); ++ ++ /* One shot, path A LOK & IQK */ ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); ++ ++ /* delay x ms */ ++ /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */ ++ ODM_delay_ms(IQK_DELAY_TIME_88E); ++ ++ /* Check failed */ ++ regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord); ++ regE94 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord); ++ regE9C = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord); ++ ++ if (!(regeac & BIT(28)) && ++ (((regE94 & 0x03FF0000) >> 16) != 0x142) && ++ (((regE9C & 0x03FF0000) >> 16) != 0x42)) ++ result |= 0x01; ++ return result; ++} ++ ++static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ ++phy_PathA_RxIQK(struct adapter *adapt, bool configPathB) ++{ ++ u32 regeac, regE94, regE9C, regEA4, u4tmp; ++ u8 result = 0x00; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ /* 1 Get TXIMR setting */ ++ /* modify RXIQK mode table */ ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x00000000); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf117B); ++ ++ /* PA,PAD off */ ++ ODM_SetRFReg(dm_odm, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000); ++ ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000); ++ ++ /* IQK setting */ ++ ODM_SetBBReg(dm_odm, rTx_IQK, bMaskDWord, 0x01007c00); ++ ODM_SetBBReg(dm_odm, rRx_IQK, bMaskDWord, 0x81004800); ++ ++ /* path-A IQK setting */ ++ ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c); ++ ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c); ++ ODM_SetBBReg(dm_odm, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f); ++ ODM_SetBBReg(dm_odm, rRx_IQK_PI_A, bMaskDWord, 0x28160000); ++ ++ /* LO calibration setting */ ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911); ++ ++ /* One shot, path A LOK & IQK */ ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); ++ ++ /* delay x ms */ ++ ODM_delay_ms(IQK_DELAY_TIME_88E); ++ ++ /* Check failed */ ++ regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord); ++ regE94 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord); ++ regE9C = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord); ++ ++ if (!(regeac & BIT(28)) && ++ (((regE94 & 0x03FF0000) >> 16) != 0x142) && ++ (((regE9C & 0x03FF0000) >> 16) != 0x42)) ++ result |= 0x01; ++ else /* if Tx not OK, ignore Rx */ ++ return result; ++ ++ u4tmp = 0x80007C00 | (regE94 & 0x3FF0000) | ((regE9C & 0x3FF0000) >> 16); ++ ODM_SetBBReg(dm_odm, rTx_IQK, bMaskDWord, u4tmp); ++ ++ /* 1 RX IQK */ ++ /* modify RXIQK mode table */ ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x00000000); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ffa); ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000); ++ ++ /* IQK setting */ ++ ODM_SetBBReg(dm_odm, rRx_IQK, bMaskDWord, 0x01004800); ++ ++ /* path-A IQK setting */ ++ ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c); ++ ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c); ++ ODM_SetBBReg(dm_odm, rTx_IQK_PI_A, bMaskDWord, 0x82160c05); ++ ODM_SetBBReg(dm_odm, rRx_IQK_PI_A, bMaskDWord, 0x28160c1f); ++ ++ /* LO calibration setting */ ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911); ++ ++ /* One shot, path A LOK & IQK */ ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); ++ ++ /* delay x ms */ ++ /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */ ++ ODM_delay_ms(IQK_DELAY_TIME_88E); ++ ++ /* Check failed */ ++ regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord); ++ regE94 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord); ++ regE9C = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord); ++ regEA4 = ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_A_2, bMaskDWord); ++ ++ /* reload RF 0xdf */ ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x00000000); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180); ++ ++ if (!(regeac & BIT(27)) && /* if Tx is OK, check whether Rx is OK */ ++ (((regEA4 & 0x03FF0000) >> 16) != 0x132) && ++ (((regeac & 0x03FF0000) >> 16) != 0x36)) ++ result |= 0x02; ++ ++ return result; ++} ++ ++static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ ++phy_PathB_IQK_8188E(struct adapter *adapt) ++{ ++ u32 regeac, regeb4, regebc, regec4, regecc; ++ u8 result = 0x00; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ /* One shot, path B LOK & IQK */ ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Cont, bMaskDWord, 0x00000002); ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Cont, bMaskDWord, 0x00000000); ++ ++ /* delay x ms */ ++ ODM_delay_ms(IQK_DELAY_TIME_88E); ++ ++ /* Check failed */ ++ regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord); ++ regeb4 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_B, bMaskDWord); ++ regebc = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_B, bMaskDWord); ++ regec4 = ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_B_2, bMaskDWord); ++ regecc = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_B_2, bMaskDWord); ++ ++ if (!(regeac & BIT(31)) && ++ (((regeb4 & 0x03FF0000) >> 16) != 0x142) && ++ (((regebc & 0x03FF0000) >> 16) != 0x42)) ++ result |= 0x01; ++ else ++ return result; ++ ++ if (!(regeac & BIT(30)) && ++ (((regec4 & 0x03FF0000) >> 16) != 0x132) && ++ (((regecc & 0x03FF0000) >> 16) != 0x36)) ++ result |= 0x02; ++ ++ return result; ++} ++ ++static void patha_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8], u8 final_candidate, bool txonly) ++{ ++ u32 Oldval_0, X, TX0_A, reg; ++ s32 Y, TX0_C; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ if (final_candidate == 0xFF) { ++ return; ++ } else if (iqkok) { ++ Oldval_0 = (ODM_GetBBReg(dm_odm, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF; ++ ++ X = result[final_candidate][0]; ++ if ((X & 0x00000200) != 0) ++ X = X | 0xFFFFFC00; ++ TX0_A = (X * Oldval_0) >> 8; ++ ODM_SetBBReg(dm_odm, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A); ++ ++ ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(31), ((X * Oldval_0 >> 7) & 0x1)); ++ ++ Y = result[final_candidate][1]; ++ if ((Y & 0x00000200) != 0) ++ Y = Y | 0xFFFFFC00; ++ ++ TX0_C = (Y * Oldval_0) >> 8; ++ ODM_SetBBReg(dm_odm, rOFDM0_XCTxAFE, 0xF0000000, ((TX0_C & 0x3C0) >> 6)); ++ ODM_SetBBReg(dm_odm, rOFDM0_XATxIQImbalance, 0x003F0000, (TX0_C & 0x3F)); ++ ++ ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(29), ((Y * Oldval_0 >> 7) & 0x1)); ++ ++ if (txonly) ++ return; ++ ++ reg = result[final_candidate][2]; ++ ODM_SetBBReg(dm_odm, rOFDM0_XARxIQImbalance, 0x3FF, reg); ++ ++ reg = result[final_candidate][3] & 0x3F; ++ ODM_SetBBReg(dm_odm, rOFDM0_XARxIQImbalance, 0xFC00, reg); ++ ++ reg = (result[final_candidate][3] >> 6) & 0xF; ++ ODM_SetBBReg(dm_odm, rOFDM0_RxIQExtAnta, 0xF0000000, reg); ++ } ++} ++ ++static void pathb_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8], u8 final_candidate, bool txonly) ++{ ++ u32 Oldval_1, X, TX1_A, reg; ++ s32 Y, TX1_C; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ if (final_candidate == 0xFF) { ++ return; ++ } else if (iqkok) { ++ Oldval_1 = (ODM_GetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF; ++ ++ X = result[final_candidate][4]; ++ if ((X & 0x00000200) != 0) ++ X = X | 0xFFFFFC00; ++ TX1_A = (X * Oldval_1) >> 8; ++ ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, 0x3FF, TX1_A); ++ ++ ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(27), ((X * Oldval_1 >> 7) & 0x1)); ++ ++ Y = result[final_candidate][5]; ++ if ((Y & 0x00000200) != 0) ++ Y = Y | 0xFFFFFC00; ++ ++ TX1_C = (Y * Oldval_1) >> 8; ++ ODM_SetBBReg(dm_odm, rOFDM0_XDTxAFE, 0xF0000000, ((TX1_C & 0x3C0) >> 6)); ++ ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, 0x003F0000, (TX1_C & 0x3F)); ++ ++ ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(25), ((Y * Oldval_1 >> 7) & 0x1)); ++ ++ if (txonly) ++ return; ++ ++ reg = result[final_candidate][6]; ++ ODM_SetBBReg(dm_odm, rOFDM0_XBRxIQImbalance, 0x3FF, reg); ++ ++ reg = result[final_candidate][7] & 0x3F; ++ ODM_SetBBReg(dm_odm, rOFDM0_XBRxIQImbalance, 0xFC00, reg); ++ ++ reg = (result[final_candidate][7] >> 6) & 0xF; ++ ODM_SetBBReg(dm_odm, rOFDM0_AGCRSSITable, 0x0000F000, reg); ++ } ++} ++ ++/* */ ++/* 2011/07/26 MH Add an API for testing IQK fail case. */ ++/* */ ++/* MP Already declare in odm.c */ ++static bool ODM_CheckPowerStatus(struct adapter *Adapter) ++{ ++ return true; ++} ++ ++void _PHY_SaveADDARegisters(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegisterNum) ++{ ++ u32 i; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ if (!ODM_CheckPowerStatus(adapt)) ++ return; ++ ++ for (i = 0; i < RegisterNum; i++) { ++ ADDABackup[i] = ODM_GetBBReg(dm_odm, ADDAReg[i], bMaskDWord); ++ } ++} ++ ++static void _PHY_SaveMACRegisters( ++ struct adapter *adapt, ++ u32 *MACReg, ++ u32 *MACBackup ++ ) ++{ ++ u32 i; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) { ++ MACBackup[i] = ODM_Read1Byte(dm_odm, MACReg[i]); ++ } ++ MACBackup[i] = ODM_Read4Byte(dm_odm, MACReg[i]); ++} ++ ++static void reload_adda_reg(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegiesterNum) ++{ ++ u32 i; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ for (i = 0; i < RegiesterNum; i++) ++ ODM_SetBBReg(dm_odm, ADDAReg[i], bMaskDWord, ADDABackup[i]); ++} ++ ++static void ++_PHY_ReloadMACRegisters( ++ struct adapter *adapt, ++ u32 *MACReg, ++ u32 *MACBackup ++ ) ++{ ++ u32 i; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) { ++ ODM_Write1Byte(dm_odm, MACReg[i], (u8)MACBackup[i]); ++ } ++ ODM_Write4Byte(dm_odm, MACReg[i], MACBackup[i]); ++} ++ ++void ++_PHY_PathADDAOn( ++ struct adapter *adapt, ++ u32 *ADDAReg, ++ bool isPathAOn, ++ bool is2t ++ ) ++{ ++ u32 pathOn; ++ u32 i; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ pathOn = isPathAOn ? 0x04db25a4 : 0x0b1b25a4; ++ if (!is2t) { ++ pathOn = 0x0bdb25a0; ++ ODM_SetBBReg(dm_odm, ADDAReg[0], bMaskDWord, 0x0b1b25a0); ++ } else { ++ ODM_SetBBReg(dm_odm, ADDAReg[0], bMaskDWord, pathOn); ++ } ++ ++ for (i = 1; i < IQK_ADDA_REG_NUM; i++) ++ ODM_SetBBReg(dm_odm, ADDAReg[i], bMaskDWord, pathOn); ++} ++ ++void ++_PHY_MACSettingCalibration( ++ struct adapter *adapt, ++ u32 *MACReg, ++ u32 *MACBackup ++ ) ++{ ++ u32 i = 0; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ ODM_Write1Byte(dm_odm, MACReg[i], 0x3F); ++ ++ for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) { ++ ODM_Write1Byte(dm_odm, MACReg[i], (u8)(MACBackup[i] & (~BIT(3)))); ++ } ++ ODM_Write1Byte(dm_odm, MACReg[i], (u8)(MACBackup[i] & (~BIT(5)))); ++} ++ ++void ++_PHY_PathAStandBy( ++ struct adapter *adapt ++ ) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x0); ++ ODM_SetBBReg(dm_odm, 0x840, bMaskDWord, 0x00010000); ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000); ++} ++ ++static void _PHY_PIModeSwitch( ++ struct adapter *adapt, ++ bool PIMode ++ ) ++{ ++ u32 mode; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ mode = PIMode ? 0x01000100 : 0x01000000; ++ ODM_SetBBReg(dm_odm, rFPGA0_XA_HSSIParameter1, bMaskDWord, mode); ++ ODM_SetBBReg(dm_odm, rFPGA0_XB_HSSIParameter1, bMaskDWord, mode); ++} ++ ++static bool phy_SimularityCompare_8188E( ++ struct adapter *adapt, ++ s32 resulta[][8], ++ u8 c1, ++ u8 c2 ++ ) ++{ ++ u32 i, j, diff, sim_bitmap, bound = 0; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */ ++ bool result = true; ++ bool is2t; ++ s32 tmp1 = 0, tmp2 = 0; ++ ++ if ((dm_odm->RFType == ODM_2T2R) || (dm_odm->RFType == ODM_2T3R) || (dm_odm->RFType == ODM_2T4R)) ++ is2t = true; ++ else ++ is2t = false; ++ ++ if (is2t) ++ bound = 8; ++ else ++ bound = 4; ++ ++ sim_bitmap = 0; ++ ++ for (i = 0; i < bound; i++) { ++ if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) { ++ if ((resulta[c1][i] & 0x00000200) != 0) ++ tmp1 = resulta[c1][i] | 0xFFFFFC00; ++ else ++ tmp1 = resulta[c1][i]; ++ ++ if ((resulta[c2][i] & 0x00000200) != 0) ++ tmp2 = resulta[c2][i] | 0xFFFFFC00; ++ else ++ tmp2 = resulta[c2][i]; ++ } else { ++ tmp1 = resulta[c1][i]; ++ tmp2 = resulta[c2][i]; ++ } ++ ++ diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1); ++ ++ if (diff > MAX_TOLERANCE) { ++ if ((i == 2 || i == 6) && !sim_bitmap) { ++ if (resulta[c1][i] + resulta[c1][i + 1] == 0) ++ final_candidate[(i / 4)] = c2; ++ else if (resulta[c2][i] + resulta[c2][i + 1] == 0) ++ final_candidate[(i / 4)] = c1; ++ else ++ sim_bitmap = sim_bitmap | (1 << i); ++ } else { ++ sim_bitmap = sim_bitmap | (1 << i); ++ } ++ } ++ } ++ ++ if (sim_bitmap == 0) { ++ for (i = 0; i < (bound / 4); i++) { ++ if (final_candidate[i] != 0xFF) { ++ for (j = i * 4; j < (i + 1) * 4 - 2; j++) ++ resulta[3][j] = resulta[final_candidate[i]][j]; ++ result = false; ++ } ++ } ++ return result; ++ } else { ++ if (!(sim_bitmap & 0x03)) { /* path A TX OK */ ++ for (i = 0; i < 2; i++) ++ resulta[3][i] = resulta[c1][i]; ++ } ++ if (!(sim_bitmap & 0x0c)) { /* path A RX OK */ ++ for (i = 2; i < 4; i++) ++ resulta[3][i] = resulta[c1][i]; ++ } ++ ++ if (!(sim_bitmap & 0x30)) { /* path B TX OK */ ++ for (i = 4; i < 6; i++) ++ resulta[3][i] = resulta[c1][i]; ++ } ++ ++ if (!(sim_bitmap & 0xc0)) { /* path B RX OK */ ++ for (i = 6; i < 8; i++) ++ resulta[3][i] = resulta[c1][i]; ++ } ++ return false; ++ } ++} ++ ++static void phy_IQCalibrate_8188E(struct adapter *adapt, s32 result[][8], u8 t, bool is2t) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ u32 i; ++ u8 PathAOK, PathBOK; ++ u32 ADDA_REG[IQK_ADDA_REG_NUM] = { ++ rFPGA0_XCD_SwitchControl, rBlue_Tooth, ++ rRx_Wait_CCA, rTx_CCK_RFON, ++ rTx_CCK_BBON, rTx_OFDM_RFON, ++ rTx_OFDM_BBON, rTx_To_Rx, ++ rTx_To_Tx, rRx_CCK, ++ rRx_OFDM, rRx_Wait_RIFS, ++ rRx_TO_Rx, rStandby, ++ rSleep, rPMPD_ANAEN }; ++ u32 IQK_MAC_REG[IQK_MAC_REG_NUM] = { ++ REG_TXPAUSE, REG_BCN_CTRL, ++ REG_BCN_CTRL_1, REG_GPIO_MUXCFG}; ++ ++ /* since 92C & 92D have the different define in IQK_BB_REG */ ++ u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = { ++ rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar, ++ rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB, ++ rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE, ++ rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD ++ }; ++ ++ u32 retryCount = 9; ++ if (*dm_odm->mp_mode == 1) ++ retryCount = 9; ++ else ++ retryCount = 2; ++ /* Note: IQ calibration must be performed after loading */ ++ /* PHY_REG.txt , and radio_a, radio_b.txt */ ++ ++ if (t == 0) { ++ /* Save ADDA parameters, turn Path A ADDA on */ ++ _PHY_SaveADDARegisters(adapt, ADDA_REG, dm_odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM); ++ _PHY_SaveMACRegisters(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup); ++ _PHY_SaveADDARegisters(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM); ++ } ++ ++ _PHY_PathADDAOn(adapt, ADDA_REG, true, is2t); ++ if (t == 0) ++ dm_odm->RFCalibrateInfo.bRfPiEnable = (u8)ODM_GetBBReg(dm_odm, rFPGA0_XA_HSSIParameter1, BIT(8)); ++ ++ if (!dm_odm->RFCalibrateInfo.bRfPiEnable) { ++ /* Switch BB to PI mode to do IQ Calibration. */ ++ _PHY_PIModeSwitch(adapt, true); ++ } ++ ++ /* BB setting */ ++ ODM_SetBBReg(dm_odm, rFPGA0_RFMOD, BIT(24), 0x00); ++ ODM_SetBBReg(dm_odm, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600); ++ ODM_SetBBReg(dm_odm, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4); ++ ODM_SetBBReg(dm_odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000); ++ ++ ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0x01); ++ ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0x01); ++ ODM_SetBBReg(dm_odm, rFPGA0_XA_RFInterfaceOE, BIT(10), 0x00); ++ ODM_SetBBReg(dm_odm, rFPGA0_XB_RFInterfaceOE, BIT(10), 0x00); ++ ++ if (is2t) { ++ ODM_SetBBReg(dm_odm, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00010000); ++ ODM_SetBBReg(dm_odm, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00010000); ++ } ++ ++ /* MAC settings */ ++ _PHY_MACSettingCalibration(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup); ++ ++ /* Page B init */ ++ /* AP or IQK */ ++ ODM_SetBBReg(dm_odm, rConfig_AntA, bMaskDWord, 0x0f600000); ++ ++ if (is2t) ++ ODM_SetBBReg(dm_odm, rConfig_AntB, bMaskDWord, 0x0f600000); ++ ++ /* IQ calibration setting */ ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000); ++ ODM_SetBBReg(dm_odm, rTx_IQK, bMaskDWord, 0x01007c00); ++ ODM_SetBBReg(dm_odm, rRx_IQK, bMaskDWord, 0x81004800); ++ ++ for (i = 0; i < retryCount; i++) { ++ PathAOK = phy_PathA_IQK_8188E(adapt, is2t); ++ if (PathAOK == 0x01) { ++ result[t][0] = (ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord) & 0x3FF0000) >> 16; ++ result[t][1] = (ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord) & 0x3FF0000) >> 16; ++ break; ++ } ++ } ++ ++ for (i = 0; i < retryCount; i++) { ++ PathAOK = phy_PathA_RxIQK(adapt, is2t); ++ if (PathAOK == 0x03) { ++ result[t][2] = (ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_A_2, bMaskDWord) & 0x3FF0000) >> 16; ++ result[t][3] = (ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord) & 0x3FF0000) >> 16; ++ break; ++ } ++ } ++ ++ if (is2t) { ++ _PHY_PathAStandBy(adapt); ++ ++ /* Turn Path B ADDA on */ ++ _PHY_PathADDAOn(adapt, ADDA_REG, false, is2t); ++ ++ for (i = 0; i < retryCount; i++) { ++ PathBOK = phy_PathB_IQK_8188E(adapt); ++ if (PathBOK == 0x03) { ++ result[t][4] = (ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_B, bMaskDWord) & 0x3FF0000) >> 16; ++ result[t][5] = (ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_B, bMaskDWord) & 0x3FF0000) >> 16; ++ result[t][6] = (ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_B_2, bMaskDWord) & 0x3FF0000) >> 16; ++ result[t][7] = (ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_B_2, bMaskDWord) & 0x3FF0000) >> 16; ++ break; ++ } else if (i == (retryCount - 1) && PathBOK == 0x01) { /* Tx IQK OK */ ++ result[t][4] = (ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_B, bMaskDWord) & 0x3FF0000) >> 16; ++ result[t][5] = (ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_B, bMaskDWord) & 0x3FF0000) >> 16; ++ } ++ } ++ } ++ ++ /* Back to BB mode, load original value */ ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0); ++ ++ if (t != 0) { ++ if (!dm_odm->RFCalibrateInfo.bRfPiEnable) { ++ /* Switch back BB to SI mode after finish IQ Calibration. */ ++ _PHY_PIModeSwitch(adapt, false); ++ } ++ ++ /* Reload ADDA power saving parameters */ ++ reload_adda_reg(adapt, ADDA_REG, dm_odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM); ++ ++ /* Reload MAC parameters */ ++ _PHY_ReloadMACRegisters(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup); ++ ++ reload_adda_reg(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM); ++ ++ /* Restore RX initial gain */ ++ ODM_SetBBReg(dm_odm, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00032ed3); ++ if (is2t) ++ ODM_SetBBReg(dm_odm, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00032ed3); ++ ++ /* load 0xe30 IQC default value */ ++ ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00); ++ ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00); ++ } ++} ++ ++static void phy_LCCalibrate_8188E(struct adapter *adapt, bool is2t) ++{ ++ u8 tmpreg; ++ u32 RF_Amode = 0, RF_Bmode = 0, LC_Cal; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ /* Check continuous TX and Packet TX */ ++ tmpreg = ODM_Read1Byte(dm_odm, 0xd03); ++ ++ if ((tmpreg & 0x70) != 0) /* Deal with contisuous TX case */ ++ ODM_Write1Byte(dm_odm, 0xd03, tmpreg & 0x8F); /* disable all continuous TX */ ++ else /* Deal with Packet TX case */ ++ ODM_Write1Byte(dm_odm, REG_TXPAUSE, 0xFF); /* block all queues */ ++ ++ if ((tmpreg & 0x70) != 0) { ++ /* 1. Read original RF mode */ ++ /* Path-A */ ++ RF_Amode = PHY_QueryRFReg(adapt, RF_PATH_A, RF_AC, bMask12Bits); ++ ++ /* Path-B */ ++ if (is2t) ++ RF_Bmode = PHY_QueryRFReg(adapt, RF_PATH_B, RF_AC, bMask12Bits); ++ ++ /* 2. Set RF mode = standby mode */ ++ /* Path-A */ ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_AC, bMask12Bits, (RF_Amode & 0x8FFFF) | 0x10000); ++ ++ /* Path-B */ ++ if (is2t) ++ ODM_SetRFReg(dm_odm, RF_PATH_B, RF_AC, bMask12Bits, (RF_Bmode & 0x8FFFF) | 0x10000); ++ } ++ ++ /* 3. Read RF reg18 */ ++ LC_Cal = PHY_QueryRFReg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits); ++ ++ /* 4. Set LC calibration begin bit15 */ ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal | 0x08000); ++ ++ ODM_sleep_ms(100); ++ ++ /* Restore original situation */ ++ if ((tmpreg & 0x70) != 0) { ++ /* Deal with continuous TX case */ ++ /* Path-A */ ++ ODM_Write1Byte(dm_odm, 0xd03, tmpreg); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_AC, bMask12Bits, RF_Amode); ++ ++ /* Path-B */ ++ if (is2t) ++ ODM_SetRFReg(dm_odm, RF_PATH_B, RF_AC, bMask12Bits, RF_Bmode); ++ } else { ++ /* Deal with Packet TX case */ ++ ODM_Write1Byte(dm_odm, REG_TXPAUSE, 0x00); ++ } ++} ++ ++void PHY_IQCalibrate_8188E(struct adapter *adapt, bool recovery) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ struct mpt_context *pMptCtx = &adapt->mppriv.MptCtx; ++ s32 result[4][8]; /* last is final result */ ++ u8 i, final_candidate; ++ bool pathaok, pathbok; ++ s32 RegE94, RegE9C, RegEA4, RegEB4, RegEBC, RegEC4; ++ bool is12simular, is13simular, is23simular; ++ bool singletone = false, carrier_sup = false; ++ u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = { ++ rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance, ++ rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable, ++ rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance, ++ rOFDM0_XCTxAFE, rOFDM0_XDTxAFE, ++ rOFDM0_RxIQExtAnta}; ++ bool is2t; ++ ++ is2t = (dm_odm->RFType == ODM_2T2R) ? true : false; ++ if (!ODM_CheckPowerStatus(adapt)) ++ return; ++ ++ if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION)) ++ return; ++ ++ if (*dm_odm->mp_mode == 1) { ++ singletone = pMptCtx->bSingleTone; ++ carrier_sup = pMptCtx->bCarrierSuppression; ++ } ++ ++ /* 20120213 Turn on when continuous Tx to pass lab testing. (required by Edlu) */ ++ if (singletone || carrier_sup) ++ return; ++ ++ if (recovery) { ++ reload_adda_reg(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9); ++ return; ++ } ++ ++ for (i = 0; i < 8; i++) { ++ result[0][i] = 0; ++ result[1][i] = 0; ++ result[2][i] = 0; ++ if ((i == 0) || (i == 2) || (i == 4) || (i == 6)) ++ result[3][i] = 0x100; ++ else ++ result[3][i] = 0; ++ } ++ final_candidate = 0xff; ++ pathaok = false; ++ pathbok = false; ++ is12simular = false; ++ is23simular = false; ++ is13simular = false; ++ ++ for (i = 0; i < 3; i++) { ++ phy_IQCalibrate_8188E(adapt, result, i, is2t); ++ ++ if (i == 1) { ++ is12simular = phy_SimularityCompare_8188E(adapt, result, 0, 1); ++ if (is12simular) { ++ final_candidate = 0; ++ break; ++ } ++ } ++ ++ if (i == 2) { ++ is13simular = phy_SimularityCompare_8188E(adapt, result, 0, 2); ++ if (is13simular) { ++ final_candidate = 0; ++ ++ break; ++ } ++ is23simular = phy_SimularityCompare_8188E(adapt, result, 1, 2); ++ if (is23simular) { ++ final_candidate = 1; ++ } else { ++ final_candidate = 3; ++ } ++ } ++ } ++ ++ for (i = 0; i < 4; i++) { ++ RegE94 = result[i][0]; ++ RegE9C = result[i][1]; ++ RegEA4 = result[i][2]; ++ RegEB4 = result[i][4]; ++ RegEBC = result[i][5]; ++ RegEC4 = result[i][6]; ++ } ++ ++ if (final_candidate != 0xff) { ++ RegE94 = result[final_candidate][0]; ++ RegE9C = result[final_candidate][1]; ++ RegEA4 = result[final_candidate][2]; ++ RegEB4 = result[final_candidate][4]; ++ RegEBC = result[final_candidate][5]; ++ dm_odm->RFCalibrateInfo.RegE94 = RegE94; ++ dm_odm->RFCalibrateInfo.RegE9C = RegE9C; ++ dm_odm->RFCalibrateInfo.RegEB4 = RegEB4; ++ dm_odm->RFCalibrateInfo.RegEBC = RegEBC; ++ RegEC4 = result[final_candidate][6]; ++ pathaok = true; ++ pathbok = true; ++ } else { ++ dm_odm->RFCalibrateInfo.RegE94 = 0x100; ++ dm_odm->RFCalibrateInfo.RegEB4 = 0x100; /* X default value */ ++ dm_odm->RFCalibrateInfo.RegE9C = 0x0; ++ dm_odm->RFCalibrateInfo.RegEBC = 0x0; /* Y default value */ ++ } ++ if (RegE94 != 0) ++ patha_fill_iqk(adapt, pathaok, result, final_candidate, (RegEA4 == 0)); ++ if (is2t) { ++ if (RegEB4 != 0) ++ pathb_fill_iqk(adapt, pathbok, result, final_candidate, (RegEC4 == 0)); ++ } ++ ++/* To Fix BSOD when final_candidate is 0xff */ ++/* by sherry 20120321 */ ++ if (final_candidate < 4) { ++ for (i = 0; i < IQK_Matrix_REG_NUM; i++) ++ dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[0].Value[0][i] = result[final_candidate][i]; ++ dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[0].bIQKDone = true; ++ } ++ ++ _PHY_SaveADDARegisters(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9); ++} ++ ++void PHY_LCCalibrate_8188E(struct adapter *adapt) ++{ ++ bool singletone = false, carrier_sup = false; ++ u32 timeout = 2000, timecount = 0; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ struct mpt_context *pMptCtx = &adapt->mppriv.MptCtx; ++ ++ if (*dm_odm->mp_mode == 1) { ++ singletone = pMptCtx->bSingleTone; ++ carrier_sup = pMptCtx->bCarrierSuppression; ++ } ++ if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION)) ++ return; ++ /* 20120213 Turn on when continuous Tx to pass lab testing. (required by Edlu) */ ++ if (singletone || carrier_sup) ++ return; ++ ++ while (*dm_odm->pbScanInProcess && timecount < timeout) { ++ ODM_delay_ms(50); ++ timecount += 50; ++ } ++ ++ dm_odm->RFCalibrateInfo.bLCKInProgress = true; ++ ++ if (dm_odm->RFType == ODM_2T2R) { ++ phy_LCCalibrate_8188E(adapt, true); ++ } else { ++ /* For 88C 1T1R */ ++ phy_LCCalibrate_8188E(adapt, false); ++ } ++ ++ dm_odm->RFCalibrateInfo.bLCKInProgress = false; ++} ++ ++static void phy_setrfpathswitch_8188e(struct adapter *adapt, bool main, bool is2t) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ if (!adapt->hw_init_completed) { ++ u8 u1btmp; ++ u1btmp = ODM_Read1Byte(dm_odm, REG_LEDCFG2) | BIT(7); ++ ODM_Write1Byte(dm_odm, REG_LEDCFG2, u1btmp); ++ ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFParameter, BIT(13), 0x01); ++ } ++ ++ if (is2t) { /* 92C */ ++ if (main) ++ ODM_SetBBReg(dm_odm, rFPGA0_XB_RFInterfaceOE, BIT(5) | BIT(6), 0x1); /* 92C_Path_A */ ++ else ++ ODM_SetBBReg(dm_odm, rFPGA0_XB_RFInterfaceOE, BIT(5) | BIT(6), 0x2); /* BT */ ++ } else { /* 88C */ ++ if (main) ++ ODM_SetBBReg(dm_odm, rFPGA0_XA_RFInterfaceOE, BIT(8) | BIT(9), 0x2); /* Main */ ++ else ++ ODM_SetBBReg(dm_odm, rFPGA0_XA_RFInterfaceOE, BIT(8) | BIT(9), 0x1); /* Aux */ ++ } ++} ++ ++void PHY_SetRFPathSwitch_8188E(struct adapter *adapt, bool main) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ if (dm_odm->RFType == ODM_2T2R) { ++ phy_setrfpathswitch_8188e(adapt, main, true); ++ } else { ++ /* For 88C 1T1R */ ++ phy_setrfpathswitch_8188e(adapt, main, false); ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c +new file mode 100644 +index 000000000000..0fd11aca7ac7 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c +@@ -0,0 +1,95 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++/*++ ++ ++Module Name: ++ HalPwrSeqCmd.c ++ ++Abstract: ++ Implement HW Power sequence configuration CMD handling routine for Realtek devices. ++ ++Major Change History: ++ When Who What ++ ---------- --------------- ------------------------------- ++ 2011-10-26 Lucas Modify to be compatible with SD4-CE driver. ++ 2011-07-07 Roger Create. ++ ++--*/ ++ ++#include "../include/HalPwrSeqCmd.h" ++ ++/* Description: */ ++/* This routine deals with the Power Configuration CMDs parsing ++ * for RTL8723/RTL8188E Series IC. ++ * Assumption: ++ * We should follow specific format which was released from HW SD. ++ */ ++u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers, ++ u8 ifacetype, struct wl_pwr_cfg pwrseqcmd[]) ++{ ++ struct wl_pwr_cfg pwrcfgcmd = {0}; ++ u8 poll_bit = false; ++ u32 aryidx = 0; ++ u8 value = 0; ++ u32 offset = 0; ++ u32 poll_count = 0; /* polling autoload done. */ ++ u32 max_poll_count = 5000; ++ ++ do { ++ pwrcfgcmd = pwrseqcmd[aryidx]; ++ ++ /* 2 Only Handle the command whose FAB, CUT, and Interface are matched */ ++ if ((GET_PWR_CFG_FAB_MASK(pwrcfgcmd) & fab_vers) && ++ (GET_PWR_CFG_CUT_MASK(pwrcfgcmd) & cut_vers) && ++ (GET_PWR_CFG_INTF_MASK(pwrcfgcmd) & ifacetype)) { ++ switch (GET_PWR_CFG_CMD(pwrcfgcmd)) { ++ case PWR_CMD_WRITE: ++ offset = GET_PWR_CFG_OFFSET(pwrcfgcmd); ++ ++ /* Read the value from system register */ ++ value = rtw_read8(padapter, offset); ++ ++ value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd)); ++ value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd)); ++ ++ /* Write the value back to system register */ ++ rtw_write8(padapter, offset, value); ++ break; ++ case PWR_CMD_POLLING: ++ poll_bit = false; ++ offset = GET_PWR_CFG_OFFSET(pwrcfgcmd); ++ do { ++ value = rtw_read8(padapter, offset); ++ ++ value &= GET_PWR_CFG_MASK(pwrcfgcmd); ++ if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd))) ++ poll_bit = true; ++ else ++ udelay(10); ++ ++ if (poll_count++ > max_poll_count) { ++ DBG_88E("Fail to polling Offset[%#x]\n", offset); ++ return false; ++ } ++ } while (!poll_bit); ++ break; ++ case PWR_CMD_DELAY: ++ if (GET_PWR_CFG_VALUE(pwrcfgcmd) == PWRSEQ_DELAY_US) ++ udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd)); ++ else ++ udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd) * 1000); ++ break; ++ case PWR_CMD_END: ++ /* When this command is parsed, end the process */ ++ return true; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ aryidx++;/* Add Array Index */ ++ } while (1); ++ return true; ++} +diff --git a/drivers/staging/r8188eu/hal/hal_com.c b/drivers/staging/r8188eu/hal/hal_com.c +new file mode 100644 +index 000000000000..f09d4d49b159 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/hal_com.c +@@ -0,0 +1,358 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++ ++#include "../include/hal_intf.h" ++#include "../include/hal_com.h" ++#include "../include/rtl8188e_hal.h" ++ ++#define _HAL_INIT_C_ ++ ++void dump_chip_info(struct HAL_VERSION chip_vers) ++{ ++ uint cnt = 0; ++ char buf[128]; ++ ++ if (IS_81XXC(chip_vers)) { ++ cnt += sprintf((buf + cnt), "Chip Version Info: %s_", ++ IS_92C_SERIAL(chip_vers) ? ++ "CHIP_8192C" : "CHIP_8188C"); ++ } else if (IS_92D(chip_vers)) { ++ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192D_"); ++ } else if (IS_8723_SERIES(chip_vers)) { ++ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723A_"); ++ } else if (IS_8188E(chip_vers)) { ++ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_"); ++ } ++ ++ cnt += sprintf((buf + cnt), "%s_", IS_NORMAL_CHIP(chip_vers) ? ++ "Normal_Chip" : "Test_Chip"); ++ cnt += sprintf((buf + cnt), "%s_", IS_CHIP_VENDOR_TSMC(chip_vers) ? ++ "TSMC" : "UMC"); ++ if (IS_A_CUT(chip_vers)) ++ cnt += sprintf((buf + cnt), "A_CUT_"); ++ else if (IS_B_CUT(chip_vers)) ++ cnt += sprintf((buf + cnt), "B_CUT_"); ++ else if (IS_C_CUT(chip_vers)) ++ cnt += sprintf((buf + cnt), "C_CUT_"); ++ else if (IS_D_CUT(chip_vers)) ++ cnt += sprintf((buf + cnt), "D_CUT_"); ++ else if (IS_E_CUT(chip_vers)) ++ cnt += sprintf((buf + cnt), "E_CUT_"); ++ else ++ cnt += sprintf((buf + cnt), "UNKNOWN_CUT(%d)_", ++ chip_vers.CUTVersion); ++ ++ if (IS_1T1R(chip_vers)) ++ cnt += sprintf((buf + cnt), "1T1R_"); ++ else if (IS_1T2R(chip_vers)) ++ cnt += sprintf((buf + cnt), "1T2R_"); ++ else if (IS_2T2R(chip_vers)) ++ cnt += sprintf((buf + cnt), "2T2R_"); ++ else ++ cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ++ chip_vers.RFType); ++ ++ cnt += sprintf((buf + cnt), "RomVer(%d)\n", chip_vers.ROMVer); ++ ++ pr_info("%s", buf); ++} ++ ++#define CHAN_PLAN_HW 0x80 ++ ++u8 /* return the final channel plan decision */ ++hal_com_get_channel_plan(struct adapter *padapter, u8 hw_channel_plan, ++ u8 sw_channel_plan, u8 def_channel_plan, ++ bool load_fail) ++{ ++ u8 sw_cfg; ++ u8 chnlplan; ++ ++ sw_cfg = true; ++ if (!load_fail) { ++ if (!rtw_is_channel_plan_valid(sw_channel_plan)) ++ sw_cfg = false; ++ if (hw_channel_plan & CHAN_PLAN_HW) ++ sw_cfg = false; ++ } ++ ++ if (sw_cfg) ++ chnlplan = sw_channel_plan; ++ else ++ chnlplan = hw_channel_plan & (~CHAN_PLAN_HW); ++ ++ if (!rtw_is_channel_plan_valid(chnlplan)) ++ chnlplan = def_channel_plan; ++ ++ return chnlplan; ++} ++ ++u8 MRateToHwRate(u8 rate) ++{ ++ u8 ret = DESC_RATE1M; ++ ++ switch (rate) { ++ /* CCK and OFDM non-HT rates */ ++ case IEEE80211_CCK_RATE_1MB: ++ ret = DESC_RATE1M; ++ break; ++ case IEEE80211_CCK_RATE_2MB: ++ ret = DESC_RATE2M; ++ break; ++ case IEEE80211_CCK_RATE_5MB: ++ ret = DESC_RATE5_5M; ++ break; ++ case IEEE80211_CCK_RATE_11MB: ++ ret = DESC_RATE11M; ++ break; ++ case IEEE80211_OFDM_RATE_6MB: ++ ret = DESC_RATE6M; ++ break; ++ case IEEE80211_OFDM_RATE_9MB: ++ ret = DESC_RATE9M; ++ break; ++ case IEEE80211_OFDM_RATE_12MB: ++ ret = DESC_RATE12M; ++ break; ++ case IEEE80211_OFDM_RATE_18MB: ++ ret = DESC_RATE18M; ++ break; ++ case IEEE80211_OFDM_RATE_24MB: ++ ret = DESC_RATE24M; ++ break; ++ case IEEE80211_OFDM_RATE_36MB: ++ ret = DESC_RATE36M; ++ break; ++ case IEEE80211_OFDM_RATE_48MB: ++ ret = DESC_RATE48M; ++ break; ++ case IEEE80211_OFDM_RATE_54MB: ++ ret = DESC_RATE54M; ++ break; ++ default: ++ break; ++ } ++ return ret; ++} ++ ++void HalSetBrateCfg(struct adapter *adapt, u8 *brates, u16 *rate_cfg) ++{ ++ u8 i, is_brate, brate; ++ ++ for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { ++ is_brate = brates[i] & IEEE80211_BASIC_RATE_MASK; ++ brate = brates[i] & 0x7f; ++ ++ if (is_brate) { ++ switch (brate) { ++ case IEEE80211_CCK_RATE_1MB: ++ *rate_cfg |= RATE_1M; ++ break; ++ case IEEE80211_CCK_RATE_2MB: ++ *rate_cfg |= RATE_2M; ++ break; ++ case IEEE80211_CCK_RATE_5MB: ++ *rate_cfg |= RATE_5_5M; ++ break; ++ case IEEE80211_CCK_RATE_11MB: ++ *rate_cfg |= RATE_11M; ++ break; ++ case IEEE80211_OFDM_RATE_6MB: ++ *rate_cfg |= RATE_6M; ++ break; ++ case IEEE80211_OFDM_RATE_9MB: ++ *rate_cfg |= RATE_9M; ++ break; ++ case IEEE80211_OFDM_RATE_12MB: ++ *rate_cfg |= RATE_12M; ++ break; ++ case IEEE80211_OFDM_RATE_18MB: ++ *rate_cfg |= RATE_18M; ++ break; ++ case IEEE80211_OFDM_RATE_24MB: ++ *rate_cfg |= RATE_24M; ++ break; ++ case IEEE80211_OFDM_RATE_36MB: ++ *rate_cfg |= RATE_36M; ++ break; ++ case IEEE80211_OFDM_RATE_48MB: ++ *rate_cfg |= RATE_48M; ++ break; ++ case IEEE80211_OFDM_RATE_54MB: ++ *rate_cfg |= RATE_54M; ++ break; ++ } ++ } ++ } ++} ++ ++static void one_out_pipe(struct adapter *adapter) ++{ ++ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapter); ++ ++ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ ++ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */ ++ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */ ++ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */ ++ ++ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ ++ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ ++ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ ++ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ ++} ++ ++static void two_out_pipe(struct adapter *adapter, bool wifi_cfg) ++{ ++ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapter); ++ ++ if (wifi_cfg) { /* WMM */ ++ /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ ++ /* 0, 1, 0, 1, 0, 0, 0, 0, 0}; */ ++ /* 0:H, 1:L */ ++ ++ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */ ++ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */ ++ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */ ++ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */ ++ ++ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ ++ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ ++ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ ++ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ ++ ++ } else {/* typical setting */ ++ /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ ++ /* 1, 1, 0, 0, 0, 0, 0, 0, 0}; */ ++ /* 0:H, 1:L */ ++ ++ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ ++ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */ ++ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */ ++ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */ ++ ++ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ ++ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ ++ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ ++ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ ++ } ++} ++ ++static void three_out_pipe(struct adapter *adapter, bool wifi_cfg) ++{ ++ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapter); ++ ++ if (wifi_cfg) {/* for WMM */ ++ /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ ++ /* 1, 2, 1, 0, 0, 0, 0, 0, 0}; */ ++ /* 0:H, 1:N, 2:L */ ++ ++ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ ++ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */ ++ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */ ++ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */ ++ ++ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ ++ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ ++ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ ++ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ ++ ++ } else {/* typical setting */ ++ /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ ++ /* 2, 2, 1, 0, 0, 0, 0, 0, 0}; */ ++ /* 0:H, 1:N, 2:L */ ++ ++ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ ++ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */ ++ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */ ++ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */ ++ ++ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ ++ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ ++ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ ++ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ ++ } ++} ++ ++bool Hal_MappingOutPipe(struct adapter *adapter, u8 numoutpipe) ++{ ++ struct registry_priv *pregistrypriv = &adapter->registrypriv; ++ bool wifi_cfg = (pregistrypriv->wifi_spec) ? true : false; ++ bool result = true; ++ ++ switch (numoutpipe) { ++ case 2: ++ two_out_pipe(adapter, wifi_cfg); ++ break; ++ case 3: ++ three_out_pipe(adapter, wifi_cfg); ++ break; ++ case 1: ++ one_out_pipe(adapter); ++ break; ++ default: ++ result = false; ++ break; ++ } ++ return result; ++} ++ ++void hal_init_macaddr(struct adapter *adapter) ++{ ++ rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR, ++ adapter->eeprompriv.mac_addr); ++} ++ ++/* ++* C2H event format: ++* Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID ++* BITS [127:120] [119:16] [15:8] [7:4] [3:0] ++*/ ++ ++void c2h_evt_clear(struct adapter *adapter) ++{ ++ rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); ++} ++ ++s32 c2h_evt_read(struct adapter *adapter, u8 *buf) ++{ ++ s32 ret = _FAIL; ++ struct c2h_evt_hdr *c2h_evt; ++ int i; ++ u8 trigger; ++ ++ if (!buf) ++ goto exit; ++ ++ trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR); ++ ++ if (trigger == C2H_EVT_HOST_CLOSE) ++ goto exit; /* Not ready */ ++ else if (trigger != C2H_EVT_FW_CLOSE) ++ goto clear_evt; /* Not a valid value */ ++ ++ c2h_evt = (struct c2h_evt_hdr *)buf; ++ ++ memset(c2h_evt, 0, 16); ++ ++ *buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL); ++ *(buf + 1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1); ++ ++ /* Read the content */ ++ for (i = 0; i < c2h_evt->plen; i++) ++ c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + ++ sizeof(*c2h_evt) + i); ++ ++ ret = _SUCCESS; ++ ++clear_evt: ++ /* ++ * Clear event to notify FW we have read the command. ++ * If this field isn't clear, the FW won't update the next ++ * command message. ++ */ ++ c2h_evt_clear(adapter); ++exit: ++ return ret; ++} +diff --git a/drivers/staging/r8188eu/hal/hal_intf.c b/drivers/staging/r8188eu/hal/hal_intf.c +new file mode 100644 +index 000000000000..a6d589e89aeb +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/hal_intf.c +@@ -0,0 +1,441 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _HAL_INTF_C_ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/hal_intf.h" ++ ++void rtw_hal_chip_configure(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.intf_chip_configure) ++ adapt->HalFunc.intf_chip_configure(adapt); ++} ++ ++void rtw_hal_read_chip_info(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.read_adapter_info) ++ adapt->HalFunc.read_adapter_info(adapt); ++} ++ ++void rtw_hal_read_chip_version(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.read_chip_version) ++ adapt->HalFunc.read_chip_version(adapt); ++} ++ ++void rtw_hal_def_value_init(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.init_default_value) ++ adapt->HalFunc.init_default_value(adapt); ++} ++ ++void rtw_hal_free_data(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.free_hal_data) ++ adapt->HalFunc.free_hal_data(adapt); ++} ++ ++void rtw_hal_dm_init(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.dm_init) ++ adapt->HalFunc.dm_init(adapt); ++} ++ ++void rtw_hal_dm_deinit(struct adapter *adapt) ++{ ++ /* cancel dm timer */ ++ if (adapt->HalFunc.dm_deinit) ++ adapt->HalFunc.dm_deinit(adapt); ++} ++ ++void rtw_hal_sw_led_init(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.InitSwLeds) ++ adapt->HalFunc.InitSwLeds(adapt); ++} ++ ++void rtw_hal_sw_led_deinit(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.DeInitSwLeds) ++ adapt->HalFunc.DeInitSwLeds(adapt); ++} ++ ++u32 rtw_hal_power_on(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.hal_power_on) ++ return adapt->HalFunc.hal_power_on(adapt); ++ return _FAIL; ++} ++ ++uint rtw_hal_init(struct adapter *adapt) ++{ ++ uint status = _SUCCESS; ++ ++ adapt->hw_init_completed = false; ++ ++ status = adapt->HalFunc.hal_init(adapt); ++ ++ if (status == _SUCCESS) { ++ adapt->hw_init_completed = true; ++ ++ if (adapt->registrypriv.notch_filter == 1) ++ rtw_hal_notch_filter(adapt, 1); ++ ++ rtw_hal_reset_security_engine(adapt); ++ } else { ++ adapt->hw_init_completed = false; ++ DBG_88E("rtw_hal_init: hal__init fail\n"); ++ } ++ ++ return status; ++} ++ ++uint rtw_hal_deinit(struct adapter *adapt) ++{ ++ uint status = _SUCCESS; ++ ++ status = adapt->HalFunc.hal_deinit(adapt); ++ ++ if (status == _SUCCESS) ++ adapt->hw_init_completed = false; ++ else ++ DBG_88E("\n rtw_hal_deinit: hal_init fail\n"); ++ ++ return status; ++} ++ ++void rtw_hal_set_hwreg(struct adapter *adapt, u8 variable, u8 *val) ++{ ++ if (adapt->HalFunc.SetHwRegHandler) ++ adapt->HalFunc.SetHwRegHandler(adapt, variable, val); ++} ++ ++void rtw_hal_get_hwreg(struct adapter *adapt, u8 variable, u8 *val) ++{ ++ if (adapt->HalFunc.GetHwRegHandler) ++ adapt->HalFunc.GetHwRegHandler(adapt, variable, val); ++} ++ ++u8 rtw_hal_set_def_var(struct adapter *adapt, enum hal_def_variable var, ++ void *val) ++{ ++ if (adapt->HalFunc.SetHalDefVarHandler) ++ return adapt->HalFunc.SetHalDefVarHandler(adapt, var, val); ++ return _FAIL; ++} ++ ++u8 rtw_hal_get_def_var(struct adapter *adapt, ++ enum hal_def_variable var, void *val) ++{ ++ if (adapt->HalFunc.GetHalDefVarHandler) ++ return adapt->HalFunc.GetHalDefVarHandler(adapt, var, val); ++ return _FAIL; ++} ++ ++void rtw_hal_set_odm_var(struct adapter *adapt, ++ enum hal_odm_variable var, void *val1, ++ bool set) ++{ ++ if (adapt->HalFunc.SetHalODMVarHandler) ++ adapt->HalFunc.SetHalODMVarHandler(adapt, var, ++ val1, set); ++} ++ ++void rtw_hal_get_odm_var(struct adapter *adapt, ++ enum hal_odm_variable var, void *val1, ++ bool set) ++{ ++ if (adapt->HalFunc.GetHalODMVarHandler) ++ adapt->HalFunc.GetHalODMVarHandler(adapt, var, ++ val1, set); ++} ++ ++void rtw_hal_enable_interrupt(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.enable_interrupt) ++ adapt->HalFunc.enable_interrupt(adapt); ++ else ++ DBG_88E("%s: HalFunc.enable_interrupt is NULL!\n", __func__); ++} ++ ++void rtw_hal_disable_interrupt(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.disable_interrupt) ++ adapt->HalFunc.disable_interrupt(adapt); ++ else ++ DBG_88E("%s: HalFunc.disable_interrupt is NULL!\n", __func__); ++} ++ ++u32 rtw_hal_inirp_init(struct adapter *adapt) ++{ ++ u32 rst = _FAIL; ++ ++ if (adapt->HalFunc.inirp_init) ++ rst = adapt->HalFunc.inirp_init(adapt); ++ else ++ DBG_88E(" %s HalFunc.inirp_init is NULL!!!\n", __func__); ++ return rst; ++} ++ ++u32 rtw_hal_inirp_deinit(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.inirp_deinit) ++ return adapt->HalFunc.inirp_deinit(adapt); ++ ++ return _FAIL; ++} ++ ++u8 rtw_hal_intf_ps_func(struct adapter *adapt, ++ enum hal_intf_ps_func efunc_id, u8 *val) ++{ ++ if (adapt->HalFunc.interface_ps_func) ++ return adapt->HalFunc.interface_ps_func(adapt, efunc_id, ++ val); ++ return _FAIL; ++} ++ ++s32 rtw_hal_xmitframe_enqueue(struct adapter *padapter, ++ struct xmit_frame *pxmitframe) ++{ ++ if (padapter->HalFunc.hal_xmitframe_enqueue) ++ return padapter->HalFunc.hal_xmitframe_enqueue(padapter, pxmitframe); ++ return false; ++} ++ ++s32 rtw_hal_xmit(struct adapter *adapt, struct xmit_frame *pxmitframe) ++{ ++ if (adapt->HalFunc.hal_xmit) ++ return adapt->HalFunc.hal_xmit(adapt, pxmitframe); ++ ++ return false; ++} ++ ++s32 rtw_hal_mgnt_xmit(struct adapter *adapt, struct xmit_frame *pmgntframe) ++{ ++ s32 ret = _FAIL; ++ if (adapt->HalFunc.mgnt_xmit) ++ ret = adapt->HalFunc.mgnt_xmit(adapt, pmgntframe); ++ return ret; ++} ++ ++s32 rtw_hal_init_xmit_priv(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.init_xmit_priv) ++ return adapt->HalFunc.init_xmit_priv(adapt); ++ return _FAIL; ++} ++ ++s32 rtw_hal_init_recv_priv(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.init_recv_priv) ++ return adapt->HalFunc.init_recv_priv(adapt); ++ ++ return _FAIL; ++} ++ ++void rtw_hal_free_recv_priv(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.free_recv_priv) ++ adapt->HalFunc.free_recv_priv(adapt); ++} ++ ++void rtw_hal_update_ra_mask(struct adapter *adapt, u32 mac_id, u8 rssi_level) ++{ ++ struct mlme_priv *pmlmepriv = &adapt->mlmepriv; ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++#ifdef CONFIG_88EU_AP_MODE ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &adapt->stapriv; ++ if ((mac_id - 1) > 0) ++ psta = pstapriv->sta_aid[(mac_id - 1) - 1]; ++ if (psta) ++ add_RATid(adapt, psta, 0);/* todo: based on rssi_level*/ ++#endif ++ } else { ++ if (adapt->HalFunc.UpdateRAMaskHandler) ++ adapt->HalFunc.UpdateRAMaskHandler(adapt, mac_id, ++ rssi_level); ++ } ++} ++ ++void rtw_hal_add_ra_tid(struct adapter *adapt, u32 bitmap, u8 arg, ++ u8 rssi_level) ++{ ++ if (adapt->HalFunc.Add_RateATid) ++ adapt->HalFunc.Add_RateATid(adapt, bitmap, arg, ++ rssi_level); ++} ++ ++/* Start specifical interface thread */ ++void rtw_hal_start_thread(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.run_thread) ++ adapt->HalFunc.run_thread(adapt); ++} ++ ++/* Start specifical interface thread */ ++void rtw_hal_stop_thread(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.cancel_thread) ++ adapt->HalFunc.cancel_thread(adapt); ++} ++ ++u32 rtw_hal_read_bbreg(struct adapter *adapt, u32 regaddr, u32 bitmask) ++{ ++ u32 data = 0; ++ ++ if (adapt->HalFunc.read_bbreg) ++ data = adapt->HalFunc.read_bbreg(adapt, regaddr, bitmask); ++ return data; ++} ++ ++void rtw_hal_write_bbreg(struct adapter *adapt, u32 regaddr, u32 bitmask, ++ u32 data) ++{ ++ if (adapt->HalFunc.write_bbreg) ++ adapt->HalFunc.write_bbreg(adapt, regaddr, bitmask, data); ++} ++ ++u32 rtw_hal_read_rfreg(struct adapter *adapt, enum rf_radio_path rfpath, ++ u32 regaddr, u32 bitmask) ++{ ++ u32 data = 0; ++ ++ if (adapt->HalFunc.read_rfreg) ++ data = adapt->HalFunc.read_rfreg(adapt, rfpath, regaddr, ++ bitmask); ++ return data; ++} ++ ++void rtw_hal_write_rfreg(struct adapter *adapt, enum rf_radio_path rfpath, ++ u32 regaddr, u32 bitmask, u32 data) ++{ ++ if (adapt->HalFunc.write_rfreg) ++ adapt->HalFunc.write_rfreg(adapt, rfpath, regaddr, ++ bitmask, data); ++} ++ ++s32 rtw_hal_interrupt_handler(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.interrupt_handler) ++ return adapt->HalFunc.interrupt_handler(adapt); ++ return _FAIL; ++} ++ ++void rtw_hal_set_bwmode(struct adapter *adapt, ++ enum ht_channel_width bandwidth, u8 offset) ++{ ++ if (adapt->HalFunc.set_bwmode_handler) ++ adapt->HalFunc.set_bwmode_handler(adapt, bandwidth, ++ offset); ++} ++ ++void rtw_hal_set_chan(struct adapter *adapt, u8 channel) ++{ ++ if (adapt->HalFunc.set_channel_handler) ++ adapt->HalFunc.set_channel_handler(adapt, channel); ++} ++ ++void rtw_hal_dm_watchdog(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.hal_dm_watchdog) ++ adapt->HalFunc.hal_dm_watchdog(adapt); ++} ++ ++void rtw_hal_bcn_related_reg_setting(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.SetBeaconRelatedRegistersHandler) ++ adapt->HalFunc.SetBeaconRelatedRegistersHandler(adapt); ++} ++ ++u8 rtw_hal_antdiv_before_linked(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.AntDivBeforeLinkHandler) ++ return adapt->HalFunc.AntDivBeforeLinkHandler(adapt); ++ return false; ++} ++ ++void rtw_hal_antdiv_rssi_compared(struct adapter *adapt, ++ struct wlan_bssid_ex *dst, ++ struct wlan_bssid_ex *src) ++{ ++ if (adapt->HalFunc.AntDivCompareHandler) ++ adapt->HalFunc.AntDivCompareHandler(adapt, dst, src); ++} ++ ++void rtw_hal_sreset_init(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.sreset_init_value) ++ adapt->HalFunc.sreset_init_value(adapt); ++} ++ ++void rtw_hal_sreset_reset(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.silentreset) ++ adapt->HalFunc.silentreset(adapt); ++} ++ ++void rtw_hal_sreset_reset_value(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.sreset_reset_value) ++ adapt->HalFunc.sreset_reset_value(adapt); ++} ++ ++void rtw_hal_sreset_xmit_status_check(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.sreset_xmit_status_check) ++ adapt->HalFunc.sreset_xmit_status_check(adapt); ++} ++ ++void rtw_hal_sreset_linked_status_check(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.sreset_linked_status_check) ++ adapt->HalFunc.sreset_linked_status_check(adapt); ++} ++ ++u8 rtw_hal_sreset_get_wifi_status(struct adapter *adapt) ++{ ++ u8 status = 0; ++ ++ if (adapt->HalFunc.sreset_get_wifi_status) ++ status = adapt->HalFunc.sreset_get_wifi_status(adapt); ++ return status; ++} ++ ++int rtw_hal_iol_cmd(struct adapter *adapter, struct xmit_frame *xmit_frame, ++ u32 max_wating_ms, u32 bndy_cnt) ++{ ++ if (adapter->HalFunc.IOL_exec_cmds_sync) ++ return adapter->HalFunc.IOL_exec_cmds_sync(adapter, xmit_frame, ++ max_wating_ms, ++ bndy_cnt); ++ return _FAIL; ++} ++ ++void rtw_hal_notch_filter(struct adapter *adapter, bool enable) ++{ ++ if (adapter->HalFunc.hal_notch_filter) ++ adapter->HalFunc.hal_notch_filter(adapter, enable); ++} ++ ++void rtw_hal_reset_security_engine(struct adapter *adapter) ++{ ++ if (adapter->HalFunc.hal_reset_security_engine) ++ adapter->HalFunc.hal_reset_security_engine(adapter); ++} ++ ++s32 rtw_hal_c2h_handler(struct adapter *adapter, struct c2h_evt_hdr *c2h_evt) ++{ ++ s32 ret = _FAIL; ++ ++ if (adapter->HalFunc.c2h_handler) ++ ret = adapter->HalFunc.c2h_handler(adapter, c2h_evt); ++ return ret; ++} ++ ++c2h_id_filter rtw_hal_c2h_id_filter_ccx(struct adapter *adapter) ++{ ++ return adapter->HalFunc.c2h_id_filter_ccx; ++} +diff --git a/drivers/staging/r8188eu/hal/odm.c b/drivers/staging/r8188eu/hal/odm.c +new file mode 100644 +index 000000000000..ed94f64d878d +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/odm.c +@@ -0,0 +1,1968 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++/* include files */ ++ ++#include "../include/odm_precomp.h" ++ ++static const u16 dB_Invert_Table[8][12] = { ++ {1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4}, ++ {4, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16}, ++ {18, 20, 22, 25, 28, 32, 35, 40, 45, 50, 56, 63}, ++ {71, 79, 89, 100, 112, 126, 141, 158, 178, 200, 224, 251}, ++ {282, 316, 355, 398, 447, 501, 562, 631, 708, 794, 891, 1000}, ++ {1122, 1259, 1413, 1585, 1778, 1995, 2239, 2512, 2818, 3162, 3548, 3981}, ++ {4467, 5012, 5623, 6310, 7079, 7943, 8913, 10000, 11220, 12589, 14125, 15849}, ++ {17783, 19953, 22387, 25119, 28184, 31623, 35481, 39811, 44668, 50119, 56234, 65535} ++}; ++ ++/* avoid to warn in FreeBSD ==> To DO modify */ ++static u32 EDCAParam[HT_IOT_PEER_MAX][3] = { ++ /* UL DL */ ++ {0x5ea42b, 0x5ea42b, 0x5ea42b}, /* 0:unknown AP */ ++ {0xa44f, 0x5ea44f, 0x5e431c}, /* 1:realtek AP */ ++ {0x5ea42b, 0x5ea42b, 0x5ea42b}, /* 2:unknown AP => realtek_92SE */ ++ {0x5ea32b, 0x5ea42b, 0x5e4322}, /* 3:broadcom AP */ ++ {0x5ea422, 0x00a44f, 0x00a44f}, /* 4:ralink AP */ ++ {0x5ea322, 0x00a630, 0x00a44f}, /* 5:atheros AP */ ++ {0x5e4322, 0x5e4322, 0x5e4322},/* 6:cisco AP */ ++ {0x5ea44f, 0x00a44f, 0x5ea42b}, /* 8:marvell AP */ ++ {0x5ea42b, 0x5ea42b, 0x5ea42b}, /* 10:unknown AP=> 92U AP */ ++ {0x5ea42b, 0xa630, 0x5e431c}, /* 11:airgocap AP */ ++}; ++ ++/* Global var */ ++u32 OFDMSwingTable[OFDM_TABLE_SIZE_92D] = { ++ 0x7f8001fe, /* 0, +6.0dB */ ++ 0x788001e2, /* 1, +5.5dB */ ++ 0x71c001c7, /* 2, +5.0dB */ ++ 0x6b8001ae, /* 3, +4.5dB */ ++ 0x65400195, /* 4, +4.0dB */ ++ 0x5fc0017f, /* 5, +3.5dB */ ++ 0x5a400169, /* 6, +3.0dB */ ++ 0x55400155, /* 7, +2.5dB */ ++ 0x50800142, /* 8, +2.0dB */ ++ 0x4c000130, /* 9, +1.5dB */ ++ 0x47c0011f, /* 10, +1.0dB */ ++ 0x43c0010f, /* 11, +0.5dB */ ++ 0x40000100, /* 12, +0dB */ ++ 0x3c8000f2, /* 13, -0.5dB */ ++ 0x390000e4, /* 14, -1.0dB */ ++ 0x35c000d7, /* 15, -1.5dB */ ++ 0x32c000cb, /* 16, -2.0dB */ ++ 0x300000c0, /* 17, -2.5dB */ ++ 0x2d4000b5, /* 18, -3.0dB */ ++ 0x2ac000ab, /* 19, -3.5dB */ ++ 0x288000a2, /* 20, -4.0dB */ ++ 0x26000098, /* 21, -4.5dB */ ++ 0x24000090, /* 22, -5.0dB */ ++ 0x22000088, /* 23, -5.5dB */ ++ 0x20000080, /* 24, -6.0dB */ ++ 0x1e400079, /* 25, -6.5dB */ ++ 0x1c800072, /* 26, -7.0dB */ ++ 0x1b00006c, /* 27. -7.5dB */ ++ 0x19800066, /* 28, -8.0dB */ ++ 0x18000060, /* 29, -8.5dB */ ++ 0x16c0005b, /* 30, -9.0dB */ ++ 0x15800056, /* 31, -9.5dB */ ++ 0x14400051, /* 32, -10.0dB */ ++ 0x1300004c, /* 33, -10.5dB */ ++ 0x12000048, /* 34, -11.0dB */ ++ 0x11000044, /* 35, -11.5dB */ ++ 0x10000040, /* 36, -12.0dB */ ++ 0x0f00003c,/* 37, -12.5dB */ ++ 0x0e400039,/* 38, -13.0dB */ ++ 0x0d800036,/* 39, -13.5dB */ ++ 0x0cc00033,/* 40, -14.0dB */ ++ 0x0c000030,/* 41, -14.5dB */ ++ 0x0b40002d,/* 42, -15.0dB */ ++}; ++ ++u8 CCKSwingTable_Ch1_Ch13[CCK_TABLE_SIZE][8] = { ++ {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */ ++ {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */ ++ {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB */ ++ {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB */ ++ {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */ ++ {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB */ ++ {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB */ ++ {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB */ ++ {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */ ++ {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB */ ++ {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */ ++ {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB */ ++ {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB */ ++ {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB */ ++ {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */ ++ {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB */ ++ {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */ ++ {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB */ ++ {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */ ++ {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB */ ++ {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB */ ++ {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB */ ++ {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB */ ++ {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB */ ++ {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB */ ++ {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB */ ++ {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB */ ++ {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB */ ++ {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB */ ++ {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB */ ++ {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB */ ++ {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB */ ++ {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB */ ++}; ++ ++u8 CCKSwingTable_Ch14[CCK_TABLE_SIZE][8] = { ++ {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */ ++ {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */ ++ {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */ ++ {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB */ ++ {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */ ++ {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB */ ++ {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */ ++ {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */ ++ {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */ ++ {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB */ ++ {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */ ++ {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB */ ++ {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB */ ++ {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */ ++ {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */ ++ {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB */ ++ {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */ ++ {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB */ ++ {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */ ++ {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB */ ++ {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB */ ++ {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB */ ++ {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB */ ++ {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB */ ++ {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB */ ++ {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB */ ++ {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB */ ++ {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB */ ++ {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB */ ++ {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB */ ++ {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB */ ++ {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB */ ++ {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB */ ++}; ++ ++#define RxDefaultAnt1 0x65a9 ++#define RxDefaultAnt2 0x569a ++ ++/* 3 Export Interface */ ++ ++/* 2011/09/21 MH Add to describe different team necessary resource allocate?? */ ++void ODM_DMInit(struct odm_dm_struct *pDM_Odm) ++{ ++ /* 2012.05.03 Luke: For all IC series */ ++ odm_CommonInfoSelfInit(pDM_Odm); ++ odm_DIGInit(pDM_Odm); ++ odm_RateAdaptiveMaskInit(pDM_Odm); ++ ++ if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) { ++ ; ++ } else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) { ++ odm_PrimaryCCA_Init(pDM_Odm); /* Gary */ ++ odm_DynamicBBPowerSavingInit(pDM_Odm); ++ odm_DynamicTxPowerInit(pDM_Odm); ++ odm_TXPowerTrackingInit(pDM_Odm); ++ ODM_EdcaTurboInit(pDM_Odm); ++ ODM_RAInfo_Init_all(pDM_Odm); ++ if ((pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) || ++ (pDM_Odm->AntDivType == CGCS_RX_HW_ANTDIV) || ++ (pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV)) ++ odm_InitHybridAntDiv(pDM_Odm); ++ else if (pDM_Odm->AntDivType == CGCS_RX_SW_ANTDIV) ++ odm_SwAntDivInit(pDM_Odm); ++ } ++} ++ ++/* 2011/09/20 MH This is the entry pointer for all team to execute HW out source DM. */ ++/* You can not add any dummy function here, be care, you can only use DM structure */ ++/* to perform any new ODM_DM. */ ++void ODM_DMWatchdog(struct odm_dm_struct *pDM_Odm) ++{ ++ /* 2012.05.03 Luke: For all IC series */ ++ odm_GlobalAdapterCheck(); ++ odm_CommonInfoSelfUpdate(pDM_Odm); ++ odm_FalseAlarmCounterStatistics(pDM_Odm); ++ odm_RSSIMonitorCheck(pDM_Odm); ++ ++ /* For CE Platform(SPRD or Tablet) */ ++ /* 8723A or 8189ES platform */ ++ /* NeilChen--2012--08--24-- */ ++ /* Fix Leave LPS issue */ ++ if ((pDM_Odm->Adapter->pwrctrlpriv.pwr_mode != PS_MODE_ACTIVE) &&/* in LPS mode */ ++ ((pDM_Odm->SupportICType & (ODM_RTL8723A)) || ++ (pDM_Odm->SupportICType & (ODM_RTL8188E) && ++ ((pDM_Odm->SupportInterface == ODM_ITRF_SDIO))))) ++ odm_DIGbyRSSI_LPS(pDM_Odm); ++ else ++ odm_DIG(pDM_Odm); ++ odm_CCKPacketDetectionThresh(pDM_Odm); ++ ++ if (*pDM_Odm->pbPowerSaving) ++ return; ++ ++ odm_RefreshRateAdaptiveMask(pDM_Odm); ++ ++ odm_DynamicBBPowerSaving(pDM_Odm); ++ if ((pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) || ++ (pDM_Odm->AntDivType == CGCS_RX_HW_ANTDIV) || ++ (pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV)) ++ odm_HwAntDiv(pDM_Odm); ++ else if (pDM_Odm->AntDivType == CGCS_RX_SW_ANTDIV) ++ odm_SwAntDivChkAntSwitch(pDM_Odm, SWAW_STEP_PEAK); ++ ++ if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) { ++ ; ++ } else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) { ++ ODM_TXPowerTrackingCheck(pDM_Odm); ++ odm_EdcaTurboCheck(pDM_Odm); ++ odm_DynamicTxPower(pDM_Odm); ++ } ++ odm_dtc(pDM_Odm); ++} ++ ++/* Init /.. Fixed HW value. Only init time. */ ++void ODM_CmnInfoInit(struct odm_dm_struct *pDM_Odm, enum odm_common_info_def CmnInfo, u32 Value) ++{ ++ /* This section is used for init value */ ++ switch (CmnInfo) { ++ /* Fixed ODM value. */ ++ case ODM_CMNINFO_ABILITY: ++ pDM_Odm->SupportAbility = (u32)Value; ++ break; ++ case ODM_CMNINFO_PLATFORM: ++ pDM_Odm->SupportPlatform = (u8)Value; ++ break; ++ case ODM_CMNINFO_INTERFACE: ++ pDM_Odm->SupportInterface = (u8)Value; ++ break; ++ case ODM_CMNINFO_MP_TEST_CHIP: ++ pDM_Odm->bIsMPChip = (u8)Value; ++ break; ++ case ODM_CMNINFO_IC_TYPE: ++ pDM_Odm->SupportICType = Value; ++ break; ++ case ODM_CMNINFO_CUT_VER: ++ pDM_Odm->CutVersion = (u8)Value; ++ break; ++ case ODM_CMNINFO_FAB_VER: ++ pDM_Odm->FabVersion = (u8)Value; ++ break; ++ case ODM_CMNINFO_RF_TYPE: ++ pDM_Odm->RFType = (u8)Value; ++ break; ++ case ODM_CMNINFO_RF_ANTENNA_TYPE: ++ pDM_Odm->AntDivType = (u8)Value; ++ break; ++ case ODM_CMNINFO_BOARD_TYPE: ++ pDM_Odm->BoardType = (u8)Value; ++ break; ++ case ODM_CMNINFO_EXT_LNA: ++ pDM_Odm->ExtLNA = (u8)Value; ++ break; ++ case ODM_CMNINFO_EXT_PA: ++ pDM_Odm->ExtPA = (u8)Value; ++ break; ++ case ODM_CMNINFO_EXT_TRSW: ++ pDM_Odm->ExtTRSW = (u8)Value; ++ break; ++ case ODM_CMNINFO_PATCH_ID: ++ pDM_Odm->PatchID = (u8)Value; ++ break; ++ case ODM_CMNINFO_BINHCT_TEST: ++ pDM_Odm->bInHctTest = (bool)Value; ++ break; ++ case ODM_CMNINFO_BWIFI_TEST: ++ pDM_Odm->bWIFITest = (bool)Value; ++ break; ++ case ODM_CMNINFO_SMART_CONCURRENT: ++ pDM_Odm->bDualMacSmartConcurrent = (bool)Value; ++ break; ++ /* To remove the compiler warning, must add an empty default statement to handle the other values. */ ++ default: ++ /* do nothing */ ++ break; ++ } ++ ++ /* Tx power tracking BB swing table. */ ++ /* The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */ ++ pDM_Odm->BbSwingIdxOfdm = 12; /* Set defalut value as index 12. */ ++ pDM_Odm->BbSwingIdxOfdmCurrent = 12; ++ pDM_Odm->BbSwingFlagOfdm = false; ++} ++ ++void ODM_CmnInfoHook(struct odm_dm_struct *pDM_Odm, enum odm_common_info_def CmnInfo, void *pValue) ++{ ++ /* */ ++ /* Hook call by reference pointer. */ ++ /* */ ++ switch (CmnInfo) { ++ /* Dynamic call by reference pointer. */ ++ case ODM_CMNINFO_MAC_PHY_MODE: ++ pDM_Odm->pMacPhyMode = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_TX_UNI: ++ pDM_Odm->pNumTxBytesUnicast = (u64 *)pValue; ++ break; ++ case ODM_CMNINFO_RX_UNI: ++ pDM_Odm->pNumRxBytesUnicast = (u64 *)pValue; ++ break; ++ case ODM_CMNINFO_WM_MODE: ++ pDM_Odm->pWirelessMode = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_BAND: ++ pDM_Odm->pBandType = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_SEC_CHNL_OFFSET: ++ pDM_Odm->pSecChOffset = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_SEC_MODE: ++ pDM_Odm->pSecurity = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_BW: ++ pDM_Odm->pBandWidth = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_CHNL: ++ pDM_Odm->pChannel = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_DMSP_GET_VALUE: ++ pDM_Odm->pbGetValueFromOtherMac = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_BUDDY_ADAPTOR: ++ pDM_Odm->pBuddyAdapter = (struct adapter **)pValue; ++ break; ++ case ODM_CMNINFO_DMSP_IS_MASTER: ++ pDM_Odm->pbMasterOfDMSP = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_SCAN: ++ pDM_Odm->pbScanInProcess = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_POWER_SAVING: ++ pDM_Odm->pbPowerSaving = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_ONE_PATH_CCA: ++ pDM_Odm->pOnePathCCA = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_DRV_STOP: ++ pDM_Odm->pbDriverStopped = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_PNP_IN: ++ pDM_Odm->pbDriverIsGoingToPnpSetPowerSleep = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_INIT_ON: ++ pDM_Odm->pinit_adpt_in_progress = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_ANT_TEST: ++ pDM_Odm->pAntennaTest = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_NET_CLOSED: ++ pDM_Odm->pbNet_closed = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_MP_MODE: ++ pDM_Odm->mp_mode = (u8 *)pValue; ++ break; ++ /* To remove the compiler warning, must add an empty default statement to handle the other values. */ ++ default: ++ /* do nothing */ ++ break; ++ } ++} ++ ++void ODM_CmnInfoPtrArrayHook(struct odm_dm_struct *pDM_Odm, enum odm_common_info_def CmnInfo, u16 Index, void *pValue) ++{ ++ /* Hook call by reference pointer. */ ++ switch (CmnInfo) { ++ /* Dynamic call by reference pointer. */ ++ case ODM_CMNINFO_STA_STATUS: ++ pDM_Odm->pODM_StaInfo[Index] = (struct sta_info *)pValue; ++ break; ++ /* To remove the compiler warning, must add an empty default statement to handle the other values. */ ++ default: ++ /* do nothing */ ++ break; ++ } ++} ++ ++/* Update Band/CHannel/.. The values are dynamic but non-per-packet. */ ++void ODM_CmnInfoUpdate(struct odm_dm_struct *pDM_Odm, u32 CmnInfo, u64 Value) ++{ ++ /* */ ++ /* This init variable may be changed in run time. */ ++ /* */ ++ switch (CmnInfo) { ++ case ODM_CMNINFO_ABILITY: ++ pDM_Odm->SupportAbility = (u32)Value; ++ break; ++ case ODM_CMNINFO_RF_TYPE: ++ pDM_Odm->RFType = (u8)Value; ++ break; ++ case ODM_CMNINFO_WIFI_DIRECT: ++ pDM_Odm->bWIFI_Direct = (bool)Value; ++ break; ++ case ODM_CMNINFO_WIFI_DISPLAY: ++ pDM_Odm->bWIFI_Display = (bool)Value; ++ break; ++ case ODM_CMNINFO_LINK: ++ pDM_Odm->bLinked = (bool)Value; ++ break; ++ case ODM_CMNINFO_RSSI_MIN: ++ pDM_Odm->RSSI_Min = (u8)Value; ++ break; ++ case ODM_CMNINFO_RA_THRESHOLD_HIGH: ++ pDM_Odm->RateAdaptive.HighRSSIThresh = (u8)Value; ++ break; ++ case ODM_CMNINFO_RA_THRESHOLD_LOW: ++ pDM_Odm->RateAdaptive.LowRSSIThresh = (u8)Value; ++ break; ++ } ++} ++ ++void odm_CommonInfoSelfInit(struct odm_dm_struct *pDM_Odm) ++{ ++ pDM_Odm->bCckHighPower = (bool)ODM_GetBBReg(pDM_Odm, 0x824, BIT(9)); ++ pDM_Odm->RFPathRxEnable = (u8)ODM_GetBBReg(pDM_Odm, 0xc04, 0x0F); ++ if (pDM_Odm->SupportICType & (ODM_RTL8192C | ODM_RTL8192D)) ++ pDM_Odm->AntDivType = CG_TRX_HW_ANTDIV; ++ if (pDM_Odm->SupportICType & (ODM_RTL8723A)) ++ pDM_Odm->AntDivType = CGCS_RX_SW_ANTDIV; ++} ++ ++void odm_CommonInfoSelfUpdate(struct odm_dm_struct *pDM_Odm) ++{ ++ u8 EntryCnt = 0; ++ u8 i; ++ struct sta_info *pEntry; ++ ++ if (*pDM_Odm->pBandWidth == ODM_BW40M) { ++ if (*pDM_Odm->pSecChOffset == 1) ++ pDM_Odm->ControlChannel = *pDM_Odm->pChannel - 2; ++ else if (*pDM_Odm->pSecChOffset == 2) ++ pDM_Odm->ControlChannel = *pDM_Odm->pChannel + 2; ++ } else { ++ pDM_Odm->ControlChannel = *pDM_Odm->pChannel; ++ } ++ ++ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { ++ pEntry = pDM_Odm->pODM_StaInfo[i]; ++ if (IS_STA_VALID(pEntry)) ++ EntryCnt++; ++ } ++ if (EntryCnt == 1) ++ pDM_Odm->bOneEntryOnly = true; ++ else ++ pDM_Odm->bOneEntryOnly = false; ++} ++ ++static int getIGIForDiff(int value_IGI) ++{ ++ #define ONERCCA_LOW_TH 0x30 ++ #define ONERCCA_LOW_DIFF 8 ++ ++ if (value_IGI < ONERCCA_LOW_TH) { ++ if ((ONERCCA_LOW_TH - value_IGI) < ONERCCA_LOW_DIFF) ++ return ONERCCA_LOW_TH; ++ else ++ return value_IGI + ONERCCA_LOW_DIFF; ++ } else { ++ return value_IGI; ++ } ++} ++ ++void ODM_Write_DIG(struct odm_dm_struct *pDM_Odm, u8 CurrentIGI) ++{ ++ struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable; ++ ++ if (pDM_DigTable->CurIGValue != CurrentIGI) { ++ if (pDM_Odm->SupportPlatform & (ODM_CE | ODM_MP)) { ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); ++ if (pDM_Odm->SupportICType != ODM_RTL8188E) ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); ++ } else if (pDM_Odm->SupportPlatform & (ODM_AP | ODM_ADSL)) { ++ switch (*pDM_Odm->pOnePathCCA) { ++ case ODM_CCA_2R: ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); ++ if (pDM_Odm->SupportICType != ODM_RTL8188E) ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); ++ break; ++ case ODM_CCA_1R_A: ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); ++ if (pDM_Odm->SupportICType != ODM_RTL8188E) ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B, pDM_Odm), ODM_BIT(IGI, pDM_Odm), getIGIForDiff(CurrentIGI)); ++ break; ++ case ODM_CCA_1R_B: ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), getIGIForDiff(CurrentIGI)); ++ if (pDM_Odm->SupportICType != ODM_RTL8188E) ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); ++ break; ++ } ++ } ++ /* pDM_DigTable->PreIGValue = pDM_DigTable->CurIGValue; */ ++ pDM_DigTable->CurIGValue = CurrentIGI; ++ } ++/* Add by Neil Chen to enable edcca to MP Platform */ ++} ++ ++/* Need LPS mode for CE platform --2012--08--24--- */ ++/* 8723AS/8189ES */ ++void odm_DIGbyRSSI_LPS(struct odm_dm_struct *pDM_Odm) ++{ ++ struct adapter *pAdapter = pDM_Odm->Adapter; ++ struct false_alarm_stats *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; ++ ++ u8 RSSI_Lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */ ++ u8 bFwCurrentInPSMode = false; ++ u8 CurrentIGI = pDM_Odm->RSSI_Min; ++ ++ if (!(pDM_Odm->SupportICType & (ODM_RTL8723A | ODM_RTL8188E))) ++ return; ++ ++ CurrentIGI = CurrentIGI + RSSI_OFFSET_DIG; ++ bFwCurrentInPSMode = pAdapter->pwrctrlpriv.bFwCurrentInPSMode; ++ ++ /* Using FW PS mode to make IGI */ ++ if (bFwCurrentInPSMode) { ++ /* Adjust by FA in LPS MODE */ ++ if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_LPS) ++ CurrentIGI = CurrentIGI + 2; ++ else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_LPS) ++ CurrentIGI = CurrentIGI + 1; ++ else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_LPS) ++ CurrentIGI = CurrentIGI - 1; ++ } else { ++ CurrentIGI = RSSI_Lower; ++ } ++ ++ /* Lower bound checking */ ++ ++ /* RSSI Lower bound check */ ++ if ((pDM_Odm->RSSI_Min - 10) > DM_DIG_MIN_NIC) ++ RSSI_Lower = (pDM_Odm->RSSI_Min - 10); ++ else ++ RSSI_Lower = DM_DIG_MIN_NIC; ++ ++ /* Upper and Lower Bound checking */ ++ if (CurrentIGI > DM_DIG_MAX_NIC) ++ CurrentIGI = DM_DIG_MAX_NIC; ++ else if (CurrentIGI < RSSI_Lower) ++ CurrentIGI = RSSI_Lower; ++ ++ ODM_Write_DIG(pDM_Odm, CurrentIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */ ++} ++ ++void odm_DIGInit(struct odm_dm_struct *pDM_Odm) ++{ ++ struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable; ++ ++ pDM_DigTable->CurIGValue = (u8)ODM_GetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm)); ++ pDM_DigTable->RssiLowThresh = DM_DIG_THRESH_LOW; ++ pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH; ++ pDM_DigTable->FALowThresh = DM_false_ALARM_THRESH_LOW; ++ pDM_DigTable->FAHighThresh = DM_false_ALARM_THRESH_HIGH; ++ if (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) { ++ pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; ++ pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC; ++ } else { ++ pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; ++ pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC; ++ } ++ pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT; ++ pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX; ++ pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN; ++ pDM_DigTable->PreCCK_CCAThres = 0xFF; ++ pDM_DigTable->CurCCK_CCAThres = 0x83; ++ pDM_DigTable->ForbiddenIGI = DM_DIG_MIN_NIC; ++ pDM_DigTable->LargeFAHit = 0; ++ pDM_DigTable->Recover_cnt = 0; ++ pDM_DigTable->DIG_Dynamic_MIN_0 = DM_DIG_MIN_NIC; ++ pDM_DigTable->DIG_Dynamic_MIN_1 = DM_DIG_MIN_NIC; ++ pDM_DigTable->bMediaConnect_0 = false; ++ pDM_DigTable->bMediaConnect_1 = false; ++ ++ /* To Initialize pDM_Odm->bDMInitialGainEnable == false to avoid DIG error */ ++ pDM_Odm->bDMInitialGainEnable = true; ++} ++ ++void odm_DIG(struct odm_dm_struct *pDM_Odm) ++{ ++ struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable; ++ struct false_alarm_stats *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; ++ u8 DIG_Dynamic_MIN; ++ u8 DIG_MaxOfMin; ++ bool FirstConnect, FirstDisConnect; ++ u8 dm_dig_max, dm_dig_min; ++ u8 CurrentIGI = pDM_DigTable->CurIGValue; ++ ++ if ((!(pDM_Odm->SupportAbility & ODM_BB_DIG)) || (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))) ++ return; ++ ++ if (*pDM_Odm->pbScanInProcess) ++ return; ++ ++ /* add by Neil Chen to avoid PSD is processing */ ++ if (!pDM_Odm->bDMInitialGainEnable) ++ return; ++ ++ if (pDM_Odm->SupportICType == ODM_RTL8192D) { ++ if (*pDM_Odm->pMacPhyMode == ODM_DMSP) { ++ if (*pDM_Odm->pbMasterOfDMSP) { ++ DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0; ++ FirstConnect = (pDM_Odm->bLinked) && (!pDM_DigTable->bMediaConnect_0); ++ FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0); ++ } else { ++ DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_1; ++ FirstConnect = (pDM_Odm->bLinked) && (!pDM_DigTable->bMediaConnect_1); ++ FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_1); ++ } ++ } else { ++ DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_1; ++ FirstConnect = (pDM_Odm->bLinked) && (!pDM_DigTable->bMediaConnect_1); ++ FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_1); ++ } ++ } else { ++ DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0; ++ FirstConnect = (pDM_Odm->bLinked) && (!pDM_DigTable->bMediaConnect_0); ++ FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0); ++ } ++ ++ /* 1 Boundary Decision */ ++ if ((pDM_Odm->SupportICType & (ODM_RTL8192C | ODM_RTL8723A)) && ++ ((pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) || pDM_Odm->ExtLNA)) { ++ if (pDM_Odm->SupportPlatform & (ODM_AP | ODM_ADSL)) { ++ dm_dig_max = DM_DIG_MAX_AP_HP; ++ dm_dig_min = DM_DIG_MIN_AP_HP; ++ } else { ++ dm_dig_max = DM_DIG_MAX_NIC_HP; ++ dm_dig_min = DM_DIG_MIN_NIC_HP; ++ } ++ DIG_MaxOfMin = DM_DIG_MAX_AP_HP; ++ } else { ++ if (pDM_Odm->SupportPlatform & (ODM_AP | ODM_ADSL)) { ++ dm_dig_max = DM_DIG_MAX_AP; ++ dm_dig_min = DM_DIG_MIN_AP; ++ DIG_MaxOfMin = dm_dig_max; ++ } else { ++ dm_dig_max = DM_DIG_MAX_NIC; ++ dm_dig_min = DM_DIG_MIN_NIC; ++ DIG_MaxOfMin = DM_DIG_MAX_AP; ++ } ++ } ++ if (pDM_Odm->bLinked) { ++ /* 2 8723A Series, offset need to be 10 */ ++ if (pDM_Odm->SupportICType == (ODM_RTL8723A)) { ++ /* 2 Upper Bound */ ++ if ((pDM_Odm->RSSI_Min + 10) > DM_DIG_MAX_NIC) ++ pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; ++ else if ((pDM_Odm->RSSI_Min + 10) < DM_DIG_MIN_NIC) ++ pDM_DigTable->rx_gain_range_max = DM_DIG_MIN_NIC; ++ else ++ pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + 10; ++ /* 2 If BT is Concurrent, need to set Lower Bound */ ++ DIG_Dynamic_MIN = DM_DIG_MIN_NIC; ++ } else { ++ /* 2 Modify DIG upper bound */ ++ if ((pDM_Odm->RSSI_Min + 20) > dm_dig_max) ++ pDM_DigTable->rx_gain_range_max = dm_dig_max; ++ else if ((pDM_Odm->RSSI_Min + 20) < dm_dig_min) ++ pDM_DigTable->rx_gain_range_max = dm_dig_min; ++ else ++ pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + 20; ++ /* 2 Modify DIG lower bound */ ++ if (pDM_Odm->bOneEntryOnly) { ++ if (pDM_Odm->RSSI_Min < dm_dig_min) ++ DIG_Dynamic_MIN = dm_dig_min; ++ else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin) ++ DIG_Dynamic_MIN = DIG_MaxOfMin; ++ else ++ DIG_Dynamic_MIN = pDM_Odm->RSSI_Min; ++ } else if ((pDM_Odm->SupportICType == ODM_RTL8188E) && ++ (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) { ++ /* 1 Lower Bound for 88E AntDiv */ ++ if (pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) ++ DIG_Dynamic_MIN = (u8)pDM_DigTable->AntDiv_RSSI_max; ++ } else { ++ DIG_Dynamic_MIN = dm_dig_min; ++ } ++ } ++ } else { ++ pDM_DigTable->rx_gain_range_max = dm_dig_max; ++ DIG_Dynamic_MIN = dm_dig_min; ++ } ++ ++ /* 1 Modify DIG lower bound, deal with abnormally large false alarm */ ++ if (pFalseAlmCnt->Cnt_all > 10000) { ++ if (pDM_DigTable->LargeFAHit != 3) ++ pDM_DigTable->LargeFAHit++; ++ if (pDM_DigTable->ForbiddenIGI < CurrentIGI) { ++ pDM_DigTable->ForbiddenIGI = CurrentIGI; ++ pDM_DigTable->LargeFAHit = 1; ++ } ++ ++ if (pDM_DigTable->LargeFAHit >= 3) { ++ if ((pDM_DigTable->ForbiddenIGI + 1) > pDM_DigTable->rx_gain_range_max) ++ pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max; ++ else ++ pDM_DigTable->rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 1); ++ pDM_DigTable->Recover_cnt = 3600; /* 3600=2hr */ ++ } ++ ++ } else { ++ /* Recovery mechanism for IGI lower bound */ ++ if (pDM_DigTable->Recover_cnt != 0) { ++ pDM_DigTable->Recover_cnt--; ++ } else { ++ if (pDM_DigTable->LargeFAHit < 3) { ++ if ((pDM_DigTable->ForbiddenIGI - 1) < DIG_Dynamic_MIN) { /* DM_DIG_MIN) */ ++ pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */ ++ pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */ ++ } else { ++ pDM_DigTable->ForbiddenIGI--; ++ pDM_DigTable->rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 1); ++ } ++ } else { ++ pDM_DigTable->LargeFAHit = 0; ++ } ++ } ++ } ++ ++ /* 1 Adjust initial gain by false alarm */ ++ if (pDM_Odm->bLinked) { ++ if (FirstConnect) { ++ CurrentIGI = pDM_Odm->RSSI_Min; ++ } else { ++ if (pDM_Odm->SupportICType == ODM_RTL8192D) { ++ if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_92D) ++ CurrentIGI = CurrentIGI + 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+2; */ ++ else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_92D) ++ CurrentIGI = CurrentIGI + 1; /* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+1; */ ++ else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_92D) ++ CurrentIGI = CurrentIGI - 1;/* pDM_DigTable->CurIGValue =pDM_DigTable->PreIGValue-1; */ ++ } else { ++ if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2) ++ CurrentIGI = CurrentIGI + 4;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+2; */ ++ else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1) ++ CurrentIGI = CurrentIGI + 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+1; */ ++ else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0) ++ CurrentIGI = CurrentIGI - 2;/* pDM_DigTable->CurIGValue =pDM_DigTable->PreIGValue-1; */ ++ } ++ } ++ } else { ++ if (FirstDisConnect) { ++ CurrentIGI = pDM_DigTable->rx_gain_range_min; ++ } else { ++ /* 2012.03.30 LukeLee: enable DIG before link but with very high thresholds */ ++ if (pFalseAlmCnt->Cnt_all > 10000) ++ CurrentIGI = CurrentIGI + 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+2; */ ++ else if (pFalseAlmCnt->Cnt_all > 8000) ++ CurrentIGI = CurrentIGI + 1;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+1; */ ++ else if (pFalseAlmCnt->Cnt_all < 500) ++ CurrentIGI = CurrentIGI - 1;/* pDM_DigTable->CurIGValue =pDM_DigTable->PreIGValue-1; */ ++ } ++ } ++ /* 1 Check initial gain by upper/lower bound */ ++ if (CurrentIGI > pDM_DigTable->rx_gain_range_max) ++ CurrentIGI = pDM_DigTable->rx_gain_range_max; ++ if (CurrentIGI < pDM_DigTable->rx_gain_range_min) ++ CurrentIGI = pDM_DigTable->rx_gain_range_min; ++ ++ /* 2 High power RSSI threshold */ ++ ++ ODM_Write_DIG(pDM_Odm, CurrentIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */ ++ pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked; ++ pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN; ++} ++ ++/* 3============================================================ */ ++/* 3 FASLE ALARM CHECK */ ++/* 3============================================================ */ ++ ++void odm_FalseAlarmCounterStatistics(struct odm_dm_struct *pDM_Odm) ++{ ++ u32 ret_value; ++ struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; ++ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) ++ return; ++ ++ if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) { ++ /* hold ofdm counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1); /* hold page C counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 1); /* hold page D counter */ ++ ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord); ++ FalseAlmCnt->Cnt_Fast_Fsync = (ret_value & 0xffff); ++ FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value & 0xffff0000) >> 16); ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord); ++ FalseAlmCnt->Cnt_OFDM_CCA = (ret_value & 0xffff); ++ FalseAlmCnt->Cnt_Parity_Fail = ((ret_value & 0xffff0000) >> 16); ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord); ++ FalseAlmCnt->Cnt_Rate_Illegal = (ret_value & 0xffff); ++ FalseAlmCnt->Cnt_Crc8_fail = ((ret_value & 0xffff0000) >> 16); ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord); ++ FalseAlmCnt->Cnt_Mcs_fail = (ret_value & 0xffff); ++ ++ FalseAlmCnt->Cnt_Ofdm_fail = FalseAlmCnt->Cnt_Parity_Fail + FalseAlmCnt->Cnt_Rate_Illegal + ++ FalseAlmCnt->Cnt_Crc8_fail + FalseAlmCnt->Cnt_Mcs_fail + ++ FalseAlmCnt->Cnt_Fast_Fsync + FalseAlmCnt->Cnt_SB_Search_fail; ++ ++ if (pDM_Odm->SupportICType == ODM_RTL8188E) { ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_SC_CNT_11N, bMaskDWord); ++ FalseAlmCnt->Cnt_BW_LSC = (ret_value & 0xffff); ++ FalseAlmCnt->Cnt_BW_USC = ((ret_value & 0xffff0000) >> 16); ++ } ++ ++ /* hold cck counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(12), 1); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(14), 1); ++ ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_LSB_11N, bMaskByte0); ++ FalseAlmCnt->Cnt_Cck_fail = ret_value; ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_MSB_11N, bMaskByte3); ++ FalseAlmCnt->Cnt_Cck_fail += (ret_value & 0xff) << 8; ++ ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord); ++ FalseAlmCnt->Cnt_CCK_CCA = ((ret_value & 0xFF) << 8) | ((ret_value & 0xFF00) >> 8); ++ ++ FalseAlmCnt->Cnt_all = (FalseAlmCnt->Cnt_Fast_Fsync + ++ FalseAlmCnt->Cnt_SB_Search_fail + ++ FalseAlmCnt->Cnt_Parity_Fail + ++ FalseAlmCnt->Cnt_Rate_Illegal + ++ FalseAlmCnt->Cnt_Crc8_fail + ++ FalseAlmCnt->Cnt_Mcs_fail + ++ FalseAlmCnt->Cnt_Cck_fail); ++ ++ FalseAlmCnt->Cnt_CCA_all = FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA; ++ ++ if (pDM_Odm->SupportICType >= ODM_RTL8723A) { ++ /* reset false alarm counter registers */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31), 1); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31), 0); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), 1); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), 0); ++ /* update ofdm counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0); /* update page C counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 0); /* update page D counter */ ++ ++ /* reset CCK CCA counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2); ++ /* reset CCK FA counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2); ++ } ++ } else { /* FOR ODM_IC_11AC_SERIES */ ++ /* read OFDM FA counter */ ++ FalseAlmCnt->Cnt_Ofdm_fail = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_11AC, bMaskLWord); ++ FalseAlmCnt->Cnt_Cck_fail = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_11AC, bMaskLWord); ++ FalseAlmCnt->Cnt_all = FalseAlmCnt->Cnt_Ofdm_fail + FalseAlmCnt->Cnt_Cck_fail; ++ ++ /* reset OFDM FA coutner */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0); ++ /* reset CCK FA counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1); ++ } ++} ++ ++/* 3============================================================ */ ++/* 3 CCK Packet Detect Threshold */ ++/* 3============================================================ */ ++ ++void odm_CCKPacketDetectionThresh(struct odm_dm_struct *pDM_Odm) ++{ ++ u8 CurCCK_CCAThres; ++ struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; ++ ++ if (!(pDM_Odm->SupportAbility & (ODM_BB_CCK_PD | ODM_BB_FA_CNT))) ++ return; ++ if (pDM_Odm->ExtLNA) ++ return; ++ if (pDM_Odm->bLinked) { ++ if (pDM_Odm->RSSI_Min > 25) { ++ CurCCK_CCAThres = 0xcd; ++ } else if ((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10)) { ++ CurCCK_CCAThres = 0x83; ++ } else { ++ if (FalseAlmCnt->Cnt_Cck_fail > 1000) ++ CurCCK_CCAThres = 0x83; ++ else ++ CurCCK_CCAThres = 0x40; ++ } ++ } else { ++ if (FalseAlmCnt->Cnt_Cck_fail > 1000) ++ CurCCK_CCAThres = 0x83; ++ else ++ CurCCK_CCAThres = 0x40; ++ } ++ ODM_Write_CCK_CCA_Thres(pDM_Odm, CurCCK_CCAThres); ++} ++ ++void ODM_Write_CCK_CCA_Thres(struct odm_dm_struct *pDM_Odm, u8 CurCCK_CCAThres) ++{ ++ struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable; ++ ++ if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres) /* modify by Guo.Mingzhi 2012-01-03 */ ++ ODM_Write1Byte(pDM_Odm, ODM_REG(CCK_CCA, pDM_Odm), CurCCK_CCAThres); ++ pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres; ++ pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres; ++} ++ ++/* 3============================================================ */ ++/* 3 BB Power Save */ ++/* 3============================================================ */ ++void odm_DynamicBBPowerSavingInit(struct odm_dm_struct *pDM_Odm) ++{ ++ struct rtl_ps *pDM_PSTable = &pDM_Odm->DM_PSTable; ++ ++ pDM_PSTable->pre_cca_state = CCA_MAX; ++ pDM_PSTable->cur_cca_state = CCA_MAX; ++ pDM_PSTable->pre_rf_state = RF_MAX; ++ pDM_PSTable->cur_rf_state = RF_MAX; ++ pDM_PSTable->rssi_val_min = 0; ++ pDM_PSTable->initialize = 0; ++} ++ ++void odm_DynamicBBPowerSaving(struct odm_dm_struct *pDM_Odm) ++{ ++ if ((pDM_Odm->SupportICType != ODM_RTL8192C) && (pDM_Odm->SupportICType != ODM_RTL8723A)) ++ return; ++ if (!(pDM_Odm->SupportAbility & ODM_BB_PWR_SAVE)) ++ return; ++ if (!(pDM_Odm->SupportPlatform & (ODM_MP | ODM_CE))) ++ return; ++ ++ /* 1 2.Power Saving for 92C */ ++ if ((pDM_Odm->SupportICType == ODM_RTL8192C) && (pDM_Odm->RFType == ODM_2T2R)) { ++ odm_1R_CCA(pDM_Odm); ++ } else { ++ /* 20100628 Joseph: Turn off BB power save for 88CE because it makesthroughput unstable. */ ++ /* 20100831 Joseph: Turn ON BB power save again after modifying AGC delay from 900ns ot 600ns. */ ++ /* 1 3.Power Saving for 88C */ ++ ODM_RF_Saving(pDM_Odm, false); ++ } ++} ++ ++void odm_1R_CCA(struct odm_dm_struct *pDM_Odm) ++{ ++ struct rtl_ps *pDM_PSTable = &pDM_Odm->DM_PSTable; ++ ++ if (pDM_Odm->RSSI_Min != 0xFF) { ++ if (pDM_PSTable->pre_cca_state == CCA_2R) { ++ if (pDM_Odm->RSSI_Min >= 35) ++ pDM_PSTable->cur_cca_state = CCA_1R; ++ else ++ pDM_PSTable->cur_cca_state = CCA_2R; ++ } else { ++ if (pDM_Odm->RSSI_Min <= 30) ++ pDM_PSTable->cur_cca_state = CCA_2R; ++ else ++ pDM_PSTable->cur_cca_state = CCA_1R; ++ } ++ } else { ++ pDM_PSTable->cur_cca_state = CCA_MAX; ++ } ++ ++ if (pDM_PSTable->pre_cca_state != pDM_PSTable->cur_cca_state) { ++ if (pDM_PSTable->cur_cca_state == CCA_1R) { ++ if (pDM_Odm->RFType == ODM_2T2R) ++ ODM_SetBBReg(pDM_Odm, 0xc04, bMaskByte0, 0x13); ++ else ++ ODM_SetBBReg(pDM_Odm, 0xc04, bMaskByte0, 0x23); ++ } else { ++ ODM_SetBBReg(pDM_Odm, 0xc04, bMaskByte0, 0x33); ++ } ++ pDM_PSTable->pre_cca_state = pDM_PSTable->cur_cca_state; ++ } ++} ++ ++void ODM_RF_Saving(struct odm_dm_struct *pDM_Odm, u8 bForceInNormal) ++{ ++ struct rtl_ps *pDM_PSTable = &pDM_Odm->DM_PSTable; ++ u8 Rssi_Up_bound = 30; ++ u8 Rssi_Low_bound = 25; ++ ++ if (pDM_Odm->PatchID == 40) { /* RT_CID_819x_FUNAI_TV */ ++ Rssi_Up_bound = 50; ++ Rssi_Low_bound = 45; ++ } ++ if (pDM_PSTable->initialize == 0) { ++ pDM_PSTable->reg_874 = (ODM_GetBBReg(pDM_Odm, 0x874, bMaskDWord) & 0x1CC000) >> 14; ++ pDM_PSTable->reg_c70 = (ODM_GetBBReg(pDM_Odm, 0xc70, bMaskDWord) & BIT(3)) >> 3; ++ pDM_PSTable->reg_85c = (ODM_GetBBReg(pDM_Odm, 0x85c, bMaskDWord) & 0xFF000000) >> 24; ++ pDM_PSTable->reg_a74 = (ODM_GetBBReg(pDM_Odm, 0xa74, bMaskDWord) & 0xF000) >> 12; ++ pDM_PSTable->initialize = 1; ++ } ++ ++ if (!bForceInNormal) { ++ if (pDM_Odm->RSSI_Min != 0xFF) { ++ if (pDM_PSTable->pre_rf_state == RF_Normal) { ++ if (pDM_Odm->RSSI_Min >= Rssi_Up_bound) ++ pDM_PSTable->cur_rf_state = RF_Save; ++ else ++ pDM_PSTable->cur_rf_state = RF_Normal; ++ } else { ++ if (pDM_Odm->RSSI_Min <= Rssi_Low_bound) ++ pDM_PSTable->cur_rf_state = RF_Normal; ++ else ++ pDM_PSTable->cur_rf_state = RF_Save; ++ } ++ } else { ++ pDM_PSTable->cur_rf_state = RF_MAX; ++ } ++ } else { ++ pDM_PSTable->cur_rf_state = RF_Normal; ++ } ++ ++ if (pDM_PSTable->pre_rf_state != pDM_PSTable->cur_rf_state) { ++ if (pDM_PSTable->cur_rf_state == RF_Save) { ++ /* 8723 RSSI report will be wrong. Set 0x874[5]=1 when enter BB power saving mode. */ ++ /* Suggested by SD3 Yu-Nan. 2011.01.20. */ ++ if (pDM_Odm->SupportICType == ODM_RTL8723A) ++ ODM_SetBBReg(pDM_Odm, 0x874, BIT(5), 0x1); /* Reg874[5]=1b'1 */ ++ ODM_SetBBReg(pDM_Odm, 0x874, 0x1C0000, 0x2); /* Reg874[20:18]=3'b010 */ ++ ODM_SetBBReg(pDM_Odm, 0xc70, BIT(3), 0); /* RegC70[3]=1'b0 */ ++ ODM_SetBBReg(pDM_Odm, 0x85c, 0xFF000000, 0x63); /* Reg85C[31:24]=0x63 */ ++ ODM_SetBBReg(pDM_Odm, 0x874, 0xC000, 0x2); /* Reg874[15:14]=2'b10 */ ++ ODM_SetBBReg(pDM_Odm, 0xa74, 0xF000, 0x3); /* RegA75[7:4]=0x3 */ ++ ODM_SetBBReg(pDM_Odm, 0x818, BIT(28), 0x0); /* Reg818[28]=1'b0 */ ++ ODM_SetBBReg(pDM_Odm, 0x818, BIT(28), 0x1); /* Reg818[28]=1'b1 */ ++ } else { ++ ODM_SetBBReg(pDM_Odm, 0x874, 0x1CC000, pDM_PSTable->reg_874); ++ ODM_SetBBReg(pDM_Odm, 0xc70, BIT(3), pDM_PSTable->reg_c70); ++ ODM_SetBBReg(pDM_Odm, 0x85c, 0xFF000000, pDM_PSTable->reg_85c); ++ ODM_SetBBReg(pDM_Odm, 0xa74, 0xF000, pDM_PSTable->reg_a74); ++ ODM_SetBBReg(pDM_Odm, 0x818, BIT(28), 0x0); ++ ++ if (pDM_Odm->SupportICType == ODM_RTL8723A) ++ ODM_SetBBReg(pDM_Odm, 0x874, BIT(5), 0x0); /* Reg874[5]=1b'0 */ ++ } ++ pDM_PSTable->pre_rf_state = pDM_PSTable->cur_rf_state; ++ } ++} ++ ++/* 3============================================================ */ ++/* 3 RATR MASK */ ++/* 3============================================================ */ ++/* 3============================================================ */ ++/* 3 Rate Adaptive */ ++/* 3============================================================ */ ++ ++void odm_RateAdaptiveMaskInit(struct odm_dm_struct *pDM_Odm) ++{ ++ struct odm_rate_adapt *pOdmRA = &pDM_Odm->RateAdaptive; ++ ++ pOdmRA->Type = DM_Type_ByDriver; ++ if (pOdmRA->Type == DM_Type_ByDriver) ++ pDM_Odm->bUseRAMask = true; ++ else ++ pDM_Odm->bUseRAMask = false; ++ ++ pOdmRA->RATRState = DM_RATR_STA_INIT; ++ pOdmRA->HighRSSIThresh = 50; ++ pOdmRA->LowRSSIThresh = 20; ++} ++ ++u32 ODM_Get_Rate_Bitmap(struct odm_dm_struct *pDM_Odm, u32 macid, u32 ra_mask, u8 rssi_level) ++{ ++ struct sta_info *pEntry; ++ u32 rate_bitmap = 0x0fffffff; ++ u8 WirelessMode; ++ ++ pEntry = pDM_Odm->pODM_StaInfo[macid]; ++ if (!IS_STA_VALID(pEntry)) ++ return ra_mask; ++ ++ WirelessMode = pEntry->wireless_mode; ++ ++ switch (WirelessMode) { ++ case ODM_WM_B: ++ if (ra_mask & 0x0000000c) /* 11M or 5.5M enable */ ++ rate_bitmap = 0x0000000d; ++ else ++ rate_bitmap = 0x0000000f; ++ break; ++ case (ODM_WM_B | ODM_WM_G): ++ if (rssi_level == DM_RATR_STA_HIGH) ++ rate_bitmap = 0x00000f00; ++ else if (rssi_level == DM_RATR_STA_MIDDLE) ++ rate_bitmap = 0x00000ff0; ++ else ++ rate_bitmap = 0x00000ff5; ++ break; ++ case (ODM_WM_B | ODM_WM_G | ODM_WM_N24G): ++ if (pDM_Odm->RFType == ODM_1T2R || pDM_Odm->RFType == ODM_1T1R) { ++ if (rssi_level == DM_RATR_STA_HIGH) { ++ rate_bitmap = 0x000f0000; ++ } else if (rssi_level == DM_RATR_STA_MIDDLE) { ++ rate_bitmap = 0x000ff000; ++ } else { ++ if (*pDM_Odm->pBandWidth == ODM_BW40M) ++ rate_bitmap = 0x000ff015; ++ else ++ rate_bitmap = 0x000ff005; ++ } ++ } else { ++ if (rssi_level == DM_RATR_STA_HIGH) { ++ rate_bitmap = 0x0f8f0000; ++ } else if (rssi_level == DM_RATR_STA_MIDDLE) { ++ rate_bitmap = 0x0f8ff000; ++ } else { ++ if (*pDM_Odm->pBandWidth == ODM_BW40M) ++ rate_bitmap = 0x0f8ff015; ++ else ++ rate_bitmap = 0x0f8ff005; ++ } ++ } ++ break; ++ default: ++ /* case WIRELESS_11_24N: */ ++ if (pDM_Odm->RFType == RF_1T2R) ++ rate_bitmap = 0x000fffff; ++ else ++ rate_bitmap = 0x0fffffff; ++ break; ++ } ++ ++ return rate_bitmap; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: odm_RefreshRateAdaptiveMask() ++ * ++ * Overview: Update rate table mask according to rssi ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 05/27/2009 hpfan Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++void odm_RefreshRateAdaptiveMask(struct odm_dm_struct *pDM_Odm) ++{ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_RA_MASK)) ++ return; ++ /* */ ++ /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ ++ /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ ++ /* HW dynamic mechanism. */ ++ /* */ ++ switch (pDM_Odm->SupportPlatform) { ++ case ODM_MP: ++ odm_RefreshRateAdaptiveMaskMP(pDM_Odm); ++ break; ++ case ODM_CE: ++ odm_RefreshRateAdaptiveMaskCE(pDM_Odm); ++ break; ++ case ODM_AP: ++ case ODM_ADSL: ++ odm_RefreshRateAdaptiveMaskAPADSL(pDM_Odm); ++ break; ++ } ++} ++ ++void odm_RefreshRateAdaptiveMaskMP(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++void odm_RefreshRateAdaptiveMaskCE(struct odm_dm_struct *pDM_Odm) ++{ ++ u8 i; ++ struct adapter *pAdapter = pDM_Odm->Adapter; ++ ++ if (pAdapter->bDriverStopped) ++ return; ++ ++ if (!pDM_Odm->bUseRAMask) ++ return; ++ ++ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { ++ struct sta_info *pstat = pDM_Odm->pODM_StaInfo[i]; ++ if (IS_STA_VALID(pstat)) { ++ if (ODM_RAStateCheck(pDM_Odm, pstat->rssi_stat.UndecoratedSmoothedPWDB, false, &pstat->rssi_level)) ++ rtw_hal_update_ra_mask(pAdapter, i, pstat->rssi_level); ++ } ++ } ++} ++ ++void odm_RefreshRateAdaptiveMaskAPADSL(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++/* Return Value: bool */ ++/* - true: RATRState is changed. */ ++bool ODM_RAStateCheck(struct odm_dm_struct *pDM_Odm, s32 RSSI, bool bForceUpdate, u8 *pRATRState) ++{ ++ struct odm_rate_adapt *pRA = &pDM_Odm->RateAdaptive; ++ const u8 GoUpGap = 5; ++ u8 HighRSSIThreshForRA = pRA->HighRSSIThresh; ++ u8 LowRSSIThreshForRA = pRA->LowRSSIThresh; ++ u8 RATRState; ++ ++ /* Threshold Adjustment: */ ++ /* when RSSI state trends to go up one or two levels, make sure RSSI is high enough. */ ++ /* Here GoUpGap is added to solve the boundary's level alternation issue. */ ++ switch (*pRATRState) { ++ case DM_RATR_STA_INIT: ++ case DM_RATR_STA_HIGH: ++ break; ++ case DM_RATR_STA_MIDDLE: ++ HighRSSIThreshForRA += GoUpGap; ++ break; ++ case DM_RATR_STA_LOW: ++ HighRSSIThreshForRA += GoUpGap; ++ LowRSSIThreshForRA += GoUpGap; ++ break; ++ default: ++ break; ++ } ++ ++ /* Decide RATRState by RSSI. */ ++ if (RSSI > HighRSSIThreshForRA) ++ RATRState = DM_RATR_STA_HIGH; ++ else if (RSSI > LowRSSIThreshForRA) ++ RATRState = DM_RATR_STA_MIDDLE; ++ else ++ RATRState = DM_RATR_STA_LOW; ++ ++ if (*pRATRState != RATRState || bForceUpdate) { ++ *pRATRState = RATRState; ++ return true; ++ } ++ return false; ++} ++ ++/* 3============================================================ */ ++/* 3 Dynamic Tx Power */ ++/* 3============================================================ */ ++ ++void odm_DynamicTxPowerInit(struct odm_dm_struct *pDM_Odm) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &pHalData->dmpriv; ++ pdmpriv->bDynamicTxPowerEnable = false; ++ pdmpriv->LastDTPLvl = TxHighPwrLevel_Normal; ++ pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; ++} ++ ++void odm_DynamicTxPower(struct odm_dm_struct *pDM_Odm) ++{ ++ /* For AP/ADSL use struct rtl8192cd_priv * */ ++ /* For CE/NIC use struct adapter * */ ++ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_DYNAMIC_TXPWR)) ++ return; ++ ++ /* 2012/01/12 MH According to Luke's suggestion, only high power will support the feature. */ ++ if (!pDM_Odm->ExtPA) ++ return; ++ ++ /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ ++ /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ ++ /* HW dynamic mechanism. */ ++ switch (pDM_Odm->SupportPlatform) { ++ case ODM_MP: ++ case ODM_CE: ++ odm_DynamicTxPowerNIC(pDM_Odm); ++ break; ++ case ODM_AP: ++ odm_DynamicTxPowerAP(pDM_Odm); ++ break; ++ case ODM_ADSL: ++ break; ++ } ++} ++ ++void odm_DynamicTxPowerNIC(struct odm_dm_struct *pDM_Odm) ++{ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_DYNAMIC_TXPWR)) ++ return; ++ ++ if (pDM_Odm->SupportICType == ODM_RTL8188E) { ++ /* ??? */ ++ /* This part need to be redefined. */ ++ } ++} ++ ++void odm_DynamicTxPowerAP(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++/* 3============================================================ */ ++/* 3 RSSI Monitor */ ++/* 3============================================================ */ ++ ++void odm_RSSIMonitorCheck(struct odm_dm_struct *pDM_Odm) ++{ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_RSSI_MONITOR)) ++ return; ++ ++ /* */ ++ /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ ++ /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ ++ /* HW dynamic mechanism. */ ++ /* */ ++ switch (pDM_Odm->SupportPlatform) { ++ case ODM_MP: ++ odm_RSSIMonitorCheckMP(pDM_Odm); ++ break; ++ case ODM_CE: ++ odm_RSSIMonitorCheckCE(pDM_Odm); ++ break; ++ case ODM_AP: ++ odm_RSSIMonitorCheckAP(pDM_Odm); ++ break; ++ case ODM_ADSL: ++ /* odm_DIGAP(pDM_Odm); */ ++ break; ++ } ++ ++} /* odm_RSSIMonitorCheck */ ++ ++void odm_RSSIMonitorCheckMP(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++static void FindMinimumRSSI(struct adapter *pAdapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ struct dm_priv *pdmpriv = &pHalData->dmpriv; ++ struct mlme_priv *pmlmepriv = &pAdapter->mlmepriv; ++ ++ /* 1 1.Determine the minimum RSSI */ ++ if (!check_fwstate(pmlmepriv, _FW_LINKED) && ++ pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0) ++ pdmpriv->MinUndecoratedPWDBForDM = 0; ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) /* Default port */ ++ pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB; ++ else /* associated entry pwdb */ ++ pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB; ++} ++ ++void odm_RSSIMonitorCheckCE(struct odm_dm_struct *pDM_Odm) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &pHalData->dmpriv; ++ int i; ++ int tmpEntryMaxPWDB = 0, tmpEntryMinPWDB = 0xff; ++ u8 sta_cnt = 0; ++ u32 PWDB_rssi[NUM_STA] = {0};/* 0~15]:MACID, [16~31]:PWDB_rssi */ ++ struct sta_info *psta; ++ u8 bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ ++ if (!check_fwstate(&Adapter->mlmepriv, _FW_LINKED)) ++ return; ++ ++ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { ++ psta = pDM_Odm->pODM_StaInfo[i]; ++ if (IS_STA_VALID(psta) && ++ (psta->state & WIFI_ASOC_STATE) && ++ memcmp(psta->hwaddr, bcast_addr, ETH_ALEN) && ++ memcmp(psta->hwaddr, myid(&Adapter->eeprompriv), ETH_ALEN)) { ++ if (psta->rssi_stat.UndecoratedSmoothedPWDB < tmpEntryMinPWDB) ++ tmpEntryMinPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB; ++ ++ if (psta->rssi_stat.UndecoratedSmoothedPWDB > tmpEntryMaxPWDB) ++ tmpEntryMaxPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB; ++ if (psta->rssi_stat.UndecoratedSmoothedPWDB != (-1)) ++ PWDB_rssi[sta_cnt++] = (psta->mac_id | (psta->rssi_stat.UndecoratedSmoothedPWDB << 16)); ++ } ++ } ++ ++ for (i = 0; i < sta_cnt; i++) { ++ if (PWDB_rssi[i] != (0)) { ++ if (pHalData->fw_ractrl) { ++ /* Report every sta's RSSI to FW */ ++ } else { ++ ODM_RA_SetRSSI_8188E( ++ &pHalData->odmpriv, (PWDB_rssi[i] & 0xFF), (u8)((PWDB_rssi[i] >> 16) & 0xFF)); ++ } ++ } ++ } ++ ++ if (tmpEntryMaxPWDB != 0) /* If associated entry is found */ ++ pdmpriv->EntryMaxUndecoratedSmoothedPWDB = tmpEntryMaxPWDB; ++ else ++ pdmpriv->EntryMaxUndecoratedSmoothedPWDB = 0; ++ ++ if (tmpEntryMinPWDB != 0xff) /* If associated entry is found */ ++ pdmpriv->EntryMinUndecoratedSmoothedPWDB = tmpEntryMinPWDB; ++ else ++ pdmpriv->EntryMinUndecoratedSmoothedPWDB = 0; ++ ++ FindMinimumRSSI(Adapter); ++ ODM_CmnInfoUpdate(&pHalData->odmpriv, ODM_CMNINFO_RSSI_MIN, pdmpriv->MinUndecoratedPWDBForDM); ++} ++ ++void odm_RSSIMonitorCheckAP(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++void ODM_InitAllTimers(struct odm_dm_struct *pDM_Odm) ++{ ++ timer_setup(&pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer, odm_SwAntDivChkAntSwitchCallback, 0); ++} ++ ++void ODM_CancelAllTimers(struct odm_dm_struct *pDM_Odm) ++{ ++ ODM_CancelTimer(pDM_Odm, &pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer); ++} ++ ++void ODM_ReleaseAllTimers(struct odm_dm_struct *pDM_Odm) ++{ ++ ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer); ++ ++ ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->FastAntTrainingTimer); ++} ++ ++/* 3============================================================ */ ++/* 3 Tx Power Tracking */ ++/* 3============================================================ */ ++ ++void odm_TXPowerTrackingInit(struct odm_dm_struct *pDM_Odm) ++{ ++ odm_TXPowerTrackingThermalMeterInit(pDM_Odm); ++} ++ ++void odm_TXPowerTrackingThermalMeterInit(struct odm_dm_struct *pDM_Odm) ++{ ++ pDM_Odm->RFCalibrateInfo.bTXPowerTracking = true; ++ pDM_Odm->RFCalibrateInfo.TXPowercount = 0; ++ pDM_Odm->RFCalibrateInfo.bTXPowerTrackingInit = false; ++ if (*pDM_Odm->mp_mode != 1) ++ pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = true; ++ MSG_88E("pDM_Odm TxPowerTrackControl = %d\n", pDM_Odm->RFCalibrateInfo.TxPowerTrackControl); ++ ++ pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = true; ++} ++ ++void ODM_TXPowerTrackingCheck(struct odm_dm_struct *pDM_Odm) ++{ ++ /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ ++ /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ ++ /* HW dynamic mechanism. */ ++ switch (pDM_Odm->SupportPlatform) { ++ case ODM_MP: ++ odm_TXPowerTrackingCheckMP(pDM_Odm); ++ break; ++ case ODM_CE: ++ odm_TXPowerTrackingCheckCE(pDM_Odm); ++ break; ++ case ODM_AP: ++ odm_TXPowerTrackingCheckAP(pDM_Odm); ++ break; ++ case ODM_ADSL: ++ break; ++ } ++} ++ ++void odm_TXPowerTrackingCheckCE(struct odm_dm_struct *pDM_Odm) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ ++ if (!(pDM_Odm->SupportAbility & ODM_RF_TX_PWR_TRACK)) ++ return; ++ ++ if (!pDM_Odm->RFCalibrateInfo.TM_Trigger) { /* at least delay 1 sec */ ++ PHY_SetRFReg(Adapter, RF_PATH_A, RF_T_METER_88E, BIT(17) | BIT(16), 0x03); ++ ++ pDM_Odm->RFCalibrateInfo.TM_Trigger = 1; ++ return; ++ } else { ++ odm_TXPowerTrackingCallback_ThermalMeter_8188E(Adapter); ++ pDM_Odm->RFCalibrateInfo.TM_Trigger = 0; ++ } ++} ++ ++void odm_TXPowerTrackingCheckMP(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++void odm_TXPowerTrackingCheckAP(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++/* antenna mapping info */ ++/* 1: right-side antenna */ ++/* 2/0: left-side antenna */ ++/* PDM_SWAT_Table->CCK_Ant1_Cnt /OFDM_Ant1_Cnt: for right-side antenna: Ant:1 RxDefaultAnt1 */ ++/* PDM_SWAT_Table->CCK_Ant2_Cnt /OFDM_Ant2_Cnt: for left-side antenna: Ant:0 RxDefaultAnt2 */ ++/* We select left antenna as default antenna in initial process, modify it as needed */ ++/* */ ++ ++/* 3============================================================ */ ++/* 3 SW Antenna Diversity */ ++/* 3============================================================ */ ++void odm_SwAntDivInit(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++void ODM_SwAntDivChkPerPktRssi(struct odm_dm_struct *pDM_Odm, u8 StationID, struct odm_phy_status_info *pPhyInfo) ++{ ++} ++ ++void odm_SwAntDivChkAntSwitch(struct odm_dm_struct *pDM_Odm, u8 Step) ++{ ++} ++ ++void ODM_SwAntDivRestAfterLink(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++void odm_SwAntDivChkAntSwitchCallback(struct timer_list *t) ++{ ++} ++ ++/* 3============================================================ */ ++/* 3 SW Antenna Diversity */ ++/* 3============================================================ */ ++ ++void odm_InitHybridAntDiv(struct odm_dm_struct *pDM_Odm) ++{ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) ++ return; ++ ++ if (pDM_Odm->SupportICType & (ODM_RTL8192C | ODM_RTL8192D)) ++ ; ++ else if (pDM_Odm->SupportICType == ODM_RTL8188E) ++ ODM_AntennaDiversityInit_88E(pDM_Odm); ++} ++ ++void ODM_AntselStatistics_88C(struct odm_dm_struct *pDM_Odm, u8 MacId, u32 PWDBAll, bool isCCKrate) ++{ ++ struct sw_ant_switch *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; ++ ++ if (pDM_SWAT_Table->antsel == 1) { ++ if (isCCKrate) { ++ pDM_SWAT_Table->CCK_Ant1_Cnt[MacId]++; ++ } else { ++ pDM_SWAT_Table->OFDM_Ant1_Cnt[MacId]++; ++ pDM_SWAT_Table->RSSI_Ant1_Sum[MacId] += PWDBAll; ++ } ++ } else { ++ if (isCCKrate) { ++ pDM_SWAT_Table->CCK_Ant2_Cnt[MacId]++; ++ } else { ++ pDM_SWAT_Table->OFDM_Ant2_Cnt[MacId]++; ++ pDM_SWAT_Table->RSSI_Ant2_Sum[MacId] += PWDBAll; ++ } ++ } ++} ++ ++void odm_HwAntDiv(struct odm_dm_struct *pDM_Odm) ++{ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) ++ return; ++ ++ if (pDM_Odm->SupportICType == ODM_RTL8188E) ++ ODM_AntennaDiversity_88E(pDM_Odm); ++} ++ ++/* EDCA Turbo */ ++void ODM_EdcaTurboInit(struct odm_dm_struct *pDM_Odm) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false; ++ pDM_Odm->DM_EDCA_Table.bIsCurRDLState = false; ++ Adapter->recvpriv.bIsAnyNonBEPkts = false; ++ ++} /* ODM_InitEdcaTurbo */ ++ ++void odm_EdcaTurboCheck(struct odm_dm_struct *pDM_Odm) ++{ ++ /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ ++ /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ ++ /* HW dynamic mechanism. */ ++ if (!(pDM_Odm->SupportAbility & ODM_MAC_EDCA_TURBO)) ++ return; ++ ++ switch (pDM_Odm->SupportPlatform) { ++ case ODM_MP: ++ break; ++ case ODM_CE: ++ odm_EdcaTurboCheckCE(pDM_Odm); ++ break; ++ case ODM_AP: ++ case ODM_ADSL: ++ break; ++ } ++} /* odm_CheckEdcaTurbo */ ++ ++void odm_EdcaTurboCheckCE(struct odm_dm_struct *pDM_Odm) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ u32 trafficIndex; ++ u32 edca_param; ++ u64 cur_tx_bytes = 0; ++ u64 cur_rx_bytes = 0; ++ u8 bbtchange = false; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct xmit_priv *pxmitpriv = &Adapter->xmitpriv; ++ struct recv_priv *precvpriv = &Adapter->recvpriv; ++ struct registry_priv *pregpriv = &Adapter->registrypriv; ++ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pregpriv->wifi_spec == 1) ++ goto dm_CheckEdcaTurbo_EXIT; ++ ++ if (pmlmeinfo->assoc_AP_vendor >= HT_IOT_PEER_MAX) ++ goto dm_CheckEdcaTurbo_EXIT; ++ ++ /* Check if the status needs to be changed. */ ++ if ((bbtchange) || (!precvpriv->bIsAnyNonBEPkts)) { ++ cur_tx_bytes = pxmitpriv->tx_bytes - pxmitpriv->last_tx_bytes; ++ cur_rx_bytes = precvpriv->rx_bytes - precvpriv->last_rx_bytes; ++ ++ /* traffic, TX or RX */ ++ if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_RALINK) || ++ (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS)) { ++ if (cur_tx_bytes > (cur_rx_bytes << 2)) { ++ /* Uplink TP is present. */ ++ trafficIndex = UP_LINK; ++ } else { ++ /* Balance TP is present. */ ++ trafficIndex = DOWN_LINK; ++ } ++ } else { ++ if (cur_rx_bytes > (cur_tx_bytes << 2)) { ++ /* Downlink TP is present. */ ++ trafficIndex = DOWN_LINK; ++ } else { ++ /* Balance TP is present. */ ++ trafficIndex = UP_LINK; ++ } ++ } ++ ++ if ((pDM_Odm->DM_EDCA_Table.prv_traffic_idx != trafficIndex) || (!pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA)) { ++ if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_CISCO) && (pmlmeext->cur_wireless_mode & WIRELESS_11_24N)) ++ edca_param = EDCAParam[pmlmeinfo->assoc_AP_vendor][trafficIndex]; ++ else ++ edca_param = EDCAParam[HT_IOT_PEER_UNKNOWN][trafficIndex]; ++ ++ rtw_write32(Adapter, REG_EDCA_BE_PARAM, edca_param); ++ ++ pDM_Odm->DM_EDCA_Table.prv_traffic_idx = trafficIndex; ++ } ++ ++ pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = true; ++ } else { ++ /* Turn Off EDCA turbo here. */ ++ /* Restore original EDCA according to the declaration of AP. */ ++ if (pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA) { ++ rtw_write32(Adapter, REG_EDCA_BE_PARAM, pHalData->AcParam_BE); ++ pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false; ++ } ++ } ++ ++dm_CheckEdcaTurbo_EXIT: ++ /* Set variables for next time. */ ++ precvpriv->bIsAnyNonBEPkts = false; ++ pxmitpriv->last_tx_bytes = pxmitpriv->tx_bytes; ++ precvpriv->last_rx_bytes = precvpriv->rx_bytes; ++} ++ ++/* need to ODM CE Platform */ ++/* move to here for ANT detection mechanism using */ ++ ++u32 GetPSDData(struct odm_dm_struct *pDM_Odm, unsigned int point, u8 initial_gain_psd) ++{ ++ u32 psd_report; ++ ++ /* Set DCO frequency index, offset=(40MHz/SamplePts)*point */ ++ ODM_SetBBReg(pDM_Odm, 0x808, 0x3FF, point); ++ ++ /* Start PSD calculation, Reg808[22]=0->1 */ ++ ODM_SetBBReg(pDM_Odm, 0x808, BIT(22), 1); ++ /* Need to wait for HW PSD report */ ++ ODM_StallExecution(30); ++ ODM_SetBBReg(pDM_Odm, 0x808, BIT(22), 0); ++ /* Read PSD report, Reg8B4[15:0] */ ++ psd_report = ODM_GetBBReg(pDM_Odm, 0x8B4, bMaskDWord) & 0x0000FFFF; ++ ++ psd_report = (u32)(ConvertTo_dB(psd_report)) + (u32)(initial_gain_psd - 0x1c); ++ ++ return psd_report; ++} ++ ++u32 ConvertTo_dB(u32 Value) ++{ ++ u8 i; ++ u8 j; ++ u32 dB; ++ ++ Value = Value & 0xFFFF; ++ for (i = 0; i < 8; i++) { ++ if (Value <= dB_Invert_Table[i][11]) ++ break; ++ } ++ ++ if (i >= 8) ++ return 96; /* maximum 96 dB */ ++ ++ for (j = 0; j < 12; j++) { ++ if (Value <= dB_Invert_Table[i][j]) ++ break; ++ } ++ ++ dB = i * 12 + j + 1; ++ ++ return dB; ++} ++ ++/* 2011/09/22 MH Add for 92D global spin lock utilization. */ ++void odm_GlobalAdapterCheck(void) ++{ ++} /* odm_GlobalAdapterCheck */ ++ ++/* Description: */ ++/* Set Single/Dual Antenna default setting for products that do not do detection in advance. */ ++/* Added by Joseph, 2012.03.22 */ ++void ODM_SingleDualAntennaDefaultSetting(struct odm_dm_struct *pDM_Odm) ++{ ++ struct sw_ant_switch *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; ++ ++ pDM_SWAT_Table->ANTA_ON = true; ++ pDM_SWAT_Table->ANTB_ON = true; ++} ++ ++/* 2 8723A ANT DETECT */ ++ ++static void odm_PHY_SaveAFERegisters(struct odm_dm_struct *pDM_Odm, u32 *AFEReg, u32 *AFEBackup, u32 RegisterNum) ++{ ++ u32 i; ++ ++ /* RTPRINT(FINIT, INIT_IQK, ("Save ADDA parameters.\n")); */ ++ for (i = 0; i < RegisterNum; i++) ++ AFEBackup[i] = ODM_GetBBReg(pDM_Odm, AFEReg[i], bMaskDWord); ++} ++ ++static void odm_PHY_ReloadAFERegisters(struct odm_dm_struct *pDM_Odm, u32 *AFEReg, u32 *AFEBackup, u32 RegiesterNum) ++{ ++ u32 i; ++ ++ for (i = 0; i < RegiesterNum; i++) ++ ODM_SetBBReg(pDM_Odm, AFEReg[i], bMaskDWord, AFEBackup[i]); ++} ++ ++/* 2 8723A ANT DETECT */ ++/* Description: */ ++/* Implement IQK single tone for RF DPK loopback and BB PSD scanning. */ ++/* This function is cooperated with BB team Neil. */ ++bool ODM_SingleDualAntennaDetection(struct odm_dm_struct *pDM_Odm, u8 mode) ++{ ++ struct sw_ant_switch *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; ++ u32 CurrentChannel, RfLoopReg; ++ u8 n; ++ u32 Reg88c, Regc08, Reg874, Regc50; ++ u8 initial_gain = 0x5a; ++ u32 PSD_report_tmp; ++ u32 AntA_report = 0x0, AntB_report = 0x0, AntO_report = 0x0; ++ bool bResult = true; ++ u32 AFE_Backup[16]; ++ u32 AFE_REG_8723A[16] = { ++ rRx_Wait_CCA, rTx_CCK_RFON, ++ rTx_CCK_BBON, rTx_OFDM_RFON, ++ rTx_OFDM_BBON, rTx_To_Rx, ++ rTx_To_Tx, rRx_CCK, ++ rRx_OFDM, rRx_Wait_RIFS, ++ rRx_TO_Rx, rStandby, ++ rSleep, rPMPD_ANAEN, ++ rFPGA0_XCD_SwitchControl, rBlue_Tooth}; ++ ++ if (!(pDM_Odm->SupportICType & (ODM_RTL8723A | ODM_RTL8192C))) ++ return bResult; ++ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) ++ return bResult; ++ ++ if (pDM_Odm->SupportICType == ODM_RTL8192C) { ++ /* Which path in ADC/DAC is turnned on for PSD: both I/Q */ ++ ODM_SetBBReg(pDM_Odm, 0x808, BIT(10) | BIT(11), 0x3); ++ /* Ageraged number: 8 */ ++ ODM_SetBBReg(pDM_Odm, 0x808, BIT(12) | BIT(13), 0x1); ++ /* pts = 128; */ ++ ODM_SetBBReg(pDM_Odm, 0x808, BIT(14) | BIT(15), 0x0); ++ } ++ ++ /* 1 Backup Current RF/BB Settings */ ++ ++ CurrentChannel = ODM_GetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask); ++ RfLoopReg = ODM_GetRFReg(pDM_Odm, RF_PATH_A, 0x00, bRFRegOffsetMask); ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, ODM_DPDT, Antenna_A); /* change to Antenna A */ ++ /* Step 1: USE IQK to transmitter single tone */ ++ ++ ODM_StallExecution(10); ++ ++ /* Store A Path Register 88c, c08, 874, c50 */ ++ Reg88c = ODM_GetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord); ++ Regc08 = ODM_GetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord); ++ Reg874 = ODM_GetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord); ++ Regc50 = ODM_GetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskDWord); ++ ++ /* Store AFE Registers */ ++ odm_PHY_SaveAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16); ++ ++ /* Set PSD 128 pts */ ++ ODM_SetBBReg(pDM_Odm, rFPGA0_PSDFunction, BIT(14) | BIT(15), 0x0); /* 128 pts */ ++ ++ /* To SET CH1 to do */ ++ ODM_SetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask, 0x01); /* Channel 1 */ ++ ++ /* AFE all on step */ ++ ODM_SetBBReg(pDM_Odm, rRx_Wait_CCA, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rTx_CCK_RFON, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rTx_CCK_BBON, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rTx_OFDM_RFON, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rTx_OFDM_BBON, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rTx_To_Rx, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rTx_To_Tx, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rRx_CCK, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rRx_OFDM, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rRx_Wait_RIFS, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rRx_TO_Rx, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rStandby, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rSleep, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rPMPD_ANAEN, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_SwitchControl, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rBlue_Tooth, bMaskDWord, 0x6FDB25A4); ++ ++ /* 3 wire Disable */ ++ ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord, 0xCCF000C0); ++ ++ /* BB IQK Setting */ ++ ODM_SetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord, 0x000800E4); ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22208000); ++ ++ /* IQK setting tone@ 4.34Mhz */ ++ ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x10008C1C); ++ ODM_SetBBReg(pDM_Odm, rTx_IQK, bMaskDWord, 0x01007c00); ++ ++ /* Page B init */ ++ ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x00080000); ++ ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x0f600000); ++ ODM_SetBBReg(pDM_Odm, rRx_IQK, bMaskDWord, 0x01004800); ++ ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x10008c1f); ++ ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x82150008); ++ ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_A, bMaskDWord, 0x28150008); ++ ODM_SetBBReg(pDM_Odm, rIQK_AGC_Rsp, bMaskDWord, 0x001028d0); ++ ++ /* RF loop Setting */ ++ ODM_SetRFReg(pDM_Odm, RF_PATH_A, 0x0, 0xFFFFF, 0x50008); ++ ++ /* IQK Single tone start */ ++ ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskDWord, 0x80800000); ++ ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); ++ ODM_StallExecution(1000); ++ PSD_report_tmp = 0x0; ++ ++ for (n = 0; n < 2; n++) { ++ PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain); ++ if (PSD_report_tmp > AntA_report) ++ AntA_report = PSD_report_tmp; ++ } ++ ++ PSD_report_tmp = 0x0; ++ ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_B); /* change to Antenna B */ ++ ODM_StallExecution(10); ++ ++ for (n = 0; n < 2; n++) { ++ PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain); ++ if (PSD_report_tmp > AntB_report) ++ AntB_report = PSD_report_tmp; ++ } ++ ++ /* change to open case */ ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, 0); /* change to Ant A and B all open case */ ++ ODM_StallExecution(10); ++ ++ for (n = 0; n < 2; n++) { ++ PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain); ++ if (PSD_report_tmp > AntO_report) ++ AntO_report = PSD_report_tmp; ++ } ++ ++ /* Close IQK Single Tone function */ ++ ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskDWord, 0x00000000); ++ PSD_report_tmp = 0x0; ++ ++ /* 1 Return to antanna A */ ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_A); ++ ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord, Reg88c); ++ ODM_SetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord, Regc08); ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, Reg874); ++ ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, 0x7F, 0x40); ++ ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskDWord, Regc50); ++ ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, CurrentChannel); ++ ODM_SetRFReg(pDM_Odm, RF_PATH_A, 0x00, bRFRegOffsetMask, RfLoopReg); ++ ++ /* Reload AFE Registers */ ++ odm_PHY_ReloadAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16); ++ ++ if (pDM_Odm->SupportICType == ODM_RTL8723A) { ++ /* 2 Test Ant B based on Ant A is ON */ ++ if (mode == ANTTESTB) { ++ if (AntA_report >= 100) { ++ if (AntB_report > (AntA_report + 1)) ++ pDM_SWAT_Table->ANTB_ON = false; ++ else ++ pDM_SWAT_Table->ANTB_ON = true; ++ } else { ++ pDM_SWAT_Table->ANTB_ON = false; /* Set Antenna B off as default */ ++ bResult = false; ++ } ++ } else if (mode == ANTTESTALL) { ++ /* 2 Test Ant A and B based on DPDT Open */ ++ if ((AntO_report >= 100) & (AntO_report < 118)) { ++ if (AntA_report > (AntO_report + 1)) ++ pDM_SWAT_Table->ANTA_ON = false; ++ else ++ pDM_SWAT_Table->ANTA_ON = true; ++ ++ if (AntB_report > (AntO_report + 2)) ++ pDM_SWAT_Table->ANTB_ON = false; ++ else ++ pDM_SWAT_Table->ANTB_ON = true; ++ } ++ } ++ } else if (pDM_Odm->SupportICType == ODM_RTL8192C) { ++ if (AntA_report >= 100) { ++ if (AntB_report > (AntA_report + 2)) { ++ pDM_SWAT_Table->ANTA_ON = false; ++ pDM_SWAT_Table->ANTB_ON = true; ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_B); ++ } else if (AntA_report > (AntB_report + 2)) { ++ pDM_SWAT_Table->ANTA_ON = true; ++ pDM_SWAT_Table->ANTB_ON = false; ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_A); ++ } else { ++ pDM_SWAT_Table->ANTA_ON = true; ++ pDM_SWAT_Table->ANTB_ON = true; ++ } ++ } else { ++ pDM_SWAT_Table->ANTA_ON = true; /* Set Antenna A on as default */ ++ pDM_SWAT_Table->ANTB_ON = false; /* Set Antenna B off as default */ ++ bResult = false; ++ } ++ } ++ return bResult; ++} ++ ++/* Justin: According to the current RRSI to adjust Response Frame TX power, 2012/11/05 */ ++void odm_dtc(struct odm_dm_struct *pDM_Odm) ++{ ++} +diff --git a/drivers/staging/r8188eu/hal/odm_HWConfig.c b/drivers/staging/r8188eu/hal/odm_HWConfig.c +new file mode 100644 +index 000000000000..ada22a526fee +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/odm_HWConfig.c +@@ -0,0 +1,567 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++ ++#define READ_AND_CONFIG READ_AND_CONFIG_MP ++ ++#define READ_AND_CONFIG_MP(ic, txt) (ODM_ReadAndConfig##txt##ic(dm_odm)) ++#define READ_AND_CONFIG_TC(ic, txt) (ODM_ReadAndConfig_TC##txt##ic(dm_odm)) ++ ++static u8 odm_QueryRxPwrPercentage(s8 AntPower) ++{ ++ if ((AntPower <= -100) || (AntPower >= 20)) ++ return 0; ++ else if (AntPower >= 0) ++ return 100; ++ else ++ return 100 + AntPower; ++} ++ ++/* 2012/01/12 MH MOve some signal strength smooth method to MP HAL layer. */ ++/* IF other SW team do not support the feature, remove this section.?? */ ++static s32 odm_sig_patch_lenove(struct odm_dm_struct *dm_odm, s32 CurrSig) ++{ ++ return 0; ++} ++ ++static s32 odm_sig_patch_netcore(struct odm_dm_struct *dm_odm, s32 CurrSig) ++{ ++ return 0; ++} ++ ++static s32 odm_SignalScaleMapping_92CSeries(struct odm_dm_struct *dm_odm, s32 CurrSig) ++{ ++ s32 RetSig = 0; ++ ++ if ((dm_odm->SupportInterface == ODM_ITRF_USB) || ++ (dm_odm->SupportInterface == ODM_ITRF_SDIO)) { ++ if (CurrSig >= 51 && CurrSig <= 100) ++ RetSig = 100; ++ else if (CurrSig >= 41 && CurrSig <= 50) ++ RetSig = 80 + ((CurrSig - 40) * 2); ++ else if (CurrSig >= 31 && CurrSig <= 40) ++ RetSig = 66 + (CurrSig - 30); ++ else if (CurrSig >= 21 && CurrSig <= 30) ++ RetSig = 54 + (CurrSig - 20); ++ else if (CurrSig >= 10 && CurrSig <= 20) ++ RetSig = 42 + (((CurrSig - 10) * 2) / 3); ++ else if (CurrSig >= 5 && CurrSig <= 9) ++ RetSig = 22 + (((CurrSig - 5) * 3) / 2); ++ else if (CurrSig >= 1 && CurrSig <= 4) ++ RetSig = 6 + (((CurrSig - 1) * 3) / 2); ++ else ++ RetSig = CurrSig; ++ } ++ return RetSig; ++} ++ ++static s32 odm_SignalScaleMapping(struct odm_dm_struct *dm_odm, s32 CurrSig) ++{ ++ if ((dm_odm->SupportPlatform == ODM_MP) && ++ (dm_odm->SupportInterface != ODM_ITRF_PCIE) && /* USB & SDIO */ ++ (dm_odm->PatchID == 10)) ++ return odm_sig_patch_netcore(dm_odm, CurrSig); ++ else if ((dm_odm->SupportPlatform == ODM_MP) && ++ (dm_odm->SupportInterface == ODM_ITRF_PCIE) && ++ (dm_odm->PatchID == 19)) ++ return odm_sig_patch_lenove(dm_odm, CurrSig); ++ else ++ return odm_SignalScaleMapping_92CSeries(dm_odm, CurrSig); ++} ++ ++/* pMgntInfo->CustomerID == RT_CID_819x_Lenovo */ ++static u8 odm_SQ_process_patch_RT_CID_819x_Lenovo(struct odm_dm_struct *dm_odm, ++ u8 isCCKrate, u8 PWDB_ALL, u8 path, u8 RSSI) ++{ ++ return 0; ++} ++ ++static u8 odm_evm_db_to_percentage(s8 value) ++{ ++ /* -33dB~0dB to 0%~99% */ ++ s8 ret_val = clamp(-value, 0, 33) * 3; ++ ++ if (ret_val == 99) ++ ret_val = 100; ++ ++ return ret_val; ++} ++ ++static void odm_RxPhyStatus92CSeries_Parsing(struct odm_dm_struct *dm_odm, ++ struct odm_phy_status_info *pPhyInfo, ++ u8 *pPhyStatus, ++ struct odm_per_pkt_info *pPktinfo, ++ struct adapter *adapt) ++{ ++ struct sw_ant_switch *pDM_SWAT_Table = &dm_odm->DM_SWAT_Table; ++ u8 i, Max_spatial_stream; ++ s8 rx_pwr[4], rx_pwr_all = 0; ++ u8 EVM, PWDB_ALL = 0, PWDB_ALL_BT; ++ u8 RSSI, total_rssi = 0; ++ u8 isCCKrate = 0; ++ u8 rf_rx_num = 0; ++ u8 cck_highpwr = 0; ++ u8 LNA_idx, VGA_idx; ++ ++ struct phy_status_rpt *pPhyStaRpt = (struct phy_status_rpt *)pPhyStatus; ++ ++ isCCKrate = ((pPktinfo->Rate >= DESC92C_RATE1M) && (pPktinfo->Rate <= DESC92C_RATE11M)) ? true : false; ++ ++ pPhyInfo->RxMIMOSignalQuality[RF_PATH_A] = -1; ++ pPhyInfo->RxMIMOSignalQuality[RF_PATH_B] = -1; ++ ++ if (isCCKrate) { ++ u8 report; ++ u8 cck_agc_rpt; ++ ++ dm_odm->PhyDbgInfo.NumQryPhyStatusCCK++; ++ /* (1)Hardware does not provide RSSI for CCK */ ++ /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */ ++ ++ cck_highpwr = dm_odm->bCckHighPower; ++ ++ cck_agc_rpt = pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a; ++ ++ /* 2011.11.28 LukeLee: 88E use different LNA & VGA gain table */ ++ /* The RSSI formula should be modified according to the gain table */ ++ /* In 88E, cck_highpwr is always set to 1 */ ++ if (dm_odm->SupportICType & (ODM_RTL8188E | ODM_RTL8812)) { ++ LNA_idx = ((cck_agc_rpt & 0xE0) >> 5); ++ VGA_idx = (cck_agc_rpt & 0x1F); ++ switch (LNA_idx) { ++ case 7: ++ if (VGA_idx <= 27) ++ rx_pwr_all = -100 + 2 * (27 - VGA_idx); /* VGA_idx = 27~2 */ ++ else ++ rx_pwr_all = -100; ++ break; ++ case 6: ++ rx_pwr_all = -48 + 2 * (2 - VGA_idx); /* VGA_idx = 2~0 */ ++ break; ++ case 5: ++ rx_pwr_all = -42 + 2 * (7 - VGA_idx); /* VGA_idx = 7~5 */ ++ break; ++ case 4: ++ rx_pwr_all = -36 + 2 * (7 - VGA_idx); /* VGA_idx = 7~4 */ ++ break; ++ case 3: ++ rx_pwr_all = -24 + 2 * (7 - VGA_idx); /* VGA_idx = 7~0 */ ++ break; ++ case 2: ++ if (cck_highpwr) ++ rx_pwr_all = -12 + 2 * (5 - VGA_idx); /* VGA_idx = 5~0 */ ++ else ++ rx_pwr_all = -6 + 2 * (5 - VGA_idx); ++ break; ++ case 1: ++ rx_pwr_all = 8 - 2 * VGA_idx; ++ break; ++ case 0: ++ rx_pwr_all = 14 - 2 * VGA_idx; ++ break; ++ default: ++ break; ++ } ++ rx_pwr_all += 6; ++ PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); ++ if (!cck_highpwr) { ++ if (PWDB_ALL >= 80) ++ PWDB_ALL = ((PWDB_ALL - 80) << 1) + ((PWDB_ALL - 80) >> 1) + 80; ++ else if ((PWDB_ALL <= 78) && (PWDB_ALL >= 20)) ++ PWDB_ALL += 3; ++ if (PWDB_ALL > 100) ++ PWDB_ALL = 100; ++ } ++ } else { ++ if (!cck_highpwr) { ++ report = (cck_agc_rpt & 0xc0) >> 6; ++ switch (report) { ++ /* 03312009 modified by cosa */ ++ /* Modify the RF RNA gain value to -40, -20, -2, 14 by Jenyu's suggestion */ ++ /* Note: different RF with the different RNA gain. */ ++ case 0x3: ++ rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); ++ break; ++ case 0x2: ++ rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); ++ break; ++ case 0x1: ++ rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); ++ break; ++ case 0x0: ++ rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); ++ break; ++ } ++ } else { ++ report = (cck_agc_rpt & 0x60) >> 5; ++ switch (report) { ++ case 0x3: ++ rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); ++ break; ++ case 0x2: ++ rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); ++ break; ++ case 0x1: ++ rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); ++ break; ++ case 0x0: ++ rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); ++ break; ++ } ++ } ++ ++ PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); ++ ++ /* Modification for ext-LNA board */ ++ if (dm_odm->BoardType == ODM_BOARD_HIGHPWR) { ++ if ((cck_agc_rpt >> 7) == 0) { ++ PWDB_ALL = (PWDB_ALL > 94) ? 100 : (PWDB_ALL + 6); ++ } else { ++ if (PWDB_ALL > 38) ++ PWDB_ALL -= 16; ++ else ++ PWDB_ALL = (PWDB_ALL <= 16) ? (PWDB_ALL >> 2) : (PWDB_ALL - 12); ++ } ++ ++ /* CCK modification */ ++ if (PWDB_ALL > 25 && PWDB_ALL <= 60) ++ PWDB_ALL += 6; ++ } else {/* Modification for int-LNA board */ ++ if (PWDB_ALL > 99) ++ PWDB_ALL -= 8; ++ else if (PWDB_ALL > 50 && PWDB_ALL <= 68) ++ PWDB_ALL += 4; ++ } ++ } ++ ++ pPhyInfo->RxPWDBAll = PWDB_ALL; ++ pPhyInfo->BTRxRSSIPercentage = PWDB_ALL; ++ pPhyInfo->RecvSignalPower = rx_pwr_all; ++ /* (3) Get Signal Quality (EVM) */ ++ if (pPktinfo->bPacketMatchBSSID) { ++ u8 SQ, SQ_rpt; ++ ++ if ((dm_odm->SupportPlatform == ODM_MP) && (dm_odm->PatchID == 19)) { ++ SQ = odm_SQ_process_patch_RT_CID_819x_Lenovo(dm_odm, isCCKrate, PWDB_ALL, 0, 0); ++ } else if (pPhyInfo->RxPWDBAll > 40 && !dm_odm->bInHctTest) { ++ SQ = 100; ++ } else { ++ SQ_rpt = pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all; ++ ++ if (SQ_rpt > 64) ++ SQ = 0; ++ else if (SQ_rpt < 20) ++ SQ = 100; ++ else ++ SQ = ((64 - SQ_rpt) * 100) / 44; ++ } ++ pPhyInfo->SignalQuality = SQ; ++ pPhyInfo->RxMIMOSignalQuality[RF_PATH_A] = SQ; ++ pPhyInfo->RxMIMOSignalQuality[RF_PATH_B] = -1; ++ } ++ } else { /* is OFDM rate */ ++ dm_odm->PhyDbgInfo.NumQryPhyStatusOFDM++; ++ ++ /* (1)Get RSSI for HT rate */ ++ ++ for (i = RF_PATH_A; i < RF_PATH_MAX; i++) { ++ /* 2008/01/30 MH we will judge RF RX path now. */ ++ if (dm_odm->RFPathRxEnable & BIT(i)) ++ rf_rx_num++; ++ ++ rx_pwr[i] = ((pPhyStaRpt->path_agc[i].gain & 0x3F) * 2) - 110; ++ if (i == RF_PATH_A) ++ adapt->signal_strength = rx_pwr[i]; ++ ++ pPhyInfo->RxPwr[i] = rx_pwr[i]; ++ ++ /* Translate DBM to percentage. */ ++ RSSI = odm_QueryRxPwrPercentage(rx_pwr[i]); ++ total_rssi += RSSI; ++ ++ /* Modification for ext-LNA board */ ++ if (dm_odm->BoardType == ODM_BOARD_HIGHPWR) { ++ if ((pPhyStaRpt->path_agc[i].trsw) == 1) ++ RSSI = (RSSI > 94) ? 100 : (RSSI + 6); ++ else ++ RSSI = (RSSI <= 16) ? (RSSI >> 3) : (RSSI - 16); ++ ++ if ((RSSI <= 34) && (RSSI >= 4)) ++ RSSI -= 4; ++ } ++ ++ pPhyInfo->RxMIMOSignalStrength[i] = (u8)RSSI; ++ ++ /* Get Rx snr value in DB */ ++ pPhyInfo->RxSNR[i] = (s32)(pPhyStaRpt->path_rxsnr[i] / 2); ++ dm_odm->PhyDbgInfo.RxSNRdB[i] = (s32)(pPhyStaRpt->path_rxsnr[i] / 2); ++ ++ /* Record Signal Strength for next packet */ ++ if (pPktinfo->bPacketMatchBSSID) { ++ if ((dm_odm->SupportPlatform == ODM_MP) && (dm_odm->PatchID == 19)) { ++ if (i == RF_PATH_A) ++ pPhyInfo->SignalQuality = odm_SQ_process_patch_RT_CID_819x_Lenovo(dm_odm, isCCKrate, PWDB_ALL, i, RSSI); ++ } ++ } ++ } ++ /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */ ++ rx_pwr_all = (((pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all) >> 1) & 0x7f) - 110; ++ ++ PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); ++ PWDB_ALL_BT = PWDB_ALL; ++ ++ pPhyInfo->RxPWDBAll = PWDB_ALL; ++ pPhyInfo->BTRxRSSIPercentage = PWDB_ALL_BT; ++ pPhyInfo->RxPower = rx_pwr_all; ++ pPhyInfo->RecvSignalPower = rx_pwr_all; ++ ++ if ((dm_odm->SupportPlatform == ODM_MP) && (dm_odm->PatchID == 19)) { ++ /* do nothing */ ++ } else { ++ /* (3)EVM of HT rate */ ++ if (pPktinfo->Rate >= DESC92C_RATEMCS8 && pPktinfo->Rate <= DESC92C_RATEMCS15) ++ Max_spatial_stream = 2; /* both spatial stream make sense */ ++ else ++ Max_spatial_stream = 1; /* only spatial stream 1 makes sense */ ++ ++ for (i = 0; i < Max_spatial_stream; i++) { ++ /* Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment */ ++ /* fill most significant bit to "zero" when doing shifting operation which may change a negative */ ++ /* value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore. */ ++ EVM = odm_evm_db_to_percentage((pPhyStaRpt->stream_rxevm[i])); /* dbm */ ++ ++ if (pPktinfo->bPacketMatchBSSID) { ++ if (i == RF_PATH_A) /* Fill value in RFD, Get the first spatial stream only */ ++ pPhyInfo->SignalQuality = (u8)(EVM & 0xff); ++ pPhyInfo->RxMIMOSignalQuality[i] = (u8)(EVM & 0xff); ++ } ++ } ++ } ++ } ++ /* UI BSS List signal strength(in percentage), make it good looking, from 0~100. */ ++ /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */ ++ if (isCCKrate) { ++ pPhyInfo->SignalStrength = (u8)(odm_SignalScaleMapping(dm_odm, PWDB_ALL));/* PWDB_ALL; */ ++ } else { ++ if (rf_rx_num != 0) ++ pPhyInfo->SignalStrength = (u8)(odm_SignalScaleMapping(dm_odm, total_rssi /= rf_rx_num)); ++ } ++ ++ /* For 92C/92D HW (Hybrid) Antenna Diversity */ ++ pDM_SWAT_Table->antsel = pPhyStaRpt->ant_sel; ++ /* For 88E HW Antenna Diversity */ ++ dm_odm->DM_FatTable.antsel_rx_keep_0 = pPhyStaRpt->ant_sel; ++ dm_odm->DM_FatTable.antsel_rx_keep_1 = pPhyStaRpt->ant_sel_b; ++ dm_odm->DM_FatTable.antsel_rx_keep_2 = pPhyStaRpt->antsel_rx_keep_2; ++} ++ ++void odm_Init_RSSIForDM(struct odm_dm_struct *dm_odm) ++{ ++} ++ ++static void odm_Process_RSSIForDM(struct odm_dm_struct *dm_odm, ++ struct odm_phy_status_info *pPhyInfo, ++ struct odm_per_pkt_info *pPktinfo) ++{ ++ s32 UndecoratedSmoothedPWDB, UndecoratedSmoothedCCK; ++ s32 UndecoratedSmoothedOFDM, RSSI_Ave; ++ u8 isCCKrate = 0; ++ u8 RSSI_max, RSSI_min, i; ++ u32 OFDM_pkt = 0; ++ u32 Weighting = 0; ++ struct sta_info *pEntry; ++ ++ if (pPktinfo->StationID == 0xFF) ++ return; ++ pEntry = dm_odm->pODM_StaInfo[pPktinfo->StationID]; ++ if (!IS_STA_VALID(pEntry)) ++ return; ++ if ((!pPktinfo->bPacketMatchBSSID)) ++ return; ++ ++ isCCKrate = ((pPktinfo->Rate >= DESC92C_RATE1M) && (pPktinfo->Rate <= DESC92C_RATE11M)) ? true : false; ++ ++ /* Smart Antenna Debug Message------------------ */ ++ if (dm_odm->SupportICType == ODM_RTL8188E) { ++ u8 antsel_tr_mux; ++ struct fast_ant_train *pDM_FatTable = &dm_odm->DM_FatTable; ++ ++ if (dm_odm->AntDivType == CG_TRX_SMART_ANTDIV) { ++ if (pDM_FatTable->FAT_State == FAT_TRAINING_STATE) { ++ if (pPktinfo->bPacketToSelf) { ++ antsel_tr_mux = (pDM_FatTable->antsel_rx_keep_2 << 2) | ++ (pDM_FatTable->antsel_rx_keep_1 << 1) | ++ pDM_FatTable->antsel_rx_keep_0; ++ pDM_FatTable->antSumRSSI[antsel_tr_mux] += pPhyInfo->RxPWDBAll; ++ pDM_FatTable->antRSSIcnt[antsel_tr_mux]++; ++ } ++ } ++ } else if ((dm_odm->AntDivType == CG_TRX_HW_ANTDIV) || (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV)) { ++ if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) { ++ antsel_tr_mux = (pDM_FatTable->antsel_rx_keep_2 << 2) | ++ (pDM_FatTable->antsel_rx_keep_1 << 1) | pDM_FatTable->antsel_rx_keep_0; ++ ODM_AntselStatistics_88E(dm_odm, antsel_tr_mux, pPktinfo->StationID, pPhyInfo->RxPWDBAll); ++ } ++ } ++ } ++ /* Smart Antenna Debug Message------------------ */ ++ ++ UndecoratedSmoothedCCK = pEntry->rssi_stat.UndecoratedSmoothedCCK; ++ UndecoratedSmoothedOFDM = pEntry->rssi_stat.UndecoratedSmoothedOFDM; ++ UndecoratedSmoothedPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB; ++ ++ if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) { ++ if (!isCCKrate) { /* ofdm rate */ ++ if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_B] == 0) { ++ RSSI_Ave = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A]; ++ } else { ++ if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_A] > pPhyInfo->RxMIMOSignalStrength[RF_PATH_B]) { ++ RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A]; ++ RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B]; ++ } else { ++ RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B]; ++ RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A]; ++ } ++ if ((RSSI_max - RSSI_min) < 3) ++ RSSI_Ave = RSSI_max; ++ else if ((RSSI_max - RSSI_min) < 6) ++ RSSI_Ave = RSSI_max - 1; ++ else if ((RSSI_max - RSSI_min) < 10) ++ RSSI_Ave = RSSI_max - 2; ++ else ++ RSSI_Ave = RSSI_max - 3; ++ } ++ ++ /* 1 Process OFDM RSSI */ ++ if (UndecoratedSmoothedOFDM <= 0) { /* initialize */ ++ UndecoratedSmoothedOFDM = pPhyInfo->RxPWDBAll; ++ } else { ++ if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedOFDM) { ++ UndecoratedSmoothedOFDM = ++ (((UndecoratedSmoothedOFDM) * (Rx_Smooth_Factor - 1)) + ++ (RSSI_Ave)) / (Rx_Smooth_Factor); ++ UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM + 1; ++ } else { ++ UndecoratedSmoothedOFDM = ++ (((UndecoratedSmoothedOFDM) * (Rx_Smooth_Factor - 1)) + ++ (RSSI_Ave)) / (Rx_Smooth_Factor); ++ } ++ } ++ ++ pEntry->rssi_stat.PacketMap = (pEntry->rssi_stat.PacketMap << 1) | BIT(0); ++ ++ } else { ++ RSSI_Ave = pPhyInfo->RxPWDBAll; ++ ++ /* 1 Process CCK RSSI */ ++ if (UndecoratedSmoothedCCK <= 0) { /* initialize */ ++ UndecoratedSmoothedCCK = pPhyInfo->RxPWDBAll; ++ } else { ++ if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedCCK) { ++ UndecoratedSmoothedCCK = ++ ((UndecoratedSmoothedCCK * (Rx_Smooth_Factor - 1)) + ++ pPhyInfo->RxPWDBAll) / Rx_Smooth_Factor; ++ UndecoratedSmoothedCCK = UndecoratedSmoothedCCK + 1; ++ } else { ++ UndecoratedSmoothedCCK = ++ ((UndecoratedSmoothedCCK * (Rx_Smooth_Factor - 1)) + ++ pPhyInfo->RxPWDBAll) / Rx_Smooth_Factor; ++ } ++ } ++ pEntry->rssi_stat.PacketMap = pEntry->rssi_stat.PacketMap << 1; ++ } ++ /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */ ++ if (pEntry->rssi_stat.ValidBit >= 64) ++ pEntry->rssi_stat.ValidBit = 64; ++ else ++ pEntry->rssi_stat.ValidBit++; ++ ++ for (i = 0; i < pEntry->rssi_stat.ValidBit; i++) ++ OFDM_pkt += (u8)(pEntry->rssi_stat.PacketMap >> i) & BIT(0); ++ ++ if (pEntry->rssi_stat.ValidBit == 64) { ++ Weighting = ((OFDM_pkt << 4) > 64) ? 64 : (OFDM_pkt << 4); ++ UndecoratedSmoothedPWDB = (Weighting * UndecoratedSmoothedOFDM + (64 - Weighting) * UndecoratedSmoothedCCK) >> 6; ++ } else { ++ if (pEntry->rssi_stat.ValidBit != 0) ++ UndecoratedSmoothedPWDB = (OFDM_pkt * UndecoratedSmoothedOFDM + ++ (pEntry->rssi_stat.ValidBit - OFDM_pkt) * ++ UndecoratedSmoothedCCK) / pEntry->rssi_stat.ValidBit; ++ else ++ UndecoratedSmoothedPWDB = 0; ++ } ++ pEntry->rssi_stat.UndecoratedSmoothedCCK = UndecoratedSmoothedCCK; ++ pEntry->rssi_stat.UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM; ++ pEntry->rssi_stat.UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB; ++ } ++} ++ ++/* Endianness before calling this API */ ++static void ODM_PhyStatusQuery_92CSeries(struct odm_dm_struct *dm_odm, ++ struct odm_phy_status_info *pPhyInfo, ++ u8 *pPhyStatus, ++ struct odm_per_pkt_info *pPktinfo, ++ struct adapter *adapt) ++{ ++ odm_RxPhyStatus92CSeries_Parsing(dm_odm, pPhyInfo, pPhyStatus, ++ pPktinfo, adapt); ++ if (dm_odm->RSSI_test) { ++ /* Select the packets to do RSSI checking for antenna switching. */ ++ if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) ++ ODM_SwAntDivChkPerPktRssi(dm_odm, pPktinfo->StationID, pPhyInfo); ++ } else { ++ odm_Process_RSSIForDM(dm_odm, pPhyInfo, pPktinfo); ++ } ++} ++ ++void ODM_PhyStatusQuery(struct odm_dm_struct *dm_odm, ++ struct odm_phy_status_info *pPhyInfo, ++ u8 *pPhyStatus, struct odm_per_pkt_info *pPktinfo, ++ struct adapter *adapt) ++{ ++ ODM_PhyStatusQuery_92CSeries(dm_odm, pPhyInfo, pPhyStatus, pPktinfo, adapt); ++} ++ ++/* For future use. */ ++void ODM_MacStatusQuery(struct odm_dm_struct *dm_odm, u8 *mac_stat, ++ u8 macid, bool pkt_match_bssid, ++ bool pkttoself, bool pkt_beacon) ++{ ++ /* 2011/10/19 Driver team will handle in the future. */ ++} ++ ++enum HAL_STATUS ODM_ConfigRFWithHeaderFile(struct odm_dm_struct *dm_odm, ++ enum rf_radio_path content, ++ enum rf_radio_path rfpath) ++{ ++ if (dm_odm->SupportICType == ODM_RTL8188E) { ++ if (rfpath == RF_PATH_A) ++ READ_AND_CONFIG(8188E, _RadioA_1T_); ++ } ++ ++ return HAL_STATUS_SUCCESS; ++} ++ ++enum HAL_STATUS ODM_ConfigBBWithHeaderFile(struct odm_dm_struct *dm_odm, ++ enum odm_bb_config_type config_tp) ++{ ++ if (dm_odm->SupportICType == ODM_RTL8188E) { ++ if (config_tp == CONFIG_BB_PHY_REG) { ++ READ_AND_CONFIG(8188E, _PHY_REG_1T_); ++ } else if (config_tp == CONFIG_BB_AGC_TAB) { ++ READ_AND_CONFIG(8188E, _AGC_TAB_1T_); ++ } else if (config_tp == CONFIG_BB_PHY_REG_PG) { ++ READ_AND_CONFIG(8188E, _PHY_REG_PG_); ++ } ++ } ++ return HAL_STATUS_SUCCESS; ++} ++ ++enum HAL_STATUS ODM_ConfigMACWithHeaderFile(struct odm_dm_struct *dm_odm) ++{ ++ u8 result = HAL_STATUS_SUCCESS; ++ if (dm_odm->SupportICType == ODM_RTL8188E) ++ result = READ_AND_CONFIG(8188E, _MAC_REG_); ++ return result; ++} +diff --git a/drivers/staging/r8188eu/hal/odm_RTL8188E.c b/drivers/staging/r8188eu/hal/odm_RTL8188E.c +new file mode 100644 +index 000000000000..c64a291f9966 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/odm_RTL8188E.c +@@ -0,0 +1,337 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++ ++void ODM_DIG_LowerBound_88E(struct odm_dm_struct *dm_odm) ++{ ++ struct rtw_dig *pDM_DigTable = &dm_odm->DM_DigTable; ++ ++ if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ++ pDM_DigTable->rx_gain_range_min = (u8)pDM_DigTable->AntDiv_RSSI_max; ++ /* If only one Entry connected */ ++} ++ ++static void odm_RX_HWAntDivInit(struct odm_dm_struct *dm_odm) ++{ ++ u32 value32; ++ ++ if (*dm_odm->mp_mode == 1) { ++ dm_odm->AntDivType = CGCS_RX_SW_ANTDIV; ++ ODM_SetBBReg(dm_odm, ODM_REG_IGI_A_11N, BIT(7), 0); /* disable HW AntDiv */ ++ ODM_SetBBReg(dm_odm, ODM_REG_LNA_SWITCH_11N, BIT(31), 1); /* 1:CG, 0:CS */ ++ return; ++ } ++ ++ /* MAC Setting */ ++ value32 = ODM_GetMACReg(dm_odm, ODM_REG_ANTSEL_PIN_11N, bMaskDWord); ++ ODM_SetMACReg(dm_odm, ODM_REG_ANTSEL_PIN_11N, bMaskDWord, value32 | (BIT(23) | BIT(25))); /* Reg4C[25]=1, Reg4C[23]=1 for pin output */ ++ /* Pin Settings */ ++ ODM_SetBBReg(dm_odm, ODM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);/* Reg870[8]=1'b0, Reg870[9]=1'b0 antsel antselb by HW */ ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(10), 0); /* Reg864[10]=1'b0 antsel2 by HW */ ++ ODM_SetBBReg(dm_odm, ODM_REG_LNA_SWITCH_11N, BIT(22), 1); /* Regb2c[22]=1'b0 disable CS/CG switch */ ++ ODM_SetBBReg(dm_odm, ODM_REG_LNA_SWITCH_11N, BIT(31), 1); /* Regb2c[31]=1'b1 output at CG only */ ++ /* OFDM Settings */ ++ ODM_SetBBReg(dm_odm, ODM_REG_ANTDIV_PARA1_11N, bMaskDWord, 0x000000a0); ++ /* CCK Settings */ ++ ODM_SetBBReg(dm_odm, ODM_REG_BB_PWR_SAV4_11N, BIT(7), 1); /* Fix CCK PHY status report issue */ ++ ODM_SetBBReg(dm_odm, ODM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1); /* CCK complete HW AntDiv within 64 samples */ ++ ODM_UpdateRxIdleAnt_88E(dm_odm, MAIN_ANT); ++ ODM_SetBBReg(dm_odm, ODM_REG_ANT_MAPPING1_11N, 0xFFFF, 0x0201); /* antenna mapping table */ ++} ++ ++static void odm_TRX_HWAntDivInit(struct odm_dm_struct *dm_odm) ++{ ++ u32 value32; ++ ++ if (*dm_odm->mp_mode == 1) { ++ dm_odm->AntDivType = CGCS_RX_SW_ANTDIV; ++ ODM_SetBBReg(dm_odm, ODM_REG_IGI_A_11N, BIT(7), 0); /* disable HW AntDiv */ ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(5) | BIT(4) | BIT(3), 0); /* Default RX (0/1) */ ++ return; ++ } ++ ++ /* MAC Setting */ ++ value32 = ODM_GetMACReg(dm_odm, ODM_REG_ANTSEL_PIN_11N, bMaskDWord); ++ ODM_SetMACReg(dm_odm, ODM_REG_ANTSEL_PIN_11N, bMaskDWord, value32 | (BIT(23) | BIT(25))); /* Reg4C[25]=1, Reg4C[23]=1 for pin output */ ++ /* Pin Settings */ ++ ODM_SetBBReg(dm_odm, ODM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);/* Reg870[8]=1'b0, Reg870[9]=1'b0 antsel antselb by HW */ ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(10), 0); /* Reg864[10]=1'b0 antsel2 by HW */ ++ ODM_SetBBReg(dm_odm, ODM_REG_LNA_SWITCH_11N, BIT(22), 0); /* Regb2c[22]=1'b0 disable CS/CG switch */ ++ ODM_SetBBReg(dm_odm, ODM_REG_LNA_SWITCH_11N, BIT(31), 1); /* Regb2c[31]=1'b1 output at CG only */ ++ /* OFDM Settings */ ++ ODM_SetBBReg(dm_odm, ODM_REG_ANTDIV_PARA1_11N, bMaskDWord, 0x000000a0); ++ /* CCK Settings */ ++ ODM_SetBBReg(dm_odm, ODM_REG_BB_PWR_SAV4_11N, BIT(7), 1); /* Fix CCK PHY status report issue */ ++ ODM_SetBBReg(dm_odm, ODM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1); /* CCK complete HW AntDiv within 64 samples */ ++ /* Tx Settings */ ++ ODM_SetBBReg(dm_odm, ODM_REG_TX_ANT_CTRL_11N, BIT(21), 0); /* Reg80c[21]=1'b0 from TX Reg */ ++ ODM_UpdateRxIdleAnt_88E(dm_odm, MAIN_ANT); ++ ++ /* antenna mapping table */ ++ if (!dm_odm->bIsMPChip) { /* testchip */ ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_DEFUALT_A_11N, BIT(10) | BIT(9) | BIT(8), 1); /* Reg858[10:8]=3'b001 */ ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_DEFUALT_A_11N, BIT(13) | BIT(12) | BIT(11), 2); /* Reg858[13:11]=3'b010 */ ++ } else { /* MPchip */ ++ ODM_SetBBReg(dm_odm, ODM_REG_ANT_MAPPING1_11N, bMaskDWord, 0x0201); /* Reg914=3'b010, Reg915=3'b001 */ ++ } ++} ++ ++static void odm_FastAntTrainingInit(struct odm_dm_struct *dm_odm) ++{ ++ u32 value32, i; ++ struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable; ++ u32 AntCombination = 2; ++ ++ if (*dm_odm->mp_mode == 1) ++ return; ++ ++ for (i = 0; i < 6; i++) { ++ dm_fat_tbl->Bssid[i] = 0; ++ dm_fat_tbl->antSumRSSI[i] = 0; ++ dm_fat_tbl->antRSSIcnt[i] = 0; ++ dm_fat_tbl->antAveRSSI[i] = 0; ++ } ++ dm_fat_tbl->TrainIdx = 0; ++ dm_fat_tbl->FAT_State = FAT_NORMAL_STATE; ++ ++ /* MAC Setting */ ++ value32 = ODM_GetMACReg(dm_odm, 0x4c, bMaskDWord); ++ ODM_SetMACReg(dm_odm, 0x4c, bMaskDWord, value32 | (BIT(23) | BIT(25))); /* Reg4C[25]=1, Reg4C[23]=1 for pin output */ ++ value32 = ODM_GetMACReg(dm_odm, 0x7B4, bMaskDWord); ++ ODM_SetMACReg(dm_odm, 0x7b4, bMaskDWord, value32 | (BIT(16) | BIT(17))); /* Reg7B4[16]=1 enable antenna training, Reg7B4[17]=1 enable A2 match */ ++ ++ /* Match MAC ADDR */ ++ ODM_SetMACReg(dm_odm, 0x7b4, 0xFFFF, 0); ++ ODM_SetMACReg(dm_odm, 0x7b0, bMaskDWord, 0); ++ ++ ODM_SetBBReg(dm_odm, 0x870, BIT(9) | BIT(8), 0);/* Reg870[8]=1'b0, Reg870[9]=1'b0 antsel antselb by HW */ ++ ODM_SetBBReg(dm_odm, 0x864, BIT(10), 0); /* Reg864[10]=1'b0 antsel2 by HW */ ++ ODM_SetBBReg(dm_odm, 0xb2c, BIT(22), 0); /* Regb2c[22]=1'b0 disable CS/CG switch */ ++ ODM_SetBBReg(dm_odm, 0xb2c, BIT(31), 1); /* Regb2c[31]=1'b1 output at CG only */ ++ ODM_SetBBReg(dm_odm, 0xca4, bMaskDWord, 0x000000a0); ++ ++ /* antenna mapping table */ ++ if (AntCombination == 2) { ++ if (!dm_odm->bIsMPChip) { /* testchip */ ++ ODM_SetBBReg(dm_odm, 0x858, BIT(10) | BIT(9) | BIT(8), 1); /* Reg858[10:8]=3'b001 */ ++ ODM_SetBBReg(dm_odm, 0x858, BIT(13) | BIT(12) | BIT(11), 2); /* Reg858[13:11]=3'b010 */ ++ } else { /* MPchip */ ++ ODM_SetBBReg(dm_odm, 0x914, bMaskByte0, 1); ++ ODM_SetBBReg(dm_odm, 0x914, bMaskByte1, 2); ++ } ++ } else if (AntCombination == 7) { ++ if (!dm_odm->bIsMPChip) { /* testchip */ ++ ODM_SetBBReg(dm_odm, 0x858, BIT(10) | BIT(9) | BIT(8), 0); /* Reg858[10:8]=3'b000 */ ++ ODM_SetBBReg(dm_odm, 0x858, BIT(13) | BIT(12) | BIT(11), 1); /* Reg858[13:11]=3'b001 */ ++ ODM_SetBBReg(dm_odm, 0x878, BIT(16), 0); ++ ODM_SetBBReg(dm_odm, 0x858, BIT(15) | BIT(14), 2); /* Reg878[0],Reg858[14:15])=3'b010 */ ++ ODM_SetBBReg(dm_odm, 0x878, BIT(19) | BIT(18) | BIT(17), 3);/* Reg878[3:1]=3b'011 */ ++ ODM_SetBBReg(dm_odm, 0x878, BIT(22) | BIT(21) | BIT(20), 4);/* Reg878[6:4]=3b'100 */ ++ ODM_SetBBReg(dm_odm, 0x878, BIT(25) | BIT(24) | BIT(23), 5);/* Reg878[9:7]=3b'101 */ ++ ODM_SetBBReg(dm_odm, 0x878, BIT(28) | BIT(27) | BIT(26), 6);/* Reg878[12:10]=3b'110 */ ++ ODM_SetBBReg(dm_odm, 0x878, BIT(31) | BIT(30) | BIT(29), 7);/* Reg878[15:13]=3b'111 */ ++ } else { /* MPchip */ ++ ODM_SetBBReg(dm_odm, 0x914, bMaskByte0, 0); ++ ODM_SetBBReg(dm_odm, 0x914, bMaskByte1, 1); ++ ODM_SetBBReg(dm_odm, 0x914, bMaskByte2, 2); ++ ODM_SetBBReg(dm_odm, 0x914, bMaskByte3, 3); ++ ODM_SetBBReg(dm_odm, 0x918, bMaskByte0, 4); ++ ODM_SetBBReg(dm_odm, 0x918, bMaskByte1, 5); ++ ODM_SetBBReg(dm_odm, 0x918, bMaskByte2, 6); ++ ODM_SetBBReg(dm_odm, 0x918, bMaskByte3, 7); ++ } ++ } ++ ++ /* Default Ant Setting when no fast training */ ++ ODM_SetBBReg(dm_odm, 0x80c, BIT(21), 1); /* Reg80c[21]=1'b1 from TX Info */ ++ ODM_SetBBReg(dm_odm, 0x864, BIT(5) | BIT(4) | BIT(3), 0); /* Default RX */ ++ ODM_SetBBReg(dm_odm, 0x864, BIT(8) | BIT(7) | BIT(6), 1); /* Optional RX */ ++ ++ /* Enter Traing state */ ++ ODM_SetBBReg(dm_odm, 0x864, BIT(2) | BIT(1) | BIT(0), (AntCombination - 1)); /* Reg864[2:0]=3'd6 ant combination=reg864[2:0]+1 */ ++ ODM_SetBBReg(dm_odm, 0xc50, BIT(7), 1); /* RegC50[7]=1'b1 enable HW AntDiv */ ++} ++ ++void ODM_AntennaDiversityInit_88E(struct odm_dm_struct *dm_odm) ++{ ++ if (dm_odm->SupportICType != ODM_RTL8188E) ++ return; ++ ++ if (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV) ++ odm_RX_HWAntDivInit(dm_odm); ++ else if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ++ odm_TRX_HWAntDivInit(dm_odm); ++ else if (dm_odm->AntDivType == CG_TRX_SMART_ANTDIV) ++ odm_FastAntTrainingInit(dm_odm); ++} ++ ++void ODM_UpdateRxIdleAnt_88E(struct odm_dm_struct *dm_odm, u8 Ant) ++{ ++ struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable; ++ u32 DefaultAnt, OptionalAnt; ++ ++ if (dm_fat_tbl->RxIdleAnt != Ant) { ++ if (Ant == MAIN_ANT) { ++ DefaultAnt = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ? MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX; ++ OptionalAnt = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ? AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX; ++ } else { ++ DefaultAnt = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ? AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX; ++ OptionalAnt = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ? MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX; ++ } ++ ++ if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) { ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(5) | BIT(4) | BIT(3), DefaultAnt); /* Default RX */ ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(8) | BIT(7) | BIT(6), OptionalAnt); /* Optional RX */ ++ ODM_SetBBReg(dm_odm, ODM_REG_ANTSEL_CTRL_11N, BIT(14) | BIT(13) | BIT(12), DefaultAnt); /* Default TX */ ++ ODM_SetMACReg(dm_odm, ODM_REG_RESP_TX_11N, BIT(6) | BIT(7), DefaultAnt); /* Resp Tx */ ++ } else if (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV) { ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(5) | BIT(4) | BIT(3), DefaultAnt); /* Default RX */ ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(8) | BIT(7) | BIT(6), OptionalAnt); /* Optional RX */ ++ } ++ } ++ dm_fat_tbl->RxIdleAnt = Ant; ++ if (Ant != MAIN_ANT) ++ pr_info("RxIdleAnt=AUX_ANT\n"); ++} ++ ++static void odm_UpdateTxAnt_88E(struct odm_dm_struct *dm_odm, u8 Ant, u32 MacId) ++{ ++ struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable; ++ u8 TargetAnt; ++ ++ if (Ant == MAIN_ANT) ++ TargetAnt = MAIN_ANT_CG_TRX; ++ else ++ TargetAnt = AUX_ANT_CG_TRX; ++ dm_fat_tbl->antsel_a[MacId] = TargetAnt & BIT(0); ++ dm_fat_tbl->antsel_b[MacId] = (TargetAnt & BIT(1)) >> 1; ++ dm_fat_tbl->antsel_c[MacId] = (TargetAnt & BIT(2)) >> 2; ++} ++ ++void ODM_SetTxAntByTxInfo_88E(struct odm_dm_struct *dm_odm, u8 *pDesc, u8 macId) ++{ ++ struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable; ++ ++ if ((dm_odm->AntDivType == CG_TRX_HW_ANTDIV) || (dm_odm->AntDivType == CG_TRX_SMART_ANTDIV)) { ++ SET_TX_DESC_ANTSEL_A_88E(pDesc, dm_fat_tbl->antsel_a[macId]); ++ SET_TX_DESC_ANTSEL_B_88E(pDesc, dm_fat_tbl->antsel_b[macId]); ++ SET_TX_DESC_ANTSEL_C_88E(pDesc, dm_fat_tbl->antsel_c[macId]); ++ } ++} ++ ++void ODM_AntselStatistics_88E(struct odm_dm_struct *dm_odm, u8 antsel_tr_mux, u32 MacId, u8 RxPWDBAll) ++{ ++ struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable; ++ if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) { ++ if (antsel_tr_mux == MAIN_ANT_CG_TRX) { ++ dm_fat_tbl->MainAnt_Sum[MacId] += RxPWDBAll; ++ dm_fat_tbl->MainAnt_Cnt[MacId]++; ++ } else { ++ dm_fat_tbl->AuxAnt_Sum[MacId] += RxPWDBAll; ++ dm_fat_tbl->AuxAnt_Cnt[MacId]++; ++ } ++ } else if (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV) { ++ if (antsel_tr_mux == MAIN_ANT_CGCS_RX) { ++ dm_fat_tbl->MainAnt_Sum[MacId] += RxPWDBAll; ++ dm_fat_tbl->MainAnt_Cnt[MacId]++; ++ } else { ++ dm_fat_tbl->AuxAnt_Sum[MacId] += RxPWDBAll; ++ dm_fat_tbl->AuxAnt_Cnt[MacId]++; ++ } ++ } ++} ++ ++static void odm_HWAntDiv(struct odm_dm_struct *dm_odm) ++{ ++ u32 i, MinRSSI = 0xFF, AntDivMaxRSSI = 0, MaxRSSI = 0, LocalMinRSSI, LocalMaxRSSI; ++ u32 Main_RSSI, Aux_RSSI; ++ u8 RxIdleAnt = 0, TargetAnt = 7; ++ struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable; ++ struct rtw_dig *pDM_DigTable = &dm_odm->DM_DigTable; ++ struct sta_info *pEntry; ++ ++ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { ++ pEntry = dm_odm->pODM_StaInfo[i]; ++ if (IS_STA_VALID(pEntry)) { ++ /* 2 Caculate RSSI per Antenna */ ++ Main_RSSI = (dm_fat_tbl->MainAnt_Cnt[i] != 0) ? (dm_fat_tbl->MainAnt_Sum[i] / dm_fat_tbl->MainAnt_Cnt[i]) : 0; ++ Aux_RSSI = (dm_fat_tbl->AuxAnt_Cnt[i] != 0) ? (dm_fat_tbl->AuxAnt_Sum[i] / dm_fat_tbl->AuxAnt_Cnt[i]) : 0; ++ TargetAnt = (Main_RSSI >= Aux_RSSI) ? MAIN_ANT : AUX_ANT; ++ /* 2 Select MaxRSSI for DIG */ ++ LocalMaxRSSI = (Main_RSSI > Aux_RSSI) ? Main_RSSI : Aux_RSSI; ++ if ((LocalMaxRSSI > AntDivMaxRSSI) && (LocalMaxRSSI < 40)) ++ AntDivMaxRSSI = LocalMaxRSSI; ++ if (LocalMaxRSSI > MaxRSSI) ++ MaxRSSI = LocalMaxRSSI; ++ ++ /* 2 Select RX Idle Antenna */ ++ if ((dm_fat_tbl->RxIdleAnt == MAIN_ANT) && (Main_RSSI == 0)) ++ Main_RSSI = Aux_RSSI; ++ else if ((dm_fat_tbl->RxIdleAnt == AUX_ANT) && (Aux_RSSI == 0)) ++ Aux_RSSI = Main_RSSI; ++ ++ LocalMinRSSI = (Main_RSSI > Aux_RSSI) ? Aux_RSSI : Main_RSSI; ++ if (LocalMinRSSI < MinRSSI) { ++ MinRSSI = LocalMinRSSI; ++ RxIdleAnt = TargetAnt; ++ } ++ /* 2 Select TRX Antenna */ ++ if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ++ odm_UpdateTxAnt_88E(dm_odm, TargetAnt, i); ++ } ++ dm_fat_tbl->MainAnt_Sum[i] = 0; ++ dm_fat_tbl->AuxAnt_Sum[i] = 0; ++ dm_fat_tbl->MainAnt_Cnt[i] = 0; ++ dm_fat_tbl->AuxAnt_Cnt[i] = 0; ++ } ++ ++ /* 2 Set RX Idle Antenna */ ++ ODM_UpdateRxIdleAnt_88E(dm_odm, RxIdleAnt); ++ ++ pDM_DigTable->AntDiv_RSSI_max = AntDivMaxRSSI; ++ pDM_DigTable->RSSI_max = MaxRSSI; ++} ++ ++void ODM_AntennaDiversity_88E(struct odm_dm_struct *dm_odm) ++{ ++ struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable; ++ if ((dm_odm->SupportICType != ODM_RTL8188E) || (!(dm_odm->SupportAbility & ODM_BB_ANT_DIV))) ++ return; ++ if (!dm_odm->bLinked) { ++ if (dm_fat_tbl->bBecomeLinked) { ++ ODM_SetBBReg(dm_odm, ODM_REG_IGI_A_11N, BIT(7), 0); /* RegC50[7]=1'b1 enable HW AntDiv */ ++ ODM_SetBBReg(dm_odm, ODM_REG_CCK_ANTDIV_PARA1_11N, BIT(15), 0); /* Enable CCK AntDiv */ ++ if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ++ ODM_SetBBReg(dm_odm, ODM_REG_TX_ANT_CTRL_11N, BIT(21), 0); /* Reg80c[21]=1'b0 from TX Reg */ ++ dm_fat_tbl->bBecomeLinked = dm_odm->bLinked; ++ } ++ return; ++ } else { ++ if (!dm_fat_tbl->bBecomeLinked) { ++ /* Because HW AntDiv is disabled before Link, we enable HW AntDiv after link */ ++ ODM_SetBBReg(dm_odm, ODM_REG_IGI_A_11N, BIT(7), 1); /* RegC50[7]=1'b1 enable HW AntDiv */ ++ ODM_SetBBReg(dm_odm, ODM_REG_CCK_ANTDIV_PARA1_11N, BIT(15), 1); /* Enable CCK AntDiv */ ++ if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ++ ODM_SetBBReg(dm_odm, ODM_REG_TX_ANT_CTRL_11N, BIT(21), 1); /* Reg80c[21]=1'b1 from TX Info */ ++ dm_fat_tbl->bBecomeLinked = dm_odm->bLinked; ++ } ++ } ++ if ((dm_odm->AntDivType == CG_TRX_HW_ANTDIV) || (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV)) ++ odm_HWAntDiv(dm_odm); ++} ++ ++/* 3============================================================ */ ++/* 3 Dynamic Primary CCA */ ++/* 3============================================================ */ ++ ++void odm_PrimaryCCA_Init(struct odm_dm_struct *dm_odm) ++{ ++ struct dyn_primary_cca *PrimaryCCA = &dm_odm->DM_PriCCA; ++ ++ PrimaryCCA->dup_rts_flag = 0; ++ PrimaryCCA->intf_flag = 0; ++ PrimaryCCA->intf_type = 0; ++ PrimaryCCA->monitor_flag = 0; ++ PrimaryCCA->pri_cca_flag = 0; ++} +diff --git a/drivers/staging/r8188eu/hal/odm_RegConfig8188E.c b/drivers/staging/r8188eu/hal/odm_RegConfig8188E.c +new file mode 100644 +index 000000000000..1bc3b49cd67f +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/odm_RegConfig8188E.c +@@ -0,0 +1,98 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++ ++void odm_ConfigRFReg_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, ++ u32 Data, enum rf_radio_path RF_PATH, ++ u32 RegAddr) ++{ ++ if (Addr == 0xffe) { ++ ODM_sleep_ms(50); ++ } else if (Addr == 0xfd) { ++ ODM_delay_ms(5); ++ } else if (Addr == 0xfc) { ++ ODM_delay_ms(1); ++ } else if (Addr == 0xfb) { ++ ODM_delay_us(50); ++ } else if (Addr == 0xfa) { ++ ODM_delay_us(5); ++ } else if (Addr == 0xf9) { ++ ODM_delay_us(1); ++ } else { ++ ODM_SetRFReg(pDM_Odm, RF_PATH, RegAddr, bRFRegOffsetMask, Data); ++ /* Add 1us delay between BB/RF register setting. */ ++ ODM_delay_us(1); ++ } ++} ++ ++void odm_ConfigRF_RadioA_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Data) ++{ ++ u32 content = 0x1000; /* RF_Content: radioa_txt */ ++ u32 maskforPhySet = (u32)(content & 0xE000); ++ ++ odm_ConfigRFReg_8188E(pDM_Odm, Addr, Data, RF_PATH_A, Addr | maskforPhySet); ++} ++ ++void odm_ConfigRF_RadioB_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Data) ++{ ++ u32 content = 0x1001; /* RF_Content: radiob_txt */ ++ u32 maskforPhySet = (u32)(content & 0xE000); ++ ++ odm_ConfigRFReg_8188E(pDM_Odm, Addr, Data, RF_PATH_B, Addr | maskforPhySet); ++} ++ ++void odm_ConfigMAC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u8 Data) ++{ ++ ODM_Write1Byte(pDM_Odm, Addr, Data); ++} ++ ++void odm_ConfigBB_AGC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data) ++{ ++ ODM_SetBBReg(pDM_Odm, Addr, Bitmask, Data); ++ /* Add 1us delay between BB/RF register setting. */ ++ ODM_delay_us(1); ++} ++ ++void odm_ConfigBB_PHY_REG_PG_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, ++ u32 Bitmask, u32 Data) ++{ ++ if (Addr == 0xfe) ++ ODM_sleep_ms(50); ++ else if (Addr == 0xfd) ++ ODM_delay_ms(5); ++ else if (Addr == 0xfc) ++ ODM_delay_ms(1); ++ else if (Addr == 0xfb) ++ ODM_delay_us(50); ++ else if (Addr == 0xfa) ++ ODM_delay_us(5); ++ else if (Addr == 0xf9) ++ ODM_delay_us(1); ++ else ++ storePwrIndexDiffRateOffset(pDM_Odm->Adapter, Addr, Bitmask, Data); ++} ++ ++void odm_ConfigBB_PHY_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data) ++{ ++ if (Addr == 0xfe) { ++ ODM_sleep_ms(50); ++ } else if (Addr == 0xfd) { ++ ODM_delay_ms(5); ++ } else if (Addr == 0xfc) { ++ ODM_delay_ms(1); ++ } else if (Addr == 0xfb) { ++ ODM_delay_us(50); ++ } else if (Addr == 0xfa) { ++ ODM_delay_us(5); ++ } else if (Addr == 0xf9) { ++ ODM_delay_us(1); ++ } else { ++ if (Addr == 0xa24) ++ pDM_Odm->RFCalibrateInfo.RegA24 = Data; ++ ODM_SetBBReg(pDM_Odm, Addr, Bitmask, Data); ++ ++ /* Add 1us delay between BB/RF register setting. */ ++ ODM_delay_us(1); ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/odm_debug.c b/drivers/staging/r8188eu/hal/odm_debug.c +new file mode 100644 +index 000000000000..7029ec4f771e +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/odm_debug.c +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++ ++u32 GlobalDebugLevel; +diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c +new file mode 100644 +index 000000000000..5a01495d74bc +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/odm_interface.c +@@ -0,0 +1,178 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++/* ODM IO Relative API. */ ++ ++u8 ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ return rtw_read8(Adapter, RegAddr); ++} ++ ++u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ return rtw_read16(Adapter, RegAddr); ++} ++ ++u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ return rtw_read32(Adapter, RegAddr); ++} ++ ++void ODM_Write1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 Data) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ rtw_write8(Adapter, RegAddr, Data); ++} ++ ++void ODM_Write2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 Data) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ rtw_write16(Adapter, RegAddr, Data); ++} ++ ++void ODM_Write4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 Data) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ rtw_write32(Adapter, RegAddr, Data); ++} ++ ++void ODM_SetMACReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 BitMask, u32 Data) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ PHY_SetBBReg(Adapter, RegAddr, BitMask, Data); ++} ++ ++u32 ODM_GetMACReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 BitMask) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ return PHY_QueryBBReg(Adapter, RegAddr, BitMask); ++} ++ ++void ODM_SetBBReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 BitMask, u32 Data) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ PHY_SetBBReg(Adapter, RegAddr, BitMask, Data); ++} ++ ++u32 ODM_GetBBReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 BitMask) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ return PHY_QueryBBReg(Adapter, RegAddr, BitMask); ++} ++ ++void ODM_SetRFReg(struct odm_dm_struct *pDM_Odm, enum rf_radio_path eRFPath, u32 RegAddr, u32 BitMask, u32 Data) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ PHY_SetRFReg(Adapter, (enum rf_radio_path)eRFPath, RegAddr, BitMask, Data); ++} ++ ++u32 ODM_GetRFReg(struct odm_dm_struct *pDM_Odm, enum rf_radio_path eRFPath, u32 RegAddr, u32 BitMask) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ return PHY_QueryRFReg(Adapter, (enum rf_radio_path)eRFPath, RegAddr, BitMask); ++} ++ ++/* ODM Memory relative API. */ ++void ODM_AllocateMemory(struct odm_dm_struct *pDM_Odm, void **pPtr, u32 length) ++{ ++ *pPtr = vzalloc(length); ++} ++ ++/* length could be ignored, used to detect memory leakage. */ ++void ODM_FreeMemory(struct odm_dm_struct *pDM_Odm, void *pPtr, u32 length) ++{ ++ vfree(pPtr); ++} ++ ++s32 ODM_CompareMemory(struct odm_dm_struct *pDM_Odm, void *pBuf1, void *pBuf2, u32 length) ++{ ++ return !memcmp(pBuf1, pBuf2, length); ++} ++ ++/* ODM MISC relative API. */ ++void ODM_AcquireSpinLock(struct odm_dm_struct *pDM_Odm, enum RT_SPINLOCK_TYPE type) ++{ ++} ++ ++void ODM_ReleaseSpinLock(struct odm_dm_struct *pDM_Odm, enum RT_SPINLOCK_TYPE type) ++{ ++} ++ ++/* Work item relative API. FOr MP driver only~! */ ++void ODM_InitializeWorkItem(struct odm_dm_struct *pDM_Odm, void *pRtWorkItem, ++ RT_WORKITEM_CALL_BACK RtWorkItemCallback, ++ void *pContext, const char *szID) ++{ ++} ++ ++void ODM_StartWorkItem(void *pRtWorkItem) ++{ ++} ++ ++void ODM_StopWorkItem(void *pRtWorkItem) ++{ ++} ++ ++void ODM_FreeWorkItem(void *pRtWorkItem) ++{ ++} ++ ++void ODM_ScheduleWorkItem(void *pRtWorkItem) ++{ ++} ++ ++void ODM_IsWorkItemScheduled(void *pRtWorkItem) ++{ ++} ++ ++/* ODM Timer relative API. */ ++void ODM_StallExecution(u32 usDelay) ++{ ++ udelay(usDelay); ++} ++ ++void ODM_delay_ms(u32 ms) ++{ ++ mdelay(ms); ++} ++ ++void ODM_delay_us(u32 us) ++{ ++ udelay(us); ++} ++ ++void ODM_sleep_ms(u32 ms) ++{ ++ msleep(ms); ++} ++ ++void ODM_sleep_us(u32 us) ++{ ++ rtw_usleep_os(us); ++} ++ ++void ODM_SetTimer(struct odm_dm_struct *pDM_Odm, struct timer_list *pTimer, u32 msDelay) ++{ ++ _set_timer(pTimer, msDelay); /* ms */ ++} ++ ++void ODM_CancelTimer(struct odm_dm_struct *pDM_Odm, struct timer_list *pTimer) ++{ ++ _cancel_timer_ex(pTimer); ++} ++ ++void ODM_ReleaseTimer(struct odm_dm_struct *pDM_Odm, struct timer_list *pTimer) ++{ ++} ++ ++/* ODM FW relative API. */ ++u32 ODM_FillH2CCmd(u8 *pH2CBuffer, u32 H2CBufferLen, u32 CmdNum, ++ u32 *pElementID, u32 *pCmdLen, ++ u8 **pCmbBuffer, u8 *CmdStartSeq) ++{ ++ return true; ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c +new file mode 100644 +index 000000000000..7d50d64cf34d +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c +@@ -0,0 +1,737 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188E_CMD_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/mlme_osdep.h" ++#include "../include/rtw_ioctl_set.h" ++ ++#include "../include/rtl8188e_hal.h" ++ ++#define RTL88E_MAX_H2C_BOX_NUMS 4 ++#define RTL88E_MAX_CMD_LEN 7 ++#define RTL88E_MESSAGE_BOX_SIZE 4 ++#define RTL88E_EX_MESSAGE_BOX_SIZE 4 ++ ++static u8 _is_fw_read_cmd_down(struct adapter *adapt, u8 msgbox_num) ++{ ++ u8 read_down = false; ++ int retry_cnts = 100; ++ ++ u8 valid; ++ ++ do { ++ valid = rtw_read8(adapt, REG_HMETFR) & BIT(msgbox_num); ++ if (0 == valid) ++ read_down = true; ++ } while ((!read_down) && (retry_cnts--)); ++ ++ return read_down; ++} ++ ++/***************************************** ++* H2C Msg format : ++* 0x1DF - 0x1D0 ++*| 31 - 8 | 7-5 4 - 0 | ++*| h2c_msg |Class_ID CMD_ID | ++* ++* Extend 0x1FF - 0x1F0 ++*|31 - 0 | ++*|ext_msg| ++******************************************/ ++static s32 FillH2CCmd_88E(struct adapter *adapt, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer) ++{ ++ u8 bcmd_down = false; ++ s32 retry_cnts = 100; ++ u8 h2c_box_num; ++ u32 msgbox_addr; ++ u32 msgbox_ex_addr; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ u8 cmd_idx, ext_cmd_len; ++ u32 h2c_cmd = 0; ++ u32 h2c_cmd_ex = 0; ++ s32 ret = _FAIL; ++ ++ if (!adapt->bFWReady) { ++ DBG_88E("FillH2CCmd_88E(): return H2C cmd because fw is not ready\n"); ++ return ret; ++ } ++ ++ if (!pCmdBuffer) ++ goto exit; ++ if (CmdLen > RTL88E_MAX_CMD_LEN) ++ goto exit; ++ if (adapt->bSurpriseRemoved) ++ goto exit; ++ ++ /* pay attention to if race condition happened in H2C cmd setting. */ ++ do { ++ h2c_box_num = haldata->LastHMEBoxNum; ++ ++ if (!_is_fw_read_cmd_down(adapt, h2c_box_num)) { ++ DBG_88E(" fw read cmd failed...\n"); ++ goto exit; ++ } ++ ++ *(u8 *)(&h2c_cmd) = ElementID; ++ ++ if (CmdLen <= 3) { ++ memcpy((u8 *)(&h2c_cmd) + 1, pCmdBuffer, CmdLen); ++ } else { ++ memcpy((u8 *)(&h2c_cmd) + 1, pCmdBuffer, 3); ++ ext_cmd_len = CmdLen - 3; ++ memcpy((u8 *)(&h2c_cmd_ex), pCmdBuffer + 3, ext_cmd_len); ++ ++ /* Write Ext command */ ++ msgbox_ex_addr = REG_HMEBOX_EXT_0 + (h2c_box_num * RTL88E_EX_MESSAGE_BOX_SIZE); ++ for (cmd_idx = 0; cmd_idx < ext_cmd_len; cmd_idx++) { ++ rtw_write8(adapt, msgbox_ex_addr + cmd_idx, *((u8 *)(&h2c_cmd_ex) + cmd_idx)); ++ } ++ } ++ /* Write command */ ++ msgbox_addr = REG_HMEBOX_0 + (h2c_box_num * RTL88E_MESSAGE_BOX_SIZE); ++ for (cmd_idx = 0; cmd_idx < RTL88E_MESSAGE_BOX_SIZE; cmd_idx++) { ++ rtw_write8(adapt, msgbox_addr + cmd_idx, *((u8 *)(&h2c_cmd) + cmd_idx)); ++ } ++ bcmd_down = true; ++ ++ haldata->LastHMEBoxNum = (h2c_box_num + 1) % RTL88E_MAX_H2C_BOX_NUMS; ++ ++ } while ((!bcmd_down) && (retry_cnts--)); ++ ++ ret = _SUCCESS; ++ ++exit: ++ ++ return ret; ++} ++ ++u8 rtl8188e_set_rssi_cmd(struct adapter *adapt, u8 *param) ++{ ++ u8 res = _SUCCESS; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ ++ if (haldata->fw_ractrl) { ++ ; ++ } else { ++ DBG_88E("==>%s fw dont support RA\n", __func__); ++ res = _FAIL; ++ } ++ ++ return res; ++} ++ ++u8 rtl8188e_set_raid_cmd(struct adapter *adapt, u32 mask) ++{ ++ u8 buf[3]; ++ u8 res = _SUCCESS; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ ++ if (haldata->fw_ractrl) { ++ __le32 lmask; ++ ++ memset(buf, 0, 3); ++ lmask = cpu_to_le32(mask); ++ memcpy(buf, &lmask, 3); ++ ++ FillH2CCmd_88E(adapt, H2C_DM_MACID_CFG, 3, buf); ++ } else { ++ DBG_88E("==>%s fw dont support RA\n", __func__); ++ res = _FAIL; ++ } ++ ++ return res; ++} ++ ++/* bitmap[0:27] = tx_rate_bitmap */ ++/* bitmap[28:31]= Rate Adaptive id */ ++/* arg[0:4] = macid */ ++/* arg[5] = Short GI */ ++void rtl8188e_Add_RateATid(struct adapter *pAdapter, u32 bitmap, u8 arg, u8 rssi_level) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(pAdapter); ++ ++ u8 macid, raid, short_gi_rate = false; ++ ++ macid = arg & 0x1f; ++ ++ raid = (bitmap >> 28) & 0x0f; ++ bitmap &= 0x0fffffff; ++ ++ if (rssi_level != DM_RATR_STA_INIT) ++ bitmap = ODM_Get_Rate_Bitmap(&haldata->odmpriv, macid, bitmap, rssi_level); ++ ++ bitmap |= ((raid << 28) & 0xf0000000); ++ ++ short_gi_rate = (arg & BIT(5)) ? true : false; ++ ++ raid = (bitmap >> 28) & 0x0f; ++ ++ bitmap &= 0x0fffffff; ++ ++ ODM_RA_UpdateRateInfo_8188E(&haldata->odmpriv, macid, raid, bitmap, short_gi_rate); ++} ++ ++void rtl8188e_set_FwPwrMode_cmd(struct adapter *adapt, u8 Mode) ++{ ++ struct setpwrmode_parm H2CSetPwrMode; ++ struct pwrctrl_priv *pwrpriv = &adapt->pwrctrlpriv; ++ u8 RLBM = 0; /* 0:Min, 1:Max, 2:User define */ ++ ++ DBG_88E("%s: Mode=%d SmartPS=%d UAPSD=%d\n", __func__, ++ Mode, pwrpriv->smart_ps, adapt->registrypriv.uapsd_enable); ++ ++ switch (Mode) { ++ case PS_MODE_ACTIVE: ++ H2CSetPwrMode.Mode = 0; ++ break; ++ case PS_MODE_MIN: ++ H2CSetPwrMode.Mode = 1; ++ break; ++ case PS_MODE_MAX: ++ RLBM = 1; ++ H2CSetPwrMode.Mode = 1; ++ break; ++ case PS_MODE_DTIM: ++ RLBM = 2; ++ H2CSetPwrMode.Mode = 1; ++ break; ++ case PS_MODE_UAPSD_WMM: ++ H2CSetPwrMode.Mode = 2; ++ break; ++ default: ++ H2CSetPwrMode.Mode = 0; ++ break; ++ } ++ ++ H2CSetPwrMode.SmartPS_RLBM = (((pwrpriv->smart_ps << 4) & 0xf0) | (RLBM & 0x0f)); ++ ++ H2CSetPwrMode.AwakeInterval = 1; ++ ++ H2CSetPwrMode.bAllQueueUAPSD = adapt->registrypriv.uapsd_enable; ++ ++ if (Mode > 0) ++ H2CSetPwrMode.PwrState = 0x00;/* AllON(0x0C), RFON(0x04), RFOFF(0x00) */ ++ else ++ H2CSetPwrMode.PwrState = 0x0C;/* AllON(0x0C), RFON(0x04), RFOFF(0x00) */ ++ ++ FillH2CCmd_88E(adapt, H2C_PS_PWR_MODE, sizeof(H2CSetPwrMode), (u8 *)&H2CSetPwrMode); ++ ++} ++ ++void rtl8188e_set_FwMediaStatus_cmd(struct adapter *adapt, __le16 mstatus_rpt) ++{ ++ u8 opmode, macid; ++ u16 mst_rpt = le16_to_cpu(mstatus_rpt); ++ opmode = (u8)mst_rpt; ++ macid = (u8)(mst_rpt >> 8); ++ ++ DBG_88E("### %s: MStatus=%x MACID=%d\n", __func__, opmode, macid); ++ FillH2CCmd_88E(adapt, H2C_COM_MEDIA_STATUS_RPT, sizeof(mst_rpt), (u8 *)&mst_rpt); ++} ++ ++static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength) ++{ ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ u32 rate_len, pktlen; ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&adapt->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); ++ SetFrameSubType(pframe, WIFI_BEACON); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ /* timestamp will be inserted by hardware */ ++ pframe += 8; ++ pktlen += 8; ++ ++ /* beacon interval: 2 bytes */ ++ memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); ++ ++ pframe += 2; ++ pktlen += 2; ++ ++ /* capability info: 2 bytes */ ++ memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); ++ ++ pframe += 2; ++ pktlen += 2; ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { ++ pktlen += cur_network->IELength - sizeof(struct ndis_802_11_fixed_ie); ++ memcpy(pframe, cur_network->IEs + sizeof(struct ndis_802_11_fixed_ie), pktlen); ++ ++ goto _ConstructBeacon; ++ } ++ ++ /* below for ad-hoc mode */ ++ ++ /* SSID */ ++ pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen); ++ ++ /* supported rates... */ ++ rate_len = rtw_get_rateset_len(cur_network->SupportedRates); ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen); ++ ++ /* DS parameter set */ ++ pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&cur_network->Configuration.DSConfig, &pktlen); ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { ++ u32 ATIMWindow; ++ /* IBSS Parameter Set... */ ++ ATIMWindow = 0; ++ pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen); ++ } ++ ++ /* todo: ERP IE */ ++ ++ /* EXTERNDED SUPPORTED RATE */ ++ if (rate_len > 8) ++ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen); ++ ++ /* todo:HT for adhoc */ ++ ++_ConstructBeacon: ++ ++ if ((pktlen + TXDESC_SIZE) > 512) { ++ DBG_88E("beacon frame too large\n"); ++ return; ++ } ++ ++ *pLength = pktlen; ++} ++ ++static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength) ++{ ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ __le16 *fctrl; ++ ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ /* Frame control. */ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ SetPwrMgt(fctrl); ++ SetFrameSubType(pframe, WIFI_PSPOLL); ++ ++ /* AID. */ ++ SetDuration(pframe, (pmlmeinfo->aid | 0xc000)); ++ ++ /* BSSID. */ ++ memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ /* TA. */ ++ memcpy(pwlanhdr->addr2, myid(&adapt->eeprompriv), ETH_ALEN); ++ ++ *pLength = 16; ++} ++ ++static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe, ++ u32 *pLength, ++ u8 *StaAddr, ++ u8 bQoS, ++ u8 AC, ++ u8 bEosp, ++ u8 bForcePowerSave) ++{ ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ u32 pktlen; ++ struct mlme_priv *pmlmepriv = &adapt->mlmepriv; ++ struct wlan_network *cur_network = &pmlmepriv->cur_network; ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ if (bForcePowerSave) ++ SetPwrMgt(fctrl); ++ ++ switch (cur_network->network.InfrastructureMode) { ++ case Ndis802_11Infrastructure: ++ SetToDs(fctrl); ++ memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&adapt->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN); ++ break; ++ case Ndis802_11APMode: ++ SetFrDs(fctrl); ++ memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, myid(&adapt->eeprompriv), ETH_ALEN); ++ break; ++ case Ndis802_11IBSS: ++ default: ++ memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&adapt->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ break; ++ } ++ ++ SetSeqNum(pwlanhdr, 0); ++ ++ if (bQoS) { ++ struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr; ++ ++ SetFrameSubType(pframe, WIFI_QOS_DATA_NULL); ++ ++ pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe; ++ SetPriority(&pwlanqoshdr->qc, AC); ++ SetEOSP(&pwlanqoshdr->qc, bEosp); ++ ++ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos); ++ } else { ++ SetFrameSubType(pframe, WIFI_DATA_NULL); ++ ++ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ } ++ ++ *pLength = pktlen; ++} ++ ++static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u8 *StaAddr, bool bHideSSID) ++{ ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ u8 *mac, *bssid; ++ u32 pktlen; ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ mac = myid(&adapt->eeprompriv); ++ bssid = cur_network->MacAddress; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, mac, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, bssid, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, 0); ++ SetFrameSubType(fctrl, WIFI_PROBERSP); ++ ++ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ pframe += pktlen; ++ ++ if (cur_network->IELength > MAX_IE_SZ) ++ return; ++ ++ memcpy(pframe, cur_network->IEs, cur_network->IELength); ++ pframe += cur_network->IELength; ++ pktlen += cur_network->IELength; ++ ++ *pLength = pktlen; ++} ++ ++/* To check if reserved page content is destroyed by beacon because beacon is too large. */ ++/* 2010.06.23. Added by tynli. */ ++void CheckFwRsvdPageContent(struct adapter *Adapter) ++{ ++} ++ ++/* */ ++/* Description: Fill the reserved packets that FW will use to RSVD page. */ ++/* Now we just send 4 types packet to rsvd page. */ ++/* (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp. */ ++/* Input: */ ++/* bDLFinished - false: At the first time we will send all the packets as a large packet to Hw, */ ++/* so we need to set the packet length to total length. */ ++/* true: At the second time, we should send the first packet (default:beacon) */ ++/* to Hw again and set the length in descriptor to the real beacon length. */ ++/* 2009.10.15 by tynli. */ ++static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished) ++{ ++ struct hal_data_8188e *haldata; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ struct xmit_priv *pxmitpriv; ++ struct mlme_ext_priv *pmlmeext; ++ struct mlme_ext_info *pmlmeinfo; ++ u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength; ++ u32 NullDataLength, QosNullLength; ++ u8 *ReservedPagePacket; ++ u8 PageNum, PageNeed, TxDescLen; ++ u16 BufIndex; ++ u32 TotalPacketLen; ++ struct rsvdpage_loc RsvdPageLoc; ++ ++ DBG_88E("%s\n", __func__); ++ ReservedPagePacket = kzalloc(1000, GFP_KERNEL); ++ if (!ReservedPagePacket) { ++ DBG_88E("%s: alloc ReservedPagePacket fail!\n", __func__); ++ return; ++ } ++ ++ haldata = GET_HAL_DATA(adapt); ++ pxmitpriv = &adapt->xmitpriv; ++ pmlmeext = &adapt->mlmeextpriv; ++ pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ TxDescLen = TXDESC_SIZE; ++ PageNum = 0; ++ ++ /* 3 (1) beacon * 2 pages */ ++ BufIndex = TXDESC_OFFSET; ++ ConstructBeacon(adapt, &ReservedPagePacket[BufIndex], &BeaconLength); ++ ++ /* When we count the first page size, we need to reserve description size for the RSVD */ ++ /* packet, it will be filled in front of the packet in TXPKTBUF. */ ++ PageNeed = (u8)PageNum_128(TxDescLen + BeaconLength); ++ /* To reserved 2 pages for beacon buffer. 2010.06.24. */ ++ if (PageNeed == 1) ++ PageNeed += 1; ++ PageNum += PageNeed; ++ haldata->FwRsvdPageStartOffset = PageNum; ++ ++ BufIndex += PageNeed * 128; ++ ++ /* 3 (2) ps-poll *1 page */ ++ RsvdPageLoc.LocPsPoll = PageNum; ++ ConstructPSPoll(adapt, &ReservedPagePacket[BufIndex], &PSPollLength); ++ rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex - TxDescLen], PSPollLength, true, false); ++ ++ PageNeed = (u8)PageNum_128(TxDescLen + PSPollLength); ++ PageNum += PageNeed; ++ ++ BufIndex += PageNeed * 128; ++ ++ /* 3 (3) null data * 1 page */ ++ RsvdPageLoc.LocNullData = PageNum; ++ ConstructNullFunctionData(adapt, &ReservedPagePacket[BufIndex], &NullDataLength, get_my_bssid(&pmlmeinfo->network), false, 0, 0, false); ++ rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex - TxDescLen], NullDataLength, false, false); ++ ++ PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength); ++ PageNum += PageNeed; ++ ++ BufIndex += PageNeed * 128; ++ ++ /* 3 (4) probe response * 1page */ ++ RsvdPageLoc.LocProbeRsp = PageNum; ++ ConstructProbeRsp(adapt, &ReservedPagePacket[BufIndex], &ProbeRspLength, get_my_bssid(&pmlmeinfo->network), false); ++ rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex - TxDescLen], ProbeRspLength, false, false); ++ ++ PageNeed = (u8)PageNum_128(TxDescLen + ProbeRspLength); ++ PageNum += PageNeed; ++ ++ BufIndex += PageNeed * 128; ++ ++ /* 3 (5) Qos null data */ ++ RsvdPageLoc.LocQosNull = PageNum; ++ ConstructNullFunctionData(adapt, &ReservedPagePacket[BufIndex], ++ &QosNullLength, get_my_bssid(&pmlmeinfo->network), true, 0, 0, false); ++ rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex - TxDescLen], QosNullLength, false, false); ++ ++ PageNeed = (u8)PageNum_128(TxDescLen + QosNullLength); ++ PageNum += PageNeed; ++ ++ TotalPacketLen = BufIndex + QosNullLength; ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ goto exit; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(adapt, pattrib); ++ pattrib->qsel = 0x10; ++ pattrib->last_txcmdsz = TotalPacketLen - TXDESC_OFFSET; ++ pattrib->pktlen = pattrib->last_txcmdsz; ++ memcpy(pmgntframe->buf_addr, ReservedPagePacket, TotalPacketLen); ++ ++ rtw_hal_mgnt_xmit(adapt, pmgntframe); ++ ++ DBG_88E("%s: Set RSVD page location to Fw\n", __func__); ++ FillH2CCmd_88E(adapt, H2C_COM_RSVD_PAGE, sizeof(RsvdPageLoc), (u8 *)&RsvdPageLoc); ++ ++exit: ++ kfree(ReservedPagePacket); ++} ++ ++void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ bool bSendBeacon = false; ++ bool bcn_valid = false; ++ u8 DLBcnCount = 0; ++ u32 poll = 0; ++ ++ DBG_88E("%s mstatus(%x)\n", __func__, mstatus); ++ ++ if (mstatus == 1) { ++ /* We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C. */ ++ /* Suggested by filen. Added by tynli. */ ++ rtw_write16(adapt, REG_BCN_PSR_RPT, (0xC000 | pmlmeinfo->aid)); ++ /* Do not set TSF again here or vWiFi beacon DMA INT will not work. */ ++ ++ /* Set REG_CR bit 8. DMA beacon by SW. */ ++ haldata->RegCR_1 |= BIT(0); ++ rtw_write8(adapt, REG_CR + 1, haldata->RegCR_1); ++ ++ /* Disable Hw protection for a time which revserd for Hw sending beacon. */ ++ /* Fix download reserved page packet fail that access collision with the protection time. */ ++ /* 2010.05.11. Added by tynli. */ ++ rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(3))); ++ rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(4)); ++ ++ if (haldata->RegFwHwTxQCtrl & BIT(6)) { ++ DBG_88E("HalDownloadRSVDPage(): There is an Adapter is sending beacon.\n"); ++ bSendBeacon = true; ++ } ++ ++ /* Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame. */ ++ rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl & (~BIT(6)))); ++ haldata->RegFwHwTxQCtrl &= (~BIT(6)); ++ ++ /* Clear beacon valid check bit. */ ++ rtw_hal_set_hwreg(adapt, HW_VAR_BCN_VALID, NULL); ++ DLBcnCount = 0; ++ poll = 0; ++ do { ++ /* download rsvd page. */ ++ SetFwRsvdPagePkt(adapt, false); ++ DLBcnCount++; ++ do { ++ yield(); ++ /* mdelay(10); */ ++ /* check rsvd page download OK. */ ++ rtw_hal_get_hwreg(adapt, HW_VAR_BCN_VALID, (u8 *)(&bcn_valid)); ++ poll++; ++ } while (!bcn_valid && (poll % 10) != 0 && !adapt->bSurpriseRemoved && !adapt->bDriverStopped); ++ } while (!bcn_valid && DLBcnCount <= 100 && !adapt->bSurpriseRemoved && !adapt->bDriverStopped); ++ ++ if (adapt->bSurpriseRemoved || adapt->bDriverStopped) ++ ; ++ else if (!bcn_valid) ++ DBG_88E("%s: 1 Download RSVD page failed! DLBcnCount:%u, poll:%u\n", __func__, DLBcnCount, poll); ++ else ++ DBG_88E("%s: 1 Download RSVD success! DLBcnCount:%u, poll:%u\n", __func__, DLBcnCount, poll); ++ /* */ ++ /* We just can send the reserved page twice during the time that Tx thread is stopped (e.g. pnpsetpower) */ ++ /* because we need to free the Tx BCN Desc which is used by the first reserved page packet. */ ++ /* At run time, we cannot get the Tx Desc until it is released in TxHandleInterrupt() so we will return */ ++ /* the beacon TCB in the following code. 2011.11.23. by tynli. */ ++ /* */ ++ ++ /* Enable Bcn */ ++ rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(3)); ++ rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(4))); ++ ++ /* To make sure that if there exists an adapter which would like to send beacon. */ ++ /* If exists, the origianl value of 0x422[6] will be 1, we should check this to */ ++ /* prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */ ++ /* the beacon cannot be sent by HW. */ ++ /* 2010.06.23. Added by tynli. */ ++ if (bSendBeacon) { ++ rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl | BIT(6))); ++ haldata->RegFwHwTxQCtrl |= BIT(6); ++ } ++ ++ /* Update RSVD page location H2C to Fw. */ ++ if (bcn_valid) { ++ rtw_hal_set_hwreg(adapt, HW_VAR_BCN_VALID, NULL); ++ DBG_88E("Set RSVD page location to Fw.\n"); ++ } ++ ++ /* Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli. */ ++ /* Clear CR[8] or beacon packet will not be send to TxBuf anymore. */ ++ haldata->RegCR_1 &= (~BIT(0)); ++ rtw_write8(adapt, REG_CR + 1, haldata->RegCR_1); ++ } ++ ++} ++ ++void rtl8188e_set_p2p_ps_offload_cmd(struct adapter *adapt, u8 p2p_ps_state) ++{ ++#ifdef CONFIG_88EU_P2P ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ struct wifidirect_info *pwdinfo = &adapt->wdinfo; ++ struct P2P_PS_Offload_t *p2p_ps_offload = &haldata->p2p_ps_offload; ++ u8 i; ++ ++ switch (p2p_ps_state) { ++ case P2P_PS_DISABLE: ++ DBG_88E("P2P_PS_DISABLE\n"); ++ memset(p2p_ps_offload, 0, 1); ++ break; ++ case P2P_PS_ENABLE: ++ DBG_88E("P2P_PS_ENABLE\n"); ++ /* update CTWindow value. */ ++ if (pwdinfo->ctwindow > 0) { ++ p2p_ps_offload->CTWindow_En = 1; ++ rtw_write8(adapt, REG_P2P_CTWIN, pwdinfo->ctwindow); ++ } ++ ++ /* hw only support 2 set of NoA */ ++ for (i = 0; i < pwdinfo->noa_num; i++) { ++ /* To control the register setting for which NOA */ ++ rtw_write8(adapt, REG_NOA_DESC_SEL, (i << 4)); ++ if (i == 0) ++ p2p_ps_offload->NoA0_En = 1; ++ else ++ p2p_ps_offload->NoA1_En = 1; ++ ++ /* config P2P NoA Descriptor Register */ ++ rtw_write32(adapt, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]); ++ rtw_write32(adapt, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]); ++ rtw_write32(adapt, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]); ++ rtw_write8(adapt, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]); ++ } ++ ++ if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) { ++ /* rst p2p circuit */ ++ rtw_write8(adapt, REG_DUAL_TSF_RST, BIT(4)); ++ ++ p2p_ps_offload->Offload_En = 1; ++ ++ if (pwdinfo->role == P2P_ROLE_GO) { ++ p2p_ps_offload->role = 1; ++ p2p_ps_offload->AllStaSleep = 0; ++ } else { ++ p2p_ps_offload->role = 0; ++ } ++ ++ p2p_ps_offload->discovery = 0; ++ } ++ break; ++ case P2P_PS_SCAN: ++ DBG_88E("P2P_PS_SCAN\n"); ++ p2p_ps_offload->discovery = 1; ++ break; ++ case P2P_PS_SCAN_DONE: ++ DBG_88E("P2P_PS_SCAN_DONE\n"); ++ p2p_ps_offload->discovery = 0; ++ pwdinfo->p2p_ps_state = P2P_PS_ENABLE; ++ break; ++ default: ++ break; ++ } ++ ++ FillH2CCmd_88E(adapt, H2C_PS_P2P_OFFLOAD, 1, (u8 *)p2p_ps_offload); ++#endif ++ ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_dm.c b/drivers/staging/r8188eu/hal/rtl8188e_dm.c +new file mode 100644 +index 000000000000..78552303c990 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_dm.c +@@ -0,0 +1,238 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++/* This file is for 92CE/92CU dynamic mechanism only */ ++#define _RTL8188E_DM_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtl8188e_hal.h" ++ ++static void dm_CheckStatistics(struct adapter *Adapter) ++{ ++} ++ ++/* Initialize GPIO setting registers */ ++static void dm_InitGPIOSetting(struct adapter *Adapter) ++{ ++ u8 tmp1byte; ++ ++ tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG); ++ tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT); ++ ++ rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte); ++} ++ ++/* */ ++/* functions */ ++/* */ ++static void Init_ODM_ComInfo_88E(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &hal_data->dmpriv; ++ struct odm_dm_struct *dm_odm = &hal_data->odmpriv; ++ u8 cut_ver, fab_ver; ++ ++ /* Init Value */ ++ memset(dm_odm, 0, sizeof(*dm_odm)); ++ ++ dm_odm->Adapter = Adapter; ++ ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_PLATFORM, ODM_CE); ++ ++ if (Adapter->interface_type == RTW_GSPI) ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_INTERFACE, ODM_ITRF_SDIO); ++ else ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_INTERFACE, Adapter->interface_type);/* RTL871X_HCI_TYPE */ ++ ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_IC_TYPE, ODM_RTL8188E); ++ ++ fab_ver = ODM_TSMC; ++ cut_ver = ODM_CUT_A; ++ ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_FAB_VER, fab_ver); ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_CUT_VER, cut_ver); ++ ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_MP_TEST_CHIP, IS_NORMAL_CHIP(hal_data->VersionID)); ++ ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_PATCH_ID, hal_data->CustomerID); ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_BWIFI_TEST, Adapter->registrypriv.wifi_spec); ++ ++ if (hal_data->rf_type == RF_1T1R) ++ ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_RF_TYPE, ODM_1T1R); ++ else if (hal_data->rf_type == RF_2T2R) ++ ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_RF_TYPE, ODM_2T2R); ++ else if (hal_data->rf_type == RF_1T2R) ++ ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_RF_TYPE, ODM_1T2R); ++ ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_RF_ANTENNA_TYPE, hal_data->TRxAntDivType); ++ ++ pdmpriv->InitODMFlag = ODM_RF_CALIBRATION | ++ ODM_RF_TX_PWR_TRACK; ++ ++ ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_ABILITY, pdmpriv->InitODMFlag); ++} ++ ++static void Update_ODM_ComInfo_88E(struct adapter *Adapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; ++ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; ++ struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv; ++ struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); ++ struct odm_dm_struct *dm_odm = &hal_data->odmpriv; ++ struct dm_priv *pdmpriv = &hal_data->dmpriv; ++ int i; ++ ++ pdmpriv->InitODMFlag = ODM_BB_DIG | ++ ODM_BB_RA_MASK | ++ ODM_BB_DYNAMIC_TXPWR | ++ ODM_BB_FA_CNT | ++ ODM_BB_RSSI_MONITOR | ++ ODM_BB_CCK_PD | ++ ODM_BB_PWR_SAVE | ++ ODM_MAC_EDCA_TURBO | ++ ODM_RF_CALIBRATION | ++ ODM_RF_TX_PWR_TRACK; ++ if (hal_data->AntDivCfg) ++ pdmpriv->InitODMFlag |= ODM_BB_ANT_DIV; ++ ++ if (Adapter->registrypriv.mp_mode == 1) { ++ pdmpriv->InitODMFlag = ODM_RF_CALIBRATION | ++ ODM_RF_TX_PWR_TRACK; ++ } ++ ++ ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_ABILITY, pdmpriv->InitODMFlag); ++ ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_TX_UNI, &Adapter->xmitpriv.tx_bytes); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_RX_UNI, &Adapter->recvpriv.rx_bytes); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_WM_MODE, &pmlmeext->cur_wireless_mode); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_SEC_CHNL_OFFSET, &hal_data->nCur40MhzPrimeSC); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_SEC_MODE, &Adapter->securitypriv.dot11PrivacyAlgrthm); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_BW, &hal_data->CurrentChannelBW); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_CHNL, &hal_data->CurrentChannel); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_NET_CLOSED, &Adapter->net_closed); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_MP_MODE, &Adapter->registrypriv.mp_mode); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_SCAN, &pmlmepriv->bScanInProcess); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_POWER_SAVING, &pwrctrlpriv->bpower_saving); ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_RF_ANTENNA_TYPE, hal_data->TRxAntDivType); ++ ++ for (i = 0; i < NUM_STA; i++) ++ ODM_CmnInfoPtrArrayHook(dm_odm, ODM_CMNINFO_STA_STATUS, i, NULL); ++} ++ ++void rtl8188e_InitHalDm(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &hal_data->dmpriv; ++ struct odm_dm_struct *dm_odm = &hal_data->odmpriv; ++ ++ dm_InitGPIOSetting(Adapter); ++ pdmpriv->DM_Type = DM_Type_ByDriver; ++ pdmpriv->DMFlag = DYNAMIC_FUNC_DISABLE; ++ Update_ODM_ComInfo_88E(Adapter); ++ ODM_DMInit(dm_odm); ++ Adapter->fix_rate = 0xFF; ++} ++ ++void rtl8188e_HalDmWatchDog(struct adapter *Adapter) ++{ ++ bool fw_cur_in_ps = false; ++ bool fw_ps_awake = true; ++ u8 hw_init_completed = false; ++ struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); ++ ++ ++ hw_init_completed = Adapter->hw_init_completed; ++ ++ if (!hw_init_completed) ++ return; ++ ++ fw_cur_in_ps = Adapter->pwrctrlpriv.bFwCurrentInPSMode; ++ rtw_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&fw_ps_awake)); ++ ++ /* Fw is under p2p powersaving mode, driver should stop dynamic mechanism. */ ++ /* modifed by thomas. 2011.06.11. */ ++ if (Adapter->wdinfo.p2p_ps_mode) ++ fw_ps_awake = false; ++ ++ if (hw_init_completed && ((!fw_cur_in_ps) && fw_ps_awake)) { ++ /* Calculate Tx/Rx statistics. */ ++ dm_CheckStatistics(Adapter); ++ ++ ++ } ++ ++ /* ODM */ ++ if (hw_init_completed) { ++ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; ++ u8 bLinked = false; ++ ++ if ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) || ++ (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))) { ++ if (Adapter->stapriv.asoc_sta_count > 2) ++ bLinked = true; ++ } else {/* Station mode */ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ bLinked = true; ++ } ++ ++ ODM_CmnInfoUpdate(&hal_data->odmpriv, ODM_CMNINFO_LINK, bLinked); ++ ODM_DMWatchdog(&hal_data->odmpriv); ++ } ++} ++ ++void rtl8188e_init_dm_priv(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &hal_data->dmpriv; ++ ++ memset(pdmpriv, 0, sizeof(struct dm_priv)); ++ Init_ODM_ComInfo_88E(Adapter); ++} ++ ++void rtl8188e_deinit_dm_priv(struct adapter *Adapter) ++{ ++} ++ ++/* Add new function to reset the state of antenna diversity before link. */ ++/* Compare RSSI for deciding antenna */ ++void AntDivCompare8188E(struct adapter *Adapter, struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src) ++{ ++ struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); ++ ++ if (0 != hal_data->AntDivCfg) { ++ /* select optimum_antenna for before linked =>For antenna diversity */ ++ if (dst->Rssi >= src->Rssi) {/* keep org parameter */ ++ src->Rssi = dst->Rssi; ++ src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna; ++ } ++ } ++} ++ ++/* Add new function to reset the state of antenna diversity before link. */ ++u8 AntDivBeforeLink8188E(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); ++ struct odm_dm_struct *dm_odm = &hal_data->odmpriv; ++ struct sw_ant_switch *dm_swat_tbl = &dm_odm->DM_SWAT_Table; ++ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; ++ ++ /* Condition that does not need to use antenna diversity. */ ++ if (hal_data->AntDivCfg == 0) ++ return false; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ return false; ++ ++ if (dm_swat_tbl->SWAS_NoLink_State == 0) { ++ /* switch channel */ ++ dm_swat_tbl->SWAS_NoLink_State = 1; ++ dm_swat_tbl->CurAntenna = (dm_swat_tbl->CurAntenna == Antenna_A) ? Antenna_B : Antenna_A; ++ ++ rtw_antenna_select_cmd(Adapter, dm_swat_tbl->CurAntenna, false); ++ return true; ++ } else { ++ dm_swat_tbl->SWAS_NoLink_State = 0; ++ return false; ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c +new file mode 100644 +index 000000000000..14758361960c +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c +@@ -0,0 +1,2304 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _HAL_INIT_C_ ++ ++#include "../include/linux/firmware.h" ++#include "../include/drv_types.h" ++#include "../include/rtw_efuse.h" ++#include "../include/rtl8188e_hal.h" ++#include "../include/rtw_iol.h" ++#include "../include/usb_ops.h" ++ ++static void iol_mode_enable(struct adapter *padapter, u8 enable) ++{ ++ u8 reg_0xf0 = 0; ++ ++ if (enable) { ++ /* Enable initial offload */ ++ reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG); ++ rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN); ++ ++ if (!padapter->bFWReady) { ++ DBG_88E("bFWReady == false call reset 8051...\n"); ++ _8051Reset88E(padapter); ++ } ++ ++ } else { ++ /* disable initial offload */ ++ reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG); ++ rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN); ++ } ++} ++ ++static s32 iol_execute(struct adapter *padapter, u8 control) ++{ ++ s32 status = _FAIL; ++ u8 reg_0x88 = 0; ++ u32 start = 0, passing_time = 0; ++ ++ control = control & 0x0f; ++ reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0); ++ rtw_write8(padapter, REG_HMEBOX_E0, reg_0x88 | control); ++ ++ start = jiffies; ++ while ((reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0)) & control && ++ (passing_time = rtw_get_passing_time_ms(start)) < 1000) { ++ ; ++ } ++ ++ reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0); ++ status = (reg_0x88 & control) ? _FAIL : _SUCCESS; ++ if (reg_0x88 & control << 4) ++ status = _FAIL; ++ return status; ++} ++ ++static s32 iol_InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy) ++{ ++ s32 rst = _SUCCESS; ++ iol_mode_enable(padapter, 1); ++ rtw_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy); ++ rst = iol_execute(padapter, CMD_INIT_LLT); ++ iol_mode_enable(padapter, 0); ++ return rst; ++} ++ ++static void ++efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) ++{ ++ u8 *efuseTbl = NULL; ++ u8 rtemp8; ++ u16 eFuse_Addr = 0; ++ u8 offset, wren; ++ u16 i, j; ++ u16 **eFuseWord = NULL; ++ u16 efuse_utilized = 0; ++ u8 u1temp = 0; ++ ++ efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL); ++ if (!efuseTbl) { ++ DBG_88E("%s: alloc efuseTbl fail!\n", __func__); ++ goto exit; ++ } ++ ++ eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16)); ++ if (!eFuseWord) { ++ DBG_88E("%s: alloc eFuseWord fail!\n", __func__); ++ goto exit; ++ } ++ ++ /* 0. Refresh efuse init map as all oxFF. */ ++ for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) ++ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) ++ eFuseWord[i][j] = 0xFFFF; ++ ++ /* */ ++ /* 1. Read the first byte to check if efuse is empty!!! */ ++ /* */ ++ /* */ ++ rtemp8 = *(phymap + eFuse_Addr); ++ if (rtemp8 != 0xFF) { ++ efuse_utilized++; ++ eFuse_Addr++; ++ } else { ++ DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, rtemp8); ++ goto exit; ++ } ++ ++ /* */ ++ /* 2. Read real efuse content. Filter PG header and every section data. */ ++ /* */ ++ while ((rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) { ++ /* Check PG header for section num. */ ++ if ((rtemp8 & 0x1F) == 0x0F) { /* extended header */ ++ u1temp = ((rtemp8 & 0xE0) >> 5); ++ rtemp8 = *(phymap + eFuse_Addr); ++ if ((rtemp8 & 0x0F) == 0x0F) { ++ eFuse_Addr++; ++ rtemp8 = *(phymap + eFuse_Addr); ++ ++ if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) ++ eFuse_Addr++; ++ continue; ++ } else { ++ offset = ((rtemp8 & 0xF0) >> 1) | u1temp; ++ wren = (rtemp8 & 0x0F); ++ eFuse_Addr++; ++ } ++ } else { ++ offset = ((rtemp8 >> 4) & 0x0f); ++ wren = (rtemp8 & 0x0f); ++ } ++ ++ if (offset < EFUSE_MAX_SECTION_88E) { ++ /* Get word enable value from PG header */ ++ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { ++ /* Check word enable condition in the section */ ++ if (!(wren & 0x01)) { ++ rtemp8 = *(phymap + eFuse_Addr); ++ eFuse_Addr++; ++ efuse_utilized++; ++ eFuseWord[offset][i] = (rtemp8 & 0xff); ++ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) ++ break; ++ rtemp8 = *(phymap + eFuse_Addr); ++ eFuse_Addr++; ++ efuse_utilized++; ++ eFuseWord[offset][i] |= (((u16)rtemp8 << 8) & 0xff00); ++ ++ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) ++ break; ++ } ++ wren >>= 1; ++ } ++ } ++ /* Read next PG header */ ++ rtemp8 = *(phymap + eFuse_Addr); ++ ++ if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) { ++ efuse_utilized++; ++ eFuse_Addr++; ++ } ++ } ++ ++ /* */ ++ /* 3. Collect 16 sections and 4 word unit into Efuse map. */ ++ /* */ ++ for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) { ++ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) { ++ efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff); ++ efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff); ++ } ++ } ++ ++ /* */ ++ /* 4. Copy from Efuse map to output pointer memory!!! */ ++ /* */ ++ for (i = 0; i < _size_byte; i++) ++ pbuf[i] = efuseTbl[_offset + i]; ++ ++ /* */ ++ /* 5. Calculate Efuse utilization. */ ++ /* */ ++ ++exit: ++ kfree(efuseTbl); ++ kfree(eFuseWord); ++} ++ ++static void efuse_read_phymap_from_txpktbuf( ++ struct adapter *adapter, ++ int bcnhead, /* beacon head, where FW store len(2-byte) and efuse physical map. */ ++ u8 *content, /* buffer to store efuse physical map */ ++ u16 *size /* for efuse content: the max byte to read. will update to byte read */ ++ ) ++{ ++ u16 dbg_addr = 0; ++ u32 start = 0, passing_time = 0; ++ u8 reg_0x143 = 0; ++ __le32 lo32 = 0, hi32 = 0; ++ u16 len = 0, count = 0; ++ int i = 0; ++ u16 limit = *size; ++ ++ u8 *pos = content; ++ ++ if (bcnhead < 0) /* if not valid */ ++ bcnhead = rtw_read8(adapter, REG_TDECTRL + 1); ++ ++ DBG_88E("%s bcnhead:%d\n", __func__, bcnhead); ++ ++ rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT); ++ ++ dbg_addr = bcnhead * 128 / 8; /* 8-bytes addressing */ ++ ++ while (1) { ++ rtw_write16(adapter, REG_PKTBUF_DBG_ADDR, dbg_addr + i); ++ ++ rtw_write8(adapter, REG_TXPKTBUF_DBG, 0); ++ start = jiffies; ++ while (!(reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG)) && ++ (passing_time = rtw_get_passing_time_ms(start)) < 1000) { ++ DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, rtw_read8(adapter, 0x106)); ++ rtw_usleep_os(100); ++ } ++ ++ /* data from EEPROM needs to be in LE */ ++ lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L)); ++ hi32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H)); ++ ++ if (i == 0) { ++ /* Although lenc is only used in a debug statement, ++ * do not remove it as the rtw_read16() call consumes ++ * 2 bytes from the EEPROM source. ++ */ ++ u16 lenc = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L); ++ ++ len = le32_to_cpu(lo32) & 0x0000ffff; ++ ++ limit = (len - 2 < limit) ? len - 2 : limit; ++ ++ DBG_88E("%s len:%u, lenc:%u\n", __func__, len, lenc); ++ ++ memcpy(pos, ((u8 *)&lo32) + 2, (limit >= count + 2) ? 2 : limit - count); ++ count += (limit >= count + 2) ? 2 : limit - count; ++ pos = content + count; ++ } else { ++ memcpy(pos, ((u8 *)&lo32), (limit >= count + 4) ? 4 : limit - count); ++ count += (limit >= count + 4) ? 4 : limit - count; ++ pos = content + count; ++ } ++ ++ if (limit > count && len - 2 > count) { ++ memcpy(pos, (u8 *)&hi32, (limit >= count + 4) ? 4 : limit - count); ++ count += (limit >= count + 4) ? 4 : limit - count; ++ pos = content + count; ++ } ++ ++ if (limit <= count || len - 2 <= count) ++ break; ++ i++; ++ } ++ rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS); ++ DBG_88E("%s read count:%u\n", __func__, count); ++ *size = count; ++} ++ ++static s32 iol_read_efuse(struct adapter *padapter, u8 txpktbuf_bndy, u16 offset, u16 size_byte, u8 *logical_map) ++{ ++ s32 status = _FAIL; ++ u8 physical_map[512]; ++ u16 size = 512; ++ ++ rtw_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy); ++ memset(physical_map, 0xFF, 512); ++ rtw_write8(padapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT); ++ status = iol_execute(padapter, CMD_READ_EFUSE_MAP); ++ if (status == _SUCCESS) ++ efuse_read_phymap_from_txpktbuf(padapter, txpktbuf_bndy, physical_map, &size); ++ efuse_phymap_to_logical(physical_map, offset, size_byte, logical_map); ++ return status; ++} ++ ++s32 rtl8188e_iol_efuse_patch(struct adapter *padapter) ++{ ++ s32 result = _SUCCESS; ++ ++ DBG_88E("==> %s\n", __func__); ++ if (rtw_IOL_applied(padapter)) { ++ iol_mode_enable(padapter, 1); ++ result = iol_execute(padapter, CMD_READ_EFUSE_MAP); ++ if (result == _SUCCESS) ++ result = iol_execute(padapter, CMD_EFUSE_PATCH); ++ ++ iol_mode_enable(padapter, 0); ++ } ++ return result; ++} ++ ++static s32 iol_ioconfig(struct adapter *padapter, u8 iocfg_bndy) ++{ ++ s32 rst = _SUCCESS; ++ ++ rtw_write8(padapter, REG_TDECTRL + 1, iocfg_bndy); ++ rst = iol_execute(padapter, CMD_IOCONFIG); ++ return rst; ++} ++ ++static int rtl8188e_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt) ++{ ++ struct pkt_attrib *pattrib = &xmit_frame->attrib; ++ u8 i; ++ int ret = _FAIL; ++ ++ if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS) ++ goto exit; ++ if (rtw_usb_bulk_size_boundary(adapter, TXDESC_SIZE + pattrib->last_txcmdsz)) { ++ if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS) ++ goto exit; ++ } ++ ++ dump_mgntframe_and_wait(adapter, xmit_frame, max_wating_ms); ++ ++ iol_mode_enable(adapter, 1); ++ for (i = 0; i < bndy_cnt; i++) { ++ u8 page_no = 0; ++ page_no = i * 2; ++ ret = iol_ioconfig(adapter, page_no); ++ if (ret != _SUCCESS) ++ break; ++ } ++ iol_mode_enable(adapter, 0); ++exit: ++ /* restore BCN_HEAD */ ++ rtw_write8(adapter, REG_TDECTRL + 1, 0); ++ return ret; ++} ++ ++void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len) ++{ ++ u32 fifo_data, reg_140; ++ u32 addr, rstatus, loop = 0; ++ u16 data_cnts = (data_len / 8) + 1; ++ u8 *pbuf = vzalloc(data_len + 10); ++ DBG_88E("###### %s ######\n", __func__); ++ ++ rtw_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT); ++ if (pbuf) { ++ for (addr = 0; addr < data_cnts; addr++) { ++ rtw_write32(Adapter, 0x140, addr); ++ rtw_usleep_os(2); ++ loop = 0; ++ do { ++ rstatus = (reg_140 = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL) & BIT(24)); ++ if (rstatus) { ++ fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L); ++ memcpy(pbuf + (addr * 8), &fifo_data, 4); ++ ++ fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H); ++ memcpy(pbuf + (addr * 8 + 4), &fifo_data, 4); ++ } ++ rtw_usleep_os(2); ++ } while (!rstatus && (loop++ < 10)); ++ } ++ rtw_IOL_cmd_buf_dump(Adapter, data_len, pbuf); ++ vfree(pbuf); ++ } ++ DBG_88E("###### %s ######\n", __func__); ++} ++ ++static void _FWDownloadEnable(struct adapter *padapter, bool enable) ++{ ++ u8 tmp; ++ ++ if (enable) { ++ /* MCU firmware download enable. */ ++ tmp = rtw_read8(padapter, REG_MCUFWDL); ++ rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01); ++ ++ /* 8051 reset */ ++ tmp = rtw_read8(padapter, REG_MCUFWDL + 2); ++ rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7); ++ } else { ++ /* MCU firmware download disable. */ ++ tmp = rtw_read8(padapter, REG_MCUFWDL); ++ rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe); ++ ++ /* Reserved for fw extension. */ ++ rtw_write8(padapter, REG_MCUFWDL + 1, 0x00); ++ } ++} ++ ++#define MAX_REG_BOLCK_SIZE 196 ++ ++static int _BlockWrite(struct adapter *padapter, void *buffer, u32 buffSize) ++{ ++ int ret = _SUCCESS; ++ u32 blockSize_p1 = 4; /* (Default) Phase #1 : PCI muse use 4-byte write to download FW */ ++ u32 blockSize_p2 = 8; /* Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */ ++ u32 blockSize_p3 = 1; /* Phase #3 : Use 1-byte, the remnant of FW image. */ ++ u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0; ++ u32 remainSize_p1 = 0, remainSize_p2 = 0; ++ u8 *bufferPtr = (u8 *)buffer; ++ u32 i = 0, offset = 0; ++ ++ blockSize_p1 = MAX_REG_BOLCK_SIZE; ++ ++ /* 3 Phase #1 */ ++ blockCount_p1 = buffSize / blockSize_p1; ++ remainSize_p1 = buffSize % blockSize_p1; ++ ++ for (i = 0; i < blockCount_p1; i++) { ++ ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1)); ++ if (ret == _FAIL) ++ goto exit; ++ } ++ ++ /* 3 Phase #2 */ ++ if (remainSize_p1) { ++ offset = blockCount_p1 * blockSize_p1; ++ ++ blockCount_p2 = remainSize_p1 / blockSize_p2; ++ remainSize_p2 = remainSize_p1 % blockSize_p2; ++ ++ for (i = 0; i < blockCount_p2; i++) { ++ ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + offset + i * blockSize_p2), blockSize_p2, (bufferPtr + offset + i * blockSize_p2)); ++ ++ if (ret == _FAIL) ++ goto exit; ++ } ++ } ++ ++ /* 3 Phase #3 */ ++ if (remainSize_p2) { ++ offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2); ++ ++ blockCount_p3 = remainSize_p2 / blockSize_p3; ++ ++ for (i = 0; i < blockCount_p3; i++) { ++ ret = rtw_write8(padapter, (FW_8188E_START_ADDRESS + offset + i), *(bufferPtr + offset + i)); ++ ++ if (ret == _FAIL) ++ goto exit; ++ } ++ } ++ ++exit: ++ return ret; ++} ++ ++static int _PageWrite(struct adapter *padapter, u32 page, void *buffer, u32 size) ++{ ++ u8 value8; ++ u8 u8Page = (u8)(page & 0x07); ++ ++ value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page; ++ rtw_write8(padapter, REG_MCUFWDL + 2, value8); ++ ++ return _BlockWrite(padapter, buffer, size); ++} ++ ++static int _WriteFW(struct adapter *padapter, void *buffer, u32 size) ++{ ++ /* Since we need dynamic decide method of dwonload fw, so we call this function to get chip version. */ ++ /* We can remove _ReadChipVersion from ReadpadapterInfo8192C later. */ ++ int ret = _SUCCESS; ++ u32 pageNums, remainSize; ++ u32 page, offset; ++ u8 *bufferPtr = (u8 *)buffer; ++ ++ pageNums = size / MAX_PAGE_SIZE; ++ remainSize = size % MAX_PAGE_SIZE; ++ ++ for (page = 0; page < pageNums; page++) { ++ offset = page * MAX_PAGE_SIZE; ++ ret = _PageWrite(padapter, page, bufferPtr + offset, MAX_PAGE_SIZE); ++ ++ if (ret == _FAIL) ++ goto exit; ++ } ++ if (remainSize) { ++ offset = pageNums * MAX_PAGE_SIZE; ++ page = pageNums; ++ ret = _PageWrite(padapter, page, bufferPtr + offset, remainSize); ++ ++ if (ret == _FAIL) ++ goto exit; ++ } ++exit: ++ return ret; ++} ++ ++void _8051Reset88E(struct adapter *padapter) ++{ ++ u8 u1bTmp; ++ ++ u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); ++ rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp & (~BIT(2))); ++ rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp | (BIT(2))); ++ DBG_88E("=====> _8051Reset88E(): 8051 reset success .\n"); ++} ++ ++static s32 _FWFreeToGo(struct adapter *padapter) ++{ ++ u32 counter = 0; ++ u32 value32; ++ ++ /* polling CheckSum report */ ++ do { ++ value32 = rtw_read32(padapter, REG_MCUFWDL); ++ if (value32 & FWDL_ChkSum_rpt) ++ break; ++ } while (counter++ < POLLING_READY_TIMEOUT_COUNT); ++ ++ if (counter >= POLLING_READY_TIMEOUT_COUNT) { ++ DBG_88E("%s: chksum report fail! REG_MCUFWDL:0x%08x\n", __func__, value32); ++ return _FAIL; ++ } ++ DBG_88E("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__, value32); ++ ++ value32 = rtw_read32(padapter, REG_MCUFWDL); ++ value32 |= MCUFWDL_RDY; ++ value32 &= ~WINTINI_RDY; ++ rtw_write32(padapter, REG_MCUFWDL, value32); ++ ++ _8051Reset88E(padapter); ++ ++ /* polling for FW ready */ ++ counter = 0; ++ do { ++ value32 = rtw_read32(padapter, REG_MCUFWDL); ++ if (value32 & WINTINI_RDY) { ++ DBG_88E("%s: Polling FW ready success!! REG_MCUFWDL:0x%08x\n", __func__, value32); ++ return _SUCCESS; ++ } ++ udelay(5); ++ } while (counter++ < POLLING_READY_TIMEOUT_COUNT); ++ ++ DBG_88E("%s: Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", __func__, value32); ++ return _FAIL; ++} ++ ++#define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0) ++ ++static int load_firmware(struct rt_firmware *pFirmware, struct device *device) ++{ ++ s32 rtStatus = _SUCCESS; ++ const struct firmware *fw; ++ const char *fw_name = "rtlwifi/rtl8188eufw.bin"; ++ int err = request_firmware(&fw, fw_name, device); ++ ++ if (err) { ++ pr_err("Request firmware failed with error 0x%x\n", err); ++ rtStatus = _FAIL; ++ goto Exit; ++ } ++ if (!fw) { ++ pr_err("Firmware %s not available\n", fw_name); ++ rtStatus = _FAIL; ++ goto Exit; ++ } ++ if (fw->size > FW_8188E_SIZE) { ++ rtStatus = _FAIL; ++ goto Exit; ++ } ++ ++ pFirmware->szFwBuffer = kzalloc(FW_8188E_SIZE, GFP_KERNEL); ++ if (!pFirmware->szFwBuffer) { ++ pr_err("Failed to allocate pFirmware->szFwBuffer\n"); ++ rtStatus = _FAIL; ++ goto Exit; ++ } ++ memcpy(pFirmware->szFwBuffer, fw->data, fw->size); ++ pFirmware->ulFwLength = fw->size; ++ release_firmware(fw); ++ DBG_88E_LEVEL(_drv_info_, "+%s: !bUsedWoWLANFw, FmrmwareLen:%d+\n", __func__, pFirmware->ulFwLength); ++ ++Exit: ++ return rtStatus; ++} ++ ++s32 rtl8188e_FirmwareDownload(struct adapter *padapter) ++{ ++ s32 rtStatus = _SUCCESS; ++ u8 writeFW_retry = 0; ++ u32 fwdl_start_time; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); ++ struct device *device = dvobj_to_dev(dvobj); ++ struct rt_firmware_hdr *pFwHdr = NULL; ++ u8 *pFirmwareBuf; ++ u32 FirmwareLen; ++ static int log_version; ++ ++ if (!dvobj->firmware.szFwBuffer) ++ rtStatus = load_firmware(&dvobj->firmware, device); ++ if (rtStatus == _FAIL) { ++ dvobj->firmware.szFwBuffer = NULL; ++ goto Exit; ++ } ++ pFirmwareBuf = dvobj->firmware.szFwBuffer; ++ FirmwareLen = dvobj->firmware.ulFwLength; ++ ++ /* To Check Fw header. Added by tynli. 2009.12.04. */ ++ pFwHdr = (struct rt_firmware_hdr *)dvobj->firmware.szFwBuffer; ++ ++ pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version); ++ pHalData->FirmwareSubVersion = pFwHdr->Subversion; ++ pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature); ++ ++ if (!log_version++) ++ pr_info("%sFirmware Version %d, SubVersion %d, Signature 0x%x\n", ++ DRIVER_PREFIX, pHalData->FirmwareVersion, ++ pHalData->FirmwareSubVersion, pHalData->FirmwareSignature); ++ ++ if (IS_FW_HEADER_EXIST(pFwHdr)) { ++ /* Shift 32 bytes for FW header */ ++ pFirmwareBuf = pFirmwareBuf + 32; ++ FirmwareLen = FirmwareLen - 32; ++ } ++ ++ /* Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */ ++ /* or it will cause download Fw fail. 2010.02.01. by tynli. */ ++ if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */ ++ rtw_write8(padapter, REG_MCUFWDL, 0x00); ++ _8051Reset88E(padapter); ++ } ++ ++ _FWDownloadEnable(padapter, true); ++ fwdl_start_time = jiffies; ++ while (1) { ++ /* reset the FWDL chksum */ ++ rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt); ++ ++ rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen); ++ ++ if (rtStatus == _SUCCESS || ++ (rtw_get_passing_time_ms(fwdl_start_time) > 500 && writeFW_retry++ >= 3)) ++ break; ++ ++ DBG_88E("%s writeFW_retry:%u, time after fwdl_start_time:%ums\n", ++ __func__, writeFW_retry, rtw_get_passing_time_ms(fwdl_start_time) ++ ); ++ } ++ _FWDownloadEnable(padapter, false); ++ if (_SUCCESS != rtStatus) { ++ DBG_88E("DL Firmware failed!\n"); ++ goto Exit; ++ } ++ ++ rtStatus = _FWFreeToGo(padapter); ++ if (_SUCCESS != rtStatus) { ++ DBG_88E("DL Firmware failed!\n"); ++ goto Exit; ++ } ++ ++Exit: ++ return rtStatus; ++} ++ ++void rtl8188e_InitializeFirmwareVars(struct adapter *padapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ ++ /* Init Fw LPS related. */ ++ padapter->pwrctrlpriv.bFwCurrentInPSMode = false; ++ ++ /* Init H2C counter. by tynli. 2009.12.09. */ ++ pHalData->LastHMEBoxNum = 0; ++} ++ ++static void rtl8188e_free_hal_data(struct adapter *padapter) ++{ ++ ++ kfree(padapter->HalData); ++ padapter->HalData = NULL; ++ ++} ++ ++/* */ ++/* Efuse related code */ ++/* */ ++enum{ ++ VOLTAGE_V25 = 0x03, ++ LDOE25_SHIFT = 28, ++ }; ++ ++static bool ++hal_EfusePgPacketWrite2ByteHeader( ++ struct adapter *pAdapter, ++ u8 efuseType, ++ u16 *pAddr, ++ struct pgpkt *pTargetPkt, ++ bool bPseudoTest); ++static bool ++hal_EfusePgPacketWrite1ByteHeader( ++ struct adapter *pAdapter, ++ u8 efuseType, ++ u16 *pAddr, ++ struct pgpkt *pTargetPkt, ++ bool bPseudoTest); ++static bool ++hal_EfusePgPacketWriteData( ++ struct adapter *pAdapter, ++ u8 efuseType, ++ u16 *pAddr, ++ struct pgpkt *pTargetPkt, ++ bool bPseudoTest); ++ ++static void ++hal_EfusePowerSwitch_RTL8188E( ++ struct adapter *pAdapter, ++ u8 bWrite, ++ u8 PwrState) ++{ ++ u8 tempval; ++ u16 tmpV16; ++ ++ if (PwrState) { ++ rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); ++ ++ /* 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */ ++ tmpV16 = rtw_read16(pAdapter, REG_SYS_ISO_CTRL); ++ if (!(tmpV16 & PWC_EV12V)) { ++ tmpV16 |= PWC_EV12V; ++ rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16); ++ } ++ /* Reset: 0x0000h[28], default valid */ ++ tmpV16 = rtw_read16(pAdapter, REG_SYS_FUNC_EN); ++ if (!(tmpV16 & FEN_ELDR)) { ++ tmpV16 |= FEN_ELDR; ++ rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16); ++ } ++ ++ /* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */ ++ tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR); ++ if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) { ++ tmpV16 |= (LOADER_CLK_EN | ANA8M); ++ rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16); ++ } ++ ++ if (bWrite) { ++ /* Enable LDO 2.5V before read/write action */ ++ tempval = rtw_read8(pAdapter, EFUSE_TEST + 3); ++ tempval &= 0x0F; ++ tempval |= (VOLTAGE_V25 << 4); ++ rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval | 0x80)); ++ } ++ } else { ++ rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); ++ ++ if (bWrite) { ++ /* Disable LDO 2.5V after read/write action */ ++ tempval = rtw_read8(pAdapter, EFUSE_TEST + 3); ++ rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval & 0x7F)); ++ } ++ } ++} ++ ++static void ++rtl8188e_EfusePowerSwitch( ++ struct adapter *pAdapter, ++ u8 bWrite, ++ u8 PwrState) ++{ ++ hal_EfusePowerSwitch_RTL8188E(pAdapter, bWrite, PwrState); ++} ++ ++static void Hal_EfuseReadEFuse88E(struct adapter *Adapter, ++ u16 _offset, ++ u16 _size_byte, ++ u8 *pbuf, ++ bool bPseudoTest ++ ) ++{ ++ u8 *efuseTbl = NULL; ++ u8 rtemp8[1]; ++ u16 eFuse_Addr = 0; ++ u8 offset, wren; ++ u16 i, j; ++ u16 **eFuseWord = NULL; ++ u16 efuse_utilized = 0; ++ u8 u1temp = 0; ++ ++ /* */ ++ /* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */ ++ /* */ ++ if ((_offset + _size_byte) > EFUSE_MAP_LEN_88E) {/* total E-Fuse table is 512bytes */ ++ DBG_88E("Hal_EfuseReadEFuse88E(): Invalid offset(%#x) with read bytes(%#x)!!\n", _offset, _size_byte); ++ goto exit; ++ } ++ ++ efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL); ++ if (!efuseTbl) { ++ DBG_88E("%s: alloc efuseTbl fail!\n", __func__); ++ goto exit; ++ } ++ ++ eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16)); ++ if (!eFuseWord) { ++ DBG_88E("%s: alloc eFuseWord fail!\n", __func__); ++ goto exit; ++ } ++ ++ /* 0. Refresh efuse init map as all oxFF. */ ++ for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) ++ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) ++ eFuseWord[i][j] = 0xFFFF; ++ ++ /* */ ++ /* 1. Read the first byte to check if efuse is empty!!! */ ++ /* */ ++ /* */ ++ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); ++ if (*rtemp8 != 0xFF) { ++ efuse_utilized++; ++ eFuse_Addr++; ++ } else { ++ DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, *rtemp8); ++ goto exit; ++ } ++ ++ /* */ ++ /* 2. Read real efuse content. Filter PG header and every section data. */ ++ /* */ ++ while ((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) { ++ /* Check PG header for section num. */ ++ if ((*rtemp8 & 0x1F) == 0x0F) { /* extended header */ ++ u1temp = ((*rtemp8 & 0xE0) >> 5); ++ ++ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); ++ ++ if ((*rtemp8 & 0x0F) == 0x0F) { ++ eFuse_Addr++; ++ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); ++ ++ if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) ++ eFuse_Addr++; ++ continue; ++ } else { ++ offset = ((*rtemp8 & 0xF0) >> 1) | u1temp; ++ wren = (*rtemp8 & 0x0F); ++ eFuse_Addr++; ++ } ++ } else { ++ offset = ((*rtemp8 >> 4) & 0x0f); ++ wren = (*rtemp8 & 0x0f); ++ } ++ ++ if (offset < EFUSE_MAX_SECTION_88E) { ++ /* Get word enable value from PG header */ ++ ++ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { ++ /* Check word enable condition in the section */ ++ if (!(wren & 0x01)) { ++ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); ++ eFuse_Addr++; ++ efuse_utilized++; ++ eFuseWord[offset][i] = (*rtemp8 & 0xff); ++ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) ++ break; ++ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); ++ eFuse_Addr++; ++ efuse_utilized++; ++ eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00); ++ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) ++ break; ++ } ++ wren >>= 1; ++ } ++ } ++ ++ /* Read next PG header */ ++ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); ++ ++ if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) { ++ efuse_utilized++; ++ eFuse_Addr++; ++ } ++ } ++ ++ /* 3. Collect 16 sections and 4 word unit into Efuse map. */ ++ for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) { ++ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) { ++ efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff); ++ efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff); ++ } ++ } ++ ++ /* 4. Copy from Efuse map to output pointer memory!!! */ ++ for (i = 0; i < _size_byte; i++) ++ pbuf[i] = efuseTbl[_offset + i]; ++ ++ /* 5. Calculate Efuse utilization. */ ++ rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_BYTES, (u8 *)&eFuse_Addr); ++ ++exit: ++ kfree(efuseTbl); ++ kfree(eFuseWord); ++} ++ ++static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest) ++{ ++ if (!bPseudoTest) { ++ int ret = _FAIL; ++ if (rtw_IOL_applied(Adapter)) { ++ rtw_hal_power_on(Adapter); ++ ++ iol_mode_enable(Adapter, 1); ++ ret = iol_read_efuse(Adapter, 0, _offset, _size_byte, pbuf); ++ iol_mode_enable(Adapter, 0); ++ ++ if (_SUCCESS == ret) ++ goto exit; ++ } ++ } ++ Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest); ++ ++exit: ++ return; ++} ++ ++static void ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest) ++{ ++ Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest); ++} ++ ++static void rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType, ++ u16 _offset, u16 _size_byte, u8 *pbuf, ++ bool bPseudoTest) ++{ ++ if (bPseudoTest) ++ ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest); ++ else ++ ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest); ++} ++ ++/* Do not support BT */ ++static void Hal_EFUSEGetEfuseDefinition88E(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut) ++{ ++ switch (type) { ++ case TYPE_EFUSE_MAX_SECTION: ++ { ++ u8 *pMax_section; ++ pMax_section = (u8 *)pOut; ++ *pMax_section = EFUSE_MAX_SECTION_88E; ++ } ++ break; ++ case TYPE_EFUSE_REAL_CONTENT_LEN: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E; ++ } ++ break; ++ case TYPE_EFUSE_CONTENT_LEN_BANK: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E; ++ } ++ break; ++ case TYPE_AVAILABLE_EFUSE_BYTES_BANK: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E); ++ } ++ break; ++ case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E); ++ } ++ break; ++ case TYPE_EFUSE_MAP_LEN: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = (u16)EFUSE_MAP_LEN_88E; ++ } ++ break; ++ case TYPE_EFUSE_PROTECT_BYTES_BANK: ++ { ++ u8 *pu1Tmp; ++ pu1Tmp = (u8 *)pOut; ++ *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E); ++ } ++ break; ++ default: ++ { ++ u8 *pu1Tmp; ++ pu1Tmp = (u8 *)pOut; ++ *pu1Tmp = 0; ++ } ++ break; ++ } ++} ++ ++static void Hal_EFUSEGetEfuseDefinition_Pseudo88E(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut) ++{ ++ switch (type) { ++ case TYPE_EFUSE_MAX_SECTION: ++ { ++ u8 *pMax_section; ++ pMax_section = (u8 *)pOut; ++ *pMax_section = EFUSE_MAX_SECTION_88E; ++ } ++ break; ++ case TYPE_EFUSE_REAL_CONTENT_LEN: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E; ++ } ++ break; ++ case TYPE_EFUSE_CONTENT_LEN_BANK: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E; ++ } ++ break; ++ case TYPE_AVAILABLE_EFUSE_BYTES_BANK: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E); ++ } ++ break; ++ case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E); ++ } ++ break; ++ case TYPE_EFUSE_MAP_LEN: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = (u16)EFUSE_MAP_LEN_88E; ++ } ++ break; ++ case TYPE_EFUSE_PROTECT_BYTES_BANK: ++ { ++ u8 *pu1Tmp; ++ pu1Tmp = (u8 *)pOut; ++ *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E); ++ } ++ break; ++ default: ++ { ++ u8 *pu1Tmp; ++ pu1Tmp = (u8 *)pOut; ++ *pu1Tmp = 0; ++ } ++ break; ++ } ++} ++ ++static void rtl8188e_EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool bPseudoTest) ++{ ++ if (bPseudoTest) ++ Hal_EFUSEGetEfuseDefinition_Pseudo88E(pAdapter, efuseType, type, pOut); ++ else ++ Hal_EFUSEGetEfuseDefinition88E(pAdapter, efuseType, type, pOut); ++} ++ ++static u8 Hal_EfuseWordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest) ++{ ++ u16 tmpaddr = 0; ++ u16 start_addr = efuse_addr; ++ u8 badworden = 0x0F; ++ u8 tmpdata[8]; ++ ++ memset((void *)tmpdata, 0xff, PGPKT_DATA_SIZE); ++ ++ if (!(word_en & BIT(0))) { ++ tmpaddr = start_addr; ++ efuse_OneByteWrite(pAdapter, start_addr++, data[0], bPseudoTest); ++ efuse_OneByteWrite(pAdapter, start_addr++, data[1], bPseudoTest); ++ ++ efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[0], bPseudoTest); ++ efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[1], bPseudoTest); ++ if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1])) ++ badworden &= (~BIT(0)); ++ } ++ if (!(word_en & BIT(1))) { ++ tmpaddr = start_addr; ++ efuse_OneByteWrite(pAdapter, start_addr++, data[2], bPseudoTest); ++ efuse_OneByteWrite(pAdapter, start_addr++, data[3], bPseudoTest); ++ ++ efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[2], bPseudoTest); ++ efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[3], bPseudoTest); ++ if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3])) ++ badworden &= (~BIT(1)); ++ } ++ if (!(word_en & BIT(2))) { ++ tmpaddr = start_addr; ++ efuse_OneByteWrite(pAdapter, start_addr++, data[4], bPseudoTest); ++ efuse_OneByteWrite(pAdapter, start_addr++, data[5], bPseudoTest); ++ ++ efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[4], bPseudoTest); ++ efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[5], bPseudoTest); ++ if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5])) ++ badworden &= (~BIT(2)); ++ } ++ if (!(word_en & BIT(3))) { ++ tmpaddr = start_addr; ++ efuse_OneByteWrite(pAdapter, start_addr++, data[6], bPseudoTest); ++ efuse_OneByteWrite(pAdapter, start_addr++, data[7], bPseudoTest); ++ ++ efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[6], bPseudoTest); ++ efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[7], bPseudoTest); ++ if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7])) ++ badworden &= (~BIT(3)); ++ } ++ return badworden; ++} ++ ++static u8 Hal_EfuseWordEnableDataWrite_Pseudo(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest) ++{ ++ u8 ret; ++ ++ ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest); ++ return ret; ++} ++ ++static u8 rtl8188e_Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest) ++{ ++ u8 ret = 0; ++ ++ if (bPseudoTest) ++ ret = Hal_EfuseWordEnableDataWrite_Pseudo(pAdapter, efuse_addr, word_en, data, bPseudoTest); ++ else ++ ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest); ++ return ret; ++} ++ ++static u16 hal_EfuseGetCurrentSize_8188e(struct adapter *pAdapter, bool bPseudoTest) ++{ ++ int bContinual = true; ++ u16 efuse_addr = 0; ++ u8 hoffset = 0, hworden = 0; ++ u8 efuse_data, word_cnts = 0; ++ ++ if (bPseudoTest) ++ efuse_addr = (u16)(fakeEfuseUsedBytes); ++ else ++ rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr); ++ ++ while (bContinual && ++ efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest) && ++ AVAILABLE_EFUSE_ADDR(efuse_addr)) { ++ if (efuse_data != 0xFF) { ++ if ((efuse_data & 0x1F) == 0x0F) { /* extended header */ ++ hoffset = efuse_data; ++ efuse_addr++; ++ efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest); ++ if ((efuse_data & 0x0F) == 0x0F) { ++ efuse_addr++; ++ continue; ++ } else { ++ hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); ++ hworden = efuse_data & 0x0F; ++ } ++ } else { ++ hoffset = (efuse_data >> 4) & 0x0F; ++ hworden = efuse_data & 0x0F; ++ } ++ word_cnts = Efuse_CalculateWordCnts(hworden); ++ /* read next header */ ++ efuse_addr = efuse_addr + (word_cnts * 2) + 1; ++ } else { ++ bContinual = false; ++ } ++ } ++ ++ if (bPseudoTest) ++ fakeEfuseUsedBytes = efuse_addr; ++ else ++ rtw_hal_set_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr); ++ ++ return efuse_addr; ++} ++ ++static u16 Hal_EfuseGetCurrentSize_Pseudo(struct adapter *pAdapter, bool bPseudoTest) ++{ ++ u16 ret = 0; ++ ++ ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest); ++ return ret; ++} ++ ++static u16 rtl8188e_EfuseGetCurrentSize(struct adapter *pAdapter, u8 efuseType, bool bPseudoTest) ++{ ++ u16 ret = 0; ++ ++ if (bPseudoTest) ++ ret = Hal_EfuseGetCurrentSize_Pseudo(pAdapter, bPseudoTest); ++ else ++ ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest); ++ return ret; ++} ++ ++static int hal_EfusePgPacketRead_8188e(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest) ++{ ++ u8 ReadState = PG_STATE_HEADER; ++ int bContinual = true; ++ int bDataEmpty = true; ++ u8 efuse_data, word_cnts = 0; ++ u16 efuse_addr = 0; ++ u8 hoffset = 0, hworden = 0; ++ u8 tmpidx = 0; ++ u8 tmpdata[8]; ++ u8 max_section = 0; ++ u8 tmp_header = 0; ++ ++ EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, (void *)&max_section, bPseudoTest); ++ ++ if (!data) ++ return false; ++ if (offset > max_section) ++ return false; ++ ++ memset((void *)data, 0xff, sizeof(u8) * PGPKT_DATA_SIZE); ++ memset((void *)tmpdata, 0xff, sizeof(u8) * PGPKT_DATA_SIZE); ++ ++ /* Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. */ ++ /* Skip dummy parts to prevent unexpected data read from Efuse. */ ++ /* By pass right now. 2009.02.19. */ ++ while (bContinual && AVAILABLE_EFUSE_ADDR(efuse_addr)) { ++ /* Header Read ------------- */ ++ if (ReadState & PG_STATE_HEADER) { ++ if (efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) { ++ if (EXT_HEADER(efuse_data)) { ++ tmp_header = efuse_data; ++ efuse_addr++; ++ efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest); ++ if (!ALL_WORDS_DISABLED(efuse_data)) { ++ hoffset = ((tmp_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); ++ hworden = efuse_data & 0x0F; ++ } else { ++ DBG_88E("Error, All words disabled\n"); ++ efuse_addr++; ++ continue; ++ } ++ } else { ++ hoffset = (efuse_data >> 4) & 0x0F; ++ hworden = efuse_data & 0x0F; ++ } ++ word_cnts = Efuse_CalculateWordCnts(hworden); ++ bDataEmpty = true; ++ ++ if (hoffset == offset) { ++ for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) { ++ if (efuse_OneByteRead(pAdapter, efuse_addr + 1 + tmpidx, &efuse_data, bPseudoTest)) { ++ tmpdata[tmpidx] = efuse_data; ++ if (efuse_data != 0xff) ++ bDataEmpty = false; ++ } ++ } ++ if (!bDataEmpty) { ++ ReadState = PG_STATE_DATA; ++ } else {/* read next header */ ++ efuse_addr = efuse_addr + (word_cnts * 2) + 1; ++ ReadState = PG_STATE_HEADER; ++ } ++ } else {/* read next header */ ++ efuse_addr = efuse_addr + (word_cnts * 2) + 1; ++ ReadState = PG_STATE_HEADER; ++ } ++ } else { ++ bContinual = false; ++ } ++ } else if (ReadState & PG_STATE_DATA) { ++ /* Data section Read ------------- */ ++ efuse_WordEnableDataRead(hworden, tmpdata, data); ++ efuse_addr = efuse_addr + (word_cnts * 2) + 1; ++ ReadState = PG_STATE_HEADER; ++ } ++ ++ } ++ ++ if ((data[0] == 0xff) && (data[1] == 0xff) && (data[2] == 0xff) && (data[3] == 0xff) && ++ (data[4] == 0xff) && (data[5] == 0xff) && (data[6] == 0xff) && (data[7] == 0xff)) ++ return false; ++ else ++ return true; ++} ++ ++static int Hal_EfusePgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest) ++{ ++ int ret; ++ ++ ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest); ++ return ret; ++} ++ ++static int Hal_EfusePgPacketRead_Pseudo(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest) ++{ ++ int ret; ++ ++ ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest); ++ return ret; ++} ++ ++static int rtl8188e_Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest) ++{ ++ int ret; ++ ++ if (bPseudoTest) ++ ret = Hal_EfusePgPacketRead_Pseudo(pAdapter, offset, data, bPseudoTest); ++ else ++ ret = Hal_EfusePgPacketRead(pAdapter, offset, data, bPseudoTest); ++ return ret; ++} ++ ++static bool hal_EfuseFixHeaderProcess(struct adapter *pAdapter, u8 efuseType, struct pgpkt *pFixPkt, u16 *pAddr, bool bPseudoTest) ++{ ++ u8 originaldata[8], badworden = 0; ++ u16 efuse_addr = *pAddr; ++ u32 PgWriteSuccess = 0; ++ ++ memset((void *)originaldata, 0xff, 8); ++ ++ if (Efuse_PgPacketRead(pAdapter, pFixPkt->offset, originaldata, bPseudoTest)) { ++ /* check if data exist */ ++ badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pFixPkt->word_en, originaldata, bPseudoTest); ++ ++ if (badworden != 0xf) { /* write fail */ ++ PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pFixPkt->offset, badworden, originaldata, bPseudoTest); ++ ++ if (!PgWriteSuccess) ++ return false; ++ else ++ efuse_addr = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest); ++ } else { ++ efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1; ++ } ++ } else { ++ efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1; ++ } ++ *pAddr = efuse_addr; ++ return true; ++} ++ ++static bool hal_EfusePgPacketWrite2ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest) ++{ ++ bool bRet = false; ++ u16 efuse_addr = *pAddr, efuse_max_available_len = 0; ++ u8 pg_header = 0, tmp_header = 0, pg_header_temp = 0; ++ u8 repeatcnt = 0; ++ ++ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len, bPseudoTest); ++ ++ while (efuse_addr < efuse_max_available_len) { ++ pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F; ++ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); ++ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); ++ ++ while (tmp_header == 0xFF) { ++ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) ++ return false; ++ ++ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); ++ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); ++ } ++ ++ /* to write ext_header */ ++ if (tmp_header == pg_header) { ++ efuse_addr++; ++ pg_header_temp = pg_header; ++ pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en; ++ ++ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); ++ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); ++ ++ while (tmp_header == 0xFF) { ++ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) ++ return false; ++ ++ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); ++ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); ++ } ++ ++ if ((tmp_header & 0x0F) == 0x0F) { /* word_en PG fail */ ++ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) { ++ return false; ++ } else { ++ efuse_addr++; ++ continue; ++ } ++ } else if (pg_header != tmp_header) { /* offset PG fail */ ++ struct pgpkt fixPkt; ++ fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1); ++ fixPkt.word_en = tmp_header & 0x0F; ++ fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en); ++ if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest)) ++ return false; ++ } else { ++ bRet = true; ++ break; ++ } ++ } else if ((tmp_header & 0x1F) == 0x0F) { /* wrong extended header */ ++ efuse_addr += 2; ++ continue; ++ } ++ } ++ ++ *pAddr = efuse_addr; ++ return bRet; ++} ++ ++static bool hal_EfusePgPacketWrite1ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest) ++{ ++ bool bRet = false; ++ u8 pg_header = 0, tmp_header = 0; ++ u16 efuse_addr = *pAddr; ++ u8 repeatcnt = 0; ++ ++ pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en; ++ ++ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); ++ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); ++ ++ while (tmp_header == 0xFF) { ++ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) ++ return false; ++ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); ++ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); ++ } ++ ++ if (pg_header == tmp_header) { ++ bRet = true; ++ } else { ++ struct pgpkt fixPkt; ++ fixPkt.offset = (tmp_header >> 4) & 0x0F; ++ fixPkt.word_en = tmp_header & 0x0F; ++ fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en); ++ if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest)) ++ return false; ++ } ++ ++ *pAddr = efuse_addr; ++ return bRet; ++} ++ ++static bool hal_EfusePgPacketWriteData(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest) ++{ ++ u16 efuse_addr = *pAddr; ++ u8 badworden = 0; ++ u32 PgWriteSuccess = 0; ++ ++ badworden = 0x0f; ++ badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest); ++ if (badworden == 0x0F) { ++ /* write ok */ ++ return true; ++ } else { ++ /* reorganize other pg packet */ ++ PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest); ++ if (!PgWriteSuccess) ++ return false; ++ else ++ return true; ++ } ++} ++ ++static bool ++hal_EfusePgPacketWriteHeader( ++ struct adapter *pAdapter, ++ u8 efuseType, ++ u16 *pAddr, ++ struct pgpkt *pTargetPkt, ++ bool bPseudoTest) ++{ ++ bool bRet = false; ++ ++ if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE) ++ bRet = hal_EfusePgPacketWrite2ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest); ++ else ++ bRet = hal_EfusePgPacketWrite1ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest); ++ ++ return bRet; ++} ++ ++static bool wordEnMatched(struct pgpkt *pTargetPkt, struct pgpkt *pCurPkt, ++ u8 *pWden) ++{ ++ u8 match_word_en = 0x0F; /* default all words are disabled */ ++ ++ /* check if the same words are enabled both target and current PG packet */ ++ if (((pTargetPkt->word_en & BIT(0)) == 0) && ++ ((pCurPkt->word_en & BIT(0)) == 0)) ++ match_word_en &= ~BIT(0); /* enable word 0 */ ++ if (((pTargetPkt->word_en & BIT(1)) == 0) && ++ ((pCurPkt->word_en & BIT(1)) == 0)) ++ match_word_en &= ~BIT(1); /* enable word 1 */ ++ if (((pTargetPkt->word_en & BIT(2)) == 0) && ++ ((pCurPkt->word_en & BIT(2)) == 0)) ++ match_word_en &= ~BIT(2); /* enable word 2 */ ++ if (((pTargetPkt->word_en & BIT(3)) == 0) && ++ ((pCurPkt->word_en & BIT(3)) == 0)) ++ match_word_en &= ~BIT(3); /* enable word 3 */ ++ ++ *pWden = match_word_en; ++ ++ if (match_word_en != 0xf) ++ return true; ++ else ++ return false; ++} ++ ++static bool hal_EfuseCheckIfDatafollowed(struct adapter *pAdapter, u8 word_cnts, u16 startAddr, bool bPseudoTest) ++{ ++ bool bRet = false; ++ u8 i, efuse_data; ++ ++ for (i = 0; i < (word_cnts * 2); i++) { ++ if (efuse_OneByteRead(pAdapter, (startAddr + i), &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) ++ bRet = true; ++ } ++ return bRet; ++} ++ ++static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest) ++{ ++ bool bRet = false; ++ u8 i, efuse_data = 0, cur_header = 0; ++ u8 matched_wden = 0, badworden = 0; ++ u16 startAddr = 0, efuse_max_available_len = 0, efuse_max = 0; ++ struct pgpkt curPkt; ++ ++ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len, bPseudoTest); ++ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&efuse_max, bPseudoTest); ++ ++ if (efuseType == EFUSE_WIFI) { ++ if (bPseudoTest) { ++ startAddr = (u16)(fakeEfuseUsedBytes % EFUSE_REAL_CONTENT_LEN); ++ } else { ++ rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr); ++ startAddr %= EFUSE_REAL_CONTENT_LEN; ++ } ++ } else { ++ if (bPseudoTest) ++ startAddr = (u16)(fakeBTEfuseUsedBytes % EFUSE_REAL_CONTENT_LEN); ++ else ++ startAddr = (u16)(BTEfuseUsedBytes % EFUSE_REAL_CONTENT_LEN); ++ } ++ ++ while (1) { ++ if (startAddr >= efuse_max_available_len) { ++ bRet = false; ++ break; ++ } ++ ++ if (efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) { ++ if (EXT_HEADER(efuse_data)) { ++ cur_header = efuse_data; ++ startAddr++; ++ efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest); ++ if (ALL_WORDS_DISABLED(efuse_data)) { ++ bRet = false; ++ break; ++ } else { ++ curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); ++ curPkt.word_en = efuse_data & 0x0F; ++ } ++ } else { ++ cur_header = efuse_data; ++ curPkt.offset = (cur_header >> 4) & 0x0F; ++ curPkt.word_en = cur_header & 0x0F; ++ } ++ ++ curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en); ++ /* if same header is found but no data followed */ ++ /* write some part of data followed by the header. */ ++ if ((curPkt.offset == pTargetPkt->offset) && ++ (!hal_EfuseCheckIfDatafollowed(pAdapter, curPkt.word_cnts, startAddr + 1, bPseudoTest)) && ++ wordEnMatched(pTargetPkt, &curPkt, &matched_wden)) { ++ /* Here to write partial data */ ++ badworden = Efuse_WordEnableDataWrite(pAdapter, startAddr + 1, matched_wden, pTargetPkt->data, bPseudoTest); ++ if (badworden != 0x0F) { ++ u32 PgWriteSuccess = 0; ++ /* if write fail on some words, write these bad words again */ ++ ++ PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest); ++ ++ if (!PgWriteSuccess) { ++ bRet = false; /* write fail, return */ ++ break; ++ } ++ } ++ /* partial write ok, update the target packet for later use */ ++ for (i = 0; i < 4; i++) { ++ if ((matched_wden & (0x1 << i)) == 0) /* this word has been written */ ++ pTargetPkt->word_en |= (0x1 << i); /* disable the word */ ++ } ++ pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en); ++ } ++ /* read from next header */ ++ startAddr = startAddr + (curPkt.word_cnts * 2) + 1; ++ } else { ++ /* not used header, 0xff */ ++ *pAddr = startAddr; ++ bRet = true; ++ break; ++ } ++ } ++ return bRet; ++} ++ ++static bool ++hal_EfusePgCheckAvailableAddr( ++ struct adapter *pAdapter, ++ u8 efuseType, ++ bool bPseudoTest ++ ) ++{ ++ u16 efuse_max_available_len = 0; ++ ++ /* Change to check TYPE_EFUSE_MAP_LEN , because 8188E raw 256, logic map over 256. */ ++ EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&efuse_max_available_len, false); ++ ++ if (Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest) >= efuse_max_available_len) ++ return false; ++ return true; ++} ++ ++static void hal_EfuseConstructPGPkt(u8 offset, u8 word_en, u8 *pData, struct pgpkt *pTargetPkt) ++{ ++ memset((void *)pTargetPkt->data, 0xFF, sizeof(u8) * 8); ++ pTargetPkt->offset = offset; ++ pTargetPkt->word_en = word_en; ++ efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data); ++ pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en); ++} ++ ++static bool hal_EfusePgPacketWrite_8188e(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *pData, bool bPseudoTest) ++{ ++ struct pgpkt targetPkt; ++ u16 startAddr = 0; ++ u8 efuseType = EFUSE_WIFI; ++ ++ if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest)) ++ return false; ++ ++ hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt); ++ ++ if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) ++ return false; ++ ++ if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) ++ return false; ++ ++ if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) ++ return false; ++ ++ return true; ++} ++ ++static int Hal_EfusePgPacketWrite_Pseudo(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest) ++{ ++ int ret; ++ ++ ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest); ++ return ret; ++} ++ ++static int Hal_EfusePgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest) ++{ ++ int ret = 0; ++ ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest); ++ ++ return ret; ++} ++ ++static int rtl8188e_Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest) ++{ ++ int ret; ++ ++ if (bPseudoTest) ++ ret = Hal_EfusePgPacketWrite_Pseudo(pAdapter, offset, word_en, data, bPseudoTest); ++ else ++ ret = Hal_EfusePgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest); ++ return ret; ++} ++ ++static struct HAL_VERSION ReadChipVersion8188E(struct adapter *padapter) ++{ ++ u32 value32; ++ struct HAL_VERSION ChipVersion; ++ struct hal_data_8188e *pHalData; ++ ++ pHalData = GET_HAL_DATA(padapter); ++ ++ value32 = rtw_read32(padapter, REG_SYS_CFG); ++ ChipVersion.ICType = CHIP_8188E; ++ ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP); ++ ++ ChipVersion.RFType = RF_TYPE_1T1R; ++ ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC); ++ ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT; /* IC version (CUT) */ ++ ++ /* For regulator mode. by tynli. 2011.01.14 */ ++ pHalData->RegulatorMode = ((value32 & TRP_BT_EN) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR); ++ ++ ChipVersion.ROMVer = 0; /* ROM code version. */ ++ pHalData->MultiFunc = RT_MULTI_FUNC_NONE; ++ ++ dump_chip_info(ChipVersion); ++ ++ pHalData->VersionID = ChipVersion; ++ ++ if (IS_1T2R(ChipVersion)) { ++ pHalData->rf_type = RF_1T2R; ++ pHalData->NumTotalRFPath = 2; ++ } else if (IS_2T2R(ChipVersion)) { ++ pHalData->rf_type = RF_2T2R; ++ pHalData->NumTotalRFPath = 2; ++ } else { ++ pHalData->rf_type = RF_1T1R; ++ pHalData->NumTotalRFPath = 1; ++ } ++ ++ MSG_88E("RF_Type is %x!!\n", pHalData->rf_type); ++ ++ return ChipVersion; ++} ++ ++static void rtl8188e_read_chip_version(struct adapter *padapter) ++{ ++ ReadChipVersion8188E(padapter); ++} ++ ++static void rtl8188e_GetHalODMVar(struct adapter *Adapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet) ++{ ++} ++ ++static void rtl8188e_SetHalODMVar(struct adapter *Adapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct odm_dm_struct *podmpriv = &pHalData->odmpriv; ++ switch (eVariable) { ++ case HAL_ODM_STA_INFO: ++ { ++ struct sta_info *psta = (struct sta_info *)pValue1; ++ if (bSet) { ++ DBG_88E("### Set STA_(%d) info\n", psta->mac_id); ++ ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta); ++ ODM_RAInfo_Init(podmpriv, psta->mac_id); ++ } else { ++ DBG_88E("### Clean STA_(%d) info\n", psta->mac_id); ++ ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, NULL); ++ } ++ } ++ break; ++ case HAL_ODM_P2P_STATE: ++ ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet); ++ break; ++ case HAL_ODM_WIFI_DISPLAY_STATE: ++ ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet); ++ break; ++ default: ++ break; ++ } ++} ++ ++void rtl8188e_clone_haldata(struct adapter *dst_adapter, struct adapter *src_adapter) ++{ ++ memcpy(dst_adapter->HalData, src_adapter->HalData, dst_adapter->hal_data_sz); ++} ++ ++void rtl8188e_start_thread(struct adapter *padapter) ++{ ++} ++ ++void rtl8188e_stop_thread(struct adapter *padapter) ++{ ++} ++ ++static void hal_notch_filter_8188e(struct adapter *adapter, bool enable) ++{ ++ if (enable) { ++ DBG_88E("Enable notch filter\n"); ++ rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT(1)); ++ } else { ++ DBG_88E("Disable notch filter\n"); ++ rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT(1)); ++ } ++} ++void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc) ++{ ++ pHalFunc->free_hal_data = &rtl8188e_free_hal_data; ++ ++ pHalFunc->dm_init = &rtl8188e_init_dm_priv; ++ pHalFunc->dm_deinit = &rtl8188e_deinit_dm_priv; ++ ++ pHalFunc->read_chip_version = &rtl8188e_read_chip_version; ++ ++ pHalFunc->set_bwmode_handler = &PHY_SetBWMode8188E; ++ pHalFunc->set_channel_handler = &PHY_SwChnl8188E; ++ ++ pHalFunc->hal_dm_watchdog = &rtl8188e_HalDmWatchDog; ++ ++ pHalFunc->Add_RateATid = &rtl8188e_Add_RateATid; ++ pHalFunc->run_thread = &rtl8188e_start_thread; ++ pHalFunc->cancel_thread = &rtl8188e_stop_thread; ++ ++ pHalFunc->AntDivBeforeLinkHandler = &AntDivBeforeLink8188E; ++ pHalFunc->AntDivCompareHandler = &AntDivCompare8188E; ++ pHalFunc->read_bbreg = &rtl8188e_PHY_QueryBBReg; ++ pHalFunc->write_bbreg = &rtl8188e_PHY_SetBBReg; ++ pHalFunc->read_rfreg = &rtl8188e_PHY_QueryRFReg; ++ pHalFunc->write_rfreg = &rtl8188e_PHY_SetRFReg; ++ ++ /* Efuse related function */ ++ pHalFunc->EfusePowerSwitch = &rtl8188e_EfusePowerSwitch; ++ pHalFunc->ReadEFuse = &rtl8188e_ReadEFuse; ++ pHalFunc->EFUSEGetEfuseDefinition = &rtl8188e_EFUSE_GetEfuseDefinition; ++ pHalFunc->EfuseGetCurrentSize = &rtl8188e_EfuseGetCurrentSize; ++ pHalFunc->Efuse_PgPacketRead = &rtl8188e_Efuse_PgPacketRead; ++ pHalFunc->Efuse_PgPacketWrite = &rtl8188e_Efuse_PgPacketWrite; ++ pHalFunc->Efuse_WordEnableDataWrite = &rtl8188e_Efuse_WordEnableDataWrite; ++ ++ pHalFunc->sreset_init_value = &sreset_init_value; ++ pHalFunc->sreset_reset_value = &sreset_reset_value; ++ pHalFunc->silentreset = &rtl8188e_silentreset_for_specific_platform; ++ pHalFunc->sreset_xmit_status_check = &rtl8188e_sreset_xmit_status_check; ++ pHalFunc->sreset_linked_status_check = &rtl8188e_sreset_linked_status_check; ++ pHalFunc->sreset_get_wifi_status = &sreset_get_wifi_status; ++ ++ pHalFunc->GetHalODMVarHandler = &rtl8188e_GetHalODMVar; ++ pHalFunc->SetHalODMVarHandler = &rtl8188e_SetHalODMVar; ++ ++ pHalFunc->IOL_exec_cmds_sync = &rtl8188e_IOL_exec_cmds_sync; ++ ++ pHalFunc->hal_notch_filter = &hal_notch_filter_8188e; ++} ++ ++u8 GetEEPROMSize8188E(struct adapter *padapter) ++{ ++ u8 size = 0; ++ u32 cr; ++ ++ cr = rtw_read16(padapter, REG_9346CR); ++ /* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */ ++ size = (cr & BOOT_FROM_EEPROM) ? 6 : 4; ++ ++ MSG_88E("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46"); ++ ++ return size; ++} ++ ++/* */ ++/* */ ++/* LLT R/W/Init function */ ++/* */ ++/* */ ++static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data) ++{ ++ s32 status = _SUCCESS; ++ s32 count = 0; ++ u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); ++ u16 LLTReg = REG_LLT_INIT; ++ ++ rtw_write32(padapter, LLTReg, value); ++ ++ /* polling */ ++ do { ++ value = rtw_read32(padapter, LLTReg); ++ if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) ++ break; ++ ++ if (count > POLLING_LLT_THRESHOLD) { ++ status = _FAIL; ++ break; ++ } ++ } while (count++); ++ ++ return status; ++} ++ ++s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy) ++{ ++ s32 status = _FAIL; ++ u32 i; ++ u32 Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER;/* 176, 22k */ ++ ++ if (rtw_IOL_applied(padapter)) { ++ status = iol_InitLLTTable(padapter, txpktbuf_bndy); ++ } else { ++ for (i = 0; i < (txpktbuf_bndy - 1); i++) { ++ status = _LLTWrite(padapter, i, i + 1); ++ if (_SUCCESS != status) ++ return status; ++ } ++ ++ /* end of list */ ++ status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF); ++ if (_SUCCESS != status) ++ return status; ++ ++ /* Make the other pages as ring buffer */ ++ /* This ring buffer is used as beacon buffer if we config this MAC as two MAC transfer. */ ++ /* Otherwise used as local loopback buffer. */ ++ for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) { ++ status = _LLTWrite(padapter, i, (i + 1)); ++ if (_SUCCESS != status) ++ return status; ++ } ++ ++ /* Let last entry point to the start entry of ring buffer */ ++ status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy); ++ if (_SUCCESS != status) { ++ return status; ++ } ++ } ++ ++ return status; ++} ++ ++void ++Hal_InitPGData88E(struct adapter *padapter) ++{ ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); ++ ++ if (!pEEPROM->bautoload_fail_flag) { /* autoload OK. */ ++ if (!is_boot_from_eeprom(padapter)) { ++ /* Read EFUSE real map to shadow. */ ++ EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false); ++ } ++ } else {/* autoload fail */ ++ /* update to default value 0xFF */ ++ if (!is_boot_from_eeprom(padapter)) ++ EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false); ++ } ++} ++ ++void ++Hal_EfuseParseIDCode88E( ++ struct adapter *padapter, ++ u8 *hwinfo ++ ) ++{ ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); ++ u16 EEPROMId; ++ ++ /* Check 0x8129 again for making sure autoload status!! */ ++ EEPROMId = le16_to_cpu(*((__le16 *)hwinfo)); ++ if (EEPROMId != RTL_EEPROM_ID) { ++ pr_err("EEPROM ID(%#x) is invalid!!\n", EEPROMId); ++ pEEPROM->bautoload_fail_flag = true; ++ } else { ++ pEEPROM->bautoload_fail_flag = false; ++ } ++ ++ pr_info("EEPROM ID = 0x%04x\n", EEPROMId); ++} ++ ++static void Hal_ReadPowerValueFromPROM_8188E(struct txpowerinfo24g *pwrInfo24G, u8 *PROMContent, bool AutoLoadFail) ++{ ++ u32 rfPath, eeAddr = EEPROM_TX_PWR_INX_88E, group, TxCount = 0; ++ ++ memset(pwrInfo24G, 0, sizeof(struct txpowerinfo24g)); ++ ++ if (AutoLoadFail) { ++ for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) { ++ /* 2.4G default value */ ++ for (group = 0; group < MAX_CHNL_GROUP_24G; group++) { ++ pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX; ++ pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX; ++ } ++ for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) { ++ if (TxCount == 0) { ++ pwrInfo24G->BW20_Diff[rfPath][0] = EEPROM_DEFAULT_24G_HT20_DIFF; ++ pwrInfo24G->OFDM_Diff[rfPath][0] = EEPROM_DEFAULT_24G_OFDM_DIFF; ++ } else { ++ pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ } ++ } ++ } ++ return; ++ } ++ ++ for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) { ++ /* 2.4G default value */ ++ for (group = 0; group < MAX_CHNL_GROUP_24G; group++) { ++ pwrInfo24G->IndexCCK_Base[rfPath][group] = PROMContent[eeAddr++]; ++ if (pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF) ++ pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX; ++ } ++ for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) { ++ pwrInfo24G->IndexBW40_Base[rfPath][group] = PROMContent[eeAddr++]; ++ if (pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF) ++ pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX; ++ } ++ for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) { ++ if (TxCount == 0) { ++ pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0; ++ if (PROMContent[eeAddr] == 0xFF) { ++ pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_HT20_DIFF; ++ } else { ++ pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4; ++ if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */ ++ pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0; ++ } ++ ++ if (PROMContent[eeAddr] == 0xFF) { ++ pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_OFDM_DIFF; ++ } else { ++ pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f); ++ if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */ ++ pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0; ++ } ++ pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0; ++ eeAddr++; ++ } else { ++ if (PROMContent[eeAddr] == 0xFF) { ++ pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ } else { ++ pwrInfo24G->BW40_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4; ++ if (pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */ ++ pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0; ++ } ++ ++ if (PROMContent[eeAddr] == 0xFF) { ++ pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ } else { ++ pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f); ++ if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */ ++ pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0; ++ } ++ eeAddr++; ++ ++ if (PROMContent[eeAddr] == 0xFF) { ++ pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ } else { ++ pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4; ++ if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */ ++ pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0; ++ } ++ ++ if (PROMContent[eeAddr] == 0xFF) { ++ pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ } else { ++ pwrInfo24G->CCK_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f); ++ if (pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */ ++ pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0; ++ } ++ eeAddr++; ++ } ++ } ++ } ++} ++ ++static void hal_get_chnl_group_88e(u8 chnl, u8 *group) ++{ ++ if (chnl < 3) /* Channel 1-2 */ ++ *group = 0; ++ else if (chnl < 6) /* Channel 3-5 */ ++ *group = 1; ++ else if (chnl < 9) /* Channel 6-8 */ ++ *group = 2; ++ else if (chnl < 12) /* Channel 9-11 */ ++ *group = 3; ++ else if (chnl < 14) /* Channel 12-13 */ ++ *group = 4; ++ else if (chnl == 14) /* Channel 14 */ ++ *group = 5; ++} ++ ++void Hal_ReadPowerSavingMode88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail) ++{ ++ if (AutoLoadFail) { ++ padapter->pwrctrlpriv.bHWPowerdown = false; ++ padapter->pwrctrlpriv.bSupportRemoteWakeup = false; ++ } else { ++ /* hw power down mode selection , 0:rf-off / 1:power down */ ++ ++ if (padapter->registrypriv.hwpdn_mode == 2) ++ padapter->pwrctrlpriv.bHWPowerdown = (hwinfo[EEPROM_RF_FEATURE_OPTION_88E] & BIT(4)); ++ else ++ padapter->pwrctrlpriv.bHWPowerdown = padapter->registrypriv.hwpdn_mode; ++ ++ /* decide hw if support remote wakeup function */ ++ /* if hw supported, 8051 (SIE) will generate WeakUP signal(D+/D- toggle) when autoresume */ ++ padapter->pwrctrlpriv.bSupportRemoteWakeup = (hwinfo[EEPROM_USB_OPTIONAL_FUNCTION0] & BIT(1)) ? true : false; ++ ++ DBG_88E("%s...bHWPwrPindetect(%x)-bHWPowerdown(%x) , bSupportRemoteWakeup(%x)\n", __func__, ++ padapter->pwrctrlpriv.bHWPwrPindetect, padapter->pwrctrlpriv.bHWPowerdown, padapter->pwrctrlpriv.bSupportRemoteWakeup); ++ ++ DBG_88E("### PS params => power_mgnt(%x), usbss_enable(%x) ###\n", padapter->registrypriv.power_mgnt, padapter->registrypriv.usbss_enable); ++ } ++} ++ ++void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *PROMContent, bool AutoLoadFail) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct txpowerinfo24g pwrInfo24G; ++ u8 rfPath, ch, group; ++ u8 TxCount; ++ ++ Hal_ReadPowerValueFromPROM_8188E(&pwrInfo24G, PROMContent, AutoLoadFail); ++ ++ if (!AutoLoadFail) ++ pHalData->bTXPowerDataReadFromEEPORM = true; ++ ++ for (rfPath = 0; rfPath < pHalData->NumTotalRFPath; rfPath++) { ++ for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) { ++ hal_get_chnl_group_88e(ch, &group); ++ ++ pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][group]; ++ if (ch == 14) ++ pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][4]; ++ else ++ pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group]; ++ ++ DBG_88E("======= Path %d, Channel %d =======\n", rfPath, ch); ++ DBG_88E("Index24G_CCK_Base[%d][%d] = 0x%x\n", rfPath, ch, pHalData->Index24G_CCK_Base[rfPath][ch]); ++ DBG_88E("Index24G_BW40_Base[%d][%d] = 0x%x\n", rfPath, ch, pHalData->Index24G_BW40_Base[rfPath][ch]); ++ } ++ for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) { ++ pHalData->CCK_24G_Diff[rfPath][TxCount] = pwrInfo24G.CCK_Diff[rfPath][TxCount]; ++ pHalData->OFDM_24G_Diff[rfPath][TxCount] = pwrInfo24G.OFDM_Diff[rfPath][TxCount]; ++ pHalData->BW20_24G_Diff[rfPath][TxCount] = pwrInfo24G.BW20_Diff[rfPath][TxCount]; ++ pHalData->BW40_24G_Diff[rfPath][TxCount] = pwrInfo24G.BW40_Diff[rfPath][TxCount]; ++ DBG_88E("======= TxCount %d =======\n", TxCount); ++ DBG_88E("CCK_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->CCK_24G_Diff[rfPath][TxCount]); ++ DBG_88E("OFDM_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->OFDM_24G_Diff[rfPath][TxCount]); ++ DBG_88E("BW20_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->BW20_24G_Diff[rfPath][TxCount]); ++ DBG_88E("BW40_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->BW40_24G_Diff[rfPath][TxCount]); ++ } ++ } ++ ++ /* 2010/10/19 MH Add Regulator recognize for CU. */ ++ if (!AutoLoadFail) { ++ pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x7); /* bit0~2 */ ++ if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF) ++ pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION & 0x7); /* bit0~2 */ ++ } else { ++ pHalData->EEPROMRegulatory = 0; ++ } ++ DBG_88E("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory); ++} ++ ++void Hal_EfuseParseXtal_8188E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ ++ if (!AutoLoadFail) { ++ pHalData->CrystalCap = hwinfo[EEPROM_XTAL_88E]; ++ if (pHalData->CrystalCap == 0xFF) ++ pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E; ++ } else { ++ pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E; ++ } ++ DBG_88E("CrystalCap: 0x%2x\n", pHalData->CrystalCap); ++} ++ ++void Hal_EfuseParseBoardType88E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ ++ if (!AutoLoadFail) ++ pHalData->BoardType = ((hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0xE0) >> 5); ++ else ++ pHalData->BoardType = 0; ++ DBG_88E("Board Type: 0x%2x\n", pHalData->BoardType); ++} ++ ++void Hal_EfuseParseEEPROMVer88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ ++ if (!AutoLoadFail) { ++ pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_88E]; ++ if (pHalData->EEPROMVersion == 0xFF) ++ pHalData->EEPROMVersion = EEPROM_Default_Version; ++ } else { ++ pHalData->EEPROMVersion = 1; ++ } ++} ++ ++void rtl8188e_EfuseParseChnlPlan(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail) ++{ ++ padapter->mlmepriv.ChannelPlan = ++ hal_com_get_channel_plan(padapter, ++ hwinfo ? hwinfo[EEPROM_ChannelPlan_88E] : 0xFF, ++ padapter->registrypriv.channel_plan, ++ RT_CHANNEL_DOMAIN_WORLD_WIDE_13, AutoLoadFail); ++ ++ DBG_88E("mlmepriv.ChannelPlan = 0x%02x\n", padapter->mlmepriv.ChannelPlan); ++} ++ ++void Hal_EfuseParseCustomerID88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ ++ if (!AutoLoadFail) { ++ pHalData->EEPROMCustomerID = hwinfo[EEPROM_CUSTOMERID_88E]; ++ } else { ++ pHalData->EEPROMCustomerID = 0; ++ pHalData->EEPROMSubCustomerID = 0; ++ } ++ DBG_88E("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID); ++} ++ ++void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent, bool AutoLoadFail) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ struct registry_priv *registry_par = &pAdapter->registrypriv; ++ ++ if (!AutoLoadFail) { ++ /* Antenna Diversity setting. */ ++ if (registry_par->antdiv_cfg == 2) { /* 2:By EFUSE */ ++ pHalData->AntDivCfg = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x18) >> 3; ++ if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF) ++ pHalData->AntDivCfg = (EEPROM_DEFAULT_BOARD_OPTION & 0x18) >> 3; ++ } else { ++ pHalData->AntDivCfg = registry_par->antdiv_cfg; /* 0:OFF , 1:ON, 2:By EFUSE */ ++ } ++ ++ if (registry_par->antdiv_type == 0) { ++ /* If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead. */ ++ pHalData->TRxAntDivType = PROMContent[EEPROM_RF_ANTENNA_OPT_88E]; ++ if (pHalData->TRxAntDivType == 0xFF) ++ pHalData->TRxAntDivType = CG_TRX_HW_ANTDIV; /* For 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port) */ ++ } else { ++ pHalData->TRxAntDivType = registry_par->antdiv_type; ++ } ++ ++ if (pHalData->TRxAntDivType == CG_TRX_HW_ANTDIV || pHalData->TRxAntDivType == CGCS_RX_HW_ANTDIV) ++ pHalData->AntDivCfg = 1; /* 0xC1[3] is ignored. */ ++ } else { ++ pHalData->AntDivCfg = 0; ++ pHalData->TRxAntDivType = pHalData->TRxAntDivType; /* The value in the driver setting of device manager. */ ++ } ++ DBG_88E("EEPROM : AntDivCfg = %x, TRxAntDivType = %x\n", pHalData->AntDivCfg, pHalData->TRxAntDivType); ++} ++ ++void Hal_ReadThermalMeter_88E(struct adapter *Adapter, u8 *PROMContent, bool AutoloadFail) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ /* ThermalMeter from EEPROM */ ++ if (!AutoloadFail) ++ pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_88E]; ++ else ++ pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E; ++ ++ if (pHalData->EEPROMThermalMeter == 0xff || AutoloadFail) { ++ pHalData->bAPKThermalMeterIgnore = true; ++ pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E; ++ } ++ DBG_88E("ThermalMeter = 0x%x\n", pHalData->EEPROMThermalMeter); ++} ++ ++void Hal_InitChannelPlan(struct adapter *padapter) ++{ ++} ++ ++bool HalDetectPwrDownMode88E(struct adapter *Adapter) ++{ ++ u8 tmpvalue = 0; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv; ++ ++ EFUSE_ShadowRead(Adapter, 1, EEPROM_RF_FEATURE_OPTION_88E, (u32 *)&tmpvalue); ++ ++ /* 2010/08/25 MH INF priority > PDN Efuse value. */ ++ if (tmpvalue & BIT(4) && pwrctrlpriv->reg_pdnmode) ++ pHalData->pwrdown = true; ++ else ++ pHalData->pwrdown = false; ++ ++ DBG_88E("HalDetectPwrDownMode(): PDN =%d\n", pHalData->pwrdown); ++ ++ return pHalData->pwrdown; ++} /* HalDetectPwrDownMode */ ++ ++/* This function is used only for 92C to set REG_BCN_CTRL(0x550) register. */ ++/* We just reserve the value of the register in variable pHalData->RegBcnCtrlVal and then operate */ ++/* the value of the register via atomic operation. */ ++/* This prevents from race condition when setting this register. */ ++/* The value of pHalData->RegBcnCtrlVal is initialized in HwConfigureRTL8192CE() function. */ ++ ++void SetBcnCtrlReg(struct adapter *padapter, u8 SetBits, u8 ClearBits) ++{ ++ struct hal_data_8188e *pHalData; ++ ++ pHalData = GET_HAL_DATA(padapter); ++ ++ pHalData->RegBcnCtrlVal |= SetBits; ++ pHalData->RegBcnCtrlVal &= ~ClearBits; ++ ++ rtw_write8(padapter, REG_BCN_CTRL, (u8)pHalData->RegBcnCtrlVal); ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_mp.c b/drivers/staging/r8188eu/hal/rtl8188e_mp.c +new file mode 100644 +index 000000000000..fc13db705511 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_mp.c +@@ -0,0 +1,798 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188E_MP_C_ ++ ++#include "../include/drv_types.h" ++#include "../include/rtw_mp.h" ++#include "../include/rtl8188e_hal.h" ++#include "../include/rtl8188e_dm.h" ++ ++s32 Hal_SetPowerTracking(struct adapter *padapter, u8 enable) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct odm_dm_struct *pDM_Odm = &pHalData->odmpriv; ++ ++ if (!netif_running(padapter->pnetdev)) ++ return _FAIL; ++ ++ if (!check_fwstate(&padapter->mlmepriv, WIFI_MP_STATE)) ++ return _FAIL; ++ ++ if (enable) ++ pDM_Odm->RFCalibrateInfo.bTXPowerTracking = true; ++ else ++ pDM_Odm->RFCalibrateInfo.bTXPowerTrackingInit = false; ++ ++ return _SUCCESS; ++} ++ ++void Hal_GetPowerTracking(struct adapter *padapter, u8 *enable) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct odm_dm_struct *pDM_Odm = &pHalData->odmpriv; ++ ++ *enable = pDM_Odm->RFCalibrateInfo.TxPowerTrackControl; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: mpt_SwitchRfSetting ++ * ++ * Overview: Change RF Setting when we siwthc channel/rate/BW for MP. ++ * ++ * Input: struct adapter * pAdapter ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 01/08/2009 MHC Suggestion from SD3 Willis for 92S series. ++ * 01/09/2009 MHC Add CCK modification for 40MHZ. Suggestion from SD3. ++ * ++ *---------------------------------------------------------------------------*/ ++void Hal_mpt_SwitchRfSetting(struct adapter *pAdapter) ++{ ++ struct mp_priv *pmp = &pAdapter->mppriv; ++ ++ /* <20120525, Kordan> Dynamic mechanism for APK, asked by Dennis. */ ++ pmp->MptCtx.backup0x52_RF_A = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0); ++ pmp->MptCtx.backup0x52_RF_B = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_B, RF_0x52, 0x000F0); ++ PHY_SetRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0, 0xD); ++ PHY_SetRFReg(pAdapter, RF_PATH_B, RF_0x52, 0x000F0, 0xD); ++} ++/*---------------------------hal\rtl8192c\MPT_Phy.c---------------------------*/ ++ ++/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/ ++void Hal_MPT_CCKTxPowerAdjust(struct adapter *Adapter, bool bInCH14) ++{ ++ u32 TempVal = 0, TempVal2 = 0, TempVal3 = 0; ++ u32 CurrCCKSwingVal = 0, CCKSwingIndex = 12; ++ u8 i; ++ ++ /* get current cck swing value and check 0xa22 & 0xa23 later to match the table. */ ++ CurrCCKSwingVal = read_bbreg(Adapter, rCCK0_TxFilter1, bMaskHWord); ++ ++ if (!bInCH14) { ++ /* Readback the current bb cck swing value and compare with the table to */ ++ /* get the current swing index */ ++ for (i = 0; i < CCK_TABLE_SIZE; i++) { ++ if (((CurrCCKSwingVal & 0xff) == (u32)CCKSwingTable_Ch1_Ch13[i][0]) && ++ (((CurrCCKSwingVal & 0xff00) >> 8) == (u32)CCKSwingTable_Ch1_Ch13[i][1])) { ++ CCKSwingIndex = i; ++ break; ++ } ++ } ++ ++ /* Write 0xa22 0xa23 */ ++ TempVal = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][0] + ++ (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][1] << 8); ++ ++ /* Write 0xa24 ~ 0xa27 */ ++ TempVal2 = 0; ++ TempVal2 = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][2] + ++ (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][3] << 8) + ++ (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][4] << 16) + ++ (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][5] << 24); ++ ++ /* Write 0xa28 0xa29 */ ++ TempVal3 = 0; ++ TempVal3 = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][6] + ++ (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][7] << 8); ++ } else { ++ for (i = 0; i < CCK_TABLE_SIZE; i++) { ++ if (((CurrCCKSwingVal & 0xff) == (u32)CCKSwingTable_Ch14[i][0]) && ++ (((CurrCCKSwingVal & 0xff00) >> 8) == (u32)CCKSwingTable_Ch14[i][1])) { ++ CCKSwingIndex = i; ++ break; ++ } ++ } ++ ++ /* Write 0xa22 0xa23 */ ++ TempVal = CCKSwingTable_Ch14[CCKSwingIndex][0] + ++ (CCKSwingTable_Ch14[CCKSwingIndex][1] << 8); ++ ++ /* Write 0xa24 ~ 0xa27 */ ++ TempVal2 = 0; ++ TempVal2 = CCKSwingTable_Ch14[CCKSwingIndex][2] + ++ (CCKSwingTable_Ch14[CCKSwingIndex][3] << 8) + ++ (CCKSwingTable_Ch14[CCKSwingIndex][4] << 16) + ++ (CCKSwingTable_Ch14[CCKSwingIndex][5] << 24); ++ ++ /* Write 0xa28 0xa29 */ ++ TempVal3 = 0; ++ TempVal3 = CCKSwingTable_Ch14[CCKSwingIndex][6] + ++ (CCKSwingTable_Ch14[CCKSwingIndex][7] << 8); ++ } ++ ++ write_bbreg(Adapter, rCCK0_TxFilter1, bMaskHWord, TempVal); ++ write_bbreg(Adapter, rCCK0_TxFilter2, bMaskDWord, TempVal2); ++ write_bbreg(Adapter, rCCK0_DebugPort, bMaskLWord, TempVal3); ++} ++ ++void Hal_MPT_CCKTxPowerAdjustbyIndex(struct adapter *pAdapter, bool beven) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ struct mpt_context *pMptCtx = &pAdapter->mppriv.MptCtx; ++ struct odm_dm_struct *pDM_Odm = &pHalData->odmpriv; ++ s32 TempCCk; ++ u8 CCK_index, CCK_index_old = 0; ++ u8 Action = 0; /* 0: no action, 1: even->odd, 2:odd->even */ ++ s32 i = 0; ++ ++ if (!IS_92C_SERIAL(pHalData->VersionID)) ++ return; ++ if (beven && !pMptCtx->bMptIndexEven) { ++ /* odd->even */ ++ Action = 2; ++ pMptCtx->bMptIndexEven = true; ++ } else if (!beven && pMptCtx->bMptIndexEven) { ++ /* even->odd */ ++ Action = 1; ++ pMptCtx->bMptIndexEven = false; ++ } ++ ++ if (Action != 0) { ++ /* Query CCK default setting From 0xa24 */ ++ TempCCk = read_bbreg(pAdapter, rCCK0_TxFilter2, bMaskDWord) & bMaskCCK; ++ for (i = 0; i < CCK_TABLE_SIZE; i++) { ++ if (pDM_Odm->RFCalibrateInfo.bCCKinCH14) { ++ if (!memcmp((void *)&TempCCk, (void *)&CCKSwingTable_Ch14[i][2], 4)) { ++ CCK_index_old = (u8)i; ++ break; ++ } ++ } else { ++ if (!memcmp((void *)&TempCCk, (void *)&CCKSwingTable_Ch1_Ch13[i][2], 4)) { ++ CCK_index_old = (u8)i; ++ break; ++ } ++ } ++ } ++ ++ if (Action == 1) ++ CCK_index = CCK_index_old - 1; ++ else ++ CCK_index = CCK_index_old + 1; ++ ++ /* Adjust CCK according to gain index */ ++ if (!pDM_Odm->RFCalibrateInfo.bCCKinCH14) { ++ rtw_write8(pAdapter, 0xa22, CCKSwingTable_Ch1_Ch13[CCK_index][0]); ++ rtw_write8(pAdapter, 0xa23, CCKSwingTable_Ch1_Ch13[CCK_index][1]); ++ rtw_write8(pAdapter, 0xa24, CCKSwingTable_Ch1_Ch13[CCK_index][2]); ++ rtw_write8(pAdapter, 0xa25, CCKSwingTable_Ch1_Ch13[CCK_index][3]); ++ rtw_write8(pAdapter, 0xa26, CCKSwingTable_Ch1_Ch13[CCK_index][4]); ++ rtw_write8(pAdapter, 0xa27, CCKSwingTable_Ch1_Ch13[CCK_index][5]); ++ rtw_write8(pAdapter, 0xa28, CCKSwingTable_Ch1_Ch13[CCK_index][6]); ++ rtw_write8(pAdapter, 0xa29, CCKSwingTable_Ch1_Ch13[CCK_index][7]); ++ } else { ++ rtw_write8(pAdapter, 0xa22, CCKSwingTable_Ch14[CCK_index][0]); ++ rtw_write8(pAdapter, 0xa23, CCKSwingTable_Ch14[CCK_index][1]); ++ rtw_write8(pAdapter, 0xa24, CCKSwingTable_Ch14[CCK_index][2]); ++ rtw_write8(pAdapter, 0xa25, CCKSwingTable_Ch14[CCK_index][3]); ++ rtw_write8(pAdapter, 0xa26, CCKSwingTable_Ch14[CCK_index][4]); ++ rtw_write8(pAdapter, 0xa27, CCKSwingTable_Ch14[CCK_index][5]); ++ rtw_write8(pAdapter, 0xa28, CCKSwingTable_Ch14[CCK_index][6]); ++ rtw_write8(pAdapter, 0xa29, CCKSwingTable_Ch14[CCK_index][7]); ++ } ++ } ++} ++/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/ ++ ++/* ++ * SetChannel ++ * Description ++ * Use H2C command to change channel, ++ * not only modify rf register, but also other setting need to be done. ++ */ ++void Hal_SetChannel(struct adapter *pAdapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ struct mp_priv *pmp = &pAdapter->mppriv; ++ struct odm_dm_struct *pDM_Odm = &pHalData->odmpriv; ++ u8 eRFPath; ++ u8 channel = pmp->channel; ++ ++ /* set RF channel register */ ++ for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) ++ _write_rfreg(pAdapter, eRFPath, ODM_CHANNEL, 0x3FF, channel); ++ Hal_mpt_SwitchRfSetting(pAdapter); ++ ++ SelectChannel(pAdapter, channel); ++ ++ if (pHalData->CurrentChannel == 14 && !pDM_Odm->RFCalibrateInfo.bCCKinCH14) { ++ pDM_Odm->RFCalibrateInfo.bCCKinCH14 = true; ++ Hal_MPT_CCKTxPowerAdjust(pAdapter, pDM_Odm->RFCalibrateInfo.bCCKinCH14); ++ } else if (pHalData->CurrentChannel != 14 && pDM_Odm->RFCalibrateInfo.bCCKinCH14) { ++ pDM_Odm->RFCalibrateInfo.bCCKinCH14 = false; ++ Hal_MPT_CCKTxPowerAdjust(pAdapter, pDM_Odm->RFCalibrateInfo.bCCKinCH14); ++ } ++} ++ ++/* ++ * Notice ++ * Switch bandwitdth may change center frequency(channel) ++ */ ++void Hal_SetBandwidth(struct adapter *pAdapter) ++{ ++ struct mp_priv *pmp = &pAdapter->mppriv; ++ ++ SetBWMode(pAdapter, pmp->bandwidth, pmp->prime_channel_offset); ++ Hal_mpt_SwitchRfSetting(pAdapter); ++} ++ ++void Hal_SetCCKTxPower(struct adapter *pAdapter, u8 *TxPower) ++{ ++ u32 tmpval = 0; ++ ++ /* rf-A cck tx power */ ++ write_bbreg(pAdapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, TxPower[RF_PATH_A]); ++ tmpval = (TxPower[RF_PATH_A] << 16) | (TxPower[RF_PATH_A] << 8) | TxPower[RF_PATH_A]; ++ write_bbreg(pAdapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); ++ ++ /* rf-B cck tx power */ ++ write_bbreg(pAdapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, TxPower[RF_PATH_B]); ++ tmpval = (TxPower[RF_PATH_B] << 16) | (TxPower[RF_PATH_B] << 8) | TxPower[RF_PATH_B]; ++ write_bbreg(pAdapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, tmpval); ++} ++ ++void Hal_SetOFDMTxPower(struct adapter *pAdapter, u8 *TxPower) ++{ ++ u32 TxAGC = 0; ++ u8 tmpval = 0; ++ ++ /* HT Tx-rf(A) */ ++ tmpval = TxPower[RF_PATH_A]; ++ TxAGC = (tmpval << 24) | (tmpval << 16) | (tmpval << 8) | tmpval; ++ ++ write_bbreg(pAdapter, rTxAGC_A_Rate18_06, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_A_Rate54_24, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_A_Mcs03_Mcs00, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_A_Mcs07_Mcs04, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_A_Mcs11_Mcs08, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_A_Mcs15_Mcs12, bMaskDWord, TxAGC); ++ ++ /* HT Tx-rf(B) */ ++ tmpval = TxPower[RF_PATH_B]; ++ TxAGC = (tmpval << 24) | (tmpval << 16) | (tmpval << 8) | tmpval; ++ ++ write_bbreg(pAdapter, rTxAGC_B_Rate18_06, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_B_Rate54_24, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_B_Mcs03_Mcs00, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_B_Mcs07_Mcs04, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_B_Mcs11_Mcs08, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_B_Mcs15_Mcs12, bMaskDWord, TxAGC); ++} ++ ++void Hal_SetAntennaPathPower(struct adapter *pAdapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ u8 TxPowerLevel[RF_PATH_MAX]; ++ u8 rfPath; ++ ++ TxPowerLevel[RF_PATH_A] = pAdapter->mppriv.txpoweridx; ++ TxPowerLevel[RF_PATH_B] = pAdapter->mppriv.txpoweridx_b; ++ ++ switch (pAdapter->mppriv.antenna_tx) { ++ case ANTENNA_A: ++ default: ++ rfPath = RF_PATH_A; ++ break; ++ case ANTENNA_B: ++ rfPath = RF_PATH_B; ++ break; ++ case ANTENNA_C: ++ rfPath = RF_PATH_C; ++ break; ++ } ++ ++ switch (pHalData->rf_chip) { ++ case RF_8225: ++ case RF_8256: ++ case RF_6052: ++ Hal_SetCCKTxPower(pAdapter, TxPowerLevel); ++ if (pAdapter->mppriv.rateidx < MPT_RATE_6M) /* CCK rate */ ++ Hal_MPT_CCKTxPowerAdjustbyIndex(pAdapter, TxPowerLevel[rfPath] % 2 == 0); ++ Hal_SetOFDMTxPower(pAdapter, TxPowerLevel); ++ break; ++ default: ++ break; ++ } ++} ++ ++void Hal_SetTxPower(struct adapter *pAdapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ u8 TxPower = pAdapter->mppriv.txpoweridx; ++ u8 TxPowerLevel[RF_PATH_MAX]; ++ u8 rf, rfPath; ++ ++ for (rf = 0; rf < RF_PATH_MAX; rf++) ++ TxPowerLevel[rf] = TxPower; ++ ++ switch (pAdapter->mppriv.antenna_tx) { ++ case ANTENNA_A: ++ default: ++ rfPath = RF_PATH_A; ++ break; ++ case ANTENNA_B: ++ rfPath = RF_PATH_B; ++ break; ++ case ANTENNA_C: ++ rfPath = RF_PATH_C; ++ break; ++ } ++ ++ switch (pHalData->rf_chip) { ++ /* 2008/09/12 MH Test only !! We enable the TX power tracking for MP!!!!! */ ++ /* We should call normal driver API later!! */ ++ case RF_8225: ++ case RF_8256: ++ case RF_6052: ++ Hal_SetCCKTxPower(pAdapter, TxPowerLevel); ++ if (pAdapter->mppriv.rateidx < MPT_RATE_6M) /* CCK rate */ ++ Hal_MPT_CCKTxPowerAdjustbyIndex(pAdapter, TxPowerLevel[rfPath] % 2 == 0); ++ Hal_SetOFDMTxPower(pAdapter, TxPowerLevel); ++ break; ++ default: ++ break; ++ } ++} ++ ++void Hal_SetDataRate(struct adapter *pAdapter) ++{ ++ Hal_mpt_SwitchRfSetting(pAdapter); ++} ++ ++void Hal_SetAntenna(struct adapter *pAdapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ ++ struct ant_sel_ofdm *p_ofdm_tx; /* OFDM Tx register */ ++ struct ant_sel_cck *p_cck_txrx; ++ u8 r_rx_antenna_ofdm = 0, r_ant_select_cck_val = 0; ++ u8 chgTx = 0, chgRx = 0; ++ u32 r_ant_select_ofdm_val = 0, r_ofdm_tx_en_val = 0; ++ ++ p_ofdm_tx = (struct ant_sel_ofdm *)&r_ant_select_ofdm_val; ++ p_cck_txrx = (struct ant_sel_cck *)&r_ant_select_cck_val; ++ ++ p_ofdm_tx->r_ant_ht1 = 0x1; ++ p_ofdm_tx->r_ant_ht2 = 0x2; /* Second TX RF path is A */ ++ p_ofdm_tx->r_ant_non_ht = 0x3; /* 0x1+0x2=0x3 */ ++ ++ switch (pAdapter->mppriv.antenna_tx) { ++ case ANTENNA_A: ++ p_ofdm_tx->r_tx_antenna = 0x1; ++ r_ofdm_tx_en_val = 0x1; ++ p_ofdm_tx->r_ant_l = 0x1; ++ p_ofdm_tx->r_ant_ht_s1 = 0x1; ++ p_ofdm_tx->r_ant_non_ht_s1 = 0x1; ++ p_cck_txrx->r_ccktx_enable = 0x8; ++ chgTx = 1; ++ ++ /* From SD3 Willis suggestion !!! Set RF A=TX and B as standby */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 1); ++ r_ofdm_tx_en_val = 0x3; ++ ++ /* Power save */ ++ ++ /* We need to close RFB by SW control */ ++ if (pHalData->rf_type == RF_2T2R) { ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(26), 1); ++ PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT(10), 0); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT(1), 1); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT(17), 0); ++ } ++ break; ++ case ANTENNA_B: ++ p_ofdm_tx->r_tx_antenna = 0x2; ++ r_ofdm_tx_en_val = 0x2; ++ p_ofdm_tx->r_ant_l = 0x2; ++ p_ofdm_tx->r_ant_ht_s1 = 0x2; ++ p_ofdm_tx->r_ant_non_ht_s1 = 0x2; ++ p_cck_txrx->r_ccktx_enable = 0x4; ++ chgTx = 1; ++ /* From SD3 Willis suggestion !!! Set RF A as standby */ ++ PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 1); ++ PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2); ++ ++ /* Power save */ ++ /* cosa r_ant_select_ofdm_val = 0x22222222; */ ++ ++ /* 2008/10/31 MH From SD3 Willi's suggestion. We must read RF 1T table. */ ++ /* 2009/01/08 MH From Sd3 Willis. We need to close RFA by SW control */ ++ if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_1T2R) { ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(10), 1); ++ PHY_SetBBReg(pAdapter, rFPGA0_XA_RFInterfaceOE, BIT(10), 0); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT(1), 0); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT(17), 1); ++ } ++ break; ++ case ANTENNA_AB: /* For 8192S */ ++ p_ofdm_tx->r_tx_antenna = 0x3; ++ r_ofdm_tx_en_val = 0x3; ++ p_ofdm_tx->r_ant_l = 0x3; ++ p_ofdm_tx->r_ant_ht_s1 = 0x3; ++ p_ofdm_tx->r_ant_non_ht_s1 = 0x3; ++ p_cck_txrx->r_ccktx_enable = 0xC; ++ chgTx = 1; ++ ++ /* From SD3 Willis suggestion !!! Set RF B as standby */ ++ PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2); ++ PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2); ++ ++ /* Disable Power save */ ++ /* cosa r_ant_select_ofdm_val = 0x3321333; */ ++ /* 2009/01/08 MH From Sd3 Willis. We need to enable RFA/B by SW control */ ++ if (pHalData->rf_type == RF_2T2R) { ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT(1), 1); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT(17), 1); ++ } ++ break; ++ default: ++ break; ++ } ++ ++ /* r_rx_antenna_ofdm, bit0=A, bit1=B, bit2=C, bit3=D */ ++ /* r_cckrx_enable : CCK default, 0=A, 1=B, 2=C, 3=D */ ++ /* r_cckrx_enable_2 : CCK option, 0=A, 1=B, 2=C, 3=D */ ++ switch (pAdapter->mppriv.antenna_rx) { ++ case ANTENNA_A: ++ r_rx_antenna_ofdm = 0x1; /* A */ ++ p_cck_txrx->r_cckrx_enable = 0x0; /* default: A */ ++ p_cck_txrx->r_cckrx_enable_2 = 0x0; /* option: A */ ++ chgRx = 1; ++ break; ++ case ANTENNA_B: ++ r_rx_antenna_ofdm = 0x2; /* B */ ++ p_cck_txrx->r_cckrx_enable = 0x1; /* default: B */ ++ p_cck_txrx->r_cckrx_enable_2 = 0x1; /* option: B */ ++ chgRx = 1; ++ break; ++ case ANTENNA_AB: ++ r_rx_antenna_ofdm = 0x3; /* AB */ ++ p_cck_txrx->r_cckrx_enable = 0x0; /* default:A */ ++ p_cck_txrx->r_cckrx_enable_2 = 0x1; /* option:B */ ++ chgRx = 1; ++ break; ++ default: ++ break; ++ } ++ ++ if (chgTx && chgRx) { ++ switch (pHalData->rf_chip) { ++ case RF_8225: ++ case RF_8256: ++ case RF_6052: ++ /* r_ant_sel_cck_val = r_ant_select_cck_val; */ ++ PHY_SetBBReg(pAdapter, rFPGA1_TxInfo, 0x7fffffff, r_ant_select_ofdm_val); /* OFDM Tx */ ++ PHY_SetBBReg(pAdapter, rFPGA0_TxInfo, 0x0000000f, r_ofdm_tx_en_val); /* OFDM Tx */ ++ PHY_SetBBReg(pAdapter, rOFDM0_TRxPathEnable, 0x0000000f, r_rx_antenna_ofdm); /* OFDM Rx */ ++ PHY_SetBBReg(pAdapter, rOFDM1_TRxPathEnable, 0x0000000f, r_rx_antenna_ofdm); /* OFDM Rx */ ++ PHY_SetBBReg(pAdapter, rCCK0_AFESetting, bMaskByte3, r_ant_select_cck_val); /* CCK TxRx */ ++ ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++s32 Hal_SetThermalMeter(struct adapter *pAdapter, u8 target_ther) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ ++ if (!netif_running(pAdapter->pnetdev)) ++ return _FAIL; ++ ++ if (!check_fwstate(&pAdapter->mlmepriv, WIFI_MP_STATE)) ++ return _FAIL; ++ ++ target_ther &= 0xff; ++ if (target_ther < 0x07) ++ target_ther = 0x07; ++ else if (target_ther > 0x1d) ++ target_ther = 0x1d; ++ ++ pHalData->EEPROMThermalMeter = target_ther; ++ ++ return _SUCCESS; ++} ++ ++void Hal_TriggerRFThermalMeter(struct adapter *pAdapter) ++{ ++ _write_rfreg(pAdapter, RF_PATH_A, RF_T_METER_88E, BIT(17) | BIT(16), 0x03); ++} ++ ++u8 Hal_ReadRFThermalMeter(struct adapter *pAdapter) ++{ ++ u32 ThermalValue = 0; ++ ++ ThermalValue = _read_rfreg(pAdapter, RF_PATH_A, RF_T_METER_88E, 0xfc00); ++ return (u8)ThermalValue; ++} ++ ++void Hal_GetThermalMeter(struct adapter *pAdapter, u8 *value) ++{ ++ Hal_TriggerRFThermalMeter(pAdapter); ++ msleep(1000); ++ *value = Hal_ReadRFThermalMeter(pAdapter); ++} ++ ++void Hal_SetSingleCarrierTx(struct adapter *pAdapter, u8 bStart) ++{ ++ pAdapter->mppriv.MptCtx.bSingleCarrier = bStart; ++ if (bStart) { ++ /* Start Single Carrier. */ ++ /* 1. if OFDM block on? */ ++ if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) ++ write_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable);/* set OFDM block on */ ++ ++ /* 2. set CCK test mode off, set to CCK normal mode */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, bDisable); ++ /* 3. turn on scramble setting */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); ++ /* 4. Turn On Single Carrier Tx and turn off the other test modes. */ ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bEnable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); ++ /* for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); ++ } else { ++ /* Stop Single Carrier. */ ++ /* Turn off all test modes. */ ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); ++ msleep(10); ++ ++ /* BB Reset */ ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); ++ ++ /* Stop for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); ++ } ++} ++ ++void Hal_SetSingleToneTx(struct adapter *pAdapter, u8 bStart) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ bool is92C = IS_92C_SERIAL(pHalData->VersionID); ++ ++ u8 rfPath; ++ u32 reg58 = 0x0; ++ switch (pAdapter->mppriv.antenna_tx) { ++ case ANTENNA_A: ++ default: ++ rfPath = RF_PATH_A; ++ break; ++ case ANTENNA_B: ++ rfPath = RF_PATH_B; ++ break; ++ case ANTENNA_C: ++ rfPath = RF_PATH_C; ++ break; ++ } ++ ++ pAdapter->mppriv.MptCtx.bSingleTone = bStart; ++ if (bStart) { ++ /* Start Single Tone. */ ++ /* <20120326, Kordan> To amplify the power of tone for Xtal calibration. (asked by Edlu) */ ++ if (IS_HARDWARE_TYPE_8188E(pAdapter)) { ++ reg58 = PHY_QueryRFReg(pAdapter, RF_PATH_A, LNA_Low_Gain_3, bRFRegOffsetMask); ++ reg58 &= 0xFFFFFFF0; ++ reg58 += 2; ++ PHY_SetRFReg(pAdapter, RF_PATH_A, LNA_Low_Gain_3, bRFRegOffsetMask, reg58); ++ } ++ PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bCCKEn, 0x0); ++ PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 0x0); ++ ++ if (is92C) { ++ _write_rfreg(pAdapter, RF_PATH_A, 0x21, BIT(19), 0x01); ++ rtw_usleep_os(100); ++ if (rfPath == RF_PATH_A) ++ write_rfreg(pAdapter, RF_PATH_B, 0x00, 0x10000); /* PAD all on. */ ++ else if (rfPath == RF_PATH_B) ++ write_rfreg(pAdapter, RF_PATH_A, 0x00, 0x10000); /* PAD all on. */ ++ write_rfreg(pAdapter, rfPath, 0x00, 0x2001f); /* PAD all on. */ ++ rtw_usleep_os(100); ++ } else { ++ write_rfreg(pAdapter, rfPath, 0x21, 0xd4000); ++ rtw_usleep_os(100); ++ write_rfreg(pAdapter, rfPath, 0x00, 0x2001f); /* PAD all on. */ ++ rtw_usleep_os(100); ++ } ++ ++ /* for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); ++ ++ } else { ++ /* Stop Single Tone. */ ++ /* <20120326, Kordan> To amplify the power of tone for Xtal calibration. (asked by Edlu) */ ++ /* <20120326, Kordan> Only in single tone mode. (asked by Edlu) */ ++ if (IS_HARDWARE_TYPE_8188E(pAdapter)) { ++ reg58 = PHY_QueryRFReg(pAdapter, RF_PATH_A, LNA_Low_Gain_3, bRFRegOffsetMask); ++ reg58 &= 0xFFFFFFF0; ++ PHY_SetRFReg(pAdapter, RF_PATH_A, LNA_Low_Gain_3, bRFRegOffsetMask, reg58); ++ } ++ write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, 0x1); ++ write_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 0x1); ++ if (is92C) { ++ _write_rfreg(pAdapter, RF_PATH_A, 0x21, BIT(19), 0x00); ++ rtw_usleep_os(100); ++ write_rfreg(pAdapter, RF_PATH_A, 0x00, 0x32d75); /* PAD all on. */ ++ write_rfreg(pAdapter, RF_PATH_B, 0x00, 0x32d75); /* PAD all on. */ ++ rtw_usleep_os(100); ++ } else { ++ write_rfreg(pAdapter, rfPath, 0x21, 0x54000); ++ rtw_usleep_os(100); ++ write_rfreg(pAdapter, rfPath, 0x00, 0x30000); /* PAD all on. */ ++ rtw_usleep_os(100); ++ } ++ ++ /* Stop for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); ++ } ++} ++ ++void Hal_SetCarrierSuppressionTx(struct adapter *pAdapter, u8 bStart) ++{ ++ pAdapter->mppriv.MptCtx.bCarrierSuppression = bStart; ++ if (bStart) { ++ /* Start Carrier Suppression. */ ++ if (pAdapter->mppriv.rateidx <= MPT_RATE_11M) { ++ /* 1. if CCK block on? */ ++ if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn)) ++ write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);/* set CCK block on */ ++ ++ /* Turn Off All Test Mode */ ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); ++ ++ write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); /* transmit mode */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKScramble, 0x0); /* turn off scramble setting */ ++ ++ /* Set CCK Tx Test Rate */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKTxRate, 0x0); /* Set FTxRate to 1Mbps */ ++ } ++ ++ /* for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); ++ } else { ++ /* Stop Carrier Suppression. */ ++ if (pAdapter->mppriv.rateidx <= MPT_RATE_11M) { ++ write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); /* normal mode */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKScramble, 0x1); /* turn on scramble setting */ ++ ++ /* BB Reset */ ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); ++ } ++ ++ /* Stop for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); ++ } ++} ++ ++void Hal_SetCCKContinuousTx(struct adapter *pAdapter, u8 bStart) ++{ ++ u32 cckrate; ++ ++ if (bStart) { ++ /* 1. if CCK block on? */ ++ if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn)) ++ write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);/* set CCK block on */ ++ ++ /* Turn Off All Test Mode */ ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); ++ /* Set CCK Tx Test Rate */ ++ cckrate = pAdapter->mppriv.rateidx; ++ write_bbreg(pAdapter, rCCK0_System, bCCKTxRate, cckrate); ++ write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); /* transmit mode */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); /* turn on scramble setting */ ++ ++ /* for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); ++ } else { ++ write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); /* normal mode */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); /* turn on scramble setting */ ++ ++ /* BB Reset */ ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); ++ ++ /* Stop for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); ++ } ++ ++ pAdapter->mppriv.MptCtx.bCckContTx = bStart; ++ pAdapter->mppriv.MptCtx.bOfdmContTx = false; ++} /* mpt_StartCckContTx */ ++ ++void Hal_SetOFDMContinuousTx(struct adapter *pAdapter, u8 bStart) ++{ ++ if (bStart) { ++ /* 1. if OFDM block on? */ ++ if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) ++ write_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable);/* set OFDM block on */ ++ ++ /* 2. set CCK test mode off, set to CCK normal mode */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, bDisable); ++ ++ /* 3. turn on scramble setting */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); ++ /* 4. Turn On Continue Tx and turn off the other test modes. */ ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bEnable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); ++ ++ /* for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); ++ ++ } else { ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); ++ /* Delay 10 ms */ ++ msleep(10); ++ /* BB Reset */ ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); ++ ++ /* Stop for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); ++ } ++ ++ pAdapter->mppriv.MptCtx.bCckContTx = false; ++ pAdapter->mppriv.MptCtx.bOfdmContTx = bStart; ++} /* mpt_StartOfdmContTx */ ++ ++void Hal_SetContinuousTx(struct adapter *pAdapter, u8 bStart) ++{ ++ pAdapter->mppriv.MptCtx.bStartContTx = bStart; ++ if (pAdapter->mppriv.rateidx <= MPT_RATE_11M) ++ Hal_SetCCKContinuousTx(pAdapter, bStart); ++ else if ((pAdapter->mppriv.rateidx >= MPT_RATE_6M) && ++ (pAdapter->mppriv.rateidx <= MPT_RATE_MCS15)) ++ Hal_SetOFDMContinuousTx(pAdapter, bStart); ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c +new file mode 100644 +index 000000000000..30a9dca8f453 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c +@@ -0,0 +1,1105 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188E_PHYCFG_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtw_iol.h" ++#include "../include/rtl8188e_hal.h" ++ ++/*---------------------------Define Local Constant---------------------------*/ ++/* Channel switch:The size of command tables for switch channel*/ ++#define MAX_PRECMD_CNT 16 ++#define MAX_RFDEPENDCMD_CNT 16 ++#define MAX_POSTCMD_CNT 16 ++ ++#define MAX_DOZE_WAITING_TIMES_9x 64 ++ ++/*---------------------------Define Local Constant---------------------------*/ ++ ++/*------------------------Define global variable-----------------------------*/ ++ ++/*------------------------Define local variable------------------------------*/ ++ ++/*--------------------Define export function prototype-----------------------*/ ++/* Please refer to header file */ ++/*--------------------Define export function prototype-----------------------*/ ++ ++/*----------------------------Function Body----------------------------------*/ ++/* */ ++/* 1. BB register R/W API */ ++/* */ ++ ++/** ++* Function: phy_CalculateBitShift ++* ++* OverView: Get shifted position of the BitMask ++* ++* Input: ++* u32 BitMask, ++* ++* Output: none ++* Return: u32 Return the shift bit bit position of the mask ++*/ ++static u32 phy_CalculateBitShift(u32 BitMask) ++{ ++ u32 i; ++ ++ for (i = 0; i <= 31; i++) { ++ if (((BitMask >> i) & 0x1) == 1) ++ break; ++ } ++ return i; ++} ++ ++/** ++* Function: PHY_QueryBBReg ++* ++* OverView: Read "sepcific bits" from BB register ++* ++* Input: ++* struct adapter *Adapter, ++* u32 RegAddr, The target address to be readback ++* u32 BitMask The target bit position in the target address ++* to be readback ++* Output: None ++* Return: u32 Data The readback register value ++* Note: This function is equal to "GetRegSetting" in PHY programming guide ++*/ ++u32 ++rtl8188e_PHY_QueryBBReg( ++ struct adapter *Adapter, ++ u32 RegAddr, ++ u32 BitMask ++ ) ++{ ++ u32 ReturnValue = 0, OriginalValue, BitShift; ++ ++ OriginalValue = rtw_read32(Adapter, RegAddr); ++ BitShift = phy_CalculateBitShift(BitMask); ++ ReturnValue = (OriginalValue & BitMask) >> BitShift; ++ return ReturnValue; ++} ++ ++/** ++* Function: PHY_SetBBReg ++* ++* OverView: Write "Specific bits" to BB register (page 8~) ++* ++* Input: ++* struct adapter *Adapter, ++* u32 RegAddr, The target address to be modified ++* u32 BitMask The target bit position in the target address ++* to be modified ++* u32 Data The new register value in the target bit position ++* of the target address ++* ++* Output: None ++* Return: None ++* Note: This function is equal to "PutRegSetting" in PHY programming guide ++*/ ++ ++void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data) ++{ ++ u32 OriginalValue, BitShift; ++ ++ if (BitMask != bMaskDWord) { /* if not "double word" write */ ++ OriginalValue = rtw_read32(Adapter, RegAddr); ++ BitShift = phy_CalculateBitShift(BitMask); ++ Data = ((OriginalValue & (~BitMask)) | (Data << BitShift)); ++ } ++ ++ rtw_write32(Adapter, RegAddr, Data); ++} ++ ++/* */ ++/* 2. RF register R/W API */ ++/* */ ++/** ++* Function: phy_RFSerialRead ++* ++* OverView: Read regster from RF chips ++* ++* Input: ++* struct adapter *Adapter, ++* enum rf_radio_path eRFPath, Radio path of A/B/C/D ++* u32 Offset, The target address to be read ++* ++* Output: None ++* Return: u32 reback value ++* Note: Threre are three types of serial operations: ++* 1. Software serial write ++* 2. Hardware LSSI-Low Speed Serial Interface ++* 3. Hardware HSSI-High speed ++* serial write. Driver need to implement (1) and (2). ++* This function is equal to the combination of RF_ReadReg() and RFLSSIRead() ++*/ ++static u32 ++phy_RFSerialRead( ++ struct adapter *Adapter, ++ enum rf_radio_path eRFPath, ++ u32 Offset ++ ) ++{ ++ u32 retValue = 0; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct bb_reg_def *pPhyReg = &pHalData->PHYRegDef[eRFPath]; ++ u32 NewOffset; ++ u32 tmplong, tmplong2; ++ u8 RfPiEnable = 0; ++ /* */ ++ /* Make sure RF register offset is correct */ ++ /* */ ++ Offset &= 0xff; ++ ++ /* */ ++ /* Switch page for 8256 RF IC */ ++ /* */ ++ NewOffset = Offset; ++ ++ /* For 92S LSSI Read RFLSSIRead */ ++ /* For RF A/B write 0x824/82c(does not work in the future) */ ++ /* We must use 0x824 for RF A and B to execute read trigger */ ++ tmplong = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord); ++ if (eRFPath == RF_PATH_A) ++ tmplong2 = tmplong; ++ else ++ tmplong2 = PHY_QueryBBReg(Adapter, pPhyReg->rfHSSIPara2, bMaskDWord); ++ ++ tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset << 23) | bLSSIReadEdge; /* T65 RF */ ++ ++ PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord, tmplong & (~bLSSIReadEdge)); ++ udelay(10);/* PlatformStallExecution(10); */ ++ ++ PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, bMaskDWord, tmplong2); ++ udelay(100);/* PlatformStallExecution(100); */ ++ ++ udelay(10);/* PlatformStallExecution(10); */ ++ ++ if (eRFPath == RF_PATH_A) ++ RfPiEnable = (u8)PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter1, BIT(8)); ++ else if (eRFPath == RF_PATH_B) ++ RfPiEnable = (u8)PHY_QueryBBReg(Adapter, rFPGA0_XB_HSSIParameter1, BIT(8)); ++ ++ if (RfPiEnable) { /* Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */ ++ retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi, bLSSIReadBackData); ++ } else { /* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */ ++ retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack, bLSSIReadBackData); ++ } ++ return retValue; ++} ++ ++/** ++* Function: phy_RFSerialWrite ++* ++* OverView: Write data to RF register (page 8~) ++* ++* Input: ++* struct adapter *Adapter, ++* enum rf_radio_path eRFPath, Radio path of A/B/C/D ++* u32 Offset, The target address to be read ++* u32 Data The new register Data in the target bit position ++* of the target to be read ++* ++* Output: None ++* Return: None ++* Note: Threre are three types of serial operations: ++* 1. Software serial write ++* 2. Hardware LSSI-Low Speed Serial Interface ++* 3. Hardware HSSI-High speed ++* serial write. Driver need to implement (1) and (2). ++* This function is equal to the combination of RF_ReadReg() and RFLSSIRead() ++ * ++ * Note: For RF8256 only ++ * The total count of RTL8256(Zebra4) register is around 36 bit it only employs ++ * 4-bit RF address. RTL8256 uses "register mode control bit" (Reg00[12], Reg00[10]) ++ * to access register address bigger than 0xf. See "Appendix-4 in PHY Configuration ++ * programming guide" for more details. ++ * Thus, we define a sub-finction for RTL8526 register address conversion ++ * =========================================================== ++ * Register Mode RegCTL[1] RegCTL[0] Note ++ * (Reg00[12]) (Reg00[10]) ++ * =========================================================== ++ * Reg_Mode0 0 x Reg 0 ~15(0x0 ~ 0xf) ++ * ------------------------------------------------------------------ ++ * Reg_Mode1 1 0 Reg 16 ~30(0x1 ~ 0xf) ++ * ------------------------------------------------------------------ ++ * Reg_Mode2 1 1 Reg 31 ~ 45(0x1 ~ 0xf) ++ * ------------------------------------------------------------------ ++ * ++ * 2008/09/02 MH Add 92S RF definition ++ * ++ * ++ * ++*/ ++static void ++phy_RFSerialWrite( ++ struct adapter *Adapter, ++ enum rf_radio_path eRFPath, ++ u32 Offset, ++ u32 Data ++ ) ++{ ++ u32 DataAndAddr = 0; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct bb_reg_def *pPhyReg = &pHalData->PHYRegDef[eRFPath]; ++ u32 NewOffset; ++ ++ /* 2009/06/17 MH We can not execute IO for power save or other accident mode. */ ++ ++ Offset &= 0xff; ++ ++ /* */ ++ /* Switch page for 8256 RF IC */ ++ /* */ ++ NewOffset = Offset; ++ ++ /* */ ++ /* Put write addr in [5:0] and write data in [31:16] */ ++ /* */ ++ DataAndAddr = ((NewOffset << 20) | (Data & 0x000fffff)) & 0x0fffffff; /* T65 RF */ ++ ++ /* */ ++ /* Write Operation */ ++ /* */ ++ PHY_SetBBReg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); ++} ++ ++/** ++* Function: PHY_QueryRFReg ++* ++* OverView: Query "Specific bits" to RF register (page 8~) ++* ++* Input: ++* struct adapter *Adapter, ++* enum rf_radio_path eRFPath, Radio path of A/B/C/D ++* u32 RegAddr, The target address to be read ++* u32 BitMask The target bit position in the target address ++* to be read ++* ++* Output: None ++* Return: u32 Readback value ++* Note: This function is equal to "GetRFRegSetting" in PHY programming guide ++*/ ++u32 rtl8188e_PHY_QueryRFReg(struct adapter *Adapter, enum rf_radio_path eRFPath, ++ u32 RegAddr, u32 BitMask) ++{ ++ u32 Original_Value, Readback_Value, BitShift; ++ ++ Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr); ++ ++ BitShift = phy_CalculateBitShift(BitMask); ++ Readback_Value = (Original_Value & BitMask) >> BitShift; ++ return Readback_Value; ++} ++ ++/** ++* Function: PHY_SetRFReg ++* ++* OverView: Write "Specific bits" to RF register (page 8~) ++* ++* Input: ++* struct adapter *Adapter, ++* enum rf_radio_path eRFPath, Radio path of A/B/C/D ++* u32 RegAddr, The target address to be modified ++* u32 BitMask The target bit position in the target address ++* to be modified ++* u32 Data The new register Data in the target bit position ++* of the target address ++* ++* Output: None ++* Return: None ++* Note: This function is equal to "PutRFRegSetting" in PHY programming guide ++*/ ++void ++rtl8188e_PHY_SetRFReg( ++ struct adapter *Adapter, ++ enum rf_radio_path eRFPath, ++ u32 RegAddr, ++ u32 BitMask, ++ u32 Data ++ ) ++{ ++ u32 Original_Value, BitShift; ++ ++ /* RF data is 12 bits only */ ++ if (BitMask != bRFRegOffsetMask) { ++ Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr); ++ BitShift = phy_CalculateBitShift(BitMask); ++ Data = ((Original_Value & (~BitMask)) | (Data << BitShift)); ++ } ++ ++ phy_RFSerialWrite(Adapter, eRFPath, RegAddr, Data); ++} ++ ++/* */ ++/* 3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */ ++/* */ ++ ++/*----------------------------------------------------------------------------- ++ * Function: PHY_MACConfig8192C ++ * ++ * Overview: Condig MAC by header file or parameter file. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 08/12/2008 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++s32 PHY_MACConfig8188E(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ int rtStatus = _SUCCESS; ++ ++ /* */ ++ /* Config MAC */ ++ /* */ ++ if (HAL_STATUS_FAILURE == ODM_ConfigMACWithHeaderFile(&pHalData->odmpriv)) ++ rtStatus = _FAIL; ++ ++ /* 2010.07.13 AMPDU aggregation number B */ ++ rtw_write16(Adapter, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); ++ ++ return rtStatus; ++} ++ ++/** ++* Function: phy_InitBBRFRegisterDefinition ++* ++* OverView: Initialize Register definition offset for Radio Path A/B/C/D ++* ++* Input: ++* struct adapter *Adapter, ++* ++* Output: None ++* Return: None ++* Note: The initialization value is constant and it should never be changes ++*/ ++static void ++phy_InitBBRFRegisterDefinition( ++ struct adapter *Adapter ++) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ /* RF Interface Sowrtware Control */ ++ pHalData->PHYRegDef[RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; /* 16 LSBs if read 32-bit from 0x870 */ ++ pHalData->PHYRegDef[RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; /* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */ ++ pHalData->PHYRegDef[RF_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;/* 16 LSBs if read 32-bit from 0x874 */ ++ pHalData->PHYRegDef[RF_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;/* 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) */ ++ ++ /* RF Interface Readback Value */ ++ pHalData->PHYRegDef[RF_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; /* 16 LSBs if read 32-bit from 0x8E0 */ ++ pHalData->PHYRegDef[RF_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;/* 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */ ++ pHalData->PHYRegDef[RF_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB;/* 16 LSBs if read 32-bit from 0x8E4 */ ++ pHalData->PHYRegDef[RF_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB;/* 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6) */ ++ ++ /* RF Interface Output (and Enable) */ ++ pHalData->PHYRegDef[RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; /* 16 LSBs if read 32-bit from 0x860 */ ++ pHalData->PHYRegDef[RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; /* 16 LSBs if read 32-bit from 0x864 */ ++ ++ /* RF Interface (Output and) Enable */ ++ pHalData->PHYRegDef[RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */ ++ pHalData->PHYRegDef[RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; /* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */ ++ ++ /* Addr of LSSI. Wirte RF register by driver */ ++ pHalData->PHYRegDef[RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; /* LSSI Parameter */ ++ pHalData->PHYRegDef[RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; ++ ++ /* RF parameter */ ++ pHalData->PHYRegDef[RF_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter; /* BB Band Select */ ++ pHalData->PHYRegDef[RF_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter; ++ pHalData->PHYRegDef[RF_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter; ++ pHalData->PHYRegDef[RF_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter; ++ ++ /* Tx AGC Gain Stage (same for all path. Should we remove this?) */ ++ pHalData->PHYRegDef[RF_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */ ++ pHalData->PHYRegDef[RF_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */ ++ pHalData->PHYRegDef[RF_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */ ++ pHalData->PHYRegDef[RF_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */ ++ ++ /* Tranceiver A~D HSSI Parameter-1 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; /* wire control parameter1 */ ++ pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1; /* wire control parameter1 */ ++ ++ /* Tranceiver A~D HSSI Parameter-2 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; /* wire control parameter2 */ ++ pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; /* wire control parameter2 */ ++ ++ /* RF switch Control */ ++ pHalData->PHYRegDef[RF_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; /* TR/Ant switch control */ ++ pHalData->PHYRegDef[RF_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl; ++ pHalData->PHYRegDef[RF_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl; ++ pHalData->PHYRegDef[RF_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl; ++ ++ /* AGC control 1 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1; ++ pHalData->PHYRegDef[RF_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1; ++ pHalData->PHYRegDef[RF_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1; ++ pHalData->PHYRegDef[RF_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1; ++ ++ /* AGC control 2 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2; ++ pHalData->PHYRegDef[RF_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2; ++ pHalData->PHYRegDef[RF_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2; ++ pHalData->PHYRegDef[RF_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2; ++ ++ /* RX AFE control 1 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance; ++ pHalData->PHYRegDef[RF_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance; ++ pHalData->PHYRegDef[RF_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance; ++ pHalData->PHYRegDef[RF_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance; ++ ++ /* RX AFE control 1 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfRxAFE = rOFDM0_XARxAFE; ++ pHalData->PHYRegDef[RF_PATH_B].rfRxAFE = rOFDM0_XBRxAFE; ++ pHalData->PHYRegDef[RF_PATH_C].rfRxAFE = rOFDM0_XCRxAFE; ++ pHalData->PHYRegDef[RF_PATH_D].rfRxAFE = rOFDM0_XDRxAFE; ++ ++ /* Tx AFE control 1 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance; ++ pHalData->PHYRegDef[RF_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance; ++ pHalData->PHYRegDef[RF_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance; ++ pHalData->PHYRegDef[RF_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance; ++ ++ /* Tx AFE control 2 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfTxAFE = rOFDM0_XATxAFE; ++ pHalData->PHYRegDef[RF_PATH_B].rfTxAFE = rOFDM0_XBTxAFE; ++ pHalData->PHYRegDef[RF_PATH_C].rfTxAFE = rOFDM0_XCTxAFE; ++ pHalData->PHYRegDef[RF_PATH_D].rfTxAFE = rOFDM0_XDTxAFE; ++ ++ /* Tranceiver LSSI Readback SI mode */ ++ pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; ++ pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack; ++ pHalData->PHYRegDef[RF_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack; ++ pHalData->PHYRegDef[RF_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack; ++ ++ /* Tranceiver LSSI Readback PI mode */ ++ pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBackPi = TransceiverA_HSPI_Readback; ++ pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBackPi = TransceiverB_HSPI_Readback; ++} ++ ++void storePwrIndexDiffRateOffset(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ if (RegAddr == rTxAGC_A_Rate18_06) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0] = Data; ++ if (RegAddr == rTxAGC_A_Rate54_24) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][1] = Data; ++ if (RegAddr == rTxAGC_A_CCK1_Mcs32) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][6] = Data; ++ if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0xffffff00) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][7] = Data; ++ if (RegAddr == rTxAGC_A_Mcs03_Mcs00) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][2] = Data; ++ if (RegAddr == rTxAGC_A_Mcs07_Mcs04) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][3] = Data; ++ if (RegAddr == rTxAGC_A_Mcs11_Mcs08) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][4] = Data; ++ if (RegAddr == rTxAGC_A_Mcs15_Mcs12) { ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][5] = Data; ++ if (pHalData->rf_type == RF_1T1R) ++ pHalData->pwrGroupCnt++; ++ } ++ if (RegAddr == rTxAGC_B_Rate18_06) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][8] = Data; ++ if (RegAddr == rTxAGC_B_Rate54_24) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][9] = Data; ++ if (RegAddr == rTxAGC_B_CCK1_55_Mcs32) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][14] = Data; ++ if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0x000000ff) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][15] = Data; ++ if (RegAddr == rTxAGC_B_Mcs03_Mcs00) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][10] = Data; ++ if (RegAddr == rTxAGC_B_Mcs07_Mcs04) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][11] = Data; ++ if (RegAddr == rTxAGC_B_Mcs11_Mcs08) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][12] = Data; ++ if (RegAddr == rTxAGC_B_Mcs15_Mcs12) { ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][13] = Data; ++ if (pHalData->rf_type != RF_1T1R) ++ pHalData->pwrGroupCnt++; ++ } ++} ++ ++static int phy_BB8188E_Config_ParaFile(struct adapter *Adapter) ++{ ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter); ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ int rtStatus = _SUCCESS; ++ ++ /* */ ++ /* 1. Read PHY_REG.TXT BB INIT!! */ ++ /* We will separate as 88C / 92C according to chip version */ ++ /* */ ++ if (HAL_STATUS_FAILURE == ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG)) ++ rtStatus = _FAIL; ++ if (rtStatus != _SUCCESS) ++ goto phy_BB8190_Config_ParaFile_Fail; ++ ++ /* 2. If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt */ ++ if (!pEEPROM->bautoload_fail_flag) { ++ pHalData->pwrGroupCnt = 0; ++ ++ if (HAL_STATUS_FAILURE == ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG_PG)) ++ rtStatus = _FAIL; ++ } ++ ++ if (rtStatus != _SUCCESS) ++ goto phy_BB8190_Config_ParaFile_Fail; ++ ++ /* 3. BB AGC table Initialization */ ++ if (HAL_STATUS_FAILURE == ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_AGC_TAB)) ++ rtStatus = _FAIL; ++ ++ if (rtStatus != _SUCCESS) ++ goto phy_BB8190_Config_ParaFile_Fail; ++ ++phy_BB8190_Config_ParaFile_Fail: ++ ++ return rtStatus; ++} ++ ++int ++PHY_BBConfig8188E( ++ struct adapter *Adapter ++ ) ++{ ++ int rtStatus = _SUCCESS; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u32 RegVal; ++ u8 CrystalCap; ++ ++ phy_InitBBRFRegisterDefinition(Adapter); ++ ++ /* Enable BB and RF */ ++ RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN); ++ rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal | BIT(13) | BIT(0) | BIT(1))); ++ ++ /* 20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */ ++ ++ rtw_write8(Adapter, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); ++ ++ rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | FEN_BB_GLB_RSTn | FEN_BBRSTB); ++ ++ /* Config BB and AGC */ ++ rtStatus = phy_BB8188E_Config_ParaFile(Adapter); ++ ++ /* write 0x24[16:11] = 0x24[22:17] = CrystalCap */ ++ CrystalCap = pHalData->CrystalCap & 0x3F; ++ PHY_SetBBReg(Adapter, REG_AFE_XTAL_CTRL, 0x7ff800, (CrystalCap | (CrystalCap << 6))); ++ ++ return rtStatus; ++} ++ ++int PHY_RFConfig8188E(struct adapter *Adapter) ++{ ++ int rtStatus = _SUCCESS; ++ ++ /* RF config */ ++ rtStatus = PHY_RF6052_Config8188E(Adapter); ++ return rtStatus; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: PHY_ConfigRFWithParaFile() ++ * ++ * Overview: This function read RF parameters from general file format, and do RF 3-wire ++ * ++ * Input: struct adapter *Adapter ++ * ps8 pFileName ++ * enum rf_radio_path eRFPath ++ * ++ * Output: NONE ++ * ++ * Return: RT_STATUS_SUCCESS: configuration file exist ++ * ++ * Note: Delay may be required for RF configuration ++ *---------------------------------------------------------------------------*/ ++int rtl8188e_PHY_ConfigRFWithParaFile(struct adapter *Adapter, u8 *pFileName, enum rf_radio_path eRFPath) ++{ ++ return _SUCCESS; ++} ++ ++void ++rtl8192c_PHY_GetHWRegOriginalValue( ++ struct adapter *Adapter ++ ) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ /* read rx initial gain */ ++ pHalData->DefaultInitialGain[0] = (u8)PHY_QueryBBReg(Adapter, rOFDM0_XAAGCCore1, bMaskByte0); ++ pHalData->DefaultInitialGain[1] = (u8)PHY_QueryBBReg(Adapter, rOFDM0_XBAGCCore1, bMaskByte0); ++ pHalData->DefaultInitialGain[2] = (u8)PHY_QueryBBReg(Adapter, rOFDM0_XCAGCCore1, bMaskByte0); ++ pHalData->DefaultInitialGain[3] = (u8)PHY_QueryBBReg(Adapter, rOFDM0_XDAGCCore1, bMaskByte0); ++ ++ /* read framesync */ ++ pHalData->framesync = (u8)PHY_QueryBBReg(Adapter, rOFDM0_RxDetector3, bMaskByte0); ++ pHalData->framesyncC34 = PHY_QueryBBReg(Adapter, rOFDM0_RxDetector2, bMaskDWord); ++} ++ ++/* */ ++/* Description: */ ++/* Map dBm into Tx power index according to */ ++/* current HW model, for example, RF and PA, and */ ++/* current wireless mode. */ ++/* By Bruce, 2008-01-29. */ ++/* */ ++static u8 phy_DbmToTxPwrIdx(struct adapter *Adapter, enum wireless_mode WirelessMode, int PowerInDbm) ++{ ++ u8 TxPwrIdx = 0; ++ int Offset = 0; ++ ++ /* */ ++ /* Tested by MP, we found that CCK Index 0 equals to 8dbm, OFDM legacy equals to */ ++ /* 3dbm, and OFDM HT equals to 0dbm respectively. */ ++ /* Note: */ ++ /* The mapping may be different by different NICs. Do not use this formula for what needs accurate result. */ ++ /* By Bruce, 2008-01-29. */ ++ /* */ ++ switch (WirelessMode) { ++ case WIRELESS_MODE_B: ++ Offset = -7; ++ break; ++ ++ case WIRELESS_MODE_G: ++ case WIRELESS_MODE_N_24G: ++ default: ++ Offset = -8; ++ break; ++ } ++ ++ if ((PowerInDbm - Offset) > 0) ++ TxPwrIdx = (u8)((PowerInDbm - Offset) * 2); ++ else ++ TxPwrIdx = 0; ++ ++ /* Tx Power Index is too large. */ ++ if (TxPwrIdx > MAX_TXPWR_IDX_NMODE_92S) ++ TxPwrIdx = MAX_TXPWR_IDX_NMODE_92S; ++ ++ return TxPwrIdx; ++} ++ ++/* */ ++/* Description: */ ++/* Map Tx power index into dBm according to */ ++/* current HW model, for example, RF and PA, and */ ++/* current wireless mode. */ ++/* By Bruce, 2008-01-29. */ ++/* */ ++static int phy_TxPwrIdxToDbm(struct adapter *Adapter, enum wireless_mode WirelessMode, u8 TxPwrIdx) ++{ ++ int Offset = 0; ++ int PwrOutDbm = 0; ++ ++ /* */ ++ /* Tested by MP, we found that CCK Index 0 equals to -7dbm, OFDM legacy equals to -8dbm. */ ++ /* Note: */ ++ /* The mapping may be different by different NICs. Do not use this formula for what needs accurate result. */ ++ /* By Bruce, 2008-01-29. */ ++ /* */ ++ switch (WirelessMode) { ++ case WIRELESS_MODE_B: ++ Offset = -7; ++ break; ++ case WIRELESS_MODE_G: ++ case WIRELESS_MODE_N_24G: ++ default: ++ Offset = -8; ++ break; ++ } ++ ++ PwrOutDbm = TxPwrIdx / 2 + Offset; /* Discard the decimal part. */ ++ ++ return PwrOutDbm; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: GetTxPowerLevel8190() ++ * ++ * Overview: This function is export to "common" moudule ++ * ++ * Input: struct adapter *Adapter ++ * psByte Power Level ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ *---------------------------------------------------------------------------*/ ++void PHY_GetTxPowerLevel8188E(struct adapter *Adapter, u32 *powerlevel) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u8 TxPwrLevel = 0; ++ int TxPwrDbm; ++ ++ /* */ ++ /* Because the Tx power indexes are different, we report the maximum of them to */ ++ /* meet the CCX TPC request. By Bruce, 2008-01-31. */ ++ /* */ ++ ++ /* CCK */ ++ TxPwrLevel = pHalData->CurrentCckTxPwrIdx; ++ TxPwrDbm = phy_TxPwrIdxToDbm(Adapter, WIRELESS_MODE_B, TxPwrLevel); ++ ++ /* Legacy OFDM */ ++ TxPwrLevel = pHalData->CurrentOfdm24GTxPwrIdx + pHalData->LegacyHTTxPowerDiff; ++ ++ /* Compare with Legacy OFDM Tx power. */ ++ if (phy_TxPwrIdxToDbm(Adapter, WIRELESS_MODE_G, TxPwrLevel) > TxPwrDbm) ++ TxPwrDbm = phy_TxPwrIdxToDbm(Adapter, WIRELESS_MODE_G, TxPwrLevel); ++ ++ /* HT OFDM */ ++ TxPwrLevel = pHalData->CurrentOfdm24GTxPwrIdx; ++ ++ /* Compare with HT OFDM Tx power. */ ++ if (phy_TxPwrIdxToDbm(Adapter, WIRELESS_MODE_N_24G, TxPwrLevel) > TxPwrDbm) ++ TxPwrDbm = phy_TxPwrIdxToDbm(Adapter, WIRELESS_MODE_N_24G, TxPwrLevel); ++ ++ *powerlevel = TxPwrDbm; ++} ++ ++static void getTxPowerIndex88E(struct adapter *Adapter, u8 channel, u8 *cckPowerLevel, ++ u8 *ofdmPowerLevel, u8 *BW20PowerLevel, ++ u8 *BW40PowerLevel) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u8 index = (channel - 1); ++ u8 TxCount = 0, path_nums; ++ ++ if ((RF_1T2R == pHalData->rf_type) || (RF_1T1R == pHalData->rf_type)) ++ path_nums = 1; ++ else ++ path_nums = 2; ++ ++ for (TxCount = 0; TxCount < path_nums; TxCount++) { ++ if (TxCount == RF_PATH_A) { ++ /* 1. CCK */ ++ cckPowerLevel[TxCount] = pHalData->Index24G_CCK_Base[TxCount][index]; ++ /* 2. OFDM */ ++ ofdmPowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->OFDM_24G_Diff[TxCount][RF_PATH_A]; ++ /* 1. BW20 */ ++ BW20PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[TxCount][RF_PATH_A]; ++ /* 2. BW40 */ ++ BW40PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[TxCount][index]; ++ } else if (TxCount == RF_PATH_B) { ++ /* 1. CCK */ ++ cckPowerLevel[TxCount] = pHalData->Index24G_CCK_Base[TxCount][index]; ++ /* 2. OFDM */ ++ ofdmPowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[TxCount][index]; ++ /* 1. BW20 */ ++ BW20PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[TxCount][RF_PATH_A] + ++ pHalData->BW20_24G_Diff[TxCount][index]; ++ /* 2. BW40 */ ++ BW40PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[TxCount][index]; ++ } else if (TxCount == RF_PATH_C) { ++ /* 1. CCK */ ++ cckPowerLevel[TxCount] = pHalData->Index24G_CCK_Base[TxCount][index]; ++ /* 2. OFDM */ ++ ofdmPowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_B][index] + ++ pHalData->BW20_24G_Diff[TxCount][index]; ++ /* 1. BW20 */ ++ BW20PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_B][index] + ++ pHalData->BW20_24G_Diff[TxCount][index]; ++ /* 2. BW40 */ ++ BW40PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[TxCount][index]; ++ } else if (TxCount == RF_PATH_D) { ++ /* 1. CCK */ ++ cckPowerLevel[TxCount] = pHalData->Index24G_CCK_Base[TxCount][index]; ++ /* 2. OFDM */ ++ ofdmPowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_B][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_C][index] + ++ pHalData->BW20_24G_Diff[TxCount][index]; ++ ++ /* 1. BW20 */ ++ BW20PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_B][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_C][index] + ++ pHalData->BW20_24G_Diff[TxCount][index]; ++ ++ /* 2. BW40 */ ++ BW40PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[TxCount][index]; ++ } ++ } ++} ++ ++static void phy_PowerIndexCheck88E(struct adapter *Adapter, u8 channel, u8 *cckPowerLevel, ++ u8 *ofdmPowerLevel, u8 *BW20PowerLevel, u8 *BW40PowerLevel) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ pHalData->CurrentCckTxPwrIdx = cckPowerLevel[0]; ++ pHalData->CurrentOfdm24GTxPwrIdx = ofdmPowerLevel[0]; ++ pHalData->CurrentBW2024GTxPwrIdx = BW20PowerLevel[0]; ++ pHalData->CurrentBW4024GTxPwrIdx = BW40PowerLevel[0]; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: SetTxPowerLevel8190() ++ * ++ * Overview: This function is export to "HalCommon" moudule ++ * We must consider RF path later!!!!!!! ++ * ++ * Input: struct adapter *Adapter ++ * u8 channel ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * 2008/11/04 MHC We remove EEPROM_93C56. ++ * We need to move CCX relative code to independet file. ++ * 2009/01/21 MHC Support new EEPROM format from SD3 requirement. ++ * ++ *---------------------------------------------------------------------------*/ ++void ++PHY_SetTxPowerLevel8188E( ++ struct adapter *Adapter, ++ u8 channel ++ ) ++{ ++ u8 cckPowerLevel[MAX_TX_COUNT] = {0}; ++ u8 ofdmPowerLevel[MAX_TX_COUNT] = {0};/* [0]:RF-A, [1]:RF-B */ ++ u8 BW20PowerLevel[MAX_TX_COUNT] = {0}; ++ u8 BW40PowerLevel[MAX_TX_COUNT] = {0}; ++ ++ getTxPowerIndex88E(Adapter, channel, &cckPowerLevel[0], &ofdmPowerLevel[0], &BW20PowerLevel[0], &BW40PowerLevel[0]); ++ ++ phy_PowerIndexCheck88E(Adapter, channel, &cckPowerLevel[0], &ofdmPowerLevel[0], &BW20PowerLevel[0], &BW40PowerLevel[0]); ++ ++ rtl8188e_PHY_RF6052SetCckTxPower(Adapter, &cckPowerLevel[0]); ++ rtl8188e_PHY_RF6052SetOFDMTxPower(Adapter, &ofdmPowerLevel[0], &BW20PowerLevel[0], &BW40PowerLevel[0], channel); ++} ++ ++/* */ ++/* Description: */ ++/* Update transmit power level of all channel supported. */ ++/* */ ++/* TODO: */ ++/* A mode. */ ++/* By Bruce, 2008-02-04. */ ++/* */ ++bool ++PHY_UpdateTxPowerDbm8188E( ++ struct adapter *Adapter, ++ int powerInDbm ++ ) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u8 idx; ++ u8 rf_path; ++ ++ /* TODO: A mode Tx power. */ ++ u8 CckTxPwrIdx = phy_DbmToTxPwrIdx(Adapter, WIRELESS_MODE_B, powerInDbm); ++ u8 OfdmTxPwrIdx = phy_DbmToTxPwrIdx(Adapter, WIRELESS_MODE_N_24G, powerInDbm); ++ ++ if (OfdmTxPwrIdx - pHalData->LegacyHTTxPowerDiff > 0) ++ OfdmTxPwrIdx -= pHalData->LegacyHTTxPowerDiff; ++ else ++ OfdmTxPwrIdx = 0; ++ ++ for (idx = 0; idx < 14; idx++) { ++ for (rf_path = 0; rf_path < 2; rf_path++) { ++ pHalData->TxPwrLevelCck[rf_path][idx] = CckTxPwrIdx; ++ pHalData->TxPwrLevelHT40_1S[rf_path][idx] = ++ pHalData->TxPwrLevelHT40_2S[rf_path][idx] = OfdmTxPwrIdx; ++ } ++ } ++ return true; ++} ++ ++void ++PHY_ScanOperationBackup8188E( ++ struct adapter *Adapter, ++ u8 Operation ++ ) ++{ ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: PHY_SetBWModeCallback8192C() ++ * ++ * Overview: Timer callback function for SetSetBWMode ++ * ++ * Input: PRT_TIMER pTimer ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Note: (1) We do not take j mode into consideration now ++ * (2) Will two workitem of "switch channel" and "switch channel bandwidth" run ++ * concurrently? ++ *---------------------------------------------------------------------------*/ ++static void ++_PHY_SetBWMode92C( ++ struct adapter *Adapter ++) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u8 regBwOpMode; ++ u8 regRRSR_RSC; ++ ++ if (pHalData->rf_chip == RF_PSEUDO_11N) ++ return; ++ ++ /* There is no 40MHz mode in RF_8225. */ ++ if (pHalData->rf_chip == RF_8225) ++ return; ++ ++ if (Adapter->bDriverStopped) ++ return; ++ ++ /* 3 */ ++ /* 3<1>Set MAC register */ ++ /* 3 */ ++ ++ regBwOpMode = rtw_read8(Adapter, REG_BWOPMODE); ++ regRRSR_RSC = rtw_read8(Adapter, REG_RRSR + 2); ++ ++ switch (pHalData->CurrentChannelBW) { ++ case HT_CHANNEL_WIDTH_20: ++ regBwOpMode |= BW_OPMODE_20MHZ; ++ /* 2007/02/07 Mark by Emily because we have not verify whether this register works */ ++ rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode); ++ break; ++ case HT_CHANNEL_WIDTH_40: ++ regBwOpMode &= ~BW_OPMODE_20MHZ; ++ /* 2007/02/07 Mark by Emily because we have not verify whether this register works */ ++ rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode); ++ regRRSR_RSC = (regRRSR_RSC & 0x90) | (pHalData->nCur40MhzPrimeSC << 5); ++ rtw_write8(Adapter, REG_RRSR + 2, regRRSR_RSC); ++ break; ++ default: ++ break; ++ } ++ ++ /* 3 */ ++ /* 3 <2>Set PHY related register */ ++ /* 3 */ ++ switch (pHalData->CurrentChannelBW) { ++ /* 20 MHz channel*/ ++ case HT_CHANNEL_WIDTH_20: ++ PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0); ++ PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0); ++ break; ++ /* 40 MHz channel*/ ++ case HT_CHANNEL_WIDTH_40: ++ PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1); ++ PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1); ++ /* Set Control channel to upper or lower. These settings are required only for 40MHz */ ++ PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand, (pHalData->nCur40MhzPrimeSC >> 1)); ++ PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00, pHalData->nCur40MhzPrimeSC); ++ PHY_SetBBReg(Adapter, 0x818, (BIT(26) | BIT(27)), ++ (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); ++ break; ++ default: ++ break; ++ } ++ /* Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315 */ ++ ++ /* 3<3>Set RF related register */ ++ switch (pHalData->rf_chip) { ++ case RF_8225: ++ break; ++ case RF_8256: ++ /* Please implement this function in Hal8190PciPhy8256.c */ ++ break; ++ case RF_PSEUDO_11N: ++ break; ++ case RF_6052: ++ rtl8188e_PHY_RF6052SetBandwidth(Adapter, pHalData->CurrentChannelBW); ++ break; ++ default: ++ break; ++ } ++} ++ ++ /*----------------------------------------------------------------------------- ++ * Function: SetBWMode8190Pci() ++ * ++ * Overview: This function is export to "HalCommon" moudule ++ * ++ * Input: struct adapter *Adapter ++ * enum ht_channel_width Bandwidth 20M or 40M ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Note: We do not take j mode into consideration now ++ *---------------------------------------------------------------------------*/ ++void PHY_SetBWMode8188E(struct adapter *Adapter, enum ht_channel_width Bandwidth, /* 20M or 40M */ ++ unsigned char Offset) /* Upper, Lower, or Don't care */ ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ enum ht_channel_width tmpBW = pHalData->CurrentChannelBW; ++ ++ pHalData->CurrentChannelBW = Bandwidth; ++ ++ pHalData->nCur40MhzPrimeSC = Offset; ++ ++ if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) ++ _PHY_SetBWMode92C(Adapter); ++ else ++ pHalData->CurrentChannelBW = tmpBW; ++} ++ ++static void _PHY_SwChnl8192C(struct adapter *Adapter, u8 channel) ++{ ++ u8 eRFPath; ++ u32 param1, param2; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ if (Adapter->bNotifyChannelChange) ++ DBG_88E("[%s] ch = %d\n", __func__, channel); ++ ++ /* s1. pre common command - CmdID_SetTxPowerLevel */ ++ PHY_SetTxPowerLevel8188E(Adapter, channel); ++ ++ /* s2. RF dependent command - CmdID_RF_WriteReg, param1=RF_CHNLBW, param2=channel */ ++ param1 = RF_CHNLBW; ++ param2 = channel; ++ for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) { ++ pHalData->RfRegChnlVal[eRFPath] = ((pHalData->RfRegChnlVal[eRFPath] & 0xfffffc00) | param2); ++ PHY_SetRFReg(Adapter, (enum rf_radio_path)eRFPath, param1, bRFRegOffsetMask, pHalData->RfRegChnlVal[eRFPath]); ++ } ++} ++ ++void PHY_SwChnl8188E(struct adapter *Adapter, u8 channel) ++{ ++ /* Call after initialization */ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ if (pHalData->rf_chip == RF_PSEUDO_11N) ++ return; /* return immediately if it is peudo-phy */ ++ ++ if (channel == 0) ++ channel = 1; ++ ++ if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) { ++ pHalData->CurrentChannel = channel; ++ _PHY_SwChnl8192C(Adapter, channel); ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_rf6052.c b/drivers/staging/r8188eu/hal/rtl8188e_rf6052.c +new file mode 100644 +index 000000000000..ad0782259654 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_rf6052.c +@@ -0,0 +1,550 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++/****************************************************************************** ++ * ++ * ++ * Module: rtl8192c_rf6052.c ( Source C File) ++ * ++ * Note: Provide RF 6052 series relative API. ++ * ++ * Function: ++ * ++ * Export: ++ * ++ * Abbrev: ++ * ++ * History: ++ * Data Who Remark ++ * ++ * 09/25/2008 MHC Create initial version. ++ * 11/05/2008 MHC Add API for tw power setting. ++ * ++ * ++******************************************************************************/ ++ ++#define _RTL8188E_RF6052_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtl8188e_hal.h" ++ ++/*---------------------------Define Local Constant---------------------------*/ ++/* Define local structure for debug!!!!! */ ++struct rf_shadow { ++ /* Shadow register value */ ++ u32 Value; ++ /* Compare or not flag */ ++ u8 Compare; ++ /* Record If it had ever modified unpredicted */ ++ u8 ErrorOrNot; ++ /* Recorver Flag */ ++ u8 Recorver; ++ /* */ ++ u8 Driver_Write; ++}; ++ ++/*---------------------------Define Local Constant---------------------------*/ ++ ++/*------------------------Define global variable-----------------------------*/ ++ ++/*------------------------Define local variable------------------------------*/ ++ ++/*----------------------------------------------------------------------------- ++ * Function: RF_ChangeTxPath ++ * ++ * Overview: For RL6052, we must change some RF settign for 1T or 2T. ++ * ++ * Input: u16 DataRate 0x80-8f, 0x90-9f ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 09/25/2008 MHC Create Version 0. ++ * Firmwaer support the utility later. ++ * ++ *---------------------------------------------------------------------------*/ ++void rtl8188e_RF_ChangeTxPath(struct adapter *Adapter, u16 DataRate) ++{ ++/* We do not support gain table change inACUT now !!!! Delete later !!! */ ++} /* RF_ChangeTxPath */ ++ ++/*----------------------------------------------------------------------------- ++ * Function: PHY_RF6052SetBandwidth() ++ * ++ * Overview: This function is called by SetBWModeCallback8190Pci() only ++ * ++ * Input: struct adapter *Adapter ++ * WIRELESS_BANDWIDTH_E Bandwidth 20M or 40M ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Note: For RF type 0222D ++ *---------------------------------------------------------------------------*/ ++void rtl8188e_PHY_RF6052SetBandwidth(struct adapter *Adapter, ++ enum ht_channel_width Bandwidth) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ switch (Bandwidth) { ++ case HT_CHANNEL_WIDTH_20: ++ pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff) | BIT(10) | BIT(11)); ++ PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]); ++ break; ++ case HT_CHANNEL_WIDTH_40: ++ pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff) | BIT(10)); ++ PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]); ++ break; ++ default: ++ break; ++ } ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: PHY_RF6052SetCckTxPower ++ * ++ * Overview: ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/05/2008 MHC Simulate 8192series.. ++ * ++ *---------------------------------------------------------------------------*/ ++ ++void ++rtl8188e_PHY_RF6052SetCckTxPower( ++ struct adapter *Adapter, ++ u8 *pPowerlevel) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &pHalData->dmpriv; ++ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; ++ u32 TxAGC[2] = {0, 0}, tmpval = 0, pwrtrac_value; ++ bool TurboScanOff = false; ++ u8 idx1, idx2; ++ u8 *ptr; ++ u8 direction; ++ /* FOR CE ,must disable turbo scan */ ++ TurboScanOff = true; ++ ++ if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { ++ TxAGC[RF_PATH_A] = 0x3f3f3f3f; ++ TxAGC[RF_PATH_B] = 0x3f3f3f3f; ++ ++ TurboScanOff = true;/* disable turbo scan */ ++ ++ if (TurboScanOff) { ++ for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) { ++ TxAGC[idx1] = ++ pPowerlevel[idx1] | (pPowerlevel[idx1] << 8) | ++ (pPowerlevel[idx1] << 16) | (pPowerlevel[idx1] << 24); ++ /* 2010/10/18 MH For external PA module. We need to limit power index to be less than 0x20. */ ++ if (TxAGC[idx1] > 0x20 && pHalData->ExternalPA) ++ TxAGC[idx1] = 0x20; ++ } ++ } ++ } else { ++ /* Driver dynamic Tx power shall not affect Tx power. ++ * It shall be determined by power training mechanism. ++i * Currently, we cannot fully disable driver dynamic ++ * tx power mechanism because it is referenced by BT ++ * coexist mechanism. ++ * In the future, two mechanism shall be separated from ++ * each other and maintained independently. */ ++ if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) { ++ TxAGC[RF_PATH_A] = 0x10101010; ++ TxAGC[RF_PATH_B] = 0x10101010; ++ } else if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level2) { ++ TxAGC[RF_PATH_A] = 0x00000000; ++ TxAGC[RF_PATH_B] = 0x00000000; ++ } else { ++ for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) { ++ TxAGC[idx1] = ++ pPowerlevel[idx1] | (pPowerlevel[idx1] << 8) | ++ (pPowerlevel[idx1] << 16) | (pPowerlevel[idx1] << 24); ++ } ++ if (pHalData->EEPROMRegulatory == 0) { ++ tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][6]) + ++ (pHalData->MCSTxPowerLevelOriginalOffset[0][7] << 8); ++ TxAGC[RF_PATH_A] += tmpval; ++ ++ tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][14]) + ++ (pHalData->MCSTxPowerLevelOriginalOffset[0][15] << 24); ++ TxAGC[RF_PATH_B] += tmpval; ++ } ++ } ++ } ++ for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) { ++ ptr = (u8 *)(&TxAGC[idx1]); ++ for (idx2 = 0; idx2 < 4; idx2++) { ++ if (*ptr > RF6052_MAX_TX_PWR) ++ *ptr = RF6052_MAX_TX_PWR; ++ ptr++; ++ } ++ } ++ ODM_TxPwrTrackAdjust88E(&pHalData->odmpriv, 1, &direction, &pwrtrac_value); ++ ++ if (direction == 1) { ++ /* Increase TX power */ ++ TxAGC[0] += pwrtrac_value; ++ TxAGC[1] += pwrtrac_value; ++ } else if (direction == 2) { ++ /* Decrease TX power */ ++ TxAGC[0] -= pwrtrac_value; ++ TxAGC[1] -= pwrtrac_value; ++ } ++ ++ /* rf-A cck tx power */ ++ tmpval = TxAGC[RF_PATH_A] & 0xff; ++ PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, tmpval); ++ tmpval = TxAGC[RF_PATH_A] >> 8; ++ PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); ++ ++ /* rf-B cck tx power */ ++ tmpval = TxAGC[RF_PATH_B] >> 24; ++ PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, tmpval); ++ tmpval = TxAGC[RF_PATH_B] & 0x00ffffff; ++ PHY_SetBBReg(Adapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, tmpval); ++} /* PHY_RF6052SetCckTxPower */ ++ ++/* */ ++/* powerbase0 for OFDM rates */ ++/* powerbase1 for HT MCS rates */ ++/* */ ++static void getpowerbase88e(struct adapter *Adapter, u8 *pPowerLevelOFDM, ++ u8 *pPowerLevelBW20, u8 *pPowerLevelBW40, u8 Channel, u32 *OfdmBase, u32 *MCSBase) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u32 powerBase0, powerBase1; ++ u8 i, powerlevel[2]; ++ ++ for (i = 0; i < 2; i++) { ++ powerBase0 = pPowerLevelOFDM[i]; ++ ++ powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | (powerBase0 << 8) | powerBase0; ++ *(OfdmBase + i) = powerBase0; ++ } ++ for (i = 0; i < pHalData->NumTotalRFPath; i++) { ++ /* Check HT20 to HT40 diff */ ++ if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20) ++ powerlevel[i] = pPowerLevelBW20[i]; ++ else ++ powerlevel[i] = pPowerLevelBW40[i]; ++ powerBase1 = powerlevel[i]; ++ powerBase1 = (powerBase1 << 24) | (powerBase1 << 16) | (powerBase1 << 8) | powerBase1; ++ *(MCSBase + i) = powerBase1; ++ } ++} ++static void get_rx_power_val_by_reg(struct adapter *Adapter, u8 Channel, ++ u8 index, u32 *powerBase0, u32 *powerBase1, ++ u32 *pOutWriteVal) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &pHalData->dmpriv; ++ u8 i, chnlGroup = 0, pwr_diff_limit[4], customer_pwr_limit; ++ s8 pwr_diff = 0; ++ u32 writeVal, customer_limit, rf; ++ u8 Regulatory = pHalData->EEPROMRegulatory; ++ ++ /* Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate */ ++ ++ for (rf = 0; rf < 2; rf++) { ++ switch (Regulatory) { ++ case 0: /* Realtek better performance */ ++ /* increase power diff defined by Realtek for large power */ ++ chnlGroup = 0; ++ writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index + (rf ? 8 : 0)] + ++ ((index < 2) ? powerBase0[rf] : powerBase1[rf]); ++ break; ++ case 1: /* Realtek regulatory */ ++ /* increase power diff defined by Realtek for regulatory */ ++ if (pHalData->pwrGroupCnt == 1) ++ chnlGroup = 0; ++ if (pHalData->pwrGroupCnt >= pHalData->PGMaxGroup) { ++ if (Channel < 3) /* Channel 1-2 */ ++ chnlGroup = 0; ++ else if (Channel < 6) /* Channel 3-5 */ ++ chnlGroup = 1; ++ else if (Channel < 9) /* Channel 6-8 */ ++ chnlGroup = 2; ++ else if (Channel < 12) /* Channel 9-11 */ ++ chnlGroup = 3; ++ else if (Channel < 14) /* Channel 12-13 */ ++ chnlGroup = 4; ++ else if (Channel == 14) /* Channel 14 */ ++ chnlGroup = 5; ++ } ++ writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index + (rf ? 8 : 0)] + ++ ((index < 2) ? powerBase0[rf] : powerBase1[rf]); ++ break; ++ case 2: /* Better regulatory */ ++ /* don't increase any power diff */ ++ writeVal = ((index < 2) ? powerBase0[rf] : powerBase1[rf]); ++ break; ++ case 3: /* Customer defined power diff. */ ++ /* increase power diff defined by customer. */ ++ chnlGroup = 0; ++ ++ if (index < 2) ++ pwr_diff = pHalData->TxPwrLegacyHtDiff[rf][Channel - 1]; ++ else if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20) ++ pwr_diff = pHalData->TxPwrHt20Diff[rf][Channel - 1]; ++ ++ if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_40) ++ customer_pwr_limit = pHalData->PwrGroupHT40[rf][Channel - 1]; ++ else ++ customer_pwr_limit = pHalData->PwrGroupHT20[rf][Channel - 1]; ++ ++ if (pwr_diff >= customer_pwr_limit) ++ pwr_diff = 0; ++ else ++ pwr_diff = customer_pwr_limit - pwr_diff; ++ ++ for (i = 0; i < 4; i++) { ++ pwr_diff_limit[i] = (u8)((pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index + (rf ? 8 : 0)] & (0x7f << (i * 8))) >> (i * 8)); ++ ++ if (pwr_diff_limit[i] > pwr_diff) ++ pwr_diff_limit[i] = pwr_diff; ++ } ++ customer_limit = (pwr_diff_limit[3] << 24) | (pwr_diff_limit[2] << 16) | ++ (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); ++ writeVal = customer_limit + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); ++ break; ++ default: ++ chnlGroup = 0; ++ writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index + (rf ? 8 : 0)] + ++ ((index < 2) ? powerBase0[rf] : powerBase1[rf]); ++ break; ++ } ++/* 20100427 Joseph: Driver dynamic Tx power shall not affect Tx power. It shall be determined by power training mechanism. */ ++/* Currently, we cannot fully disable driver dynamic tx power mechanism because it is referenced by BT coexist mechanism. */ ++/* In the future, two mechanism shall be separated from each other and maintained independently. Thanks for Lanhsin's reminder. */ ++ /* 92d do not need this */ ++ if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) ++ writeVal = 0x14141414; ++ else if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level2) ++ writeVal = 0x00000000; ++ ++ /* 20100628 Joseph: High power mode for BT-Coexist mechanism. */ ++ /* This mechanism is only applied when Driver-Highpower-Mechanism is OFF. */ ++ if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_BT1) ++ writeVal = writeVal - 0x06060606; ++ *(pOutWriteVal + rf) = writeVal; ++ } ++} ++static void writeOFDMPowerReg88E(struct adapter *Adapter, u8 index, u32 *pValue) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u16 regoffset_a[6] = { ++ rTxAGC_A_Rate18_06, rTxAGC_A_Rate54_24, ++ rTxAGC_A_Mcs03_Mcs00, rTxAGC_A_Mcs07_Mcs04, ++ rTxAGC_A_Mcs11_Mcs08, rTxAGC_A_Mcs15_Mcs12}; ++ u16 regoffset_b[6] = { ++ rTxAGC_B_Rate18_06, rTxAGC_B_Rate54_24, ++ rTxAGC_B_Mcs03_Mcs00, rTxAGC_B_Mcs07_Mcs04, ++ rTxAGC_B_Mcs11_Mcs08, rTxAGC_B_Mcs15_Mcs12}; ++ u8 i, rf, pwr_val[4]; ++ u32 writeVal; ++ u16 regoffset; ++ ++ for (rf = 0; rf < 2; rf++) { ++ writeVal = pValue[rf]; ++ for (i = 0; i < 4; i++) { ++ pwr_val[i] = (u8)((writeVal & (0x7f << (i * 8))) >> (i * 8)); ++ if (pwr_val[i] > RF6052_MAX_TX_PWR) ++ pwr_val[i] = RF6052_MAX_TX_PWR; ++ } ++ writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) | (pwr_val[1] << 8) | pwr_val[0]; ++ ++ if (rf == 0) ++ regoffset = regoffset_a[index]; ++ else ++ regoffset = regoffset_b[index]; ++ ++ PHY_SetBBReg(Adapter, regoffset, bMaskDWord, writeVal); ++ ++ /* 201005115 Joseph: Set Tx Power diff for Tx power training mechanism. */ ++ if (((pHalData->rf_type == RF_2T2R) && ++ (regoffset == rTxAGC_A_Mcs15_Mcs12 || regoffset == rTxAGC_B_Mcs15_Mcs12)) || ++ ((pHalData->rf_type != RF_2T2R) && ++ (regoffset == rTxAGC_A_Mcs07_Mcs04 || regoffset == rTxAGC_B_Mcs07_Mcs04))) { ++ writeVal = pwr_val[3]; ++ if (regoffset == rTxAGC_A_Mcs15_Mcs12 || regoffset == rTxAGC_A_Mcs07_Mcs04) ++ regoffset = 0xc90; ++ if (regoffset == rTxAGC_B_Mcs15_Mcs12 || regoffset == rTxAGC_B_Mcs07_Mcs04) ++ regoffset = 0xc98; ++ for (i = 0; i < 3; i++) { ++ if (i != 2) ++ writeVal = (writeVal > 8) ? (writeVal - 8) : 0; ++ else ++ writeVal = (writeVal > 6) ? (writeVal - 6) : 0; ++ rtw_write8(Adapter, (u32)(regoffset + i), (u8)writeVal); ++ } ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: PHY_RF6052SetOFDMTxPower ++ * ++ * Overview: For legacy and HY OFDM, we must read EEPROM TX power index for ++ * different channel and read original value in TX power register area from ++ * 0xe00. We increase offset and original value to be correct tx pwr. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/05/2008 MHC Simulate 8192 series method. ++ * 01/06/2009 MHC 1. Prevent Path B tx power overflow or underflow dure to ++ * A/B pwr difference or legacy/HT pwr diff. ++ * 2. We concern with path B legacy/HT OFDM difference. ++ * 01/22/2009 MHC Support new EPRO format from SD3. ++ * ++ *---------------------------------------------------------------------------*/ ++ ++void ++rtl8188e_PHY_RF6052SetOFDMTxPower( ++ struct adapter *Adapter, ++ u8 *pPowerLevelOFDM, ++ u8 *pPowerLevelBW20, ++ u8 *pPowerLevelBW40, ++ u8 Channel) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u32 writeVal[2], powerBase0[2], powerBase1[2], pwrtrac_value; ++ u8 direction; ++ u8 index = 0; ++ ++ getpowerbase88e(Adapter, pPowerLevelOFDM, pPowerLevelBW20, pPowerLevelBW40, Channel, &powerBase0[0], &powerBase1[0]); ++ ++ /* 2012/04/23 MH According to power tracking value, we need to revise OFDM tx power. */ ++ /* This is ued to fix unstable power tracking mode. */ ++ ODM_TxPwrTrackAdjust88E(&pHalData->odmpriv, 0, &direction, &pwrtrac_value); ++ ++ for (index = 0; index < 6; index++) { ++ get_rx_power_val_by_reg(Adapter, Channel, index, ++ &powerBase0[0], &powerBase1[0], ++ &writeVal[0]); ++ ++ if (direction == 1) { ++ writeVal[0] += pwrtrac_value; ++ writeVal[1] += pwrtrac_value; ++ } else if (direction == 2) { ++ writeVal[0] -= pwrtrac_value; ++ writeVal[1] -= pwrtrac_value; ++ } ++ writeOFDMPowerReg88E(Adapter, index, &writeVal[0]); ++ } ++} ++ ++static int phy_RF6052_Config_ParaFile(struct adapter *Adapter) ++{ ++ struct bb_reg_def *pPhyReg; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u32 u4RegValue = 0; ++ u8 eRFPath; ++ int rtStatus = _SUCCESS; ++ ++ /* 3----------------------------------------------------------------- */ ++ /* 3 <2> Initialize RF */ ++ /* 3----------------------------------------------------------------- */ ++ for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) { ++ pPhyReg = &pHalData->PHYRegDef[eRFPath]; ++ ++ /*----Store original RFENV control type----*/ ++ switch (eRFPath) { ++ case RF_PATH_A: ++ case RF_PATH_C: ++ u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV); ++ break; ++ case RF_PATH_B: ++ case RF_PATH_D: ++ u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV << 16); ++ break; ++ } ++ /*----Set RF_ENV enable----*/ ++ PHY_SetBBReg(Adapter, pPhyReg->rfintfe, bRFSI_RFENV << 16, 0x1); ++ udelay(1);/* PlatformStallExecution(1); */ ++ ++ /*----Set RF_ENV output high----*/ ++ PHY_SetBBReg(Adapter, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); ++ udelay(1);/* PlatformStallExecution(1); */ ++ ++ /* Set bit number of Address and Data for RF register */ ++ PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); /* Set 1 to 4 bits for 8255 */ ++ udelay(1);/* PlatformStallExecution(1); */ ++ ++ PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); /* Set 0 to 12 bits for 8255 */ ++ udelay(1);/* PlatformStallExecution(1); */ ++ ++ /*----Initialize RF fom connfiguration file----*/ ++ switch (eRFPath) { ++ case RF_PATH_A: ++ if (HAL_STATUS_FAILURE == ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv, (enum rf_radio_path)eRFPath, (enum rf_radio_path)eRFPath)) ++ rtStatus = _FAIL; ++ break; ++ case RF_PATH_B: ++ if (HAL_STATUS_FAILURE == ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv, (enum rf_radio_path)eRFPath, (enum rf_radio_path)eRFPath)) ++ rtStatus = _FAIL; ++ break; ++ case RF_PATH_C: ++ break; ++ case RF_PATH_D: ++ break; ++ } ++ /*----Restore RFENV control type----*/; ++ switch (eRFPath) { ++ case RF_PATH_A: ++ case RF_PATH_C: ++ PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue); ++ break; ++ case RF_PATH_B: ++ case RF_PATH_D: ++ PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV << 16, u4RegValue); ++ break; ++ } ++ if (rtStatus != _SUCCESS) ++ goto phy_RF6052_Config_ParaFile_Fail; ++ } ++ return rtStatus; ++ ++phy_RF6052_Config_ParaFile_Fail: ++ return rtStatus; ++} ++ ++int PHY_RF6052_Config8188E(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ int rtStatus = _SUCCESS; ++ ++ /* */ ++ /* Initialize general global value */ ++ /* */ ++ /* TODO: Extend RF_PATH_C and RF_PATH_D in the future */ ++ if (pHalData->rf_type == RF_1T1R) ++ pHalData->NumTotalRFPath = 1; ++ else ++ pHalData->NumTotalRFPath = 2; ++ ++ /* */ ++ /* Config BB and RF */ ++ /* */ ++ rtStatus = phy_RF6052_Config_ParaFile(Adapter); ++ return rtStatus; ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c +new file mode 100644 +index 000000000000..244286789b6d +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c +@@ -0,0 +1,186 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188E_REDESC_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtl8188e_hal.h" ++ ++static void process_rssi(struct adapter *padapter, struct recv_frame *prframe) ++{ ++ struct rx_pkt_attrib *pattrib = &prframe->attrib; ++ struct signal_stat *signal_stat = &padapter->recvpriv.signal_strength_data; ++ ++ if (signal_stat->update_req) { ++ signal_stat->total_num = 0; ++ signal_stat->total_val = 0; ++ signal_stat->update_req = 0; ++ } ++ ++ signal_stat->total_num++; ++ signal_stat->total_val += pattrib->phy_info.SignalStrength; ++ signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num; ++} /* Process_UI_RSSI_8192C */ ++ ++static void process_link_qual(struct adapter *padapter, struct recv_frame *prframe) ++{ ++ struct rx_pkt_attrib *pattrib; ++ struct signal_stat *signal_stat; ++ ++ if (!prframe || !padapter) ++ return; ++ ++ pattrib = &prframe->attrib; ++ signal_stat = &padapter->recvpriv.signal_qual_data; ++ ++ if (signal_stat->update_req) { ++ signal_stat->total_num = 0; ++ signal_stat->total_val = 0; ++ signal_stat->update_req = 0; ++ } ++ ++ signal_stat->total_num++; ++ signal_stat->total_val += pattrib->phy_info.SignalQuality; ++ signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num; ++} ++ ++void rtl8188e_process_phy_info(struct adapter *padapter, void *prframe) ++{ ++ struct recv_frame *precvframe = (struct recv_frame *)prframe; ++ ++ /* Check RSSI */ ++ process_rssi(padapter, precvframe); ++ /* Check EVM */ ++ process_link_qual(padapter, precvframe); ++} ++ ++void update_recvframe_attrib_88e(struct recv_frame *precvframe, struct recv_stat *prxstat) ++{ ++ struct rx_pkt_attrib *pattrib; ++ struct recv_stat report; ++ ++ report.rxdw0 = prxstat->rxdw0; ++ report.rxdw1 = prxstat->rxdw1; ++ report.rxdw2 = prxstat->rxdw2; ++ report.rxdw3 = prxstat->rxdw3; ++ report.rxdw4 = prxstat->rxdw4; ++ report.rxdw5 = prxstat->rxdw5; ++ ++ pattrib = &precvframe->attrib; ++ memset(pattrib, 0, sizeof(struct rx_pkt_attrib)); ++ ++ pattrib->crc_err = (u8)((le32_to_cpu(report.rxdw0) >> 14) & 0x1);/* u8)prxreport->crc32; */ ++ ++ /* update rx report to recv_frame attribute */ ++ pattrib->pkt_rpt_type = (u8)((le32_to_cpu(report.rxdw3) >> 14) & 0x3);/* prxreport->rpt_sel; */ ++ ++ if (pattrib->pkt_rpt_type == NORMAL_RX) { /* Normal rx packet */ ++ pattrib->pkt_len = (u16)(le32_to_cpu(report.rxdw0) & 0x00003fff);/* u16)prxreport->pktlen; */ ++ pattrib->drvinfo_sz = (u8)((le32_to_cpu(report.rxdw0) >> 16) & 0xf) * 8;/* u8)(prxreport->drvinfosize << 3); */ ++ ++ pattrib->physt = (u8)((le32_to_cpu(report.rxdw0) >> 26) & 0x1);/* u8)prxreport->physt; */ ++ ++ pattrib->bdecrypted = (le32_to_cpu(report.rxdw0) & BIT(27)) ? 0 : 1;/* u8)(prxreport->swdec ? 0 : 1); */ ++ pattrib->encrypt = (u8)((le32_to_cpu(report.rxdw0) >> 20) & 0x7);/* u8)prxreport->security; */ ++ ++ pattrib->qos = (u8)((le32_to_cpu(report.rxdw0) >> 23) & 0x1);/* u8)prxreport->qos; */ ++ pattrib->priority = (u8)((le32_to_cpu(report.rxdw1) >> 8) & 0xf);/* u8)prxreport->tid; */ ++ ++ pattrib->amsdu = (u8)((le32_to_cpu(report.rxdw1) >> 13) & 0x1);/* u8)prxreport->amsdu; */ ++ ++ pattrib->seq_num = (u16)(le32_to_cpu(report.rxdw2) & 0x00000fff);/* u16)prxreport->seq; */ ++ pattrib->frag_num = (u8)((le32_to_cpu(report.rxdw2) >> 12) & 0xf);/* u8)prxreport->frag; */ ++ pattrib->mfrag = (u8)((le32_to_cpu(report.rxdw1) >> 27) & 0x1);/* u8)prxreport->mf; */ ++ pattrib->mdata = (u8)((le32_to_cpu(report.rxdw1) >> 26) & 0x1);/* u8)prxreport->md; */ ++ ++ pattrib->mcs_rate = (u8)(le32_to_cpu(report.rxdw3) & 0x3f);/* u8)prxreport->rxmcs; */ ++ pattrib->rxht = (u8)((le32_to_cpu(report.rxdw3) >> 6) & 0x1);/* u8)prxreport->rxht; */ ++ ++ pattrib->icv_err = (u8)((le32_to_cpu(report.rxdw0) >> 15) & 0x1);/* u8)prxreport->icverr; */ ++ pattrib->shift_sz = (u8)((le32_to_cpu(report.rxdw0) >> 24) & 0x3); ++ } else if (pattrib->pkt_rpt_type == TX_REPORT1) { /* CCX */ ++ pattrib->pkt_len = TX_RPT1_PKT_LEN; ++ pattrib->drvinfo_sz = 0; ++ } else if (pattrib->pkt_rpt_type == TX_REPORT2) { /* TX RPT */ ++ pattrib->pkt_len = (u16)(le32_to_cpu(report.rxdw0) & 0x3FF);/* Rx length[9:0] */ ++ pattrib->drvinfo_sz = 0; ++ ++ /* */ ++ /* Get TX report MAC ID valid. */ ++ /* */ ++ pattrib->MacIDValidEntry[0] = le32_to_cpu(report.rxdw4); ++ pattrib->MacIDValidEntry[1] = le32_to_cpu(report.rxdw5); ++ ++ } else if (pattrib->pkt_rpt_type == HIS_REPORT) { /* USB HISR RPT */ ++ pattrib->pkt_len = (u16)(le32_to_cpu(report.rxdw0) & 0x00003fff);/* u16)prxreport->pktlen; */ ++ } ++} ++ ++/* ++ * Notice: ++ * Before calling this function, ++ * precvframe->rx_data should be ready! ++ */ ++void update_recvframe_phyinfo_88e(struct recv_frame *precvframe, struct phy_stat *pphy_status) ++{ ++ struct adapter *padapter = precvframe->adapter; ++ struct rx_pkt_attrib *pattrib = &precvframe->attrib; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct odm_phy_status_info *pPHYInfo = (struct odm_phy_status_info *)(&pattrib->phy_info); ++ u8 *wlanhdr; ++ struct odm_per_pkt_info pkt_info; ++ u8 *sa = NULL; ++ struct sta_priv *pstapriv; ++ struct sta_info *psta; ++ ++ pkt_info.bPacketMatchBSSID = false; ++ pkt_info.bPacketToSelf = false; ++ pkt_info.bPacketBeacon = false; ++ ++ wlanhdr = get_recvframe_data(precvframe); ++ ++ pkt_info.bPacketMatchBSSID = ((!IsFrameTypeCtrl(wlanhdr)) && ++ !pattrib->icv_err && !pattrib->crc_err && ++ !memcmp(get_hdr_bssid(wlanhdr), ++ get_bssid(&padapter->mlmepriv), ETH_ALEN)); ++ ++ pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && ++ (!memcmp(get_da(wlanhdr), ++ myid(&padapter->eeprompriv), ETH_ALEN)); ++ ++ pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && ++ (GetFrameSubType(wlanhdr) == WIFI_BEACON); ++ ++ if (pkt_info.bPacketBeacon) { ++ if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) ++ sa = padapter->mlmepriv.cur_network.network.MacAddress; ++ /* to do Ad-hoc */ ++ } else { ++ sa = get_sa(wlanhdr); ++ } ++ ++ pstapriv = &padapter->stapriv; ++ pkt_info.StationID = 0xFF; ++ psta = rtw_get_stainfo(pstapriv, sa); ++ if (psta) ++ pkt_info.StationID = psta->mac_id; ++ pkt_info.Rate = pattrib->mcs_rate; ++ ++ ODM_PhyStatusQuery(&pHalData->odmpriv, pPHYInfo, (u8 *)pphy_status, &(pkt_info), padapter); ++ ++ precvframe->psta = NULL; ++ if (pkt_info.bPacketMatchBSSID && ++ (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE))) { ++ if (psta) { ++ precvframe->psta = psta; ++ rtl8188e_process_phy_info(padapter, precvframe); ++ } ++ } else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) { ++ if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) { ++ if (psta) ++ precvframe->psta = psta; ++ } ++ rtl8188e_process_phy_info(padapter, precvframe); ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c +new file mode 100644 +index 000000000000..16fa249e35d3 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c +@@ -0,0 +1,64 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188E_SRESET_C_ ++ ++#include "../include/rtl8188e_sreset.h" ++#include "../include/rtl8188e_hal.h" ++ ++void rtl8188e_silentreset_for_specific_platform(struct adapter *padapter) ++{ ++} ++ ++void rtl8188e_sreset_xmit_status_check(struct adapter *padapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct sreset_priv *psrtpriv = &pHalData->srestpriv; ++ ++ unsigned long current_time; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ unsigned int diff_time; ++ u32 txdma_status; ++ ++ txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS); ++ if (txdma_status != 0x00) { ++ DBG_88E("%s REG_TXDMA_STATUS:0x%08x\n", __func__, txdma_status); ++ rtw_write32(padapter, REG_TXDMA_STATUS, txdma_status); ++ rtl8188e_silentreset_for_specific_platform(padapter); ++ } ++ /* total xmit irp = 4 */ ++ current_time = jiffies; ++ if (0 == pxmitpriv->free_xmitbuf_cnt) { ++ diff_time = jiffies_to_msecs(current_time - psrtpriv->last_tx_time); ++ ++ if (diff_time > 2000) { ++ if (psrtpriv->last_tx_complete_time == 0) { ++ psrtpriv->last_tx_complete_time = current_time; ++ } else { ++ diff_time = jiffies_to_msecs(current_time - psrtpriv->last_tx_complete_time); ++ if (diff_time > 4000) { ++ DBG_88E("%s tx hang\n", __func__); ++ rtl8188e_silentreset_for_specific_platform(padapter); ++ } ++ } ++ } ++ } ++} ++ ++void rtl8188e_sreset_linked_status_check(struct adapter *padapter) ++{ ++ u32 rx_dma_status = 0; ++ u8 fw_status = 0; ++ rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS); ++ if (rx_dma_status != 0x00) { ++ DBG_88E("%s REG_RXDMA_STATUS:0x%08x\n", __func__, rx_dma_status); ++ rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status); ++ } ++ fw_status = rtw_read8(padapter, REG_FMETHR); ++ if (fw_status != 0x00) { ++ if (fw_status == 1) ++ DBG_88E("%s REG_FW_STATUS (0x%02x), Read_Efuse_Fail !!\n", __func__, fw_status); ++ else if (fw_status == 2) ++ DBG_88E("%s REG_FW_STATUS (0x%02x), Condition_No_Match !!\n", __func__, fw_status); ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_xmit.c b/drivers/staging/r8188eu/hal/rtl8188e_xmit.c +new file mode 100644 +index 000000000000..46b871f3f631 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_xmit.c +@@ -0,0 +1,22 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188E_XMIT_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtl8188e_hal.h" ++ ++void handle_txrpt_ccx_88e(struct adapter *adapter, u8 *buf) ++{ ++ struct txrpt_ccx_88e *txrpt_ccx = (struct txrpt_ccx_88e *)buf; ++ ++ if (txrpt_ccx->int_ccx) { ++ if (txrpt_ccx->pkt_ok) ++ rtw_ack_tx_done(&adapter->xmitpriv, ++ RTW_SCTX_DONE_SUCCESS); ++ else ++ rtw_ack_tx_done(&adapter->xmitpriv, ++ RTW_SCTX_DONE_CCX_PKT_FAIL); ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188eu_led.c b/drivers/staging/r8188eu/hal/rtl8188eu_led.c +new file mode 100644 +index 000000000000..452d4bb87aba +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188eu_led.c +@@ -0,0 +1,94 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtl8188e_hal.h" ++#include "../include/rtl8188e_led.h" ++ ++/* LED object. */ ++ ++/* LED_819xUsb routines. */ ++/* Description: */ ++/* Turn on LED according to LedPin specified. */ ++void SwLedOn(struct adapter *padapter, struct LED_871x *pLed) ++{ ++ u8 LedCfg; ++ ++ if (padapter->bSurpriseRemoved || padapter->bDriverStopped) ++ return; ++ LedCfg = rtw_read8(padapter, REG_LEDCFG2); ++ switch (pLed->LedPin) { ++ case LED_PIN_LED0: ++ rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0xf0) | BIT(5) | BIT(6)); /* SW control led0 on. */ ++ break; ++ case LED_PIN_LED1: ++ rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0x0f) | BIT(5)); /* SW control led1 on. */ ++ break; ++ default: ++ break; ++ } ++ pLed->bLedOn = true; ++} ++ ++/* Description: */ ++/* Turn off LED according to LedPin specified. */ ++void SwLedOff(struct adapter *padapter, struct LED_871x *pLed) ++{ ++ u8 LedCfg; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ ++ if (padapter->bSurpriseRemoved || padapter->bDriverStopped) ++ goto exit; ++ ++ LedCfg = rtw_read8(padapter, REG_LEDCFG2);/* 0x4E */ ++ ++ switch (pLed->LedPin) { ++ case LED_PIN_LED0: ++ if (pHalData->bLedOpenDrain) { ++ /* Open-drain arrangement for controlling the LED) */ ++ LedCfg &= 0x90; /* Set to software control. */ ++ rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3))); ++ LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG); ++ LedCfg &= 0xFE; ++ rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg); ++ } else { ++ rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3) | BIT(5) | BIT(6))); ++ } ++ break; ++ case LED_PIN_LED1: ++ LedCfg &= 0x0f; /* Set to software control. */ ++ rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3))); ++ break; ++ default: ++ break; ++ } ++exit: ++ pLed->bLedOn = false; ++} ++ ++/* Interface to manipulate LED objects. */ ++/* Default LED behavior. */ ++ ++/* Description: */ ++/* Initialize all LED_871x objects. */ ++void rtl8188eu_InitSwLeds(struct adapter *padapter) ++{ ++ struct led_priv *pledpriv = &padapter->ledpriv; ++ ++ pledpriv->LedControlHandler = LedControl8188eu; ++ ++ InitLed871x(padapter, &pledpriv->SwLed0, LED_PIN_LED0); ++ ++ InitLed871x(padapter, &pledpriv->SwLed1, LED_PIN_LED1); ++} ++ ++/* Description: */ ++/* DeInitialize all LED_819xUsb objects. */ ++void rtl8188eu_DeInitSwLeds(struct adapter *padapter) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ ++ DeInitLed871x(&ledpriv->SwLed0); ++ DeInitLed871x(&ledpriv->SwLed1); ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188eu_recv.c b/drivers/staging/r8188eu/hal/rtl8188eu_recv.c +new file mode 100644 +index 000000000000..2da7bde80cc0 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188eu_recv.c +@@ -0,0 +1,117 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188EU_RECV_C_ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/mlme_osdep.h" ++ ++#include "../include/usb_ops.h" ++#include "../include/wifi.h" ++ ++#include "../include/rtl8188e_hal.h" ++ ++void rtl8188eu_init_recvbuf(struct adapter *padapter, struct recv_buf *precvbuf) ++{ ++ precvbuf->transfer_len = 0; ++ ++ precvbuf->len = 0; ++ ++ precvbuf->ref_cnt = 0; ++ ++ if (precvbuf->pbuf) { ++ precvbuf->pdata = precvbuf->pbuf; ++ precvbuf->phead = precvbuf->pbuf; ++ precvbuf->ptail = precvbuf->pbuf; ++ precvbuf->pend = precvbuf->pdata + MAX_RECVBUF_SZ; ++ } ++} ++ ++int rtl8188eu_init_recv_priv(struct adapter *padapter) ++{ ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ int i, res = _SUCCESS; ++ struct recv_buf *precvbuf; ++ ++ tasklet_init(&precvpriv->recv_tasklet, ++ rtl8188eu_recv_tasklet, ++ (unsigned long)padapter); ++ ++ /* init recv_buf */ ++ _rtw_init_queue(&precvpriv->free_recv_buf_queue); ++ ++ precvpriv->pallocated_recv_buf = kzalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4, ++ GFP_KERNEL); ++ if (!precvpriv->pallocated_recv_buf) { ++ res = _FAIL; ++ goto exit; ++ } ++ memset(precvpriv->pallocated_recv_buf, 0, NR_RECVBUFF * sizeof(struct recv_buf) + 4); ++ ++ precvpriv->precv_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(precvpriv->pallocated_recv_buf), 4); ++ ++ precvbuf = (struct recv_buf *)precvpriv->precv_buf; ++ ++ for (i = 0; i < NR_RECVBUFF; i++) { ++ INIT_LIST_HEAD(&precvbuf->list); ++ spin_lock_init(&precvbuf->recvbuf_lock); ++ precvbuf->alloc_sz = MAX_RECVBUF_SZ; ++ res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf); ++ if (res == _FAIL) ++ break; ++ precvbuf->ref_cnt = 0; ++ precvbuf->adapter = padapter; ++ precvbuf++; ++ } ++ precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF; ++ skb_queue_head_init(&precvpriv->rx_skb_queue); ++ { ++ int i; ++ size_t tmpaddr = 0; ++ size_t alignment = 0; ++ struct sk_buff *pskb = NULL; ++ ++ skb_queue_head_init(&precvpriv->free_recv_skb_queue); ++ ++ for (i = 0; i < NR_PREALLOC_RECV_SKB; i++) { ++ pskb = __netdev_alloc_skb(padapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, GFP_KERNEL); ++ if (pskb) { ++ pskb->dev = padapter->pnetdev; ++ tmpaddr = (size_t)pskb->data; ++ alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); ++ skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment)); ++ ++ skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); ++ } ++ pskb = NULL; ++ } ++ } ++exit: ++ return res; ++} ++ ++void rtl8188eu_free_recv_priv(struct adapter *padapter) ++{ ++ int i; ++ struct recv_buf *precvbuf; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ ++ precvbuf = (struct recv_buf *)precvpriv->precv_buf; ++ ++ for (i = 0; i < NR_RECVBUFF; i++) { ++ rtw_os_recvbuf_resource_free(padapter, precvbuf); ++ precvbuf++; ++ } ++ ++ kfree(precvpriv->pallocated_recv_buf); ++ ++ if (skb_queue_len(&precvpriv->rx_skb_queue)) ++ DBG_88E(KERN_WARNING "rx_skb_queue not empty\n"); ++ skb_queue_purge(&precvpriv->rx_skb_queue); ++ ++ if (skb_queue_len(&precvpriv->free_recv_skb_queue)) ++ DBG_88E(KERN_WARNING "free_recv_skb_queue not empty, %d\n", skb_queue_len(&precvpriv->free_recv_skb_queue)); ++ ++ skb_queue_purge(&precvpriv->free_recv_skb_queue); ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/r8188eu/hal/rtl8188eu_xmit.c +new file mode 100644 +index 000000000000..17be67ac5fae +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188eu_xmit.c +@@ -0,0 +1,672 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188E_XMIT_C_ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wifi.h" ++#include "../include/osdep_intf.h" ++#include "../include/usb_ops.h" ++#include "../include/rtl8188e_hal.h" ++ ++s32 rtl8188eu_init_xmit_priv(struct adapter *adapt) ++{ ++ struct xmit_priv *pxmitpriv = &adapt->xmitpriv; ++ ++ tasklet_init(&pxmitpriv->xmit_tasklet, ++ rtl8188eu_xmit_tasklet, ++ (unsigned long)adapt); ++ return _SUCCESS; ++} ++ ++static u8 urb_zero_packet_chk(struct adapter *adapt, int sz) ++{ ++ u8 set_tx_desc_offset; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ set_tx_desc_offset = (((sz + TXDESC_SIZE) % haldata->UsbBulkOutSize) == 0) ? 1 : 0; ++ ++ return set_tx_desc_offset; ++} ++ ++static void rtl8188eu_cal_txdesc_chksum(struct tx_desc *ptxdesc) ++{ ++ u16 *usptr = (u16 *)ptxdesc; ++ u32 count = 16; /* (32 bytes / 2 bytes per XOR) => 16 times */ ++ u32 index; ++ u16 checksum = 0; ++ ++ /* Clear first */ ++ ptxdesc->txdw7 &= cpu_to_le32(0xffff0000); ++ ++ for (index = 0; index < count; index++) ++ checksum = checksum ^ le16_to_cpu(*(__le16 *)(usptr + index)); ++ ptxdesc->txdw7 |= cpu_to_le32(0x0000ffff & checksum); ++} ++ ++/* Description: In normal chip, we should send some packet to Hw which will be used by Fw */ ++/* in FW LPS mode. The function is to fill the Tx descriptor of this packets, then */ ++/* Fw can tell Hw to send these packet derectly. */ ++void rtl8188e_fill_fake_txdesc(struct adapter *adapt, u8 *desc, u32 BufferLen, u8 ispspoll, u8 is_btqosnull) ++{ ++ struct tx_desc *ptxdesc; ++ ++ /* Clear all status */ ++ ptxdesc = (struct tx_desc *)desc; ++ memset(desc, 0, TXDESC_SIZE); ++ ++ /* offset 0 */ ++ ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); /* own, bFirstSeg, bLastSeg; */ ++ ++ ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00ff0000); /* 32 bytes for TX Desc */ ++ ++ ptxdesc->txdw0 |= cpu_to_le32(BufferLen & 0x0000ffff); /* Buffer size + command header */ ++ ++ /* offset 4 */ ++ ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT << QSEL_SHT) & 0x00001f00); /* Fixed queue of Mgnt queue */ ++ ++ /* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw. */ ++ if (ispspoll) { ++ ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR); ++ } else { ++ ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); /* Hw set sequence number */ ++ ptxdesc->txdw3 |= cpu_to_le32((8 << 28)); /* set bit3 to 1. Suugested by TimChen. 2009.12.29. */ ++ } ++ ++ if (is_btqosnull) ++ ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); /* BT NULL */ ++ ++ /* offset 16 */ ++ ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */ ++ ++ /* USB interface drop packet if the checksum of descriptor isn't correct. */ ++ /* Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.). */ ++ rtl8188eu_cal_txdesc_chksum(ptxdesc); ++} ++ ++static void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc) ++{ ++ if ((pattrib->encrypt > 0) && !pattrib->bswenc) { ++ switch (pattrib->encrypt) { ++ /* SEC_TYPE : 0:NO_ENC,1:WEP40/TKIP,2:WAPI,3:AES */ ++ case _WEP40_: ++ case _WEP104_: ++ ptxdesc->txdw1 |= cpu_to_le32((0x01 << SEC_TYPE_SHT) & 0x00c00000); ++ ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT); ++ break; ++ case _TKIP_: ++ case _TKIP_WTMIC_: ++ ptxdesc->txdw1 |= cpu_to_le32((0x01 << SEC_TYPE_SHT) & 0x00c00000); ++ ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT); ++ break; ++ case _AES_: ++ ptxdesc->txdw1 |= cpu_to_le32((0x03 << SEC_TYPE_SHT) & 0x00c00000); ++ ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT); ++ break; ++ case _NO_PRIVACY_: ++ default: ++ break; ++ } ++ } ++} ++ ++static void fill_txdesc_vcs(struct pkt_attrib *pattrib, __le32 *pdw) ++{ ++ switch (pattrib->vcs_mode) { ++ case RTS_CTS: ++ *pdw |= cpu_to_le32(RTS_EN); ++ break; ++ case CTS_TO_SELF: ++ *pdw |= cpu_to_le32(CTS_2_SELF); ++ break; ++ case NONE_VCS: ++ default: ++ break; ++ } ++ if (pattrib->vcs_mode) { ++ *pdw |= cpu_to_le32(HW_RTS_EN); ++ /* Set RTS BW */ ++ if (pattrib->ht_en) { ++ *pdw |= (pattrib->bwmode & HT_CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(27)) : 0; ++ ++ if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) ++ *pdw |= cpu_to_le32((0x01 << 28) & 0x30000000); ++ else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER) ++ *pdw |= cpu_to_le32((0x02 << 28) & 0x30000000); ++ else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ++ *pdw |= 0; ++ else ++ *pdw |= cpu_to_le32((0x03 << 28) & 0x30000000); ++ } ++ } ++} ++ ++static void fill_txdesc_phy(struct pkt_attrib *pattrib, __le32 *pdw) ++{ ++ if (pattrib->ht_en) { ++ *pdw |= (pattrib->bwmode & HT_CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(25)) : 0; ++ ++ if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) ++ *pdw |= cpu_to_le32((0x01 << DATA_SC_SHT) & 0x003f0000); ++ else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER) ++ *pdw |= cpu_to_le32((0x02 << DATA_SC_SHT) & 0x003f0000); ++ else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ++ *pdw |= 0; ++ else ++ *pdw |= cpu_to_le32((0x03 << DATA_SC_SHT) & 0x003f0000); ++ } ++} ++ ++static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt) ++{ ++ int pull = 0; ++ uint qsel; ++ u8 data_rate, pwr_status, offset; ++ struct adapter *adapt = pxmitframe->padapter; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ struct tx_desc *ptxdesc = (struct tx_desc *)pmem; ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (adapt->registrypriv.mp_mode == 0) { ++ if ((!bagg_pkt) && (urb_zero_packet_chk(adapt, sz) == 0)) { ++ ptxdesc = (struct tx_desc *)(pmem + PACKET_OFFSET_SZ); ++ pull = 1; ++ } ++ } ++ ++ memset(ptxdesc, 0, sizeof(struct tx_desc)); ++ ++ /* 4 offset 0 */ ++ ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); ++ ptxdesc->txdw0 |= cpu_to_le32(sz & 0x0000ffff);/* update TXPKTSIZE */ ++ ++ offset = TXDESC_SIZE + OFFSET_SZ; ++ ++ ptxdesc->txdw0 |= cpu_to_le32(((offset) << OFFSET_SHT) & 0x00ff0000);/* 32 bytes for TX Desc */ ++ ++ if (is_multicast_ether_addr(pattrib->ra)) ++ ptxdesc->txdw0 |= cpu_to_le32(BMC); ++ ++ if (adapt->registrypriv.mp_mode == 0) { ++ if (!bagg_pkt) { ++ if ((pull) && (pxmitframe->pkt_offset > 0)) ++ pxmitframe->pkt_offset = pxmitframe->pkt_offset - 1; ++ } ++ } ++ ++ /* pkt_offset, unit:8 bytes padding */ ++ if (pxmitframe->pkt_offset > 0) ++ ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000); ++ ++ /* driver uses rate */ ++ ptxdesc->txdw4 |= cpu_to_le32(USERATE);/* rate control always by driver */ ++ ++ if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) { ++ /* offset 4 */ ++ ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x3F); ++ ++ qsel = (uint)(pattrib->qsel & 0x0000001f); ++ ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); ++ ++ ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000F0000); ++ ++ fill_txdesc_sectype(pattrib, ptxdesc); ++ ++ if (pattrib->ampdu_en) { ++ ptxdesc->txdw2 |= cpu_to_le32(AGG_EN);/* AGG EN */ ++ ptxdesc->txdw6 = cpu_to_le32(0x6666f800); ++ } else { ++ ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);/* AGG BK */ ++ } ++ ++ /* offset 8 */ ++ ++ /* offset 12 */ ++ ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0FFF0000); ++ ++ /* offset 16 , offset 20 */ ++ if (pattrib->qos_en) ++ ptxdesc->txdw4 |= cpu_to_le32(QOS);/* QoS */ ++ ++ /* offset 20 */ ++ if (pxmitframe->agg_num > 1) ++ ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << USB_TXAGG_NUM_SHT) & 0xFF000000); ++ ++ if ((pattrib->ether_type != 0x888e) && ++ (pattrib->ether_type != 0x0806) && ++ (pattrib->ether_type != 0x88b4) && ++ (pattrib->dhcp_pkt != 1)) { ++ /* Non EAP & ARP & DHCP type data packet */ ++ ++ fill_txdesc_vcs(pattrib, &ptxdesc->txdw4); ++ fill_txdesc_phy(pattrib, &ptxdesc->txdw4); ++ ++ ptxdesc->txdw4 |= cpu_to_le32(0x00000008);/* RTS Rate=24M */ ++ ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);/* DATA/RTS Rate FB LMT */ ++ ++ if (pattrib->ht_en) { ++ if (ODM_RA_GetShortGI_8188E(&haldata->odmpriv, pattrib->mac_id)) ++ ptxdesc->txdw5 |= cpu_to_le32(SGI);/* SGI */ ++ } ++ data_rate = ODM_RA_GetDecisionRate_8188E(&haldata->odmpriv, pattrib->mac_id); ++ ptxdesc->txdw5 |= cpu_to_le32(data_rate & 0x3F); ++ pwr_status = ODM_RA_GetHwPwrStatus_8188E(&haldata->odmpriv, pattrib->mac_id); ++ ptxdesc->txdw4 |= cpu_to_le32((pwr_status & 0x7) << PWR_STATUS_SHT); ++ } else { ++ /* EAP data packet and ARP packet and DHCP. */ ++ /* Use the 1M data rate to send the EAP/ARP packet. */ ++ /* This will maybe make the handshake smooth. */ ++ ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);/* AGG BK */ ++ if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) ++ ptxdesc->txdw4 |= cpu_to_le32(BIT(24));/* DATA_SHORT */ ++ ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); ++ } ++ } else if ((pxmitframe->frame_tag & 0x0f) == MGNT_FRAMETAG) { ++ /* offset 4 */ ++ ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x3f); ++ ++ qsel = (uint)(pattrib->qsel & 0x0000001f); ++ ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); ++ ++ ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000f0000); ++ ++ /* offset 8 */ ++ /* CCX-TXRPT ack for xmit mgmt frames. */ ++ if (pxmitframe->ack_report) ++ ptxdesc->txdw2 |= cpu_to_le32(BIT(19)); ++ ++ /* offset 12 */ ++ ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0FFF0000); ++ ++ /* offset 20 */ ++ ptxdesc->txdw5 |= cpu_to_le32(RTY_LMT_EN);/* retry limit enable */ ++ if (pattrib->retry_ctrl) ++ ptxdesc->txdw5 |= cpu_to_le32(0x00180000);/* retry limit = 6 */ ++ else ++ ptxdesc->txdw5 |= cpu_to_le32(0x00300000);/* retry limit = 12 */ ++ ++ ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); ++ } else if ((pxmitframe->frame_tag & 0x0f) == TXAGG_FRAMETAG) { ++ DBG_88E("pxmitframe->frame_tag == TXAGG_FRAMETAG\n"); ++ } else if (((pxmitframe->frame_tag & 0x0f) == MP_FRAMETAG) && ++ (adapt->registrypriv.mp_mode == 1)) { ++ fill_txdesc_for_mp(adapt, ptxdesc); ++ } else { ++ DBG_88E("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag); ++ ++ /* offset 4 */ ++ ptxdesc->txdw1 |= cpu_to_le32((4) & 0x3f);/* CAM_ID(MAC_ID) */ ++ ++ ptxdesc->txdw1 |= cpu_to_le32((6 << RATE_ID_SHT) & 0x000f0000);/* raid */ ++ ++ /* offset 8 */ ++ ++ /* offset 12 */ ++ ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0fff0000); ++ ++ /* offset 20 */ ++ ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); ++ } ++ ++ /* 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. */ ++ /* (1) The sequence number of each non-Qos frame / broadcast / multicast / */ ++ /* mgnt frame should be controlled by Hw because Fw will also send null data */ ++ /* which we cannot control when Fw LPS enable. */ ++ /* --> default enable non-Qos data sequense number. 2010.06.23. by tynli. */ ++ /* (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. */ ++ /* (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. */ ++ /* 2010.06.23. Added by tynli. */ ++ if (!pattrib->qos_en) { ++ ptxdesc->txdw3 |= cpu_to_le32(EN_HWSEQ); /* Hw set sequence number */ ++ ptxdesc->txdw4 |= cpu_to_le32(HW_SSN); /* Hw set sequence number */ ++ } ++ ++ ODM_SetTxAntByTxInfo_88E(&haldata->odmpriv, pmem, pattrib->mac_id); ++ ++ rtl8188eu_cal_txdesc_chksum(ptxdesc); ++ return pull; ++} ++ ++/* for non-agg data frame or management frame */ ++static s32 rtw_dump_xframe(struct adapter *adapt, struct xmit_frame *pxmitframe) ++{ ++ s32 ret = _SUCCESS; ++ s32 inner_ret = _SUCCESS; ++ int t, sz, w_sz, pull = 0; ++ u8 *mem_addr; ++ u32 ff_hwaddr; ++ struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ struct xmit_priv *pxmitpriv = &adapt->xmitpriv; ++ struct security_priv *psecuritypriv = &adapt->securitypriv; ++ if ((pxmitframe->frame_tag == DATA_FRAMETAG) && ++ (pxmitframe->attrib.ether_type != 0x0806) && ++ (pxmitframe->attrib.ether_type != 0x888e) && ++ (pxmitframe->attrib.ether_type != 0x88b4) && ++ (pxmitframe->attrib.dhcp_pkt != 1)) ++ rtw_issue_addbareq_cmd(adapt, pxmitframe); ++ mem_addr = pxmitframe->buf_addr; ++ ++ for (t = 0; t < pattrib->nr_frags; t++) { ++ if (inner_ret != _SUCCESS && ret == _SUCCESS) ++ ret = _FAIL; ++ ++ if (t != (pattrib->nr_frags - 1)) { ++ sz = pxmitpriv->frag_len; ++ sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len); ++ } else { ++ /* no frag */ ++ sz = pattrib->last_txcmdsz; ++ } ++ ++ pull = update_txdesc(pxmitframe, mem_addr, sz, false); ++ ++ if (pull) { ++ mem_addr += PACKET_OFFSET_SZ; /* pull txdesc head */ ++ pxmitframe->buf_addr = mem_addr; ++ w_sz = sz + TXDESC_SIZE; ++ } else { ++ w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ; ++ } ++ ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe); ++ ++ inner_ret = rtw_write_port(adapt, ff_hwaddr, w_sz, (unsigned char *)pxmitbuf); ++ ++ rtw_count_tx_stats(adapt, pxmitframe, sz); ++ ++ mem_addr += w_sz; ++ ++ mem_addr = (u8 *)RND4(((size_t)(mem_addr))); ++ } ++ ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ ++ if (ret != _SUCCESS) ++ rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN); ++ ++ return ret; ++} ++ ++static u32 xmitframe_need_length(struct xmit_frame *pxmitframe) ++{ ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ ++ u32 len = 0; ++ ++ /* no consider fragement */ ++ len = pattrib->hdrlen + pattrib->iv_len + ++ SNAP_SIZE + sizeof(u16) + ++ pattrib->pktlen + ++ ((pattrib->bswenc) ? pattrib->icv_len : 0); ++ ++ if (pattrib->encrypt == _TKIP_) ++ len += 8; ++ ++ return len; ++} ++ ++s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ struct xmit_frame *pxmitframe = NULL; ++ struct xmit_frame *pfirstframe = NULL; ++ ++ /* aggregate variable */ ++ struct hw_xmit *phwxmit; ++ struct sta_info *psta = NULL; ++ struct tx_servq *ptxservq = NULL; ++ struct list_head *xmitframe_plist = NULL, *xmitframe_phead = NULL; ++ ++ u32 pbuf; /* next pkt address */ ++ u32 pbuf_tail; /* last pkt tail */ ++ u32 len; /* packet length, except TXDESC_SIZE and PKT_OFFSET */ ++ ++ u32 bulksize = haldata->UsbBulkOutSize; ++ u8 desc_cnt; ++ u32 bulkptr; ++ ++ /* dump frame variable */ ++ u32 ff_hwaddr; ++ ++ /* check xmitbuffer is ok */ ++ if (!pxmitbuf) { ++ pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); ++ if (!pxmitbuf) ++ return false; ++ } ++ ++ /* 3 1. pick up first frame */ ++ do { ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ ++ pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); ++ if (!pxmitframe) { ++ /* no more xmit frame, release xmit buffer */ ++ rtw_free_xmitbuf(pxmitpriv, pxmitbuf); ++ return false; ++ } ++ ++ pxmitframe->pxmitbuf = pxmitbuf; ++ pxmitframe->buf_addr = pxmitbuf->pbuf; ++ pxmitbuf->priv_data = pxmitframe; ++ ++ pxmitframe->agg_num = 1; /* alloc xmitframe should assign to 1. */ ++ pxmitframe->pkt_offset = 1; /* first frame of aggregation, reserve offset */ ++ ++ rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe); ++ ++ /* always return ndis_packet after rtw_xmitframe_coalesce */ ++ rtw_os_xmit_complete(adapt, pxmitframe); ++ ++ break; ++ } while (1); ++ ++ /* 3 2. aggregate same priority and same DA(AP or STA) frames */ ++ pfirstframe = pxmitframe; ++ len = xmitframe_need_length(pfirstframe) + TXDESC_SIZE + (pfirstframe->pkt_offset * PACKET_OFFSET_SZ); ++ pbuf_tail = len; ++ pbuf = _RND8(pbuf_tail); ++ ++ /* check pkt amount in one bulk */ ++ desc_cnt = 0; ++ bulkptr = bulksize; ++ if (pbuf < bulkptr) { ++ desc_cnt++; ++ } else { ++ desc_cnt = 0; ++ bulkptr = ((pbuf / bulksize) + 1) * bulksize; /* round to next bulksize */ ++ } ++ ++ /* dequeue same priority packet from station tx queue */ ++ psta = pfirstframe->attrib.psta; ++ switch (pfirstframe->attrib.priority) { ++ case 1: ++ case 2: ++ ptxservq = &psta->sta_xmitpriv.bk_q; ++ phwxmit = pxmitpriv->hwxmits + 3; ++ break; ++ case 4: ++ case 5: ++ ptxservq = &psta->sta_xmitpriv.vi_q; ++ phwxmit = pxmitpriv->hwxmits + 1; ++ break; ++ case 6: ++ case 7: ++ ptxservq = &psta->sta_xmitpriv.vo_q; ++ phwxmit = pxmitpriv->hwxmits; ++ break; ++ case 0: ++ case 3: ++ default: ++ ptxservq = &psta->sta_xmitpriv.be_q; ++ phwxmit = pxmitpriv->hwxmits + 2; ++ break; ++ } ++ spin_lock_bh(&pxmitpriv->lock); ++ ++ xmitframe_phead = get_list_head(&ptxservq->sta_pending); ++ xmitframe_plist = xmitframe_phead->next; ++ ++ while (xmitframe_phead != xmitframe_plist) { ++ pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); ++ xmitframe_plist = xmitframe_plist->next; ++ ++ pxmitframe->agg_num = 0; /* not first frame of aggregation */ ++ pxmitframe->pkt_offset = 0; /* not first frame of aggregation, no need to reserve offset */ ++ ++ len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ); ++ ++ if (_RND8(pbuf + len) > MAX_XMITBUF_SZ) { ++ pxmitframe->agg_num = 1; ++ pxmitframe->pkt_offset = 1; ++ break; ++ } ++ list_del_init(&pxmitframe->list); ++ ptxservq->qcnt--; ++ phwxmit->accnt--; ++ ++ pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf; ++ ++ rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe); ++ /* always return ndis_packet after rtw_xmitframe_coalesce */ ++ rtw_os_xmit_complete(adapt, pxmitframe); ++ ++ /* (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz */ ++ update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, true); ++ ++ /* don't need xmitframe any more */ ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ ++ /* handle pointer and stop condition */ ++ pbuf_tail = pbuf + len; ++ pbuf = _RND8(pbuf_tail); ++ ++ pfirstframe->agg_num++; ++ if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num) ++ break; ++ ++ if (pbuf < bulkptr) { ++ desc_cnt++; ++ if (desc_cnt == haldata->UsbTxAggDescNum) ++ break; ++ } else { ++ desc_cnt = 0; ++ bulkptr = ((pbuf / bulksize) + 1) * bulksize; ++ } ++ } /* end while (aggregate same priority and same DA(AP or STA) frames) */ ++ ++ if (list_empty(&ptxservq->sta_pending.queue)) ++ list_del_init(&ptxservq->tx_pending); ++ ++ spin_unlock_bh(&pxmitpriv->lock); ++ if ((pfirstframe->attrib.ether_type != 0x0806) && ++ (pfirstframe->attrib.ether_type != 0x888e) && ++ (pfirstframe->attrib.ether_type != 0x88b4) && ++ (pfirstframe->attrib.dhcp_pkt != 1)) ++ rtw_issue_addbareq_cmd(adapt, pfirstframe); ++ /* 3 3. update first frame txdesc */ ++ if ((pbuf_tail % bulksize) == 0) { ++ /* remove pkt_offset */ ++ pbuf_tail -= PACKET_OFFSET_SZ; ++ pfirstframe->buf_addr += PACKET_OFFSET_SZ; ++ pfirstframe->pkt_offset--; ++ } ++ ++ update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, true); ++ ++ /* 3 4. write xmit buffer to USB FIFO */ ++ ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe); ++ rtw_write_port(adapt, ff_hwaddr, pbuf_tail, (u8 *)pxmitbuf); ++ ++ /* 3 5. update statisitc */ ++ pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE); ++ pbuf_tail -= (pfirstframe->pkt_offset * PACKET_OFFSET_SZ); ++ ++ rtw_count_tx_stats(adapt, pfirstframe, pbuf_tail); ++ ++ rtw_free_xmitframe(pxmitpriv, pfirstframe); ++ ++ return true; ++} ++ ++static s32 xmitframe_direct(struct adapter *adapt, struct xmit_frame *pxmitframe) ++{ ++ s32 res = _SUCCESS; ++ ++ res = rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe); ++ if (res == _SUCCESS) ++ rtw_dump_xframe(adapt, pxmitframe); ++ else ++ DBG_88E("==> %s xmitframe_coalsece failed\n", __func__); ++ return res; ++} ++ ++/* ++ * Return ++ * true dump packet directly ++ * false enqueue packet ++ */ ++static s32 pre_xmitframe(struct adapter *adapt, struct xmit_frame *pxmitframe) ++{ ++ s32 res; ++ struct xmit_buf *pxmitbuf = NULL; ++ struct xmit_priv *pxmitpriv = &adapt->xmitpriv; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ struct mlme_priv *pmlmepriv = &adapt->mlmepriv; ++ ++ spin_lock_bh(&pxmitpriv->lock); ++ ++ if (rtw_txframes_sta_ac_pending(adapt, pattrib) > 0) ++ goto enqueue; ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) ++ goto enqueue; ++ ++ pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); ++ if (!pxmitbuf) ++ goto enqueue; ++ ++ spin_unlock_bh(&pxmitpriv->lock); ++ ++ pxmitframe->pxmitbuf = pxmitbuf; ++ pxmitframe->buf_addr = pxmitbuf->pbuf; ++ pxmitbuf->priv_data = pxmitframe; ++ ++ if (xmitframe_direct(adapt, pxmitframe) != _SUCCESS) { ++ rtw_free_xmitbuf(pxmitpriv, pxmitbuf); ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ } ++ ++ return true; ++ ++enqueue: ++ res = rtw_xmitframe_enqueue(adapt, pxmitframe); ++ spin_unlock_bh(&pxmitpriv->lock); ++ ++ if (res != _SUCCESS) { ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ ++ /* Trick, make the statistics correct */ ++ pxmitpriv->tx_pkts--; ++ pxmitpriv->tx_drop++; ++ return true; ++ } ++ ++ return false; ++} ++ ++s32 rtl8188eu_mgnt_xmit(struct adapter *adapt, struct xmit_frame *pmgntframe) ++{ ++ return rtw_dump_xframe(adapt, pmgntframe); ++} ++ ++/* ++ * Return ++ * true dump packet directly ok ++ * false temporary can't transmit packets to hardware ++ */ ++s32 rtl8188eu_hal_xmit(struct adapter *adapt, struct xmit_frame *pxmitframe) ++{ ++ return pre_xmitframe(adapt, pxmitframe); ++} +diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c +new file mode 100644 +index 000000000000..5cdabf43d4fd +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/usb_halinit.c +@@ -0,0 +1,2271 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _HCI_HAL_INIT_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtw_efuse.h" ++ ++#include "../include/rtl8188e_hal.h" ++#include "../include/rtl8188e_led.h" ++#include "../include/rtw_iol.h" ++#include "../include/usb_ops.h" ++#include "../include/usb_osintf.h" ++ ++#define HAL_MAC_ENABLE 1 ++#define HAL_BB_ENABLE 1 ++#define HAL_RF_ENABLE 1 ++ ++static void _ConfigNormalChipOutEP_8188E(struct adapter *adapt, u8 NumOutPipe) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ ++ switch (NumOutPipe) { ++ case 3: ++ haldata->OutEpQueueSel = TX_SELE_HQ | TX_SELE_LQ | TX_SELE_NQ; ++ haldata->OutEpNumber = 3; ++ break; ++ case 2: ++ haldata->OutEpQueueSel = TX_SELE_HQ | TX_SELE_NQ; ++ haldata->OutEpNumber = 2; ++ break; ++ case 1: ++ haldata->OutEpQueueSel = TX_SELE_HQ; ++ haldata->OutEpNumber = 1; ++ break; ++ default: ++ break; ++ } ++ DBG_88E("%s OutEpQueueSel(0x%02x), OutEpNumber(%d)\n", __func__, haldata->OutEpQueueSel, haldata->OutEpNumber); ++} ++ ++static bool HalUsbSetQueuePipeMapping8188EUsb(struct adapter *adapt, u8 NumInPipe, u8 NumOutPipe) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ bool result = false; ++ ++ _ConfigNormalChipOutEP_8188E(adapt, NumOutPipe); ++ ++ /* Normal chip with one IN and one OUT doesn't have interrupt IN EP. */ ++ if (1 == haldata->OutEpNumber) { ++ if (1 != NumInPipe) ++ return result; ++ } ++ ++ /* All config other than above support one Bulk IN and one Interrupt IN. */ ++ ++ result = Hal_MappingOutPipe(adapt, NumOutPipe); ++ ++ return result; ++} ++ ++static void rtl8188eu_interface_configure(struct adapter *adapt) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapt); ++ ++ if (pdvobjpriv->ishighspeed) ++ haldata->UsbBulkOutSize = USB_HIGH_SPEED_BULK_SIZE;/* 512 bytes */ ++ else ++ haldata->UsbBulkOutSize = USB_FULL_SPEED_BULK_SIZE;/* 64 bytes */ ++ ++ haldata->interfaceIndex = pdvobjpriv->InterfaceNumber; ++ ++ haldata->UsbTxAggMode = 1; ++ haldata->UsbTxAggDescNum = 0x6; /* only 4 bits */ ++ ++ haldata->UsbRxAggMode = USB_RX_AGG_DMA;/* USB_RX_AGG_DMA; */ ++ haldata->UsbRxAggBlockCount = 8; /* unit : 512b */ ++ haldata->UsbRxAggBlockTimeout = 0x6; ++ haldata->UsbRxAggPageCount = 48; /* uint :128 b 0x0A; 10 = MAX_RX_DMA_BUFFER_SIZE/2/haldata->UsbBulkOutSize */ ++ haldata->UsbRxAggPageTimeout = 0x4; /* 6, absolute time = 34ms/(2^6) */ ++ ++ HalUsbSetQueuePipeMapping8188EUsb(adapt, ++ pdvobjpriv->RtNumInPipes, pdvobjpriv->RtNumOutPipes); ++} ++ ++static u32 rtl8188eu_InitPowerOn(struct adapter *adapt) ++{ ++ u16 value16; ++ /* HW Power on sequence */ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ if (haldata->bMacPwrCtrlOn) ++ return _SUCCESS; ++ ++ if (!HalPwrSeqCmdParsing(adapt, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_PWR_ON_FLOW)) { ++ DBG_88E(KERN_ERR "%s: run power on flow fail\n", __func__); ++ return _FAIL; ++ } ++ ++ /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */ ++ /* Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */ ++ rtw_write16(adapt, REG_CR, 0x00); /* suggseted by zhouzhou, by page, 20111230 */ ++ ++ /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */ ++ value16 = rtw_read16(adapt, REG_CR); ++ value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN ++ | PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN); ++ /* for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */ ++ ++ rtw_write16(adapt, REG_CR, value16); ++ haldata->bMacPwrCtrlOn = true; ++ ++ return _SUCCESS; ++} ++ ++/* Shall USB interface init this? */ ++static void _InitInterrupt(struct adapter *Adapter) ++{ ++ u32 imr, imr_ex; ++ u8 usb_opt; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ /* HISR write one to clear */ ++ rtw_write32(Adapter, REG_HISR_88E, 0xFFFFFFFF); ++ /* HIMR - */ ++ imr = IMR_PSTIMEOUT_88E | IMR_TBDER_88E | IMR_CPWM_88E | IMR_CPWM2_88E; ++ rtw_write32(Adapter, REG_HIMR_88E, imr); ++ haldata->IntrMask[0] = imr; ++ ++ imr_ex = IMR_TXERR_88E | IMR_RXERR_88E | IMR_TXFOVW_88E | IMR_RXFOVW_88E; ++ rtw_write32(Adapter, REG_HIMRE_88E, imr_ex); ++ haldata->IntrMask[1] = imr_ex; ++ ++ /* REG_USB_SPECIAL_OPTION - BIT(4) */ ++ /* 0; Use interrupt endpoint to upload interrupt pkt */ ++ /* 1; Use bulk endpoint to upload interrupt pkt, */ ++ usb_opt = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION); ++ ++ if (!adapter_to_dvobj(Adapter)->ishighspeed) ++ usb_opt = usb_opt & (~INT_BULK_SEL); ++ else ++ usb_opt = usb_opt | (INT_BULK_SEL); ++ ++ rtw_write8(Adapter, REG_USB_SPECIAL_OPTION, usb_opt); ++} ++ ++static void _InitQueueReservedPage(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ struct registry_priv *pregistrypriv = &Adapter->registrypriv; ++ u32 numHQ = 0; ++ u32 numLQ = 0; ++ u32 numNQ = 0; ++ u32 numPubQ; ++ u32 value32; ++ u8 value8; ++ bool bWiFiConfig = pregistrypriv->wifi_spec; ++ ++ if (bWiFiConfig) { ++ if (haldata->OutEpQueueSel & TX_SELE_HQ) ++ numHQ = 0x29; ++ ++ if (haldata->OutEpQueueSel & TX_SELE_LQ) ++ numLQ = 0x1C; ++ ++ /* NOTE: This step shall be proceed before writting REG_RQPN. */ ++ if (haldata->OutEpQueueSel & TX_SELE_NQ) ++ numNQ = 0x1C; ++ value8 = (u8)_NPQ(numNQ); ++ rtw_write8(Adapter, REG_RQPN_NPQ, value8); ++ ++ numPubQ = 0xA8 - numHQ - numLQ - numNQ; ++ ++ /* TX DMA */ ++ value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN; ++ rtw_write32(Adapter, REG_RQPN, value32); ++ } else { ++ rtw_write16(Adapter, REG_RQPN_NPQ, 0x0000);/* Just follow MP Team,??? Georgia 03/28 */ ++ rtw_write16(Adapter, REG_RQPN_NPQ, 0x0d); ++ rtw_write32(Adapter, REG_RQPN, 0x808E000d);/* reserve 7 page for LPS */ ++ } ++} ++ ++static void _InitTxBufferBoundary(struct adapter *Adapter, u8 txpktbuf_bndy) ++{ ++ rtw_write8(Adapter, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); ++ rtw_write8(Adapter, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); ++ rtw_write8(Adapter, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy); ++ rtw_write8(Adapter, REG_TRXFF_BNDY, txpktbuf_bndy); ++ rtw_write8(Adapter, REG_TDECTRL + 1, txpktbuf_bndy); ++} ++ ++static void _InitPageBoundary(struct adapter *Adapter) ++{ ++ /* RX Page Boundary */ ++ /* */ ++ u16 rxff_bndy = MAX_RX_DMA_BUFFER_SIZE_88E - 1; ++ ++ rtw_write16(Adapter, (REG_TRXFF_BNDY + 2), rxff_bndy); ++} ++ ++static void _InitNormalChipRegPriority(struct adapter *Adapter, u16 beQ, ++ u16 bkQ, u16 viQ, u16 voQ, u16 mgtQ, ++ u16 hiQ) ++{ ++ u16 value16 = (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7); ++ ++ value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) | ++ _TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) | ++ _TXDMA_MGQ_MAP(mgtQ) | _TXDMA_HIQ_MAP(hiQ); ++ ++ rtw_write16(Adapter, REG_TRXDMA_CTRL, value16); ++} ++ ++static void _InitNormalChipOneOutEpPriority(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ u16 value = 0; ++ switch (haldata->OutEpQueueSel) { ++ case TX_SELE_HQ: ++ value = QUEUE_HIGH; ++ break; ++ case TX_SELE_LQ: ++ value = QUEUE_LOW; ++ break; ++ case TX_SELE_NQ: ++ value = QUEUE_NORMAL; ++ break; ++ default: ++ break; ++ } ++ _InitNormalChipRegPriority(Adapter, value, value, value, value, ++ value, value); ++} ++ ++static void _InitNormalChipTwoOutEpPriority(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ struct registry_priv *pregistrypriv = &Adapter->registrypriv; ++ u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ; ++ u16 valueHi = 0; ++ u16 valueLow = 0; ++ ++ switch (haldata->OutEpQueueSel) { ++ case (TX_SELE_HQ | TX_SELE_LQ): ++ valueHi = QUEUE_HIGH; ++ valueLow = QUEUE_LOW; ++ break; ++ case (TX_SELE_NQ | TX_SELE_LQ): ++ valueHi = QUEUE_NORMAL; ++ valueLow = QUEUE_LOW; ++ break; ++ case (TX_SELE_HQ | TX_SELE_NQ): ++ valueHi = QUEUE_HIGH; ++ valueLow = QUEUE_NORMAL; ++ break; ++ default: ++ break; ++ } ++ ++ if (!pregistrypriv->wifi_spec) { ++ beQ = valueLow; ++ bkQ = valueLow; ++ viQ = valueHi; ++ voQ = valueHi; ++ mgtQ = valueHi; ++ hiQ = valueHi; ++ } else {/* for WMM ,CONFIG_OUT_EP_WIFI_MODE */ ++ beQ = valueLow; ++ bkQ = valueHi; ++ viQ = valueHi; ++ voQ = valueLow; ++ mgtQ = valueHi; ++ hiQ = valueHi; ++ } ++ _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ); ++} ++ ++static void _InitNormalChipThreeOutEpPriority(struct adapter *Adapter) ++{ ++ struct registry_priv *pregistrypriv = &Adapter->registrypriv; ++ u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ; ++ ++ if (!pregistrypriv->wifi_spec) {/* typical setting */ ++ beQ = QUEUE_LOW; ++ bkQ = QUEUE_LOW; ++ viQ = QUEUE_NORMAL; ++ voQ = QUEUE_HIGH; ++ mgtQ = QUEUE_HIGH; ++ hiQ = QUEUE_HIGH; ++ } else {/* for WMM */ ++ beQ = QUEUE_LOW; ++ bkQ = QUEUE_NORMAL; ++ viQ = QUEUE_NORMAL; ++ voQ = QUEUE_HIGH; ++ mgtQ = QUEUE_HIGH; ++ hiQ = QUEUE_HIGH; ++ } ++ _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ); ++} ++ ++static void _InitQueuePriority(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ switch (haldata->OutEpNumber) { ++ case 1: ++ _InitNormalChipOneOutEpPriority(Adapter); ++ break; ++ case 2: ++ _InitNormalChipTwoOutEpPriority(Adapter); ++ break; ++ case 3: ++ _InitNormalChipThreeOutEpPriority(Adapter); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void _InitNetworkType(struct adapter *Adapter) ++{ ++ u32 value32; ++ ++ value32 = rtw_read32(Adapter, REG_CR); ++ /* TODO: use the other function to set network type */ ++ value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP); ++ ++ rtw_write32(Adapter, REG_CR, value32); ++} ++ ++static void _InitTransferPageSize(struct adapter *Adapter) ++{ ++ /* Tx page size is always 128. */ ++ ++ u8 value8; ++ value8 = _PSRX(PBP_128) | _PSTX(PBP_128); ++ rtw_write8(Adapter, REG_PBP, value8); ++} ++ ++static void _InitDriverInfoSize(struct adapter *Adapter, u8 drvInfoSize) ++{ ++ rtw_write8(Adapter, REG_RX_DRVINFO_SZ, drvInfoSize); ++} ++ ++static void _InitWMACSetting(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ haldata->ReceiveConfig = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | ++ RCR_CBSSID_DATA | RCR_CBSSID_BCN | ++ RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL | ++ RCR_APP_MIC | RCR_APP_PHYSTS; ++ ++ /* some REG_RCR will be modified later by phy_ConfigMACWithHeaderFile() */ ++ rtw_write32(Adapter, REG_RCR, haldata->ReceiveConfig); ++ ++ /* Accept all multicast address */ ++ rtw_write32(Adapter, REG_MAR, 0xFFFFFFFF); ++ rtw_write32(Adapter, REG_MAR + 4, 0xFFFFFFFF); ++} ++ ++static void _InitAdaptiveCtrl(struct adapter *Adapter) ++{ ++ u16 value16; ++ u32 value32; ++ ++ /* Response Rate Set */ ++ value32 = rtw_read32(Adapter, REG_RRSR); ++ value32 &= ~RATE_BITMAP_ALL; ++ value32 |= RATE_RRSR_CCK_ONLY_1M; ++ rtw_write32(Adapter, REG_RRSR, value32); ++ ++ /* CF-END Threshold */ ++ ++ /* SIFS (used in NAV) */ ++ value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10); ++ rtw_write16(Adapter, REG_SPEC_SIFS, value16); ++ ++ /* Retry Limit */ ++ value16 = _LRL(0x30) | _SRL(0x30); ++ rtw_write16(Adapter, REG_RL, value16); ++} ++ ++static void _InitEDCA(struct adapter *Adapter) ++{ ++ /* Set Spec SIFS (used in NAV) */ ++ rtw_write16(Adapter, REG_SPEC_SIFS, 0x100a); ++ rtw_write16(Adapter, REG_MAC_SPEC_SIFS, 0x100a); ++ ++ /* Set SIFS for CCK */ ++ rtw_write16(Adapter, REG_SIFS_CTX, 0x100a); ++ ++ /* Set SIFS for OFDM */ ++ rtw_write16(Adapter, REG_SIFS_TRX, 0x100a); ++ ++ /* TXOP */ ++ rtw_write32(Adapter, REG_EDCA_BE_PARAM, 0x005EA42B); ++ rtw_write32(Adapter, REG_EDCA_BK_PARAM, 0x0000A44F); ++ rtw_write32(Adapter, REG_EDCA_VI_PARAM, 0x005EA324); ++ rtw_write32(Adapter, REG_EDCA_VO_PARAM, 0x002FA226); ++} ++ ++static void _InitBeaconMaxError(struct adapter *Adapter, bool InfraMode) ++{ ++} ++ ++static void _InitHWLed(struct adapter *Adapter) ++{ ++ struct led_priv *pledpriv = &Adapter->ledpriv; ++ ++ if (pledpriv->LedStrategy != HW_LED) ++ return; ++ ++/* HW led control */ ++/* to do .... */ ++/* must consider cases of antenna diversity/ commbo card/solo card/mini card */ ++} ++ ++static void _InitRDGSetting(struct adapter *Adapter) ++{ ++ rtw_write8(Adapter, REG_RD_CTRL, 0xFF); ++ rtw_write16(Adapter, REG_RD_NAV_NXT, 0x200); ++ rtw_write8(Adapter, REG_RD_RESP_PKT_TH, 0x05); ++} ++ ++static void _InitRxSetting(struct adapter *Adapter) ++{ ++ rtw_write32(Adapter, REG_MACID, 0x87654321); ++ rtw_write32(Adapter, 0x0700, 0x87654321); ++} ++ ++static void _InitRetryFunction(struct adapter *Adapter) ++{ ++ u8 value8; ++ ++ value8 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL); ++ value8 |= EN_AMPDU_RTY_NEW; ++ rtw_write8(Adapter, REG_FWHW_TXQ_CTRL, value8); ++ ++ /* Set ACK timeout */ ++ rtw_write8(Adapter, REG_ACKTO, 0x40); ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: usb_AggSettingTxUpdate() ++ * ++ * Overview: Separate TX/RX parameters update independent for TP detection and ++ * dynamic TX/RX aggreagtion parameters update. ++ * ++ * Input: struct adapter * ++ * ++ * Output/Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 12/10/2010 MHC Separate to smaller function. ++ * ++ *---------------------------------------------------------------------------*/ ++static void usb_AggSettingTxUpdate(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ u32 value32; ++ ++ if (Adapter->registrypriv.wifi_spec) ++ haldata->UsbTxAggMode = false; ++ ++ if (haldata->UsbTxAggMode) { ++ value32 = rtw_read32(Adapter, REG_TDECTRL); ++ value32 = value32 & ~(BLK_DESC_NUM_MASK << BLK_DESC_NUM_SHIFT); ++ value32 |= ((haldata->UsbTxAggDescNum & BLK_DESC_NUM_MASK) << BLK_DESC_NUM_SHIFT); ++ ++ rtw_write32(Adapter, REG_TDECTRL, value32); ++ } ++} /* usb_AggSettingTxUpdate */ ++ ++/*----------------------------------------------------------------------------- ++ * Function: usb_AggSettingRxUpdate() ++ * ++ * Overview: Separate TX/RX parameters update independent for TP detection and ++ * dynamic TX/RX aggreagtion parameters update. ++ * ++ * Input: struct adapter * ++ * ++ * Output/Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 12/10/2010 MHC Separate to smaller function. ++ * ++ *---------------------------------------------------------------------------*/ ++static void ++usb_AggSettingRxUpdate( ++ struct adapter *Adapter ++ ) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ u8 valueDMA; ++ u8 valueUSB; ++ ++ valueDMA = rtw_read8(Adapter, REG_TRXDMA_CTRL); ++ valueUSB = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION); ++ ++ switch (haldata->UsbRxAggMode) { ++ case USB_RX_AGG_DMA: ++ valueDMA |= RXDMA_AGG_EN; ++ valueUSB &= ~USB_AGG_EN; ++ break; ++ case USB_RX_AGG_USB: ++ valueDMA &= ~RXDMA_AGG_EN; ++ valueUSB |= USB_AGG_EN; ++ break; ++ case USB_RX_AGG_MIX: ++ valueDMA |= RXDMA_AGG_EN; ++ valueUSB |= USB_AGG_EN; ++ break; ++ case USB_RX_AGG_DISABLE: ++ default: ++ valueDMA &= ~RXDMA_AGG_EN; ++ valueUSB &= ~USB_AGG_EN; ++ break; ++ } ++ ++ rtw_write8(Adapter, REG_TRXDMA_CTRL, valueDMA); ++ rtw_write8(Adapter, REG_USB_SPECIAL_OPTION, valueUSB); ++ ++ switch (haldata->UsbRxAggMode) { ++ case USB_RX_AGG_DMA: ++ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, haldata->UsbRxAggPageCount); ++ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH + 1, haldata->UsbRxAggPageTimeout); ++ break; ++ case USB_RX_AGG_USB: ++ rtw_write8(Adapter, REG_USB_AGG_TH, haldata->UsbRxAggBlockCount); ++ rtw_write8(Adapter, REG_USB_AGG_TO, haldata->UsbRxAggBlockTimeout); ++ break; ++ case USB_RX_AGG_MIX: ++ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, haldata->UsbRxAggPageCount); ++ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH + 1, (haldata->UsbRxAggPageTimeout & 0x1F));/* 0x280[12:8] */ ++ rtw_write8(Adapter, REG_USB_AGG_TH, haldata->UsbRxAggBlockCount); ++ rtw_write8(Adapter, REG_USB_AGG_TO, haldata->UsbRxAggBlockTimeout); ++ break; ++ case USB_RX_AGG_DISABLE: ++ default: ++ /* TODO: */ ++ break; ++ } ++ ++ switch (PBP_128) { ++ case PBP_128: ++ haldata->HwRxPageSize = 128; ++ break; ++ case PBP_64: ++ haldata->HwRxPageSize = 64; ++ break; ++ case PBP_256: ++ haldata->HwRxPageSize = 256; ++ break; ++ case PBP_512: ++ haldata->HwRxPageSize = 512; ++ break; ++ case PBP_1024: ++ haldata->HwRxPageSize = 1024; ++ break; ++ default: ++ break; ++ } ++} /* usb_AggSettingRxUpdate */ ++ ++static void InitUsbAggregationSetting(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ /* Tx aggregation setting */ ++ usb_AggSettingTxUpdate(Adapter); ++ ++ /* Rx aggregation setting */ ++ usb_AggSettingRxUpdate(Adapter); ++ ++ /* 201/12/10 MH Add for USB agg mode dynamic switch. */ ++ haldata->UsbRxHighSpeedMode = false; ++} ++ ++static void _InitOperationMode(struct adapter *Adapter) ++{ ++} ++ ++static void _InitBeaconParameters(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ rtw_write16(Adapter, REG_BCN_CTRL, 0x1010); ++ ++ /* TODO: Remove these magic number */ ++ rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0x6404);/* ms */ ++ rtw_write8(Adapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);/* 5ms */ ++ rtw_write8(Adapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); /* 2ms */ ++ ++ /* Suggested by designer timchen. Change beacon AIFS to the largest number */ ++ /* beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */ ++ rtw_write16(Adapter, REG_BCNTCFG, 0x660F); ++ ++ haldata->RegBcnCtrlVal = rtw_read8(Adapter, REG_BCN_CTRL); ++ haldata->RegTxPause = rtw_read8(Adapter, REG_TXPAUSE); ++ haldata->RegFwHwTxQCtrl = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2); ++ haldata->RegReg542 = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2); ++ haldata->RegCR_1 = rtw_read8(Adapter, REG_CR + 1); ++} ++ ++static void _BeaconFunctionEnable(struct adapter *Adapter, ++ bool Enable, bool Linked) ++{ ++ rtw_write8(Adapter, REG_BCN_CTRL, (BIT(4) | BIT(3) | BIT(1))); ++ ++ rtw_write8(Adapter, REG_RD_CTRL + 1, 0x6F); ++} ++ ++/* Set CCK and OFDM Block "ON" */ ++static void _BBTurnOnBlock(struct adapter *Adapter) ++{ ++ PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bCCKEn, 0x1); ++ PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bOFDMEn, 0x1); ++} ++ ++enum { ++ Antenna_Lfet = 1, ++ Antenna_Right = 2, ++}; ++ ++static void _InitAntenna_Selection(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ if (haldata->AntDivCfg == 0) ++ return; ++ DBG_88E("==> %s ....\n", __func__); ++ ++ rtw_write32(Adapter, REG_LEDCFG0, rtw_read32(Adapter, REG_LEDCFG0) | BIT(23)); ++ PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, BIT(13), 0x01); ++ ++ if (PHY_QueryBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300) == Antenna_A) ++ haldata->CurAntenna = Antenna_A; ++ else ++ haldata->CurAntenna = Antenna_B; ++ DBG_88E("%s,Cur_ant:(%x)%s\n", __func__, haldata->CurAntenna, (haldata->CurAntenna == Antenna_A) ? "Antenna_A" : "Antenna_B"); ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: HwSuspendModeEnable92Cu() ++ * ++ * Overview: HW suspend mode switch. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 08/23/2010 MHC HW suspend mode switch test.. ++ *---------------------------------------------------------------------------*/ ++enum rt_rf_power_state RfOnOffDetect(struct adapter *adapt) ++{ ++ u8 val8; ++ enum rt_rf_power_state rfpowerstate = rf_off; ++ ++ if (adapt->pwrctrlpriv.bHWPowerdown) { ++ val8 = rtw_read8(adapt, REG_HSISR); ++ DBG_88E("pwrdown, 0x5c(BIT(7))=%02x\n", val8); ++ rfpowerstate = (val8 & BIT(7)) ? rf_off : rf_on; ++ } else { /* rf on/off */ ++ rtw_write8(adapt, REG_MAC_PINMUX_CFG, rtw_read8(adapt, REG_MAC_PINMUX_CFG) & ~(BIT(3))); ++ val8 = rtw_read8(adapt, REG_GPIO_IO_SEL); ++ DBG_88E("GPIO_IN=%02x\n", val8); ++ rfpowerstate = (val8 & BIT(3)) ? rf_on : rf_off; ++ } ++ return rfpowerstate; ++} /* HalDetectPwrDownMode */ ++ ++static u32 rtl8188eu_hal_init(struct adapter *Adapter) ++{ ++ u8 value8 = 0; ++ u16 value16; ++ u8 txpktbuf_bndy; ++ u32 status = _SUCCESS; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv; ++ struct registry_priv *pregistrypriv = &Adapter->registrypriv; ++ u32 init_start_time = jiffies; ++ ++ #define HAL_INIT_PROFILE_TAG(stage) do {} while (0) ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BEGIN); ++ ++ if (Adapter->pwrctrlpriv.bkeepfwalive) { ++ _ps_open_RF(Adapter); ++ ++ if (haldata->odmpriv.RFCalibrateInfo.bIQKInitialized) { ++ PHY_IQCalibrate_8188E(Adapter, true); ++ } else { ++ PHY_IQCalibrate_8188E(Adapter, false); ++ haldata->odmpriv.RFCalibrateInfo.bIQKInitialized = true; ++ } ++ ++ ODM_TXPowerTrackingCheck(&haldata->odmpriv); ++ PHY_LCCalibrate_8188E(Adapter); ++ ++ goto exit; ++ } ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PW_ON); ++ status = rtl8188eu_InitPowerOn(Adapter); ++ if (status == _FAIL) ++ goto exit; ++ ++ /* Save target channel */ ++ haldata->CurrentChannel = 6;/* default set to 6 */ ++ ++ if (pwrctrlpriv->reg_rfoff) { ++ pwrctrlpriv->rf_pwrstate = rf_off; ++ } ++ ++ /* 2010/08/09 MH We need to check if we need to turnon or off RF after detecting */ ++ /* HW GPIO pin. Before PHY_RFConfig8192C. */ ++ /* 2010/08/26 MH If Efuse does not support sective suspend then disable the function. */ ++ ++ if (!pregistrypriv->wifi_spec) { ++ txpktbuf_bndy = TX_PAGE_BOUNDARY_88E; ++ } else { ++ /* for WMM */ ++ txpktbuf_bndy = WMM_NORMAL_TX_PAGE_BOUNDARY_88E; ++ } ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC01); ++ _InitQueueReservedPage(Adapter); ++ _InitQueuePriority(Adapter); ++ _InitPageBoundary(Adapter); ++ _InitTransferPageSize(Adapter); ++ ++ _InitTxBufferBoundary(Adapter, 0); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_DOWNLOAD_FW); ++ if (Adapter->registrypriv.mp_mode == 1) { ++ _InitRxSetting(Adapter); ++ Adapter->bFWReady = false; ++ haldata->fw_ractrl = false; ++ } else { ++ status = rtl8188e_FirmwareDownload(Adapter); ++ ++ if (status != _SUCCESS) { ++ DBG_88E("%s: Download Firmware failed!!\n", __func__); ++ Adapter->bFWReady = false; ++ haldata->fw_ractrl = false; ++ return status; ++ } else { ++ Adapter->bFWReady = true; ++ haldata->fw_ractrl = false; ++ } ++ } ++ rtl8188e_InitializeFirmwareVars(Adapter); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MAC); ++#if (HAL_MAC_ENABLE == 1) ++ status = PHY_MACConfig8188E(Adapter); ++ if (status == _FAIL) { ++ DBG_88E(" ### Failed to init MAC ......\n "); ++ goto exit; ++ } ++#endif ++ ++ /* */ ++ /* d. Initialize BB related configurations. */ ++ /* */ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BB); ++#if (HAL_BB_ENABLE == 1) ++ status = PHY_BBConfig8188E(Adapter); ++ if (status == _FAIL) { ++ DBG_88E(" ### Failed to init BB ......\n "); ++ goto exit; ++ } ++#endif ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_RF); ++#if (HAL_RF_ENABLE == 1) ++ status = PHY_RFConfig8188E(Adapter); ++ if (status == _FAIL) { ++ DBG_88E(" ### Failed to init RF ......\n "); ++ goto exit; ++ } ++#endif ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_EFUSE_PATCH); ++ status = rtl8188e_iol_efuse_patch(Adapter); ++ if (status == _FAIL) { ++ DBG_88E("%s rtl8188e_iol_efuse_patch failed\n", __func__); ++ goto exit; ++ } ++ ++ _InitTxBufferBoundary(Adapter, txpktbuf_bndy); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_LLTT); ++ status = InitLLTTable(Adapter, txpktbuf_bndy); ++ if (status == _FAIL) ++ goto exit; ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC02); ++ /* Get Rx PHY status in order to report RSSI and others. */ ++ _InitDriverInfoSize(Adapter, DRVINFO_SZ); ++ ++ _InitInterrupt(Adapter); ++ hal_init_macaddr(Adapter);/* set mac_address */ ++ _InitNetworkType(Adapter);/* set msr */ ++ _InitWMACSetting(Adapter); ++ _InitAdaptiveCtrl(Adapter); ++ _InitEDCA(Adapter); ++ _InitRetryFunction(Adapter); ++ InitUsbAggregationSetting(Adapter); ++ _InitOperationMode(Adapter);/* todo */ ++ _InitBeaconParameters(Adapter); ++ _InitBeaconMaxError(Adapter, true); ++ ++ /* */ ++ /* Init CR MACTXEN, MACRXEN after setting RxFF boundary REG_TRXFF_BNDY to patch */ ++ /* Hw bug which Hw initials RxFF boundary size to a value which is larger than the real Rx buffer size in 88E. */ ++ /* */ ++ /* Enable MACTXEN/MACRXEN block */ ++ value16 = rtw_read16(Adapter, REG_CR); ++ value16 |= (MACTXEN | MACRXEN); ++ rtw_write8(Adapter, REG_CR, value16); ++ ++ if (haldata->bRDGEnable) ++ _InitRDGSetting(Adapter); ++ ++ /* Enable TX Report */ ++ /* Enable Tx Report Timer */ ++ value8 = rtw_read8(Adapter, REG_TX_RPT_CTRL); ++ rtw_write8(Adapter, REG_TX_RPT_CTRL, (value8 | BIT(1) | BIT(0))); ++ /* Set MAX RPT MACID */ ++ rtw_write8(Adapter, REG_TX_RPT_CTRL + 1, 2);/* FOR sta mode ,0: bc/mc ,1:AP */ ++ /* Tx RPT Timer. Unit: 32us */ ++ rtw_write16(Adapter, REG_TX_RPT_TIME, 0xCdf0); ++ ++ rtw_write8(Adapter, REG_EARLY_MODE_CONTROL, 0); ++ ++ rtw_write16(Adapter, REG_PKT_VO_VI_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */ ++ rtw_write16(Adapter, REG_PKT_BE_BK_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */ ++ ++ _InitHWLed(Adapter); ++ ++ /* Keep RfRegChnlVal for later use. */ ++ haldata->RfRegChnlVal[0] = PHY_QueryRFReg(Adapter, (enum rf_radio_path)0, RF_CHNLBW, bRFRegOffsetMask); ++ haldata->RfRegChnlVal[1] = PHY_QueryRFReg(Adapter, (enum rf_radio_path)1, RF_CHNLBW, bRFRegOffsetMask); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_TURN_ON_BLOCK); ++ _BBTurnOnBlock(Adapter); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_SECURITY); ++ invalidate_cam_all(Adapter); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC11); ++ /* 2010/12/17 MH We need to set TX power according to EFUSE content at first. */ ++ PHY_SetTxPowerLevel8188E(Adapter, haldata->CurrentChannel); ++ ++/* Move by Neo for USB SS to below setp */ ++/* _RfPowerSave(Adapter); */ ++ ++ _InitAntenna_Selection(Adapter); ++ ++ /* */ ++ /* Disable BAR, suggested by Scott */ ++ /* 2010.04.09 add by hpfan */ ++ /* */ ++ rtw_write32(Adapter, REG_BAR_MODE_CTRL, 0x0201ffff); ++ ++ /* HW SEQ CTRL */ ++ /* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */ ++ rtw_write8(Adapter, REG_HWSEQ_CTRL, 0xFF); ++ ++ if (pregistrypriv->wifi_spec) ++ rtw_write16(Adapter, REG_FAST_EDCA_CTRL, 0); ++ ++ /* Nav limit , suggest by scott */ ++ rtw_write8(Adapter, 0x652, 0x0); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_HAL_DM); ++ rtl8188e_InitHalDm(Adapter); ++ ++ if (Adapter->registrypriv.mp_mode == 1) { ++ Adapter->mppriv.channel = haldata->CurrentChannel; ++ MPT_InitializeAdapter(Adapter, Adapter->mppriv.channel); ++ } else { ++ /* 2010/08/11 MH Merge from 8192SE for Minicard init. We need to confirm current radio status */ ++ /* and then decide to enable RF or not.!!!??? For Selective suspend mode. We may not */ ++ /* call initstruct adapter. May cause some problem?? */ ++ /* Fix the bug that Hw/Sw radio off before S3/S4, the RF off action will not be executed */ ++ /* in MgntActSet_RF_State() after wake up, because the value of haldata->eRFPowerState */ ++ /* is the same as eRfOff, we should change it to eRfOn after we config RF parameters. */ ++ /* Added by tynli. 2010.03.30. */ ++ pwrctrlpriv->rf_pwrstate = rf_on; ++ ++ /* enable Tx report. */ ++ rtw_write8(Adapter, REG_FWHW_TXQ_CTRL + 1, 0x0F); ++ ++ /* Suggested by SD1 pisa. Added by tynli. 2011.10.21. */ ++ rtw_write8(Adapter, REG_EARLY_MODE_CONTROL + 3, 0x01);/* Pretx_en, for WEP/TKIP SEC */ ++ ++ /* tynli_test_tx_report. */ ++ rtw_write16(Adapter, REG_TX_RPT_TIME, 0x3DF0); ++ ++ /* enable tx DMA to drop the redundate data of packet */ ++ rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK) | DROP_DATA_EN)); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK); ++ /* 2010/08/26 MH Merge from 8192CE. */ ++ if (pwrctrlpriv->rf_pwrstate == rf_on) { ++ if (haldata->odmpriv.RFCalibrateInfo.bIQKInitialized) { ++ PHY_IQCalibrate_8188E(Adapter, true); ++ } else { ++ PHY_IQCalibrate_8188E(Adapter, false); ++ haldata->odmpriv.RFCalibrateInfo.bIQKInitialized = true; ++ } ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_PW_TRACK); ++ ++ ODM_TXPowerTrackingCheck(&haldata->odmpriv); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_LCK); ++ PHY_LCCalibrate_8188E(Adapter); ++ } ++ } ++ ++/* HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PABIAS); */ ++/* _InitPABias(Adapter); */ ++ rtw_write8(Adapter, REG_USB_HRPWM, 0); ++ ++ /* ack for xmit mgmt frames. */ ++ rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, rtw_read32(Adapter, REG_FWHW_TXQ_CTRL) | BIT(12)); ++ ++exit: ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END); ++ ++ DBG_88E("%s in %dms\n", __func__, rtw_get_passing_time_ms(init_start_time)); ++ ++ return status; ++} ++ ++void _ps_open_RF(struct adapter *adapt) ++{ ++ /* here call with bRegSSPwrLvl 1, bRegSSPwrLvl 2 needs to be verified */ ++ /* phy_SsPwrSwitch92CU(adapt, rf_on, 1); */ ++} ++ ++static void _ps_close_RF(struct adapter *adapt) ++{ ++ /* here call with bRegSSPwrLvl 1, bRegSSPwrLvl 2 needs to be verified */ ++ /* phy_SsPwrSwitch92CU(adapt, rf_off, 1); */ ++} ++ ++static void CardDisableRTL8188EU(struct adapter *Adapter) ++{ ++ u8 val8; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ /* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */ ++ val8 = rtw_read8(Adapter, REG_TX_RPT_CTRL); ++ rtw_write8(Adapter, REG_TX_RPT_CTRL, val8 & (~BIT(1))); ++ ++ /* stop rx */ ++ rtw_write8(Adapter, REG_CR, 0x0); ++ ++ /* Run LPS WL RFOFF flow */ ++ HalPwrSeqCmdParsing(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_LPS_ENTER_FLOW); ++ ++ /* 2. 0x1F[7:0] = 0 turn off RF */ ++ ++ val8 = rtw_read8(Adapter, REG_MCUFWDL); ++ if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */ ++ /* Reset MCU 0x2[10]=0. */ ++ val8 = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1); ++ val8 &= ~BIT(2); /* 0x2[10], FEN_CPUEN */ ++ rtw_write8(Adapter, REG_SYS_FUNC_EN + 1, val8); ++ } ++ ++ /* reset MCU ready status */ ++ rtw_write8(Adapter, REG_MCUFWDL, 0); ++ ++ /* YJ,add,111212 */ ++ /* Disable 32k */ ++ val8 = rtw_read8(Adapter, REG_32K_CTRL); ++ rtw_write8(Adapter, REG_32K_CTRL, val8 & (~BIT(0))); ++ ++ /* Card disable power action flow */ ++ HalPwrSeqCmdParsing(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_DISABLE_FLOW); ++ ++ /* Reset MCU IO Wrapper */ ++ val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1); ++ rtw_write8(Adapter, REG_RSV_CTRL + 1, (val8 & (~BIT(3)))); ++ val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1); ++ rtw_write8(Adapter, REG_RSV_CTRL + 1, val8 | BIT(3)); ++ ++ /* YJ,test add, 111207. For Power Consumption. */ ++ val8 = rtw_read8(Adapter, GPIO_IN); ++ rtw_write8(Adapter, GPIO_OUT, val8); ++ rtw_write8(Adapter, GPIO_IO_SEL, 0xFF);/* Reg0x46 */ ++ ++ val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL); ++ rtw_write8(Adapter, REG_GPIO_IO_SEL, (val8 << 4)); ++ val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1); ++ rtw_write8(Adapter, REG_GPIO_IO_SEL + 1, val8 | 0x0F);/* Reg0x43 */ ++ rtw_write32(Adapter, REG_BB_PAD_CTRL, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */ ++ haldata->bMacPwrCtrlOn = false; ++ Adapter->bFWReady = false; ++} ++static void rtl8192cu_hw_power_down(struct adapter *adapt) ++{ ++ /* 2010/-8/09 MH For power down module, we need to enable register block contrl reg at 0x1c. */ ++ /* Then enable power down control bit of register 0x04 BIT(4) and BIT(15) as 1. */ ++ ++ /* Enable register area 0x0-0xc. */ ++ rtw_write8(adapt, REG_RSV_CTRL, 0x0); ++ rtw_write16(adapt, REG_APS_FSMCO, 0x8812); ++} ++ ++static u32 rtl8188eu_hal_deinit(struct adapter *Adapter) ++{ ++ ++ DBG_88E("==> %s\n", __func__); ++ ++ rtw_write32(Adapter, REG_HIMR_88E, IMR_DISABLED_88E); ++ rtw_write32(Adapter, REG_HIMRE_88E, IMR_DISABLED_88E); ++ ++ DBG_88E("bkeepfwalive(%x)\n", Adapter->pwrctrlpriv.bkeepfwalive); ++ if (Adapter->pwrctrlpriv.bkeepfwalive) { ++ _ps_close_RF(Adapter); ++ if ((Adapter->pwrctrlpriv.bHWPwrPindetect) && (Adapter->pwrctrlpriv.bHWPowerdown)) ++ rtl8192cu_hw_power_down(Adapter); ++ } else { ++ if (Adapter->hw_init_completed) { ++ CardDisableRTL8188EU(Adapter); ++ ++ if ((Adapter->pwrctrlpriv.bHWPwrPindetect) && (Adapter->pwrctrlpriv.bHWPowerdown)) ++ rtl8192cu_hw_power_down(Adapter); ++ } ++ } ++ return _SUCCESS; ++ } ++ ++static unsigned int rtl8188eu_inirp_init(struct adapter *Adapter) ++{ ++ u8 i; ++ struct recv_buf *precvbuf; ++ uint status; ++ struct intf_hdl *pintfhdl = &Adapter->iopriv.intf; ++ struct recv_priv *precvpriv = &Adapter->recvpriv; ++ u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); ++ ++ _read_port = pintfhdl->io_ops._read_port; ++ ++ status = _SUCCESS; ++ ++ precvpriv->ff_hwaddr = RECV_BULK_IN_ADDR; ++ ++ /* issue Rx irp to receive data */ ++ precvbuf = (struct recv_buf *)precvpriv->precv_buf; ++ for (i = 0; i < NR_RECVBUFF; i++) { ++ if (!_read_port(pintfhdl, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf)) { ++ status = _FAIL; ++ goto exit; ++ } ++ ++ precvbuf++; ++ precvpriv->free_recv_buf_queue_cnt--; ++ } ++ ++exit: ++ return status; ++} ++ ++static unsigned int rtl8188eu_inirp_deinit(struct adapter *Adapter) ++{ ++ rtw_read_port_cancel(Adapter); ++ ++ return _SUCCESS; ++} ++ ++/* */ ++/* */ ++/* EEPROM/EFUSE Content Parsing */ ++/* */ ++/* */ ++static void _ReadLEDSetting(struct adapter *Adapter, u8 *PROMContent, bool AutoloadFail) ++{ ++ struct led_priv *pledpriv = &Adapter->ledpriv; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ pledpriv->bRegUseLed = true; ++ pledpriv->LedStrategy = SW_LED_MODE1; ++ haldata->bLedOpenDrain = true;/* Support Open-drain arrangement for controlling the LED. */ ++} ++ ++static void Hal_EfuseParsePIDVID_8188EU(struct adapter *adapt, u8 *hwinfo, bool AutoLoadFail) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ ++ if (!AutoLoadFail) { ++ /* VID, PID */ ++ haldata->EEPROMVID = EF2BYTE(*(__le16 *)&hwinfo[EEPROM_VID_88EU]); ++ haldata->EEPROMPID = EF2BYTE(*(__le16 *)&hwinfo[EEPROM_PID_88EU]); ++ ++ /* Customer ID, 0x00 and 0xff are reserved for Realtek. */ ++ haldata->EEPROMCustomerID = *(u8 *)&hwinfo[EEPROM_CUSTOMERID_88E]; ++ haldata->EEPROMSubCustomerID = EEPROM_Default_SubCustomerID; ++ } else { ++ haldata->EEPROMVID = EEPROM_Default_VID; ++ haldata->EEPROMPID = EEPROM_Default_PID; ++ ++ /* Customer ID, 0x00 and 0xff are reserved for Realtek. */ ++ haldata->EEPROMCustomerID = EEPROM_Default_CustomerID; ++ haldata->EEPROMSubCustomerID = EEPROM_Default_SubCustomerID; ++ } ++ ++ DBG_88E("VID = 0x%04X, PID = 0x%04X\n", haldata->EEPROMVID, haldata->EEPROMPID); ++ DBG_88E("Customer ID: 0x%02X, SubCustomer ID: 0x%02X\n", haldata->EEPROMCustomerID, haldata->EEPROMSubCustomerID); ++} ++ ++static void Hal_EfuseParseMACAddr_8188EU(struct adapter *adapt, u8 *hwinfo, bool AutoLoadFail) ++{ ++ u16 i; ++ u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x88, 0x02}; ++ struct eeprom_priv *eeprom = GET_EEPROM_EFUSE_PRIV(adapt); ++ ++ if (AutoLoadFail) { ++ for (i = 0; i < 6; i++) ++ eeprom->mac_addr[i] = sMacAddr[i]; ++ } else { ++ /* Read Permanent MAC address */ ++ memcpy(eeprom->mac_addr, &hwinfo[EEPROM_MAC_ADDR_88EU], ETH_ALEN); ++ } ++} ++ ++static void Hal_CustomizeByCustomerID_8188EU(struct adapter *adapt) ++{ ++} ++ ++static void ++readAdapterInfo_8188EU( ++ struct adapter *adapt ++ ) ++{ ++ struct eeprom_priv *eeprom = GET_EEPROM_EFUSE_PRIV(adapt); ++ ++ /* parse the eeprom/efuse content */ ++ Hal_EfuseParseIDCode88E(adapt, eeprom->efuse_eeprom_data); ++ Hal_EfuseParsePIDVID_8188EU(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_EfuseParseMACAddr_8188EU(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ ++ Hal_ReadPowerSavingMode88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_ReadTxPowerInfo88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_EfuseParseEEPROMVer88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ rtl8188e_EfuseParseChnlPlan(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_EfuseParseXtal_8188E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_EfuseParseCustomerID88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_ReadAntennaDiversity88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_EfuseParseBoardType88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_ReadThermalMeter_88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ ++ /* */ ++ /* The following part initialize some vars by PG info. */ ++ /* */ ++ Hal_InitChannelPlan(adapt); ++ Hal_CustomizeByCustomerID_8188EU(adapt); ++ ++ _ReadLEDSetting(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++} ++ ++static void _ReadPROMContent( ++ struct adapter *Adapter ++ ) ++{ ++ struct eeprom_priv *eeprom = GET_EEPROM_EFUSE_PRIV(Adapter); ++ u8 eeValue; ++ ++ /* check system boot selection */ ++ eeValue = rtw_read8(Adapter, REG_9346CR); ++ eeprom->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false; ++ eeprom->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true; ++ ++ DBG_88E("Boot from %s, Autoload %s !\n", (eeprom->EepromOrEfuse ? "EEPROM" : "EFUSE"), ++ (eeprom->bautoload_fail_flag ? "Fail" : "OK")); ++ ++ Hal_InitPGData88E(Adapter); ++ readAdapterInfo_8188EU(Adapter); ++} ++ ++static void _ReadRFType(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ haldata->rf_chip = RF_6052; ++} ++ ++static int _ReadAdapterInfo8188EU(struct adapter *Adapter) ++{ ++ u32 start = jiffies; ++ ++ MSG_88E("====> %s\n", __func__); ++ ++ _ReadRFType(Adapter);/* rf_chip -> _InitRFType() */ ++ _ReadPROMContent(Adapter); ++ ++ MSG_88E("<==== %s in %d ms\n", __func__, rtw_get_passing_time_ms(start)); ++ ++ return _SUCCESS; ++} ++ ++static void ReadAdapterInfo8188EU(struct adapter *Adapter) ++{ ++ /* Read EEPROM size before call any EEPROM function */ ++ Adapter->EepromAddressSize = GetEEPROMSize8188E(Adapter); ++ ++ _ReadAdapterInfo8188EU(Adapter); ++} ++ ++#define GPIO_DEBUG_PORT_NUM 0 ++static void rtl8192cu_trigger_gpio_0(struct adapter *adapt) ++{ ++} ++ ++static void ResumeTxBeacon(struct adapter *adapt) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ ++ /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */ ++ /* which should be read from register to a global variable. */ ++ ++ rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl) | BIT(6)); ++ haldata->RegFwHwTxQCtrl |= BIT(6); ++ rtw_write8(adapt, REG_TBTT_PROHIBIT + 1, 0xff); ++ haldata->RegReg542 |= BIT(0); ++ rtw_write8(adapt, REG_TBTT_PROHIBIT + 2, haldata->RegReg542); ++} ++ ++static void StopTxBeacon(struct adapter *adapt) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ ++ /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */ ++ /* which should be read from register to a global variable. */ ++ ++ rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl) & (~BIT(6))); ++ haldata->RegFwHwTxQCtrl &= (~BIT(6)); ++ rtw_write8(adapt, REG_TBTT_PROHIBIT + 1, 0x64); ++ haldata->RegReg542 &= ~(BIT(0)); ++ rtw_write8(adapt, REG_TBTT_PROHIBIT + 2, haldata->RegReg542); ++ ++ /* todo: CheckFwRsvdPageContent(Adapter); 2010.06.23. Added by tynli. */ ++} ++ ++static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val) ++{ ++ u8 val8; ++ u8 mode = *((u8 *)val); ++ ++ /* disable Port0 TSF update */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4)); ++ ++ /* set net_type */ ++ val8 = rtw_read8(Adapter, MSR) & 0x0c; ++ val8 |= mode; ++ rtw_write8(Adapter, MSR, val8); ++ ++ DBG_88E("%s()-%d mode = %d\n", __func__, __LINE__, mode); ++ ++ if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) { ++ StopTxBeacon(Adapter); ++ ++ rtw_write8(Adapter, REG_BCN_CTRL, 0x19);/* disable atim wnd */ ++ } else if (mode == _HW_STATE_ADHOC_) { ++ ResumeTxBeacon(Adapter); ++ rtw_write8(Adapter, REG_BCN_CTRL, 0x1a); ++ } else if (mode == _HW_STATE_AP_) { ++ ResumeTxBeacon(Adapter); ++ ++ rtw_write8(Adapter, REG_BCN_CTRL, 0x12); ++ ++ /* Set RCR */ ++ rtw_write32(Adapter, REG_RCR, 0x7000208e);/* CBSSID_DATA must set to 0,reject ICV_ERR packet */ ++ /* enable to rx data frame */ ++ rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF); ++ /* enable to rx ps-poll */ ++ rtw_write16(Adapter, REG_RXFLTMAP1, 0x0400); ++ ++ /* Beacon Control related register for first time */ ++ rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms */ ++ ++ rtw_write8(Adapter, REG_ATIMWND, 0x0a); /* 10ms */ ++ rtw_write16(Adapter, REG_BCNTCFG, 0x00); ++ rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0xff04); ++ rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */ ++ ++ /* reset TSF */ ++ rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0)); ++ ++ /* BIT(3) - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */ ++ rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4)); ++ ++ /* enable BCN0 Function for if1 */ ++ /* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */ ++ rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP | EN_BCN_FUNCTION | BIT(1))); ++ ++ /* dis BCN1 ATIM WND if if2 is station */ ++ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) | BIT(0)); ++ } ++} ++ ++static void hw_var_set_macaddr(struct adapter *Adapter, u8 variable, u8 *val) ++{ ++ u8 idx = 0; ++ u32 reg_macid; ++ ++ reg_macid = REG_MACID; ++ ++ for (idx = 0; idx < 6; idx++) ++ rtw_write8(Adapter, (reg_macid + idx), val[idx]); ++} ++ ++static void hw_var_set_bssid(struct adapter *Adapter, u8 variable, u8 *val) ++{ ++ u8 idx = 0; ++ u32 reg_bssid; ++ ++ reg_bssid = REG_BSSID; ++ ++ for (idx = 0; idx < 6; idx++) ++ rtw_write8(Adapter, (reg_bssid + idx), val[idx]); ++} ++ ++static void hw_var_set_bcn_func(struct adapter *Adapter, u8 variable, u8 *val) ++{ ++ u32 bcn_ctrl_reg; ++ ++ bcn_ctrl_reg = REG_BCN_CTRL; ++ ++ if (*((u8 *)val)) ++ rtw_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT)); ++ else ++ rtw_write8(Adapter, bcn_ctrl_reg, rtw_read8(Adapter, bcn_ctrl_reg) & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT))); ++} ++ ++static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &haldata->dmpriv; ++ struct odm_dm_struct *podmpriv = &haldata->odmpriv; ++ ++ switch (variable) { ++ case HW_VAR_MEDIA_STATUS: ++ { ++ u8 val8; ++ ++ val8 = rtw_read8(Adapter, MSR) & 0x0c; ++ val8 |= *((u8 *)val); ++ rtw_write8(Adapter, MSR, val8); ++ } ++ break; ++ case HW_VAR_MEDIA_STATUS1: ++ { ++ u8 val8; ++ ++ val8 = rtw_read8(Adapter, MSR) & 0x03; ++ val8 |= *((u8 *)val) << 2; ++ rtw_write8(Adapter, MSR, val8); ++ } ++ break; ++ case HW_VAR_SET_OPMODE: ++ hw_var_set_opmode(Adapter, variable, val); ++ break; ++ case HW_VAR_MAC_ADDR: ++ hw_var_set_macaddr(Adapter, variable, val); ++ break; ++ case HW_VAR_BSSID: ++ hw_var_set_bssid(Adapter, variable, val); ++ break; ++ case HW_VAR_BASIC_RATE: ++ { ++ u16 BrateCfg = 0; ++ u8 RateIndex = 0; ++ ++ /* 2007.01.16, by Emily */ ++ /* Select RRSR (in Legacy-OFDM and CCK) */ ++ /* For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate. */ ++ /* We do not use other rates. */ ++ HalSetBrateCfg(Adapter, val, &BrateCfg); ++ DBG_88E("HW_VAR_BASIC_RATE: BrateCfg(%#x)\n", BrateCfg); ++ ++ /* 2011.03.30 add by Luke Lee */ ++ /* CCK 2M ACK should be disabled for some BCM and Atheros AP IOT */ ++ /* because CCK 2M has poor TXEVM */ ++ /* CCK 5.5M & 11M ACK should be enabled for better performance */ ++ ++ BrateCfg = (BrateCfg | 0xd) & 0x15d; ++ haldata->BasicRateSet = BrateCfg; ++ ++ BrateCfg |= 0x01; /* default enable 1M ACK rate */ ++ /* Set RRSR rate table. */ ++ rtw_write8(Adapter, REG_RRSR, BrateCfg & 0xff); ++ rtw_write8(Adapter, REG_RRSR + 1, (BrateCfg >> 8) & 0xff); ++ rtw_write8(Adapter, REG_RRSR + 2, rtw_read8(Adapter, REG_RRSR + 2) & 0xf0); ++ ++ /* Set RTS initial rate */ ++ while (BrateCfg > 0x1) { ++ BrateCfg = (BrateCfg >> 1); ++ RateIndex++; ++ } ++ /* Ziv - Check */ ++ rtw_write8(Adapter, REG_INIRTS_RATE_SEL, RateIndex); ++ } ++ break; ++ case HW_VAR_TXPAUSE: ++ rtw_write8(Adapter, REG_TXPAUSE, *((u8 *)val)); ++ break; ++ case HW_VAR_BCN_FUNC: ++ hw_var_set_bcn_func(Adapter, variable, val); ++ break; ++ case HW_VAR_CORRECT_TSF: ++ { ++ u64 tsf; ++ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ tsf = pmlmeext->TSFValue - do_div(pmlmeext->TSFValue, ++ pmlmeinfo->bcn_interval * 1024) - 1024; /* us */ ++ ++ if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) ++ StopTxBeacon(Adapter); ++ ++ /* disable related TSF function */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(3))); ++ ++ rtw_write32(Adapter, REG_TSFTR, tsf); ++ rtw_write32(Adapter, REG_TSFTR + 4, tsf >> 32); ++ ++ /* enable related TSF function */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(3)); ++ ++ if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) ++ ResumeTxBeacon(Adapter); ++ } ++ break; ++ case HW_VAR_CHECK_BSSID: ++ if (*((u8 *)val)) { ++ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN); ++ } else { ++ u32 val32; ++ ++ val32 = rtw_read32(Adapter, REG_RCR); ++ ++ val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); ++ ++ rtw_write32(Adapter, REG_RCR, val32); ++ } ++ break; ++ case HW_VAR_MLME_DISCONNECT: ++ /* Set RCR to not to receive data frame when NO LINK state */ ++ /* reject all data frames */ ++ rtw_write16(Adapter, REG_RXFLTMAP2, 0x00); ++ ++ /* reset TSF */ ++ rtw_write8(Adapter, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); ++ ++ /* disable update TSF */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4)); ++ break; ++ case HW_VAR_MLME_SITESURVEY: ++ if (*((u8 *)val)) { /* under sitesurvey */ ++ /* config RCR to receive different BSSID & not to receive data frame */ ++ u32 v = rtw_read32(Adapter, REG_RCR); ++ v &= ~(RCR_CBSSID_BCN); ++ rtw_write32(Adapter, REG_RCR, v); ++ /* reject all data frame */ ++ rtw_write16(Adapter, REG_RXFLTMAP2, 0x00); ++ ++ /* disable update TSF */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4)); ++ } else { /* sitesurvey done */ ++ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if ((is_client_associated_to_ap(Adapter)) || ++ ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) { ++ /* enable to rx data frame */ ++ rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF); ++ ++ /* enable update TSF */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4))); ++ } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { ++ rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF); ++ /* enable update TSF */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4))); ++ } ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { ++ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN); ++ } else { ++ if (Adapter->in_cta_test) { ++ u32 v = rtw_read32(Adapter, REG_RCR); ++ v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */ ++ rtw_write32(Adapter, REG_RCR, v); ++ } else { ++ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN); ++ } ++ } ++ } ++ break; ++ case HW_VAR_MLME_JOIN: ++ { ++ u8 RetryLimit = 0x30; ++ u8 type = *((u8 *)val); ++ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; ++ ++ if (type == 0) { /* prepare to join */ ++ /* enable to rx data frame.Accept all data frame */ ++ rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF); ++ ++ if (Adapter->in_cta_test) { ++ u32 v = rtw_read32(Adapter, REG_RCR); ++ v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */ ++ rtw_write32(Adapter, REG_RCR, v); ++ } else { ++ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN); ++ } ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) ++ RetryLimit = (haldata->CustomerID == RT_CID_CCX) ? 7 : 48; ++ else /* Ad-hoc Mode */ ++ RetryLimit = 0x7; ++ } else if (type == 1) { ++ /* joinbss_event call back when join res < 0 */ ++ rtw_write16(Adapter, REG_RXFLTMAP2, 0x00); ++ } else if (type == 2) { ++ /* sta add event call back */ ++ /* enable update TSF */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4))); ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) ++ RetryLimit = 0x7; ++ } ++ rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT); ++ } ++ break; ++ case HW_VAR_BEACON_INTERVAL: ++ rtw_write16(Adapter, REG_BCN_INTERVAL, *((u16 *)val)); ++ break; ++ case HW_VAR_SLOT_TIME: ++ { ++ u8 u1bAIFS, aSifsTime; ++ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ rtw_write8(Adapter, REG_SLOT, val[0]); ++ ++ if (pmlmeinfo->WMM_enable == 0) { ++ if (pmlmeext->cur_wireless_mode == WIRELESS_11B) ++ aSifsTime = 10; ++ else ++ aSifsTime = 16; ++ ++ u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime); ++ ++ /* Temporary removed, 2008.06.20. */ ++ rtw_write8(Adapter, REG_EDCA_VO_PARAM, u1bAIFS); ++ rtw_write8(Adapter, REG_EDCA_VI_PARAM, u1bAIFS); ++ rtw_write8(Adapter, REG_EDCA_BE_PARAM, u1bAIFS); ++ rtw_write8(Adapter, REG_EDCA_BK_PARAM, u1bAIFS); ++ } ++ } ++ break; ++ case HW_VAR_RESP_SIFS: ++ /* RESP_SIFS for CCK */ ++ rtw_write8(Adapter, REG_R2T_SIFS, val[0]); /* SIFS_T2T_CCK (0x08) */ ++ rtw_write8(Adapter, REG_R2T_SIFS + 1, val[1]); /* SIFS_R2T_CCK(0x08) */ ++ /* RESP_SIFS for OFDM */ ++ rtw_write8(Adapter, REG_T2T_SIFS, val[2]); /* SIFS_T2T_OFDM (0x0a) */ ++ rtw_write8(Adapter, REG_T2T_SIFS + 1, val[3]); /* SIFS_R2T_OFDM(0x0a) */ ++ break; ++ case HW_VAR_ACK_PREAMBLE: ++ { ++ u8 regTmp; ++ u8 bShortPreamble = *((bool *)val); ++ /* Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */ ++ regTmp = (haldata->nCur40MhzPrimeSC) << 5; ++ if (bShortPreamble) ++ regTmp |= 0x80; ++ ++ rtw_write8(Adapter, REG_RRSR + 2, regTmp); ++ } ++ break; ++ case HW_VAR_SEC_CFG: ++ rtw_write8(Adapter, REG_SECCFG, *((u8 *)val)); ++ break; ++ case HW_VAR_DM_FLAG: ++ podmpriv->SupportAbility = *((u8 *)val); ++ break; ++ case HW_VAR_DM_FUNC_OP: ++ if (val[0]) ++ podmpriv->BK_SupportAbility = podmpriv->SupportAbility; ++ else ++ podmpriv->SupportAbility = podmpriv->BK_SupportAbility; ++ break; ++ case HW_VAR_DM_FUNC_SET: ++ if (*((u32 *)val) == DYNAMIC_ALL_FUNC_ENABLE) { ++ pdmpriv->DMFlag = pdmpriv->InitDMFlag; ++ podmpriv->SupportAbility = pdmpriv->InitODMFlag; ++ } else { ++ podmpriv->SupportAbility |= *((u32 *)val); ++ } ++ break; ++ case HW_VAR_DM_FUNC_CLR: ++ podmpriv->SupportAbility &= *((u32 *)val); ++ break; ++ case HW_VAR_CAM_EMPTY_ENTRY: ++ { ++ u8 ucIndex = *((u8 *)val); ++ u8 i; ++ u32 ulCommand = 0; ++ u32 ulContent = 0; ++ u32 ulEncAlgo = CAM_AES; ++ ++ for (i = 0; i < CAM_CONTENT_COUNT; i++) { ++ /* filled id in CAM config 2 byte */ ++ if (i == 0) ++ ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2); ++ else ++ ulContent = 0; ++ /* polling bit, and No Write enable, and address */ ++ ulCommand = CAM_CONTENT_COUNT * ucIndex + i; ++ ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE; ++ /* write content 0 is equall to mark invalid */ ++ rtw_write32(Adapter, WCAMI, ulContent); /* delay_ms(40); */ ++ rtw_write32(Adapter, RWCAM, ulCommand); /* delay_ms(40); */ ++ } ++ } ++ break; ++ case HW_VAR_CAM_INVALID_ALL: ++ rtw_write32(Adapter, RWCAM, BIT(31) | BIT(30)); ++ break; ++ case HW_VAR_CAM_WRITE: ++ { ++ u32 cmd; ++ u32 *cam_val = (u32 *)val; ++ rtw_write32(Adapter, WCAMI, cam_val[0]); ++ ++ cmd = CAM_POLLINIG | CAM_WRITE | cam_val[1]; ++ rtw_write32(Adapter, RWCAM, cmd); ++ } ++ break; ++ case HW_VAR_AC_PARAM_VO: ++ rtw_write32(Adapter, REG_EDCA_VO_PARAM, ((u32 *)(val))[0]); ++ break; ++ case HW_VAR_AC_PARAM_VI: ++ rtw_write32(Adapter, REG_EDCA_VI_PARAM, ((u32 *)(val))[0]); ++ break; ++ case HW_VAR_AC_PARAM_BE: ++ haldata->AcParam_BE = ((u32 *)(val))[0]; ++ rtw_write32(Adapter, REG_EDCA_BE_PARAM, ((u32 *)(val))[0]); ++ break; ++ case HW_VAR_AC_PARAM_BK: ++ rtw_write32(Adapter, REG_EDCA_BK_PARAM, ((u32 *)(val))[0]); ++ break; ++ case HW_VAR_ACM_CTRL: ++ { ++ u8 acm_ctrl = *((u8 *)val); ++ u8 AcmCtrl = rtw_read8(Adapter, REG_ACMHWCTRL); ++ ++ if (acm_ctrl > 1) ++ AcmCtrl = AcmCtrl | 0x1; ++ ++ if (acm_ctrl & BIT(3)) ++ AcmCtrl |= AcmHw_VoqEn; ++ else ++ AcmCtrl &= (~AcmHw_VoqEn); ++ ++ if (acm_ctrl & BIT(2)) ++ AcmCtrl |= AcmHw_ViqEn; ++ else ++ AcmCtrl &= (~AcmHw_ViqEn); ++ ++ if (acm_ctrl & BIT(1)) ++ AcmCtrl |= AcmHw_BeqEn; ++ else ++ AcmCtrl &= (~AcmHw_BeqEn); ++ ++ DBG_88E("[HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl); ++ rtw_write8(Adapter, REG_ACMHWCTRL, AcmCtrl); ++ } ++ break; ++ case HW_VAR_AMPDU_MIN_SPACE: ++ { ++ u8 MinSpacingToSet; ++ u8 SecMinSpace; ++ ++ MinSpacingToSet = *((u8 *)val); ++ if (MinSpacingToSet <= 7) { ++ switch (Adapter->securitypriv.dot11PrivacyAlgrthm) { ++ case _NO_PRIVACY_: ++ case _AES_: ++ SecMinSpace = 0; ++ break; ++ case _WEP40_: ++ case _WEP104_: ++ case _TKIP_: ++ case _TKIP_WTMIC_: ++ SecMinSpace = 6; ++ break; ++ default: ++ SecMinSpace = 7; ++ break; ++ } ++ if (MinSpacingToSet < SecMinSpace) ++ MinSpacingToSet = SecMinSpace; ++ rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (rtw_read8(Adapter, REG_AMPDU_MIN_SPACE) & 0xf8) | MinSpacingToSet); ++ } ++ } ++ break; ++ case HW_VAR_AMPDU_FACTOR: ++ { ++ u8 RegToSet_Normal[4] = {0x41, 0xa8, 0x72, 0xb9}; ++ u8 FactorToSet; ++ u8 *pRegToSet; ++ u8 index = 0; ++ ++ pRegToSet = RegToSet_Normal; /* 0xb972a841; */ ++ FactorToSet = *((u8 *)val); ++ if (FactorToSet <= 3) { ++ FactorToSet = (1 << (FactorToSet + 2)); ++ if (FactorToSet > 0xf) ++ FactorToSet = 0xf; ++ ++ for (index = 0; index < 4; index++) { ++ if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4)) ++ pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet << 4); ++ ++ if ((pRegToSet[index] & 0x0f) > FactorToSet) ++ pRegToSet[index] = (pRegToSet[index] & 0xf0) | (FactorToSet); ++ ++ rtw_write8(Adapter, (REG_AGGLEN_LMT + index), pRegToSet[index]); ++ } ++ } ++ } ++ break; ++ case HW_VAR_RXDMA_AGG_PG_TH: ++ { ++ u8 threshold = *((u8 *)val); ++ if (threshold == 0) ++ threshold = haldata->UsbRxAggPageCount; ++ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, threshold); ++ } ++ break; ++ case HW_VAR_SET_RPWM: ++ break; ++ case HW_VAR_H2C_FW_PWRMODE: ++ { ++ u8 psmode = (*(u8 *)val); ++ ++ /* Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power */ ++ /* saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang. */ ++ if ((psmode != PS_MODE_ACTIVE) && (!IS_92C_SERIAL(haldata->VersionID))) ++ ODM_RF_Saving(podmpriv, true); ++ rtl8188e_set_FwPwrMode_cmd(Adapter, psmode); ++ } ++ break; ++ case HW_VAR_H2C_FW_JOINBSSRPT: ++ { ++ u8 mstatus = (*(u8 *)val); ++ rtl8188e_set_FwJoinBssReport_cmd(Adapter, mstatus); ++ } ++ break; ++#ifdef CONFIG_88EU_P2P ++ case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: ++ { ++ u8 p2p_ps_state = (*(u8 *)val); ++ rtl8188e_set_p2p_ps_offload_cmd(Adapter, p2p_ps_state); ++ } ++ break; ++#endif ++ case HW_VAR_INITIAL_GAIN: ++ { ++ struct rtw_dig *pDigTable = &podmpriv->DM_DigTable; ++ u32 rx_gain = ((u32 *)(val))[0]; ++ ++ if (rx_gain == 0xff) {/* restore rx gain */ ++ ODM_Write_DIG(podmpriv, pDigTable->BackupIGValue); ++ } else { ++ pDigTable->BackupIGValue = pDigTable->CurIGValue; ++ ODM_Write_DIG(podmpriv, rx_gain); ++ } ++ } ++ break; ++ case HW_VAR_TRIGGER_GPIO_0: ++ rtl8192cu_trigger_gpio_0(Adapter); ++ break; ++ case HW_VAR_RPT_TIMER_SETTING: ++ { ++ u16 min_rpt_time = (*(u16 *)val); ++ ODM_RA_Set_TxRPT_Time(podmpriv, min_rpt_time); ++ } ++ break; ++ case HW_VAR_ANTENNA_DIVERSITY_SELECT: ++ { ++ u8 Optimum_antenna = (*(u8 *)val); ++ u8 Ant; ++ /* switch antenna to Optimum_antenna */ ++ if (haldata->CurAntenna != Optimum_antenna) { ++ Ant = (Optimum_antenna == 2) ? MAIN_ANT : AUX_ANT; ++ ODM_UpdateRxIdleAnt_88E(&haldata->odmpriv, Ant); ++ ++ haldata->CurAntenna = Optimum_antenna; ++ } ++ } ++ break; ++ case HW_VAR_EFUSE_BYTES: /* To set EFUE total used bytes, added by Roger, 2008.12.22. */ ++ haldata->EfuseUsedBytes = *((u16 *)val); ++ break; ++ case HW_VAR_FIFO_CLEARN_UP: ++ { ++ struct pwrctrl_priv *pwrpriv = &Adapter->pwrctrlpriv; ++ u8 trycnt = 100; ++ ++ /* pause tx */ ++ rtw_write8(Adapter, REG_TXPAUSE, 0xff); ++ ++ /* keep sn */ ++ Adapter->xmitpriv.nqos_ssn = rtw_read16(Adapter, REG_NQOS_SEQ); ++ ++ if (!pwrpriv->bkeepfwalive) { ++ /* RX DMA stop */ ++ rtw_write32(Adapter, REG_RXPKT_NUM, (rtw_read32(Adapter, REG_RXPKT_NUM) | RW_RELEASE_EN)); ++ do { ++ if (!(rtw_read32(Adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) ++ break; ++ } while (trycnt--); ++ if (trycnt == 0) ++ DBG_88E("Stop RX DMA failed......\n"); ++ ++ /* RQPN Load 0 */ ++ rtw_write16(Adapter, REG_RQPN_NPQ, 0x0); ++ rtw_write32(Adapter, REG_RQPN, 0x80000000); ++ mdelay(10); ++ } ++ } ++ break; ++ case HW_VAR_CHECK_TXBUF: ++ break; ++ case HW_VAR_APFM_ON_MAC: ++ haldata->bMacPwrCtrlOn = *val; ++ DBG_88E("%s: bMacPwrCtrlOn=%d\n", __func__, haldata->bMacPwrCtrlOn); ++ break; ++ case HW_VAR_TX_RPT_MAX_MACID: ++ { ++ u8 maxMacid = *val; ++ DBG_88E("### MacID(%d),Set Max Tx RPT MID(%d)\n", maxMacid, maxMacid + 1); ++ rtw_write8(Adapter, REG_TX_RPT_CTRL + 1, maxMacid + 1); ++ } ++ break; ++ case HW_VAR_H2C_MEDIA_STATUS_RPT: ++ rtl8188e_set_FwMediaStatus_cmd(Adapter, (*(__le16 *)val)); ++ break; ++ case HW_VAR_BCN_VALID: ++ /* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */ ++ rtw_write8(Adapter, REG_TDECTRL + 2, rtw_read8(Adapter, REG_TDECTRL + 2) | BIT(0)); ++ break; ++ default: ++ break; ++ } ++ ++} ++ ++static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ struct odm_dm_struct *podmpriv = &haldata->odmpriv; ++ ++ switch (variable) { ++ case HW_VAR_BASIC_RATE: ++ *((u16 *)(val)) = haldata->BasicRateSet; ++ fallthrough; ++ case HW_VAR_TXPAUSE: ++ val[0] = rtw_read8(Adapter, REG_TXPAUSE); ++ break; ++ case HW_VAR_BCN_VALID: ++ /* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2 */ ++ val[0] = (BIT(0) & rtw_read8(Adapter, REG_TDECTRL + 2)) ? true : false; ++ break; ++ case HW_VAR_DM_FLAG: ++ val[0] = podmpriv->SupportAbility; ++ break; ++ case HW_VAR_RF_TYPE: ++ val[0] = haldata->rf_type; ++ break; ++ case HW_VAR_FWLPS_RF_ON: ++ { ++ /* When we halt NIC, we should check if FW LPS is leave. */ ++ if (Adapter->pwrctrlpriv.rf_pwrstate == rf_off) { ++ /* If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave, */ ++ /* because Fw is unload. */ ++ val[0] = true; ++ } else { ++ u32 valRCR; ++ valRCR = rtw_read32(Adapter, REG_RCR); ++ valRCR &= 0x00070000; ++ if (valRCR) ++ val[0] = false; ++ else ++ val[0] = true; ++ } ++ } ++ break; ++ case HW_VAR_CURRENT_ANTENNA: ++ val[0] = haldata->CurAntenna; ++ break; ++ case HW_VAR_EFUSE_BYTES: /* To get EFUE total used bytes, added by Roger, 2008.12.22. */ ++ *((u16 *)(val)) = haldata->EfuseUsedBytes; ++ break; ++ case HW_VAR_APFM_ON_MAC: ++ *val = haldata->bMacPwrCtrlOn; ++ break; ++ case HW_VAR_CHK_HI_QUEUE_EMPTY: ++ *val = ((rtw_read32(Adapter, REG_HGQ_INFORMATION) & 0x0000ff00) == 0) ? true : false; ++ break; ++ default: ++ break; ++ } ++ ++} ++ ++/* */ ++/* Description: */ ++/* Query setting of specified variable. */ ++/* */ ++static u8 ++GetHalDefVar8188EUsb( ++ struct adapter *Adapter, ++ enum hal_def_variable eVariable, ++ void *pValue ++ ) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ u8 bResult = _SUCCESS; ++ ++ switch (eVariable) { ++ case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: ++ { ++ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; ++ struct sta_priv *pstapriv = &Adapter->stapriv; ++ struct sta_info *psta; ++ psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress); ++ if (psta) ++ *((int *)pValue) = psta->rssi_stat.UndecoratedSmoothedPWDB; ++ } ++ break; ++ case HAL_DEF_IS_SUPPORT_ANT_DIV: ++ *((u8 *)pValue) = (haldata->AntDivCfg == 0) ? false : true; ++ break; ++ case HAL_DEF_CURRENT_ANTENNA: ++ *((u8 *)pValue) = haldata->CurAntenna; ++ break; ++ case HAL_DEF_DRVINFO_SZ: ++ *((u32 *)pValue) = DRVINFO_SZ; ++ break; ++ case HAL_DEF_MAX_RECVBUF_SZ: ++ *((u32 *)pValue) = MAX_RECVBUF_SZ; ++ break; ++ case HAL_DEF_RX_PACKET_OFFSET: ++ *((u32 *)pValue) = RXDESC_SIZE + DRVINFO_SZ; ++ break; ++ case HAL_DEF_DBG_DM_FUNC: ++ *((u32 *)pValue) = haldata->odmpriv.SupportAbility; ++ break; ++ case HAL_DEF_RA_DECISION_RATE: ++ { ++ u8 MacID = *((u8 *)pValue); ++ *((u8 *)pValue) = ODM_RA_GetDecisionRate_8188E(&haldata->odmpriv, MacID); ++ } ++ break; ++ case HAL_DEF_RA_SGI: ++ { ++ u8 MacID = *((u8 *)pValue); ++ *((u8 *)pValue) = ODM_RA_GetShortGI_8188E(&haldata->odmpriv, MacID); ++ } ++ break; ++ case HAL_DEF_PT_PWR_STATUS: ++ { ++ u8 MacID = *((u8 *)pValue); ++ *((u8 *)pValue) = ODM_RA_GetHwPwrStatus_8188E(&haldata->odmpriv, MacID); ++ } ++ break; ++ case HW_VAR_MAX_RX_AMPDU_FACTOR: ++ *((u32 *)pValue) = MAX_AMPDU_FACTOR_64K; ++ break; ++ case HW_DEF_RA_INFO_DUMP: ++ { ++ u8 entry_id = *((u8 *)pValue); ++ if (check_fwstate(&Adapter->mlmepriv, _FW_LINKED)) { ++ DBG_88E("============ RA status check ===================\n"); ++ DBG_88E("Mac_id:%d , RateID = %d, RAUseRate = 0x%08x, RateSGI = %d, DecisionRate = 0x%02x ,PTStage = %d\n", ++ entry_id, ++ haldata->odmpriv.RAInfo[entry_id].RateID, ++ haldata->odmpriv.RAInfo[entry_id].RAUseRate, ++ haldata->odmpriv.RAInfo[entry_id].RateSGI, ++ haldata->odmpriv.RAInfo[entry_id].DecisionRate, ++ haldata->odmpriv.RAInfo[entry_id].PTStage); ++ } ++ } ++ break; ++ case HAL_DEF_DBG_DUMP_RXPKT: ++ *((u8 *)pValue) = haldata->bDumpRxPkt; ++ break; ++ case HAL_DEF_DBG_DUMP_TXPKT: ++ *((u8 *)pValue) = haldata->bDumpTxPkt; ++ break; ++ default: ++ bResult = _FAIL; ++ break; ++ } ++ ++ return bResult; ++} ++ ++/* */ ++/* Description: */ ++/* Change default setting of specified variable. */ ++/* */ ++static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eVariable, void *pValue) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ u8 bResult = _SUCCESS; ++ ++ switch (eVariable) { ++ case HAL_DEF_DBG_DM_FUNC: ++ { ++ u8 dm_func = *((u8 *)pValue); ++ struct odm_dm_struct *podmpriv = &haldata->odmpriv; ++ ++ if (dm_func == 0) { /* disable all dynamic func */ ++ podmpriv->SupportAbility = DYNAMIC_FUNC_DISABLE; ++ DBG_88E("==> Disable all dynamic function...\n"); ++ } else if (dm_func == 1) {/* disable DIG */ ++ podmpriv->SupportAbility &= (~DYNAMIC_BB_DIG); ++ DBG_88E("==> Disable DIG...\n"); ++ } else if (dm_func == 2) {/* disable High power */ ++ podmpriv->SupportAbility &= (~DYNAMIC_BB_DYNAMIC_TXPWR); ++ } else if (dm_func == 3) {/* disable tx power tracking */ ++ podmpriv->SupportAbility &= (~DYNAMIC_RF_CALIBRATION); ++ DBG_88E("==> Disable tx power tracking...\n"); ++ } else if (dm_func == 5) {/* disable antenna diversity */ ++ podmpriv->SupportAbility &= (~DYNAMIC_BB_ANT_DIV); ++ } else if (dm_func == 6) {/* turn on all dynamic func */ ++ if (!(podmpriv->SupportAbility & DYNAMIC_BB_DIG)) { ++ struct rtw_dig *pDigTable = &podmpriv->DM_DigTable; ++ pDigTable->CurIGValue = rtw_read8(Adapter, 0xc50); ++ } ++ podmpriv->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE; ++ DBG_88E("==> Turn on all dynamic function...\n"); ++ } ++ } ++ break; ++ case HAL_DEF_DBG_DUMP_RXPKT: ++ haldata->bDumpRxPkt = *((u8 *)pValue); ++ break; ++ case HAL_DEF_DBG_DUMP_TXPKT: ++ haldata->bDumpTxPkt = *((u8 *)pValue); ++ break; ++ default: ++ bResult = _FAIL; ++ break; ++ } ++ ++ return bResult; ++} ++ ++static void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_level) ++{ ++ u8 init_rate = 0; ++ u8 networkType, raid; ++ u32 mask, rate_bitmap; ++ u8 shortGIrate = false; ++ int supportRateNum = 0; ++ struct sta_info *psta; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ ++ if (mac_id >= NUM_STA) /* CAM_SIZE */ ++ return; ++ psta = pmlmeinfo->FW_sta_info[mac_id].psta; ++ if (!psta) ++ return; ++ switch (mac_id) { ++ case 0:/* for infra mode */ ++ supportRateNum = rtw_get_rateset_len(cur_network->SupportedRates); ++ networkType = judge_network_type(adapt, cur_network->SupportedRates, supportRateNum) & 0xf; ++ raid = networktype_to_raid(networkType); ++ mask = update_supported_rate(cur_network->SupportedRates, supportRateNum); ++ mask |= (pmlmeinfo->HT_enable) ? update_MSC_rate(&pmlmeinfo->HT_caps) : 0; ++ if (support_short_GI(adapt, &pmlmeinfo->HT_caps)) ++ shortGIrate = true; ++ break; ++ case 1:/* for broadcast/multicast */ ++ supportRateNum = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[mac_id].SupportedRates); ++ if (pmlmeext->cur_wireless_mode & WIRELESS_11B) ++ networkType = WIRELESS_11B; ++ else ++ networkType = WIRELESS_11G; ++ raid = networktype_to_raid(networkType); ++ mask = update_basic_rate(cur_network->SupportedRates, supportRateNum); ++ break; ++ default: /* for each sta in IBSS */ ++ supportRateNum = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[mac_id].SupportedRates); ++ networkType = judge_network_type(adapt, pmlmeinfo->FW_sta_info[mac_id].SupportedRates, supportRateNum) & 0xf; ++ raid = networktype_to_raid(networkType); ++ mask = update_supported_rate(cur_network->SupportedRates, supportRateNum); ++ ++ /* todo: support HT in IBSS */ ++ break; ++ } ++ ++ rate_bitmap = 0x0fffffff; ++ rate_bitmap = ODM_Get_Rate_Bitmap(&haldata->odmpriv, mac_id, mask, rssi_level); ++ DBG_88E("%s => mac_id:%d, networkType:0x%02x, mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n", ++ __func__, mac_id, networkType, mask, rssi_level, rate_bitmap); ++ ++ mask &= rate_bitmap; ++ ++ init_rate = get_highest_rate_idx(mask) & 0x3f; ++ ++ if (haldata->fw_ractrl) { ++ u8 arg; ++ ++ arg = mac_id & 0x1f;/* MACID */ ++ arg |= BIT(7); ++ if (shortGIrate) ++ arg |= BIT(5); ++ mask |= ((raid << 28) & 0xf0000000); ++ DBG_88E("update raid entry, mask=0x%x, arg=0x%x\n", mask, arg); ++ psta->ra_mask = mask; ++ mask |= ((raid << 28) & 0xf0000000); ++ ++ /* to do ,for 8188E-SMIC */ ++ rtl8188e_set_raid_cmd(adapt, mask); ++ } else { ++ ODM_RA_UpdateRateInfo_8188E(&haldata->odmpriv, ++ mac_id, ++ raid, ++ mask, ++ shortGIrate ++ ); ++ } ++ /* set ra_id */ ++ psta->raid = raid; ++ psta->init_rate = init_rate; ++} ++ ++static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt) ++{ ++ u32 value32; ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u32 bcn_ctrl_reg = REG_BCN_CTRL; ++ /* reset TSF, enable update TSF, correcting TSF On Beacon */ ++ ++ /* BCN interval */ ++ rtw_write16(adapt, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval); ++ rtw_write8(adapt, REG_ATIMWND, 0x02);/* 2ms */ ++ ++ _InitBeaconParameters(adapt); ++ ++ rtw_write8(adapt, REG_SLOT, 0x09); ++ ++ value32 = rtw_read32(adapt, REG_TCR); ++ value32 &= ~TSFRST; ++ rtw_write32(adapt, REG_TCR, value32); ++ ++ value32 |= TSFRST; ++ rtw_write32(adapt, REG_TCR, value32); ++ ++ /* NOTE: Fix test chip's bug (about contention windows's randomness) */ ++ rtw_write8(adapt, REG_RXTSF_OFFSET_CCK, 0x50); ++ rtw_write8(adapt, REG_RXTSF_OFFSET_OFDM, 0x50); ++ ++ _BeaconFunctionEnable(adapt, true, true); ++ ++ ResumeTxBeacon(adapt); ++ ++ rtw_write8(adapt, bcn_ctrl_reg, rtw_read8(adapt, bcn_ctrl_reg) | BIT(1)); ++} ++ ++static void rtl8188eu_init_default_value(struct adapter *adapt) ++{ ++ struct hal_data_8188e *haldata; ++ struct pwrctrl_priv *pwrctrlpriv; ++ u8 i; ++ ++ haldata = GET_HAL_DATA(adapt); ++ pwrctrlpriv = &adapt->pwrctrlpriv; ++ ++ /* init default value */ ++ haldata->fw_ractrl = false; ++ if (!pwrctrlpriv->bkeepfwalive) ++ haldata->LastHMEBoxNum = 0; ++ ++ /* init dm default value */ ++ haldata->odmpriv.RFCalibrateInfo.bIQKInitialized = false; ++ haldata->odmpriv.RFCalibrateInfo.TM_Trigger = 0;/* for IQK */ ++ haldata->pwrGroupCnt = 0; ++ haldata->PGMaxGroup = 13; ++ haldata->odmpriv.RFCalibrateInfo.ThermalValue_HP_index = 0; ++ for (i = 0; i < HP_THERMAL_NUM; i++) ++ haldata->odmpriv.RFCalibrateInfo.ThermalValue_HP[i] = 0; ++} ++ ++static u8 rtl8188eu_ps_func(struct adapter *Adapter, enum hal_intf_ps_func efunc_id, u8 *val) ++{ ++ u8 bResult = true; ++ return bResult; ++} ++ ++void rtl8188eu_set_hal_ops(struct adapter *adapt) ++{ ++ struct hal_ops *halfunc = &adapt->HalFunc; ++ ++ adapt->HalData = kzalloc(sizeof(struct hal_data_8188e), GFP_KERNEL); ++ if (!adapt->HalData) ++ DBG_88E("cant not alloc memory for HAL DATA\n"); ++ adapt->hal_data_sz = sizeof(struct hal_data_8188e); ++ ++ halfunc->hal_power_on = rtl8188eu_InitPowerOn; ++ halfunc->hal_init = &rtl8188eu_hal_init; ++ halfunc->hal_deinit = &rtl8188eu_hal_deinit; ++ ++ halfunc->inirp_init = &rtl8188eu_inirp_init; ++ halfunc->inirp_deinit = &rtl8188eu_inirp_deinit; ++ ++ halfunc->init_xmit_priv = &rtl8188eu_init_xmit_priv; ++ ++ halfunc->init_recv_priv = &rtl8188eu_init_recv_priv; ++ halfunc->free_recv_priv = &rtl8188eu_free_recv_priv; ++ halfunc->InitSwLeds = &rtl8188eu_InitSwLeds; ++ halfunc->DeInitSwLeds = &rtl8188eu_DeInitSwLeds; ++ ++ halfunc->init_default_value = &rtl8188eu_init_default_value; ++ halfunc->intf_chip_configure = &rtl8188eu_interface_configure; ++ halfunc->read_adapter_info = &ReadAdapterInfo8188EU; ++ ++ halfunc->SetHwRegHandler = &SetHwReg8188EU; ++ halfunc->GetHwRegHandler = &GetHwReg8188EU; ++ halfunc->GetHalDefVarHandler = &GetHalDefVar8188EUsb; ++ halfunc->SetHalDefVarHandler = &SetHalDefVar8188EUsb; ++ ++ halfunc->UpdateRAMaskHandler = &UpdateHalRAMask8188EUsb; ++ halfunc->SetBeaconRelatedRegistersHandler = &SetBeaconRelatedRegisters8188EUsb; ++ ++ halfunc->hal_xmit = &rtl8188eu_hal_xmit; ++ halfunc->mgnt_xmit = &rtl8188eu_mgnt_xmit; ++ ++ halfunc->interface_ps_func = &rtl8188eu_ps_func; ++ ++ rtl8188e_set_hal_ops(halfunc); ++ ++} +diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c +new file mode 100644 +index 000000000000..0cf69033c529 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c +@@ -0,0 +1,562 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/osdep_intf.h" ++#include "../include/usb_ops.h" ++#include "../include/recv_osdep.h" ++#include "../include/rtl8188e_hal.h" ++ ++static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void *pdata, u16 len, u8 requesttype) ++{ ++ struct adapter *adapt = pintfhdl->padapter; ++ struct dvobj_priv *dvobjpriv = adapter_to_dvobj(adapt); ++ struct usb_device *udev = dvobjpriv->pusbdev; ++ unsigned int pipe; ++ int status = 0; ++ u8 *pIo_buf; ++ int vendorreq_times = 0; ++ ++ if ((adapt->bSurpriseRemoved) || (adapt->pwrctrlpriv.pnp_bstop_trx)) { ++ status = -EPERM; ++ goto exit; ++ } ++ ++ if (len > MAX_VENDOR_REQ_CMD_SIZE) { ++ DBG_88E("[%s] Buffer len error ,vendor request failed\n", __func__); ++ status = -EINVAL; ++ goto exit; ++ } ++ ++ _enter_critical_mutex(&dvobjpriv->usb_vendor_req_mutex, NULL); ++ ++ /* Acquire IO memory for vendorreq */ ++ pIo_buf = dvobjpriv->usb_vendor_req_buf; ++ ++ if (!pIo_buf) { ++ DBG_88E("[%s] pIo_buf == NULL\n", __func__); ++ status = -ENOMEM; ++ goto release_mutex; ++ } ++ ++ if (requesttype == REALTEK_USB_VENQT_READ) ++ pipe = usb_rcvctrlpipe(udev, 0);/* read_in */ ++ else ++ pipe = usb_sndctrlpipe(udev, 0);/* write_out */ ++ ++ while (++vendorreq_times <= MAX_USBCTRL_VENDORREQ_TIMES) { ++ if (requesttype == REALTEK_USB_VENQT_READ) ++ memset(pIo_buf, 0, len); ++ else ++ memcpy(pIo_buf, pdata, len); ++ ++ status = usb_control_msg(udev, pipe, REALTEK_USB_VENQT_CMD_REQ, ++ requesttype, value, REALTEK_USB_VENQT_CMD_IDX, ++ pIo_buf, len, RTW_USB_CONTROL_MSG_TIMEOUT); ++ ++ if (status == len) { /* Success this control transfer. */ ++ rtw_reset_continual_urb_error(dvobjpriv); ++ if (requesttype == REALTEK_USB_VENQT_READ) ++ memcpy(pdata, pIo_buf, len); ++ } else { /* error cases */ ++ DBG_88E("reg 0x%x, usb %s %u fail, status:%d value=0x%x, vendorreq_times:%d\n", ++ value, (requesttype == REALTEK_USB_VENQT_READ) ? "read" : "write", ++ len, status, *(u32 *)pdata, vendorreq_times); ++ ++ if (status < 0) { ++ if (status == (-ESHUTDOWN) || status == -ENODEV) { ++ adapt->bSurpriseRemoved = true; ++ } else { ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ haldata->srestpriv.wifi_error_status = USB_VEN_REQ_CMD_FAIL; ++ } ++ } else { /* status != len && status >= 0 */ ++ if (status > 0) { ++ if (requesttype == REALTEK_USB_VENQT_READ) { ++ /* For Control read transfer, we have to copy the read data from pIo_buf to pdata. */ ++ memcpy(pdata, pIo_buf, len); ++ } ++ } ++ } ++ ++ if (rtw_inc_and_chk_continual_urb_error(dvobjpriv)) { ++ adapt->bSurpriseRemoved = true; ++ break; ++ } ++ ++ } ++ ++ /* firmware download is checksumed, don't retry */ ++ if ((value >= FW_8188E_START_ADDRESS && value <= FW_8188E_END_ADDRESS) || status == len) ++ break; ++ } ++release_mutex: ++ _exit_critical_mutex(&dvobjpriv->usb_vendor_req_mutex, NULL); ++exit: ++ return status; ++} ++ ++static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr) ++{ ++ u16 wvalue = (u16)(addr & 0x0000ffff); ++ u8 data; ++ ++ usbctrl_vendorreq(pintfhdl, wvalue, &data, 1, REALTEK_USB_VENQT_READ); ++ ++ return data; ++} ++ ++static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr) ++{ ++ u16 wvalue = (u16)(addr & 0x0000ffff); ++ __le32 data; ++ ++ usbctrl_vendorreq(pintfhdl, wvalue, &data, 2, REALTEK_USB_VENQT_READ); ++ ++ return (u16)(le32_to_cpu(data) & 0xffff); ++} ++ ++static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr) ++{ ++ u16 wvalue = (u16)(addr & 0x0000ffff); ++ __le32 data; ++ ++ usbctrl_vendorreq(pintfhdl, wvalue, &data, 4, REALTEK_USB_VENQT_READ); ++ ++ return le32_to_cpu(data); ++} ++ ++static int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val) ++{ ++ u16 wvalue = (u16)(addr & 0x0000ffff); ++ ++ return usbctrl_vendorreq(pintfhdl, wvalue, &val, 1, REALTEK_USB_VENQT_WRITE); ++} ++ ++static int usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val) ++{ ++ u16 wvalue = (u16)(addr & 0x0000ffff); ++ __le32 data = cpu_to_le32(val & 0x0000ffff); ++ ++ return usbctrl_vendorreq(pintfhdl, wvalue, &data, 2, REALTEK_USB_VENQT_WRITE); ++} ++ ++static int usb_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val) ++{ ++ u16 wvalue = (u16)(addr & 0x0000ffff); ++ __le32 data = cpu_to_le32(val); ++ ++ return usbctrl_vendorreq(pintfhdl, wvalue, &data, 4, REALTEK_USB_VENQT_WRITE); ++} ++ ++static int usb_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata) ++{ ++ u16 wvalue = (u16)(addr & 0x0000ffff); ++ u8 buf[VENDOR_CMD_MAX_DATA_LEN] = {0}; ++ ++ if (length > VENDOR_CMD_MAX_DATA_LEN) ++ return -EINVAL; ++ ++ memcpy(buf, pdata, length); ++ ++ return usbctrl_vendorreq(pintfhdl, wvalue, buf, (length & 0xffff), REALTEK_USB_VENQT_WRITE); ++} ++ ++static void interrupt_handler_8188eu(struct adapter *adapt, u16 pkt_len, u8 *pbuf) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ ++ if (pkt_len != INTERRUPT_MSG_FORMAT_LEN) { ++ DBG_88E("%s Invalid interrupt content length (%d)!\n", __func__, pkt_len); ++ return; ++ } ++ ++ /* HISR */ ++ memcpy(&haldata->IntArray[0], &pbuf[USB_INTR_CONTENT_HISR_OFFSET], 4); ++ memcpy(&haldata->IntArray[1], &pbuf[USB_INTR_CONTENT_HISRE_OFFSET], 4); ++ ++ /* C2H Event */ ++ if (pbuf[0] != 0) ++ memcpy(&haldata->C2hArray[0], &pbuf[USB_INTR_CONTENT_C2H_OFFSET], 16); ++} ++ ++static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb) ++{ ++ u8 *pbuf; ++ u8 shift_sz = 0; ++ u16 pkt_cnt; ++ u32 pkt_offset, skb_len, alloc_sz; ++ s32 transfer_len; ++ struct recv_stat *prxstat; ++ struct phy_stat *pphy_status = NULL; ++ struct sk_buff *pkt_copy = NULL; ++ struct recv_frame *precvframe = NULL; ++ struct rx_pkt_attrib *pattrib = NULL; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ struct recv_priv *precvpriv = &adapt->recvpriv; ++ struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue; ++ ++ transfer_len = (s32)pskb->len; ++ pbuf = pskb->data; ++ ++ prxstat = (struct recv_stat *)pbuf; ++ pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff; ++ ++ do { ++ prxstat = (struct recv_stat *)pbuf; ++ ++ precvframe = rtw_alloc_recvframe(pfree_recv_queue); ++ if (!precvframe) { ++ DBG_88E("%s()-%d: rtw_alloc_recvframe() failed! RX Drop!\n", __func__, __LINE__); ++ goto _exit_recvbuf2recvframe; ++ } ++ ++ INIT_LIST_HEAD(&precvframe->list); ++ precvframe->precvbuf = NULL; /* can't access the precvbuf for new arch. */ ++ precvframe->len = 0; ++ ++ update_recvframe_attrib_88e(precvframe, prxstat); ++ ++ pattrib = &precvframe->attrib; ++ ++ if ((pattrib->crc_err) || (pattrib->icv_err)) { ++ DBG_88E("%s: RX Warning! crc_err=%d icv_err=%d, skip!\n", __func__, pattrib->crc_err, pattrib->icv_err); ++ ++ rtw_free_recvframe(precvframe, pfree_recv_queue); ++ goto _exit_recvbuf2recvframe; ++ } ++ ++ if ((pattrib->physt) && (pattrib->pkt_rpt_type == NORMAL_RX)) ++ pphy_status = (struct phy_stat *)(pbuf + RXDESC_OFFSET); ++ ++ pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len; ++ ++ if ((pattrib->pkt_len <= 0) || (pkt_offset > transfer_len)) { ++ DBG_88E("%s()-%d: RX Warning!,pkt_len<=0 or pkt_offset> transfoer_len\n", __func__, __LINE__); ++ rtw_free_recvframe(precvframe, pfree_recv_queue); ++ goto _exit_recvbuf2recvframe; ++ } ++ ++ /* Modified by Albert 20101213 */ ++ /* For 8 bytes IP header alignment. */ ++ if (pattrib->qos) /* Qos data, wireless lan header length is 26 */ ++ shift_sz = 6; ++ else ++ shift_sz = 0; ++ ++ skb_len = pattrib->pkt_len; ++ ++ /* for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. */ ++ /* modify alloc_sz for recvive crc error packet by thomas 2011-06-02 */ ++ if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) { ++ if (skb_len <= 1650) ++ alloc_sz = 1664; ++ else ++ alloc_sz = skb_len + 14; ++ } else { ++ alloc_sz = skb_len; ++ /* 6 is for IP header 8 bytes alignment in QoS packet case. */ ++ /* 8 is for skb->data 4 bytes alignment. */ ++ alloc_sz += 14; ++ } ++ ++ pkt_copy = netdev_alloc_skb(adapt->pnetdev, alloc_sz); ++ if (pkt_copy) { ++ pkt_copy->dev = adapt->pnetdev; ++ precvframe->pkt = pkt_copy; ++ precvframe->rx_head = pkt_copy->data; ++ precvframe->rx_end = pkt_copy->data + alloc_sz; ++ skb_reserve(pkt_copy, 8 - ((size_t)(pkt_copy->data) & 7));/* force pkt_copy->data at 8-byte alignment address */ ++ skb_reserve(pkt_copy, shift_sz);/* force ip_hdr at 8-byte alignment address according to shift_sz. */ ++ memcpy(pkt_copy->data, (pbuf + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len); ++ precvframe->rx_tail = pkt_copy->data; ++ precvframe->rx_data = pkt_copy->data; ++ } else { ++ if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) { ++ DBG_88E("recvbuf2recvframe: alloc_skb fail , drop frag frame\n"); ++ rtw_free_recvframe(precvframe, pfree_recv_queue); ++ goto _exit_recvbuf2recvframe; ++ } ++ precvframe->pkt = skb_clone(pskb, GFP_ATOMIC); ++ if (precvframe->pkt) { ++ precvframe->rx_tail = pbuf + pattrib->drvinfo_sz + RXDESC_SIZE; ++ precvframe->rx_head = precvframe->rx_tail; ++ precvframe->rx_data = precvframe->rx_tail; ++ precvframe->rx_end = pbuf + pattrib->drvinfo_sz + RXDESC_SIZE + alloc_sz; ++ } else { ++ DBG_88E("recvbuf2recvframe: skb_clone fail\n"); ++ rtw_free_recvframe(precvframe, pfree_recv_queue); ++ goto _exit_recvbuf2recvframe; ++ } ++ } ++ ++ recvframe_put(precvframe, skb_len); ++ ++ switch (haldata->UsbRxAggMode) { ++ case USB_RX_AGG_DMA: ++ case USB_RX_AGG_MIX: ++ pkt_offset = (u16)_RND128(pkt_offset); ++ break; ++ case USB_RX_AGG_USB: ++ pkt_offset = (u16)_RND4(pkt_offset); ++ break; ++ case USB_RX_AGG_DISABLE: ++ default: ++ break; ++ } ++ if (pattrib->pkt_rpt_type == NORMAL_RX) { /* Normal rx packet */ ++ if (pattrib->physt) ++ update_recvframe_phyinfo_88e(precvframe, (struct phy_stat *)pphy_status); ++ rtw_recv_entry(precvframe); ++ } else { ++ /* enqueue recvframe to txrtp queue */ ++ if (pattrib->pkt_rpt_type == TX_REPORT1) { ++ /* CCX-TXRPT ack for xmit mgmt frames. */ ++ handle_txrpt_ccx_88e(adapt, precvframe->rx_data); ++ } else if (pattrib->pkt_rpt_type == TX_REPORT2) { ++ ODM_RA_TxRPT2Handle_8188E( ++ &haldata->odmpriv, ++ precvframe->rx_data, ++ pattrib->pkt_len, ++ pattrib->MacIDValidEntry[0], ++ pattrib->MacIDValidEntry[1] ++ ); ++ } else if (pattrib->pkt_rpt_type == HIS_REPORT) { ++ interrupt_handler_8188eu(adapt, pattrib->pkt_len, precvframe->rx_data); ++ } ++ rtw_free_recvframe(precvframe, pfree_recv_queue); ++ } ++ pkt_cnt--; ++ transfer_len -= pkt_offset; ++ pbuf += pkt_offset; ++ precvframe = NULL; ++ pkt_copy = NULL; ++ ++ if (transfer_len > 0 && pkt_cnt == 0) ++ pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff; ++ ++ } while ((transfer_len > 0) && (pkt_cnt > 0)); ++ ++_exit_recvbuf2recvframe: ++ ++ return _SUCCESS; ++} ++ ++void rtl8188eu_recv_tasklet(unsigned long priv) ++{ ++ struct sk_buff *pskb; ++ struct adapter *adapt = (struct adapter *)priv; ++ struct recv_priv *precvpriv = &adapt->recvpriv; ++ ++ while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) { ++ if ((adapt->bDriverStopped) || (adapt->bSurpriseRemoved)) { ++ DBG_88E("recv_tasklet => bDriverStopped or bSurpriseRemoved\n"); ++ dev_kfree_skb_any(pskb); ++ break; ++ } ++ recvbuf2recvframe(adapt, pskb); ++ skb_reset_tail_pointer(pskb); ++ pskb->len = 0; ++ skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); ++ } ++} ++ ++static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs) ++{ ++ struct recv_buf *precvbuf = (struct recv_buf *)purb->context; ++ struct adapter *adapt = (struct adapter *)precvbuf->adapter; ++ struct recv_priv *precvpriv = &adapt->recvpriv; ++ ++ precvpriv->rx_pending_cnt--; ++ ++ if (adapt->bSurpriseRemoved || adapt->bDriverStopped || adapt->bReadPortCancel) { ++ precvbuf->reuse = true; ++ DBG_88E("%s() RX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bReadPortCancel(%d)\n", ++ __func__, adapt->bDriverStopped, ++ adapt->bSurpriseRemoved, adapt->bReadPortCancel); ++ return; ++ } ++ ++ if (purb->status == 0) { /* SUCCESS */ ++ if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)) { ++ precvbuf->reuse = true; ++ rtw_read_port(adapt, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); ++ DBG_88E("%s()-%d: RX Warning!\n", __func__, __LINE__); ++ } else { ++ rtw_reset_continual_urb_error(adapter_to_dvobj(adapt)); ++ ++ precvbuf->transfer_len = purb->actual_length; ++ skb_put(precvbuf->pskb, purb->actual_length); ++ skb_queue_tail(&precvpriv->rx_skb_queue, precvbuf->pskb); ++ ++ if (skb_queue_len(&precvpriv->rx_skb_queue) <= 1) ++ tasklet_schedule(&precvpriv->recv_tasklet); ++ ++ precvbuf->pskb = NULL; ++ precvbuf->reuse = false; ++ rtw_read_port(adapt, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); ++ } ++ } else { ++ DBG_88E("###=> usb_read_port_complete => urb status(%d)\n", purb->status); ++ skb_put(precvbuf->pskb, purb->actual_length); ++ precvbuf->pskb = NULL; ++ ++ if (rtw_inc_and_chk_continual_urb_error(adapter_to_dvobj(adapt))) ++ adapt->bSurpriseRemoved = true; ++ ++ switch (purb->status) { ++ case -EINVAL: ++ case -EPIPE: ++ case -ENODEV: ++ case -ESHUTDOWN: ++ case -ENOENT: ++ adapt->bDriverStopped = true; ++ break; ++ case -EPROTO: ++ case -EOVERFLOW: ++ { ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ haldata->srestpriv.wifi_error_status = USB_READ_PORT_FAIL; ++ } ++ precvbuf->reuse = true; ++ rtw_read_port(adapt, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); ++ break; ++ case -EINPROGRESS: ++ DBG_88E("ERROR: URB IS IN PROGRESS!/n"); ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++static u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) ++{ ++ struct urb *purb = NULL; ++ struct recv_buf *precvbuf = (struct recv_buf *)rmem; ++ struct adapter *adapter = pintfhdl->padapter; ++ struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter); ++ struct recv_priv *precvpriv = &adapter->recvpriv; ++ struct usb_device *pusbd = pdvobj->pusbdev; ++ int err; ++ unsigned int pipe; ++ size_t tmpaddr = 0; ++ size_t alignment = 0; ++ u32 ret = _SUCCESS; ++ ++ if (adapter->bDriverStopped || adapter->bSurpriseRemoved || ++ adapter->pwrctrlpriv.pnp_bstop_trx) ++ return _FAIL; ++ ++ if (!precvbuf) ++ return _FAIL; ++ ++ if (!precvbuf->reuse || !precvbuf->pskb) { ++ precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue); ++ if (precvbuf->pskb) ++ precvbuf->reuse = true; ++ } ++ ++ rtl8188eu_init_recvbuf(adapter, precvbuf); ++ ++ /* re-assign for linux based on skb */ ++ if (!precvbuf->reuse || !precvbuf->pskb) { ++ precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); ++ if (!precvbuf->pskb) { ++ DBG_88E("#### usb_read_port() alloc_skb fail!#####\n"); ++ return _FAIL; ++ } ++ ++ tmpaddr = (size_t)precvbuf->pskb->data; ++ alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); ++ skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment)); ++ ++ precvbuf->phead = precvbuf->pskb->head; ++ precvbuf->pdata = precvbuf->pskb->data; ++ precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); ++ precvbuf->pend = skb_end_pointer(precvbuf->pskb); ++ precvbuf->pbuf = precvbuf->pskb->data; ++ } else { /* reuse skb */ ++ precvbuf->phead = precvbuf->pskb->head; ++ precvbuf->pdata = precvbuf->pskb->data; ++ precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); ++ precvbuf->pend = skb_end_pointer(precvbuf->pskb); ++ precvbuf->pbuf = precvbuf->pskb->data; ++ ++ precvbuf->reuse = false; ++ } ++ ++ precvpriv->rx_pending_cnt++; ++ ++ purb = precvbuf->purb; ++ ++ /* translate DMA FIFO addr to pipehandle */ ++ pipe = ffaddr2pipehdl(pdvobj, addr); ++ ++ usb_fill_bulk_urb(purb, pusbd, pipe, ++ precvbuf->pbuf, ++ MAX_RECVBUF_SZ, ++ usb_read_port_complete, ++ precvbuf);/* context is precvbuf */ ++ ++ err = usb_submit_urb(purb, GFP_ATOMIC); ++ if ((err) && (err != (-EPERM))) { ++ DBG_88E("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n", ++ err, purb->status); ++ ret = _FAIL; ++ } ++ ++ return ret; ++} ++ ++void rtl8188eu_xmit_tasklet(unsigned long priv) ++{ ++ int ret = false; ++ struct adapter *adapt = (struct adapter *)priv; ++ struct xmit_priv *pxmitpriv = &adapt->xmitpriv; ++ ++ if (check_fwstate(&adapt->mlmepriv, _FW_UNDER_SURVEY)) ++ return; ++ ++ while (1) { ++ if ((adapt->bDriverStopped) || ++ (adapt->bSurpriseRemoved) || ++ (adapt->bWritePortCancel)) { ++ DBG_88E("xmit_tasklet => bDriverStopped or bSurpriseRemoved or bWritePortCancel\n"); ++ break; ++ } ++ ++ ret = rtl8188eu_xmitframe_complete(adapt, pxmitpriv, NULL); ++ ++ if (!ret) ++ break; ++ } ++} ++ ++void rtl8188eu_set_intf_ops(struct _io_ops *pops) ++{ ++ ++ memset((u8 *)pops, 0, sizeof(struct _io_ops)); ++ pops->_read8 = &usb_read8; ++ pops->_read16 = &usb_read16; ++ pops->_read32 = &usb_read32; ++ pops->_read_mem = &usb_read_mem; ++ pops->_read_port = &usb_read_port; ++ pops->_write8 = &usb_write8; ++ pops->_write16 = &usb_write16; ++ pops->_write32 = &usb_write32; ++ pops->_writeN = &usb_writeN; ++ pops->_write_mem = &usb_write_mem; ++ pops->_write_port = &usb_write_port; ++ pops->_read_port_cancel = &usb_read_port_cancel; ++ pops->_write_port_cancel = &usb_write_port_cancel; ++ ++} ++ ++void rtl8188eu_set_hw_type(struct adapter *adapt) ++{ ++ adapt->chip_type = RTL8188E; ++ adapt->HardwareType = HARDWARE_TYPE_RTL8188EU; ++ DBG_88E("CHIP TYPE: RTL8188E\n"); ++} +diff --git a/drivers/staging/r8188eu/include/Hal8188EPhyCfg.h b/drivers/staging/r8188eu/include/Hal8188EPhyCfg.h +new file mode 100644 +index 000000000000..4370ec2fa981 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/Hal8188EPhyCfg.h +@@ -0,0 +1,249 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __INC_HAL8188EPHYCFG_H__ ++#define __INC_HAL8188EPHYCFG_H__ ++ ++/*--------------------------Define Parameters-------------------------------*/ ++#define LOOP_LIMIT 5 ++#define MAX_STALL_TIME 50 /* us */ ++#define AntennaDiversityValue 0x80 ++#define MAX_TXPWR_IDX_NMODE_92S 63 ++#define Reset_Cnt_Limit 3 ++ ++#define IQK_MAC_REG_NUM 4 ++#define IQK_ADDA_REG_NUM 16 ++#define IQK_BB_REG_NUM 9 ++#define HP_THERMAL_NUM 8 ++ ++#define MAX_AGGR_NUM 0x07 ++ ++/*--------------------------Define Parameters-------------------------------*/ ++ ++/*------------------------------Define structure----------------------------*/ ++enum sw_chnl_cmd_id { ++ CmdID_End, ++ CmdID_SetTxPowerLevel, ++ CmdID_BBRegWrite10, ++ CmdID_WritePortUlong, ++ CmdID_WritePortUshort, ++ CmdID_WritePortUchar, ++ CmdID_RF_WriteReg, ++}; ++ ++/* 1. Switch channel related */ ++struct sw_chnl_cmd { ++ enum sw_chnl_cmd_id CmdID; ++ u32 Para1; ++ u32 Para2; ++ u32 msDelay; ++}; ++ ++enum hw90_block { ++ HW90_BLOCK_MAC = 0, ++ HW90_BLOCK_PHY0 = 1, ++ HW90_BLOCK_PHY1 = 2, ++ HW90_BLOCK_RF = 3, ++ HW90_BLOCK_MAXIMUM = 4, /* Never use this */ ++}; ++ ++enum rf_radio_path { ++ RF_PATH_A = 0, /* Radio Path A */ ++ RF_PATH_B = 1, /* Radio Path B */ ++ RF_PATH_C = 2, /* Radio Path C */ ++ RF_PATH_D = 3, /* Radio Path D */ ++}; ++ ++#define MAX_PG_GROUP 13 ++ ++#define RF_PATH_MAX 3 ++#define MAX_TX_COUNT 4 /* path numbers */ ++ ++#define CHANNEL_MAX_NUMBER 14 /* 14 is the max chnl number */ ++#define MAX_CHNL_GROUP_24G 6 /* ch1~2, ch3~5, ch6~8, ++ *ch9~11, ch12~13, CH 14 ++ * total three groups */ ++#define CHANNEL_GROUP_MAX_88E 6 ++ ++enum wireless_mode { ++ WIRELESS_MODE_UNKNOWN = 0x00, ++ WIRELESS_MODE_B = BIT(0), ++ WIRELESS_MODE_G = BIT(1), ++ WIRELESS_MODE_AUTO = BIT(5), ++ WIRELESS_MODE_N_24G = BIT(3), ++}; ++ ++enum phy_rate_tx_offset_area { ++ RA_OFFSET_LEGACY_OFDM1, ++ RA_OFFSET_LEGACY_OFDM2, ++ RA_OFFSET_HT_OFDM1, ++ RA_OFFSET_HT_OFDM2, ++ RA_OFFSET_HT_OFDM3, ++ RA_OFFSET_HT_OFDM4, ++ RA_OFFSET_HT_CCK, ++}; ++ ++/* BB/RF related */ ++enum RF_TYPE_8190P { ++ RF_TYPE_MIN, /* 0 */ ++ RF_8225 = 1, /* 1 11b/g RF for verification only */ ++ RF_8256 = 2, /* 2 11b/g/n */ ++ RF_6052 = 4, /* 4 11b/g/n RF */ ++ /* TODO: We should remove this psudo PHY RF after we get new RF. */ ++ RF_PSEUDO_11N = 5, /* 5, It is a temporality RF. */ ++}; ++ ++struct bb_reg_def { ++ u32 rfintfs; /* set software control: */ ++ /* 0x870~0x877[8 bytes] */ ++ u32 rfintfi; /* readback data: */ ++ /* 0x8e0~0x8e7[8 bytes] */ ++ u32 rfintfo; /* output data: */ ++ /* 0x860~0x86f [16 bytes] */ ++ u32 rfintfe; /* output enable: */ ++ /* 0x860~0x86f [16 bytes] */ ++ u32 rf3wireOffset; /* LSSI data: */ ++ /* 0x840~0x84f [16 bytes] */ ++ u32 rfLSSI_Select; /* BB Band Select: */ ++ /* 0x878~0x87f [8 bytes] */ ++ u32 rfTxGainStage; /* Tx gain stage: */ ++ /* 0x80c~0x80f [4 bytes] */ ++ u32 rfHSSIPara1; /* wire parameter control1 : */ ++ /* 0x820~0x823,0x828~0x82b, ++ * 0x830~0x833, 0x838~0x83b [16 bytes] */ ++ u32 rfHSSIPara2; /* wire parameter control2 : */ ++ /* 0x824~0x827,0x82c~0x82f, 0x834~0x837, ++ * 0x83c~0x83f [16 bytes] */ ++ u32 rfSwitchControl; /* Tx Rx antenna control : */ ++ /* 0x858~0x85f [16 bytes] */ ++ u32 rfAGCControl1; /* AGC parameter control1 : */ ++ /* 0xc50~0xc53,0xc58~0xc5b, 0xc60~0xc63, ++ * 0xc68~0xc6b [16 bytes] */ ++ u32 rfAGCControl2; /* AGC parameter control2 : */ ++ /* 0xc54~0xc57,0xc5c~0xc5f, 0xc64~0xc67, ++ * 0xc6c~0xc6f [16 bytes] */ ++ u32 rfRxIQImbalance; /* OFDM Rx IQ imbalance matrix : */ ++ /* 0xc14~0xc17,0xc1c~0xc1f, 0xc24~0xc27, ++ * 0xc2c~0xc2f [16 bytes] */ ++ u32 rfRxAFE; /* Rx IQ DC ofset and Rx digital filter, ++ * Rx DC notch filter : */ ++ /* 0xc10~0xc13,0xc18~0xc1b, 0xc20~0xc23, ++ * 0xc28~0xc2b [16 bytes] */ ++ u32 rfTxIQImbalance; /* OFDM Tx IQ imbalance matrix */ ++ /* 0xc80~0xc83,0xc88~0xc8b, 0xc90~0xc93, ++ * 0xc98~0xc9b [16 bytes] */ ++ u32 rfTxAFE; /* Tx IQ DC Offset and Tx DFIR type */ ++ /* 0xc84~0xc87,0xc8c~0xc8f, 0xc94~0xc97, ++ * 0xc9c~0xc9f [16 bytes] */ ++ u32 rfLSSIReadBack; /* LSSI RF readback data SI mode */ ++ /* 0x8a0~0x8af [16 bytes] */ ++ u32 rfLSSIReadBackPi; /* LSSI RF readback data PI mode 0x8b8-8bc for ++ * Path A and B */ ++}; ++ ++struct ant_sel_ofdm { ++ u32 r_tx_antenna:4; ++ u32 r_ant_l:4; ++ u32 r_ant_non_ht:4; ++ u32 r_ant_ht1:4; ++ u32 r_ant_ht2:4; ++ u32 r_ant_ht_s1:4; ++ u32 r_ant_non_ht_s1:4; ++ u32 OFDM_TXSC:2; ++ u32 reserved:2; ++}; ++ ++struct ant_sel_cck { ++ u8 r_cckrx_enable_2:2; ++ u8 r_cckrx_enable:2; ++ u8 r_ccktx_enable:4; ++}; ++ ++/*------------------------------Define structure----------------------------*/ ++ ++/*------------------------Export global variable----------------------------*/ ++/*------------------------Export global variable----------------------------*/ ++ ++/*------------------------Export Marco Definition---------------------------*/ ++/*------------------------Export Marco Definition---------------------------*/ ++ ++/*--------------------------Exported Function prototype---------------------*/ ++/* */ ++/* BB and RF register read/write */ ++/* */ ++u32 rtl8188e_PHY_QueryBBReg(struct adapter *adapter, u32 regaddr, u32 mask); ++void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, ++ u32 mask, u32 data); ++u32 rtl8188e_PHY_QueryRFReg(struct adapter *adapter, enum rf_radio_path rfpath, ++ u32 regaddr, u32 mask); ++void rtl8188e_PHY_SetRFReg(struct adapter *adapter, enum rf_radio_path rfpath, ++ u32 regaddr, u32 mask, u32 data); ++ ++/* Initialization related function */ ++/* MAC/BB/RF HAL config */ ++int PHY_MACConfig8188E(struct adapter *adapter); ++int PHY_BBConfig8188E(struct adapter *adapter); ++int PHY_RFConfig8188E(struct adapter *adapter); ++ ++/* RF config */ ++int rtl8188e_PHY_ConfigRFWithParaFile(struct adapter *adapter, u8 *filename, ++ enum rf_radio_path rfpath); ++int rtl8188e_PHY_ConfigRFWithHeaderFile(struct adapter *adapter, ++ enum rf_radio_path rfpath); ++ ++/* Read initi reg value for tx power setting. */ ++void rtl8192c_PHY_GetHWRegOriginalValue(struct adapter *adapter); ++ ++/* BB TX Power R/W */ ++void PHY_GetTxPowerLevel8188E(struct adapter *adapter, u32 *powerlevel); ++void PHY_SetTxPowerLevel8188E(struct adapter *adapter, u8 channel); ++bool PHY_UpdateTxPowerDbm8188E(struct adapter *adapter, int power); ++ ++void PHY_ScanOperationBackup8188E(struct adapter *Adapter, u8 Operation); ++ ++/* Switch bandwidth for 8192S */ ++void PHY_SetBWMode8188E(struct adapter *adapter, ++ enum ht_channel_width chnlwidth, unsigned char offset); ++ ++/* channel switch related funciton */ ++void PHY_SwChnl8188E(struct adapter *adapter, u8 channel); ++/* Call after initialization */ ++void ChkFwCmdIoDone(struct adapter *adapter); ++ ++/* BB/MAC/RF other monitor API */ ++void PHY_SetRFPathSwitch_8188E(struct adapter *adapter, bool main); ++ ++void PHY_SwitchEphyParameter(struct adapter *adapter); ++ ++void PHY_EnableHostClkReq(struct adapter *adapter); ++ ++bool SetAntennaConfig92C(struct adapter *adapter, u8 defaultant); ++ ++void storePwrIndexDiffRateOffset(struct adapter *adapter, u32 regaddr, ++ u32 mask, u32 data); ++/*--------------------------Exported Function prototype---------------------*/ ++ ++#define PHY_QueryBBReg(adapt, regaddr, mask) \ ++ rtl8188e_PHY_QueryBBReg((adapt), (regaddr), (mask)) ++#define PHY_SetBBReg(adapt, regaddr, bitmask, data) \ ++ rtl8188e_PHY_SetBBReg((adapt), (regaddr), (bitmask), (data)) ++#define PHY_QueryRFReg(adapt, rfpath, regaddr, bitmask) \ ++ rtl8188e_PHY_QueryRFReg((adapt), (rfpath), (regaddr), (bitmask)) ++#define PHY_SetRFReg(adapt, rfpath, regaddr, bitmask, data) \ ++ rtl8188e_PHY_SetRFReg((adapt), (rfpath), (regaddr), (bitmask), (data)) ++ ++#define PHY_SetMacReg PHY_SetBBReg ++ ++#define SIC_HW_SUPPORT 0 ++ ++#define SIC_MAX_POLL_CNT 5 ++ ++#define SIC_CMD_READY 0 ++#define SIC_CMD_WRITE 1 ++#define SIC_CMD_READ 2 ++ ++#define SIC_CMD_REG 0x1EB /* 1byte */ ++#define SIC_ADDR_REG 0x1E8 /* 1b9~1ba, 2 bytes */ ++#define SIC_DATA_REG 0x1EC /* 1bc~1bf */ ++ ++#endif /* __INC_HAL8192CPHYCFG_H */ +diff --git a/drivers/staging/r8188eu/include/Hal8188EPhyReg.h b/drivers/staging/r8188eu/include/Hal8188EPhyReg.h +new file mode 100644 +index 000000000000..8b8c75a1f149 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/Hal8188EPhyReg.h +@@ -0,0 +1,1072 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __INC_HAL8188EPHYREG_H__ ++#define __INC_HAL8188EPHYREG_H__ ++/*--------------------------Define Parameters-------------------------------*/ ++/* */ ++/* BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF */ ++/* 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF */ ++/* 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 */ ++/* 3. RF register 0x00-2E */ ++/* 4. Bit Mask for BB/RF register */ ++/* 5. Other definition for BB/RF R/W */ ++/* */ ++ ++/* */ ++/* 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF */ ++/* 1. Page1(0x100) */ ++/* */ ++#define rPMAC_Reset 0x100 ++#define rPMAC_TxStart 0x104 ++#define rPMAC_TxLegacySIG 0x108 ++#define rPMAC_TxHTSIG1 0x10c ++#define rPMAC_TxHTSIG2 0x110 ++#define rPMAC_PHYDebug 0x114 ++#define rPMAC_TxPacketNum 0x118 ++#define rPMAC_TxIdle 0x11c ++#define rPMAC_TxMACHeader0 0x120 ++#define rPMAC_TxMACHeader1 0x124 ++#define rPMAC_TxMACHeader2 0x128 ++#define rPMAC_TxMACHeader3 0x12c ++#define rPMAC_TxMACHeader4 0x130 ++#define rPMAC_TxMACHeader5 0x134 ++#define rPMAC_TxDataType 0x138 ++#define rPMAC_TxRandomSeed 0x13c ++#define rPMAC_CCKPLCPPreamble 0x140 ++#define rPMAC_CCKPLCPHeader 0x144 ++#define rPMAC_CCKCRC16 0x148 ++#define rPMAC_OFDMRxCRC32OK 0x170 ++#define rPMAC_OFDMRxCRC32Er 0x174 ++#define rPMAC_OFDMRxParityEr 0x178 ++#define rPMAC_OFDMRxCRC8Er 0x17c ++#define rPMAC_CCKCRxRC16Er 0x180 ++#define rPMAC_CCKCRxRC32Er 0x184 ++#define rPMAC_CCKCRxRC32OK 0x188 ++#define rPMAC_TxStatus 0x18c ++ ++/* 2. Page2(0x200) */ ++/* The following two definition are only used for USB interface. */ ++#define RF_BB_CMD_ADDR 0x02c0 /* RF/BB r/w cmd address. */ ++#define RF_BB_CMD_DATA 0x02c4 /* RF/BB r/w cmd data. */ ++ ++/* 3. Page8(0x800) */ ++#define rFPGA0_RFMOD 0x800 /* RF mode & CCK TxSC RF BW Setting */ ++ ++#define rFPGA0_TxInfo 0x804 /* Status report?? */ ++#define rFPGA0_PSDFunction 0x808 ++ ++#define rFPGA0_TxGainStage 0x80c /* Set TX PWR init gain? */ ++ ++#define rFPGA0_RFTiming1 0x810 /* Useless now */ ++#define rFPGA0_RFTiming2 0x814 ++ ++#define rFPGA0_XA_HSSIParameter1 0x820 /* RF 3 wire register */ ++#define rFPGA0_XA_HSSIParameter2 0x824 ++#define rFPGA0_XB_HSSIParameter1 0x828 ++#define rFPGA0_XB_HSSIParameter2 0x82c ++ ++#define rFPGA0_XA_LSSIParameter 0x840 ++#define rFPGA0_XB_LSSIParameter 0x844 ++ ++#define rFPGA0_RFWakeUpParameter 0x850 /* Useless now */ ++#define rFPGA0_RFSleepUpParameter 0x854 ++ ++#define rFPGA0_XAB_SwitchControl 0x858 /* RF Channel switch */ ++#define rFPGA0_XCD_SwitchControl 0x85c ++ ++#define rFPGA0_XA_RFInterfaceOE 0x860 /* RF Channel switch */ ++#define rFPGA0_XB_RFInterfaceOE 0x864 ++ ++#define rFPGA0_XAB_RFInterfaceSW 0x870 /* RF Iface Software Control */ ++#define rFPGA0_XCD_RFInterfaceSW 0x874 ++ ++#define rFPGA0_XAB_RFParameter 0x878 /* RF Parameter */ ++#define rFPGA0_XCD_RFParameter 0x87c ++ ++/* Crystal cap setting RF-R/W protection for parameter4?? */ ++#define rFPGA0_AnalogParameter1 0x880 ++#define rFPGA0_AnalogParameter2 0x884 ++#define rFPGA0_AnalogParameter3 0x888 ++/* enable ad/da clock1 for dual-phy */ ++#define rFPGA0_AdDaClockEn 0x888 ++#define rFPGA0_AnalogParameter4 0x88c ++ ++#define rFPGA0_XA_LSSIReadBack 0x8a0 /* Tranceiver LSSI Readback */ ++#define rFPGA0_XB_LSSIReadBack 0x8a4 ++#define rFPGA0_XC_LSSIReadBack 0x8a8 ++#define rFPGA0_XD_LSSIReadBack 0x8ac ++ ++#define rFPGA0_PSDReport 0x8b4 /* Useless now */ ++/* Transceiver A HSPI Readback */ ++#define TransceiverA_HSPI_Readback 0x8b8 ++/* Transceiver B HSPI Readback */ ++#define TransceiverB_HSPI_Readback 0x8bc ++/* Useless now RF Interface Readback Value */ ++#define rFPGA0_XAB_RFInterfaceRB 0x8e0 ++#define rFPGA0_XCD_RFInterfaceRB 0x8e4 /* Useless now */ ++ ++/* 4. Page9(0x900) */ ++/* RF mode & OFDM TxSC RF BW Setting?? */ ++#define rFPGA1_RFMOD 0x900 ++ ++#define rFPGA1_TxBlock 0x904 /* Useless now */ ++#define rFPGA1_DebugSelect 0x908 /* Useless now */ ++#define rFPGA1_TxInfo 0x90c /* Useless now Status report */ ++ ++/* 5. PageA(0xA00) */ ++/* Set Control channel to upper or lower - required only for 40MHz */ ++#define rCCK0_System 0xa00 ++ ++/* Disable init gain now Select RX path by RSSI */ ++#define rCCK0_AFESetting 0xa04 ++/* Disable init gain now Init gain */ ++#define rCCK0_CCA 0xa08 ++ ++/* AGC default value, saturation level Antenna Diversity, RX AGC, LNA Threshold, ++ * RX LNA Threshold useless now. Not the same as 90 series */ ++#define rCCK0_RxAGC1 0xa0c ++#define rCCK0_RxAGC2 0xa10 /* AGC & DAGC */ ++ ++#define rCCK0_RxHP 0xa14 ++ ++/* Timing recovery & Channel estimation threshold */ ++#define rCCK0_DSPParameter1 0xa18 ++#define rCCK0_DSPParameter2 0xa1c /* SQ threshold */ ++ ++#define rCCK0_TxFilter1 0xa20 ++#define rCCK0_TxFilter2 0xa24 ++#define rCCK0_DebugPort 0xa28 /* debug port and Tx filter3 */ ++#define rCCK0_FalseAlarmReport 0xa2c /* 0xa2d useless now */ ++#define rCCK0_TRSSIReport 0xa50 ++#define rCCK0_RxReport 0xa54 /* 0xa57 */ ++#define rCCK0_FACounterLower 0xa5c /* 0xa5b */ ++#define rCCK0_FACounterUpper 0xa58 /* 0xa5c */ ++ ++/* */ ++/* PageB(0xB00) */ ++/* */ ++#define rPdp_AntA 0xb00 ++#define rPdp_AntA_4 0xb04 ++#define rConfig_Pmpd_AntA 0xb28 ++#define rConfig_AntA 0xb68 ++#define rConfig_AntB 0xb6c ++#define rPdp_AntB 0xb70 ++#define rPdp_AntB_4 0xb74 ++#define rConfig_Pmpd_AntB 0xb98 ++#define rAPK 0xbd8 ++ ++/* */ ++/* 6. PageC(0xC00) */ ++/* */ ++#define rOFDM0_LSTF 0xc00 ++ ++#define rOFDM0_TRxPathEnable 0xc04 ++#define rOFDM0_TRMuxPar 0xc08 ++#define rOFDM0_TRSWIsolation 0xc0c ++ ++/* RxIQ DC offset, Rx digital filter, DC notch filter */ ++#define rOFDM0_XARxAFE 0xc10 ++#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imblance matrix */ ++#define rOFDM0_XBRxAFE 0xc18 ++#define rOFDM0_XBRxIQImbalance 0xc1c ++#define rOFDM0_XCRxAFE 0xc20 ++#define rOFDM0_XCRxIQImbalance 0xc24 ++#define rOFDM0_XDRxAFE 0xc28 ++#define rOFDM0_XDRxIQImbalance 0xc2c ++ ++#define rOFDM0_RxDetector1 0xc30 /*PD,BW & SBD DM tune init gain*/ ++#define rOFDM0_RxDetector2 0xc34 /* SBD & Fame Sync. */ ++#define rOFDM0_RxDetector3 0xc38 /* Frame Sync. */ ++#define rOFDM0_RxDetector4 0xc3c /* PD, SBD, Frame Sync & Short-GI */ ++ ++#define rOFDM0_RxDSP 0xc40 /* Rx Sync Path */ ++#define rOFDM0_CFOandDAGC 0xc44 /* CFO & DAGC */ ++#define rOFDM0_CCADropThreshold 0xc48 /* CCA Drop threshold */ ++#define rOFDM0_ECCAThreshold 0xc4c /* energy CCA */ ++ ++#define rOFDM0_XAAGCCore1 0xc50 /* DIG */ ++#define rOFDM0_XAAGCCore2 0xc54 ++#define rOFDM0_XBAGCCore1 0xc58 ++#define rOFDM0_XBAGCCore2 0xc5c ++#define rOFDM0_XCAGCCore1 0xc60 ++#define rOFDM0_XCAGCCore2 0xc64 ++#define rOFDM0_XDAGCCore1 0xc68 ++#define rOFDM0_XDAGCCore2 0xc6c ++ ++#define rOFDM0_AGCParameter1 0xc70 ++#define rOFDM0_AGCParameter2 0xc74 ++#define rOFDM0_AGCRSSITable 0xc78 ++#define rOFDM0_HTSTFAGC 0xc7c ++ ++#define rOFDM0_XATxIQImbalance 0xc80 /* TX PWR TRACK and DIG */ ++#define rOFDM0_XATxAFE 0xc84 ++#define rOFDM0_XBTxIQImbalance 0xc88 ++#define rOFDM0_XBTxAFE 0xc8c ++#define rOFDM0_XCTxIQImbalance 0xc90 ++#define rOFDM0_XCTxAFE 0xc94 ++#define rOFDM0_XDTxIQImbalance 0xc98 ++#define rOFDM0_XDTxAFE 0xc9c ++ ++#define rOFDM0_RxIQExtAnta 0xca0 ++#define rOFDM0_TxCoeff1 0xca4 ++#define rOFDM0_TxCoeff2 0xca8 ++#define rOFDM0_TxCoeff3 0xcac ++#define rOFDM0_TxCoeff4 0xcb0 ++#define rOFDM0_TxCoeff5 0xcb4 ++#define rOFDM0_TxCoeff6 0xcb8 ++#define rOFDM0_RxHPParameter 0xce0 ++#define rOFDM0_TxPseudoNoiseWgt 0xce4 ++#define rOFDM0_FrameSync 0xcf0 ++#define rOFDM0_DFSReport 0xcf4 ++ ++/* */ ++/* 7. PageD(0xD00) */ ++/* */ ++#define rOFDM1_LSTF 0xd00 ++#define rOFDM1_TRxPathEnable 0xd04 ++ ++#define rOFDM1_CFO 0xd08 /* No setting now */ ++#define rOFDM1_CSI1 0xd10 ++#define rOFDM1_SBD 0xd14 ++#define rOFDM1_CSI2 0xd18 ++#define rOFDM1_CFOTracking 0xd2c ++#define rOFDM1_TRxMesaure1 0xd34 ++#define rOFDM1_IntfDet 0xd3c ++#define rOFDM1_PseudoNoiseStateAB 0xd50 ++#define rOFDM1_PseudoNoiseStateCD 0xd54 ++#define rOFDM1_RxPseudoNoiseWgt 0xd58 ++ ++#define rOFDM_PHYCounter1 0xda0 /* cca, parity fail */ ++#define rOFDM_PHYCounter2 0xda4 /* rate illegal, crc8 fail */ ++#define rOFDM_PHYCounter3 0xda8 /* MCS not support */ ++ ++#define rOFDM_ShortCFOAB 0xdac /* No setting now */ ++#define rOFDM_ShortCFOCD 0xdb0 ++#define rOFDM_LongCFOAB 0xdb4 ++#define rOFDM_LongCFOCD 0xdb8 ++#define rOFDM_TailCFOAB 0xdbc ++#define rOFDM_TailCFOCD 0xdc0 ++#define rOFDM_PWMeasure1 0xdc4 ++#define rOFDM_PWMeasure2 0xdc8 ++#define rOFDM_BWReport 0xdcc ++#define rOFDM_AGCReport 0xdd0 ++#define rOFDM_RxSNR 0xdd4 ++#define rOFDM_RxEVMCSI 0xdd8 ++#define rOFDM_SIGReport 0xddc ++ ++/* */ ++/* 8. PageE(0xE00) */ ++/* */ ++#define rTxAGC_A_Rate18_06 0xe00 ++#define rTxAGC_A_Rate54_24 0xe04 ++#define rTxAGC_A_CCK1_Mcs32 0xe08 ++#define rTxAGC_A_Mcs03_Mcs00 0xe10 ++#define rTxAGC_A_Mcs07_Mcs04 0xe14 ++#define rTxAGC_A_Mcs11_Mcs08 0xe18 ++#define rTxAGC_A_Mcs15_Mcs12 0xe1c ++ ++#define rTxAGC_B_Rate18_06 0x830 ++#define rTxAGC_B_Rate54_24 0x834 ++#define rTxAGC_B_CCK1_55_Mcs32 0x838 ++#define rTxAGC_B_Mcs03_Mcs00 0x83c ++#define rTxAGC_B_Mcs07_Mcs04 0x848 ++#define rTxAGC_B_Mcs11_Mcs08 0x84c ++#define rTxAGC_B_Mcs15_Mcs12 0x868 ++#define rTxAGC_B_CCK11_A_CCK2_11 0x86c ++ ++#define rFPGA0_IQK 0xe28 ++#define rTx_IQK_Tone_A 0xe30 ++#define rRx_IQK_Tone_A 0xe34 ++#define rTx_IQK_PI_A 0xe38 ++#define rRx_IQK_PI_A 0xe3c ++ ++#define rTx_IQK 0xe40 ++#define rRx_IQK 0xe44 ++#define rIQK_AGC_Pts 0xe48 ++#define rIQK_AGC_Rsp 0xe4c ++#define rTx_IQK_Tone_B 0xe50 ++#define rRx_IQK_Tone_B 0xe54 ++#define rTx_IQK_PI_B 0xe58 ++#define rRx_IQK_PI_B 0xe5c ++#define rIQK_AGC_Cont 0xe60 ++ ++#define rBlue_Tooth 0xe6c ++#define rRx_Wait_CCA 0xe70 ++#define rTx_CCK_RFON 0xe74 ++#define rTx_CCK_BBON 0xe78 ++#define rTx_OFDM_RFON 0xe7c ++#define rTx_OFDM_BBON 0xe80 ++#define rTx_To_Rx 0xe84 ++#define rTx_To_Tx 0xe88 ++#define rRx_CCK 0xe8c ++ ++#define rTx_Power_Before_IQK_A 0xe94 ++#define rTx_Power_After_IQK_A 0xe9c ++ ++#define rRx_Power_Before_IQK_A 0xea0 ++#define rRx_Power_Before_IQK_A_2 0xea4 ++#define rRx_Power_After_IQK_A 0xea8 ++#define rRx_Power_After_IQK_A_2 0xeac ++ ++#define rTx_Power_Before_IQK_B 0xeb4 ++#define rTx_Power_After_IQK_B 0xebc ++ ++#define rRx_Power_Before_IQK_B 0xec0 ++#define rRx_Power_Before_IQK_B_2 0xec4 ++#define rRx_Power_After_IQK_B 0xec8 ++#define rRx_Power_After_IQK_B_2 0xecc ++ ++#define rRx_OFDM 0xed0 ++#define rRx_Wait_RIFS 0xed4 ++#define rRx_TO_Rx 0xed8 ++#define rStandby 0xedc ++#define rSleep 0xee0 ++#define rPMPD_ANAEN 0xeec ++ ++/* */ ++/* 7. RF Register 0x00-0x2E (RF 8256) */ ++/* RF-0222D 0x00-3F */ ++/* */ ++/* Zebra1 */ ++#define rZebra1_HSSIEnable 0x0 /* Useless now */ ++#define rZebra1_TRxEnable1 0x1 ++#define rZebra1_TRxEnable2 0x2 ++#define rZebra1_AGC 0x4 ++#define rZebra1_ChargePump 0x5 ++#define rZebra1_Channel 0x7 /* RF channel switch */ ++ ++/* endif */ ++#define rZebra1_TxGain 0x8 /* Useless now */ ++#define rZebra1_TxLPF 0x9 ++#define rZebra1_RxLPF 0xb ++#define rZebra1_RxHPFCorner 0xc ++ ++/* Zebra4 */ ++#define rGlobalCtrl 0 /* Useless now */ ++#define rRTL8256_TxLPF 19 ++#define rRTL8256_RxLPF 11 ++ ++/* RTL8258 */ ++#define rRTL8258_TxLPF 0x11 /* Useless now */ ++#define rRTL8258_RxLPF 0x13 ++#define rRTL8258_RSSILPF 0xa ++ ++/* */ ++/* RL6052 Register definition */ ++/* */ ++#define RF_AC 0x00 /* */ ++ ++#define RF_IQADJ_G1 0x01 /* */ ++#define RF_IQADJ_G2 0x02 /* */ ++ ++#define RF_POW_TRSW 0x05 /* */ ++ ++#define RF_GAIN_RX 0x06 /* */ ++#define RF_GAIN_TX 0x07 /* */ ++ ++#define RF_TXM_IDAC 0x08 /* */ ++#define RF_IPA_G 0x09 /* */ ++#define RF_TXBIAS_G 0x0A ++#define RF_TXPA_AG 0x0B ++#define RF_IPA_A 0x0C /* */ ++#define RF_TXBIAS_A 0x0D ++#define RF_BS_PA_APSET_G9_G11 0x0E ++#define RF_BS_IQGEN 0x0F /* */ ++ ++#define RF_MODE1 0x10 /* */ ++#define RF_MODE2 0x11 /* */ ++ ++#define RF_RX_AGC_HP 0x12 /* */ ++#define RF_TX_AGC 0x13 /* */ ++#define RF_BIAS 0x14 /* */ ++#define RF_IPA 0x15 /* */ ++#define RF_TXBIAS 0x16 ++#define RF_POW_ABILITY 0x17 /* */ ++#define RF_CHNLBW 0x18 /* RF channel and BW switch */ ++#define RF_TOP 0x19 /* */ ++ ++#define RF_RX_G1 0x1A /* */ ++#define RF_RX_G2 0x1B /* */ ++ ++#define RF_RX_BB2 0x1C /* */ ++#define RF_RX_BB1 0x1D /* */ ++ ++#define RF_RCK1 0x1E /* */ ++#define RF_RCK2 0x1F /* */ ++ ++#define RF_TX_G1 0x20 /* */ ++#define RF_TX_G2 0x21 /* */ ++#define RF_TX_G3 0x22 /* */ ++ ++#define RF_TX_BB1 0x23 /* */ ++ ++#define RF_T_METER_92D 0x42 /* */ ++#define RF_T_METER_88E 0x42 /* */ ++#define RF_T_METER 0x24 /* */ ++ ++#define RF_SYN_G1 0x25 /* RF TX Power control */ ++#define RF_SYN_G2 0x26 /* RF TX Power control */ ++#define RF_SYN_G3 0x27 /* RF TX Power control */ ++#define RF_SYN_G4 0x28 /* RF TX Power control */ ++#define RF_SYN_G5 0x29 /* RF TX Power control */ ++#define RF_SYN_G6 0x2A /* RF TX Power control */ ++#define RF_SYN_G7 0x2B /* RF TX Power control */ ++#define RF_SYN_G8 0x2C /* RF TX Power control */ ++ ++#define RF_RCK_OS 0x30 /* RF TX PA control */ ++#define RF_TXPA_G1 0x31 /* RF TX PA control */ ++#define RF_TXPA_G2 0x32 /* RF TX PA control */ ++#define RF_TXPA_G3 0x33 /* RF TX PA control */ ++#define RF_TX_BIAS_A 0x35 ++#define RF_TX_BIAS_D 0x36 ++#define RF_LOBF_9 0x38 ++#define RF_RXRF_A3 0x3C /* */ ++#define RF_TRSW 0x3F ++ ++#define RF_TXRF_A2 0x41 ++#define RF_TXPA_G4 0x46 ++#define RF_TXPA_A4 0x4B ++#define RF_0x52 0x52 ++#define RF_WE_LUT 0xEF ++ ++/* */ ++/* Bit Mask */ ++/* */ ++/* 1. Page1(0x100) */ ++#define bBBResetB 0x100 /* Useless now? */ ++#define bGlobalResetB 0x200 ++#define bOFDMTxStart 0x4 ++#define bCCKTxStart 0x8 ++#define bCRC32Debug 0x100 ++#define bPMACLoopback 0x10 ++#define bTxLSIG 0xffffff ++#define bOFDMTxRate 0xf ++#define bOFDMTxReserved 0x10 ++#define bOFDMTxLength 0x1ffe0 ++#define bOFDMTxParity 0x20000 ++#define bTxHTSIG1 0xffffff ++#define bTxHTMCSRate 0x7f ++#define bTxHTBW 0x80 ++#define bTxHTLength 0xffff00 ++#define bTxHTSIG2 0xffffff ++#define bTxHTSmoothing 0x1 ++#define bTxHTSounding 0x2 ++#define bTxHTReserved 0x4 ++#define bTxHTAggreation 0x8 ++#define bTxHTSTBC 0x30 ++#define bTxHTAdvanceCoding 0x40 ++#define bTxHTShortGI 0x80 ++#define bTxHTNumberHT_LTF 0x300 ++#define bTxHTCRC8 0x3fc00 ++#define bCounterReset 0x10000 ++#define bNumOfOFDMTx 0xffff ++#define bNumOfCCKTx 0xffff0000 ++#define bTxIdleInterval 0xffff ++#define bOFDMService 0xffff0000 ++#define bTxMACHeader 0xffffffff ++#define bTxDataInit 0xff ++#define bTxHTMode 0x100 ++#define bTxDataType 0x30000 ++#define bTxRandomSeed 0xffffffff ++#define bCCKTxPreamble 0x1 ++#define bCCKTxSFD 0xffff0000 ++#define bCCKTxSIG 0xff ++#define bCCKTxService 0xff00 ++#define bCCKLengthExt 0x8000 ++#define bCCKTxLength 0xffff0000 ++#define bCCKTxCRC16 0xffff ++#define bCCKTxStatus 0x1 ++#define bOFDMTxStatus 0x2 ++ ++#define IS_BB_REG_OFFSET_92S(_Offset) \ ++ ((_Offset >= 0x800) && (_Offset <= 0xfff)) ++ ++/* 2. Page8(0x800) */ ++#define bRFMOD 0x1 /* Reg 0x800 rFPGA0_RFMOD */ ++#define bJapanMode 0x2 ++#define bCCKTxSC 0x30 ++#define bCCKEn 0x1000000 ++#define bOFDMEn 0x2000000 ++ ++#define bOFDMRxADCPhase 0x10000 /* Useless now */ ++#define bOFDMTxDACPhase 0x40000 ++#define bXATxAGC 0x3f ++ ++#define bAntennaSelect 0x0300 ++ ++#define bXBTxAGC 0xf00 /* Reg 80c rFPGA0_TxGainStage */ ++#define bXCTxAGC 0xf000 ++#define bXDTxAGC 0xf0000 ++ ++#define bPAStart 0xf0000000 /* Useless now */ ++#define bTRStart 0x00f00000 ++#define bRFStart 0x0000f000 ++#define bBBStart 0x000000f0 ++#define bBBCCKStart 0x0000000f ++#define bPAEnd 0xf /* Reg0x814 */ ++#define bTREnd 0x0f000000 ++#define bRFEnd 0x000f0000 ++#define bCCAMask 0x000000f0 /* T2R */ ++#define bR2RCCAMask 0x00000f00 ++#define bHSSI_R2TDelay 0xf8000000 ++#define bHSSI_T2RDelay 0xf80000 ++#define bContTxHSSI 0x400 /* change gain at continue Tx */ ++#define bIGFromCCK 0x200 ++#define bAGCAddress 0x3f ++#define bRxHPTx 0x7000 ++#define bRxHPT2R 0x38000 ++#define bRxHPCCKIni 0xc0000 ++#define bAGCTxCode 0xc00000 ++#define bAGCRxCode 0x300000 ++ ++/* Reg 0x820~84f rFPGA0_XA_HSSIParameter1 */ ++#define b3WireDataLength 0x800 ++#define b3WireAddressLength 0x400 ++ ++#define b3WireRFPowerDown 0x1 /* Useless now */ ++#define b5GPAPEPolarity 0x40000000 ++#define b2GPAPEPolarity 0x80000000 ++#define bRFSW_TxDefaultAnt 0x3 ++#define bRFSW_TxOptionAnt 0x30 ++#define bRFSW_RxDefaultAnt 0x300 ++#define bRFSW_RxOptionAnt 0x3000 ++#define bRFSI_3WireData 0x1 ++#define bRFSI_3WireClock 0x2 ++#define bRFSI_3WireLoad 0x4 ++#define bRFSI_3WireRW 0x8 ++#define bRFSI_3Wire 0xf ++ ++#define bRFSI_RFENV 0x10 /* Reg 0x870 rFPGA0_XAB_RFInterfaceSW */ ++ ++#define bRFSI_TRSW 0x20 /* Useless now */ ++#define bRFSI_TRSWB 0x40 ++#define bRFSI_ANTSW 0x100 ++#define bRFSI_ANTSWB 0x200 ++#define bRFSI_PAPE 0x400 ++#define bRFSI_PAPE5G 0x800 ++#define bBandSelect 0x1 ++#define bHTSIG2_GI 0x80 ++#define bHTSIG2_Smoothing 0x01 ++#define bHTSIG2_Sounding 0x02 ++#define bHTSIG2_Aggreaton 0x08 ++#define bHTSIG2_STBC 0x30 ++#define bHTSIG2_AdvCoding 0x40 ++#define bHTSIG2_NumOfHTLTF 0x300 ++#define bHTSIG2_CRC8 0x3fc ++#define bHTSIG1_MCS 0x7f ++#define bHTSIG1_BandWidth 0x80 ++#define bHTSIG1_HTLength 0xffff ++#define bLSIG_Rate 0xf ++#define bLSIG_Reserved 0x10 ++#define bLSIG_Length 0x1fffe ++#define bLSIG_Parity 0x20 ++#define bCCKRxPhase 0x4 ++ ++#define bLSSIReadAddress 0x7f800000 /* T65 RF */ ++ ++#define bLSSIReadEdge 0x80000000 /* LSSI "Read" edge signal */ ++ ++#define bLSSIReadBackData 0xfffff /* T65 RF */ ++ ++#define bLSSIReadOKFlag 0x1000 /* Useless now */ ++#define bCCKSampleRate 0x8 /* 0: 44MHz, 1:88MHz */ ++#define bRegulator0Standby 0x1 ++#define bRegulatorPLLStandby 0x2 ++#define bRegulator1Standby 0x4 ++#define bPLLPowerUp 0x8 ++#define bDPLLPowerUp 0x10 ++#define bDA10PowerUp 0x20 ++#define bAD7PowerUp 0x200 ++#define bDA6PowerUp 0x2000 ++#define bXtalPowerUp 0x4000 ++#define b40MDClkPowerUP 0x8000 ++#define bDA6DebugMode 0x20000 ++#define bDA6Swing 0x380000 ++ ++/* Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ */ ++#define bADClkPhase 0x4000000 ++ ++#define b80MClkDelay 0x18000000 /* Useless */ ++#define bAFEWatchDogEnable 0x20000000 ++ ++/* Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap */ ++#define bXtalCap01 0xc0000000 ++#define bXtalCap23 0x3 ++#define bXtalCap92x 0x0f000000 ++#define bXtalCap 0x0f000000 ++ ++#define bIntDifClkEnable 0x400 /* Useless */ ++#define bExtSigClkEnable 0x800 ++#define bBandgapMbiasPowerUp 0x10000 ++#define bAD11SHGain 0xc0000 ++#define bAD11InputRange 0x700000 ++#define bAD11OPCurrent 0x3800000 ++#define bIPathLoopback 0x4000000 ++#define bQPathLoopback 0x8000000 ++#define bAFELoopback 0x10000000 ++#define bDA10Swing 0x7e0 ++#define bDA10Reverse 0x800 ++#define bDAClkSource 0x1000 ++#define bAD7InputRange 0x6000 ++#define bAD7Gain 0x38000 ++#define bAD7OutputCMMode 0x40000 ++#define bAD7InputCMMode 0x380000 ++#define bAD7Current 0xc00000 ++#define bRegulatorAdjust 0x7000000 ++#define bAD11PowerUpAtTx 0x1 ++#define bDA10PSAtTx 0x10 ++#define bAD11PowerUpAtRx 0x100 ++#define bDA10PSAtRx 0x1000 ++#define bCCKRxAGCFormat 0x200 ++#define bPSDFFTSamplepPoint 0xc000 ++#define bPSDAverageNum 0x3000 ++#define bIQPathControl 0xc00 ++#define bPSDFreq 0x3ff ++#define bPSDAntennaPath 0x30 ++#define bPSDIQSwitch 0x40 ++#define bPSDRxTrigger 0x400000 ++#define bPSDTxTrigger 0x80000000 ++#define bPSDSineToneScale 0x7f000000 ++#define bPSDReport 0xffff ++ ++/* 3. Page9(0x900) */ ++#define bOFDMTxSC 0x30000000 /* Useless */ ++#define bCCKTxOn 0x1 ++#define bOFDMTxOn 0x2 ++#define bDebugPage 0xfff /* reset debug page and HWord, LWord */ ++#define bDebugItem 0xff /* reset debug page and LWord */ ++#define bAntL 0x10 ++#define bAntNonHT 0x100 ++#define bAntHT1 0x1000 ++#define bAntHT2 0x10000 ++#define bAntHT1S1 0x100000 ++#define bAntNonHTS1 0x1000000 ++ ++/* 4. PageA(0xA00) */ ++#define bCCKBBMode 0x3 /* Useless */ ++#define bCCKTxPowerSaving 0x80 ++#define bCCKRxPowerSaving 0x40 ++ ++#define bCCKSideBand 0x10 /* Reg 0xa00 rCCK0_System 20/40 */ ++ ++#define bCCKScramble 0x8 /* Useless */ ++#define bCCKAntDiversity 0x8000 ++#define bCCKCarrierRecovery 0x4000 ++#define bCCKTxRate 0x3000 ++#define bCCKDCCancel 0x0800 ++#define bCCKISICancel 0x0400 ++#define bCCKMatchFilter 0x0200 ++#define bCCKEqualizer 0x0100 ++#define bCCKPreambleDetect 0x800000 ++#define bCCKFastFalseCCA 0x400000 ++#define bCCKChEstStart 0x300000 ++#define bCCKCCACount 0x080000 ++#define bCCKcs_lim 0x070000 ++#define bCCKBistMode 0x80000000 ++#define bCCKCCAMask 0x40000000 ++#define bCCKTxDACPhase 0x4 ++#define bCCKRxADCPhase 0x20000000 /* r_rx_clk */ ++#define bCCKr_cp_mode0 0x0100 ++#define bCCKTxDCOffset 0xf0 ++#define bCCKRxDCOffset 0xf ++#define bCCKCCAMode 0xc000 ++#define bCCKFalseCS_lim 0x3f00 ++#define bCCKCS_ratio 0xc00000 ++#define bCCKCorgBit_sel 0x300000 ++#define bCCKPD_lim 0x0f0000 ++#define bCCKNewCCA 0x80000000 ++#define bCCKRxHPofIG 0x8000 ++#define bCCKRxIG 0x7f00 ++#define bCCKLNAPolarity 0x800000 ++#define bCCKRx1stGain 0x7f0000 ++#define bCCKRFExtend 0x20000000 /* CCK Rx Iinital gain polarity */ ++#define bCCKRxAGCSatLevel 0x1f000000 ++#define bCCKRxAGCSatCount 0xe0 ++#define bCCKRxRFSettle 0x1f /* AGCsamp_dly */ ++#define bCCKFixedRxAGC 0x8000 ++#define bCCKAntennaPolarity 0x2000 ++#define bCCKTxFilterType 0x0c00 ++#define bCCKRxAGCReportType 0x0300 ++#define bCCKRxDAGCEn 0x80000000 ++#define bCCKRxDAGCPeriod 0x20000000 ++#define bCCKRxDAGCSatLevel 0x1f000000 ++#define bCCKTimingRecovery 0x800000 ++#define bCCKTxC0 0x3f0000 ++#define bCCKTxC1 0x3f000000 ++#define bCCKTxC2 0x3f ++#define bCCKTxC3 0x3f00 ++#define bCCKTxC4 0x3f0000 ++#define bCCKTxC5 0x3f000000 ++#define bCCKTxC6 0x3f ++#define bCCKTxC7 0x3f00 ++#define bCCKDebugPort 0xff0000 ++#define bCCKDACDebug 0x0f000000 ++#define bCCKFalseAlarmEnable 0x8000 ++#define bCCKFalseAlarmRead 0x4000 ++#define bCCKTRSSI 0x7f ++#define bCCKRxAGCReport 0xfe ++#define bCCKRxReport_AntSel 0x80000000 ++#define bCCKRxReport_MFOff 0x40000000 ++#define bCCKRxRxReport_SQLoss 0x20000000 ++#define bCCKRxReport_Pktloss 0x10000000 ++#define bCCKRxReport_Lockedbit 0x08000000 ++#define bCCKRxReport_RateError 0x04000000 ++#define bCCKRxReport_RxRate 0x03000000 ++#define bCCKRxFACounterLower 0xff ++#define bCCKRxFACounterUpper 0xff000000 ++#define bCCKRxHPAGCStart 0xe000 ++#define bCCKRxHPAGCFinal 0x1c00 ++#define bCCKRxFalseAlarmEnable 0x8000 ++#define bCCKFACounterFreeze 0x4000 ++#define bCCKTxPathSel 0x10000000 ++#define bCCKDefaultRxPath 0xc000000 ++#define bCCKOptionRxPath 0x3000000 ++ ++/* 5. PageC(0xC00) */ ++#define bNumOfSTF 0x3 /* Useless */ ++#define bShift_L 0xc0 ++#define bGI_TH 0xc ++#define bRxPathA 0x1 ++#define bRxPathB 0x2 ++#define bRxPathC 0x4 ++#define bRxPathD 0x8 ++#define bTxPathA 0x1 ++#define bTxPathB 0x2 ++#define bTxPathC 0x4 ++#define bTxPathD 0x8 ++#define bTRSSIFreq 0x200 ++#define bADCBackoff 0x3000 ++#define bDFIRBackoff 0xc000 ++#define bTRSSILatchPhase 0x10000 ++#define bRxIDCOffset 0xff ++#define bRxQDCOffset 0xff00 ++#define bRxDFIRMode 0x1800000 ++#define bRxDCNFType 0xe000000 ++#define bRXIQImb_A 0x3ff ++#define bRXIQImb_B 0xfc00 ++#define bRXIQImb_C 0x3f0000 ++#define bRXIQImb_D 0xffc00000 ++#define bDC_dc_Notch 0x60000 ++#define bRxNBINotch 0x1f000000 ++#define bPD_TH 0xf ++#define bPD_TH_Opt2 0xc000 ++#define bPWED_TH 0x700 ++#define bIfMF_Win_L 0x800 ++#define bPD_Option 0x1000 ++#define bMF_Win_L 0xe000 ++#define bBW_Search_L 0x30000 ++#define bwin_enh_L 0xc0000 ++#define bBW_TH 0x700000 ++#define bED_TH2 0x3800000 ++#define bBW_option 0x4000000 ++#define bRatio_TH 0x18000000 ++#define bWindow_L 0xe0000000 ++#define bSBD_Option 0x1 ++#define bFrame_TH 0x1c ++#define bFS_Option 0x60 ++#define bDC_Slope_check 0x80 ++#define bFGuard_Counter_DC_L 0xe00 ++#define bFrame_Weight_Short 0x7000 ++#define bSub_Tune 0xe00000 ++#define bFrame_DC_Length 0xe000000 ++#define bSBD_start_offset 0x30000000 ++#define bFrame_TH_2 0x7 ++#define bFrame_GI2_TH 0x38 ++#define bGI2_Sync_en 0x40 ++#define bSarch_Short_Early 0x300 ++#define bSarch_Short_Late 0xc00 ++#define bSarch_GI2_Late 0x70000 ++#define bCFOAntSum 0x1 ++#define bCFOAcc 0x2 ++#define bCFOStartOffset 0xc ++#define bCFOLookBack 0x70 ++#define bCFOSumWeight 0x80 ++#define bDAGCEnable 0x10000 ++#define bTXIQImb_A 0x3ff ++#define bTXIQImb_B 0xfc00 ++#define bTXIQImb_C 0x3f0000 ++#define bTXIQImb_D 0xffc00000 ++#define bTxIDCOffset 0xff ++#define bTxQDCOffset 0xff00 ++#define bTxDFIRMode 0x10000 ++#define bTxPesudoNoiseOn 0x4000000 ++#define bTxPesudoNoise_A 0xff ++#define bTxPesudoNoise_B 0xff00 ++#define bTxPesudoNoise_C 0xff0000 ++#define bTxPesudoNoise_D 0xff000000 ++#define bCCADropOption 0x20000 ++#define bCCADropThres 0xfff00000 ++#define bEDCCA_H 0xf ++#define bEDCCA_L 0xf0 ++#define bLambda_ED 0x300 ++#define bRxInitialGain 0x7f ++#define bRxAntDivEn 0x80 ++#define bRxAGCAddressForLNA 0x7f00 ++#define bRxHighPowerFlow 0x8000 ++#define bRxAGCFreezeThres 0xc0000 ++#define bRxFreezeStep_AGC1 0x300000 ++#define bRxFreezeStep_AGC2 0xc00000 ++#define bRxFreezeStep_AGC3 0x3000000 ++#define bRxFreezeStep_AGC0 0xc000000 ++#define bRxRssi_Cmp_En 0x10000000 ++#define bRxQuickAGCEn 0x20000000 ++#define bRxAGCFreezeThresMode 0x40000000 ++#define bRxOverFlowCheckType 0x80000000 ++#define bRxAGCShift 0x7f ++#define bTRSW_Tri_Only 0x80 ++#define bPowerThres 0x300 ++#define bRxAGCEn 0x1 ++#define bRxAGCTogetherEn 0x2 ++#define bRxAGCMin 0x4 ++#define bRxHP_Ini 0x7 ++#define bRxHP_TRLNA 0x70 ++#define bRxHP_RSSI 0x700 ++#define bRxHP_BBP1 0x7000 ++#define bRxHP_BBP2 0x70000 ++#define bRxHP_BBP3 0x700000 ++#define bRSSI_H 0x7f0000 /* threshold for high power */ ++#define bRSSI_Gen 0x7f000000 /* threshold for ant diversity */ ++#define bRxSettle_TRSW 0x7 ++#define bRxSettle_LNA 0x38 ++#define bRxSettle_RSSI 0x1c0 ++#define bRxSettle_BBP 0xe00 ++#define bRxSettle_RxHP 0x7000 ++#define bRxSettle_AntSW_RSSI 0x38000 ++#define bRxSettle_AntSW 0xc0000 ++#define bRxProcessTime_DAGC 0x300000 ++#define bRxSettle_HSSI 0x400000 ++#define bRxProcessTime_BBPPW 0x800000 ++#define bRxAntennaPowerShift 0x3000000 ++#define bRSSITableSelect 0xc000000 ++#define bRxHP_Final 0x7000000 ++#define bRxHTSettle_BBP 0x7 ++#define bRxHTSettle_HSSI 0x8 ++#define bRxHTSettle_RxHP 0x70 ++#define bRxHTSettle_BBPPW 0x80 ++#define bRxHTSettle_Idle 0x300 ++#define bRxHTSettle_Reserved 0x1c00 ++#define bRxHTRxHPEn 0x8000 ++#define bRxHTAGCFreezeThres 0x30000 ++#define bRxHTAGCTogetherEn 0x40000 ++#define bRxHTAGCMin 0x80000 ++#define bRxHTAGCEn 0x100000 ++#define bRxHTDAGCEn 0x200000 ++#define bRxHTRxHP_BBP 0x1c00000 ++#define bRxHTRxHP_Final 0xe0000000 ++#define bRxPWRatioTH 0x3 ++#define bRxPWRatioEn 0x4 ++#define bRxMFHold 0x3800 ++#define bRxPD_Delay_TH1 0x38 ++#define bRxPD_Delay_TH2 0x1c0 ++#define bRxPD_DC_COUNT_MAX 0x600 ++#define bRxPD_Delay_TH 0x8000 ++#define bRxProcess_Delay 0xf0000 ++#define bRxSearchrange_GI2_Early 0x700000 ++#define bRxFrame_Guard_Counter_L 0x3800000 ++#define bRxSGI_Guard_L 0xc000000 ++#define bRxSGI_Search_L 0x30000000 ++#define bRxSGI_TH 0xc0000000 ++#define bDFSCnt0 0xff ++#define bDFSCnt1 0xff00 ++#define bDFSFlag 0xf0000 ++#define bMFWeightSum 0x300000 ++#define bMinIdxTH 0x7f000000 ++#define bDAFormat 0x40000 ++#define bTxChEmuEnable 0x01000000 ++#define bTRSWIsolation_A 0x7f ++#define bTRSWIsolation_B 0x7f00 ++#define bTRSWIsolation_C 0x7f0000 ++#define bTRSWIsolation_D 0x7f000000 ++#define bExtLNAGain 0x7c00 ++ ++/* 6. PageE(0xE00) */ ++#define bSTBCEn 0x4 /* Useless */ ++#define bAntennaMapping 0x10 ++#define bNss 0x20 ++#define bCFOAntSumD 0x200 ++#define bPHYCounterReset 0x8000000 ++#define bCFOReportGet 0x4000000 ++#define bOFDMContinueTx 0x10000000 ++#define bOFDMSingleCarrier 0x20000000 ++#define bOFDMSingleTone 0x40000000 ++#define bHTDetect 0x100 ++#define bCFOEn 0x10000 ++#define bCFOValue 0xfff00000 ++#define bSigTone_Re 0x3f ++#define bSigTone_Im 0x7f00 ++#define bCounter_CCA 0xffff ++#define bCounter_ParityFail 0xffff0000 ++#define bCounter_RateIllegal 0xffff ++#define bCounter_CRC8Fail 0xffff0000 ++#define bCounter_MCSNoSupport 0xffff ++#define bCounter_FastSync 0xffff ++#define bShortCFO 0xfff ++#define bShortCFOTLength 12 /* total */ ++#define bShortCFOFLength 11 /* fraction */ ++#define bLongCFO 0x7ff ++#define bLongCFOTLength 11 ++#define bLongCFOFLength 11 ++#define bTailCFO 0x1fff ++#define bTailCFOTLength 13 ++#define bTailCFOFLength 12 ++#define bmax_en_pwdB 0xffff ++#define bCC_power_dB 0xffff0000 ++#define bnoise_pwdB 0xffff ++#define bPowerMeasTLength 10 ++#define bPowerMeasFLength 3 ++#define bRx_HT_BW 0x1 ++#define bRxSC 0x6 ++#define bRx_HT 0x8 ++#define bNB_intf_det_on 0x1 ++#define bIntf_win_len_cfg 0x30 ++#define bNB_Intf_TH_cfg 0x1c0 ++#define bRFGain 0x3f ++#define bTableSel 0x40 ++#define bTRSW 0x80 ++#define bRxSNR_A 0xff ++#define bRxSNR_B 0xff00 ++#define bRxSNR_C 0xff0000 ++#define bRxSNR_D 0xff000000 ++#define bSNREVMTLength 8 ++#define bSNREVMFLength 1 ++#define bCSI1st 0xff ++#define bCSI2nd 0xff00 ++#define bRxEVM1st 0xff0000 ++#define bRxEVM2nd 0xff000000 ++#define bSIGEVM 0xff ++#define bPWDB 0xff00 ++#define bSGIEN 0x10000 ++ ++#define bSFactorQAM1 0xf /* Useless */ ++#define bSFactorQAM2 0xf0 ++#define bSFactorQAM3 0xf00 ++#define bSFactorQAM4 0xf000 ++#define bSFactorQAM5 0xf0000 ++#define bSFactorQAM6 0xf0000 ++#define bSFactorQAM7 0xf00000 ++#define bSFactorQAM8 0xf000000 ++#define bSFactorQAM9 0xf0000000 ++#define bCSIScheme 0x100000 ++ ++#define bNoiseLvlTopSet 0x3 /* Useless */ ++#define bChSmooth 0x4 ++#define bChSmoothCfg1 0x38 ++#define bChSmoothCfg2 0x1c0 ++#define bChSmoothCfg3 0xe00 ++#define bChSmoothCfg4 0x7000 ++#define bMRCMode 0x800000 ++#define bTHEVMCfg 0x7000000 ++ ++#define bLoopFitType 0x1 /* Useless */ ++#define bUpdCFO 0x40 ++#define bUpdCFOOffData 0x80 ++#define bAdvUpdCFO 0x100 ++#define bAdvTimeCtrl 0x800 ++#define bUpdClko 0x1000 ++#define bFC 0x6000 ++#define bTrackingMode 0x8000 ++#define bPhCmpEnable 0x10000 ++#define bUpdClkoLTF 0x20000 ++#define bComChCFO 0x40000 ++#define bCSIEstiMode 0x80000 ++#define bAdvUpdEqz 0x100000 ++#define bUChCfg 0x7000000 ++#define bUpdEqz 0x8000000 ++ ++/* Rx Pseduo noise */ ++#define bRxPesudoNoiseOn 0x20000000 /* Useless */ ++#define bRxPesudoNoise_A 0xff ++#define bRxPesudoNoise_B 0xff00 ++#define bRxPesudoNoise_C 0xff0000 ++#define bRxPesudoNoise_D 0xff000000 ++#define bPesudoNoiseState_A 0xffff ++#define bPesudoNoiseState_B 0xffff0000 ++#define bPesudoNoiseState_C 0xffff ++#define bPesudoNoiseState_D 0xffff0000 ++ ++/* 7. RF Register */ ++/* Zebra1 */ ++#define bZebra1_HSSIEnable 0x8 /* Useless */ ++#define bZebra1_TRxControl 0xc00 ++#define bZebra1_TRxGainSetting 0x07f ++#define bZebra1_RxCorner 0xc00 ++#define bZebra1_TxChargePump 0x38 ++#define bZebra1_RxChargePump 0x7 ++#define bZebra1_ChannelNum 0xf80 ++#define bZebra1_TxLPFBW 0x400 ++#define bZebra1_RxLPFBW 0x600 ++ ++/* Zebra4 */ ++#define bRTL8256RegModeCtrl1 0x100 /* Useless */ ++#define bRTL8256RegModeCtrl0 0x40 ++#define bRTL8256_TxLPFBW 0x18 ++#define bRTL8256_RxLPFBW 0x600 ++ ++/* RTL8258 */ ++#define bRTL8258_TxLPFBW 0xc /* Useless */ ++#define bRTL8258_RxLPFBW 0xc00 ++#define bRTL8258_RSSILPFBW 0xc0 ++ ++/* */ ++/* Other Definition */ ++/* */ ++ ++/* byte endable for sb_write */ ++#define bByte0 0x1 /* Useless */ ++#define bByte1 0x2 ++#define bByte2 0x4 ++#define bByte3 0x8 ++#define bWord0 0x3 ++#define bWord1 0xc ++#define bDWord 0xf ++ ++/* for PutRegsetting & GetRegSetting BitMask */ ++#define bMaskByte0 0xff /* Reg 0xc50 rOFDM0_XAAGCCore~0xC6f */ ++#define bMaskByte1 0xff00 ++#define bMaskByte2 0xff0000 ++#define bMaskByte3 0xff000000 ++#define bMaskHWord 0xffff0000 ++#define bMaskLWord 0x0000ffff ++#define bMaskDWord 0xffffffff ++#define bMask12Bits 0xfff ++#define bMaskH4Bits 0xf0000000 ++#define bMaskOFDM_D 0xffc00000 ++#define bMaskCCK 0x3f3f3f3f ++ ++/* for PutRFRegsetting & GetRFRegSetting BitMask */ ++#define bRFRegOffsetMask 0xfffff ++ ++#define bEnable 0x1 /* Useless */ ++#define bDisable 0x0 ++ ++#define LeftAntenna 0x0 /* Useless */ ++#define RightAntenna 0x1 ++ ++#define tCheckTxStatus 500 /* 500ms Useless */ ++#define tUpdateRxCounter 100 /* 100ms */ ++ ++#define rateCCK 0 /* Useless */ ++#define rateOFDM 1 ++#define rateHT 2 ++ ++/* define Register-End */ ++#define bPMAC_End 0x1ff /* Useless */ ++#define bFPGAPHY0_End 0x8ff ++#define bFPGAPHY1_End 0x9ff ++#define bCCKPHY0_End 0xaff ++#define bOFDMPHY0_End 0xcff ++#define bOFDMPHY1_End 0xdff ++ ++#define bPMACControl 0x0 /* Useless */ ++#define bWMACControl 0x1 ++#define bWNICControl 0x2 ++ ++#define PathA 0x0 /* Useless */ ++#define PathB 0x1 ++#define PathC 0x2 ++#define PathD 0x3 ++ ++/*--------------------------Define Parameters-------------------------------*/ ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/Hal8188EPwrSeq.h b/drivers/staging/r8188eu/include/Hal8188EPwrSeq.h +new file mode 100644 +index 000000000000..a73bd1a5d57b +--- /dev/null ++++ b/drivers/staging/r8188eu/include/Hal8188EPwrSeq.h +@@ -0,0 +1,155 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __HAL8188EPWRSEQ_H__ ++#define __HAL8188EPWRSEQ_H__ ++ ++#include "HalPwrSeqCmd.h" ++ ++/* ++ Check document WM-20110607-Paul-RTL8188E_Power_Architecture-R02.vsd ++ There are 6 HW Power States: ++ 0: POFF--Power Off ++ 1: PDN--Power Down ++ 2: CARDEMU--Card Emulation ++ 3: ACT--Active Mode ++ 4: LPS--Low Power State ++ 5: SUS--Suspend ++ ++ The transision from different states are defined below ++ TRANS_CARDEMU_TO_ACT ++ TRANS_ACT_TO_CARDEMU ++ TRANS_CARDEMU_TO_SUS ++ TRANS_SUS_TO_CARDEMU ++ TRANS_CARDEMU_TO_PDN ++ TRANS_ACT_TO_LPS ++ TRANS_LPS_TO_ACT ++ ++ TRANS_END ++ ++ PWR SEQ Version: rtl8188E_PwrSeq_V09.h ++*/ ++#define RTL8188E_TRANS_CARDEMU_TO_ACT_STEPS 10 ++#define RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS 10 ++#define RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS 10 ++#define RTL8188E_TRANS_SUS_TO_CARDEMU_STEPS 10 ++#define RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS 10 ++#define RTL8188E_TRANS_PDN_TO_CARDEMU_STEPS 10 ++#define RTL8188E_TRANS_ACT_TO_LPS_STEPS 15 ++#define RTL8188E_TRANS_LPS_TO_ACT_STEPS 15 ++#define RTL8188E_TRANS_END_STEPS 1 ++ ++#define RTL8188E_TRANS_CARDEMU_TO_ACT \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)},/* wait till 0x04[17] = 1 power ready*/ \ ++ {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0)|BIT(1), 0}, /* 0x02[1:0] = 0 reset BB*/ \ ++ {0x0026, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)}, /*0x24[23] = 2b'01 schmit trigger */ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, /* 0x04[15] = 0 disable HWPDN (control by DRV)*/\ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4)|BIT(3), 0}, /*0x04[12:11] = 2b'00 disable WL suspend*/ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*0x04[8] = 1 polling until return 0*/ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0}, /*wait till 0x04[8] = 0*/ \ ++ {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*LDO normal mode*/ \ ++ {0x0074, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*SDIO Driving*/ \ ++ ++#define RTL8188E_TRANS_ACT_TO_CARDEMU \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},/*0x1F[7:0] = 0 turn off RF*/ \ ++ {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*LDO Sleep mode*/ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \ ++ ++#define RTL8188E_TRANS_CARDEMU_TO_SUS \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, /*0x04[12:11] = 2b'01enable WL suspend*/ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)|BIT(4)}, /*0x04[12:11] = 2b'11enable WL suspend for PCIe*/ \ ++ {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, BIT(7)}, /* 0x04[31:30] = 2b'10 enable enable bandgap mbias in suspend */ \ ++ {0x0041, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*Clear SIC_EN register 0x40[12] = 1'b0 */ \ ++ {0xfe10, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*Set USB suspend enable local register 0xfe10[4]=1 */ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*Set SDIO suspend local register*/ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0}, /*wait power state to suspend*/ ++ ++#define RTL8188E_TRANS_SUS_TO_CARDEMU \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, /*Set SDIO suspend local register*/ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, /*wait power state to suspend*/\ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ ++ ++#define RTL8188E_TRANS_CARDEMU_TO_CARDDIS \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0x0026, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)}, /*0x24[23] = 2b'01 schmit trigger */ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ ++ {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, /* 0x04[31:30] = 2b'10 enable enable bandgap mbias in suspend */ \ ++ {0x0041, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*Clear SIC_EN register 0x40[12] = 1'b0 */ \ ++ {0xfe10, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*Set USB suspend enable local register 0xfe10[4]=1 */ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*Set SDIO suspend local register*/ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0}, /*wait power state to suspend*/ ++ ++#define RTL8188E_TRANS_CARDDIS_TO_CARDEMU \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, /*Set SDIO suspend local register*/ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, /*wait power state to suspend*/\ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ ++ ++#define RTL8188E_TRANS_CARDEMU_TO_PDN \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0},/* 0x04[16] = 0*/\ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)},/* 0x04[15] = 1*/ ++ ++#define RTL8188E_TRANS_PDN_TO_CARDEMU \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here */ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},/* 0x04[15] = 0*/ ++ ++/* This is used by driver for LPSRadioOff Procedure, not for FW LPS Step */ ++#define RTL8188E_TRANS_ACT_TO_LPS \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here */ \ ++ {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x7F},/*Tx Pause*/ \ ++ {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ ++ {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ ++ {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ ++ {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ ++ {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0},/*CCK and OFDM are disabled,and clock are gated*/ \ ++ {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ ++ {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x3F},/*Reset MAC TRX*/ \ ++ {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0},/*check if removed later*/ \ ++ {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)},/*Respond TxOK to scheduler*/ \ ++ ++#define RTL8188E_TRANS_LPS_TO_ACT \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here */ \ ++ {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/\ ++ {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\ ++ {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/\ ++ {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\ ++ {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*. 0x08[4] = 0 switch TSF to 40M*/\ ++ {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0}, /*Polling 0x109[7]=0 TSF in 40M*/\ ++ {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6)|BIT(7), 0}, /*. 0x29[7:6] = 2b'00 enable BB clock*/\ ++ {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, /*. 0x101[1] = 1*/\ ++ {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ ++ {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1)|BIT(0), BIT(1)|BIT(0)}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\ ++ {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ ++ ++#define RTL8188E_TRANS_END \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,0, PWR_CMD_END, 0, 0}, /* */ ++ ++extern struct wl_pwr_cfg rtl8188E_power_on_flow[RTL8188E_TRANS_CARDEMU_TO_ACT_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_radio_off_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_card_disable_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_card_enable_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_suspend_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_resume_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_hwpdn_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_enter_lps_flow[RTL8188E_TRANS_ACT_TO_LPS_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_leave_lps_flow[RTL8188E_TRANS_LPS_TO_ACT_STEPS+RTL8188E_TRANS_END_STEPS]; ++ ++#endif /* __HAL8188EPWRSEQ_H__ */ +diff --git a/drivers/staging/r8188eu/include/Hal8188ERateAdaptive.h b/drivers/staging/r8188eu/include/Hal8188ERateAdaptive.h +new file mode 100644 +index 000000000000..d5ced507a648 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/Hal8188ERateAdaptive.h +@@ -0,0 +1,64 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright (c) 2011 Realtek Semiconductor Corp. */ ++ ++#ifndef __INC_RA_H ++#define __INC_RA_H ++/* Module Name: RateAdaptive.h ++ * Abstract: Prototype of RA and related data structure. ++ */ ++ ++#include ++ ++/* Rate adaptive define */ ++#define PERENTRY 23 ++#define RETRYSIZE 5 ++#define RATESIZE 28 ++#define TX_RPT2_ITEM_SIZE 8 ++ ++/* TX report 2 format in Rx desc */ ++#define GET_TX_RPT2_DESC_PKT_LEN_88E(__rxstatusdesc) \ ++ le32_get_bits(*(__le32 *)__rxstatusdesc, GENMASK(8, 0)) ++#define GET_TX_RPT2_DESC_MACID_VALID_1_88E(__rxstatusdesc) \ ++ le32_to_cpu((*(__le32 *)(__rxstatusdesc + 16)) ++#define GET_TX_RPT2_DESC_MACID_VALID_2_88E(__rxstatusdesc) \ ++ le32_to_cpu((*(__le32 *)(__rxstatusdesc + 20)) ++ ++#define GET_TX_REPORT_TYPE1_RERTY_0(__paddr) \ ++ le16_get_bits(*(__le16 *)__paddr, GENMASK(15, 0)) ++#define GET_TX_REPORT_TYPE1_RERTY_1(__paddr) \ ++ LE_BITS_TO_1BYTE(__paddr + 2, 0, 8) ++#define GET_TX_REPORT_TYPE1_RERTY_2(__paddr) \ ++ LE_BITS_TO_1BYTE(__paddr + 3, 0, 8) ++#define GET_TX_REPORT_TYPE1_RERTY_3(__paddr) \ ++ LE_BITS_TO_1BYTE(__paddr + 4, 0, 8) ++#define GET_TX_REPORT_TYPE1_RERTY_4(__paddr) \ ++ LE_BITS_TO_1BYTE(__paddr + 5, 0, 8) ++#define GET_TX_REPORT_TYPE1_DROP_0(__paddr) \ ++ LE_BITS_TO_1BYTE(__paddr + 6, 0, 8) ++/* End rate adaptive define */ ++ ++void ODM_RASupport_Init(struct odm_dm_struct *dm_odm); ++ ++int ODM_RAInfo_Init_all(struct odm_dm_struct *dm_odm); ++ ++int ODM_RAInfo_Init(struct odm_dm_struct *dm_odm, u8 MacID); ++ ++u8 ODM_RA_GetShortGI_8188E(struct odm_dm_struct *dm_odm, u8 MacID); ++ ++u8 ODM_RA_GetDecisionRate_8188E(struct odm_dm_struct *dm_odm, u8 MacID); ++ ++u8 ODM_RA_GetHwPwrStatus_8188E(struct odm_dm_struct *dm_odm, u8 MacID); ++void ODM_RA_UpdateRateInfo_8188E(struct odm_dm_struct *dm_odm, u8 MacID, ++ u8 RateID, u32 RateMask, ++ u8 SGIEnable); ++ ++void ODM_RA_SetRSSI_8188E(struct odm_dm_struct *dm_odm, u8 macid, ++ u8 rssi); ++ ++void ODM_RA_TxRPT2Handle_8188E(struct odm_dm_struct *dm_odm, ++ u8 *txrpt_buf, u16 txrpt_len, ++ u32 validentry0, u32 validentry1); ++ ++void ODM_RA_Set_TxRPT_Time(struct odm_dm_struct *dm_odm, u16 minRptTime); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/HalHWImg8188E_BB.h b/drivers/staging/r8188eu/include/HalHWImg8188E_BB.h +new file mode 100644 +index 000000000000..8270fdbc2844 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/HalHWImg8188E_BB.h +@@ -0,0 +1,27 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __INC_BB_8188E_HW_IMG_H ++#define __INC_BB_8188E_HW_IMG_H ++ ++/* static bool CheckCondition(const u32 Condition, const u32 Hex); */ ++ ++/****************************************************************************** ++* AGC_TAB_1T.TXT ++******************************************************************************/ ++ ++enum HAL_STATUS ODM_ReadAndConfig_AGC_TAB_1T_8188E(struct odm_dm_struct *odm); ++ ++/****************************************************************************** ++* PHY_REG_1T.TXT ++******************************************************************************/ ++ ++enum HAL_STATUS ODM_ReadAndConfig_PHY_REG_1T_8188E(struct odm_dm_struct *odm); ++ ++/****************************************************************************** ++* PHY_REG_PG.TXT ++******************************************************************************/ ++ ++void ODM_ReadAndConfig_PHY_REG_PG_8188E(struct odm_dm_struct *dm_odm); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/HalHWImg8188E_FW.h b/drivers/staging/r8188eu/include/HalHWImg8188E_FW.h +new file mode 100644 +index 000000000000..5ddcd283097b +--- /dev/null ++++ b/drivers/staging/r8188eu/include/HalHWImg8188E_FW.h +@@ -0,0 +1,16 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __INC_FW_8188E_HW_IMG_H ++#define __INC_FW_8188E_HW_IMG_H ++ ++/****************************************************************************** ++* FW_AP.TXT ++******************************************************************************/ ++/****************************************************************************** ++* FW_WoWLAN.TXT ++******************************************************************************/ ++#define ArrayLength_8188E_FW_WoWLAN 15764 ++extern const u8 Array_8188E_FW_WoWLAN[ArrayLength_8188E_FW_WoWLAN]; ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/HalHWImg8188E_MAC.h b/drivers/staging/r8188eu/include/HalHWImg8188E_MAC.h +new file mode 100644 +index 000000000000..391c1754b0b6 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/HalHWImg8188E_MAC.h +@@ -0,0 +1,13 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __INC_MAC_8188E_HW_IMG_H ++#define __INC_MAC_8188E_HW_IMG_H ++ ++/****************************************************************************** ++* MAC_REG.TXT ++******************************************************************************/ ++ ++enum HAL_STATUS ODM_ReadAndConfig_MAC_REG_8188E(struct odm_dm_struct *pDM_Odm); ++ ++#endif /* end of HWIMG_SUPPORT */ +diff --git a/drivers/staging/r8188eu/include/HalHWImg8188E_RF.h b/drivers/staging/r8188eu/include/HalHWImg8188E_RF.h +new file mode 100644 +index 000000000000..0c67c3df20b9 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/HalHWImg8188E_RF.h +@@ -0,0 +1,13 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __INC_RF_8188E_HW_IMG_H ++#define __INC_RF_8188E_HW_IMG_H ++ ++/****************************************************************************** ++ * RadioA_1T.TXT ++ ******************************************************************************/ ++ ++enum HAL_STATUS ODM_ReadAndConfig_RadioA_1T_8188E(struct odm_dm_struct *odm); ++ ++#endif /* end of HWIMG_SUPPORT */ +diff --git a/drivers/staging/r8188eu/include/HalPhyRf_8188e.h b/drivers/staging/r8188eu/include/HalPhyRf_8188e.h +new file mode 100644 +index 000000000000..d4a27662309f +--- /dev/null ++++ b/drivers/staging/r8188eu/include/HalPhyRf_8188e.h +@@ -0,0 +1,41 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __HAL_PHY_RF_8188E_H__ ++#define __HAL_PHY_RF_8188E_H__ ++ ++/*--------------------------Define Parameters-------------------------------*/ ++#define IQK_DELAY_TIME_88E 10 /* ms */ ++#define index_mapping_NUM_88E 15 ++#define AVG_THERMAL_NUM_88E 4 ++ ++void ODM_TxPwrTrackAdjust88E(struct odm_dm_struct *pDM_Odm, ++ u8 Type, /* 0 = OFDM, 1 = CCK */ ++ u8 *pDirection,/* 1 = +(incr) 2 = -(decr) */ ++ u32 *pOutWriteVal); /* Tx tracking CCK/OFDM BB ++ * swing index adjust */ ++ ++void odm_TXPowerTrackingCallback_ThermalMeter_8188E(struct adapter *Adapter); ++ ++/* 1 7. IQK */ ++ ++void PHY_IQCalibrate_8188E(struct adapter *Adapter, bool ReCovery); ++ ++/* LC calibrate */ ++void PHY_LCCalibrate_8188E(struct adapter *pAdapter); ++ ++/* AP calibrate */ ++void PHY_DigitalPredistortion_8188E(struct adapter *pAdapter); ++ ++void _PHY_SaveADDARegisters(struct adapter *pAdapter, u32 *ADDAReg, ++ u32 *ADDABackup, u32 RegisterNum); ++ ++void _PHY_PathADDAOn(struct adapter *pAdapter, u32 *ADDAReg, ++ bool isPathAOn, bool is2T); ++ ++void _PHY_MACSettingCalibration(struct adapter *pAdapter, u32 *MACReg, ++ u32 *MACBackup); ++ ++void _PHY_PathAStandBy(struct adapter *pAdapter); ++ ++#endif /* #ifndef __HAL_PHY_RF_8188E_H__ */ +diff --git a/drivers/staging/r8188eu/include/HalPwrSeqCmd.h b/drivers/staging/r8188eu/include/HalPwrSeqCmd.h +new file mode 100644 +index 000000000000..fe7ac910beb8 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/HalPwrSeqCmd.h +@@ -0,0 +1,110 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __HALPWRSEQCMD_H__ ++#define __HALPWRSEQCMD_H__ ++ ++#include "drv_types.h" ++ ++/*---------------------------------------------*/ ++/* 3 The value of cmd: 4 bits */ ++/*---------------------------------------------*/ ++#define PWR_CMD_READ 0x00 ++ /* offset: the read register offset */ ++ /* msk: the mask of the read value */ ++ /* value: N/A, left by 0 */ ++ /* note: dirver shall implement this function by read & msk */ ++ ++#define PWR_CMD_WRITE 0x01 ++ /* offset: the read register offset */ ++ /* msk: the mask of the write bits */ ++ /* value: write value */ ++ /* note: driver shall implement this cmd by read & msk after write */ ++ ++#define PWR_CMD_POLLING 0x02 ++ /* offset: the read register offset */ ++ /* msk: the mask of the polled value */ ++ /* value: the value to be polled, masked by the msd field. */ ++ /* note: driver shall implement this cmd by */ ++ /* do{ */ ++ /* if ( (Read(offset) & msk) == (value & msk) ) */ ++ /* break; */ ++ /* } while (not timeout); */ ++ ++#define PWR_CMD_DELAY 0x03 ++ /* offset: the value to delay */ ++ /* msk: N/A */ ++ /* value: the unit of delay, 0: us, 1: ms */ ++ ++#define PWR_CMD_END 0x04 ++ /* offset: N/A */ ++ /* msk: N/A */ ++ /* value: N/A */ ++ ++/*---------------------------------------------*/ ++/* 3 The value of base: 4 bits */ ++/*---------------------------------------------*/ ++ /* define the base address of each block */ ++#define PWR_BASEADDR_MAC 0x00 ++#define PWR_BASEADDR_USB 0x01 ++#define PWR_BASEADDR_PCIE 0x02 ++#define PWR_BASEADDR_SDIO 0x03 ++ ++/*---------------------------------------------*/ ++/* 3 The value of interface_msk: 4 bits */ ++/*---------------------------------------------*/ ++#define PWR_INTF_SDIO_MSK BIT(0) ++#define PWR_INTF_USB_MSK BIT(1) ++#define PWR_INTF_PCI_MSK BIT(2) ++#define PWR_INTF_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) ++ ++/*---------------------------------------------*/ ++/* 3 The value of fab_msk: 4 bits */ ++/*---------------------------------------------*/ ++#define PWR_FAB_TSMC_MSK BIT(0) ++#define PWR_FAB_UMC_MSK BIT(1) ++#define PWR_FAB_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) ++ ++/*---------------------------------------------*/ ++/* 3 The value of cut_msk: 8 bits */ ++/*---------------------------------------------*/ ++#define PWR_CUT_TESTCHIP_MSK BIT(0) ++#define PWR_CUT_A_MSK BIT(1) ++#define PWR_CUT_B_MSK BIT(2) ++#define PWR_CUT_C_MSK BIT(3) ++#define PWR_CUT_D_MSK BIT(4) ++#define PWR_CUT_E_MSK BIT(5) ++#define PWR_CUT_F_MSK BIT(6) ++#define PWR_CUT_G_MSK BIT(7) ++#define PWR_CUT_ALL_MSK 0xFF ++ ++enum pwrseq_cmd_delat_unit { ++ PWRSEQ_DELAY_US, ++ PWRSEQ_DELAY_MS, ++}; ++ ++struct wl_pwr_cfg { ++ u16 offset; ++ u8 cut_msk; ++ u8 fab_msk:4; ++ u8 interface_msk:4; ++ u8 base:4; ++ u8 cmd:4; ++ u8 msk; ++ u8 value; ++}; ++ ++#define GET_PWR_CFG_OFFSET(__PWR_CMD) __PWR_CMD.offset ++#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) __PWR_CMD.cut_msk ++#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) __PWR_CMD.fab_msk ++#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) __PWR_CMD.interface_msk ++#define GET_PWR_CFG_BASE(__PWR_CMD) __PWR_CMD.base ++#define GET_PWR_CFG_CMD(__PWR_CMD) __PWR_CMD.cmd ++#define GET_PWR_CFG_MASK(__PWR_CMD) __PWR_CMD.msk ++#define GET_PWR_CFG_VALUE(__PWR_CMD) __PWR_CMD.value ++ ++/* Prototype of protected function. */ ++u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 CutVersion, u8 FabVersion, ++ u8 InterfaceType, struct wl_pwr_cfg PwrCfgCmd[]); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/HalVerDef.h b/drivers/staging/r8188eu/include/HalVerDef.h +new file mode 100644 +index 000000000000..a0f5bf52e75a +--- /dev/null ++++ b/drivers/staging/r8188eu/include/HalVerDef.h +@@ -0,0 +1,149 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++#ifndef __HAL_VERSION_DEF_H__ ++#define __HAL_VERSION_DEF_H__ ++ ++enum HAL_IC_TYPE { ++ CHIP_8192S = 0, ++ CHIP_8188C = 1, ++ CHIP_8192C = 2, ++ CHIP_8192D = 3, ++ CHIP_8723A = 4, ++ CHIP_8188E = 5, ++ CHIP_8881A = 6, ++ CHIP_8812A = 7, ++ CHIP_8821A = 8, ++ CHIP_8723B = 9, ++ CHIP_8192E = 10, ++}; ++ ++enum HAL_CHIP_TYPE { ++ TEST_CHIP = 0, ++ NORMAL_CHIP = 1, ++ FPGA = 2, ++}; ++ ++enum HAL_CUT_VERSION { ++ A_CUT_VERSION = 0, ++ B_CUT_VERSION = 1, ++ C_CUT_VERSION = 2, ++ D_CUT_VERSION = 3, ++ E_CUT_VERSION = 4, ++ F_CUT_VERSION = 5, ++ G_CUT_VERSION = 6, ++}; ++ ++enum HAL_VENDOR { ++ CHIP_VENDOR_TSMC = 0, ++ CHIP_VENDOR_UMC = 1, ++}; ++ ++enum HAL_RF_TYPE { ++ RF_TYPE_1T1R = 0, ++ RF_TYPE_1T2R = 1, ++ RF_TYPE_2T2R = 2, ++ RF_TYPE_2T3R = 3, ++ RF_TYPE_2T4R = 4, ++ RF_TYPE_3T3R = 5, ++ RF_TYPE_3T4R = 6, ++ RF_TYPE_4T4R = 7, ++}; ++ ++struct HAL_VERSION { ++ enum HAL_IC_TYPE ICType; ++ enum HAL_CHIP_TYPE ChipType; ++ enum HAL_CUT_VERSION CUTVersion; ++ enum HAL_VENDOR VendorType; ++ enum HAL_RF_TYPE RFType; ++ u8 ROMVer; ++}; ++ ++/* Get element */ ++#define GET_CVID_IC_TYPE(version) (((version).ICType)) ++#define GET_CVID_CHIP_TYPE(version) (((version).ChipType)) ++#define GET_CVID_RF_TYPE(version) (((version).RFType)) ++#define GET_CVID_MANUFACTUER(version) (((version).VendorType)) ++#define GET_CVID_CUT_VERSION(version) (((version).CUTVersion)) ++#define GET_CVID_ROM_VERSION(version) (((version).ROMVer) & ROM_VERSION_MASK) ++ ++/* Common Macro. -- */ ++/* HAL_VERSION VersionID */ ++ ++/* HAL_IC_TYPE_E */ ++#define IS_81XXC(version) \ ++ (((GET_CVID_IC_TYPE(version) == CHIP_8192C) || \ ++ (GET_CVID_IC_TYPE(version) == CHIP_8188C)) ? true : false) ++#define IS_8723_SERIES(version) \ ++ ((GET_CVID_IC_TYPE(version) == CHIP_8723A) ? true : false) ++#define IS_92D(version) \ ++ ((GET_CVID_IC_TYPE(version) == CHIP_8192D) ? true : false) ++#define IS_8188E(version) \ ++ ((GET_CVID_IC_TYPE(version) == CHIP_8188E) ? true : false) ++ ++/* HAL_CHIP_TYPE_E */ ++#define IS_TEST_CHIP(version) \ ++ ((GET_CVID_CHIP_TYPE(version) == TEST_CHIP) ? true : false) ++#define IS_NORMAL_CHIP(version) \ ++ ((GET_CVID_CHIP_TYPE(version) == NORMAL_CHIP) ? true : false) ++ ++/* HAL_CUT_VERSION_E */ ++#define IS_A_CUT(version) \ ++ ((GET_CVID_CUT_VERSION(version) == A_CUT_VERSION) ? true : false) ++#define IS_B_CUT(version) \ ++ ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? true : false) ++#define IS_C_CUT(version) \ ++ ((GET_CVID_CUT_VERSION(version) == C_CUT_VERSION) ? true : false) ++#define IS_D_CUT(version) \ ++ ((GET_CVID_CUT_VERSION(version) == D_CUT_VERSION) ? true : false) ++#define IS_E_CUT(version) \ ++ ((GET_CVID_CUT_VERSION(version) == E_CUT_VERSION) ? true : false) ++ ++/* HAL_VENDOR_E */ ++#define IS_CHIP_VENDOR_TSMC(version) \ ++ ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_TSMC) ? true : false) ++#define IS_CHIP_VENDOR_UMC(version) \ ++ ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_UMC) ? true : false) ++ ++/* HAL_RF_TYPE_E */ ++#define IS_1T1R(version) \ ++ ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T1R) ? true : false) ++#define IS_1T2R(version) \ ++ ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R) ? true : false) ++#define IS_2T2R(version) \ ++ ((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R) ? true : false) ++ ++/* Chip version Macro. -- */ ++#define IS_81XXC_TEST_CHIP(version) \ ++ ((IS_81XXC(version) && (!IS_NORMAL_CHIP(version))) ? true : false) ++ ++#define IS_92C_SERIAL(version) \ ++ ((IS_81XXC(version) && IS_2T2R(version)) ? true : false) ++#define IS_81xxC_VENDOR_UMC_A_CUT(version) \ ++ (IS_81XXC(version) ? (IS_CHIP_VENDOR_UMC(version) ? \ ++ (IS_A_CUT(version) ? true : false) : false) : false) ++#define IS_81xxC_VENDOR_UMC_B_CUT(version) \ ++ (IS_81XXC(version) ? (IS_CHIP_VENDOR_UMC(version) ? \ ++ (IS_B_CUT(version) ? true : false) : false) : false) ++#define IS_81xxC_VENDOR_UMC_C_CUT(version) \ ++ (IS_81XXC(version) ? (IS_CHIP_VENDOR_UMC(version) ? \ ++ (IS_C_CUT(version) ? true : false) : false) : false) ++ ++#define IS_NORMAL_CHIP92D(version) \ ++ ((IS_92D(version)) ? \ ++ ((GET_CVID_CHIP_TYPE(version) == NORMAL_CHIP) ? true : false) : false) ++ ++#define IS_92D_SINGLEPHY(version) \ ++ ((IS_92D(version)) ? (IS_2T2R(version) ? true : false) : false) ++#define IS_92D_C_CUT(version) \ ++ ((IS_92D(version)) ? (IS_C_CUT(version) ? true : false) : false) ++#define IS_92D_D_CUT(version) \ ++ ((IS_92D(version)) ? (IS_D_CUT(version) ? true : false) : false) ++#define IS_92D_E_CUT(version) \ ++ ((IS_92D(version)) ? (IS_E_CUT(version) ? true : false) : false) ++ ++#define IS_8723A_A_CUT(version) \ ++ ((IS_8723_SERIES(version)) ? (IS_A_CUT(version) ? true : false) : false) ++#define IS_8723A_B_CUT(version) \ ++ ((IS_8723_SERIES(version)) ? (IS_B_CUT(version) ? true : false) : false) ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/basic_types.h b/drivers/staging/r8188eu/include/basic_types.h +new file mode 100644 +index 000000000000..d82b2171d584 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/basic_types.h +@@ -0,0 +1,123 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __BASIC_TYPES_H__ ++#define __BASIC_TYPES_H__ ++ ++#define SUCCESS 0 ++#define FAIL (-1) ++ ++#include ++#define NDIS_OID uint ++ ++typedef void (*proc_t)(void *); ++ ++#define FIELD_OFFSET(s, field) ((ssize_t)&((s *)(0))->field) ++ ++#define MEM_ALIGNMENT_OFFSET (sizeof(size_t)) ++#define MEM_ALIGNMENT_PADDING (sizeof(size_t) - 1) ++ ++/* port from fw */ ++/* TODO: Macros Below are Sync from SD7-Driver. It is necessary ++ * to check correctness */ ++ ++/* ++ * Call endian free function when ++ * 1. Read/write packet content. ++ * 2. Before write integer to IO. ++ * 3. After read integer from IO. ++*/ ++ ++/* Convert little data endian to host ordering */ ++#define EF1BYTE(_val) \ ++ ((u8)(_val)) ++#define EF2BYTE(_val) \ ++ (le16_to_cpu(_val)) ++#define EF4BYTE(_val) \ ++ (le32_to_cpu(_val)) ++ ++/* Read data from memory */ ++#define READEF1BYTE(_ptr) \ ++ EF1BYTE(*((u8 *)(_ptr))) ++/* Read le16 data from memory and convert to host ordering */ ++#define READEF2BYTE(_ptr) \ ++ EF2BYTE(*(_ptr)) ++#define READEF4BYTE(_ptr) \ ++ EF4BYTE(*(_ptr)) ++ ++/* Write data to memory */ ++#define WRITEEF1BYTE(_ptr, _val) \ ++ do { \ ++ (*((u8 *)(_ptr))) = EF1BYTE(_val) \ ++ } while (0) ++/* Write le data to memory in host ordering */ ++#define WRITEEF2BYTE(_ptr, _val) \ ++ do { \ ++ (*((u16 *)(_ptr))) = EF2BYTE(_val) \ ++ } while (0) ++ ++#define WRITEEF4BYTE(_ptr, _val) \ ++ do { \ ++ (*((u32 *)(_ptr))) = EF2BYTE(_val) \ ++ } while (0) ++ ++/* Create a bit mask ++ * Examples: ++ * BIT_LEN_MASK_32(0) => 0x00000000 ++ * BIT_LEN_MASK_32(1) => 0x00000001 ++ * BIT_LEN_MASK_32(2) => 0x00000003 ++ * BIT_LEN_MASK_32(32) => 0xFFFFFFFF ++ */ ++#define BIT_LEN_MASK_32(__bitlen) \ ++ (0xFFFFFFFF >> (32 - (__bitlen))) ++#define BIT_LEN_MASK_16(__bitlen) \ ++ (0xFFFF >> (16 - (__bitlen))) ++#define BIT_LEN_MASK_8(__bitlen) \ ++ (0xFF >> (8 - (__bitlen))) ++ ++/* Create an offset bit mask ++ * Examples: ++ * BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003 ++ * BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000 ++ */ ++#define BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen) \ ++ (BIT_LEN_MASK_32(__bitlen) << (__bitoffset)) ++#define BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen) \ ++ (BIT_LEN_MASK_16(__bitlen) << (__bitoffset)) ++#define BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen) \ ++ (BIT_LEN_MASK_8(__bitlen) << (__bitoffset)) ++ ++/*Description: ++ * Return 4-byte value in host byte ordering from ++ * 4-byte pointer in little-endian system. ++ */ ++#define LE_P4BYTE_TO_HOST_4BYTE(__pstart) \ ++ (EF4BYTE(*((__le32 *)(__pstart)))) ++#define LE_P2BYTE_TO_HOST_2BYTE(__pstart) \ ++ (EF2BYTE(*((__le16 *)(__pstart)))) ++#define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \ ++ (EF1BYTE(*((u8 *)(__pstart)))) ++ ++/*Description: ++Translate subfield (continuous bits in little-endian) of 4-byte ++value to host byte ordering.*/ ++#define LE_BITS_TO_4BYTE(__pstart, __bitoffset, __bitlen) \ ++ ( \ ++ (LE_P4BYTE_TO_HOST_4BYTE(__pstart) >> (__bitoffset)) & \ ++ BIT_LEN_MASK_32(__bitlen) \ ++ ) ++#define LE_BITS_TO_2BYTE(__pstart, __bitoffset, __bitlen) \ ++ ( \ ++ (LE_P2BYTE_TO_HOST_2BYTE(__pstart) >> (__bitoffset)) & \ ++ BIT_LEN_MASK_16(__bitlen) \ ++ ) ++#define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \ ++ ( \ ++ (LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset)) & \ ++ BIT_LEN_MASK_8(__bitlen) \ ++ ) ++ ++#define N_BYTE_ALIGMENT(__value, __aligment) ((__aligment == 1) ? \ ++ (__value) : (((__value + __aligment - 1) / __aligment) * __aligment)) ++ ++#endif /* __BASIC_TYPES_H__ */ +diff --git a/drivers/staging/r8188eu/include/drv_types.h b/drivers/staging/r8188eu/include/drv_types.h +new file mode 100644 +index 000000000000..04f4224c11de +--- /dev/null ++++ b/drivers/staging/r8188eu/include/drv_types.h +@@ -0,0 +1,323 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++/*----------------------------------------------------------------------------- ++ ++ For type defines and data structure defines ++ ++------------------------------------------------------------------------------*/ ++ ++#ifndef __DRV_TYPES_H__ ++#define __DRV_TYPES_H__ ++ ++#define DRV_NAME "r8188eu" ++#define CONFIG_88EU_AP_MODE 1 ++#define CONFIG_88EU_P2P 1 ++ ++#include "osdep_service.h" ++#include "wlan_bssdef.h" ++#include "rtw_ht.h" ++#include "rtw_cmd.h" ++#include "rtw_xmit.h" ++#include "rtw_recv.h" ++#include "hal_intf.h" ++#include "hal_com.h" ++#include "rtw_security.h" ++#include "rtw_pwrctrl.h" ++#include "rtw_io.h" ++#include "rtw_eeprom.h" ++#include "sta_info.h" ++#include "rtw_mlme.h" ++#include "rtw_debug.h" ++#include "rtw_rf.h" ++#include "rtw_event.h" ++#include "rtw_led.h" ++#include "rtw_mlme_ext.h" ++#include "rtw_p2p.h" ++#include "rtw_ap.h" ++#include "rtw_mp.h" ++#include "rtw_br_ext.h" ++ ++#define DRIVERVERSION "v4.1.4_6773.20130222" ++ ++#define SPEC_DEV_ID_NONE BIT(0) ++#define SPEC_DEV_ID_DISABLE_HT BIT(1) ++#define SPEC_DEV_ID_ENABLE_PS BIT(2) ++#define SPEC_DEV_ID_RF_CONFIG_1T1R BIT(3) ++#define SPEC_DEV_ID_RF_CONFIG_2T2R BIT(4) ++#define SPEC_DEV_ID_ASSIGN_IFNAME BIT(5) ++ ++struct specific_device_id { ++ u32 flags; ++ u16 idVendor; ++ u16 idProduct; ++}; ++ ++struct registry_priv { ++ u8 chip_version; ++ u8 rfintfs; ++ u8 lbkmode; ++ u8 hci; ++ struct ndis_802_11_ssid ssid; ++ u8 network_mode; /* infra, ad-hoc, auto */ ++ u8 channel;/* ad-hoc support requirement */ ++ u8 wireless_mode;/* A, B, G, auto */ ++ u8 scan_mode;/* active, passive */ ++ u8 radio_enable; ++ u8 preamble;/* long, short, auto */ ++ u8 vrtl_carrier_sense;/* Enable, Disable, Auto */ ++ u8 vcs_type;/* RTS/CTS, CTS-to-self */ ++ u16 rts_thresh; ++ u16 frag_thresh; ++ u8 adhoc_tx_pwr; ++ u8 soft_ap; ++ u8 power_mgnt; ++ u8 ips_mode; ++ u8 smart_ps; ++ u8 long_retry_lmt; ++ u8 short_retry_lmt; ++ u16 busy_thresh; ++ u8 ack_policy; ++ u8 mp_mode; ++ u8 software_encrypt; ++ u8 software_decrypt; ++ u8 acm_method; ++ /* UAPSD */ ++ u8 wmm_enable; ++ u8 uapsd_enable; ++ u8 uapsd_max_sp; ++ u8 uapsd_acbk_en; ++ u8 uapsd_acbe_en; ++ u8 uapsd_acvi_en; ++ u8 uapsd_acvo_en; ++ ++ u8 led_enable; ++ ++ struct wlan_bssid_ex dev_network; ++ ++ u8 ht_enable; ++ u8 cbw40_enable; ++ u8 ampdu_enable;/* for tx */ ++ u8 rx_stbc; ++ u8 ampdu_amsdu;/* A-MPDU Supports A-MSDU is permitted */ ++ u8 lowrate_two_xmit; ++ ++ u8 rf_config; ++ u8 low_power; ++ ++ u8 wifi_spec;/* !turbo_mode */ ++ ++ u8 channel_plan; ++ bool bAcceptAddbaReq; ++ ++ u8 antdiv_cfg; ++ u8 antdiv_type; ++ ++ u8 usbss_enable;/* 0:disable,1:enable */ ++ u8 hwpdn_mode;/* 0:disable,1:enable,2:decide by EFUSE config */ ++ u8 hwpwrp_detect;/* 0:disable,1:enable */ ++ ++ u8 hw_wps_pbc;/* 0:disable,1:enable */ ++ ++ u8 max_roaming_times; /* the max number driver will try */ ++ ++ u8 fw_iol; /* enable iol without other concern */ ++ ++ u8 enable80211d; ++ ++ u8 ifname[16]; ++ u8 if2name[16]; ++ ++ u8 notch_filter; ++}; ++ ++/* For registry parameters */ ++#define RGTRY_OFT(field) ((u32)FIELD_OFFSET(struct registry_priv, field)) ++#define RGTRY_SZ(field) sizeof(((struct registry_priv *)0)->field) ++#define BSSID_OFT(field) ((u32)FIELD_OFFSET(struct wlan_bssid_ex, field)) ++#define BSSID_SZ(field) sizeof(((struct wlan_bssid_ex *)0)->field) ++ ++#define MAX_CONTINUAL_URB_ERR 4 ++ ++struct rt_firmware { ++ u8 *szFwBuffer; ++ u32 ulFwLength; ++}; ++ ++struct dvobj_priv { ++ struct adapter *if1; ++ struct adapter *if2; ++ ++ /* For 92D, DMDP have 2 interface. */ ++ u8 InterfaceNumber; ++ u8 NumInterfaces; ++ ++ /* In /Out Pipe information */ ++ int RtInPipe[2]; ++ int RtOutPipe[3]; ++ u8 Queue2Pipe[HW_QUEUE_ENTRY];/* for out pipe mapping */ ++ ++ u8 irq_alloc; ++ ++ struct rt_firmware firmware; ++ ++/*-------- below is for USB INTERFACE --------*/ ++ ++ u8 nr_endpoint; ++ u8 ishighspeed; ++ u8 RtNumInPipes; ++ u8 RtNumOutPipes; ++ int ep_num[5]; /* endpoint number */ ++ int RegUsbSS; ++ struct semaphore usb_suspend_sema; ++ struct mutex usb_vendor_req_mutex; ++ ++ u8 *usb_alloc_vendor_req_buf; ++ u8 *usb_vendor_req_buf; ++ ++ struct usb_interface *pusbintf; ++ struct usb_device *pusbdev; ++ ++ atomic_t continual_urb_error; ++ u8 signal_strength; ++}; ++ ++static inline struct device *dvobj_to_dev(struct dvobj_priv *dvobj) ++{ ++ /* todo: get interface type from dvobj and the return ++ * the dev accordingly */ ++ return &dvobj->pusbintf->dev; ++}; ++ ++enum _IFACE_TYPE { ++ IFACE_PORT0, /* mapping to port0 for C/D series chips */ ++ IFACE_PORT1, /* mapping to port1 for C/D series chip */ ++ MAX_IFACE_PORT, ++}; ++ ++enum _ADAPTER_TYPE { ++ PRIMARY_ADAPTER, ++ SECONDARY_ADAPTER, ++ MAX_ADAPTER, ++}; ++ ++enum driver_state { ++ DRIVER_NORMAL = 0, ++ DRIVER_DISAPPEAR = 1, ++ DRIVER_REPLACE_DONGLE = 2, ++}; ++ ++struct adapter { ++ int DriverState;/* for disable driver using module, use dongle toi ++ * replace module. */ ++ int pid[3];/* process id from UI, 0:wps, 1:hostapd, 2:dhcpcd */ ++ int bDongle;/* build-in module or external dongle */ ++ u16 chip_type; ++ u16 HardwareType; ++ u16 interface_type;/* USB,SDIO,SPI,PCI */ ++ ++ struct dvobj_priv *dvobj; ++ struct mlme_priv mlmepriv; ++ struct mlme_ext_priv mlmeextpriv; ++ struct cmd_priv cmdpriv; ++ struct evt_priv evtpriv; ++ struct io_priv iopriv; ++ struct xmit_priv xmitpriv; ++ struct recv_priv recvpriv; ++ struct sta_priv stapriv; ++ struct security_priv securitypriv; ++ struct registry_priv registrypriv; ++ struct pwrctrl_priv pwrctrlpriv; ++ struct eeprom_priv eeprompriv; ++ struct led_priv ledpriv; ++ struct mp_priv mppriv; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ struct hostapd_priv *phostapdpriv; ++#endif ++ ++ struct wifidirect_info wdinfo; ++ ++ void *HalData; ++ u32 hal_data_sz; ++ struct hal_ops HalFunc; ++ ++ s32 bDriverStopped; ++ s32 bSurpriseRemoved; ++ s32 bCardDisableWOHSM; ++ ++ u32 IsrContent; ++ u32 ImrContent; ++ ++ u8 EepromAddressSize; ++ u8 hw_init_completed; ++ u8 bDriverIsGoingToUnload; ++ u8 init_adpt_in_progress; ++ u8 bHaltInProgress; ++ s8 signal_strength; ++ ++ void *cmdThread; ++ void *evtThread; ++ void *xmitThread; ++ void *recvThread; ++ void (*intf_start)(struct adapter *adapter); ++ void (*intf_stop)(struct adapter *adapter); ++ struct net_device *pnetdev; ++ ++ /* used by rtw_rereg_nd_name related function */ ++ struct rereg_nd_name_data { ++ struct net_device *old_pnetdev; ++ char old_ifname[IFNAMSIZ]; ++ u8 old_ips_mode; ++ u8 old_bRegUseLed; ++ } rereg_nd_name_priv; ++ ++ int bup; ++ struct net_device_stats stats; ++ struct iw_statistics iwstats; ++ struct proc_dir_entry *dir_dev;/* for proc directory */ ++ ++ int net_closed; ++ u8 bFWReady; ++ u8 bBTFWReady; ++ u8 bReadPortCancel; ++ u8 bWritePortCancel; ++ u8 bRxRSSIDisplay; ++ /* The driver will show up the desired channel number ++ * when this flag is 1. */ ++ u8 bNotifyChannelChange; ++#ifdef CONFIG_88EU_P2P ++ /* The driver will show the current P2P status when the ++ * upper application reads it. */ ++ u8 bShowGetP2PState; ++#endif ++ struct adapter *pbuddy_adapter; ++ ++ struct mutex *hw_init_mutex; ++ ++ spinlock_t br_ext_lock; ++ struct nat25_network_db_entry *nethash[NAT25_HASH_SIZE]; ++ int pppoe_connection_in_progress; ++ unsigned char pppoe_addr[MACADDRLEN]; ++ unsigned char scdb_mac[MACADDRLEN]; ++ unsigned char scdb_ip[4]; ++ struct nat25_network_db_entry *scdb_entry; ++ unsigned char br_mac[MACADDRLEN]; ++ unsigned char br_ip[4]; ++ struct br_ext_info ethBrExtInfo; ++ ++ u8 fix_rate; ++ ++ unsigned char in_cta_test; ++}; ++ ++#define adapter_to_dvobj(adapter) (adapter->dvobj) ++ ++int rtw_handle_dualmac(struct adapter *adapter, bool init); ++ ++static inline u8 *myid(struct eeprom_priv *peepriv) ++{ ++ return peepriv->mac_addr; ++} ++ ++#endif /* __DRV_TYPES_H__ */ +diff --git a/drivers/staging/r8188eu/include/hal_com.h b/drivers/staging/r8188eu/include/hal_com.h +new file mode 100644 +index 000000000000..95167f0b327f +--- /dev/null ++++ b/drivers/staging/r8188eu/include/hal_com.h +@@ -0,0 +1,156 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __HAL_COMMON_H__ ++#define __HAL_COMMON_H__ ++ ++/* */ ++/* Rate Definition */ ++/* */ ++/* CCK */ ++#define RATR_1M 0x00000001 ++#define RATR_2M 0x00000002 ++#define RATR_55M 0x00000004 ++#define RATR_11M 0x00000008 ++/* OFDM */ ++#define RATR_6M 0x00000010 ++#define RATR_9M 0x00000020 ++#define RATR_12M 0x00000040 ++#define RATR_18M 0x00000080 ++#define RATR_24M 0x00000100 ++#define RATR_36M 0x00000200 ++#define RATR_48M 0x00000400 ++#define RATR_54M 0x00000800 ++/* MCS 1 Spatial Stream */ ++#define RATR_MCS0 0x00001000 ++#define RATR_MCS1 0x00002000 ++#define RATR_MCS2 0x00004000 ++#define RATR_MCS3 0x00008000 ++#define RATR_MCS4 0x00010000 ++#define RATR_MCS5 0x00020000 ++#define RATR_MCS6 0x00040000 ++#define RATR_MCS7 0x00080000 ++/* MCS 2 Spatial Stream */ ++#define RATR_MCS8 0x00100000 ++#define RATR_MCS9 0x00200000 ++#define RATR_MCS10 0x00400000 ++#define RATR_MCS11 0x00800000 ++#define RATR_MCS12 0x01000000 ++#define RATR_MCS13 0x02000000 ++#define RATR_MCS14 0x04000000 ++#define RATR_MCS15 0x08000000 ++ ++/* CCK */ ++#define RATE_1M BIT(0) ++#define RATE_2M BIT(1) ++#define RATE_5_5M BIT(2) ++#define RATE_11M BIT(3) ++/* OFDM */ ++#define RATE_6M BIT(4) ++#define RATE_9M BIT(5) ++#define RATE_12M BIT(6) ++#define RATE_18M BIT(7) ++#define RATE_24M BIT(8) ++#define RATE_36M BIT(9) ++#define RATE_48M BIT(10) ++#define RATE_54M BIT(11) ++/* MCS 1 Spatial Stream */ ++#define RATE_MCS0 BIT(12) ++#define RATE_MCS1 BIT(13) ++#define RATE_MCS2 BIT(14) ++#define RATE_MCS3 BIT(15) ++#define RATE_MCS4 BIT(16) ++#define RATE_MCS5 BIT(17) ++#define RATE_MCS6 BIT(18) ++#define RATE_MCS7 BIT(19) ++/* MCS 2 Spatial Stream */ ++#define RATE_MCS8 BIT(20) ++#define RATE_MCS9 BIT(21) ++#define RATE_MCS10 BIT(22) ++#define RATE_MCS11 BIT(23) ++#define RATE_MCS12 BIT(24) ++#define RATE_MCS13 BIT(25) ++#define RATE_MCS14 BIT(26) ++#define RATE_MCS15 BIT(27) ++ ++/* ALL CCK Rate */ ++#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) ++#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M | \ ++ RATR_24M | RATR_36M | RATR_48M | RATR_54M) ++#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \ ++ RATR_MCS3 | RATR_MCS4 | RATR_MCS5|RATR_MCS6 | \ ++ RATR_MCS7) ++#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \ ++ RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \ ++ RATR_MCS14 | RATR_MCS15) ++ ++/*------------------------------ Tx Desc definition Macro --------------------*/ ++/* pragma mark -- Tx Desc related definition. -- */ ++/* Rate */ ++/* CCK Rates, TxHT = 0 */ ++#define DESC_RATE1M 0x00 ++#define DESC_RATE2M 0x01 ++#define DESC_RATE5_5M 0x02 ++#define DESC_RATE11M 0x03 ++ ++/* OFDM Rates, TxHT = 0 */ ++#define DESC_RATE6M 0x04 ++#define DESC_RATE9M 0x05 ++#define DESC_RATE12M 0x06 ++#define DESC_RATE18M 0x07 ++#define DESC_RATE24M 0x08 ++#define DESC_RATE36M 0x09 ++#define DESC_RATE48M 0x0a ++#define DESC_RATE54M 0x0b ++ ++/* MCS Rates, TxHT = 1 */ ++#define DESC_RATEMCS0 0x0c ++#define DESC_RATEMCS1 0x0d ++#define DESC_RATEMCS2 0x0e ++#define DESC_RATEMCS3 0x0f ++#define DESC_RATEMCS4 0x10 ++#define DESC_RATEMCS5 0x11 ++#define DESC_RATEMCS6 0x12 ++#define DESC_RATEMCS7 0x13 ++#define DESC_RATEMCS8 0x14 ++#define DESC_RATEMCS9 0x15 ++#define DESC_RATEMCS10 0x16 ++#define DESC_RATEMCS11 0x17 ++#define DESC_RATEMCS12 0x18 ++#define DESC_RATEMCS13 0x19 ++#define DESC_RATEMCS14 0x1a ++#define DESC_RATEMCS15 0x1b ++#define DESC_RATEMCS15_SG 0x1c ++#define DESC_RATEMCS32 0x20 ++ ++/* 1 Byte long (in unit of TU) */ ++#define REG_P2P_CTWIN 0x0572 ++#define REG_NOA_DESC_SEL 0x05CF ++#define REG_NOA_DESC_DURATION 0x05E0 ++#define REG_NOA_DESC_INTERVAL 0x05E4 ++#define REG_NOA_DESC_START 0x05E8 ++#define REG_NOA_DESC_COUNT 0x05EC ++ ++#include "HalVerDef.h" ++void dump_chip_info(struct HAL_VERSION ChipVersion); ++ ++/* return the final channel plan decision */ ++u8 hal_com_get_channel_plan(struct adapter *padapter, ++ u8 hw_channel_plan, ++ u8 sw_channel_plan, ++ u8 def_channel_plan, ++ bool AutoLoadFail ++); ++ ++u8 MRateToHwRate(u8 rate); ++ ++void HalSetBrateCfg(struct adapter *Adapter, u8 *mBratesOS, u16 *pBrateCfg); ++ ++bool Hal_MappingOutPipe(struct adapter *pAdapter, u8 NumOutPipe); ++ ++void hal_init_macaddr(struct adapter *adapter); ++ ++void c2h_evt_clear(struct adapter *adapter); ++s32 c2h_evt_read(struct adapter *adapter, u8 *buf); ++ ++#endif /* __HAL_COMMON_H__ */ +diff --git a/drivers/staging/r8188eu/include/hal_intf.h b/drivers/staging/r8188eu/include/hal_intf.h +new file mode 100644 +index 000000000000..fa252540e596 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/hal_intf.h +@@ -0,0 +1,411 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#ifndef __HAL_INTF_H__ ++#define __HAL_INTF_H__ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "Hal8188EPhyCfg.h" ++ ++enum RTL871X_HCI_TYPE { ++ RTW_PCIE = BIT(0), ++ RTW_USB = BIT(1), ++ RTW_SDIO = BIT(2), ++ RTW_GSPI = BIT(3), ++}; ++ ++enum _CHIP_TYPE { ++ NULL_CHIP_TYPE, ++ RTL8712_8188S_8191S_8192S, ++ RTL8188C_8192C, ++ RTL8192D, ++ RTL8723A, ++ RTL8188E, ++ MAX_CHIP_TYPE ++}; ++ ++enum hw_variables { ++ HW_VAR_MEDIA_STATUS, ++ HW_VAR_MEDIA_STATUS1, ++ HW_VAR_SET_OPMODE, ++ HW_VAR_MAC_ADDR, ++ HW_VAR_BSSID, ++ HW_VAR_INIT_RTS_RATE, ++ HW_VAR_BASIC_RATE, ++ HW_VAR_TXPAUSE, ++ HW_VAR_BCN_FUNC, ++ HW_VAR_CORRECT_TSF, ++ HW_VAR_CHECK_BSSID, ++ HW_VAR_MLME_DISCONNECT, ++ HW_VAR_MLME_SITESURVEY, ++ HW_VAR_MLME_JOIN, ++ HW_VAR_BEACON_INTERVAL, ++ HW_VAR_SLOT_TIME, ++ HW_VAR_RESP_SIFS, ++ HW_VAR_ACK_PREAMBLE, ++ HW_VAR_SEC_CFG, ++ HW_VAR_BCN_VALID, ++ HW_VAR_RF_TYPE, ++ HW_VAR_DM_FLAG, ++ HW_VAR_DM_FUNC_OP, ++ HW_VAR_DM_FUNC_SET, ++ HW_VAR_DM_FUNC_CLR, ++ HW_VAR_CAM_EMPTY_ENTRY, ++ HW_VAR_CAM_INVALID_ALL, ++ HW_VAR_CAM_WRITE, ++ HW_VAR_CAM_READ, ++ HW_VAR_AC_PARAM_VO, ++ HW_VAR_AC_PARAM_VI, ++ HW_VAR_AC_PARAM_BE, ++ HW_VAR_AC_PARAM_BK, ++ HW_VAR_ACM_CTRL, ++ HW_VAR_AMPDU_MIN_SPACE, ++ HW_VAR_AMPDU_FACTOR, ++ HW_VAR_RXDMA_AGG_PG_TH, ++ HW_VAR_SET_RPWM, ++ HW_VAR_H2C_FW_PWRMODE, ++ HW_VAR_H2C_FW_JOINBSSRPT, ++ HW_VAR_FWLPS_RF_ON, ++ HW_VAR_H2C_FW_P2P_PS_OFFLOAD, ++ HW_VAR_TDLS_WRCR, ++ HW_VAR_TDLS_INIT_CH_SEN, ++ HW_VAR_TDLS_RS_RCR, ++ HW_VAR_TDLS_DONE_CH_SEN, ++ HW_VAR_INITIAL_GAIN, ++ HW_VAR_TRIGGER_GPIO_0, ++ HW_VAR_BT_SET_COEXIST, ++ HW_VAR_BT_ISSUE_DELBA, ++ HW_VAR_CURRENT_ANTENNA, ++ HW_VAR_ANTENNA_DIVERSITY_LINK, ++ HW_VAR_ANTENNA_DIVERSITY_SELECT, ++ HW_VAR_SWITCH_EPHY_WoWLAN, ++ HW_VAR_EFUSE_USAGE, ++ HW_VAR_EFUSE_BYTES, ++ HW_VAR_EFUSE_BT_USAGE, ++ HW_VAR_EFUSE_BT_BYTES, ++ HW_VAR_FIFO_CLEARN_UP, ++ HW_VAR_CHECK_TXBUF, ++ HW_VAR_APFM_ON_MAC, /* Auto FSM to Turn On, include clock, isolation, ++ * power control for MAC only */ ++ /* The valid upper nav range for the HW updating, if the true value is ++ * larger than the upper range, the HW won't update it. */ ++ /* Unit in microsecond. 0 means disable this function. */ ++ HW_VAR_NAV_UPPER, ++ HW_VAR_RPT_TIMER_SETTING, ++ HW_VAR_TX_RPT_MAX_MACID, ++ HW_VAR_H2C_MEDIA_STATUS_RPT, ++ HW_VAR_CHK_HI_QUEUE_EMPTY, ++}; ++ ++enum hal_def_variable { ++ HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, ++ HAL_DEF_IS_SUPPORT_ANT_DIV, ++ HAL_DEF_CURRENT_ANTENNA, ++ HAL_DEF_DRVINFO_SZ, ++ HAL_DEF_MAX_RECVBUF_SZ, ++ HAL_DEF_RX_PACKET_OFFSET, ++ HAL_DEF_DBG_DUMP_RXPKT,/* for dbg */ ++ HAL_DEF_DBG_DM_FUNC,/* for dbg */ ++ HAL_DEF_RA_DECISION_RATE, ++ HAL_DEF_RA_SGI, ++ HAL_DEF_PT_PWR_STATUS, ++ HW_VAR_MAX_RX_AMPDU_FACTOR, ++ HW_DEF_RA_INFO_DUMP, ++ HAL_DEF_DBG_DUMP_TXPKT, ++}; ++ ++enum hal_odm_variable { ++ HAL_ODM_STA_INFO, ++ HAL_ODM_P2P_STATE, ++ HAL_ODM_WIFI_DISPLAY_STATE, ++}; ++ ++enum hal_intf_ps_func { ++ HAL_USB_SELECT_SUSPEND, ++ HAL_MAX_ID, ++}; ++ ++typedef s32 (*c2h_id_filter)(u8 id); ++ ++struct hal_ops { ++ u32 (*hal_power_on)(struct adapter *padapter); ++ u32 (*hal_init)(struct adapter *padapter); ++ u32 (*hal_deinit)(struct adapter *padapter); ++ ++ void (*free_hal_data)(struct adapter *padapter); ++ ++ u32 (*inirp_init)(struct adapter *padapter); ++ u32 (*inirp_deinit)(struct adapter *padapter); ++ ++ s32 (*init_xmit_priv)(struct adapter *padapter); ++ ++ s32 (*init_recv_priv)(struct adapter *padapter); ++ void (*free_recv_priv)(struct adapter *padapter); ++ ++ void (*InitSwLeds)(struct adapter *padapter); ++ void (*DeInitSwLeds)(struct adapter *padapter); ++ ++ void (*dm_init)(struct adapter *padapter); ++ void (*dm_deinit)(struct adapter *padapter); ++ void (*read_chip_version)(struct adapter *padapter); ++ ++ void (*init_default_value)(struct adapter *padapter); ++ ++ void (*intf_chip_configure)(struct adapter *padapter); ++ ++ void (*read_adapter_info)(struct adapter *padapter); ++ ++ void (*enable_interrupt)(struct adapter *padapter); ++ void (*disable_interrupt)(struct adapter *padapter); ++ s32 (*interrupt_handler)(struct adapter *padapter); ++ ++ void (*set_bwmode_handler)(struct adapter *padapter, ++ enum ht_channel_width Bandwidth, ++ u8 Offset); ++ void (*set_channel_handler)(struct adapter *padapter, u8 channel); ++ ++ void (*hal_dm_watchdog)(struct adapter *padapter); ++ ++ void (*SetHwRegHandler)(struct adapter *padapter, u8 variable, ++ u8 *val); ++ void (*GetHwRegHandler)(struct adapter *padapter, u8 variable, ++ u8 *val); ++ ++ u8 (*GetHalDefVarHandler)(struct adapter *padapter, ++ enum hal_def_variable eVariable, ++ void *pValue); ++ u8 (*SetHalDefVarHandler)(struct adapter *padapter, ++ enum hal_def_variable eVariable, ++ void *pValue); ++ ++ void (*GetHalODMVarHandler)(struct adapter *padapter, ++ enum hal_odm_variable eVariable, ++ void *pValue1, bool bSet); ++ void (*SetHalODMVarHandler)(struct adapter *padapter, ++ enum hal_odm_variable eVariable, ++ void *pValue1, bool bSet); ++ ++ void (*UpdateRAMaskHandler)(struct adapter *padapter, ++ u32 mac_id, u8 rssi_level); ++ void (*SetBeaconRelatedRegistersHandler)(struct adapter *padapter); ++ ++ void (*Add_RateATid)(struct adapter *adapter, u32 bitmap, u8 arg, ++ u8 rssi_level); ++ void (*run_thread)(struct adapter *adapter); ++ void (*cancel_thread)(struct adapter *adapter); ++ ++ u8 (*AntDivBeforeLinkHandler)(struct adapter *adapter); ++ void (*AntDivCompareHandler)(struct adapter *adapter, ++ struct wlan_bssid_ex *dst, ++ struct wlan_bssid_ex *src); ++ u8 (*interface_ps_func)(struct adapter *padapter, ++ enum hal_intf_ps_func efunc_id, u8 *val); ++ ++ s32 (*hal_xmit)(struct adapter *padapter, ++ struct xmit_frame *pxmitframe); ++ s32 (*mgnt_xmit)(struct adapter *padapter, ++ struct xmit_frame *pmgntframe); ++ s32 (*hal_xmitframe_enqueue)(struct adapter *padapter, ++ struct xmit_frame *pxmitframe); ++ ++ u32 (*read_bbreg)(struct adapter *padapter, u32 RegAddr, ++ u32 BitMask); ++ void (*write_bbreg)(struct adapter *padapter, u32 RegAddr, ++ u32 BitMask, u32 Data); ++ u32 (*read_rfreg)(struct adapter *padapter, ++ enum rf_radio_path eRFPath, u32 RegAddr, ++ u32 BitMask); ++ void (*write_rfreg)(struct adapter *padapter, ++ enum rf_radio_path eRFPath, u32 RegAddr, ++ u32 BitMask, u32 Data); ++ ++ void (*EfusePowerSwitch)(struct adapter *padapter, u8 bWrite, ++ u8 PwrState); ++ void (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset, ++ u16 _size_byte, u8 *pbuf, bool bPseudoTest); ++ void (*EFUSEGetEfuseDefinition)(struct adapter *padapter, u8 efuseType, ++ u8 type, void *pOut, bool bPseudoTest); ++ u16 (*EfuseGetCurrentSize)(struct adapter *padapter, u8 efuseType, ++ bool bPseudoTest); ++ int (*Efuse_PgPacketRead)(struct adapter *adapter, u8 offset, ++ u8 *data, bool bPseudoTest); ++ int (*Efuse_PgPacketWrite)(struct adapter *padapter, u8 offset, ++ u8 word_en, u8 *data, bool bPseudoTest); ++ u8 (*Efuse_WordEnableDataWrite)(struct adapter *padapter, ++ u16 efuse_addr, u8 word_en, ++ u8 *data, bool bPseudoTest); ++ bool (*Efuse_PgPacketWrite_BT)(struct adapter *padapter, u8 offset, ++ u8 word_en, u8 *data, bool test); ++ ++ void (*sreset_init_value)(struct adapter *padapter); ++ void (*sreset_reset_value)(struct adapter *padapter); ++ void (*silentreset)(struct adapter *padapter); ++ void (*sreset_xmit_status_check)(struct adapter *padapter); ++ void (*sreset_linked_status_check) (struct adapter *padapter); ++ u8 (*sreset_get_wifi_status)(struct adapter *padapter); ++ ++ int (*IOL_exec_cmds_sync)(struct adapter *padapter, ++ struct xmit_frame *frame, u32 max_wait, ++ u32 bndy_cnt); ++ ++ void (*hal_notch_filter)(struct adapter *adapter, bool enable); ++ void (*hal_reset_security_engine)(struct adapter *adapter); ++ s32 (*c2h_handler)(struct adapter *padapter, ++ struct c2h_evt_hdr *c2h_evt); ++ c2h_id_filter c2h_id_filter_ccx; ++}; ++ ++enum rt_eeprom_type { ++ EEPROM_93C46, ++ EEPROM_93C56, ++ EEPROM_BOOT_EFUSE, ++}; ++ ++#define RF_CHANGE_BY_INIT 0 ++#define RF_CHANGE_BY_IPS BIT(28) ++#define RF_CHANGE_BY_PS BIT(29) ++#define RF_CHANGE_BY_HW BIT(30) ++#define RF_CHANGE_BY_SW BIT(31) ++ ++enum hardware_type { ++ HARDWARE_TYPE_RTL8180, ++ HARDWARE_TYPE_RTL8185, ++ HARDWARE_TYPE_RTL8187, ++ HARDWARE_TYPE_RTL8188, ++ HARDWARE_TYPE_RTL8190P, ++ HARDWARE_TYPE_RTL8192E, ++ HARDWARE_TYPE_RTL819xU, ++ HARDWARE_TYPE_RTL8192SE, ++ HARDWARE_TYPE_RTL8192SU, ++ HARDWARE_TYPE_RTL8192CE, ++ HARDWARE_TYPE_RTL8192CU, ++ HARDWARE_TYPE_RTL8192DE, ++ HARDWARE_TYPE_RTL8192DU, ++ HARDWARE_TYPE_RTL8723AE, ++ HARDWARE_TYPE_RTL8723AU, ++ HARDWARE_TYPE_RTL8723AS, ++ HARDWARE_TYPE_RTL8188EE, ++ HARDWARE_TYPE_RTL8188EU, ++ HARDWARE_TYPE_RTL8188ES, ++ HARDWARE_TYPE_MAX, ++}; ++ ++/* RTL8188E Series */ ++#define IS_HARDWARE_TYPE_8188EE(_Adapter) \ ++(((struct adapter *)_Adapter)->HardwareType == HARDWARE_TYPE_RTL8188EE) ++#define IS_HARDWARE_TYPE_8188EU(_Adapter) \ ++(((struct adapter *)_Adapter)->HardwareType == HARDWARE_TYPE_RTL8188EU) ++#define IS_HARDWARE_TYPE_8188ES(_Adapter) \ ++(((struct adapter *)_Adapter)->HardwareType == HARDWARE_TYPE_RTL8188ES) ++#define IS_HARDWARE_TYPE_8188E(_Adapter) \ ++(IS_HARDWARE_TYPE_8188EE(_Adapter) || IS_HARDWARE_TYPE_8188EU(_Adapter) || \ ++ IS_HARDWARE_TYPE_8188ES(_Adapter)) ++ ++#define GET_EEPROM_EFUSE_PRIV(adapter) (&adapter->eeprompriv) ++ ++#define is_boot_from_eeprom(adapter) (adapter->eeprompriv.EepromOrEfuse) ++ ++void rtl8188eu_set_hal_ops(struct adapter *padapter); ++void rtw_hal_def_value_init(struct adapter *padapter); ++ ++void rtw_hal_free_data(struct adapter *padapter); ++ ++void rtw_hal_dm_init(struct adapter *padapter); ++void rtw_hal_dm_deinit(struct adapter *padapter); ++void rtw_hal_sw_led_init(struct adapter *padapter); ++void rtw_hal_sw_led_deinit(struct adapter *padapter); ++ ++u32 rtw_hal_power_on(struct adapter *padapter); ++uint rtw_hal_init(struct adapter *padapter); ++uint rtw_hal_deinit(struct adapter *padapter); ++void rtw_hal_stop(struct adapter *padapter); ++void rtw_hal_set_hwreg(struct adapter *padapter, u8 variable, u8 *val); ++void rtw_hal_get_hwreg(struct adapter *padapter, u8 variable, u8 *val); ++ ++void rtw_hal_chip_configure(struct adapter *padapter); ++void rtw_hal_read_chip_info(struct adapter *padapter); ++void rtw_hal_read_chip_version(struct adapter *padapter); ++ ++u8 rtw_hal_set_def_var(struct adapter *padapter, ++ enum hal_def_variable eVariable, void *pValue); ++u8 rtw_hal_get_def_var(struct adapter *padapter, ++ enum hal_def_variable eVariable, void *pValue); ++ ++void rtw_hal_set_odm_var(struct adapter *padapter, ++ enum hal_odm_variable eVariable, void *pValue1, ++ bool bSet); ++void rtw_hal_get_odm_var(struct adapter *padapter, ++ enum hal_odm_variable eVariable, ++ void *pValue1, bool bSet); ++ ++void rtw_hal_enable_interrupt(struct adapter *padapter); ++void rtw_hal_disable_interrupt(struct adapter *padapter); ++ ++u32 rtw_hal_inirp_init(struct adapter *padapter); ++u32 rtw_hal_inirp_deinit(struct adapter *padapter); ++ ++u8 rtw_hal_intf_ps_func(struct adapter *padapter, ++ enum hal_intf_ps_func efunc_id, u8 *val); ++s32 rtw_hal_xmitframe_enqueue(struct adapter *padapter, ++ struct xmit_frame *pxmitframe); ++ ++s32 rtw_hal_xmit(struct adapter *padapter, struct xmit_frame *pxmitframe); ++s32 rtw_hal_mgnt_xmit(struct adapter *padapter, ++ struct xmit_frame *pmgntframe); ++ ++s32 rtw_hal_init_xmit_priv(struct adapter *padapter); ++ ++s32 rtw_hal_init_recv_priv(struct adapter *padapter); ++void rtw_hal_free_recv_priv(struct adapter *padapter); ++ ++void rtw_hal_update_ra_mask(struct adapter *padapter, u32 mac_id, u8 level); ++void rtw_hal_add_ra_tid(struct adapter *adapt, u32 bitmap, u8 arg, u8 level); ++void rtw_hal_clone_data(struct adapter *dst_adapt, ++ struct adapter *src_adapt); ++void rtw_hal_start_thread(struct adapter *padapter); ++void rtw_hal_stop_thread(struct adapter *padapter); ++ ++void rtw_hal_bcn_related_reg_setting(struct adapter *padapter); ++ ++u32 rtw_hal_read_bbreg(struct adapter *padapter, u32 RegAddr, u32 BitMask); ++void rtw_hal_write_bbreg(struct adapter *padapter, u32 RegAddr, u32 BitMask, ++ u32 Data); ++u32 rtw_hal_read_rfreg(struct adapter *padapter, enum rf_radio_path eRFPath, ++ u32 RegAddr, u32 BitMask); ++void rtw_hal_write_rfreg(struct adapter *padapter, ++ enum rf_radio_path eRFPath, u32 RegAddr, ++ u32 BitMask, u32 Data); ++ ++s32 rtw_hal_interrupt_handler(struct adapter *padapter); ++ ++void rtw_hal_set_bwmode(struct adapter *padapter, ++ enum ht_channel_width Bandwidth, u8 Offset); ++void rtw_hal_set_chan(struct adapter *padapter, u8 channel); ++void rtw_hal_dm_watchdog(struct adapter *padapter); ++ ++u8 rtw_hal_antdiv_before_linked(struct adapter *padapter); ++void rtw_hal_antdiv_rssi_compared(struct adapter *padapter, ++ struct wlan_bssid_ex *dst, ++ struct wlan_bssid_ex *src); ++ ++void rtw_hal_sreset_init(struct adapter *padapter); ++void rtw_hal_sreset_reset(struct adapter *padapter); ++void rtw_hal_sreset_reset_value(struct adapter *padapter); ++void rtw_hal_sreset_xmit_status_check(struct adapter *padapter); ++void rtw_hal_sreset_linked_status_check(struct adapter *padapter); ++u8 rtw_hal_sreset_get_wifi_status(struct adapter *padapter); ++ ++int rtw_hal_iol_cmd(struct adapter *adapter, struct xmit_frame *xmit_frame, ++ u32 max_wating_ms, u32 bndy_cnt); ++ ++void rtw_hal_notch_filter(struct adapter *adapter, bool enable); ++void rtw_hal_reset_security_engine(struct adapter *adapter); ++ ++s32 rtw_hal_c2h_handler(struct adapter *adapter, ++ struct c2h_evt_hdr *c2h_evt); ++c2h_id_filter rtw_hal_c2h_id_filter_ccx(struct adapter *adapter); ++void indicate_wx_scan_complete_event(struct adapter *padapter); ++u8 rtw_do_join(struct adapter *padapter); ++ ++#endif /* __HAL_INTF_H__ */ +diff --git a/drivers/staging/r8188eu/include/ieee80211.h b/drivers/staging/r8188eu/include/ieee80211.h +new file mode 100644 +index 000000000000..bc5b030e9c40 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/ieee80211.h +@@ -0,0 +1,1226 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __IEEE80211_H ++#define __IEEE80211_H ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "wifi.h" ++#include ++ ++#define MGMT_QUEUE_NUM 5 ++ ++#define ETH_ALEN 6 ++#define ETH_TYPE_LEN 2 ++#define PAYLOAD_TYPE_LEN 1 ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++#define RTL_IOCTL_HOSTAPD (SIOCIWFIRSTPRIV + 28) ++ ++/* RTL871X_IOCTL_HOSTAPD ioctl() cmd: */ ++enum { ++ RTL871X_HOSTAPD_FLUSH = 1, ++ RTL871X_HOSTAPD_ADD_STA = 2, ++ RTL871X_HOSTAPD_REMOVE_STA = 3, ++ RTL871X_HOSTAPD_GET_INFO_STA = 4, ++ /* REMOVED: PRISM2_HOSTAPD_RESET_TXEXC_STA = 5, */ ++ RTL871X_HOSTAPD_GET_WPAIE_STA = 5, ++ RTL871X_SET_ENCRYPTION = 6, ++ RTL871X_GET_ENCRYPTION = 7, ++ RTL871X_HOSTAPD_SET_FLAGS_STA = 8, ++ RTL871X_HOSTAPD_GET_RID = 9, ++ RTL871X_HOSTAPD_SET_RID = 10, ++ RTL871X_HOSTAPD_SET_ASSOC_AP_ADDR = 11, ++ RTL871X_HOSTAPD_SET_GENERIC_ELEMENT = 12, ++ RTL871X_HOSTAPD_MLME = 13, ++ RTL871X_HOSTAPD_SCAN_REQ = 14, ++ RTL871X_HOSTAPD_STA_CLEAR_STATS = 15, ++ RTL871X_HOSTAPD_SET_BEACON = 16, ++ RTL871X_HOSTAPD_SET_WPS_BEACON = 17, ++ RTL871X_HOSTAPD_SET_WPS_PROBE_RESP = 18, ++ RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP = 19, ++ RTL871X_HOSTAPD_SET_HIDDEN_SSID = 20, ++ RTL871X_HOSTAPD_SET_MACADDR_ACL = 21, ++ RTL871X_HOSTAPD_ACL_ADD_STA = 22, ++ RTL871X_HOSTAPD_ACL_REMOVE_STA = 23, ++}; ++ ++/* STA flags */ ++#define WLAN_STA_AUTH BIT(0) ++#define WLAN_STA_ASSOC BIT(1) ++#define WLAN_STA_PS BIT(2) ++#define WLAN_STA_TIM BIT(3) ++#define WLAN_STA_PERM BIT(4) ++#define WLAN_STA_AUTHORIZED BIT(5) ++#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */ ++#define WLAN_STA_SHORT_PREAMBLE BIT(7) ++#define WLAN_STA_PREAUTH BIT(8) ++#define WLAN_STA_WME BIT(9) ++#define WLAN_STA_MFP BIT(10) ++#define WLAN_STA_HT BIT(11) ++#define WLAN_STA_WPS BIT(12) ++#define WLAN_STA_MAYBE_WPS BIT(13) ++#define WLAN_STA_NONERP BIT(31) ++ ++#endif ++ ++#define IEEE_CMD_SET_WPA_PARAM 1 ++#define IEEE_CMD_SET_WPA_IE 2 ++#define IEEE_CMD_SET_ENCRYPTION 3 ++#define IEEE_CMD_MLME 4 ++ ++#define IEEE_PARAM_WPA_ENABLED 1 ++#define IEEE_PARAM_TKIP_COUNTERMEASURES 2 ++#define IEEE_PARAM_DROP_UNENCRYPTED 3 ++#define IEEE_PARAM_PRIVACY_INVOKED 4 ++#define IEEE_PARAM_AUTH_ALGS 5 ++#define IEEE_PARAM_IEEE_802_1X 6 ++#define IEEE_PARAM_WPAX_SELECT 7 ++ ++#define AUTH_ALG_OPEN_SYSTEM 0x1 ++#define AUTH_ALG_SHARED_KEY 0x2 ++#define AUTH_ALG_LEAP 0x00000004 ++ ++#define IEEE_MLME_STA_DEAUTH 1 ++#define IEEE_MLME_STA_DISASSOC 2 ++ ++#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2 ++#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3 ++#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4 ++#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5 ++#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6 ++#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7 ++ ++#define IEEE_CRYPT_ALG_NAME_LEN 16 ++ ++#define WPA_CIPHER_NONE BIT(0) ++#define WPA_CIPHER_WEP40 BIT(1) ++#define WPA_CIPHER_WEP104 BIT(2) ++#define WPA_CIPHER_TKIP BIT(3) ++#define WPA_CIPHER_CCMP BIT(4) ++ ++ ++#define WPA_SELECTOR_LEN 4 ++extern u8 RTW_WPA_OUI_TYPE[]; ++extern u16 RTW_WPA_VERSION; ++extern u8 WPA_AUTH_KEY_MGMT_NONE[]; ++extern u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[]; ++extern u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[]; ++extern u8 WPA_CIPHER_SUITE_NONE[]; ++extern u8 WPA_CIPHER_SUITE_WEP40[]; ++extern u8 WPA_CIPHER_SUITE_TKIP[]; ++extern u8 WPA_CIPHER_SUITE_WRAP[]; ++extern u8 WPA_CIPHER_SUITE_CCMP[]; ++extern u8 WPA_CIPHER_SUITE_WEP104[]; ++ ++#define RSN_HEADER_LEN 4 ++#define RSN_SELECTOR_LEN 4 ++ ++extern u16 RSN_VERSION_BSD; ++extern u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[]; ++extern u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[]; ++extern u8 RSN_CIPHER_SUITE_NONE[]; ++extern u8 RSN_CIPHER_SUITE_WEP40[]; ++extern u8 RSN_CIPHER_SUITE_TKIP[]; ++extern u8 RSN_CIPHER_SUITE_WRAP[]; ++extern u8 RSN_CIPHER_SUITE_CCMP[]; ++extern u8 RSN_CIPHER_SUITE_WEP104[]; ++ ++enum ratr_table_mode { ++ RATR_INX_WIRELESS_NGB = 0, /* BGN 40 Mhz 2SS 1SS */ ++ RATR_INX_WIRELESS_NG = 1, /* GN or N */ ++ RATR_INX_WIRELESS_NB = 2, /* BGN 20 Mhz 2SS 1SS or BN */ ++ RATR_INX_WIRELESS_N = 3, ++ RATR_INX_WIRELESS_GB = 4, ++ RATR_INX_WIRELESS_G = 5, ++ RATR_INX_WIRELESS_B = 6, ++ RATR_INX_WIRELESS_MC = 7, ++ RATR_INX_WIRELESS_AC_N = 8, ++}; ++ ++enum NETWORK_TYPE { ++ WIRELESS_INVALID = 0, ++ /* Sub-Element */ ++ WIRELESS_11B = BIT(0), /* tx:cck only, rx:cck only, hw: cck */ ++ WIRELESS_11G = BIT(1), /* tx:ofdm only, rx:ofdm & cck, hw:cck & ofdm*/ ++ WIRELESS_11_24N = BIT(3), /* tx:MCS only, rx:MCS & cck, hw:MCS & cck */ ++ ++ /* Combination */ ++ /* tx: cck & ofdm, rx: cck & ofdm & MCS, hw: cck & ofdm */ ++ WIRELESS_11BG = (WIRELESS_11B | WIRELESS_11G), ++ /* tx: ofdm & MCS, rx: ofdm & cck & MCS, hw: cck & ofdm */ ++ WIRELESS_11G_24N = (WIRELESS_11G | WIRELESS_11_24N), ++ /* tx: ofdm & cck & MCS, rx: ofdm & cck & MCS, hw: ofdm & cck */ ++ WIRELESS_11BG_24N = (WIRELESS_11B | WIRELESS_11G | WIRELESS_11_24N), ++}; ++ ++#define SUPPORTED_24G_NETTYPE_MSK \ ++ (WIRELESS_11B | WIRELESS_11G | WIRELESS_11_24N) ++ ++#define IsSupported24G(NetType) \ ++ ((NetType) & SUPPORTED_24G_NETTYPE_MSK ? true : false) ++ ++#define IsEnableHWCCK(NetType) \ ++ IsSupported24G(NetType) ++ ++#define IsSupportedRxCCK(NetType) IsEnableHWCCK(NetType) ++ ++#define IsSupportedTxCCK(NetType) \ ++ ((NetType) & (WIRELESS_11B) ? true : false) ++#define IsSupportedTxOFDM(NetType) \ ++ ((NetType) & (WIRELESS_11G) ? true : false) ++#define IsSupportedTxMCS(NetType) \ ++ ((NetType) & (WIRELESS_11_24N) ? true : false) ++ ++struct ieee_param { ++ u32 cmd; ++ u8 sta_addr[ETH_ALEN]; ++ union { ++ struct { ++ u8 name; ++ u32 value; ++ } wpa_param; ++ struct { ++ u32 len; ++ u8 reserved[32]; ++ u8 data[0]; ++ } wpa_ie; ++ struct { ++ int command; ++ int reason_code; ++ } mlme; ++ struct { ++ u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; ++ u8 set_tx; ++ u32 err; ++ u8 idx; ++ u8 seq[8]; /* sequence counter (set: RX, get: TX) */ ++ u16 key_len; ++ u8 key[0]; ++ } crypt; ++#ifdef CONFIG_88EU_AP_MODE ++ struct { ++ u16 aid; ++ u16 capability; ++ int flags; ++ u8 tx_supp_rates[16]; ++ struct ieee80211_ht_cap ht_cap; ++ } add_sta; ++ struct { ++ u8 reserved[2];/* for set max_num_sta */ ++ u8 buf[0]; ++ } bcn_ie; ++#endif ++ ++ } u; ++}; ++ ++#ifdef CONFIG_88EU_AP_MODE ++struct ieee_param_ex { ++ u32 cmd; ++ u8 sta_addr[ETH_ALEN]; ++ u8 data[0]; ++}; ++ ++struct sta_data { ++ u16 aid; ++ u16 capability; ++ int flags; ++ u32 sta_set; ++ u8 tx_supp_rates[16]; ++ u32 tx_supp_rates_len; ++ struct ieee80211_ht_cap ht_cap; ++ u64 rx_pkts; ++ u64 rx_bytes; ++ u64 rx_drops; ++ u64 tx_pkts; ++ u64 tx_bytes; ++ u64 tx_drops; ++}; ++#endif ++ ++#define IEEE80211_DATA_LEN 2304 ++/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section ++ 6.2.1.1.2. ++ ++ The figure in section 7.1.2 suggests a body size of up to 2312 ++ bytes is allowed, which is a bit confusing, I suspect this ++ represents the 2304 bytes of real data, plus a possible 8 bytes of ++ WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ ++ ++#define IEEE80211_HLEN 30 ++#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) ++ ++/* this is stolen from ipw2200 driver */ ++#define IEEE_IBSS_MAC_HASH_SIZE 31 ++ ++struct ieee_ibss_seq { ++ u8 mac[ETH_ALEN]; ++ u16 seq_num; ++ u16 frag_num; ++ unsigned long packet_time; ++ struct list_head list; ++}; ++ ++struct rtw_ieee80211_hdr { ++ __le16 frame_ctl; ++ __le16 duration_id; ++ u8 addr1[ETH_ALEN]; ++ u8 addr2[ETH_ALEN]; ++ u8 addr3[ETH_ALEN]; ++ u16 seq_ctl; ++ u8 addr4[ETH_ALEN]; ++} __packed; ++ ++struct rtw_ieee80211_hdr_3addr { ++ __le16 frame_ctl; ++ __le16 duration_id; ++ u8 addr1[ETH_ALEN]; ++ u8 addr2[ETH_ALEN]; ++ u8 addr3[ETH_ALEN]; ++ u16 seq_ctl; ++} __packed; ++ ++struct rtw_ieee80211_hdr_qos { ++ __le16 frame_ctl; ++ __le16 duration_id; ++ u8 addr1[ETH_ALEN]; ++ u8 addr2[ETH_ALEN]; ++ u8 addr3[ETH_ALEN]; ++ u16 seq_ctl; ++ u8 addr4[ETH_ALEN]; ++ u16 qc; ++} __packed; ++ ++struct rtw_ieee80211_hdr_3addr_qos { ++ __le16 frame_ctl; ++ __le16 duration_id; ++ u8 addr1[ETH_ALEN]; ++ u8 addr2[ETH_ALEN]; ++ u8 addr3[ETH_ALEN]; ++ u16 seq_ctl; ++ u16 qc; ++} __packed; ++ ++struct eapol { ++ u8 snap[6]; ++ u16 ethertype; ++ u8 version; ++ u8 type; ++ u16 length; ++} __packed; ++ ++enum eap_type { ++ EAP_PACKET = 0, ++ EAPOL_START, ++ EAPOL_LOGOFF, ++ EAPOL_KEY, ++ EAPOL_ENCAP_ASF_ALERT ++}; ++ ++#define IEEE80211_3ADDR_LEN 24 ++#define IEEE80211_4ADDR_LEN 30 ++#define IEEE80211_FCS_LEN 4 ++ ++#define MIN_FRAG_THRESHOLD 256U ++#define MAX_FRAG_THRESHOLD 2346U ++ ++/* Frame control field constants */ ++#define RTW_IEEE80211_FCTL_VERS 0x0003 ++#define RTW_IEEE80211_FCTL_FTYPE 0x000c ++#define RTW_IEEE80211_FCTL_STYPE 0x00f0 ++#define RTW_IEEE80211_FCTL_TODS 0x0100 ++#define RTW_IEEE80211_FCTL_FROMDS 0x0200 ++#define RTW_IEEE80211_FCTL_MOREFRAGS 0x0400 ++#define RTW_IEEE80211_FCTL_RETRY 0x0800 ++#define RTW_IEEE80211_FCTL_PM 0x1000 ++#define RTW_IEEE80211_FCTL_MOREDATA 0x2000 ++#define RTW_IEEE80211_FCTL_PROTECTED 0x4000 ++#define RTW_IEEE80211_FCTL_ORDER 0x8000 ++#define RTW_IEEE80211_FCTL_CTL_EXT 0x0f00 ++ ++#define RTW_IEEE80211_FTYPE_MGMT 0x0000 ++#define RTW_IEEE80211_FTYPE_CTL 0x0004 ++#define RTW_IEEE80211_FTYPE_DATA 0x0008 ++#define RTW_IEEE80211_FTYPE_EXT 0x000c ++ ++/* management */ ++#define RTW_IEEE80211_STYPE_ASSOC_REQ 0x0000 ++#define RTW_IEEE80211_STYPE_ASSOC_RESP 0x0010 ++#define RTW_IEEE80211_STYPE_REASSOC_REQ 0x0020 ++#define RTW_IEEE80211_STYPE_REASSOC_RESP 0x0030 ++#define RTW_IEEE80211_STYPE_PROBE_REQ 0x0040 ++#define RTW_IEEE80211_STYPE_PROBE_RESP 0x0050 ++#define RTW_IEEE80211_STYPE_BEACON 0x0080 ++#define RTW_IEEE80211_STYPE_ATIM 0x0090 ++#define RTW_IEEE80211_STYPE_DISASSOC 0x00A0 ++#define RTW_IEEE80211_STYPE_AUTH 0x00B0 ++#define RTW_IEEE80211_STYPE_DEAUTH 0x00C0 ++#define RTW_IEEE80211_STYPE_ACTION 0x00D0 ++ ++/* control */ ++#define RTW_IEEE80211_STYPE_CTL_EXT 0x0060 ++#define RTW_IEEE80211_STYPE_BACK_REQ 0x0080 ++#define RTW_IEEE80211_STYPE_BACK 0x0090 ++#define RTW_IEEE80211_STYPE_PSPOLL 0x00A0 ++#define RTW_IEEE80211_STYPE_RTS 0x00B0 ++#define RTW_IEEE80211_STYPE_CTS 0x00C0 ++#define RTW_IEEE80211_STYPE_ACK 0x00D0 ++#define RTW_IEEE80211_STYPE_CFEND 0x00E0 ++#define RTW_IEEE80211_STYPE_CFENDACK 0x00F0 ++ ++/* data */ ++#define RTW_IEEE80211_STYPE_DATA 0x0000 ++#define RTW_IEEE80211_STYPE_DATA_CFACK 0x0010 ++#define RTW_IEEE80211_STYPE_DATA_CFPOLL 0x0020 ++#define RTW_IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 ++#define RTW_IEEE80211_STYPE_NULLFUNC 0x0040 ++#define RTW_IEEE80211_STYPE_CFACK 0x0050 ++#define RTW_IEEE80211_STYPE_CFPOLL 0x0060 ++#define RTW_IEEE80211_STYPE_CFACKPOLL 0x0070 ++#define RTW_IEEE80211_STYPE_QOS_DATA 0x0080 ++#define RTW_IEEE80211_STYPE_QOS_DATA_CFACK 0x0090 ++#define RTW_IEEE80211_STYPE_QOS_DATA_CFPOLL 0x00A0 ++#define RTW_IEEE80211_STYPE_QOS_DATA_CFACKPOLL 0x00B0 ++#define RTW_IEEE80211_STYPE_QOS_NULLFUNC 0x00C0 ++#define RTW_IEEE80211_STYPE_QOS_CFACK 0x00D0 ++#define RTW_IEEE80211_STYPE_QOS_CFPOLL 0x00E0 ++#define RTW_IEEE80211_STYPE_QOS_CFACKPOLL 0x00F0 ++ ++/* sequence control field */ ++#define RTW_IEEE80211_SCTL_FRAG 0x000F ++#define RTW_IEEE80211_SCTL_SEQ 0xFFF0 ++ ++#define RTW_ERP_INFO_NON_ERP_PRESENT BIT(0) ++#define RTW_ERP_INFO_USE_PROTECTION BIT(1) ++#define RTW_ERP_INFO_BARKER_PREAMBLE_MODE BIT(2) ++ ++/* QoS, QOS */ ++#define NORMAL_ACK 0 ++#define NO_ACK 1 ++#define NON_EXPLICIT_ACK 2 ++#define BLOCK_ACK 3 ++ ++#ifndef ETH_P_PAE ++#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ ++#endif /* ETH_P_PAE */ ++ ++#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ ++ ++#define ETH_P_ECONET 0x0018 ++ ++#ifndef ETH_P_80211_RAW ++#define ETH_P_80211_RAW (ETH_P_ECONET + 1) ++#endif ++ ++/* IEEE 802.11 defines */ ++ ++#define P80211_OUI_LEN 3 ++ ++struct ieee80211_snap_hdr { ++ u8 dsap; /* always 0xAA */ ++ u8 ssap; /* always 0xAA */ ++ u8 ctrl; /* always 0x03 */ ++ u8 oui[P80211_OUI_LEN]; /* organizational universal id */ ++} __packed; ++ ++#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) ++ ++#define WLAN_FC_GET_TYPE(fc) ((fc) & RTW_IEEE80211_FCTL_FTYPE) ++#define WLAN_FC_GET_STYPE(fc) ((fc) & RTW_IEEE80211_FCTL_STYPE) ++ ++#define WLAN_QC_GET_TID(qc) ((qc) & 0x0f) ++ ++#define WLAN_GET_SEQ_FRAG(seq) ((seq) & RTW_IEEE80211_SCTL_FRAG) ++#define WLAN_GET_SEQ_SEQ(seq) ((seq) & RTW_IEEE80211_SCTL_SEQ) ++ ++/* Authentication algorithms */ ++#define WLAN_AUTH_OPEN 0 ++#define WLAN_AUTH_SHARED_KEY 1 ++ ++#define WLAN_AUTH_CHALLENGE_LEN 128 ++ ++#define WLAN_CAPABILITY_BSS (1<<0) ++#define WLAN_CAPABILITY_IBSS (1<<1) ++#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) ++#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) ++#define WLAN_CAPABILITY_PRIVACY (1<<4) ++#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) ++#define WLAN_CAPABILITY_PBCC (1<<6) ++#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) ++#define WLAN_CAPABILITY_SHORT_SLOT (1<<10) ++ ++/* Status codes */ ++#define WLAN_STATUS_SUCCESS 0 ++#define WLAN_STATUS_UNSPECIFIED_FAILURE 1 ++#define WLAN_STATUS_CAPS_UNSUPPORTED 10 ++#define WLAN_STATUS_REASSOC_NO_ASSOC 11 ++#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 ++#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 ++#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 ++#define WLAN_STATUS_CHALLENGE_FAIL 15 ++#define WLAN_STATUS_AUTH_TIMEOUT 16 ++#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 ++#define WLAN_STATUS_ASSOC_DENIED_RATES 18 ++/* 802.11b */ ++#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 ++#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20 ++#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21 ++ ++/* Reason codes */ ++#define WLAN_REASON_UNSPECIFIED 1 ++#define WLAN_REASON_PREV_AUTH_NOT_VALID 2 ++#define WLAN_REASON_DEAUTH_LEAVING 3 ++#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 ++#define WLAN_REASON_DISASSOC_AP_BUSY 5 ++#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 ++#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 ++#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 ++#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 ++#define WLAN_REASON_JOIN_WRONG_CHANNEL 65534 ++#define WLAN_REASON_EXPIRATION_CHK 65535 ++ ++/* Information Element IDs */ ++#define WLAN_EID_SSID 0 ++#define WLAN_EID_SUPP_RATES 1 ++#define WLAN_EID_FH_PARAMS 2 ++#define WLAN_EID_DS_PARAMS 3 ++#define WLAN_EID_CF_PARAMS 4 ++#define WLAN_EID_TIM 5 ++#define WLAN_EID_IBSS_PARAMS 6 ++#define WLAN_EID_CHALLENGE 16 ++/* EIDs defined by IEEE 802.11h - START */ ++#define WLAN_EID_PWR_CONSTRAINT 32 ++#define WLAN_EID_PWR_CAPABILITY 33 ++#define WLAN_EID_TPC_REQUEST 34 ++#define WLAN_EID_TPC_REPORT 35 ++#define WLAN_EID_SUPPORTED_CHANNELS 36 ++#define WLAN_EID_CHANNEL_SWITCH 37 ++#define WLAN_EID_MEASURE_REQUEST 38 ++#define WLAN_EID_MEASURE_REPORT 39 ++#define WLAN_EID_QUITE 40 ++#define WLAN_EID_IBSS_DFS 41 ++/* EIDs defined by IEEE 802.11h - END */ ++#define WLAN_EID_ERP_INFO 42 ++#define WLAN_EID_HT_CAP 45 ++#define WLAN_EID_RSN 48 ++#define WLAN_EID_EXT_SUPP_RATES 50 ++#define WLAN_EID_MOBILITY_DOMAIN 54 ++#define WLAN_EID_FAST_BSS_TRANSITION 55 ++#define WLAN_EID_TIMEOUT_INTERVAL 56 ++#define WLAN_EID_RIC_DATA 57 ++#define WLAN_EID_HT_OPERATION 61 ++#define WLAN_EID_SECONDARY_CHANNEL_OFFSET 62 ++#define WLAN_EID_20_40_BSS_COEXISTENCE 72 ++#define WLAN_EID_20_40_BSS_INTOLERANT 73 ++#define WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS 74 ++#define WLAN_EID_MMIE 76 ++#define WLAN_EID_VENDOR_SPECIFIC 221 ++#define WLAN_EID_GENERIC (WLAN_EID_VENDOR_SPECIFIC) ++ ++#define IEEE80211_MGMT_HDR_LEN 24 ++#define IEEE80211_DATA_HDR3_LEN 24 ++#define IEEE80211_DATA_HDR4_LEN 30 ++ ++#define IEEE80211_STATMASK_SIGNAL (1<<0) ++#define IEEE80211_STATMASK_RSSI (1<<1) ++#define IEEE80211_STATMASK_NOISE (1<<2) ++#define IEEE80211_STATMASK_RATE (1<<3) ++#define IEEE80211_STATMASK_WEMASK 0x7 ++ ++#define IEEE80211_CCK_MODULATION (1<<0) ++#define IEEE80211_OFDM_MODULATION (1<<1) ++ ++#define IEEE80211_24GHZ_BAND (1<<0) ++#define IEEE80211_52GHZ_BAND (1<<1) ++ ++#define IEEE80211_CCK_RATE_LEN 4 ++#define IEEE80211_NUM_OFDM_RATESLEN 8 ++ ++#define IEEE80211_CCK_RATE_1MB 0x02 ++#define IEEE80211_CCK_RATE_2MB 0x04 ++#define IEEE80211_CCK_RATE_5MB 0x0B ++#define IEEE80211_CCK_RATE_11MB 0x16 ++#define IEEE80211_OFDM_RATE_LEN 8 ++#define IEEE80211_OFDM_RATE_6MB 0x0C ++#define IEEE80211_OFDM_RATE_9MB 0x12 ++#define IEEE80211_OFDM_RATE_12MB 0x18 ++#define IEEE80211_OFDM_RATE_18MB 0x24 ++#define IEEE80211_OFDM_RATE_24MB 0x30 ++#define IEEE80211_OFDM_RATE_36MB 0x48 ++#define IEEE80211_OFDM_RATE_48MB 0x60 ++#define IEEE80211_OFDM_RATE_54MB 0x6C ++#define IEEE80211_BASIC_RATE_MASK 0x80 ++ ++#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) ++#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) ++#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) ++#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) ++#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) ++#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) ++#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) ++#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) ++#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) ++#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) ++#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) ++#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) ++ ++#define IEEE80211_CCK_RATES_MASK 0x0000000F ++#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ ++ IEEE80211_CCK_RATE_2MB_MASK) ++#define IEEE80211_CCK_DEFAULT_RATES_MASK \ ++ (IEEE80211_CCK_BASIC_RATES_MASK | \ ++ IEEE80211_CCK_RATE_5MB_MASK | \ ++ IEEE80211_CCK_RATE_11MB_MASK) ++ ++#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 ++#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ ++ IEEE80211_OFDM_RATE_12MB_MASK | \ ++ IEEE80211_OFDM_RATE_24MB_MASK) ++#define IEEE80211_OFDM_DEFAULT_RATES_MASK \ ++ (IEEE80211_OFDM_BASIC_RATES_MASK | \ ++ IEEE80211_OFDM_RATE_9MB_MASK | \ ++ IEEE80211_OFDM_RATE_18MB_MASK | \ ++ IEEE80211_OFDM_RATE_36MB_MASK | \ ++ IEEE80211_OFDM_RATE_48MB_MASK | \ ++ IEEE80211_OFDM_RATE_54MB_MASK) ++#define IEEE80211_DEFAULT_RATES_MASK \ ++ (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ ++ IEEE80211_CCK_DEFAULT_RATES_MASK) ++ ++#define IEEE80211_NUM_OFDM_RATES 8 ++#define IEEE80211_NUM_CCK_RATES 4 ++#define IEEE80211_OFDM_SHIFT_MASK_A 4 ++ ++/* NOTE: This data is for statistical purposes; not all hardware provides this ++ * information for frames received. Not setting these will not cause ++ * any adverse affects. */ ++struct ieee80211_rx_stats { ++ /* u32 mac_time[2]; */ ++ s8 rssi; ++ u8 signal; ++ u8 noise; ++ u8 received_channel; ++ u16 rate; /* in 100 kbps */ ++ /* u8 control; */ ++ u8 mask; ++ u8 freq; ++ u16 len; ++}; ++ ++/* IEEE 802.11 requires that STA supports concurrent reception of at least ++ * three fragmented frames. This define can be increased to support more ++ * concurrent frames, but it should be noted that each entry can consume about ++ * 2 kB of RAM and increasing cache size will slow down frame reassembly. */ ++#define IEEE80211_FRAG_CACHE_LEN 4 ++ ++struct ieee80211_frag_entry { ++ u32 first_frag_time; ++ uint seq; ++ uint last_frag; ++ uint qos; /* jackson */ ++ uint tid; /* jackson */ ++ struct sk_buff *skb; ++ u8 src_addr[ETH_ALEN]; ++ u8 dst_addr[ETH_ALEN]; ++}; ++ ++struct ieee80211_stats { ++ uint tx_unicast_frames; ++ uint tx_multicast_frames; ++ uint tx_fragments; ++ uint tx_unicast_octets; ++ uint tx_multicast_octets; ++ uint tx_deferred_transmissions; ++ uint tx_single_retry_frames; ++ uint tx_multiple_retry_frames; ++ uint tx_retry_limit_exceeded; ++ uint tx_discards; ++ uint rx_unicast_frames; ++ uint rx_multicast_frames; ++ uint rx_fragments; ++ uint rx_unicast_octets; ++ uint rx_multicast_octets; ++ uint rx_fcs_errors; ++ uint rx_discards_no_buffer; ++ uint tx_discards_wrong_sa; ++ uint rx_discards_undecryptable; ++ uint rx_message_in_msg_fragments; ++ uint rx_message_in_bad_msg_fragments; ++}; ++ ++struct ieee80211_softmac_stats { ++ uint rx_ass_ok; ++ uint rx_ass_err; ++ uint rx_probe_rq; ++ uint tx_probe_rs; ++ uint tx_beacons; ++ uint rx_auth_rq; ++ uint rx_auth_rs_ok; ++ uint rx_auth_rs_err; ++ uint tx_auth_rq; ++ uint no_auth_rs; ++ uint no_ass_rs; ++ uint tx_ass_rq; ++ uint rx_ass_rq; ++ uint tx_probe_rq; ++ uint reassoc; ++ uint swtxstop; ++ uint swtxawake; ++}; ++ ++#define SEC_KEY_1 (1<<0) ++#define SEC_KEY_2 (1<<1) ++#define SEC_KEY_3 (1<<2) ++#define SEC_KEY_4 (1<<3) ++#define SEC_ACTIVE_KEY (1<<4) ++#define SEC_AUTH_MODE (1<<5) ++#define SEC_UNICAST_GROUP (1<<6) ++#define SEC_LEVEL (1<<7) ++#define SEC_ENABLED (1<<8) ++ ++#define SEC_LEVEL_0 0 /* None */ ++#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */ ++#define SEC_LEVEL_2 2 /* Level 1 + TKIP */ ++#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */ ++#define SEC_LEVEL_3 4 /* Level 2 + CCMP */ ++ ++#define WEP_KEYS 4 ++#define WEP_KEY_LEN 13 ++ ++struct ieee80211_security { ++ u16 active_key:2, ++ enabled:1, ++ auth_mode:2, ++ auth_algo:4, ++ unicast_uses_group:1; ++ u8 key_sizes[WEP_KEYS]; ++ u8 keys[WEP_KEYS][WEP_KEY_LEN]; ++ u8 level; ++ u16 flags; ++} __packed; ++ ++/* ++ ++ 802.11 data frame from AP ++ ++ ,-------------------------------------------------------------------. ++Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | ++ |------|------|---------|---------|---------|------|---------|------| ++Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | ++ | | tion | (BSSID) | | | ence | data | | ++ `-------------------------------------------------------------------' ++ ++Total: 28-2340 bytes ++ ++*/ ++ ++struct ieee80211_header_data { ++ u16 frame_ctl; ++ u16 duration_id; ++ u8 addr1[6]; ++ u8 addr2[6]; ++ u8 addr3[6]; ++ u16 seq_ctrl; ++}; ++ ++#define BEACON_PROBE_SSID_ID_POSITION 12 ++ ++/* Management Frame Information Element Types */ ++#define MFIE_TYPE_SSID 0 ++#define MFIE_TYPE_RATES 1 ++#define MFIE_TYPE_FH_SET 2 ++#define MFIE_TYPE_DS_SET 3 ++#define MFIE_TYPE_CF_SET 4 ++#define MFIE_TYPE_TIM 5 ++#define MFIE_TYPE_IBSS_SET 6 ++#define MFIE_TYPE_CHALLENGE 16 ++#define MFIE_TYPE_ERP 42 ++#define MFIE_TYPE_RSN 48 ++#define MFIE_TYPE_RATES_EX 50 ++#define MFIE_TYPE_GENERIC 221 ++ ++struct ieee80211_info_element_hdr { ++ u8 id; ++ u8 len; ++} __packed; ++ ++struct ieee80211_info_element { ++ u8 id; ++ u8 len; ++ u8 data[0]; ++} __packed; ++ ++/* ++ * These are the data types that can make up management packets ++ * ++ u16 auth_algorithm; ++ u16 auth_sequence; ++ u16 beacon_interval; ++ u16 capability; ++ u8 current_ap[ETH_ALEN]; ++ u16 listen_interval; ++ struct { ++ u16 association_id:14, reserved:2; ++ } __packed; ++ u32 time_stamp[2]; ++ u16 reason; ++ u16 status; ++*/ ++ ++#define IEEE80211_DEFAULT_TX_ESSID "Penguin" ++#define IEEE80211_DEFAULT_BASIC_RATE 10 ++ ++struct ieee80211_authentication { ++ struct ieee80211_header_data header; ++ u16 algorithm; ++ u16 transaction; ++ u16 status; ++ /* struct ieee80211_info_element_hdr info_element; */ ++} __packed; ++ ++struct ieee80211_probe_response { ++ struct ieee80211_header_data header; ++ u32 time_stamp[2]; ++ u16 beacon_interval; ++ u16 capability; ++ struct ieee80211_info_element info_element; ++} __packed; ++ ++struct ieee80211_probe_request { ++ struct ieee80211_header_data header; ++} __packed; ++ ++struct ieee80211_assoc_request_frame { ++ struct rtw_ieee80211_hdr_3addr header; ++ u16 capability; ++ u16 listen_interval; ++ struct ieee80211_info_element_hdr info_element; ++} __packed; ++ ++struct ieee80211_assoc_response_frame { ++ struct rtw_ieee80211_hdr_3addr header; ++ u16 capability; ++ u16 status; ++ u16 aid; ++} __packed; ++ ++struct ieee80211_txb { ++ u8 nr_frags; ++ u8 encrypted; ++ u16 reserved; ++ u16 frag_size; ++ u16 payload_size; ++ struct sk_buff *fragments[0]; ++}; ++ ++/* SWEEP TABLE ENTRIES NUMBER*/ ++#define MAX_SWEEP_TAB_ENTRIES 42 ++#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7 ++/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs ++ * only use 8, and then use extended rates for the remaining supported ++ * rates. Other APs, however, stick all of their supported rates on the ++ * main rates information element... */ ++#define MAX_RATES_LENGTH ((u8)12) ++#define MAX_RATES_EX_LENGTH ((u8)16) ++#define MAX_NETWORK_COUNT 128 ++#define MAX_CHANNEL_NUMBER 161 ++#define IEEE80211_SOFTMAC_SCAN_TIME 400 ++/* HZ / 2) */ ++#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2) ++ ++#define CRC_LENGTH 4U ++ ++#define MAX_WPA_IE_LEN (256) ++#define MAX_WPS_IE_LEN (512) ++#define MAX_P2P_IE_LEN (256) ++#define MAX_WFD_IE_LEN (128) ++ ++#define NETWORK_EMPTY_ESSID (1<<0) ++#define NETWORK_HAS_OFDM (1<<1) ++#define NETWORK_HAS_CCK (1<<2) ++ ++#define IEEE80211_DTIM_MBCAST 4 ++#define IEEE80211_DTIM_UCAST 2 ++#define IEEE80211_DTIM_VALID 1 ++#define IEEE80211_DTIM_INVALID 0 ++ ++#define IEEE80211_PS_DISABLED 0 ++#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST ++#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST ++#define IW_ESSID_MAX_SIZE 32 ++/* ++join_res: ++-1: authentication fail ++-2: association fail ++> 0: TID ++*/ ++ ++enum ieee80211_state { ++ /* the card is not linked at all */ ++ IEEE80211_NOLINK = 0, ++ ++ /* IEEE80211_ASSOCIATING* are for BSS client mode ++ * the driver shall not perform RX filtering unless ++ * the state is LINKED. ++ * The driver shall just check for the state LINKED and ++ * defaults to NOLINK for ALL the other states (including ++ * LINKED_SCANNING) ++ */ ++ ++ /* the association procedure will start (wq scheduling)*/ ++ IEEE80211_ASSOCIATING, ++ IEEE80211_ASSOCIATING_RETRY, ++ ++ /* the association procedure is sending AUTH request*/ ++ IEEE80211_ASSOCIATING_AUTHENTICATING, ++ ++ /* the association procedure has successfully authentcated ++ * and is sending association request ++ */ ++ IEEE80211_ASSOCIATING_AUTHENTICATED, ++ ++ /* the link is ok. the card associated to a BSS or linked ++ * to a ibss cell or acting as an AP and creating the bss ++ */ ++ IEEE80211_LINKED, ++ ++ /* same as LINKED, but the driver shall apply RX filter ++ * rules as we are in NO_LINK mode. As the card is still ++ * logically linked, but it is doing a syncro site survey ++ * then it will be back to LINKED state. ++ */ ++ IEEE80211_LINKED_SCANNING, ++ ++}; ++ ++#define DEFAULT_MAX_SCAN_AGE (15 * HZ) ++#define DEFAULT_FTS 2346 ++ ++static inline int is_multicast_mac_addr(const u8 *addr) ++{ ++ return ((addr[0] != 0xff) && (0x01 & addr[0])); ++} ++ ++static inline int is_broadcast_mac_addr(const u8 *addr) ++{ ++ return (addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && ++ (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff); ++} ++ ++#define CFG_IEEE80211_RESERVE_FCS (1<<0) ++#define CFG_IEEE80211_COMPUTE_FCS (1<<1) ++ ++struct tx_pending { ++ int frag; ++ struct ieee80211_txb *txb; ++}; ++ ++#define MAXTID 16 ++ ++#define IEEE_A (1<<0) ++#define IEEE_B (1<<1) ++#define IEEE_G (1<<2) ++#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) ++ ++/* Baron move to ieee80211.c */ ++int ieee80211_is_empty_essid(const char *essid, int essid_len); ++int ieee80211_get_hdrlen(u16 fc); ++ ++/* Action category code */ ++enum rtw_ieee80211_category { ++ RTW_WLAN_CATEGORY_SPECTRUM_MGMT = 0, ++ RTW_WLAN_CATEGORY_QOS = 1, ++ RTW_WLAN_CATEGORY_DLS = 2, ++ RTW_WLAN_CATEGORY_BACK = 3, ++ RTW_WLAN_CATEGORY_PUBLIC = 4, /* IEEE 802.11 public action frames */ ++ RTW_WLAN_CATEGORY_RADIO_MEASUREMENT = 5, ++ RTW_WLAN_CATEGORY_FT = 6, ++ RTW_WLAN_CATEGORY_HT = 7, ++ RTW_WLAN_CATEGORY_SA_QUERY = 8, ++ RTW_WLAN_CATEGORY_TDLS = 12, ++ RTW_WLAN_CATEGORY_WMM = 17, ++ RTW_WLAN_CATEGORY_P2P = 0x7f,/* P2P action frames */ ++}; ++ ++/* SPECTRUM_MGMT action code */ ++enum rtw_ieee80211_spectrum_mgmt_actioncode { ++ RTW_WLAN_ACTION_SPCT_MSR_REQ = 0, ++ RTW_WLAN_ACTION_SPCT_MSR_RPRT = 1, ++ RTW_WLAN_ACTION_SPCT_TPC_REQ = 2, ++ RTW_WLAN_ACTION_SPCT_TPC_RPRT = 3, ++ RTW_WLAN_ACTION_SPCT_CHL_SWITCH = 4, ++ RTW_WLAN_ACTION_SPCT_EXT_CHL_SWITCH = 5, ++}; ++ ++enum _PUBLIC_ACTION { ++ ACT_PUBLIC_BSSCOEXIST = 0, /* 20/40 BSS Coexistence */ ++ ACT_PUBLIC_DSE_ENABLE = 1, ++ ACT_PUBLIC_DSE_DEENABLE = 2, ++ ACT_PUBLIC_DSE_REG_LOCATION = 3, ++ ACT_PUBLIC_EXT_CHL_SWITCH = 4, ++ ACT_PUBLIC_DSE_MSR_REQ = 5, ++ ACT_PUBLIC_DSE_MSR_RPRT = 6, ++ ACT_PUBLIC_MP = 7, /* Measurement Pilot */ ++ ACT_PUBLIC_DSE_PWR_CONSTRAINT = 8, ++ ACT_PUBLIC_VENDOR = 9, /* for WIFI_DIRECT */ ++ ACT_PUBLIC_GAS_INITIAL_REQ = 10, ++ ACT_PUBLIC_GAS_INITIAL_RSP = 11, ++ ACT_PUBLIC_GAS_COMEBACK_REQ = 12, ++ ACT_PUBLIC_GAS_COMEBACK_RSP = 13, ++ ACT_PUBLIC_TDLS_DISCOVERY_RSP = 14, ++ ACT_PUBLIC_LOCATION_TRACK = 15, ++ ACT_PUBLIC_MAX ++}; ++ ++/* BACK action code */ ++enum rtw_ieee80211_back_actioncode { ++ RTW_WLAN_ACTION_ADDBA_REQ = 0, ++ RTW_WLAN_ACTION_ADDBA_RESP = 1, ++ RTW_WLAN_ACTION_DELBA = 2, ++}; ++ ++/* HT features action code */ ++enum rtw_ieee80211_ht_actioncode { ++ RTW_WLAN_ACTION_NOTIFY_CH_WIDTH = 0, ++ RTW_WLAN_ACTION_SM_PS = 1, ++ RTW_WLAN_ACTION_PSPM = 2, ++ RTW_WLAN_ACTION_PCO_PHASE = 3, ++ RTW_WLAN_ACTION_MIMO_CSI_MX = 4, ++ RTW_WLAN_ACTION_MIMO_NONCP_BF = 5, ++ RTW_WLAN_ACTION_MIMP_CP_BF = 6, ++ RTW_WLAN_ACTION_ASEL_INDICATES_FB = 7, ++ RTW_WLAN_ACTION_HI_INFO_EXCHG = 8, ++}; ++ ++/* BACK (block-ack) parties */ ++enum rtw_ieee80211_back_parties { ++ RTW_WLAN_BACK_RECIPIENT = 0, ++ RTW_WLAN_BACK_INITIATOR = 1, ++ RTW_WLAN_BACK_TIMER = 2, ++}; ++ ++#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) ++ * 00:50:F2 */ ++#define WME_OUI_TYPE 2 ++#define WME_OUI_SUBTYPE_INFORMATION_ELEMENT 0 ++#define WME_OUI_SUBTYPE_PARAMETER_ELEMENT 1 ++#define WME_OUI_SUBTYPE_TSPEC_ELEMENT 2 ++#define WME_VERSION 1 ++ ++#define WME_ACTION_CODE_SETUP_REQUEST 0 ++#define WME_ACTION_CODE_SETUP_RESPONSE 1 ++#define WME_ACTION_CODE_TEARDOWN 2 ++ ++#define WME_SETUP_RESPONSE_STATUS_ADMISSION_ACCEPTED 0 ++#define WME_SETUP_RESPONSE_STATUS_INVALID_PARAMETERS 1 ++#define WME_SETUP_RESPONSE_STATUS_REFUSED 3 ++ ++#define WME_TSPEC_DIRECTION_UPLINK 0 ++#define WME_TSPEC_DIRECTION_DOWNLINK 1 ++#define WME_TSPEC_DIRECTION_BI_DIRECTIONAL 3 ++ ++#define OUI_BROADCOM 0x00904c /* Broadcom (Epigram) */ ++ ++#define VENDOR_HT_CAPAB_OUI_TYPE 0x33 /* 00-90-4c:0x33 */ ++ ++/** ++ * enum rtw_ieee80211_channel_flags - channel flags ++ * ++ * Channel flags set by the regulatory control code. ++ * ++ * @RTW_IEEE80211_CHAN_DISABLED: This channel is disabled. ++ * @RTW_IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted ++ * on this channel. ++ * @RTW_IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel. ++ * @RTW_IEEE80211_CHAN_RADAR: Radar detection is required on this channel. ++ * @RTW_IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel ++ * is not permitted. ++ * @RTW_IEEE80211_CHAN_NO_HT40MINUS: extension channel below this channel ++ * is not permitted. ++ */ ++enum rtw_ieee80211_channel_flags { ++ RTW_IEEE80211_CHAN_DISABLED = 1<<0, ++ RTW_IEEE80211_CHAN_PASSIVE_SCAN = 1<<1, ++ RTW_IEEE80211_CHAN_NO_IBSS = 1<<2, ++ RTW_IEEE80211_CHAN_RADAR = 1<<3, ++ RTW_IEEE80211_CHAN_NO_HT40PLUS = 1<<4, ++ RTW_IEEE80211_CHAN_NO_HT40MINUS = 1<<5, ++}; ++ ++#define RTW_IEEE80211_CHAN_NO_HT40 \ ++ (RTW_IEEE80211_CHAN_NO_HT40PLUS | RTW_IEEE80211_CHAN_NO_HT40MINUS) ++ ++/* Represent channel details, subset of ieee80211_channel */ ++struct rtw_ieee80211_channel { ++ u16 hw_value; ++ u32 flags; ++}; ++ ++#define CHAN_FMT \ ++ "hw_value:%u, " \ ++ "flags:0x%08x" \ ++ ++#define CHAN_ARG(channel) \ ++ (channel)->hw_value \ ++ , (channel)->flags \ ++ ++/* Parsed Information Elements */ ++struct rtw_ieee802_11_elems { ++ u8 *ssid; ++ u8 ssid_len; ++ u8 *supp_rates; ++ u8 supp_rates_len; ++ u8 *fh_params; ++ u8 fh_params_len; ++ u8 *ds_params; ++ u8 ds_params_len; ++ u8 *cf_params; ++ u8 cf_params_len; ++ u8 *tim; ++ u8 tim_len; ++ u8 *ibss_params; ++ u8 ibss_params_len; ++ u8 *challenge; ++ u8 challenge_len; ++ u8 *erp_info; ++ u8 erp_info_len; ++ u8 *ext_supp_rates; ++ u8 ext_supp_rates_len; ++ u8 *wpa_ie; ++ u8 wpa_ie_len; ++ u8 *rsn_ie; ++ u8 rsn_ie_len; ++ u8 *wme; ++ u8 wme_len; ++ u8 *wme_tspec; ++ u8 wme_tspec_len; ++ u8 *wps_ie; ++ u8 wps_ie_len; ++ u8 *power_cap; ++ u8 power_cap_len; ++ u8 *supp_channels; ++ u8 supp_channels_len; ++ u8 *mdie; ++ u8 mdie_len; ++ u8 *ftie; ++ u8 ftie_len; ++ u8 *timeout_int; ++ u8 timeout_int_len; ++ u8 *ht_capabilities; ++ u8 ht_capabilities_len; ++ u8 *ht_operation; ++ u8 ht_operation_len; ++ u8 *vendor_ht_cap; ++ u8 vendor_ht_cap_len; ++}; ++ ++enum parse_res { ++ ParseOK = 0, ++ ParseUnknown = 1, ++ ParseFailed = -1 ++}; ++ ++enum parse_res rtw_ieee802_11_parse_elems(u8 *start, uint len, ++ struct rtw_ieee802_11_elems *elems, ++ int show_errors); ++ ++u8 *rtw_set_fixed_ie(unsigned char *pbuf, unsigned int len, ++ unsigned char *source, unsigned int *frlen); ++u8 *rtw_set_ie(u8 *pbuf, int index, uint len, u8 *source, uint *frlen); ++ ++enum secondary_ch_offset { ++ SCN = 0, /* no secondary channel */ ++ SCA = 1, /* secondary channel above */ ++ SCB = 3, /* secondary channel below */ ++}; ++u8 secondary_ch_offset_to_hal_ch_offset(u8 ch_offset); ++u8 hal_ch_offset_to_secondary_ch_offset(u8 ch_offset); ++u8 *rtw_set_ie_ch_switch(u8 *buf, u32 *buf_len, u8 ch_switch_mode, ++ u8 new_ch, u8 ch_switch_cnt); ++u8 *rtw_set_ie_secondary_ch_offset(u8 *buf, u32 *buf_len, ++ u8 secondary_ch_offset); ++u8 *rtw_set_ie_mesh_ch_switch_parm(u8 *buf, u32 *buf_len, u8 ttl, ++ u8 flags, u16 reason, u16 precedence); ++ ++u8 *rtw_get_ie(u8 *pbuf, int index, int *len, int limit); ++u8 *rtw_get_ie_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, ++ u8 oui_len, u8 *ie, uint *ielen); ++int rtw_ies_remove_ie(u8 *ies, uint *ies_len, uint offset, ++ u8 eid, u8 *oui, u8 oui_len); ++ ++void rtw_set_supported_rate(u8 *SupportedRates, uint mode); ++ ++unsigned char *rtw_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit); ++unsigned char *rtw_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit); ++int rtw_get_wpa_cipher_suite(u8 *s); ++int rtw_get_wpa2_cipher_suite(u8 *s); ++int rtw_get_wapi_ie(u8 *in_ie, uint in_len, u8 *wapi_ie, u16 *wapi_len); ++int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, ++ int *pairwise_cipher, int *is_8021x); ++int rtw_parse_wpa2_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, ++ int *pairwise_cipher, int *is_8021x); ++ ++int rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, ++ u8 *wpa_ie, u16 *wpa_len); ++ ++u8 rtw_is_wps_ie(u8 *ie_ptr, uint *wps_ielen); ++u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen); ++u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, ++ u8 *buf_attr, u32 *len_attr); ++u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, ++ u8 *buf_content, uint *len_content); ++ ++/** ++ * for_each_ie - iterate over continuous IEs ++ * @ie: ++ * @buf: ++ * @buf_len: ++ */ ++#define for_each_ie(ie, buf, buf_len) \ ++ for (ie = (void *)buf; (((u8 *)ie) - ((u8 *)buf) + 1) < buf_len; \ ++ ie = (void *)(((u8 *)ie) + *(((u8 *)ie)+1) + 2)) ++ ++void dump_ies(u8 *buf, u32 buf_len); ++void dump_wps_ie(u8 *ie, u32 ie_len); ++ ++#ifdef CONFIG_88EU_P2P ++void dump_p2p_ie(u8 *ie, u32 ie_len); ++u8 *rtw_get_p2p_ie(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen); ++u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id, ++ u8 *buf_attr, u32 *len_attr); ++u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id, ++ u8 *buf_content, uint *len_content); ++u32 rtw_set_p2p_attr_content(u8 *pbuf, u8 attr_id, u16 attr_len, ++ u8 *pdata_attr); ++void rtw_wlan_bssid_ex_remove_p2p_attr(struct wlan_bssid_ex *bss_ex, ++ u8 attr_id); ++#endif ++ ++uint rtw_get_rateset_len(u8 *rateset); ++ ++struct registry_priv; ++int rtw_generate_ie(struct registry_priv *pregistrypriv); ++ ++int rtw_get_bit_value_from_ieee_value(u8 val); ++ ++uint rtw_is_cckrates_included(u8 *rate); ++ ++uint rtw_is_cckratesonly_included(u8 *rate); ++ ++int rtw_check_network_type(unsigned char *rate, int ratelen, int channel); ++ ++void rtw_get_bcn_info(struct wlan_network *pnetwork); ++ ++void rtw_macaddr_cfg(u8 *mac_addr); ++ ++u16 rtw_mcs_rate(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40, ++ unsigned char *MCS_rate); ++ ++int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category, ++ u8 *action); ++const char *action_public_str(u8 action); ++ ++#endif /* IEEE80211_H */ +diff --git a/drivers/staging/r8188eu/include/ieee80211_ext.h b/drivers/staging/r8188eu/include/ieee80211_ext.h +new file mode 100644 +index 000000000000..e7ade835d478 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/ieee80211_ext.h +@@ -0,0 +1,271 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __IEEE80211_EXT_H ++#define __IEEE80211_EXT_H ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define WMM_OUI_TYPE 2 ++#define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0 ++#define WMM_OUI_SUBTYPE_PARAMETER_ELEMENT 1 ++#define WMM_OUI_SUBTYPE_TSPEC_ELEMENT 2 ++#define WMM_VERSION 1 ++ ++#define WPA_PROTO_WPA BIT(0) ++#define WPA_PROTO_RSN BIT(1) ++ ++#define WPA_KEY_MGMT_IEEE8021X BIT(0) ++#define WPA_KEY_MGMT_PSK BIT(1) ++#define WPA_KEY_MGMT_NONE BIT(2) ++#define WPA_KEY_MGMT_IEEE8021X_NO_WPA BIT(3) ++#define WPA_KEY_MGMT_WPA_NONE BIT(4) ++ ++#define WPA_CAPABILITY_PREAUTH BIT(0) ++#define WPA_CAPABILITY_MGMT_FRAME_PROTECTION BIT(6) ++#define WPA_CAPABILITY_PEERKEY_ENABLED BIT(9) ++ ++#define PMKID_LEN 16 ++ ++struct wpa_ie_hdr { ++ u8 elem_id; ++ u8 len; ++ u8 oui[4]; /* 24-bit OUI followed by 8-bit OUI type */ ++ u8 version[2]; /* little endian */ ++} __packed; ++ ++struct rsn_ie_hdr { ++ u8 elem_id; /* WLAN_EID_RSN */ ++ u8 len; ++ u8 version[2]; /* little endian */ ++} __packed; ++ ++struct wme_ac_parameter { ++#if defined(__LITTLE_ENDIAN) ++ /* byte 1 */ ++ u8 aifsn:4, ++ acm:1, ++ aci:2, ++ reserved:1; ++ ++ /* byte 2 */ ++ u8 eCWmin:4, ++ eCWmax:4; ++#elif defined(__BIG_ENDIAN) ++ /* byte 1 */ ++ u8 reserved:1, ++ aci:2, ++ acm:1, ++ aifsn:4; ++ ++ /* byte 2 */ ++ u8 eCWmax:4, ++ eCWmin:4; ++#else ++#error "Please fix " ++#endif ++ ++ /* bytes 3 & 4 */ ++ u16 txopLimit; ++} __packed; ++ ++struct wme_parameter_element { ++ /* required fields for WME version 1 */ ++ u8 oui[3]; ++ u8 oui_type; ++ u8 oui_subtype; ++ u8 version; ++ u8 acInfo; ++ u8 reserved; ++ struct wme_ac_parameter ac[4]; ++ ++} __packed; ++ ++#define WPA_PUT_LE16(a, val) \ ++ do { \ ++ (a)[1] = ((u16) (val)) >> 8; \ ++ (a)[0] = ((u16) (val)) & 0xff; \ ++ } while (0) ++ ++#define WPA_PUT_BE32(a, val) \ ++ do { \ ++ (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ ++ (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ ++ (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ ++ (a)[3] = (u8) (((u32) (val)) & 0xff); \ ++ } while (0) ++ ++#define WPA_PUT_LE32(a, val) \ ++ do { \ ++ (a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \ ++ (a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \ ++ (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ ++ (a)[0] = (u8) (((u32) (val)) & 0xff); \ ++ } while (0) ++ ++#define RSN_SELECTOR_PUT(a, val) WPA_PUT_BE32((u8 *)(a), (val)) ++ ++/* Action category code */ ++enum ieee80211_category { ++ WLAN_CATEGORY_SPECTRUM_MGMT = 0, ++ WLAN_CATEGORY_QOS = 1, ++ WLAN_CATEGORY_DLS = 2, ++ WLAN_CATEGORY_BACK = 3, ++ WLAN_CATEGORY_HT = 7, ++ WLAN_CATEGORY_WMM = 17, ++}; ++ ++/* SPECTRUM_MGMT action code */ ++enum ieee80211_spectrum_mgmt_actioncode { ++ WLAN_ACTION_SPCT_MSR_REQ = 0, ++ WLAN_ACTION_SPCT_MSR_RPRT = 1, ++ WLAN_ACTION_SPCT_TPC_REQ = 2, ++ WLAN_ACTION_SPCT_TPC_RPRT = 3, ++ WLAN_ACTION_SPCT_CHL_SWITCH = 4, ++ WLAN_ACTION_SPCT_EXT_CHL_SWITCH = 5, ++}; ++ ++/* BACK action code */ ++enum ieee80211_back_actioncode { ++ WLAN_ACTION_ADDBA_REQ = 0, ++ WLAN_ACTION_ADDBA_RESP = 1, ++ WLAN_ACTION_DELBA = 2, ++}; ++ ++/* HT features action code */ ++enum ieee80211_ht_actioncode { ++ WLAN_ACTION_NOTIFY_CH_WIDTH = 0, ++ WLAN_ACTION_SM_PS = 1, ++ WLAN_ACTION_PSPM = 2, ++ WLAN_ACTION_PCO_PHASE = 3, ++ WLAN_ACTION_MIMO_CSI_MX = 4, ++ WLAN_ACTION_MIMO_NONCP_BF = 5, ++ WLAN_ACTION_MIMP_CP_BF = 6, ++ WLAN_ACTION_ASEL_INDICATES_FB = 7, ++ WLAN_ACTION_HI_INFO_EXCHG = 8, ++}; ++ ++/* BACK (block-ack) parties */ ++enum ieee80211_back_parties { ++ WLAN_BACK_RECIPIENT = 0, ++ WLAN_BACK_INITIATOR = 1, ++ WLAN_BACK_TIMER = 2, ++}; ++ ++struct ieee80211_mgmt { ++ u16 frame_control; ++ u16 duration; ++ u8 da[6]; ++ u8 sa[6]; ++ u8 bssid[6]; ++ u16 seq_ctrl; ++ union { ++ struct { ++ u16 auth_alg; ++ u16 auth_transaction; ++ u16 status_code; ++ /* possibly followed by Challenge text */ ++ u8 variable[0]; ++ } __packed auth; ++ struct { ++ u16 reason_code; ++ } __packed deauth; ++ struct { ++ u16 capab_info; ++ u16 listen_interval; ++ /* followed by SSID and Supported rates */ ++ u8 variable[0]; ++ } __packed assoc_req; ++ struct { ++ u16 capab_info; ++ u16 status_code; ++ u16 aid; ++ /* followed by Supported rates */ ++ u8 variable[0]; ++ } __packed assoc_resp, reassoc_resp; ++ struct { ++ u16 capab_info; ++ u16 listen_interval; ++ u8 current_ap[6]; ++ /* followed by SSID and Supported rates */ ++ u8 variable[0]; ++ } __packed reassoc_req; ++ struct { ++ u16 reason_code; ++ } __packed disassoc; ++ struct { ++ __le64 timestamp; ++ u16 beacon_int; ++ u16 capab_info; ++ /* followed by some of SSID, Supported rates, ++ * FH Params, DS Params, CF Params, IBSS Params, TIM */ ++ u8 variable[0]; ++ } __packed beacon; ++ struct { ++ /* only variable items: SSID, Supported rates */ ++ u8 variable[0]; ++ } __packed probe_req; ++ struct { ++ __le64 timestamp; ++ u16 beacon_int; ++ u16 capab_info; ++ /* followed by some of SSID, Supported rates, ++ * FH Params, DS Params, CF Params, IBSS Params */ ++ u8 variable[0]; ++ } __packed probe_resp; ++ struct { ++ u8 category; ++ union { ++ struct { ++ u8 action_code; ++ u8 dialog_token; ++ u8 status_code; ++ u8 variable[0]; ++ } __packed wme_action; ++ struct { ++ u8 action_code; ++ u8 dialog_token; ++ u16 capab; ++ u16 timeout; ++ u16 start_seq_num; ++ } __packed addba_req; ++ struct { ++ u8 action_code; ++ u8 dialog_token; ++ u16 status; ++ u16 capab; ++ u16 timeout; ++ } __packed addba_resp; ++ struct { ++ u8 action_code; ++ u16 params; ++ u16 reason_code; ++ } __packed delba; ++ structi { ++ u8 action_code; ++ /* capab_info for open and confirm, ++ * reason for close ++ */ ++ u16 aux; ++ /* Followed in plink_confirm by status ++ * code, AID and supported rates, ++ * and directly by supported rates in ++ * plink_open and plink_close ++ */ ++ u8 variable[0]; ++ } __packed plink_action; ++ struct{ ++ u8 action_code; ++ u8 variable[0]; ++ } __packed mesh_action; ++ } __packed u; ++ } __packed action; ++ } __packed u; ++} __packed; ++ ++/* mgmt header + 1 byte category code */ ++#define IEEE80211_MIN_ACTION_SIZE \ ++ FIELD_OFFSET(struct ieee80211_mgmt, u.action.u) ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/ioctl_cfg80211.h b/drivers/staging/r8188eu/include/ioctl_cfg80211.h +new file mode 100644 +index 000000000000..e22481050ef8 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/ioctl_cfg80211.h +@@ -0,0 +1,91 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. i*/ ++ ++#ifndef __IOCTL_CFG80211_H__ ++#define __IOCTL_CFG80211_H__ ++ ++struct rtw_wdev_invit_info { ++ u8 token; ++ u8 flags; ++ u8 status; ++ u8 req_op_ch; ++ u8 rsp_op_ch; ++}; ++ ++#define rtw_wdev_invit_info_init(invit_info) \ ++ do { \ ++ (invit_info)->token = 0; \ ++ (invit_info)->flags = 0x00; \ ++ (invit_info)->status = 0xff; \ ++ (invit_info)->req_op_ch = 0; \ ++ (invit_info)->rsp_op_ch = 0; \ ++ } while (0) ++ ++struct rtw_wdev_priv { ++ struct wireless_dev *rtw_wdev; ++ ++ struct adapter *padapter; ++ ++ struct cfg80211_scan_request *scan_request; ++ spinlock_t scan_req_lock; ++ ++ struct net_device *pmon_ndev;/* for monitor interface */ ++ char ifname_mon[IFNAMSIZ + 1]; /* name of monitor interface */ ++ ++ u8 p2p_enabled; ++ ++ u8 provdisc_req_issued; ++ ++ struct rtw_wdev_invit_info invit_info; ++ ++ u8 bandroid_scan; ++ bool block; ++ bool power_mgmt; ++}; ++ ++#define wdev_to_priv(w) ((struct rtw_wdev_priv *)(wdev_priv(w))) ++ ++#define wiphy_to_wdev(x) \ ++((struct wireless_dev *)(((struct rtw_wdev_priv *)wiphy_priv(x))->rtw_wdev)) ++ ++int rtw_wdev_alloc(struct adapter *padapter, struct device *dev); ++void rtw_wdev_free(struct wireless_dev *wdev); ++void rtw_wdev_unregister(struct wireless_dev *wdev); ++ ++void rtw_cfg80211_init_wiphy(struct adapter *padapter); ++ ++void rtw_cfg80211_surveydone_event_callback(struct adapter *padapter); ++ ++void rtw_cfg80211_indicate_connect(struct adapter *padapter); ++void rtw_cfg80211_indicate_disconnect(struct adapter *padapter); ++void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv, ++ bool aborted); ++ ++#ifdef CONFIG_88EU_AP_MODE ++void rtw_cfg80211_indicate_sta_assoc(struct adapter *padapter, ++ u8 *pmgmt_frame, uint frame_len); ++void rtw_cfg80211_indicate_sta_disassoc(struct adapter *padapter, ++ unsigned char *da, ++ unsigned short reason); ++#endif /* CONFIG_88EU_AP_MODE */ ++ ++void rtw_cfg80211_issue_p2p_provision_request(struct adapter *padapter, ++ const u8 *buf, size_t len); ++void rtw_cfg80211_rx_p2p_action_public(struct adapter *padapter, ++ u8 *pmgmt_frame, uint frame_len); ++void rtw_cfg80211_rx_action_p2p(struct adapter *padapter, u8 *pmgmt_frame, ++ uint frame_len); ++void rtw_cfg80211_rx_action(struct adapter *adapter, u8 *frame, ++ uint frame_len, const char *msg); ++ ++int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, ++ char *buf, int len, int type); ++ ++bool rtw_cfg80211_pwr_mgmt(struct adapter *adapter); ++ ++#define rtw_cfg80211_rx_mgmt(dev, freq, sig_dbm, buf, len, gfp) \ ++ cfg80211_rx_mgmt(dev, freq, sig_dbm, buf, len, gfp) ++#define rtw_cfg80211_send_rx_assoc(dev, bss, buf, len) \ ++ cfg80211_send_rx_assoc(dev, bss, buf, len) ++ ++#endif /* __IOCTL_CFG80211_H__ */ +diff --git a/drivers/staging/r8188eu/include/mlme_osdep.h b/drivers/staging/r8188eu/include/mlme_osdep.h +new file mode 100644 +index 000000000000..5b9f688f9424 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/mlme_osdep.h +@@ -0,0 +1,19 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __MLME_OSDEP_H_ ++#define __MLME_OSDEP_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++void rtw_init_mlme_timer(struct adapter *padapter); ++void rtw_os_indicate_disconnect(struct adapter *adapter); ++void rtw_os_indicate_connect(struct adapter *adapter); ++void rtw_os_indicate_scan_done(struct adapter *padapter, bool aborted); ++void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie); ++ ++void rtw_reset_securitypriv(struct adapter *adapter); ++void indicate_wx_scan_complete_event(struct adapter *padapter); ++ ++#endif /* _MLME_OSDEP_H_ */ +diff --git a/drivers/staging/r8188eu/include/mp_custom_oid.h b/drivers/staging/r8188eu/include/mp_custom_oid.h +new file mode 100644 +index 000000000000..7bcb857c795d +--- /dev/null ++++ b/drivers/staging/r8188eu/include/mp_custom_oid.h +@@ -0,0 +1,333 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __CUSTOM_OID_H ++#define __CUSTOM_OID_H ++ ++/* by Owen */ ++/* 0xFF818000 - 0xFF81802F RTL8180 Mass Production Kit */ ++/* 0xFF818500 - 0xFF81850F RTL8185 Setup Utility */ ++/* 0xFF818580 - 0xFF81858F RTL8185 Phy Status Utility */ ++ ++/* */ ++ ++/* by Owen for Production Kit */ ++/* For Production Kit with Agilent Equipments */ ++/* in order to make our custom oids hopefully somewhat unique */ ++/* we will use 0xFF (indicating implementation specific OID) */ ++/* 81(first byte of non zero Realtek unique identifier) */ ++/* 80 (second byte of non zero Realtek unique identifier) */ ++/* XX (the custom OID number - providing 255 possible custom oids) */ ++ ++#define OID_RT_PRO_RESET_DUT 0xFF818000 ++#define OID_RT_PRO_SET_DATA_RATE 0xFF818001 ++#define OID_RT_PRO_START_TEST 0xFF818002 ++#define OID_RT_PRO_STOP_TEST 0xFF818003 ++#define OID_RT_PRO_SET_PREAMBLE 0xFF818004 ++#define OID_RT_PRO_SET_SCRAMBLER 0xFF818005 ++#define OID_RT_PRO_SET_FILTER_BB 0xFF818006 ++#define OID_RT_PRO_SET_MANUAL_DIVERSITY_BB 0xFF818007 ++#define OID_RT_PRO_SET_CHANNEL_DIRECT_CALL 0xFF818008 ++#define OID_RT_PRO_SET_SLEEP_MODE_DIRECT_CALL 0xFF818009 ++#define OID_RT_PRO_SET_WAKE_MODE_DIRECT_CALL 0xFF81800A ++ ++#define OID_RT_PRO_SET_TX_ANTENNA_BB 0xFF81800D ++#define OID_RT_PRO_SET_ANTENNA_BB 0xFF81800E ++#define OID_RT_PRO_SET_CR_SCRAMBLER 0xFF81800F ++#define OID_RT_PRO_SET_CR_NEW_FILTER 0xFF818010 ++#define OID_RT_PRO_SET_TX_POWER_CONTROL 0xFF818011 ++#define OID_RT_PRO_SET_CR_TX_CONFIG 0xFF818012 ++#define OID_RT_PRO_GET_TX_POWER_CONTROL 0xFF818013 ++#define OID_RT_PRO_GET_CR_SIGNAL_QUALITY 0xFF818014 ++#define OID_RT_PRO_SET_CR_SETPOINT 0xFF818015 ++#define OID_RT_PRO_SET_INTEGRATOR 0xFF818016 ++#define OID_RT_PRO_SET_SIGNAL_QUALITY 0xFF818017 ++#define OID_RT_PRO_GET_INTEGRATOR 0xFF818018 ++#define OID_RT_PRO_GET_SIGNAL_QUALITY 0xFF818019 ++#define OID_RT_PRO_QUERY_EEPROM_TYPE 0xFF81801A ++#define OID_RT_PRO_WRITE_MAC_ADDRESS 0xFF81801B ++#define OID_RT_PRO_READ_MAC_ADDRESS 0xFF81801C ++#define OID_RT_PRO_WRITE_CIS_DATA 0xFF81801D ++#define OID_RT_PRO_READ_CIS_DATA 0xFF81801E ++#define OID_RT_PRO_WRITE_POWER_CONTROL 0xFF81801F ++#define OID_RT_PRO_READ_POWER_CONTROL 0xFF818020 ++#define OID_RT_PRO_WRITE_EEPROM 0xFF818021 ++#define OID_RT_PRO_READ_EEPROM 0xFF818022 ++#define OID_RT_PRO_RESET_TX_PACKET_SENT 0xFF818023 ++#define OID_RT_PRO_QUERY_TX_PACKET_SENT 0xFF818024 ++#define OID_RT_PRO_RESET_RX_PACKET_RECEIVED 0xFF818025 ++#define OID_RT_PRO_QUERY_RX_PACKET_RECEIVED 0xFF818026 ++#define OID_RT_PRO_QUERY_RX_PACKET_CRC32_ERROR 0xFF818027 ++#define OID_RT_PRO_QUERY_CURRENT_ADDRESS 0xFF818028 ++#define OID_RT_PRO_QUERY_PERMANENT_ADDRESS 0xFF818029 ++#define OID_RT_PRO_SET_PHILIPS_RF_PARAMETERS 0xFF81802A ++#define OID_RT_PRO_RECEIVE_PACKET 0xFF81802C ++/* added by Owen on 04/08/03 for Cameo's request */ ++#define OID_RT_PRO_WRITE_EEPROM_BYTE 0xFF81802D ++#define OID_RT_PRO_READ_EEPROM_BYTE 0xFF81802E ++#define OID_RT_PRO_SET_MODULATION 0xFF81802F ++/* */ ++ ++/* Sean */ ++#define OID_RT_DRIVER_OPTION 0xFF818080 ++#define OID_RT_RF_OFF 0xFF818081 ++#define OID_RT_AUTH_STATUS 0xFF818082 ++ ++/* */ ++#define OID_RT_PRO_SET_CONTINUOUS_TX 0xFF81800B ++#define OID_RT_PRO_SET_SINGLE_CARRIER_TX 0xFF81800C ++#define OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX 0xFF81802B ++#define OID_RT_PRO_SET_SINGLE_TONE_TX 0xFF818043 ++/* */ ++ ++/* by Owen for RTL8185 Phy Status Report Utility */ ++#define OID_RT_UTILITY_false_ALARM_COUNTERS 0xFF818580 ++#define OID_RT_UTILITY_SELECT_DEBUG_MODE 0xFF818581 ++#define OID_RT_UTILITY_SELECT_SUBCARRIER_NUMBER 0xFF818582 ++#define OID_RT_UTILITY_GET_RSSI_STATUS 0xFF818583 ++#define OID_RT_UTILITY_GET_FRAME_DETECTION_STATUS 0xFF818584 ++#define OID_RT_UTILITY_GET_AGC_AND_FREQUENCY_OFFSET_ESTIMATION_STATUS \ ++ 0xFF818585 ++#define OID_RT_UTILITY_GET_CHANNEL_ESTIMATION_STATUS 0xFF818586 ++/* */ ++ ++/* by Owen on 03/09/19-03/09/22 for RTL8185 */ ++#define OID_RT_WIRELESS_MODE 0xFF818500 ++#define OID_RT_SUPPORTED_RATES 0xFF818501 ++#define OID_RT_DESIRED_RATES 0xFF818502 ++#define OID_RT_WIRELESS_MODE_STARTING_ADHOC 0xFF818503 ++/* */ ++ ++#define OID_RT_GET_CONNECT_STATE 0xFF030001 ++#define OID_RT_RESCAN 0xFF030002 ++#define OID_RT_SET_KEY_LENGTH 0xFF030003 ++#define OID_RT_SET_DEFAULT_KEY_ID 0xFF030004 ++ ++#define OID_RT_SET_CHANNEL 0xFF010182 ++#define OID_RT_SET_SNIFFER_MODE 0xFF010183 ++#define OID_RT_GET_SIGNAL_QUALITY 0xFF010184 ++#define OID_RT_GET_SMALL_PACKET_CRC 0xFF010185 ++#define OID_RT_GET_MIDDLE_PACKET_CRC 0xFF010186 ++#define OID_RT_GET_LARGE_PACKET_CRC 0xFF010187 ++#define OID_RT_GET_TX_RETRY 0xFF010188 ++#define OID_RT_GET_RX_RETRY 0xFF010189 ++#define OID_RT_PRO_SET_FW_DIG_STATE 0xFF01018A/* S */ ++#define OID_RT_PRO_SET_FW_RA_STATE 0xFF01018B/* S */ ++ ++#define OID_RT_GET_RX_TOTAL_PACKET 0xFF010190 ++#define OID_RT_GET_TX_BEACON_OK 0xFF010191 ++#define OID_RT_GET_TX_BEACON_ERR 0xFF010192 ++#define OID_RT_GET_RX_ICV_ERR 0xFF010193 ++#define OID_RT_SET_ENCRYPTION_ALGORITHM 0xFF010194 ++#define OID_RT_SET_NO_AUTO_RESCAN 0xFF010195 ++#define OID_RT_GET_PREAMBLE_MODE 0xFF010196 ++#define OID_RT_GET_DRIVER_UP_DELTA_TIME 0xFF010197 ++#define OID_RT_GET_AP_IP 0xFF010198 ++#define OID_RT_GET_CHANNELPLAN 0xFF010199 ++#define OID_RT_SET_PREAMBLE_MODE 0xFF01019A ++#define OID_RT_SET_BCN_INTVL 0xFF01019B ++#define OID_RT_GET_RF_VENDER 0xFF01019C ++#define OID_RT_DEDICATE_PROBE 0xFF01019D ++#define OID_RT_PRO_RX_FILTER_PATTERN 0xFF01019E ++ ++#define OID_RT_GET_DCST_CURRENT_THRESHOLD 0xFF01019F ++ ++#define OID_RT_GET_CCA_ERR 0xFF0101A0 ++#define OID_RT_GET_CCA_UPGRADE_THRESHOLD 0xFF0101A1 ++#define OID_RT_GET_CCA_FALLBACK_THRESHOLD 0xFF0101A2 ++ ++#define OID_RT_GET_CCA_UPGRADE_EVALUATE_TIMES 0xFF0101A3 ++#define OID_RT_GET_CCA_FALLBACK_EVALUATE_TIMES 0xFF0101A4 ++ ++/* by Owen on 03/31/03 for Cameo's request */ ++#define OID_RT_SET_RATE_ADAPTIVE 0xFF0101A5 ++/* */ ++#define OID_RT_GET_DCST_EVALUATE_PERIOD 0xFF0101A5 ++#define OID_RT_GET_DCST_TIME_UNIT_INDEX 0xFF0101A6 ++#define OID_RT_GET_TOTAL_TX_BYTES 0xFF0101A7 ++#define OID_RT_GET_TOTAL_RX_BYTES 0xFF0101A8 ++#define OID_RT_CURRENT_TX_POWER_LEVEL 0xFF0101A9 ++#define OID_RT_GET_ENC_KEY_MISMATCH_COUNT 0xFF0101AA ++#define OID_RT_GET_ENC_KEY_MATCH_COUNT 0xFF0101AB ++#define OID_RT_GET_CHANNEL 0xFF0101AC ++ ++#define OID_RT_SET_CHANNELPLAN 0xFF0101AD ++#define OID_RT_GET_HARDWARE_RADIO_OFF 0xFF0101AE ++#define OID_RT_CHANNELPLAN_BY_COUNTRY 0xFF0101AF ++#define OID_RT_SCAN_AVAILABLE_BSSID 0xFF0101B0 ++#define OID_RT_GET_HARDWARE_VERSION 0xFF0101B1 ++#define OID_RT_GET_IS_ROAMING 0xFF0101B2 ++#define OID_RT_GET_IS_PRIVACY 0xFF0101B3 ++#define OID_RT_GET_KEY_MISMATCH 0xFF0101B4 ++#define OID_RT_SET_RSSI_ROAM_TRAFFIC_TH 0xFF0101B5 ++#define OID_RT_SET_RSSI_ROAM_SIGNAL_TH 0xFF0101B6 ++#define OID_RT_RESET_LOG 0xFF0101B7 ++#define OID_RT_GET_LOG 0xFF0101B8 ++#define OID_RT_SET_INDICATE_HIDDEN_AP 0xFF0101B9 ++#define OID_RT_GET_HEADER_FAIL 0xFF0101BA ++#define OID_RT_SUPPORTED_WIRELESS_MODE 0xFF0101BB ++#define OID_RT_GET_CHANNEL_LIST 0xFF0101BC ++#define OID_RT_GET_SCAN_IN_PROGRESS 0xFF0101BD ++#define OID_RT_GET_TX_INFO 0xFF0101BE ++#define OID_RT_RF_READ_WRITE_OFFSET 0xFF0101BF ++#define OID_RT_RF_READ_WRITE 0xFF0101C0 ++ ++/* For Netgear request. 2005.01.13, by rcnjko. */ ++#define OID_RT_FORCED_DATA_RATE 0xFF0101C1 ++#define OID_RT_WIRELESS_MODE_FOR_SCAN_LIST 0xFF0101C2 ++/* For Netgear request. 2005.02.17, by rcnjko. */ ++#define OID_RT_GET_BSS_WIRELESS_MODE 0xFF0101C3 ++/* For AZ project. 2005.06.27, by rcnjko. */ ++#define OID_RT_SCAN_WITH_MAGIC_PACKET 0xFF0101C4 ++ ++/* Vincent 8185MP */ ++#define OID_RT_PRO_RX_FILTER 0xFF0111C0 ++ ++#define OID_CE_USB_WRITE_REGISTRY 0xFF0111C1 ++#define OID_CE_USB_READ_REGISTRY 0xFF0111C2 ++ ++#define OID_RT_PRO_SET_INITIAL_GA 0xFF0111C3 ++#define OID_RT_PRO_SET_BB_RF_STANDBY_MODE 0xFF0111C4 ++#define OID_RT_PRO_SET_BB_RF_SHUTDOWN_MODE 0xFF0111C5 ++#define OID_RT_PRO_SET_TX_CHARGE_PUMP 0xFF0111C6 ++#define OID_RT_PRO_SET_RX_CHARGE_PUMP 0xFF0111C7 ++#define OID_RT_PRO_RF_WRITE_REGISTRY 0xFF0111C8 ++#define OID_RT_PRO_RF_READ_REGISTRY 0xFF0111C9 ++#define OID_RT_PRO_QUERY_RF_TYPE 0xFF0111CA ++ ++/* AP OID */ ++#define OID_RT_AP_GET_ASSOCIATED_STATION_LIST 0xFF010300 ++#define OID_RT_AP_GET_CURRENT_TIME_STAMP 0xFF010301 ++#define OID_RT_AP_SWITCH_INTO_AP_MODE 0xFF010302 ++#define OID_RT_AP_SET_DTIM_PERIOD 0xFF010303 ++/* Determine if driver supports AP mode. */ ++#define OID_RT_AP_SUPPORTED 0xFF010304 ++/* Set WPA-PSK passphrase into authenticator. */ ++#define OID_RT_AP_SET_PASSPHRASE 0xFF010305 ++ ++/* 8187MP. 2004.09.06, by rcnjko. */ ++#define OID_RT_PRO8187_WI_POLL 0xFF818780 ++#define OID_RT_PRO_WRITE_BB_REG 0xFF818781 ++#define OID_RT_PRO_READ_BB_REG 0xFF818782 ++#define OID_RT_PRO_WRITE_RF_REG 0xFF818783 ++#define OID_RT_PRO_READ_RF_REG 0xFF818784 ++ ++/* Meeting House. added by Annie, 2005-07-20. */ ++#define OID_RT_MH_VENDER_ID 0xFFEDC100 ++ ++/* 8711 MP OID added 20051230. */ ++#define OID_RT_PRO8711_JOIN_BSS 0xFF871100/* S */ ++ ++#define OID_RT_PRO_READ_REGISTER 0xFF871101 /* Q */ ++#define OID_RT_PRO_WRITE_REGISTER 0xFF871102 /* S */ ++ ++#define OID_RT_PRO_BURST_READ_REGISTER 0xFF871103 /* Q */ ++#define OID_RT_PRO_BURST_WRITE_REGISTER 0xFF871104 /* S */ ++ ++#define OID_RT_PRO_WRITE_TXCMD 0xFF871105 /* S */ ++ ++#define OID_RT_PRO_READ16_EEPROM 0xFF871106 /* Q */ ++#define OID_RT_PRO_WRITE16_EEPROM 0xFF871107 /* S */ ++ ++#define OID_RT_PRO_H2C_SET_COMMAND 0xFF871108 /* S */ ++#define OID_RT_PRO_H2C_QUERY_RESULT 0xFF871109 /* Q */ ++ ++#define OID_RT_PRO8711_WI_POLL 0xFF87110A /* Q */ ++#define OID_RT_PRO8711_PKT_LOSS 0xFF87110B /* Q */ ++#define OID_RT_RD_ATTRIB_MEM 0xFF87110C/* Q */ ++#define OID_RT_WR_ATTRIB_MEM 0xFF87110D/* S */ ++ ++/* Method 2 for H2C/C2H */ ++#define OID_RT_PRO_H2C_CMD_MODE 0xFF871110 /* S */ ++#define OID_RT_PRO_H2C_CMD_RSP_MODE 0xFF871111 /* Q */ ++#define OID_RT_PRO_H2C_CMD_EVENT_MODE 0xFF871112 /* S */ ++#define OID_RT_PRO_WAIT_C2H_EVENT 0xFF871113 /* Q */ ++#define OID_RT_PRO_RW_ACCESS_PROTOCOL_TEST 0xFF871114/* Q */ ++ ++#define OID_RT_PRO_SCSI_ACCESS_TEST 0xFF871115 /* Q, S */ ++ ++#define OID_RT_PRO_SCSI_TCPIPOFFLOAD_OUT 0xFF871116 /* S */ ++#define OID_RT_PRO_SCSI_TCPIPOFFLOAD_IN 0xFF871117 /* Q,S */ ++#define OID_RT_RRO_RX_PKT_VIA_IOCTRL 0xFF871118 /* Q */ ++#define OID_RT_RRO_RX_PKTARRAY_VIA_IOCTRL 0xFF871119 /* Q */ ++ ++#define OID_RT_RPO_SET_PWRMGT_TEST 0xFF87111A /* S */ ++#define OID_RT_PRO_QRY_PWRMGT_TEST 0XFF87111B /* Q */ ++#define OID_RT_RPO_ASYNC_RWIO_TEST 0xFF87111C /* S */ ++#define OID_RT_RPO_ASYNC_RWIO_POLL 0xFF87111D /* Q */ ++#define OID_RT_PRO_SET_RF_INTFS 0xFF87111E /* S */ ++#define OID_RT_POLL_RX_STATUS 0xFF87111F /* Q */ ++ ++#define OID_RT_PRO_CFG_DEBUG_MESSAGE 0xFF871120 /* Q,S */ ++#define OID_RT_PRO_SET_DATA_RATE_EX 0xFF871121/* S */ ++#define OID_RT_PRO_SET_BASIC_RATE 0xFF871122/* S */ ++#define OID_RT_PRO_READ_TSSI 0xFF871123/* S */ ++#define OID_RT_PRO_SET_POWER_TRACKING 0xFF871124/* S */ ++ ++#define OID_RT_PRO_QRY_PWRSTATE 0xFF871150 /* Q */ ++#define OID_RT_PRO_SET_PWRSTATE 0xFF871151 /* S */ ++ ++/* Method 2 , using workitem */ ++#define OID_RT_SET_READ_REG 0xFF871181 /* S */ ++#define OID_RT_SET_WRITE_REG 0xFF871182 /* S */ ++#define OID_RT_SET_BURST_READ_REG 0xFF871183 /* S */ ++#define OID_RT_SET_BURST_WRITE_REG 0xFF871184 /* S */ ++#define OID_RT_SET_WRITE_TXCMD 0xFF871185 /* S */ ++#define OID_RT_SET_READ16_EEPROM 0xFF871186 /* S */ ++#define OID_RT_SET_WRITE16_EEPROM 0xFF871187 /* S */ ++#define OID_RT_QRY_POLL_WKITEM 0xFF871188 /* Q */ ++ ++/* For SDIO INTERFACE only */ ++#define OID_RT_PRO_SYNCPAGERW_SRAM 0xFF8711A0 /* Q, S */ ++#define OID_RT_PRO_871X_DRV_EXT 0xFF8711A1 ++ ++/* For USB INTERFACE only */ ++#define OID_RT_PRO_USB_VENDOR_REQ 0xFF8711B0 /* Q, S */ ++#define OID_RT_PRO_SCSI_AUTO_TEST 0xFF8711B1 /* S */ ++#define OID_RT_PRO_USB_MAC_AC_FIFO_WRITE 0xFF8711B2 /* S */ ++#define OID_RT_PRO_USB_MAC_RX_FIFO_READ 0xFF8711B3 /* Q */ ++#define OID_RT_PRO_USB_MAC_RX_FIFO_POLLING 0xFF8711B4 /* Q */ ++ ++#define OID_RT_PRO_H2C_SET_RATE_TABLE 0xFF8711FB /* S */ ++#define OID_RT_PRO_H2C_GET_RATE_TABLE 0xFF8711FC /* S */ ++#define OID_RT_PRO_H2C_C2H_LBK_TEST 0xFF8711FE ++ ++#define OID_RT_PRO_ENCRYPTION_CTRL 0xFF871200 /* Q, S */ ++#define OID_RT_PRO_ADD_STA_INFO 0xFF871201 /* S */ ++#define OID_RT_PRO_DELE_STA_INFO 0xFF871202 /* S */ ++#define OID_RT_PRO_QUERY_DR_VARIABLE 0xFF871203 /* Q */ ++ ++#define OID_RT_PRO_RX_PACKET_TYPE 0xFF871204 /* Q, S */ ++ ++#define OID_RT_PRO_READ_EFUSE 0xFF871205 /* Q */ ++#define OID_RT_PRO_WRITE_EFUSE 0xFF871206 /* S */ ++#define OID_RT_PRO_RW_EFUSE_PGPKT 0xFF871207 /* Q, S */ ++#define OID_RT_GET_EFUSE_CURRENT_SIZE 0xFF871208 /* Q */ ++ ++#define OID_RT_SET_BANDWIDTH 0xFF871209 /* S */ ++#define OID_RT_SET_CRYSTAL_CAP 0xFF87120A /* S */ ++ ++#define OID_RT_SET_RX_PACKET_TYPE 0xFF87120B /* S */ ++ ++#define OID_RT_GET_EFUSE_MAX_SIZE 0xFF87120C /* Q */ ++ ++#define OID_RT_PRO_SET_TX_AGC_OFFSET 0xFF87120D /* S */ ++ ++#define OID_RT_PRO_SET_PKT_TEST_MODE 0xFF87120E /* S */ ++ ++#define OID_RT_PRO_FOR_EVM_TEST_SETTING 0xFF87120F /* S */ ++ ++#define OID_RT_PRO_GET_THERMAL_METER 0xFF871210 /* Q */ ++ ++#define OID_RT_RESET_PHY_RX_PACKET_COUNT 0xFF871211 /* S */ ++#define OID_RT_GET_PHY_RX_PACKET_RECEIVED 0xFF871212 /* Q */ ++#define OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR 0xFF871213 /* Q */ ++ ++#define OID_RT_SET_POWER_DOWN 0xFF871214 /* S */ ++ ++#define OID_RT_GET_POWER_MODE 0xFF871215 /* Q */ ++ ++#define OID_RT_PRO_EFUSE 0xFF871216 /* Q, S */ ++#define OID_RT_PRO_EFUSE_MAP 0xFF871217 /* Q, S */ ++ ++#endif /* ifndef __CUSTOM_OID_H */ +diff --git a/drivers/staging/r8188eu/include/odm.h b/drivers/staging/r8188eu/include/odm.h +new file mode 100644 +index 000000000000..d9041ee576bb +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm.h +@@ -0,0 +1,1154 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __HALDMOUTSRC_H__ ++#define __HALDMOUTSRC_H__ ++ ++/* Definition */ ++/* Define all team support ability. */ ++ ++/* Define for all teams. Please Define the constant in your precomp header. */ ++ ++/* define DM_ODM_SUPPORT_AP 0 */ ++/* define DM_ODM_SUPPORT_ADSL 0 */ ++/* define DM_ODM_SUPPORT_CE 0 */ ++/* define DM_ODM_SUPPORT_MP 1 */ ++ ++/* Define ODM SW team support flag. */ ++ ++/* Antenna Switch Relative Definition. */ ++ ++/* Add new function SwAntDivCheck8192C(). */ ++/* This is the main function of Antenna diversity function before link. */ ++/* Mainly, it just retains last scan result and scan again. */ ++/* After that, it compares the scan result to see which one gets better ++ * RSSI. It selects antenna with better receiving power and returns better ++ * scan result. */ ++ ++#define TP_MODE 0 ++#define RSSI_MODE 1 ++#define TRAFFIC_LOW 0 ++#define TRAFFIC_HIGH 1 ++ ++/* 3 Tx Power Tracking */ ++/* 3============================================================ */ ++#define DPK_DELTA_MAPPING_NUM 13 ++#define index_mapping_HP_NUM 15 ++ ++/* */ ++/* 3 PSD Handler */ ++/* 3============================================================ */ ++ ++#define AFH_PSD 1 /* 0:normal PSD scan, 1: only do 20 pts PSD */ ++#define MODE_40M 0 /* 0:20M, 1:40M */ ++#define PSD_TH2 3 ++#define PSD_CHM 20 /* Minimum channel number for BT AFH */ ++#define SIR_STEP_SIZE 3 ++#define Smooth_Size_1 5 ++#define Smooth_TH_1 3 ++#define Smooth_Size_2 10 ++#define Smooth_TH_2 4 ++#define Smooth_Size_3 20 ++#define Smooth_TH_3 4 ++#define Smooth_Step_Size 5 ++#define Adaptive_SIR 1 ++#define PSD_RESCAN 4 ++#define PSD_SCAN_INTERVAL 700 /* ms */ ++ ++/* 8723A High Power IGI Setting */ ++#define DM_DIG_HIGH_PWR_IGI_LOWER_BOUND 0x22 ++#define DM_DIG_Gmode_HIGH_PWR_IGI_LOWER_BOUND 0x28 ++#define DM_DIG_HIGH_PWR_THRESHOLD 0x3a ++ ++/* LPS define */ ++#define DM_DIG_FA_TH0_LPS 4 /* 4 in lps */ ++#define DM_DIG_FA_TH1_LPS 15 /* 15 lps */ ++#define DM_DIG_FA_TH2_LPS 30 /* 30 lps */ ++#define RSSI_OFFSET_DIG 0x05; ++ ++/* ANT Test */ ++#define ANTTESTALL 0x00 /* Ant A or B will be Testing */ ++#define ANTTESTA 0x01 /* Ant A will be Testing */ ++#define ANTTESTB 0x02 /* Ant B will be testing */ ++ ++/* structure and define */ ++ ++/* Add for AP/ADSLpseudo DM structuer requirement. */ ++/* We need to remove to other position??? */ ++struct rtl8192cd_priv { ++ u8 temp; ++}; ++ ++struct rtw_dig { ++ u8 Dig_Enable_Flag; ++ u8 Dig_Ext_Port_Stage; ++ ++ int RssiLowThresh; ++ int RssiHighThresh; ++ ++ u32 FALowThresh; ++ u32 FAHighThresh; ++ ++ u8 CurSTAConnectState; ++ u8 PreSTAConnectState; ++ u8 CurMultiSTAConnectState; ++ ++ u8 PreIGValue; ++ u8 CurIGValue; ++ u8 BackupIGValue; ++ ++ s8 BackoffVal; ++ s8 BackoffVal_range_max; ++ s8 BackoffVal_range_min; ++ u8 rx_gain_range_max; ++ u8 rx_gain_range_min; ++ u8 Rssi_val_min; ++ ++ u8 PreCCK_CCAThres; ++ u8 CurCCK_CCAThres; ++ u8 PreCCKPDState; ++ u8 CurCCKPDState; ++ ++ u8 LargeFAHit; ++ u8 ForbiddenIGI; ++ u32 Recover_cnt; ++ ++ u8 DIG_Dynamic_MIN_0; ++ u8 DIG_Dynamic_MIN_1; ++ bool bMediaConnect_0; ++ bool bMediaConnect_1; ++ ++ u32 AntDiv_RSSI_max; ++ u32 RSSI_max; ++}; ++ ++struct rtl_ps { ++ u8 pre_cca_state; ++ u8 cur_cca_state; ++ ++ u8 pre_rf_state; ++ u8 cur_rf_state; ++ ++ int rssi_val_min; ++ ++ u8 initialize; ++ u32 reg_874; ++ u32 reg_c70; ++ u32 reg_85c; ++ u32 reg_a74; ++ ++}; ++ ++struct false_alarm_stats { ++ u32 Cnt_Parity_Fail; ++ u32 Cnt_Rate_Illegal; ++ u32 Cnt_Crc8_fail; ++ u32 Cnt_Mcs_fail; ++ u32 Cnt_Ofdm_fail; ++ u32 Cnt_Cck_fail; ++ u32 Cnt_all; ++ u32 Cnt_Fast_Fsync; ++ u32 Cnt_SB_Search_fail; ++ u32 Cnt_OFDM_CCA; ++ u32 Cnt_CCK_CCA; ++ u32 Cnt_CCA_all; ++ u32 Cnt_BW_USC; /* Gary */ ++ u32 Cnt_BW_LSC; /* Gary */ ++}; ++ ++struct dyn_primary_cca { ++ u8 pri_cca_flag; ++ u8 intf_flag; ++ u8 intf_type; ++ u8 dup_rts_flag; ++ u8 monitor_flag; ++}; ++ ++struct rx_hpc { ++ u8 RXHP_flag; ++ u8 PSD_func_trigger; ++ u8 PSD_bitmap_RXHP[80]; ++ u8 Pre_IGI; ++ u8 Cur_IGI; ++ u8 Pre_pw_th; ++ u8 Cur_pw_th; ++ bool First_time_enter; ++ bool RXHP_enable; ++ u8 TP_Mode; ++ struct timer_list PSDTimer; ++}; ++ ++#define ASSOCIATE_ENTRY_NUM 32 /* Max size of AsocEntry[]. */ ++#define ODM_ASSOCIATE_ENTRY_NUM ASSOCIATE_ENTRY_NUM ++ ++/* This indicates two different steps. */ ++/* In SWAW_STEP_PEAK, driver needs to switch antenna and listen to ++ * the signal on the air. */ ++/* In SWAW_STEP_DETERMINE, driver just compares the signal captured in ++ * SWAW_STEP_PEAK with original RSSI to determine if it is necessary to ++ * switch antenna. */ ++ ++#define SWAW_STEP_PEAK 0 ++#define SWAW_STEP_DETERMINE 1 ++ ++#define TP_MODE 0 ++#define RSSI_MODE 1 ++#define TRAFFIC_LOW 0 ++#define TRAFFIC_HIGH 1 ++ ++struct sw_ant_switch { ++ u8 try_flag; ++ s32 PreRSSI; ++ u8 CurAntenna; ++ u8 PreAntenna; ++ u8 RSSI_Trying; ++ u8 TestMode; ++ u8 bTriggerAntennaSwitch; ++ u8 SelectAntennaMap; ++ u8 RSSI_target; ++ ++ /* Before link Antenna Switch check */ ++ u8 SWAS_NoLink_State; ++ u32 SWAS_NoLink_BK_Reg860; ++ bool ANTA_ON; /* To indicate Ant A is or not */ ++ bool ANTB_ON; /* To indicate Ant B is on or not */ ++ ++ s32 RSSI_sum_A; ++ s32 RSSI_sum_B; ++ s32 RSSI_cnt_A; ++ s32 RSSI_cnt_B; ++ u64 lastTxOkCnt; ++ u64 lastRxOkCnt; ++ u64 TXByteCnt_A; ++ u64 TXByteCnt_B; ++ u64 RXByteCnt_A; ++ u64 RXByteCnt_B; ++ u8 TrafficLoad; ++ struct timer_list SwAntennaSwitchTimer; ++ /* Hybrid Antenna Diversity */ ++ u32 CCK_Ant1_Cnt[ASSOCIATE_ENTRY_NUM]; ++ u32 CCK_Ant2_Cnt[ASSOCIATE_ENTRY_NUM]; ++ u32 OFDM_Ant1_Cnt[ASSOCIATE_ENTRY_NUM]; ++ u32 OFDM_Ant2_Cnt[ASSOCIATE_ENTRY_NUM]; ++ u32 RSSI_Ant1_Sum[ASSOCIATE_ENTRY_NUM]; ++ u32 RSSI_Ant2_Sum[ASSOCIATE_ENTRY_NUM]; ++ u8 TxAnt[ASSOCIATE_ENTRY_NUM]; ++ u8 TargetSTA; ++ u8 antsel; ++ u8 RxIdleAnt; ++}; ++ ++struct edca_turbo { ++ bool bCurrentTurboEDCA; ++ bool bIsCurRDLState; ++ u32 prv_traffic_idx; /* edca turbo */ ++}; ++ ++struct odm_rate_adapt { ++ u8 Type; /* DM_Type_ByFW/DM_Type_ByDriver */ ++ u8 HighRSSIThresh; /* if RSSI > HighRSSIThresh => RATRState is DM_RATR_STA_HIGH */ ++ u8 LowRSSIThresh; /* if RSSI <= LowRSSIThresh => RATRState is DM_RATR_STA_LOW */ ++ u8 RATRState; /* Current RSSI level, DM_RATR_STA_HIGH/DM_RATR_STA_MIDDLE/DM_RATR_STA_LOW */ ++ u32 LastRATR; /* RATR Register Content */ ++}; ++ ++#define IQK_MAC_REG_NUM 4 ++#define IQK_ADDA_REG_NUM 16 ++#define IQK_BB_REG_NUM_MAX 10 ++#define IQK_BB_REG_NUM 9 ++#define HP_THERMAL_NUM 8 ++ ++#define AVG_THERMAL_NUM 8 ++#define IQK_Matrix_REG_NUM 8 ++#define IQK_Matrix_Settings_NUM 1+24+21 ++ ++#define DM_Type_ByFWi 0 ++#define DM_Type_ByDriver 1 ++ ++/* Declare for common info */ ++ ++struct odm_phy_status_info { ++ u8 RxPWDBAll; ++ u8 SignalQuality; /* in 0-100 index. */ ++ u8 RxMIMOSignalQuality[MAX_PATH_NUM_92CS]; /* EVM */ ++ u8 RxMIMOSignalStrength[MAX_PATH_NUM_92CS];/* in 0~100 index */ ++ s8 RxPower; /* in dBm Translate from PWdB */ ++ s8 RecvSignalPower;/* Real power in dBm for this packet, no ++ * beautification and aggregation. Keep this raw ++ * info to be used for the other procedures. */ ++ u8 BTRxRSSIPercentage; ++ u8 SignalStrength; /* in 0-100 index. */ ++ u8 RxPwr[MAX_PATH_NUM_92CS];/* per-path's pwdb */ ++ u8 RxSNR[MAX_PATH_NUM_92CS];/* per-path's SNR */ ++}; ++ ++struct odm_phy_dbg_info { ++ /* ODM Write,debug info */ ++ s8 RxSNRdB[MAX_PATH_NUM_92CS]; ++ u64 NumQryPhyStatus; ++ u64 NumQryPhyStatusCCK; ++ u64 NumQryPhyStatusOFDM; ++ /* Others */ ++ s32 RxEVM[MAX_PATH_NUM_92CS]; ++}; ++ ++struct odm_per_pkt_info { ++ s8 Rate; ++ u8 StationID; ++ bool bPacketMatchBSSID; ++ bool bPacketToSelf; ++ bool bPacketBeacon; ++}; ++ ++struct odm_mac_status_info { ++ u8 test; ++}; ++ ++enum odm_ability { ++ /* BB Team */ ++ ODM_DIG = 0x00000001, ++ ODM_HIGH_POWER = 0x00000002, ++ ODM_CCK_CCA_TH = 0x00000004, ++ ODM_FA_STATISTICS = 0x00000008, ++ ODM_RAMASK = 0x00000010, ++ ODM_RSSI_MONITOR = 0x00000020, ++ ODM_SW_ANTDIV = 0x00000040, ++ ODM_HW_ANTDIV = 0x00000080, ++ ODM_BB_PWRSV = 0x00000100, ++ ODM_2TPATHDIV = 0x00000200, ++ ODM_1TPATHDIV = 0x00000400, ++ ODM_PSD2AFH = 0x00000800 ++}; ++ ++/* 2011/20/20 MH For MP driver RT_WLAN_STA = struct sta_info */ ++/* Please declare below ODM relative info in your STA info structure. */ ++ ++struct odm_sta_info { ++ /* Driver Write */ ++ bool bUsed; /* record the sta status link or not? */ ++ u8 IOTPeer; /* Enum value. HT_IOT_PEER_E */ ++ ++ /* ODM Write */ ++ /* 1 PHY_STATUS_INFO */ ++ u8 RSSI_Path[4]; /* */ ++ u8 RSSI_Ave; ++ u8 RXEVM[4]; ++ u8 RXSNR[4]; ++}; ++ ++/* 2011/10/20 MH Define Common info enum for all team. */ ++ ++enum odm_common_info_def { ++ /* Fixed value: */ ++ ++ /* HOOK BEFORE REG INIT----------- */ ++ ODM_CMNINFO_PLATFORM = 0, ++ ODM_CMNINFO_ABILITY, /* ODM_ABILITY_E */ ++ ODM_CMNINFO_INTERFACE, /* ODM_INTERFACE_E */ ++ ODM_CMNINFO_MP_TEST_CHIP, ++ ODM_CMNINFO_IC_TYPE, /* ODM_IC_TYPE_E */ ++ ODM_CMNINFO_CUT_VER, /* ODM_CUT_VERSION_E */ ++ ODM_CMNINFO_FAB_VER, /* ODM_FAB_E */ ++ ODM_CMNINFO_RF_TYPE, /* RF_PATH_E or ODM_RF_TYPE_E? */ ++ ODM_CMNINFO_BOARD_TYPE, /* ODM_BOARD_TYPE_E */ ++ ODM_CMNINFO_EXT_LNA, /* true */ ++ ODM_CMNINFO_EXT_PA, ++ ODM_CMNINFO_EXT_TRSW, ++ ODM_CMNINFO_PATCH_ID, /* CUSTOMER ID */ ++ ODM_CMNINFO_BINHCT_TEST, ++ ODM_CMNINFO_BWIFI_TEST, ++ ODM_CMNINFO_SMART_CONCURRENT, ++ /* HOOK BEFORE REG INIT----------- */ ++ ++ /* Dynamic value: */ ++/* POINTER REFERENCE----------- */ ++ ODM_CMNINFO_MAC_PHY_MODE, /* ODM_MAC_PHY_MODE_E */ ++ ODM_CMNINFO_TX_UNI, ++ ODM_CMNINFO_RX_UNI, ++ ODM_CMNINFO_WM_MODE, /* ODM_WIRELESS_MODE_E */ ++ ODM_CMNINFO_BAND, /* ODM_BAND_TYPE_E */ ++ ODM_CMNINFO_SEC_CHNL_OFFSET, /* ODM_SEC_CHNL_OFFSET_E */ ++ ODM_CMNINFO_SEC_MODE, /* ODM_SECURITY_E */ ++ ODM_CMNINFO_BW, /* ODM_BW_E */ ++ ODM_CMNINFO_CHNL, ++ ++ ODM_CMNINFO_DMSP_GET_VALUE, ++ ODM_CMNINFO_BUDDY_ADAPTOR, ++ ODM_CMNINFO_DMSP_IS_MASTER, ++ ODM_CMNINFO_SCAN, ++ ODM_CMNINFO_POWER_SAVING, ++ ODM_CMNINFO_ONE_PATH_CCA, /* ODM_CCA_PATH_E */ ++ ODM_CMNINFO_DRV_STOP, ++ ODM_CMNINFO_PNP_IN, ++ ODM_CMNINFO_INIT_ON, ++ ODM_CMNINFO_ANT_TEST, ++ ODM_CMNINFO_NET_CLOSED, ++ ODM_CMNINFO_MP_MODE, ++/* POINTER REFERENCE----------- */ ++ ++/* CALL BY VALUE------------- */ ++ ODM_CMNINFO_WIFI_DIRECT, ++ ODM_CMNINFO_WIFI_DISPLAY, ++ ODM_CMNINFO_LINK, ++ ODM_CMNINFO_RSSI_MIN, ++ ODM_CMNINFO_RA_THRESHOLD_HIGH, /* u8 */ ++ ODM_CMNINFO_RA_THRESHOLD_LOW, /* u8 */ ++ ODM_CMNINFO_RF_ANTENNA_TYPE, /* u8 */ ++ ODM_CMNINFO_BT_DISABLED, ++ ODM_CMNINFO_BT_OPERATION, ++ ODM_CMNINFO_BT_DIG, ++ ODM_CMNINFO_BT_BUSY, /* Check Bt is using or not */ ++ ODM_CMNINFO_BT_DISABLE_EDCA, ++/* CALL BY VALUE-------------*/ ++ ++ /* Dynamic ptr array hook itms. */ ++ ODM_CMNINFO_STA_STATUS, ++ ODM_CMNINFO_PHY_STATUS, ++ ODM_CMNINFO_MAC_STATUS, ++ ODM_CMNINFO_MAX, ++}; ++ ++/* 2011/10/20 MH Define ODM support ability. ODM_CMNINFO_ABILITY */ ++ ++enum odm_ability_def { ++ /* BB ODM section BIT 0-15 */ ++ ODM_BB_DIG = BIT(0), ++ ODM_BB_RA_MASK = BIT(1), ++ ODM_BB_DYNAMIC_TXPWR = BIT(2), ++ ODM_BB_FA_CNT = BIT(3), ++ ODM_BB_RSSI_MONITOR = BIT(4), ++ ODM_BB_CCK_PD = BIT(5), ++ ODM_BB_ANT_DIV = BIT(6), ++ ODM_BB_PWR_SAVE = BIT(7), ++ ODM_BB_PWR_TRA = BIT(8), ++ ODM_BB_RATE_ADAPTIVE = BIT(9), ++ ODM_BB_PATH_DIV = BIT(10), ++ ODM_BB_PSD = BIT(11), ++ ODM_BB_RXHP = BIT(12), ++ ++ /* MAC DM section BIT 16-23 */ ++ ODM_MAC_EDCA_TURBO = BIT(16), ++ ODM_MAC_EARLY_MODE = BIT(17), ++ ++ /* RF ODM section BIT 24-31 */ ++ ODM_RF_TX_PWR_TRACK = BIT(24), ++ ODM_RF_RX_GAIN_TRACK = BIT(25), ++ ODM_RF_CALIBRATION = BIT(26), ++}; ++ ++/* ODM_CMNINFO_INTERFACE */ ++enum odm_interface_def { ++ ODM_ITRF_PCIE = 0x1, ++ ODM_ITRF_USB = 0x2, ++ ODM_ITRF_SDIO = 0x4, ++ ODM_ITRF_ALL = 0x7, ++}; ++ ++/* ODM_CMNINFO_IC_TYPE */ ++enum odm_ic_type { ++ ODM_RTL8192S = BIT(0), ++ ODM_RTL8192C = BIT(1), ++ ODM_RTL8192D = BIT(2), ++ ODM_RTL8723A = BIT(3), ++ ODM_RTL8188E = BIT(4), ++ ODM_RTL8812 = BIT(5), ++ ODM_RTL8821 = BIT(6), ++}; ++ ++#define ODM_IC_11N_SERIES \ ++ (ODM_RTL8192S | ODM_RTL8192C | ODM_RTL8192D | \ ++ ODM_RTL8723A | ODM_RTL8188E) ++#define ODM_IC_11AC_SERIES (ODM_RTL8812) ++ ++/* ODM_CMNINFO_CUT_VER */ ++enum odm_cut_version { ++ ODM_CUT_A = 1, ++ ODM_CUT_B = 2, ++ ODM_CUT_C = 3, ++ ODM_CUT_D = 4, ++ ODM_CUT_E = 5, ++ ODM_CUT_F = 6, ++ ODM_CUT_TEST = 7, ++}; ++ ++/* ODM_CMNINFO_FAB_VER */ ++enum odm_fab_Version { ++ ODM_TSMC = 0, ++ ODM_UMC = 1, ++}; ++ ++/* ODM_CMNINFO_RF_TYPE */ ++/* For example 1T2R (A+AB = BIT(0)|BIT(4)|BIT(5)) */ ++enum odm_rf_path { ++ ODM_RF_TX_A = BIT(0), ++ ODM_RF_TX_B = BIT(1), ++ ODM_RF_TX_C = BIT(2), ++ ODM_RF_TX_D = BIT(3), ++ ODM_RF_RX_A = BIT(4), ++ ODM_RF_RX_B = BIT(5), ++ ODM_RF_RX_C = BIT(6), ++ ODM_RF_RX_D = BIT(7), ++}; ++ ++enum odm_rf_type { ++ ODM_1T1R = 0, ++ ODM_1T2R = 1, ++ ODM_2T2R = 2, ++ ODM_2T3R = 3, ++ ODM_2T4R = 4, ++ ODM_3T3R = 5, ++ ODM_3T4R = 6, ++ ODM_4T4R = 7, ++}; ++ ++/* ODM Dynamic common info value definition */ ++ ++enum odm_mac_phy_mode { ++ ODM_SMSP = 0, ++ ODM_DMSP = 1, ++ ODM_DMDP = 2, ++}; ++ ++enum odm_bt_coexist { ++ ODM_BT_BUSY = 1, ++ ODM_BT_ON = 2, ++ ODM_BT_OFF = 3, ++ ODM_BT_NONE = 4, ++}; ++ ++/* ODM_CMNINFO_OP_MODE */ ++enum odm_operation_mode { ++ ODM_NO_LINK = BIT(0), ++ ODM_LINK = BIT(1), ++ ODM_SCAN = BIT(2), ++ ODM_POWERSAVE = BIT(3), ++ ODM_AP_MODE = BIT(4), ++ ODM_CLIENT_MODE = BIT(5), ++ ODM_AD_HOC = BIT(6), ++ ODM_WIFI_DIRECT = BIT(7), ++ ODM_WIFI_DISPLAY = BIT(8), ++}; ++ ++/* ODM_CMNINFO_WM_MODE */ ++enum odm_wireless_mode { ++ ODM_WM_UNKNOW = 0x0, ++ ODM_WM_B = BIT(0), ++ ODM_WM_G = BIT(1), ++ ODM_WM_N24G = BIT(3), ++ ODM_WM_AUTO = BIT(5), ++}; ++ ++/* ODM_CMNINFO_BAND */ ++enum odm_band_type { ++ ODM_BAND_2_4G = BIT(0), ++}; ++ ++/* ODM_CMNINFO_SEC_CHNL_OFFSET */ ++enum odm_sec_chnl_offset { ++ ODM_DONT_CARE = 0, ++ ODM_BELOW = 1, ++ ODM_ABOVE = 2 ++}; ++ ++/* ODM_CMNINFO_SEC_MODE */ ++enum odm_security { ++ ODM_SEC_OPEN = 0, ++ ODM_SEC_WEP40 = 1, ++ ODM_SEC_TKIP = 2, ++ ODM_SEC_RESERVE = 3, ++ ODM_SEC_AESCCMP = 4, ++ ODM_SEC_WEP104 = 5, ++ ODM_WEP_WPA_MIXED = 6, /* WEP + WPA */ ++ ODM_SEC_SMS4 = 7, ++}; ++ ++/* ODM_CMNINFO_BW */ ++enum odm_bw { ++ ODM_BW20M = 0, ++ ODM_BW40M = 1, ++}; ++ ++/* ODM_CMNINFO_BOARD_TYPE */ ++enum odm_board_type { ++ ODM_BOARD_NORMAL = 0, ++ ODM_BOARD_HIGHPWR = 1, ++ ODM_BOARD_MINICARD = 2, ++ ODM_BOARD_SLIM = 3, ++ ODM_BOARD_COMBO = 4, ++}; ++ ++/* ODM_CMNINFO_ONE_PATH_CCA */ ++enum odm_cca_path { ++ ODM_CCA_2R = 0, ++ ODM_CCA_1R_A = 1, ++ ODM_CCA_1R_B = 2, ++}; ++ ++struct odm_ra_info { ++ u8 RateID; ++ u32 RateMask; ++ u32 RAUseRate; ++ u8 RateSGI; ++ u8 RssiStaRA; ++ u8 PreRssiStaRA; ++ u8 SGIEnable; ++ u8 DecisionRate; ++ u8 PreRate; ++ u8 HighestRate; ++ u8 LowestRate; ++ u32 NscUp; ++ u32 NscDown; ++ u16 RTY[5]; ++ u32 TOTAL; ++ u16 DROP; ++ u8 Active; ++ u16 RptTime; ++ u8 RAWaitingCounter; ++ u8 RAPendingCounter; ++ u8 PTActive; /* on or off */ ++ u8 PTTryState; /* 0 trying state, 1 for decision state */ ++ u8 PTStage; /* 0~6 */ ++ u8 PTStopCount; /* Stop PT counter */ ++ u8 PTPreRate; /* if rate change do PT */ ++ u8 PTPreRssi; /* if RSSI change 5% do PT */ ++ u8 PTModeSS; /* decide whitch rate should do PT */ ++ u8 RAstage; /* StageRA, decide how many times RA will be done ++ * between PT */ ++ u8 PTSmoothFactor; ++}; ++ ++struct ijk_matrix_regs_set { ++ bool bIQKDone; ++ s32 Value[1][IQK_Matrix_REG_NUM]; ++}; ++ ++struct odm_rf_cal { ++ /* for tx power tracking */ ++ u32 RegA24; /* for TempCCK */ ++ s32 RegE94; ++ s32 RegE9C; ++ s32 RegEB4; ++ s32 RegEBC; ++ ++ u8 TXPowercount; ++ bool bTXPowerTrackingInit; ++ bool bTXPowerTracking; ++ u8 TxPowerTrackControl; /* for mp mode, turn off txpwrtracking ++ * as default */ ++ u8 TM_Trigger; ++ u8 InternalPA5G[2]; /* pathA / pathB */ ++ ++ u8 ThermalMeter[2]; /* ThermalMeter, index 0 for RFIC0, ++ * and 1 for RFIC1 */ ++ u8 ThermalValue; ++ u8 ThermalValue_LCK; ++ u8 ThermalValue_IQK; ++ u8 ThermalValue_DPK; ++ u8 ThermalValue_AVG[AVG_THERMAL_NUM]; ++ u8 ThermalValue_AVG_index; ++ u8 ThermalValue_RxGain; ++ u8 ThermalValue_Crystal; ++ u8 ThermalValue_DPKstore; ++ u8 ThermalValue_DPKtrack; ++ bool TxPowerTrackingInProgress; ++ bool bDPKenable; ++ ++ bool bReloadtxpowerindex; ++ u8 bRfPiEnable; ++ u32 TXPowerTrackingCallbackCnt; /* cosa add for debug */ ++ ++ u8 bCCKinCH14; ++ u8 CCK_index; ++ u8 OFDM_index[2]; ++ bool bDoneTxpower; ++ ++ u8 ThermalValue_HP[HP_THERMAL_NUM]; ++ u8 ThermalValue_HP_index; ++ struct ijk_matrix_regs_set IQKMatrixRegSetting[IQK_Matrix_Settings_NUM]; ++ ++ u8 Delta_IQK; ++ u8 Delta_LCK; ++ ++ /* for IQK */ ++ u32 RegC04; ++ u32 Reg874; ++ u32 RegC08; ++ u32 RegB68; ++ u32 RegB6C; ++ u32 Reg870; ++ u32 Reg860; ++ u32 Reg864; ++ ++ bool bIQKInitialized; ++ bool bLCKInProgress; ++ bool bAntennaDetected; ++ u32 ADDA_backup[IQK_ADDA_REG_NUM]; ++ u32 IQK_MAC_backup[IQK_MAC_REG_NUM]; ++ u32 IQK_BB_backup_recover[9]; ++ u32 IQK_BB_backup[IQK_BB_REG_NUM]; ++ ++ /* for APK */ ++ u32 APKoutput[2][2]; /* path A/B; output1_1a/output1_2a */ ++ u8 bAPKdone; ++ u8 bAPKThermalMeterIgnore; ++ u8 bDPdone; ++ u8 bDPPathAOK; ++ u8 bDPPathBOK; ++}; ++ ++/* ODM Dynamic common info value definition */ ++ ++struct fast_ant_train { ++ u8 Bssid[6]; ++ u8 antsel_rx_keep_0; ++ u8 antsel_rx_keep_1; ++ u8 antsel_rx_keep_2; ++ u32 antSumRSSI[7]; ++ u32 antRSSIcnt[7]; ++ u32 antAveRSSI[7]; ++ u8 FAT_State; ++ u32 TrainIdx; ++ u8 antsel_a[ODM_ASSOCIATE_ENTRY_NUM]; ++ u8 antsel_b[ODM_ASSOCIATE_ENTRY_NUM]; ++ u8 antsel_c[ODM_ASSOCIATE_ENTRY_NUM]; ++ u32 MainAnt_Sum[ODM_ASSOCIATE_ENTRY_NUM]; ++ u32 AuxAnt_Sum[ODM_ASSOCIATE_ENTRY_NUM]; ++ u32 MainAnt_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; ++ u32 AuxAnt_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; ++ u8 RxIdleAnt; ++ bool bBecomeLinked; ++}; ++ ++enum fat_state { ++ FAT_NORMAL_STATE = 0, ++ FAT_TRAINING_STATE = 1, ++}; ++ ++enum ant_div_type { ++ NO_ANTDIV = 0xFF, ++ CG_TRX_HW_ANTDIV = 0x01, ++ CGCS_RX_HW_ANTDIV = 0x02, ++ FIXED_HW_ANTDIV = 0x03, ++ CG_TRX_SMART_ANTDIV = 0x04, ++ CGCS_RX_SW_ANTDIV = 0x05, ++}; ++ ++/* Copy from SD4 defined structure. We use to support PHY DM integration. */ ++struct odm_dm_struct { ++ /* Add for different team use temporarily */ ++ struct adapter *Adapter; /* For CE/NIC team */ ++ struct rtl8192cd_priv *priv; /* For AP/ADSL team */ ++ /* WHen you use above pointers, they must be initialized. */ ++ bool odm_ready; ++ ++ struct rtl8192cd_priv *fake_priv; ++ ++/* ODM HANDLE, DRIVER NEEDS NOT TO HOOK------ */ ++ bool bCckHighPower; ++ u8 RFPathRxEnable; /* ODM_CMNINFO_RFPATH_ENABLE */ ++ u8 ControlChannel; ++/* ODM HANDLE, DRIVER NEEDS NOT TO HOOK------ */ ++ ++/* 1 COMMON INFORMATION */ ++ /* Init Value */ ++/* HOOK BEFORE REG INIT----------- */ ++ /* ODM Platform info AP/ADSL/CE/MP = 1/2/3/4 */ ++ u8 SupportPlatform; ++ /* ODM Support Ability DIG/RATR/TX_PWR_TRACK/ �K�K = 1/2/3/�K */ ++ u32 SupportAbility; ++ /* ODM PCIE/USB/SDIO/GSPI = 0/1/2/3 */ ++ u8 SupportInterface; ++ /* ODM composite or independent. Bit oriented/ 92C+92D+ .... or any ++ * other type = 1/2/3/... */ ++ u32 SupportICType; ++ /* Cut Version TestChip/A-cut/B-cut... = 0/1/2/3/... */ ++ u8 CutVersion; ++ /* Fab Version TSMC/UMC = 0/1 */ ++ u8 FabVersion; ++ /* RF Type 4T4R/3T3R/2T2R/1T2R/1T1R/... */ ++ u8 RFType; ++ /* Board Type Normal/HighPower/MiniCard/SLIM/Combo/. = 0/1/2/3/4/. */ ++ u8 BoardType; ++ /* with external LNA NO/Yes = 0/1 */ ++ u8 ExtLNA; ++ /* with external PA NO/Yes = 0/1 */ ++ u8 ExtPA; ++ /* with external TRSW NO/Yes = 0/1 */ ++ u8 ExtTRSW; ++ u8 PatchID; /* Customer ID */ ++ bool bInHctTest; ++ bool bWIFITest; ++ ++ bool bDualMacSmartConcurrent; ++ u32 BK_SupportAbility; ++ u8 AntDivType; ++/* HOOK BEFORE REG INIT----------- */ ++ ++ /* Dynamic Value */ ++/* POINTER REFERENCE----------- */ ++ ++ u8 u8_temp; ++ bool bool_temp; ++ struct adapter *adapter_temp; ++ ++ /* MAC PHY Mode SMSP/DMSP/DMDP = 0/1/2 */ ++ u8 *pMacPhyMode; ++ /* TX Unicast byte count */ ++ u64 *pNumTxBytesUnicast; ++ /* RX Unicast byte count */ ++ u64 *pNumRxBytesUnicast; ++ /* Wireless mode B/G/A/N = BIT(0)/BIT(1)/BIT(2)/BIT(3) */ ++ u8 *pWirelessMode; /* ODM_WIRELESS_MODE_E */ ++ /* Frequence band 2.4G/5G = 0/1 */ ++ u8 *pBandType; ++ /* Secondary channel offset don't_care/below/above = 0/1/2 */ ++ u8 *pSecChOffset; ++ /* Security mode Open/WEP/AES/TKIP = 0/1/2/3 */ ++ u8 *pSecurity; ++ /* BW info 20M/40M/80M = 0/1/2 */ ++ u8 *pBandWidth; ++ /* Central channel location Ch1/Ch2/.... */ ++ u8 *pChannel; /* central channel number */ ++ /* Common info for 92D DMSP */ ++ ++ bool *pbGetValueFromOtherMac; ++ struct adapter **pBuddyAdapter; ++ bool *pbMasterOfDMSP; /* MAC0: master, MAC1: slave */ ++ /* Common info for Status */ ++ bool *pbScanInProcess; ++ bool *pbPowerSaving; ++ /* CCA Path 2-path/path-A/path-B = 0/1/2; using ODM_CCA_PATH_E. */ ++ u8 *pOnePathCCA; ++ /* pMgntInfo->AntennaTest */ ++ u8 *pAntennaTest; ++ bool *pbNet_closed; ++/* POINTER REFERENCE----------- */ ++ /* */ ++/* CALL BY VALUE------------- */ ++ bool bWIFI_Direct; ++ bool bWIFI_Display; ++ bool bLinked; ++ u8 RSSI_Min; ++ u8 InterfaceIndex; /* Add for 92D dual MAC: 0--Mac0 1--Mac1 */ ++ bool bIsMPChip; ++ bool bOneEntryOnly; ++ /* Common info for BTDM */ ++ bool bBtDisabled; /* BT is disabled */ ++ bool bBtHsOperation; /* BT HS mode is under progress */ ++ u8 btHsDigVal; /* use BT rssi to decide the DIG value */ ++ bool bBtDisableEdcaTurbo;/* Under some condition, don't enable the ++ * EDCA Turbo */ ++ bool bBtBusy; /* BT is busy. */ ++/* CALL BY VALUE------------- */ ++ ++ /* 2 Define STA info. */ ++ /* _ODM_STA_INFO */ ++ /* For MP, we need to reduce one array pointer for default port.?? */ ++ struct sta_info *pODM_StaInfo[ODM_ASSOCIATE_ENTRY_NUM]; ++ ++ u16 CurrminRptTime; ++ struct odm_ra_info RAInfo[ODM_ASSOCIATE_ENTRY_NUM]; /* Use MacID as ++ * array index. STA MacID=0, ++ * VWiFi Client MacID={1, ODM_ASSOCIATE_ENTRY_NUM-1} */ ++ /* */ ++ /* 2012/02/14 MH Add to share 88E ra with other SW team. */ ++ /* We need to colelct all support abilit to a proper area. */ ++ /* */ ++ bool RaSupport88E; ++ ++ /* Define ........... */ ++ ++ /* Latest packet phy info (ODM write) */ ++ struct odm_phy_dbg_info PhyDbgInfo; ++ ++ /* Latest packet phy info (ODM write) */ ++ struct odm_mac_status_info *pMacInfo; ++ ++ /* Different Team independt structure?? */ ++ ++ /* ODM Structure */ ++ struct fast_ant_train DM_FatTable; ++ struct rtw_dig DM_DigTable; ++ struct rtl_ps DM_PSTable; ++ struct dyn_primary_cca DM_PriCCA; ++ struct rx_hpc DM_RXHP_Table; ++ struct false_alarm_stats FalseAlmCnt; ++ struct false_alarm_stats FlaseAlmCntBuddyAdapter; ++ struct sw_ant_switch DM_SWAT_Table; ++ bool RSSI_test; ++ ++ struct edca_turbo DM_EDCA_Table; ++ u32 WMMEDCA_BE; ++ /* Copy from SD4 structure */ ++ /* */ ++ /* ================================================== */ ++ /* */ ++ ++ bool *pbDriverStopped; ++ bool *pbDriverIsGoingToPnpSetPowerSleep; ++ bool *pinit_adpt_in_progress; ++ ++ /* PSD */ ++ bool bUserAssignLevel; ++ struct timer_list PSDTimer; ++ u8 RSSI_BT; /* come from BT */ ++ bool bPSDinProcess; ++ bool bDMInitialGainEnable; ++ ++ /* for rate adaptive, in fact, 88c/92c fw will handle this */ ++ u8 bUseRAMask; ++ ++ struct odm_rate_adapt RateAdaptive; ++ ++ struct odm_rf_cal RFCalibrateInfo; ++ ++ /* TX power tracking */ ++ u8 BbSwingIdxOfdm; ++ u8 BbSwingIdxOfdmCurrent; ++ u8 BbSwingIdxOfdmBase; ++ bool BbSwingFlagOfdm; ++ u8 BbSwingIdxCck; ++ u8 BbSwingIdxCckCurrent; ++ u8 BbSwingIdxCckBase; ++ bool BbSwingFlagCck; ++ u8 *mp_mode; ++ /* ODM system resource. */ ++ ++ /* ODM relative time. */ ++ struct timer_list PathDivSwitchTimer; ++ /* 2011.09.27 add for Path Diversity */ ++ struct timer_list CCKPathDiversityTimer; ++ struct timer_list FastAntTrainingTimer; ++}; /* DM_Dynamic_Mechanism_Structure */ ++ ++enum ODM_RF_CONTENT { ++ odm_radioa_txt = 0x1000, ++ odm_radiob_txt = 0x1001, ++ odm_radioc_txt = 0x1002, ++ odm_radiod_txt = 0x1003 ++}; ++ ++enum odm_bb_config_type { ++ CONFIG_BB_PHY_REG, ++ CONFIG_BB_AGC_TAB, ++ CONFIG_BB_AGC_TAB_2G, ++ CONFIG_BB_PHY_REG_PG, ++}; ++ ++/* Status code */ ++enum rt_status { ++ RT_STATUS_SUCCESS, ++ RT_STATUS_FAILURE, ++ RT_STATUS_PENDING, ++ RT_STATUS_RESOURCE, ++ RT_STATUS_INVALID_CONTEXT, ++ RT_STATUS_INVALID_PARAMETER, ++ RT_STATUS_NOT_SUPPORT, ++ RT_STATUS_OS_API_FAILED, ++}; ++ ++/* 3=========================================================== */ ++/* 3 DIG */ ++/* 3=========================================================== */ ++ ++enum dm_dig_op { ++ RT_TYPE_THRESH_HIGH = 0, ++ RT_TYPE_THRESH_LOW = 1, ++ RT_TYPE_BACKOFF = 2, ++ RT_TYPE_RX_GAIN_MIN = 3, ++ RT_TYPE_RX_GAIN_MAX = 4, ++ RT_TYPE_ENABLE = 5, ++ RT_TYPE_DISABLE = 6, ++ DIG_OP_TYPE_MAX ++}; ++ ++#define DM_DIG_THRESH_HIGH 40 ++#define DM_DIG_THRESH_LOW 35 ++ ++#define DM_SCAN_RSSI_TH 0x14 /* scan return issue for LC */ ++ ++#define DM_false_ALARM_THRESH_LOW 400 ++#define DM_false_ALARM_THRESH_HIGH 1000 ++ ++#define DM_DIG_MAX_NIC 0x4e ++#define DM_DIG_MIN_NIC 0x1e /* 0x22/0x1c */ ++ ++#define DM_DIG_MAX_AP 0x32 ++#define DM_DIG_MIN_AP 0x20 ++ ++#define DM_DIG_MAX_NIC_HP 0x46 ++#define DM_DIG_MIN_NIC_HP 0x2e ++ ++#define DM_DIG_MAX_AP_HP 0x42 ++#define DM_DIG_MIN_AP_HP 0x30 ++ ++/* vivi 92c&92d has different definition, 20110504 */ ++/* this is for 92c */ ++#define DM_DIG_FA_TH0 0x200/* 0x20 */ ++#define DM_DIG_FA_TH1 0x300/* 0x100 */ ++#define DM_DIG_FA_TH2 0x400/* 0x200 */ ++/* this is for 92d */ ++#define DM_DIG_FA_TH0_92D 0x100 ++#define DM_DIG_FA_TH1_92D 0x400 ++#define DM_DIG_FA_TH2_92D 0x600 ++ ++#define DM_DIG_BACKOFF_MAX 12 ++#define DM_DIG_BACKOFF_MIN -4 ++#define DM_DIG_BACKOFF_DEFAULT 10 ++ ++/* 3=========================================================== */ ++/* 3 AGC RX High Power Mode */ ++/* 3=========================================================== */ ++#define LNA_Low_Gain_1 0x64 ++#define LNA_Low_Gain_2 0x5A ++#define LNA_Low_Gain_3 0x58 ++ ++#define FA_RXHP_TH1 5000 ++#define FA_RXHP_TH2 1500 ++#define FA_RXHP_TH3 800 ++#define FA_RXHP_TH4 600 ++#define FA_RXHP_TH5 500 ++ ++/* 3=========================================================== */ ++/* 3 EDCA */ ++/* 3=========================================================== */ ++ ++/* 3=========================================================== */ ++/* 3 Dynamic Tx Power */ ++/* 3=========================================================== */ ++/* Dynamic Tx Power Control Threshold */ ++#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 ++#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 ++#define TX_POWER_NEAR_FIELD_THRESH_AP 0x3F ++ ++#define TxHighPwrLevel_Normal 0 ++#define TxHighPwrLevel_Level1 1 ++#define TxHighPwrLevel_Level2 2 ++#define TxHighPwrLevel_BT1 3 ++#define TxHighPwrLevel_BT2 4 ++#define TxHighPwrLevel_15 5 ++#define TxHighPwrLevel_35 6 ++#define TxHighPwrLevel_50 7 ++#define TxHighPwrLevel_70 8 ++#define TxHighPwrLevel_100 9 ++ ++/* 3=========================================================== */ ++/* 3 Rate Adaptive */ ++/* 3=========================================================== */ ++#define DM_RATR_STA_INIT 0 ++#define DM_RATR_STA_HIGH 1 ++#define DM_RATR_STA_MIDDLE 2 ++#define DM_RATR_STA_LOW 3 ++ ++/* 3=========================================================== */ ++/* 3 BB Power Save */ ++/* 3=========================================================== */ ++ ++enum dm_1r_cca { ++ CCA_1R = 0, ++ CCA_2R = 1, ++ CCA_MAX = 2, ++}; ++ ++enum dm_rf { ++ RF_Save = 0, ++ RF_Normal = 1, ++ RF_MAX = 2, ++}; ++ ++/* 3=========================================================== */ ++/* 3 Antenna Diversity */ ++/* 3=========================================================== */ ++enum dm_swas { ++ Antenna_A = 1, ++ Antenna_B = 2, ++ Antenna_MAX = 3, ++}; ++ ++/* Maximal number of antenna detection mechanism needs to perform. */ ++#define MAX_ANTENNA_DETECTION_CNT 10 ++ ++/* Extern Global Variables. */ ++#define OFDM_TABLE_SIZE_92C 37 ++#define OFDM_TABLE_SIZE_92D 43 ++#define CCK_TABLE_SIZE 33 ++ ++extern u32 OFDMSwingTable[OFDM_TABLE_SIZE_92D]; ++extern u8 CCKSwingTable_Ch1_Ch13[CCK_TABLE_SIZE][8]; ++extern u8 CCKSwingTable_Ch14 [CCK_TABLE_SIZE][8]; ++ ++/* check Sta pointer valid or not */ ++#define IS_STA_VALID(pSta) (pSta) ++/* 20100514 Joseph: Add definition for antenna switching test after link. */ ++/* This indicates two different the steps. */ ++/* In SWAW_STEP_PEAK, driver needs to switch antenna and listen to the ++ * signal on the air. */ ++/* In SWAW_STEP_DETERMINE, driver just compares the signal captured in ++ * SWAW_STEP_PEAK */ ++/* with original RSSI to determine if it is necessary to switch antenna. */ ++#define SWAW_STEP_PEAK 0 ++#define SWAW_STEP_DETERMINE 1 ++ ++void ODM_Write_DIG(struct odm_dm_struct *pDM_Odm, u8 CurrentIGI); ++void ODM_Write_CCK_CCA_Thres(struct odm_dm_struct *pDM_Odm, u8 CurCCK_CCAThres); ++ ++void ODM_SetAntenna(struct odm_dm_struct *pDM_Odm, u8 Antenna); ++ ++#define dm_RF_Saving ODM_RF_Saving ++void ODM_RF_Saving(struct odm_dm_struct *pDM_Odm, u8 bForceInNormal); ++ ++#define SwAntDivRestAfterLink ODM_SwAntDivRestAfterLink ++void ODM_SwAntDivRestAfterLink(struct odm_dm_struct *pDM_Odm); ++ ++#define dm_CheckTXPowerTracking ODM_TXPowerTrackingCheck ++void ODM_TXPowerTrackingCheck(struct odm_dm_struct *pDM_Odm); ++ ++bool ODM_RAStateCheck(struct odm_dm_struct *pDM_Odm, s32 RSSI, ++ bool bForceUpdate, u8 *pRATRState); ++ ++#define dm_SWAW_RSSI_Check ODM_SwAntDivChkPerPktRssi ++void ODM_SwAntDivChkPerPktRssi(struct odm_dm_struct *pDM_Odm, u8 StationID, ++ struct odm_phy_status_info *pPhyInfo); ++ ++u32 ConvertTo_dB(u32 Value); ++ ++u32 GetPSDData(struct odm_dm_struct *pDM_Odm, unsigned int point, ++ u8 initial_gain_psd); ++ ++void odm_DIGbyRSSI_LPS(struct odm_dm_struct *pDM_Odm); ++ ++u32 ODM_Get_Rate_Bitmap(struct odm_dm_struct *pDM_Odm, u32 macid, ++ u32 ra_mask, u8 rssi_level); ++ ++void ODM_DMInit(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_DMWatchdog(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_CmnInfoInit(struct odm_dm_struct *pDM_Odm, ++ enum odm_common_info_def CmnInfo, u32 Value); ++ ++void ODM_CmnInfoHook(struct odm_dm_struct *pDM_Odm, ++ enum odm_common_info_def CmnInfo, void *pValue); ++ ++void ODM_CmnInfoPtrArrayHook(struct odm_dm_struct *pDM_Odm, ++ enum odm_common_info_def CmnInfo, ++ u16 Index, void *pValue); ++ ++void ODM_CmnInfoUpdate(struct odm_dm_struct *pDM_Odm, u32 CmnInfo, u64 Value); ++ ++void ODM_InitAllTimers(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_CancelAllTimers(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_ReleaseAllTimers(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_AntselStatistics_88C(struct odm_dm_struct *pDM_Odm, u8 MacId, ++ u32 PWDBAll, bool isCCKrate); ++ ++void ODM_SingleDualAntennaDefaultSetting(struct odm_dm_struct *pDM_Odm); ++ ++bool ODM_SingleDualAntennaDetection(struct odm_dm_struct *pDM_Odm, u8 mode); ++ ++void odm_dtc(struct odm_dm_struct *pDM_Odm); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/odm_HWConfig.h b/drivers/staging/r8188eu/include/odm_HWConfig.h +new file mode 100644 +index 000000000000..9b2ab3bcf992 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_HWConfig.h +@@ -0,0 +1,116 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __HALHWOUTSRC_H__ ++#define __HALHWOUTSRC_H__ ++ ++/* Definition */ ++/* CCK Rates, TxHT = 0 */ ++#define DESC92C_RATE1M 0x00 ++#define DESC92C_RATE2M 0x01 ++#define DESC92C_RATE5_5M 0x02 ++#define DESC92C_RATE11M 0x03 ++ ++/* OFDM Rates, TxHT = 0 */ ++#define DESC92C_RATE6M 0x04 ++#define DESC92C_RATE9M 0x05 ++#define DESC92C_RATE12M 0x06 ++#define DESC92C_RATE18M 0x07 ++#define DESC92C_RATE24M 0x08 ++#define DESC92C_RATE36M 0x09 ++#define DESC92C_RATE48M 0x0a ++#define DESC92C_RATE54M 0x0b ++ ++/* MCS Rates, TxHT = 1 */ ++#define DESC92C_RATEMCS0 0x0c ++#define DESC92C_RATEMCS1 0x0d ++#define DESC92C_RATEMCS2 0x0e ++#define DESC92C_RATEMCS3 0x0f ++#define DESC92C_RATEMCS4 0x10 ++#define DESC92C_RATEMCS5 0x11 ++#define DESC92C_RATEMCS6 0x12 ++#define DESC92C_RATEMCS7 0x13 ++#define DESC92C_RATEMCS8 0x14 ++#define DESC92C_RATEMCS9 0x15 ++#define DESC92C_RATEMCS10 0x16 ++#define DESC92C_RATEMCS11 0x17 ++#define DESC92C_RATEMCS12 0x18 ++#define DESC92C_RATEMCS13 0x19 ++#define DESC92C_RATEMCS14 0x1a ++#define DESC92C_RATEMCS15 0x1b ++#define DESC92C_RATEMCS15_SG 0x1c ++#define DESC92C_RATEMCS32 0x20 ++ ++/* structure and define */ ++ ++struct phy_rx_agc_info { ++ #ifdef __LITTLE_ENDIAN ++ u8 gain:7, trsw:1; ++ #else ++ u8 trsw:1, gain:7; ++ #endif ++}; ++ ++struct phy_status_rpt { ++ struct phy_rx_agc_info path_agc[3]; ++ u8 ch_corr[2]; ++ u8 cck_sig_qual_ofdm_pwdb_all; ++ u8 cck_agc_rpt_ofdm_cfosho_a; ++ u8 cck_rpt_b_ofdm_cfosho_b; ++ u8 rsvd_1;/* ch_corr_msb; */ ++ u8 noise_power_db_msb; ++ u8 path_cfotail[2]; ++ u8 pcts_mask[2]; ++ s8 stream_rxevm[2]; ++ u8 path_rxsnr[3]; ++ u8 noise_power_db_lsb; ++ u8 rsvd_2[3]; ++ u8 stream_csi[2]; ++ u8 stream_target_csi[2]; ++ s8 sig_evm; ++ u8 rsvd_3; ++ ++#ifdef __LITTLE_ENDIAN ++ u8 antsel_rx_keep_2:1; /* ex_intf_flg:1; */ ++ u8 sgi_en:1; ++ u8 rxsc:2; ++ u8 idle_long:1; ++ u8 r_ant_train_en:1; ++ u8 ant_sel_b:1; ++ u8 ant_sel:1; ++#else /* _BIG_ENDIAN_ */ ++ u8 ant_sel:1; ++ u8 ant_sel_b:1; ++ u8 r_ant_train_en:1; ++ u8 idle_long:1; ++ u8 rxsc:2; ++ u8 sgi_en:1; ++ u8 antsel_rx_keep_2:1; /* ex_intf_flg:1; */ ++#endif ++}; ++ ++void odm_Init_RSSIForDM(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_PhyStatusQuery(struct odm_dm_struct *pDM_Odm, ++ struct odm_phy_status_info *pPhyInfo, ++ u8 *pPhyStatus, ++ struct odm_per_pkt_info *pPktinfo, ++ struct adapter *adapt); ++ ++void ODM_MacStatusQuery(struct odm_dm_struct *pDM_Odm, ++ u8 *pMacStatus, ++ u8 MacID, ++ bool bPacketMatchBSSID, ++ bool bPacketToSelf, ++ bool bPacketBeacon); ++ ++enum HAL_STATUS ODM_ConfigRFWithHeaderFile(struct odm_dm_struct *pDM_Odm, ++ enum rf_radio_path Content, ++ enum rf_radio_path eRFPath); ++ ++enum HAL_STATUS ODM_ConfigBBWithHeaderFile(struct odm_dm_struct *pDM_Odm, ++ enum odm_bb_config_type ConfigType); ++ ++enum HAL_STATUS ODM_ConfigMACWithHeaderFile(struct odm_dm_struct *pDM_Odm); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/odm_RTL8188E.h b/drivers/staging/r8188eu/include/odm_RTL8188E.h +new file mode 100644 +index 000000000000..00d2678532f8 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_RTL8188E.h +@@ -0,0 +1,36 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __ODM_RTL8188E_H__ ++#define __ODM_RTL8188E_H__ ++ ++#define MAIN_ANT 0 ++#define AUX_ANT 1 ++#define MAIN_ANT_CG_TRX 1 ++#define AUX_ANT_CG_TRX 0 ++#define MAIN_ANT_CGCS_RX 0 ++#define AUX_ANT_CGCS_RX 1 ++ ++void ODM_DIG_LowerBound_88E(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_AntennaDiversityInit_88E(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_AntennaDiversity_88E(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_SetTxAntByTxInfo_88E(struct odm_dm_struct *pDM_Odm, u8 *pDesc, ++ u8 macId); ++ ++void ODM_UpdateRxIdleAnt_88E(struct odm_dm_struct *pDM_Odm, u8 Ant); ++ ++void ODM_AntselStatistics_88E(struct odm_dm_struct *pDM_Odm, u8 antsel_tr_mux, ++ u32 MacId, u8 RxPWDBAll); ++ ++void odm_FastAntTraining(struct odm_dm_struct *pDM_Odm); ++ ++void odm_FastAntTrainingCallback(struct odm_dm_struct *pDM_Odm); ++ ++void odm_FastAntTrainingWorkItemCallback(struct odm_dm_struct *pDM_Odm); ++ ++void odm_PrimaryCCA_Init(struct odm_dm_struct *pDM_Odm); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/odm_RegConfig8188E.h b/drivers/staging/r8188eu/include/odm_RegConfig8188E.h +new file mode 100644 +index 000000000000..86b5b2d24210 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_RegConfig8188E.h +@@ -0,0 +1,27 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __INC_ODM_REGCONFIG_H_8188E ++#define __INC_ODM_REGCONFIG_H_8188E ++ ++void odm_ConfigRFReg_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Data, ++ enum rf_radio_path RF_PATH, u32 RegAddr); ++ ++void odm_ConfigRF_RadioA_8188E(struct odm_dm_struct *pDM_Odm, ++ u32 Addr, u32 Data); ++ ++void odm_ConfigRF_RadioB_8188E(struct odm_dm_struct *pDM_Odm, ++ u32 Addr, u32 Data); ++ ++void odm_ConfigMAC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u8 Data); ++ ++void odm_ConfigBB_AGC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, ++ u32 Bitmask, u32 Data); ++ ++void odm_ConfigBB_PHY_REG_PG_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, ++ u32 Bitmask, u32 Data); ++ ++void odm_ConfigBB_PHY_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, ++ u32 Bitmask, u32 Data); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/odm_RegDefine11AC.h b/drivers/staging/r8188eu/include/odm_RegDefine11AC.h +new file mode 100644 +index 000000000000..bba7511cf244 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_RegDefine11AC.h +@@ -0,0 +1,29 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __ODM_REGDEFINE11AC_H__ ++#define __ODM_REGDEFINE11AC_H__ ++ ++/* 2 RF REG LIST */ ++ ++/* 2 BB REG LIST */ ++/* PAGE 8 */ ++/* PAGE 9 */ ++#define ODM_REG_OFDM_FA_RST_11AC 0x9A4 ++/* PAGE A */ ++#define ODM_REG_CCK_CCA_11AC 0xA0A ++#define ODM_REG_CCK_FA_RST_11AC 0xA2C ++#define ODM_REG_CCK_FA_11AC 0xA5C ++/* PAGE C */ ++#define ODM_REG_IGI_A_11AC 0xC50 ++/* PAGE E */ ++#define ODM_REG_IGI_B_11AC 0xE50 ++/* PAGE F */ ++#define ODM_REG_OFDM_FA_11AC 0xF48 ++ ++/* 2 MAC REG LIST */ ++ ++/* DIG Related */ ++#define ODM_BIT_IGI_11AC 0xFFFFFFFF ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/odm_RegDefine11N.h b/drivers/staging/r8188eu/include/odm_RegDefine11N.h +new file mode 100644 +index 000000000000..5d1d73490c1c +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_RegDefine11N.h +@@ -0,0 +1,143 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __ODM_REGDEFINE11N_H__ ++#define __ODM_REGDEFINE11N_H__ ++ ++/* 2 RF REG LIST */ ++#define ODM_REG_RF_MODE_11N 0x00 ++#define ODM_REG_RF_0B_11N 0x0B ++#define ODM_REG_CHNBW_11N 0x18 ++#define ODM_REG_T_METER_11N 0x24 ++#define ODM_REG_RF_25_11N 0x25 ++#define ODM_REG_RF_26_11N 0x26 ++#define ODM_REG_RF_27_11N 0x27 ++#define ODM_REG_RF_2B_11N 0x2B ++#define ODM_REG_RF_2C_11N 0x2C ++#define ODM_REG_RXRF_A3_11N 0x3C ++#define ODM_REG_T_METER_92D_11N 0x42 ++#define ODM_REG_T_METER_88E_11N 0x42 ++ ++/* 2 BB REG LIST */ ++/* PAGE 8 */ ++#define ODM_REG_BB_CTRL_11N 0x800 ++#define ODM_REG_RF_PIN_11N 0x804 ++#define ODM_REG_PSD_CTRL_11N 0x808 ++#define ODM_REG_TX_ANT_CTRL_11N 0x80C ++#define ODM_REG_BB_PWR_SAV5_11N 0x818 ++#define ODM_REG_CCK_RPT_FORMAT_11N 0x824 ++#define ODM_REG_RX_DEFUALT_A_11N 0x858 ++#define ODM_REG_RX_DEFUALT_B_11N 0x85A ++#define ODM_REG_BB_PWR_SAV3_11N 0x85C ++#define ODM_REG_ANTSEL_CTRL_11N 0x860 ++#define ODM_REG_RX_ANT_CTRL_11N 0x864 ++#define ODM_REG_PIN_CTRL_11N 0x870 ++#define ODM_REG_BB_PWR_SAV1_11N 0x874 ++#define ODM_REG_ANTSEL_PATH_11N 0x878 ++#define ODM_REG_BB_3WIRE_11N 0x88C ++#define ODM_REG_SC_CNT_11N 0x8C4 ++#define ODM_REG_PSD_DATA_11N 0x8B4 ++/* PAGE 9 */ ++#define ODM_REG_ANT_MAPPING1_11N 0x914 ++#define ODM_REG_ANT_MAPPING2_11N 0x918 ++/* PAGE A */ ++#define ODM_REG_CCK_ANTDIV_PARA1_11N 0xA00 ++#define ODM_REG_CCK_CCA_11N 0xA0A ++#define ODM_REG_CCK_ANTDIV_PARA2_11N 0xA0C ++#define ODM_REG_CCK_ANTDIV_PARA3_11N 0xA10 ++#define ODM_REG_CCK_ANTDIV_PARA4_11N 0xA14 ++#define ODM_REG_CCK_FILTER_PARA1_11N 0xA22 ++#define ODM_REG_CCK_FILTER_PARA2_11N 0xA23 ++#define ODM_REG_CCK_FILTER_PARA3_11N 0xA24 ++#define ODM_REG_CCK_FILTER_PARA4_11N 0xA25 ++#define ODM_REG_CCK_FILTER_PARA5_11N 0xA26 ++#define ODM_REG_CCK_FILTER_PARA6_11N 0xA27 ++#define ODM_REG_CCK_FILTER_PARA7_11N 0xA28 ++#define ODM_REG_CCK_FILTER_PARA8_11N 0xA29 ++#define ODM_REG_CCK_FA_RST_11N 0xA2C ++#define ODM_REG_CCK_FA_MSB_11N 0xA58 ++#define ODM_REG_CCK_FA_LSB_11N 0xA5C ++#define ODM_REG_CCK_CCA_CNT_11N 0xA60 ++#define ODM_REG_BB_PWR_SAV4_11N 0xA74 ++/* PAGE B */ ++#define ODM_REG_LNA_SWITCH_11N 0xB2C ++#define ODM_REG_PATH_SWITCH_11N 0xB30 ++#define ODM_REG_RSSI_CTRL_11N 0xB38 ++#define ODM_REG_CONFIG_ANTA_11N 0xB68 ++#define ODM_REG_RSSI_BT_11N 0xB9C ++/* PAGE C */ ++#define ODM_REG_OFDM_FA_HOLDC_11N 0xC00 ++#define ODM_REG_RX_PATH_11N 0xC04 ++#define ODM_REG_TRMUX_11N 0xC08 ++#define ODM_REG_OFDM_FA_RSTC_11N 0xC0C ++#define ODM_REG_RXIQI_MATRIX_11N 0xC14 ++#define ODM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C ++#define ODM_REG_IGI_A_11N 0xC50 ++#define ODM_REG_ANTDIV_PARA2_11N 0xC54 ++#define ODM_REG_IGI_B_11N 0xC58 ++#define ODM_REG_ANTDIV_PARA3_11N 0xC5C ++#define ODM_REG_BB_PWR_SAV2_11N 0xC70 ++#define ODM_REG_RX_OFF_11N 0xC7C ++#define ODM_REG_TXIQK_MATRIXA_11N 0xC80 ++#define ODM_REG_TXIQK_MATRIXB_11N 0xC88 ++#define ODM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94 ++#define ODM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C ++#define ODM_REG_RXIQK_MATRIX_LSB_11N 0xCA0 ++#define ODM_REG_ANTDIV_PARA1_11N 0xCA4 ++#define ODM_REG_OFDM_FA_TYPE1_11N 0xCF0 ++/* PAGE D */ ++#define ODM_REG_OFDM_FA_RSTD_11N 0xD00 ++#define ODM_REG_OFDM_FA_TYPE2_11N 0xDA0 ++#define ODM_REG_OFDM_FA_TYPE3_11N 0xDA4 ++#define ODM_REG_OFDM_FA_TYPE4_11N 0xDA8 ++/* PAGE E */ ++#define ODM_REG_TXAGC_A_6_18_11N 0xE00 ++#define ODM_REG_TXAGC_A_24_54_11N 0xE04 ++#define ODM_REG_TXAGC_A_1_MCS32_11N 0xE08 ++#define ODM_REG_TXAGC_A_MCS0_3_11N 0xE10 ++#define ODM_REG_TXAGC_A_MCS4_7_11N 0xE14 ++#define ODM_REG_TXAGC_A_MCS8_11_11N 0xE18 ++#define ODM_REG_TXAGC_A_MCS12_15_11N 0xE1C ++#define ODM_REG_FPGA0_IQK_11N 0xE28 ++#define ODM_REG_TXIQK_TONE_A_11N 0xE30 ++#define ODM_REG_RXIQK_TONE_A_11N 0xE34 ++#define ODM_REG_TXIQK_PI_A_11N 0xE38 ++#define ODM_REG_RXIQK_PI_A_11N 0xE3C ++#define ODM_REG_TXIQK_11N 0xE40 ++#define ODM_REG_RXIQK_11N 0xE44 ++#define ODM_REG_IQK_AGC_PTS_11N 0xE48 ++#define ODM_REG_IQK_AGC_RSP_11N 0xE4C ++#define ODM_REG_BLUETOOTH_11N 0xE6C ++#define ODM_REG_RX_WAIT_CCA_11N 0xE70 ++#define ODM_REG_TX_CCK_RFON_11N 0xE74 ++#define ODM_REG_TX_CCK_BBON_11N 0xE78 ++#define ODM_REG_OFDM_RFON_11N 0xE7C ++#define ODM_REG_OFDM_BBON_11N 0xE80 ++#define ODM_REG_TX2RX_11N 0xE84 ++#define ODM_REG_TX2TX_11N 0xE88 ++#define ODM_REG_RX_CCK_11N 0xE8C ++#define ODM_REG_RX_OFDM_11N 0xED0 ++#define ODM_REG_RX_WAIT_RIFS_11N 0xED4 ++#define ODM_REG_RX2RX_11N 0xED8 ++#define ODM_REG_STANDBY_11N 0xEDC ++#define ODM_REG_SLEEP_11N 0xEE0 ++#define ODM_REG_PMPD_ANAEN_11N 0xEEC ++ ++/* 2 MAC REG LIST */ ++#define ODM_REG_BB_RST_11N 0x02 ++#define ODM_REG_ANTSEL_PIN_11N 0x4C ++#define ODM_REG_EARLY_MODE_11N 0x4D0 ++#define ODM_REG_RSSI_MONITOR_11N 0x4FE ++#define ODM_REG_EDCA_VO_11N 0x500 ++#define ODM_REG_EDCA_VI_11N 0x504 ++#define ODM_REG_EDCA_BE_11N 0x508 ++#define ODM_REG_EDCA_BK_11N 0x50C ++#define ODM_REG_TXPAUSE_11N 0x522 ++#define ODM_REG_RESP_TX_11N 0x6D8 ++#define ODM_REG_ANT_TRAIN_PARA1_11N 0x7b0 ++#define ODM_REG_ANT_TRAIN_PARA2_11N 0x7b4 ++ ++/* DIG Related */ ++#define ODM_BIT_IGI_11N 0x0000007F ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/odm_interface.h b/drivers/staging/r8188eu/include/odm_interface.h +new file mode 100644 +index 000000000000..6b589413d56c +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_interface.h +@@ -0,0 +1,147 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __ODM_INTERFACE_H__ ++#define __ODM_INTERFACE_H__ ++ ++/* */ ++/* =========== Constant/Structure/Enum/... Define */ ++/* */ ++ ++/* */ ++/* =========== Macro Define */ ++/* */ ++ ++#define _reg_all(_name) ODM_##_name ++#define _reg_ic(_name, _ic) ODM_##_name##_ic ++#define _bit_all(_name) BIT_##_name ++#define _bit_ic(_name, _ic) BIT_##_name##_ic ++ ++/* _cat: implemented by Token-Pasting Operator. */ ++ ++/*=================================== ++ ++#define ODM_REG_DIG_11N 0xC50 ++#define ODM_REG_DIG_11AC 0xDDD ++ ++ODM_REG(DIG,_pDM_Odm) ++=====================================*/ ++ ++#define _reg_11N(_name) ODM_REG_##_name##_11N ++#define _reg_11AC(_name) ODM_REG_##_name##_11AC ++#define _bit_11N(_name) ODM_BIT_##_name##_11N ++#define _bit_11AC(_name) ODM_BIT_##_name##_11AC ++ ++#define _cat(_name, _ic_type, _func) \ ++ ( \ ++ ((_ic_type) & ODM_IC_11N_SERIES) ? _func##_11N(_name) : \ ++ _func##_11AC(_name) \ ++ ) ++ ++/* _name: name of register or bit. */ ++/* Example: "ODM_REG(R_A_AGC_CORE1, pDM_Odm)" */ ++/* gets "ODM_R_A_AGC_CORE1" or "ODM_R_A_AGC_CORE1_8192C", ++ * depends on SupportICType. */ ++#define ODM_REG(_name, _pDM_Odm) _cat(_name, _pDM_Odm->SupportICType, _reg) ++#define ODM_BIT(_name, _pDM_Odm) _cat(_name, _pDM_Odm->SupportICType, _bit) ++ ++enum odm_h2c_cmd { ++ ODM_H2C_RSSI_REPORT = 0, ++ ODM_H2C_PSD_RESULT= 1, ++ ODM_H2C_PathDiv = 2, ++ ODM_MAX_H2CCMD ++}; ++ ++/* 2012/02/17 MH For non-MP compile pass only. Linux does not support workitem. */ ++/* Suggest HW team to use thread instead of workitem. Windows also support the feature. */ ++typedef void (*RT_WORKITEM_CALL_BACK)(void *pContext); ++ ++/* =========== Extern Variable ??? It should be forbidden. */ ++ ++/* =========== EXtern Function Prototype */ ++ ++u8 ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr); ++ ++u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr); ++ ++u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr); ++ ++void ODM_Write1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 Data); ++ ++void ODM_Write2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 Data); ++ ++void ODM_Write4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 Data); ++ ++void ODM_SetMACReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, ++ u32 BitMask, u32 Data); ++ ++u32 ODM_GetMACReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 BitMask); ++ ++void ODM_SetBBReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, ++ u32 BitMask, u32 Data); ++ ++u32 ODM_GetBBReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 BitMask); ++ ++void ODM_SetRFReg(struct odm_dm_struct *pDM_Odm, enum rf_radio_path eRFPath, ++ u32 RegAddr, u32 BitMask, u32 Data); ++ ++u32 ODM_GetRFReg(struct odm_dm_struct *pDM_Odm, enum rf_radio_path eRFPath, ++ u32 RegAddr, u32 BitMask); ++ ++/* Memory Relative Function. */ ++void ODM_AllocateMemory(struct odm_dm_struct *pDM_Odm, void **pPtr, u32 length); ++void ODM_FreeMemory(struct odm_dm_struct *pDM_Odm, void *pPtr, u32 length); ++ ++s32 ODM_CompareMemory(struct odm_dm_struct *pDM_Odm, void *pBuf1, void *pBuf2, ++ u32 length); ++ ++/* ODM MISC-spin lock relative API. */ ++void ODM_AcquireSpinLock(struct odm_dm_struct *pDM_Odm, ++ enum RT_SPINLOCK_TYPE type); ++ ++void ODM_ReleaseSpinLock(struct odm_dm_struct *pDM_Odm, ++ enum RT_SPINLOCK_TYPE type); ++ ++/* ODM MISC-workitem relative API. */ ++void ODM_InitializeWorkItem(struct odm_dm_struct *pDM_Odm, void *pRtWorkItem, ++ RT_WORKITEM_CALL_BACK RtWorkItemCallback, ++ void *pContext, const char *szID); ++ ++void ODM_StartWorkItem(void *pRtWorkItem); ++ ++void ODM_StopWorkItem(void *pRtWorkItem); ++ ++void ODM_FreeWorkItem(void *pRtWorkItem); ++ ++void ODM_ScheduleWorkItem(void *pRtWorkItem); ++ ++void ODM_IsWorkItemScheduled(void *pRtWorkItem); ++ ++/* ODM Timer relative API. */ ++void ODM_StallExecution(u32 usDelay); ++ ++void ODM_delay_ms(u32 ms); ++ ++void ODM_delay_us(u32 us); ++ ++void ODM_sleep_ms(u32 ms); ++ ++void ODM_sleep_us(u32 us); ++ ++void ODM_SetTimer(struct odm_dm_struct *pDM_Odm, struct timer_list *pTimer, ++ u32 msDelay); ++ ++void ODM_InitializeTimer(struct odm_dm_struct *pDM_Odm, ++ struct timer_list *pTimer, void *CallBackFunc, ++ void *pContext, const char *szID); ++ ++void ODM_CancelTimer(struct odm_dm_struct *pDM_Odm, struct timer_list *pTimer); ++ ++void ODM_ReleaseTimer(struct odm_dm_struct *pDM_Odm, struct timer_list *pTimer); ++ ++/* ODM FW relative API. */ ++u32 ODM_FillH2CCmd(u8 *pH2CBuffer, u32 H2CBufferLen, u32 CmdNum, ++ u32 *pElementID, u32 *pCmdLen, u8 **pCmbBuffer, ++ u8 *CmdStartSeq); ++ ++#endif /* __ODM_INTERFACE_H__ */ +diff --git a/drivers/staging/r8188eu/include/odm_precomp.h b/drivers/staging/r8188eu/include/odm_precomp.h +new file mode 100644 +index 000000000000..a1d6d674bda6 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_precomp.h +@@ -0,0 +1,76 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. i*/ ++ ++#ifndef __ODM_PRECOMP_H__ ++#define __ODM_PRECOMP_H__ ++ ++#include "odm_types.h" ++ ++#define TEST_FALG___ 1 ++ ++/* 2 Config Flags and Structs - defined by each ODM Type */ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "hal_intf.h" ++ ++/* 2 OutSrc Header Files */ ++ ++#include "odm.h" ++#include "odm_HWConfig.h" ++#include "odm_RegDefine11AC.h" ++#include "odm_RegDefine11N.h" ++ ++#include "HalPhyRf_8188e.h"/* for IQK,LCK,Power-tracking */ ++#include "Hal8188ERateAdaptive.h"/* for RA,Power training */ ++#include "rtl8188e_hal.h" ++ ++#include "odm_interface.h" ++#include "odm_reg.h" ++ ++#include "HalHWImg8188E_MAC.h" ++#include "HalHWImg8188E_RF.h" ++#include "HalHWImg8188E_BB.h" ++ ++#include "odm_RegConfig8188E.h" ++#include "odm_RTL8188E.h" ++ ++void odm_DIGInit(struct odm_dm_struct *pDM_Odm); ++void odm_RateAdaptiveMaskInit(struct odm_dm_struct *pDM_Odm); ++void odm_DynamicBBPowerSavingInit(struct odm_dm_struct *pDM_Odm); ++void odm_DynamicTxPowerInit(struct odm_dm_struct *pDM_Odm); ++void odm_TXPowerTrackingInit(struct odm_dm_struct *pDM_Odm); ++void ODM_EdcaTurboInit(struct odm_dm_struct *pDM_Odm); ++void odm_SwAntDivInit_NIC(struct odm_dm_struct *pDM_Odm); ++void odm_GlobalAdapterCheck(void); ++void odm_CommonInfoSelfUpdate(struct odm_dm_struct *pDM_Odm); ++void odm_FalseAlarmCounterStatistics(struct odm_dm_struct *pDM_Odm); ++void odm_DIG(struct odm_dm_struct *pDM_Odm); ++void odm_CCKPacketDetectionThresh(struct odm_dm_struct *pDM_Odm); ++void odm_RefreshRateAdaptiveMaskMP(struct odm_dm_struct *pDM_Odm); ++void odm_DynamicBBPowerSaving(struct odm_dm_struct *pDM_Odm); ++void odm_SwAntDivChkAntSwitch(struct odm_dm_struct *pDM_Odm, u8 Step); ++void odm_EdcaTurboCheck(struct odm_dm_struct *pDM_Odm); ++void odm_DynamicTxPower(struct odm_dm_struct *pDM_Odm); ++void odm_CommonInfoSelfInit(struct odm_dm_struct *pDM_Odm); ++void odm_SwAntDivInit(struct odm_dm_struct *pDM_Odm); ++void odm_RSSIMonitorCheck(struct odm_dm_struct *pDM_Odm); ++void odm_RefreshRateAdaptiveMask(struct odm_dm_struct *pDM_Odm); ++void odm_1R_CCA(struct odm_dm_struct *pDM_Odm); ++void odm_RefreshRateAdaptiveMaskCE(struct odm_dm_struct *pDM_Odm); ++void odm_RefreshRateAdaptiveMaskAPADSL(struct odm_dm_struct *pDM_Odm); ++void odm_DynamicTxPowerNIC(struct odm_dm_struct *pDM_Odm); ++void odm_DynamicTxPowerAP(struct odm_dm_struct *pDM_Odm); ++void odm_RSSIMonitorCheckMP(struct odm_dm_struct *pDM_Odm); ++void odm_RSSIMonitorCheckCE(struct odm_dm_struct *pDM_Odm); ++void odm_RSSIMonitorCheckAP(struct odm_dm_struct *pDM_Odm); ++void odm_TXPowerTrackingThermalMeterInit(struct odm_dm_struct *pDM_Odm); ++void odm_EdcaTurboCheckCE(struct odm_dm_struct *pDM_Odm); ++void odm_TXPowerTrackingCheckCE(struct odm_dm_struct *pDM_Odm); ++void odm_TXPowerTrackingCheckMP(struct odm_dm_struct *pDM_Odm); ++void odm_TXPowerTrackingCheckAP(struct odm_dm_struct *pDM_Odm); ++void odm_SwAntDivChkAntSwitchCallback(struct timer_list *t); ++void odm_InitHybridAntDiv(struct odm_dm_struct *pDM_Odm); ++void odm_HwAntDiv(struct odm_dm_struct *pDM_Odm); ++ ++#endif /* __ODM_PRECOMP_H__ */ +diff --git a/drivers/staging/r8188eu/include/odm_reg.h b/drivers/staging/r8188eu/include/odm_reg.h +new file mode 100644 +index 000000000000..78d7e904947c +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_reg.h +@@ -0,0 +1,89 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. i*/ ++ ++#ifndef __HAL_ODM_REG_H__ ++#define __HAL_ODM_REG_H__ ++ ++/* Register Definition */ ++ ++/* MAC REG */ ++#define ODM_BB_RESET 0x002 ++#define ODM_DUMMY 0x4fe ++#define ODM_EDCA_VO_PARAM 0x500 ++#define ODM_EDCA_VI_PARAM 0x504 ++#define ODM_EDCA_BE_PARAM 0x508 ++#define ODM_EDCA_BK_PARAM 0x50C ++#define ODM_TXPAUSE 0x522 ++ ++/* BB REG */ ++#define ODM_FPGA_PHY0_PAGE8 0x800 ++#define ODM_PSD_SETTING 0x808 ++#define ODM_AFE_SETTING 0x818 ++#define ODM_TXAGC_B_6_18 0x830 ++#define ODM_TXAGC_B_24_54 0x834 ++#define ODM_TXAGC_B_MCS32_5 0x838 ++#define ODM_TXAGC_B_MCS0_MCS3 0x83c ++#define ODM_TXAGC_B_MCS4_MCS7 0x848 ++#define ODM_TXAGC_B_MCS8_MCS11 0x84c ++#define ODM_ANALOG_REGISTER 0x85c ++#define ODM_RF_INTERFACE_OUTPUT 0x860 ++#define ODM_TXAGC_B_MCS12_MCS15 0x868 ++#define ODM_TXAGC_B_11_A_2_11 0x86c ++#define ODM_AD_DA_LSB_MASK 0x874 ++#define ODM_ENABLE_3_WIRE 0x88c ++#define ODM_PSD_REPORT 0x8b4 ++#define ODM_R_ANT_SELECT 0x90c ++#define ODM_CCK_ANT_SELECT 0xa07 ++#define ODM_CCK_PD_THRESH 0xa0a ++#define ODM_CCK_RF_REG1 0xa11 ++#define ODM_CCK_MATCH_FILTER 0xa20 ++#define ODM_CCK_RAKE_MAC 0xa2e ++#define ODM_CCK_CNT_RESET 0xa2d ++#define ODM_CCK_TX_DIVERSITY 0xa2f ++#define ODM_CCK_FA_CNT_MSB 0xa5b ++#define ODM_CCK_FA_CNT_LSB 0xa5c ++#define ODM_CCK_NEW_FUNCTION 0xa75 ++#define ODM_OFDM_PHY0_PAGE_C 0xc00 ++#define ODM_OFDM_RX_ANT 0xc04 ++#define ODM_R_A_RXIQI 0xc14 ++#define ODM_R_A_AGC_CORE1 0xc50 ++#define ODM_R_A_AGC_CORE2 0xc54 ++#define ODM_R_B_AGC_CORE1 0xc58 ++#define ODM_R_AGC_PAR 0xc70 ++#define ODM_R_HTSTF_AGC_PAR 0xc7c ++#define ODM_TX_PWR_TRAINING_A 0xc90 ++#define ODM_TX_PWR_TRAINING_B 0xc98 ++#define ODM_OFDM_FA_CNT1 0xcf0 ++#define ODM_OFDM_PHY0_PAGE_D 0xd00 ++#define ODM_OFDM_FA_CNT2 0xda0 ++#define ODM_OFDM_FA_CNT3 0xda4 ++#define ODM_OFDM_FA_CNT4 0xda8 ++#define ODM_TXAGC_A_6_18 0xe00 ++#define ODM_TXAGC_A_24_54 0xe04 ++#define ODM_TXAGC_A_1_MCS32 0xe08 ++#define ODM_TXAGC_A_MCS0_MCS3 0xe10 ++#define ODM_TXAGC_A_MCS4_MCS7 0xe14 ++#define ODM_TXAGC_A_MCS8_MCS11 0xe18 ++#define ODM_TXAGC_A_MCS12_MCS15 0xe1c ++ ++/* RF REG */ ++#define ODM_GAIN_SETTING 0x00 ++#define ODM_CHANNEL 0x18 ++ ++/* Ant Detect Reg */ ++#define ODM_DPDT 0x300 ++ ++/* PSD Init */ ++#define ODM_PSDREG 0x808 ++ ++/* 92D Path Div */ ++#define PATHDIV_REG 0xB30 ++#define PATHDIV_TRI 0xBA0 ++ ++/* */ ++/* Bitmap Definition */ ++/* */ ++ ++#define BIT_FA_RESET BIT(0) ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/odm_types.h b/drivers/staging/r8188eu/include/odm_types.h +new file mode 100644 +index 000000000000..6f4a4bd37ec1 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_types.h +@@ -0,0 +1,45 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __ODM_TYPES_H__ ++#define __ODM_TYPES_H__ ++ ++/* */ ++/* Define Different SW team support */ ++/* */ ++#define ODM_AP 0x01 /* BIT(0) */ ++#define ODM_ADSL 0x02 /* BIT(1) */ ++#define ODM_CE 0x04 /* BIT(2) */ ++#define ODM_MP 0x08 /* BIT(3) */ ++ ++#define RT_PCI_INTERFACE 1 ++#define RT_USB_INTERFACE 2 ++#define RT_SDIO_INTERFACE 3 ++ ++enum HAL_STATUS { ++ HAL_STATUS_SUCCESS, ++ HAL_STATUS_FAILURE, ++}; ++ ++enum RT_SPINLOCK_TYPE { ++ RT_TEMP = 1, ++}; ++ ++#include "basic_types.h" ++ ++#define DEV_BUS_TYPE RT_USB_INTERFACE ++ ++#define SET_TX_DESC_ANTSEL_A_88E(__ptxdesc, __value) \ ++ le32p_replace_bits((__le32 *)(__ptxdesc + 8), __value, BIT(24)) ++#define SET_TX_DESC_ANTSEL_B_88E(__ptxdesc, __value) \ ++ le32p_replace_bits((__le32 *)(__ptxdesc + 8), __value, BIT(25)) ++#define SET_TX_DESC_ANTSEL_C_88E(__ptxdesc, __value) \ ++ le32p_replace_bits((__le32 *)(__ptxdesc + 28), __value, BIT(29)) ++ ++/* define useless flag to avoid compile warning */ ++#define USE_WORKITEM 0 ++#define FOR_BRAZIL_PRETEST 0 ++#define BT_30_SUPPORT 0 ++#define FPGA_TWO_MAC_VERIFICATION 0 ++ ++#endif /* __ODM_TYPES_H__ */ +diff --git a/drivers/staging/r8188eu/include/osdep_intf.h b/drivers/staging/r8188eu/include/osdep_intf.h +new file mode 100644 +index 000000000000..3ea60feee2db +--- /dev/null ++++ b/drivers/staging/r8188eu/include/osdep_intf.h +@@ -0,0 +1,64 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __OSDEP_INTF_H_ ++#define __OSDEP_INTF_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++struct intf_priv { ++ u8 *intf_dev; ++ u32 max_iosz; /* USB2.0: 128, USB1.1: 64, SDIO:64 */ ++ u32 max_xmitsz; /* USB2.0: unlimited, SDIO:512 */ ++ u32 max_recvsz; /* USB2.0: unlimited, SDIO:512 */ ++ ++ u8 *io_rwmem; ++ u8 *allocated_io_rwmem; ++ u32 io_wsz; /* unit: 4bytes */ ++ u32 io_rsz;/* unit: 4bytes */ ++ u8 intf_status; ++ ++ void (*_bus_io)(u8 *priv); ++ ++/* ++Under Sync. IRP (SDIO/USB) ++A protection mechanism is necessary for the io_rwmem(read/write protocol) ++ ++Under Async. IRP (SDIO/USB) ++The protection mechanism is through the pending queue. ++*/ ++ struct mutex ioctl_mutex; ++ /* when in USB, IO is through interrupt in/out endpoints */ ++ struct usb_device *udev; ++ struct urb *piorw_urb; ++ u8 io_irp_cnt; ++ u8 bio_irp_pending; ++ struct semaphore io_retevt; ++ struct timer_list io_timer; ++ u8 bio_irp_timeout; ++ u8 bio_timer_cancel; ++}; ++ ++u8 rtw_init_drv_sw(struct adapter *padapter); ++u8 rtw_free_drv_sw(struct adapter *padapter); ++u8 rtw_reset_drv_sw(struct adapter *padapter); ++ ++u32 rtw_start_drv_threads(struct adapter *padapter); ++void rtw_stop_drv_threads (struct adapter *padapter); ++void rtw_cancel_all_timer(struct adapter *padapter); ++ ++int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname); ++struct net_device *rtw_init_netdev(struct adapter *padapter); ++u16 rtw_recv_select_queue(struct sk_buff *skb); ++void rtw_proc_init_one(struct net_device *dev); ++void rtw_proc_remove_one(struct net_device *dev); ++ ++void rtw_ips_dev_unload(struct adapter *padapter); ++ ++int rtw_ips_pwr_up(struct adapter *padapter); ++void rtw_ips_pwr_down(struct adapter *padapter); ++int rtw_hw_suspend(struct adapter *padapter); ++int rtw_hw_resume(struct adapter *padapter); ++ ++#endif /* _OSDEP_INTF_H_ */ +diff --git a/drivers/staging/r8188eu/include/osdep_service.h b/drivers/staging/r8188eu/include/osdep_service.h +new file mode 100644 +index 000000000000..029aa4e92c9b +--- /dev/null ++++ b/drivers/staging/r8188eu/include/osdep_service.h +@@ -0,0 +1,315 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __OSDEP_SERVICE_H_ ++#define __OSDEP_SERVICE_H_ ++ ++#include ++#include "basic_types.h" ++ ++#define _FAIL 0 ++#define _SUCCESS 1 ++#define RTW_RX_HANDLED 2 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* Necessary because we use the proc fs */ ++#include /* for struct tasklet_struct */ ++#include ++#include ++#include ++ ++#include ++#include ++ ++struct __queue { ++ struct list_head queue; ++ spinlock_t lock; ++}; ++ ++#define thread_exit() complete_and_exit(NULL, 0) ++ ++static inline struct list_head *get_list_head(struct __queue *queue) ++{ ++ return (&(queue->queue)); ++} ++ ++static inline int _enter_critical_mutex(struct mutex *pmutex, unsigned long *pirqL) ++{ ++ int ret; ++ ++ ret = mutex_lock_interruptible(pmutex); ++ return ret; ++} ++ ++static inline void _exit_critical_mutex(struct mutex *pmutex, unsigned long *pirqL) ++{ ++ mutex_unlock(pmutex); ++} ++ ++static inline void rtw_list_delete(struct list_head *plist) ++{ ++ list_del_init(plist); ++} ++ ++static inline void _set_timer(struct timer_list *ptimer,u32 delay_time) ++{ ++ mod_timer(ptimer , (jiffies+(delay_time*HZ/1000))); ++} ++ ++static inline void _cancel_timer(struct timer_list *ptimer,u8 *bcancelled) ++{ ++ del_timer_sync(ptimer); ++ *bcancelled= true;/* true ==1; false==0 */ ++} ++ ++#define RTW_TIMER_HDL_ARGS void *FunctionContext ++#define RTW_TIMER_HDL_NAME(name) rtw_##name##_timer_hdl ++#define RTW_DECLARE_TIMER_HDL(name) void RTW_TIMER_HDL_NAME(name)(RTW_TIMER_HDL_ARGS) ++ ++static inline void _init_workitem(struct work_struct *pwork, void *pfunc, void * cntx) ++{ ++ INIT_WORK(pwork, pfunc); ++} ++ ++static inline void _set_workitem(struct work_struct *pwork) ++{ ++ schedule_work(pwork); ++} ++ ++static inline void _cancel_workitem_sync(struct work_struct *pwork) ++{ ++ cancel_work_sync(pwork); ++} ++/* */ ++/* Global Mutex: can only be used at PASSIVE level. */ ++/* */ ++ ++#define ACQUIRE_GLOBAL_MUTEX(_MutexCounter) \ ++{ \ ++ while (atomic_inc_return((atomic_t *)&(_MutexCounter)) != 1)\ ++ { \ ++ atomic_dec((atomic_t *)&(_MutexCounter)); \ ++ msleep(10); \ ++ } \ ++} ++ ++#define RELEASE_GLOBAL_MUTEX(_MutexCounter) \ ++{ \ ++ atomic_dec((atomic_t *)&(_MutexCounter)); \ ++} ++ ++static inline int rtw_netif_queue_stopped(struct net_device *pnetdev) ++{ ++ return netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 0)) && ++ netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 1)) && ++ netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 2)) && ++ netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 3)); ++} ++ ++static inline void rtw_netif_wake_queue(struct net_device *pnetdev) ++{ ++ netif_tx_wake_all_queues(pnetdev); ++} ++ ++static inline void rtw_netif_start_queue(struct net_device *pnetdev) ++{ ++ netif_tx_start_all_queues(pnetdev); ++} ++ ++static inline void rtw_netif_stop_queue(struct net_device *pnetdev) ++{ ++ netif_tx_stop_all_queues(pnetdev); ++} ++ ++extern int RTW_STATUS_CODE(int error_code); ++ ++extern unsigned char MCS_rate_2R[16]; ++extern unsigned char MCS_rate_1R[16]; ++extern unsigned char RTW_WPA_OUI[]; ++extern unsigned char WPA_TKIP_CIPHER[4]; ++extern unsigned char RSN_TKIP_CIPHER[4]; ++ ++void *rtw_malloc2d(int h, int w, int size); ++ ++u32 _rtw_down_sema(struct semaphore *sema); ++void _rtw_mutex_init(struct mutex *pmutex); ++void _rtw_mutex_free(struct mutex *pmutex); ++ ++void _rtw_init_queue(struct __queue *pqueue); ++ ++u32 rtw_systime_to_ms(u32 systime); ++u32 rtw_ms_to_systime(u32 ms); ++s32 rtw_get_passing_time_ms(u32 start); ++ ++void rtw_usleep_os(int us); ++ ++u32 rtw_atoi(u8 *s); ++ ++static inline unsigned char _cancel_timer_ex(struct timer_list *ptimer) ++{ ++ return del_timer_sync(ptimer); ++} ++ ++static __inline void thread_enter(char *name) ++{ ++#ifdef daemonize ++ daemonize("%s", name); ++#endif ++ allow_signal(SIGTERM); ++} ++ ++static inline void flush_signals_thread(void) ++{ ++ if (signal_pending (current)) ++ flush_signals(current); ++} ++ ++static inline int res_to_status(int res) ++{ ++ return res; ++} ++ ++#define _RND(sz, r) ((((sz)+((r)-1))/(r))*(r)) ++#define RND4(x) (((x >> 2) + (((x & 3) == 0) ? 0: 1)) << 2) ++ ++static inline u32 _RND4(u32 sz) ++{ ++ u32 val; ++ ++ val = ((sz >> 2) + ((sz & 3) ? 1: 0)) << 2; ++ return val; ++} ++ ++static inline u32 _RND8(u32 sz) ++{ ++ u32 val; ++ ++ val = ((sz >> 3) + ((sz & 7) ? 1: 0)) << 3; ++ return val; ++} ++ ++static inline u32 _RND128(u32 sz) ++{ ++ u32 val; ++ ++ val = ((sz >> 7) + ((sz & 127) ? 1: 0)) << 7; ++ return val; ++} ++ ++static inline u32 _RND256(u32 sz) ++{ ++ u32 val; ++ ++ val = ((sz >> 8) + ((sz & 255) ? 1: 0)) << 8; ++ return val; ++} ++ ++static inline u32 _RND512(u32 sz) ++{ ++ u32 val; ++ ++ val = ((sz >> 9) + ((sz & 511) ? 1: 0)) << 9; ++ return val; ++} ++ ++static inline u32 bitshift(u32 bitmask) ++{ ++ u32 i; ++ ++ for (i = 0; i <= 31; i++) ++ if (((bitmask>>i) & 0x1) == 1) break; ++ return i; ++} ++ ++/* limitation of path length */ ++#define PATH_LENGTH_MAX PATH_MAX ++ ++struct rtw_netdev_priv_indicator { ++ void *priv; ++ u32 sizeof_priv; ++}; ++struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, ++ void *old_priv); ++struct net_device *rtw_alloc_etherdev(int sizeof_priv); ++ ++#define rtw_netdev_priv(netdev) \ ++ (((struct rtw_netdev_priv_indicator *)netdev_priv(netdev))->priv) ++void rtw_free_netdev(struct net_device *netdev); ++ ++#define NDEV_FMT "%s" ++#define NDEV_ARG(ndev) ndev->name ++#define ADPT_FMT "%s" ++#define ADPT_ARG(adapter) adapter->pnetdev->name ++#define FUNC_NDEV_FMT "%s(%s)" ++#define FUNC_NDEV_ARG(ndev) __func__, ndev->name ++#define FUNC_ADPT_FMT "%s(%s)" ++#define FUNC_ADPT_ARG(adapter) __func__, adapter->pnetdev->name ++ ++#define rtw_signal_process(pid, sig) kill_pid(find_vpid((pid)),(sig), 1) ++ ++/* Macros for handling unaligned memory accesses */ ++ ++#define RTW_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1])) ++#define RTW_PUT_BE16(a, val) \ ++ do { \ ++ (a)[0] = ((u16) (val)) >> 8; \ ++ (a)[1] = ((u16) (val)) & 0xff; \ ++ } while (0) ++ ++#define RTW_PUT_LE16(a, val) \ ++ do { \ ++ (a)[1] = ((u16) (val)) >> 8; \ ++ (a)[0] = ((u16) (val)) & 0xff; \ ++ } while (0) ++ ++#define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \ ++ ((u32) (a)[2])) ++ ++#define RTW_PUT_BE32(a, val) \ ++ do { \ ++ (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ ++ (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ ++ (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ ++ (a)[3] = (u8) (((u32) (val)) & 0xff); \ ++ } while (0) ++ ++void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len); ++ ++struct rtw_cbuf { ++ u32 write; ++ u32 read; ++ u32 size; ++ void *bufs[0]; ++}; ++ ++bool rtw_cbuf_full(struct rtw_cbuf *cbuf); ++bool rtw_cbuf_empty(struct rtw_cbuf *cbuf); ++bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf); ++void *rtw_cbuf_pop(struct rtw_cbuf *cbuf); ++struct rtw_cbuf *rtw_cbuf_alloc(u32 size); ++int wifirate2_ratetbl_inx(unsigned char rate); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/recv_osdep.h b/drivers/staging/r8188eu/include/recv_osdep.h +new file mode 100644 +index 000000000000..72ddf515071e +--- /dev/null ++++ b/drivers/staging/r8188eu/include/recv_osdep.h +@@ -0,0 +1,37 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RECV_OSDEP_H_ ++#define __RECV_OSDEP_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++int _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter); ++void _rtw_free_recv_priv(struct recv_priv *precvpriv); ++ ++s32 rtw_recv_entry(struct recv_frame *precv_frame); ++int rtw_recv_indicatepkt(struct adapter *adapter, struct recv_frame *recv_frame); ++void rtw_recv_returnpacket(struct net_device *cnxt, struct sk_buff *retpkt); ++ ++void rtw_hostapd_mlme_rx(struct adapter *padapter, struct recv_frame *recv_fr); ++void rtw_handle_tkip_mic_err(struct adapter *padapter, u8 bgroup); ++ ++int rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter); ++void rtw_free_recv_priv(struct recv_priv *precvpriv); ++ ++int rtw_os_recv_resource_init(struct recv_priv *recvpr, struct adapter *adapt); ++int rtw_os_recv_resource_alloc(struct adapter *adapt, struct recv_frame *recvfr); ++void rtw_os_recv_resource_free(struct recv_priv *precvpriv); ++ ++int rtw_os_recvbuf_resource_alloc(struct adapter *adapt, struct recv_buf *buf); ++int rtw_os_recvbuf_resource_free(struct adapter *adapt, struct recv_buf *buf); ++ ++void rtw_os_read_port(struct adapter *padapter, struct recv_buf *precvbuf); ++ ++void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl); ++int _netdev_open(struct net_device *pnetdev); ++int netdev_open(struct net_device *pnetdev); ++int netdev_close(struct net_device *pnetdev); ++ ++#endif /* */ +diff --git a/drivers/staging/r8188eu/include/rtl8188e_cmd.h b/drivers/staging/r8188eu/include/rtl8188e_cmd.h +new file mode 100644 +index 000000000000..6fbf9a47430b +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_cmd.h +@@ -0,0 +1,106 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_CMD_H__ ++#define __RTL8188E_CMD_H__ ++ ++enum RTL8188E_H2C_CMD_ID { ++ /* Class Common */ ++ H2C_COM_RSVD_PAGE = 0x00, ++ H2C_COM_MEDIA_STATUS_RPT = 0x01, ++ H2C_COM_SCAN = 0x02, ++ H2C_COM_KEEP_ALIVE = 0x03, ++ H2C_COM_DISCNT_DECISION = 0x04, ++ H2C_COM_INIT_OFFLOAD = 0x06, ++ H2C_COM_REMOTE_WAKE_CTL = 0x07, ++ H2C_COM_AP_OFFLOAD = 0x08, ++ H2C_COM_BCN_RSVD_PAGE = 0x09, ++ H2C_COM_PROB_RSP_RSVD_PAGE = 0x0A, ++ ++ /* Class PS */ ++ H2C_PS_PWR_MODE = 0x20, ++ H2C_PS_TUNE_PARA = 0x21, ++ H2C_PS_TUNE_PARA_2 = 0x22, ++ H2C_PS_LPS_PARA = 0x23, ++ H2C_PS_P2P_OFFLOAD = 0x24, ++ ++ /* Class DM */ ++ H2C_DM_MACID_CFG = 0x40, ++ H2C_DM_TXBF = 0x41, ++ ++ /* Class BT */ ++ H2C_BT_COEX_MASK = 0x60, ++ H2C_BT_COEX_GPIO_MODE = 0x61, ++ H2C_BT_DAC_SWING_VAL = 0x62, ++ H2C_BT_PSD_RST = 0x63, ++ ++ /* Class */ ++ H2C_RESET_TSF = 0xc0, ++}; ++ ++struct cmd_msg_parm { ++ u8 eid; /* element id */ ++ u8 sz; /* sz */ ++ u8 buf[6]; ++}; ++ ++enum { ++ PWRS ++}; ++ ++struct setpwrmode_parm { ++ u8 Mode;/* 0:Active,1:LPS,2:WMMPS */ ++ u8 SmartPS_RLBM;/* LPS= 0:PS_Poll,1:PS_Poll,2:NullData,WMM= 0:PS_Poll,1:NullData */ ++ u8 AwakeInterval; /* unit: beacon interval */ ++ u8 bAllQueueUAPSD; ++ u8 PwrState;/* AllON(0x0c),RFON(0x04),RFOFF(0x00) */ ++}; ++ ++struct H2C_SS_RFOFF_PARAM { ++ u8 ROFOn; /* 1: on, 0:off */ ++ u16 gpio_period; /* unit: 1024 us */ ++} __packed; ++ ++struct joinbssrpt_parm { ++ u8 OpMode; /* RT_MEDIA_STATUS */ ++}; ++ ++struct rsvdpage_loc { ++ u8 LocProbeRsp; ++ u8 LocPsPoll; ++ u8 LocNullData; ++ u8 LocQosNull; ++ u8 LocBTQosNull; ++}; ++ ++struct P2P_PS_Offload_t { ++ u8 Offload_En:1; ++ u8 role:1; /* 1: Owner, 0: Client */ ++ u8 CTWindow_En:1; ++ u8 NoA0_En:1; ++ u8 NoA1_En:1; ++ u8 AllStaSleep:1; /* Only valid in Owner */ ++ u8 discovery:1; ++ u8 rsvd:1; ++}; ++ ++struct P2P_PS_CTWPeriod_t { ++ u8 CTWPeriod; /* TU */ ++}; ++ ++/* host message to firmware cmd */ ++void rtl8188e_set_FwPwrMode_cmd(struct adapter *padapter, u8 Mode); ++void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *padapter, u8 mstatus); ++u8 rtl8188e_set_rssi_cmd(struct adapter *padapter, u8 *param); ++u8 rtl8188e_set_raid_cmd(struct adapter *padapter, u32 mask); ++void rtl8188e_Add_RateATid(struct adapter *padapter, u32 bitmap, u8 arg, ++ u8 rssi_level); ++ ++#ifdef CONFIG_88EU_P2P ++void rtl8188e_set_p2p_ps_offload_cmd(struct adapter *adapt, u8 p2p_ps_state); ++#endif /* CONFIG_88EU_P2P */ ++ ++void CheckFwRsvdPageContent(struct adapter *adapt); ++void rtl8188e_set_FwMediaStatus_cmd(struct adapter *adapt, __le16 mstatus_rpt); ++ ++#endif/* __RTL8188E_CMD_H__ */ +diff --git a/drivers/staging/r8188eu/include/rtl8188e_dm.h b/drivers/staging/r8188eu/include/rtl8188e_dm.h +new file mode 100644 +index 000000000000..3ead20b321a9 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_dm.h +@@ -0,0 +1,47 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_DM_H__ ++#define __RTL8188E_DM_H__ ++ ++enum{ ++ UP_LINK, ++ DOWN_LINK, ++}; ++/* duplicate code,will move to ODM ######### */ ++#define IQK_MAC_REG_NUM 4 ++#define IQK_ADDA_REG_NUM 16 ++#define IQK_BB_REG_NUM 9 ++#define HP_THERMAL_NUM 8 ++/* duplicate code,will move to ODM ######### */ ++struct dm_priv { ++ u8 DM_Type; ++ u8 DMFlag; ++ u8 InitDMFlag; ++ u32 InitODMFlag; ++ ++ /* Upper and Lower Signal threshold for Rate Adaptive*/ ++ int UndecoratedSmoothedPWDB; ++ int UndecoratedSmoothedCCK; ++ int EntryMinUndecoratedSmoothedPWDB; ++ int EntryMaxUndecoratedSmoothedPWDB; ++ int MinUndecoratedPWDBForDM; ++ int LastMinUndecoratedPWDBForDM; ++ ++ /* for High Power */ ++ u8 bDynamicTxPowerEnable; ++ u8 LastDTPLvl; ++ u8 DynamicTxHighPowerLvl;/* Tx Power Control for Near/Far Range */ ++ u8 PowerIndex_backup[6]; ++}; ++ ++void rtl8188e_init_dm_priv(struct adapter *adapt); ++void rtl8188e_deinit_dm_priv(struct adapter *adapt); ++void rtl8188e_InitHalDm(struct adapter *adapt); ++void rtl8188e_HalDmWatchDog(struct adapter *adapt); ++ ++void AntDivCompare8188E(struct adapter *adapt, struct wlan_bssid_ex *dst, ++ struct wlan_bssid_ex *src); ++u8 AntDivBeforeLink8188E(struct adapter *adapt); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtl8188e_hal.h b/drivers/staging/r8188eu/include/rtl8188e_hal.h +new file mode 100644 +index 000000000000..3939bf053de1 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_hal.h +@@ -0,0 +1,452 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_HAL_H__ ++#define __RTL8188E_HAL_H__ ++ ++/* include HAL Related header after HAL Related compiling flags */ ++#include "rtl8188e_spec.h" ++#include "Hal8188EPhyReg.h" ++#include "Hal8188EPhyCfg.h" ++#include "rtl8188e_rf.h" ++#include "rtl8188e_dm.h" ++#include "rtl8188e_recv.h" ++#include "rtl8188e_xmit.h" ++#include "rtl8188e_cmd.h" ++#include "Hal8188EPwrSeq.h" ++#include "rtl8188e_sreset.h" ++#include "rtw_efuse.h" ++ ++#include "odm_precomp.h" ++ ++/* Fw Array */ ++#define Rtl8188E_FwImageArray Rtl8188EFwImgArray ++#define Rtl8188E_FWImgArrayLength Rtl8188EFWImgArrayLength ++ ++#define RTL8188E_FW_UMC_IMG "rtl8188E\\rtl8188efw.bin" ++#define RTL8188E_PHY_REG "rtl8188E\\PHY_REG_1T.txt" ++#define RTL8188E_PHY_RADIO_A "rtl8188E\\radio_a_1T.txt" ++#define RTL8188E_PHY_RADIO_B "rtl8188E\\radio_b_1T.txt" ++#define RTL8188E_AGC_TAB "rtl8188E\\AGC_TAB_1T.txt" ++#define RTL8188E_PHY_MACREG "rtl8188E\\MAC_REG.txt" ++#define RTL8188E_PHY_REG_PG "rtl8188E\\PHY_REG_PG.txt" ++#define RTL8188E_PHY_REG_MP "rtl8188E\\PHY_REG_MP.txt" ++ ++/* RTL8188E Power Configuration CMDs for USB/SDIO interfaces */ ++#define Rtl8188E_NIC_PWR_ON_FLOW rtl8188E_power_on_flow ++#define Rtl8188E_NIC_RF_OFF_FLOW rtl8188E_radio_off_flow ++#define Rtl8188E_NIC_DISABLE_FLOW rtl8188E_card_disable_flow ++#define Rtl8188E_NIC_ENABLE_FLOW rtl8188E_card_enable_flow ++#define Rtl8188E_NIC_SUSPEND_FLOW rtl8188E_suspend_flow ++#define Rtl8188E_NIC_RESUME_FLOW rtl8188E_resume_flow ++#define Rtl8188E_NIC_PDN_FLOW rtl8188E_hwpdn_flow ++#define Rtl8188E_NIC_LPS_ENTER_FLOW rtl8188E_enter_lps_flow ++#define Rtl8188E_NIC_LPS_LEAVE_FLOW rtl8188E_leave_lps_flow ++ ++#define DRVINFO_SZ 4 /* unit is 8bytes */ ++#define PageNum_128(_Len) (u32)(((_Len)>>7) + ((_Len) & 0x7F ? 1 : 0)) ++ ++/* download firmware related data structure */ ++#define FW_8188E_SIZE 0x4000 /* 16384,16k */ ++#define FW_8188E_START_ADDRESS 0x1000 ++#define FW_8188E_END_ADDRESS 0x1FFF /* 0x5FFF */ ++ ++#define MAX_PAGE_SIZE 4096 /* @ page : 4k bytes */ ++ ++#define IS_FW_HEADER_EXIST(_pFwHdr) \ ++ ((le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x92C0 || \ ++ (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x88C0 || \ ++ (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x2300 || \ ++ (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x88E0) ++ ++/* This structure must be careful with byte-ordering */ ++ ++struct rt_firmware_hdr { ++ /* 8-byte alinment required */ ++ /* LONG WORD 0 ---- */ ++ __le16 Signature; /* 92C0: test chip; 92C, ++ * 88C0: test chip; 88C1: MP A-cut; ++ * 92C1: MP A-cut */ ++ u8 Category; /* AP/NIC and USB/PCI */ ++ u8 Function; /* Reserved for different FW function ++ * indcation, for further use when ++ * driver needs to download different ++ * FW for different conditions */ ++ __le16 Version; /* FW Version */ ++ u8 Subversion; /* FW Subversion, default 0x00 */ ++ u16 Rsvd1; ++ ++ /* LONG WORD 1 ---- */ ++ u8 Month; /* Release time Month field */ ++ u8 Date; /* Release time Date field */ ++ u8 Hour; /* Release time Hour field */ ++ u8 Minute; /* Release time Minute field */ ++ __le16 RamCodeSize; /* The size of RAM code */ ++ u8 Foundry; ++ u8 Rsvd2; ++ ++ /* LONG WORD 2 ---- */ ++ __le32 SvnIdx; /* The SVN entry index */ ++ u32 Rsvd3; ++ ++ /* LONG WORD 3 ---- */ ++ u32 Rsvd4; ++ u32 Rsvd5; ++}; ++ ++#define DRIVER_EARLY_INT_TIME 0x05 ++#define BCN_DMA_ATIME_INT_TIME 0x02 ++ ++enum usb_rx_agg_mode { ++ USB_RX_AGG_DISABLE, ++ USB_RX_AGG_DMA, ++ USB_RX_AGG_USB, ++ USB_RX_AGG_MIX ++}; ++ ++#define MAX_RX_DMA_BUFFER_SIZE_88E \ ++ 0x2400 /* 9k for 88E nornal chip , MaxRxBuff=10k-max(TxReportSize(64*8), ++ * WOLPattern(16*24)) */ ++ ++#define MAX_TX_REPORT_BUFFER_SIZE 0x0400 /* 1k */ ++ ++/* BK, BE, VI, VO, HCCA, MANAGEMENT, COMMAND, HIGH, BEACON. */ ++#define MAX_TX_QUEUE 9 ++ ++#define TX_SELE_HQ BIT(0) /* High Queue */ ++#define TX_SELE_LQ BIT(1) /* Low Queue */ ++#define TX_SELE_NQ BIT(2) /* Normal Queue */ ++ ++/* Note: We will divide number of page equally for each queue other ++ * than public queue! */ ++/* 22k = 22528 bytes = 176 pages (@page = 128 bytes) */ ++/* must reserved about 7 pages for LPS => 176-7 = 169 (0xA9) */ ++/* 2*BCN / 1*ps-poll / 1*null-data /1*prob_rsp /1*QOS null-data /1*BT QOS ++ * null-data */ ++ ++#define TX_TOTAL_PAGE_NUMBER_88E 0xA9/* 169 (21632=> 21k) */ ++ ++#define TX_PAGE_BOUNDARY_88E (TX_TOTAL_PAGE_NUMBER_88E + 1) ++ ++/* Note: For Normal Chip Setting ,modify later */ ++#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER \ ++ TX_TOTAL_PAGE_NUMBER_88E /* 0xA9 , 0xb0=>176=>22k */ ++#define WMM_NORMAL_TX_PAGE_BOUNDARY_88E \ ++ (WMM_NORMAL_TX_TOTAL_PAGE_NUMBER + 1) /* 0xA9 */ ++ ++/* Chip specific */ ++#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3) ++#define CHIP_BONDING_92C_1T2R 0x1 ++#define CHIP_BONDING_88C_USB_MCARD 0x2 ++#define CHIP_BONDING_88C_USB_HP 0x1 ++#include "HalVerDef.h" ++#include "hal_com.h" ++ ++/* Channel Plan */ ++enum ChannelPlan { ++ CHPL_FCC = 0, ++ CHPL_IC = 1, ++ CHPL_ETSI = 2, ++ CHPL_SPA = 3, ++ CHPL_FRANCE = 4, ++ CHPL_MKK = 5, ++ CHPL_MKK1 = 6, ++ CHPL_ISRAEL = 7, ++ CHPL_TELEC = 8, ++ CHPL_GLOBAL = 9, ++ CHPL_WORLD = 10, ++}; ++ ++struct txpowerinfo24g { ++ u8 IndexCCK_Base[RF_PATH_MAX][MAX_CHNL_GROUP_24G]; ++ u8 IndexBW40_Base[RF_PATH_MAX][MAX_CHNL_GROUP_24G]; ++ /* If only one tx, only BW20 and OFDM are used. */ ++ s8 CCK_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++ s8 OFDM_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++ s8 BW20_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++ s8 BW40_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++}; ++ ++#define EFUSE_REAL_CONTENT_LEN 512 ++#define EFUSE_MAX_SECTION 16 ++#define EFUSE_IC_ID_OFFSET 506 /* For some inferior IC purpose*/ ++#define AVAILABLE_EFUSE_ADDR(addr) (addr < EFUSE_REAL_CONTENT_LEN) ++/* To prevent out of boundary programming case, */ ++/* leave 1byte and program full section */ ++/* 9bytes + 1byt + 5bytes and pre 1byte. */ ++/* For worst case: */ ++/* | 1byte|----8bytes----|1byte|--5bytes--| */ ++/* | | Reserved(14bytes) | */ ++ ++/* PG data exclude header, dummy 6 bytes frome CP test and reserved 1byte. */ ++#define EFUSE_OOB_PROTECT_BYTES 15 ++ ++#define HWSET_MAX_SIZE_88E 512 ++ ++#define EFUSE_REAL_CONTENT_LEN_88E 256 ++#define EFUSE_MAP_LEN_88E 512 ++#define EFUSE_MAP_LEN EFUSE_MAP_LEN_88E ++#define EFUSE_MAX_SECTION_88E 64 ++#define EFUSE_MAX_WORD_UNIT_88E 4 ++#define EFUSE_IC_ID_OFFSET_88E 506 ++#define AVAILABLE_EFUSE_ADDR_88E(addr) \ ++ (addr < EFUSE_REAL_CONTENT_LEN_88E) ++/* To prevent out of boundary programming case, leave 1byte and program ++ * full section */ ++/* 9bytes + 1byt + 5bytes and pre 1byte. */ ++/* For worst case: */ ++/* | 2byte|----8bytes----|1byte|--7bytes--| 92D */ ++/* PG data exclude header, dummy 7 bytes frome CP test and reserved 1byte. */ ++#define EFUSE_OOB_PROTECT_BYTES_88E 18 ++#define EFUSE_PROTECT_BYTES_BANK_88E 16 ++ ++/* EFUSE for BT definition */ ++#define EFUSE_BT_REAL_CONTENT_LEN 1536 /* 512*3 */ ++#define EFUSE_BT_MAP_LEN 1024 /* 1k bytes */ ++#define EFUSE_BT_MAX_SECTION 128 /* 1024/8 */ ++ ++#define EFUSE_PROTECT_BYTES_BANK 16 ++ ++/* For RTL8723 WiFi/BT/GPS multi-function configuration. */ ++enum rt_multi_func { ++ RT_MULTI_FUNC_NONE = 0x00, ++ RT_MULTI_FUNC_WIFI = 0x01, ++ RT_MULTI_FUNC_BT = 0x02, ++ RT_MULTI_FUNC_GPS = 0x04, ++}; ++ ++/* For RTL8723 regulator mode. */ ++enum rt_regulator_mode { ++ RT_SWITCHING_REGULATOR = 0, ++ RT_LDO_REGULATOR = 1, ++}; ++ ++struct hal_data_8188e { ++ struct HAL_VERSION VersionID; ++ enum rt_multi_func MultiFunc; /* For multi-function consideration. */ ++ enum rt_regulator_mode RegulatorMode; /* switching regulator or LDO */ ++ u16 CustomerID; ++ ++ u16 FirmwareVersion; ++ u16 FirmwareVersionRev; ++ u16 FirmwareSubVersion; ++ u16 FirmwareSignature; ++ u8 PGMaxGroup; ++ /* current WIFI_PHY values */ ++ u32 ReceiveConfig; ++ enum wireless_mode CurrentWirelessMode; ++ enum ht_channel_width CurrentChannelBW; ++ u8 CurrentChannel; ++ u8 nCur40MhzPrimeSC;/* Control channel sub-carrier */ ++ ++ u16 BasicRateSet; ++ ++ /* rf_ctrl */ ++ u8 rf_chip; ++ u8 rf_type; ++ u8 NumTotalRFPath; ++ ++ u8 BoardType; ++ ++ /* EEPROM setting. */ ++ u16 EEPROMVID; ++ u16 EEPROMPID; ++ u16 EEPROMSVID; ++ u16 EEPROMSDID; ++ u8 EEPROMCustomerID; ++ u8 EEPROMSubCustomerID; ++ u8 EEPROMVersion; ++ u8 EEPROMRegulatory; ++ ++ u8 bTXPowerDataReadFromEEPORM; ++ u8 EEPROMThermalMeter; ++ u8 bAPKThermalMeterIgnore; ++ ++ bool EepromOrEfuse; ++ struct efuse_hal EfuseHal; ++ ++ u8 Index24G_CCK_Base[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ u8 Index24G_BW40_Base[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ /* If only one tx, only BW20 and OFDM are used. */ ++ s8 CCK_24G_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++ s8 OFDM_24G_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++ s8 BW20_24G_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++ s8 BW40_24G_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++ ++ u8 TxPwrLevelCck[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ /* For HT 40MHZ pwr */ ++ u8 TxPwrLevelHT40_1S[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ /* For HT 40MHZ pwr */ ++ u8 TxPwrLevelHT40_2S[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ /* HT 20<->40 Pwr diff */ ++ u8 TxPwrHt20Diff[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ /* For HT<->legacy pwr diff */ ++ u8 TxPwrLegacyHtDiff[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ /* For power group */ ++ u8 PwrGroupHT20[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ u8 PwrGroupHT40[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ ++ u8 LegacyHTTxPowerDiff;/* Legacy to HT rate power diff */ ++ /* The current Tx Power Level */ ++ u8 CurrentCckTxPwrIdx; ++ u8 CurrentOfdm24GTxPwrIdx; ++ u8 CurrentBW2024GTxPwrIdx; ++ u8 CurrentBW4024GTxPwrIdx; ++ ++ /* Read/write are allow for following hardware information variables */ ++ u8 framesync; ++ u32 framesyncC34; ++ u8 framesyncMonitor; ++ u8 DefaultInitialGain[4]; ++ u8 pwrGroupCnt; ++ u32 MCSTxPowerLevelOriginalOffset[MAX_PG_GROUP][16]; ++ u32 CCKTxPowerLevelOriginalOffset; ++ ++ u8 CrystalCap; ++ u32 AntennaTxPath; /* Antenna path Tx */ ++ u32 AntennaRxPath; /* Antenna path Rx */ ++ u8 BluetoothCoexist; ++ u8 ExternalPA; ++ ++ u8 bLedOpenDrain; /* Open-drain support for controlling the LED.*/ ++ ++ u8 b1x1RecvCombine; /* for 1T1R receive combining */ ++ ++ u32 AcParam_BE; /* Original parameter for BE, use for EDCA turbo. */ ++ ++ struct bb_reg_def PHYRegDef[4]; /* Radio A/B/C/D */ ++ ++ u32 RfRegChnlVal[2]; ++ ++ /* RDG enable */ ++ bool bRDGEnable; ++ ++ /* for host message to fw */ ++ u8 LastHMEBoxNum; ++ ++ u8 fw_ractrl; ++ u8 RegTxPause; ++ /* Beacon function related global variable. */ ++ u32 RegBcnCtrlVal; ++ u8 RegFwHwTxQCtrl; ++ u8 RegReg542; ++ u8 RegCR_1; ++ ++ struct dm_priv dmpriv; ++ struct odm_dm_struct odmpriv; ++ struct sreset_priv srestpriv; ++ ++ u8 CurAntenna; ++ u8 AntDivCfg; ++ u8 TRxAntDivType; ++ ++ u8 bDumpRxPkt;/* for debug */ ++ u8 bDumpTxPkt;/* for debug */ ++ u8 FwRsvdPageStartOffset; /* Reserve page start offset except ++ * beacon in TxQ. */ ++ ++ /* 2010/08/09 MH Add CU power down mode. */ ++ bool pwrdown; ++ ++ /* Add for dual MAC 0--Mac0 1--Mac1 */ ++ u32 interfaceIndex; ++ ++ u8 OutEpQueueSel; ++ u8 OutEpNumber; ++ ++ /* Add for USB aggreation mode dynamic shceme. */ ++ bool UsbRxHighSpeedMode; ++ ++ /* 2010/11/22 MH Add for slim combo debug mode selective. */ ++ /* This is used for fix the drawback of CU TSMC-A/UMC-A cut. ++ * HW auto suspend ability. Close BT clock. */ ++ bool SlimComboDbg; ++ ++ u16 EfuseUsedBytes; ++ ++#ifdef CONFIG_88EU_P2P ++ struct P2P_PS_Offload_t p2p_ps_offload; ++#endif ++ ++ /* Auto FSM to Turn On, include clock, isolation, power control ++ * for MAC only */ ++ u8 bMacPwrCtrlOn; ++ ++ u32 UsbBulkOutSize; ++ ++ /* Interrupt relatd register information. */ ++ u32 IntArray[3];/* HISR0,HISR1,HSISR */ ++ u32 IntrMask[3]; ++ u8 C2hArray[16]; ++ u8 UsbTxAggMode; ++ u8 UsbTxAggDescNum; ++ u16 HwRxPageSize; /* Hardware setting */ ++ u32 MaxUsbRxAggBlock; ++ ++ enum usb_rx_agg_mode UsbRxAggMode; ++ u8 UsbRxAggBlockCount; /* USB Block count. Block size is ++ * 512-byte in high speed and 64-byte ++ * in full speed */ ++ u8 UsbRxAggBlockTimeout; ++ u8 UsbRxAggPageCount; /* 8192C DMA page count */ ++ u8 UsbRxAggPageTimeout; ++}; ++ ++#define GET_HAL_DATA(__pAdapter) \ ++ ((struct hal_data_8188e *)((__pAdapter)->HalData)) ++#define GET_RF_TYPE(priv) (GET_HAL_DATA(priv)->rf_type) ++ ++#define INCLUDE_MULTI_FUNC_BT(_Adapter) \ ++ (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_BT) ++#define INCLUDE_MULTI_FUNC_GPS(_Adapter) \ ++ (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_GPS) ++ ++/* rtl8188e_hal_init.c */ ++s32 rtl8188e_FirmwareDownload(struct adapter *padapter); ++void _8051Reset88E(struct adapter *padapter); ++void rtl8188e_InitializeFirmwareVars(struct adapter *padapter); ++ ++s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy); ++ ++/* EFuse */ ++u8 GetEEPROMSize8188E(struct adapter *padapter); ++void Hal_InitPGData88E(struct adapter *padapter); ++void Hal_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo); ++void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *hwinfo, ++ bool AutoLoadFail); ++ ++void Hal_EfuseParseEEPROMVer88E(struct adapter *padapter, u8 *hwinfo, ++ bool AutoLoadFail); ++void rtl8188e_EfuseParseChnlPlan(struct adapter *padapter, u8 *hwinfo, ++ bool AutoLoadFail); ++void Hal_EfuseParseCustomerID88E(struct adapter *padapter, u8 *hwinfo, ++ bool AutoLoadFail); ++void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter,u8 *PROMContent, ++ bool AutoLoadFail); ++void Hal_ReadThermalMeter_88E(struct adapter * dapter, u8 *PROMContent, ++ bool AutoloadFail); ++void Hal_EfuseParseXtal_8188E(struct adapter *pAdapter, u8 *hwinfo, ++ bool AutoLoadFail); ++void Hal_EfuseParseBoardType88E(struct adapter *pAdapter, u8 *hwinfo, ++ bool AutoLoadFail); ++void Hal_ReadPowerSavingMode88E(struct adapter *pAdapter, u8 *hwinfo, ++ bool AutoLoadFail); ++ ++bool HalDetectPwrDownMode88E(struct adapter *Adapter); ++ ++void Hal_InitChannelPlan(struct adapter *padapter); ++void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc); ++ ++/* register */ ++void SetBcnCtrlReg(struct adapter *padapter, u8 SetBits, u8 ClearBits); ++ ++void rtl8188e_clone_haldata(struct adapter *dst, struct adapter *src); ++void rtl8188e_start_thread(struct adapter *padapter); ++void rtl8188e_stop_thread(struct adapter *padapter); ++ ++void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int len); ++s32 rtl8188e_iol_efuse_patch(struct adapter *padapter); ++void rtw_cancel_all_timer(struct adapter *padapter); ++void _ps_open_RF(struct adapter *adapt); ++ ++#endif /* __RTL8188E_HAL_H__ */ +diff --git a/drivers/staging/r8188eu/include/rtl8188e_led.h b/drivers/staging/r8188eu/include/rtl8188e_led.h +new file mode 100644 +index 000000000000..b00954198764 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_led.h +@@ -0,0 +1,18 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_LED_H__ ++#define __RTL8188E_LED_H__ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++/* */ ++/* Interface to manipulate LED objects. */ ++/* */ ++void rtl8188eu_InitSwLeds(struct adapter *padapter); ++void rtl8188eu_DeInitSwLeds(struct adapter *padapter); ++void SwLedOn(struct adapter *padapter, struct LED_871x *pLed); ++void SwLedOff(struct adapter *padapter, struct LED_871x *pLed); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtl8188e_recv.h b/drivers/staging/r8188eu/include/rtl8188e_recv.h +new file mode 100644 +index 000000000000..a91daf84d6c3 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_recv.h +@@ -0,0 +1,53 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_RECV_H__ ++#define __RTL8188E_RECV_H__ ++ ++#define TX_RPT1_PKT_LEN 8 ++ ++#define RECV_BLK_SZ 512 ++#define RECV_BLK_CNT 16 ++#define RECV_BLK_TH RECV_BLK_CNT ++#define RECV_BULK_IN_ADDR 0x80 ++#define RECV_INT_IN_ADDR 0x81 ++ ++#define NR_PREALLOC_RECV_SKB (8) ++ ++#define NR_RECVBUFF (4) ++ ++#define MAX_RECVBUF_SZ (15360) /* 15k < 16k */ ++ ++struct phy_stat { ++ unsigned int phydw0; ++ unsigned int phydw1; ++ unsigned int phydw2; ++ unsigned int phydw3; ++ unsigned int phydw4; ++ unsigned int phydw5; ++ unsigned int phydw6; ++ unsigned int phydw7; ++}; ++ ++/* Rx smooth factor */ ++#define Rx_Smooth_Factor (20) ++ ++enum rx_packet_type { ++ NORMAL_RX,/* Normal rx packet */ ++ TX_REPORT1,/* CCX */ ++ TX_REPORT2,/* TX RPT */ ++ HIS_REPORT,/* USB HISR RPT */ ++}; ++ ++#define INTERRUPT_MSG_FORMAT_LEN 60 ++void rtl8188eu_init_recvbuf(struct adapter *padapter, struct recv_buf *buf); ++s32 rtl8188eu_init_recv_priv(struct adapter *padapter); ++void rtl8188eu_free_recv_priv(struct adapter * padapter); ++void rtl8188eu_recv_hdl(struct adapter * padapter, struct recv_buf *precvbuf); ++void rtl8188eu_recv_tasklet(unsigned long priv); ++void rtl8188e_query_rx_phy_status(struct recv_frame *fr, struct phy_stat *phy); ++void rtl8188e_process_phy_info(struct adapter * padapter, void *prframe); ++void update_recvframe_phyinfo_88e(struct recv_frame *fra, struct phy_stat *phy); ++void update_recvframe_attrib_88e(struct recv_frame *fra, struct recv_stat *stat); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtl8188e_rf.h b/drivers/staging/r8188eu/include/rtl8188e_rf.h +new file mode 100644 +index 000000000000..da6b7f8212a3 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_rf.h +@@ -0,0 +1,19 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_RF_H__ ++#define __RTL8188E_RF_H__ ++ ++#define RF6052_MAX_TX_PWR 0x3F ++#define RF6052_MAX_REG 0x3F ++#define RF6052_MAX_PATH 2 ++ ++int PHY_RF6052_Config8188E(struct adapter *Adapter); ++void rtl8188e_RF_ChangeTxPath(struct adapter *Adapter, u16 DataRate); ++void rtl8188e_PHY_RF6052SetBandwidth(struct adapter *Adapter, ++ enum ht_channel_width Bandwidth); ++void rtl8188e_PHY_RF6052SetCckTxPower(struct adapter *Adapter, u8 *level); ++void rtl8188e_PHY_RF6052SetOFDMTxPower(struct adapter *Adapter, u8 *ofdm, ++ u8 *pwrbw20, u8 *pwrbw40, u8 channel); ++ ++#endif/* __RTL8188E_RF_H__ */ +diff --git a/drivers/staging/r8188eu/include/rtl8188e_spec.h b/drivers/staging/r8188eu/include/rtl8188e_spec.h +new file mode 100644 +index 000000000000..1c96f7b81245 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_spec.h +@@ -0,0 +1,1381 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_SPEC_H__ ++#define __RTL8188E_SPEC_H__ ++ ++/* 8192C Regsiter offset definition */ ++ ++#define HAL_PS_TIMER_INT_DELAY 50 /* 50 microseconds */ ++#define HAL_92C_NAV_UPPER_UNIT 128 /* micro-second */ ++ ++#define MAC_ADDR_LEN 6 ++/* 8188E PKT_BUFF_ACCESS_CTRL value */ ++#define TXPKT_BUF_SELECT 0x69 ++#define RXPKT_BUF_SELECT 0xA5 ++#define DISABLE_TRXPKT_BUF_ACCESS 0x0 ++ ++/* 0x0000h ~ 0x00FFh System Configuration */ ++#define REG_SYS_ISO_CTRL 0x0000 ++#define REG_SYS_FUNC_EN 0x0002 ++#define REG_APS_FSMCO 0x0004 ++#define REG_SYS_CLKR 0x0008 ++#define REG_9346CR 0x000A ++#define REG_EE_VPD 0x000C ++#define REG_AFE_MISC 0x0010 ++#define REG_SPS0_CTRL 0x0011 ++#define REG_SPS_OCP_CFG 0x0018 ++#define REG_RSV_CTRL 0x001C ++#define REG_RF_CTRL 0x001F ++#define REG_LDOA15_CTRL 0x0020 ++#define REG_LDOV12D_CTRL 0x0021 ++#define REG_LDOHCI12_CTRL 0x0022 ++#define REG_LPLDO_CTRL 0x0023 ++#define REG_AFE_XTAL_CTRL 0x0024 ++#define REG_AFE_PLL_CTRL 0x0028 ++#define REG_APE_PLL_CTRL_EXT 0x002c ++#define REG_EFUSE_CTRL 0x0030 ++#define REG_EFUSE_TEST 0x0034 ++#define REG_GPIO_MUXCFG 0x0040 ++#define REG_GPIO_IO_SEL 0x0042 ++#define REG_MAC_PINMUX_CFG 0x0043 ++#define REG_GPIO_PIN_CTRL 0x0044 ++#define REG_GPIO_INTM 0x0048 ++#define REG_LEDCFG0 0x004C ++#define REG_LEDCFG1 0x004D ++#define REG_LEDCFG2 0x004E ++#define REG_LEDCFG3 0x004F ++#define REG_FSIMR 0x0050 ++#define REG_FSISR 0x0054 ++#define REG_HSIMR 0x0058 ++#define REG_HSISR 0x005c ++#define REG_GPIO_PIN_CTRL_2 0x0060 /* RTL8723 WIFI/BT/GPS ++ * Multi-Function GPIO Pin Control. */ ++#define REG_GPIO_IO_SEL_2 0x0062 /* RTL8723 WIFI/BT/GPS ++ * Multi-Function GPIO Select. */ ++#define REG_BB_PAD_CTRL 0x0064 ++#define REG_MULTI_FUNC_CTRL 0x0068 /* RTL8723 WIFI/BT/GPS ++ * Multi-Function control source. */ ++#define REG_GPIO_OUTPUT 0x006c ++#define REG_AFE_XTAL_CTRL_EXT 0x0078 /* RTL8188E */ ++#define REG_XCK_OUT_CTRL 0x007c /* RTL8188E */ ++#define REG_MCUFWDL 0x0080 ++#define REG_WOL_EVENT 0x0081 /* RTL8188E */ ++#define REG_MCUTSTCFG 0x0084 ++#define REG_HMEBOX_E0 0x0088 ++#define REG_HMEBOX_E1 0x008A ++#define REG_HMEBOX_E2 0x008C ++#define REG_HMEBOX_E3 0x008E ++#define REG_HMEBOX_EXT_0 0x01F0 ++#define REG_HMEBOX_EXT_1 0x01F4 ++#define REG_HMEBOX_EXT_2 0x01F8 ++#define REG_HMEBOX_EXT_3 0x01FC ++#define REG_HIMR_88E 0x00B0 ++#define REG_HISR_88E 0x00B4 ++#define REG_HIMRE_88E 0x00B8 ++#define REG_HISRE_88E 0x00BC ++#define REG_EFUSE_ACCESS 0x00CF /* Efuse access protection ++ * for RTL8723 */ ++#define REG_BIST_SCAN 0x00D0 ++#define REG_BIST_RPT 0x00D4 ++#define REG_BIST_ROM_RPT 0x00D8 ++#define REG_USB_SIE_INTF 0x00E0 ++#define REG_PCIE_MIO_INTF 0x00E4 ++#define REG_PCIE_MIO_INTD 0x00E8 ++#define REG_HPON_FSM 0x00EC ++#define REG_SYS_CFG 0x00F0 ++#define REG_GPIO_OUTSTS 0x00F4 /* For RTL8723 only. */ ++#define REG_TYPE_ID 0x00FC ++ ++#define REG_MAC_PHY_CTRL_NORMAL 0x00f8 ++ ++/* 0x0100h ~ 0x01FFh MACTOP General Configuration */ ++#define REG_CR 0x0100 ++#define REG_PBP 0x0104 ++#define REG_PKT_BUFF_ACCESS_CTRL 0x0106 ++#define REG_TRXDMA_CTRL 0x010C ++#define REG_TRXFF_BNDY 0x0114 ++#define REG_TRXFF_STATUS 0x0118 ++#define REG_RXFF_PTR 0x011C ++/* define REG_HIMR 0x0120 */ ++/* define REG_HISR 0x0124 */ ++#define REG_HIMRE 0x0128 ++#define REG_HISRE 0x012C ++#define REG_CPWM 0x012F ++#define REG_FWIMR 0x0130 ++#define REG_FTIMR 0x0138 ++#define REG_FWISR 0x0134 ++#define REG_PKTBUF_DBG_CTRL 0x0140 ++#define REG_PKTBUF_DBG_ADDR (REG_PKTBUF_DBG_CTRL) ++#define REG_RXPKTBUF_DBG (REG_PKTBUF_DBG_CTRL+2) ++#define REG_TXPKTBUF_DBG (REG_PKTBUF_DBG_CTRL+3) ++#define REG_RXPKTBUF_CTRL (REG_PKTBUF_DBG_CTRL+2) ++#define REG_PKTBUF_DBG_DATA_L 0x0144 ++#define REG_PKTBUF_DBG_DATA_H 0x0148 ++ ++#define REG_TC0_CTRL 0x0150 ++#define REG_TC1_CTRL 0x0154 ++#define REG_TC2_CTRL 0x0158 ++#define REG_TC3_CTRL 0x015C ++#define REG_TC4_CTRL 0x0160 ++#define REG_TCUNIT_BASE 0x0164 ++#define REG_MBIST_START 0x0174 ++#define REG_MBIST_DONE 0x0178 ++#define REG_MBIST_FAIL 0x017C ++#define REG_32K_CTRL 0x0194 /* RTL8188E */ ++#define REG_C2HEVT_MSG_NORMAL 0x01A0 ++#define REG_C2HEVT_CLEAR 0x01AF ++#define REG_MCUTST_1 0x01c0 ++#define REG_FMETHR 0x01C8 ++#define REG_HMETFR 0x01CC ++#define REG_HMEBOX_0 0x01D0 ++#define REG_HMEBOX_1 0x01D4 ++#define REG_HMEBOX_2 0x01D8 ++#define REG_HMEBOX_3 0x01DC ++ ++#define REG_LLT_INIT 0x01E0 ++ ++/* 0x0200h ~ 0x027Fh TXDMA Configuration */ ++#define REG_RQPN 0x0200 ++#define REG_FIFOPAGE 0x0204 ++#define REG_TDECTRL 0x0208 ++#define REG_TXDMA_OFFSET_CHK 0x020C ++#define REG_TXDMA_STATUS 0x0210 ++#define REG_RQPN_NPQ 0x0214 ++ ++/* 0x0280h ~ 0x02FFh RXDMA Configuration */ ++#define REG_RXDMA_AGG_PG_TH 0x0280 ++#define REG_RXPKT_NUM 0x0284 ++#define REG_RXDMA_STATUS 0x0288 ++ ++/* 0x0300h ~ 0x03FFh PCIe */ ++#define REG_PCIE_CTRL_REG 0x0300 ++#define REG_INT_MIG 0x0304 /* Interrupt Migration */ ++#define REG_BCNQ_DESA 0x0308 /* TX Beacon Descr Address */ ++#define REG_HQ_DESA 0x0310 /* TX High Queue Descr Addr */ ++#define REG_MGQ_DESA 0x0318 /* TX Manage Queue Descr Addr*/ ++#define REG_VOQ_DESA 0x0320 /* TX VO Queue Descr Addr */ ++#define REG_VIQ_DESA 0x0328 /* TX VI Queue Descr Addr */ ++#define REG_BEQ_DESA 0x0330 /* TX BE Queue Descr Addr */ ++#define REG_BKQ_DESA 0x0338 /* TX BK Queue Descr Addr */ ++#define REG_RX_DESA 0x0340 /* RX Queue Descr Addr */ ++#define REG_MDIO 0x0354 /* MDIO for Access PCIE PHY */ ++#define REG_DBG_SEL 0x0360 /* Debug Selection Register */ ++#define REG_PCIE_HRPWM 0x0361 /* PCIe RPWM */ ++#define REG_PCIE_HCPWM 0x0363 /* PCIe CPWM */ ++#define REG_WATCH_DOG 0x0368 ++ ++/* RTL8723 series ------------------------------ */ ++#define REG_PCIE_HISR 0x03A0 ++ ++/* spec version 11 */ ++/* 0x0400h ~ 0x047Fh Protocol Configuration */ ++#define REG_VOQ_INFORMATION 0x0400 ++#define REG_VIQ_INFORMATION 0x0404 ++#define REG_BEQ_INFORMATION 0x0408 ++#define REG_BKQ_INFORMATION 0x040C ++#define REG_MGQ_INFORMATION 0x0410 ++#define REG_HGQ_INFORMATION 0x0414 ++#define REG_BCNQ_INFORMATION 0x0418 ++#define REG_TXPKT_EMPTY 0x041A ++ ++#define REG_CPU_MGQ_INFORMATION 0x041C ++#define REG_FWHW_TXQ_CTRL 0x0420 ++#define REG_HWSEQ_CTRL 0x0423 ++#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 ++#define REG_TXPKTBUF_MGQ_BDNY 0x0425 ++#define REG_LIFETIME_EN 0x0426 ++#define REG_MULTI_BCNQ_OFFSET 0x0427 ++#define REG_SPEC_SIFS 0x0428 ++#define REG_RL 0x042A ++#define REG_DARFRC 0x0430 ++#define REG_RARFRC 0x0438 ++#define REG_RRSR 0x0440 ++#define REG_ARFR0 0x0444 ++#define REG_ARFR1 0x0448 ++#define REG_ARFR2 0x044C ++#define REG_ARFR3 0x0450 ++#define REG_AGGLEN_LMT 0x0458 ++#define REG_AMPDU_MIN_SPACE 0x045C ++#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D ++#define REG_FAST_EDCA_CTRL 0x0460 ++#define REG_RD_RESP_PKT_TH 0x0463 ++#define REG_INIRTS_RATE_SEL 0x0480 ++/* define REG_INIDATA_RATE_SEL 0x0484 */ ++#define REG_POWER_STATUS 0x04A4 ++#define REG_POWER_STAGE1 0x04B4 ++#define REG_POWER_STAGE2 0x04B8 ++#define REG_PKT_VO_VI_LIFE_TIME 0x04C0 ++#define REG_PKT_BE_BK_LIFE_TIME 0x04C2 ++#define REG_STBC_SETTING 0x04C4 ++#define REG_PROT_MODE_CTRL 0x04C8 ++#define REG_MAX_AGGR_NUM 0x04CA ++#define REG_RTS_MAX_AGGR_NUM 0x04CB ++#define REG_BAR_MODE_CTRL 0x04CC ++#define REG_RA_TRY_RATE_AGG_LMT 0x04CF ++#define REG_EARLY_MODE_CONTROL 0x4D0 ++#define REG_NQOS_SEQ 0x04DC ++#define REG_QOS_SEQ 0x04DE ++#define REG_NEED_CPU_HANDLE 0x04E0 ++#define REG_PKT_LOSE_RPT 0x04E1 ++#define REG_PTCL_ERR_STATUS 0x04E2 ++#define REG_TX_RPT_CTRL 0x04EC ++#define REG_TX_RPT_TIME 0x04F0 /* 2 byte */ ++#define REG_DUMMY 0x04FC ++ ++/* 0x0500h ~ 0x05FFh EDCA Configuration */ ++#define REG_EDCA_VO_PARAM 0x0500 ++#define REG_EDCA_VI_PARAM 0x0504 ++#define REG_EDCA_BE_PARAM 0x0508 ++#define REG_EDCA_BK_PARAM 0x050C ++#define REG_BCNTCFG 0x0510 ++#define REG_PIFS 0x0512 ++#define REG_RDG_PIFS 0x0513 ++#define REG_SIFS_CTX 0x0514 ++#define REG_SIFS_TRX 0x0516 ++#define REG_TSFTR_SYN_OFFSET 0x0518 ++#define REG_AGGR_BREAK_TIME 0x051A ++#define REG_SLOT 0x051B ++#define REG_TX_PTCL_CTRL 0x0520 ++#define REG_TXPAUSE 0x0522 ++#define REG_DIS_TXREQ_CLR 0x0523 ++#define REG_RD_CTRL 0x0524 ++/* Format for offset 540h-542h: */ ++/* [3:0]: TBTT prohibit setup in unit of 32us. The time for HW getting ++ * beacon content before TBTT. */ ++/* [7:4]: Reserved. */ ++/* [19:8]: TBTT prohibit hold in unit of 32us. The time for HW holding ++ * to send the beacon packet. */ ++/* [23:20]: Reserved */ ++/* Description: */ ++/* | */ ++/* |<--Setup--|--Hold------------>| */ ++/* --------------|---------------------- */ ++/* | */ ++/* TBTT */ ++/* Note: We cannot update beacon content to HW or send any AC packets during ++ * the time between Setup and Hold. */ ++#define REG_TBTT_PROHIBIT 0x0540 ++#define REG_RD_NAV_NXT 0x0544 ++#define REG_NAV_PROT_LEN 0x0546 ++#define REG_BCN_CTRL 0x0550 ++#define REG_BCN_CTRL_1 0x0551 ++#define REG_MBID_NUM 0x0552 ++#define REG_DUAL_TSF_RST 0x0553 ++#define REG_BCN_INTERVAL 0x0554 ++#define REG_DRVERLYINT 0x0558 ++#define REG_BCNDMATIM 0x0559 ++#define REG_ATIMWND 0x055A ++#define REG_BCN_MAX_ERR 0x055D ++#define REG_RXTSF_OFFSET_CCK 0x055E ++#define REG_RXTSF_OFFSET_OFDM 0x055F ++#define REG_TSFTR 0x0560 ++#define REG_TSFTR1 0x0568 ++#define REG_ATIMWND_1 0x0570 ++#define REG_PSTIMER 0x0580 ++#define REG_TIMER0 0x0584 ++#define REG_TIMER1 0x0588 ++#define REG_ACMHWCTRL 0x05C0 ++ ++/* define REG_FW_TSF_SYNC_CNT 0x04A0 */ ++#define REG_FW_RESET_TSF_CNT_1 0x05FC ++#define REG_FW_RESET_TSF_CNT_0 0x05FD ++#define REG_FW_BCN_DIS_CNT 0x05FE ++ ++/* 0x0600h ~ 0x07FFh WMAC Configuration */ ++#define REG_APSD_CTRL 0x0600 ++#define REG_BWOPMODE 0x0603 ++#define REG_TCR 0x0604 ++#define REG_RCR 0x0608 ++#define REG_RX_PKT_LIMIT 0x060C ++#define REG_RX_DLK_TIME 0x060D ++#define REG_RX_DRVINFO_SZ 0x060F ++ ++#define REG_MACID 0x0610 ++#define REG_BSSID 0x0618 ++#define REG_MAR 0x0620 ++#define REG_MBIDCAMCFG 0x0628 ++ ++#define REG_USTIME_EDCA 0x0638 ++#define REG_MAC_SPEC_SIFS 0x063A ++ ++/* 20100719 Joseph: Hardware register definition change. (HW datasheet v54) */ ++/* [15:8]SIFS_R2T_OFDM, [7:0]SIFS_R2T_CCK */ ++#define REG_R2T_SIFS 0x063C ++/* [15:8]SIFS_T2T_OFDM, [7:0]SIFS_T2T_CCK */ ++#define REG_T2T_SIFS 0x063E ++#define REG_ACKTO 0x0640 ++#define REG_CTS2TO 0x0641 ++#define REG_EIFS 0x0642 ++ ++/* RXERR_RPT */ ++#define RXERR_TYPE_OFDM_PPDU 0 ++#define RXERR_TYPE_OFDM_false_ALARM 1 ++#define RXERR_TYPE_OFDM_MPDU_OK 2 ++#define RXERR_TYPE_OFDM_MPDU_FAIL 3 ++#define RXERR_TYPE_CCK_PPDU 4 ++#define RXERR_TYPE_CCK_false_ALARM 5 ++#define RXERR_TYPE_CCK_MPDU_OK 6 ++#define RXERR_TYPE_CCK_MPDU_FAIL 7 ++#define RXERR_TYPE_HT_PPDU 8 ++#define RXERR_TYPE_HT_false_ALARM 9 ++#define RXERR_TYPE_HT_MPDU_TOTAL 10 ++#define RXERR_TYPE_HT_MPDU_OK 11 ++#define RXERR_TYPE_HT_MPDU_FAIL 12 ++#define RXERR_TYPE_RX_FULL_DROP 15 ++ ++#define RXERR_COUNTER_MASK 0xFFFFF ++#define RXERR_RPT_RST BIT(27) ++#define _RXERR_RPT_SEL(type) ((type) << 28) ++ ++/* Note: */ ++/* The NAV upper value is very important to WiFi 11n 5.2.3 NAV test. ++ * The default value is always too small, but the WiFi TestPlan test ++ * by 25,000 microseconds of NAV through sending CTS in the air. ++ * We must update this value greater than 25,000 microseconds to pass ++ * the item. The offset of NAV_UPPER in 8192C Spec is incorrect, and ++ * the offset should be 0x0652. */ ++#define REG_NAV_UPPER 0x0652 /* unit of 128 */ ++ ++/* WMA, BA, CCX */ ++/* define REG_NAV_CTRL 0x0650 */ ++#define REG_BACAMCMD 0x0654 ++#define REG_BACAMCONTENT 0x0658 ++#define REG_LBDLY 0x0660 ++#define REG_FWDLY 0x0661 ++#define REG_RXERR_RPT 0x0664 ++#define REG_WMAC_TRXPTCL_CTL 0x0668 ++ ++/* Security */ ++#define REG_CAMCMD 0x0670 ++#define REG_CAMWRITE 0x0674 ++#define REG_CAMREAD 0x0678 ++#define REG_CAMDBG 0x067C ++#define REG_SECCFG 0x0680 ++ ++/* Power */ ++#define REG_WOW_CTRL 0x0690 ++#define REG_PS_RX_INFO 0x0692 ++#define REG_UAPSD_TID 0x0693 ++#define REG_WKFMCAM_CMD 0x0698 ++#define REG_WKFMCAM_NUM_88E 0x698 ++#define REG_RXFLTMAP0 0x06A0 ++#define REG_RXFLTMAP1 0x06A2 ++#define REG_RXFLTMAP2 0x06A4 ++#define REG_BCN_PSR_RPT 0x06A8 ++#define REG_BT_COEX_TABLE 0x06C0 ++ ++/* Hardware Port 2 */ ++#define REG_MACID1 0x0700 ++#define REG_BSSID1 0x0708 ++ ++/* 0xFE00h ~ 0xFE55h USB Configuration */ ++#define REG_USB_INFO 0xFE17 ++#define REG_USB_SPECIAL_OPTION 0xFE55 ++#define REG_USB_DMA_AGG_TO 0xFE5B ++#define REG_USB_AGG_TO 0xFE5C ++#define REG_USB_AGG_TH 0xFE5D ++ ++/* For normal chip */ ++#define REG_NORMAL_SIE_VID 0xFE60 /* 0xFE60~0xFE61 */ ++#define REG_NORMAL_SIE_PID 0xFE62 /* 0xFE62~0xFE63 */ ++#define REG_NORMAL_SIE_OPTIONAL 0xFE64 ++#define REG_NORMAL_SIE_EP 0xFE65 /* 0xFE65~0xFE67 */ ++#define REG_NORMAL_SIE_PHY 0xFE68 /* 0xFE68~0xFE6B */ ++#define REG_NORMAL_SIE_OPTIONAL2 0xFE6C ++#define REG_NORMAL_SIE_GPS_EP 0xFE6D /* 0xFE6D, for RTL8723 only. */ ++#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 /* 0xFE70~0xFE75 */ ++#define REG_NORMAL_SIE_STRING 0xFE80 /* 0xFE80~0xFEDF */ ++ ++/* TODO: use these definition when using REG_xxx naming rule. */ ++/* NOTE: DO NOT Remove these definition. Use later. */ ++ ++#define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */ ++#define EFUSE_TEST REG_EFUSE_TEST /* E-Fuse Test. */ ++#define MSR (REG_CR + 2) /* Media Status reg */ ++#define ISR REG_HISR_88E ++/* Timing Sync Function Timer Register. */ ++#define TSFR REG_TSFTR ++ ++#define PBP REG_PBP ++ ++/* Redifine MACID register, to compatible prior ICs. */ ++/* MAC ID Register, Offset 0x0050-0x0053 */ ++#define IDR0 REG_MACID ++/* MAC ID Register, Offset 0x0054-0x0055 */ ++#define IDR4 (REG_MACID + 4) ++ ++/* 9. Security Control Registers (Offset: ) */ ++/* IN 8190 Data Sheet is called CAMcmd */ ++#define RWCAM REG_CAMCMD ++/* Software write CAM input content */ ++#define WCAMI REG_CAMWRITE ++/* Software read/write CAM config */ ++#define RCAMO REG_CAMREAD ++#define CAMDBG REG_CAMDBG ++/* Security Configuration Register */ ++#define SECR REG_SECCFG ++ ++/* Unused register */ ++#define UnusedRegister 0x1BF ++#define DCAM UnusedRegister ++#define PSR UnusedRegister ++#define BBAddr UnusedRegister ++#define PhyDataR UnusedRegister ++ ++/* Min Spacing related settings. */ ++#define MAX_MSS_DENSITY_2T 0x13 ++#define MAX_MSS_DENSITY_1T 0x0A ++ ++/* EEPROM enable when set 1 */ ++#define CmdEEPROM_En BIT(5) ++/* System EEPROM select, 0: boot from E-FUSE, 1: The EEPROM used is 9346 */ ++#define CmdEERPOMSEL BIT(4) ++#define Cmd9346CR_9356SEL BIT(4) ++ ++/* 8192C GPIO MUX Configuration Register (offset 0x40, 4 byte) */ ++#define GPIOSEL_GPIO 0 ++#define GPIOSEL_ENBT BIT(5) ++ ++/* 8192C GPIO PIN Control Register (offset 0x44, 4 byte) */ ++/* GPIO pins input value */ ++#define GPIO_IN REG_GPIO_PIN_CTRL ++/* GPIO pins output value */ ++#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) ++/* GPIO pins output enable when a bit is set to "1"; otherwise, ++ * input is configured. */ ++#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) ++#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) ++ ++/* 8723/8188E Host System Interrupt Mask Register (offset 0x58, 32 byte) */ ++#define HSIMR_GPIO12_0_INT_EN BIT(0) ++#define HSIMR_SPS_OCP_INT_EN BIT(5) ++#define HSIMR_RON_INT_EN BIT(6) ++#define HSIMR_PDN_INT_EN BIT(7) ++#define HSIMR_GPIO9_INT_EN BIT(25) ++ ++/* 8723/8188E Host System Interrupt Status Register (offset 0x5C, 32 byte) */ ++#define HSISR_GPIO12_0_INT BIT(0) ++#define HSISR_SPS_OCP_INT BIT(5) ++#define HSISR_RON_INT_EN BIT(6) ++#define HSISR_PDNINT BIT(7) ++#define HSISR_GPIO9_INT BIT(25) ++ ++/* 8192C (MSR) Media Status Register (Offset 0x4C, 8 bits) */ ++/* ++Network Type ++00: No link ++01: Link in ad hoc network ++10: Link in infrastructure network ++11: AP mode ++Default: 00b. ++*/ ++#define MSR_NOLINK 0x00 ++#define MSR_ADHOC 0x01 ++#define MSR_INFRA 0x02 ++#define MSR_AP 0x03 ++ ++/* 88EU (MSR) Media Status Register (Offset 0x4C, 8 bits) */ ++#define USB_INTR_CONTENT_C2H_OFFSET 0 ++#define USB_INTR_CONTENT_CPWM1_OFFSET 16 ++#define USB_INTR_CONTENT_CPWM2_OFFSET 20 ++#define USB_INTR_CONTENT_HISR_OFFSET 48 ++#define USB_INTR_CONTENT_HISRE_OFFSET 52 ++ ++/* 88E Driver Initialization Offload REG_FDHM0(Offset 0x88, 8 bits) */ ++/* IOL config for REG_FDHM0(Reg0x88) */ ++#define CMD_INIT_LLT BIT(0) ++#define CMD_READ_EFUSE_MAP BIT(1) ++#define CMD_EFUSE_PATCH BIT(2) ++#define CMD_IOCONFIG BIT(3) ++#define CMD_INIT_LLT_ERR BIT(4) ++#define CMD_READ_EFUSE_MAP_ERR BIT(5) ++#define CMD_EFUSE_PATCH_ERR BIT(6) ++#define CMD_IOCONFIG_ERR BIT(7) ++ ++/* 6. Adaptive Control Registers (Offset: 0x0160 - 0x01CF) */ ++/* 8192C Response Rate Set Register (offset 0x181, 24bits) */ ++#define RRSR_1M BIT(0) ++#define RRSR_2M BIT(1) ++#define RRSR_5_5M BIT(2) ++#define RRSR_11M BIT(3) ++#define RRSR_6M BIT(4) ++#define RRSR_9M BIT(5) ++#define RRSR_12M BIT(6) ++#define RRSR_18M BIT(7) ++#define RRSR_24M BIT(8) ++#define RRSR_36M BIT(9) ++#define RRSR_48M BIT(10) ++#define RRSR_54M BIT(11) ++#define RRSR_MCS0 BIT(12) ++#define RRSR_MCS1 BIT(13) ++#define RRSR_MCS2 BIT(14) ++#define RRSR_MCS3 BIT(15) ++#define RRSR_MCS4 BIT(16) ++#define RRSR_MCS5 BIT(17) ++#define RRSR_MCS6 BIT(18) ++#define RRSR_MCS7 BIT(19) ++ ++/* 8192C Response Rate Set Register (offset 0x1BF, 8bits) */ ++/* WOL bit information */ ++#define HAL92C_WOL_PTK_UPDATE_EVENT BIT(0) ++#define HAL92C_WOL_GTK_UPDATE_EVENT BIT(1) ++ ++/* 8192C BW_OPMODE bits (Offset 0x203, 8bit) */ ++#define BW_OPMODE_20MHZ BIT(2) ++ ++/* 8192C CAM Config Setting (offset 0x250, 1 byte) */ ++#define CAM_VALID BIT(15) ++#define CAM_NOTVALID 0x0000 ++#define CAM_USEDK BIT(5) ++ ++#define CAM_CONTENT_COUNT 8 ++ ++#define CAM_NONE 0x0 ++#define CAM_WEP40 0x01 ++#define CAM_TKIP 0x02 ++#define CAM_AES 0x04 ++#define CAM_WEP104 0x05 ++#define CAM_SMS4 0x6 ++ ++#define TOTAL_CAM_ENTRY 32 ++#define HALF_CAM_ENTRY 16 ++ ++#define CAM_CONFIG_USEDK true ++#define CAM_CONFIG_NO_USEDK false ++ ++#define CAM_WRITE BIT(16) ++#define CAM_READ 0x00000000 ++#define CAM_POLLINIG BIT(31) ++ ++#define SCR_UseDK 0x01 ++#define SCR_TxSecEnable 0x02 ++#define SCR_RxSecEnable 0x04 ++ ++/* 10. Power Save Control Registers (Offset: 0x0260 - 0x02DF) */ ++#define WOW_PMEN BIT(0) /* Power management Enable. */ ++#define WOW_WOMEN BIT(1) /* WoW function on or off. */ ++#define WOW_MAGIC BIT(2) /* Magic packet */ ++#define WOW_UWF BIT(3) /* Unicast Wakeup frame. */ ++ ++/* 12. Host Interrupt Status Registers (Offset: 0x0300 - 0x030F) */ ++/* 8188 IMR/ISR bits */ ++#define IMR_DISABLED_88E 0x0 ++/* IMR DW0(0x0060-0063) Bit 0-31 */ ++#define IMR_TXCCK_88E BIT(30) /* TXRPT interrupt when CCX bit of the packet is set */ ++#define IMR_PSTIMEOUT_88E BIT(29) /* Power Save Time Out Interrupt */ ++#define IMR_GTINT4_88E BIT(28) /* When GTIMER4 expires, this bit is set to 1 */ ++#define IMR_GTINT3_88E BIT(27) /* When GTIMER3 expires, this bit is set to 1 */ ++#define IMR_TBDER_88E BIT(26) /* Transmit Beacon0 Error */ ++#define IMR_TBDOK_88E BIT(25) /* Transmit Beacon0 OK */ ++#define IMR_TSF_BIT32_TOGGLE_88E BIT(24) /* TSF Timer BIT32 toggle indication interrupt */ ++#define IMR_BCNDMAINT0_88E BIT(20) /* Beacon DMA Interrupt 0 */ ++#define IMR_BCNDERR0_88E BIT(16) /* Beacon Queue DMA Error 0 */ ++#define IMR_HSISR_IND_ON_INT_88E BIT(15) /* HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1) */ ++#define IMR_BCNDMAINT_E_88E BIT(14) /* Beacon DMA Interrupt Extension for Win7 */ ++#define IMR_ATIMEND_88E BIT(12) /* CTWidnow End or ATIM Window End */ ++#define IMR_HISR1_IND_INT_88E BIT(11) /* HISR1 Indicator (HISR1 & HIMR1 is true, this bit is set to 1) */ ++#define IMR_C2HCMD_88E BIT(10) /* CPU to Host Command INT Status, Write 1 clear */ ++#define IMR_CPWM2_88E BIT(9) /* CPU power Mode exchange INT Status, Write 1 clear */ ++#define IMR_CPWM_88E BIT(8) /* CPU power Mode exchange INT Status, Write 1 clear */ ++#define IMR_HIGHDOK_88E BIT(7) /* High Queue DMA OK */ ++#define IMR_MGNTDOK_88E BIT(6) /* Management Queue DMA OK */ ++#define IMR_BKDOK_88E BIT(5) /* AC_BK DMA OK */ ++#define IMR_BEDOK_88E BIT(4) /* AC_BE DMA OK */ ++#define IMR_VIDOK_88E BIT(3) /* AC_VI DMA OK */ ++#define IMR_VODOK_88E BIT(2) /* AC_VO DMA OK */ ++#define IMR_RDU_88E BIT(1) /* Rx Descriptor Unavailable */ ++#define IMR_ROK_88E BIT(0) /* Receive DMA OK */ ++ ++/* IMR DW1(0x00B4-00B7) Bit 0-31 */ ++#define IMR_BCNDMAINT7_88E BIT(27) /* Beacon DMA Interrupt 7 */ ++#define IMR_BCNDMAINT6_88E BIT(26) /* Beacon DMA Interrupt 6 */ ++#define IMR_BCNDMAINT5_88E BIT(25) /* Beacon DMA Interrupt 5 */ ++#define IMR_BCNDMAINT4_88E BIT(24) /* Beacon DMA Interrupt 4 */ ++#define IMR_BCNDMAINT3_88E BIT(23) /* Beacon DMA Interrupt 3 */ ++#define IMR_BCNDMAINT2_88E BIT(22) /* Beacon DMA Interrupt 2 */ ++#define IMR_BCNDMAINT1_88E BIT(21) /* Beacon DMA Interrupt 1 */ ++#define IMR_BCNDERR7_88E BIT(20) /* Beacon DMA Error Int 7 */ ++#define IMR_BCNDERR6_88E BIT(19) /* Beacon DMA Error Int 6 */ ++#define IMR_BCNDERR5_88E BIT(18) /* Beacon DMA Error Int 5 */ ++#define IMR_BCNDERR4_88E BIT(17) /* Beacon DMA Error Int 4 */ ++#define IMR_BCNDERR3_88E BIT(16) /* Beacon DMA Error Int 3 */ ++#define IMR_BCNDERR2_88E BIT(15) /* Beacon DMA Error Int 2 */ ++#define IMR_BCNDERR1_88E BIT(14) /* Beacon DMA Error Int 1 */ ++#define IMR_ATIMEND_E_88E BIT(13) /* ATIM Window End Ext for Win7 */ ++#define IMR_TXERR_88E BIT(11) /* Tx Err Flag Int Status, write 1 clear. */ ++#define IMR_RXERR_88E BIT(10) /* Rx Err Flag INT Status, Write 1 clear */ ++#define IMR_TXFOVW_88E BIT(9) /* Transmit FIFO Overflow */ ++#define IMR_RXFOVW_88E BIT(8) /* Receive FIFO Overflow */ ++ ++#define HAL_NIC_UNPLUG_ISR 0xFFFFFFFF /* The value when the NIC is unplugged for PCI. */ ++ ++/* 8192C EFUSE */ ++#define HWSET_MAX_SIZE 256 ++#define HWSET_MAX_SIZE_88E 512 ++ ++/*=================================================================== ++===================================================================== ++Here the register defines are for 92C. When the define is as same with 92C, ++we will use the 92C's define for the consistency ++So the following defines for 92C is not entire!!!!!! ++===================================================================== ++=====================================================================*/ ++/* ++Based on Datasheet V33---090401 ++Register Summary ++Current IOREG MAP ++0x0000h ~ 0x00FFh System Configuration (256 Bytes) ++0x0100h ~ 0x01FFh MACTOP General Configuration (256 Bytes) ++0x0200h ~ 0x027Fh TXDMA Configuration (128 Bytes) ++0x0280h ~ 0x02FFh RXDMA Configuration (128 Bytes) ++0x0300h ~ 0x03FFh PCIE EMAC Reserved Region (256 Bytes) ++0x0400h ~ 0x04FFh Protocol Configuration (256 Bytes) ++0x0500h ~ 0x05FFh EDCA Configuration (256 Bytes) ++0x0600h ~ 0x07FFh WMAC Configuration (512 Bytes) ++0x2000h ~ 0x3FFFh 8051 FW Download Region (8196 Bytes) ++*/ ++/* 8192C (TXPAUSE) transmission pause (Offset 0x522, 8 bits) */ ++/* Note: */ ++/* The bits of stopping AC(VO/VI/BE/BK) queue in datasheet ++ * RTL8192S/RTL8192C are wrong, */ ++/* the correct arragement is VO - Bit0, VI - Bit1, BE - Bit2, ++ * and BK - Bit3. */ ++/* 8723 and 88E may be not correct either in the earlier version. */ ++#define StopBecon BIT(6) ++#define StopHigh BIT(5) ++#define StopMgt BIT(4) ++#define StopBK BIT(3) ++#define StopBE BIT(2) ++#define StopVI BIT(1) ++#define StopVO BIT(0) ++ ++/* 8192C (RCR) Receive Configuration Register(Offset 0x608, 32 bits) */ ++#define RCR_APPFCS BIT(31) /* WMAC append FCS after payload */ ++#define RCR_APP_MIC BIT(30) ++#define RCR_APP_PHYSTS BIT(28) ++#define RCR_APP_ICV BIT(29) ++#define RCR_APP_PHYST_RXFF BIT(28) ++#define RCR_APP_BA_SSN BIT(27) /* Accept BA SSN */ ++#define RCR_ENMBID BIT(24) /* Enable Multiple BssId. */ ++#define RCR_LSIGEN BIT(23) ++#define RCR_MFBEN BIT(22) ++#define RCR_HTC_LOC_CTRL BIT(14) /* MFC<--HTC=1 MFC-->HTC=0 */ ++#define RCR_AMF BIT(13) /* Accept management type frame */ ++#define RCR_ACF BIT(12) /* Accept control type frame */ ++#define RCR_ADF BIT(11) /* Accept data type frame */ ++#define RCR_AICV BIT(9) /* Accept ICV error packet */ ++#define RCR_ACRC32 BIT(8) /* Accept CRC32 error packet */ ++#define RCR_CBSSID_BCN BIT(7) /* Accept BSSID match packet ++ * (Rx beacon, probe rsp) */ ++#define RCR_CBSSID_DATA BIT(6) /* Accept BSSID match (Data)*/ ++#define RCR_CBSSID RCR_CBSSID_DATA /* Accept BSSID match */ ++#define RCR_APWRMGT BIT(5) /* Accept power management pkt*/ ++#define RCR_ADD3 BIT(4) /* Accept address 3 match pkt */ ++#define RCR_AB BIT(3) /* Accept broadcast packet */ ++#define RCR_AM BIT(2) /* Accept multicast packet */ ++#define RCR_APM BIT(1) /* Accept physical match pkt */ ++#define RCR_AAP BIT(0) /* Accept all unicast packet */ ++#define RCR_MXDMA_OFFSET 8 ++#define RCR_FIFO_OFFSET 13 ++ ++/* 0xFE00h ~ 0xFE55h USB Configuration */ ++#define REG_USB_INFO 0xFE17 ++#define REG_USB_SPECIAL_OPTION 0xFE55 ++#define REG_USB_DMA_AGG_TO 0xFE5B ++#define REG_USB_AGG_TO 0xFE5C ++#define REG_USB_AGG_TH 0xFE5D ++ ++#define REG_USB_HRPWM 0xFE58 ++#define REG_USB_HCPWM 0xFE57 ++/* 8192C Regsiter Bit and Content definition */ ++/* 0x0000h ~ 0x00FFh System Configuration */ ++ ++/* 2 SYS_ISO_CTRL */ ++#define ISO_MD2PP BIT(0) ++#define ISO_UA2USB BIT(1) ++#define ISO_UD2CORE BIT(2) ++#define ISO_PA2PCIE BIT(3) ++#define ISO_PD2CORE BIT(4) ++#define ISO_IP2MAC BIT(5) ++#define ISO_DIOP BIT(6) ++#define ISO_DIOE BIT(7) ++#define ISO_EB2CORE BIT(8) ++#define ISO_DIOR BIT(9) ++#define PWC_EV12V BIT(15) ++ ++/* 2 SYS_FUNC_EN */ ++#define FEN_BBRSTB BIT(0) ++#define FEN_BB_GLB_RSTn BIT(1) ++#define FEN_USBA BIT(2) ++#define FEN_UPLL BIT(3) ++#define FEN_USBD BIT(4) ++#define FEN_DIO_PCIE BIT(5) ++#define FEN_PCIEA BIT(6) ++#define FEN_PPLL BIT(7) ++#define FEN_PCIED BIT(8) ++#define FEN_DIOE BIT(9) ++#define FEN_CPUEN BIT(10) ++#define FEN_DCORE BIT(11) ++#define FEN_ELDR BIT(12) ++#define FEN_DIO_RF BIT(13) ++#define FEN_HWPDN BIT(14) ++#define FEN_MREGEN BIT(15) ++ ++/* 2 APS_FSMCO */ ++#define PFM_LDALL BIT(0) ++#define PFM_ALDN BIT(1) ++#define PFM_LDKP BIT(2) ++#define PFM_WOWL BIT(3) ++#define EnPDN BIT(4) ++#define PDN_PL BIT(5) ++#define APFM_ONMAC BIT(8) ++#define APFM_OFF BIT(9) ++#define APFM_RSM BIT(10) ++#define AFSM_HSUS BIT(11) ++#define AFSM_PCIE BIT(12) ++#define APDM_MAC BIT(13) ++#define APDM_HOST BIT(14) ++#define APDM_HPDN BIT(15) ++#define RDY_MACON BIT(16) ++#define SUS_HOST BIT(17) ++#define ROP_ALD BIT(20) ++#define ROP_PWR BIT(21) ++#define ROP_SPS BIT(22) ++#define SOP_MRST BIT(25) ++#define SOP_FUSE BIT(26) ++#define SOP_ABG BIT(27) ++#define SOP_AMB BIT(28) ++#define SOP_RCK BIT(29) ++#define SOP_A8M BIT(30) ++#define XOP_BTCK BIT(31) ++ ++/* 2 SYS_CLKR */ ++#define ANAD16V_EN BIT(0) ++#define ANA8M BIT(1) ++#define MACSLP BIT(4) ++#define LOADER_CLK_EN BIT(5) ++ ++/* 2 9346CR */ ++ ++#define BOOT_FROM_EEPROM BIT(4) ++#define EEPROM_EN BIT(5) ++ ++/* 2 SPS0_CTRL */ ++ ++/* 2 SPS_OCP_CFG */ ++ ++/* 2 RF_CTRL */ ++#define RF_EN BIT(0) ++#define RF_RSTB BIT(1) ++#define RF_SDMRSTB BIT(2) ++ ++/* 2 LDOV12D_CTRL */ ++#define LDV12_EN BIT(0) ++#define LDV12_SDBY BIT(1) ++#define LPLDO_HSM BIT(2) ++#define LPLDO_LSM_DIS BIT(3) ++#define _LDV12_VADJ(x) (((x) & 0xF) << 4) ++ ++/* 2EFUSE_CTRL */ ++#define ALD_EN BIT(18) ++#define EF_PD BIT(19) ++#define EF_FLAG BIT(31) ++ ++/* 2 EFUSE_TEST (For RTL8723 partially) */ ++#define EF_TRPT BIT(7) ++/* 00: Wifi Efuse, 01: BT Efuse0, 10: BT Efuse1, 11: BT Efuse2 */ ++#define EF_CELL_SEL (BIT(8)|BIT(9)) ++#define LDOE25_EN BIT(31) ++#define EFUSE_SEL(x) (((x) & 0x3) << 8) ++#define EFUSE_SEL_MASK 0x300 ++#define EFUSE_WIFI_SEL_0 0x0 ++#define EFUSE_BT_SEL_0 0x1 ++#define EFUSE_BT_SEL_1 0x2 ++#define EFUSE_BT_SEL_2 0x3 ++ ++#define EFUSE_ACCESS_ON 0x69 /* For RTL8723 only. */ ++#define EFUSE_ACCESS_OFF 0x00 /* For RTL8723 only. */ ++ ++/* 2 8051FWDL */ ++/* 2 MCUFWDL */ ++#define MCUFWDL_EN BIT(0) ++#define MCUFWDL_RDY BIT(1) ++#define FWDL_ChkSum_rpt BIT(2) ++#define MACINI_RDY BIT(3) ++#define BBINI_RDY BIT(4) ++#define RFINI_RDY BIT(5) ++#define WINTINI_RDY BIT(6) ++#define RAM_DL_SEL BIT(7) /* 1:RAM, 0:ROM */ ++#define ROM_DLEN BIT(19) ++#define CPRST BIT(23) ++ ++/* 2 REG_SYS_CFG */ ++#define XCLK_VLD BIT(0) ++#define ACLK_VLD BIT(1) ++#define UCLK_VLD BIT(2) ++#define PCLK_VLD BIT(3) ++#define PCIRSTB BIT(4) ++#define V15_VLD BIT(5) ++#define SW_OFFLOAD_EN BIT(7) ++#define SIC_IDLE BIT(8) ++#define BD_MAC2 BIT(9) ++#define BD_MAC1 BIT(10) ++#define IC_MACPHY_MODE BIT(11) ++#define CHIP_VER (BIT(12)|BIT(13)|BIT(14)|BIT(15)) ++#define BT_FUNC BIT(16) ++#define VENDOR_ID BIT(19) ++#define PAD_HWPD_IDN BIT(22) ++#define TRP_VAUX_EN BIT(23) /* RTL ID */ ++#define TRP_BT_EN BIT(24) ++#define BD_PKG_SEL BIT(25) ++#define BD_HCI_SEL BIT(26) ++#define TYPE_ID BIT(27) ++ ++#define CHIP_VER_RTL_MASK 0xF000 /* Bit 12 ~ 15 */ ++#define CHIP_VER_RTL_SHIFT 12 ++ ++/* 2REG_GPIO_OUTSTS (For RTL8723 only) */ ++#define EFS_HCI_SEL (BIT(0)|BIT(1)) ++#define PAD_HCI_SEL (BIT(2)|BIT(3)) ++#define HCI_SEL (BIT(4)|BIT(5)) ++#define PKG_SEL_HCI BIT(6) ++#define FEN_GPS BIT(7) ++#define FEN_BT BIT(8) ++#define FEN_WL BIT(9) ++#define FEN_PCI BIT(10) ++#define FEN_USB BIT(11) ++#define BTRF_HWPDN_N BIT(12) ++#define WLRF_HWPDN_N BIT(13) ++#define PDN_BT_N BIT(14) ++#define PDN_GPS_N BIT(15) ++#define BT_CTL_HWPDN BIT(16) ++#define GPS_CTL_HWPDN BIT(17) ++#define PPHY_SUSB BIT(20) ++#define UPHY_SUSB BIT(21) ++#define PCI_SUSEN BIT(22) ++#define USB_SUSEN BIT(23) ++#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28)) ++ ++/* 2SYS_CFG */ ++#define RTL_ID BIT(23) /* TestChip ID, 1:Test(RLE); 0:MP(RL) */ ++ ++/* 0x0100h ~ 0x01FFh MACTOP General Configuration */ ++ ++/* 2 Function Enable Registers */ ++/* 2 CR */ ++ ++#define HCI_TXDMA_EN BIT(0) ++#define HCI_RXDMA_EN BIT(1) ++#define TXDMA_EN BIT(2) ++#define RXDMA_EN BIT(3) ++#define PROTOCOL_EN BIT(4) ++#define SCHEDULE_EN BIT(5) ++#define MACTXEN BIT(6) ++#define MACRXEN BIT(7) ++#define ENSWBCN BIT(8) ++#define ENSEC BIT(9) ++#define CALTMR_EN BIT(10) /* 32k CAL TMR enable */ ++ ++/* Network type */ ++#define _NETTYPE(x) (((x) & 0x3) << 16) ++#define MASK_NETTYPE 0x30000 ++#define NT_NO_LINK 0x0 ++#define NT_LINK_AD_HOC 0x1 ++#define NT_LINK_AP 0x2 ++#define NT_AS_AP 0x3 ++ ++/* 2 PBP - Page Size Register */ ++#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) ++#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) ++#define _PSRX_MASK 0xF ++#define _PSTX_MASK 0xF0 ++#define _PSRX(x) (x) ++#define _PSTX(x) ((x) << 4) ++ ++#define PBP_64 0x0 ++#define PBP_128 0x1 ++#define PBP_256 0x2 ++#define PBP_512 0x3 ++#define PBP_1024 0x4 ++ ++/* 2 TX/RXDMA */ ++#define RXDMA_ARBBW_EN BIT(0) ++#define RXSHFT_EN BIT(1) ++#define RXDMA_AGG_EN BIT(2) ++#define QS_VO_QUEUE BIT(8) ++#define QS_VI_QUEUE BIT(9) ++#define QS_BE_QUEUE BIT(10) ++#define QS_BK_QUEUE BIT(11) ++#define QS_MANAGER_QUEUE BIT(12) ++#define QS_HIGH_QUEUE BIT(13) ++ ++#define HQSEL_VOQ BIT(0) ++#define HQSEL_VIQ BIT(1) ++#define HQSEL_BEQ BIT(2) ++#define HQSEL_BKQ BIT(3) ++#define HQSEL_MGTQ BIT(4) ++#define HQSEL_HIQ BIT(5) ++ ++/* For normal driver, 0x10C */ ++#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) ++#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) ++#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) ++#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8 ) ++#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6 ) ++#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4 ) ++ ++#define QUEUE_LOW 1 ++#define QUEUE_NORMAL 2 ++#define QUEUE_HIGH 3 ++ ++/* 2 TRXFF_BNDY */ ++ ++/* 2 LLT_INIT */ ++#define _LLT_NO_ACTIVE 0x0 ++#define _LLT_WRITE_ACCESS 0x1 ++#define _LLT_READ_ACCESS 0x2 ++ ++#define _LLT_INIT_DATA(x) ((x) & 0xFF) ++#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) ++#define _LLT_OP(x) (((x) & 0x3) << 30) ++#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) ++ ++/* 0x0200h ~ 0x027Fh TXDMA Configuration */ ++/* 2RQPN */ ++#define _HPQ(x) ((x) & 0xFF) ++#define _LPQ(x) (((x) & 0xFF) << 8) ++#define _PUBQ(x) (((x) & 0xFF) << 16) ++/* NOTE: in RQPN_NPQ register */ ++#define _NPQ(x) ((x) & 0xFF) ++ ++#define HPQ_PUBLIC_DIS BIT(24) ++#define LPQ_PUBLIC_DIS BIT(25) ++#define LD_RQPN BIT(31) ++ ++/* 2TDECTRL */ ++#define BCN_VALID BIT(16) ++#define BCN_HEAD(x) (((x) & 0xFF) << 8) ++#define BCN_HEAD_MASK 0xFF00 ++ ++/* 2 TDECTL */ ++#define BLK_DESC_NUM_SHIFT 4 ++#define BLK_DESC_NUM_MASK 0xF ++ ++/* 2 TXDMA_OFFSET_CHK */ ++#define DROP_DATA_EN BIT(9) ++ ++/* 0x0280h ~ 0x028Bh RX DMA Configuration */ ++ ++/* REG_RXDMA_CONTROL, 0x0286h */ ++ ++/* 2 REG_RXPKT_NUM, 0x0284 */ ++#define RXPKT_RELEASE_POLL BIT(16) ++#define RXDMA_IDLE BIT(17) ++#define RW_RELEASE_EN BIT(18) ++ ++/* 0x0400h ~ 0x047Fh Protocol Configuration */ ++/* 2 FWHW_TXQ_CTRL */ ++#define EN_AMPDU_RTY_NEW BIT(7) ++ ++/* 2 SPEC SIFS */ ++#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) ++#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) ++ ++/* 2 RL */ ++#define RETRY_LIMIT_SHORT_SHIFT 8 ++#define RETRY_LIMIT_LONG_SHIFT 0 ++ ++/* 0x0500h ~ 0x05FFh EDCA Configuration */ ++ ++/* 2 EDCA setting */ ++#define AC_PARAM_TXOP_LIMIT_OFFSET 16 ++#define AC_PARAM_ECW_MAX_OFFSET 12 ++#define AC_PARAM_ECW_MIN_OFFSET 8 ++#define AC_PARAM_AIFS_OFFSET 0 ++ ++#define _LRL(x) ((x) & 0x3F) ++#define _SRL(x) (((x) & 0x3F) << 8) ++ ++/* 2 BCN_CTRL */ ++#define EN_MBSSID BIT(1) ++#define EN_TXBCN_RPT BIT(2) ++#define EN_BCN_FUNCTION BIT(3) ++#define DIS_TSF_UPDATE BIT(3) ++ ++/* The same function but different bit field. */ ++#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) ++#define DIS_TSF_UDT0_TEST_CHIP BIT(5) ++#define STOP_BCNQ BIT(6) ++ ++/* 2 ACMHWCTRL */ ++#define AcmHw_HwEn BIT(0) ++#define AcmHw_BeqEn BIT(1) ++#define AcmHw_ViqEn BIT(2) ++#define AcmHw_VoqEn BIT(3) ++#define AcmHw_BeqStatus BIT(4) ++#define AcmHw_ViqStatus BIT(5) ++#define AcmHw_VoqStatus BIT(6) ++ ++/* 0x0600h ~ 0x07FFh WMAC Configuration */ ++/* 2APSD_CTRL */ ++#define APSDOFF BIT(6) ++#define APSDOFF_STATUS BIT(7) ++ ++#define RATE_BITMAP_ALL 0xFFFFF ++ ++/* Only use CCK 1M rate for ACK */ ++#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 ++ ++/* 2 TCR */ ++#define TSFRST BIT(0) ++#define DIS_GCLK BIT(1) ++#define PAD_SEL BIT(2) ++#define PWR_ST BIT(6) ++#define PWRBIT_OW_EN BIT(7) ++#define ACRC BIT(8) ++#define CFENDFORM BIT(9) ++#define ICV BIT(10) ++ ++/* 2 RCR */ ++#define AAP BIT(0) ++#define APM BIT(1) ++#define AM BIT(2) ++#define AB BIT(3) ++#define ADD3 BIT(4) ++#define APWRMGT BIT(5) ++#define CBSSID BIT(6) ++#define CBSSID_DATA BIT(6) ++#define CBSSID_BCN BIT(7) ++#define ACRC32 BIT(8) ++#define AICV BIT(9) ++#define ADF BIT(11) ++#define ACF BIT(12) ++#define AMF BIT(13) ++#define HTC_LOC_CTRL BIT(14) ++#define UC_DATA_EN BIT(16) ++#define BM_DATA_EN BIT(17) ++#define MFBEN BIT(22) ++#define LSIGEN BIT(23) ++#define EnMBID BIT(24) ++#define APP_BASSN BIT(27) ++#define APP_PHYSTS BIT(28) ++#define APP_ICV BIT(29) ++#define APP_MIC BIT(30) ++#define APP_FCS BIT(31) ++ ++/* 2 SECCFG */ ++#define SCR_TxUseDK BIT(0) /* Force Tx Use Default Key */ ++#define SCR_RxUseDK BIT(1) /* Force Rx Use Default Key */ ++#define SCR_TxEncEnable BIT(2) /* Enable Tx Encryption */ ++#define SCR_RxDecEnable BIT(3) /* Enable Rx Decryption */ ++#define SCR_SKByA2 BIT(4) /* Search kEY BY A2 */ ++#define SCR_NoSKMC BIT(5) /* No Key Search Multicast */ ++#define SCR_TXBCUSEDK BIT(6) /* Force Tx Bcast pkt Use Default Key */ ++#define SCR_RXBCUSEDK BIT(7) /* Force Rx Bcast pkt Use Default Key */ ++ ++/* RTL8188E SDIO Configuration */ ++ ++/* I/O bus domain address mapping */ ++#define SDIO_LOCAL_BASE 0x10250000 ++#define WLAN_IOREG_BASE 0x10260000 ++#define FIRMWARE_FIFO_BASE 0x10270000 ++#define TX_HIQ_BASE 0x10310000 ++#define TX_MIQ_BASE 0x10320000 ++#define TX_LOQ_BASE 0x10330000 ++#define RX_RX0FF_BASE 0x10340000 ++ ++/* SDIO host local register space mapping. */ ++#define SDIO_LOCAL_MSK 0x0FFF ++#define WLAN_IOREG_MSK 0x7FFF ++#define WLAN_FIFO_MSK 0x1FFF /* Aggregation Length[12:0] */ ++#define WLAN_RX0FF_MSK 0x0003 ++ ++/* Without ref to the SDIO Device ID */ ++#define SDIO_WITHOUT_REF_DEVICE_ID 0 ++#define SDIO_LOCAL_DEVICE_ID 0 /* 0b[16], 000b[15:13] */ ++#define WLAN_TX_HIQ_DEVICE_ID 4 /* 0b[16], 100b[15:13] */ ++#define WLAN_TX_MIQ_DEVICE_ID 5 /* 0b[16], 101b[15:13] */ ++#define WLAN_TX_LOQ_DEVICE_ID 6 /* 0b[16], 110b[15:13] */ ++#define WLAN_RX0FF_DEVICE_ID 7 /* 0b[16], 111b[15:13] */ ++#define WLAN_IOREG_DEVICE_ID 8 /* 1b[16] */ ++ ++/* SDIO Tx Free Page Index */ ++#define HI_QUEUE_IDX 0 ++#define MID_QUEUE_IDX 1 ++#define LOW_QUEUE_IDX 2 ++#define PUBLIC_QUEUE_IDX 3 ++ ++#define SDIO_MAX_TX_QUEUE 3 /* HIQ, MIQ and LOQ */ ++#define SDIO_MAX_RX_QUEUE 1 ++ ++/* SDIO Tx Control */ ++#define SDIO_REG_TX_CTRL 0x0000 ++/* SDIO Host Interrupt Mask */ ++#define SDIO_REG_HIMR 0x0014 ++/* SDIO Host Interrupt Service Routine */ ++#define SDIO_REG_HISR 0x0018 ++/* HCI Current Power Mode */ ++#define SDIO_REG_HCPWM 0x0019 ++/* RXDMA Request Length */ ++#define SDIO_REG_RX0_REQ_LEN 0x001C ++/* Free Tx Buffer Page */ ++#define SDIO_REG_FREE_TXPG 0x0020 ++/* HCI Current Power Mode 1 */ ++#define SDIO_REG_HCPWM1 0x0024 ++/* HCI Current Power Mode 2 */ ++#define SDIO_REG_HCPWM2 0x0026 ++/* HTSF Informaion */ ++#define SDIO_REG_HTSFR_INFO 0x0030 ++/* HCI Request Power Mode 1 */ ++#define SDIO_REG_HRPWM1 0x0080 ++/* HCI Request Power Mode 2 */ ++#define SDIO_REG_HRPWM2 0x0082 ++/* HCI Power Save Clock */ ++#define SDIO_REG_HPS_CLKR 0x0084 ++/* SDIO HCI Suspend Control */ ++#define SDIO_REG_HSUS_CTRL 0x0086 ++/* SDIO Host Extension Interrupt Mask Always */ ++#define SDIO_REG_HIMR_ON 0x0090 ++/* SDIO Host Extension Interrupt Status Always */ ++#define SDIO_REG_HISR_ON 0x0091 ++ ++#define SDIO_HIMR_DISABLED 0 ++ ++/* RTL8188E SDIO Host Interrupt Mask Register */ ++#define SDIO_HIMR_RX_REQUEST_MSK BIT(0) ++#define SDIO_HIMR_AVAL_MSK BIT(1) ++#define SDIO_HIMR_TXERR_MSK BIT(2) ++#define SDIO_HIMR_RXERR_MSK BIT(3) ++#define SDIO_HIMR_TXFOVW_MSK BIT(4) ++#define SDIO_HIMR_RXFOVW_MSK BIT(5) ++#define SDIO_HIMR_TXBCNOK_MSK BIT(6) ++#define SDIO_HIMR_TXBCNERR_MSK BIT(7) ++#define SDIO_HIMR_BCNERLY_INT_MSK BIT(16) ++#define SDIO_HIMR_C2HCMD_MSK BIT(17) ++#define SDIO_HIMR_CPWM1_MSK BIT(18) ++#define SDIO_HIMR_CPWM2_MSK BIT(19) ++#define SDIO_HIMR_HSISR_IND_MSK BIT(20) ++#define SDIO_HIMR_GTINT3_IND_MSK BIT(21) ++#define SDIO_HIMR_GTINT4_IND_MSK BIT(22) ++#define SDIO_HIMR_PSTIMEOUT_MSK BIT(23) ++#define SDIO_HIMR_OCPINT_MSK BIT(24) ++#define SDIO_HIMR_ATIMEND_MSK BIT(25) ++#define SDIO_HIMR_ATIMEND_E_MSK BIT(26) ++#define SDIO_HIMR_CTWEND_MSK BIT(27) ++ ++/* RTL8188E SDIO Specific */ ++#define SDIO_HIMR_MCU_ERR_MSK BIT(28) ++#define SDIO_HIMR_TSF_BIT32_TOGGLE_MSK BIT(29) ++ ++/* SDIO Host Interrupt Service Routine */ ++#define SDIO_HISR_RX_REQUEST BIT(0) ++#define SDIO_HISR_AVAL BIT(1) ++#define SDIO_HISR_TXERR BIT(2) ++#define SDIO_HISR_RXERR BIT(3) ++#define SDIO_HISR_TXFOVW BIT(4) ++#define SDIO_HISR_RXFOVW BIT(5) ++#define SDIO_HISR_TXBCNOK BIT(6) ++#define SDIO_HISR_TXBCNERR BIT(7) ++#define SDIO_HISR_BCNERLY_INT BIT(16) ++#define SDIO_HISR_C2HCMD BIT(17) ++#define SDIO_HISR_CPWM1 BIT(18) ++#define SDIO_HISR_CPWM2 BIT(19) ++#define SDIO_HISR_HSISR_IND BIT(20) ++#define SDIO_HISR_GTINT3_IND BIT(21) ++#define SDIO_HISR_GTINT4_IND BIT(22) ++#define SDIO_HISR_PSTIME BIT(23) ++#define SDIO_HISR_OCPINT BIT(24) ++#define SDIO_HISR_ATIMEND BIT(25) ++#define SDIO_HISR_ATIMEND_E BIT(26) ++#define SDIO_HISR_CTWEND BIT(27) ++ ++/* RTL8188E SDIO Specific */ ++#define SDIO_HISR_MCU_ERR BIT(28) ++#define SDIO_HISR_TSF_BIT32_TOGGLE BIT(29) ++ ++#define MASK_SDIO_HISR_CLEAR \ ++ (SDIO_HISR_TXERR | SDIO_HISR_RXERR | SDIO_HISR_TXFOVW |\ ++ SDIO_HISR_RXFOVW | SDIO_HISR_TXBCNOK | SDIO_HISR_TXBCNERR |\ ++ SDIO_HISR_C2HCMD | SDIO_HISR_CPWM1 | SDIO_HISR_CPWM2 |\ ++ SDIO_HISR_HSISR_IND | SDIO_HISR_GTINT3_IND | SDIO_HISR_GTINT4_IND |\ ++ SDIO_HISR_PSTIMEOUT | SDIO_HISR_OCPINT) ++ ++/* SDIO HCI Suspend Control Register */ ++#define HCI_RESUME_PWR_RDY BIT(1) ++#define HCI_SUS_CTRL BIT(0) ++ ++/* SDIO Tx FIFO related */ ++/* The number of Tx FIFO free page */ ++#define SDIO_TX_FREE_PG_QUEUE 4 ++#define SDIO_TX_FIFO_PAGE_SZ 128 ++ ++/* 0xFE00h ~ 0xFE55h USB Configuration */ ++ ++/* 2 USB Information (0xFE17) */ ++#define USB_IS_HIGH_SPEED 0 ++#define USB_IS_FULL_SPEED 1 ++#define USB_SPEED_MASK BIT(5) ++ ++#define USB_NORMAL_SIE_EP_MASK 0xF ++#define USB_NORMAL_SIE_EP_SHIFT 4 ++ ++/* 2 Special Option */ ++#define USB_AGG_EN BIT(3) ++ ++/* 0; Use interrupt endpoint to upload interrupt pkt */ ++/* 1; Use bulk endpoint to upload interrupt pkt, */ ++#define INT_BULK_SEL BIT(4) ++ ++/* 2REG_C2HEVT_CLEAR */ ++/* Set by driver and notify FW that the driver has read ++ * the C2H command message */ ++#define C2H_EVT_HOST_CLOSE 0x00 ++/* Set by FW indicating that FW had set the C2H command ++ * message and it's not yet read by driver. */ ++#define C2H_EVT_FW_CLOSE 0xFF ++ ++/* 2REG_MULTI_FUNC_CTRL(For RTL8723 Only) */ ++/* Enable GPIO[9] as WiFi HW PDn source */ ++#define WL_HWPDN_EN BIT(0) ++/* WiFi HW PDn polarity control */ ++#define WL_HWPDN_SL BIT(1) ++/* WiFi function enable */ ++#define WL_FUNC_EN BIT(2) ++/* Enable GPIO[9] as WiFi RF HW PDn source */ ++#define WL_HWROF_EN BIT(3) ++/* Enable GPIO[11] as BT HW PDn source */ ++#define BT_HWPDN_EN BIT(16) ++/* BT HW PDn polarity control */ ++#define BT_HWPDN_SL BIT(17) ++/* BT function enable */ ++#define BT_FUNC_EN BIT(18) ++/* Enable GPIO[11] as BT/GPS RF HW PDn source */ ++#define BT_HWROF_EN BIT(19) ++/* Enable GPIO[10] as GPS HW PDn source */ ++#define GPS_HWPDN_EN BIT(20) ++/* GPS HW PDn polarity control */ ++#define GPS_HWPDN_SL BIT(21) ++/* GPS function enable */ ++#define GPS_FUNC_EN BIT(22) ++ ++/* 3 REG_LIFECTRL_CTRL */ ++#define HAL92C_EN_PKT_LIFE_TIME_BK BIT(3) ++#define HAL92C_EN_PKT_LIFE_TIME_BE BIT(2) ++#define HAL92C_EN_PKT_LIFE_TIME_VI BIT(1) ++#define HAL92C_EN_PKT_LIFE_TIME_VO BIT(0) ++ ++#define HAL92C_MSDU_LIFE_TIME_UNIT 128 /* in us */ ++ ++/* General definitions */ ++#define LAST_ENTRY_OF_TX_PKT_BUFFER 176 /* 22k 22528 bytes */ ++ ++#define POLLING_LLT_THRESHOLD 20 ++#define POLLING_READY_TIMEOUT_COUNT 1000 ++/* GPIO BIT */ ++#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) ++ ++/* 8192C EEPROM/EFUSE share register definition. */ ++ ++/* EEPROM/Efuse PG Offset for 88EE/88EU/88ES */ ++#define EEPROM_TX_PWR_INX_88E 0x10 ++ ++#define EEPROM_ChannelPlan_88E 0xB8 ++#define EEPROM_XTAL_88E 0xB9 ++#define EEPROM_THERMAL_METER_88E 0xBA ++#define EEPROM_IQK_LCK_88E 0xBB ++ ++#define EEPROM_RF_BOARD_OPTION_88E 0xC1 ++#define EEPROM_RF_FEATURE_OPTION_88E 0xC2 ++#define EEPROM_RF_BT_SETTING_88E 0xC3 ++#define EEPROM_VERSION_88E 0xC4 ++#define EEPROM_CUSTOMERID_88E 0xC5 ++#define EEPROM_RF_ANTENNA_OPT_88E 0xC9 ++ ++/* RTL88EE */ ++#define EEPROM_MAC_ADDR_88EE 0xD0 ++#define EEPROM_VID_88EE 0xD6 ++#define EEPROM_DID_88EE 0xD8 ++#define EEPROM_SVID_88EE 0xDA ++#define EEPROM_SMID_88EE 0xDC ++ ++/* RTL88EU */ ++#define EEPROM_MAC_ADDR_88EU 0xD7 ++#define EEPROM_VID_88EU 0xD0 ++#define EEPROM_PID_88EU 0xD2 ++#define EEPROM_USB_OPTIONAL_FUNCTION0 0xD4 ++ ++/* RTL88ES */ ++#define EEPROM_MAC_ADDR_88ES 0x11A ++ ++/* EEPROM/Efuse Value Type */ ++#define EETYPE_TX_PWR 0x0 ++ ++/* Default Value for EEPROM or EFUSE!!! */ ++#define EEPROM_Default_TSSI 0x0 ++#define EEPROM_Default_TxPowerDiff 0x0 ++#define EEPROM_Default_CrystalCap 0x5 ++/* Default: 2X2, RTL8192CE(QFPN68) */ ++#define EEPROM_Default_BoardType 0x02 ++#define EEPROM_Default_TxPower 0x1010 ++#define EEPROM_Default_HT2T_TxPwr 0x10 ++ ++#define EEPROM_Default_LegacyHTTxPowerDiff 0x3 ++#define EEPROM_Default_ThermalMeter 0x12 ++ ++#define EEPROM_Default_AntTxPowerDiff 0x0 ++#define EEPROM_Default_TxPwDiff_CrystalCap 0x5 ++#define EEPROM_Default_TxPowerLevel 0x2A ++ ++#define EEPROM_Default_HT40_2SDiff 0x0 ++/* HT20<->40 default Tx Power Index Difference */ ++#define EEPROM_Default_HT20_Diff 2 ++#define EEPROM_Default_LegacyHTTxPowerDiff 0x3 ++#define EEPROM_Default_HT40_PwrMaxOffset 0 ++#define EEPROM_Default_HT20_PwrMaxOffset 0 ++ ++#define EEPROM_Default_CrystalCap_88E 0x20 ++#define EEPROM_Default_ThermalMeter_88E 0x18 ++ ++/* New EFUSE deafult value */ ++#define EEPROM_DEFAULT_24G_INDEX 0x2D ++#define EEPROM_DEFAULT_24G_HT20_DIFF 0X02 ++#define EEPROM_DEFAULT_24G_OFDM_DIFF 0X04 ++ ++#define EEPROM_DEFAULT_DIFF 0XFE ++#define EEPROM_DEFAULT_CHANNEL_PLAN 0x7F ++#define EEPROM_DEFAULT_BOARD_OPTION 0x00 ++#define EEPROM_DEFAULT_FEATURE_OPTION 0x00 ++#define EEPROM_DEFAULT_BT_OPTION 0x10 ++ ++/* For debug */ ++#define EEPROM_Default_PID 0x1234 ++#define EEPROM_Default_VID 0x5678 ++#define EEPROM_Default_CustomerID 0xAB ++#define EEPROM_Default_CustomerID_8188E 0x00 ++#define EEPROM_Default_SubCustomerID 0xCD ++#define EEPROM_Default_Version 0 ++ ++#define EEPROM_CHANNEL_PLAN_FCC 0x0 ++#define EEPROM_CHANNEL_PLAN_IC 0x1 ++#define EEPROM_CHANNEL_PLAN_ETSI 0x2 ++#define EEPROM_CHANNEL_PLAN_SPA 0x3 ++#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 ++#define EEPROM_CHANNEL_PLAN_MKK 0x5 ++#define EEPROM_CHANNEL_PLAN_MKK1 0x6 ++#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 ++#define EEPROM_CHANNEL_PLAN_TELEC 0x8 ++#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMA 0x9 ++#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA ++#define EEPROM_CHANNEL_PLAN_NCC 0xB ++#define EEPROM_USB_OPTIONAL1 0xE ++#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 ++ ++#define EEPROM_CID_DEFAULT 0x0 ++#define EEPROM_CID_TOSHIBA 0x4 ++#define EEPROM_CID_CCX 0x10 /* CCX test. */ ++#define EEPROM_CID_QMI 0x0D ++#define EEPROM_CID_WHQL 0xFE ++#define RTL_EEPROM_ID 0x8129 ++ ++#endif /* __RTL8188E_SPEC_H__ */ +diff --git a/drivers/staging/r8188eu/include/rtl8188e_sreset.h b/drivers/staging/r8188eu/include/rtl8188e_sreset.h +new file mode 100644 +index 000000000000..880c5792d5dd +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_sreset.h +@@ -0,0 +1,15 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTL8188E_SRESET_H_ ++#define _RTL8188E_SRESET_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "rtw_sreset.h" ++ ++void rtl8188e_silentreset_for_specific_platform(struct adapter *padapter); ++void rtl8188e_sreset_xmit_status_check(struct adapter *padapter); ++void rtl8188e_sreset_linked_status_check(struct adapter *padapter); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtl8188e_xmit.h b/drivers/staging/r8188eu/include/rtl8188e_xmit.h +new file mode 100644 +index 000000000000..f1f2ccfc765e +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_xmit.h +@@ -0,0 +1,150 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_XMIT_H__ ++#define __RTL8188E_XMIT_H__ ++ ++#define MAX_TX_AGG_PACKET_NUMBER 0xFF ++/* */ ++/* Queue Select Value in TxDesc */ ++/* */ ++#define QSLT_BK 0x2/* 0x01 */ ++#define QSLT_BE 0x0 ++#define QSLT_VI 0x5/* 0x4 */ ++#define QSLT_VO 0x7/* 0x6 */ ++#define QSLT_BEACON 0x10 ++#define QSLT_HIGH 0x11 ++#define QSLT_MGNT 0x12 ++#define QSLT_CMD 0x13 ++ ++/* For 88e early mode */ ++#define SET_EARLYMODE_PKTNUM(__paddr, __value) \ ++ le32p_replace_bits((__le32 *)__paddr, __value, GENMASK(2, 0)) ++#define SET_EARLYMODE_LEN0(__pAddr, __Value) \ ++ le32p_replace_bits((__le32 *)__paddr, __value, GENMASK(15, 4)) ++#define SET_EARLYMODE_LEN1(__paddr, __value) \ ++ le32p_replace_bits((__le32 *)__paddr, __value, GENMASK(27, 16)) ++#define SET_EARLYMODE_LEN2_1(__pdr, __vValue) \ ++ le32p_replace_bits((__le32 *)__paddr, __value, GENMASK(31, 28)) ++#define SET_EARLYMODE_LEN2_2(__paddr, __value) \ ++ le32p_replace_bits((__le32 *)(__paddr + 4), __value, GENMASK(7, 0)) ++#define SET_EARLYMODE_LEN3(__pAddr, __Value) \ ++ le32p_replace_bits((__le32 *)(__paddr + 4), __value, GENMASK(19, 8)) ++#define SET_EARLYMODE_LEN4(__paAddr, __vValue) \ ++ le32p_replace_bits((__le32 *)(__paddr + 4), __value, GENMASK(31, 20)) ++ ++/* defined for TX DESC Operation */ ++ ++#define MAX_TID (15) ++ ++/* OFFSET 0 */ ++#define OFFSET_SZ 0 ++#define OFFSET_SHT 16 ++#define BMC BIT(24) ++#define LSG BIT(26) ++#define FSG BIT(27) ++#define OWN BIT(31) ++ ++/* OFFSET 4 */ ++#define PKT_OFFSET_SZ 0 ++#define QSEL_SHT 8 ++#define RATE_ID_SHT 16 ++#define NAVUSEHDR BIT(20) ++#define SEC_TYPE_SHT 22 ++#define PKT_OFFSET_SHT 26 ++ ++/* OFFSET 8 */ ++#define AGG_EN BIT(12) ++#define AGG_BK BIT(16) ++#define AMPDU_DENSITY_SHT 20 ++#define ANTSEL_A BIT(24) ++#define ANTSEL_B BIT(25) ++#define TX_ANT_CCK_SHT 26 ++#define TX_ANTL_SHT 28 ++#define TX_ANT_HT_SHT 30 ++ ++/* OFFSET 12 */ ++#define SEQ_SHT 16 ++#define EN_HWSEQ BIT(31) ++ ++/* OFFSET 16 */ ++#define QOS BIT(6) ++#define HW_SSN BIT(7) ++#define USERATE BIT(8) ++#define DISDATAFB BIT(10) ++#define CTS_2_SELF BIT(11) ++#define RTS_EN BIT(12) ++#define HW_RTS_EN BIT(13) ++#define DATA_SHORT BIT(24) ++#define PWR_STATUS_SHT 15 ++#define DATA_SC_SHT 20 ++#define DATA_BW BIT(25) ++ ++/* OFFSET 20 */ ++#define RTY_LMT_EN BIT(17) ++ ++enum TXDESC_SC { ++ SC_DONT_CARE = 0x00, ++ SC_UPPER = 0x01, ++ SC_LOWER = 0x02, ++ SC_DUPLICATE = 0x03 ++}; ++/* OFFSET 20 */ ++#define SGI BIT(6) ++#define USB_TXAGG_NUM_SHT 24 ++ ++#define txdesc_set_ccx_sw_88e(txdesc, value) \ ++ do { \ ++ ((struct txdesc_88e *)(txdesc))->sw1 = (((value)>>8) & 0x0f); \ ++ ((struct txdesc_88e *)(txdesc))->sw0 = ((value) & 0xff); \ ++ } while (0) ++ ++struct txrpt_ccx_88e { ++ /* offset 0 */ ++ u8 tag1:1; ++ u8 pkt_num:3; ++ u8 txdma_underflow:1; ++ u8 int_bt:1; ++ u8 int_tri:1; ++ u8 int_ccx:1; ++ ++ /* offset 1 */ ++ u8 mac_id:6; ++ u8 pkt_ok:1; ++ u8 bmc:1; ++ ++ /* offset 2 */ ++ u8 retry_cnt:6; ++ u8 lifetime_over:1; ++ u8 retry_over:1; ++ ++ /* offset 3 */ ++ u8 ccx_qtime0; ++ u8 ccx_qtime1; ++ ++ /* offset 5 */ ++ u8 final_data_rate; ++ ++ /* offset 6 */ ++ u8 sw1:4; ++ u8 qsel:4; ++ ++ /* offset 7 */ ++ u8 sw0; ++}; ++ ++void rtl8188e_fill_fake_txdesc(struct adapter *padapter, u8 *pDesc, ++ u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull); ++s32 rtl8188eu_init_xmit_priv(struct adapter *padapter); ++s32 rtl8188eu_hal_xmit(struct adapter *padapter, struct xmit_frame *frame); ++s32 rtl8188eu_mgnt_xmit(struct adapter *padapter, struct xmit_frame *frame); ++s32 rtl8188eu_xmit_buf_handler(struct adapter *padapter); ++#define hal_xmit_handler rtl8188eu_xmit_buf_handler ++void rtl8188eu_xmit_tasklet(unsigned long priv); ++s32 rtl8188eu_xmitframe_complete(struct adapter *padapter, ++ struct xmit_priv *pxmitpriv, ++ struct xmit_buf *pxmitbuf); ++ ++void handle_txrpt_ccx_88e(struct adapter *adapter, u8 *buf); ++ ++#endif /* __RTL8188E_XMIT_H__ */ +diff --git a/drivers/staging/r8188eu/include/rtw_ap.h b/drivers/staging/r8188eu/include/rtw_ap.h +new file mode 100644 +index 000000000000..2eb556968509 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_ap.h +@@ -0,0 +1,47 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#ifndef __RTW_AP_H_ ++#define __RTW_AP_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++/* external function */ ++void rtw_indicate_sta_assoc_event(struct adapter *padapter, ++ struct sta_info *psta); ++void rtw_indicate_sta_disassoc_event(struct adapter *padapter, ++ struct sta_info *psta); ++void init_mlme_ap_info(struct adapter *padapter); ++void free_mlme_ap_info(struct adapter *padapter); ++void update_beacon(struct adapter *padapter, u8 ie_id, ++ u8 *oui, u8 tx); ++void add_RATid(struct adapter *padapter, struct sta_info *psta, ++ u8 rssi_level); ++void expire_timeout_chk(struct adapter *padapter); ++void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta); ++int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len); ++void rtw_ap_restore_network(struct adapter *padapter); ++void rtw_set_macaddr_acl(struct adapter *padapter, int mode); ++int rtw_acl_add_sta(struct adapter *padapter, u8 *addr); ++int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr); ++ ++#ifdef CONFIG_88EU_AP_MODE ++void associated_clients_update(struct adapter *padapter, u8 updated); ++void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta); ++u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta); ++void sta_info_update(struct adapter *padapter, struct sta_info *psta); ++void ap_sta_info_defer_update(struct adapter *padapter, struct sta_info *psta); ++u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta, ++ bool active, u16 reason); ++int rtw_sta_flush(struct adapter *padapter); ++int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset); ++void start_ap_mode(struct adapter *padapter); ++void stop_ap_mode(struct adapter *padapter); ++#endif ++#endif /* end of CONFIG_88EU_AP_MODE */ ++void update_bmc_sta(struct adapter *padapter); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_br_ext.h b/drivers/staging/r8188eu/include/rtw_br_ext.h +new file mode 100644 +index 000000000000..69905d30c191 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_br_ext.h +@@ -0,0 +1,49 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_BR_EXT_H_ ++#define _RTW_BR_EXT_H_ ++ ++#define MACADDRLEN 6 ++#define _DEBUG_ERR DBG_88E ++#define _DEBUG_INFO DBG_88E ++#define DEBUG_WARN DBG_88E ++#define DEBUG_INFO DBG_88E ++#define DEBUG_ERR DBG_88E ++#define GET_MY_HWADDR(padapter) ((padapter)->eeprompriv.mac_addr) ++ ++#define NAT25_HASH_BITS 4 ++#define NAT25_HASH_SIZE (1 << NAT25_HASH_BITS) ++#define NAT25_AGEING_TIME 300 ++ ++#define MAX_NETWORK_ADDR_LEN 17 ++ ++struct nat25_network_db_entry { ++ struct nat25_network_db_entry *next_hash; ++ struct nat25_network_db_entry **pprev_hash; ++ atomic_t use_count; ++ unsigned char macAddr[6]; ++ unsigned long ageing_timer; ++ unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; ++}; ++ ++enum NAT25_METHOD { ++ NAT25_MIN, ++ NAT25_CHECK, ++ NAT25_INSERT, ++ NAT25_PARSE, ++ NAT25_MAX ++}; ++ ++struct br_ext_info { ++ unsigned int nat25_disable; ++ unsigned int macclone_enable; ++ unsigned int dhcp_bcst_disable; ++ int addPPPoETag; /* 1: Add PPPoE relay-SID, 0: disable */ ++ unsigned char nat25_dmzMac[MACADDRLEN]; ++ unsigned int nat25sc_disable; ++}; ++ ++void nat25_db_cleanup(struct adapter *priv); ++ ++#endif /* _RTW_BR_EXT_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_cmd.h b/drivers/staging/r8188eu/include/rtw_cmd.h +new file mode 100644 +index 000000000000..c14d9052b997 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_cmd.h +@@ -0,0 +1,975 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_CMD_H_ ++#define __RTW_CMD_H_ ++ ++#include "wlan_bssdef.h" ++#include "rtw_rf.h" ++#include "rtw_led.h" ++ ++#define C2H_MEM_SZ (16*1024) ++ ++#include "osdep_service.h" ++#include "ieee80211.h" /* */ ++ ++#define FREE_CMDOBJ_SZ 128 ++ ++#define MAX_CMDSZ 1024 ++#define MAX_RSPSZ 512 ++#define MAX_EVTSZ 1024 ++ ++#define CMDBUFF_ALIGN_SZ 512 ++ ++struct cmd_obj { ++ struct adapter *padapter; ++ u16 cmdcode; ++ u8 res; ++ u8 *parmbuf; ++ u32 cmdsz; ++ u8 *rsp; ++ u32 rspsz; ++ struct list_head list; ++}; ++ ++struct cmd_priv { ++ struct semaphore cmd_queue_sema; ++ struct semaphore terminate_cmdthread_sema; ++ struct __queue cmd_queue; ++ u8 cmd_seq; ++ u8 *cmd_buf; /* shall be non-paged, and 4 bytes aligned */ ++ u8 *cmd_allocated_buf; ++ u8 *rsp_buf; /* shall be non-paged, and 4 bytes aligned */ ++ u8 *rsp_allocated_buf; ++ u32 cmd_issued_cnt; ++ u32 cmd_done_cnt; ++ u32 rsp_cnt; ++ u8 cmdthd_running; ++ struct adapter *padapter; ++}; ++ ++struct evt_priv { ++ struct work_struct c2h_wk; ++ bool c2h_wk_alive; ++ struct rtw_cbuf *c2h_queue; ++ #define C2H_QUEUE_MAX_LEN 10 ++ atomic_t event_seq; ++ u8 *evt_buf; /* shall be non-paged, and 4 bytes aligned */ ++ u8 *evt_allocated_buf; ++ u32 evt_done_cnt; ++}; ++ ++#define init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code) \ ++do {\ ++ INIT_LIST_HEAD(&pcmd->list);\ ++ pcmd->cmdcode = code;\ ++ pcmd->parmbuf = (u8 *)(pparm);\ ++ pcmd->cmdsz = sizeof(*pparm);\ ++ pcmd->rsp = NULL;\ ++ pcmd->rspsz = 0;\ ++} while (0) ++ ++struct c2h_evt_hdr { ++ u8 id:4; ++ u8 plen:4; ++ u8 seq; ++ u8 payload[0]; ++}; ++ ++#define c2h_evt_exist(c2h_evt) ((c2h_evt)->id || (c2h_evt)->plen) ++ ++u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *obj); ++struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv); ++void rtw_free_cmd_obj(struct cmd_obj *pcmd); ++ ++int rtw_cmd_thread(void *context); ++ ++u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv); ++void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv); ++ ++u32 rtw_init_evt_priv(struct evt_priv *pevtpriv); ++void rtw_free_evt_priv(struct evt_priv *pevtpriv); ++void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv); ++void rtw_evt_notify_isr(struct evt_priv *pevtpriv); ++#ifdef CONFIG_88EU_P2P ++u8 p2p_protocol_wk_cmd(struct adapter *padapter, int intCmdType); ++#endif /* CONFIG_88EU_P2P */ ++ ++enum rtw_drvextra_cmd_id { ++ NONE_WK_CID, ++ DYNAMIC_CHK_WK_CID, ++ DM_CTRL_WK_CID, ++ PBC_POLLING_WK_CID, ++ POWER_SAVING_CTRL_WK_CID,/* IPS,AUTOSuspend */ ++ LPS_CTRL_WK_CID, ++ ANT_SELECT_WK_CID, ++ P2P_PS_WK_CID, ++ P2P_PROTO_WK_CID, ++ CHECK_HIQ_WK_CID,/* for softap mode, check hi queue if empty */ ++ INTEl_WIDI_WK_CID, ++ C2H_WK_CID, ++ RTP_TIMER_CFG_WK_CID, ++ MAX_WK_CID ++}; ++ ++enum LPS_CTRL_TYPE { ++ LPS_CTRL_SCAN = 0, ++ LPS_CTRL_JOINBSS = 1, ++ LPS_CTRL_CONNECT = 2, ++ LPS_CTRL_DISCONNECT = 3, ++ LPS_CTRL_SPECIAL_PACKET = 4, ++ LPS_CTRL_LEAVE = 5, ++}; ++ ++enum RFINTFS { ++ SWSI, ++ HWSI, ++ HWPI, ++}; ++ ++/* ++Caller Mode: Infra, Ad-HoC(C) ++ ++Notes: To enter USB suspend mode ++ ++Command Mode ++ ++*/ ++struct usb_suspend_parm { ++ u32 action;/* 1: sleep, 0:resume */ ++}; ++ ++/* ++Caller Mode: Infra, Ad-HoC ++ ++Notes: To join a known BSS. ++ ++Command-Event Mode ++ ++*/ ++ ++/* ++Caller Mode: Infra, Ad-Hoc ++ ++Notes: To join the specified bss ++ ++Command Event Mode ++ ++*/ ++struct joinbss_parm { ++ struct wlan_bssid_ex network; ++}; ++ ++/* ++Caller Mode: Infra, Ad-HoC(C) ++ ++Notes: To disconnect the current associated BSS ++ ++Command Mode ++ ++*/ ++struct disconnect_parm { ++ u32 deauth_timeout_ms; ++}; ++ ++/* ++Caller Mode: AP, Ad-HoC(M) ++ ++Notes: To create a BSS ++ ++Command Mode ++*/ ++struct createbss_parm { ++ struct wlan_bssid_ex network; ++}; ++ ++struct setopmode_parm { ++ u8 mode; ++ u8 rsvd[3]; ++}; ++ ++/* ++Caller Mode: AP, Ad-HoC, Infra ++ ++Notes: To ask RTL8711 performing site-survey ++ ++Command-Event Mode ++ ++*/ ++ ++#define RTW_SSID_SCAN_AMOUNT 9 /* for WEXT_CSCAN_AMOUNT 9 */ ++#define RTW_CHANNEL_SCAN_AMOUNT (14+37) ++struct sitesurvey_parm { ++ int scan_mode; /* active: 1, passive: 0 */ ++ u8 ssid_num; ++ u8 ch_num; ++ struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT]; ++ struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT]; ++}; ++ ++/* ++Caller Mode: Any ++ ++Notes: To set the auth type of RTL8711. open/shared/802.1x ++ ++Command Mode ++ ++*/ ++struct setauth_parm { ++ u8 mode; /* 0: legacy open, 1: legacy shared 2: 802.1x */ ++ u8 _1x; /* 0: PSK, 1: TLS */ ++ u8 rsvd[2]; ++}; ++ ++/* ++Caller Mode: Infra ++ ++a. algorithm: wep40, wep104, tkip & aes ++b. keytype: grp key/unicast key ++c. key contents ++ ++when shared key ==> keyid is the camid ++when 802.1x ==> keyid [0:1] ==> grp key ++when 802.1x ==> keyid > 2 ==> unicast key ++ ++*/ ++struct setkey_parm { ++ u8 algorithm; /* could be none, wep40, TKIP, CCMP, wep104 */ ++ u8 keyid; ++ u8 grpkey; /* 1: this is the grpkey for 802.1x. ++ * 0: this is the unicast key for 802.1x */ ++ u8 set_tx; /* 1: main tx key for wep. 0: other key. */ ++ u8 key[16]; /* this could be 40 or 104 */ ++}; ++ ++/* ++When in AP or Ad-Hoc mode, this is used to ++allocate an sw/hw entry for a newly associated sta. ++ ++Command ++ ++when shared key ==> algorithm/keyid ++ ++*/ ++struct set_stakey_parm { ++ u8 addr[ETH_ALEN]; ++ u8 algorithm; ++ u8 id;/* currently for erasing cam entry if ++ * algorithm == _NO_PRIVACY_ */ ++ u8 key[16]; ++}; ++ ++struct set_stakey_rsp { ++ u8 addr[ETH_ALEN]; ++ u8 keyid; ++ u8 rsvd; ++}; ++ ++/* ++Caller Ad-Hoc/AP ++ ++Command -Rsp(AID == CAMID) mode ++ ++This is to force fw to add an sta_data entry per driver's request. ++ ++FW will write an cam entry associated with it. ++ ++*/ ++struct set_assocsta_parm { ++ u8 addr[ETH_ALEN]; ++}; ++ ++struct set_assocsta_rsp { ++ u8 cam_id; ++ u8 rsvd[3]; ++}; ++ ++/* ++ Caller Ad-Hoc/AP ++ ++ Command mode ++ ++ This is to force fw to del an sta_data entry per driver's request ++ ++ FW will invalidate the cam entry associated with it. ++ ++*/ ++struct del_assocsta_parm { ++ u8 addr[ETH_ALEN]; ++}; ++ ++/* ++Caller Mode: AP/Ad-HoC(M) ++ ++Notes: To notify fw that given staid has changed its power state ++ ++Command Mode ++ ++*/ ++struct setstapwrstate_parm { ++ u8 staid; ++ u8 status; ++ u8 hwaddr[6]; ++}; ++ ++/* ++Caller Mode: Any ++ ++Notes: To setup the basic rate of RTL8711 ++ ++Command Mode ++ ++*/ ++struct setbasicrate_parm { ++ u8 basicrates[NumRates]; ++}; ++ ++/* ++Caller Mode: Any ++ ++Notes: To read the current basic rate ++ ++Command-Rsp Mode ++ ++*/ ++struct getbasicrate_parm { ++ u32 rsvd; ++}; ++ ++struct getbasicrate_rsp { ++ u8 basicrates[NumRates]; ++}; ++ ++/* ++Caller Mode: Any ++ ++Notes: To setup the data rate of RTL8711 ++ ++Command Mode ++ ++*/ ++struct setdatarate_parm { ++ u8 mac_id; ++ u8 datarates[NumRates]; ++}; ++ ++/* ++Caller Mode: Any ++ ++Notes: To read the current data rate ++ ++Command-Rsp Mode ++ ++*/ ++struct getdatarate_parm { ++ u32 rsvd; ++ ++}; ++struct getdatarate_rsp { ++ u8 datarates[NumRates]; ++}; ++ ++/* ++Caller Mode: Any ++AP: AP can use the info for the contents of beacon frame ++Infra: STA can use the info when sitesurveying ++Ad-HoC(M): Like AP ++Ad-HoC(C): Like STA ++ ++Notes: To set the phy capability of the NIC ++ ++Command Mode ++ ++*/ ++ ++struct setphyinfo_parm { ++ struct regulatory_class class_sets[NUM_REGULATORYS]; ++ u8 status; ++}; ++ ++struct getphyinfo_parm { ++ u32 rsvd; ++}; ++ ++struct getphyinfo_rsp { ++ struct regulatory_class class_sets[NUM_REGULATORYS]; ++ u8 status; ++}; ++ ++/* ++Caller Mode: Any ++ ++Notes: To set the channel/modem/band ++This command will be used when channel/modem/band is changed. ++ ++Command Mode ++ ++*/ ++struct setphy_parm { ++ u8 rfchannel; ++ u8 modem; ++}; ++ ++/* ++Caller Mode: Any ++ ++Notes: To get the current setting of channel/modem/band ++ ++Command-Rsp Mode ++ ++*/ ++struct getphy_parm { ++ u32 rsvd; ++ ++}; ++struct getphy_rsp { ++ u8 rfchannel; ++ u8 modem; ++}; ++ ++struct readBB_parm { ++ u8 offset; ++}; ++struct readBB_rsp { ++ u8 value; ++}; ++ ++struct readTSSI_parm { ++ u8 offset; ++}; ++struct readTSSI_rsp { ++ u8 value; ++}; ++ ++struct writeBB_parm { ++ u8 offset; ++ u8 value; ++}; ++ ++struct readRF_parm { ++ u8 offset; ++}; ++struct readRF_rsp { ++ u32 value; ++}; ++ ++struct writeRF_parm { ++ u32 offset; ++ u32 value; ++}; ++ ++struct getrfintfs_parm { ++ u8 rfintfs; ++}; ++ ++struct Tx_Beacon_param ++{ ++ struct wlan_bssid_ex network; ++}; ++ ++/* ++ Notes: This command is used for H2C/C2H loopback testing ++ ++ mac[0] == 0 ++ ==> CMD mode, return H2C_SUCCESS. ++ The following condition must be ture under CMD mode ++ mac[1] == mac[4], mac[2] == mac[3], mac[0]=mac[5]= 0; ++ s0 == 0x1234, s1 == 0xabcd, w0 == 0x78563412, w1 == 0x5aa5def7; ++ s2 == (b1 << 8 | b0); ++ ++ mac[0] == 1 ++ ==> CMD_RSP mode, return H2C_SUCCESS_RSP ++ ++ The rsp layout shall be: ++ rsp: parm: ++ mac[0] = mac[5]; ++ mac[1] = mac[4]; ++ mac[2] = mac[3]; ++ mac[3] = mac[2]; ++ mac[4] = mac[1]; ++ mac[5] = mac[0]; ++ s0 = s1; ++ s1 = swap16(s0); ++ w0 = swap32(w1); ++ b0 = b1 ++ s2 = s0 + s1 ++ b1 = b0 ++ w1 = w0 ++ ++ mac[0] == 2 ++ ==> CMD_EVENT mode, return H2C_SUCCESS ++ The event layout shall be: ++ event: parm: ++ mac[0] = mac[5]; ++ mac[1] = mac[4]; ++ mac[2] = event's seq no, starting from 1 to parm's marc[3] ++ mac[3] = mac[2]; ++ mac[4] = mac[1]; ++ mac[5] = mac[0]; ++ s0 = swap16(s0) - event.mac[2]; ++ s1 = s1 + event.mac[2]; ++ w0 = swap32(w0); ++ b0 = b1 ++ s2 = s0 + event.mac[2] ++ b1 = b0 ++ w1 = swap32(w1) - event.mac[2]; ++ ++ parm->mac[3] is the total event counts that host requested. ++ event will be the same with the cmd's param. ++*/ ++ ++/* CMD param Format for driver extra cmd handler */ ++struct drvextra_cmd_parm { ++ int ec_id; /* extra cmd id */ ++ int type_size; /* Can use this field as the type id or command size */ ++ unsigned char *pbuf; ++}; ++ ++/*------------------- Below are used for RF/BB tunning ---------------------*/ ++ ++struct setantenna_parm { ++ u8 tx_antset; ++ u8 rx_antset; ++ u8 tx_antenna; ++ u8 rx_antenna; ++}; ++ ++struct enrateadaptive_parm { ++ u32 en; ++}; ++ ++struct settxagctbl_parm { ++ u32 txagc[MAX_RATES_LENGTH]; ++}; ++ ++struct gettxagctbl_parm { ++ u32 rsvd; ++}; ++struct gettxagctbl_rsp { ++ u32 txagc[MAX_RATES_LENGTH]; ++}; ++ ++struct setagcctrl_parm { ++ u32 agcctrl; /* 0: pure hw, 1: fw */ ++}; ++ ++struct setssup_parm { ++ u32 ss_ForceUp[MAX_RATES_LENGTH]; ++}; ++ ++struct getssup_parm { ++ u32 rsvd; ++}; ++ ++struct getssup_rsp { ++ u8 ss_ForceUp[MAX_RATES_LENGTH]; ++}; ++ ++struct setssdlevel_parm { ++ u8 ss_DLevel[MAX_RATES_LENGTH]; ++}; ++ ++struct getssdlevel_parm { ++ u32 rsvd; ++}; ++ ++struct getssdlevel_rsp { ++ u8 ss_DLevel[MAX_RATES_LENGTH]; ++}; ++ ++struct setssulevel_parm { ++ u8 ss_ULevel[MAX_RATES_LENGTH]; ++}; ++ ++struct getssulevel_parm { ++ u32 rsvd; ++}; ++ ++struct getssulevel_rsp { ++ u8 ss_ULevel[MAX_RATES_LENGTH]; ++}; ++ ++struct setcountjudge_parm { ++ u8 count_judge[MAX_RATES_LENGTH]; ++}; ++ ++struct getcountjudge_parm { ++ u32 rsvd; ++}; ++ ++struct getcountjudge_rsp { ++ u8 count_judge[MAX_RATES_LENGTH]; ++}; ++ ++struct setratable_parm { ++ u8 ss_ForceUp[NumRates]; ++ u8 ss_ULevel[NumRates]; ++ u8 ss_DLevel[NumRates]; ++ u8 count_judge[NumRates]; ++}; ++ ++struct getratable_parm { ++ uint rsvd; ++}; ++ ++struct getratable_rsp { ++ u8 ss_ForceUp[NumRates]; ++ u8 ss_ULevel[NumRates]; ++ u8 ss_DLevel[NumRates]; ++ u8 count_judge[NumRates]; ++}; ++ ++/* to get TX,RX retry count */ ++ ++struct gettxretrycnt_parm { ++ unsigned int rsvd; ++}; ++ ++struct gettxretrycnt_rsp { ++ unsigned long tx_retrycnt; ++}; ++ ++struct getrxretrycnt_parm { ++ unsigned int rsvd; ++}; ++ ++struct getrxretrycnt_rsp { ++ unsigned long rx_retrycnt; ++}; ++ ++/* to get BCNOK,BCNERR count */ ++struct getbcnokcnt_parm { ++ unsigned int rsvd; ++}; ++ ++struct getbcnokcnt_rsp { ++ unsigned long bcnokcnt; ++}; ++ ++struct getbcnerrcnt_parm { ++ unsigned int rsvd; ++}; ++ ++struct getbcnerrcnt_rsp { ++ unsigned long bcnerrcnt; ++}; ++ ++/* to get current TX power level */ ++struct getcurtxpwrlevel_parm { ++ unsigned int rsvd; ++}; ++struct getcurtxpwrlevel_rspi { ++ unsigned short tx_power; ++}; ++ ++struct setprobereqextraie_parm { ++ unsigned char e_id; ++ unsigned char ie_len; ++ unsigned char ie[0]; ++}; ++ ++struct setassocreqextraie_parm { ++ unsigned char e_id; ++ unsigned char ie_len; ++ unsigned char ie[0]; ++}; ++ ++struct setproberspextraie_parm { ++ unsigned char e_id; ++ unsigned char ie_len; ++ unsigned char ie[0]; ++}; ++ ++struct setassocrspextraie_parm { ++ unsigned char e_id; ++ unsigned char ie_len; ++ unsigned char ie[0]; ++}; ++ ++struct addBaReq_parm { ++ unsigned int tid; ++ u8 addr[ETH_ALEN]; ++}; ++ ++/*H2C Handler index: 46 */ ++struct set_ch_parm { ++ u8 ch; ++ u8 bw; ++ u8 ch_offset; ++}; ++ ++/*H2C Handler index: 59 */ ++struct SetChannelPlan_param ++{ ++ u8 channel_plan; ++}; ++ ++/*H2C Handler index: 60 */ ++struct LedBlink_param ++{ ++ struct LED_871x *pLed; ++}; ++ ++/*H2C Handler index: 61 */ ++struct SetChannelSwitch_param ++{ ++ u8 new_ch_no; ++}; ++ ++/*H2C Handler index: 62 */ ++struct TDLSoption_param ++{ ++ u8 addr[ETH_ALEN]; ++ u8 option; ++}; ++ ++#define GEN_CMD_CODE(cmd) cmd ## _CMD_ ++ ++/* ++ ++Result: ++0x00: success ++0x01: success, and check Response. ++0x02: cmd ignored due to duplicated sequcne number ++0x03: cmd dropped due to invalid cmd code ++0x04: reserved. ++ ++*/ ++ ++#define H2C_RSP_OFFSET 512 ++ ++#define H2C_SUCCESS 0x00 ++#define H2C_SUCCESS_RSP 0x01 ++#define H2C_DUPLICATED 0x02 ++#define H2C_DROPPED 0x03 ++#define H2C_PARAMETERS_ERROR 0x04 ++#define H2C_REJECTED 0x05 ++#define H2C_CMD_OVERFLOW 0x06 ++#define H2C_RESERVED 0x07 ++ ++u8 rtw_setassocsta_cmd(struct adapter *padapter, u8 *mac_addr); ++u8 rtw_setstandby_cmd(struct adapter *padapter, uint action); ++u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, ++ int ssid_num, struct rtw_ieee80211_channel *ch, ++ int ch_num); ++u8 rtw_createbss_cmd(struct adapter *padapter); ++u8 rtw_createbss_cmd_ex(struct adapter *padapter, unsigned char *pbss, ++ unsigned int sz); ++u8 rtw_setphy_cmd(struct adapter *padapter, u8 modem, u8 ch); ++u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key); ++u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry, u8 enqueue); ++u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network* pnetwork); ++u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueue); ++u8 rtw_setopmode_cmd(struct adapter *padapter, enum ndis_802_11_network_infra networktype); ++u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset); ++u8 rtw_setbasicrate_cmd(struct adapter *padapter, u8 *rateset); ++u8 rtw_setbbreg_cmd(struct adapter * padapter, u8 offset, u8 val); ++u8 rtw_setrfreg_cmd(struct adapter * padapter, u8 offset, u32 val); ++u8 rtw_getbbreg_cmd(struct adapter * padapter, u8 offset, u8 * pval); ++u8 rtw_getrfreg_cmd(struct adapter * padapter, u8 offset, u8 * pval); ++u8 rtw_setrfintfs_cmd(struct adapter *padapter, u8 mode); ++u8 rtw_setrttbl_cmd(struct adapter *padapter, struct setratable_parm *prate_table); ++u8 rtw_getrttbl_cmd(struct adapter *padapter, struct getratable_rsp *pval); ++ ++u8 rtw_gettssi_cmd(struct adapter *padapter, u8 offset,u8 *pval); ++u8 rtw_setfwdig_cmd(struct adapter*padapter, u8 type); ++u8 rtw_setfwra_cmd(struct adapter*padapter, u8 type); ++ ++u8 rtw_addbareq_cmd(struct adapter*padapter, u8 tid, u8 *addr); ++ ++u8 rtw_dynamic_chk_wk_cmd(struct adapter *adapter); ++ ++u8 rtw_lps_ctrl_wk_cmd(struct adapter*padapter, u8 lps_ctrl_type, u8 enqueue); ++u8 rtw_rpt_timer_cfg_cmd(struct adapter*padapter, u16 minRptTime); ++ ++ u8 rtw_antenna_select_cmd(struct adapter*padapter, u8 antenna,u8 enqueue); ++u8 rtw_ps_cmd(struct adapter*padapter); ++ ++#ifdef CONFIG_88EU_AP_MODE ++u8 rtw_chk_hi_queue_cmd(struct adapter*padapter); ++#endif ++ ++u8 rtw_set_ch_cmd(struct adapter*padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue); ++u8 rtw_set_chplan_cmd(struct adapter*padapter, u8 chplan, u8 enqueue); ++u8 rtw_led_blink_cmd(struct adapter*padapter, struct LED_871x * pLed); ++u8 rtw_set_csa_cmd(struct adapter*padapter, u8 new_ch_no); ++u8 rtw_tdls_cmd(struct adapter *padapter, u8 *addr, u8 option); ++ ++u8 rtw_c2h_wk_cmd(struct adapter *padapter, u8 *c2h_evt); ++ ++u8 rtw_drvextra_cmd_hdl(struct adapter *padapter, unsigned char *pbuf); ++ ++void rtw_survey_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd); ++void rtw_disassoc_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd); ++void rtw_joinbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd); ++void rtw_createbss_cmd_callback(struct adapter *adapt, struct cmd_obj *pcmd); ++void rtw_getbbrfreg_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cmd); ++void rtw_readtssi_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cmd); ++ ++void rtw_setstaKey_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cmd); ++void rtw_setassocsta_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cm); ++void rtw_getrttbl_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cmd); ++ ++struct _cmd_callback { ++ u32 cmd_code; ++ void (*callback)(struct adapter *padapter, struct cmd_obj *cmd); ++}; ++ ++enum rtw_h2c_cmd { ++ GEN_CMD_CODE(_Read_MACREG), /*0*/ ++ GEN_CMD_CODE(_Write_MACREG), ++ GEN_CMD_CODE(_Read_BBREG), ++ GEN_CMD_CODE(_Write_BBREG), ++ GEN_CMD_CODE(_Read_RFREG), ++ GEN_CMD_CODE(_Write_RFREG), /*5*/ ++ GEN_CMD_CODE(_Read_EEPROM), ++ GEN_CMD_CODE(_Write_EEPROM), ++ GEN_CMD_CODE(_Read_EFUSE), ++ GEN_CMD_CODE(_Write_EFUSE), ++ ++ GEN_CMD_CODE(_Read_CAM), /*10*/ ++ GEN_CMD_CODE(_Write_CAM), ++ GEN_CMD_CODE(_setBCNITV), ++ GEN_CMD_CODE(_setMBIDCFG), ++ GEN_CMD_CODE(_JoinBss), /*14*/ ++ GEN_CMD_CODE(_DisConnect), /*15*/ ++ GEN_CMD_CODE(_CreateBss), ++ GEN_CMD_CODE(_SetOpMode), ++ GEN_CMD_CODE(_SiteSurvey), /*18*/ ++ GEN_CMD_CODE(_SetAuth), ++ ++ GEN_CMD_CODE(_SetKey), /*20*/ ++ GEN_CMD_CODE(_SetStaKey), ++ GEN_CMD_CODE(_SetAssocSta), ++ GEN_CMD_CODE(_DelAssocSta), ++ GEN_CMD_CODE(_SetStaPwrState), ++ GEN_CMD_CODE(_SetBasicRate), /*25*/ ++ GEN_CMD_CODE(_GetBasicRate), ++ GEN_CMD_CODE(_SetDataRate), ++ GEN_CMD_CODE(_GetDataRate), ++ GEN_CMD_CODE(_SetPhyInfo), ++ ++ GEN_CMD_CODE(_GetPhyInfo), /*30*/ ++ GEN_CMD_CODE(_SetPhy), ++ GEN_CMD_CODE(_GetPhy), ++ GEN_CMD_CODE(_readRssi), ++ GEN_CMD_CODE(_readGain), ++ GEN_CMD_CODE(_SetAtim), /*35*/ ++ GEN_CMD_CODE(_SetPwrMode), ++ GEN_CMD_CODE(_JoinbssRpt), ++ GEN_CMD_CODE(_SetRaTable), ++ GEN_CMD_CODE(_GetRaTable), ++ ++ GEN_CMD_CODE(_GetCCXReport), /*40*/ ++ GEN_CMD_CODE(_GetDTMReport), ++ GEN_CMD_CODE(_GetTXRateStatistics), ++ GEN_CMD_CODE(_SetUsbSuspend), ++ GEN_CMD_CODE(_SetH2cLbk), ++ GEN_CMD_CODE(_AddBAReq), /*45*/ ++ GEN_CMD_CODE(_SetChannel), /*46*/ ++ GEN_CMD_CODE(_SetTxPower), ++ GEN_CMD_CODE(_SwitchAntenna), ++ GEN_CMD_CODE(_SetCrystalCap), ++ GEN_CMD_CODE(_SetSingleCarrierTx), /*50*/ ++ ++ GEN_CMD_CODE(_SetSingleToneTx),/*51*/ ++ GEN_CMD_CODE(_SetCarrierSuppressionTx), ++ GEN_CMD_CODE(_SetContinuousTx), ++ GEN_CMD_CODE(_SwitchBandwidth), /*54*/ ++ GEN_CMD_CODE(_TX_Beacon), /*55*/ ++ ++ GEN_CMD_CODE(_Set_MLME_EVT), /*56*/ ++ GEN_CMD_CODE(_Set_Drv_Extra), /*57*/ ++ GEN_CMD_CODE(_Set_H2C_MSG), /*58*/ ++ ++ GEN_CMD_CODE(_SetChannelPlan), /*59*/ ++ GEN_CMD_CODE(_LedBlink), /*60*/ ++ ++ GEN_CMD_CODE(_SetChannelSwitch), /*61*/ ++ GEN_CMD_CODE(_TDLS), /*62*/ ++ ++ MAX_H2CCMD ++}; ++ ++#define _GetBBReg_CMD_ _Read_BBREG_CMD_ ++#define _SetBBReg_CMD_ _Write_BBREG_CMD_ ++#define _GetRFReg_CMD_ _Read_RFREG_CMD_ ++#define _SetRFReg_CMD_ _Write_RFREG_CMD_ ++ ++#ifdef _RTW_CMD_C_ ++static struct _cmd_callback rtw_cmd_callback[] = ++{ ++ {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/ ++ {GEN_CMD_CODE(_Write_MACREG), NULL}, ++ {GEN_CMD_CODE(_Read_BBREG), &rtw_getbbrfreg_cmdrsp_callback}, ++ {GEN_CMD_CODE(_Write_BBREG), NULL}, ++ {GEN_CMD_CODE(_Read_RFREG), &rtw_getbbrfreg_cmdrsp_callback}, ++ {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/ ++ {GEN_CMD_CODE(_Read_EEPROM), NULL}, ++ {GEN_CMD_CODE(_Write_EEPROM), NULL}, ++ {GEN_CMD_CODE(_Read_EFUSE), NULL}, ++ {GEN_CMD_CODE(_Write_EFUSE), NULL}, ++ ++ {GEN_CMD_CODE(_Read_CAM), NULL}, /*10*/ ++ {GEN_CMD_CODE(_Write_CAM), NULL}, ++ {GEN_CMD_CODE(_setBCNITV), NULL}, ++ {GEN_CMD_CODE(_setMBIDCFG), NULL}, ++ {GEN_CMD_CODE(_JoinBss), &rtw_joinbss_cmd_callback}, /*14*/ ++ {GEN_CMD_CODE(_DisConnect), &rtw_disassoc_cmd_callback}, /*15*/ ++ {GEN_CMD_CODE(_CreateBss), &rtw_createbss_cmd_callback}, ++ {GEN_CMD_CODE(_SetOpMode), NULL}, ++ {GEN_CMD_CODE(_SiteSurvey), &rtw_survey_cmd_callback}, /*18*/ ++ {GEN_CMD_CODE(_SetAuth), NULL}, ++ ++ {GEN_CMD_CODE(_SetKey), NULL}, /*20*/ ++ {GEN_CMD_CODE(_SetStaKey), &rtw_setstaKey_cmdrsp_callback}, ++ {GEN_CMD_CODE(_SetAssocSta), &rtw_setassocsta_cmdrsp_callback}, ++ {GEN_CMD_CODE(_DelAssocSta), NULL}, ++ {GEN_CMD_CODE(_SetStaPwrState), NULL}, ++ {GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/ ++ {GEN_CMD_CODE(_GetBasicRate), NULL}, ++ {GEN_CMD_CODE(_SetDataRate), NULL}, ++ {GEN_CMD_CODE(_GetDataRate), NULL}, ++ {GEN_CMD_CODE(_SetPhyInfo), NULL}, ++ ++ {GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/ ++ {GEN_CMD_CODE(_SetPhy), NULL}, ++ {GEN_CMD_CODE(_GetPhy), NULL}, ++ {GEN_CMD_CODE(_readRssi), NULL}, ++ {GEN_CMD_CODE(_readGain), NULL}, ++ {GEN_CMD_CODE(_SetAtim), NULL}, /*35*/ ++ {GEN_CMD_CODE(_SetPwrMode), NULL}, ++ {GEN_CMD_CODE(_JoinbssRpt), NULL}, ++ {GEN_CMD_CODE(_SetRaTable), NULL}, ++ {GEN_CMD_CODE(_GetRaTable), NULL}, ++ ++ {GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/ ++ {GEN_CMD_CODE(_GetDTMReport), NULL}, ++ {GEN_CMD_CODE(_GetTXRateStatistics), NULL}, ++ {GEN_CMD_CODE(_SetUsbSuspend), NULL}, ++ {GEN_CMD_CODE(_SetH2cLbk), NULL}, ++ {GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/ ++ {GEN_CMD_CODE(_SetChannel), NULL}, /*46*/ ++ {GEN_CMD_CODE(_SetTxPower), NULL}, ++ {GEN_CMD_CODE(_SwitchAntenna), NULL}, ++ {GEN_CMD_CODE(_SetCrystalCap), NULL}, ++ {GEN_CMD_CODE(_SetSingleCarrierTx), NULL}, /*50*/ ++ ++ {GEN_CMD_CODE(_SetSingleToneTx), NULL}, /*51*/ ++ {GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL}, ++ {GEN_CMD_CODE(_SetContinuousTx), NULL}, ++ {GEN_CMD_CODE(_SwitchBandwidth), NULL}, /*54*/ ++ {GEN_CMD_CODE(_TX_Beacon), NULL},/*55*/ ++ ++ {GEN_CMD_CODE(_Set_MLME_EVT), NULL},/*56*/ ++ {GEN_CMD_CODE(_Set_Drv_Extra), NULL},/*57*/ ++ {GEN_CMD_CODE(_Set_H2C_MSG), NULL},/*58*/ ++ {GEN_CMD_CODE(_SetChannelPlan), NULL},/*59*/ ++ {GEN_CMD_CODE(_LedBlink), NULL},/*60*/ ++ ++ {GEN_CMD_CODE(_SetChannelSwitch), NULL},/*61*/ ++ {GEN_CMD_CODE(_TDLS), NULL},/*62*/ ++}; ++#endif ++ ++#endif /* _CMD_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_debug.h b/drivers/staging/r8188eu/include/rtw_debug.h +new file mode 100644 +index 000000000000..3c3bf2a4f30e +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_debug.h +@@ -0,0 +1,231 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_DEBUG_H__ ++#define __RTW_DEBUG_H__ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define _drv_always_ 1 ++#define _drv_emerg_ 2 ++#define _drv_alert_ 3 ++#define _drv_crit_ 4 ++#define _drv_err_ 5 ++#define _drv_warning_ 6 ++#define _drv_notice_ 7 ++#define _drv_info_ 8 ++#define _drv_debug_ 9 ++ ++#define _module_rtl871x_xmit_c_ BIT(0) ++#define _module_xmit_osdep_c_ BIT(1) ++#define _module_rtl871x_recv_c_ BIT(2) ++#define _module_recv_osdep_c_ BIT(3) ++#define _module_rtl871x_mlme_c_ BIT(4) ++#define _module_mlme_osdep_c_ BIT(5) ++#define _module_rtl871x_sta_mgt_c_ BIT(6) ++#define _module_rtl871x_cmd_c_ BIT(7) ++#define _module_cmd_osdep_c_ BIT(8) ++#define _module_rtl871x_io_c_ BIT(9) ++#define _module_io_osdep_c_ BIT(10) ++#define _module_os_intfs_c_ BIT(11) ++#define _module_rtl871x_security_c_ BIT(12) ++#define _module_rtl871x_eeprom_c_ BIT(13) ++#define _module_hal_init_c_ BIT(14) ++#define _module_hci_hal_init_c_ BIT(15) ++#define _module_rtl871x_ioctl_c_ BIT(16) ++#define _module_rtl871x_ioctl_set_c_ BIT(17) ++#define _module_rtl871x_ioctl_query_c_ BIT(18) ++#define _module_rtl871x_pwrctrl_c_ BIT(19) ++#define _module_hci_intfs_c_ BIT(20) ++#define _module_hci_ops_c_ BIT(21) ++#define _module_osdep_service_c_ BIT(22) ++#define _module_mp_ BIT(23) ++#define _module_hci_ops_os_c_ BIT(24) ++#define _module_rtl871x_ioctl_os_c BIT(25) ++#define _module_rtl8712_cmd_c_ BIT(26) ++#define _module_rtl8192c_xmit_c_ BIT(27) ++#define _module_hal_xmit_c_ BIT(28) ++#define _module_efuse_ BIT(29) ++#define _module_rtl8712_recv_c_ BIT(30) ++#define _module_rtl8712_led_c_ BIT(31) ++ ++#define DRIVER_PREFIX "R8188EU: " ++ ++extern u32 GlobalDebugLevel; ++ ++#define DBG_88E_LEVEL(_level, fmt, arg...) \ ++ do { \ ++ if (_level <= GlobalDebugLevel) \ ++ pr_info(DRIVER_PREFIX"INFO " fmt, ##arg); \ ++ } while (0) ++ ++#define DBG_88E(...) \ ++ do { \ ++ if (_drv_err_ <= GlobalDebugLevel) \ ++ pr_info(DRIVER_PREFIX __VA_ARGS__); \ ++ } while (0) ++ ++#define MSG_88E(...) \ ++ do { \ ++ if (_drv_err_ <= GlobalDebugLevel) \ ++ pr_info(DRIVER_PREFIX __VA_ARGS__); \ ++ } while (0) ++ ++int proc_get_drv_version(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_write_reg(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_write_reg(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++int proc_get_read_reg(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_read_reg(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++ ++int proc_get_fwstate(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++int proc_get_sec_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++int proc_get_mlmext_state(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_qos_option(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++int proc_get_ht_option(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++int proc_get_rf_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++int proc_get_ap_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_adapter_state(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_trx_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_mac_reg_dump1(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_mac_reg_dump2(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_mac_reg_dump3(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_bb_reg_dump1(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_bb_reg_dump2(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_bb_reg_dump3(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_rf_reg_dump1(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_rf_reg_dump2(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_rf_reg_dump3(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_rf_reg_dump4(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++int proc_get_all_sta_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++#endif ++ ++int proc_get_best_channel(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_rx_signal(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_rx_signal(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++ ++int proc_get_ht_enable(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_ht_enable(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++ ++int proc_get_cbw40_enable(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_cbw40_enable(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++ ++int proc_get_ampdu_enable(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_ampdu_enable(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++ ++int proc_get_rx_stbc(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_rx_stbc(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++ ++int proc_get_two_path_rssi(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_rssi_disp(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_rssi_disp(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++ ++#ifdef CONFIG_BT_COEXIST ++int proc_get_btcoex_dbg(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_btcoex_dbg(struct file *file, const char *buffer, ++ signed long count, void *data); ++ ++#endif /* CONFIG_BT_COEXIST */ ++ ++#endif /* __RTW_DEBUG_H__ */ +diff --git a/drivers/staging/r8188eu/include/rtw_eeprom.h b/drivers/staging/r8188eu/include/rtw_eeprom.h +new file mode 100644 +index 000000000000..9f8a9c070339 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_eeprom.h +@@ -0,0 +1,114 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_EEPROM_H__ ++#define __RTW_EEPROM_H__ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define RTL8712_EEPROM_ID 0x8712 ++ ++#define HWSET_MAX_SIZE_512 512 ++#define EEPROM_MAX_SIZE HWSET_MAX_SIZE_512 ++ ++#define CLOCK_RATE 50 /* 100us */ ++ ++/* EEPROM opcodes */ ++#define EEPROM_READ_OPCODE 06 ++#define EEPROM_WRITE_OPCODE 05 ++#define EEPROM_ERASE_OPCODE 07 ++#define EEPROM_EWEN_OPCODE 19 /* Erase/write enable */ ++#define EEPROM_EWDS_OPCODE 16 /* Erase/write disable */ ++ ++/* Country codes */ ++#define USA 0x555320 ++#define EUROPE 0x1 /* temp, should be provided later */ ++#define JAPAN 0x2 /* temp, should be provided later */ ++ ++#define EEPROM_CID_DEFAULT 0x0 ++#define EEPROM_CID_ALPHA 0x1 ++#define EEPROM_CID_Senao 0x3 ++#define EEPROM_CID_NetCore 0x5 ++#define EEPROM_CID_CAMEO 0X8 ++#define EEPROM_CID_SITECOM 0x9 ++#define EEPROM_CID_COREGA 0xB ++#define EEPROM_CID_EDIMAX_BELK 0xC ++#define EEPROM_CID_SERCOMM_BELK 0xE ++#define EEPROM_CID_CAMEO1 0xF ++#define EEPROM_CID_WNC_COREGA 0x12 ++#define EEPROM_CID_CLEVO 0x13 ++#define EEPROM_CID_WHQL 0xFE ++ ++/* Customer ID, note that: */ ++/* This variable is initiailzed through EEPROM or registry, */ ++/* however, its definition may be different with that in EEPROM for */ ++/* EEPROM size consideration. So, we have to perform proper translation ++ * between them. */ ++/* Besides, CustomerID of registry has precedence of that of EEPROM. */ ++/* defined below. 060703, by rcnjko. */ ++enum RT_CUSTOMER_ID { ++ RT_CID_DEFAULT = 0, ++ RT_CID_8187_ALPHA0 = 1, ++ RT_CID_8187_SERCOMM_PS = 2, ++ RT_CID_8187_HW_LED = 3, ++ RT_CID_8187_NETGEAR = 4, ++ RT_CID_WHQL = 5, ++ RT_CID_819x_CAMEO = 6, ++ RT_CID_819x_RUNTOP = 7, ++ RT_CID_819x_Senao = 8, ++ RT_CID_TOSHIBA = 9, /* Merge by Jacken, 2008/01/31. */ ++ RT_CID_819x_Netcore = 10, ++ RT_CID_Nettronix = 11, ++ RT_CID_DLINK = 12, ++ RT_CID_PRONET = 13, ++ RT_CID_COREGA = 14, ++ RT_CID_CHINA_MOBILE = 15, ++ RT_CID_819x_ALPHA = 16, ++ RT_CID_819x_Sitecom = 17, ++ RT_CID_CCX = 18, /* It's set under CCX logo test and isn't demanded ++ * for CCX functions, but for test behavior like retry ++ * limit and tx report. By Bruce, 2009-02-17. */ ++ RT_CID_819x_Lenovo = 19, ++ RT_CID_819x_QMI = 20, ++ RT_CID_819x_Edimax_Belkin = 21, ++ RT_CID_819x_Sercomm_Belkin = 22, ++ RT_CID_819x_CAMEO1 = 23, ++ RT_CID_819x_MSI = 24, ++ RT_CID_819x_Acer = 25, ++ RT_CID_819x_AzWave_ASUS = 26, ++ RT_CID_819x_AzWave = 27, /* For AzWave in PCIe,i ++ * The ID is AzWave use and not only Asus */ ++ RT_CID_819x_HP = 28, ++ RT_CID_819x_WNC_COREGA = 29, ++ RT_CID_819x_Arcadyan_Belkin = 30, ++ RT_CID_819x_SAMSUNG = 31, ++ RT_CID_819x_CLEVO = 32, ++ RT_CID_819x_DELL = 33, ++ RT_CID_819x_PRONETS = 34, ++ RT_CID_819x_Edimax_ASUS = 35, ++ RT_CID_819x_CAMEO_NETGEAR = 36, ++ RT_CID_PLANEX = 37, ++ RT_CID_CC_C = 38, ++ RT_CID_819x_Xavi = 39, ++ RT_CID_819x_FUNAI_TV = 40, ++ RT_CID_819x_ALPHA_WD=41, ++}; ++ ++struct eeprom_priv { ++ u8 bautoload_fail_flag; ++ u8 bloadfile_fail_flag; ++ u8 bloadmac_fail_flag; ++ u8 mac_addr[6]; /* PermanentAddress */ ++ u16 channel_plan; ++ u8 EepromOrEfuse; ++ u8 efuse_eeprom_data[HWSET_MAX_SIZE_512] __aligned(4); ++}; ++ ++void eeprom_write16(struct adapter *padapter, u16 reg, u16 data); ++u16 eeprom_read16(struct adapter *padapter, u16 reg); ++void read_eeprom_content(struct adapter *padapter); ++void eeprom_read_sz(struct adapter *adapt, u16 reg, u8 *data, u32 sz); ++void read_eeprom_content_by_attrib(struct adapter *padapter); ++ ++#endif /* __RTL871X_EEPROM_H__ */ +diff --git a/drivers/staging/r8188eu/include/rtw_efuse.h b/drivers/staging/r8188eu/include/rtw_efuse.h +new file mode 100644 +index 000000000000..b3ff46db2091 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_efuse.h +@@ -0,0 +1,134 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_EFUSE_H__ ++#define __RTW_EFUSE_H__ ++ ++#include "osdep_service.h" ++ ++#define EFUSE_ERROE_HANDLE 1 ++ ++#define PG_STATE_HEADER 0x01 ++#define PG_STATE_WORD_0 0x02 ++#define PG_STATE_WORD_1 0x04 ++#define PG_STATE_WORD_2 0x08 ++#define PG_STATE_WORD_3 0x10 ++#define PG_STATE_DATA 0x20 ++ ++#define PG_SWBYTE_H 0x01 ++#define PG_SWBYTE_L 0x02 ++ ++#define PGPKT_DATA_SIZE 8 ++ ++#define EFUSE_WIFI 0 ++#define EFUSE_BT 1 ++ ++enum _EFUSE_DEF_TYPE { ++ TYPE_EFUSE_MAX_SECTION = 0, ++ TYPE_EFUSE_REAL_CONTENT_LEN = 1, ++ TYPE_AVAILABLE_EFUSE_BYTES_BANK = 2, ++ TYPE_AVAILABLE_EFUSE_BYTES_TOTAL = 3, ++ TYPE_EFUSE_MAP_LEN = 4, ++ TYPE_EFUSE_PROTECT_BYTES_BANK = 5, ++ TYPE_EFUSE_CONTENT_LEN_BANK = 6, ++}; ++ ++/* E-Fuse */ ++#define EFUSE_MAP_SIZE 512 ++#define EFUSE_MAX_SIZE 256 ++/* end of E-Fuse */ ++ ++#define EFUSE_MAX_MAP_LEN 512 ++#define EFUSE_MAX_HW_SIZE 512 ++#define EFUSE_MAX_SECTION_BASE 16 ++ ++#define EXT_HEADER(header) ((header & 0x1F) == 0x0F) ++#define ALL_WORDS_DISABLED(wde) ((wde & 0x0F) == 0x0F) ++#define GET_HDR_OFFSET_2_0(header) ((header & 0xE0) >> 5) ++ ++#define EFUSE_REPEAT_THRESHOLD_ 3 ++ ++/* The following is for BT Efuse definition */ ++#define EFUSE_BT_MAX_MAP_LEN 1024 ++#define EFUSE_MAX_BANK 4 ++#define EFUSE_MAX_BT_BANK (EFUSE_MAX_BANK-1) ++/*--------------------------Define Parameters-------------------------------*/ ++#define EFUSE_MAX_WORD_UNIT 4 ++ ++/*------------------------------Define structure----------------------------*/ ++struct pgpkt { ++ u8 offset; ++ u8 word_en; ++ u8 data[8]; ++ u8 word_cnts; ++}; ++ ++/*------------------------------Define structure----------------------------*/ ++struct efuse_hal { ++ u8 fakeEfuseBank; ++ u32 fakeEfuseUsedBytes; ++ u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE]; ++ u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN]; ++ u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN]; ++ ++ u16 BTEfuseUsedBytes; ++ u8 BTEfuseUsedPercentage; ++ u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; ++ u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]; ++ u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]; ++ ++ u16 fakeBTEfuseUsedBytes; ++ u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; ++ u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]; ++ u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]; ++}; ++ ++/*------------------------Export global variable----------------------------*/ ++extern u8 fakeEfuseBank; ++extern u32 fakeEfuseUsedBytes; ++extern u8 fakeEfuseContent[]; ++extern u8 fakeEfuseInitMap[]; ++extern u8 fakeEfuseModifiedMap[]; ++ ++extern u32 BTEfuseUsedBytes; ++extern u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; ++extern u8 BTEfuseInitMap[]; ++extern u8 BTEfuseModifiedMap[]; ++ ++extern u32 fakeBTEfuseUsedBytes; ++extern u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; ++extern u8 fakeBTEfuseInitMap[]; ++extern u8 fakeBTEfuseModifiedMap[]; ++/*------------------------Export global variable----------------------------*/ ++ ++u8 efuse_GetCurrentSize(struct adapter *adapter, u16 *size); ++u16 efuse_GetMaxSize(struct adapter *adapter); ++u8 rtw_efuse_access(struct adapter *adapter, u8 read, u16 start_addr, ++ u16 cnts, u8 *data); ++u8 rtw_efuse_map_read(struct adapter *adapter, u16 addr, u16 cnts, u8 *data); ++u8 rtw_efuse_map_write(struct adapter *adapter, u16 addr, u16 cnts, u8 *data); ++u8 rtw_BT_efuse_map_read(struct adapter *adapter, u16 addr, ++ u16 cnts, u8 *data); ++u8 rtw_BT_efuse_map_write(struct adapter *adapter, u16 addr, ++ u16 cnts, u8 *data); ++u16 Efuse_GetCurrentSize(struct adapter *adapter, u8 efusetype, bool test); ++u8 Efuse_CalculateWordCnts(u8 word_en); ++void ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf, bool test); ++void EFUSE_GetEfuseDefinition(struct adapter *adapt, u8 type, u8 type1, ++ void *out, bool bPseudoTest); ++u8 efuse_OneByteRead(struct adapter *adapter, u16 addr, u8 *data, bool test); ++u8 efuse_OneByteWrite(struct adapter *adapter, u16 addr, u8 data, bool test); ++ ++void Efuse_PowerSwitch(struct adapter *adapt,u8 bWrite,u8 PwrState); ++int Efuse_PgPacketRead(struct adapter *adapt, u8 offset, u8 *data, bool test); ++int Efuse_PgPacketWrite(struct adapter *adapter, u8 offset, u8 word, u8 *data, ++ bool test); ++void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata); ++u8 Efuse_WordEnableDataWrite(struct adapter *adapter, u16 efuse_addr, ++ u8 word_en, u8 *data, bool test); ++ ++u8 EFUSE_Read1Byte(struct adapter *adapter, u16 address); ++void EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype, bool test); ++void EFUSE_ShadowRead(struct adapter *adapt, u8 type, u16 offset, u32 *val); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_event.h b/drivers/staging/r8188eu/include/rtw_event.h +new file mode 100644 +index 000000000000..54dc1ea437fc +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_event.h +@@ -0,0 +1,97 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_EVENT_H_ ++#define _RTW_EVENT_H_ ++ ++#include "osdep_service.h" ++ ++#include "wlan_bssdef.h" ++#include ++#include ++ ++/* ++Used to report a bss has been scanned ++*/ ++struct survey_event { ++ struct wlan_bssid_ex bss; ++}; ++ ++/* ++Used to report that the requested site survey has been done. ++ ++bss_cnt indicates the number of bss that has been reported. ++ ++*/ ++struct surveydone_event { ++ unsigned int bss_cnt; ++ ++}; ++ ++/* ++Used to report the link result of joinning the given bss ++ ++join_res: ++-1: authentication fail ++-2: association fail ++> 0: TID ++ ++*/ ++struct joinbss_event { ++ struct wlan_network network; ++}; ++ ++/* ++Used to report a given STA has joinned the created BSS. ++It is used in AP/Ad-HoC(M) mode. ++*/ ++ ++struct stassoc_event { ++ unsigned char macaddr[6]; ++ unsigned char rsvd[2]; ++ int cam_id; ++}; ++ ++struct stadel_event { ++ unsigned char macaddr[6]; ++ unsigned char rsvd[2]; /* for reason */ ++ int mac_id; ++}; ++ ++struct addba_event { ++ unsigned int tid; ++}; ++ ++#define GEN_EVT_CODE(event) event ## _EVT_ ++ ++struct fwevent { ++ u32 parmsize; ++ void (*event_callback)(struct adapter *dev, u8 *pbuf); ++}; ++ ++#define C2HEVENT_SZ 32 ++ ++struct event_node { ++ unsigned char *node; ++ unsigned char evt_code; ++ unsigned short evt_sz; ++ int *caller_ff_tail; ++ int caller_ff_sz; ++}; ++ ++struct c2hevent_queue { ++ int head; ++ int tail; ++ struct event_node nodes[C2HEVENT_SZ]; ++ unsigned char seq; ++}; ++ ++#define NETWORK_QUEUE_SZ 4 ++ ++struct network_queue { ++ int head; ++ int tail; ++ struct wlan_bssid_ex networks[NETWORK_QUEUE_SZ]; ++}; ++ ++#endif /* _WLANEVENT_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_ht.h b/drivers/staging/r8188eu/include/rtw_ht.h +new file mode 100644 +index 000000000000..2b56b7c38c86 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_ht.h +@@ -0,0 +1,28 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_HT_H_ ++#define _RTW_HT_H_ ++ ++#include "osdep_service.h" ++#include "wifi.h" ++ ++struct ht_priv { ++ u32 ht_option; ++ u32 ampdu_enable;/* for enable Tx A-MPDU */ ++ u32 tx_amsdu_enable;/* for enable Tx A-MSDU */ ++ u32 tx_amdsu_maxlen; /* 1: 8k, 0:4k ; default:8k, for tx */ ++ u32 rx_ampdu_maxlen; /* for rx reordering ctrl win_sz, ++ * updated when join_callback. */ ++ u8 bwmode;/* */ ++ u8 ch_offset;/* PRIME_CHNL_OFFSET */ ++ u8 sgi;/* short GI */ ++ ++ /* for processing Tx A-MPDU */ ++ u8 agg_enable_bitmap; ++ u8 candidate_tid_bitmap; ++ ++ struct ieee80211_ht_cap ht_cap; ++}; ++ ++#endif /* _RTL871X_HT_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h +new file mode 100644 +index 000000000000..4b41c7b03972 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_io.h +@@ -0,0 +1,367 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_IO_H_ ++#define _RTW_IO_H_ ++ ++#include "osdep_service.h" ++#include "osdep_intf.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define rtw_usb_buffer_alloc(dev, size, dma) \ ++ usb_alloc_coherent((dev), (size), (in_interrupt() ? \ ++ GFP_ATOMIC : GFP_KERNEL), (dma)) ++#define rtw_usb_buffer_free(dev, size, addr, dma) \ ++ usb_free_coherent((dev), (size), (addr), (dma)) ++ ++#define NUM_IOREQ 8 ++ ++#define MAX_PROT_SZ (64-16) ++ ++#define _IOREADY 0 ++#define _IO_WAIT_COMPLETE 1 ++#define _IO_WAIT_RSP 2 ++ ++/* IO COMMAND TYPE */ ++#define _IOSZ_MASK_ (0x7F) ++#define _IO_WRITE_ BIT(7) ++#define _IO_FIXED_ BIT(8) ++#define _IO_BURST_ BIT(9) ++#define _IO_BYTE_ BIT(10) ++#define _IO_HW_ BIT(11) ++#define _IO_WORD_ BIT(12) ++#define _IO_SYNC_ BIT(13) ++#define _IO_CMDMASK_ (0x1F80) ++ ++/* ++ For prompt mode accessing, caller shall free io_req ++ Otherwise, io_handler will free io_req ++*/ ++ ++/* IO STATUS TYPE */ ++#define _IO_ERR_ BIT(2) ++#define _IO_SUCCESS_ BIT(1) ++#define _IO_DONE_ BIT(0) ++ ++#define IO_RD32 (_IO_SYNC_ | _IO_WORD_) ++#define IO_RD16 (_IO_SYNC_ | _IO_HW_) ++#define IO_RD8 (_IO_SYNC_ | _IO_BYTE_) ++ ++#define IO_RD32_ASYNC (_IO_WORD_) ++#define IO_RD16_ASYNC (_IO_HW_) ++#define IO_RD8_ASYNC (_IO_BYTE_) ++ ++#define IO_WR32 (_IO_WRITE_ | _IO_SYNC_ | _IO_WORD_) ++#define IO_WR16 (_IO_WRITE_ | _IO_SYNC_ | _IO_HW_) ++#define IO_WR8 (_IO_WRITE_ | _IO_SYNC_ | _IO_BYTE_) ++ ++#define IO_WR32_ASYNC (_IO_WRITE_ | _IO_WORD_) ++#define IO_WR16_ASYNC (_IO_WRITE_ | _IO_HW_) ++#define IO_WR8_ASYNC (_IO_WRITE_ | _IO_BYTE_) ++ ++/* ++ Only Sync. burst accessing is provided. ++*/ ++ ++#define IO_WR_BURST(x) \ ++ (_IO_WRITE_ | _IO_SYNC_ | _IO_BURST_ | ((x) & _IOSZ_MASK_)) ++#define IO_RD_BURST(x) \ ++ (_IO_SYNC_ | _IO_BURST_ | ((x) & _IOSZ_MASK_)) ++ ++/* below is for the intf_option bit defition... */ ++ ++#define _INTF_ASYNC_ BIT(0) /* support async io */ ++ ++struct intf_priv; ++struct intf_hdl; ++struct io_queue; ++ ++struct _io_ops { ++ u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr); ++ u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr); ++ u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr); ++ int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); ++ int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val); ++ int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val); ++ int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr, u32 length, ++ u8 *pdata); ++ int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val); ++ int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val); ++ int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val); ++ void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, ++ u8 *pmem); ++ void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, ++ u8 *pmem); ++ u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, ++ u8 *pmem); ++ u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, ++ u8 *pmem); ++ void (*_read_port_cancel)(struct intf_hdl *pintfhdl); ++ void (*_write_port_cancel)(struct intf_hdl *pintfhdl); ++}; ++ ++struct io_req { ++ struct list_head list; ++ u32 addr; ++ u32 val; ++ u32 command; ++ u32 status; ++ u8 *pbuf; ++ struct semaphore sema; ++ ++ void (*_async_io_callback)(struct adapter *padater, ++ struct io_req *pio_req, u8 *cnxt); ++ u8 *cnxt; ++}; ++ ++struct intf_hdl { ++ struct adapter *padapter; ++ struct dvobj_priv *pintf_dev; ++ struct _io_ops io_ops; ++}; ++ ++struct reg_protocol_rd { ++#ifdef __LITTLE_ENDIAN ++ /* DW1 */ ++ u32 NumOfTrans:4; ++ u32 Reserved1:4; ++ u32 Reserved2:24; ++ /* DW2 */ ++ u32 ByteCount:7; ++ u32 WriteEnable:1; /* 0:read, 1:write */ ++ u32 FixOrContinuous:1; /* 0:continuous, 1: Fix */ ++ u32 BurstMode:1; ++ u32 Byte1Access:1; ++ u32 Byte2Access:1; ++ u32 Byte4Access:1; ++ u32 Reserved3:3; ++ u32 Reserved4:16; ++ /* DW3 */ ++ u32 BusAddress; ++ /* DW4 */ ++ /* u32 Value; */ ++#else ++/* DW1 */ ++ u32 Reserved1:4; ++ u32 NumOfTrans:4; ++ u32 Reserved2:24; ++ /* DW2 */ ++ u32 WriteEnable:1; ++ u32 ByteCount:7; ++ u32 Reserved3:3; ++ u32 Byte4Access:1; ++ ++ u32 Byte2Access:1; ++ u32 Byte1Access:1; ++ u32 BurstMode:1; ++ u32 FixOrContinuous:1; ++ u32 Reserved4:16; ++ /* DW3 */ ++ u32 BusAddress; ++ ++ /* DW4 */ ++#endif ++}; ++ ++struct reg_protocol_wt { ++#ifdef __LITTLE_ENDIAN ++ /* DW1 */ ++ u32 NumOfTrans:4; ++ u32 Reserved1:4; ++ u32 Reserved2:24; ++ /* DW2 */ ++ u32 ByteCount:7; ++ u32 WriteEnable:1; /* 0:read, 1:write */ ++ u32 FixOrContinuous:1; /* 0:continuous, 1: Fix */ ++ u32 BurstMode:1; ++ u32 Byte1Access:1; ++ u32 Byte2Access:1; ++ u32 Byte4Access:1; ++ u32 Reserved3:3; ++ u32 Reserved4:16; ++ /* DW3 */ ++ u32 BusAddress; ++ /* DW4 */ ++ u32 Value; ++#else ++ /* DW1 */ ++ u32 Reserved1 :4; ++ u32 NumOfTrans:4; ++ u32 Reserved2:24; ++ /* DW2 */ ++ u32 WriteEnable:1; ++ u32 ByteCount:7; ++ u32 Reserved3:3; ++ u32 Byte4Access:1; ++ u32 Byte2Access:1; ++ u32 Byte1Access:1; ++ u32 BurstMode:1; ++ u32 FixOrContinuous:1; ++ u32 Reserved4:16; ++ /* DW3 */ ++ u32 BusAddress; ++ /* DW4 */ ++ u32 Value; ++#endif ++}; ++ ++/* ++Below is the data structure used by _io_handler ++*/ ++ ++struct io_queue { ++ spinlock_t lock; ++ struct list_head free_ioreqs; ++ struct list_head pending; /* The io_req list that will be served ++ * in the single protocol read/write.*/ ++ struct list_head processing; ++ u8 *free_ioreqs_buf; /* 4-byte aligned */ ++ u8 *pallocated_free_ioreqs_buf; ++ struct intf_hdl intf; ++}; ++ ++struct io_priv { ++ struct adapter *padapter; ++ struct intf_hdl intf; ++}; ++ ++uint ioreq_flush(struct adapter *adapter, struct io_queue *ioqueue); ++void sync_ioreq_enqueue(struct io_req *preq,struct io_queue *ioqueue); ++uint sync_ioreq_flush(struct adapter *adapter, struct io_queue *ioqueue); ++uint free_ioreq(struct io_req *preq, struct io_queue *pio_queue); ++struct io_req *alloc_ioreq(struct io_queue *pio_q); ++ ++uint register_intf_hdl(u8 *dev, struct intf_hdl *pintfhdl); ++void unregister_intf_hdl(struct intf_hdl *pintfhdl); ++ ++void _rtw_attrib_read(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++ ++u8 _rtw_read8(struct adapter *adapter, u32 addr); ++u16 _rtw_read16(struct adapter *adapter, u32 addr); ++u32 _rtw_read32(struct adapter *adapter, u32 addr); ++void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++void _rtw_read_port_cancel(struct adapter *adapter); ++ ++int _rtw_write8(struct adapter *adapter, u32 addr, u8 val); ++int _rtw_write16(struct adapter *adapter, u32 addr, u16 val); ++int _rtw_write32(struct adapter *adapter, u32 addr, u32 val); ++int _rtw_writeN(struct adapter *adapter, u32 addr, u32 length, u8 *pdata); ++ ++int _rtw_write8_async(struct adapter *adapter, u32 addr, u8 val); ++int _rtw_write16_async(struct adapter *adapter, u32 addr, u16 val); ++int _rtw_write32_async(struct adapter *adapter, u32 addr, u32 val); ++ ++void _rtw_write_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++u32 _rtw_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt, ++ u8 *pmem, int timeout_ms); ++void _rtw_write_port_cancel(struct adapter *adapter); ++ ++#define rtw_read8(adapter, addr) _rtw_read8((adapter), (addr)) ++#define rtw_read16(adapter, addr) _rtw_read16((adapter), (addr)) ++#define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr)) ++#define rtw_read_mem(adapter, addr, cnt, mem) \ ++ _rtw_read_mem((adapter), (addr), (cnt), (mem)) ++#define rtw_read_port(adapter, addr, cnt, mem) \ ++ _rtw_read_port((adapter), (addr), (cnt), (mem)) ++#define rtw_read_port_cancel(adapter) _rtw_read_port_cancel((adapter)) ++ ++#define rtw_write8(adapter, addr, val) \ ++ _rtw_write8((adapter), (addr), (val)) ++#define rtw_write16(adapter, addr, val) \ ++ _rtw_write16((adapter), (addr), (val)) ++#define rtw_write32(adapter, addr, val) \ ++ _rtw_write32((adapter), (addr), (val)) ++#define rtw_writeN(adapter, addr, length, data) \ ++ _rtw_writeN((adapter), (addr), (length), (data)) ++#define rtw_write8_async(adapter, addr, val) \ ++ _rtw_write8_async((adapter), (addr), (val)) ++#define rtw_write16_async(adapter, addr, val) \ ++ _rtw_write16_async((adapter), (addr), (val)) ++#define rtw_write32_async(adapter, addr, val) \ ++ _rtw_write32_async((adapter), (addr), (val)) ++#define rtw_write_mem(adapter, addr, cnt, mem) \ ++ _rtw_write_mem((adapter), (addr), (cnt), (mem)) ++#define rtw_write_port(adapter, addr, cnt, mem) \ ++ _rtw_write_port((adapter), (addr), (cnt), (mem)) ++#define rtw_write_port_and_wait(adapter, addr, cnt, mem, timeout_ms) \ ++ _rtw_write_port_and_wait((adapter), (addr), (cnt), (mem), (timeout_ms)) ++#define rtw_write_port_cancel(adapter) _rtw_write_port_cancel((adapter)) ++ ++void rtw_write_scsi(struct adapter *adapter, u32 cnt, u8 *pmem); ++ ++/* ioreq */ ++void ioreq_read8(struct adapter *adapter, u32 addr, u8 *pval); ++void ioreq_read16(struct adapter *adapter, u32 addr, u16 *pval); ++void ioreq_read32(struct adapter *adapter, u32 addr, u32 *pval); ++void ioreq_write8(struct adapter *adapter, u32 addr, u8 val); ++void ioreq_write16(struct adapter *adapter, u32 addr, u16 val); ++void ioreq_write32(struct adapter *adapter, u32 addr, u32 val); ++ ++uint async_read8(struct adapter *adapter, u32 addr, u8 *pbuff, ++ void (*_async_io_callback)(struct adapter *padater, ++ struct io_req *pio_req, ++ u8 *cnxt), u8 *cnxt); ++uint async_read16(struct adapter *adapter, u32 addr, u8 *pbuff, ++ void (*_async_io_callback)(struct adapter *padater, ++ struct io_req *pio_req, ++ u8 *cnxt), u8 *cnxt); ++uint async_read32(struct adapter *adapter, u32 addr, u8 *pbuff, ++ void (*_async_io_callback)(struct adapter *padater, ++ struct io_req *pio_req, ++ u8 *cnxt), u8 *cnxt); ++ ++void async_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++void async_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++ ++void async_write8(struct adapter *adapter, u32 addr, u8 val, ++ void (*_async_io_callback)(struct adapter *padater, ++ struct io_req *pio_req, ++ u8 *cnxt), u8 *cnxt); ++void async_write16(struct adapter *adapter, u32 addr, u16 val, ++ void (*_async_io_callback)(struct adapter *padater, ++ struct io_req *pio_req, ++ u8 *cnxt), u8 *cnxt); ++void async_write32(struct adapter *adapter, u32 addr, u32 val, ++ void (*_async_io_callback)(struct adapter *padater, ++ struct io_req *pio_req, ++ u8 *cnxt), u8 *cnxt); ++ ++void async_write_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++void async_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++ ++int rtw_init_io_priv(struct adapter *padapter, ++ void (*set_intf_ops)(struct _io_ops *pops)); ++ ++uint alloc_io_queue(struct adapter *adapter); ++void free_io_queue(struct adapter *adapter); ++void async_bus_io(struct io_queue *pio_q); ++void bus_sync_io(struct io_queue *pio_q); ++u32 _ioreq2rwmem(struct io_queue *pio_q); ++void dev_power_down(struct adapter * Adapter, u8 bpwrup); ++ ++#define PlatformEFIOWrite1Byte(_a,_b,_c) \ ++ rtw_write8(_a,_b,_c) ++#define PlatformEFIOWrite2Byte(_a,_b,_c) \ ++ rtw_write16(_a,_b,_c) ++#define PlatformEFIOWrite4Byte(_a,_b,_c) \ ++ rtw_write32(_a,_b,_c) ++ ++#define PlatformEFIORead1Byte(_a,_b) \ ++ rtw_read8(_a,_b) ++#define PlatformEFIORead2Byte(_a,_b) \ ++ rtw_read16(_a,_b) ++#define PlatformEFIORead4Byte(_a,_b) \ ++ rtw_read32(_a,_b) ++ ++#endif /* _RTL8711_IO_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_ioctl.h b/drivers/staging/r8188eu/include/rtw_ioctl.h +new file mode 100644 +index 000000000000..a36bd7313755 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_ioctl.h +@@ -0,0 +1,92 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_IOCTL_H_ ++#define _RTW_IOCTL_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#ifndef OID_802_11_CAPABILITY ++ #define OID_802_11_CAPABILITY 0x0d010122 ++#endif ++ ++#ifndef OID_802_11_PMKID ++ #define OID_802_11_PMKID 0x0d010123 ++#endif ++ ++/* For DDK-defined OIDs */ ++#define OID_NDIS_SEG1 0x00010100 ++#define OID_NDIS_SEG2 0x00010200 ++#define OID_NDIS_SEG3 0x00020100 ++#define OID_NDIS_SEG4 0x01010100 ++#define OID_NDIS_SEG5 0x01020100 ++#define OID_NDIS_SEG6 0x01020200 ++#define OID_NDIS_SEG7 0xFD010100 ++#define OID_NDIS_SEG8 0x0D010100 ++#define OID_NDIS_SEG9 0x0D010200 ++#define OID_NDIS_SEG10 0x0D020200 ++ ++#define SZ_OID_NDIS_SEG1 23 ++#define SZ_OID_NDIS_SEG2 3 ++#define SZ_OID_NDIS_SEG3 6 ++#define SZ_OID_NDIS_SEG4 6 ++#define SZ_OID_NDIS_SEG5 4 ++#define SZ_OID_NDIS_SEG6 8 ++#define SZ_OID_NDIS_SEG7 7 ++#define SZ_OID_NDIS_SEG8 36 ++#define SZ_OID_NDIS_SEG9 24 ++#define SZ_OID_NDIS_SEG10 19 ++ ++/* For Realtek-defined OIDs */ ++#define OID_MP_SEG1 0xFF871100 ++#define OID_MP_SEG2 0xFF818000 ++ ++#define OID_MP_SEG3 0xFF818700 ++#define OID_MP_SEG4 0xFF011100 ++ ++enum oid_type { ++ QUERY_OID, ++ SET_OID ++}; ++ ++struct oid_funs_node { ++ unsigned int oid_start; /* the starting number for OID */ ++ unsigned int oid_end; /* the ending number for OID */ ++ struct oid_obj_priv *node_array; ++ unsigned int array_sz; /* the size of node_array */ ++ int query_counter; /* count the number of query hits for this segment */ ++ int set_counter; /* count the number of set hits for this segment */ ++}; ++ ++struct oid_par_priv { ++ void *adapter_context; ++ NDIS_OID oid; ++ void *information_buf; ++ u32 information_buf_len; ++ u32 *bytes_rw; ++ u32 *bytes_needed; ++ enum oid_type type_of_oid; ++ u32 dbg; ++}; ++ ++struct oid_obj_priv { ++ unsigned char dbg; /* 0: without OID debug message ++ * 1: with OID debug message */ ++ int (*oidfuns)(struct oid_par_priv *poid_par_priv); ++}; ++ ++extern struct iw_handler_def rtw_handlers_def; ++ ++int drv_query_info(struct net_device *miniportadaptercontext, NDIS_OID oid, ++ void *informationbuffer, u32 informationbufferlength, ++ u32 *byteswritten, u32 *bytesneeded); ++ ++int drv_set_info(struct net_device *MiniportAdapterContext, ++ NDIS_OID oid, void *informationbuffer, ++ u32 informationbufferlength, u32 *bytesread, ++ u32 *bytesneeded); ++ ++extern int ui_pid[3]; ++ ++#endif /* #ifndef __INC_CEINFO_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_ioctl_rtl.h b/drivers/staging/r8188eu/include/rtw_ioctl_rtl.h +new file mode 100644 +index 000000000000..6d3d1ef923f6 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_ioctl_rtl.h +@@ -0,0 +1,63 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_IOCTL_RTL_H_ ++#define _RTW_IOCTL_RTL_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++/* oid_rtl_seg_01_01 ************** */ ++int oid_rt_get_signal_quality_hdl(struct oid_par_priv *poid_par_priv);/* 84 */ ++int oid_rt_get_small_packet_crc_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_middle_packet_crc_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_large_packet_crc_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_tx_retry_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_rx_retry_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_rx_total_packet_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_tx_beacon_ok_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_tx_beacon_err_hdl(struct oid_par_priv *poid_par_priv); ++ ++int oid_rt_pro_set_fw_dig_state_hdl(struct oid_par_priv *poid_par_priv);/* 8a */ ++int oid_rt_pro_set_fw_ra_state_hdl(struct oid_par_priv *poid_par_priv); /* 8b */ ++ ++int oid_rt_get_rx_icv_err_hdl(struct oid_par_priv *poid_par_priv);/* 93 */ ++int oid_rt_set_encryption_algorithm_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_preamble_mode_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_ap_ip_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_channelplan_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_set_channelplan_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_set_preamble_mode_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_set_bcn_intvl_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_dedicate_probe_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_total_tx_bytes_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_total_rx_bytes_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_current_tx_power_level_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_enc_key_mismatch_count_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_enc_key_match_count_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_channel_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_hardware_radio_off_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_key_mismatch_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_supported_wireless_mode_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_channel_list_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_scan_in_progress_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_forced_data_rate_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_wireless_mode_for_scan_list_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_bss_wireless_mode_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_scan_with_magic_packet_hdl(struct oid_par_priv *poid_par_priv); ++ ++/* oid_rtl_seg_01_03 section start ************** */ ++int oid_rt_ap_get_associated_station_list_hdl(struct oid_par_priv *priv); ++int oid_rt_ap_switch_into_ap_mode_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_ap_supported_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_ap_set_passphrase_hdl(struct oid_par_priv *poid_par_priv); ++ ++/* oid_rtl_seg_01_11 */ ++int oid_rt_pro_rf_write_registry_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_pro_rf_read_registry_hdl(struct oid_par_priv *poid_par_priv); ++ ++/* oid_rtl_seg_03_00 section start ************** */ ++int oid_rt_get_connect_state_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_set_default_key_id_hdl(struct oid_par_priv *poid_par_priv); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_ioctl_set.h b/drivers/staging/r8188eu/include/rtw_ioctl_set.h +new file mode 100644 +index 000000000000..6216b8ab3a79 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_ioctl_set.h +@@ -0,0 +1,33 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_IOCTL_SET_H_ ++#define __RTW_IOCTL_SET_H_ ++ ++#include "drv_types.h" ++ ++typedef u8 NDIS_802_11_PMKID_VALUE[16]; ++ ++u8 rtw_set_802_11_add_key(struct adapter *adapt, struct ndis_802_11_key *key); ++u8 rtw_set_802_11_authentication_mode(struct adapter *adapt, ++ enum ndis_802_11_auth_mode authmode); ++u8 rtw_set_802_11_bssid(struct adapter*adapter, u8 *bssid); ++u8 rtw_set_802_11_add_wep(struct adapter *adapter, struct ndis_802_11_wep *wep); ++u8 rtw_set_802_11_disassociate(struct adapter *adapter); ++u8 rtw_set_802_11_bssid_list_scan(struct adapter*adapter, ++ struct ndis_802_11_ssid *pssid, ++ int ssid_max_num); ++u8 rtw_set_802_11_infrastructure_mode(struct adapter *adapter, ++ enum ndis_802_11_network_infra type); ++u8 rtw_set_802_11_remove_wep(struct adapter *adapter, u32 keyindex); ++u8 rtw_set_802_11_ssid(struct adapter *adapt, struct ndis_802_11_ssid *ssid); ++u8 rtw_set_802_11_remove_key(struct adapter *adapt, ++ struct ndis_802_11_remove_key *key); ++u8 rtw_validate_ssid(struct ndis_802_11_ssid *ssid); ++u16 rtw_get_cur_max_rate(struct adapter *adapter); ++int rtw_set_scan_mode(struct adapter *adapter, enum rt_scan_type scan_mode); ++int rtw_set_channel_plan(struct adapter *adapter, u8 channel_plan); ++int rtw_set_country(struct adapter *adapter, const char *country_code); ++int rtw_change_ifname(struct adapter *padapter, const char *ifname); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_iol.h b/drivers/staging/r8188eu/include/rtw_iol.h +new file mode 100644 +index 000000000000..471f9ca092a8 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_iol.h +@@ -0,0 +1,68 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_IOL_H_ ++#define __RTW_IOL_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define IOREG_CMD_END_LEN 4 ++ ++struct ioreg_cfg { ++ u8 length; ++ u8 cmd_id; ++ __le16 address; ++ __le32 data; ++ __le32 mask; ++}; ++ ++enum ioreg_cmd { ++ IOREG_CMD_LLT = 0x01, ++ IOREG_CMD_REFUSE = 0x02, ++ IOREG_CMD_EFUSE_PATH = 0x03, ++ IOREG_CMD_WB_REG = 0x04, ++ IOREG_CMD_WW_REG = 0x05, ++ IOREG_CMD_WD_REG = 0x06, ++ IOREG_CMD_W_RF = 0x07, ++ IOREG_CMD_DELAY_US = 0x10, ++ IOREG_CMD_DELAY_MS = 0x11, ++ IOREG_CMD_END = 0xFF, ++}; ++ ++struct xmit_frame *rtw_IOL_accquire_xmit_frame(struct adapter *adapter); ++int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, ++ u32 cmd_len); ++int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary); ++int rtw_IOL_exec_cmds_sync(struct adapter *adapter, ++ struct xmit_frame *xmit_frame, u32 max_wating_ms, ++ u32 bndy_cnt); ++bool rtw_IOL_applied(struct adapter *adapter); ++int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us); ++int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms); ++int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame); ++ ++void read_efuse_from_txpktbuf(struct adapter *adapter, int bcnhead, ++ u8 *content, u16 *size); ++ ++int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, ++ u8 value, u8 mask); ++int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, ++ u16 value, u16 mask); ++int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, ++ u32 value, u32 mask); ++int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, ++ u16 addr, u32 value, u32 mask); ++#define rtw_IOL_append_WB_cmd(xmit_frame, addr, value, mask) \ ++ _rtw_IOL_append_WB_cmd((xmit_frame), (addr), (value) ,(mask)) ++#define rtw_IOL_append_WW_cmd(xmit_frame, addr, value, mask) \ ++ _rtw_IOL_append_WW_cmd((xmit_frame), (addr), (value),(mask)) ++#define rtw_IOL_append_WD_cmd(xmit_frame, addr, value, mask) \ ++ _rtw_IOL_append_WD_cmd((xmit_frame), (addr), (value), (mask)) ++#define rtw_IOL_append_WRF_cmd(xmit_frame, rf_path, addr, value, mask) \ ++ _rtw_IOL_append_WRF_cmd((xmit_frame),(rf_path), (addr), (value), (mask)) ++ ++u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame); ++void rtw_IOL_cmd_buf_dump(struct adapter *Adapter,int buf_len,u8 *pbuf); ++ ++#endif /* __RTW_IOL_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_led.h b/drivers/staging/r8188eu/include/rtw_led.h +new file mode 100644 +index 000000000000..f0965aa5b470 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_led.h +@@ -0,0 +1,181 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_LED_H_ ++#define __RTW_LED_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define MSECS(t) (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000) ++ ++#define LED_BLINK_NORMAL_INTERVAL 100 ++#define LED_BLINK_SLOWLY_INTERVAL 200 ++#define LED_BLINK_LONG_INTERVAL 400 ++ ++#define LED_BLINK_NO_LINK_INTERVAL_ALPHA 1000 ++#define LED_BLINK_LINK_INTERVAL_ALPHA 500 /* 500 */ ++#define LED_BLINK_SCAN_INTERVAL_ALPHA 180 /* 150 */ ++#define LED_BLINK_FASTER_INTERVAL_ALPHA 50 ++#define LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA 5000 ++ ++#define LED_BLINK_NORMAL_INTERVAL_NETTRONIX 100 ++#define LED_BLINK_SLOWLY_INTERVAL_NETTRONIX 2000 ++ ++#define LED_BLINK_SLOWLY_INTERVAL_PORNET 1000 ++#define LED_BLINK_NORMAL_INTERVAL_PORNET 100 ++ ++#define LED_BLINK_FAST_INTERVAL_BITLAND 30 ++ ++/* 060403, rcnjko: Customized for AzWave. */ ++#define LED_CM2_BLINK_ON_INTERVAL 250 ++#define LED_CM2_BLINK_OFF_INTERVAL 4750 ++ ++#define LED_CM8_BLINK_INTERVAL 500 /* for QMI */ ++#define LED_CM8_BLINK_OFF_INTERVAL 3750 /* for QMI */ ++ ++/* 080124, lanhsin: Customized for RunTop */ ++#define LED_RunTop_BLINK_INTERVAL 300 ++ ++/* 060421, rcnjko: Customized for Sercomm Printer Server case. */ ++#define LED_CM3_BLINK_INTERVAL 1500 ++ ++enum LED_CTL_MODE { ++ LED_CTL_POWER_ON = 1, ++ LED_CTL_LINK = 2, ++ LED_CTL_NO_LINK = 3, ++ LED_CTL_TX = 4, ++ LED_CTL_RX = 5, ++ LED_CTL_SITE_SURVEY = 6, ++ LED_CTL_POWER_OFF = 7, ++ LED_CTL_START_TO_LINK = 8, ++ LED_CTL_START_WPS = 9, ++ LED_CTL_STOP_WPS = 10, ++ LED_CTL_START_WPS_BOTTON = 11, /* added for runtop */ ++ LED_CTL_STOP_WPS_FAIL = 12, /* added for ALPHA */ ++ LED_CTL_STOP_WPS_FAIL_OVERLAP = 13, /* added for BELKIN */ ++ LED_CTL_CONNECTION_NO_TRANSFER = 14, ++}; ++ ++enum LED_STATE_871x { ++ LED_UNKNOWN = 0, ++ RTW_LED_ON = 1, ++ RTW_LED_OFF = 2, ++ LED_BLINK_NORMAL = 3, ++ LED_BLINK_SLOWLY = 4, ++ LED_BLINK_POWER_ON = 5, ++ LED_BLINK_SCAN = 6, /* LED is blinking during scanning period, ++ * the # of times to blink is depend on time ++ * for scanning. */ ++ LED_BLINK_NO_LINK = 7, /* LED is blinking during no link state. */ ++ LED_BLINK_StartToBlink = 8,/* Customzied for Sercomm Printer ++ * Server case */ ++ LED_BLINK_TXRX = 9, ++ LED_BLINK_WPS = 10, /* LED is blinkg during WPS communication */ ++ LED_BLINK_WPS_STOP = 11, /* for ALPHA */ ++ LED_BLINK_WPS_STOP_OVERLAP = 12, /* for BELKIN */ ++ LED_BLINK_RUNTOP = 13, /* Customized for RunTop */ ++ LED_BLINK_CAMEO = 14, ++ LED_BLINK_XAVI = 15, ++ LED_BLINK_ALWAYS_ON = 16, ++}; ++ ++enum LED_PIN_871x { ++ LED_PIN_NULL = 0, ++ LED_PIN_LED0 = 1, ++ LED_PIN_LED1 = 2, ++ LED_PIN_LED2 = 3, ++ LED_PIN_GPIO0 = 4, ++}; ++ ++struct LED_871x { ++ struct adapter *padapter; ++ ++ enum LED_PIN_871x LedPin; /* Identify how to implement this ++ * SW led. */ ++ enum LED_STATE_871x CurrLedState; /* Current LED state. */ ++ enum LED_STATE_871x BlinkingLedState; /* Next state for blinking, ++ * either RTW_LED_ON or RTW_LED_OFF are. */ ++ ++ u8 bLedOn; /* true if LED is ON, false if LED is OFF. */ ++ ++ u8 bLedBlinkInProgress; /* true if it is blinking, false o.w.. */ ++ ++ u8 bLedWPSBlinkInProgress; ++ ++ u32 BlinkTimes; /* Number of times to toggle led state for blinking. */ ++ ++ struct timer_list BlinkTimer; /* Timer object for led blinking. */ ++ ++ u8 bSWLedCtrl; ++ ++ /* ALPHA, added by chiyoko, 20090106 */ ++ u8 bLedNoLinkBlinkInProgress; ++ u8 bLedLinkBlinkInProgress; ++ u8 bLedStartToLinkBlinkInProgress; ++ u8 bLedScanBlinkInProgress; ++ struct work_struct BlinkWorkItem; /* Workitem used by BlinkTimer to ++ * manipulate H/W to blink LED. */ ++}; ++ ++#define IS_LED_WPS_BLINKING(_LED_871x) \ ++ (((struct LED_871x *)_LED_871x)->CurrLedState == LED_BLINK_WPS || \ ++ ((struct LED_871x *)_LED_871x)->CurrLedState == LED_BLINK_WPS_STOP || \ ++ ((struct LED_871x *)_LED_871x)->bLedWPSBlinkInProgress) ++ ++#define IS_LED_BLINKING(_LED_871x) \ ++ (((struct LED_871x *)_LED_871x)->bLedWPSBlinkInProgress || \ ++ ((struct LED_871x *)_LED_871x)->bLedScanBlinkInProgress) ++ ++/* LED customization. */ ++ ++enum LED_STRATEGY_871x { ++ SW_LED_MODE0 = 0, /* SW control 1 LED via GPIO0. It is default option.*/ ++ SW_LED_MODE1= 1, /* 2 LEDs, through LED0 and LED1. For ALPHA. */ ++ SW_LED_MODE2 = 2, /* SW control 1 LED via GPIO0, customized for AzWave ++ * 8187 minicard. */ ++ SW_LED_MODE3 = 3, /* SW control 1 LED via GPIO0, customized for Sercomm ++ * Printer Server case. */ ++ SW_LED_MODE4 = 4, /* for Edimax / Belkin */ ++ SW_LED_MODE5 = 5, /* for Sercomm / Belkin */ ++ SW_LED_MODE6 = 6, /* for 88CU minicard, porting from ce SW_LED_MODE7 */ ++ HW_LED = 50, /* HW control 2 LEDs, LED0 and LED1 (there are 4 ++ * different control modes, see MAC.CONFIG1 for details.)*/ ++ LED_ST_NONE = 99, ++}; ++ ++void LedControl8188eu(struct adapter *padapter, enum LED_CTL_MODE LedAction); ++ ++struct led_priv{ ++ /* add for led control */ ++ struct LED_871x SwLed0; ++ struct LED_871x SwLed1; ++ enum LED_STRATEGY_871x LedStrategy; ++ u8 bRegUseLed; ++ void (*LedControlHandler)(struct adapter *padapter, ++ enum LED_CTL_MODE LedAction); ++ /* add for led control */ ++}; ++ ++#define rtw_led_control(adapt, action) \ ++ do { \ ++ if ((adapt)->ledpriv.LedControlHandler) \ ++ (adapt)->ledpriv.LedControlHandler((adapt), (action)); \ ++ } while (0) ++ ++void BlinkTimerCallback(struct timer_list *t); ++void BlinkWorkItemCallback(struct work_struct *work); ++ ++void ResetLedStatus(struct LED_871x * pLed); ++ ++void InitLed871x(struct adapter *padapter, struct LED_871x *pLed, ++ enum LED_PIN_871x LedPin); ++ ++void DeInitLed871x(struct LED_871x *pLed); ++ ++/* hal... */ ++void BlinkHandler(struct LED_871x * pLed); ++void SwLedOn(struct adapter *padapter, struct LED_871x *pLed); ++void SwLedOff(struct adapter *padapter, struct LED_871x *pLed); ++ ++#endif /* __RTW_LED_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_mlme.h b/drivers/staging/r8188eu/include/rtw_mlme.h +new file mode 100644 +index 000000000000..bbb41471472d +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_mlme.h +@@ -0,0 +1,632 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_MLME_H_ ++#define __RTW_MLME_H_ ++ ++#include "osdep_service.h" ++#include "mlme_osdep.h" ++#include "drv_types.h" ++#include "wlan_bssdef.h" ++ ++#define MAX_BSS_CNT 128 ++#define MAX_JOIN_TIMEOUT 6500 ++ ++/* Increase the scanning timeout because of increasing the SURVEY_TO value. */ ++ ++#define SCANNING_TIMEOUT 8000 ++ ++#define SCAN_INTERVAL (30) /* unit:2sec, 30*2=60sec */ ++ ++#define SCANQUEUE_LIFETIME 20 /* unit:sec */ ++ ++#define WIFI_NULL_STATE 0x00000000 ++ ++#define WIFI_ASOC_STATE 0x00000001 /* Under Linked state */ ++#define WIFI_REASOC_STATE 0x00000002 ++#define WIFI_SLEEP_STATE 0x00000004 ++#define WIFI_STATION_STATE 0x00000008 ++ ++#define WIFI_AP_STATE 0x00000010 ++#define WIFI_ADHOC_STATE 0x00000020 ++#define WIFI_ADHOC_MASTER_STATE 0x00000040 ++#define WIFI_UNDER_LINKING 0x00000080 ++ ++#define WIFI_UNDER_WPS 0x00000100 ++#define WIFI_STA_ALIVE_CHK_STATE 0x00000400 ++#define WIFI_SITE_MONITOR 0x00000800 /* to indicate the station is under site surveying */ ++ ++#define WIFI_MP_STATE 0x00010000 ++#define WIFI_MP_CTX_BACKGROUND 0x00020000 /* in continuous tx background */ ++#define WIFI_MP_CTX_ST 0x00040000 /* in continuous tx with single-tone */ ++#define WIFI_MP_CTX_BACKGROUND_PENDING 0x00080000 /* pending in continuous tx background due to out of skb */ ++#define WIFI_MP_CTX_CCK_HW 0x00100000 /* in continuous tx */ ++#define WIFI_MP_CTX_CCK_CS 0x00200000 /* in continuous tx with carrier suppression */ ++#define WIFI_MP_LPBK_STATE 0x00400000 ++ ++#define _FW_UNDER_LINKING WIFI_UNDER_LINKING ++#define _FW_LINKED WIFI_ASOC_STATE ++#define _FW_UNDER_SURVEY WIFI_SITE_MONITOR ++ ++enum dot11AuthAlgrthmNum { ++ dot11AuthAlgrthm_Open = 0, ++ dot11AuthAlgrthm_Shared, ++ dot11AuthAlgrthm_8021X, ++ dot11AuthAlgrthm_Auto, ++ dot11AuthAlgrthm_WAPI, ++ dot11AuthAlgrthm_MaxNum ++}; ++ ++/* Scan type including active and passive scan. */ ++enum rt_scan_type { ++ SCAN_PASSIVE, ++ SCAN_ACTIVE, ++ SCAN_MIX, ++}; ++ ++enum SCAN_RESULT_TYPE { ++ SCAN_RESULT_P2P_ONLY = 0, /* Will return all the P2P devices. */ ++ SCAN_RESULT_ALL = 1, /* Will return all the scanned device, ++ * include AP. */ ++ SCAN_RESULT_WFD_TYPE = 2 /* Will just return the correct WFD ++ * device. */ ++ /* If this device is Miracast sink ++ * device, it will just return all the ++ * Miracast source devices. */ ++}; ++ ++/* ++there are several "locks" in mlme_priv, ++since mlme_priv is a shared resource between many threads, ++like ISR/Call-Back functions, the OID handlers, and even timer functions. ++ ++Each _queue has its own locks, already. ++Other items are protected by mlme_priv.lock. ++ ++To avoid possible dead lock, any thread trying to modifiying mlme_priv ++SHALL not lock up more than one lock at a time! ++*/ ++ ++#define traffic_threshold 10 ++#define traffic_scan_period 500 ++ ++struct sitesurvey_ctrl { ++ u64 last_tx_pkts; ++ uint last_rx_pkts; ++ int traffic_busy; ++ struct timer_list sitesurvey_ctrl_timer; ++}; ++ ++struct rt_link_detect { ++ u32 NumTxOkInPeriod; ++ u32 NumRxOkInPeriod; ++ u32 NumRxUnicastOkInPeriod; ++ bool bBusyTraffic; ++ bool bTxBusyTraffic; ++ bool bRxBusyTraffic; ++ bool bHigherBusyTraffic; /* For interrupt migration purpose. */ ++ bool bHigherBusyRxTraffic; /* We may disable Tx interrupt according ++ * to Rx traffic. */ ++ bool bHigherBusyTxTraffic; /* We may disable Tx interrupt according ++ * to Tx traffic. */ ++}; ++ ++struct profile_info { ++ u8 ssidlen; ++ u8 ssid[ WLAN_SSID_MAXLEN ]; ++ u8 peermac[ ETH_ALEN ]; ++}; ++ ++struct tx_invite_req_info { ++ u8 token; ++ u8 benable; ++ u8 go_ssid[ WLAN_SSID_MAXLEN ]; ++ u8 ssidlen; ++ u8 go_bssid[ ETH_ALEN ]; ++ u8 peer_macaddr[ ETH_ALEN ]; ++ u8 operating_ch; /* This information will be set by using the ++ * p2p_set op_ch=x */ ++ u8 peer_ch; /* The listen channel for peer P2P device */ ++}; ++ ++struct tx_invite_resp_info { ++ u8 token; /* Used to record the dialog token of p2p invitation ++ * request frame. */ ++}; ++ ++struct tx_provdisc_req_info { ++ u16 wps_config_method_request; /* Used when sending the ++ * provisioning request frame*/ ++ u16 peer_channel_num[2]; /* The channel number which the ++ * receiver stands. */ ++ struct ndis_802_11_ssid ssid; ++ u8 peerDevAddr[ETH_ALEN]; /* Peer device address */ ++ u8 peerIFAddr[ETH_ALEN]; /* Peer interface address */ ++ u8 benable; /* This provision discovery ++ * request frame is trigger ++ * to send or not */ ++}; ++ ++/* When peer device issue prov_disc_req first, we should store the following ++ * information */ ++/* The UI must know this information to know which config method the ++ * remote p2p device needs. */ ++struct rx_provdisc_req_info { ++ u8 peerDevAddr[ETH_ALEN]; /* Peer device address */ ++ u8 strconfig_method_desc_of_prov_disc_req[4]; /* description ++ * for the config method located in the provisioning ++ * discovery request frame. */ ++}; ++ ++struct tx_nego_req_info { ++ u16 peer_channel_num[2]; /* The channel number. */ ++ u8 peerDevAddr[ETH_ALEN]; /* Peer device address */ ++ u8 benable; /* This negotiation request frame is ++ * trigger to send or not */ ++}; ++ ++struct group_id_info { ++ u8 go_device_addr[ ETH_ALEN ]; /* The GO's device address of ++ * this P2P group */ ++ u8 ssid[ WLAN_SSID_MAXLEN ]; /* The SSID of this P2P group */ ++}; ++ ++struct scan_limit_info { ++ u8 scan_op_ch_only; /* When this flag is set, the driver ++ * should only scan the op. channel */ ++ u8 operation_ch[2]; /* Store the op. chan of invitation */ ++}; ++ ++struct wifidirect_info { ++ struct adapter *padapter; ++ struct timer_list find_phase_timer; ++ struct timer_list restore_p2p_state_timer; ++ ++ /* Used to do the scanning. After confirming the peer is availalble, ++ * the driver transmits the P2P frame to peer. */ ++ struct timer_list pre_tx_scan_timer; ++ struct timer_list reset_ch_sitesurvey; ++ struct timer_list reset_ch_sitesurvey2; /* Just for resetting the scan ++ * limit function by using p2p nego */ ++ struct tx_provdisc_req_info tx_prov_disc_info; ++ struct rx_provdisc_req_info rx_prov_disc_info; ++ struct tx_invite_req_info invitereq_info; ++ /* Store the profile information of persistent group */ ++ struct profile_info profileinfo[P2P_MAX_PERSISTENT_GROUP_NUM]; ++ struct tx_invite_resp_info inviteresp_info; ++ struct tx_nego_req_info nego_req_info; ++ /* Store the group id info when doing the group negot handshake. */ ++ struct group_id_info groupid_info; ++ /* Used for get the limit scan channel from the Invitation procedure */ ++ struct scan_limit_info rx_invitereq_info; ++ /* Used for get the limit scan chan from the P2P negotiation handshake*/ ++ struct scan_limit_info p2p_info; ++ enum P2P_ROLE role; ++ enum P2P_STATE pre_p2p_state; ++ enum P2P_STATE p2p_state; ++ /* The device address should be the mac address of this device. */ ++ u8 device_addr[ETH_ALEN]; ++ u8 interface_addr[ETH_ALEN]; ++ u8 social_chan[4]; ++ u8 listen_channel; ++ u8 operating_channel; ++ u8 listen_dwell; /* This value should be between 1 and 3 */ ++ u8 support_rate[8]; ++ u8 p2p_wildcard_ssid[P2P_WILDCARD_SSID_LEN]; ++ u8 intent; /* should only include the intent value. */ ++ u8 p2p_peer_interface_addr[ETH_ALEN]; ++ u8 p2p_peer_device_addr[ETH_ALEN]; ++ u8 peer_intent; /* Included the intent value and tie breaker value. */ ++ /* Device name for displaying on searching device screen */ ++ u8 device_name[WPS_MAX_DEVICE_NAME_LEN]; ++ u8 device_name_len; ++ u8 profileindex; /* Used to point to the index of profileinfo array */ ++ u8 peer_operating_ch; ++ u8 find_phase_state_exchange_cnt; ++ /* The device password ID for group negotiation */ ++ u16 device_password_id_for_nego; ++ u8 negotiation_dialog_token; ++ /* SSID information for group negotitation */ ++ u8 nego_ssid[WLAN_SSID_MAXLEN]; ++ u8 nego_ssidlen; ++ u8 p2p_group_ssid[WLAN_SSID_MAXLEN]; ++ u8 p2p_group_ssid_len; ++ /* Flag to know if the persistent function should be supported or not.*/ ++ u8 persistent_supported; ++ /* In the Sigma test, the Sigma will provide this enable from the ++ * sta_set_p2p CAPI. */ ++ /* 0: disable */ ++ /* 1: enable */ ++ u8 session_available; /* Flag to set the WFD session available to ++ * enable or disable "by Sigma" */ ++ /* In the Sigma test, the Sigma will disable the session available ++ * by using the sta_preset CAPI. */ ++ /* 0: disable */ ++ /* 1: enable */ ++ u8 wfd_tdls_enable; /* Flag to enable or disable the TDLS by WFD Sigma*/ ++ /* 0: disable */ ++ /* 1: enable */ ++ u8 wfd_tdls_weaksec; /* Flag to enable or disable the weak security ++ * function for TDLS by WFD Sigma */ ++ /* 0: disable */ ++ /* In this case, the driver can't issue the tdsl ++ * setup request frame. */ ++ /* 1: enable */ ++ /* In this case, the driver can issue the tdls ++ * setup request frame */ ++ /* even the current security is weak security. */ ++ ++ /* This field will store the WPS value (PIN value or PBC) that UI had ++ * got from the user. */ ++ enum P2P_WPSINFO ui_got_wps_info; ++ u16 supported_wps_cm; /* This field describes the WPS config method ++ * which this driver supported. */ ++ /* The value should be the combination of config ++ * method defined in page104 of WPS v2.0 spec.*/ ++ /* This field will contain the length of body of P2P Channel List ++ * attribute of group negotiation response frame. */ ++ uint channel_list_attr_len; ++ /* This field will contain the body of P2P Channel List attribute of ++ * group negotitation response frame. */ ++ /* We will use the channel_cnt and channel_list fields when constructing ++ * the group negotiation confirm frame. */ ++ u8 channel_list_attr[100]; ++ enum P2P_PS_MODE p2p_ps_mode; /* indicate p2p ps mode */ ++ enum P2P_PS_STATE p2p_ps_state; /* indicate p2p ps state */ ++ u8 noa_index; /* Identifies and instance of Notice of Absence timing. */ ++ u8 ctwindow; /* Client traffic window. A period of time in TU after TBTT. */ ++ u8 opp_ps; /* opportunistic power save. */ ++ u8 noa_num; /* number of NoA descriptor in P2P IE. */ ++ u8 noa_count[P2P_MAX_NOA_NUM]; /* Count for owner, Type of client. */ ++ /* Max duration for owner, preferred or min acceptable duration for ++ * client. */ ++ u32 noa_duration[P2P_MAX_NOA_NUM]; ++ /* Length of interval for owner, preferred or max acceptable interval ++ * of client. */ ++ u32 noa_interval[P2P_MAX_NOA_NUM]; ++ /* schedule expressed in terms of the lower 4 bytes of the TSF timer. */ ++ u32 noa_start_time[P2P_MAX_NOA_NUM]; ++}; ++ ++struct tdls_ss_record { /* signal strength record */ ++ u8 macaddr[ETH_ALEN]; ++ u8 RxPWDBAll; ++ u8 is_tdls_sta; /* true: direct link sta, false: else */ ++}; ++ ++struct tdls_info { ++ u8 ap_prohibited; ++ uint setup_state; ++ u8 sta_cnt; ++ u8 sta_maximum; /* 1:tdls sta is equal (NUM_STA-1), reach max direct link number; 0: else; */ ++ struct tdls_ss_record ss_record; ++ u8 macid_index; /* macid entry that is ready to write */ ++ u8 clear_cam; /* cam entry that is trying to clear, using it in direct link teardown */ ++ u8 ch_sensing; ++ u8 cur_channel; ++ u8 candidate_ch; ++ u8 collect_pkt_num[MAX_CHANNEL_NUM]; ++ spinlock_t cmd_lock; ++ spinlock_t hdl_lock; ++ u8 watchdog_count; ++ u8 dev_discovered; /* WFD_TDLS: for sigma test */ ++ u8 enable; ++}; ++ ++struct qos_priv { ++ /* bit mask option: u-apsd, ++ * s-apsd, ts, block ack... */ ++ unsigned int qos_option; ++}; ++ ++struct mlme_priv { ++ spinlock_t lock; ++ int fw_state; /* shall we protect this variable? maybe not necessarily... */ ++ u8 bScanInProcess; ++ u8 to_join; /* flag */ ++ u8 to_roaming; /* roaming trying times */ ++ ++ u8 *nic_hdl; ++ ++ u8 not_indic_disco; ++ struct list_head *pscanned; ++ struct __queue free_bss_pool; ++ struct __queue scanned_queue; ++ u8 *free_bss_buf; ++ u8 key_mask; /* use to restore wep key after hal_init */ ++ u32 num_of_scanned; ++ ++ struct ndis_802_11_ssid assoc_ssid; ++ u8 assoc_bssid[6]; ++ ++ struct wlan_network cur_network; ++ struct wlan_network *cur_network_scanned; ++ ++ u32 scan_interval; ++ ++ struct timer_list assoc_timer; ++ ++ uint assoc_by_bssid; ++ uint assoc_by_rssi; ++ ++ struct timer_list scan_to_timer; /* driver itself handles scan_timeout status. */ ++ u32 scan_start_time; /* used to evaluate the time spent in scanning */ ++ ++ struct qos_priv qospriv; ++ ++ /* Number of non-HT AP/stations */ ++ int num_sta_no_ht; ++ ++ /* Number of HT AP/stations 20 MHz */ ++ /* int num_sta_ht_20mhz; */ ++ ++ int num_FortyMHzIntolerant; ++ struct ht_priv htpriv; ++ struct rt_link_detect LinkDetectInfo; ++ struct timer_list dynamic_chk_timer; /* dynamic/periodic check timer */ ++ ++ u8 acm_mask; /* for wmm acm mask */ ++ u8 ChannelPlan; ++ enum rt_scan_type scan_mode; /* active: 1, passive: 0 */ ++ ++ /* u8 probereq_wpsie[MAX_WPS_IE_LEN];added in probe req */ ++ /* int probereq_wpsie_len; */ ++ u8 *wps_probe_req_ie; ++ u32 wps_probe_req_ie_len; ++ ++ u8 *assoc_req; ++ u32 assoc_req_len; ++ u8 *assoc_rsp; ++ u32 assoc_rsp_len; ++ ++#if defined (CONFIG_88EU_AP_MODE) ++ /* Number of associated Non-ERP stations (i.e., stations using 802.11b ++ * in 802.11g BSS) */ ++ int num_sta_non_erp; ++ ++ /* Number of associated stations that do not support Short Slot Time */ ++ int num_sta_no_short_slot_time; ++ ++ /* Number of associated stations that do not support Short Preamble */ ++ int num_sta_no_short_preamble; ++ ++ int olbc; /* Overlapping Legacy BSS Condition */ ++ ++ /* Number of HT assoc sta that do not support greenfield */ ++ int num_sta_ht_no_gf; ++ ++ /* Number of associated non-HT stations */ ++ /* int num_sta_no_ht; */ ++ ++ /* Number of HT associated stations 20 MHz */ ++ int num_sta_ht_20mhz; ++ ++ /* Overlapping BSS information */ ++ int olbc_ht; ++ ++ u16 ht_op_mode; ++ ++ u8 *wps_beacon_ie; ++ /* u8 *wps_probe_req_ie; */ ++ u8 *wps_probe_resp_ie; ++ u8 *wps_assoc_resp_ie; ++ ++ u32 wps_beacon_ie_len; ++ u32 wps_probe_resp_ie_len; ++ u32 wps_assoc_resp_ie_len; ++ ++ u8 *p2p_beacon_ie; ++ u8 *p2p_probe_req_ie; ++ u8 *p2p_probe_resp_ie; ++ u8 *p2p_go_probe_resp_ie; /* for GO */ ++ u8 *p2p_assoc_req_ie; ++ ++ u32 p2p_beacon_ie_len; ++ u32 p2p_probe_req_ie_len; ++ u32 p2p_probe_resp_ie_len; ++ u32 p2p_go_probe_resp_ie_len; /* for GO */ ++ u32 p2p_assoc_req_ie_len; ++ spinlock_t bcn_update_lock; ++ u8 update_bcn; ++#endif /* if defined (CONFIG_88EU_AP_MODE) */ ++}; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++struct hostapd_priv { ++ struct adapter *padapter; ++}; ++ ++int hostapd_mode_init(struct adapter *padapter); ++void hostapd_mode_unload(struct adapter *padapter); ++#endif ++ ++extern unsigned char WPA_TKIP_CIPHER[4]; ++extern unsigned char RSN_TKIP_CIPHER[4]; ++extern unsigned char REALTEK_96B_IE[]; ++extern unsigned char MCS_rate_2R[16]; ++extern unsigned char MCS_rate_1R[16]; ++ ++void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf); ++void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf); ++void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf); ++void rtw_joinbss_event_callback(struct adapter *adapter, u8 *pbuf); ++void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf); ++void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf); ++void indicate_wx_scan_complete_event(struct adapter *padapter); ++void rtw_indicate_wx_assoc_event(struct adapter *padapter); ++void rtw_indicate_wx_disassoc_event(struct adapter *padapter); ++int event_thread(void *context); ++void rtw_join_timeout_handler (struct timer_list *t); ++void _rtw_scan_timeout_handler (struct timer_list *t); ++void rtw_free_network_queue(struct adapter *adapter, u8 isfreeall); ++int rtw_init_mlme_priv(struct adapter *adapter); ++void rtw_free_mlme_priv (struct mlme_priv *pmlmepriv); ++int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv); ++int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, ++ int keyid, u8 set_tx); ++int rtw_set_auth(struct adapter *adapter, struct security_priv *psecuritypriv); ++ ++static inline u8 *get_bssid(struct mlme_priv *pmlmepriv) ++{ /* if sta_mode:pmlmepriv->cur_network.network.MacAddress=> bssid */ ++ /* if adhoc_mode:pmlmepriv->cur_network.network.MacAddress=> ibss mac address */ ++ return pmlmepriv->cur_network.network.MacAddress; ++} ++ ++static inline int check_fwstate(struct mlme_priv *pmlmepriv, int state) ++{ ++ if (pmlmepriv->fw_state & state) ++ return true; ++ ++ return false; ++} ++ ++static inline int get_fwstate(struct mlme_priv *pmlmepriv) ++{ ++ return pmlmepriv->fw_state; ++} ++ ++/* ++ * No Limit on the calling context, ++ * therefore set it to be the critical section... ++ * ++ * ### NOTE:#### (!!!!) ++ * MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock ++ */ ++static inline void set_fwstate(struct mlme_priv *pmlmepriv, int state) ++{ ++ pmlmepriv->fw_state |= state; ++ /* FOR HW integration */ ++ if (_FW_UNDER_SURVEY==state) ++ pmlmepriv->bScanInProcess = true; ++} ++ ++static inline void _clr_fwstate_(struct mlme_priv *pmlmepriv, int state) ++{ ++ pmlmepriv->fw_state &= ~state; ++ /* FOR HW integration */ ++ if (_FW_UNDER_SURVEY==state) ++ pmlmepriv->bScanInProcess = false; ++} ++ ++/* ++ * No Limit on the calling context, ++ * therefore set it to be the critical section... ++ */ ++static inline void clr_fwstate(struct mlme_priv *pmlmepriv, int state) ++{ ++ spin_lock_bh(&pmlmepriv->lock); ++ if (check_fwstate(pmlmepriv, state)) ++ pmlmepriv->fw_state ^= state; ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++static inline void clr_fwstate_ex(struct mlme_priv *pmlmepriv, int state) ++{ ++ spin_lock_bh(&pmlmepriv->lock); ++ _clr_fwstate_(pmlmepriv, state); ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++static inline void up_scanned_network(struct mlme_priv *pmlmepriv) ++{ ++ spin_lock_bh(&pmlmepriv->lock); ++ pmlmepriv->num_of_scanned++; ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++static inline void down_scanned_network(struct mlme_priv *pmlmepriv) ++{ ++ spin_lock_bh(&pmlmepriv->lock); ++ pmlmepriv->num_of_scanned--; ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++static inline void set_scanned_network_val(struct mlme_priv *pmlmepriv, int val) ++{ ++ spin_lock_bh(&pmlmepriv->lock); ++ pmlmepriv->num_of_scanned = val; ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++u16 rtw_get_capability(struct wlan_bssid_ex *bss); ++void rtw_update_scanned_network(struct adapter *adapter, ++ struct wlan_bssid_ex *target); ++void rtw_disconnect_hdl_under_linked(struct adapter *adapter, ++ struct sta_info *psta, u8 free_assoc); ++void rtw_generate_random_ibss(u8 *pibss); ++struct wlan_network *rtw_find_network(struct __queue *scanned_queue, u8 *addr); ++struct wlan_network *rtw_get_oldest_wlan_network(struct __queue *scanned_queue); ++ ++void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue); ++void rtw_indicate_disconnect(struct adapter *adapter); ++void rtw_indicate_connect(struct adapter *adapter); ++void rtw_indicate_scan_done( struct adapter *padapter, bool aborted); ++void rtw_scan_abort(struct adapter *adapter); ++ ++int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, ++ uint in_len); ++int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, ++ uint in_len, uint initial_out_len); ++void rtw_init_registrypriv_dev_network(struct adapter *adapter); ++ ++void rtw_update_registrypriv_dev_network(struct adapter *adapter); ++ ++void rtw_get_encrypt_decrypt_from_registrypriv(struct adapter *adapter); ++ ++void _rtw_join_timeout_handler(struct adapter *adapter); ++void rtw_scan_timeout_handler(struct adapter *adapter); ++ ++ void rtw_dynamic_check_timer_handlder(struct adapter *adapter); ++#define rtw_is_scan_deny(adapter) false ++#define rtw_clear_scan_deny(adapter) do {} while (0) ++#define rtw_set_scan_deny_timer_hdl(adapter) do {} while (0) ++#define rtw_set_scan_deny(adapter, ms) do {} while (0) ++ ++int _rtw_init_mlme_priv(struct adapter *padapter); ++ ++void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv); ++ ++void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv); ++ ++int _rtw_enqueue_network(struct __queue *queue, struct wlan_network *pnetwork); ++ ++struct wlan_network *_rtw_dequeue_network(struct __queue *queue); ++ ++ struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv); ++ ++void _rtw_free_network(struct mlme_priv *pmlmepriv, ++ struct wlan_network *pnetwork, u8 isfreeall); ++void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, ++ struct wlan_network *pnetwork); ++ ++struct wlan_network* _rtw_find_network(struct __queue *scanned_queue, u8 *addr); ++ ++void _rtw_free_network_queue(struct adapter *padapter, u8 isfreeall); ++ ++int rtw_if_up(struct adapter *padapter); ++ ++u8 *rtw_get_capability_from_ie(u8 *ie); ++u8 *rtw_get_timestampe_from_ie(u8 *ie); ++u8 *rtw_get_beacon_interval_from_ie(u8 *ie); ++ ++void rtw_joinbss_reset(struct adapter *padapter); ++ ++unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, ++ u8 *out_ie, uint in_len, uint *pout_len); ++void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len); ++void rtw_issue_addbareq_cmd(struct adapter *padapter, ++ struct xmit_frame *pxmitframe); ++ ++int rtw_is_same_ibss(struct adapter *adapter, struct wlan_network *pnetwork); ++int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst); ++ ++void rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network); ++void _rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network); ++void rtw_set_roaming(struct adapter *adapter, u8 to_roaming); ++u8 rtw_to_roaming(struct adapter *adapter); ++ ++void rtw_sta_media_status_rpt(struct adapter *adapter, struct sta_info *psta, ++ u32 mstatus); ++ ++#endif /* __RTL871X_MLME_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h +new file mode 100644 +index 000000000000..d2f4d3ce7b90 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h +@@ -0,0 +1,857 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_MLME_EXT_H_ ++#define __RTW_MLME_EXT_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "wlan_bssdef.h" ++ ++/* Commented by Albert 20101105 */ ++/* Increase the SURVEY_TO value from 100 to 150 ( 100ms to 150ms ) */ ++/* The Realtek 8188CE SoftAP will spend around 100ms to send the probe response after receiving the probe request. */ ++/* So, this driver tried to extend the dwell time for each scanning channel. */ ++/* This will increase the chance to receive the probe response from SoftAP. */ ++ ++#define SURVEY_TO (100) ++#define REAUTH_TO (300) /* 50) */ ++#define REASSOC_TO (300) /* 50) */ ++/* define DISCONNECT_TO (3000) */ ++#define ADDBA_TO (2000) ++ ++#define LINKED_TO (1) /* unit:2 sec, 1x2=2 sec */ ++ ++#define REAUTH_LIMIT (4) ++#define REASSOC_LIMIT (4) ++#define READDBA_LIMIT (2) ++ ++#define ROAMING_LIMIT 8 ++ ++#define DYNAMIC_FUNC_DISABLE (0x0) ++ ++/* ====== ODM_ABILITY_E ======== */ ++/* BB ODM section BIT 0-15 */ ++#define DYNAMIC_BB_DIG BIT(0) ++#define DYNAMIC_BB_RA_MASK BIT(1) ++#define DYNAMIC_BB_DYNAMIC_TXPWR BIT(2) ++#define DYNAMIC_BB_BB_FA_CNT BIT(3) ++ ++#define DYNAMIC_BB_RSSI_MONITOR BIT(4) ++#define DYNAMIC_BB_CCK_PD BIT(5) ++#define DYNAMIC_BB_ANT_DIV BIT(6) ++#define DYNAMIC_BB_PWR_SAVE BIT(7) ++#define DYNAMIC_BB_PWR_TRA BIT(8) ++#define DYNAMIC_BB_RATE_ADAPTIVE BIT(9) ++#define DYNAMIC_BB_PATH_DIV BIT(10) ++#define DYNAMIC_BB_PSD BIT(11) ++ ++/* MAC DM section BIT 16-23 */ ++#define DYNAMIC_MAC_EDCA_TURBO BIT(16) ++#define DYNAMIC_MAC_EARLY_MODE BIT(17) ++ ++/* RF ODM section BIT 24-31 */ ++#define DYNAMIC_RF_TX_PWR_TRACK BIT(24) ++#define DYNAMIC_RF_RX_GAIN_TRACK BIT(25) ++#define DYNAMIC_RF_CALIBRATION BIT(26) ++ ++#define DYNAMIC_ALL_FUNC_ENABLE 0xFFFFFFF ++ ++#define _HW_STATE_NOLINK_ 0x00 ++#define _HW_STATE_ADHOC_ 0x01 ++#define _HW_STATE_STATION_ 0x02 ++#define _HW_STATE_AP_ 0x03 ++ ++#define _1M_RATE_ 0 ++#define _2M_RATE_ 1 ++#define _5M_RATE_ 2 ++#define _11M_RATE_ 3 ++#define _6M_RATE_ 4 ++#define _9M_RATE_ 5 ++#define _12M_RATE_ 6 ++#define _18M_RATE_ 7 ++#define _24M_RATE_ 8 ++#define _36M_RATE_ 9 ++#define _48M_RATE_ 10 ++#define _54M_RATE_ 11 ++ ++extern unsigned char RTW_WPA_OUI[]; ++extern unsigned char WMM_OUI[]; ++extern unsigned char WPS_OUI[]; ++extern unsigned char WFD_OUI[]; ++extern unsigned char P2P_OUI[]; ++ ++extern unsigned char WMM_INFO_OUI[]; ++extern unsigned char WMM_PARA_OUI[]; ++ ++/* Channel Plan Type. */ ++/* Note: */ ++/* We just add new channel plan when the new channel plan is different ++ * from any of the following channel plan. */ ++/* If you just want to customize the actions(scan period or join actions) ++ * about one of the channel plan, */ ++/* customize them in struct rt_channel_info in the RT_CHANNEL_LIST. */ ++enum RT_CHANNEL_DOMAIN { ++ /* old channel plan mapping ===== */ ++ RT_CHANNEL_DOMAIN_FCC = 0x00, ++ RT_CHANNEL_DOMAIN_IC = 0x01, ++ RT_CHANNEL_DOMAIN_ETSI = 0x02, ++ RT_CHANNEL_DOMAIN_SPAIN = 0x03, ++ RT_CHANNEL_DOMAIN_FRANCE = 0x04, ++ RT_CHANNEL_DOMAIN_MKK = 0x05, ++ RT_CHANNEL_DOMAIN_MKK1 = 0x06, ++ RT_CHANNEL_DOMAIN_ISRAEL = 0x07, ++ RT_CHANNEL_DOMAIN_TELEC = 0x08, ++ RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN = 0x09, ++ RT_CHANNEL_DOMAIN_WORLD_WIDE_13 = 0x0A, ++ RT_CHANNEL_DOMAIN_TAIWAN = 0x0B, ++ RT_CHANNEL_DOMAIN_CHINA = 0x0C, ++ RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO = 0x0D, ++ RT_CHANNEL_DOMAIN_KOREA = 0x0E, ++ RT_CHANNEL_DOMAIN_TURKEY = 0x0F, ++ RT_CHANNEL_DOMAIN_JAPAN = 0x10, ++ RT_CHANNEL_DOMAIN_FCC_NO_DFS = 0x11, ++ RT_CHANNEL_DOMAIN_JAPAN_NO_DFS = 0x12, ++ RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS = 0x14, ++ ++ /* new channel plan mapping, (2GDOMAIN_5GDOMAIN) ===== */ ++ RT_CHANNEL_DOMAIN_WORLD_NULL = 0x20, ++ RT_CHANNEL_DOMAIN_ETSI1_NULL = 0x21, ++ RT_CHANNEL_DOMAIN_FCC1_NULL = 0x22, ++ RT_CHANNEL_DOMAIN_MKK1_NULL = 0x23, ++ RT_CHANNEL_DOMAIN_ETSI2_NULL = 0x24, ++ RT_CHANNEL_DOMAIN_FCC1_FCC1 = 0x25, ++ RT_CHANNEL_DOMAIN_WORLD_ETSI1 = 0x26, ++ RT_CHANNEL_DOMAIN_MKK1_MKK1 = 0x27, ++ RT_CHANNEL_DOMAIN_WORLD_KCC1 = 0x28, ++ RT_CHANNEL_DOMAIN_WORLD_FCC2 = 0x29, ++ RT_CHANNEL_DOMAIN_WORLD_FCC3 = 0x30, ++ RT_CHANNEL_DOMAIN_WORLD_FCC4 = 0x31, ++ RT_CHANNEL_DOMAIN_WORLD_FCC5 = 0x32, ++ RT_CHANNEL_DOMAIN_WORLD_FCC6 = 0x33, ++ RT_CHANNEL_DOMAIN_FCC1_FCC7 = 0x34, ++ RT_CHANNEL_DOMAIN_WORLD_ETSI2 = 0x35, ++ RT_CHANNEL_DOMAIN_WORLD_ETSI3 = 0x36, ++ RT_CHANNEL_DOMAIN_MKK1_MKK2 = 0x37, ++ RT_CHANNEL_DOMAIN_MKK1_MKK3 = 0x38, ++ RT_CHANNEL_DOMAIN_FCC1_NCC1 = 0x39, ++ RT_CHANNEL_DOMAIN_FCC1_NCC2 = 0x40, ++ RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G = 0x41, ++ /* Add new channel plan above this line=============== */ ++ RT_CHANNEL_DOMAIN_MAX, ++ RT_CHANNEL_DOMAIN_REALTEK_DEFINE = 0x7F, ++}; ++ ++enum RT_CHANNEL_DOMAIN_2G { ++ RT_CHANNEL_DOMAIN_2G_WORLD = 0x00, /* Worldwide 13 */ ++ RT_CHANNEL_DOMAIN_2G_ETSI1 = 0x01, /* Europe */ ++ RT_CHANNEL_DOMAIN_2G_FCC1 = 0x02, /* US */ ++ RT_CHANNEL_DOMAIN_2G_MKK1 = 0x03, /* Japan */ ++ RT_CHANNEL_DOMAIN_2G_ETSI2 = 0x04, /* France */ ++ RT_CHANNEL_DOMAIN_2G_NULL = 0x05, ++ /* Add new channel plan above this line=============== */ ++ RT_CHANNEL_DOMAIN_2G_MAX, ++}; ++ ++#define rtw_is_channel_plan_valid(chplan) \ ++ (chplan < RT_CHANNEL_DOMAIN_MAX || \ ++ chplan == RT_CHANNEL_DOMAIN_REALTEK_DEFINE) ++ ++struct rt_channel_plan { ++ unsigned char Channel[MAX_CHANNEL_NUM]; ++ unsigned char Len; ++}; ++ ++struct rt_channel_plan_2g { ++ unsigned char Channel[MAX_CHANNEL_NUM_2G]; ++ unsigned char Len; ++}; ++ ++struct rt_channel_plan_map { ++ unsigned char Index2G; ++}; ++ ++enum Associated_AP { ++ atherosAP = 0, ++ broadcomAP = 1, ++ ciscoAP = 2, ++ marvellAP = 3, ++ ralinkAP = 4, ++ realtekAP = 5, ++ airgocapAP = 6, ++ unknownAP = 7, ++ maxAP, ++}; ++ ++enum HT_IOT_PEER { ++ HT_IOT_PEER_UNKNOWN = 0, ++ HT_IOT_PEER_REALTEK = 1, ++ HT_IOT_PEER_REALTEK_92SE = 2, ++ HT_IOT_PEER_BROADCOM = 3, ++ HT_IOT_PEER_RALINK = 4, ++ HT_IOT_PEER_ATHEROS = 5, ++ HT_IOT_PEER_CISCO = 6, ++ HT_IOT_PEER_MERU = 7, ++ HT_IOT_PEER_MARVELL = 8, ++ HT_IOT_PEER_REALTEK_SOFTAP = 9,/* peer is RealTek SOFT_AP */ ++ HT_IOT_PEER_SELF_SOFTAP = 10, /* Self is SoftAP */ ++ HT_IOT_PEER_AIRGO = 11, ++ HT_IOT_PEER_INTEL = 12, ++ HT_IOT_PEER_RTK_APCLIENT = 13, ++ HT_IOT_PEER_REALTEK_81XX = 14, ++ HT_IOT_PEER_REALTEK_WOW = 15, ++ HT_IOT_PEER_TENDA = 16, ++ HT_IOT_PEER_MAX = 17 ++}; ++ ++enum SCAN_STATE { ++ SCAN_DISABLE = 0, ++ SCAN_START = 1, ++ SCAN_TXNULL = 2, ++ SCAN_PROCESS = 3, ++ SCAN_COMPLETE = 4, ++ SCAN_STATE_MAX, ++}; ++ ++struct mlme_handler { ++ unsigned int num; ++ char *str; ++ unsigned int (*func)(struct adapter *adapt, struct recv_frame *frame); ++}; ++ ++struct action_handler { ++ unsigned int num; ++ char* str; ++ unsigned int (*func)(struct adapter *adapt, struct recv_frame *frame); ++}; ++ ++struct ss_res { ++ int state; ++ int bss_cnt; ++ int channel_idx; ++ int scan_mode; ++ u8 ssid_num; ++ u8 ch_num; ++ struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT]; ++ struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT]; ++}; ++ ++/* define AP_MODE 0x0C */ ++/* define STATION_MODE 0x08 */ ++/* define AD_HOC_MODE 0x04 */ ++/* define NO_LINK_MODE 0x00 */ ++ ++#define WIFI_FW_NULL_STATE _HW_STATE_NOLINK_ ++#define WIFI_FW_STATION_STATE _HW_STATE_STATION_ ++#define WIFI_FW_AP_STATE _HW_STATE_AP_ ++#define WIFI_FW_ADHOC_STATE _HW_STATE_ADHOC_ ++ ++#define WIFI_FW_AUTH_NULL 0x00000100 ++#define WIFI_FW_AUTH_STATE 0x00000200 ++#define WIFI_FW_AUTH_SUCCESS 0x00000400 ++ ++#define WIFI_FW_ASSOC_STATE 0x00002000 ++#define WIFI_FW_ASSOC_SUCCESS 0x00004000 ++ ++#define WIFI_FW_LINKING_STATE (WIFI_FW_AUTH_NULL | \ ++ WIFI_FW_AUTH_STATE | \ ++ WIFI_FW_AUTH_SUCCESS | \ ++ WIFI_FW_ASSOC_STATE) ++ ++struct FW_Sta_Info { ++ struct sta_info *psta; ++ u32 status; ++ u32 rx_pkt; ++ u32 retry; ++ unsigned char SupportedRates[NDIS_802_11_LENGTH_RATES_EX]; ++}; ++ ++/* ++ * Usage: ++ * When one iface acted as AP mode and the other iface is STA mode and scanning, ++ * it should switch back to AP's operating channel periodically. ++ * Parameters info: ++ * When the driver scanned RTW_SCAN_NUM_OF_CH channels, it would switch back to ++ * AP's operating channel for ++ * RTW_STAY_AP_CH_MILLISECOND * SURVEY_TO milliseconds. ++ * Example: ++ * For chip supports 2.4G + 5GHz and AP mode is operating in channel 1, ++ * RTW_SCAN_NUM_OF_CH is 8, RTW_STAY_AP_CH_MS is 3 and SURVEY_TO is 100. ++ * When it's STA mode gets set_scan command, ++ * it would ++ * 1. Doing the scan on channel 1.2.3.4.5.6.7.8 ++ * 2. Back to channel 1 for 300 milliseconds ++ * 3. Go through doing site survey on channel 9.10.11.36.40.44.48.52 ++ * 4. Back to channel 1 for 300 milliseconds ++ * 5. ... and so on, till survey done. ++ */ ++ ++struct mlme_ext_info { ++ u32 state; ++ u32 reauth_count; ++ u32 reassoc_count; ++ u32 link_count; ++ u32 auth_seq; ++ u32 auth_algo; /* 802.11 auth, could be open, shared, auto */ ++ u32 authModeToggle; ++ u32 enc_algo;/* encrypt algorithm; */ ++ u32 key_index; /* this is only valid for legacy wep, ++ * 0~3 for key id. */ ++ u32 iv; ++ u8 chg_txt[128]; ++ u16 aid; ++ u16 bcn_interval; ++ u16 capability; ++ u8 assoc_AP_vendor; ++ u8 slotTime; ++ u8 preamble_mode; ++ u8 WMM_enable; ++ u8 ERP_enable; ++ u8 ERP_IE; ++ u8 HT_enable; ++ u8 HT_caps_enable; ++ u8 HT_info_enable; ++ u8 HT_protection; ++ u8 turboMode_cts2self; ++ u8 turboMode_rtsen; ++ u8 SM_PS; ++ u8 agg_enable_bitmap; ++ u8 ADDBA_retry_count; ++ u8 candidate_tid_bitmap; ++ u8 dialogToken; ++ /* Accept ADDBA Request */ ++ bool bAcceptAddbaReq; ++ u8 bwmode_updated; ++ u8 hidden_ssid_mode; ++ ++ struct ADDBA_request ADDBA_req; ++ struct WMM_para_element WMM_param; ++ struct HT_caps_element HT_caps; ++ struct HT_info_element HT_info; ++ struct wlan_bssid_ex network;/* join network or bss_network, ++ * if in ap mode, it is the same ++ * as cur_network.network */ ++ struct FW_Sta_Info FW_sta_info[NUM_STA]; ++}; ++ ++/* The channel information about this channel including joining, ++ * scanning, and power constraints. */ ++struct rt_channel_info { ++ u8 ChannelNum; /* The channel number. */ ++ enum rt_scan_type ScanType; /* Scan type such as passive ++ * or active scan. */ ++ u32 rx_count; ++}; ++ ++int rtw_ch_set_search_ch(struct rt_channel_info *ch_set, const u32 ch); ++ ++/* P2P_MAX_REG_CLASSES - Maximum number of regulatory classes */ ++#define P2P_MAX_REG_CLASSES 10 ++ ++/* P2P_MAX_REG_CLASS_CHANNELS - Maximum number of chan per regulatory class */ ++#define P2P_MAX_REG_CLASS_CHANNELS 20 ++ ++/* struct p2p_channels - List of supported channels */ ++struct p2p_channels { ++ /* struct p2p_reg_class - Supported regulatory class */ ++ struct p2p_reg_class { ++ /* reg_class - Regulatory class (IEEE 802.11-2007, Annex J) */ ++ u8 reg_class; ++ ++ /* channel - Supported channels */ ++ u8 channel[P2P_MAX_REG_CLASS_CHANNELS]; ++ ++ /* channels - Number of channel entries in use */ ++ size_t channels; ++ } reg_class[P2P_MAX_REG_CLASSES]; ++ ++ /* reg_classes - Number of reg_class entries in use */ ++ size_t reg_classes; ++}; ++ ++struct p2p_oper_class_map { ++ enum hw_mode {IEEE80211G} mode; ++ u8 op_class; ++ u8 min_chan; ++ u8 max_chan; ++ u8 inc; ++ enum {BW20, BW40PLUS, BW40MINUS} bw; ++}; ++ ++struct mlme_ext_priv { ++ struct adapter *padapter; ++ u8 mlmeext_init; ++ atomic_t event_seq; ++ u16 mgnt_seq; ++ ++ unsigned char cur_channel; ++ unsigned char cur_bwmode; ++ unsigned char cur_ch_offset;/* PRIME_CHNL_OFFSET */ ++ unsigned char cur_wireless_mode; /* NETWORK_TYPE */ ++ ++ unsigned char oper_channel; /* saved chan info when call ++ * set_channel_bw */ ++ unsigned char oper_bwmode; ++ unsigned char oper_ch_offset;/* PRIME_CHNL_OFFSET */ ++ ++ unsigned char max_chan_nums; ++ struct rt_channel_info channel_set[MAX_CHANNEL_NUM]; ++ struct p2p_channels channel_list; ++ unsigned char basicrate[NumRates]; ++ unsigned char datarate[NumRates]; ++ ++ struct ss_res sitesurvey_res; ++ struct mlme_ext_info mlmext_info;/* for sta/adhoc mode, including ++ * current scan/connecting/connected ++ * related info. For ap mode, ++ * network includes ap's cap_info*/ ++ struct timer_list survey_timer; ++ struct timer_list link_timer; ++ u16 chan_scan_time; ++ ++ u8 scan_abort; ++ u8 tx_rate; /* TXRATE when USERATE is set. */ ++ ++ u32 retry; /* retry for issue probereq */ ++ ++ u64 TSFValue; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ unsigned char bstart_bss; ++#endif ++ u8 update_channel_plan_by_ap_done; ++ /* recv_decache check for Action_public frame */ ++ u8 action_public_dialog_token; ++ u16 action_public_rxseq; ++ u8 active_keep_alive_check; ++}; ++ ++int init_mlme_ext_priv(struct adapter *adapter); ++int init_hw_mlme_ext(struct adapter *padapter); ++void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext); ++extern void init_mlme_ext_timer(struct adapter *padapter); ++extern void init_addba_retry_timer(struct adapter *adapt, struct sta_info *sta); ++extern struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv); ++ ++unsigned char networktype_to_raid(unsigned char network_type); ++u8 judge_network_type(struct adapter *padapter, unsigned char *rate, int len); ++void get_rate_set(struct adapter *padapter, unsigned char *pbssrate, int *len); ++void UpdateBrateTbl(struct adapter *padapter, u8 *mBratesOS); ++void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen); ++ ++void Save_DM_Func_Flag(struct adapter *padapter); ++void Restore_DM_Func_Flag(struct adapter *padapter); ++void Switch_DM_Func(struct adapter *padapter, u32 mode, u8 enable); ++ ++void Set_MSR(struct adapter *padapter, u8 type); ++ ++u8 rtw_get_oper_ch(struct adapter *adapter); ++void rtw_set_oper_ch(struct adapter *adapter, u8 ch); ++u8 rtw_get_oper_bw(struct adapter *adapter); ++void rtw_set_oper_bw(struct adapter *adapter, u8 bw); ++u8 rtw_get_oper_choffset(struct adapter *adapter); ++void rtw_set_oper_choffset(struct adapter *adapter, u8 offset); ++ ++void set_channel_bwmode(struct adapter *padapter, unsigned char channel, ++ unsigned char channel_offset, unsigned short bwmode); ++void SelectChannel(struct adapter *padapter, unsigned char channel); ++void SetBWMode(struct adapter *padapter, unsigned short bwmode, ++ unsigned char channel_offset); ++ ++unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval); ++ ++void write_cam(struct adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key); ++void clear_cam_entry(struct adapter *padapter, u8 entry); ++ ++void invalidate_cam_all(struct adapter *padapter); ++void CAM_empty_entry(struct adapter * Adapter, u8 ucIndex); ++ ++int allocate_fw_sta_entry(struct adapter *padapter); ++void flush_all_cam_entry(struct adapter *padapter); ++ ++void site_survey(struct adapter *padapter); ++u8 collect_bss_info(struct adapter *padapter, struct recv_frame *precv_frame, ++ struct wlan_bssid_ex *bssid); ++void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, ++ struct adapter *adapter, bool update_ie); ++ ++int get_bsstype(unsigned short capability); ++u8 *get_my_bssid(struct wlan_bssid_ex *pnetwork); ++u16 get_beacon_interval(struct wlan_bssid_ex *bss); ++ ++int is_client_associated_to_ap(struct adapter *padapter); ++int is_client_associated_to_ibss(struct adapter *padapter); ++int is_IBSS_empty(struct adapter *padapter); ++ ++unsigned char check_assoc_AP(u8 *pframe, uint len); ++ ++int WMM_param_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE); ++void WMMOnAssocRsp(struct adapter *padapter); ++ ++void HT_caps_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE); ++void HT_info_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE); ++void HTOnAssocRsp(struct adapter *padapter); ++ ++void ERP_IE_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE); ++void VCS_update(struct adapter *padapter, struct sta_info *psta); ++ ++void update_beacon_info(struct adapter *padapter, u8 *pframe, uint len, ++ struct sta_info *psta); ++int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len); ++void update_IOT_info(struct adapter *padapter); ++void update_capinfo(struct adapter *adapter, u16 updatecap); ++void update_wireless_mode(struct adapter *padapter); ++void update_tx_basic_rate(struct adapter *padapter, u8 modulation); ++void update_bmc_sta_support_rate(struct adapter *padapter, u32 mac_id); ++int update_sta_support_rate(struct adapter *padapter, u8 *pvar_ie, ++ uint var_ie_len, int cam_idx); ++ ++/* for sta/adhoc mode */ ++void update_sta_info(struct adapter *padapter, struct sta_info *psta); ++unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz); ++unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz); ++unsigned int update_MSC_rate(struct HT_caps_element *pHT_caps); ++void Update_RA_Entry(struct adapter *padapter, u32 mac_id); ++void set_sta_rate(struct adapter *padapter, struct sta_info *psta); ++ ++unsigned int receive_disconnect(struct adapter *padapter, ++ unsigned char *macaddr, unsigned short reason); ++ ++unsigned char get_highest_rate_idx(u32 mask); ++int support_short_GI(struct adapter *padapter, struct HT_caps_element *caps); ++unsigned int is_ap_in_tkip(struct adapter *padapter); ++unsigned int is_ap_in_wep(struct adapter *padapter); ++unsigned int should_forbid_n_rate(struct adapter *padapter); ++ ++void report_join_res(struct adapter *padapter, int res); ++void report_survey_event(struct adapter *padapter, struct recv_frame *precv_frame); ++void report_surveydone_event(struct adapter *padapter); ++void report_del_sta_event(struct adapter *padapter, ++ unsigned char *addr, unsigned short reason); ++void report_add_sta_event(struct adapter *padapter, unsigned char* addr, ++ int cam_idx); ++ ++void beacon_timing_control(struct adapter *padapter); ++extern u8 set_tx_beacon_cmd(struct adapter*padapter); ++unsigned int setup_beacon_frame(struct adapter *padapter, ++ unsigned char *beacon_frame); ++void update_mgnt_tx_rate(struct adapter *padapter, u8 rate); ++void update_mgntframe_attrib(struct adapter *padapter, ++ struct pkt_attrib *pattrib); ++void dump_mgntframe(struct adapter *padapter, struct xmit_frame *pmgntframe); ++s32 dump_mgntframe_and_wait(struct adapter *padapter, ++ struct xmit_frame *pmgntframe, int timeout_ms); ++s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, ++ struct xmit_frame *pmgntframe); ++ ++#ifdef CONFIG_88EU_P2P ++void issue_probersp_p2p(struct adapter *padapter, unsigned char *da); ++void issue_p2p_provision_request(struct adapter *padapter, u8 *pssid, ++ u8 ussidlen, u8 *pdev_raddr); ++void issue_p2p_GO_request(struct adapter *padapter, u8 *raddr); ++void issue_probereq_p2p(struct adapter *padapter, u8 *da); ++int issue_probereq_p2p_ex(struct adapter *adapter, u8 *da, int try_cnt, ++ int wait_ms); ++void issue_p2p_invitation_response(struct adapter *padapter, u8 *raddr, ++ u8 dialogToken, u8 success); ++void issue_p2p_invitation_request(struct adapter *padapter, u8* raddr); ++#endif /* CONFIG_88EU_P2P */ ++void issue_beacon(struct adapter *padapter, int timeout_ms); ++void issue_probersp(struct adapter *padapter, unsigned char *da, ++ u8 is_valid_p2p_probereq); ++void issue_assocreq(struct adapter *padapter); ++void issue_asocrsp(struct adapter *padapter, unsigned short status, ++ struct sta_info *pstat, int pkt_type); ++void issue_auth(struct adapter *padapter, struct sta_info *psta, ++ unsigned short status); ++void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, ++ u8 *da); ++s32 issue_probereq_ex(struct adapter *adapter, struct ndis_802_11_ssid *pssid, ++ u8* da, int try_cnt, int wait_ms); ++int issue_nulldata(struct adapter *padapter, unsigned char *da, ++ unsigned int power_mode, int try_cnt, int wait_ms); ++int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, ++ u16 tid, int try_cnt, int wait_ms); ++int issue_deauth(struct adapter *padapter, unsigned char *da, ++ unsigned short reason); ++int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason, ++ int try_cnt, int wait_ms); ++void issue_action_spct_ch_switch(struct adapter *padapter, u8 *ra, u8 new_ch, ++ u8 ch_offset); ++void issue_action_BA(struct adapter *padapter, unsigned char *raddr, ++ unsigned char action, unsigned short status); ++unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr); ++unsigned int send_beacon(struct adapter *padapter); ++ ++void start_clnt_assoc(struct adapter *padapter); ++void start_clnt_auth(struct adapter *padapter); ++void start_clnt_join(struct adapter *padapter); ++void start_create_ibss(struct adapter *padapter); ++ ++unsigned int OnAssocReq(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAssocRsp(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnProbeReq(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnProbeRsp(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int DoReserved(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnBeacon(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAtim(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnDisassoc(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAuth(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAuthClient(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnDeAuth(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAction(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++ ++unsigned int on_action_spct(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAction_qos(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAction_dls(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAction_back(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int on_action_public(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAction_ht(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAction_wmm(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAction_p2p(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++ ++void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res); ++void mlmeext_sta_del_event_callback(struct adapter *padapter); ++void mlmeext_sta_add_event_callback(struct adapter *padapter, ++ struct sta_info *psta); ++ ++void linked_status_chk(struct adapter *padapter); ++ ++void survey_timer_hdl (struct adapter *padapter); ++void link_timer_hdl (struct adapter *padapter); ++void addba_timer_hdl(struct sta_info *psta); ++ ++#define set_survey_timer(mlmeext, ms) \ ++ do { \ ++ _set_timer(&(mlmeext)->survey_timer, (ms)); \ ++ } while (0) ++ ++#define set_link_timer(mlmeext, ms) \ ++ do { \ ++ _set_timer(&(mlmeext)->link_timer, (ms)); \ ++ } while (0) ++ ++int cckrates_included(unsigned char *rate, int ratelen); ++int cckratesonly_included(unsigned char *rate, int ratelen); ++ ++void process_addba_req(struct adapter *padapter, u8 *paddba_req, u8 *addr); ++ ++void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len); ++void correct_TSF(struct adapter *padapter, struct mlme_ext_priv *pmlmeext); ++ ++struct cmd_hdl { ++ uint parmsize; ++ u8 (*h2cfuns)(struct adapter *padapter, u8 *pbuf); ++}; ++ ++u8 read_macreg_hdl(struct adapter *padapter, u8 *pbuf); ++u8 write_macreg_hdl(struct adapter *padapter, u8 *pbuf); ++u8 read_bbreg_hdl(struct adapter *padapter, u8 *pbuf); ++u8 write_bbreg_hdl(struct adapter *padapter, u8 *pbuf); ++u8 read_rfreg_hdl(struct adapter *padapter, u8 *pbuf); ++u8 write_rfreg_hdl(struct adapter *padapter, u8 *pbuf); ++u8 NULL_hdl(struct adapter *padapter, u8 *pbuf); ++u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf); ++u8 disconnect_hdl(struct adapter *padapter, u8 *pbuf); ++u8 createbss_hdl(struct adapter *padapter, u8 *pbuf); ++u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf); ++u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf); ++u8 setauth_hdl(struct adapter *padapter, u8 *pbuf); ++u8 setkey_hdl(struct adapter *padapter, u8 *pbuf); ++u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf); ++u8 set_assocsta_hdl(struct adapter *padapter, u8 *pbuf); ++u8 del_assocsta_hdl(struct adapter *padapter, u8 *pbuf); ++u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf); ++ ++u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf); ++u8 h2c_msg_hdl(struct adapter *padapter, unsigned char *pbuf); ++u8 tx_beacon_hdl(struct adapter *padapter, unsigned char *pbuf); ++u8 set_ch_hdl(struct adapter *padapter, u8 *pbuf); ++u8 set_chplan_hdl(struct adapter *padapter, unsigned char *pbuf); ++u8 led_blink_hdl(struct adapter *padapter, unsigned char *pbuf); ++/* Handling DFS channel switch announcement ie. */ ++u8 set_csa_hdl(struct adapter *padapter, unsigned char *pbuf); ++u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf); ++ ++#define GEN_DRV_CMD_HANDLER(size, cmd) {size, &cmd ## _hdl}, ++#define GEN_MLME_EXT_HANDLER(size, cmd) {size, cmd}, ++ ++#ifdef _RTW_CMD_C_ ++ ++static struct cmd_hdl wlancmds[] = { ++ GEN_DRV_CMD_HANDLER(0, NULL) /*0*/ ++ GEN_DRV_CMD_HANDLER(0, NULL) ++ GEN_DRV_CMD_HANDLER(0, NULL) ++ GEN_DRV_CMD_HANDLER(0, NULL) ++ GEN_DRV_CMD_HANDLER(0, NULL) ++ GEN_DRV_CMD_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) /*10*/ ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct joinbss_parm), join_cmd_hdl) /*14*/ ++ GEN_MLME_EXT_HANDLER(sizeof (struct disconnect_parm), disconnect_hdl) ++ GEN_MLME_EXT_HANDLER(sizeof (struct createbss_parm), createbss_hdl) ++ GEN_MLME_EXT_HANDLER(sizeof (struct setopmode_parm), setopmode_hdl) ++ GEN_MLME_EXT_HANDLER(sizeof (struct sitesurvey_parm), ++ sitesurvey_cmd_hdl) /*18*/ ++ GEN_MLME_EXT_HANDLER(sizeof (struct setauth_parm), setauth_hdl) ++ GEN_MLME_EXT_HANDLER(sizeof (struct setkey_parm), setkey_hdl) /*20*/ ++ GEN_MLME_EXT_HANDLER(sizeof (struct set_stakey_parm), set_stakey_hdl) ++ GEN_MLME_EXT_HANDLER(sizeof (struct set_assocsta_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct del_assocsta_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct setstapwrstate_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct setbasicrate_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct getbasicrate_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct setdatarate_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct getdatarate_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct setphyinfo_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct getphyinfo_parm), NULL) /*30*/ ++ GEN_MLME_EXT_HANDLER(sizeof (struct setphy_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct getphy_parm), NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) /*40*/ ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl) ++ GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), set_ch_hdl) /* 46 */ ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) /*50*/ ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(sizeof(struct Tx_Beacon_param), ++ tx_beacon_hdl) /*55*/ ++ ++ GEN_MLME_EXT_HANDLER(0, mlme_evt_hdl) /*56*/ ++ GEN_MLME_EXT_HANDLER(0, rtw_drvextra_cmd_hdl) /*57*/ ++ ++ GEN_MLME_EXT_HANDLER(0, h2c_msg_hdl) /*58*/ ++ GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param), ++ set_chplan_hdl) /*59*/ ++ GEN_MLME_EXT_HANDLER(sizeof(struct LedBlink_param), ++ led_blink_hdl) /*60*/ ++ ++ GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelSwitch_param), ++ set_csa_hdl) /*61*/ ++ GEN_MLME_EXT_HANDLER(sizeof(struct TDLSoption_param), ++ tdls_hdl) /*62*/ ++}; ++ ++#endif ++ ++struct C2HEvent_Header { ++#ifdef __LITTLE_ENDIAN ++ unsigned int len:16; ++ unsigned int ID:8; ++ unsigned int seq:8; ++#elif defined(__BIG_ENDIAN) ++ unsigned int seq:8; ++ unsigned int ID:8; ++ unsigned int len:16; ++#endif ++ unsigned int rsvd; ++}; ++ ++void rtw_dummy_event_callback(struct adapter *adapter, u8 *pbuf); ++void rtw_fwdbg_event_callback(struct adapter *adapter, u8 *pbuf); ++ ++enum rtw_c2h_event { ++ GEN_EVT_CODE(_Read_MACREG) = 0, /*0*/ ++ GEN_EVT_CODE(_Read_BBREG), ++ GEN_EVT_CODE(_Read_RFREG), ++ GEN_EVT_CODE(_Read_EEPROM), ++ GEN_EVT_CODE(_Read_EFUSE), ++ GEN_EVT_CODE(_Read_CAM), /*5*/ ++ GEN_EVT_CODE(_Get_BasicRate), ++ GEN_EVT_CODE(_Get_DataRate), ++ GEN_EVT_CODE(_Survey), /*8*/ ++ GEN_EVT_CODE(_SurveyDone), /*9*/ ++ ++ GEN_EVT_CODE(_JoinBss) , /*10*/ ++ GEN_EVT_CODE(_AddSTA), ++ GEN_EVT_CODE(_DelSTA), ++ GEN_EVT_CODE(_AtimDone), ++ GEN_EVT_CODE(_TX_Report), ++ GEN_EVT_CODE(_CCX_Report), /*15*/ ++ GEN_EVT_CODE(_DTM_Report), ++ GEN_EVT_CODE(_TX_Rate_Statistics), ++ GEN_EVT_CODE(_C2HLBK), ++ GEN_EVT_CODE(_FWDBG), ++ GEN_EVT_CODE(_C2HFEEDBACK), /*20*/ ++ GEN_EVT_CODE(_ADDBA), ++ GEN_EVT_CODE(_C2HBCN), ++ GEN_EVT_CODE(_ReportPwrState), /* filen: only for PCIE, USB */ ++ GEN_EVT_CODE(_CloseRF), /* filen: only for PCIE, ++ * work around ASPM */ ++ MAX_C2HEVT ++}; ++ ++#ifdef _RTW_MLME_EXT_C_ ++ ++static struct fwevent wlanevents[] = { ++ {0, rtw_dummy_event_callback}, /*0*/ ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++ {0, &rtw_survey_event_callback}, /*8*/ ++ {sizeof (struct surveydone_event), &rtw_surveydone_event_callback},/*9*/ ++ {0, &rtw_joinbss_event_callback}, /*10*/ ++ {sizeof(struct stassoc_event), &rtw_stassoc_event_callback}, ++ {sizeof(struct stadel_event), &rtw_stadel_event_callback}, ++ {0, NULL}, ++ {0, rtw_dummy_event_callback}, ++ {0, NULL}, /*15*/ ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++ {0, rtw_fwdbg_event_callback}, ++ {0, NULL}, /*20*/ ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++}; ++ ++#endif/* _RTL_MLME_EXT_C_ */ ++ ++#endif /* __RTW_MLME_EXT_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_mp.h b/drivers/staging/r8188eu/include/rtw_mp.h +new file mode 100644 +index 000000000000..3a259d991348 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_mp.h +@@ -0,0 +1,474 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_MP_H_ ++#define _RTW_MP_H_ ++ ++/* 00 - Success */ ++/* 11 - Error */ ++#define STATUS_SUCCESS (0x00000000L) ++#define STATUS_PENDING (0x00000103L) ++ ++#define STATUS_UNSUCCESSFUL (0xC0000001L) ++#define STATUS_INSUFFICIENT_RESOURCES (0xC000009AL) ++#define STATUS_NOT_SUPPORTED (0xC00000BBL) ++ ++#define NDIS_STATUS_SUCCESS ((int)STATUS_SUCCESS) ++#define NDIS_STATUS_PENDING ((int)STATUS_PENDING) ++#define NDIS_STATUS_NOT_RECOGNIZED ((int)0x00010001L) ++#define NDIS_STATUS_NOT_COPIED ((int)0x00010002L) ++#define NDIS_STATUS_NOT_ACCEPTED ((int)0x00010003L) ++#define NDIS_STATUS_CALL_ACTIVE ((int)0x00010007L) ++ ++#define NDIS_STATUS_FAILURE ((int)STATUS_UNSUCCESSFUL) ++#define NDIS_STATUS_RESOURCES ((int)STATUS_INSUFFICIENT_RESOURCES) ++#define NDIS_STATUS_CLOSING ((int)0xC0010002L) ++#define NDIS_STATUS_BAD_VERSION ((int)0xC0010004L) ++#define NDIS_STATUS_BAD_CHARACTERISTICS ((int)0xC0010005L) ++#define NDIS_STATUS_ADAPTER_NOT_FOUND ((int)0xC0010006L) ++#define NDIS_STATUS_OPEN_FAILED ((int)0xC0010007L) ++#define NDIS_STATUS_DEVICE_FAILED ((int)0xC0010008L) ++#define NDIS_STATUS_MULTICAST_FULL ((int)0xC0010009L) ++#define NDIS_STATUS_MULTICAST_EXISTS ((int)0xC001000AL) ++#define NDIS_STATUS_MULTICAST_NOT_FOUND ((int)0xC001000BL) ++#define NDIS_STATUS_REQUEST_ABORTED ((int)0xC001000CL) ++#define NDIS_STATUS_RESET_IN_PROGRESS ((int)0xC001000DL) ++#define NDIS_STATUS_CLOSING_INDICATING ((int)0xC001000EL) ++#define NDIS_STATUS_NOT_SUPPORTED ((int)STATUS_NOT_SUPPORTED) ++#define NDIS_STATUS_INVALID_PACKET ((int)0xC001000FL) ++#define NDIS_STATUS_OPEN_LIST_FULL ((int)0xC0010010L) ++#define NDIS_STATUS_ADAPTER_NOT_READY ((int)0xC0010011L) ++#define NDIS_STATUS_ADAPTER_NOT_OPEN ((int)0xC0010012L) ++#define NDIS_STATUS_NOT_INDICATING ((int)0xC0010013L) ++#define NDIS_STATUS_INVALID_LENGTH ((int)0xC0010014L) ++#define NDIS_STATUS_INVALID_DATA ((int)0xC0010015L) ++#define NDIS_STATUS_BUFFER_TOO_SHORT ((int)0xC0010016L) ++#define NDIS_STATUS_INVALID_OID ((int)0xC0010017L) ++#define NDIS_STATUS_ADAPTER_REMOVED ((int)0xC0010018L) ++#define NDIS_STATUS_UNSUPPORTED_MEDIA ((int)0xC0010019L) ++#define NDIS_STATUS_GROUP_ADDRESS_IN_USE ((int)0xC001001AL) ++#define NDIS_STATUS_FILE_NOT_FOUND ((int)0xC001001BL) ++#define NDIS_STATUS_ERROR_READING_FILE ((int)0xC001001CL) ++#define NDIS_STATUS_ALREADY_MAPPED ((int)0xC001001DL) ++#define NDIS_STATUS_RESOURCE_CONFLICT ((int)0xC001001EL) ++#define NDIS_STATUS_NO_CABLE ((int)0xC001001FL) ++ ++#define NDIS_STATUS_INVALID_SAP ((int)0xC0010020L) ++#define NDIS_STATUS_SAP_IN_USE ((int)0xC0010021L) ++#define NDIS_STATUS_INVALID_ADDRESS ((int)0xC0010022L) ++#define NDIS_STATUS_VC_NOT_ACTIVATED ((int)0xC0010023L) ++#define NDIS_STATUS_DEST_OUT_OF_ORDER ((int)0xC0010024L) /*cause 27*/ ++#define NDIS_STATUS_VC_NOT_AVAILABLE ((int)0xC0010025L) /*cause 35,45 */ ++#define NDIS_STATUS_CELLRATE_NOT_AVAILABLE ((int)0xC0010026L) /*cause 37*/ ++#define NDIS_STATUS_INCOMPATABLE_QOS ((int)0xC0010027L) /*cause 49*/ ++#define NDIS_STATUS_AAL_PARAMS_UNSUPPORTED ((int)0xC0010028L) /*cause 93*/ ++#define NDIS_STATUS_NO_ROUTE_TO_DESTINATION ((int)0xC0010029L) /*cause 3 */ ++ ++enum antenna_path { ++ ANTENNA_NONE = 0x00, ++ ANTENNA_D, ++ ANTENNA_C, ++ ANTENNA_CD, ++ ANTENNA_B, ++ ANTENNA_BD, ++ ANTENNA_BC, ++ ANTENNA_BCD, ++ ANTENNA_A, ++ ANTENNA_AD, ++ ANTENNA_AC, ++ ANTENNA_ACD, ++ ANTENNA_AB, ++ ANTENNA_ABD, ++ ANTENNA_ABC, ++ ANTENNA_ABCD ++}; ++ ++#define MAX_MP_XMITBUF_SZ 2048 ++#define NR_MP_XMITFRAME 8 ++ ++struct mp_xmit_frame { ++ struct list_head list; ++ struct pkt_attrib attrib; ++ struct sk_buff *pkt; ++ int frame_tag; ++ struct adapter *padapter; ++ struct urb *pxmit_urb[8]; ++ /* insert urb, irp, and irpcnt info below... */ ++ u8 *mem_addr; ++ u32 sz[8]; ++ u8 bpending[8]; ++ int ac_tag[8]; ++ int last[8]; ++ uint irpcnt; ++ uint fragcnt; ++ uint mem[(MAX_MP_XMITBUF_SZ >> 2)]; ++}; ++ ++struct mp_wiparam { ++ u32 bcompleted; ++ u32 act_type; ++ u32 io_offset; ++ u32 io_value; ++}; ++ ++typedef void(*wi_act_func)(void *padapter); ++ ++struct mp_tx { ++ u8 stop; ++ u32 count, sended; ++ u8 payload; ++ struct pkt_attrib attrib; ++ struct tx_desc desc; ++ u8 *pallocated_buf; ++ u8 *buf; ++ u32 buf_size, write_size; ++ void *PktTxThread; ++}; ++ ++#include "Hal8188EPhyCfg.h" ++ ++#define MP_MAX_LINES 1000 ++#define MP_MAX_LINES_BYTES 256 ++ ++typedef void (*MPT_WORK_ITEM_HANDLER)(void *Adapter); ++ ++struct mpt_context { ++ /* Indicate if we have started Mass Production Test. */ ++ bool bMassProdTest; ++ ++ /* Indicate if the driver is unloading or unloaded. */ ++ bool bMptDrvUnload; ++ ++ struct semaphore MPh2c_Sema; ++ struct timer_list MPh2c_timeout_timer; ++/* Event used to sync H2c for BT control */ ++ ++ bool MptH2cRspEvent; ++ bool MptBtC2hEvent; ++ bool bMPh2c_timeout; ++ ++ /* 8190 PCI does not support NDIS_WORK_ITEM. */ ++ /* Work Item for Mass Production Test. */ ++ /* Event used to sync the case unloading driver and MptWorkItem ++ * is still in progress. */ ++ /* Indicate a MptWorkItem is scheduled and not yet finished. */ ++ bool bMptWorkItemInProgress; ++ /* An instance which implements function and context of MptWorkItem. */ ++ MPT_WORK_ITEM_HANDLER CurrMptAct; ++ ++ /* 1=Start, 0=Stop from UI. */ ++ u32 MptTestStart; ++ /* _TEST_MODE, defined in MPT_Req2.h */ ++ u32 MptTestItem; ++ /* Variable needed in each implementation of CurrMptAct. */ ++ u32 MptActType; /* Type of action performed in CurrMptAct. */ ++ /* The Offset of IO operation is depend of MptActType. */ ++ u32 MptIoOffset; ++ /* The Value of IO operation is depend of MptActType. */ ++ u32 MptIoValue; ++ /* The RfPath of IO operation is depend of MptActType. */ ++ u32 MptRfPath; ++ ++ enum wireless_mode MptWirelessModeToSw; /* Wireless mode to switch. */ ++ u8 MptChannelToSw; /* Channel to switch. */ ++ u8 MptInitGainToSet; /* Initial gain to set. */ ++ u32 MptBandWidth; /* bandwidth to switch. */ ++ u32 MptRateIndex; /* rate index. */ ++ /* Register value kept for Single Carrier Tx test. */ ++ u8 btMpCckTxPower; ++ /* Register value kept for Single Carrier Tx test. */ ++ u8 btMpOfdmTxPower; ++ /* For MP Tx Power index */ ++ u8 TxPwrLevel[2]; /* rf-A, rf-B */ ++ ++ /* Content of RCR Regsiter for Mass Production Test. */ ++ u32 MptRCR; ++ /* true if we only receive packets with specific pattern. */ ++ bool bMptFilterPattern; ++ /* Rx OK count, statistics used in Mass Production Test. */ ++ u32 MptRxOkCnt; ++ /* Rx CRC32 error count, statistics used in Mass Production Test. */ ++ u32 MptRxCrcErrCnt; ++ ++ bool bCckContTx; /* true if we are in CCK Continuous Tx test. */ ++ bool bOfdmContTx; /* true if we are in OFDM Continuous Tx test. */ ++ bool bStartContTx; /* true if we have start Continuous Tx test. */ ++ /* true if we are in Single Carrier Tx test. */ ++ bool bSingleCarrier; ++ /* true if we are in Carrier Suppression Tx Test. */ ++ bool bCarrierSuppression; ++ /* true if we are in Single Tone Tx test. */ ++ bool bSingleTone; ++ ++ /* ACK counter asked by K.Y.. */ ++ bool bMptEnableAckCounter; ++ u32 MptAckCounter; ++ ++ u8 APK_bound[2]; /* for APK path A/path B */ ++ bool bMptIndexEven; ++ ++ u8 backup0xc50; ++ u8 backup0xc58; ++ u8 backup0xc30; ++ u8 backup0x52_RF_A; ++ u8 backup0x52_RF_B; ++ ++ u8 h2cReqNum; ++ u8 c2hBuf[20]; ++ ++ u8 btInBuf[100]; ++ u32 mptOutLen; ++ u8 mptOutBuf[100]; ++}; ++ ++enum { ++ WRITE_REG = 1, ++ READ_REG, ++ WRITE_RF, ++ READ_RF, ++ MP_START, ++ MP_STOP, ++ MP_RATE, ++ MP_CHANNEL, ++ MP_BANDWIDTH, ++ MP_TXPOWER, ++ MP_ANT_TX, ++ MP_ANT_RX, ++ MP_CTX, ++ MP_QUERY, ++ MP_ARX, ++ MP_PSD, ++ MP_PWRTRK, ++ MP_THER, ++ MP_IOCTL, ++ EFUSE_GET, ++ EFUSE_SET, ++ MP_RESET_STATS, ++ MP_DUMP, ++ MP_PHYPARA, ++ MP_SetRFPathSwh, ++ MP_QueryDrvStats, ++ MP_SetBT, ++ CTA_TEST, ++ MP_NULL, ++}; ++ ++struct mp_priv { ++ struct adapter *papdater; ++ ++ /* Testing Flag */ ++ /* 0 for normal type packet, 1 for loopback packet (16bytes TXCMD) */ ++ u32 mode; ++ ++ u32 prev_fw_state; ++ ++ /* OID cmd handler */ ++ struct mp_wiparam workparam; ++ ++ /* Tx Section */ ++ u8 TID; ++ u32 tx_pktcount; ++ struct mp_tx tx; ++ ++ /* Rx Section */ ++ u32 rx_pktcount; ++ u32 rx_crcerrpktcount; ++ u32 rx_pktloss; ++ ++ struct recv_stat rxstat; ++ ++ /* RF/BB relative */ ++ u8 channel; ++ u8 bandwidth; ++ u8 prime_channel_offset; ++ u8 txpoweridx; ++ u8 txpoweridx_b; ++ u8 rateidx; ++ u32 preamble; ++ u32 CrystalCap; ++ ++ u16 antenna_tx; ++ u16 antenna_rx; ++ ++ u8 check_mp_pkt; ++ ++ u8 bSetTxPower; ++ ++ struct wlan_network mp_network; ++ unsigned char network_macaddr[ETH_ALEN]; ++ ++ u8 *pallocated_mp_xmitframe_buf; ++ u8 *pmp_xmtframe_buf; ++ struct __queue free_mp_xmitqueue; ++ u32 free_mp_xmitframe_cnt; ++ ++ struct mpt_context MptCtx; ++}; ++ ++struct iocmd_struct { ++ u8 cmdclass; ++ u16 value; ++ u8 index; ++}; ++ ++struct rf_reg_param { ++ u32 path; ++ u32 offset; ++ u32 value; ++}; ++ ++struct bb_reg_param { ++ u32 offset; ++ u32 value; ++}; ++/* */ ++ ++#define LOWER true ++#define RAISE false ++ ++/* Hardware Registers */ ++#define BB_REG_BASE_ADDR 0x800 ++ ++/* MP variables */ ++enum mp_mode_{ ++ MP_OFF, ++ MP_ON, ++ MP_ERR, ++ MP_CONTINUOUS_TX, ++ MP_SINGLE_CARRIER_TX, ++ MP_CARRIER_SUPPRISSION_TX, ++ MP_SINGLE_TONE_TX, ++ MP_PACKET_TX, ++ MP_PACKET_RX ++}; ++ ++extern u8 mpdatarate[NumRates]; ++ ++/* MP set force data rate base on the definition. */ ++enum mpt_rate_index { ++ /* CCK rate. */ ++ MPT_RATE_1M, /* 0 */ ++ MPT_RATE_2M, ++ MPT_RATE_55M, ++ MPT_RATE_11M, /* 3 */ ++ ++ /* OFDM rate. */ ++ MPT_RATE_6M, /* 4 */ ++ MPT_RATE_9M, ++ MPT_RATE_12M, ++ MPT_RATE_18M, ++ MPT_RATE_24M, ++ MPT_RATE_36M, ++ MPT_RATE_48M, ++ MPT_RATE_54M, /* 11 */ ++ ++ /* HT rate. */ ++ MPT_RATE_MCS0, /* 12 */ ++ MPT_RATE_MCS1, ++ MPT_RATE_MCS2, ++ MPT_RATE_MCS3, ++ MPT_RATE_MCS4, ++ MPT_RATE_MCS5, ++ MPT_RATE_MCS6, ++ MPT_RATE_MCS7, /* 19 */ ++ MPT_RATE_MCS8, ++ MPT_RATE_MCS9, ++ MPT_RATE_MCS10, ++ MPT_RATE_MCS11, ++ MPT_RATE_MCS12, ++ MPT_RATE_MCS13, ++ MPT_RATE_MCS14, ++ MPT_RATE_MCS15, /* 27 */ ++ MPT_RATE_LAST ++}; ++ ++#define MAX_TX_PWR_INDEX_N_MODE 64 /* 0x3F */ ++ ++enum power_mode { ++ POWER_LOW = 0, ++ POWER_NORMAL ++}; ++ ++#define RX_PKT_BROADCAST 1 ++#define RX_PKT_DEST_ADDR 2 ++#define RX_PKT_PHY_MATCH 3 ++ ++enum encry_ctrl_state { ++ HW_CONTROL, /* hw encryption& decryption */ ++ SW_CONTROL, /* sw encryption& decryption */ ++ HW_ENCRY_SW_DECRY, /* hw encryption & sw decryption */ ++ SW_ENCRY_HW_DECRY /* sw encryption & hw decryption */ ++}; ++ ++s32 init_mp_priv(struct adapter *padapter); ++void free_mp_priv(struct mp_priv *pmp_priv); ++s32 MPT_InitializeAdapter(struct adapter *padapter, u8 Channel); ++void MPT_DeInitAdapter(struct adapter *padapter); ++s32 mp_start_test(struct adapter *padapter); ++void mp_stop_test(struct adapter *padapter); ++ ++u32 _read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask); ++void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val); ++ ++u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask); ++void write_bbreg(struct adapter *padapter, u32 addr, u32 bitmask, u32 val); ++u32 read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr); ++void write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 val); ++ ++void SetChannel(struct adapter *pAdapter); ++void SetBandwidth(struct adapter *pAdapter); ++void SetTxPower(struct adapter *pAdapter); ++void SetAntennaPathPower(struct adapter *pAdapter); ++void SetDataRate(struct adapter *pAdapter); ++ ++void SetAntenna(struct adapter *pAdapter); ++ ++s32 SetThermalMeter(struct adapter *pAdapter, u8 target_ther); ++void GetThermalMeter(struct adapter *pAdapter, u8 *value); ++ ++void SetContinuousTx(struct adapter *pAdapter, u8 bStart); ++void SetSingleCarrierTx(struct adapter *pAdapter, u8 bStart); ++void SetSingleToneTx(struct adapter *pAdapter, u8 bStart); ++void SetCarrierSuppressionTx(struct adapter *pAdapter, u8 bStart); ++void PhySetTxPowerLevel(struct adapter *pAdapter); ++ ++void fill_txdesc_for_mp(struct adapter *padapter, struct tx_desc *ptxdesc); ++void SetPacketTx(struct adapter *padapter); ++void SetPacketRx(struct adapter *pAdapter, u8 bStartRx); ++ ++void ResetPhyRxPktCount(struct adapter *pAdapter); ++u32 GetPhyRxPktReceived(struct adapter *pAdapter); ++u32 GetPhyRxPktCRC32Error(struct adapter *pAdapter); ++ ++s32 SetPowerTracking(struct adapter *padapter, u8 enable); ++void GetPowerTracking(struct adapter *padapter, u8 *enable); ++u32 mp_query_psd(struct adapter *pAdapter, u8 *data); ++void Hal_SetAntenna(struct adapter *pAdapter); ++void Hal_SetBandwidth(struct adapter *pAdapter); ++void Hal_SetTxPower(struct adapter *pAdapter); ++void Hal_SetCarrierSuppressionTx(struct adapter *pAdapter, u8 bStart); ++void Hal_SetSingleToneTx(struct adapter *pAdapter, u8 bStart); ++void Hal_SetSingleCarrierTx (struct adapter *pAdapter, u8 bStart); ++void Hal_SetContinuousTx (struct adapter *pAdapter, u8 bStart); ++void Hal_SetBandwidth(struct adapter *pAdapter); ++void Hal_SetDataRate(struct adapter *pAdapter); ++void Hal_SetChannel(struct adapter *pAdapter); ++void Hal_SetAntennaPathPower(struct adapter *pAdapter); ++s32 Hal_SetThermalMeter(struct adapter *pAdapter, u8 target_ther); ++s32 Hal_SetPowerTracking(struct adapter *padapter, u8 enable); ++void Hal_GetPowerTracking(struct adapter *padapter, u8 * enable); ++void Hal_GetThermalMeter(struct adapter *pAdapter, u8 *value); ++void Hal_mpt_SwitchRfSetting(struct adapter *pAdapter); ++void Hal_MPT_CCKTxPowerAdjust(struct adapter * Adapter, bool bInCH14); ++void Hal_MPT_CCKTxPowerAdjustbyIndex(struct adapter *pAdapter, bool beven); ++void Hal_SetCCKTxPower(struct adapter *pAdapter, u8 * TxPower); ++void Hal_SetOFDMTxPower(struct adapter *pAdapter, u8 * TxPower); ++void Hal_TriggerRFThermalMeter(struct adapter *pAdapter); ++u8 Hal_ReadRFThermalMeter(struct adapter *pAdapter); ++void Hal_SetCCKContinuousTx(struct adapter *pAdapter, u8 bStart); ++void Hal_SetOFDMContinuousTx(struct adapter *pAdapter, u8 bStart); ++void Hal_ProSetCrystalCap (struct adapter *pAdapter , u32 CrystalCapVal); ++void _rtw_mp_xmit_priv(struct xmit_priv *pxmitpriv); ++void MP_PHY_SetRFPathSwitch(struct adapter *pAdapter ,bool bMain); ++ ++#endif /* _RTW_MP_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_mp_ioctl.h b/drivers/staging/r8188eu/include/rtw_mp_ioctl.h +new file mode 100644 +index 000000000000..cf99f39a582e +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_mp_ioctl.h +@@ -0,0 +1,242 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_MP_IOCTL_H_ ++#define _RTW_MP_IOCTL_H_ ++ ++#include "drv_types.h" ++#include "mp_custom_oid.h" ++#include "rtw_ioctl.h" ++#include "rtw_ioctl_rtl.h" ++#include "rtw_efuse.h" ++#include "rtw_mp.h" ++ ++struct cfg_dbg_msg_struct { ++ u32 DebugLevel; ++ u32 DebugComponent_H32; ++ u32 DebugComponent_L32; ++}; ++ ++struct mp_rw_reg { ++ u32 offset; ++ u32 width; ++ u32 value; ++}; ++ ++struct efuse_access_struct { ++ u16 start_addr; ++ u16 cnts; ++ u8 data[0]; ++}; ++ ++struct burst_rw_reg { ++ u32 offset; ++ u32 len; ++ u8 Data[256]; ++}; ++ ++struct usb_vendor_req { ++ u8 bRequest; ++ u16 wValue; ++ u16 wIndex; ++ u16 wLength; ++ u8 u8Dir;/* 0:OUT, 1:IN */ ++ u8 u8InData; ++}; ++ ++struct dr_variable_struct { ++ u8 offset; ++ u32 variable; ++}; ++ ++#define _irqlevel_changed_(a, b) ++ ++int rtl8188eu_oid_rt_pro_set_data_rate_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_tx_power_control_hdl(struct oid_par_priv *poid_par_priv); ++ ++int rtl8188eu_oid_rt_pro_query_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_query_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_query_rx_packet_crc32_error_hdl(struct oid_par_priv *par_priv); ++int rtl8188eu_oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv *par_priv); ++int rtl8188eu_oid_rt_pro_set_modulation_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv *par_priv); ++int rtl8188eu_oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv *poid_par_priv); ++ ++/* rtl8188eu_oid_rtl_seg_81_87 */ ++int rtl8188eu_oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv); ++ ++int rtl8188eu_oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv); ++ ++/* rtl8188eu_oid_rtl_seg_87_11_00 */ ++int rtl8188eu_oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_burst_read_register_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_burst_write_register_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_write16_eeprom_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_wr_attrib_mem_hdl (struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv); ++/* rtl8188eu_oid_rtl_seg_87_11_20 */ ++int rtl8188eu_oid_rt_pro_cfg_debug_message_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_data_rate_ex_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_basic_rate_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_read_tssi_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_power_tracking_hdl(struct oid_par_priv *poid_par_priv); ++/* rtl8188eu_oid_rtl_seg_87_11_50 */ ++int rtl8188eu_oid_rt_pro_qry_pwrstate_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_pwrstate_hdl(struct oid_par_priv *poid_par_priv); ++/* rtl8188eu_oid_rtl_seg_87_11_F0 */ ++int rtl8188eu_oid_rt_pro_h2c_set_rate_table_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_h2c_get_rate_table_hdl(struct oid_par_priv *poid_par_priv); ++ ++/* rtl8188eu_oid_rtl_seg_87_12_00 */ ++int rtl8188eu_oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_query_dr_variable_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_get_efuse_current_size_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_tx_agc_offset_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_pkt_test_mode_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv *par_priv); ++int rtl8188eu_oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_get_power_mode_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_trigger_gpio_hdl(struct oid_par_priv *poid_par_priv); ++ ++struct rwreg_param { ++ u32 offset; ++ u32 width; ++ u32 value; ++}; ++ ++struct bbreg_param { ++ u32 offset; ++ u32 phymask; ++ u32 value; ++}; ++ ++struct txpower_param { ++ u32 pwr_index; ++}; ++ ++struct datarate_param { ++ u32 rate_index; ++}; ++ ++struct rfintfs_parm { ++ u32 rfintfs; ++}; ++ ++struct mp_xmit_parm { ++ u8 enable; ++ u32 count; ++ u16 length; ++ u8 payload_type; ++ u8 da[ETH_ALEN]; ++}; ++ ++struct mp_xmit_packet { ++ u32 len; ++ u32 mem[MAX_MP_XMITBUF_SZ >> 2]; ++}; ++ ++struct psmode_param { ++ u32 ps_mode; ++ u32 smart_ps; ++}; ++ ++/* for OID_RT_PRO_READ16_EEPROM & OID_RT_PRO_WRITE16_EEPROM */ ++struct eeprom_rw_param { ++ u32 offset; ++ u16 value; ++}; ++ ++struct mp_ioctl_handler { ++ u32 paramsize; ++ s32 (*handler)(struct oid_par_priv* poid_par_priv); ++ u32 oid; ++}; ++ ++struct mp_ioctl_param{ ++ u32 subcode; ++ u32 len; ++ u8 data[0]; ++}; ++ ++#define GEN_MP_IOCTL_SUBCODE(code) _MP_IOCTL_ ## code ## _CMD_ ++ ++enum RTL871X_MP_IOCTL_SUBCODE { ++ GEN_MP_IOCTL_SUBCODE(MP_START), /*0*/ ++ GEN_MP_IOCTL_SUBCODE(MP_STOP), ++ GEN_MP_IOCTL_SUBCODE(READ_REG), ++ GEN_MP_IOCTL_SUBCODE(WRITE_REG), ++ GEN_MP_IOCTL_SUBCODE(READ_BB_REG), ++ GEN_MP_IOCTL_SUBCODE(WRITE_BB_REG), /*5*/ ++ GEN_MP_IOCTL_SUBCODE(READ_RF_REG), ++ GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG), ++ GEN_MP_IOCTL_SUBCODE(SET_CHANNEL), ++ GEN_MP_IOCTL_SUBCODE(SET_TXPOWER), ++ GEN_MP_IOCTL_SUBCODE(SET_DATARATE), /*10*/ ++ GEN_MP_IOCTL_SUBCODE(SET_BANDWIDTH), ++ GEN_MP_IOCTL_SUBCODE(SET_ANTENNA), ++ GEN_MP_IOCTL_SUBCODE(CNTU_TX), ++ GEN_MP_IOCTL_SUBCODE(SC_TX), ++ GEN_MP_IOCTL_SUBCODE(CS_TX), /*15*/ ++ GEN_MP_IOCTL_SUBCODE(ST_TX), ++ GEN_MP_IOCTL_SUBCODE(IOCTL_XMIT_PACKET), ++ GEN_MP_IOCTL_SUBCODE(SET_RX_PKT_TYPE), ++ GEN_MP_IOCTL_SUBCODE(RESET_PHY_RX_PKT_CNT), ++ GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_RECV), /*20*/ ++ GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_ERROR), ++ GEN_MP_IOCTL_SUBCODE(READ16_EEPROM), ++ GEN_MP_IOCTL_SUBCODE(WRITE16_EEPROM), ++ GEN_MP_IOCTL_SUBCODE(EFUSE), ++ GEN_MP_IOCTL_SUBCODE(EFUSE_MAP), /*25*/ ++ GEN_MP_IOCTL_SUBCODE(GET_EFUSE_MAX_SIZE), ++ GEN_MP_IOCTL_SUBCODE(GET_EFUSE_CURRENT_SIZE), ++ GEN_MP_IOCTL_SUBCODE(GET_THERMAL_METER), ++ GEN_MP_IOCTL_SUBCODE(SET_PTM), ++ GEN_MP_IOCTL_SUBCODE(SET_POWER_DOWN), /*30*/ ++ GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO), ++ GEN_MP_IOCTL_SUBCODE(SET_DM_BT), /*35*/ ++ GEN_MP_IOCTL_SUBCODE(DEL_BA), /*36*/ ++ GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS), /*37*/ ++ MAX_MP_IOCTL_SUBCODE, ++}; ++ ++s32 rtl8188eu_mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv); ++ ++#define GEN_HANDLER(sz, hdl, oid) {sz, hdl, oid}, ++ ++#define EXT_MP_IOCTL_HANDLER(sz, subcode, oid) \ ++ {sz, rtl8188eu_mp_ioctl_##subcode##_hdl, oid}, ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_mp_phy_regdef.h b/drivers/staging/r8188eu/include/rtw_mp_phy_regdef.h +new file mode 100644 +index 000000000000..c2be770a5f5d +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_mp_phy_regdef.h +@@ -0,0 +1,1063 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++/***************************************************************************** ++ * ++ * Module: __RTW_MP_PHY_REGDEF_H_ ++ * ++ * ++ * Note: 1. Define PMAC/BB register map ++ * 2. Define RF register map ++ * 3. PMAC/BB register bit mask. ++ * 4. RF reg bit mask. ++ * 5. Other BB/RF relative definition. ++ * ++ * ++ * Export: Constants, macro, functions(API), global variables(None). ++ * ++ * Abbrev: ++ * ++ * History: ++ * Data Who Remark ++ * 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h. ++ * 2. Reorganize code architecture. ++ * 09/25/2008 MH 1. Add RL6052 register definition ++ * ++ *****************************************************************************/ ++#ifndef __RTW_MP_PHY_REGDEF_H_ ++#define __RTW_MP_PHY_REGDEF_H_ ++ ++/*--------------------------Define Parameters-------------------------------*/ ++ ++/* */ ++/* 8192S Regsiter offset definition */ ++/* */ ++ ++/* */ ++/* BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF */ ++/* 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF */ ++/* 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 */ ++/* 3. RF register 0x00-2E */ ++/* 4. Bit Mask for BB/RF register */ ++/* 5. Other definition for BB/RF R/W */ ++/* */ ++ ++/* */ ++/* 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF */ ++/* 1. Page1(0x100) */ ++/* */ ++#define rPMAC_Reset 0x100 ++#define rPMAC_TxStart 0x104 ++#define rPMAC_TxLegacySIG 0x108 ++#define rPMAC_TxHTSIG1 0x10c ++#define rPMAC_TxHTSIG2 0x110 ++#define rPMAC_PHYDebug 0x114 ++#define rPMAC_TxPacketNum 0x118 ++#define rPMAC_TxIdle 0x11c ++#define rPMAC_TxMACHeader0 0x120 ++#define rPMAC_TxMACHeader1 0x124 ++#define rPMAC_TxMACHeader2 0x128 ++#define rPMAC_TxMACHeader3 0x12c ++#define rPMAC_TxMACHeader4 0x130 ++#define rPMAC_TxMACHeader5 0x134 ++#define rPMAC_TxDataType 0x138 ++#define rPMAC_TxRandomSeed 0x13c ++#define rPMAC_CCKPLCPPreamble 0x140 ++#define rPMAC_CCKPLCPHeader 0x144 ++#define rPMAC_CCKCRC16 0x148 ++#define rPMAC_OFDMRxCRC32OK 0x170 ++#define rPMAC_OFDMRxCRC32Er 0x174 ++#define rPMAC_OFDMRxParityEr 0x178 ++#define rPMAC_OFDMRxCRC8Er 0x17c ++#define rPMAC_CCKCRxRC16Er 0x180 ++#define rPMAC_CCKCRxRC32Er 0x184 ++#define rPMAC_CCKCRxRC32OK 0x188 ++#define rPMAC_TxStatus 0x18c ++ ++/* */ ++/* 2. Page2(0x200) */ ++/* */ ++/* The following two definition are only used for USB interface. */ ++/* define RF_BB_CMD_ADDR 0x02c0 RF/BB read/write command address. */ ++/* define RF_BB_CMD_DATA 0x02c4 RF/BB read/write command data. */ ++ ++/* */ ++/* 3. Page8(0x800) */ ++/* */ ++#define rFPGA0_RFMOD 0x800 /* RF mode & CCK TxSC RF BW Setting?? */ ++ ++#define rFPGA0_TxInfo 0x804 /* Status report?? */ ++#define rFPGA0_PSDFunction 0x808 ++ ++#define rFPGA0_TxGainStage 0x80c /* Set TX PWR init gain? */ ++ ++#define rFPGA0_RFTiming1 0x810 /* Useless now */ ++#define rFPGA0_RFTiming2 0x814 ++/* define rFPGA0_XC_RFTiming 0x818 */ ++/* define rFPGA0_XD_RFTiming 0x81c */ ++ ++#define rFPGA0_XA_HSSIParameter1 0x820 /* RF 3 wire register */ ++#define rFPGA0_XA_HSSIParameter2 0x824 ++#define rFPGA0_XB_HSSIParameter1 0x828 ++#define rFPGA0_XB_HSSIParameter2 0x82c ++#define rFPGA0_XC_HSSIParameter1 0x830 ++#define rFPGA0_XC_HSSIParameter2 0x834 ++#define rFPGA0_XD_HSSIParameter1 0x838 ++#define rFPGA0_XD_HSSIParameter2 0x83c ++#define rFPGA0_XA_LSSIParameter 0x840 ++#define rFPGA0_XB_LSSIParameter 0x844 ++#define rFPGA0_XC_LSSIParameter 0x848 ++#define rFPGA0_XD_LSSIParameter 0x84c ++ ++#define rFPGA0_RFWakeUpParameter 0x850 /* Useless now */ ++#define rFPGA0_RFSleepUpParameter 0x854 ++ ++#define rFPGA0_XAB_SwitchControl 0x858 /* RF Channel switch */ ++#define rFPGA0_XCD_SwitchControl 0x85c ++ ++#define rFPGA0_XA_RFInterfaceOE 0x860 /* RF Channel switch */ ++#define rFPGA0_XB_RFInterfaceOE 0x864 ++#define rFPGA0_XC_RFInterfaceOE 0x868 ++#define rFPGA0_XD_RFInterfaceOE 0x86c ++ ++#define rFPGA0_XAB_RFInterfaceSW 0x870 /* RF Interface Software Control */ ++#define rFPGA0_XCD_RFInterfaceSW 0x874 ++ ++#define rFPGA0_XAB_RFParameter 0x878 /* RF Parameter */ ++#define rFPGA0_XCD_RFParameter 0x87c ++ ++#define rFPGA0_AnalogParameter1 0x880 /* Crystal cap setting RF-R/W protection for parameter4?? */ ++#define rFPGA0_AnalogParameter2 0x884 ++#define rFPGA0_AnalogParameter3 0x888 /* Useless now */ ++#define rFPGA0_AnalogParameter4 0x88c ++ ++#define rFPGA0_XA_LSSIReadBack 0x8a0 /* Tranceiver LSSI Readback */ ++#define rFPGA0_XB_LSSIReadBack 0x8a4 ++#define rFPGA0_XC_LSSIReadBack 0x8a8 ++#define rFPGA0_XD_LSSIReadBack 0x8ac ++ ++#define rFPGA0_PSDReport 0x8b4 /* Useless now */ ++#define rFPGA0_XAB_RFInterfaceRB 0x8e0 /* Useless now RF Interface Readback Value */ ++#define rFPGA0_XCD_RFInterfaceRB 0x8e4 /* Useless now */ ++ ++/* */ ++/* 4. Page9(0x900) */ ++/* */ ++#define rFPGA1_RFMOD 0x900 /* RF mode & OFDM TxSC RF BW Setting?? */ ++ ++#define rFPGA1_TxBlock 0x904 /* Useless now */ ++#define rFPGA1_DebugSelect 0x908 /* Useless now */ ++#define rFPGA1_TxInfo 0x90c /* Useless now Status report?? */ ++ ++/* */ ++/* 5. PageA(0xA00) */ ++/* */ ++/* Set Control channel to upper or lower. These settings are required only for 40MHz */ ++#define rCCK0_System 0xa00 ++ ++#define rCCK0_AFESetting 0xa04 /* Disable init gain now Select RX path by RSSI */ ++#define rCCK0_CCA 0xa08 /* Disable init gain now Init gain */ ++ ++#define rCCK0_RxAGC1 0xa0c /* AGC default value, saturation level Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. Not the same as 90 series */ ++#define rCCK0_RxAGC2 0xa10 /* AGC & DAGC */ ++ ++#define rCCK0_RxHP 0xa14 ++ ++#define rCCK0_DSPParameter1 0xa18 /* Timing recovery & Channel estimation threshold */ ++#define rCCK0_DSPParameter2 0xa1c /* SQ threshold */ ++ ++#define rCCK0_TxFilter1 0xa20 ++#define rCCK0_TxFilter2 0xa24 ++#define rCCK0_DebugPort 0xa28 /* debug port and Tx filter3 */ ++#define rCCK0_FalseAlarmReport 0xa2c /* 0xa2d useless now 0xa30-a4f channel report */ ++#define rCCK0_TRSSIReport 0xa50 ++#define rCCK0_RxReport 0xa54 /* 0xa57 */ ++#define rCCK0_FACounterLower 0xa5c /* 0xa5b */ ++#define rCCK0_FACounterUpper 0xa58 /* 0xa5c */ ++ ++/* */ ++/* 6. PageC(0xC00) */ ++/* */ ++#define rOFDM0_LSTF 0xc00 ++ ++#define rOFDM0_TRxPathEnable 0xc04 ++#define rOFDM0_TRMuxPar 0xc08 ++#define rOFDM0_TRSWIsolation 0xc0c ++ ++#define rOFDM0_XARxAFE 0xc10 /* RxIQ DC offset, Rx digital filter, DC notch filter */ ++#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imblance matrix */ ++#define rOFDM0_XBRxAFE 0xc18 ++#define rOFDM0_XBRxIQImbalance 0xc1c ++#define rOFDM0_XCRxAFE 0xc20 ++#define rOFDM0_XCRxIQImbalance 0xc24 ++#define rOFDM0_XDRxAFE 0xc28 ++#define rOFDM0_XDRxIQImbalance 0xc2c ++ ++#define rOFDM0_RxDetector1 0xc30 /* PD,BW & SBD DM tune init gain */ ++#define rOFDM0_RxDetector2 0xc34 /* SBD & Fame Sync. */ ++#define rOFDM0_RxDetector3 0xc38 /* Frame Sync. */ ++#define rOFDM0_RxDetector4 0xc3c /* PD, SBD, Frame Sync & Short-GI */ ++ ++#define rOFDM0_RxDSP 0xc40 /* Rx Sync Path */ ++#define rOFDM0_CFOandDAGC 0xc44 /* CFO & DAGC */ ++#define rOFDM0_CCADropThreshold 0xc48 /* CCA Drop threshold */ ++#define rOFDM0_ECCAThreshold 0xc4c /* energy CCA */ ++ ++#define rOFDM0_XAAGCCore1 0xc50 /* DIG */ ++#define rOFDM0_XAAGCCore2 0xc54 ++#define rOFDM0_XBAGCCore1 0xc58 ++#define rOFDM0_XBAGCCore2 0xc5c ++#define rOFDM0_XCAGCCore1 0xc60 ++#define rOFDM0_XCAGCCore2 0xc64 ++#define rOFDM0_XDAGCCore1 0xc68 ++#define rOFDM0_XDAGCCore2 0xc6c ++ ++#define rOFDM0_AGCParameter1 0xc70 ++#define rOFDM0_AGCParameter2 0xc74 ++#define rOFDM0_AGCRSSITable 0xc78 ++#define rOFDM0_HTSTFAGC 0xc7c ++ ++#define rOFDM0_XATxIQImbalance 0xc80 /* TX PWR TRACK and DIG */ ++#define rOFDM0_XATxAFE 0xc84 ++#define rOFDM0_XBTxIQImbalance 0xc88 ++#define rOFDM0_XBTxAFE 0xc8c ++#define rOFDM0_XCTxIQImbalance 0xc90 ++#define rOFDM0_XCTxAFE 0xc94 ++#define rOFDM0_XDTxIQImbalance 0xc98 ++#define rOFDM0_XDTxAFE 0xc9c ++#define rOFDM0_RxIQExtAnta 0xca0 ++ ++#define rOFDM0_RxHPParameter 0xce0 ++#define rOFDM0_TxPseudoNoiseWgt 0xce4 ++#define rOFDM0_FrameSync 0xcf0 ++#define rOFDM0_DFSReport 0xcf4 ++#define rOFDM0_TxCoeff1 0xca4 ++#define rOFDM0_TxCoeff2 0xca8 ++#define rOFDM0_TxCoeff3 0xcac ++#define rOFDM0_TxCoeff4 0xcb0 ++#define rOFDM0_TxCoeff5 0xcb4 ++#define rOFDM0_TxCoeff6 0xcb8 ++ ++/* 7. PageD(0xD00) */ ++#define rOFDM1_LSTF 0xd00 ++#define rOFDM1_TRxPathEnable 0xd04 ++ ++#define rOFDM1_CFO 0xd08 /* No setting now */ ++#define rOFDM1_CSI1 0xd10 ++#define rOFDM1_SBD 0xd14 ++#define rOFDM1_CSI2 0xd18 ++#define rOFDM1_CFOTracking 0xd2c ++#define rOFDM1_TRxMesaure1 0xd34 ++#define rOFDM1_IntfDet 0xd3c ++#define rOFDM1_PseudoNoiseStateAB 0xd50 ++#define rOFDM1_PseudoNoiseStateCD 0xd54 ++#define rOFDM1_RxPseudoNoiseWgt 0xd58 ++ ++#define rOFDM_PHYCounter1 0xda0 /* cca, parity fail */ ++#define rOFDM_PHYCounter2 0xda4 /* rate illegal, crc8 fail */ ++#define rOFDM_PHYCounter3 0xda8 /* MCS not support */ ++ ++#define rOFDM_ShortCFOAB 0xdac /* No setting now */ ++#define rOFDM_ShortCFOCD 0xdb0 ++#define rOFDM_LongCFOAB 0xdb4 ++#define rOFDM_LongCFOCD 0xdb8 ++#define rOFDM_TailCFOAB 0xdbc ++#define rOFDM_TailCFOCD 0xdc0 ++#define rOFDM_PWMeasure1 0xdc4 ++#define rOFDM_PWMeasure2 0xdc8 ++#define rOFDM_BWReport 0xdcc ++#define rOFDM_AGCReport 0xdd0 ++#define rOFDM_RxSNR 0xdd4 ++#define rOFDM_RxEVMCSI 0xdd8 ++#define rOFDM_SIGReport 0xddc ++ ++/* */ ++/* 8. PageE(0xE00) */ ++/* */ ++#define rTxAGC_Rate18_06 0xe00 ++#define rTxAGC_Rate54_24 0xe04 ++#define rTxAGC_CCK_Mcs32 0xe08 ++#define rTxAGC_Mcs03_Mcs00 0xe10 ++#define rTxAGC_Mcs07_Mcs04 0xe14 ++#define rTxAGC_Mcs11_Mcs08 0xe18 ++#define rTxAGC_Mcs15_Mcs12 0xe1c ++ ++/* Analog- control in RX_WAIT_CCA : REG: EE0 [Analog- Power & Control Register] */ ++#define rRx_Wait_CCCA 0xe70 ++#define rAnapar_Ctrl_BB 0xee0 ++ ++/* */ ++/* 7. RF Register 0x00-0x2E (RF 8256) */ ++/* RF-0222D 0x00-3F */ ++/* */ ++/* Zebra1 */ ++#define RTL92SE_FPGA_VERIFY 0 ++#define rZebra1_HSSIEnable 0x0 /* Useless now */ ++#define rZebra1_TRxEnable1 0x1 ++#define rZebra1_TRxEnable2 0x2 ++#define rZebra1_AGC 0x4 ++#define rZebra1_ChargePump 0x5 ++/* if (RTL92SE_FPGA_VERIFY == 1) */ ++#define rZebra1_Channel 0x7 /* RF channel switch */ ++/* else */ ++ ++/* endif */ ++#define rZebra1_TxGain 0x8 /* Useless now */ ++#define rZebra1_TxLPF 0x9 ++#define rZebra1_RxLPF 0xb ++#define rZebra1_RxHPFCorner 0xc ++ ++/* Zebra4 */ ++#define rGlobalCtrl 0 /* Useless now */ ++#define rRTL8256_TxLPF 19 ++#define rRTL8256_RxLPF 11 ++ ++/* RTL8258 */ ++#define rRTL8258_TxLPF 0x11 /* Useless now */ ++#define rRTL8258_RxLPF 0x13 ++#define rRTL8258_RSSILPF 0xa ++ ++/* */ ++/* RL6052 Register definition */ ++#define RF_AC 0x00 /* */ ++ ++#define RF_IQADJ_G1 0x01 /* */ ++#define RF_IQADJ_G2 0x02 /* */ ++#define RF_POW_TRSW 0x05 /* */ ++ ++#define RF_GAIN_RX 0x06 /* */ ++#define RF_GAIN_TX 0x07 /* */ ++ ++#define RF_TXM_IDAC 0x08 /* */ ++#define RF_BS_IQGEN 0x0F /* */ ++ ++#define RF_MODE1 0x10 /* */ ++#define RF_MODE2 0x11 /* */ ++ ++#define RF_RX_AGC_HP 0x12 /* */ ++#define RF_TX_AGC 0x13 /* */ ++#define RF_BIAS 0x14 /* */ ++#define RF_IPA 0x15 /* */ ++#define RF_TXBIAS 0x16 /* */ ++#define RF_POW_ABILITY 0x17 /* */ ++#define RF_MODE_AG 0x18 /* */ ++#define rRfChannel 0x18 /* RF channel and BW switch */ ++#define RF_CHNLBW 0x18 /* RF channel and BW switch */ ++#define RF_TOP 0x19 /* */ ++ ++#define RF_RX_G1 0x1A /* */ ++#define RF_RX_G2 0x1B /* */ ++ ++#define RF_RX_BB2 0x1C /* */ ++#define RF_RX_BB1 0x1D /* */ ++ ++#define RF_RCK1 0x1E /* */ ++#define RF_RCK2 0x1F /* */ ++ ++#define RF_TX_G1 0x20 /* */ ++#define RF_TX_G2 0x21 /* */ ++#define RF_TX_G3 0x22 /* */ ++ ++#define RF_TX_BB1 0x23 /* */ ++ ++#define RF_T_METER 0x24 /* */ ++ ++#define RF_SYN_G1 0x25 /* RF TX Power control */ ++#define RF_SYN_G2 0x26 /* RF TX Power control */ ++#define RF_SYN_G3 0x27 /* RF TX Power control */ ++#define RF_SYN_G4 0x28 /* RF TX Power control */ ++#define RF_SYN_G5 0x29 /* RF TX Power control */ ++#define RF_SYN_G6 0x2A /* RF TX Power control */ ++#define RF_SYN_G7 0x2B /* RF TX Power control */ ++#define RF_SYN_G8 0x2C /* RF TX Power control */ ++ ++#define RF_RCK_OS 0x30 /* RF TX PA control */ ++#define RF_TXPA_G1 0x31 /* RF TX PA control */ ++#define RF_TXPA_G2 0x32 /* RF TX PA control */ ++#define RF_TXPA_G3 0x33 /* RF TX PA control */ ++ ++/* */ ++/* Bit Mask */ ++/* */ ++/* 1. Page1(0x100) */ ++#define bBBResetB 0x100 /* Useless now? */ ++#define bGlobalResetB 0x200 ++#define bOFDMTxStart 0x4 ++#define bCCKTxStart 0x8 ++#define bCRC32Debug 0x100 ++#define bPMACLoopback 0x10 ++#define bTxLSIG 0xffffff ++#define bOFDMTxRate 0xf ++#define bOFDMTxReserved 0x10 ++#define bOFDMTxLength 0x1ffe0 ++#define bOFDMTxParity 0x20000 ++#define bTxHTSIG1 0xffffff ++#define bTxHTMCSRate 0x7f ++#define bTxHTBW 0x80 ++#define bTxHTLength 0xffff00 ++#define bTxHTSIG2 0xffffff ++#define bTxHTSmoothing 0x1 ++#define bTxHTSounding 0x2 ++#define bTxHTReserved 0x4 ++#define bTxHTAggreation 0x8 ++#define bTxHTSTBC 0x30 ++#define bTxHTAdvanceCoding 0x40 ++#define bTxHTShortGI 0x80 ++#define bTxHTNumberHT_LTF 0x300 ++#define bTxHTCRC8 0x3fc00 ++#define bCounterReset 0x10000 ++#define bNumOfOFDMTx 0xffff ++#define bNumOfCCKTx 0xffff0000 ++#define bTxIdleInterval 0xffff ++#define bOFDMService 0xffff0000 ++#define bTxMACHeader 0xffffffff ++#define bTxDataInit 0xff ++#define bTxHTMode 0x100 ++#define bTxDataType 0x30000 ++#define bTxRandomSeed 0xffffffff ++#define bCCKTxPreamble 0x1 ++#define bCCKTxSFD 0xffff0000 ++#define bCCKTxSIG 0xff ++#define bCCKTxService 0xff00 ++#define bCCKLengthExt 0x8000 ++#define bCCKTxLength 0xffff0000 ++#define bCCKTxCRC16 0xffff ++#define bCCKTxStatus 0x1 ++#define bOFDMTxStatus 0x2 ++ ++#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && (_Offset <= 0xfff)) ++ ++/* 2. Page8(0x800) */ ++#define bRFMOD 0x1 /* Reg 0x800 rFPGA0_RFMOD */ ++#define bJapanMode 0x2 ++#define bCCKTxSC 0x30 ++#define bCCKEn 0x1000000 ++#define bOFDMEn 0x2000000 ++ ++#define bOFDMRxADCPhase 0x10000 /* Useless now */ ++#define bOFDMTxDACPhase 0x40000 ++#define bXATxAGC 0x3f ++ ++#define bXBTxAGC 0xf00 /* Reg 80c rFPGA0_TxGainStage */ ++#define bXCTxAGC 0xf000 ++#define bXDTxAGC 0xf0000 ++ ++#define bPAStart 0xf0000000 /* Useless now */ ++#define bTRStart 0x00f00000 ++#define bRFStart 0x0000f000 ++#define bBBStart 0x000000f0 ++#define bBBCCKStart 0x0000000f ++#define bPAEnd 0xf /* Reg0x814 */ ++#define bTREnd 0x0f000000 ++#define bRFEnd 0x000f0000 ++#define bCCAMask 0x000000f0 /* T2R */ ++#define bR2RCCAMask 0x00000f00 ++#define bHSSI_R2TDelay 0xf8000000 ++#define bHSSI_T2RDelay 0xf80000 ++#define bContTxHSSI 0x400 /* chane gain at continue Tx */ ++#define bIGFromCCK 0x200 ++#define bAGCAddress 0x3f ++#define bRxHPTx 0x7000 ++#define bRxHPT2R 0x38000 ++#define bRxHPCCKIni 0xc0000 ++#define bAGCTxCode 0xc00000 ++#define bAGCRxCode 0x300000 ++ ++#define b3WireDataLength 0x800 /* Reg 0x820~84f rFPGA0_XA_HSSIParameter1 */ ++#define b3WireAddressLength 0x400 ++ ++#define b3WireRFPowerDown 0x1 /* Useless now */ ++/* define bHWSISelect 0x8 */ ++#define b5GPAPEPolarity 0x40000000 ++#define b2GPAPEPolarity 0x80000000 ++#define bRFSW_TxDefaultAnt 0x3 ++#define bRFSW_TxOptionAnt 0x30 ++#define bRFSW_RxDefaultAnt 0x300 ++#define bRFSW_RxOptionAnt 0x3000 ++#define bRFSI_3WireData 0x1 ++#define bRFSI_3WireClock 0x2 ++#define bRFSI_3WireLoad 0x4 ++#define bRFSI_3WireRW 0x8 ++#define bRFSI_3Wire 0xf ++ ++#define bRFSI_RFENV 0x10 /* Reg 0x870 rFPGA0_XAB_RFInterfaceSW */ ++ ++#define bRFSI_TRSW 0x20 /* Useless now */ ++#define bRFSI_TRSWB 0x40 ++#define bRFSI_ANTSW 0x100 ++#define bRFSI_ANTSWB 0x200 ++#define bRFSI_PAPE 0x400 ++#define bRFSI_PAPE5G 0x800 ++#define bBandSelect 0x1 ++#define bHTSIG2_GI 0x80 ++#define bHTSIG2_Smoothing 0x01 ++#define bHTSIG2_Sounding 0x02 ++#define bHTSIG2_Aggreaton 0x08 ++#define bHTSIG2_STBC 0x30 ++#define bHTSIG2_AdvCoding 0x40 ++#define bHTSIG2_NumOfHTLTF 0x300 ++#define bHTSIG2_CRC8 0x3fc ++#define bHTSIG1_MCS 0x7f ++#define bHTSIG1_BandWidth 0x80 ++#define bHTSIG1_HTLength 0xffff ++#define bLSIG_Rate 0xf ++#define bLSIG_Reserved 0x10 ++#define bLSIG_Length 0x1fffe ++#define bLSIG_Parity 0x20 ++#define bCCKRxPhase 0x4 ++#if (RTL92SE_FPGA_VERIFY == 1) ++#define bLSSIReadAddress 0x3f000000 /* LSSI "Read" Address ++ Reg 0x824 rFPGA0_XA_HSSIParameter2 */ ++#else ++#define bLSSIReadAddress 0x7f800000 /* T65 RF */ ++#endif ++#define bLSSIReadEdge 0x80000000 /* LSSI "Read" edge signal */ ++#if (RTL92SE_FPGA_VERIFY == 1) ++#define bLSSIReadBackData 0xfff /* Reg 0x8a0 ++ rFPGA0_XA_LSSIReadBack */ ++#else ++#define bLSSIReadBackData 0xfffff /* T65 RF */ ++#endif ++#define bLSSIReadOKFlag 0x1000 /* Useless now */ ++#define bCCKSampleRate 0x8 /* 0: 44MHz, 1:88MHz */ ++#define bRegulator0Standby 0x1 ++#define bRegulatorPLLStandby 0x2 ++#define bRegulator1Standby 0x4 ++#define bPLLPowerUp 0x8 ++#define bDPLLPowerUp 0x10 ++#define bDA10PowerUp 0x20 ++#define bAD7PowerUp 0x200 ++#define bDA6PowerUp 0x2000 ++#define bXtalPowerUp 0x4000 ++#define b40MDClkPowerUP 0x8000 ++#define bDA6DebugMode 0x20000 ++#define bDA6Swing 0x380000 ++ ++#define bADClkPhase 0x4000000 /* Reg 0x880 ++ rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ */ ++ ++#define b80MClkDelay 0x18000000 /* Useless */ ++#define bAFEWatchDogEnable 0x20000000 ++ ++#define bXtalCap01 0xc0000000 /* Reg 0x884 ++ rFPGA0_AnalogParameter2 Crystal cap */ ++#define bXtalCap23 0x3 ++#define bXtalCap92x 0x0f000000 ++#define bXtalCap 0x0f000000 ++ ++#define bIntDifClkEnable 0x400 /* Useless */ ++#define bExtSigClkEnable 0x800 ++#define bBandgapMbiasPowerUp 0x10000 ++#define bAD11SHGain 0xc0000 ++#define bAD11InputRange 0x700000 ++#define bAD11OPCurrent 0x3800000 ++#define bIPathLoopback 0x4000000 ++#define bQPathLoopback 0x8000000 ++#define bAFELoopback 0x10000000 ++#define bDA10Swing 0x7e0 ++#define bDA10Reverse 0x800 ++#define bDAClkSource 0x1000 ++#define bAD7InputRange 0x6000 ++#define bAD7Gain 0x38000 ++#define bAD7OutputCMMode 0x40000 ++#define bAD7InputCMMode 0x380000 ++#define bAD7Current 0xc00000 ++#define bRegulatorAdjust 0x7000000 ++#define bAD11PowerUpAtTx 0x1 ++#define bDA10PSAtTx 0x10 ++#define bAD11PowerUpAtRx 0x100 ++#define bDA10PSAtRx 0x1000 ++#define bCCKRxAGCFormat 0x200 ++#define bPSDFFTSamplepPoint 0xc000 ++#define bPSDAverageNum 0x3000 ++#define bIQPathControl 0xc00 ++#define bPSDFreq 0x3ff ++#define bPSDAntennaPath 0x30 ++#define bPSDIQSwitch 0x40 ++#define bPSDRxTrigger 0x400000 ++#define bPSDTxTrigger 0x80000000 ++#define bPSDSineToneScale 0x7f000000 ++#define bPSDReport 0xffff ++ ++/* 3. Page9(0x900) */ ++#define bOFDMTxSC 0x30000000 /* Useless */ ++#define bCCKTxOn 0x1 ++#define bOFDMTxOn 0x2 ++#define bDebugPage 0xfff /* reset debug page and HWord, ++ * LWord */ ++#define bDebugItem 0xff /* reset debug page and LWord */ ++#define bAntL 0x10 ++#define bAntNonHT 0x100 ++#define bAntHT1 0x1000 ++#define bAntHT2 0x10000 ++#define bAntHT1S1 0x100000 ++#define bAntNonHTS1 0x1000000 ++ ++/* 4. PageA(0xA00) */ ++#define bCCKBBMode 0x3 /* Useless */ ++#define bCCKTxPowerSaving 0x80 ++#define bCCKRxPowerSaving 0x40 ++ ++#define bCCKSideBand 0x10 /* Reg 0xa00 rCCK0 20/40 sw */ ++ ++#define bCCKScramble 0x8 /* Useless */ ++#define bCCKAntDiversity 0x8000 ++#define bCCKCarrierRecovery 0x4000 ++#define bCCKTxRate 0x3000 ++#define bCCKDCCancel 0x0800 ++#define bCCKISICancel 0x0400 ++#define bCCKMatchFilter 0x0200 ++#define bCCKEqualizer 0x0100 ++#define bCCKPreambleDetect 0x800000 ++#define bCCKFastFalseCCA 0x400000 ++#define bCCKChEstStart 0x300000 ++#define bCCKCCACount 0x080000 ++#define bCCKcs_lim 0x070000 ++#define bCCKBistMode 0x80000000 ++#define bCCKCCAMask 0x40000000 ++#define bCCKTxDACPhase 0x4 ++#define bCCKRxADCPhase 0x20000000 /* r_rx_clk */ ++#define bCCKr_cp_mode0 0x0100 ++#define bCCKTxDCOffset 0xf0 ++#define bCCKRxDCOffset 0xf ++#define bCCKCCAMode 0xc000 ++#define bCCKFalseCS_lim 0x3f00 ++#define bCCKCS_ratio 0xc00000 ++#define bCCKCorgBit_sel 0x300000 ++#define bCCKPD_lim 0x0f0000 ++#define bCCKNewCCA 0x80000000 ++#define bCCKRxHPofIG 0x8000 ++#define bCCKRxIG 0x7f00 ++#define bCCKLNAPolarity 0x800000 ++#define bCCKRx1stGain 0x7f0000 ++#define bCCKRFExtend 0x20000000 /* CCK Rx init gain polar */ ++#define bCCKRxAGCSatLevel 0x1f000000 ++#define bCCKRxAGCSatCount 0xe0 ++#define bCCKRxRFSettle 0x1f /* AGCsamp_dly */ ++#define bCCKFixedRxAGC 0x8000 ++#define bCCKAntennaPolarity 0x2000 ++#define bCCKTxFilterType 0x0c00 ++#define bCCKRxAGCReportType 0x0300 ++#define bCCKRxDAGCEn 0x80000000 ++#define bCCKRxDAGCPeriod 0x20000000 ++#define bCCKRxDAGCSatLevel 0x1f000000 ++#define bCCKTimingRecovery 0x800000 ++#define bCCKTxC0 0x3f0000 ++#define bCCKTxC1 0x3f000000 ++#define bCCKTxC2 0x3f ++#define bCCKTxC3 0x3f00 ++#define bCCKTxC4 0x3f0000 ++#define bCCKTxC5 0x3f000000 ++#define bCCKTxC6 0x3f ++#define bCCKTxC7 0x3f00 ++#define bCCKDebugPort 0xff0000 ++#define bCCKDACDebug 0x0f000000 ++#define bCCKFalseAlarmEnable 0x8000 ++#define bCCKFalseAlarmRead 0x4000 ++#define bCCKTRSSI 0x7f ++#define bCCKRxAGCReport 0xfe ++#define bCCKRxReport_AntSel 0x80000000 ++#define bCCKRxReport_MFOff 0x40000000 ++#define bCCKRxRxReport_SQLoss 0x20000000 ++#define bCCKRxReport_Pktloss 0x10000000 ++#define bCCKRxReport_Lockedbit 0x08000000 ++#define bCCKRxReport_RateError 0x04000000 ++#define bCCKRxReport_RxRate 0x03000000 ++#define bCCKRxFACounterLower 0xff ++#define bCCKRxFACounterUpper 0xff000000 ++#define bCCKRxHPAGCStart 0xe000 ++#define bCCKRxHPAGCFinal 0x1c00 ++#define bCCKRxFalseAlarmEnable 0x8000 ++#define bCCKFACounterFreeze 0x4000 ++#define bCCKTxPathSel 0x10000000 ++#define bCCKDefaultRxPath 0xc000000 ++#define bCCKOptionRxPath 0x3000000 ++ ++/* 5. PageC(0xC00) */ ++#define bNumOfSTF 0x3 /* Useless */ ++#define bShift_L 0xc0 ++#define bGI_TH 0xc ++#define bRxPathA 0x1 ++#define bRxPathB 0x2 ++#define bRxPathC 0x4 ++#define bRxPathD 0x8 ++#define bTxPathA 0x1 ++#define bTxPathB 0x2 ++#define bTxPathC 0x4 ++#define bTxPathD 0x8 ++#define bTRSSIFreq 0x200 ++#define bADCBackoff 0x3000 ++#define bDFIRBackoff 0xc000 ++#define bTRSSILatchPhase 0x10000 ++#define bRxIDCOffset 0xff ++#define bRxQDCOffset 0xff00 ++#define bRxDFIRMode 0x1800000 ++#define bRxDCNFType 0xe000000 ++#define bRXIQImb_A 0x3ff ++#define bRXIQImb_B 0xfc00 ++#define bRXIQImb_C 0x3f0000 ++#define bRXIQImb_D 0xffc00000 ++#define bDC_dc_Notch 0x60000 ++#define bRxNBINotch 0x1f000000 ++#define bPD_TH 0xf ++#define bPD_TH_Opt2 0xc000 ++#define bPWED_TH 0x700 ++#define bIfMF_Win_L 0x800 ++#define bPD_Option 0x1000 ++#define bMF_Win_L 0xe000 ++#define bBW_Search_L 0x30000 ++#define bwin_enh_L 0xc0000 ++#define bBW_TH 0x700000 ++#define bED_TH2 0x3800000 ++#define bBW_option 0x4000000 ++#define bRatio_TH 0x18000000 ++#define bWindow_L 0xe0000000 ++#define bSBD_Option 0x1 ++#define bFrame_TH 0x1c ++#define bFS_Option 0x60 ++#define bDC_Slope_check 0x80 ++#define bFGuard_Counter_DC_L 0xe00 ++#define bFrame_Weight_Short 0x7000 ++#define bSub_Tune 0xe00000 ++#define bFrame_DC_Length 0xe000000 ++#define bSBD_start_offset 0x30000000 ++#define bFrame_TH_2 0x7 ++#define bFrame_GI2_TH 0x38 ++#define bGI2_Sync_en 0x40 ++#define bSarch_Short_Early 0x300 ++#define bSarch_Short_Late 0xc00 ++#define bSarch_GI2_Late 0x70000 ++#define bCFOAntSum 0x1 ++#define bCFOAcc 0x2 ++#define bCFOStartOffset 0xc ++#define bCFOLookBack 0x70 ++#define bCFOSumWeight 0x80 ++#define bDAGCEnable 0x10000 ++#define bTXIQImb_A 0x3ff ++#define bTXIQImb_B 0xfc00 ++#define bTXIQImb_C 0x3f0000 ++#define bTXIQImb_D 0xffc00000 ++#define bTxIDCOffset 0xff ++#define bTxQDCOffset 0xff00 ++#define bTxDFIRMode 0x10000 ++#define bTxPesudoNoiseOn 0x4000000 ++#define bTxPesudoNoise_A 0xff ++#define bTxPesudoNoise_B 0xff00 ++#define bTxPesudoNoise_C 0xff0000 ++#define bTxPesudoNoise_D 0xff000000 ++#define bCCADropOption 0x20000 ++#define bCCADropThres 0xfff00000 ++#define bEDCCA_H 0xf ++#define bEDCCA_L 0xf0 ++#define bLambda_ED 0x300 ++#define bRxInitialGain 0x7f ++#define bRxAntDivEn 0x80 ++#define bRxAGCAddressForLNA 0x7f00 ++#define bRxHighPowerFlow 0x8000 ++#define bRxAGCFreezeThres 0xc0000 ++#define bRxFreezeStep_AGC1 0x300000 ++#define bRxFreezeStep_AGC2 0xc00000 ++#define bRxFreezeStep_AGC3 0x3000000 ++#define bRxFreezeStep_AGC0 0xc000000 ++#define bRxRssi_Cmp_En 0x10000000 ++#define bRxQuickAGCEn 0x20000000 ++#define bRxAGCFreezeThresMode 0x40000000 ++#define bRxOverFlowCheckType 0x80000000 ++#define bRxAGCShift 0x7f ++#define bTRSW_Tri_Only 0x80 ++#define bPowerThres 0x300 ++#define bRxAGCEn 0x1 ++#define bRxAGCTogetherEn 0x2 ++#define bRxAGCMin 0x4 ++#define bRxHP_Ini 0x7 ++#define bRxHP_TRLNA 0x70 ++#define bRxHP_RSSI 0x700 ++#define bRxHP_BBP1 0x7000 ++#define bRxHP_BBP2 0x70000 ++#define bRxHP_BBP3 0x700000 ++#define bRSSI_H 0x7f0000 /* thresh for hi power */ ++#define bRSSI_Gen 0x7f000000 /* thresh for ant div */ ++#define bRxSettle_TRSW 0x7 ++#define bRxSettle_LNA 0x38 ++#define bRxSettle_RSSI 0x1c0 ++#define bRxSettle_BBP 0xe00 ++#define bRxSettle_RxHP 0x7000 ++#define bRxSettle_AntSW_RSSI 0x38000 ++#define bRxSettle_AntSW 0xc0000 ++#define bRxProcessTime_DAGC 0x300000 ++#define bRxSettle_HSSI 0x400000 ++#define bRxProcessTime_BBPPW 0x800000 ++#define bRxAntennaPowerShift 0x3000000 ++#define bRSSITableSelect 0xc000000 ++#define bRxHP_Final 0x7000000 ++#define bRxHTSettle_BBP 0x7 ++#define bRxHTSettle_HSSI 0x8 ++#define bRxHTSettle_RxHP 0x70 ++#define bRxHTSettle_BBPPW 0x80 ++#define bRxHTSettle_Idle 0x300 ++#define bRxHTSettle_Reserved 0x1c00 ++#define bRxHTRxHPEn 0x8000 ++#define bRxHTAGCFreezeThres 0x30000 ++#define bRxHTAGCTogetherEn 0x40000 ++#define bRxHTAGCMin 0x80000 ++#define bRxHTAGCEn 0x100000 ++#define bRxHTDAGCEn 0x200000 ++#define bRxHTRxHP_BBP 0x1c00000 ++#define bRxHTRxHP_Final 0xe0000000 ++#define bRxPWRatioTH 0x3 ++#define bRxPWRatioEn 0x4 ++#define bRxMFHold 0x3800 ++#define bRxPD_Delay_TH1 0x38 ++#define bRxPD_Delay_TH2 0x1c0 ++#define bRxPD_DC_COUNT_MAX 0x600 ++/* define bRxMF_Hold 0x3800 */ ++#define bRxPD_Delay_TH 0x8000 ++#define bRxProcess_Delay 0xf0000 ++#define bRxSearchrange_GI2_Early 0x700000 ++#define bRxFrame_Guard_Counter_L 0x3800000 ++#define bRxSGI_Guard_L 0xc000000 ++#define bRxSGI_Search_L 0x30000000 ++#define bRxSGI_TH 0xc0000000 ++#define bDFSCnt0 0xff ++#define bDFSCnt1 0xff00 ++#define bDFSFlag 0xf0000 ++#define bMFWeightSum 0x300000 ++#define bMinIdxTH 0x7f000000 ++#define bDAFormat 0x40000 ++#define bTxChEmuEnable 0x01000000 ++#define bTRSWIsolation_A 0x7f ++#define bTRSWIsolation_B 0x7f00 ++#define bTRSWIsolation_C 0x7f0000 ++#define bTRSWIsolation_D 0x7f000000 ++#define bExtLNAGain 0x7c00 ++ ++/* 6. PageE(0xE00) */ ++#define bSTBCEn 0x4 /* Useless */ ++#define bAntennaMapping 0x10 ++#define bNss 0x20 ++#define bCFOAntSumD 0x200 ++#define bPHYCounterReset 0x8000000 ++#define bCFOReportGet 0x4000000 ++#define bOFDMContinueTx 0x10000000 ++#define bOFDMSingleCarrier 0x20000000 ++#define bOFDMSingleTone 0x40000000 ++/* define bRxPath1 0x01 */ ++/* define bRxPath2 0x02 */ ++/* define bRxPath3 0x04 */ ++/* define bRxPath4 0x08 */ ++/* define bTxPath1 0x10 */ ++/* define bTxPath2 0x20 */ ++#define bHTDetect 0x100 ++#define bCFOEn 0x10000 ++#define bCFOValue 0xfff00000 ++#define bSigTone_Re 0x3f ++#define bSigTone_Im 0x7f00 ++#define bCounter_CCA 0xffff ++#define bCounter_ParityFail 0xffff0000 ++#define bCounter_RateIllegal 0xffff ++#define bCounter_CRC8Fail 0xffff0000 ++#define bCounter_MCSNoSupport 0xffff ++#define bCounter_FastSync 0xffff ++#define bShortCFO 0xfff ++#define bShortCFOTLength 12 /* total */ ++#define bShortCFOFLength 11 /* fraction */ ++#define bLongCFO 0x7ff ++#define bLongCFOTLength 11 ++#define bLongCFOFLength 11 ++#define bTailCFO 0x1fff ++#define bTailCFOTLength 13 ++#define bTailCFOFLength 12 ++#define bmax_en_pwdB 0xffff ++#define bCC_power_dB 0xffff0000 ++#define bnoise_pwdB 0xffff ++#define bPowerMeasTLength 10 ++#define bPowerMeasFLength 3 ++#define bRx_HT_BW 0x1 ++#define bRxSC 0x6 ++#define bRx_HT 0x8 ++#define bNB_intf_det_on 0x1 ++#define bIntf_win_len_cfg 0x30 ++#define bNB_Intf_TH_cfg 0x1c0 ++#define bRFGain 0x3f ++#define bTableSel 0x40 ++#define bTRSW 0x80 ++#define bRxSNR_A 0xff ++#define bRxSNR_B 0xff00 ++#define bRxSNR_C 0xff0000 ++#define bRxSNR_D 0xff000000 ++#define bSNREVMTLength 8 ++#define bSNREVMFLength 1 ++#define bCSI1st 0xff ++#define bCSI2nd 0xff00 ++#define bRxEVM1st 0xff0000 ++#define bRxEVM2nd 0xff000000 ++#define bSIGEVM 0xff ++#define bPWDB 0xff00 ++#define bSGIEN 0x10000 ++ ++#define bSFactorQAM1 0xf /* Useless */ ++#define bSFactorQAM2 0xf0 ++#define bSFactorQAM3 0xf00 ++#define bSFactorQAM4 0xf000 ++#define bSFactorQAM5 0xf0000 ++#define bSFactorQAM6 0xf0000 ++#define bSFactorQAM7 0xf00000 ++#define bSFactorQAM8 0xf000000 ++#define bSFactorQAM9 0xf0000000 ++#define bCSIScheme 0x100000 ++ ++#define bNoiseLvlTopSet 0x3 /* Useless */ ++#define bChSmooth 0x4 ++#define bChSmoothCfg1 0x38 ++#define bChSmoothCfg2 0x1c0 ++#define bChSmoothCfg3 0xe00 ++#define bChSmoothCfg4 0x7000 ++#define bMRCMode 0x800000 ++#define bTHEVMCfg 0x7000000 ++ ++#define bLoopFitType 0x1 /* Useless */ ++#define bUpdCFO 0x40 ++#define bUpdCFOOffData 0x80 ++#define bAdvUpdCFO 0x100 ++#define bAdvTimeCtrl 0x800 ++#define bUpdClko 0x1000 ++#define bFC 0x6000 ++#define bTrackingMode 0x8000 ++#define bPhCmpEnable 0x10000 ++#define bUpdClkoLTF 0x20000 ++#define bComChCFO 0x40000 ++#define bCSIEstiMode 0x80000 ++#define bAdvUpdEqz 0x100000 ++#define bUChCfg 0x7000000 ++#define bUpdEqz 0x8000000 ++ ++#define bTxAGCRate18_06 0x7f7f7f7f /* Useless */ ++#define bTxAGCRate54_24 0x7f7f7f7f ++#define bTxAGCRateMCS32 0x7f ++#define bTxAGCRateCCK 0x7f00 ++#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f ++#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f ++#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f ++#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f ++ ++/* Rx Pseduo noise */ ++#define bRxPesudoNoiseOn 0x20000000 /* Useless */ ++#define bRxPesudoNoise_A 0xff ++#define bRxPesudoNoise_B 0xff00 ++#define bRxPesudoNoise_C 0xff0000 ++#define bRxPesudoNoise_D 0xff000000 ++#define bPesudoNoiseState_A 0xffff ++#define bPesudoNoiseState_B 0xffff0000 ++#define bPesudoNoiseState_C 0xffff ++#define bPesudoNoiseState_D 0xffff0000 ++ ++/* 7. RF Register */ ++/* Zebra1 */ ++#define bZebra1_HSSIEnable 0x8 /* Useless */ ++#define bZebra1_TRxControl 0xc00 ++#define bZebra1_TRxGainSetting 0x07f ++#define bZebra1_RxCorner 0xc00 ++#define bZebra1_TxChargePump 0x38 ++#define bZebra1_RxChargePump 0x7 ++#define bZebra1_ChannelNum 0xf80 ++#define bZebra1_TxLPFBW 0x400 ++#define bZebra1_RxLPFBW 0x600 ++ ++/* Zebra4 */ ++#define bRTL8256RegModeCtrl1 0x100 /* Useless */ ++#define bRTL8256RegModeCtrl0 0x40 ++#define bRTL8256_TxLPFBW 0x18 ++#define bRTL8256_RxLPFBW 0x600 ++ ++/* RTL8258 */ ++#define bRTL8258_TxLPFBW 0xc /* Useless */ ++#define bRTL8258_RxLPFBW 0xc00 ++#define bRTL8258_RSSILPFBW 0xc0 ++ ++/* */ ++/* Other Definition */ ++/* */ ++ ++/* byte endable for sb_write */ ++#define bByte0 0x1 /* Useless */ ++#define bByte1 0x2 ++#define bByte2 0x4 ++#define bByte3 0x8 ++#define bWord0 0x3 ++#define bWord1 0xc ++#define bDWord 0xf ++ ++/* for PutRegsetting & GetRegSetting BitMask */ ++#define bMaskByte0 0xff /* Reg 0xc50 rOFDM0_XAAGCCore~0xC6f */ ++#define bMaskByte1 0xff00 ++#define bMaskByte2 0xff0000 ++#define bMaskByte3 0xff000000 ++#define bMaskHWord 0xffff0000 ++#define bMaskLWord 0x0000ffff ++#define bMaskDWord 0xffffffff ++#define bMaskH4Bits 0xf0000000 ++#define bMaskOFDM_D 0xffc00000 ++#define bMaskCCK 0x3f3f3f3f ++#define bMask12Bits 0xfff ++ ++/* for PutRFRegsetting & GetRFRegSetting BitMask */ ++#if (RTL92SE_FPGA_VERIFY == 1) ++#define bRFRegOffsetMask 0xfff ++#else ++#define bRFRegOffsetMask 0xfffff ++#endif ++#define bEnable 0x1 /* Useless */ ++#define bDisabl 0x0 ++ ++#define LeftAntenna 0x0 /* Useless */ ++#define RightAntenna 0x1 ++ ++#define tCheckTxStatus 500 /* 500ms Useless */ ++#define tUpdateRxCounter 100 /* 100ms */ ++ ++#define rateCCK 0 /* Useless */ ++#define rateOFDM 1 ++#define rateHT 2 ++ ++/* define Register-End */ ++#define bPMAC_End 0x1ff /* Useless */ ++#define bFPGAPHY0_End 0x8ff ++#define bFPGAPHY1_End 0x9ff ++#define bCCKPHY0_End 0xaff ++#define bOFDMPHY0_End 0xcff ++#define bOFDMPHY1_End 0xdff ++ ++/* define max debug item in each debug page */ ++/* define bMaxItem_FPGA_PHY0 0x9 */ ++/* define bMaxItem_FPGA_PHY1 0x3 */ ++/* define bMaxItem_PHY_11B 0x16 */ ++/* define bMaxItem_OFDM_PHY0 0x29 */ ++/* define bMaxItem_OFDM_PHY1 0x0 */ ++ ++#define bPMACControl 0x0 /* Useless */ ++#define bWMACControl 0x1 ++#define bWNICControl 0x2 ++ ++#define RCR_AAP BIT(0) /* accept all physical address */ ++#define RCR_APM BIT(1) /* accept physical match */ ++#define RCR_AM BIT(2) /* accept multicast */ ++#define RCR_AB BIT(3) /* accept broadcast */ ++#define RCR_ACRC32 BIT(5) /* accept error packet */ ++#define RCR_9356SEL BIT(6) ++#define RCR_AICV BIT(12) /* Accept ICV error packet */ ++#define RCR_RXFTH0 (BIT(13)|BIT(14)|BIT(15)) /* Rx FIFO threshold */ ++#define RCR_ADF BIT(18) /* Accept Data(frame type) frame */ ++#define RCR_ACF BIT(19) /* Accept control frame */ ++#define RCR_AMF BIT(20) /* Accept management frame */ ++#define RCR_ADD3 BIT(21) ++#define RCR_APWRMGT BIT(22) /* Accept power management packet */ ++#define RCR_CBSSID BIT(23) /* Accept BSSID match packet */ ++#define RCR_ENMARP BIT(28) /* enable mac auto reset phy */ ++#define RCR_EnCS1 BIT(29) /* enable carrier sense method 1 */ ++#define RCR_EnCS2 BIT(30) /* enable carrier sense method 2 */ ++#define RCR_OnlyErlPkt BIT(31) /* Rx Early mode is performed for ++ * packet size greater than 1536 */ ++ ++/*--------------------------Define Parameters-------------------------------*/ ++ ++#endif /* __INC_HAL8192SPHYREG_H */ +diff --git a/drivers/staging/r8188eu/include/rtw_p2p.h b/drivers/staging/r8188eu/include/rtw_p2p.h +new file mode 100644 +index 000000000000..92b9bfe3ea0b +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_p2p.h +@@ -0,0 +1,119 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_P2P_H_ ++#define __RTW_P2P_H_ ++ ++#include "drv_types.h" ++ ++u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); ++u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); ++u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo, ++ u8 *pbuf, u8 *pssid, u8 ussidlen, ++ u8 *pdev_raddr); ++u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo, ++ u8 *pbuf, u8 status_code); ++u32 build_deauth_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); ++u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len); ++u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len, struct sta_info *psta); ++u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len); ++u32 process_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len); ++u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len); ++u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe); ++u8 process_p2p_group_negotation_req(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len); ++u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len); ++u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len); ++u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe, ++ uint len); ++void p2p_protocol_wk_hdl(struct adapter *padapter, int intcmdtype); ++void process_p2p_ps_ie(struct adapter *padapter, u8 *ies, u32 ielength); ++void p2p_ps_wk_hdl(struct adapter *padapter, u8 p2p_ps_state); ++u8 p2p_ps_wk_cmd(struct adapter *padapter, u8 p2p_ps_state, u8 enqueue); ++void reset_global_wifidirect_info(struct adapter *padapter); ++int rtw_init_wifi_display_info(struct adapter *padapter); ++void rtw_init_wifidirect_timers(struct adapter *padapter); ++void rtw_init_wifidirect_addrs(struct adapter *padapter, u8 *dev_addr, ++ u8 *iface_addr); ++void init_wifidirect_info(struct adapter *padapter, enum P2P_ROLE role); ++int rtw_p2p_enable(struct adapter *padapter, enum P2P_ROLE role); ++ ++static inline void _rtw_p2p_set_state(struct wifidirect_info *wdinfo, ++ enum P2P_STATE state) ++{ ++ if (wdinfo->p2p_state != state) ++ wdinfo->p2p_state = state; ++} ++ ++static inline void _rtw_p2p_set_pre_state(struct wifidirect_info *wdinfo, ++ enum P2P_STATE state) ++{ ++ if (wdinfo->pre_p2p_state != state) ++ wdinfo->pre_p2p_state = state; ++} ++ ++static inline void _rtw_p2p_set_role(struct wifidirect_info *wdinfo, ++ enum P2P_ROLE role) ++{ ++ if (wdinfo->role != role) ++ wdinfo->role = role; ++} ++ ++static inline int _rtw_p2p_state(struct wifidirect_info *wdinfo) ++{ ++ return wdinfo->p2p_state; ++} ++ ++static inline int _rtw_p2p_pre_state(struct wifidirect_info *wdinfo) ++{ ++ return wdinfo->pre_p2p_state; ++} ++ ++static inline int _rtw_p2p_role(struct wifidirect_info *wdinfo) ++{ ++ return wdinfo->role; ++} ++ ++static inline bool _rtw_p2p_chk_state(struct wifidirect_info *wdinfo, ++ enum P2P_STATE state) ++{ ++ return wdinfo->p2p_state == state; ++} ++ ++static inline bool _rtw_p2p_chk_role(struct wifidirect_info *wdinfo, ++ enum P2P_ROLE role) ++{ ++ return wdinfo->role == role; ++} ++ ++#define rtw_p2p_set_state(wdinfo, state) _rtw_p2p_set_state(wdinfo, state) ++#define rtw_p2p_set_pre_state(wdinfo, state) \ ++ _rtw_p2p_set_pre_state(wdinfo, state) ++#define rtw_p2p_set_role(wdinfo, role) _rtw_p2p_set_role(wdinfo, role) ++ ++#define rtw_p2p_state(wdinfo) _rtw_p2p_state(wdinfo) ++#define rtw_p2p_pre_state(wdinfo) _rtw_p2p_pre_state(wdinfo) ++#define rtw_p2p_role(wdinfo) _rtw_p2p_role(wdinfo) ++#define rtw_p2p_chk_state(wdinfo, state) _rtw_p2p_chk_state(wdinfo, state) ++#define rtw_p2p_chk_role(wdinfo, role) _rtw_p2p_chk_role(wdinfo, role) ++ ++#define rtw_p2p_findphase_ex_set(wdinfo, value) \ ++ ((wdinfo)->find_phase_state_exchange_cnt = (value)) ++ ++/* is this find phase exchange for social channel scan? */ ++#define rtw_p2p_findphase_ex_is_social(wdinfo) \ ++((wdinfo)->find_phase_state_exchange_cnt >= P2P_FINDPHASE_EX_SOCIAL_FIRST) ++ ++/* should we need find phase exchange anymore? */ ++#define rtw_p2p_findphase_ex_is_needed(wdinfo) \ ++ ((wdinfo)->find_phase_state_exchange_cnt < P2P_FINDPHASE_EX_MAX && \ ++ (wdinfo)->find_phase_state_exchange_cnt != P2P_FINDPHASE_EX_NONE) ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_pwrctrl.h b/drivers/staging/r8188eu/include/rtw_pwrctrl.h +new file mode 100644 +index 000000000000..543f928e8089 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_pwrctrl.h +@@ -0,0 +1,266 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#ifndef __RTW_PWRCTRL_H_ ++#define __RTW_PWRCTRL_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define FW_PWR0 0 ++#define FW_PWR1 1 ++#define FW_PWR2 2 ++#define FW_PWR3 3 ++#define HW_PWR0 7 ++#define HW_PWR1 6 ++#define HW_PWR2 2 ++#define HW_PWR3 0 ++#define HW_PWR4 8 ++ ++#define FW_PWRMSK 0x7 ++ ++#define XMIT_ALIVE BIT(0) ++#define RECV_ALIVE BIT(1) ++#define CMD_ALIVE BIT(2) ++#define EVT_ALIVE BIT(3) ++ ++enum power_mgnt { ++ PS_MODE_ACTIVE = 0, ++ PS_MODE_MIN, ++ PS_MODE_MAX, ++ PS_MODE_DTIM, ++ PS_MODE_VOIP, ++ PS_MODE_UAPSD_WMM, ++ PS_MODE_UAPSD, ++ PS_MODE_IBSS, ++ PS_MODE_WWLAN, ++ PM_Radio_Off, ++ PM_Card_Disable, ++ PS_MODE_NUM ++}; ++ ++/* ++ BIT[2:0] = HW state ++ BIT[3] = Protocol PS state, 0: register active state, ++ 1: register sleep state ++ BIT[4] = sub-state ++*/ ++ ++#define PS_DPS BIT(0) ++#define PS_LCLK (PS_DPS) ++#define PS_RF_OFF BIT(1) ++#define PS_ALL_ON BIT(2) ++#define PS_ST_ACTIVE BIT(3) ++ ++#define PS_ISR_ENABLE BIT(4) ++#define PS_IMR_ENABLE BIT(5) ++#define PS_ACK BIT(6) ++#define PS_TOGGLE BIT(7) ++ ++#define PS_STATE_MASK (0x0F) ++#define PS_STATE_HW_MASK (0x07) ++#define PS_SEQ_MASK (0xc0) ++ ++#define PS_STATE(x) (PS_STATE_MASK & (x)) ++#define PS_STATE_HW(x) (PS_STATE_HW_MASK & (x)) ++#define PS_SEQ(x) (PS_SEQ_MASK & (x)) ++ ++#define PS_STATE_S0 (PS_DPS) ++#define PS_STATE_S1 (PS_LCLK) ++#define PS_STATE_S2 (PS_RF_OFF) ++#define PS_STATE_S3 (PS_ALL_ON) ++#define PS_STATE_S4 ((PS_ST_ACTIVE) | (PS_ALL_ON)) ++ ++#define PS_IS_RF_ON(x) ((x) & (PS_ALL_ON)) ++#define PS_IS_ACTIVE(x) ((x) & (PS_ST_ACTIVE)) ++#define CLR_PS_STATE(x) ((x) = ((x) & (0xF0))) ++ ++struct reportpwrstate_parm { ++ unsigned char mode; ++ unsigned char state; /* the CPWM value */ ++ unsigned short rsvd; ++}; ++ ++static inline void _init_pwrlock(struct semaphore *plock) ++{ ++ sema_init(plock, 1); ++} ++ ++static inline void _free_pwrlock(struct semaphore *plock) ++{ ++} ++ ++static inline void _enter_pwrlock(struct semaphore *plock) ++{ ++ _rtw_down_sema(plock); ++} ++ ++static inline void _exit_pwrlock(struct semaphore *plock) ++{ ++ up(plock); ++} ++ ++#define LPS_DELAY_TIME 1*HZ /* 1 sec */ ++ ++#define EXE_PWR_NONE 0x01 ++#define EXE_PWR_IPS 0x02 ++#define EXE_PWR_LPS 0x04 ++ ++/* RF state. */ ++enum rt_rf_power_state { ++ rf_on, /* RF is on after RFSleep or RFOff */ ++ rf_sleep, /* 802.11 Power Save mode */ ++ rf_off, /* HW/SW Radio OFF or Inactive Power Save */ ++ /* Add the new RF state above this line===== */ ++ rf_max ++}; ++ ++/* RF Off Level for IPS or HW/SW radio off */ ++#define RT_RF_OFF_LEVL_ASPM BIT(0) /* PCI ASPM */ ++#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /* PCI clock request */ ++#define RT_RF_OFF_LEVL_PCI_D3 BIT(2) /* PCI D3 mode */ ++#define RT_RF_OFF_LEVL_HALT_NIC BIT(3) /* NIC halt, re-init hw param*/ ++#define RT_RF_OFF_LEVL_FREE_FW BIT(4) /* FW free, re-download the FW*/ ++#define RT_RF_OFF_LEVL_FW_32K BIT(5) /* FW in 32k */ ++#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6) /* Always enable ASPM and Clock ++ * Req in initialization. */ ++#define RT_RF_LPS_DISALBE_2R BIT(30) /* When LPS is on, disable 2R ++ * if no packet is RX or TX. */ ++#define RT_RF_LPS_LEVEL_ASPM BIT(31) /* LPS with ASPM */ ++ ++#define RT_IN_PS_LEVEL(ppsc, _PS_FLAG) \ ++ ((ppsc->cur_ps_level & _PS_FLAG) ? true : false) ++#define RT_CLEAR_PS_LEVEL(ppsc, _PS_FLAG) \ ++ (ppsc->cur_ps_level &= (~(_PS_FLAG))) ++#define RT_SET_PS_LEVEL(ppsc, _PS_FLAG) \ ++ (ppsc->cur_ps_level |= _PS_FLAG) ++ ++enum _PS_BBRegBackup_ { ++ PSBBREG_RF0 = 0, ++ PSBBREG_RF1, ++ PSBBREG_RF2, ++ PSBBREG_AFE0, ++ PSBBREG_TOTALCNT ++}; ++ ++enum { /* for ips_mode */ ++ IPS_NONE = 0, ++ IPS_NORMAL, ++ IPS_LEVEL_2, ++}; ++ ++struct pwrctrl_priv { ++ struct semaphore lock; ++ volatile u8 rpwm; /* requested power state for fw */ ++ volatile u8 cpwm; /* fw current power state. updated when ++ * 1. read from HCPWM 2. driver lowers power level */ ++ volatile u8 tog; /* toggling */ ++ volatile u8 cpwm_tog; /* toggling */ ++ ++ u8 pwr_mode; ++ u8 smart_ps; ++ u8 bcn_ant_mode; ++ ++ u32 alives; ++ struct work_struct cpwm_event; ++ u8 bpower_saving; ++ ++ u8 b_hw_radio_off; ++ u8 reg_rfoff; ++ u8 reg_pdnmode; /* powerdown mode */ ++ u32 rfoff_reason; ++ ++ /* RF OFF Level */ ++ u32 cur_ps_level; ++ u32 reg_rfps_level; ++ uint ips_enter_cnts; ++ uint ips_leave_cnts; ++ ++ u8 ips_mode; ++ u8 ips_mode_req; /* used to accept the mode setting request, ++ * will update to ipsmode later */ ++ uint bips_processing; ++ u32 ips_deny_time; /* will deny IPS when system time less than this */ ++ u8 ps_processing; /* temp used to mark whether in rtw_ps_processor */ ++ ++ u8 bLeisurePs; ++ u8 LpsIdleCount; ++ u8 power_mgnt; ++ u8 bFwCurrentInPSMode; ++ u32 DelayLPSLastTimeStamp; ++ u8 btcoex_rfon; ++ s32 pnp_current_pwr_state; ++ u8 pnp_bstop_trx; ++ ++ u8 bInternalAutoSuspend; ++ u8 bInSuspend; ++#ifdef CONFIG_BT_COEXIST ++ u8 bAutoResume; ++ u8 autopm_cnt; ++#endif ++ u8 bSupportRemoteWakeup; ++ struct timer_list pwr_state_check_timer; ++ int pwr_state_check_interval; ++ u8 pwr_state_check_cnts; ++ ++ int ps_flag; ++ ++ enum rt_rf_power_state rf_pwrstate;/* cur power state */ ++ enum rt_rf_power_state change_rfpwrstate; ++ ++ u8 wepkeymask; ++ u8 bHWPowerdown;/* if support hw power down */ ++ u8 bHWPwrPindetect; ++ u8 bkeepfwalive; ++ u8 brfoffbyhw; ++ unsigned long PS_BBRegBackup[PSBBREG_TOTALCNT]; ++}; ++ ++#define rtw_get_ips_mode_req(pwrctrlpriv) \ ++ (pwrctrlpriv)->ips_mode_req ++ ++#define rtw_ips_mode_req(pwrctrlpriv, ips_mode) \ ++ ((pwrctrlpriv)->ips_mode_req = (ips_mode)) ++ ++#define RTW_PWR_STATE_CHK_INTERVAL 2000 ++ ++#define _rtw_set_pwr_state_check_timer(pwrctrlpriv, ms) \ ++ do { \ ++ _set_timer(&(pwrctrlpriv)->pwr_state_check_timer, (ms)); \ ++ } while (0) ++ ++#define rtw_set_pwr_state_check_timer(pwrctrl) \ ++ _rtw_set_pwr_state_check_timer((pwrctrl), \ ++ (pwrctrl)->pwr_state_check_interval) ++ ++void rtw_init_pwrctrl_priv(struct adapter *adapter); ++void rtw_free_pwrctrl_priv(struct adapter *adapter); ++ ++void rtw_set_ps_mode(struct adapter *adapter, u8 ps_mode, u8 smart_ps, ++ u8 bcn_ant_mode); ++void rtw_set_rpwm(struct adapter *adapter, u8 val8); ++void LeaveAllPowerSaveMode(struct adapter *adapter); ++void ips_enter(struct adapter *padapter); ++int ips_leave(struct adapter *padapter); ++ ++void rtw_ps_processor(struct adapter *padapter); ++ ++enum rt_rf_power_state RfOnOffDetect(struct adapter *iadapter); ++ ++s32 LPS_RF_ON_check(struct adapter *adapter, u32 delay_ms); ++void LPS_Enter(struct adapter *adapter); ++void LPS_Leave(struct adapter *adapter); ++ ++u8 rtw_interface_ps_func(struct adapter *adapter, ++ enum hal_intf_ps_func efunc_id, u8 *val); ++void rtw_set_ips_deny(struct adapter *adapter, u32 ms); ++int _rtw_pwr_wakeup(struct adapter *adapter, u32 ips_defer_ms, ++ const char *caller); ++#define rtw_pwr_wakeup(adapter) \ ++ _rtw_pwr_wakeup(adapter, RTW_PWR_STATE_CHK_INTERVAL, __func__) ++#define rtw_pwr_wakeup_ex(adapter, ips_deffer_ms) \ ++ _rtw_pwr_wakeup(adapter, ips_deffer_ms, __func__) ++int rtw_pm_set_ips(struct adapter *adapter, u8 mode); ++int rtw_pm_set_lps(struct adapter *adapter, u8 mode); ++ ++#endif /* __RTL871X_PWRCTRL_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_recv.h b/drivers/staging/r8188eu/include/rtw_recv.h +new file mode 100644 +index 000000000000..d1d1ca0e56d6 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_recv.h +@@ -0,0 +1,413 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#ifndef _RTW_RECV_H_ ++#define _RTW_RECV_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define NR_RECVFRAME 256 ++ ++#define RXFRAME_ALIGN 8 ++#define RXFRAME_ALIGN_SZ (1<signal_stat_timer, \ ++ (recvpriv)->signal_stat_sampling_interval) ++ ++struct sta_recv_priv { ++ spinlock_t lock; ++ int option; ++ struct __queue defrag_q; /* keeping the fragment frame until defrag */ ++ struct stainfo_rxcache rxcache; ++}; ++ ++struct recv_buf { ++ struct list_head list; ++ spinlock_t recvbuf_lock; ++ u32 ref_cnt; ++ struct adapter *adapter; ++ u8 *pbuf; ++ u8 *pallocated_buf; ++ u32 len; ++ u8 *phead; ++ u8 *pdata; ++ u8 *ptail; ++ u8 *pend; ++ struct urb *purb; ++ dma_addr_t dma_transfer_addr; /* (in) dma addr for transfer_buffer */ ++ u32 alloc_sz; ++ u8 irp_pending; ++ int transfer_len; ++ struct sk_buff *pskb; ++ u8 reuse; ++}; ++ ++/* ++ head -----> ++ ++ data -----> ++ ++ payload ++ ++ tail -----> ++ ++ end -----> ++ ++ len = (unsigned int )(tail - data); ++ ++*/ ++struct recv_frame { ++ struct list_head list; ++ struct sk_buff *pkt; ++ struct sk_buff *pkt_newalloc; ++ struct adapter *adapter; ++ u8 fragcnt; ++ int frame_tag; ++ struct rx_pkt_attrib attrib; ++ uint len; ++ u8 *rx_head; ++ u8 *rx_data; ++ u8 *rx_tail; ++ u8 *rx_end; ++ void *precvbuf; ++ struct sta_info *psta; ++ /* for A-MPDU Rx reordering buffer control */ ++ struct recv_reorder_ctrl *preorder_ctrl; ++}; ++ ++struct recv_frame *_rtw_alloc_recvframe(struct __queue *pfree_recv_queue); ++struct recv_frame *rtw_alloc_recvframe(struct __queue *pfree_recv_queue); ++void rtw_init_recvframe(struct recv_frame *precvframe, ++ struct recv_priv *precvpriv); ++int rtw_free_recvframe(struct recv_frame *precvframe, ++ struct __queue *pfree_recv_queue); ++#define rtw_dequeue_recvframe(queue) rtw_alloc_recvframe(queue) ++int _rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue); ++int rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue); ++void rtw_free_recvframe_queue(struct __queue *pframequeue, ++ struct __queue *pfree_recv_queue); ++u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter); ++int rtw_enqueue_recvbuf_to_head(struct recv_buf *buf, struct __queue *queue); ++int rtw_enqueue_recvbuf(struct recv_buf *precvbuf, struct __queue *queue); ++struct recv_buf *rtw_dequeue_recvbuf(struct __queue *queue); ++ ++void rtw_reordering_ctrl_timeout_handler(void *pcontext); ++ ++static inline u8 *get_rxmem(struct recv_frame *precvframe) ++{ ++ /* always return rx_head... */ ++ if (precvframe == NULL) ++ return NULL; ++ return precvframe->rx_head; ++} ++ ++static inline u8 *get_rx_status(struct recv_frame *precvframe) ++{ ++ return get_rxmem(precvframe); ++} ++ ++static inline u8 *get_recvframe_data(struct recv_frame *precvframe) ++{ ++ /* always return rx_data */ ++ if (precvframe == NULL) ++ return NULL; ++ ++ return precvframe->rx_data; ++} ++ ++static inline u8 *recvframe_push(struct recv_frame *precvframe, int sz) ++{ ++ /* append data before rx_data */ ++ ++ /* add data to the start of recv_frame ++ * ++ * This function extends the used data area of the recv_frame at the buffer ++ * start. rx_data must be still larger than rx_head, after pushing. ++ */ ++ if (precvframe == NULL) ++ return NULL; ++ precvframe->rx_data -= sz ; ++ if (precvframe->rx_data < precvframe->rx_head) { ++ precvframe->rx_data += sz; ++ return NULL; ++ } ++ precvframe->len += sz; ++ return precvframe->rx_data; ++} ++ ++static inline u8 *recvframe_pull(struct recv_frame *precvframe, int sz) ++{ ++ /* rx_data += sz; move rx_data sz bytes hereafter */ ++ ++ /* used for extract sz bytes from rx_data, update rx_data and return ++ * the updated rx_data to the caller */ ++ ++ if (precvframe == NULL) ++ return NULL; ++ precvframe->rx_data += sz; ++ if (precvframe->rx_data > precvframe->rx_tail) { ++ precvframe->rx_data -= sz; ++ return NULL; ++ } ++ precvframe->len -= sz; ++ return precvframe->rx_data; ++} ++ ++static inline u8 *recvframe_put(struct recv_frame *precvframe, int sz) ++{ ++ /* used for append sz bytes from ptr to rx_tail, update rx_tail ++ * and return the updated rx_tail to the caller */ ++ /* after putting, rx_tail must be still larger than rx_end. */ ++ ++ if (precvframe == NULL) ++ return NULL; ++ ++ precvframe->rx_tail += sz; ++ ++ if (precvframe->rx_tail > precvframe->rx_end) { ++ precvframe->rx_tail -= sz; ++ return NULL; ++ } ++ precvframe->len += sz; ++ return precvframe->rx_tail; ++} ++ ++static inline u8 *recvframe_pull_tail(struct recv_frame *precvframe, int sz) ++{ ++ /* rmv data from rx_tail (by yitsen) */ ++ ++ /* used for extract sz bytes from rx_end, update rx_end and return ++ * the updated rx_end to the caller */ ++ /* after pulling, rx_end must be still larger than rx_data. */ ++ ++ if (precvframe == NULL) ++ return NULL; ++ precvframe->rx_tail -= sz; ++ if (precvframe->rx_tail < precvframe->rx_data) { ++ precvframe->rx_tail += sz; ++ return NULL; ++ } ++ precvframe->len -= sz; ++ return precvframe->rx_tail; ++} ++ ++static inline int get_recvframe_len(struct recv_frame *precvframe) ++{ ++ return precvframe->len; ++} ++ ++static inline s32 translate_percentage_to_dbm(u32 sig_stren_index) ++{ ++ s32 power; /* in dBm. */ ++ ++ /* Translate to dBm (x=0.5y-95). */ ++ power = (s32)((sig_stren_index + 1) >> 1); ++ power -= 95; ++ ++ return power; ++} ++ ++struct sta_info; ++ ++void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv); ++ ++void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_rf.h b/drivers/staging/r8188eu/include/rtw_rf.h +new file mode 100644 +index 000000000000..48129da9c93f +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_rf.h +@@ -0,0 +1,126 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_RF_H_ ++#define __RTW_RF_H_ ++ ++#include "rtw_cmd.h" ++ ++#define OFDM_PHY 1 ++#define MIXED_PHY 2 ++#define CCK_PHY 3 ++ ++#define NumRates (13) ++ ++/* slot time for 11g */ ++#define SHORT_SLOT_TIME 9 ++#define NON_SHORT_SLOT_TIME 20 ++ ++#define RTL8711_RF_MAX_SENS 6 ++#define RTL8711_RF_DEF_SENS 4 ++ ++/* We now define the following channels as the max channels in each ++ * channel plan. */ ++/* 2G, total 14 chnls */ ++/* {1,2,3,4,5,6,7,8,9,10,11,12,13,14} */ ++#define MAX_CHANNEL_NUM_2G 14 ++#define MAX_CHANNEL_NUM 14 /* 2.4 GHz only */ ++ ++#define NUM_REGULATORYS 1 ++ ++/* Country codes */ ++#define USA 0x555320 ++#define EUROPE 0x1 /* temp, should be provided later */ ++#define JAPAN 0x2 /* temp, should be provided later */ ++ ++struct regulatory_class { ++ u32 starting_freq; /* MHz, */ ++ u8 channel_set[MAX_CHANNEL_NUM]; ++ u8 channel_cck_power[MAX_CHANNEL_NUM]; /* dbm */ ++ u8 channel_ofdm_power[MAX_CHANNEL_NUM]; /* dbm */ ++ u8 txpower_limit; /* dbm */ ++ u8 channel_spacing; /* MHz */ ++ u8 modem; ++}; ++ ++enum capability { ++ cESS = 0x0001, ++ cIBSS = 0x0002, ++ cPollable = 0x0004, ++ cPollReq = 0x0008, ++ cPrivacy = 0x0010, ++ cShortPreamble = 0x0020, ++ cPBCC = 0x0040, ++ cChannelAgility = 0x0080, ++ cSpectrumMgnt = 0x0100, ++ cQos = 0x0200, /* For HCCA, use with CF-Pollable ++ * and CF-PollReq */ ++ cShortSlotTime = 0x0400, ++ cAPSD = 0x0800, ++ cRM = 0x1000, /* RRM (Radio Request Measurement) */ ++ cDSSS_OFDM = 0x2000, ++ cDelayedBA = 0x4000, ++ cImmediateBA = 0x8000, ++}; ++ ++enum _REG_PREAMBLE_MODE { ++ PREAMBLE_LONG = 1, ++ PREAMBLE_AUTO = 2, ++ PREAMBLE_SHORT = 3, ++}; ++ ++enum _RTL8712_RF_MIMO_CONFIG_ { ++ RTL8712_RFCONFIG_1T = 0x10, ++ RTL8712_RFCONFIG_2T = 0x20, ++ RTL8712_RFCONFIG_1R = 0x01, ++ RTL8712_RFCONFIG_2R = 0x02, ++ RTL8712_RFCONFIG_1T1R = 0x11, ++ RTL8712_RFCONFIG_1T2R = 0x12, ++ RTL8712_RFCONFIG_TURBO = 0x92, ++ RTL8712_RFCONFIG_2T2R = 0x22 ++}; ++ ++enum rf90_radio_path { ++ RF90_PATH_A = 0, /* Radio Path A */ ++ RF90_PATH_B = 1, /* Radio Path B */ ++ RF90_PATH_C = 2, /* Radio Path C */ ++ RF90_PATH_D = 3 /* Radio Path D */ ++}; ++ ++/* Bandwidth Offset */ ++#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 ++#define HAL_PRIME_CHNL_OFFSET_LOWER 1 ++#define HAL_PRIME_CHNL_OFFSET_UPPER 2 ++ ++/* Represent Channel Width in HT Capabilities */ ++/* */ ++enum ht_channel_width { ++ HT_CHANNEL_WIDTH_20 = 0, ++ HT_CHANNEL_WIDTH_40 = 1, ++}; ++ ++/* */ ++/* Represent Extension Channel Offset in HT Capabilities */ ++/* This is available only in 40Mhz mode. */ ++/* */ ++enum ht_extchnl_offset { ++ HT_EXTCHNL_OFFSET_NO_EXT = 0, ++ HT_EXTCHNL_OFFSET_UPPER = 1, ++ HT_EXTCHNL_OFFSET_NO_DEF = 2, ++ HT_EXTCHNL_OFFSET_LOWER = 3, ++}; ++ ++/* 2007/11/15 MH Define different RF type. */ ++enum rt_rf_type_def { ++ RF_1T2R = 0, ++ RF_2T4R = 1, ++ RF_2T2R = 2, ++ RF_1T1R = 3, ++ RF_2T2R_GREEN = 4, ++ RF_819X_MAX_TYPE = 5, ++}; ++ ++u32 rtw_ch2freq(u32 ch); ++u32 rtw_freq2ch(u32 freq); ++ ++#endif /* _RTL8711_RF_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_security.h b/drivers/staging/r8188eu/include/rtw_security.h +new file mode 100644 +index 000000000000..ec6ecdb7bc98 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_security.h +@@ -0,0 +1,341 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_SECURITY_H_ ++#define __RTW_SECURITY_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define _NO_PRIVACY_ 0x0 ++#define _WEP40_ 0x1 ++#define _TKIP_ 0x2 ++#define _TKIP_WTMIC_ 0x3 ++#define _AES_ 0x4 ++#define _WEP104_ 0x5 ++#define _WEP_WPA_MIXED_ 0x07 /* WEP + WPA */ ++#define _SMS4_ 0x06 ++ ++#define is_wep_enc(alg) (((alg) == _WEP40_) || ((alg) == _WEP104_)) ++ ++#define _WPA_IE_ID_ 0xdd ++#define _WPA2_IE_ID_ 0x30 ++ ++#define SHA256_MAC_LEN 32 ++#define AES_BLOCK_SIZE 16 ++#define AES_PRIV_SIZE (4 * 44) ++ ++enum { ++ ENCRYP_PROTOCOL_OPENSYS, /* open system */ ++ ENCRYP_PROTOCOL_WEP, /* WEP */ ++ ENCRYP_PROTOCOL_WPA, /* WPA */ ++ ENCRYP_PROTOCOL_WPA2, /* WPA2 */ ++ ENCRYP_PROTOCOL_WAPI, /* WAPI: Not support in this version */ ++ ENCRYP_PROTOCOL_MAX ++}; ++ ++#ifndef Ndis802_11AuthModeWPA2 ++#define Ndis802_11AuthModeWPA2 (Ndis802_11AuthModeWPANone + 1) ++#endif ++ ++#ifndef Ndis802_11AuthModeWPA2PSK ++#define Ndis802_11AuthModeWPA2PSK (Ndis802_11AuthModeWPANone + 2) ++#endif ++ ++union pn48 { ++ u64 val; ++ ++#ifdef __LITTLE_ENDIAN ++ struct { ++ u8 TSC0; ++ u8 TSC1; ++ u8 TSC2; ++ u8 TSC3; ++ u8 TSC4; ++ u8 TSC5; ++ u8 TSC6; ++ u8 TSC7; ++ } _byte_; ++ ++#elif defined(__BIG_ENDIAN) ++ ++ struct { ++ u8 TSC7; ++ u8 TSC6; ++ u8 TSC5; ++ u8 TSC4; ++ u8 TSC3; ++ u8 TSC2; ++ u8 TSC1; ++ u8 TSC0; ++ } _byte_; ++#endif ++}; ++ ++union Keytype { ++ u8 skey[16]; ++ u32 lkey[4]; ++}; ++ ++struct rt_pmkid_list { ++ u8 bUsed; ++ u8 Bssid[6]; ++ u8 PMKID[16]; ++ u8 SsidBuf[33]; ++ u8 *ssid_octet; ++ u16 ssid_length; ++}; ++ ++struct security_priv { ++ u32 dot11AuthAlgrthm; /* 802.11 auth, could be open, ++ * shared, 8021x and authswitch */ ++ u32 dot11PrivacyAlgrthm; /* This specify the privacy for ++ * shared auth. algorithm. */ ++ /* WEP */ ++ u32 dot11PrivacyKeyIndex; /* this is only valid for legendary ++ * wep, 0~3 for key id.(tx key index) */ ++ union Keytype dot11DefKey[4]; /* this is only valid for def. key */ ++ u32 dot11DefKeylen[4]; ++ u32 dot118021XGrpPrivacy; /* This specify the privacy algthm. ++ * used for Grp key */ ++ u32 dot118021XGrpKeyid; /* key id used for Grp Key ++ * ( tx key index) */ ++ union Keytype dot118021XGrpKey[4]; /* 802.1x Group Key, ++ * for inx0 and inx1 */ ++ union Keytype dot118021XGrptxmickey[4]; ++ union Keytype dot118021XGrprxmickey[4]; ++ union pn48 dot11Grptxpn; /* PN48 used for Grp Key xmit.*/ ++ union pn48 dot11Grprxpn; /* PN48 used for Grp Key recv.*/ ++#ifdef CONFIG_88EU_AP_MODE ++ /* extend security capabilities for AP_MODE */ ++ unsigned int dot8021xalg;/* 0:disable, 1:psk, 2:802.1x */ ++ unsigned int wpa_psk;/* 0:disable, bit(0): WPA, bit(1):WPA2 */ ++ unsigned int wpa_group_cipher; ++ unsigned int wpa2_group_cipher; ++ unsigned int wpa_pairwise_cipher; ++ unsigned int wpa2_pairwise_cipher; ++#endif ++ u8 wps_ie[MAX_WPS_IE_LEN];/* added in assoc req */ ++ int wps_ie_len; ++ u8 binstallGrpkey; ++ u8 busetkipkey; ++ u8 bcheck_grpkey; ++ u8 bgrpkey_handshake; ++ s32 sw_encrypt;/* from registry_priv */ ++ s32 sw_decrypt;/* from registry_priv */ ++ s32 hw_decrypted;/* if the rx packets is hw_decrypted==false,i ++ * it means the hw has not been ready. */ ++ ++ /* keeps the auth_type & enc_status from upper layer ++ * ioctl(wpa_supplicant or wzc) */ ++ u32 ndisauthtype; /* NDIS_802_11_AUTHENTICATION_MODE */ ++ u32 ndisencryptstatus; /* NDIS_802_11_ENCRYPTION_STATUS */ ++ struct wlan_bssid_ex sec_bss; /* for joinbss (h2c buffer) usage */ ++ struct ndis_802_11_wep ndiswep; ++ u8 assoc_info[600]; ++ u8 szofcapability[256]; /* for wpa2 usage */ ++ u8 oidassociation[512]; /* for wpa/wpa2 usage */ ++ u8 authenticator_ie[256]; /* store ap security information element */ ++ u8 supplicant_ie[256]; /* store sta security information element */ ++ ++ /* for tkip countermeasure */ ++ u32 last_mic_err_time; ++ u8 btkip_countermeasure; ++ u8 btkip_wait_report; ++ u32 btkip_countermeasure_time; ++ ++ /* */ ++ /* For WPA2 Pre-Authentication. */ ++ /* */ ++ struct rt_pmkid_list PMKIDList[NUM_PMKID_CACHE]; ++ u8 PMKIDIndex; ++ u8 bWepDefaultKeyIdxSet; ++}; ++ ++#define GET_ENCRY_ALGO(psecuritypriv, psta, encry_algo, bmcst) \ ++do { \ ++ switch (psecuritypriv->dot11AuthAlgrthm) { \ ++ case dot11AuthAlgrthm_Open: \ ++ case dot11AuthAlgrthm_Shared: \ ++ case dot11AuthAlgrthm_Auto: \ ++ encry_algo = (u8)psecuritypriv->dot11PrivacyAlgrthm; \ ++ break; \ ++ case dot11AuthAlgrthm_8021X: \ ++ if (bmcst) \ ++ encry_algo = (u8)psecuritypriv->dot118021XGrpPrivacy;\ ++ else \ ++ encry_algo = (u8)psta->dot118021XPrivacy; \ ++ break; \ ++ case dot11AuthAlgrthm_WAPI: \ ++ encry_algo = (u8)psecuritypriv->dot11PrivacyAlgrthm; \ ++ break; \ ++ } \ ++} while (0) ++ ++#define SET_ICE_IV_LEN(iv_len, icv_len, encrypt) \ ++do { \ ++ switch (encrypt) { \ ++ case _WEP40_: \ ++ case _WEP104_: \ ++ iv_len = 4; \ ++ icv_len = 4; \ ++ break; \ ++ case _TKIP_: \ ++ iv_len = 8; \ ++ icv_len = 4; \ ++ break; \ ++ case _AES_: \ ++ iv_len = 8; \ ++ icv_len = 8; \ ++ break; \ ++ case _SMS4_: \ ++ iv_len = 18; \ ++ icv_len = 16; \ ++ break; \ ++ default: \ ++ iv_len = 0; \ ++ icv_len = 0; \ ++ break; \ ++ } \ ++} while (0) ++ ++#define GET_TKIP_PN(iv, dot11txpn) \ ++do { \ ++ dot11txpn._byte_.TSC0 = iv[2]; \ ++ dot11txpn._byte_.TSC1 = iv[0]; \ ++ dot11txpn._byte_.TSC2 = iv[4]; \ ++ dot11txpn._byte_.TSC3 = iv[5]; \ ++ dot11txpn._byte_.TSC4 = iv[6]; \ ++ dot11txpn._byte_.TSC5 = iv[7]; \ ++} while (0) ++ ++#define ROL32(A, n) (((A) << (n)) | (((A)>>(32-(n))) & ((1UL << (n)) - 1))) ++#define ROR32(A, n) ROL32((A), 32-(n)) ++ ++struct mic_data { ++ u32 K0, K1; /* Key */ ++ u32 L, R; /* Current state */ ++ u32 M; /* Message accumulator (single word) */ ++ u32 nBytesInM; /* # bytes in M */ ++}; ++ ++extern const u32 Te0[256]; ++extern const u32 Te1[256]; ++extern const u32 Te2[256]; ++extern const u32 Te3[256]; ++extern const u32 Te4[256]; ++extern const u32 Td0[256]; ++extern const u32 Td1[256]; ++extern const u32 Td2[256]; ++extern const u32 Td3[256]; ++extern const u32 Td4[256]; ++extern const u32 rcon[10]; ++extern const u8 Td4s[256]; ++extern const u8 rcons[10]; ++ ++#define RCON(i) (rcons[(i)] << 24) ++ ++static inline u32 rotr(u32 val, int bits) ++{ ++ return (val >> bits) | (val << (32 - bits)); ++} ++ ++#define TE0(i) Te0[((i) >> 24) & 0xff] ++#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8) ++#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16) ++#define TE3(i) rotr(Te0[(i) & 0xff], 24) ++#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000) ++#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000) ++#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00) ++#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff) ++#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000) ++#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000) ++#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00) ++#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff) ++#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff) ++ ++#define TD0(i) Td0[((i) >> 24) & 0xff] ++#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8) ++#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16) ++#define TD3(i) rotr(Td0[(i) & 0xff], 24) ++#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24) ++#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16) ++#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8) ++#define TD44(i) (Td4s[(i) & 0xff]) ++#define TD0_(i) Td0[(i) & 0xff] ++#define TD1_(i) rotr(Td0[(i) & 0xff], 8) ++#define TD2_(i) rotr(Td0[(i) & 0xff], 16) ++#define TD3_(i) rotr(Td0[(i) & 0xff], 24) ++ ++#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \ ++ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) ++ ++#define PUTU32(ct, st) { \ ++(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \ ++(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } ++ ++#define WPA_GET_BE32(a) ((((u32)(a)[0]) << 24) | (((u32)(a)[1]) << 16) | \ ++ (((u32)(a)[2]) << 8) | ((u32)(a)[3])) ++ ++#define WPA_PUT_LE16(a, val) \ ++ do { \ ++ (a)[1] = ((u16)(val)) >> 8; \ ++ (a)[0] = ((u16)(val)) & 0xff; \ ++ } while (0) ++ ++#define WPA_PUT_BE32(a, val) \ ++ do { \ ++ (a)[0] = (u8)((((u32)(val)) >> 24) & 0xff); \ ++ (a)[1] = (u8)((((u32)(val)) >> 16) & 0xff); \ ++ (a)[2] = (u8)((((u32)(val)) >> 8) & 0xff); \ ++ (a)[3] = (u8)(((u32)(val)) & 0xff); \ ++ } while (0) ++ ++#define WPA_PUT_BE64(a, val) \ ++ do { \ ++ (a)[0] = (u8)(((u64)(val)) >> 56); \ ++ (a)[1] = (u8)(((u64)(val)) >> 48); \ ++ (a)[2] = (u8)(((u64)(val)) >> 40); \ ++ (a)[3] = (u8)(((u64)(val)) >> 32); \ ++ (a)[4] = (u8)(((u64)(val)) >> 24); \ ++ (a)[5] = (u8)(((u64)(val)) >> 16); \ ++ (a)[6] = (u8)(((u64)(val)) >> 8); \ ++ (a)[7] = (u8)(((u64)(val)) & 0xff); \ ++ } while (0) ++ ++/* ===== start - public domain SHA256 implementation ===== */ ++ ++/* This is based on SHA256 implementation in LibTomCrypt that was released into ++ * public domain by Tom St Denis. */ ++ ++/* Various logical functions */ ++#define RORc(x, y) \ ++ (((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y)&31)) | \ ++ ((unsigned long)(x) << (unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) ++#define Ch(x, y ,z) (z ^ (x & (y ^ z))) ++#define Maj(x, y, z) (((x | y) & z) | (x & y)) ++#define S(x, n) RORc((x), (n)) ++#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) ++#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) ++#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) ++#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) ++#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) ++#ifndef MIN ++#define MIN(x, y) (((x) < (y)) ? (x) : (y)) ++#endif ++ ++void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key); ++void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b); ++void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nBytes); ++void rtw_secgetmic(struct mic_data *pmicdata, u8 *dst); ++void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, ++ u8 *Miccode, u8 priority); ++u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe); ++u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe); ++void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe); ++u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe); ++u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe); ++void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe); ++void rtw_use_tkipkey_handler(void *FunctionContext); ++ ++#endif /* __RTL871X_SECURITY_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_sreset.h b/drivers/staging/r8188eu/include/rtw_sreset.h +new file mode 100644 +index 000000000000..4e97997c305b +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_sreset.h +@@ -0,0 +1,34 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#ifndef _RTW_SRESET_C_ ++#define _RTW_SRESET_C_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++struct sreset_priv { ++ struct mutex silentreset_mutex; ++ u8 silent_reset_inprogress; ++ u8 wifi_error_status; ++ unsigned long last_tx_time; ++ unsigned long last_tx_complete_time; ++}; ++ ++#include "rtl8188e_hal.h" ++ ++#define WIFI_STATUS_SUCCESS 0 ++#define USB_VEN_REQ_CMD_FAIL BIT(0) ++#define USB_READ_PORT_FAIL BIT(1) ++#define USB_WRITE_PORT_FAIL BIT(2) ++#define WIFI_MAC_TXDMA_ERROR BIT(3) ++#define WIFI_TX_HANG BIT(4) ++#define WIFI_RX_HANG BIT(5) ++#define WIFI_IF_NOT_EXIST BIT(6) ++ ++void sreset_init_value(struct adapter *padapter); ++void sreset_reset_value(struct adapter *padapter); ++u8 sreset_get_wifi_status(struct adapter *padapter); ++void sreset_set_wifi_error_status(struct adapter *padapter, u32 status); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_xmit.h b/drivers/staging/r8188eu/include/rtw_xmit.h +new file mode 100644 +index 000000000000..5f6e2402e5c4 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_xmit.h +@@ -0,0 +1,367 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_XMIT_H_ ++#define _RTW_XMIT_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define MAX_XMITBUF_SZ (20480) /* 20k */ ++#define NR_XMITBUFF (4) ++ ++#define XMITBUF_ALIGN_SZ 4 ++ ++/* xmit extension buff defination */ ++#define MAX_XMIT_EXTBUF_SZ (1536) ++#define NR_XMIT_EXTBUFF (32) ++ ++#define MAX_NUMBLKS (1) ++ ++#define XMIT_VO_QUEUE (0) ++#define XMIT_VI_QUEUE (1) ++#define XMIT_BE_QUEUE (2) ++#define XMIT_BK_QUEUE (3) ++ ++#define VO_QUEUE_INX 0 ++#define VI_QUEUE_INX 1 ++#define BE_QUEUE_INX 2 ++#define BK_QUEUE_INX 3 ++#define BCN_QUEUE_INX 4 ++#define MGT_QUEUE_INX 5 ++#define HIGH_QUEUE_INX 6 ++#define TXCMD_QUEUE_INX 7 ++ ++#define HW_QUEUE_ENTRY 8 ++ ++#define WEP_IV(pattrib_iv, dot11txpn, keyidx)\ ++do {\ ++ pattrib_iv[0] = dot11txpn._byte_.TSC0;\ ++ pattrib_iv[1] = dot11txpn._byte_.TSC1;\ ++ pattrib_iv[2] = dot11txpn._byte_.TSC2;\ ++ pattrib_iv[3] = ((keyidx & 0x3)<<6);\ ++ dot11txpn.val = (dot11txpn.val == 0xffffff) ? 0 : (dot11txpn.val+1);\ ++} while (0) ++ ++#define TKIP_IV(pattrib_iv, dot11txpn, keyidx)\ ++do {\ ++ pattrib_iv[0] = dot11txpn._byte_.TSC1;\ ++ pattrib_iv[1] = (dot11txpn._byte_.TSC1 | 0x20) & 0x7f;\ ++ pattrib_iv[2] = dot11txpn._byte_.TSC0;\ ++ pattrib_iv[3] = BIT(5) | ((keyidx & 0x3)<<6);\ ++ pattrib_iv[4] = dot11txpn._byte_.TSC2;\ ++ pattrib_iv[5] = dot11txpn._byte_.TSC3;\ ++ pattrib_iv[6] = dot11txpn._byte_.TSC4;\ ++ pattrib_iv[7] = dot11txpn._byte_.TSC5;\ ++ dot11txpn.val = dot11txpn.val == 0xffffffffffffULL ? 0 : (dot11txpn.val+1);\ ++} while (0) ++ ++#define AES_IV(pattrib_iv, dot11txpn, keyidx)\ ++do { \ ++ pattrib_iv[0] = dot11txpn._byte_.TSC0; \ ++ pattrib_iv[1] = dot11txpn._byte_.TSC1; \ ++ pattrib_iv[2] = 0; \ ++ pattrib_iv[3] = BIT(5) | ((keyidx & 0x3)<<6); \ ++ pattrib_iv[4] = dot11txpn._byte_.TSC2; \ ++ pattrib_iv[5] = dot11txpn._byte_.TSC3; \ ++ pattrib_iv[6] = dot11txpn._byte_.TSC4; \ ++ pattrib_iv[7] = dot11txpn._byte_.TSC5; \ ++ dot11txpn.val = dot11txpn.val == 0xffffffffffffULL ? 0 : (dot11txpn.val+1);\ ++} while (0) ++ ++#define HWXMIT_ENTRY 4 ++ ++#define TXDESC_SIZE 32 ++ ++#define PACKET_OFFSET_SZ (8) ++#define TXDESC_OFFSET (TXDESC_SIZE + PACKET_OFFSET_SZ) ++ ++struct tx_desc { ++ /* DWORD 0 */ ++ __le32 txdw0; ++ __le32 txdw1; ++ __le32 txdw2; ++ __le32 txdw3; ++ __le32 txdw4; ++ __le32 txdw5; ++ __le32 txdw6; ++ __le32 txdw7; ++}; ++ ++union txdesc { ++ struct tx_desc txdesc; ++ unsigned int value[TXDESC_SIZE>>2]; ++}; ++ ++struct hw_xmit { ++ struct __queue *sta_queue; ++ int accnt; ++}; ++ ++/* reduce size */ ++struct pkt_attrib { ++ u8 type; ++ u8 subtype; ++ u8 bswenc; ++ u8 dhcp_pkt; ++ u16 ether_type; ++ u16 seqnum; ++ u16 pkt_hdrlen; /* the original 802.3 pkt header len */ ++ u16 hdrlen; /* the WLAN Header Len */ ++ u32 pktlen; /* the original 802.3 pkt raw_data len (not include ++ * ether_hdr data) */ ++ u32 last_txcmdsz; ++ u8 nr_frags; ++ u8 encrypt; /* when 0 indicate no encrypt. when non-zero, ++ * indicate the encrypt algorith */ ++ u8 iv_len; ++ u8 icv_len; ++ u8 iv[18]; ++ u8 icv[16]; ++ u8 priority; ++ u8 ack_policy; ++ u8 mac_id; ++ u8 vcs_mode; /* virtual carrier sense method */ ++ u8 dst[ETH_ALEN] __aligned(2); ++ u8 src[ETH_ALEN] __aligned(2); ++ u8 ta[ETH_ALEN] __aligned(2); ++ u8 ra[ETH_ALEN] __aligned(2); ++ u8 key_idx; ++ u8 qos_en; ++ u8 ht_en; ++ u8 raid;/* rate adpative id */ ++ u8 bwmode; ++ u8 ch_offset;/* PRIME_CHNL_OFFSET */ ++ u8 sgi;/* short GI */ ++ u8 ampdu_en;/* tx ampdu enable */ ++ u8 mdata;/* more data bit */ ++ u8 pctrl;/* per packet txdesc control enable */ ++ u8 triggered;/* for ap mode handling Power Saving sta */ ++ u8 qsel; ++ u8 eosp; ++ u8 rate; ++ u8 intel_proxim; ++ u8 retry_ctrl; ++ struct sta_info *psta; ++}; ++ ++#define WLANHDR_OFFSET 64 ++ ++#define NULL_FRAMETAG (0x0) ++#define DATA_FRAMETAG 0x01 ++#define L2_FRAMETAG 0x02 ++#define MGNT_FRAMETAG 0x03 ++#define AMSDU_FRAMETAG 0x04 ++ ++#define EII_FRAMETAG 0x05 ++#define IEEE8023_FRAMETAG 0x06 ++ ++#define MP_FRAMETAG 0x07 ++ ++#define TXAGG_FRAMETAG 0x08 ++ ++struct submit_ctx { ++ u32 submit_time; /* */ ++ u32 timeout_ms; /* <0: not synchronous, 0: wait forever, >0: up to ms waiting */ ++ int status; /* status for operation */ ++ struct completion done; ++}; ++ ++enum { ++ RTW_SCTX_SUBMITTED = -1, ++ RTW_SCTX_DONE_SUCCESS = 0, ++ RTW_SCTX_DONE_UNKNOWN, ++ RTW_SCTX_DONE_TIMEOUT, ++ RTW_SCTX_DONE_BUF_ALLOC, ++ RTW_SCTX_DONE_BUF_FREE, ++ RTW_SCTX_DONE_WRITE_PORT_ERR, ++ RTW_SCTX_DONE_TX_DESC_NA, ++ RTW_SCTX_DONE_TX_DENY, ++ RTW_SCTX_DONE_CCX_PKT_FAIL, ++ RTW_SCTX_DONE_DRV_STOP, ++ RTW_SCTX_DONE_DEV_REMOVE, ++}; ++ ++void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms); ++int rtw_sctx_wait(struct submit_ctx *sctx); ++void rtw_sctx_done_err(struct submit_ctx **sctx, int status); ++void rtw_sctx_done(struct submit_ctx **sctx); ++ ++struct xmit_buf { ++ struct list_head list; ++ struct adapter *padapter; ++ u8 *pallocated_buf; ++ u8 *pbuf; ++ void *priv_data; ++ u16 ext_tag; /* 0: Normal xmitbuf, 1: extension xmitbuf. */ ++ u16 flags; ++ u32 alloc_sz; ++ u32 len; ++ struct submit_ctx *sctx; ++ u32 ff_hwaddr; ++ struct urb *pxmit_urb[8]; ++ dma_addr_t dma_transfer_addr; /* (in) dma addr for transfer_buffer */ ++ u8 bpending[8]; ++ int last[8]; ++}; ++ ++struct xmit_frame { ++ struct list_head list; ++ struct pkt_attrib attrib; ++ struct sk_buff *pkt; ++ int frame_tag; ++ struct adapter *padapter; ++ u8 *buf_addr; ++ struct xmit_buf *pxmitbuf; ++ ++ u8 agg_num; ++ s8 pkt_offset; ++ u8 ack_report; ++}; ++ ++struct tx_servq { ++ struct list_head tx_pending; ++ struct __queue sta_pending; ++ int qcnt; ++}; ++ ++struct sta_xmit_priv { ++ spinlock_t lock; ++ int option; ++ int apsd_setting; /* When bit mask is on, the associated edca ++ * queue supports APSD. */ ++ struct tx_servq be_q; /* priority == 0,3 */ ++ struct tx_servq bk_q; /* priority == 1,2 */ ++ struct tx_servq vi_q; /* priority == 4,5 */ ++ struct tx_servq vo_q; /* priority == 6,7 */ ++ struct list_head legacy_dz; ++ struct list_head apsd; ++ u16 txseq_tid[16]; ++}; ++ ++struct hw_txqueue { ++ volatile int head; ++ volatile int tail; ++ volatile int free_sz; /* in units of 64 bytes */ ++ volatile int free_cmdsz; ++ volatile int txsz[8]; ++ uint ff_hwaddr; ++ uint cmd_hwaddr; ++ int ac_tag; ++}; ++ ++struct agg_pkt_info { ++ u16 offset; ++ u16 pkt_len; ++}; ++ ++struct xmit_priv { ++ spinlock_t lock; ++ struct semaphore xmit_sema; ++ struct semaphore terminate_xmitthread_sema; ++ struct __queue be_pending; ++ struct __queue bk_pending; ++ struct __queue vi_pending; ++ struct __queue vo_pending; ++ struct __queue bm_pending; ++ u8 *pallocated_frame_buf; ++ u8 *pxmit_frame_buf; ++ uint free_xmitframe_cnt; ++ struct __queue free_xmit_queue; ++ uint frag_len; ++ struct adapter *adapter; ++ u8 vcs_setting; ++ u8 vcs; ++ u8 vcs_type; ++ u64 tx_bytes; ++ u64 tx_pkts; ++ u64 tx_drop; ++ u64 last_tx_bytes; ++ u64 last_tx_pkts; ++ struct hw_xmit *hwxmits; ++ u8 hwxmit_entry; ++ u8 wmm_para_seq[4];/* sequence for wmm ac parameter strength ++ * from large to small. it's value is 0->vo, ++ * 1->vi, 2->be, 3->bk. */ ++ struct semaphore tx_retevt;/* all tx return event; */ ++ u8 txirp_cnt;/* */ ++ struct tasklet_struct xmit_tasklet; ++ /* per AC pending irp */ ++ int beq_cnt; ++ int bkq_cnt; ++ int viq_cnt; ++ int voq_cnt; ++ struct __queue free_xmitbuf_queue; ++ struct __queue pending_xmitbuf_queue; ++ u8 *pallocated_xmitbuf; ++ u8 *pxmitbuf; ++ uint free_xmitbuf_cnt; ++ struct __queue free_xmit_extbuf_queue; ++ u8 *pallocated_xmit_extbuf; ++ u8 *pxmit_extbuf; ++ uint free_xmit_extbuf_cnt; ++ u16 nqos_ssn; ++ int ack_tx; ++ struct mutex ack_tx_mutex; ++ struct submit_ctx ack_tx_ops; ++}; ++ ++struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv); ++s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, ++ struct xmit_buf *pxmitbuf); ++struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv); ++s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, ++ struct xmit_buf *pxmitbuf); ++void rtw_count_tx_stats(struct adapter *padapter, ++ struct xmit_frame *pxmitframe, int sz); ++void rtw_update_protection(struct adapter *padapter, u8 *ie, uint ie_len); ++s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, ++ struct pkt_attrib *pattrib); ++s32 rtw_put_snap(u8 *data, u16 h_proto); ++ ++struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv); ++s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, ++ struct xmit_frame *pxmitframe); ++void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, ++ struct __queue *pframequeue); ++struct tx_servq *rtw_get_sta_pending(struct adapter *padapter, ++ struct sta_info *psta, int up, u8 *ac); ++s32 rtw_xmitframe_enqueue(struct adapter *padapter, ++ struct xmit_frame *pxmitframe); ++struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, ++ struct hw_xmit *phwxmit_i, int entry); ++ ++s32 rtw_xmit_classifier(struct adapter *padapter, ++ struct xmit_frame *pxmitframe); ++u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib); ++#define rtw_wlan_pkt_size(f) rtw_calculate_wlan_pkt_size_by_attribue(&f->attrib) ++s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, ++ struct xmit_frame *pxmitframe); ++s32 _rtw_init_hw_txqueue(struct hw_txqueue *phw_txqueue, u8 ac_tag); ++void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv); ++s32 rtw_txframes_pending(struct adapter *padapter); ++s32 rtw_txframes_sta_ac_pending(struct adapter *padapter, ++ struct pkt_attrib *pattrib); ++void rtw_init_hwxmits(struct hw_xmit *phwxmit, int entry); ++s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter); ++void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv); ++void rtw_alloc_hwxmits(struct adapter *padapter); ++void rtw_free_hwxmits(struct adapter *padapter); ++s32 rtw_xmit(struct adapter *padapter, struct sk_buff **pkt); ++ ++#if defined(CONFIG_88EU_AP_MODE) ++int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_frame *pxmitframe); ++void stop_sta_xmit(struct adapter *padapter, struct sta_info *psta); ++void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta); ++void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *psta); ++#endif ++ ++u8 qos_acm(u8 acm_mask, u8 priority); ++u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe); ++int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms); ++void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status); ++ ++/* include after declaring struct xmit_buf, in order to avoid warning */ ++#include "xmit_osdep.h" ++ ++#endif /* _RTL871X_XMIT_H_ */ +diff --git a/drivers/staging/r8188eu/include/sta_info.h b/drivers/staging/r8188eu/include/sta_info.h +new file mode 100644 +index 000000000000..8ff99fc6381d +--- /dev/null ++++ b/drivers/staging/r8188eu/include/sta_info.h +@@ -0,0 +1,368 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __STA_INFO_H_ ++#define __STA_INFO_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "wifi.h" ++ ++#define IBSS_START_MAC_ID 2 ++#define NUM_STA 32 ++#define NUM_ACL 16 ++ ++/* if mode ==0, then the sta is allowed once the addr is hit. */ ++/* if mode ==1, then the sta is rejected once the addr is non-hit. */ ++struct rtw_wlan_acl_node { ++ struct list_head list; ++ u8 addr[ETH_ALEN]; ++ u8 valid; ++}; ++ ++/* mode=0, disable */ ++/* mode=1, accept unless in deny list */ ++/* mode=2, deny unless in accept list */ ++struct wlan_acl_pool { ++ int mode; ++ int num; ++ struct rtw_wlan_acl_node aclnode[NUM_ACL]; ++ struct __queue acl_node_q; ++}; ++ ++struct rssi_sta { ++ s32 UndecoratedSmoothedPWDB; ++ s32 UndecoratedSmoothedCCK; ++ s32 UndecoratedSmoothedOFDM; ++ u64 PacketMap; ++ u8 ValidBit; ++}; ++ ++struct stainfo_stats { ++ u64 rx_mgnt_pkts; ++ u64 rx_beacon_pkts; ++ u64 rx_probereq_pkts; ++ u64 rx_probersp_pkts; ++ u64 rx_probersp_bm_pkts; ++ u64 rx_probersp_uo_pkts; ++ u64 rx_ctrl_pkts; ++ u64 rx_data_pkts; ++ ++ u64 last_rx_mgnt_pkts; ++ u64 last_rx_beacon_pkts; ++ u64 last_rx_probereq_pkts; ++ u64 last_rx_probersp_pkts; ++ u64 last_rx_probersp_bm_pkts; ++ u64 last_rx_probersp_uo_pkts; ++ u64 last_rx_ctrl_pkts; ++ u64 last_rx_data_pkts; ++ u64 rx_bytes; ++ u64 rx_drops; ++ u64 tx_pkts; ++ u64 tx_bytes; ++ u64 tx_drops; ++}; ++ ++struct sta_info { ++ spinlock_t lock; ++ struct list_head list; /* free_sta_queue */ ++ struct list_head hash_list; /* sta_hash */ ++ ++ struct sta_xmit_priv sta_xmitpriv; ++ struct sta_recv_priv sta_recvpriv; ++ ++ struct __queue sleep_q; ++ unsigned int sleepq_len; ++ ++ uint state; ++ uint aid; ++ uint mac_id; ++ uint qos_option; ++ u8 hwaddr[ETH_ALEN]; ++ ++ uint ieee8021x_blocked; /* 0: allowed, 1:blocked */ ++ uint dot118021XPrivacy; /* aes, tkip... */ ++ union Keytype dot11tkiptxmickey; ++ union Keytype dot11tkiprxmickey; ++ union Keytype dot118021x_UncstKey; ++ union pn48 dot11txpn; /* PN48 used for Unicast xmit. */ ++ union pn48 dot11rxpn; /* PN48 used for Unicast recv. */ ++ u8 bssrateset[16]; ++ u32 bssratelen; ++ s32 rssi; ++ s32 signal_quality; ++ ++ u8 cts2self; ++ u8 rtsen; ++ ++ u8 raid; ++ u8 init_rate; ++ u32 ra_mask; ++ u8 wireless_mode; /* NETWORK_TYPE */ ++ struct stainfo_stats sta_stats; ++ ++ /* for A-MPDU TX, ADDBA timeout check */ ++ struct timer_list addba_retry_timer; ++ ++ /* for A-MPDU Rx reordering buffer control */ ++ struct recv_reorder_ctrl recvreorder_ctrl[16]; ++ ++ /* for A-MPDU Tx */ ++ /* unsigned char ampdu_txen_bitmap; */ ++ u16 BA_starting_seqctrl[16]; ++ ++ struct ht_priv htpriv; ++ ++ /* Notes: */ ++ /* STA_Mode: */ ++ /* curr_network(mlme_priv/security_priv/qos/ht) + ++ * sta_info: (STA & AP) CAP/INFO */ ++ /* scan_q: AP CAP/INFO */ ++ ++ /* AP_Mode: */ ++ /* curr_network(mlme_priv/security_priv/qos/ht) : AP CAP/INFO */ ++ /* sta_info: (AP & STA) CAP/INFO */ ++ ++ struct list_head asoc_list; ++#ifdef CONFIG_88EU_AP_MODE ++ struct list_head auth_list; ++ ++ unsigned int expire_to; ++ unsigned int auth_seq; ++ unsigned int authalg; ++ unsigned char chg_txt[128]; ++ ++ u16 capability; ++ int flags; ++ ++ int dot8021xalg;/* 0:disable, 1:psk, 2:802.1x */ ++ int wpa_psk;/* 0:disable, bit(0): WPA, bit(1):WPA2 */ ++ int wpa_group_cipher; ++ int wpa2_group_cipher; ++ int wpa_pairwise_cipher; ++ int wpa2_pairwise_cipher; ++ ++ u8 bpairwise_key_installed; ++ ++ u8 wpa_ie[32]; ++ ++ u8 nonerp_set; ++ u8 no_short_slot_time_set; ++ u8 no_short_preamble_set; ++ u8 no_ht_gf_set; ++ u8 no_ht_set; ++ u8 ht_20mhz_set; ++ ++ unsigned int tx_ra_bitmap; ++ u8 qos_info; ++ ++ u8 max_sp_len; ++ u8 uapsd_bk;/* BIT(0): Delivery enabled, BIT(1): Trigger enabled */ ++ u8 uapsd_be; ++ u8 uapsd_vi; ++ u8 uapsd_vo; ++ ++ u8 has_legacy_ac; ++ unsigned int sleepq_ac_len; ++#endif /* CONFIG_88EU_AP_MODE */ ++ ++#ifdef CONFIG_88EU_P2P ++ /* p2p priv data */ ++ u8 is_p2p_device; ++ u8 p2p_status_code; ++ ++ /* p2p client info */ ++ u8 dev_addr[ETH_ALEN]; ++ u8 dev_cap; ++ u16 config_methods; ++ u8 primary_dev_type[8]; ++ u8 num_of_secdev_type; ++ u8 secdev_types_list[32];/* 32/8 == 4; */ ++ u16 dev_name_len; ++ u8 dev_name[32]; ++#endif /* CONFIG_88EU_P2P */ ++ u8 under_exist_checking; ++ u8 keep_alive_trycnt; ++ ++ /* for DM */ ++ struct rssi_sta rssi_stat; ++ ++ /* ================ODM Relative Info======================= */ ++ /* Please be careful, don't declare too much structure here. ++ * It will cost memory * STA support num. */ ++ /* 2011/10/20 MH Add for ODM STA info. */ ++ /* Driver Write */ ++ u8 bValid; /* record the sta status link or not? */ ++ u8 IOTPeer; /* Enum value. HT_IOT_PEER_E */ ++ u8 rssi_level; /* for Refresh RA mask */ ++ /* ODM Write */ ++ /* 1 PHY_STATUS_INFO */ ++ u8 RSSI_Path[4]; /* */ ++ u8 RSSI_Ave; ++ u8 RXEVM[4]; ++ u8 RXSNR[4]; ++ ++ /* ================ODM Relative Info======================= */ ++ /* */ ++ ++ /* To store the sequence number of received management frame */ ++ u16 RxMgmtFrameSeqNum; ++}; ++ ++#define sta_rx_pkts(sta) \ ++ (sta->sta_stats.rx_mgnt_pkts \ ++ + sta->sta_stats.rx_ctrl_pkts \ ++ + sta->sta_stats.rx_data_pkts) ++ ++#define sta_last_rx_pkts(sta) \ ++ (sta->sta_stats.last_rx_mgnt_pkts \ ++ + sta->sta_stats.last_rx_ctrl_pkts \ ++ + sta->sta_stats.last_rx_data_pkts) ++ ++#define sta_rx_data_pkts(sta) \ ++ (sta->sta_stats.rx_data_pkts) ++ ++#define sta_last_rx_data_pkts(sta) \ ++ (sta->sta_stats.last_rx_data_pkts) ++ ++#define sta_rx_mgnt_pkts(sta) \ ++ (sta->sta_stats.rx_mgnt_pkts) ++ ++#define sta_last_rx_mgnt_pkts(sta) \ ++ (sta->sta_stats.last_rx_mgnt_pkts) ++ ++#define sta_rx_beacon_pkts(sta) \ ++ (sta->sta_stats.rx_beacon_pkts) ++ ++#define sta_last_rx_beacon_pkts(sta) \ ++ (sta->sta_stats.last_rx_beacon_pkts) ++ ++#define sta_rx_probereq_pkts(sta) \ ++ (sta->sta_stats.rx_probereq_pkts) ++ ++#define sta_last_rx_probereq_pkts(sta) \ ++ (sta->sta_stats.last_rx_probereq_pkts) ++ ++#define sta_rx_probersp_pkts(sta) \ ++ (sta->sta_stats.rx_probersp_pkts) ++ ++#define sta_last_rx_probersp_pkts(sta) \ ++ (sta->sta_stats.last_rx_probersp_pkts) ++ ++#define sta_rx_probersp_bm_pkts(sta) \ ++ (sta->sta_stats.rx_probersp_bm_pkts) ++ ++#define sta_last_rx_probersp_bm_pkts(sta) \ ++ (sta->sta_stats.last_rx_probersp_bm_pkts) ++ ++#define sta_rx_probersp_uo_pkts(sta) \ ++ (sta->sta_stats.rx_probersp_uo_pkts) ++ ++#define sta_last_rx_probersp_uo_pkts(sta) \ ++ (sta->sta_stats.last_rx_probersp_uo_pkts) ++ ++#define sta_update_last_rx_pkts(sta) \ ++do { \ ++ sta->sta_stats.last_rx_mgnt_pkts = sta->sta_stats.rx_mgnt_pkts; \ ++ sta->sta_stats.last_rx_beacon_pkts = sta->sta_stats.rx_beacon_pkts; \ ++ sta->sta_stats.last_rx_probereq_pkts = sta->sta_stats.rx_probereq_pkts; \ ++ sta->sta_stats.last_rx_probersp_pkts = sta->sta_stats.rx_probersp_pkts; \ ++ sta->sta_stats.last_rx_probersp_bm_pkts = sta->sta_stats.rx_probersp_bm_pkts; \ ++ sta->sta_stats.last_rx_probersp_uo_pkts = sta->sta_stats.rx_probersp_uo_pkts; \ ++ sta->sta_stats.last_rx_ctrl_pkts = sta->sta_stats.rx_ctrl_pkts; \ ++ sta->sta_stats.last_rx_data_pkts = sta->sta_stats.rx_data_pkts; \ ++} while (0) ++ ++#define STA_RX_PKTS_ARG(sta) \ ++ sta->sta_stats.rx_mgnt_pkts \ ++ , sta->sta_stats.rx_ctrl_pkts \ ++ , sta->sta_stats.rx_data_pkts ++ ++#define STA_LAST_RX_PKTS_ARG(sta) \ ++ sta->sta_stats.last_rx_mgnt_pkts \ ++ , sta->sta_stats.last_rx_ctrl_pkts \ ++ , sta->sta_stats.last_rx_data_pkts ++ ++#define STA_RX_PKTS_DIFF_ARG(sta) \ ++ sta->sta_stats.rx_mgnt_pkts - sta->sta_stats.last_rx_mgnt_pkts \ ++ , sta->sta_stats.rx_ctrl_pkts - sta->sta_stats.last_rx_ctrl_pkts \ ++ , sta->sta_stats.rx_data_pkts - sta->sta_stats.last_rx_data_pkts ++ ++#define STA_PKTS_FMT "(m:%llu, c:%llu, d:%llu)" ++ ++struct sta_priv { ++ u8 *pallocated_stainfo_buf; ++ u8 *pstainfo_buf; ++ struct __queue free_sta_queue; ++ ++ spinlock_t sta_hash_lock; ++ struct list_head sta_hash[NUM_STA]; ++ int asoc_sta_count; ++ struct __queue sleep_q; ++ struct __queue wakeup_q; ++ ++ struct adapter *padapter; ++ ++ spinlock_t asoc_list_lock; ++ struct list_head asoc_list; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ struct list_head auth_list; ++ spinlock_t auth_list_lock; ++ u8 asoc_list_cnt; ++ u8 auth_list_cnt; ++ ++ unsigned int auth_to; /* sec, time to expire in authenticating. */ ++ unsigned int assoc_to; /* sec, time to expire before associating. */ ++ unsigned int expire_to; /* sec , time to expire after associated. */ ++ ++ /* pointers to STA info; based on allocated AID or NULL if AID free ++ * AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1 ++ * and so on ++ */ ++ struct sta_info *sta_aid[NUM_STA]; ++ ++ u16 sta_dz_bitmap;/* only support 15 stations, station aid bitmap ++ * for sleeping sta. */ ++ u16 tim_bitmap; /* only support 15 stations, aid=0~15 mapping ++ * bit0~bit15 */ ++ ++ u16 max_num_sta; ++ ++ struct wlan_acl_pool acl_list; ++#endif ++ ++}; ++ ++static inline u32 wifi_mac_hash(u8 *mac) ++{ ++ u32 x; ++ ++ x = mac[0]; ++ x = (x << 2) ^ mac[1]; ++ x = (x << 2) ^ mac[2]; ++ x = (x << 2) ^ mac[3]; ++ x = (x << 2) ^ mac[4]; ++ x = (x << 2) ^ mac[5]; ++ ++ x ^= x >> 8; ++ x = x & (NUM_STA - 1); ++ return x; ++} ++ ++extern u32 _rtw_init_sta_priv(struct sta_priv *pstapriv); ++extern u32 _rtw_free_sta_priv(struct sta_priv *pstapriv); ++ ++#define stainfo_offset_valid(offset) (offset < NUM_STA && offset >= 0) ++int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta); ++struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int off); ++ ++extern struct sta_info *rtw_alloc_stainfo(struct sta_priv *stapriv, u8 *hwaddr); ++extern u32 rtw_free_stainfo(struct adapter *adapt, struct sta_info *psta); ++extern void rtw_free_all_stainfo(struct adapter *adapt); ++extern struct sta_info *rtw_get_stainfo(struct sta_priv *stapriv, u8 *hwaddr); ++extern u32 rtw_init_bcmc_stainfo(struct adapter *adapt); ++extern struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter); ++extern u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr); ++ ++#endif /* _STA_INFO_H_ */ +diff --git a/drivers/staging/r8188eu/include/usb_ops.h b/drivers/staging/r8188eu/include/usb_ops.h +new file mode 100644 +index 000000000000..c53cc54b6b87 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/usb_ops.h +@@ -0,0 +1,72 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __USB_OPS_H_ ++#define __USB_OPS_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "osdep_intf.h" ++ ++#define REALTEK_USB_VENQT_READ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE) ++#define REALTEK_USB_VENQT_WRITE (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) ++#define REALTEK_USB_VENQT_CMD_REQ 0x05 ++#define REALTEK_USB_VENQT_CMD_IDX 0x00 ++ ++#define ALIGNMENT_UNIT 16 ++#define MAX_VENDOR_REQ_CMD_SIZE 254 /* 8188cu SIE Support */ ++#define MAX_USB_IO_CTL_SIZE (MAX_VENDOR_REQ_CMD_SIZE + ALIGNMENT_UNIT) ++ ++#include "usb_ops_linux.h" ++ ++void rtl8188eu_set_hw_type(struct adapter *padapter); ++#define hal_set_hw_type rtl8188eu_set_hw_type ++void rtl8188eu_set_intf_ops(struct _io_ops *pops); ++#define usb_set_intf_ops rtl8188eu_set_intf_ops ++ ++/* ++ * Increase and check if the continual_urb_error of this @param dvobjprivei ++ * is larger than MAX_CONTINUAL_URB_ERR ++ * @return true: ++ * @return false: ++ */ ++static inline int rtw_inc_and_chk_continual_urb_error(struct dvobj_priv *dvobj) ++{ ++ int ret = false; ++ int value; ++ value = atomic_inc_return(&dvobj->continual_urb_error); ++ if (value > MAX_CONTINUAL_URB_ERR) { ++ DBG_88E("[dvobj:%p][ERROR] continual_urb_error:%d > %d\n", ++ dvobj, value, MAX_CONTINUAL_URB_ERR); ++ ret = true; ++ } ++ return ret; ++} ++ ++/* ++* Set the continual_urb_error of this @param dvobjprive to 0 ++*/ ++static inline void rtw_reset_continual_urb_error(struct dvobj_priv *dvobj) ++{ ++ atomic_set(&dvobj->continual_urb_error, 0); ++} ++ ++#define USB_HIGH_SPEED_BULK_SIZE 512 ++#define USB_FULL_SPEED_BULK_SIZE 64 ++ ++static inline u8 rtw_usb_bulk_size_boundary(struct adapter *padapter, ++ int buf_len) ++{ ++ u8 rst = true; ++ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); ++ ++ if (pdvobjpriv->ishighspeed) ++ rst = (0 == (buf_len) % USB_HIGH_SPEED_BULK_SIZE) ? ++ true : false; ++ else ++ rst = (0 == (buf_len) % USB_FULL_SPEED_BULK_SIZE) ? ++ true : false; ++ return rst; ++} ++ ++#endif /* __USB_OPS_H_ */ +diff --git a/drivers/staging/r8188eu/include/usb_ops_linux.h b/drivers/staging/r8188eu/include/usb_ops_linux.h +new file mode 100644 +index 000000000000..c357a3b1560e +--- /dev/null ++++ b/drivers/staging/r8188eu/include/usb_ops_linux.h +@@ -0,0 +1,39 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __USB_OPS_LINUX_H__ ++#define __USB_OPS_LINUX_H__ ++ ++#define VENDOR_CMD_MAX_DATA_LEN 254 ++ ++#define RTW_USB_CONTROL_MSG_TIMEOUT_TEST 10/* ms */ ++#define RTW_USB_CONTROL_MSG_TIMEOUT 500/* ms */ ++ ++#define MAX_USBCTRL_VENDORREQ_TIMES 10 ++ ++#define RTW_USB_BULKOUT_TIME 5000/* ms */ ++ ++#define _usbctrl_vendorreq_async_callback(urb, regs) \ ++ _usbctrl_vendorreq_async_callback(urb) ++#define usb_bulkout_zero_complete(purb, regs) \ ++ usb_bulkout_zero_complete(purb) ++#define usb_write_mem_complete(purb, regs) \ ++ usb_write_mem_complete(purb) ++#define usb_write_port_complete(purb, regs) \ ++ usb_write_port_complete(purb) ++#define usb_read_port_complete(purb, regs) \ ++ usb_read_port_complete(purb) ++#define usb_read_interrupt_complete(purb, regs) \ ++ usb_read_interrupt_complete(purb) ++ ++unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr); ++ ++void usb_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem); ++void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem); ++ ++void usb_read_port_cancel(struct intf_hdl *pintfhdl); ++ ++u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem); ++void usb_write_port_cancel(struct intf_hdl *pintfhdl); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/usb_osintf.h b/drivers/staging/r8188eu/include/usb_osintf.h +new file mode 100644 +index 000000000000..d1a1f739309c +--- /dev/null ++++ b/drivers/staging/r8188eu/include/usb_osintf.h +@@ -0,0 +1,29 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __USB_OSINTF_H ++#define __USB_OSINTF_H ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "usb_vendor_req.h" ++ ++extern char *rtw_initmac; ++extern int rtw_mc2u_disable; ++ ++#define USBD_HALTED(Status) ((u32)(Status) >> 30 == 3) ++ ++u8 usbvendorrequest(struct dvobj_priv *pdvobjpriv, enum bt_usb_request brequest, ++ enum rt_usb_wvalue wvalue, u8 windex, void *data, ++ u8 datalen, u8 isdirectionin); ++int pm_netdev_open(struct net_device *pnetdev, u8 bnormal); ++void netdev_br_init(struct net_device *netdev); ++void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb); ++void *scdb_findEntry(struct adapter *priv, unsigned char *macAddr, ++ unsigned char *ipAddr); ++void nat25_db_expire(struct adapter *priv); ++int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method); ++ ++int rtw_resume_process(struct adapter *padapter); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/usb_vendor_req.h b/drivers/staging/r8188eu/include/usb_vendor_req.h +new file mode 100644 +index 000000000000..7337b1b7419f +--- /dev/null ++++ b/drivers/staging/r8188eu/include/usb_vendor_req.h +@@ -0,0 +1,35 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _USB_VENDOR_REQUEST_H_ ++#define _USB_VENDOR_REQUEST_H_ ++ ++/* 4 Set/Get Register related wIndex/Data */ ++#define RT_USB_RESET_MASK_OFF 0 ++#define RT_USB_RESET_MASK_ON 1 ++#define RT_USB_SLEEP_MASK_OFF 0 ++#define RT_USB_SLEEP_MASK_ON 1 ++#define RT_USB_LDO_ON 1 ++#define RT_USB_LDO_OFF 0 ++ ++/* 4 Set/Get SYSCLK related wValue or Data */ ++#define RT_USB_SYSCLK_32KHZ 0 ++#define RT_USB_SYSCLK_40MHZ 1 ++#define RT_USB_SYSCLK_60MHZ 2 ++ ++enum bt_usb_request { ++ RT_USB_SET_REGISTER = 1, ++ RT_USB_SET_SYSCLK = 2, ++ RT_USB_GET_SYSCLK = 3, ++ RT_USB_GET_REGISTER = 4 ++}; ++ ++enum rt_usb_wvalue { ++ RT_USB_RESET_MASK = 1, ++ RT_USB_SLEEP_MASK = 2, ++ RT_USB_USB_HRCPWM = 3, ++ RT_USB_LDO = 4, ++ RT_USB_BOOT_TYPE = 5 ++}; ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/wifi.h b/drivers/staging/r8188eu/include/wifi.h +new file mode 100644 +index 000000000000..0b3fd94cea18 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/wifi.h +@@ -0,0 +1,1029 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#ifndef _WIFI_H_ ++#define _WIFI_H_ ++ ++#include ++ ++#ifdef BIT ++/* error "BIT define occurred earlier elsewhere!\n" */ ++#undef BIT ++#endif ++#define BIT(x) (1 << (x)) ++ ++#define WLAN_ETHHDR_LEN 14 ++#define WLAN_ETHADDR_LEN 6 ++#define WLAN_IEEE_OUI_LEN 3 ++#define WLAN_ADDR_LEN 6 ++#define WLAN_CRC_LEN 4 ++#define WLAN_BSSID_LEN 6 ++#define WLAN_BSS_TS_LEN 8 ++#define WLAN_HDR_A3_LEN 24 ++#define WLAN_HDR_A4_LEN 30 ++#define WLAN_HDR_A3_QOS_LEN 26 ++#define WLAN_HDR_A4_QOS_LEN 32 ++#define WLAN_SSID_MAXLEN 32 ++#define WLAN_DATA_MAXLEN 2312 ++ ++#define WLAN_A3_PN_OFFSET 24 ++#define WLAN_A4_PN_OFFSET 30 ++ ++#define WLAN_MIN_ETHFRM_LEN 60 ++#define WLAN_MAX_ETHFRM_LEN 1514 ++#define WLAN_ETHHDR_LEN 14 ++ ++#define P80211CAPTURE_VERSION 0x80211001 ++ ++/* This value is tested by WiFi 11n Test Plan 5.2.3. */ ++/* This test verifies the WLAN NIC can update the NAV through sending ++ * the CTS with large duration. */ ++#define WiFiNavUpperUs 30000 /* 30 ms */ ++ ++enum WIFI_FRAME_TYPE { ++ WIFI_MGT_TYPE = (0), ++ WIFI_CTRL_TYPE = (BIT(2)), ++ WIFI_DATA_TYPE = (BIT(3)), ++ WIFI_QOS_DATA_TYPE = (BIT(7)|BIT(3)), /* QoS Data */ ++}; ++ ++enum WIFI_FRAME_SUBTYPE { ++ /* below is for mgt frame */ ++ WIFI_ASSOCREQ = (0 | WIFI_MGT_TYPE), ++ WIFI_ASSOCRSP = (BIT(4) | WIFI_MGT_TYPE), ++ WIFI_REASSOCREQ = (BIT(5) | WIFI_MGT_TYPE), ++ WIFI_REASSOCRSP = (BIT(5) | BIT(4) | WIFI_MGT_TYPE), ++ WIFI_PROBEREQ = (BIT(6) | WIFI_MGT_TYPE), ++ WIFI_PROBERSP = (BIT(6) | BIT(4) | WIFI_MGT_TYPE), ++ WIFI_BEACON = (BIT(7) | WIFI_MGT_TYPE), ++ WIFI_ATIM = (BIT(7) | BIT(4) | WIFI_MGT_TYPE), ++ WIFI_DISASSOC = (BIT(7) | BIT(5) | WIFI_MGT_TYPE), ++ WIFI_AUTH = (BIT(7) | BIT(5) | BIT(4) | WIFI_MGT_TYPE), ++ WIFI_DEAUTH = (BIT(7) | BIT(6) | WIFI_MGT_TYPE), ++ WIFI_ACTION = (BIT(7) | BIT(6) | BIT(4) | WIFI_MGT_TYPE), ++ ++ /* below is for control frame */ ++ WIFI_PSPOLL = (BIT(7) | BIT(5) | WIFI_CTRL_TYPE), ++ WIFI_RTS = (BIT(7) | BIT(5) | BIT(4) | WIFI_CTRL_TYPE), ++ WIFI_CTS = (BIT(7) | BIT(6) | WIFI_CTRL_TYPE), ++ WIFI_ACK = (BIT(7) | BIT(6) | BIT(4) | WIFI_CTRL_TYPE), ++ WIFI_CFEND = (BIT(7) | BIT(6) | BIT(5) | WIFI_CTRL_TYPE), ++ WIFI_CFEND_CFACK = (BIT(7) | BIT(6) | BIT(5) | BIT(4) | ++ WIFI_CTRL_TYPE), ++ ++ /* below is for data frame */ ++ WIFI_DATA = (0 | WIFI_DATA_TYPE), ++ WIFI_DATA_CFACK = (BIT(4) | WIFI_DATA_TYPE), ++ WIFI_DATA_CFPOLL = (BIT(5) | WIFI_DATA_TYPE), ++ WIFI_DATA_CFACKPOLL = (BIT(5) | BIT(4) | WIFI_DATA_TYPE), ++ WIFI_DATA_NULL = (BIT(6) | WIFI_DATA_TYPE), ++ WIFI_CF_ACK = (BIT(6) | BIT(4) | WIFI_DATA_TYPE), ++ WIFI_CF_POLL = (BIT(6) | BIT(5) | WIFI_DATA_TYPE), ++ WIFI_CF_ACKPOLL = (BIT(6) | BIT(5) | BIT(4) | WIFI_DATA_TYPE), ++ WIFI_QOS_DATA_NULL = (BIT(6) | WIFI_QOS_DATA_TYPE), ++}; ++ ++enum WIFI_REASON_CODE { ++ _RSON_RESERVED_ = 0, ++ _RSON_UNSPECIFIED_ = 1, ++ _RSON_AUTH_NO_LONGER_VALID_ = 2, ++ _RSON_DEAUTH_STA_LEAVING_ = 3, ++ _RSON_INACTIVITY_ = 4, ++ _RSON_UNABLE_HANDLE_ = 5, ++ _RSON_CLS2_ = 6, ++ _RSON_CLS3_ = 7, ++ _RSON_DISAOC_STA_LEAVING_ = 8, ++ _RSON_ASOC_NOT_AUTH_ = 9, ++ ++ /* WPA reason */ ++ _RSON_INVALID_IE_ = 13, ++ _RSON_MIC_FAILURE_ = 14, ++ _RSON_4WAY_HNDSHK_TIMEOUT_ = 15, ++ _RSON_GROUP_KEY_UPDATE_TIMEOUT_ = 16, ++ _RSON_DIFF_IE_ = 17, ++ _RSON_MLTCST_CIPHER_NOT_VALID_ = 18, ++ _RSON_UNICST_CIPHER_NOT_VALID_ = 19, ++ _RSON_AKMP_NOT_VALID_ = 20, ++ _RSON_UNSUPPORT_RSNE_VER_ = 21, ++ _RSON_INVALID_RSNE_CAP_ = 22, ++ _RSON_IEEE_802DOT1X_AUTH_FAIL_ = 23, ++ ++ /* belowing are Realtek definition */ ++ _RSON_PMK_NOT_AVAILABLE_ = 24, ++ _RSON_TDLS_TEAR_TOOFAR_ = 25, ++ _RSON_TDLS_TEAR_UN_RSN_ = 26, ++}; ++ ++/* Reason codes (IEEE 802.11-2007, 7.3.1.7, Table 7-22) ++ ++#define WLAN_REASON_UNSPECIFIED 1 ++#define WLAN_REASON_PREV_AUTH_NOT_VALID 2 ++#define WLAN_REASON_DEAUTH_LEAVING 3 ++#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 ++#define WLAN_REASON_DISASSOC_AP_BUSY 5 ++#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 ++#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 ++#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 ++#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 */ ++/* IEEE 802.11h */ ++#define WLAN_REASON_PWR_CAPABILITY_NOT_VALID 10 ++#define WLAN_REASON_SUPPORTED_CHANNEL_NOT_VALID 11 ++ ++/* IEEE 802.11i ++#define WLAN_REASON_INVALID_IE 13 ++#define WLAN_REASON_MICHAEL_MIC_FAILURE 14 ++#define WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT 15 ++#define WLAN_REASON_GROUP_KEY_UPDATE_TIMEOUT 16 ++#define WLAN_REASON_IE_IN_4WAY_DIFFERS 17 ++#define WLAN_REASON_GROUP_CIPHER_NOT_VALID 18 ++#define WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID 19 ++#define WLAN_REASON_AKMP_NOT_VALID 20 ++#define WLAN_REASON_UNSUPPORTED_RSN_IE_VERSION 21 ++#define WLAN_REASON_INVALID_RSN_IE_CAPAB 22 ++#define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23 ++#define WLAN_REASON_CIPHER_SUITE_REJECTED 24 */ ++ ++enum WIFI_STATUS_CODE { ++ _STATS_SUCCESSFUL_ = 0, ++ _STATS_FAILURE_ = 1, ++ _STATS_CAP_FAIL_ = 10, ++ _STATS_NO_ASOC_ = 11, ++ _STATS_OTHER_ = 12, ++ _STATS_NO_SUPP_ALG_ = 13, ++ _STATS_OUT_OF_AUTH_SEQ_ = 14, ++ _STATS_CHALLENGE_FAIL_ = 15, ++ _STATS_AUTH_TIMEOUT_ = 16, ++ _STATS_UNABLE_HANDLE_STA_ = 17, ++ _STATS_RATE_FAIL_ = 18, ++}; ++ ++/* Status codes (IEEE 802.11-2007, 7.3.1.9, Table 7-23) ++#define WLAN_STATUS_SUCCESS 0 ++#define WLAN_STATUS_UNSPECIFIED_FAILURE 1 ++#define WLAN_STATUS_CAPS_UNSUPPORTED 10 ++#define WLAN_STATUS_REASSOC_NO_ASSOC 11 ++#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 ++#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 ++#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 ++#define WLAN_STATUS_CHALLENGE_FAIL 15 ++#define WLAN_STATUS_AUTH_TIMEOUT 16 ++#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 ++#define WLAN_STATUS_ASSOC_DENIED_RATES 18 */ ++ ++/* entended */ ++/* IEEE 802.11b */ ++#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 ++#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20 ++#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21 ++/* IEEE 802.11h */ ++#define WLAN_STATUS_SPEC_MGMT_REQUIRED 22 ++#define WLAN_STATUS_PWR_CAPABILITY_NOT_VALID 23 ++#define WLAN_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24 ++/* IEEE 802.11g */ ++#define WLAN_STATUS_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25 ++#define WLAN_STATUS_ASSOC_DENIED_NO_ER_PBCC 26 ++#define WLAN_STATUS_ASSOC_DENIED_NO_DSSS_OFDM 27 ++/* IEEE 802.11w */ ++#define WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY 30 ++#define WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31 ++/* IEEE 802.11i */ ++#define WLAN_STATUS_INVALID_IE 40 ++#define WLAN_STATUS_GROUP_CIPHER_NOT_VALID 41 ++#define WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID 42 ++#define WLAN_STATUS_AKMP_NOT_VALID 43 ++#define WLAN_STATUS_UNSUPPORTED_RSN_IE_VERSION 44 ++#define WLAN_STATUS_INVALID_RSN_IE_CAPAB 45 ++#define WLAN_STATUS_CIPHER_REJECTED_PER_POLICY 46 ++#define WLAN_STATUS_TS_NOT_CREATED 47 ++#define WLAN_STATUS_DIRECT_LINK_NOT_ALLOWED 48 ++#define WLAN_STATUS_DEST_STA_NOT_PRESENT 49 ++#define WLAN_STATUS_DEST_STA_NOT_QOS_STA 50 ++#define WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE 51 ++/* IEEE 802.11r */ ++#define WLAN_STATUS_INVALID_FT_ACTION_FRAME_COUNT 52 ++#define WLAN_STATUS_INVALID_PMKID 53 ++#define WLAN_STATUS_INVALID_MDIE 54 ++#define WLAN_STATUS_INVALID_FTIE 55 ++ ++enum WIFI_REG_DOMAIN { ++ DOMAIN_FCC = 1, ++ DOMAIN_IC = 2, ++ DOMAIN_ETSI = 3, ++ DOMAIN_SPA = 4, ++ DOMAIN_FRANCE = 5, ++ DOMAIN_MKK = 6, ++ DOMAIN_ISRAEL = 7, ++ DOMAIN_MKK1 = 8, ++ DOMAIN_MKK2 = 9, ++ DOMAIN_MKK3 = 10, ++ DOMAIN_MAX ++}; ++ ++#define _TO_DS_ BIT(8) ++#define _FROM_DS_ BIT(9) ++#define _MORE_FRAG_ BIT(10) ++#define _RETRY_ BIT(11) ++#define _PWRMGT_ BIT(12) ++#define _MORE_DATA_ BIT(13) ++#define _PRIVACY_ BIT(14) ++#define _ORDER_ BIT(15) ++ ++#define SetToDs(pbuf) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(_TO_DS_) ++ ++#define GetToDs(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_TO_DS_)) != 0) ++ ++#define ClearToDs(pbuf) \ ++ *(__le16 *)(pbuf) &= (~cpu_to_le16(_TO_DS_)) ++ ++#define SetFrDs(pbuf) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(_FROM_DS_) ++ ++#define GetFrDs(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_FROM_DS_)) != 0) ++ ++#define ClearFrDs(pbuf) \ ++ *(__le16 *)(pbuf) &= (~cpu_to_le16(_FROM_DS_)) ++ ++#define get_tofr_ds(pframe) ((GetToDs(pframe) << 1) | GetFrDs(pframe)) ++ ++#define SetMFrag(pbuf) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(_MORE_FRAG_) ++ ++#define GetMFrag(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_MORE_FRAG_)) != 0) ++ ++#define ClearMFrag(pbuf) \ ++ *(__le16 *)(pbuf) &= (~cpu_to_le16(_MORE_FRAG_)) ++ ++#define SetRetry(pbuf) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(_RETRY_) ++ ++#define GetRetry(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_RETRY_)) != 0) ++ ++#define ClearRetry(pbuf) \ ++ *(__le16 *)(pbuf) &= (~cpu_to_le16(_RETRY_)) ++ ++#define SetPwrMgt(pbuf) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(_PWRMGT_) ++ ++#define GetPwrMgt(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_PWRMGT_)) != 0) ++ ++#define ClearPwrMgt(pbuf) \ ++ *(__le16 *)(pbuf) &= (~cpu_to_le16(_PWRMGT_)) ++ ++#define SetMData(pbuf) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(_MORE_DATA_) ++ ++#define GetMData(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_MORE_DATA_)) != 0) ++ ++#define ClearMData(pbuf) \ ++ *(__le16 *)(pbuf) &= (~cpu_to_le16(_MORE_DATA_)) ++ ++#define SetPrivacy(pbuf) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(_PRIVACY_) ++ ++#define GetPrivacy(pbuf) \ ++ (((*(__le16 *)(pbuf)) & cpu_to_le16(_PRIVACY_)) != 0) ++ ++#define ClearPrivacy(pbuf) \ ++ *(__le16 *)(pbuf) &= (~cpu_to_le16(_PRIVACY_)) ++ ++#define GetOrder(pbuf) \ ++ (((*(__le16 *)(pbuf)) & cpu_to_le16(_ORDER_)) != 0) ++ ++#define GetFrameType(pbuf) \ ++ (le16_to_cpu(*(__le16 *)(pbuf)) & (BIT(3) | BIT(2))) ++ ++#define SetFrameType(pbuf, type) \ ++ do { \ ++ *(unsigned short *)(pbuf) &= __constant_cpu_to_le16(~(BIT(3) | BIT(2))); \ ++ *(unsigned short *)(pbuf) |= __constant_cpu_to_le16(type); \ ++ } while (0) ++ ++#define GetFrameSubType(pbuf) (le16_to_cpu(*(__le16 *)(pbuf)) & (BIT(7) |\ ++ BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2))) ++ ++#define SetFrameSubType(pbuf, type) \ ++ do { \ ++ *(__le16 *)(pbuf) &= cpu_to_le16(~(BIT(7) | BIT(6) | \ ++ BIT(5) | BIT(4) | BIT(3) | BIT(2))); \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(type); \ ++ } while (0) ++ ++#define GetSequence(pbuf) \ ++ (le16_to_cpu(*(__le16 *)((size_t)(pbuf) + 22)) >> 4) ++ ++#define GetFragNum(pbuf) \ ++ (le16_to_cpu(*(__le16 *)((size_t)(pbuf) + 22)) & 0x0f) ++ ++#define GetTupleCache(pbuf) \ ++ (cpu_to_le16(*(unsigned short *)((size_t)(pbuf) + 22))) ++ ++#define SetFragNum(pbuf, num) \ ++ do { \ ++ *(unsigned short *)((size_t)(pbuf) + 22) = \ ++ ((*(unsigned short *)((size_t)(pbuf) + 22)) & \ ++ le16_to_cpu(~(0x000f))) | \ ++ cpu_to_le16(0x0f & (num)); \ ++ } while (0) ++ ++#define SetSeqNum(pbuf, num) \ ++ do { \ ++ *(__le16 *)((size_t)(pbuf) + 22) = \ ++ ((*(__le16 *)((size_t)(pbuf) + 22)) & cpu_to_le16((unsigned short)0x000f)) | \ ++ cpu_to_le16((unsigned short)(0xfff0 & (num << 4))); \ ++ } while (0) ++ ++#define SetDuration(pbuf, dur) \ ++ *(__le16 *)((size_t)(pbuf) + 2) = cpu_to_le16(0xffff & (dur)) ++ ++#define SetPriority(pbuf, tid) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(tid & 0xf) ++ ++#define GetPriority(pbuf) ((le16_to_cpu(*(__le16 *)(pbuf))) & 0xf) ++ ++#define SetEOSP(pbuf, eosp) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16((eosp & 1) << 4) ++ ++#define SetAckpolicy(pbuf, ack) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16((ack & 3) << 5) ++ ++#define GetAckpolicy(pbuf) (((le16_to_cpu(*(__le16 *)pbuf)) >> 5) & 0x3) ++ ++#define GetAMsdu(pbuf) (((le16_to_cpu(*(__le16 *)pbuf)) >> 7) & 0x1) ++ ++#define SetAMsdu(pbuf, amsdu) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16((amsdu & 1) << 7) ++ ++#define GetAid(pbuf) (le16_to_cpu(*(__le16 *)((size_t)(pbuf) + 2)) & 0x3fff) ++ ++#define GetTid(pbuf) (le16_to_cpu(*(__le16 *)((size_t)(pbuf) + \ ++ (((GetToDs(pbuf)<<1) | GetFrDs(pbuf)) == 3 ? \ ++ 30 : 24))) & 0x000f) ++ ++#define GetAddr1Ptr(pbuf) ((unsigned char *)((size_t)(pbuf) + 4)) ++ ++#define GetAddr2Ptr(pbuf) ((unsigned char *)((size_t)(pbuf) + 10)) ++ ++#define GetAddr3Ptr(pbuf) ((unsigned char *)((size_t)(pbuf) + 16)) ++ ++#define GetAddr4Ptr(pbuf) ((unsigned char *)((size_t)(pbuf) + 24)) ++ ++static inline int IS_MCAST(unsigned char *da) ++{ ++ if ((*da) & 0x01) ++ return true; ++ else ++ return false; ++} ++ ++static inline unsigned char *get_da(unsigned char *pframe) ++{ ++ unsigned char *da; ++ unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); ++ ++ switch (to_fr_ds) { ++ case 0x00: /* ToDs=0, FromDs=0 */ ++ da = GetAddr1Ptr(pframe); ++ break; ++ case 0x01: /* ToDs=0, FromDs=1 */ ++ da = GetAddr1Ptr(pframe); ++ break; ++ case 0x02: /* ToDs=1, FromDs=0 */ ++ da = GetAddr3Ptr(pframe); ++ break; ++ default: /* ToDs=1, FromDs=1 */ ++ da = GetAddr3Ptr(pframe); ++ break; ++ } ++ return da; ++} ++ ++static inline unsigned char *get_sa(unsigned char *pframe) ++{ ++ unsigned char *sa; ++ unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); ++ ++ switch (to_fr_ds) { ++ case 0x00: /* ToDs=0, FromDs=0 */ ++ sa = GetAddr2Ptr(pframe); ++ break; ++ case 0x01: /* ToDs=0, FromDs=1 */ ++ sa = GetAddr3Ptr(pframe); ++ break; ++ case 0x02: /* ToDs=1, FromDs=0 */ ++ sa = GetAddr2Ptr(pframe); ++ break; ++ default: /* ToDs=1, FromDs=1 */ ++ sa = GetAddr4Ptr(pframe); ++ break; ++ } ++ return sa; ++} ++ ++static inline unsigned char *get_hdr_bssid(unsigned char *pframe) ++{ ++ unsigned char *sa; ++ unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); ++ ++ switch (to_fr_ds) { ++ case 0x00: /* ToDs=0, FromDs=0 */ ++ sa = GetAddr3Ptr(pframe); ++ break; ++ case 0x01: /* ToDs=0, FromDs=1 */ ++ sa = GetAddr2Ptr(pframe); ++ break; ++ case 0x02: /* ToDs=1, FromDs=0 */ ++ sa = GetAddr1Ptr(pframe); ++ break; ++ case 0x03: /* ToDs=1, FromDs=1 */ ++ sa = GetAddr1Ptr(pframe); ++ break; ++ default: ++ sa = NULL; /* */ ++ break; ++ } ++ return sa; ++} ++ ++static inline int IsFrameTypeCtrl(unsigned char *pframe) ++{ ++ if (WIFI_CTRL_TYPE == GetFrameType(pframe)) ++ return true; ++ else ++ return false; ++} ++/*----------------------------------------------------------------------------- ++ Below is for the security related definition ++------------------------------------------------------------------------------*/ ++#define _RESERVED_FRAME_TYPE_ 0 ++#define _SKB_FRAME_TYPE_ 2 ++#define _PRE_ALLOCMEM_ 1 ++#define _PRE_ALLOCHDR_ 3 ++#define _PRE_ALLOCLLCHDR_ 4 ++#define _PRE_ALLOCICVHDR_ 5 ++#define _PRE_ALLOCMICHDR_ 6 ++ ++#define _SIFSTIME_ \ ++ (priv->pmib->dot11BssType.net_work_type = 10) ++#define _ACKCTSLNG_ 14 /* 14 bytes long, including crclng */ ++#define _CRCLNG_ 4 ++ ++#define _ASOCREQ_IE_OFFSET_ 4 /* excluding wlan_hdr */ ++#define _ASOCRSP_IE_OFFSET_ 6 ++#define _REASOCREQ_IE_OFFSET_ 10 ++#define _REASOCRSP_IE_OFFSET_ 6 ++#define _PROBEREQ_IE_OFFSET_ 0 ++#define _PROBERSP_IE_OFFSET_ 12 ++#define _AUTH_IE_OFFSET_ 6 ++#define _DEAUTH_IE_OFFSET_ 0 ++#define _BEACON_IE_OFFSET_ 12 ++#define _PUBLIC_ACTION_IE_OFFSET_ 8 ++ ++#define _FIXED_IE_LENGTH_ _BEACON_IE_OFFSET_ ++ ++#define _SSID_IE_ 0 ++#define _SUPPORTEDRATES_IE_ 1 ++#define _DSSET_IE_ 3 ++#define _TIM_IE_ 5 ++#define _IBSS_PARA_IE_ 6 ++#define _COUNTRY_IE_ 7 ++#define _CHLGETXT_IE_ 16 ++#define _SUPPORTED_CH_IE_ 36 ++#define _CH_SWTICH_ANNOUNCE_ 37 /* Secondary Channel Offset */ ++#define _RSN_IE_2_ 48 ++#define _SSN_IE_1_ 221 ++#define _ERPINFO_IE_ 42 ++#define _EXT_SUPPORTEDRATES_IE_ 50 ++ ++#define _HT_CAPABILITY_IE_ 45 ++#define _FTIE_ 55 ++#define _TIMEOUT_ITVL_IE_ 56 ++#define _SRC_IE_ 59 ++#define _HT_EXTRA_INFO_IE_ 61 ++#define _HT_ADD_INFO_IE_ 61 /* _HT_EXTRA_INFO_IE_ */ ++#define _WAPI_IE_ 68 ++ ++#define EID_BSSCoexistence 72 /* 20/40 BSS Coexistence */ ++#define EID_BSSIntolerantChlReport 73 ++#define _RIC_Descriptor_IE_ 75 ++ ++#define _LINK_ID_IE_ 101 ++#define _CH_SWITCH_TIMING_ 104 ++#define _PTI_BUFFER_STATUS_ 106 ++#define _EXT_CAP_IE_ 127 ++#define _VENDOR_SPECIFIC_IE_ 221 ++ ++#define _RESERVED47_ 47 ++ ++/* --------------------------------------------------------------------------- ++ Below is the fixed elements... ++-----------------------------------------------------------------------------*/ ++#define _AUTH_ALGM_NUM_ 2 ++#define _AUTH_SEQ_NUM_ 2 ++#define _BEACON_ITERVAL_ 2 ++#define _CAPABILITY_ 2 ++#define _CURRENT_APADDR_ 6 ++#define _LISTEN_INTERVAL_ 2 ++#define _RSON_CODE_ 2 ++#define _ASOC_ID_ 2 ++#define _STATUS_CODE_ 2 ++#define _TIMESTAMP_ 8 ++ ++#define AUTH_ODD_TO 0 ++#define AUTH_EVEN_TO 1 ++ ++#define WLAN_ETHCONV_ENCAP 1 ++#define WLAN_ETHCONV_RFC1042 2 ++#define WLAN_ETHCONV_8021h 3 ++ ++#define cap_ESS BIT(0) ++#define cap_IBSS BIT(1) ++#define cap_CFPollable BIT(2) ++#define cap_CFRequest BIT(3) ++#define cap_Privacy BIT(4) ++#define cap_ShortPremble BIT(5) ++#define cap_PBCC BIT(6) ++#define cap_ChAgility BIT(7) ++#define cap_SpecMgmt BIT(8) ++#define cap_QoSi BIT(9) ++#define cap_ShortSlot BIT(10) ++ ++/*----------------------------------------------------------------------------- ++ Below is the definition for 802.11i / 802.1x ++------------------------------------------------------------------------------*/ ++#define _IEEE8021X_MGT_ 1 /* WPA */ ++#define _IEEE8021X_PSK_ 2 /* WPA with pre-shared key */ ++ ++/* ++#define _NO_PRIVACY_ 0 ++#define _WEP_40_PRIVACY_ 1 ++#define _TKIP_PRIVACY_ 2 ++#define _WRAP_PRIVACY_ 3 ++#define _CCMP_PRIVACY_ 4 ++#define _WEP_104_PRIVACY_ 5 ++#define _WEP_WPA_MIXED_PRIVACY_ 6 WEP + WPA ++*/ ++ ++/*----------------------------------------------------------------------------- ++ Below is the definition for WMM ++------------------------------------------------------------------------------*/ ++#define _WMM_IE_Length_ 7 /* for WMM STA */ ++#define _WMM_Para_Element_Length_ 24 ++ ++/*----------------------------------------------------------------------------- ++ Below is the definition for 802.11n ++------------------------------------------------------------------------------*/ ++ ++#define SetOrderBit(pbuf) \ ++ do { \ ++ *(unsigned short *)(pbuf) |= cpu_to_le16(_ORDER_); \ ++ } while (0) ++ ++#define GetOrderBit(pbuf) \ ++ (((*(unsigned short *)(pbuf)) & le16_to_cpu(_ORDER_)) != 0) ++ ++/** ++ * struct rtw_ieee80211_bar - HT Block Ack Request ++ * ++ * This structure refers to "HT BlockAckReq" as ++ * described in 802.11n draft section 7.2.1.7.1 ++ */ ++struct rtw_ieee80211_bar { ++ __le16 frame_control; ++ __le16 duration; ++ unsigned char ra[ETH_ALEN]; ++ unsigned char ta[ETH_ALEN]; ++ __le16 control; ++ __le16 start_seq_num; ++} __packed; ++ ++/** ++ * struct ieee80211_ht_cap - HT additional information ++ * ++ * This structure refers to "HT information element" as ++ * described in 802.11n draft section 7.3.2.53 ++ */ ++struct ieee80211_ht_addt_info { ++ unsigned char control_chan; ++ unsigned char ht_param; ++ __le16 operation_mode; ++ __le16 stbc_param; ++ unsigned char basic_set[16]; ++} __packed; ++ ++struct HT_caps_element { ++ union { ++ struct { ++ __le16 HT_caps_info; ++ unsigned char AMPDU_para; ++ unsigned char MCS_rate[16]; ++ __le16 HT_ext_caps; ++ __le16 Beamforming_caps; ++ unsigned char ASEL_caps; ++ } HT_cap_element; ++ unsigned char HT_cap[26]; ++ } u; ++} __packed; ++ ++struct HT_info_element { ++ unsigned char primary_channel; ++ unsigned char infos[5]; ++ unsigned char MCS_rate[16]; ++} __packed; ++ ++struct AC_param { ++ unsigned char ACI_AIFSN; ++ unsigned char CW; ++ __le16 TXOP_limit; ++} __packed; ++ ++struct WMM_para_element { ++ unsigned char QoS_info; ++ unsigned char reserved; ++ struct AC_param ac_param[4]; ++} __packed; ++ ++struct ADDBA_request { ++ unsigned char action_code; ++ unsigned char dialog_token; ++ __le16 BA_para_set; ++ __le16 BA_timeout_value; ++ __le16 BA_starting_seqctrl; ++} __packed; ++ ++enum ht_cap_ampdu_factor { ++ MAX_AMPDU_FACTOR_8K = 0, ++ MAX_AMPDU_FACTOR_16K = 1, ++ MAX_AMPDU_FACTOR_32K = 2, ++ MAX_AMPDU_FACTOR_64K = 3, ++}; ++ ++/* Spatial Multiplexing Power Save Modes */ ++#define WLAN_HT_CAP_SM_PS_STATIC 0 ++#define WLAN_HT_CAP_SM_PS_DYNAMIC 1 ++#define WLAN_HT_CAP_SM_PS_INVALID 2 ++#define WLAN_HT_CAP_SM_PS_DISABLED 3 ++ ++#define OP_MODE_PURE 0 ++#define OP_MODE_MAY_BE_LEGACY_STAS 1 ++#define OP_MODE_20MHZ_HT_STA_ASSOCED 2 ++#define OP_MODE_MIXED 3 ++ ++#define HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK ((u8) BIT(0) | BIT(1)) ++#define HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE ((u8) BIT(0)) ++#define HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW ((u8) BIT(0) | BIT(1)) ++#define HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH ((u8) BIT(2)) ++#define HT_INFO_HT_PARAM_RIFS_MODE ((u8) BIT(3)) ++#define HT_INFO_HT_PARAM_CTRL_ACCESS_ONLY ((u8) BIT(4)) ++#define HT_INFO_HT_PARAM_SRV_INTERVAL_GRANULARITY ((u8) BIT(5)) ++ ++#define HT_INFO_OPERATION_MODE_OP_MODE_MASK \ ++ ((u16) (0x0001 | 0x0002)) ++#define HT_INFO_OPERATION_MODE_OP_MODE_OFFSET 0 ++#define HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT ((u8) BIT(2)) ++#define HT_INFO_OPERATION_MODE_TRANSMIT_BURST_LIMIT ((u8) BIT(3)) ++#define HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT ((u8) BIT(4)) ++ ++#define HT_INFO_STBC_PARAM_DUAL_BEACON ((u16) BIT(6)) ++#define HT_INFO_STBC_PARAM_DUAL_STBC_PROTECT ((u16) BIT(7)) ++#define HT_INFO_STBC_PARAM_SECONDARY_BC ((u16) BIT(8)) ++#define HT_INFO_STBC_PARAM_LSIG_TXOP_PROTECT_ALLOWED ((u16) BIT(9)) ++#define HT_INFO_STBC_PARAM_PCO_ACTIVE ((u16) BIT(10)) ++#define HT_INFO_STBC_PARAM_PCO_PHASE ((u16) BIT(11)) ++ ++/* ===============WPS Section=============== */ ++/* For WPSv1.0 */ ++#define WPSOUI 0x0050f204 ++/* WPS attribute ID */ ++#define WPS_ATTR_VER1 0x104A ++#define WPS_ATTR_SIMPLE_CONF_STATE 0x1044 ++#define WPS_ATTR_RESP_TYPE 0x103B ++#define WPS_ATTR_UUID_E 0x1047 ++#define WPS_ATTR_MANUFACTURER 0x1021 ++#define WPS_ATTR_MODEL_NAME 0x1023 ++#define WPS_ATTR_MODEL_NUMBER 0x1024 ++#define WPS_ATTR_SERIAL_NUMBER 0x1042 ++#define WPS_ATTR_PRIMARY_DEV_TYPE 0x1054 ++#define WPS_ATTR_SEC_DEV_TYPE_LIST 0x1055 ++#define WPS_ATTR_DEVICE_NAME 0x1011 ++#define WPS_ATTR_CONF_METHOD 0x1008 ++#define WPS_ATTR_RF_BANDS 0x103C ++#define WPS_ATTR_DEVICE_PWID 0x1012 ++#define WPS_ATTR_REQUEST_TYPE 0x103A ++#define WPS_ATTR_ASSOCIATION_STATE 0x1002 ++#define WPS_ATTR_CONFIG_ERROR 0x1009 ++#define WPS_ATTR_VENDOR_EXT 0x1049 ++#define WPS_ATTR_SELECTED_REGISTRAR 0x1041 ++ ++/* Value of WPS attribute "WPS_ATTR_DEVICE_NAME */ ++#define WPS_MAX_DEVICE_NAME_LEN 32 ++ ++/* Value of WPS Request Type Attribute */ ++#define WPS_REQ_TYPE_ENROLLEE_INFO_ONLY 0x00 ++#define WPS_REQ_TYPE_ENROLLEE_OPEN_8021X 0x01 ++#define WPS_REQ_TYPE_REGISTRAR 0x02 ++#define WPS_REQ_TYPE_WLAN_MANAGER_REGISTRAR 0x03 ++ ++/* Value of WPS Response Type Attribute */ ++#define WPS_RESPONSE_TYPE_INFO_ONLY 0x00 ++#define WPS_RESPONSE_TYPE_8021X 0x01 ++#define WPS_RESPONSE_TYPE_REGISTRAR 0x02 ++#define WPS_RESPONSE_TYPE_AP 0x03 ++ ++/* Value of WPS WiFi Simple Configuration State Attribute */ ++#define WPS_WSC_STATE_NOT_CONFIG 0x01 ++#define WPS_WSC_STATE_CONFIG 0x02 ++ ++/* Value of WPS Version Attribute */ ++#define WPS_VERSION_1 0x10 ++ ++/* Value of WPS Configuration Method Attribute */ ++#define WPS_CONFIG_METHOD_FLASH 0x0001 ++#define WPS_CONFIG_METHOD_ETHERNET 0x0002 ++#define WPS_CONFIG_METHOD_LABEL 0x0004 ++#define WPS_CONFIG_METHOD_DISPLAY 0x0008 ++#define WPS_CONFIG_METHOD_E_NFC 0x0010 ++#define WPS_CONFIG_METHOD_I_NFC 0x0020 ++#define WPS_CONFIG_METHOD_NFC 0x0040 ++#define WPS_CONFIG_METHOD_PBC 0x0080 ++#define WPS_CONFIG_METHOD_KEYPAD 0x0100 ++#define WPS_CONFIG_METHOD_VPBC 0x0280 ++#define WPS_CONFIG_METHOD_PPBC 0x0480 ++#define WPS_CONFIG_METHOD_VDISPLAY 0x2008 ++#define WPS_CONFIG_METHOD_PDISPLAY 0x4008 ++ ++/* Value of Category ID of WPS Primary Device Type Attribute */ ++#define WPS_PDT_CID_DISPLAYS 0x0007 ++#define WPS_PDT_CID_MULIT_MEDIA 0x0008 ++#define WPS_PDT_CID_RTK_WIDI WPS_PDT_CID_MULIT_MEDIA ++ ++/* Value of Sub Category ID of WPS Primary Device Type Attribute */ ++#define WPS_PDT_SCID_MEDIA_SERVER 0x0005 ++#define WPS_PDT_SCID_RTK_DMP WPS_PDT_SCID_MEDIA_SERVER ++ ++/* Value of Device Password ID */ ++#define WPS_DPID_P 0x0000 ++#define WPS_DPID_USER_SPEC 0x0001 ++#define WPS_DPID_MACHINE_SPEC 0x0002 ++#define WPS_DPID_REKEY 0x0003 ++#define WPS_DPID_PBC 0x0004 ++#define WPS_DPID_REGISTRAR_SPEC 0x0005 ++ ++/* Value of WPS RF Bands Attribute */ ++#define WPS_RF_BANDS_2_4_GHZ 0x01 ++#define WPS_RF_BANDS_5_GHZ 0x02 ++ ++/* Value of WPS Association State Attribute */ ++#define WPS_ASSOC_STATE_NOT_ASSOCIATED 0x00 ++#define WPS_ASSOC_STATE_CONNECTION_SUCCESS 0x01 ++#define WPS_ASSOC_STATE_CONFIGURATION_FAILURE 0x02 ++#define WPS_ASSOC_STATE_ASSOCIATION_FAILURE 0x03 ++#define WPS_ASSOC_STATE_IP_FAILURE 0x04 ++ ++/* =====================P2P Section===================== */ ++/* For P2P */ ++#define P2POUI 0x506F9A09 ++ ++/* P2P Attribute ID */ ++#define P2P_ATTR_STATUS 0x00 ++#define P2P_ATTR_MINOR_REASON_CODE 0x01 ++#define P2P_ATTR_CAPABILITY 0x02 ++#define P2P_ATTR_DEVICE_ID 0x03 ++#define P2P_ATTR_GO_INTENT 0x04 ++#define P2P_ATTR_CONF_TIMEOUT 0x05 ++#define P2P_ATTR_LISTEN_CH 0x06 ++#define P2P_ATTR_GROUP_BSSID 0x07 ++#define P2P_ATTR_EX_LISTEN_TIMING 0x08 ++#define P2P_ATTR_INTENTED_IF_ADDR 0x09 ++#define P2P_ATTR_MANAGEABILITY 0x0A ++#define P2P_ATTR_CH_LIST 0x0B ++#define P2P_ATTR_NOA 0x0C ++#define P2P_ATTR_DEVICE_INFO 0x0D ++#define P2P_ATTR_GROUP_INFO 0x0E ++#define P2P_ATTR_GROUP_ID 0x0F ++#define P2P_ATTR_INTERFACE 0x10 ++#define P2P_ATTR_OPERATING_CH 0x11 ++#define P2P_ATTR_INVITATION_FLAGS 0x12 ++ ++/* Value of Status Attribute */ ++#define P2P_STATUS_SUCCESS 0x00 ++#define P2P_STATUS_FAIL_INFO_UNAVAILABLE 0x01 ++#define P2P_STATUS_FAIL_INCOMPATIBLE_PARAM 0x02 ++#define P2P_STATUS_FAIL_LIMIT_REACHED 0x03 ++#define P2P_STATUS_FAIL_INVALID_PARAM 0x04 ++#define P2P_STATUS_FAIL_REQUEST_UNABLE 0x05 ++#define P2P_STATUS_FAIL_PREVOUS_PROTO_ERR 0x06 ++#define P2P_STATUS_FAIL_NO_COMMON_CH 0x07 ++#define P2P_STATUS_FAIL_UNKNOWN_P2PGROUP 0x08 ++#define P2P_STATUS_FAIL_BOTH_GOINTENT_15 0x09 ++#define P2P_STATUS_FAIL_INCOMPATIBLE_PROVSION 0x0A ++#define P2P_STATUS_FAIL_USER_REJECT 0x0B ++ ++/* Value of Inviation Flags Attribute */ ++#define P2P_INVITATION_FLAGS_PERSISTENT BIT(0) ++ ++#define DMP_P2P_DEVCAP_SUPPORT (P2P_DEVCAP_SERVICE_DISCOVERY | \ ++ P2P_DEVCAP_CLIENT_DISCOVERABILITY | \ ++ P2P_DEVCAP_CONCURRENT_OPERATION | \ ++ P2P_DEVCAP_INVITATION_PROC) ++ ++#define DMP_P2P_GRPCAP_SUPPORT (P2P_GRPCAP_INTRABSS) ++ ++/* Value of Device Capability Bitmap */ ++#define P2P_DEVCAP_SERVICE_DISCOVERY BIT(0) ++#define P2P_DEVCAP_CLIENT_DISCOVERABILITY BIT(1) ++#define P2P_DEVCAP_CONCURRENT_OPERATION BIT(2) ++#define P2P_DEVCAP_INFRA_MANAGED BIT(3) ++#define P2P_DEVCAP_DEVICE_LIMIT BIT(4) ++#define P2P_DEVCAP_INVITATION_PROC BIT(5) ++ ++/* Value of Group Capability Bitmap */ ++#define P2P_GRPCAP_GO BIT(0) ++#define P2P_GRPCAP_PERSISTENT_GROUP BIT(1) ++#define P2P_GRPCAP_GROUP_LIMIT BIT(2) ++#define P2P_GRPCAP_INTRABSS BIT(3) ++#define P2P_GRPCAP_CROSS_CONN BIT(4) ++#define P2P_GRPCAP_PERSISTENT_RECONN BIT(5) ++#define P2P_GRPCAP_GROUP_FORMATION BIT(6) ++ ++/* P2P Public Action Frame (Management Frame) */ ++#define P2P_PUB_ACTION_ACTION 0x09 ++ ++/* P2P Public Action Frame Type */ ++#define P2P_GO_NEGO_REQ 0 ++#define P2P_GO_NEGO_RESP 1 ++#define P2P_GO_NEGO_CONF 2 ++#define P2P_INVIT_REQ 3 ++#define P2P_INVIT_RESP 4 ++#define P2P_DEVDISC_REQ 5 ++#define P2P_DEVDISC_RESP 6 ++#define P2P_PROVISION_DISC_REQ 7 ++#define P2P_PROVISION_DISC_RESP 8 ++ ++/* P2P Action Frame Type */ ++#define P2P_NOTICE_OF_ABSENCE 0 ++#define P2P_PRESENCE_REQUEST 1 ++#define P2P_PRESENCE_RESPONSE 2 ++#define P2P_GO_DISC_REQUEST 3 ++ ++#define P2P_MAX_PERSISTENT_GROUP_NUM 10 ++ ++#define P2P_PROVISIONING_SCAN_CNT 3 ++ ++#define P2P_WILDCARD_SSID_LEN 7 ++ ++/* default value, used when: (1)p2p disabed or (2)p2p enabled ++ * but only do 1 scan phase */ ++#define P2P_FINDPHASE_EX_NONE 0 ++/* used when p2p enabled and want to do 1 scan phase and ++ * P2P_FINDPHASE_EX_MAX-1 find phase */ ++#define P2P_FINDPHASE_EX_FULL 1 ++#define P2P_FINDPHASE_EX_SOCIAL_FIRST (P2P_FINDPHASE_EX_FULL+1) ++#define P2P_FINDPHASE_EX_MAX 4 ++#define P2P_FINDPHASE_EX_SOCIAL_LAST P2P_FINDPHASE_EX_MAX ++ ++/* 5 seconds timeout for sending the provision discovery request */ ++#define P2P_PROVISION_TIMEOUT 5000 ++/* 3 seconds timeout for sending the prov disc request concurrent mode */ ++#define P2P_CONCURRENT_PROVISION_TIME 3000 ++/* 5 seconds timeout for receiving the group negotiation response */ ++#define P2P_GO_NEGO_TIMEOUT 5000 ++/* 3 seconds timeout for sending the negotiation request under concurrent mode */ ++#define P2P_CONCURRENT_GO_NEGO_TIME 3000 ++/* 100ms */ ++#define P2P_TX_PRESCAN_TIMEOUT 100 ++/* 5 seconds timeout for sending the invitation request */ ++#define P2P_INVITE_TIMEOUT 5000 ++/* 3 seconds timeout for sending the invitation request under concurrent mode */ ++#define P2P_CONCURRENT_INVITE_TIME 3000 ++/* 25 seconds timeout to reset the scan channel (based on channel plan) */ ++#define P2P_RESET_SCAN_CH 25000 ++#define P2P_MAX_INTENT 15 ++ ++#define P2P_MAX_NOA_NUM 2 ++ ++/* WPS Configuration Method */ ++#define WPS_CM_NONE 0x0000 ++#define WPS_CM_LABEL 0x0004 ++#define WPS_CM_DISPLYA 0x0008 ++#define WPS_CM_EXTERNAL_NFC_TOKEN 0x0010 ++#define WPS_CM_INTEGRATED_NFC_TOKEN 0x0020 ++#define WPS_CM_NFC_INTERFACE 0x0040 ++#define WPS_CM_PUSH_BUTTON 0x0080 ++#define WPS_CM_KEYPAD 0x0100 ++#define WPS_CM_SW_PUHS_BUTTON 0x0280 ++#define WPS_CM_HW_PUHS_BUTTON 0x0480 ++#define WPS_CM_SW_DISPLAY_P 0x2008 ++#define WPS_CM_LCD_DISPLAY_P 0x4008 ++ ++enum P2P_ROLE { ++ P2P_ROLE_DISABLE = 0, ++ P2P_ROLE_DEVICE = 1, ++ P2P_ROLE_CLIENT = 2, ++ P2P_ROLE_GO = 3 ++}; ++ ++enum P2P_STATE { ++ P2P_STATE_NONE = 0, /* P2P disable */ ++ /* P2P had enabled and do nothing */ ++ P2P_STATE_IDLE = 1, ++ P2P_STATE_LISTEN = 2, /* In pure listen state */ ++ P2P_STATE_SCAN = 3, /* In scan phase */ ++ /* In the listen state of find phase */ ++ P2P_STATE_FIND_PHASE_LISTEN = 4, ++ /* In the search state of find phase */ ++ P2P_STATE_FIND_PHASE_SEARCH = 5, ++ /* In P2P provisioning discovery */ ++ P2P_STATE_TX_PROVISION_DIS_REQ = 6, ++ P2P_STATE_RX_PROVISION_DIS_RSP = 7, ++ P2P_STATE_RX_PROVISION_DIS_REQ = 8, ++ /* Doing the group owner negoitation handshake */ ++ P2P_STATE_GONEGO_ING = 9, ++ /* finish the group negoitation handshake with success */ ++ P2P_STATE_GONEGO_OK = 10, ++ /* finish the group negoitation handshake with failure */ ++ P2P_STATE_GONEGO_FAIL = 11, ++ /* receiving the P2P Inviation request and match with the profile. */ ++ P2P_STATE_RECV_INVITE_REQ_MATCH = 12, ++ /* Doing the P2P WPS */ ++ P2P_STATE_PROVISIONING_ING = 13, ++ /* Finish the P2P WPS */ ++ P2P_STATE_PROVISIONING_DONE = 14, ++ /* Transmit the P2P Invitation request */ ++ P2P_STATE_TX_INVITE_REQ = 15, ++ /* Receiving the P2P Invitation response */ ++ P2P_STATE_RX_INVITE_RESP_OK = 16, ++ /* receiving the P2P Inviation request and dismatch with the profile. */ ++ P2P_STATE_RECV_INVITE_REQ_DISMATCH = 17, ++ /* receiving the P2P Inviation request and this wifi is GO. */ ++ P2P_STATE_RECV_INVITE_REQ_GO = 18, ++ /* receiving the P2P Inviation request to join an existing P2P Group. */ ++ P2P_STATE_RECV_INVITE_REQ_JOIN = 19, ++ /* recveing the P2P Inviation response with failure */ ++ P2P_STATE_RX_INVITE_RESP_FAIL = 20, ++ /* receiving p2p negoitation response with information is not available */ ++ P2P_STATE_RX_INFOR_NOREADY = 21, ++ /* sending p2p negoitation response with information is not available */ ++ P2P_STATE_TX_INFOR_NOREADY = 22, ++}; ++ ++enum P2P_WPSINFO { ++ P2P_NO_WPSINFO = 0, ++ P2P_GOT_WPSINFO_PEER_DISPLAY_PIN = 1, ++ P2P_GOT_WPSINFO_SELF_DISPLAY_PIN = 2, ++ P2P_GOT_WPSINFO_PBC = 3, ++}; ++ ++#define P2P_PRIVATE_IOCTL_SET_LEN 64 ++ ++enum P2P_PROTO_WK_ID { ++ P2P_FIND_PHASE_WK = 0, ++ P2P_RESTORE_STATE_WK = 1, ++ P2P_PRE_TX_PROVDISC_PROCESS_WK = 2, ++ P2P_PRE_TX_NEGOREQ_PROCESS_WK = 3, ++ P2P_PRE_TX_INVITEREQ_PROCESS_WK = 4, ++ P2P_AP_P2P_CH_SWITCH_PROCESS_WK =5, ++ P2P_RO_CH_WK = 6, ++}; ++ ++enum P2P_PS_STATE { ++ P2P_PS_DISABLE = 0, ++ P2P_PS_ENABLE = 1, ++ P2P_PS_SCAN = 2, ++ P2P_PS_SCAN_DONE = 3, ++ P2P_PS_ALLSTASLEEP = 4, /* for P2P GO */ ++}; ++ ++enum P2P_PS_MODE { ++ P2P_PS_NONE = 0, ++ P2P_PS_CTWINDOW = 1, ++ P2P_PS_NOA = 2, ++ P2P_PS_MIX = 3, /* CTWindow and NoA */ ++}; ++ ++/* =====================WFD Section===================== */ ++/* For Wi-Fi Display */ ++#define WFD_ATTR_DEVICE_INFO 0x00 ++#define WFD_ATTR_ASSOC_BSSID 0x01 ++#define WFD_ATTR_COUPLED_SINK_INFO 0x06 ++#define WFD_ATTR_LOCAL_IP_ADDR 0x08 ++#define WFD_ATTR_SESSION_INFO 0x09 ++#define WFD_ATTR_ALTER_MAC 0x0a ++ ++/* For WFD Device Information Attribute */ ++#define WFD_DEVINFO_SOURCE 0x0000 ++#define WFD_DEVINFO_PSINK 0x0001 ++#define WFD_DEVINFO_SSINK 0x0002 ++#define WFD_DEVINFO_DUAL 0x0003 ++ ++#define WFD_DEVINFO_SESSION_AVAIL 0x0010 ++#define WFD_DEVINFO_WSD 0x0040 ++#define WFD_DEVINFO_PC_TDLS 0x0080 ++#define WFD_DEVINFO_HDCP_SUPPORT 0x0100 ++ ++#define IP_MCAST_MAC(mac) \ ++ ((mac[0] == 0x01) && (mac[1] == 0x00) && (mac[2] == 0x5e)) ++#define ICMPV6_MCAST_MAC(mac) \ ++ ((mac[0] == 0x33) && (mac[1] == 0x33) && (mac[2] != 0xff)) ++ ++#endif /* _WIFI_H_ */ +diff --git a/drivers/staging/r8188eu/include/wlan_bssdef.h b/drivers/staging/r8188eu/include/wlan_bssdef.h +new file mode 100644 +index 000000000000..99ca097b8edd +--- /dev/null ++++ b/drivers/staging/r8188eu/include/wlan_bssdef.h +@@ -0,0 +1,327 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __WLAN_BSSDEF_H__ ++#define __WLAN_BSSDEF_H__ ++ ++#define MAX_IE_SZ 768 ++ ++#define NDIS_802_11_LENGTH_SSID 32 ++#define NDIS_802_11_LENGTH_RATES 8 ++#define NDIS_802_11_LENGTH_RATES_EX 16 ++ ++#define NDIS_802_11_RSSI long /* in dBm */ ++ ++struct ndis_802_11_ssid { ++ u32 SsidLength; ++ u8 Ssid[32]; ++}; ++ ++enum NDIS_802_11_NETWORK_TYPE { ++ Ndis802_11FH, ++ Ndis802_11DS, ++ Ndis802_11OFDM5, ++ Ndis802_11OFDM24, ++ Ndis802_11NetworkTypeMax /* dummy upper bound */ ++}; ++ ++struct ndis_802_11_config_fh { ++ u32 Length; /* Length of structure */ ++ u32 HopPattern; /* As defined by 802.11, MSB set */ ++ u32 HopSet; /* to one if non-802.11 */ ++ u32 DwellTime; /* units are Kusec */ ++}; ++ ++/* ++ * FW will only save the channel number in DSConfig. ++ * ODI Handler will convert the channel number to freq. number. ++ */ ++struct ndis_802_11_config { ++ u32 Length; /* Length of structure */ ++ u32 BeaconPeriod; /* units are Kusec */ ++ u32 ATIMWindow; /* units are Kusec */ ++ u32 DSConfig; /* Frequency, units are kHz */ ++ struct ndis_802_11_config_fh FHConfig; ++}; ++ ++enum ndis_802_11_network_infra { ++ Ndis802_11IBSS, ++ Ndis802_11Infrastructure, ++ Ndis802_11AutoUnknown, ++ Ndis802_11InfrastructureMax, /* dummy upper bound */ ++ Ndis802_11APMode ++}; ++ ++struct ndis_802_11_fixed_ie { ++ u8 Timestamp[8]; ++ u16 BeaconInterval; ++ u16 Capabilities; ++}; ++ ++struct ndis_802_11_var_ie { ++ u8 ElementID; ++ u8 Length; ++ u8 data[1]; ++}; ++ ++/* ++ * Length is the 4 bytes multiples of the sume of ++ * [ETH_ALEN] + 2 + sizeof (struct ndis_802_11_ssid) + sizeof (u32) ++ * + sizeof (NDIS_802_11_RSSI) + sizeof (enum NDIS_802_11_NETWORK_TYPE) ++ * + sizeof (struct ndis_802_11_config) ++ * + NDIS_802_11_LENGTH_RATES_EX + IELength ++ * ++ * Except the IELength, all other fields are fixed length. ++ * Therefore, we can define a macro to represent the partial sum. */ ++ ++enum ndis_802_11_auth_mode { ++ Ndis802_11AuthModeOpen, ++ Ndis802_11AuthModeShared, ++ Ndis802_11AuthModeAutoSwitch, ++ Ndis802_11AuthModeWPA, ++ Ndis802_11AuthModeWPAPSK, ++ Ndis802_11AuthModeWPANone, ++ Ndis802_11AuthModeWAPI, ++ Ndis802_11AuthModeMax /* Not a real mode, upper bound */ ++}; ++ ++enum ndis_802_11_wep_status { ++ Ndis802_11WEPEnabled, ++ Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, ++ Ndis802_11WEPDisabled, ++ Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, ++ Ndis802_11WEPKeyAbsent, ++ Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, ++ Ndis802_11WEPNotSupported, ++ Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, ++ Ndis802_11Encryption2Enabled, ++ Ndis802_11Encryption2KeyAbsent, ++ Ndis802_11Encryption3Enabled, ++ Ndis802_11Encryption3KeyAbsent, ++ Ndis802_11_EncryptionWAPI ++}; ++ ++#define NDIS_802_11_AI_REQFI_CAPABILITIES 1 ++#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2 ++#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4 ++ ++#define NDIS_802_11_AI_RESFI_CAPABILITIES 1 ++#define NDIS_802_11_AI_RESFI_STATUSCODE 2 ++#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4 ++ ++struct ndis_802_11_ai_reqfi { ++ u16 Capabilities; ++ u16 ListenInterval; ++ unsigned char CurrentAPAddress[ETH_ALEN]; ++}; ++ ++struct ndis_802_11_ai_resfi { ++ u16 Capabilities; ++ u16 StatusCode; ++ u16 AssociationId; ++}; ++ ++struct ndis_802_11_assoc_info { ++ u32 Length; ++ u16 AvailableRequestFixedIEs; ++ struct ndis_802_11_ai_reqfi RequestFixedIEs; ++ u32 RequestIELength; ++ u32 OffsetRequestIEs; ++ u16 AvailableResponseFixedIEs; ++ struct ndis_802_11_ai_resfi ResponseFixedIEs; ++ u32 ResponseIELength; ++ u32 OffsetResponseIEs; ++}; ++ ++enum ndis_802_11_reload_def { ++ Ndis802_11ReloadWEPKeys ++}; ++ ++/* Key mapping keys require a BSSID */ ++struct ndis_802_11_key { ++ u32 Length; /* Length of this structure */ ++ u32 KeyIndex; ++ u32 KeyLength; /* length of key in bytes */ ++ unsigned char BSSID[ETH_ALEN]; ++ unsigned long long KeyRSC; ++ u8 KeyMaterial[32]; /* var len depending on above field */ ++}; ++ ++struct ndis_802_11_remove_key { ++ u32 Length; /* Length */ ++ u32 KeyIndex; ++ unsigned char BSSID[ETH_ALEN]; ++}; ++ ++struct ndis_802_11_wep { ++ u32 Length; /* Length of this structure */ ++ u32 KeyIndex; /* 0 is the per-client key, ++ * 1-N are the global keys */ ++ u32 KeyLength; /* length of key in bytes */ ++ u8 KeyMaterial[16];/* variable len depending on above field */ ++}; ++ ++struct ndis_802_11_auth_req { ++ u32 Length; /* Length of structure */ ++ unsigned char Bssid[ETH_ALEN]; ++ u32 Flags; ++}; ++ ++enum ndis_802_11_status_type { ++ Ndis802_11StatusType_Authentication, ++ Ndis802_11StatusType_MediaStreamMode, ++ Ndis802_11StatusType_PMKID_CandidateList, ++ Ndis802_11StatusTypeMax /* not a real type, defined as ++ * an upper bound */ ++}; ++ ++struct ndis_802_11_status_ind { ++ enum ndis_802_11_status_type StatusType; ++}; ++ ++/* mask for authentication/integrity fields */ ++#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f ++#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01 ++#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02 ++#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06 ++#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E ++ ++/* MIC check time, 60 seconds. */ ++#define MIC_CHECK_TIME 60000000 ++ ++struct ndis_802_11_auth_evt { ++ struct ndis_802_11_status_ind Status; ++ struct ndis_802_11_auth_req Request[1]; ++}; ++ ++struct ndis_802_11_test { ++ u32 Length; ++ u32 Type; ++ union { ++ struct ndis_802_11_auth_evt AuthenticationEvent; ++ NDIS_802_11_RSSI RssiTrigger; ++ } tt; ++}; ++ ++#ifndef Ndis802_11APMode ++#define Ndis802_11APMode (Ndis802_11InfrastructureMax+1) ++#endif ++ ++struct wlan_phy_info { ++ u8 SignalStrength;/* in percentage) */ ++ u8 SignalQuality;/* in percentage) */ ++ u8 Optimum_antenna; /* for Antenna diversity */ ++ u8 Reserved_0; ++}; ++ ++struct wlan_bcn_info { ++ /* these infor get from rtw_get_encrypt_info when ++ * * translate scan to UI */ ++ u8 encryp_protocol;/* ENCRYP_PROTOCOL_E: OPEN/WEP/WPA/WPA2/WAPI */ ++ int group_cipher; /* WPA/WPA2 group cipher */ ++ int pairwise_cipher;/* WPA/WPA2/WEP pairwise cipher */ ++ int is_8021x; ++ ++ /* bwmode 20/40 and ch_offset UP/LOW */ ++ unsigned short ht_cap_info; ++ unsigned char ht_info_infos_0; ++}; ++ ++/* temporally add #pragma pack for structure alignment issue of ++* struct wlan_bssid_ex and get_struct wlan_bssid_ex_sz() ++*/ ++struct wlan_bssid_ex { ++ u32 Length; ++ unsigned char MacAddress[ETH_ALEN]; ++ u8 Reserved[2];/* 0]: IS beacon frame */ ++ struct ndis_802_11_ssid Ssid; ++ u32 Privacy; ++ NDIS_802_11_RSSI Rssi;/* in dBM,raw data ,get from PHY) */ ++ enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; ++ struct ndis_802_11_config Configuration; ++ enum ndis_802_11_network_infra InfrastructureMode; ++ unsigned char SupportedRates[NDIS_802_11_LENGTH_RATES_EX]; ++ struct wlan_phy_info PhyInfo; ++ u32 IELength; ++ u8 IEs[MAX_IE_SZ]; /* timestamp, beacon interval, and ++ * capability information) */ ++} __packed; ++ ++static inline uint get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss) ++{ ++ return sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + bss->IELength; ++} ++ ++struct wlan_network { ++ struct list_head list; ++ int network_type; /* refer to ieee80211.h for WIRELESS_11B/G */ ++ int fixed; /* set fixed when not to be removed ++ * in site-surveying */ ++ unsigned long last_scanned; /* timestamp for the network */ ++ int aid; /* will only be valid when a BSS is joinned. */ ++ int join_res; ++ struct wlan_bssid_ex network; /* must be the last item */ ++ struct wlan_bcn_info BcnInfo; ++}; ++ ++enum VRTL_CARRIER_SENSE { ++ DISABLE_VCS, ++ ENABLE_VCS, ++ AUTO_VCS ++}; ++ ++enum VCS_TYPE { ++ NONE_VCS, ++ RTS_CTS, ++ CTS_TO_SELF ++}; ++ ++#define PWR_CAM 0 ++#define PWR_MINPS 1 ++#define PWR_MAXPS 2 ++#define PWR_UAPSD 3 ++#define PWR_VOIP 4 ++ ++enum UAPSD_MAX_SP { ++ NO_LIMIT, ++ TWO_MSDU, ++ FOUR_MSDU, ++ SIX_MSDU ++}; ++ ++#define NUM_PRE_AUTH_KEY 16 ++#define NUM_PMKID_CACHE NUM_PRE_AUTH_KEY ++ ++/* ++* WPA2 ++*/ ++ ++struct pmkid_candidate { ++ unsigned char BSSID[ETH_ALEN]; ++ u32 Flags; ++}; ++ ++struct ndis_802_11_pmkid_list { ++ u32 Version; /* Version of the structure */ ++ u32 NumCandidates; /* No. of pmkid candidates */ ++ struct pmkid_candidate CandidateList[1]; ++}; ++ ++struct ndis_802_11_auth_encrypt { ++ enum ndis_802_11_auth_mode AuthModeSupported; ++ enum ndis_802_11_wep_status EncryptStatusSupported; ++}; ++ ++struct ndis_802_11_cap { ++ u32 Length; ++ u32 Version; ++ u32 NoOfPMKIDs; ++ u32 NoOfAuthEncryptPairsSupported; ++ struct ndis_802_11_auth_encrypt AuthenticationEncryptionSupported[1]; ++}; ++ ++u8 key_2char2num(u8 hch, u8 lch); ++u8 key_char2num(u8 ch); ++u8 str_2char2num(u8 hch, u8 lch); ++ ++#endif /* ifndef WLAN_BSSDEF_H_ */ +diff --git a/drivers/staging/r8188eu/include/xmit_osdep.h b/drivers/staging/r8188eu/include/xmit_osdep.h +new file mode 100644 +index 000000000000..191c36361b63 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/xmit_osdep.h +@@ -0,0 +1,51 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __XMIT_OSDEP_H_ ++#define __XMIT_OSDEP_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++struct pkt_file { ++ struct sk_buff *pkt; ++ size_t pkt_len; /* the remainder length of the open_file */ ++ unsigned char *cur_buffer; ++ u8 *buf_start; ++ u8 *cur_addr; ++ size_t buf_len; ++}; ++ ++extern int rtw_ht_enable; ++extern int rtw_cbw40_enable; ++extern int rtw_ampdu_enable;/* for enable tx_ampdu */ ++ ++#define NR_XMITFRAME 256 ++ ++struct xmit_priv; ++struct pkt_attrib; ++struct sta_xmit_priv; ++struct xmit_frame; ++struct xmit_buf; ++ ++int rtw_xmit_entry(struct sk_buff *pkt, struct net_device *pnetdev); ++ ++void rtw_os_xmit_schedule(struct adapter *padapter); ++ ++int rtw_os_xmit_resource_alloc(struct adapter *padapter, ++ struct xmit_buf *pxmitbuf, u32 alloc_sz); ++void rtw_os_xmit_resource_free(struct adapter *padapter, ++ struct xmit_buf *pxmitbuf, u32 free_sz); ++ ++void rtw_set_tx_chksum_offload(struct sk_buff *pkt, struct pkt_attrib *pattrib); ++ ++uint rtw_remainder_len(struct pkt_file *pfile); ++void _rtw_open_pktfile(struct sk_buff *pkt, struct pkt_file *pfile); ++uint _rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen); ++int rtw_endofpktfile(struct pkt_file *pfile); ++ ++void rtw_os_pkt_complete(struct adapter *padapter, struct sk_buff *pkt); ++void rtw_os_xmit_complete(struct adapter *padapter, ++ struct xmit_frame *pxframe); ++ ++#endif /* __XMIT_OSDEP_H_ */ +diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c +new file mode 100644 +index 000000000000..1fd375076001 +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c +@@ -0,0 +1,6649 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _IOCTL_LINUX_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wlan_bssdef.h" ++#include "../include/rtw_debug.h" ++#include "../include/wifi.h" ++#include "../include/rtw_mlme.h" ++#include "../include/rtw_mlme_ext.h" ++#include "../include/rtw_ioctl.h" ++#include "../include/rtw_ioctl_set.h" ++#include "../include/rtw_mp_ioctl.h" ++#include "../include/usb_ops.h" ++#include "../include/rtl8188e_hal.h" ++ ++#include "../include/rtw_mp.h" ++#include "../include/rtw_iol.h" ++ ++#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30) ++ ++#define SCAN_ITEM_SIZE 768 ++#define MAX_CUSTOM_LEN 64 ++#define RATE_COUNT 4 ++ ++/* combo scan */ ++#define WEXT_CSCAN_AMOUNT 9 ++#define WEXT_CSCAN_BUF_LEN 360 ++#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00" ++#define WEXT_CSCAN_HEADER_SIZE 12 ++#define WEXT_CSCAN_SSID_SECTION 'S' ++#define WEXT_CSCAN_CHANNEL_SECTION 'C' ++#define WEXT_CSCAN_NPROBE_SECTION 'N' ++#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A' ++#define WEXT_CSCAN_PASV_DWELL_SECTION 'P' ++#define WEXT_CSCAN_HOME_DWELL_SECTION 'H' ++#define WEXT_CSCAN_TYPE_SECTION 'T' ++ ++static struct mp_ioctl_handler mp_ioctl_hdl[] = { ++/*0*/ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_start_test_hdl, OID_RT_PRO_START_TEST) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_stop_test_hdl, OID_RT_PRO_STOP_TEST) ++ ++ GEN_HANDLER(sizeof(struct rwreg_param), rtl8188eu_oid_rt_pro_read_register_hdl, OID_RT_PRO_READ_REGISTER) ++ GEN_HANDLER(sizeof(struct rwreg_param), rtl8188eu_oid_rt_pro_write_register_hdl, OID_RT_PRO_WRITE_REGISTER) ++ GEN_HANDLER(sizeof(struct bb_reg_param), rtl8188eu_oid_rt_pro_read_bb_reg_hdl, OID_RT_PRO_READ_BB_REG) ++/*5*/ GEN_HANDLER(sizeof(struct bb_reg_param), rtl8188eu_oid_rt_pro_write_bb_reg_hdl, OID_RT_PRO_WRITE_BB_REG) ++ GEN_HANDLER(sizeof(struct rf_reg_param), rtl8188eu_oid_rt_pro_read_rf_reg_hdl, OID_RT_PRO_RF_READ_REGISTRY) ++ GEN_HANDLER(sizeof(struct rf_reg_param), rtl8188eu_oid_rt_pro_write_rf_reg_hdl, OID_RT_PRO_RF_WRITE_REGISTRY) ++ ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_channel_direct_call_hdl, OID_RT_PRO_SET_CHANNEL_DIRECT_CALL) ++ GEN_HANDLER(sizeof(struct txpower_param), rtl8188eu_oid_rt_pro_set_tx_power_control_hdl, OID_RT_PRO_SET_TX_POWER_CONTROL) ++/*10*/ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_data_rate_hdl, OID_RT_PRO_SET_DATA_RATE) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_set_bandwidth_hdl, OID_RT_SET_BANDWIDTH) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_antenna_bb_hdl, OID_RT_PRO_SET_ANTENNA_BB) ++ ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_continuous_tx_hdl, OID_RT_PRO_SET_CONTINUOUS_TX) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_single_carrier_tx_hdl, OID_RT_PRO_SET_SINGLE_CARRIER_TX) ++/*15*/ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_carrier_suppression_tx_hdl, OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_single_tone_tx_hdl, OID_RT_PRO_SET_SINGLE_TONE_TX) ++ ++ EXT_MP_IOCTL_HANDLER(0, xmit_packet, 0) ++ ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_set_rx_packet_type_hdl, OID_RT_SET_RX_PACKET_TYPE) ++ GEN_HANDLER(0, rtl8188eu_oid_rt_reset_phy_rx_packet_count_hdl, OID_RT_RESET_PHY_RX_PACKET_COUNT) ++/*20*/ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_phy_rx_packet_received_hdl, OID_RT_GET_PHY_RX_PACKET_RECEIVED) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_phy_rx_packet_crc32_error_hdl, OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR) ++ ++ GEN_HANDLER(sizeof(struct eeprom_rw_param), NULL, 0) ++ GEN_HANDLER(sizeof(struct eeprom_rw_param), NULL, 0) ++ GEN_HANDLER(sizeof(struct efuse_access_struct), rtl8188eu_oid_rt_pro_efuse_hdl, OID_RT_PRO_EFUSE) ++/*25*/ GEN_HANDLER(0, rtl8188eu_oid_rt_pro_efuse_map_hdl, OID_RT_PRO_EFUSE_MAP) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_efuse_max_size_hdl, OID_RT_GET_EFUSE_MAX_SIZE) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_efuse_current_size_hdl, OID_RT_GET_EFUSE_CURRENT_SIZE) ++ ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_thermal_meter_hdl, OID_RT_PRO_GET_THERMAL_METER) ++ GEN_HANDLER(sizeof(u8), rtl8188eu_oid_rt_pro_set_power_tracking_hdl, OID_RT_PRO_SET_POWER_TRACKING) ++/*30*/ GEN_HANDLER(sizeof(u8), rtl8188eu_oid_rt_set_power_down_hdl, OID_RT_SET_POWER_DOWN) ++/*31*/ GEN_HANDLER(0, rtl8188eu_oid_rt_pro_trigger_gpio_hdl, 0) ++}; ++ ++static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000, ++ 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, ++ 48000000, 54000000}; ++ ++void indicate_wx_scan_complete_event(struct adapter *padapter) ++{ ++ union iwreq_data wrqu; ++ ++ memset(&wrqu, 0, sizeof(union iwreq_data)); ++ wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL); ++} ++ ++void rtw_indicate_wx_assoc_event(struct adapter *padapter) ++{ ++ union iwreq_data wrqu; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ memset(&wrqu, 0, sizeof(union iwreq_data)); ++ ++ wrqu.ap_addr.sa_family = ARPHRD_ETHER; ++ ++ memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN); ++ ++ DBG_88E_LEVEL(_drv_always_, "assoc success\n"); ++ wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); ++} ++ ++void rtw_indicate_wx_disassoc_event(struct adapter *padapter) ++{ ++ union iwreq_data wrqu; ++ ++ memset(&wrqu, 0, sizeof(union iwreq_data)); ++ ++ wrqu.ap_addr.sa_family = ARPHRD_ETHER; ++ memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); ++ ++ DBG_88E_LEVEL(_drv_always_, "indicate disassoc\n"); ++ wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); ++} ++ ++static char *translate_scan(struct adapter *padapter, ++ struct iw_request_info *info, ++ struct wlan_network *pnetwork, ++ char *start, char *stop) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct iw_event iwe; ++ u16 cap; ++ __le16 le_tmp; ++ u32 ht_ielen = 0; ++ char *custom; ++ char *p; ++ u16 max_rate = 0, rate, ht_cap = false; ++ u32 i = 0; ++ u8 bw_40MHz = 0, short_GI = 0; ++ u16 mcs_rate = 0; ++ u8 ss, sq; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ++ u32 blnGotP2PIE = false; ++ ++ /* User is doing the P2P device discovery */ ++ /* The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE. */ ++ /* If not, the driver should ignore this AP and go to the next AP. */ ++ ++ /* Verifying the SSID */ ++ if (!memcmp(pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN)) { ++ u32 p2pielen = 0; ++ ++ if (pnetwork->network.Reserved[0] == 2) {/* Probe Request */ ++ /* Verifying the P2P IE */ ++ if (rtw_get_p2p_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &p2pielen)) ++ blnGotP2PIE = true; ++ } else {/* Beacon or Probe Respones */ ++ /* Verifying the P2P IE */ ++ if (rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen)) ++ blnGotP2PIE = true; ++ } ++ } ++ ++ if (!blnGotP2PIE) ++ return start; ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ /* AP MAC address */ ++ iwe.cmd = SIOCGIWAP; ++ iwe.u.ap_addr.sa_family = ARPHRD_ETHER; ++ ++ memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN); ++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN); ++ ++ /* Add the ESSID */ ++ iwe.cmd = SIOCGIWESSID; ++ iwe.u.data.flags = 1; ++ iwe.u.data.length = min_t(u16, pnetwork->network.Ssid.SsidLength, 32); ++ start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid); ++ ++ /* parsing HT_CAP_IE */ ++ p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - 12); ++ ++ if (p && ht_ielen > 0) { ++ struct ieee80211_ht_cap *pht_capie; ++ ++ ht_cap = true; ++ pht_capie = (struct ieee80211_ht_cap *)(p + 2); ++ memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2); ++ bw_40MHz = (le16_to_cpu(pht_capie->cap_info) & ++ IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0; ++ short_GI = (le16_to_cpu(pht_capie->cap_info) & ++ (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0; ++ } ++ ++ /* Add the protocol name */ ++ iwe.cmd = SIOCGIWNAME; ++ if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates))) { ++ if (ht_cap) ++ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn"); ++ else ++ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b"); ++ } else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates))) { ++ if (ht_cap) ++ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn"); ++ else ++ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg"); ++ } else { ++ if (ht_cap) ++ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn"); ++ else ++ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g"); ++ } ++ ++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN); ++ ++ /* Add mode */ ++ iwe.cmd = SIOCGIWMODE; ++ memcpy(&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2); ++ ++ cap = le16_to_cpu(le_tmp); ++ ++ if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) { ++ if (cap & WLAN_CAPABILITY_BSS) ++ iwe.u.mode = IW_MODE_MASTER; ++ else ++ iwe.u.mode = IW_MODE_ADHOC; ++ ++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN); ++ } ++ ++ if (pnetwork->network.Configuration.DSConfig < 1) ++ pnetwork->network.Configuration.DSConfig = 1; ++ ++ /* Add frequency/channel */ ++ iwe.cmd = SIOCGIWFREQ; ++ iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000; ++ iwe.u.freq.e = 1; ++ iwe.u.freq.i = pnetwork->network.Configuration.DSConfig; ++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN); ++ ++ /* Add encryption capability */ ++ iwe.cmd = SIOCGIWENCODE; ++ if (cap & WLAN_CAPABILITY_PRIVACY) ++ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; ++ else ++ iwe.u.data.flags = IW_ENCODE_DISABLED; ++ iwe.u.data.length = 0; ++ start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid); ++ ++ /*Add basic and extended rates */ ++ max_rate = 0; ++ custom = kzalloc(MAX_CUSTOM_LEN, GFP_ATOMIC); ++ if (!custom) ++ return start; ++ p = custom; ++ p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): "); ++ while (pnetwork->network.SupportedRates[i] != 0) { ++ rate = pnetwork->network.SupportedRates[i] & 0x7F; ++ if (rate > max_rate) ++ max_rate = rate; ++ p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), ++ "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); ++ i++; ++ } ++ ++ if (ht_cap) { ++ if (mcs_rate & 0x8000)/* MCS15 */ ++ max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130); ++ else if (mcs_rate & 0x0080)/* MCS7 */ ++ ; ++ else/* default MCS7 */ ++ max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65); ++ ++ max_rate = max_rate * 2;/* Mbps/2; */ ++ } ++ ++ iwe.cmd = SIOCGIWRATE; ++ iwe.u.bitrate.fixed = 0; ++ iwe.u.bitrate.disabled = 0; ++ iwe.u.bitrate.value = max_rate * 500000; ++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN); ++ ++ /* parsing WPA/WPA2 IE */ ++ { ++ u8 *buf; ++ u8 *wpa_ie, *rsn_ie; ++ u16 wpa_len = 0, rsn_len = 0; ++ u8 *p; ++ ++ buf = kzalloc(MAX_WPA_IE_LEN, GFP_ATOMIC); ++ if (!buf) ++ goto exit; ++ wpa_ie = kzalloc(255, GFP_ATOMIC); ++ if (!wpa_ie) { ++ kfree(buf); ++ goto exit; ++ } ++ rsn_ie = kzalloc(255, GFP_ATOMIC); ++ if (!rsn_ie) { ++ kfree(buf); ++ kfree(wpa_ie); ++ goto exit; ++ } ++ rtw_get_sec_ie(pnetwork->network.IEs, pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len); ++ ++ if (wpa_len > 0) { ++ p = buf; ++ memset(buf, 0, MAX_WPA_IE_LEN); ++ p += sprintf(p, "wpa_ie ="); ++ for (i = 0; i < wpa_len; i++) ++ p += sprintf(p, "%02x", wpa_ie[i]); ++ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = IWEVCUSTOM; ++ iwe.u.data.length = strlen(buf); ++ start = iwe_stream_add_point(info, start, stop, &iwe, buf); ++ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = IWEVGENIE; ++ iwe.u.data.length = wpa_len; ++ start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie); ++ } ++ if (rsn_len > 0) { ++ p = buf; ++ memset(buf, 0, MAX_WPA_IE_LEN); ++ p += sprintf(p, "rsn_ie ="); ++ for (i = 0; i < rsn_len; i++) ++ p += sprintf(p, "%02x", rsn_ie[i]); ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = IWEVCUSTOM; ++ iwe.u.data.length = strlen(buf); ++ start = iwe_stream_add_point(info, start, stop, &iwe, buf); ++ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = IWEVGENIE; ++ iwe.u.data.length = rsn_len; ++ start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie); ++ } ++ kfree(buf); ++ kfree(wpa_ie); ++ kfree(rsn_ie); ++ } ++ ++ {/* parsing WPS IE */ ++ uint cnt = 0, total_ielen; ++ u8 *wpsie_ptr = NULL; ++ uint wps_ielen = 0; ++ ++ u8 *ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_; ++ total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_; ++ ++ while (cnt < total_ielen) { ++ if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) { ++ wpsie_ptr = &ie_ptr[cnt]; ++ iwe.cmd = IWEVGENIE; ++ iwe.u.data.length = (u16)wps_ielen; ++ start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr); ++ } ++ cnt += ie_ptr[cnt + 1] + 2; /* goto next */ ++ } ++ } ++ ++ /* Add quality statistics */ ++ iwe.cmd = IWEVQUAL; ++ iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED) && ++ is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) { ++ ss = padapter->recvpriv.signal_strength; ++ sq = padapter->recvpriv.signal_qual; ++ } else { ++ ss = pnetwork->network.PhyInfo.SignalStrength; ++ sq = pnetwork->network.PhyInfo.SignalQuality; ++ } ++ ++ iwe.u.qual.level = (u8)ss; ++ iwe.u.qual.qual = (u8)sq; /* signal quality */ ++ iwe.u.qual.noise = 0; /* noise level */ ++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN); ++exit: ++ kfree(custom); ++ return start; ++} ++ ++static int wpa_set_auth_algs(struct net_device *dev, u32 value) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int ret = 0; ++ ++ if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) { ++ DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value); ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch; ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; ++ } else if (value & AUTH_ALG_SHARED_KEY) { ++ DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n", value); ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ ++ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared; ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; ++ } else if (value & AUTH_ALG_OPEN_SYSTEM) { ++ DBG_88E("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n"); ++ if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) { ++ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; ++ } ++ } else if (value & AUTH_ALG_LEAP) { ++ DBG_88E("wpa_set_auth_algs, AUTH_ALG_LEAP\n"); ++ } else { ++ DBG_88E("wpa_set_auth_algs, error!\n"); ++ ret = -EINVAL; ++ } ++ return ret; ++} ++ ++static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len) ++{ ++ int ret = 0; ++ u32 wep_key_idx, wep_key_len, wep_total_len; ++ struct ndis_802_11_wep *pwep = NULL; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ param->u.crypt.err = 0; ++ param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; ++ ++ if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && ++ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && ++ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { ++ if (param->u.crypt.idx >= WEP_KEYS) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ } else { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ if (strcmp(param->u.crypt.alg, "WEP") == 0) { ++ DBG_88E("wpa_set_encryption, crypt.alg = WEP\n"); ++ ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; ++ padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_; ++ ++ wep_key_idx = param->u.crypt.idx; ++ wep_key_len = param->u.crypt.key_len; ++ ++ DBG_88E("(1)wep_key_idx =%d\n", wep_key_idx); ++ ++ if (wep_key_idx > WEP_KEYS) ++ return -EINVAL; ++ ++ if (wep_key_len > 0) { ++ wep_key_len = wep_key_len <= 5 ? 5 : 13; ++ wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial); ++ pwep = kmalloc(wep_total_len, GFP_KERNEL); ++ if (!pwep) ++ goto exit; ++ ++ memset(pwep, 0, wep_total_len); ++ pwep->KeyLength = wep_key_len; ++ pwep->Length = wep_total_len; ++ if (wep_key_len == 13) { ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; ++ padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_; ++ } ++ } else { ++ ret = -EINVAL; ++ goto exit; ++ } ++ pwep->KeyIndex = wep_key_idx; ++ pwep->KeyIndex |= 0x80000000; ++ memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength); ++ if (param->u.crypt.set_tx) { ++ DBG_88E("wep, set_tx = 1\n"); ++ if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL) ++ ret = -EOPNOTSUPP; ++ } else { ++ DBG_88E("wep, set_tx = 0\n"); ++ if (wep_key_idx >= WEP_KEYS) { ++ ret = -EOPNOTSUPP; ++ goto exit; ++ } ++ memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0], pwep->KeyMaterial, pwep->KeyLength); ++ psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength; ++ rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0); ++ } ++ goto exit; ++ } ++ ++ if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802_1x */ ++ struct sta_info *psta, *pbcmc_sta; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE)) { /* sta mode */ ++ psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); ++ if (!psta) { ++ ; ++ } else { ++ if (strcmp(param->u.crypt.alg, "none") != 0) ++ psta->ieee8021x_blocked = false; ++ ++ if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) || ++ (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) ++ psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; ++ ++ if (param->u.crypt.set_tx == 1) { /* pairwise key */ ++ memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); ++ ++ if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */ ++ memcpy(psta->dot11tkiptxmickey.skey, ¶m->u.crypt.key[16], 8); ++ memcpy(psta->dot11tkiprxmickey.skey, ¶m->u.crypt.key[24], 8); ++ padapter->securitypriv.busetkipkey = false; ++ } ++ ++ DBG_88E(" ~~~~set sta key:unicastkey\n"); ++ ++ rtw_setstakey_cmd(padapter, (unsigned char *)psta, true); ++ } else { /* group key */ ++ memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); ++ memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[16], 8); ++ memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[24], 8); ++ padapter->securitypriv.binstallGrpkey = true; ++ DBG_88E(" ~~~~set sta key:groupkey\n"); ++ ++ padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx; ++ ++ rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1); ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE); ++#endif /* CONFIG_88EU_P2P */ ++ } ++ } ++ pbcmc_sta = rtw_get_bcmc_stainfo(padapter); ++ if (!pbcmc_sta) { ++ ; ++ } else { ++ /* Jeff: don't disable ieee8021x_blocked while clearing key */ ++ if (strcmp(param->u.crypt.alg, "none") != 0) ++ pbcmc_sta->ieee8021x_blocked = false; ++ ++ if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) || ++ (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) ++ pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; ++ } ++ } ++ } ++ ++exit: ++ ++ kfree(pwep); ++ ++ return ret; ++} ++ ++static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ielen) ++{ ++ u8 *buf = NULL; ++ int group_cipher = 0, pairwise_cipher = 0; ++ int ret = 0; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ if (ielen > MAX_WPA_IE_LEN || !pie) { ++ _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); ++ if (!pie) ++ return ret; ++ else ++ return -EINVAL; ++ } ++ ++ if (ielen) { ++ buf = kzalloc(ielen, GFP_KERNEL); ++ if (!buf) { ++ ret = -ENOMEM; ++ goto exit; ++ } ++ ++ memcpy(buf, pie, ielen); ++ ++ /* dump */ ++ { ++ int i; ++ DBG_88E("\n wpa_ie(length:%d):\n", ielen); ++ for (i = 0; i < ielen; i += 8) ++ DBG_88E("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", buf[i], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]); ++ } ++ ++ if (ielen < RSN_HEADER_LEN) { ++ ret = -1; ++ goto exit; ++ } ++ ++ if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; ++ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; ++ memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen); ++ } ++ ++ if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; ++ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; ++ memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen); ++ } ++ ++ switch (group_cipher) { ++ case WPA_CIPHER_NONE: ++ padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; ++ break; ++ case WPA_CIPHER_WEP40: ++ padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ break; ++ case WPA_CIPHER_TKIP: ++ padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; ++ break; ++ case WPA_CIPHER_CCMP: ++ padapter->securitypriv.dot118021XGrpPrivacy = _AES_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; ++ break; ++ case WPA_CIPHER_WEP104: ++ padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ break; ++ } ++ ++ switch (pairwise_cipher) { ++ case WPA_CIPHER_NONE: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; ++ break; ++ case WPA_CIPHER_WEP40: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ break; ++ case WPA_CIPHER_TKIP: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; ++ break; ++ case WPA_CIPHER_CCMP: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _AES_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; ++ break; ++ case WPA_CIPHER_WEP104: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ break; ++ } ++ ++ _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); ++ {/* set wps_ie */ ++ u16 cnt = 0; ++ u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; ++ ++ while (cnt < ielen) { ++ eid = buf[cnt]; ++ if ((eid == _VENDOR_SPECIFIC_IE_) && (!memcmp(&buf[cnt + 2], wps_oui, 4))) { ++ DBG_88E("SET WPS_IE\n"); ++ ++ padapter->securitypriv.wps_ie_len = ((buf[cnt + 1] + 2) < (MAX_WPA_IE_LEN << 2)) ? (buf[cnt + 1] + 2) : (MAX_WPA_IE_LEN << 2); ++ ++ memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len); ++ ++ set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS); ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK)) ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING); ++#endif /* CONFIG_88EU_P2P */ ++ cnt += buf[cnt + 1] + 2; ++ break; ++ } else { ++ cnt += buf[cnt + 1] + 2; /* goto next */ ++ } ++ } ++ } ++ } ++ ++exit: ++ kfree(buf); ++ return ret; ++} ++ ++typedef unsigned char NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; ++ ++static int rtw_wx_get_name(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u32 ht_ielen = 0; ++ char *p; ++ u8 ht_cap = false; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; ++ NDIS_802_11_RATES_EX *prates = NULL; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) { ++ /* parsing HT_CAP_IE */ ++ p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength - 12); ++ if (p && ht_ielen > 0) ++ ht_cap = true; ++ ++ prates = &pcur_bss->SupportedRates; ++ ++ if (rtw_is_cckratesonly_included((u8 *)prates)) { ++ if (ht_cap) ++ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn"); ++ else ++ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b"); ++ } else if (rtw_is_cckrates_included((u8 *)prates)) { ++ if (ht_cap) ++ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn"); ++ else ++ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg"); ++ } else { ++ if (ht_cap) ++ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn"); ++ else ++ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); ++ } ++ } else { ++ snprintf(wrqu->name, IFNAMSIZ, "unassociated"); ++ } ++ ++ ++ ++ return 0; ++} ++ ++static int rtw_wx_get_freq(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ /* wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000; */ ++ wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000; ++ wrqu->freq.e = 1; ++ wrqu->freq.i = pcur_bss->Configuration.DSConfig; ++ } else { ++ wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000; ++ wrqu->freq.e = 1; ++ wrqu->freq.i = padapter->mlmeextpriv.cur_channel; ++ } ++ ++ return 0; ++} ++ ++static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a, ++ union iwreq_data *wrqu, char *b) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ enum ndis_802_11_network_infra networkType; ++ int ret = 0; ++ ++ ++ ++ if (_FAIL == rtw_pwr_wakeup(padapter)) { ++ ret = -EPERM; ++ goto exit; ++ } ++ ++ if (!padapter->hw_init_completed) { ++ ret = -EPERM; ++ goto exit; ++ } ++ ++ switch (wrqu->mode) { ++ case IW_MODE_AUTO: ++ networkType = Ndis802_11AutoUnknown; ++ DBG_88E("set_mode = IW_MODE_AUTO\n"); ++ break; ++ case IW_MODE_ADHOC: ++ networkType = Ndis802_11IBSS; ++ DBG_88E("set_mode = IW_MODE_ADHOC\n"); ++ break; ++ case IW_MODE_MASTER: ++ networkType = Ndis802_11APMode; ++ DBG_88E("set_mode = IW_MODE_MASTER\n"); ++ break; ++ case IW_MODE_INFRA: ++ networkType = Ndis802_11Infrastructure; ++ DBG_88E("set_mode = IW_MODE_INFRA\n"); ++ break; ++ default: ++ ret = -EINVAL; ++ goto exit; ++ } ++ if (!rtw_set_802_11_infrastructure_mode(padapter, networkType)) { ++ ret = -EPERM; ++ goto exit; ++ } ++ rtw_setopmode_cmd(padapter, networkType); ++exit: ++ ++ return ret; ++} ++ ++static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a, ++ union iwreq_data *wrqu, char *b) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) ++ wrqu->mode = IW_MODE_INFRA; ++ else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) || ++ (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))) ++ wrqu->mode = IW_MODE_ADHOC; ++ else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ wrqu->mode = IW_MODE_MASTER; ++ else ++ wrqu->mode = IW_MODE_AUTO; ++ ++ ++ ++ return 0; ++} ++ ++static int rtw_wx_set_pmkid(struct net_device *dev, ++ struct iw_request_info *a, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u8 j, blInserted = false; ++ int ret = false; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct iw_pmksa *pPMK = (struct iw_pmksa *)extra; ++ u8 strZeroMacAddress[ETH_ALEN] = {0x00}; ++ u8 strIssueBssid[ETH_ALEN] = {0x00}; ++ ++ memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN); ++ if (pPMK->cmd == IW_PMKSA_ADD) { ++ DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n"); ++ if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN)) ++ return ret; ++ else ++ ret = true; ++ blInserted = false; ++ ++ /* overwrite PMKID */ ++ for (j = 0; j < NUM_PMKID_CACHE; j++) { ++ if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) { ++ /* BSSID is matched, the same AP => rewrite with new PMKID. */ ++ DBG_88E("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n"); ++ memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN); ++ psecuritypriv->PMKIDList[j].bUsed = true; ++ psecuritypriv->PMKIDIndex = j + 1; ++ blInserted = true; ++ break; ++ } ++ } ++ ++ if (!blInserted) { ++ /* Find a new entry */ ++ DBG_88E("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n", ++ psecuritypriv->PMKIDIndex); ++ ++ memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN); ++ memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN); ++ ++ psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = true; ++ psecuritypriv->PMKIDIndex++; ++ if (psecuritypriv->PMKIDIndex == 16) ++ psecuritypriv->PMKIDIndex = 0; ++ } ++ } else if (pPMK->cmd == IW_PMKSA_REMOVE) { ++ DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n"); ++ ret = true; ++ for (j = 0; j < NUM_PMKID_CACHE; j++) { ++ if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) { ++ /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */ ++ memset(psecuritypriv->PMKIDList[j].Bssid, 0x00, ETH_ALEN); ++ psecuritypriv->PMKIDList[j].bUsed = false; ++ break; ++ } ++ } ++ } else if (pPMK->cmd == IW_PMKSA_FLUSH) { ++ DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n"); ++ memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); ++ psecuritypriv->PMKIDIndex = 0; ++ ret = true; ++ } ++ return ret; ++} ++ ++static int rtw_wx_get_sens(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ wrqu->sens.value = 0; ++ wrqu->sens.fixed = 0; /* no auto select */ ++ wrqu->sens.disabled = 1; ++ return 0; ++} ++ ++static int rtw_wx_get_range(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct iw_range *range = (struct iw_range *)extra; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ u16 val; ++ int i; ++ ++ wrqu->data.length = sizeof(*range); ++ memset(range, 0, sizeof(*range)); ++ ++ /* Let's try to keep this struct in the same order as in ++ * linux/include/wireless.h ++ */ ++ ++ /* TODO: See what values we can set, and remove the ones we can't ++ * set, or fill them with some default data. ++ */ ++ ++ /* ~5 Mb/s real (802.11b) */ ++ range->throughput = 5 * 1000 * 1000; ++ ++ /* signal level threshold range */ ++ ++ /* percent values between 0 and 100. */ ++ range->max_qual.qual = 100; ++ range->max_qual.level = 100; ++ range->max_qual.noise = 100; ++ range->max_qual.updated = 7; /* Updated all three */ ++ ++ range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ ++ /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ ++ range->avg_qual.level = 178; /* -78 dBm */ ++ range->avg_qual.noise = 0; ++ range->avg_qual.updated = 7; /* Updated all three */ ++ ++ range->num_bitrates = RATE_COUNT; ++ ++ for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) ++ range->bitrate[i] = rtw_rates[i]; ++ ++ range->min_frag = MIN_FRAG_THRESHOLD; ++ range->max_frag = MAX_FRAG_THRESHOLD; ++ ++ range->pm_capa = 0; ++ ++ range->we_version_compiled = WIRELESS_EXT; ++ range->we_version_source = 16; ++ ++ for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) { ++ /* Include only legal frequencies for some countries */ ++ if (pmlmeext->channel_set[i].ChannelNum != 0) { ++ range->freq[val].i = pmlmeext->channel_set[i].ChannelNum; ++ range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000; ++ range->freq[val].e = 1; ++ val++; ++ } ++ ++ if (val == IW_MAX_FREQUENCIES) ++ break; ++ } ++ ++ range->num_channels = val; ++ range->num_frequency = val; ++ ++/* The following code will proivde the security capability to network manager. */ ++/* If the driver doesn't provide this capability to network manager, */ ++/* the WPA/WPA2 routers can't be chosen in the network manager. */ ++ ++/* ++#define IW_SCAN_CAPA_NONE 0x00 ++#define IW_SCAN_CAPA_ESSID 0x01 ++#define IW_SCAN_CAPA_BSSID 0x02 ++#define IW_SCAN_CAPA_CHANNEL 0x04 ++#define IW_SCAN_CAPA_MODE 0x08 ++#define IW_SCAN_CAPA_RATE 0x10 ++#define IW_SCAN_CAPA_TYPE 0x20 ++#define IW_SCAN_CAPA_TIME 0x40 ++*/ ++ ++ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | ++ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; ++ ++ range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | ++ IW_SCAN_CAPA_BSSID | IW_SCAN_CAPA_CHANNEL | ++ IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE; ++ ++ ++ return 0; ++} ++ ++/* set bssid flow */ ++/* s1. rtw_set_802_11_infrastructure_mode() */ ++/* s2. rtw_set_802_11_authentication_mode() */ ++/* s3. set_802_11_encryption_mode() */ ++/* s4. rtw_set_802_11_bssid() */ ++static int rtw_wx_set_wap(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *awrq, ++ char *extra) ++{ ++ uint ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct sockaddr *temp = (struct sockaddr *)awrq; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *phead; ++ u8 *dst_bssid, *src_bssid; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ enum ndis_802_11_auth_mode authmode; ++ ++ ++ ++ if (_FAIL == rtw_pwr_wakeup(padapter)) { ++ ret = -1; ++ goto exit; ++ } ++ ++ if (!padapter->bup) { ++ ret = -1; ++ goto exit; ++ } ++ ++ if (temp->sa_family != ARPHRD_ETHER) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ authmode = padapter->securitypriv.ndisauthtype; ++ spin_lock_bh(&queue->lock); ++ phead = get_list_head(queue); ++ pmlmepriv->pscanned = phead->next; ++ ++ while (phead != pmlmepriv->pscanned) { ++ ++ pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list); ++ ++ pmlmepriv->pscanned = pmlmepriv->pscanned->next; ++ ++ dst_bssid = pnetwork->network.MacAddress; ++ ++ src_bssid = temp->sa_data; ++ ++ if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) { ++ if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) { ++ ret = -1; ++ spin_unlock_bh(&queue->lock); ++ goto exit; ++ } ++ ++ break; ++ } ++ } ++ spin_unlock_bh(&queue->lock); ++ ++ rtw_set_802_11_authentication_mode(padapter, authmode); ++ /* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */ ++ if (!rtw_set_802_11_bssid(padapter, temp->sa_data)) { ++ ret = -1; ++ goto exit; ++ } ++ ++exit: ++ ++ ++ ++ return ret; ++} ++ ++static int rtw_wx_get_wap(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; ++ ++ wrqu->ap_addr.sa_family = ARPHRD_ETHER; ++ ++ memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || ++ check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN); ++ else ++ memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); ++ ++ ++ ++ return 0; ++} ++ ++static int rtw_wx_set_mlme(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ u16 reason; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct iw_mlme *mlme = (struct iw_mlme *)extra; ++ ++ if (!mlme) ++ return -1; ++ ++ DBG_88E("%s\n", __func__); ++ ++ reason = mlme->reason_code; ++ ++ DBG_88E("%s, cmd =%d, reason =%d\n", __func__, mlme->cmd, reason); ++ ++ switch (mlme->cmd) { ++ case IW_MLME_DEAUTH: ++ if (!rtw_set_802_11_disassociate(padapter)) ++ ret = -1; ++ break; ++ case IW_MLME_DISASSOC: ++ if (!rtw_set_802_11_disassociate(padapter)) ++ ret = -1; ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ return ret; ++} ++ ++static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, ++ union iwreq_data *wrqu, char *extra) ++{ ++ u8 _status = false; ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT]; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ if (padapter->registrypriv.mp_mode == 1) { ++ if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { ++ ret = -1; ++ goto exit; ++ } ++ } ++ if (_FAIL == rtw_pwr_wakeup(padapter)) { ++ ret = -1; ++ goto exit; ++ } ++ ++ if (padapter->bDriverStopped) { ++ DBG_88E("bDriverStopped =%d\n", padapter->bDriverStopped); ++ ret = -1; ++ goto exit; ++ } ++ ++ if (!padapter->bup) { ++ ret = -1; ++ goto exit; ++ } ++ ++ if (!padapter->hw_init_completed) { ++ ret = -1; ++ goto exit; ++ } ++ ++ /* When Busy Traffic, driver do not site survey. So driver return success. */ ++ /* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */ ++ /* modify by thomas 2011-02-22. */ ++ if (pmlmepriv->LinkDetectInfo.bBusyTraffic) { ++ indicate_wx_scan_complete_event(padapter); ++ goto exit; ++ } ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) { ++ indicate_wx_scan_complete_event(padapter); ++ goto exit; ++ } ++ ++/* For the DMP WiFi Display project, the driver won't to scan because */ ++/* the pmlmepriv->scan_interval is always equal to 3. */ ++/* So, the wpa_supplicant won't find out the WPS SoftAP. */ ++ ++#ifdef CONFIG_88EU_P2P ++ if (pwdinfo->p2p_state != P2P_STATE_NONE) { ++ rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH); ++ rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL); ++ rtw_free_network_queue(padapter, true); ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ memset(ssid, 0, sizeof(struct ndis_802_11_ssid) * RTW_SSID_SCAN_AMOUNT); ++ ++ if (wrqu->data.length == sizeof(struct iw_scan_req)) { ++ struct iw_scan_req *req = (struct iw_scan_req *)extra; ++ ++ if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { ++ int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE); ++ ++ memcpy(ssid[0].Ssid, req->essid, len); ++ ssid[0].SsidLength = len; ++ ++ DBG_88E("IW_SCAN_THIS_ESSID, ssid =%s, len =%d\n", req->essid, req->essid_len); ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0); ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { ++ DBG_88E("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n"); ++ } ++ } else { ++ if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE && ++ !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) { ++ int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE; ++ char *pos = extra + WEXT_CSCAN_HEADER_SIZE; ++ char section; ++ char sec_len; ++ int ssid_index = 0; ++ ++ while (len >= 1) { ++ section = *(pos++); ++ len -= 1; ++ ++ switch (section) { ++ case WEXT_CSCAN_SSID_SECTION: ++ if (len < 1) { ++ len = 0; ++ break; ++ } ++ sec_len = *(pos++); len -= 1; ++ if (sec_len > 0 && sec_len <= len) { ++ ssid[ssid_index].SsidLength = sec_len; ++ memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength); ++ ssid_index++; ++ } ++ pos += sec_len; ++ len -= sec_len; ++ break; ++ case WEXT_CSCAN_TYPE_SECTION: ++ case WEXT_CSCAN_CHANNEL_SECTION: ++ pos += 1; ++ len -= 1; ++ break; ++ case WEXT_CSCAN_PASV_DWELL_SECTION: ++ case WEXT_CSCAN_HOME_DWELL_SECTION: ++ case WEXT_CSCAN_ACTV_DWELL_SECTION: ++ pos += 2; ++ len -= 2; ++ break; ++ default: ++ len = 0; /* stop parsing */ ++ } ++ } ++ ++ /* it has still some scan parameter to parse, we only do this now... */ ++ _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT); ++ } else { ++ _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0); ++ } ++ } ++ ++ if (!_status) ++ ret = -1; ++ ++exit: ++ ++ return ret; ++} ++ ++static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct list_head *plist, *phead; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ char *ev = extra; ++ char *stop = ev + wrqu->data.length; ++ u32 ret = 0; ++ u32 cnt = 0; ++ u32 wait_for_surveydone; ++ int wait_status; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ if (padapter->pwrctrlpriv.brfoffbyhw && padapter->bDriverStopped) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++#ifdef CONFIG_88EU_P2P ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ++ /* P2P is enabled */ ++ wait_for_surveydone = 200; ++ } else { ++ /* P2P is disabled */ ++ wait_for_surveydone = 100; ++ } ++#else ++ { ++ wait_for_surveydone = 100; ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ wait_status = _FW_UNDER_SURVEY | _FW_UNDER_LINKING; ++ ++ while (check_fwstate(pmlmepriv, wait_status)) { ++ msleep(30); ++ cnt++; ++ if (cnt > wait_for_surveydone) ++ break; ++ } ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ if ((stop - ev) < SCAN_ITEM_SIZE) { ++ ret = -E2BIG; ++ break; ++ } ++ ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ /* report network only if the current channel set contains the channel to which this network belongs */ ++ if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0) ++ ev = translate_scan(padapter, a, pnetwork, ev, stop); ++ ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ wrqu->data.length = ev - extra; ++ wrqu->data.flags = 0; ++ ++exit: ++ ++ return ret; ++} ++ ++/* set ssid flow */ ++/* s1. rtw_set_802_11_infrastructure_mode() */ ++/* s2. set_802_11_authenticaion_mode() */ ++/* s3. set_802_11_encryption_mode() */ ++/* s4. rtw_set_802_11_ssid() */ ++static int rtw_wx_set_essid(struct net_device *dev, ++ struct iw_request_info *a, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct list_head *phead; ++ struct wlan_network *pnetwork = NULL; ++ enum ndis_802_11_auth_mode authmode; ++ struct ndis_802_11_ssid ndis_ssid; ++ u8 *dst_ssid, *src_ssid; ++ ++ uint ret = 0, len; ++ ++ if (_FAIL == rtw_pwr_wakeup(padapter)) { ++ ret = -1; ++ goto exit; ++ } ++ ++ if (!padapter->bup) { ++ ret = -1; ++ goto exit; ++ } ++ ++ if (wrqu->essid.length > IW_ESSID_MAX_SIZE) { ++ ret = -E2BIG; ++ goto exit; ++ } ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ ret = -1; ++ goto exit; ++ } ++ ++ authmode = padapter->securitypriv.ndisauthtype; ++ DBG_88E("=>%s\n", __func__); ++ if (wrqu->essid.flags && wrqu->essid.length) { ++ len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE; ++ ++ if (wrqu->essid.length != 33) ++ DBG_88E("ssid =%s, len =%d\n", extra, wrqu->essid.length); ++ ++ memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid)); ++ ndis_ssid.SsidLength = len; ++ memcpy(ndis_ssid.Ssid, extra, len); ++ src_ssid = ndis_ssid.Ssid; ++ ++ spin_lock_bh(&queue->lock); ++ phead = get_list_head(queue); ++ pmlmepriv->pscanned = phead->next; ++ ++ while (phead != pmlmepriv->pscanned) { ++ pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list); ++ ++ pmlmepriv->pscanned = pmlmepriv->pscanned->next; ++ ++ dst_ssid = pnetwork->network.Ssid.Ssid; ++ ++ if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) && ++ (pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) { ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { ++ if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode) ++ continue; ++ } ++ ++ if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) { ++ ret = -1; ++ spin_unlock_bh(&queue->lock); ++ goto exit; ++ } ++ ++ break; ++ } ++ } ++ spin_unlock_bh(&queue->lock); ++ rtw_set_802_11_authentication_mode(padapter, authmode); ++ if (!rtw_set_802_11_ssid(padapter, &ndis_ssid)) { ++ ret = -1; ++ goto exit; ++ } ++ } ++ ++exit: ++ ++ DBG_88E("<=%s, ret %d\n", __func__, ret); ++ ++ ++ ++ return ret; ++} ++ ++static int rtw_wx_get_essid(struct net_device *dev, ++ struct iw_request_info *a, ++ union iwreq_data *wrqu, char *extra) ++{ ++ u32 len, ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; ++ ++ if ((check_fwstate(pmlmepriv, _FW_LINKED)) || ++ (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) { ++ len = pcur_bss->Ssid.SsidLength; ++ memcpy(extra, pcur_bss->Ssid.Ssid, len); ++ } else { ++ len = 0; ++ *extra = 0; ++ } ++ wrqu->essid.length = len; ++ wrqu->essid.flags = 1; ++ ++ return ret; ++} ++ ++static int rtw_wx_set_rate(struct net_device *dev, ++ struct iw_request_info *a, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int i, ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u8 datarates[NumRates]; ++ u32 target_rate = wrqu->bitrate.value; ++ u32 fixed = wrqu->bitrate.fixed; ++ u32 ratevalue = 0; ++ u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff}; ++ ++ if (target_rate == -1) { ++ ratevalue = 11; ++ goto set_rate; ++ } ++ target_rate = target_rate / 100000; ++ ++ switch (target_rate) { ++ case 10: ++ ratevalue = 0; ++ break; ++ case 20: ++ ratevalue = 1; ++ break; ++ case 55: ++ ratevalue = 2; ++ break; ++ case 60: ++ ratevalue = 3; ++ break; ++ case 90: ++ ratevalue = 4; ++ break; ++ case 110: ++ ratevalue = 5; ++ break; ++ case 120: ++ ratevalue = 6; ++ break; ++ case 180: ++ ratevalue = 7; ++ break; ++ case 240: ++ ratevalue = 8; ++ break; ++ case 360: ++ ratevalue = 9; ++ break; ++ case 480: ++ ratevalue = 10; ++ break; ++ case 540: ++ ratevalue = 11; ++ break; ++ default: ++ ratevalue = 11; ++ break; ++ } ++ ++set_rate: ++ ++ for (i = 0; i < NumRates; i++) { ++ if (ratevalue == mpdatarate[i]) { ++ datarates[i] = mpdatarate[i]; ++ if (fixed == 0) ++ break; ++ } else { ++ datarates[i] = 0xff; ++ } ++ } ++ ++ if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS) ++ ret = -1; ++ ++ return ret; ++} ++ ++static int rtw_wx_get_rate(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ u16 max_rate = 0; ++ ++ max_rate = rtw_get_cur_max_rate((struct adapter *)rtw_netdev_priv(dev)); ++ ++ if (max_rate == 0) ++ return -EPERM; ++ ++ wrqu->bitrate.fixed = 0; /* no auto select */ ++ wrqu->bitrate.value = max_rate * 100000; ++ ++ return 0; ++} ++ ++static int rtw_wx_set_rts(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ ++ ++ if (wrqu->rts.disabled) { ++ padapter->registrypriv.rts_thresh = 2347; ++ } else { ++ if (wrqu->rts.value < 0 || ++ wrqu->rts.value > 2347) ++ return -EINVAL; ++ ++ padapter->registrypriv.rts_thresh = wrqu->rts.value; ++ } ++ ++ DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh); ++ ++ ++ ++ return 0; ++} ++ ++static int rtw_wx_get_rts(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ ++ ++ DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh); ++ ++ wrqu->rts.value = padapter->registrypriv.rts_thresh; ++ wrqu->rts.fixed = 0; /* no auto select */ ++ /* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */ ++ ++ ++ ++ return 0; ++} ++ ++static int rtw_wx_set_frag(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ ++ ++ if (wrqu->frag.disabled) { ++ padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD; ++ } else { ++ if (wrqu->frag.value < MIN_FRAG_THRESHOLD || ++ wrqu->frag.value > MAX_FRAG_THRESHOLD) ++ return -EINVAL; ++ ++ padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1; ++ } ++ ++ DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len); ++ ++ ++ ++ return 0; ++} ++ ++static int rtw_wx_get_frag(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ ++ ++ DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len); ++ ++ wrqu->frag.value = padapter->xmitpriv.frag_len; ++ wrqu->frag.fixed = 0; /* no auto select */ ++ ++ ++ ++ return 0; ++} ++ ++static int rtw_wx_get_retry(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ wrqu->retry.value = 7; ++ wrqu->retry.fixed = 0; /* no auto select */ ++ wrqu->retry.disabled = 1; ++ ++ return 0; ++} ++ ++static int rtw_wx_set_enc(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *keybuf) ++{ ++ u32 key, ret = 0; ++ u32 keyindex_provided; ++ struct ndis_802_11_wep wep; ++ enum ndis_802_11_auth_mode authmode; ++ ++ struct iw_point *erq = &wrqu->encoding; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ DBG_88E("+rtw_wx_set_enc, flags = 0x%x\n", erq->flags); ++ ++ memset(&wep, 0, sizeof(struct ndis_802_11_wep)); ++ ++ key = erq->flags & IW_ENCODE_INDEX; ++ ++ ++ ++ if (erq->flags & IW_ENCODE_DISABLED) { ++ DBG_88E("EncryptionDisabled\n"); ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; ++ padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ ++ authmode = Ndis802_11AuthModeOpen; ++ padapter->securitypriv.ndisauthtype = authmode; ++ ++ goto exit; ++ } ++ ++ if (key) { ++ if (key > WEP_KEYS) ++ return -EINVAL; ++ key--; ++ keyindex_provided = 1; ++ } else { ++ keyindex_provided = 0; ++ key = padapter->securitypriv.dot11PrivacyKeyIndex; ++ DBG_88E("rtw_wx_set_enc, key =%d\n", key); ++ } ++ ++ /* set authentication mode */ ++ if (erq->flags & IW_ENCODE_OPEN) { ++ DBG_88E("rtw_wx_set_enc():IW_ENCODE_OPEN\n"); ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */ ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; ++ padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; ++ authmode = Ndis802_11AuthModeOpen; ++ padapter->securitypriv.ndisauthtype = authmode; ++ } else if (erq->flags & IW_ENCODE_RESTRICTED) { ++ DBG_88E("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n"); ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; ++ padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_; ++ authmode = Ndis802_11AuthModeShared; ++ padapter->securitypriv.ndisauthtype = authmode; ++ } else { ++ DBG_88E("rtw_wx_set_enc():erq->flags = 0x%x\n", erq->flags); ++ ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */ ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ ++ padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; ++ authmode = Ndis802_11AuthModeOpen; ++ padapter->securitypriv.ndisauthtype = authmode; ++ } ++ ++ wep.KeyIndex = key; ++ if (erq->length > 0) { ++ wep.KeyLength = erq->length <= 5 ? 5 : 13; ++ ++ wep.Length = wep.KeyLength + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial); ++ } else { ++ wep.KeyLength = 0; ++ ++ if (keyindex_provided == 1) { ++ /* set key_id only, no given KeyMaterial(erq->length == 0). */ ++ padapter->securitypriv.dot11PrivacyKeyIndex = key; ++ ++ DBG_88E("(keyindex_provided == 1), keyid =%d, key_len =%d\n", key, padapter->securitypriv.dot11DefKeylen[key]); ++ ++ switch (padapter->securitypriv.dot11DefKeylen[key]) { ++ case 5: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; ++ break; ++ case 13: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; ++ break; ++ default: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ break; ++ } ++ ++ goto exit; ++ } ++ } ++ ++ wep.KeyIndex |= 0x80000000; ++ ++ memcpy(wep.KeyMaterial, keybuf, wep.KeyLength); ++ ++ if (!rtw_set_802_11_add_wep(padapter, &wep)) { ++ if (rf_on == pwrpriv->rf_pwrstate) ++ ret = -EOPNOTSUPP; ++ goto exit; ++ } ++ ++exit: ++ ++ ++ ++ return ret; ++} ++ ++static int rtw_wx_get_enc(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *keybuf) ++{ ++ uint key, ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct iw_point *erq = &wrqu->encoding; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED) != true) { ++ if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ erq->length = 0; ++ erq->flags |= IW_ENCODE_DISABLED; ++ return 0; ++ } ++ } ++ ++ key = erq->flags & IW_ENCODE_INDEX; ++ ++ if (key) { ++ if (key > WEP_KEYS) ++ return -EINVAL; ++ key--; ++ } else { ++ key = padapter->securitypriv.dot11PrivacyKeyIndex; ++ } ++ ++ erq->flags = key + 1; ++ ++ switch (padapter->securitypriv.ndisencryptstatus) { ++ case Ndis802_11EncryptionNotSupported: ++ case Ndis802_11EncryptionDisabled: ++ erq->length = 0; ++ erq->flags |= IW_ENCODE_DISABLED; ++ break; ++ case Ndis802_11Encryption1Enabled: ++ erq->length = padapter->securitypriv.dot11DefKeylen[key]; ++ if (erq->length) { ++ memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]); ++ ++ erq->flags |= IW_ENCODE_ENABLED; ++ ++ if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) ++ erq->flags |= IW_ENCODE_OPEN; ++ else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared) ++ erq->flags |= IW_ENCODE_RESTRICTED; ++ } else { ++ erq->length = 0; ++ erq->flags |= IW_ENCODE_DISABLED; ++ } ++ break; ++ case Ndis802_11Encryption2Enabled: ++ case Ndis802_11Encryption3Enabled: ++ erq->length = 16; ++ erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY); ++ break; ++ default: ++ erq->length = 0; ++ erq->flags |= IW_ENCODE_DISABLED; ++ break; ++ } ++ ++ ++ return ret; ++} ++ ++static int rtw_wx_get_power(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ wrqu->power.value = 0; ++ wrqu->power.fixed = 0; /* no auto select */ ++ wrqu->power.disabled = 1; ++ ++ return 0; ++} ++ ++static int rtw_wx_set_gen_ie(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length); ++ return ret; ++} ++ ++static int rtw_wx_set_auth(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct iw_param *param = (struct iw_param *)&wrqu->param; ++ int ret = 0; ++ ++ switch (param->flags & IW_AUTH_INDEX) { ++ case IW_AUTH_WPA_VERSION: ++ break; ++ case IW_AUTH_CIPHER_PAIRWISE: ++ ++ break; ++ case IW_AUTH_CIPHER_GROUP: ++ ++ break; ++ case IW_AUTH_KEY_MGMT: ++ /* ++ * ??? does not use these parameters ++ */ ++ break; ++ case IW_AUTH_TKIP_COUNTERMEASURES: ++ if (param->value) { ++ /* wpa_supplicant is enabling the tkip countermeasure. */ ++ padapter->securitypriv.btkip_countermeasure = true; ++ } else { ++ /* wpa_supplicant is disabling the tkip countermeasure. */ ++ padapter->securitypriv.btkip_countermeasure = false; ++ } ++ break; ++ case IW_AUTH_DROP_UNENCRYPTED: ++ /* HACK: ++ * ++ * wpa_supplicant calls set_wpa_enabled when the driver ++ * is loaded and unloaded, regardless of if WPA is being ++ * used. No other calls are made which can be used to ++ * determine if encryption will be used or not prior to ++ * association being expected. If encryption is not being ++ * used, drop_unencrypted is set to false, else true -- we ++ * can use this to determine if the CAP_PRIVACY_ON bit should ++ * be set. ++ */ ++ ++ if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled) ++ break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */ ++ /* then it needn't reset it; */ ++ ++ if (param->value) { ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; ++ padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ ++ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; ++ } ++ ++ break; ++ case IW_AUTH_80211_AUTH_ALG: ++ /* ++ * It's the starting point of a link layer connection using wpa_supplicant ++ */ ++ if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { ++ LeaveAllPowerSaveMode(padapter); ++ rtw_disassoc_cmd(padapter, 500, false); ++ DBG_88E("%s...call rtw_indicate_disconnect\n ", __func__); ++ rtw_indicate_disconnect(padapter); ++ rtw_free_assoc_resources(padapter, 1); ++ } ++ ret = wpa_set_auth_algs(dev, (u32)param->value); ++ break; ++ case IW_AUTH_WPA_ENABLED: ++ break; ++ case IW_AUTH_RX_UNENCRYPTED_EAPOL: ++ break; ++ case IW_AUTH_PRIVACY_INVOKED: ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return ret; ++} ++ ++static int rtw_wx_set_enc_ext(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ char *alg_name; ++ u32 param_len; ++ struct ieee_param *param = NULL; ++ struct iw_point *pencoding = &wrqu->encoding; ++ struct iw_encode_ext *pext = (struct iw_encode_ext *)extra; ++ int ret = 0; ++ ++ param_len = sizeof(struct ieee_param) + pext->key_len; ++ param = kzalloc(param_len, GFP_KERNEL); ++ if (!param) ++ return -ENOMEM; ++ ++ param->cmd = IEEE_CMD_SET_ENCRYPTION; ++ memset(param->sta_addr, 0xff, ETH_ALEN); ++ ++ switch (pext->alg) { ++ case IW_ENCODE_ALG_NONE: ++ /* todo: remove key */ ++ /* remove = 1; */ ++ alg_name = "none"; ++ break; ++ case IW_ENCODE_ALG_WEP: ++ alg_name = "WEP"; ++ break; ++ case IW_ENCODE_ALG_TKIP: ++ alg_name = "TKIP"; ++ break; ++ case IW_ENCODE_ALG_CCMP: ++ alg_name = "CCMP"; ++ break; ++ default: ++ return -1; ++ } ++ ++ strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN); ++ ++ if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) ++ param->u.crypt.set_tx = 1; ++ ++ /* cliW: WEP does not have group key ++ * just not checking GROUP key setting ++ */ ++ if ((pext->alg != IW_ENCODE_ALG_WEP) && ++ (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)) ++ param->u.crypt.set_tx = 0; ++ ++ param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1; ++ ++ if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) ++ memcpy(param->u.crypt.seq, pext->rx_seq, 8); ++ ++ if (pext->key_len) { ++ param->u.crypt.key_len = pext->key_len; ++ memcpy(param->u.crypt.key, pext + 1, pext->key_len); ++ } ++ ++ ret = wpa_set_encryption(dev, param, param_len); ++ ++ kfree(param); ++ return ret; ++} ++ ++static int rtw_wx_get_nick(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ if (extra) { ++ wrqu->data.length = 14; ++ wrqu->data.flags = 1; ++ memcpy(extra, "", 14); ++ } ++ ++ /* dump debug info here */ ++ return 0; ++} ++ ++static int rtw_wx_read32(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter; ++ struct iw_point *p; ++ u16 len; ++ u32 addr; ++ u32 data32; ++ u32 bytes; ++ u8 *ptmp; ++ ++ padapter = (struct adapter *)rtw_netdev_priv(dev); ++ p = &wrqu->data; ++ len = p->length; ++ ptmp = kmalloc(len, GFP_KERNEL); ++ if (!ptmp) ++ return -ENOMEM; ++ ++ if (copy_from_user(ptmp, p->pointer, len)) { ++ kfree(ptmp); ++ return -EFAULT; ++ } ++ ++ bytes = 0; ++ addr = 0; ++ sscanf(ptmp, "%d,%x", &bytes, &addr); ++ ++ switch (bytes) { ++ case 1: ++ data32 = rtw_read8(padapter, addr); ++ sprintf(extra, "0x%02X", data32); ++ break; ++ case 2: ++ data32 = rtw_read16(padapter, addr); ++ sprintf(extra, "0x%04X", data32); ++ break; ++ case 4: ++ data32 = rtw_read32(padapter, addr); ++ sprintf(extra, "0x%08X", data32); ++ break; ++ default: ++ DBG_88E(KERN_INFO "%s: usage> read [bytes],[address(hex)]\n", __func__); ++ return -EINVAL; ++ } ++ DBG_88E(KERN_INFO "%s: addr = 0x%08X data =%s\n", __func__, addr, extra); ++ ++ kfree(ptmp); ++ return 0; ++} ++ ++static int rtw_wx_write32(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ u32 addr; ++ u32 data32; ++ u32 bytes; ++ ++ bytes = 0; ++ addr = 0; ++ data32 = 0; ++ sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32); ++ ++ switch (bytes) { ++ case 1: ++ rtw_write8(padapter, addr, (u8)data32); ++ DBG_88E(KERN_INFO "%s: addr = 0x%08X data = 0x%02X\n", __func__, addr, (u8)data32); ++ break; ++ case 2: ++ rtw_write16(padapter, addr, (u16)data32); ++ DBG_88E(KERN_INFO "%s: addr = 0x%08X data = 0x%04X\n", __func__, addr, (u16)data32); ++ break; ++ case 4: ++ rtw_write32(padapter, addr, data32); ++ DBG_88E(KERN_INFO "%s: addr = 0x%08X data = 0x%08X\n", __func__, addr, data32); ++ break; ++ default: ++ DBG_88E(KERN_INFO "%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int rtw_wx_read_rf(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u32 path, addr, data32; ++ ++ path = *(u32 *)extra; ++ addr = *((u32 *)extra + 1); ++ data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF); ++ /* ++ * IMPORTANT!! ++ * Only when wireless private ioctl is at odd order, ++ * "extra" would be copied to user space. ++ */ ++ sprintf(extra, "0x%05x", data32); ++ ++ return 0; ++} ++ ++static int rtw_wx_write_rf(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u32 path, addr, data32; ++ ++ path = *(u32 *)extra; ++ addr = *((u32 *)extra + 1); ++ data32 = *((u32 *)extra + 2); ++ rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32); ++ ++ return 0; ++} ++ ++static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a, ++ union iwreq_data *wrqu, char *b) ++{ ++ return -1; ++} ++ ++static int dummy(struct net_device *dev, struct iw_request_info *a, ++ union iwreq_data *wrqu, char *b) ++{ ++ return -1; ++} ++ ++static int rtw_wx_set_channel_plan(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 channel_plan_req = (u8)(*((int *)wrqu)); ++ ++ if (_SUCCESS == rtw_set_chplan_cmd(padapter, channel_plan_req, 1)) ++ DBG_88E("%s set channel_plan = 0x%02X\n", __func__, pmlmepriv->ChannelPlan); ++ else ++ return -EPERM; ++ ++ return 0; ++} ++ ++static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev, ++ struct iw_request_info *a, ++ union iwreq_data *wrqu, char *b) ++{ ++ return 0; ++} ++ ++static int rtw_wx_get_sensitivity(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *buf) ++{ ++ return 0; ++} ++ ++static int rtw_wx_set_mtk_wps_ie(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ return 0; ++} ++ ++/* ++ * For all data larger than 16 octets, we need to use a ++ * pointer to memory allocated in user space. ++ */ ++static int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ return 0; ++} ++ ++static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 len) ++{ ++ struct mp_rw_reg *RegRWStruct; ++ struct rf_reg_param *prfreg; ++ u8 path; ++ u8 offset; ++ u32 value; ++ ++ DBG_88E("%s\n", __func__); ++ ++ switch (id) { ++ case GEN_MP_IOCTL_SUBCODE(MP_START): ++ DBG_88E("871x_driver is only for normal mode, can't enter mp mode\n"); ++ break; ++ case GEN_MP_IOCTL_SUBCODE(READ_REG): ++ RegRWStruct = (struct mp_rw_reg *)pdata; ++ switch (RegRWStruct->width) { ++ case 1: ++ RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset); ++ break; ++ case 2: ++ RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset); ++ break; ++ case 4: ++ RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset); ++ break; ++ default: ++ break; ++ } ++ ++ break; ++ case GEN_MP_IOCTL_SUBCODE(WRITE_REG): ++ RegRWStruct = (struct mp_rw_reg *)pdata; ++ switch (RegRWStruct->width) { ++ case 1: ++ rtw_write8(padapter, RegRWStruct->offset, (u8)RegRWStruct->value); ++ break; ++ case 2: ++ rtw_write16(padapter, RegRWStruct->offset, (u16)RegRWStruct->value); ++ break; ++ case 4: ++ rtw_write32(padapter, RegRWStruct->offset, (u32)RegRWStruct->value); ++ break; ++ default: ++ break; ++ } ++ ++ break; ++ case GEN_MP_IOCTL_SUBCODE(READ_RF_REG): ++ ++ prfreg = (struct rf_reg_param *)pdata; ++ ++ path = (u8)prfreg->path; ++ offset = (u8)prfreg->offset; ++ ++ value = rtw_hal_read_rfreg(padapter, path, offset, 0xffffffff); ++ ++ prfreg->value = value; ++ ++ break; ++ case GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG): ++ ++ prfreg = (struct rf_reg_param *)pdata; ++ ++ path = (u8)prfreg->path; ++ offset = (u8)prfreg->offset; ++ value = prfreg->value; ++ ++ rtw_hal_write_rfreg(padapter, path, offset, 0xffffffff, value); ++ ++ break; ++ case GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO): ++ DBG_88E("==> trigger gpio 0\n"); ++ rtw_hal_set_hwreg(padapter, HW_VAR_TRIGGER_GPIO_0, NULL); ++ break; ++ case GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS): ++ *pdata = rtw_hal_sreset_get_wifi_status(padapter); ++ break; ++ default: ++ break; ++ } ++} ++ ++static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ u32 BytesRead, BytesWritten, BytesNeeded; ++ struct oid_par_priv oid_par; ++ struct mp_ioctl_handler *phandler; ++ struct mp_ioctl_param *poidparam; ++ uint status = 0; ++ u16 len; ++ u8 *pparmbuf = NULL, bset; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct iw_point *p = &wrqu->data; ++ ++ if ((!p->length) || (!p->pointer)) { ++ ret = -EINVAL; ++ goto _rtw_mp_ioctl_hdl_exit; ++ } ++ pparmbuf = NULL; ++ bset = (u8)(p->flags & 0xFFFF); ++ len = p->length; ++ pparmbuf = kmalloc(len, GFP_KERNEL); ++ if (!pparmbuf) { ++ ret = -ENOMEM; ++ goto _rtw_mp_ioctl_hdl_exit; ++ } ++ ++ if (copy_from_user(pparmbuf, p->pointer, len)) { ++ ret = -EFAULT; ++ goto _rtw_mp_ioctl_hdl_exit; ++ } ++ ++ poidparam = (struct mp_ioctl_param *)pparmbuf; ++ ++ if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) { ++ ret = -EINVAL; ++ goto _rtw_mp_ioctl_hdl_exit; ++ } ++ ++ if (padapter->registrypriv.mp_mode == 1) { ++ phandler = mp_ioctl_hdl + poidparam->subcode; ++ ++ if ((phandler->paramsize != 0) && (poidparam->len < phandler->paramsize)) { ++ ret = -EINVAL; ++ goto _rtw_mp_ioctl_hdl_exit; ++ } ++ ++ if (phandler->handler) { ++ oid_par.adapter_context = padapter; ++ oid_par.oid = phandler->oid; ++ oid_par.information_buf = poidparam->data; ++ oid_par.information_buf_len = poidparam->len; ++ oid_par.dbg = 0; ++ ++ BytesWritten = 0; ++ BytesNeeded = 0; ++ ++ if (bset) { ++ oid_par.bytes_rw = &BytesRead; ++ oid_par.bytes_needed = &BytesNeeded; ++ oid_par.type_of_oid = SET_OID; ++ } else { ++ oid_par.bytes_rw = &BytesWritten; ++ oid_par.bytes_needed = &BytesNeeded; ++ oid_par.type_of_oid = QUERY_OID; ++ } ++ ++ status = phandler->handler(&oid_par); ++ } else { ++ DBG_88E("rtw_mp_ioctl_hdl(): err!, subcode =%d, oid =%d, handler =%p\n", ++ poidparam->subcode, phandler->oid, phandler->handler); ++ ret = -EFAULT; ++ goto _rtw_mp_ioctl_hdl_exit; ++ } ++ } else { ++ rtw_dbg_mode_hdl(padapter, poidparam->subcode, poidparam->data, poidparam->len); ++ } ++ ++ if (bset == 0x00) {/* query info */ ++ if (copy_to_user(p->pointer, pparmbuf, len)) ++ ret = -EFAULT; ++ } ++ ++ if (status) { ++ ret = -EFAULT; ++ goto _rtw_mp_ioctl_hdl_exit; ++ } ++ ++_rtw_mp_ioctl_hdl_exit: ++ ++ kfree(pparmbuf); ++ return ret; ++} ++ ++static int rtw_get_ap_info(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ u32 cnt = 0, wpa_ielen; ++ struct list_head *plist, *phead; ++ unsigned char *pbuf; ++ u8 bssid[ETH_ALEN]; ++ char data[32]; ++ struct wlan_network *pnetwork = NULL; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct iw_point *pdata = &wrqu->data; ++ ++ DBG_88E("+rtw_get_aplist_info\n"); ++ ++ if (padapter->bDriverStopped || !pdata) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING)))) { ++ msleep(30); ++ cnt++; ++ if (cnt > 100) ++ break; ++ } ++ pdata->flags = 0; ++ if (pdata->length >= 32) { ++ if (copy_from_user(data, pdata->pointer, 32)) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ } else { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ if (!mac_pton(data, bssid)) { ++ DBG_88E("Invalid BSSID '%s'.\n", (u8 *)data); ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ return -EINVAL; ++ } ++ ++ if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) { ++ /* BSSID match, then check if supporting wpa/wpa2 */ ++ DBG_88E("BSSID:%pM\n", (bssid)); ++ ++ pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12); ++ if (pbuf && (wpa_ielen > 0)) { ++ pdata->flags = 1; ++ break; ++ } ++ ++ pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12); ++ if (pbuf && (wpa_ielen > 0)) { ++ pdata->flags = 2; ++ break; ++ } ++ } ++ ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (pdata->length >= 34) { ++ if (copy_to_user(pdata->pointer + 32, (u8 *)&pdata->flags, 1)) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ } ++ ++exit: ++ ++ return ret; ++} ++ ++static int rtw_set_pid(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ int *pdata = (int *)wrqu; ++ int selector; ++ ++ if (padapter->bDriverStopped || !pdata) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ selector = *pdata; ++ if (selector < 3 && selector >= 0) { ++ padapter->pid[selector] = *(pdata + 1); ++ ui_pid[selector] = *(pdata + 1); ++ DBG_88E("%s set pid[%d] =%d\n", __func__, selector, padapter->pid[selector]); ++ } else { ++ DBG_88E("%s selector %d error\n", __func__, selector); ++ } ++exit: ++ return ret; ++} ++ ++static int rtw_wps_start(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct iw_point *pdata = &wrqu->data; ++ u32 u32wps_start = 0; ++ ++ if (!pdata) ++ return -EINVAL; ++ ret = copy_from_user((void *)&u32wps_start, pdata->pointer, 4); ++ if (ret) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ if (padapter->bDriverStopped) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ if (u32wps_start == 0) ++ u32wps_start = *extra; ++ ++ DBG_88E("[%s] wps_start = %d\n", __func__, u32wps_start); ++ ++ if (u32wps_start == 1) /* WPS Start */ ++ rtw_led_control(padapter, LED_CTL_START_WPS); ++ else if (u32wps_start == 2) /* WPS Stop because of wps success */ ++ rtw_led_control(padapter, LED_CTL_STOP_WPS); ++ else if (u32wps_start == 3) /* WPS Stop because of wps fail */ ++ rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL); ++ ++exit: ++ return ret; ++} ++ ++#ifdef CONFIG_88EU_P2P ++static int rtw_wext_p2p_enable(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ enum P2P_ROLE init_role = P2P_ROLE_DISABLE; ++ ++ if (*extra == '0') ++ init_role = P2P_ROLE_DISABLE; ++ else if (*extra == '1') ++ init_role = P2P_ROLE_DEVICE; ++ else if (*extra == '2') ++ init_role = P2P_ROLE_CLIENT; ++ else if (*extra == '3') ++ init_role = P2P_ROLE_GO; ++ ++ if (_FAIL == rtw_p2p_enable(padapter, init_role)) { ++ ret = -EFAULT; ++ goto exit; ++ } ++ ++ /* set channel/bandwidth */ ++ if (init_role != P2P_ROLE_DISABLE) { ++ u8 channel, ch_offset; ++ u16 bwmode; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) { ++ /* Stay at the listen state and wait for discovery. */ ++ channel = pwdinfo->listen_channel; ++ pwdinfo->operating_channel = pwdinfo->listen_channel; ++ ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ bwmode = HT_CHANNEL_WIDTH_20; ++ } else { ++ pwdinfo->operating_channel = pmlmeext->cur_channel; ++ ++ channel = pwdinfo->operating_channel; ++ ch_offset = pmlmeext->cur_ch_offset; ++ bwmode = pmlmeext->cur_bwmode; ++ } ++ ++ set_channel_bwmode(padapter, channel, ch_offset, bwmode); ++ } ++ ++exit: ++ return ret; ++} ++ ++static int rtw_p2p_set_go_nego_ssid(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] ssid = %s, len = %zu\n", __func__, extra, strlen(extra)); ++ memcpy(pwdinfo->nego_ssid, extra, strlen(extra)); ++ pwdinfo->nego_ssidlen = strlen(extra); ++ ++ return ret; ++} ++ ++static int rtw_p2p_set_intent(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 intent = pwdinfo->intent; ++ ++ switch (wrqu->data.length) { ++ case 1: ++ intent = extra[0] - '0'; ++ break; ++ case 2: ++ intent = str_2char2num(extra[0], extra[1]); ++ break; ++ } ++ if (intent <= 15) ++ pwdinfo->intent = intent; ++ else ++ ret = -1; ++ DBG_88E("[%s] intent = %d\n", __func__, intent); ++ return ret; ++} ++ ++static int rtw_p2p_set_listen_ch(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 listen_ch = pwdinfo->listen_channel; /* Listen channel number */ ++ ++ switch (wrqu->data.length) { ++ case 1: ++ listen_ch = extra[0] - '0'; ++ break; ++ case 2: ++ listen_ch = str_2char2num(extra[0], extra[1]); ++ break; ++ } ++ ++ if ((listen_ch == 1) || (listen_ch == 6) || (listen_ch == 11)) { ++ pwdinfo->listen_channel = listen_ch; ++ set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ } else { ++ ret = -1; ++ } ++ ++ DBG_88E("[%s] listen_ch = %d\n", __func__, pwdinfo->listen_channel); ++ ++ return ret; ++} ++ ++static int rtw_p2p_set_op_ch(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++/* Commented by Albert 20110524 */ ++/* This function is used to set the operating channel if the driver will become the group owner */ ++ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 op_ch = pwdinfo->operating_channel; /* Operating channel number */ ++ ++ switch (wrqu->data.length) { ++ case 1: ++ op_ch = extra[0] - '0'; ++ break; ++ case 2: ++ op_ch = str_2char2num(extra[0], extra[1]); ++ break; ++ } ++ ++ if (op_ch > 0) ++ pwdinfo->operating_channel = op_ch; ++ else ++ ret = -1; ++ ++ DBG_88E("[%s] op_ch = %d\n", __func__, pwdinfo->operating_channel); ++ ++ return ret; ++} ++ ++static int rtw_p2p_profilefound(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ /* Comment by Albert 2010/10/13 */ ++ /* Input data format: */ ++ /* Ex: 0 */ ++ /* Ex: 1XX:XX:XX:XX:XX:XXYYSSID */ ++ /* 0 => Reflush the profile record list. */ ++ /* 1 => Add the profile list */ ++ /* XX:XX:XX:XX:XX:XX => peer's MAC Address (ex: 00:E0:4C:00:00:01) */ ++ /* YY => SSID Length */ ++ /* SSID => SSID for persistence group */ ++ ++ DBG_88E("[%s] In value = %s, len = %d\n", __func__, extra, wrqu->data.length - 1); ++ ++ /* The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function. */ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ++ if (extra[0] == '0') { ++ /* Remove all the profile information of wifidirect_info structure. */ ++ memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM); ++ pwdinfo->profileindex = 0; ++ } else { ++ if (pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM) { ++ ret = -1; ++ } else { ++ int jj, kk; ++ ++ /* Add this profile information into pwdinfo->profileinfo */ ++ /* Ex: 1XX:XX:XX:XX:XX:XXYYSSID */ ++ for (jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3) ++ pwdinfo->profileinfo[pwdinfo->profileindex].peermac[jj] = key_2char2num(extra[kk], extra[kk + 1]); ++ ++ pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen = (extra[18] - '0') * 10 + (extra[19] - '0'); ++ memcpy(pwdinfo->profileinfo[pwdinfo->profileindex].ssid, &extra[20], pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen); ++ pwdinfo->profileindex++; ++ } ++ } ++ } ++ ++ return ret; ++} ++ ++static int rtw_p2p_setDN(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] %s %d\n", __func__, extra, wrqu->data.length - 1); ++ memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN); ++ memcpy(pwdinfo->device_name, extra, wrqu->data.length - 1); ++ pwdinfo->device_name_len = wrqu->data.length - 1; ++ ++ return ret; ++} ++ ++static int rtw_p2p_get_status(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ if (padapter->bShowGetP2PState) ++ DBG_88E("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), ++ pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2], ++ pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]); ++ ++ /* Commented by Albert 2010/10/12 */ ++ /* Because of the output size limitation, I had removed the "Role" information. */ ++ /* About the "Role" information, we will use the new private IOCTL to get the "Role" information. */ ++ sprintf(extra, "\n\nStatus =%.2d\n", rtw_p2p_state(pwdinfo)); ++ wrqu->data.length = strlen(extra); ++ ++ return ret; ++} ++ ++/* Commented by Albert 20110520 */ ++/* This function will return the config method description */ ++/* This config method description will show us which config method the remote P2P device is intended to use */ ++/* by sending the provisioning discovery request frame. */ ++ ++static int rtw_p2p_get_req_cm(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ sprintf(extra, "\n\nCM =%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req); ++ wrqu->data.length = strlen(extra); ++ return ret; ++} ++ ++static int rtw_p2p_get_role(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), ++ pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2], ++ pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]); ++ ++ sprintf(extra, "\n\nRole =%.2d\n", rtw_p2p_role(pwdinfo)); ++ wrqu->data.length = strlen(extra); ++ return ret; ++} ++ ++static int rtw_p2p_get_peer_ifaddr(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] Role = %d, Status = %d, peer addr = %pM\n", __func__, ++ rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), ++ pwdinfo->p2p_peer_interface_addr); ++ sprintf(extra, "\nMAC %pM", ++ pwdinfo->p2p_peer_interface_addr); ++ wrqu->data.length = strlen(extra); ++ return ret; ++} ++ ++static int rtw_p2p_get_peer_devaddr(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++ ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] Role = %d, Status = %d, peer addr = %pM\n", __func__, ++ rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), ++ pwdinfo->rx_prov_disc_info.peerDevAddr); ++ sprintf(extra, "\n%pM", ++ pwdinfo->rx_prov_disc_info.peerDevAddr); ++ wrqu->data.length = strlen(extra); ++ return ret; ++} ++ ++static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++ ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] Role = %d, Status = %d, peer addr = %pM\n", ++ __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), ++ pwdinfo->p2p_peer_device_addr); ++ sprintf(extra, "\nMAC %pM", ++ pwdinfo->p2p_peer_device_addr); ++ wrqu->data.length = strlen(extra); ++ return ret; ++} ++ ++static int rtw_p2p_get_groupid(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++ ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ sprintf(extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s", ++ pwdinfo->groupid_info.go_device_addr[0], pwdinfo->groupid_info.go_device_addr[1], ++ pwdinfo->groupid_info.go_device_addr[2], pwdinfo->groupid_info.go_device_addr[3], ++ pwdinfo->groupid_info.go_device_addr[4], pwdinfo->groupid_info.go_device_addr[5], ++ pwdinfo->groupid_info.ssid); ++ wrqu->data.length = strlen(extra); ++ return ret; ++} ++ ++static int rtw_p2p_get_op_ch(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++ ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] Op_ch = %02x\n", __func__, pwdinfo->operating_channel); ++ ++ sprintf(extra, "\n\nOp_ch =%.2d\n", pwdinfo->operating_channel); ++ wrqu->data.length = strlen(extra); ++ return ret; ++} ++ ++static int rtw_p2p_get_wps_configmethod(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u8 peerMAC[ETH_ALEN] = {0x00}; ++ int jj, kk; ++ u8 peerMACStr[17] = {0x00}; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ u8 blnMatch = 0; ++ u16 attr_content = 0; ++ uint attr_contentlen = 0; ++ /* 6 is the string "wpsCM =", 17 is the MAC addr, we have to clear it at wrqu->data.pointer */ ++ u8 attr_content_str[6 + 17] = {0x00}; ++ ++ /* Commented by Albert 20110727 */ ++ /* The input data is the MAC address which the application wants to know its WPS config method. */ ++ /* After knowing its WPS config method, the application can decide the config method for provisioning discovery. */ ++ /* Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05 */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, (char *)extra); ++ if (copy_from_user(peerMACStr, wrqu->data.pointer + 6, 17)) ++ return -EFAULT; ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]); ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) { ++ u8 *wpsie; ++ uint wpsie_len = 0; ++ __be16 be_tmp; ++ ++ /* The mac address is matched. */ ++ wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len); ++ if (wpsie) { ++ rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&be_tmp, &attr_contentlen); ++ if (attr_contentlen) { ++ attr_content = be16_to_cpu(be_tmp); ++ sprintf(attr_content_str, "\n\nM =%.4d", attr_content); ++ blnMatch = 1; ++ } ++ } ++ break; ++ } ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (!blnMatch) ++ sprintf(attr_content_str, "\n\nM = 0000"); ++ ++ if (copy_to_user(wrqu->data.pointer, attr_content_str, 6 + 17)) ++ return -EFAULT; ++ return ret; ++} ++ ++static int rtw_p2p_get_go_device_address(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u8 peerMAC[ETH_ALEN] = {0x00}; ++ int jj, kk; ++ u8 peerMACStr[17] = {0x00}; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ u8 blnMatch = 0; ++ u8 *p2pie; ++ uint p2pielen = 0, attr_contentlen = 0; ++ u8 attr_content[100] = {0x00}; ++ ++ u8 go_devadd_str[100 + 10] = {0x00}; ++ /* +10 is for the str "go_devadd =", we have to clear it at wrqu->data.pointer */ ++ ++ /* Commented by Albert 20121209 */ ++ /* The input data is the GO's interface address which the application wants to know its device address. */ ++ /* Format: iwpriv wlanx p2p_get2 go_devadd = 00:E0:4C:00:00:05 */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, (char *)extra); ++ if (copy_from_user(peerMACStr, wrqu->data.pointer + 10, 17)) ++ return -EFAULT; ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]); ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) { ++ /* Commented by Albert 2011/05/18 */ ++ /* Match the device address located in the P2P IE */ ++ /* This is for the case that the P2P device address is not the same as the P2P interface address. */ ++ ++ p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen); ++ if (p2pie) { ++ while (p2pie) { ++ /* The P2P Device ID attribute is included in the Beacon frame. */ ++ /* The P2P Device Info attribute is included in the probe response frame. */ ++ ++ memset(attr_content, 0x00, 100); ++ if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) { ++ /* Handle the P2P Device ID attribute of Beacon first */ ++ blnMatch = 1; ++ break; ++ } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) { ++ /* Handle the P2P Device Info attribute of probe response */ ++ blnMatch = 1; ++ break; ++ } ++ ++ /* Get the next P2P IE */ ++ p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen); ++ } ++ } ++ } ++ ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (!blnMatch) ++ sprintf(go_devadd_str, "\n\ndev_add = NULL"); ++ else ++ sprintf(go_devadd_str, "\ndev_add =%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", ++ attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]); ++ ++ if (copy_to_user(wrqu->data.pointer, go_devadd_str, 10 + 17)) ++ return -EFAULT; ++ return ret; ++} ++ ++static int rtw_p2p_get_device_type(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u8 peerMAC[ETH_ALEN] = {0x00}; ++ int jj, kk; ++ u8 peerMACStr[17] = {0x00}; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ u8 blnMatch = 0; ++ u8 dev_type[8] = {0x00}; ++ uint dev_type_len = 0; ++ u8 dev_type_str[17 + 9] = {0x00}; /* +9 is for the str "dev_type =", we have to clear it at wrqu->data.pointer */ ++ ++ /* Commented by Albert 20121209 */ ++ /* The input data is the MAC address which the application wants to know its device type. */ ++ /* Such user interface could know the device type. */ ++ /* Format: iwpriv wlanx p2p_get2 dev_type = 00:E0:4C:00:00:05 */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, (char *)extra); ++ if (copy_from_user(peerMACStr, wrqu->data.pointer + 9, 17)) ++ return -EFAULT; ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]); ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) { ++ u8 *wpsie; ++ uint wpsie_len = 0; ++ ++ /* The mac address is matched. */ ++ ++ wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], ++ pnetwork->network.IELength - 12, ++ NULL, &wpsie_len); ++ if (wpsie) { ++ rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len); ++ if (dev_type_len) { ++ u16 type = 0; ++ __be16 be_tmp; ++ ++ memcpy(&be_tmp, dev_type, 2); ++ type = be16_to_cpu(be_tmp); ++ sprintf(dev_type_str, "\n\nN =%.2d", type); ++ blnMatch = 1; ++ } ++ } ++ break; ++ } ++ ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (!blnMatch) ++ sprintf(dev_type_str, "\n\nN = 00"); ++ ++ if (copy_to_user(wrqu->data.pointer, dev_type_str, 9 + 17)) { ++ return -EFAULT; ++ } ++ ++ return ret; ++} ++ ++static int rtw_p2p_get_device_name(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u8 peerMAC[ETH_ALEN] = {0x00}; ++ int jj, kk; ++ u8 peerMACStr[17] = {0x00}; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ u8 blnMatch = 0; ++ u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = {0x00}; ++ uint dev_len = 0; ++ u8 dev_name_str[WPS_MAX_DEVICE_NAME_LEN + 5] = {0x00}; /* +5 is for the str "devN =", we have to clear it at wrqu->data.pointer */ ++ ++ /* Commented by Albert 20121225 */ ++ /* The input data is the MAC address which the application wants to know its device name. */ ++ /* Such user interface could show peer device's device name instead of ssid. */ ++ /* Format: iwpriv wlanx p2p_get2 devN = 00:E0:4C:00:00:05 */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, (char *)extra); ++ if (copy_from_user(peerMACStr, wrqu->data.pointer + 5, 17)) ++ return -EFAULT; ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]); ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) { ++ u8 *wpsie; ++ uint wpsie_len = 0; ++ ++ /* The mac address is matched. */ ++ wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len); ++ if (wpsie) { ++ rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len); ++ if (dev_len) { ++ sprintf(dev_name_str, "\n\nN =%s", dev_name); ++ blnMatch = 1; ++ } ++ } ++ break; ++ } ++ ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (!blnMatch) ++ sprintf(dev_name_str, "\n\nN = 0000"); ++ ++ if (copy_to_user(wrqu->data.pointer, dev_name_str, 5 + ((dev_len > 17) ? dev_len : 17))) ++ return -EFAULT; ++ return ret; ++} ++ ++static int rtw_p2p_get_invitation_procedure(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u8 peerMAC[ETH_ALEN] = {0x00}; ++ int jj, kk; ++ u8 peerMACStr[17] = {0x00}; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ u8 blnMatch = 0; ++ u8 *p2pie; ++ uint p2pielen = 0, attr_contentlen = 0; ++ u8 attr_content[2] = {0x00}; ++ ++ u8 inv_proc_str[17 + 8] = {0x00}; ++ /* +8 is for the str "InvProc =", we have to clear it at wrqu->data.pointer */ ++ ++ /* Commented by Ouden 20121226 */ ++ /* The application wants to know P2P initiation procedure is supported or not. */ ++ /* Format: iwpriv wlanx p2p_get2 InvProc = 00:E0:4C:00:00:05 */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, (char *)extra); ++ if (copy_from_user(peerMACStr, wrqu->data.pointer + 8, 17)) ++ return -EFAULT; ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]); ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) { ++ /* Commented by Albert 20121226 */ ++ /* Match the device address located in the P2P IE */ ++ /* This is for the case that the P2P device address is not the same as the P2P interface address. */ ++ ++ p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen); ++ if (p2pie) { ++ while (p2pie) { ++ if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen)) { ++ /* Handle the P2P capability attribute */ ++ blnMatch = 1; ++ break; ++ } ++ ++ /* Get the next P2P IE */ ++ p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen); ++ } ++ } ++ } ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (!blnMatch) { ++ sprintf(inv_proc_str, "\nIP =-1"); ++ } else { ++ if (attr_content[0] & 0x20) ++ sprintf(inv_proc_str, "\nIP = 1"); ++ else ++ sprintf(inv_proc_str, "\nIP = 0"); ++ } ++ if (copy_to_user(wrqu->data.pointer, inv_proc_str, 8 + 17)) ++ return -EFAULT; ++ return ret; ++} ++ ++static int rtw_p2p_connect(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 peerMAC[ETH_ALEN] = {0x00}; ++ int jj, kk; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ uint uintPeerChannel = 0; ++ ++ /* Commented by Albert 20110304 */ ++ /* The input data contains two informations. */ ++ /* 1. First information is the MAC address which wants to formate with */ ++ /* 2. Second information is the WPS PINCode or "pbc" string for push button method */ ++ /* Format: 00:E0:4C:00:00:05 */ ++ /* Format: 00:E0:4C:00:00:05 */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, extra); ++ ++ if (pwdinfo->p2p_state == P2P_STATE_NONE) { ++ DBG_88E("[%s] WiFi Direct is disable!\n", __func__); ++ return ret; ++ } ++ ++ if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO) ++ return -1; ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]); ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) { ++ uintPeerChannel = pnetwork->network.Configuration.DSConfig; ++ break; ++ } ++ ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (uintPeerChannel) { ++ memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info)); ++ memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info)); ++ ++ pwdinfo->nego_req_info.peer_channel_num[0] = uintPeerChannel; ++ memcpy(pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN); ++ pwdinfo->nego_req_info.benable = true; ++ ++ _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); ++ if (rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK) { ++ /* Restore to the listen state if the current p2p state is not nego OK */ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); ++ } ++ ++ rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING); ++ ++ DBG_88E("[%s] Start PreTx Procedure!\n", __func__); ++ _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); ++ _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT); ++ } else { ++ DBG_88E("[%s] Not Found in Scanning Queue~\n", __func__); ++ ret = -1; ++ } ++ return ret; ++} ++ ++static int rtw_p2p_invite_req(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ int jj, kk; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ uint uintPeerChannel = 0; ++ u8 attr_content[50] = {0x00}; ++ u8 *p2pie; ++ uint p2pielen = 0, attr_contentlen = 0; ++ struct tx_invite_req_info *pinvite_req_info = &pwdinfo->invitereq_info; ++ ++ /* The input data contains two informations. */ ++ /* 1. First information is the P2P device address which you want to send to. */ ++ /* 2. Second information is the group id which combines with GO's mac address, space and GO's ssid. */ ++ /* Command line sample: iwpriv wlan0 p2p_set invite ="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */ ++ /* Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, extra); ++ ++ if (wrqu->data.length <= 37) { ++ DBG_88E("[%s] Wrong format!\n", __func__); ++ return ret; ++ } ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ++ DBG_88E("[%s] WiFi Direct is disable!\n", __func__); ++ return ret; ++ } else { ++ /* Reset the content of struct tx_invite_req_info */ ++ pinvite_req_info->benable = false; ++ memset(pinvite_req_info->go_bssid, 0x00, ETH_ALEN); ++ memset(pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN); ++ pinvite_req_info->ssidlen = 0x00; ++ pinvite_req_info->operating_ch = pwdinfo->operating_channel; ++ memset(pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN); ++ pinvite_req_info->token = 3; ++ } ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ pinvite_req_info->peer_macaddr[jj] = key_2char2num(extra[kk], extra[kk + 1]); ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ /* Commented by Albert 2011/05/18 */ ++ /* Match the device address located in the P2P IE */ ++ /* This is for the case that the P2P device address is not the same as the P2P interface address. */ ++ ++ p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen); ++ if (p2pie) { ++ /* The P2P Device ID attribute is included in the Beacon frame. */ ++ /* The P2P Device Info attribute is included in the probe response frame. */ ++ ++ if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) { ++ /* Handle the P2P Device ID attribute of Beacon first */ ++ if (!memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) { ++ uintPeerChannel = pnetwork->network.Configuration.DSConfig; ++ break; ++ } ++ } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) { ++ /* Handle the P2P Device Info attribute of probe response */ ++ if (!memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) { ++ uintPeerChannel = pnetwork->network.Configuration.DSConfig; ++ break; ++ } ++ } ++ } ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (uintPeerChannel) { ++ /* Store the GO's bssid */ ++ for (jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3) ++ pinvite_req_info->go_bssid[jj] = key_2char2num(extra[kk], extra[kk + 1]); ++ ++ /* Store the GO's ssid */ ++ pinvite_req_info->ssidlen = wrqu->data.length - 36; ++ memcpy(pinvite_req_info->go_ssid, &extra[36], (u32)pinvite_req_info->ssidlen); ++ pinvite_req_info->benable = true; ++ pinvite_req_info->peer_ch = uintPeerChannel; ++ ++ rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ); ++ ++ set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ ++ _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); ++ ++ _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT); ++ } else { ++ DBG_88E("[%s] NOT Found in the Scanning Queue!\n", __func__); ++ } ++ return ret; ++} ++ ++static int rtw_p2p_set_persistent(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ /* The input data is 0 or 1 */ ++ /* 0: disable persistent group functionality */ ++ /* 1: enable persistent group founctionality */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, extra); ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ++ DBG_88E("[%s] WiFi Direct is disable!\n", __func__); ++ return ret; ++ } else { ++ if (extra[0] == '0') /* Disable the persistent group function. */ ++ pwdinfo->persistent_supported = false; ++ else if (extra[0] == '1') /* Enable the persistent group function. */ ++ pwdinfo->persistent_supported = true; ++ else ++ pwdinfo->persistent_supported = false; ++ } ++ pr_info("[%s] persistent_supported = %d\n", __func__, pwdinfo->persistent_supported); ++ return ret; ++} ++ ++static int rtw_p2p_prov_disc(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 peerMAC[ETH_ALEN] = {0x00}; ++ int jj, kk; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ uint uintPeerChannel = 0; ++ u8 attr_content[100] = {0x00}; ++ u8 *p2pie; ++ uint p2pielen = 0, attr_contentlen = 0; ++ ++ /* The input data contains two informations. */ ++ /* 1. First information is the MAC address which wants to issue the provisioning discovery request frame. */ ++ /* 2. Second information is the WPS configuration method which wants to discovery */ ++ /* Format: 00:E0:4C:00:00:05_display */ ++ /* Format: 00:E0:4C:00:00:05_keypad */ ++ /* Format: 00:E0:4C:00:00:05_pbc */ ++ /* Format: 00:E0:4C:00:00:05_label */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, extra); ++ ++ if (pwdinfo->p2p_state == P2P_STATE_NONE) { ++ DBG_88E("[%s] WiFi Direct is disable!\n", __func__); ++ return ret; ++ } else { ++ /* Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request. */ ++ memset(pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN); ++ memset(pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN); ++ memset(&pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof(struct ndis_802_11_ssid)); ++ pwdinfo->tx_prov_disc_info.peer_channel_num[0] = 0; ++ pwdinfo->tx_prov_disc_info.peer_channel_num[1] = 0; ++ pwdinfo->tx_prov_disc_info.benable = false; ++ } ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]); ++ ++ if (!memcmp(&extra[18], "display", 7)) { ++ pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA; ++ } else if (!memcmp(&extra[18], "keypad", 7)) { ++ pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD; ++ } else if (!memcmp(&extra[18], "pbc", 3)) { ++ pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON; ++ } else if (!memcmp(&extra[18], "label", 5)) { ++ pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL; ++ } else { ++ DBG_88E("[%s] Unknown WPS config methodn", __func__); ++ return ret; ++ } ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ if (uintPeerChannel != 0) ++ break; ++ ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ /* Commented by Albert 2011/05/18 */ ++ /* Match the device address located in the P2P IE */ ++ /* This is for the case that the P2P device address is not the same as the P2P interface address. */ ++ ++ p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen); ++ if (p2pie) { ++ while (p2pie) { ++ /* The P2P Device ID attribute is included in the Beacon frame. */ ++ /* The P2P Device Info attribute is included in the probe response frame. */ ++ ++ if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) { ++ /* Handle the P2P Device ID attribute of Beacon first */ ++ if (!memcmp(attr_content, peerMAC, ETH_ALEN)) { ++ uintPeerChannel = pnetwork->network.Configuration.DSConfig; ++ break; ++ } ++ } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) { ++ /* Handle the P2P Device Info attribute of probe response */ ++ if (!memcmp(attr_content, peerMAC, ETH_ALEN)) { ++ uintPeerChannel = pnetwork->network.Configuration.DSConfig; ++ break; ++ } ++ } ++ ++ /* Get the next P2P IE */ ++ p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen); ++ } ++ } ++ ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (uintPeerChannel) { ++ DBG_88E("[%s] peer channel: %d!\n", __func__, uintPeerChannel); ++ memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN); ++ memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN); ++ pwdinfo->tx_prov_disc_info.peer_channel_num[0] = (u16)uintPeerChannel; ++ pwdinfo->tx_prov_disc_info.benable = true; ++ rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ); ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) { ++ memcpy(&pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof(struct ndis_802_11_ssid)); ++ } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ memcpy(pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN); ++ pwdinfo->tx_prov_disc_info.ssid.SsidLength = P2P_WILDCARD_SSID_LEN; ++ } ++ ++ set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ ++ _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); ++ ++ _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT); ++ } else { ++ DBG_88E("[%s] NOT Found in the Scanning Queue!\n", __func__); ++ } ++ return ret; ++} ++ ++/* This function is used to inform the driver the user had specified the pin code value or pbc */ ++/* to application. */ ++ ++static int rtw_p2p_got_wpsinfo(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] data = %s\n", __func__, extra); ++ /* Added by Albert 20110328 */ ++ /* if the input data is P2P_NO_WPSINFO -> reset the wpsinfo */ ++ /* if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device. */ ++ /* if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself. */ ++ /* if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC */ ++ ++ if (*extra == '0') ++ pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO; ++ else if (*extra == '1') ++ pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN; ++ else if (*extra == '2') ++ pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN; ++ else if (*extra == '3') ++ pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC; ++ else ++ pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO; ++ return ret; ++} ++ ++#endif /* CONFIG_88EU_P2P */ ++ ++static int rtw_p2p_set(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ ++#ifdef CONFIG_88EU_P2P ++ DBG_88E("[%s] extra = %s\n", __func__, extra); ++ if (!memcmp(extra, "enable =", 7)) { ++ rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]); ++ } else if (!memcmp(extra, "setDN =", 6)) { ++ wrqu->data.length -= 6; ++ rtw_p2p_setDN(dev, info, wrqu, &extra[6]); ++ } else if (!memcmp(extra, "profilefound =", 13)) { ++ wrqu->data.length -= 13; ++ rtw_p2p_profilefound(dev, info, wrqu, &extra[13]); ++ } else if (!memcmp(extra, "prov_disc =", 10)) { ++ wrqu->data.length -= 10; ++ rtw_p2p_prov_disc(dev, info, wrqu, &extra[10]); ++ } else if (!memcmp(extra, "nego =", 5)) { ++ wrqu->data.length -= 5; ++ rtw_p2p_connect(dev, info, wrqu, &extra[5]); ++ } else if (!memcmp(extra, "intent =", 7)) { ++ /* Commented by Albert 2011/03/23 */ ++ /* The wrqu->data.length will include the null character */ ++ /* So, we will decrease 7 + 1 */ ++ wrqu->data.length -= 8; ++ rtw_p2p_set_intent(dev, info, wrqu, &extra[7]); ++ } else if (!memcmp(extra, "ssid =", 5)) { ++ wrqu->data.length -= 5; ++ rtw_p2p_set_go_nego_ssid(dev, info, wrqu, &extra[5]); ++ } else if (!memcmp(extra, "got_wpsinfo =", 12)) { ++ wrqu->data.length -= 12; ++ rtw_p2p_got_wpsinfo(dev, info, wrqu, &extra[12]); ++ } else if (!memcmp(extra, "listen_ch =", 10)) { ++ /* Commented by Albert 2011/05/24 */ ++ /* The wrqu->data.length will include the null character */ ++ /* So, we will decrease (10 + 1) */ ++ wrqu->data.length -= 11; ++ rtw_p2p_set_listen_ch(dev, info, wrqu, &extra[10]); ++ } else if (!memcmp(extra, "op_ch =", 6)) { ++ /* Commented by Albert 2011/05/24 */ ++ /* The wrqu->data.length will include the null character */ ++ /* So, we will decrease (6 + 1) */ ++ wrqu->data.length -= 7; ++ rtw_p2p_set_op_ch(dev, info, wrqu, &extra[6]); ++ } else if (!memcmp(extra, "invite =", 7)) { ++ wrqu->data.length -= 8; ++ rtw_p2p_invite_req(dev, info, wrqu, &extra[7]); ++ } else if (!memcmp(extra, "persistent =", 11)) { ++ wrqu->data.length -= 11; ++ rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]); ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ return ret; ++} ++ ++static int rtw_p2p_get(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ ++#ifdef CONFIG_88EU_P2P ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ if (padapter->bShowGetP2PState) ++ DBG_88E("[%s] extra = %s\n", __func__, (char *)wrqu->data.pointer); ++ if (!memcmp(wrqu->data.pointer, "status", 6)) { ++ rtw_p2p_get_status(dev, info, wrqu, extra); ++ } else if (!memcmp(wrqu->data.pointer, "role", 4)) { ++ rtw_p2p_get_role(dev, info, wrqu, extra); ++ } else if (!memcmp(wrqu->data.pointer, "peer_ifa", 8)) { ++ rtw_p2p_get_peer_ifaddr(dev, info, wrqu, extra); ++ } else if (!memcmp(wrqu->data.pointer, "req_cm", 6)) { ++ rtw_p2p_get_req_cm(dev, info, wrqu, extra); ++ } else if (!memcmp(wrqu->data.pointer, "peer_deva", 9)) { ++ /* Get the P2P device address when receiving the provision discovery request frame. */ ++ rtw_p2p_get_peer_devaddr(dev, info, wrqu, extra); ++ } else if (!memcmp(wrqu->data.pointer, "group_id", 8)) { ++ rtw_p2p_get_groupid(dev, info, wrqu, extra); ++ } else if (!memcmp(wrqu->data.pointer, "peer_deva_inv", 9)) { ++ /* Get the P2P device address when receiving the P2P Invitation request frame. */ ++ rtw_p2p_get_peer_devaddr_by_invitation(dev, info, wrqu, extra); ++ } else if (!memcmp(wrqu->data.pointer, "op_ch", 5)) { ++ rtw_p2p_get_op_ch(dev, info, wrqu, extra); ++ } ++#endif /* CONFIG_88EU_P2P */ ++ return ret; ++} ++ ++static int rtw_p2p_get2(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ ++#ifdef CONFIG_88EU_P2P ++ DBG_88E("[%s] extra = %s\n", __func__, (char *)wrqu->data.pointer); ++ if (!memcmp(extra, "wpsCM =", 6)) { ++ wrqu->data.length -= 6; ++ rtw_p2p_get_wps_configmethod(dev, info, wrqu, &extra[6]); ++ } else if (!memcmp(extra, "devN =", 5)) { ++ wrqu->data.length -= 5; ++ rtw_p2p_get_device_name(dev, info, wrqu, &extra[5]); ++ } else if (!memcmp(extra, "dev_type =", 9)) { ++ wrqu->data.length -= 9; ++ rtw_p2p_get_device_type(dev, info, wrqu, &extra[9]); ++ } else if (!memcmp(extra, "go_devadd =", 10)) { ++ wrqu->data.length -= 10; ++ rtw_p2p_get_go_device_address(dev, info, wrqu, &extra[10]); ++ } else if (!memcmp(extra, "InvProc =", 8)) { ++ wrqu->data.length -= 8; ++ rtw_p2p_get_invitation_procedure(dev, info, wrqu, &extra[8]); ++ } ++ ++#endif /* CONFIG_88EU_P2P */ ++ ++ return ret; ++} ++ ++static int rtw_cta_test_start(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ DBG_88E("%s %s\n", __func__, extra); ++ if (!strcmp(extra, "1")) ++ padapter->in_cta_test = 1; ++ else ++ padapter->in_cta_test = 0; ++ ++ if (padapter->in_cta_test) { ++ u32 v = rtw_read32(padapter, REG_RCR); ++ v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */ ++ rtw_write32(padapter, REG_RCR, v); ++ DBG_88E("enable RCR_ADF\n"); ++ } else { ++ u32 v = rtw_read32(padapter, REG_RCR); ++ v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;/* RCR_ADF */ ++ rtw_write32(padapter, REG_RCR, v); ++ DBG_88E("disable RCR_ADF\n"); ++ } ++ return ret; ++} ++ ++static int rtw_rereg_nd_name(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv; ++ char new_ifname[IFNAMSIZ]; ++ ++ if (rereg_priv->old_ifname[0] == 0) { ++ char *reg_ifname; ++ reg_ifname = padapter->registrypriv.if2name; ++ ++ strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ); ++ rereg_priv->old_ifname[IFNAMSIZ - 1] = 0; ++ } ++ ++ if (wrqu->data.length > IFNAMSIZ) ++ return -EFAULT; ++ ++ if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ)) ++ return -EFAULT; ++ ++ if (0 == strcmp(rereg_priv->old_ifname, new_ifname)) ++ return ret; ++ ++ DBG_88E("%s new_ifname:%s\n", __func__, new_ifname); ++ ret = rtw_change_ifname(padapter, new_ifname); ++ if (0 != ret) ++ goto exit; ++ ++ if (!memcmp(rereg_priv->old_ifname, "disable%d", 9)) { ++ padapter->ledpriv.bRegUseLed = rereg_priv->old_bRegUseLed; ++ rtw_hal_sw_led_init(padapter); ++ rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode); ++ } ++ ++ strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ); ++ rereg_priv->old_ifname[IFNAMSIZ - 1] = 0; ++ ++ if (!memcmp(new_ifname, "disable%d", 9)) { ++ DBG_88E("%s disable\n", __func__); ++ /* free network queue for Android's timming issue */ ++ rtw_free_network_queue(padapter, true); ++ ++ /* close led */ ++ rtw_led_control(padapter, LED_CTL_POWER_OFF); ++ rereg_priv->old_bRegUseLed = padapter->ledpriv.bRegUseLed; ++ padapter->ledpriv.bRegUseLed = false; ++ rtw_hal_sw_led_deinit(padapter); ++ ++ /* the interface is being "disabled", we can do deeper IPS */ ++ rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv); ++ rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL); ++ } ++exit: ++ return ret; ++} ++ ++static void mac_reg_dump(struct adapter *padapter) ++{ ++ int i, j = 1; ++ pr_info("\n ======= MAC REG =======\n"); ++ for (i = 0x0; i < 0x300; i += 4) { ++ if (j % 4 == 1) ++ pr_info("0x%02x", i); ++ pr_info(" 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ pr_info("\n"); ++ } ++ for (i = 0x400; i < 0x800; i += 4) { ++ if (j % 4 == 1) ++ pr_info("0x%02x", i); ++ pr_info(" 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ pr_info("\n"); ++ } ++} ++ ++static void bb_reg_dump(struct adapter *padapter) ++{ ++ int i, j = 1; ++ pr_info("\n ======= BB REG =======\n"); ++ for (i = 0x800; i < 0x1000; i += 4) { ++ if (j % 4 == 1) ++ pr_info("0x%02x", i); ++ ++ pr_info(" 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ pr_info("\n"); ++ } ++} ++ ++static void rf_reg_dump(struct adapter *padapter) ++{ ++ int i, j = 1, path; ++ u32 value; ++ u8 rf_type, path_nums = 0; ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ ++ pr_info("\n ======= RF REG =======\n"); ++ if ((RF_1T2R == rf_type) || (RF_1T1R == rf_type)) ++ path_nums = 1; ++ else ++ path_nums = 2; ++ ++ for (path = 0; path < path_nums; path++) { ++ pr_info("\nRF_Path(%x)\n", path); ++ for (i = 0; i < 0x100; i++) { ++ value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); ++ if (j % 4 == 1) ++ pr_info("0x%02x ", i); ++ pr_info(" 0x%08x ", value); ++ if ((j++) % 4 == 0) ++ pr_info("\n"); ++ } ++ } ++} ++ ++static int rtw_dbg_port(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ u8 major_cmd, minor_cmd; ++ u16 arg; ++ s32 extra_arg; ++ u32 *pdata, val32; ++ struct sta_info *psta; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct wlan_network *cur_network = &pmlmepriv->cur_network; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ pdata = (u32 *)&wrqu->data; ++ ++ val32 = *pdata; ++ arg = (u16)(val32 & 0x0000ffff); ++ major_cmd = (u8)(val32 >> 24); ++ minor_cmd = (u8)((val32 >> 16) & 0x00ff); ++ ++ extra_arg = *(pdata + 1); ++ ++ switch (major_cmd) { ++ case 0x70:/* read_reg */ ++ switch (minor_cmd) { ++ case 1: ++ DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg)); ++ break; ++ case 2: ++ DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg)); ++ break; ++ case 4: ++ DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg)); ++ break; ++ } ++ break; ++ case 0x71:/* write_reg */ ++ switch (minor_cmd) { ++ case 1: ++ rtw_write8(padapter, arg, extra_arg); ++ DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg)); ++ break; ++ case 2: ++ rtw_write16(padapter, arg, extra_arg); ++ DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg)); ++ break; ++ case 4: ++ rtw_write32(padapter, arg, extra_arg); ++ DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg)); ++ break; ++ } ++ break; ++ case 0x72:/* read_bb */ ++ DBG_88E("read_bbreg(0x%x) = 0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff)); ++ break; ++ case 0x73:/* write_bb */ ++ rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg); ++ DBG_88E("write_bbreg(0x%x) = 0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff)); ++ break; ++ case 0x74:/* read_rf */ ++ DBG_88E("read RF_reg path(0x%02x), offset(0x%x), value(0x%08x)\n", minor_cmd, arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff)); ++ break; ++ case 0x75:/* write_rf */ ++ rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg); ++ DBG_88E("write RF_reg path(0x%02x), offset(0x%x), value(0x%08x)\n", minor_cmd, arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff)); ++ break; ++ ++ case 0x76: ++ switch (minor_cmd) { ++ case 0x00: /* normal mode, */ ++ padapter->recvpriv.is_signal_dbg = 0; ++ break; ++ case 0x01: /* dbg mode */ ++ padapter->recvpriv.is_signal_dbg = 1; ++ extra_arg = extra_arg > 100 ? 100 : extra_arg; ++ extra_arg = extra_arg < 0 ? 0 : extra_arg; ++ padapter->recvpriv.signal_strength_dbg = extra_arg; ++ break; ++ } ++ break; ++ case 0x78: /* IOL test */ ++ switch (minor_cmd) { ++ case 0x04: /* LLT table initialization test */ ++ { ++ u8 page_boundary = 0xf9; ++ struct xmit_frame *xmit_frame; ++ ++ xmit_frame = rtw_IOL_accquire_xmit_frame(padapter); ++ if (!xmit_frame) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary); ++ ++ if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500, 0)) ++ ret = -EPERM; ++ } ++ break; ++ case 0x05: /* blink LED test */ ++ { ++ u16 reg = 0x4c; ++ u32 blink_num = 50; ++ u32 blink_delay_ms = 200; ++ int i; ++ struct xmit_frame *xmit_frame; ++ ++ xmit_frame = rtw_IOL_accquire_xmit_frame(padapter); ++ if (!xmit_frame) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ for (i = 0; i < blink_num; i++) { ++ rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00, 0xff); ++ rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms); ++ rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08, 0xff); ++ rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms); ++ } ++ if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms * blink_num * 2) + 200, 0)) ++ ret = -EPERM; ++ } ++ break; ++ ++ case 0x06: /* continuous write byte test */ ++ { ++ u16 reg = arg; ++ u16 start_value = 0; ++ u32 write_num = extra_arg; ++ int i; ++ u8 final; ++ struct xmit_frame *xmit_frame; ++ ++ xmit_frame = rtw_IOL_accquire_xmit_frame(padapter); ++ if (!xmit_frame) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ for (i = 0; i < write_num; i++) ++ rtw_IOL_append_WB_cmd(xmit_frame, reg, i + start_value, 0xFF); ++ if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0)) ++ ret = -EPERM; ++ ++ final = rtw_read8(padapter, reg); ++ if (start_value + write_num - 1 == final) ++ DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final); ++ else ++ DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final); ++ } ++ break; ++ ++ case 0x07: /* continuous write word test */ ++ { ++ u16 reg = arg; ++ u16 start_value = 200; ++ u32 write_num = extra_arg; ++ ++ int i; ++ u16 final; ++ struct xmit_frame *xmit_frame; ++ ++ xmit_frame = rtw_IOL_accquire_xmit_frame(padapter); ++ if (!xmit_frame) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ for (i = 0; i < write_num; i++) ++ rtw_IOL_append_WW_cmd(xmit_frame, reg, i + start_value, 0xFFFF); ++ if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0)) ++ ret = -EPERM; ++ ++ final = rtw_read16(padapter, reg); ++ if (start_value + write_num - 1 == final) ++ DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final); ++ else ++ DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final); ++ } ++ break; ++ case 0x08: /* continuous write dword test */ ++ { ++ u16 reg = arg; ++ u32 start_value = 0x110000c7; ++ u32 write_num = extra_arg; ++ ++ int i; ++ u32 final; ++ struct xmit_frame *xmit_frame; ++ ++ xmit_frame = rtw_IOL_accquire_xmit_frame(padapter); ++ if (!xmit_frame) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ for (i = 0; i < write_num; i++) ++ rtw_IOL_append_WD_cmd(xmit_frame, reg, i + start_value, 0xFFFFFFFF); ++ if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0)) ++ ret = -EPERM; ++ ++ final = rtw_read32(padapter, reg); ++ if (start_value + write_num - 1 == final) ++ DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n", ++ reg, write_num, start_value, final); ++ else ++ DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Fail, start:%u, final:%u\n", ++ reg, write_num, start_value, final); ++ } ++ break; ++ } ++ break; ++ case 0x79: ++ { ++ /* ++ * dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15 ++ * dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15 ++ */ ++ u8 value = extra_arg & 0x0f; ++ u8 sign = minor_cmd; ++ u16 write_value = 0; ++ ++ DBG_88E("%s set RESP_TXAGC to %s %u\n", __func__, sign ? "minus" : "plus", value); ++ ++ if (sign) ++ value = value | 0x10; ++ ++ write_value = value | (value << 5); ++ rtw_write16(padapter, 0x6d9, write_value); ++ } ++ break; ++ case 0x7a: ++ receive_disconnect(padapter, pmlmeinfo->network.MacAddress ++ , WLAN_REASON_EXPIRATION_CHK); ++ break; ++ case 0x7F: ++ switch (minor_cmd) { ++ case 0x0: ++ DBG_88E("fwstate = 0x%x\n", get_fwstate(pmlmepriv)); ++ break; ++ case 0x01: ++ DBG_88E("auth_alg = 0x%x, enc_alg = 0x%x, auth_type = 0x%x, enc_type = 0x%x\n", ++ psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, ++ psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus); ++ break; ++ case 0x02: ++ DBG_88E("pmlmeinfo->state = 0x%x\n", pmlmeinfo->state); ++ break; ++ case 0x03: ++ DBG_88E("qos_option =%d\n", pmlmepriv->qospriv.qos_option); ++ DBG_88E("ht_option =%d\n", pmlmepriv->htpriv.ht_option); ++ break; ++ case 0x04: ++ DBG_88E("cur_ch =%d\n", pmlmeext->cur_channel); ++ DBG_88E("cur_bw =%d\n", pmlmeext->cur_bwmode); ++ DBG_88E("cur_ch_off =%d\n", pmlmeext->cur_ch_offset); ++ break; ++ case 0x05: ++ psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress); ++ if (psta) { ++ int i; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ ++ DBG_88E("SSID =%s\n", cur_network->network.Ssid.Ssid); ++ DBG_88E("sta's macaddr: %pM\n", psta->hwaddr); ++ DBG_88E("cur_channel =%d, cur_bwmode =%d, cur_ch_offset =%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); ++ DBG_88E("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self); ++ DBG_88E("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); ++ DBG_88E("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); ++ DBG_88E("bwmode =%d, ch_offset =%d, sgi =%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi); ++ DBG_88E("ampdu_enable = %d\n", psta->htpriv.ampdu_enable); ++ DBG_88E("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); ++ for (i = 0; i < 16; i++) { ++ preorder_ctrl = &psta->recvreorder_ctrl[i]; ++ if (preorder_ctrl->enable) ++ DBG_88E("tid =%d, indicate_seq =%d\n", i, preorder_ctrl->indicate_seq); ++ } ++ } else { ++ DBG_88E("can't get sta's macaddr, cur_network's macaddr:%pM\n", (cur_network->network.MacAddress)); ++ } ++ break; ++ case 0x06: ++ { ++ u32 ODMFlag; ++ rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag)); ++ DBG_88E("(B)DMFlag = 0x%x, arg = 0x%x\n", ODMFlag, arg); ++ ODMFlag = (u32)(0x0f & arg); ++ DBG_88E("(A)DMFlag = 0x%x\n", ODMFlag); ++ rtw_hal_set_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag)); ++ } ++ break; ++ case 0x07: ++ DBG_88E("bSurpriseRemoved =%d, bDriverStopped =%d\n", ++ padapter->bSurpriseRemoved, padapter->bDriverStopped); ++ break; ++ case 0x08: ++ { ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ ++ DBG_88E("free_xmitbuf_cnt =%d, free_xmitframe_cnt =%d, free_xmit_extbuf_cnt =%d\n", ++ pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmit_extbuf_cnt); ++ DBG_88E("rx_urb_pending_cn =%d\n", precvpriv->rx_pending_cnt); ++ } ++ break; ++ case 0x09: ++ { ++ int i, j; ++ struct list_head *plist, *phead; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ DBG_88E("sta_dz_bitmap = 0x%x, tim_bitmap = 0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap); ++#endif ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ ++ for (i = 0; i < NUM_STA; i++) { ++ phead = &pstapriv->sta_hash[i]; ++ plist = phead->next; ++ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, hash_list); ++ ++ plist = plist->next; ++ ++ if (extra_arg == psta->aid) { ++ DBG_88E("sta's macaddr:%pM\n", (psta->hwaddr)); ++ DBG_88E("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self); ++ DBG_88E("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); ++ DBG_88E("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); ++ DBG_88E("bwmode =%d, ch_offset =%d, sgi =%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi); ++ DBG_88E("ampdu_enable = %d\n", psta->htpriv.ampdu_enable); ++ DBG_88E("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ DBG_88E("capability = 0x%x\n", psta->capability); ++ DBG_88E("flags = 0x%x\n", psta->flags); ++ DBG_88E("wpa_psk = 0x%x\n", psta->wpa_psk); ++ DBG_88E("wpa2_group_cipher = 0x%x\n", psta->wpa2_group_cipher); ++ DBG_88E("wpa2_pairwise_cipher = 0x%x\n", psta->wpa2_pairwise_cipher); ++ DBG_88E("qos_info = 0x%x\n", psta->qos_info); ++#endif ++ DBG_88E("dot118021XPrivacy = 0x%x\n", psta->dot118021XPrivacy); ++ ++ for (j = 0; j < 16; j++) { ++ preorder_ctrl = &psta->recvreorder_ctrl[j]; ++ if (preorder_ctrl->enable) ++ DBG_88E("tid =%d, indicate_seq =%d\n", j, preorder_ctrl->indicate_seq); ++ } ++ } ++ } ++ } ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ } ++ break; ++ case 0x0c:/* dump rx/tx packet */ ++ if (arg == 0) { ++ DBG_88E("dump rx packet (%d)\n", extra_arg); ++ rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg)); ++ } else if (arg == 1) { ++ DBG_88E("dump tx packet (%d)\n", extra_arg); ++ rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg)); ++ } ++ break; ++ case 0x0f: ++ if (extra_arg == 0) { ++ DBG_88E("###### silent reset test.......#####\n"); ++ rtw_hal_sreset_reset(padapter); ++ } ++ break; ++ case 0x15: ++ { ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ DBG_88E("==>silent resete cnts:%d\n", pwrpriv->ips_enter_cnts); ++ } ++ break; ++ case 0x10:/* driver version display */ ++ DBG_88E("rtw driver version =%s\n", DRIVERVERSION); ++ break; ++ case 0x11: ++ DBG_88E("turn %s Rx RSSI display function\n", (extra_arg == 1) ? "on" : "off"); ++ padapter->bRxRSSIDisplay = extra_arg; ++ break; ++ case 0x12: /* set rx_stbc */ ++ { ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ /* 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g */ ++ /* default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */ ++ if (pregpriv && ++ (extra_arg == 0 || ++ extra_arg == 1 || ++ extra_arg == 2 || ++ extra_arg == 3)) { ++ pregpriv->rx_stbc = extra_arg; ++ DBG_88E("set rx_stbc =%d\n", pregpriv->rx_stbc); ++ } else { ++ DBG_88E("get rx_stbc =%d\n", pregpriv->rx_stbc); ++ } ++ } ++ break; ++ case 0x13: /* set ampdu_enable */ ++ { ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ /* 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec) */ ++ if (pregpriv && extra_arg >= 0 && extra_arg < 3) { ++ pregpriv->ampdu_enable = extra_arg; ++ DBG_88E("set ampdu_enable =%d\n", pregpriv->ampdu_enable); ++ } else { ++ DBG_88E("get ampdu_enable =%d\n", pregpriv->ampdu_enable); ++ } ++ } ++ break; ++ case 0x14: /* get wifi_spec */ ++ { ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ DBG_88E("get wifi_spec =%d\n", pregpriv->wifi_spec); ++ } ++ break; ++ case 0x23: ++ DBG_88E("turn %s the bNotifyChannelChange Variable\n", (extra_arg == 1) ? "on" : "off"); ++ padapter->bNotifyChannelChange = extra_arg; ++ break; ++ case 0x24: ++#ifdef CONFIG_88EU_P2P ++ DBG_88E("turn %s the bShowGetP2PState Variable\n", (extra_arg == 1) ? "on" : "off"); ++ padapter->bShowGetP2PState = extra_arg; ++#endif /* CONFIG_88EU_P2P */ ++ break; ++ case 0xaa: ++ if (extra_arg > 0x13) ++ extra_arg = 0xFF; ++ DBG_88E("chang data rate to :0x%02x\n", extra_arg); ++ padapter->fix_rate = extra_arg; ++ break; ++ case 0xdd:/* registers dump, 0 for mac reg, 1 for bb reg, 2 for rf reg */ ++ if (extra_arg == 0) ++ mac_reg_dump(padapter); ++ else if (extra_arg == 1) ++ bb_reg_dump(padapter); ++ else if (extra_arg == 2) ++ rf_reg_dump(padapter); ++ break; ++ case 0xee:/* turn on/off dynamic funcs */ ++ { ++ u32 odm_flag; ++ ++ if (0xf == extra_arg) { ++ rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &odm_flag); ++ DBG_88E(" === DMFlag(0x%08x) ===\n", odm_flag); ++ DBG_88E("extra_arg = 0 - disable all dynamic func\n"); ++ DBG_88E("extra_arg = 1 - disable DIG- BIT(0)\n"); ++ DBG_88E("extra_arg = 2 - disable High power - BIT(1)\n"); ++ DBG_88E("extra_arg = 3 - disable tx power tracking - BIT(2)\n"); ++ DBG_88E("extra_arg = 4 - disable BT coexistence - BIT(3)\n"); ++ DBG_88E("extra_arg = 5 - disable antenna diversity - BIT(4)\n"); ++ DBG_88E("extra_arg = 6 - enable all dynamic func\n"); ++ } else { ++ /* extra_arg = 0 - disable all dynamic func ++ extra_arg = 1 - disable DIG ++ extra_arg = 2 - disable tx power tracking ++ extra_arg = 3 - turn on all dynamic func ++ */ ++ rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &(extra_arg)); ++ rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &odm_flag); ++ DBG_88E(" === DMFlag(0x%08x) ===\n", odm_flag); ++ } ++ } ++ break; ++ ++ case 0xfd: ++ rtw_write8(padapter, 0xc50, arg); ++ DBG_88E("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50)); ++ rtw_write8(padapter, 0xc58, arg); ++ DBG_88E("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58)); ++ break; ++ case 0xfe: ++ DBG_88E("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50)); ++ DBG_88E("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58)); ++ break; ++ case 0xff: ++ DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210)); ++ DBG_88E("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608)); ++ DBG_88E("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280)); ++ DBG_88E("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284)); ++ DBG_88E("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288)); ++ ++ DBG_88E("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664)); ++ ++ DBG_88E("\n"); ++ ++ DBG_88E("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430)); ++ DBG_88E("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438)); ++ ++ DBG_88E("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440)); ++ ++ DBG_88E("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458)); ++ ++ DBG_88E("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484)); ++ DBG_88E("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488)); ++ ++ DBG_88E("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444)); ++ DBG_88E("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448)); ++ DBG_88E("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c)); ++ DBG_88E("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450)); ++ break; ++ } ++ break; ++ default: ++ DBG_88E("error dbg cmd!\n"); ++ break; ++ } ++ return ret; ++} ++ ++static int rtw_wx_set_priv(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *awrq, ++ char *extra) ++{ ++ int ret = 0; ++ int len = 0; ++ char *ext; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct iw_point *dwrq = (struct iw_point *)awrq; ++ ++ if (dwrq->length == 0) ++ return -EFAULT; ++ ++ len = dwrq->length; ++ ext = vmalloc(len); ++ if (!ext) ++ return -ENOMEM; ++ ++ if (copy_from_user(ext, dwrq->pointer, len)) { ++ vfree(ext); ++ return -EFAULT; ++ } ++ ++ /* added for wps2.0 @20110524 */ ++ if (dwrq->flags == 0x8766 && len > 8) { ++ u32 cp_sz; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 *probereq_wpsie = ext; ++ int probereq_wpsie_len = len; ++ u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; ++ ++ if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) && ++ (!memcmp(&probereq_wpsie[2], wps_oui, 4))) { ++ cp_sz = probereq_wpsie_len > MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN : probereq_wpsie_len; ++ ++ pmlmepriv->wps_probe_req_ie_len = 0; ++ kfree(pmlmepriv->wps_probe_req_ie); ++ pmlmepriv->wps_probe_req_ie = NULL; ++ ++ pmlmepriv->wps_probe_req_ie = kmalloc(cp_sz, GFP_KERNEL); ++ if (!pmlmepriv->wps_probe_req_ie) { ++ ret = -EINVAL; ++ goto FREE_EXT; ++ } ++ memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz); ++ pmlmepriv->wps_probe_req_ie_len = cp_sz; ++ } ++ goto FREE_EXT; ++ } ++ ++ if (len >= WEXT_CSCAN_HEADER_SIZE && ++ !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) { ++ ret = rtw_wx_set_scan(dev, info, awrq, ext); ++ goto FREE_EXT; ++ } ++ ++FREE_EXT: ++ ++ vfree(ext); ++ ++ return ret; ++} ++ ++static int rtw_pm_set(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ unsigned mode = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ DBG_88E("[%s] extra = %s\n", __func__, extra); ++ ++ if (!memcmp(extra, "lps =", 4)) { ++ sscanf(extra + 4, "%u", &mode); ++ ret = rtw_pm_set_lps(padapter, mode); ++ } else if (!memcmp(extra, "ips =", 4)) { ++ sscanf(extra + 4, "%u", &mode); ++ ret = rtw_pm_set_ips(padapter, mode); ++ } else { ++ ret = -EINVAL; ++ } ++ ++ return ret; ++} ++ ++static int rtw_mp_efuse_get(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wdata, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); ++ struct hal_data_8188e *haldata = GET_HAL_DATA(padapter); ++ struct efuse_hal *pEfuseHal; ++ struct iw_point *wrqu; ++ ++ u8 *PROMContent = pEEPROM->efuse_eeprom_data; ++ u8 ips_mode = 0, lps_mode = 0; ++ struct pwrctrl_priv *pwrctrlpriv; ++ u8 *data = NULL; ++ u8 *rawdata = NULL; ++ char *pch, *ptmp, *token, *tmp[3] = {NULL, NULL, NULL}; ++ u16 i = 0, j = 0, mapLen = 0, addr = 0, cnts = 0; ++ u16 max_available_size = 0, raw_cursize = 0, raw_maxsize = 0; ++ int err; ++ u8 org_fw_iol = padapter->registrypriv.fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */ ++ ++ wrqu = (struct iw_point *)wdata; ++ pwrctrlpriv = &padapter->pwrctrlpriv; ++ pEfuseHal = &haldata->EfuseHal; ++ ++ err = 0; ++ data = kzalloc(EFUSE_BT_MAX_MAP_LEN, GFP_KERNEL); ++ if (!data) { ++ err = -ENOMEM; ++ goto exit; ++ } ++ rawdata = kzalloc(EFUSE_BT_MAX_MAP_LEN, GFP_KERNEL); ++ if (!rawdata) { ++ err = -ENOMEM; ++ goto exit; ++ } ++ ++ if (copy_from_user(extra, wrqu->pointer, wrqu->length)) { ++ err = -EFAULT; ++ goto exit; ++ } ++ lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */ ++ rtw_pm_set_lps(padapter, PS_MODE_ACTIVE); ++ ++ ips_mode = pwrctrlpriv->ips_mode;/* keep org value */ ++ rtw_pm_set_ips(padapter, IPS_NONE); ++ ++ pch = extra; ++ DBG_88E("%s: in =%s\n", __func__, extra); ++ ++ i = 0; ++ /* mac 16 "00e04c871200" rmap, 00, 2 */ ++ while ((token = strsep(&pch, ",")) != NULL) { ++ if (i > 2) ++ break; ++ tmp[i] = token; ++ i++; ++ } ++ padapter->registrypriv.fw_iol = 0;/* 0:Disable, 1:enable, 2:by usb speed */ ++ ++ if (strcmp(tmp[0], "status") == 0) { ++ sprintf(extra, "Load File efuse =%s, Load File MAC =%s", (pEEPROM->bloadfile_fail_flag ? "FAIL" : "OK"), (pEEPROM->bloadmac_fail_flag ? "FAIL" : "OK")); ++ ++ goto exit; ++ } else if (strcmp(tmp[0], "filemap") == 0) { ++ mapLen = EFUSE_MAP_SIZE; ++ ++ sprintf(extra, "\n"); ++ for (i = 0; i < EFUSE_MAP_SIZE; i += 16) { ++ sprintf(extra + strlen(extra), "0x%02x\t", i); ++ for (j = 0; j < 8; j++) ++ sprintf(extra + strlen(extra), "%02X ", PROMContent[i + j]); ++ sprintf(extra + strlen(extra), "\t"); ++ for (; j < 16; j++) ++ sprintf(extra + strlen(extra), "%02X ", PROMContent[i + j]); ++ sprintf(extra + strlen(extra), "\n"); ++ } ++ } else if (strcmp(tmp[0], "realmap") == 0) { ++ mapLen = EFUSE_MAP_SIZE; ++ if (rtw_efuse_map_read(padapter, 0, mapLen, pEfuseHal->fakeEfuseInitMap) == _FAIL) { ++ DBG_88E("%s: read realmap Fail!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ sprintf(extra, "\n"); ++ for (i = 0; i < EFUSE_MAP_SIZE; i += 16) { ++ sprintf(extra + strlen(extra), "0x%02x\t", i); ++ for (j = 0; j < 8; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeEfuseInitMap[i + j]); ++ sprintf(extra + strlen(extra), "\t"); ++ for (; j < 16; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeEfuseInitMap[i + j]); ++ sprintf(extra + strlen(extra), "\n"); ++ } ++ } else if (strcmp(tmp[0], "rmap") == 0) { ++ if (!tmp[1] || !tmp[2]) { ++ DBG_88E("%s: rmap Fail!! Parameters error!\n", __func__); ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ /* rmap addr cnts */ ++ addr = simple_strtoul(tmp[1], &ptmp, 16); ++ DBG_88E("%s: addr =%x\n", __func__, addr); ++ ++ cnts = simple_strtoul(tmp[2], &ptmp, 10); ++ if (cnts == 0) { ++ DBG_88E("%s: rmap Fail!! cnts error!\n", __func__); ++ err = -EINVAL; ++ goto exit; ++ } ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_map_read error!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ *extra = 0; ++ for (i = 0; i < cnts; i++) ++ sprintf(extra + strlen(extra), "0x%02X ", data[i]); ++ } else if (strcmp(tmp[0], "realraw") == 0) { ++ addr = 0; ++ mapLen = EFUSE_MAX_SIZE; ++ if (rtw_efuse_access(padapter, false, addr, mapLen, rawdata) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_access Fail!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ sprintf(extra, "\n"); ++ for (i = 0; i < mapLen; i++) { ++ sprintf(extra + strlen(extra), "%02X", rawdata[i]); ++ ++ if ((i & 0xF) == 0xF) ++ sprintf(extra + strlen(extra), "\n"); ++ else if ((i & 0x7) == 0x7) ++ sprintf(extra + strlen(extra), "\t"); ++ else ++ sprintf(extra + strlen(extra), " "); ++ } ++ } else if (strcmp(tmp[0], "mac") == 0) { ++ cnts = 6; ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_map_read error!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ *extra = 0; ++ for (i = 0; i < cnts; i++) { ++ sprintf(extra + strlen(extra), "%02X", data[i]); ++ if (i != (cnts - 1)) ++ sprintf(extra + strlen(extra), ":"); ++ } ++ } else if (strcmp(tmp[0], "vidpid") == 0) { ++ cnts = 4; ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EFAULT; ++ goto exit; ++ } ++ if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_access error!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ *extra = 0; ++ for (i = 0; i < cnts; i++) { ++ sprintf(extra + strlen(extra), "0x%02X", data[i]); ++ if (i != (cnts - 1)) ++ sprintf(extra + strlen(extra), ","); ++ } ++ } else if (strcmp(tmp[0], "ableraw") == 0) { ++ efuse_GetCurrentSize(padapter, &raw_cursize); ++ raw_maxsize = efuse_GetMaxSize(padapter); ++ sprintf(extra, "[available raw size] = %d bytes", raw_maxsize - raw_cursize); ++ } else if (strcmp(tmp[0], "btfmap") == 0) { ++ mapLen = EFUSE_BT_MAX_MAP_LEN; ++ if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) { ++ DBG_88E("%s: rtw_BT_efuse_map_read Fail!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ sprintf(extra, "\n"); ++ for (i = 0; i < 512; i += 16) { ++ /* set 512 because the iwpriv's extra size have limit 0x7FF */ ++ sprintf(extra + strlen(extra), "0x%03x\t", i); ++ for (j = 0; j < 8; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->BTEfuseInitMap[i + j]); ++ sprintf(extra + strlen(extra), "\t"); ++ for (; j < 16; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->BTEfuseInitMap[i + j]); ++ sprintf(extra + strlen(extra), "\n"); ++ } ++ } else if (strcmp(tmp[0], "btbmap") == 0) { ++ mapLen = EFUSE_BT_MAX_MAP_LEN; ++ if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) { ++ DBG_88E("%s: rtw_BT_efuse_map_read Fail!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ sprintf(extra, "\n"); ++ for (i = 512; i < 1024; i += 16) { ++ sprintf(extra + strlen(extra), "0x%03x\t", i); ++ for (j = 0; j < 8; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->BTEfuseInitMap[i + j]); ++ sprintf(extra + strlen(extra), "\t"); ++ for (; j < 16; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->BTEfuseInitMap[i + j]); ++ sprintf(extra + strlen(extra), "\n"); ++ } ++ } else if (strcmp(tmp[0], "btrmap") == 0) { ++ if (!tmp[1] || !tmp[2]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ /* rmap addr cnts */ ++ addr = simple_strtoul(tmp[1], &ptmp, 16); ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ ++ cnts = simple_strtoul(tmp[2], &ptmp, 10); ++ if (cnts == 0) { ++ DBG_88E("%s: btrmap Fail!! cnts error!\n", __func__); ++ err = -EINVAL; ++ goto exit; ++ } ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_BT_efuse_map_read(padapter, addr, cnts, data) == _FAIL) { ++ DBG_88E("%s: rtw_BT_efuse_map_read error!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ *extra = 0; ++ for (i = 0; i < cnts; i++) ++ sprintf(extra + strlen(extra), " 0x%02X ", data[i]); ++ } else if (strcmp(tmp[0], "btffake") == 0) { ++ sprintf(extra, "\n"); ++ for (i = 0; i < 512; i += 16) { ++ sprintf(extra + strlen(extra), "0x%03x\t", i); ++ for (j = 0; j < 8; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]); ++ sprintf(extra + strlen(extra), "\t"); ++ for (; j < 16; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]); ++ sprintf(extra + strlen(extra), "\n"); ++ } ++ } else if (strcmp(tmp[0], "btbfake") == 0) { ++ sprintf(extra, "\n"); ++ for (i = 512; i < 1024; i += 16) { ++ sprintf(extra + strlen(extra), "0x%03x\t", i); ++ for (j = 0; j < 8; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]); ++ sprintf(extra + strlen(extra), "\t"); ++ for (; j < 16; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]); ++ sprintf(extra + strlen(extra), "\n"); ++ } ++ } else if (strcmp(tmp[0], "wlrfkmap") == 0) { ++ sprintf(extra, "\n"); ++ for (i = 0; i < EFUSE_MAP_SIZE; i += 16) { ++ sprintf(extra + strlen(extra), "0x%02x\t", i); ++ for (j = 0; j < 8; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeEfuseModifiedMap[i + j]); ++ sprintf(extra + strlen(extra), "\t"); ++ for (; j < 16; j++) ++ sprintf(extra + strlen(extra), " %02X", pEfuseHal->fakeEfuseModifiedMap[i + j]); ++ sprintf(extra + strlen(extra), "\n"); ++ } ++ } else { ++ sprintf(extra, "Command not found!"); ++ } ++ ++exit: ++ kfree(data); ++ kfree(rawdata); ++ if (!err) ++ wrqu->length = strlen(extra); ++ ++ rtw_pm_set_ips(padapter, ips_mode); ++ rtw_pm_set_lps(padapter, lps_mode); ++ padapter->registrypriv.fw_iol = org_fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */ ++ return err; ++} ++ ++static int rtw_mp_efuse_set(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wdata, char *extra) ++{ ++ struct adapter *padapter; ++ struct pwrctrl_priv *pwrctrlpriv; ++ struct hal_data_8188e *haldata; ++ struct efuse_hal *pEfuseHal; ++ ++ u8 ips_mode = 0, lps_mode = 0; ++ u32 i, jj, kk; ++ u8 *setdata = NULL; ++ u8 *ShadowMapBT = NULL; ++ u8 *ShadowMapWiFi = NULL; ++ u8 *setrawdata = NULL; ++ char *pch, *ptmp, *token, *tmp[3] = {NULL, NULL, NULL}; ++ u16 addr = 0, cnts = 0, max_available_size = 0; ++ int err; ++ ++ padapter = rtw_netdev_priv(dev); ++ pwrctrlpriv = &padapter->pwrctrlpriv; ++ haldata = GET_HAL_DATA(padapter); ++ pEfuseHal = &haldata->EfuseHal; ++ err = 0; ++ setdata = kzalloc(1024, GFP_KERNEL); ++ if (!setdata) { ++ err = -ENOMEM; ++ goto exit; ++ } ++ ShadowMapBT = kmalloc(EFUSE_BT_MAX_MAP_LEN, GFP_KERNEL); ++ if (!ShadowMapBT) { ++ err = -ENOMEM; ++ goto exit; ++ } ++ ShadowMapWiFi = kmalloc(EFUSE_MAP_SIZE, GFP_KERNEL); ++ if (!ShadowMapWiFi) { ++ err = -ENOMEM; ++ goto exit; ++ } ++ setrawdata = kmalloc(EFUSE_MAX_SIZE, GFP_KERNEL); ++ if (!setrawdata) { ++ err = -ENOMEM; ++ goto exit; ++ } ++ ++ lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */ ++ rtw_pm_set_lps(padapter, PS_MODE_ACTIVE); ++ ++ ips_mode = pwrctrlpriv->ips_mode;/* keep org value */ ++ rtw_pm_set_ips(padapter, IPS_NONE); ++ ++ pch = extra; ++ DBG_88E("%s: in =%s\n", __func__, extra); ++ ++ i = 0; ++ while ((token = strsep(&pch, ",")) != NULL) { ++ if (i > 2) ++ break; ++ tmp[i] = token; ++ i++; ++ } ++ ++ /* tmp[0],[1],[2] */ ++ /* wmap, addr, 00e04c871200 */ ++ if (strcmp(tmp[0], "wmap") == 0) { ++ if (!tmp[1] || !tmp[2]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ addr = simple_strtoul(tmp[1], &ptmp, 16); ++ addr &= 0xFFF; ++ ++ cnts = strlen(tmp[2]); ++ if (cnts % 2) { ++ err = -EINVAL; ++ goto exit; ++ } ++ cnts /= 2; ++ if (cnts == 0) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ DBG_88E("%s: map data =%s\n", __func__, tmp[2]); ++ ++ for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) ++ setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]); ++ /* Change to check TYPE_EFUSE_MAP_LEN, because 8188E raw 256, logic map over 256. */ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_map_write error!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ } else if (strcmp(tmp[0], "wraw") == 0) { ++ if (!tmp[1] || !tmp[2]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ addr = simple_strtoul(tmp[1], &ptmp, 16); ++ addr &= 0xFFF; ++ ++ cnts = strlen(tmp[2]); ++ if (cnts % 2) { ++ err = -EINVAL; ++ goto exit; ++ } ++ cnts /= 2; ++ if (cnts == 0) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ DBG_88E("%s: raw data =%s\n", __func__, tmp[2]); ++ ++ for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) ++ setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]); ++ ++ if (rtw_efuse_access(padapter, true, addr, cnts, setrawdata) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_access error!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ } else if (strcmp(tmp[0], "mac") == 0) { ++ if (!tmp[1]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ /* mac, 00e04c871200 */ ++ addr = EEPROM_MAC_ADDR_88EU; ++ cnts = strlen(tmp[1]); ++ if (cnts % 2) { ++ err = -EINVAL; ++ goto exit; ++ } ++ cnts /= 2; ++ if (cnts == 0) { ++ err = -EINVAL; ++ goto exit; ++ } ++ if (cnts > 6) { ++ DBG_88E("%s: error data for mac addr =\"%s\"\n", __func__, tmp[1]); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ DBG_88E("%s: MAC address =%s\n", __func__, tmp[1]); ++ ++ for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) ++ setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]); ++ /* Change to check TYPE_EFUSE_MAP_LEN, because 8188E raw 256, logic map over 256. */ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_map_write error!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ } else if (strcmp(tmp[0], "vidpid") == 0) { ++ if (!tmp[1]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ /* pidvid, da0b7881 */ ++ addr = EEPROM_VID_88EE; ++ cnts = strlen(tmp[1]); ++ if (cnts % 2) { ++ err = -EINVAL; ++ goto exit; ++ } ++ cnts /= 2; ++ if (cnts == 0) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ DBG_88E("%s: VID/PID =%s\n", __func__, tmp[1]); ++ ++ for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) ++ setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]); ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_map_write error!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ } else if (strcmp(tmp[0], "btwmap") == 0) { ++ if (!tmp[1] || !tmp[2]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ addr = simple_strtoul(tmp[1], &ptmp, 16); ++ addr &= 0xFFF; ++ ++ cnts = strlen(tmp[2]); ++ if (cnts % 2) { ++ err = -EINVAL; ++ goto exit; ++ } ++ cnts /= 2; ++ if (cnts == 0) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ DBG_88E("%s: BT data =%s\n", __func__, tmp[2]); ++ ++ for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) ++ setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]); ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_BT_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) { ++ DBG_88E("%s: rtw_BT_efuse_map_write error!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ } else if (strcmp(tmp[0], "btwfake") == 0) { ++ if (!tmp[1] || !tmp[2]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ addr = simple_strtoul(tmp[1], &ptmp, 16); ++ addr &= 0xFFF; ++ ++ cnts = strlen(tmp[2]); ++ if (cnts % 2) { ++ err = -EINVAL; ++ goto exit; ++ } ++ cnts /= 2; ++ if (cnts == 0) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ DBG_88E("%s: BT tmp data =%s\n", __func__, tmp[2]); ++ ++ for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) ++ pEfuseHal->fakeBTEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]); ++ } else if (strcmp(tmp[0], "btdumpfake") == 0) { ++ if (rtw_BT_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _SUCCESS) { ++ DBG_88E("%s: BT read all map success\n", __func__); ++ } else { ++ DBG_88E("%s: BT read all map Fail!\n", __func__); ++ err = -EFAULT; ++ } ++ } else if (strcmp(tmp[0], "wldumpfake") == 0) { ++ if (rtw_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeEfuseModifiedMap) == _SUCCESS) { ++ DBG_88E("%s: BT read all map success\n", __func__); ++ } else { ++ DBG_88E("%s: BT read all map Fail\n", __func__); ++ err = -EFAULT; ++ } ++ } else if (strcmp(tmp[0], "btfk2map") == 0) { ++ memcpy(pEfuseHal->BTEfuseModifiedMap, pEfuseHal->fakeBTEfuseModifiedMap, EFUSE_BT_MAX_MAP_LEN); ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if (max_available_size < 1) { ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL) { ++ DBG_88E("%s: rtw_BT_efuse_map_write error!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ } else if (strcmp(tmp[0], "wlfk2map") == 0) { ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if (max_available_size < 1) { ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_efuse_map_write(padapter, 0x00, EFUSE_MAX_MAP_LEN, pEfuseHal->fakeEfuseModifiedMap) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_map_write error!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ } else if (strcmp(tmp[0], "wlwfake") == 0) { ++ if (!tmp[1] || !tmp[2]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ addr = simple_strtoul(tmp[1], &ptmp, 16); ++ addr &= 0xFFF; ++ ++ cnts = strlen(tmp[2]); ++ if (cnts % 2) { ++ err = -EINVAL; ++ goto exit; ++ } ++ cnts /= 2; ++ if (cnts == 0) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ DBG_88E("%s: map tmp data =%s\n", __func__, tmp[2]); ++ ++ for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) ++ pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]); ++ } ++ ++exit: ++ kfree(setdata); ++ kfree(ShadowMapBT); ++ kfree(ShadowMapWiFi); ++ kfree(setrawdata); ++ ++ rtw_pm_set_ips(padapter, ips_mode); ++ rtw_pm_set_lps(padapter, lps_mode); ++ ++ return err; ++} ++ ++/* ++ * Input Format: %s,%d,%d ++ * %s is width, could be ++ * "b" for 1 byte ++ * "w" for WORD (2 bytes) ++ * "dw" for DWORD (4 bytes) ++ * 1st %d is address(offset) ++ * 2st %d is data to write ++ */ ++static int rtw_mp_write_reg(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ char *pch, *pnext, *ptmp; ++ char *width_str; ++ char width; ++ u32 addr, data; ++ int ret; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ pch = extra; ++ pnext = strpbrk(pch, ",.-"); ++ if (!pnext) ++ return -EINVAL; ++ *pnext = 0; ++ width_str = pch; ++ ++ pch = pnext + 1; ++ pnext = strpbrk(pch, ",.-"); ++ if (!pnext) ++ return -EINVAL; ++ *pnext = 0; ++ addr = simple_strtoul(pch, &ptmp, 16); ++ if (addr > 0x3FFF) ++ return -EINVAL; ++ ++ pch = pnext + 1; ++ if ((pch - extra) >= wrqu->length) ++ return -EINVAL; ++ data = simple_strtoul(pch, &ptmp, 16); ++ ++ ret = 0; ++ width = width_str[0]; ++ switch (width) { ++ case 'b': ++ /* 1 byte */ ++ if (data > 0xFF) { ++ ret = -EINVAL; ++ break; ++ } ++ rtw_write8(padapter, addr, data); ++ break; ++ case 'w': ++ /* 2 bytes */ ++ if (data > 0xFFFF) { ++ ret = -EINVAL; ++ break; ++ } ++ rtw_write16(padapter, addr, data); ++ break; ++ case 'd': ++ /* 4 bytes */ ++ rtw_write32(padapter, addr, data); ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ return ret; ++} ++ ++/* ++ * Input Format: %s,%d ++ * %s is width, could be ++ * "b" for 1 byte ++ * "w" for WORD (2 bytes) ++ * "dw" for DWORD (4 bytes) ++ * %d is address(offset) ++ * ++ * Return: ++ * %d for data readed ++ */ ++static int rtw_mp_read_reg(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ char *pch, *pnext, *ptmp; ++ char *width_str; ++ char width; ++ char data[20], tmp[20]; ++ u32 addr; ++ u32 ret, i = 0, j = 0, strtout = 0; ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ memset(data, 0, 20); ++ memset(tmp, 0, 20); ++ memset(extra, 0, wrqu->length); ++ ++ pch = input; ++ pnext = strpbrk(pch, ",.-"); ++ if (!pnext) { ++ kfree(input); ++ return -EINVAL; ++ } ++ *pnext = 0; ++ width_str = pch; ++ ++ pch = pnext + 1; ++ if ((pch - input) >= wrqu->length) { ++ kfree(input); ++ return -EINVAL; ++ } ++ kfree(input); ++ addr = simple_strtoul(pch, &ptmp, 16); ++ if (addr > 0x3FFF) ++ return -EINVAL; ++ ++ ret = 0; ++ width = width_str[0]; ++ switch (width) { ++ case 'b': ++ /* 1 byte */ ++ sprintf(extra, "%d\n", rtw_read8(padapter, addr)); ++ wrqu->length = strlen(extra); ++ break; ++ case 'w': ++ /* 2 bytes */ ++ sprintf(data, "%04x\n", rtw_read16(padapter, addr)); ++ for (i = 0; i <= strlen(data); i++) { ++ if (i % 2 == 0) { ++ tmp[j] = ' '; ++ j++; ++ } ++ if (data[i] != '\0') ++ tmp[j] = data[i]; ++ j++; ++ } ++ pch = tmp; ++ DBG_88E("pch =%s", pch); ++ ++ while (*pch != '\0') { ++ pnext = strpbrk(pch, " "); ++ if (!pnext) ++ break; ++ ++ pnext++; ++ if (*pnext != '\0') { ++ strtout = simple_strtoul(pnext, &ptmp, 16); ++ sprintf(extra + strlen(extra), " %d", strtout); ++ } else { ++ break; ++ } ++ pch = pnext; ++ } ++ wrqu->length = 6; ++ break; ++ case 'd': ++ /* 4 bytes */ ++ sprintf(data, "%08x", rtw_read32(padapter, addr)); ++ /* add read data format blank */ ++ for (i = 0; i <= strlen(data); i++) { ++ if (i % 2 == 0) { ++ tmp[j] = ' '; ++ j++; ++ } ++ if (data[i] != '\0') ++ tmp[j] = data[i]; ++ ++ j++; ++ } ++ pch = tmp; ++ DBG_88E("pch =%s", pch); ++ ++ while (*pch != '\0') { ++ pnext = strpbrk(pch, " "); ++ if (!pnext) ++ break; ++ pnext++; ++ if (*pnext != '\0') { ++ strtout = simple_strtoul(pnext, &ptmp, 16); ++ sprintf(extra + strlen(extra), " %d", strtout); ++ } else { ++ break; ++ } ++ pch = pnext; ++ } ++ wrqu->length = strlen(extra); ++ break; ++ default: ++ wrqu->length = 0; ++ ret = -EINVAL; ++ break; ++ } ++ ++ return ret; ++} ++ ++/* ++ * Input Format: %d,%x,%x ++ * %d is RF path, should be smaller than RF_PATH_MAX ++ * 1st %x is address(offset) ++ * 2st %x is data to write ++ */ ++ static int rtw_mp_write_rf(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u32 path, addr, data; ++ int ret; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ ret = sscanf(extra, "%d,%x,%x", &path, &addr, &data); ++ if (ret < 3) ++ return -EINVAL; ++ ++ if (path >= RF_PATH_MAX) ++ return -EINVAL; ++ if (addr > 0xFF) ++ return -EINVAL; ++ if (data > 0xFFFFF) ++ return -EINVAL; ++ ++ memset(extra, 0, wrqu->length); ++ ++ write_rfreg(padapter, path, addr, data); ++ ++ sprintf(extra, "write_rf completed\n"); ++ wrqu->length = strlen(extra); ++ ++ return 0; ++} ++ ++/* ++ * Input Format: %d,%x ++ * %d is RF path, should be smaller than RF_PATH_MAX ++ * %x is address(offset) ++ * ++ * Return: ++ * %d for data readed ++ */ ++static int rtw_mp_read_rf(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ char *pch, *pnext, *ptmp; ++ char data[20], tmp[20]; ++ u32 path, addr; ++ u32 ret, i = 0, j = 0, strtou = 0; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ ret = sscanf(input, "%d,%x", &path, &addr); ++ kfree(input); ++ if (ret < 2) ++ return -EINVAL; ++ ++ if (path >= RF_PATH_MAX) ++ return -EINVAL; ++ if (addr > 0xFF) ++ return -EINVAL; ++ ++ memset(extra, 0, wrqu->length); ++ ++ sprintf(data, "%08x", read_rfreg(padapter, path, addr)); ++ /* add read data format blank */ ++ for (i = 0; i <= strlen(data); i++) { ++ if (i % 2 == 0) { ++ tmp[j] = ' '; ++ j++; ++ } ++ tmp[j] = data[i]; ++ j++; ++ } ++ pch = tmp; ++ DBG_88E("pch =%s", pch); ++ ++ while (*pch != '\0') { ++ pnext = strpbrk(pch, " "); ++ pnext++; ++ if (*pnext != '\0') { ++ strtou = simple_strtoul(pnext, &ptmp, 16); ++ sprintf(extra + strlen(extra), " %d", strtou); ++ } else { ++ break; ++ } ++ pch = pnext; ++ } ++ wrqu->length = strlen(extra); ++ return 0; ++} ++ ++static int rtw_mp_start(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (padapter->registrypriv.mp_mode == 0) { ++ padapter->registrypriv.mp_mode = 1; ++ ++ rtw_pm_set_ips(padapter, IPS_NONE); ++ LeaveAllPowerSaveMode(padapter); ++ ++ MPT_InitializeAdapter(padapter, 1); ++ } ++ if (padapter->registrypriv.mp_mode == 0) ++ return -EPERM; ++ if (padapter->mppriv.mode == MP_OFF) { ++ if (mp_start_test(padapter) == _FAIL) ++ return -EPERM; ++ padapter->mppriv.mode = MP_ON; ++ } ++ return 0; ++} ++ ++static int rtw_mp_stop(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (padapter->registrypriv.mp_mode == 1) { ++ MPT_DeInitAdapter(padapter); ++ padapter->registrypriv.mp_mode = 0; ++ } ++ ++ if (padapter->mppriv.mode != MP_OFF) { ++ mp_stop_test(padapter); ++ padapter->mppriv.mode = MP_OFF; ++ } ++ ++ return 0; ++} ++ ++extern int wifirate2_ratetbl_inx(unsigned char rate); ++ ++static int rtw_mp_rate(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u32 rate = MPT_RATE_1M; ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ rate = rtw_atoi(input); ++ sprintf(extra, "Set data rate to %d", rate); ++ kfree(input); ++ if (rate <= 0x7f) ++ rate = wifirate2_ratetbl_inx((u8)rate); ++ else ++ rate = (rate - 0x80 + MPT_RATE_MCS0); ++ ++ if (rate >= MPT_RATE_LAST) ++ return -EINVAL; ++ ++ padapter->mppriv.rateidx = rate; ++ Hal_SetDataRate(padapter); ++ ++ wrqu->length = strlen(extra) + 1; ++ return 0; ++} ++ ++static int rtw_mp_channel(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ u32 channel = 1; ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ channel = rtw_atoi(input); ++ sprintf(extra, "Change channel %d to channel %d", padapter->mppriv.channel, channel); ++ ++ padapter->mppriv.channel = channel; ++ Hal_SetChannel(padapter); ++ ++ wrqu->length = strlen(extra) + 1; ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_bandwidth(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u32 bandwidth = 0, sg = 0; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ sscanf(extra, "40M =%d, shortGI =%d", &bandwidth, &sg); ++ ++ if (bandwidth != HT_CHANNEL_WIDTH_40) ++ bandwidth = HT_CHANNEL_WIDTH_20; ++ ++ padapter->mppriv.bandwidth = (u8)bandwidth; ++ padapter->mppriv.preamble = sg; ++ ++ SetBandwidth(padapter); ++ ++ return 0; ++} ++ ++static int rtw_mp_txpower(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u32 idx_a = 0, idx_b = 0; ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ sscanf(input, "patha =%d, pathb =%d", &idx_a, &idx_b); ++ ++ sprintf(extra, "Set power level path_A:%d path_B:%d", idx_a, idx_b); ++ padapter->mppriv.txpoweridx = (u8)idx_a; ++ padapter->mppriv.txpoweridx_b = (u8)idx_b; ++ padapter->mppriv.bSetTxPower = 1; ++ Hal_SetAntennaPathPower(padapter); ++ ++ wrqu->length = strlen(extra) + 1; ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_ant_tx(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u8 i; ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ u16 antenna = 0; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ ++ sprintf(extra, "switch Tx antenna to %s", input); ++ ++ for (i = 0; i < strlen(input); i++) { ++ switch (input[i]) { ++ case 'a': ++ antenna |= ANTENNA_A; ++ break; ++ case 'b': ++ antenna |= ANTENNA_B; ++ break; ++ } ++ } ++ padapter->mppriv.antenna_tx = antenna; ++ ++ Hal_SetAntenna(padapter); ++ ++ wrqu->length = strlen(extra) + 1; ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_ant_rx(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u8 i; ++ u16 antenna = 0; ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ memset(extra, 0, wrqu->length); ++ ++ sprintf(extra, "switch Rx antenna to %s", input); ++ ++ for (i = 0; i < strlen(input); i++) { ++ switch (input[i]) { ++ case 'a': ++ antenna |= ANTENNA_A; ++ break; ++ case 'b': ++ antenna |= ANTENNA_B; ++ break; ++ } ++ } ++ ++ padapter->mppriv.antenna_rx = antenna; ++ Hal_SetAntenna(padapter); ++ wrqu->length = strlen(extra); ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_ctx(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u32 pkTx = 1, countPkTx = 1, cotuTx = 1, CarrSprTx = 1, scTx = 1, sgleTx = 1, stop = 1; ++ u32 bStartTest = 1; ++ u32 count = 0; ++ struct mp_priv *pmp_priv; ++ struct pkt_attrib *pattrib; ++ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ pmp_priv = &padapter->mppriv; ++ ++ if (copy_from_user(extra, wrqu->pointer, wrqu->length)) ++ return -EFAULT; ++ ++ DBG_88E("%s: in =%s\n", __func__, extra); ++ ++ countPkTx = strncmp(extra, "count =", 5); /* strncmp true is 0 */ ++ cotuTx = strncmp(extra, "background", 20); ++ CarrSprTx = strncmp(extra, "background, cs", 20); ++ scTx = strncmp(extra, "background, sc", 20); ++ sgleTx = strncmp(extra, "background, stone", 20); ++ pkTx = strncmp(extra, "background, pkt", 20); ++ stop = strncmp(extra, "stop", 4); ++ sscanf(extra, "count =%d, pkt", &count); ++ ++ memset(extra, '\0', sizeof(*extra)); ++ ++ if (stop == 0) { ++ bStartTest = 0; /* To set Stop */ ++ pmp_priv->tx.stop = 1; ++ sprintf(extra, "Stop continuous Tx"); ++ } else { ++ bStartTest = 1; ++ if (pmp_priv->mode != MP_ON) { ++ if (pmp_priv->tx.stop != 1) { ++ DBG_88E("%s: MP_MODE != ON %d\n", __func__, pmp_priv->mode); ++ return -EFAULT; ++ } ++ } ++ } ++ ++ if (pkTx == 0 || countPkTx == 0) ++ pmp_priv->mode = MP_PACKET_TX; ++ if (sgleTx == 0) ++ pmp_priv->mode = MP_SINGLE_TONE_TX; ++ if (cotuTx == 0) ++ pmp_priv->mode = MP_CONTINUOUS_TX; ++ if (CarrSprTx == 0) ++ pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX; ++ if (scTx == 0) ++ pmp_priv->mode = MP_SINGLE_CARRIER_TX; ++ ++ switch (pmp_priv->mode) { ++ case MP_PACKET_TX: ++ if (bStartTest == 0) { ++ pmp_priv->tx.stop = 1; ++ pmp_priv->mode = MP_ON; ++ sprintf(extra, "Stop continuous Tx"); ++ } else if (pmp_priv->tx.stop == 1) { ++ sprintf(extra, "Start continuous DA = ffffffffffff len = 1500 count =%u,\n", count); ++ pmp_priv->tx.stop = 0; ++ pmp_priv->tx.count = count; ++ pmp_priv->tx.payload = 2; ++ pattrib = &pmp_priv->tx.attrib; ++ pattrib->pktlen = 1500; ++ memset(pattrib->dst, 0xFF, ETH_ALEN); ++ SetPacketTx(padapter); ++ } else { ++ return -EFAULT; ++ } ++ wrqu->length = strlen(extra); ++ return 0; ++ case MP_SINGLE_TONE_TX: ++ if (bStartTest != 0) ++ sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes."); ++ Hal_SetSingleToneTx(padapter, (u8)bStartTest); ++ break; ++ case MP_CONTINUOUS_TX: ++ if (bStartTest != 0) ++ sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes."); ++ Hal_SetContinuousTx(padapter, (u8)bStartTest); ++ break; ++ case MP_CARRIER_SUPPRISSION_TX: ++ if (bStartTest != 0) { ++ if (pmp_priv->rateidx <= MPT_RATE_11M) { ++ sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes."); ++ Hal_SetCarrierSuppressionTx(padapter, (u8)bStartTest); ++ } else { ++ sprintf(extra, "Specify carrier suppression but not CCK rate"); ++ } ++ } ++ break; ++ case MP_SINGLE_CARRIER_TX: ++ if (bStartTest != 0) ++ sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes."); ++ Hal_SetSingleCarrierTx(padapter, (u8)bStartTest); ++ break; ++ default: ++ sprintf(extra, "Error! Continuous-Tx is not on-going."); ++ return -EFAULT; ++ } ++ ++ if (bStartTest == 1 && pmp_priv->mode != MP_ON) { ++ struct mp_priv *pmp_priv = &padapter->mppriv; ++ if (pmp_priv->tx.stop == 0) { ++ pmp_priv->tx.stop = 1; ++ msleep(5); ++ } ++ pmp_priv->tx.stop = 0; ++ pmp_priv->tx.count = 1; ++ SetPacketTx(padapter); ++ } else { ++ pmp_priv->mode = MP_ON; ++ } ++ ++ wrqu->length = strlen(extra); ++ return 0; ++} ++ ++static int rtw_mp_arx(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u8 bStartRx = 0, bStopRx = 0, bQueryPhy; ++ u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0; ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!input) ++ return -ENOMEM; ++ ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ DBG_88E("%s: %s\n", __func__, input); ++ ++ bStartRx = (strncmp(input, "start", 5) == 0) ? 1 : 0; /* strncmp true is 0 */ ++ bStopRx = (strncmp(input, "stop", 5) == 0) ? 1 : 0; /* strncmp true is 0 */ ++ bQueryPhy = (strncmp(input, "phy", 3) == 0) ? 1 : 0; /* strncmp true is 0 */ ++ ++ if (bStartRx) { ++ sprintf(extra, "start"); ++ SetPacketRx(padapter, bStartRx); ++ } else if (bStopRx) { ++ SetPacketRx(padapter, 0); ++ sprintf(extra, "Received packet OK:%d CRC error:%d", padapter->mppriv.rx_pktcount, padapter->mppriv.rx_crcerrpktcount); ++ } else if (bQueryPhy) { ++ /* ++ OFDM FA ++ RegCF0[15:0] ++ RegCF2[31:16] ++ RegDA0[31:16] ++ RegDA4[15:0] ++ RegDA4[31:16] ++ RegDA8[15:0] ++ CCK FA ++ (RegA5B<<8) | RegA5C ++ */ ++ cckok = read_bbreg(padapter, 0xf88, 0xffffffff); ++ cckcrc = read_bbreg(padapter, 0xf84, 0xffffffff); ++ ofdmok = read_bbreg(padapter, 0xf94, 0x0000FFFF); ++ ofdmcrc = read_bbreg(padapter, 0xf94, 0xFFFF0000); ++ htok = read_bbreg(padapter, 0xf90, 0x0000FFFF); ++ htcrc = read_bbreg(padapter, 0xf90, 0xFFFF0000); ++ ++ OFDM_FA = read_bbreg(padapter, 0xcf0, 0x0000FFFF); ++ OFDM_FA = read_bbreg(padapter, 0xcf2, 0xFFFF0000); ++ OFDM_FA = read_bbreg(padapter, 0xda0, 0xFFFF0000); ++ OFDM_FA = read_bbreg(padapter, 0xda4, 0x0000FFFF); ++ OFDM_FA = read_bbreg(padapter, 0xda4, 0xFFFF0000); ++ OFDM_FA = read_bbreg(padapter, 0xda8, 0x0000FFFF); ++ CCK_FA = (rtw_read8(padapter, 0xa5b) << 8) | (rtw_read8(padapter, 0xa5c)); ++ ++ sprintf(extra, "Phy Received packet OK:%d CRC error:%d FA Counter: %d", cckok + ofdmok + htok, cckcrc + ofdmcrc + htcrc, OFDM_FA + CCK_FA); ++ } ++ wrqu->length = strlen(extra) + 1; ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_trx_query(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u32 txok, txfail, rxok, rxfail; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ txok = padapter->mppriv.tx.sended; ++ txfail = 0; ++ rxok = padapter->mppriv.rx_pktcount; ++ rxfail = padapter->mppriv.rx_crcerrpktcount; ++ ++ memset(extra, '\0', 128); ++ ++ sprintf(extra, "Tx OK:%d, Tx Fail:%d, Rx OK:%d, CRC error:%d ", txok, txfail, rxok, rxfail); ++ ++ wrqu->length = strlen(extra) + 1; ++ ++ return 0; ++} ++ ++static int rtw_mp_pwrtrk(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u8 enable; ++ u32 thermal; ++ s32 ret; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ memset(extra, 0, wrqu->length); ++ ++ enable = 1; ++ if (wrqu->length > 1) {/* not empty string */ ++ if (strncmp(input, "stop", 4) == 0) { ++ enable = 0; ++ sprintf(extra, "mp tx power tracking stop"); ++ } else if (sscanf(input, "ther =%d", &thermal)) { ++ ret = Hal_SetThermalMeter(padapter, (u8)thermal); ++ if (ret == _FAIL) ++ return -EPERM; ++ sprintf(extra, "mp tx power tracking start, target value =%d ok ", thermal); ++ } else { ++ kfree(input); ++ return -EINVAL; ++ } ++ } ++ ++ kfree(input); ++ ret = Hal_SetPowerTracking(padapter, enable); ++ if (ret == _FAIL) ++ return -EPERM; ++ ++ wrqu->length = strlen(extra); ++ return 0; ++} ++ ++static int rtw_mp_psd(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ ++ strcpy(extra, input); ++ ++ wrqu->length = mp_query_psd(padapter, extra); ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_thermal(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u8 val; ++ u16 bwrite = 1; ++ u16 addr = EEPROM_THERMAL_METER_88E; ++ ++ u16 cnt = 1; ++ u16 max_available_size = 0; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (copy_from_user(extra, wrqu->pointer, wrqu->length)) ++ return -EFAULT; ++ ++ bwrite = strncmp(extra, "write", 6); /* strncmp true is 0 */ ++ ++ Hal_GetThermalMeter(padapter, &val); ++ ++ if (bwrite == 0) { ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if (2 > max_available_size) { ++ DBG_88E("no available efuse!\n"); ++ return -EFAULT; ++ } ++ if (rtw_efuse_map_write(padapter, addr, cnt, &val) == _FAIL) { ++ DBG_88E("rtw_efuse_map_write error\n"); ++ return -EFAULT; ++ } else { ++ sprintf(extra, " efuse write ok :%d", val); ++ } ++ } else { ++ sprintf(extra, "%d", val); ++ } ++ wrqu->length = strlen(extra); ++ ++ return 0; ++} ++ ++static int rtw_mp_reset_stats(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ struct mp_priv *pmp_priv; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ pmp_priv = &padapter->mppriv; ++ ++ pmp_priv->tx.sended = 0; ++ pmp_priv->tx_pktcount = 0; ++ pmp_priv->rx_pktcount = 0; ++ pmp_priv->rx_crcerrpktcount = 0; ++ ++ /* reset phy counter */ ++ write_bbreg(padapter, 0xf14, BIT(16), 0x1); ++ msleep(10); ++ write_bbreg(padapter, 0xf14, BIT(16), 0x0); ++ ++ return 0; ++} ++ ++static int rtw_mp_dump(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u32 value; ++ u8 rf_type, path_nums = 0; ++ u32 i, j = 1, path; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (strncmp(extra, "all", 4) == 0) { ++ DBG_88E("\n ======= MAC REG =======\n"); ++ for (i = 0x0; i < 0x300; i += 4) { ++ if (j % 4 == 1) ++ DBG_88E("0x%02x", i); ++ DBG_88E(" 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ DBG_88E("\n"); ++ } ++ for (i = 0x400; i < 0x1000; i += 4) { ++ if (j % 4 == 1) ++ DBG_88E("0x%02x", i); ++ DBG_88E(" 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ DBG_88E("\n"); ++ } ++ ++ j = 1; ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ ++ DBG_88E("\n ======= RF REG =======\n"); ++ if ((RF_1T2R == rf_type) || (RF_1T1R == rf_type)) ++ path_nums = 1; ++ else ++ path_nums = 2; ++ ++ for (path = 0; path < path_nums; path++) { ++ for (i = 0; i < 0x34; i++) { ++ value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); ++ if (j % 4 == 1) ++ DBG_88E("0x%02x ", i); ++ DBG_88E(" 0x%08x ", value); ++ if ((j++) % 4 == 0) ++ DBG_88E("\n"); ++ } ++ } ++ } ++ return 0; ++} ++ ++static int rtw_mp_phypara(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ u32 valxcap; ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ ++ DBG_88E("%s:iwpriv in =%s\n", __func__, input); ++ ++ sscanf(input, "xcap =%d", &valxcap); ++ ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_SetRFPath(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ char *input = kmalloc(wrqu->data.length, GFP_KERNEL); ++ u8 bMain = 1, bTurnoff = 1; ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length)) ++ return -EFAULT; ++ DBG_88E("%s:iwpriv in =%s\n", __func__, input); ++ ++ bMain = strncmp(input, "1", 2); /* strncmp true is 0 */ ++ bTurnoff = strncmp(input, "0", 3); /* strncmp true is 0 */ ++ ++ if (bMain == 0) { ++ MP_PHY_SetRFPathSwitch(padapter, true); ++ DBG_88E("%s:PHY_SetRFPathSwitch = true\n", __func__); ++ } else if (bTurnoff == 0) { ++ MP_PHY_SetRFPathSwitch(padapter, false); ++ DBG_88E("%s:PHY_SetRFPathSwitch = false\n", __func__); ++ } ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_QueryDrv(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ char *input = kmalloc(wrqu->data.length, GFP_KERNEL); ++ u8 qAutoLoad = 1; ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); ++ ++ if (!input) ++ return -ENOMEM; ++ ++ if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length)) ++ return -EFAULT; ++ DBG_88E("%s:iwpriv in =%s\n", __func__, input); ++ ++ qAutoLoad = strncmp(input, "autoload", 8); /* strncmp true is 0 */ ++ ++ if (qAutoLoad == 0) { ++ DBG_88E("%s:qAutoLoad\n", __func__); ++ ++ if (pEEPROM->bautoload_fail_flag) ++ sprintf(extra, "fail"); ++ else ++ sprintf(extra, "ok"); ++ } ++ wrqu->data.length = strlen(extra) + 1; ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_set(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wdata, char *extra) ++{ ++ struct iw_point *wrqu = (struct iw_point *)wdata; ++ u32 subcmd = wrqu->flags; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!padapter) ++ return -ENETDOWN; ++ ++ if (!extra) { ++ wrqu->length = 0; ++ return -EIO; ++ } ++ ++ switch (subcmd) { ++ case MP_START: ++ DBG_88E("set case mp_start\n"); ++ rtw_mp_start(dev, info, wrqu, extra); ++ break; ++ case MP_STOP: ++ DBG_88E("set case mp_stop\n"); ++ rtw_mp_stop(dev, info, wrqu, extra); ++ break; ++ case MP_BANDWIDTH: ++ DBG_88E("set case mp_bandwidth\n"); ++ rtw_mp_bandwidth(dev, info, wrqu, extra); ++ break; ++ case MP_RESET_STATS: ++ DBG_88E("set case MP_RESET_STATS\n"); ++ rtw_mp_reset_stats(dev, info, wrqu, extra); ++ break; ++ case MP_SetRFPathSwh: ++ DBG_88E("set MP_SetRFPathSwitch\n"); ++ rtw_mp_SetRFPath(dev, info, wdata, extra); ++ break; ++ case CTA_TEST: ++ DBG_88E("set CTA_TEST\n"); ++ rtw_cta_test_start(dev, info, wdata, extra); ++ break; ++ } ++ ++ return 0; ++} ++ ++static int rtw_mp_get(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wdata, char *extra) ++{ ++ struct iw_point *wrqu = (struct iw_point *)wdata; ++ u32 subcmd = wrqu->flags; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!padapter) ++ return -ENETDOWN; ++ if (!extra) { ++ wrqu->length = 0; ++ return -EIO; ++ } ++ ++ switch (subcmd) { ++ case WRITE_REG: ++ rtw_mp_write_reg(dev, info, wrqu, extra); ++ break; ++ case WRITE_RF: ++ rtw_mp_write_rf(dev, info, wrqu, extra); ++ break; ++ case MP_PHYPARA: ++ DBG_88E("mp_get MP_PHYPARA\n"); ++ rtw_mp_phypara(dev, info, wrqu, extra); ++ break; ++ case MP_CHANNEL: ++ DBG_88E("set case mp_channel\n"); ++ rtw_mp_channel(dev, info, wrqu, extra); ++ break; ++ case READ_REG: ++ DBG_88E("mp_get READ_REG\n"); ++ rtw_mp_read_reg(dev, info, wrqu, extra); ++ break; ++ case READ_RF: ++ DBG_88E("mp_get READ_RF\n"); ++ rtw_mp_read_rf(dev, info, wrqu, extra); ++ break; ++ case MP_RATE: ++ DBG_88E("set case mp_rate\n"); ++ rtw_mp_rate(dev, info, wrqu, extra); ++ break; ++ case MP_TXPOWER: ++ DBG_88E("set case MP_TXPOWER\n"); ++ rtw_mp_txpower(dev, info, wrqu, extra); ++ break; ++ case MP_ANT_TX: ++ DBG_88E("set case MP_ANT_TX\n"); ++ rtw_mp_ant_tx(dev, info, wrqu, extra); ++ break; ++ case MP_ANT_RX: ++ DBG_88E("set case MP_ANT_RX\n"); ++ rtw_mp_ant_rx(dev, info, wrqu, extra); ++ break; ++ case MP_QUERY: ++ rtw_mp_trx_query(dev, info, wrqu, extra); ++ break; ++ case MP_CTX: ++ DBG_88E("set case MP_CTX\n"); ++ rtw_mp_ctx(dev, info, wrqu, extra); ++ break; ++ case MP_ARX: ++ DBG_88E("set case MP_ARX\n"); ++ rtw_mp_arx(dev, info, wrqu, extra); ++ break; ++ case EFUSE_GET: ++ DBG_88E("efuse get EFUSE_GET\n"); ++ rtw_mp_efuse_get(dev, info, wdata, extra); ++ break; ++ case MP_DUMP: ++ DBG_88E("set case MP_DUMP\n"); ++ rtw_mp_dump(dev, info, wrqu, extra); ++ break; ++ case MP_PSD: ++ DBG_88E("set case MP_PSD\n"); ++ rtw_mp_psd(dev, info, wrqu, extra); ++ break; ++ case MP_THER: ++ DBG_88E("set case MP_THER\n"); ++ rtw_mp_thermal(dev, info, wrqu, extra); ++ break; ++ case MP_QueryDrvStats: ++ DBG_88E("mp_get MP_QueryDrvStats\n"); ++ rtw_mp_QueryDrv(dev, info, wdata, extra); ++ break; ++ case MP_PWRTRK: ++ DBG_88E("set case MP_PWRTRK\n"); ++ rtw_mp_pwrtrk(dev, info, wrqu, extra); ++ break; ++ case EFUSE_SET: ++ DBG_88E("set case efuse set\n"); ++ rtw_mp_efuse_set(dev, info, wdata, extra); ++ break; ++ } ++ ++ msleep(10); /* delay 5ms for sending pkt before exit adb shell operation */ ++ return 0; ++} ++ ++static int rtw_tdls(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ return 0; ++} ++ ++static int rtw_tdls_get(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ return 0; ++} ++ ++static int rtw_test( ++ struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ u32 len; ++ u8 *pbuf, *pch; ++ char *ptmp; ++ u8 *delim = ","; ++ ++ DBG_88E("+%s\n", __func__); ++ len = wrqu->data.length; ++ ++ pbuf = kzalloc(len, GFP_KERNEL); ++ if (!pbuf) { ++ DBG_88E("%s: no memory!\n", __func__); ++ return -ENOMEM; ++ } ++ ++ if (copy_from_user(pbuf, wrqu->data.pointer, len)) { ++ kfree(pbuf); ++ DBG_88E("%s: copy from user fail!\n", __func__); ++ return -EFAULT; ++ } ++ DBG_88E("%s: string =\"%s\"\n", __func__, pbuf); ++ ++ ptmp = (char *)pbuf; ++ pch = strsep(&ptmp, delim); ++ if (!pch || strlen(pch) == 0) { ++ kfree(pbuf); ++ DBG_88E("%s: parameter error(level 1)!\n", __func__); ++ return -EFAULT; ++ } ++ kfree(pbuf); ++ return 0; ++} ++ ++static iw_handler rtw_handlers[] = { ++ IW_HANDLER(SIOCGIWNAME, rtw_wx_get_name), ++ IW_HANDLER(SIOCSIWNWID, dummy), ++ IW_HANDLER(SIOCGIWNWID, dummy), ++ IW_HANDLER(SIOCGIWFREQ, rtw_wx_get_freq), ++ IW_HANDLER(SIOCSIWMODE, rtw_wx_set_mode), ++ IW_HANDLER(SIOCGIWMODE, rtw_wx_get_mode), ++ IW_HANDLER(SIOCSIWSENS, dummy), ++ IW_HANDLER(SIOCGIWSENS, rtw_wx_get_sens), ++ IW_HANDLER(SIOCGIWRANGE, rtw_wx_get_range), ++ IW_HANDLER(SIOCSIWPRIV, rtw_wx_set_priv), ++ IW_HANDLER(SIOCSIWSPY, dummy), ++ IW_HANDLER(SIOCGIWSPY, dummy), ++ IW_HANDLER(SIOCSIWAP, rtw_wx_set_wap), ++ IW_HANDLER(SIOCGIWAP, rtw_wx_get_wap), ++ IW_HANDLER(SIOCSIWMLME, rtw_wx_set_mlme), ++ IW_HANDLER(SIOCGIWAPLIST, dummy), ++ IW_HANDLER(SIOCSIWSCAN, rtw_wx_set_scan), ++ IW_HANDLER(SIOCGIWSCAN, rtw_wx_get_scan), ++ IW_HANDLER(SIOCSIWESSID, rtw_wx_set_essid), ++ IW_HANDLER(SIOCGIWESSID, rtw_wx_get_essid), ++ IW_HANDLER(SIOCSIWNICKN, dummy), ++ IW_HANDLER(SIOCGIWNICKN, rtw_wx_get_nick), ++ IW_HANDLER(SIOCSIWRATE, rtw_wx_set_rate), ++ IW_HANDLER(SIOCGIWRATE, rtw_wx_get_rate), ++ IW_HANDLER(SIOCSIWRTS, rtw_wx_set_rts), ++ IW_HANDLER(SIOCGIWRTS, rtw_wx_get_rts), ++ IW_HANDLER(SIOCSIWFRAG, rtw_wx_set_frag), ++ IW_HANDLER(SIOCGIWFRAG, rtw_wx_get_frag), ++ IW_HANDLER(SIOCSIWTXPOW, dummy), ++ IW_HANDLER(SIOCGIWTXPOW, dummy), ++ IW_HANDLER(SIOCSIWRETRY, dummy), ++ IW_HANDLER(SIOCGIWRETRY, rtw_wx_get_retry), ++ IW_HANDLER(SIOCSIWENCODE, rtw_wx_set_enc), ++ IW_HANDLER(SIOCGIWENCODE, rtw_wx_get_enc), ++ IW_HANDLER(SIOCSIWPOWER, dummy), ++ IW_HANDLER(SIOCGIWPOWER, rtw_wx_get_power), ++ IW_HANDLER(SIOCSIWGENIE, rtw_wx_set_gen_ie), ++ IW_HANDLER(SIOCSIWAUTH, rtw_wx_set_auth), ++ IW_HANDLER(SIOCSIWENCODEEXT, rtw_wx_set_enc_ext), ++ IW_HANDLER(SIOCSIWPMKSA, rtw_wx_set_pmkid), ++}; ++ ++static const struct iw_priv_args rtw_private_args[] = { ++ { ++ SIOCIWFIRSTPRIV + 0x0, ++ IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x1, ++ IW_PRIV_TYPE_CHAR | 0x7FF, ++ IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x4, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x5, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x6, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x7, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x8, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x9, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie" ++ }, ++ ++ { ++ SIOCIWFIRSTPRIV + 0xA, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan" ++ }, ++ ++ { ++ SIOCIWFIRSTPRIV + 0xB, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0xC, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0xD, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x10, ++ IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, 0, "p2p_set" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x11, ++ IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | P2P_PRIVATE_IOCTL_SET_LEN, "p2p_get" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x12, ++ IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IFNAMSIZ, "p2p_get2" ++ }, ++ {SIOCIWFIRSTPRIV + 0x13, IW_PRIV_TYPE_CHAR | 128, 0, "NULL"}, ++ { ++ SIOCIWFIRSTPRIV + 0x14, ++ IW_PRIV_TYPE_CHAR | 64, 0, "tdls" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x15, ++ IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | P2P_PRIVATE_IOCTL_SET_LEN, "tdls_get" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x16, ++ IW_PRIV_TYPE_CHAR | 64, 0, "pm_set" ++ }, ++ ++ {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ, 0, "rereg_nd_name"}, ++ ++ {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"}, ++ {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"}, ++ {SIOCIWFIRSTPRIV + 0x1D, IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test" ++ }, ++ ++ {SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0, ""}, /* set */ ++ {SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, ""},/* get */ ++/* --- sub-ioctls definitions --- */ ++ ++ {MP_START, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_start"}, /* set */ ++ {MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara"},/* get */ ++ {MP_STOP, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_stop"}, /* set */ ++ {MP_CHANNEL, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel"},/* get */ ++ {MP_BANDWIDTH, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_bandwidth"}, /* set */ ++ {MP_RATE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate"},/* get */ ++ {MP_RESET_STATS, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_reset_stats"}, ++ {MP_QUERY, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_query"}, /* get */ ++ {READ_REG, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg"}, ++ {MP_RATE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate"}, ++ {READ_RF, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf"}, ++ {MP_PSD, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"}, ++ {MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump"}, ++ {MP_TXPOWER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"}, ++ {MP_ANT_TX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"}, ++ {MP_ANT_RX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"}, ++ {WRITE_REG, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg"}, ++ {WRITE_RF, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf"}, ++ {MP_CTX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"}, ++ {MP_ARX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"}, ++ {MP_THER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"}, ++ {EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_set"}, ++ {EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"}, ++ {MP_PWRTRK, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_pwrtrk"}, ++ {MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery"}, ++ {MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"}, /* mp_ioctl */ ++ {MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_setrfpath"}, ++ {CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"}, ++}; ++ ++static iw_handler rtw_private_handler[] = { ++rtw_wx_write32, /* 0x00 */ ++rtw_wx_read32, /* 0x01 */ ++rtw_drvext_hdl, /* 0x02 */ ++rtw_mp_ioctl_hdl, /* 0x03 */ ++ ++/* for MM DTV platform */ ++ rtw_get_ap_info, /* 0x04 */ ++ ++ rtw_set_pid, /* 0x05 */ ++ rtw_wps_start, /* 0x06 */ ++ ++ rtw_wx_get_sensitivity, /* 0x07 */ ++ rtw_wx_set_mtk_wps_probe_ie, /* 0x08 */ ++ rtw_wx_set_mtk_wps_ie, /* 0x09 */ ++ ++/* Set Channel depend on the country code */ ++ rtw_wx_set_channel_plan, /* 0x0A */ ++ ++ rtw_dbg_port, /* 0x0B */ ++ rtw_wx_write_rf, /* 0x0C */ ++ rtw_wx_read_rf, /* 0x0D */ ++ ++ rtw_mp_set, /* 0x0E */ ++ rtw_mp_get, /* 0x0F */ ++ rtw_p2p_set, /* 0x10 */ ++ rtw_p2p_get, /* 0x11 */ ++ rtw_p2p_get2, /* 0x12 */ ++ ++ NULL, /* 0x13 */ ++ rtw_tdls, /* 0x14 */ ++ rtw_tdls_get, /* 0x15 */ ++ ++ rtw_pm_set, /* 0x16 */ ++ rtw_wx_priv_null, /* 0x17 */ ++ rtw_rereg_nd_name, /* 0x18 */ ++ rtw_wx_priv_null, /* 0x19 */ ++ ++ rtw_mp_efuse_set, /* 0x1A */ ++ rtw_mp_efuse_get, /* 0x1B */ ++ NULL, /* 0x1C is reserved for hostapd */ ++ rtw_test, /* 0x1D */ ++}; ++ ++static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct iw_statistics *piwstats = &padapter->iwstats; ++ int tmp_noise = 0; ++ int tmp; ++ ++ if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { ++ piwstats->qual.qual = 0; ++ piwstats->qual.level = 0; ++ piwstats->qual.noise = 0; ++ } else { ++ tmp_noise = padapter->recvpriv.noise; ++ ++ piwstats->qual.level = padapter->signal_strength; ++ tmp = 219 + 3 * padapter->signal_strength; ++ tmp = min(100, tmp); ++ tmp = max(0, tmp); ++ piwstats->qual.qual = tmp; ++ piwstats->qual.noise = tmp_noise; ++ } ++ piwstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; ++ return &padapter->iwstats; ++} ++ ++struct iw_handler_def rtw_handlers_def = { ++ .standard = rtw_handlers, ++ .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler), ++ .private = rtw_private_handler, ++ .private_args = (struct iw_priv_args *)rtw_private_args, ++ .num_private = sizeof(rtw_private_handler) / sizeof(iw_handler), ++ .num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args), ++ .get_wireless_stats = rtw_get_wireless_stats, ++}; +diff --git a/drivers/staging/r8188eu/os_dep/mlme_linux.c b/drivers/staging/r8188eu/os_dep/mlme_linux.c +new file mode 100644 +index 000000000000..e3ee9dc7ab90 +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/mlme_linux.c +@@ -0,0 +1,216 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. i*/ ++ ++#define _MLME_OSDEP_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/mlme_osdep.h" ++ ++void rtw_join_timeout_handler (struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, mlmepriv.assoc_timer); ++ ++ _rtw_join_timeout_handler(adapter); ++} ++ ++void _rtw_scan_timeout_handler (struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, mlmepriv.scan_to_timer); ++ ++ rtw_scan_timeout_handler(adapter); ++} ++ ++static void _dynamic_check_timer_handlder(struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, mlmepriv.dynamic_chk_timer); ++ ++ if (adapter->registrypriv.mp_mode == 1) ++ return; ++ rtw_dynamic_check_timer_handlder(adapter); ++ _set_timer(&adapter->mlmepriv.dynamic_chk_timer, 2000); ++} ++ ++void rtw_init_mlme_timer(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ timer_setup(&pmlmepriv->assoc_timer, rtw_join_timeout_handler, 0); ++ timer_setup(&pmlmepriv->scan_to_timer, _rtw_scan_timeout_handler, 0); ++ timer_setup(&pmlmepriv->dynamic_chk_timer, _dynamic_check_timer_handlder, 0); ++} ++ ++void rtw_os_indicate_connect(struct adapter *adapter) ++{ ++ ++ rtw_indicate_wx_assoc_event(adapter); ++ netif_carrier_on(adapter->pnetdev); ++ if (adapter->pid[2] != 0) ++ rtw_signal_process(adapter->pid[2], SIGALRM); ++ ++} ++ ++void rtw_os_indicate_scan_done(struct adapter *padapter, bool aborted) ++{ ++ indicate_wx_scan_complete_event(padapter); ++} ++ ++static struct rt_pmkid_list backup_pmkid[NUM_PMKID_CACHE]; ++ ++void rtw_reset_securitypriv(struct adapter *adapter) ++{ ++ u8 backup_index = 0; ++ u8 backup_counter = 0x00; ++ u32 backup_time = 0; ++ ++ if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { ++ /* 802.1x */ ++ /* We have to backup the PMK information for WiFi PMK Caching test item. */ ++ /* Backup the btkip_countermeasure information. */ ++ /* When the countermeasure is trigger, the driver have to disconnect with AP for 60 seconds. */ ++ memset(&backup_pmkid[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); ++ memcpy(&backup_pmkid[0], &adapter->securitypriv.PMKIDList[0], sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); ++ backup_index = adapter->securitypriv.PMKIDIndex; ++ backup_counter = adapter->securitypriv.btkip_countermeasure; ++ backup_time = adapter->securitypriv.btkip_countermeasure_time; ++ memset((unsigned char *)&adapter->securitypriv, 0, sizeof(struct security_priv)); ++ ++ /* Restore the PMK information to securitypriv structure for the following connection. */ ++ memcpy(&adapter->securitypriv.PMKIDList[0], ++ &backup_pmkid[0], ++ sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); ++ adapter->securitypriv.PMKIDIndex = backup_index; ++ adapter->securitypriv.btkip_countermeasure = backup_counter; ++ adapter->securitypriv.btkip_countermeasure_time = backup_time; ++ adapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; ++ adapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled; ++ } else { ++ /* reset values in securitypriv */ ++ struct security_priv *psec_priv = &adapter->securitypriv; ++ ++ psec_priv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ ++ psec_priv->dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ psec_priv->dot11PrivacyKeyIndex = 0; ++ psec_priv->dot118021XGrpPrivacy = _NO_PRIVACY_; ++ psec_priv->dot118021XGrpKeyid = 1; ++ psec_priv->ndisauthtype = Ndis802_11AuthModeOpen; ++ psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled; ++ } ++} ++ ++void rtw_os_indicate_disconnect(struct adapter *adapter) ++{ ++ ++ netif_carrier_off(adapter->pnetdev); /* Do it first for tx broadcast pkt after disconnection issue! */ ++ rtw_indicate_wx_disassoc_event(adapter); ++ rtw_reset_securitypriv(adapter); ++} ++ ++void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie) ++{ ++ uint len; ++ u8 *buff, *p, i; ++ union iwreq_data wrqu; ++ ++ buff = NULL; ++ if (authmode == _WPA_IE_ID_) { ++ buff = kzalloc(IW_CUSTOM_MAX, GFP_KERNEL); ++ if (!buff) ++ return; ++ p = buff; ++ p += sprintf(p, "ASSOCINFO(ReqIEs ="); ++ len = sec_ie[1] + 2; ++ len = (len < IW_CUSTOM_MAX) ? len : IW_CUSTOM_MAX; ++ for (i = 0; i < len; i++) ++ p += sprintf(p, "%02x", sec_ie[i]); ++ p += sprintf(p, ")"); ++ memset(&wrqu, 0, sizeof(wrqu)); ++ wrqu.data.length = p - buff; ++ wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ? ++ wrqu.data.length : IW_CUSTOM_MAX; ++ wireless_send_event(adapter->pnetdev, IWEVCUSTOM, &wrqu, buff); ++ kfree(buff); ++ } ++} ++ ++static void _survey_timer_hdl(struct timer_list *t) ++{ ++ struct adapter *padapter = from_timer(padapter, t, mlmeextpriv.survey_timer); ++ ++ survey_timer_hdl(padapter); ++} ++ ++static void _link_timer_hdl(struct timer_list *t) ++{ ++ struct adapter *padapter = from_timer(padapter, t, mlmeextpriv.link_timer); ++ link_timer_hdl(padapter); ++} ++ ++static void _addba_timer_hdl(struct timer_list *t) ++{ ++ struct sta_info *psta = from_timer(psta, t, addba_retry_timer); ++ addba_timer_hdl(psta); ++} ++ ++void init_addba_retry_timer(struct adapter *padapter, struct sta_info *psta) ++{ ++ timer_setup(&psta->addba_retry_timer, _addba_timer_hdl, 0); ++} ++ ++void init_mlme_ext_timer(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ timer_setup(&pmlmeext->survey_timer, _survey_timer_hdl, 0); ++ timer_setup(&pmlmeext->link_timer, _link_timer_hdl, 0); ++} ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++void rtw_indicate_sta_assoc_event(struct adapter *padapter, struct sta_info *psta) ++{ ++ union iwreq_data wrqu; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ if (!psta) ++ return; ++ ++ if (psta->aid > NUM_STA) ++ return; ++ ++ if (pstapriv->sta_aid[psta->aid - 1] != psta) ++ return; ++ ++ wrqu.addr.sa_family = ARPHRD_ETHER; ++ ++ memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN); ++ ++ DBG_88E("+rtw_indicate_sta_assoc_event\n"); ++ ++ wireless_send_event(padapter->pnetdev, IWEVREGISTERED, &wrqu, NULL); ++} ++ ++void rtw_indicate_sta_disassoc_event(struct adapter *padapter, struct sta_info *psta) ++{ ++ union iwreq_data wrqu; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ if (!psta) ++ return; ++ ++ if (psta->aid > NUM_STA) ++ return; ++ ++ if (pstapriv->sta_aid[psta->aid - 1] != psta) ++ return; ++ ++ wrqu.addr.sa_family = ARPHRD_ETHER; ++ ++ memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN); ++ ++ DBG_88E("+rtw_indicate_sta_disassoc_event\n"); ++ ++ wireless_send_event(padapter->pnetdev, IWEVEXPIRED, &wrqu, NULL); ++} ++ ++#endif +diff --git a/drivers/staging/r8188eu/os_dep/os_intfs.c b/drivers/staging/r8188eu/os_dep/os_intfs.c +new file mode 100644 +index 000000000000..8d0158f4a45d +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/os_intfs.c +@@ -0,0 +1,1199 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _OS_INTFS_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/xmit_osdep.h" ++#include "../include/recv_osdep.h" ++#include "../include/hal_intf.h" ++#include "../include/rtw_ioctl.h" ++ ++#include "../include/usb_osintf.h" ++#include "../include/rtw_br_ext.h" ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Realtek Wireless Lan Driver"); ++MODULE_AUTHOR("Realtek Semiconductor Corp."); ++MODULE_VERSION(DRIVERVERSION); ++ ++#define CONFIG_BR_EXT_BRNAME "br0" ++#define RTW_NOTCH_FILTER 0 /* 0:Disable, 1:Enable, */ ++ ++/* module param defaults */ ++static int rtw_chip_version = 0x00; ++static int rtw_rfintfs = HWPI; ++static int rtw_lbkmode;/* RTL8712_AIR_TRX; */ ++static int rtw_network_mode = Ndis802_11IBSS;/* Ndis802_11Infrastructure; infra, ad-hoc, auto */ ++static int rtw_channel = 1;/* ad-hoc support requirement */ ++static int rtw_wireless_mode = WIRELESS_11BG_24N; ++static int rtw_vrtl_carrier_sense = AUTO_VCS; ++static int rtw_vcs_type = RTS_CTS;/* */ ++static int rtw_rts_thresh = 2347;/* */ ++static int rtw_frag_thresh = 2346;/* */ ++static int rtw_preamble = PREAMBLE_LONG;/* long, short, auto */ ++static int rtw_scan_mode = 1;/* active, passive */ ++static int rtw_adhoc_tx_pwr = 1; ++static int rtw_soft_ap; ++static int rtw_power_mgnt = 1; ++static int rtw_ips_mode = IPS_NORMAL; ++ ++static int rtw_smart_ps = 2; ++ ++module_param(rtw_ips_mode, int, 0644); ++MODULE_PARM_DESC(rtw_ips_mode, "The default IPS mode"); ++ ++static int rtw_debug = 1; ++static int rtw_radio_enable = 1; ++static int rtw_long_retry_lmt = 7; ++static int rtw_short_retry_lmt = 7; ++static int rtw_busy_thresh = 40; ++static int rtw_ack_policy = NORMAL_ACK; ++ ++static int rtw_mp_mode; ++ ++static int rtw_software_encrypt; ++static int rtw_software_decrypt; ++ ++static int rtw_acm_method;/* 0:By SW 1:By HW. */ ++ ++static int rtw_wmm_enable = 1;/* default is set to enable the wmm. */ ++static int rtw_uapsd_enable; ++static int rtw_uapsd_max_sp = NO_LIMIT; ++static int rtw_uapsd_acbk_en; ++static int rtw_uapsd_acbe_en; ++static int rtw_uapsd_acvi_en; ++static int rtw_uapsd_acvo_en; ++ ++static int rtw_led_enable = 1; ++ ++int rtw_ht_enable = 1; ++int rtw_cbw40_enable = 3; /* 0 :disable, bit(0): enable 2.4g, bit(1): enable 5g */ ++int rtw_ampdu_enable = 1;/* for enable tx_ampdu */ ++static int rtw_rx_stbc = 1;/* 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */ ++static int rtw_ampdu_amsdu;/* 0: disabled, 1:enabled, 2:auto */ ++ ++static int rtw_lowrate_two_xmit = 1;/* Use 2 path Tx to transmit MCS0~7 and legacy mode */ ++ ++static int rtw_rf_config = RF_819X_MAX_TYPE; /* auto */ ++static int rtw_low_power; ++static int rtw_wifi_spec; ++static int rtw_channel_plan = RT_CHANNEL_DOMAIN_MAX; ++static int rtw_AcceptAddbaReq = true;/* 0:Reject AP's Add BA req, 1:Accept AP's Add BA req. */ ++ ++static int rtw_antdiv_cfg = 2; /* 0:OFF , 1:ON, 2:decide by Efuse config */ ++static int rtw_antdiv_type; /* 0:decide by efuse 1: for 88EE, 1Tx and 1RxCG are diversity.(2 Ant with SPDT), 2: for 88EE, 1Tx and 2Rx are diversity.(2 Ant, Tx and RxCG are both on aux port, RxCS is on main port), 3: for 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port) */ ++ ++static int rtw_enusbss;/* 0:disable, 1:enable */ ++ ++static int rtw_hwpdn_mode = 2;/* 0:disable, 1:enable, 2: by EFUSE config */ ++ ++static int rtw_hwpwrp_detect; /* HW power ping detect 0:disable , 1:enable */ ++ ++static int rtw_hw_wps_pbc = 1; ++ ++int rtw_mc2u_disable; ++ ++static int rtw_80211d; ++ ++static char *ifname = "wlan%d"; ++module_param(ifname, charp, 0644); ++MODULE_PARM_DESC(ifname, "The default name to allocate for first interface"); ++ ++static char *if2name = "wlan%d"; ++module_param(if2name, charp, 0644); ++MODULE_PARM_DESC(if2name, "The default name to allocate for second interface"); ++ ++char *rtw_initmac; /* temp mac address if users want to use instead of the mac address in Efuse */ ++ ++module_param(rtw_initmac, charp, 0644); ++module_param(rtw_channel_plan, int, 0644); ++module_param(rtw_chip_version, int, 0644); ++module_param(rtw_rfintfs, int, 0644); ++module_param(rtw_lbkmode, int, 0644); ++module_param(rtw_network_mode, int, 0644); ++module_param(rtw_channel, int, 0644); ++module_param(rtw_mp_mode, int, 0644); ++module_param(rtw_wmm_enable, int, 0644); ++module_param(rtw_vrtl_carrier_sense, int, 0644); ++module_param(rtw_vcs_type, int, 0644); ++module_param(rtw_busy_thresh, int, 0644); ++module_param(rtw_led_enable, int, 0644); ++module_param(rtw_ht_enable, int, 0644); ++module_param(rtw_cbw40_enable, int, 0644); ++module_param(rtw_ampdu_enable, int, 0644); ++module_param(rtw_rx_stbc, int, 0644); ++module_param(rtw_ampdu_amsdu, int, 0644); ++module_param(rtw_lowrate_two_xmit, int, 0644); ++module_param(rtw_rf_config, int, 0644); ++module_param(rtw_power_mgnt, int, 0644); ++module_param(rtw_smart_ps, int, 0644); ++module_param(rtw_low_power, int, 0644); ++module_param(rtw_wifi_spec, int, 0644); ++module_param(rtw_antdiv_cfg, int, 0644); ++module_param(rtw_antdiv_type, int, 0644); ++module_param(rtw_enusbss, int, 0644); ++module_param(rtw_hwpdn_mode, int, 0644); ++module_param(rtw_hwpwrp_detect, int, 0644); ++module_param(rtw_hw_wps_pbc, int, 0644); ++ ++static uint rtw_max_roaming_times = 2; ++module_param(rtw_max_roaming_times, uint, 0644); ++MODULE_PARM_DESC(rtw_max_roaming_times, "The max roaming times to try"); ++ ++static int rtw_fw_iol = 1;/* 0:Disable, 1:enable, 2:by usb speed */ ++module_param(rtw_fw_iol, int, 0644); ++MODULE_PARM_DESC(rtw_fw_iol, "FW IOL"); ++ ++module_param(rtw_mc2u_disable, int, 0644); ++ ++module_param(rtw_80211d, int, 0644); ++MODULE_PARM_DESC(rtw_80211d, "Enable 802.11d mechanism"); ++ ++static uint rtw_notch_filter = RTW_NOTCH_FILTER; ++module_param(rtw_notch_filter, uint, 0644); ++MODULE_PARM_DESC(rtw_notch_filter, "0:Disable, 1:Enable, 2:Enable only for P2P"); ++module_param_named(debug, rtw_debug, int, 0444); ++MODULE_PARM_DESC(debug, "Set debug level (1-9) (default 1)"); ++ ++/* dummy routines */ ++void rtw_proc_remove_one(struct net_device *dev) ++{ ++} ++ ++void rtw_proc_init_one(struct net_device *dev) ++{ ++} ++ ++#if 0 /* TODO: Convert these to /sys */ ++void rtw_proc_init_one(struct net_device *dev) ++{ ++ struct proc_dir_entry *dir_dev = NULL; ++ struct proc_dir_entry *entry = NULL; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ u8 rf_type; ++ ++ if (!rtw_proc) { ++ memcpy(rtw_proc_name, DRV_NAME, sizeof(DRV_NAME)); ++ ++ rtw_proc = create_proc_entry(rtw_proc_name, S_IFDIR, init_net.proc_net); ++ if (!rtw_proc) { ++ DBG_88E(KERN_ERR "Unable to create rtw_proc directory\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("ver_info", S_IFREG | S_IRUGO, rtw_proc, proc_get_drv_version, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ } ++ ++ if (!padapter->dir_dev) { ++ padapter->dir_dev = create_proc_entry(dev->name, ++ S_IFDIR | S_IRUGO | S_IXUGO, ++ rtw_proc); ++ dir_dev = padapter->dir_dev; ++ if (!dir_dev) { ++ if (rtw_proc_cnt == 0) { ++ if (rtw_proc) { ++ remove_proc_entry(rtw_proc_name, init_net.proc_net); ++ rtw_proc = NULL; ++ } ++ } ++ ++ pr_info("Unable to create dir_dev directory\n"); ++ return; ++ } ++ } else { ++ return; ++ } ++ ++ rtw_proc_cnt++; ++ ++ entry = create_proc_read_entry("write_reg", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_write_reg, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_write_reg; ++ ++ entry = create_proc_read_entry("read_reg", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_read_reg, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_read_reg; ++ ++ entry = create_proc_read_entry("fwstate", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_fwstate, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("sec_info", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_sec_info, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("mlmext_state", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_mlmext_state, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("qos_option", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_qos_option, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("ht_option", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_ht_option, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("rf_info", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rf_info, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("ap_info", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_ap_info, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("adapter_state", S_IFREG | S_IRUGO, ++ dir_dev, proc_getstruct adapter_state, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("trx_info", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_trx_info, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("mac_reg_dump1", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_mac_reg_dump1, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("mac_reg_dump2", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_mac_reg_dump2, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("mac_reg_dump3", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_mac_reg_dump3, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("bb_reg_dump1", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_bb_reg_dump1, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("bb_reg_dump2", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_bb_reg_dump2, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("bb_reg_dump3", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_bb_reg_dump3, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("rf_reg_dump1", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rf_reg_dump1, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("rf_reg_dump2", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rf_reg_dump2, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ if ((RF_1T2R == rf_type) || (RF_1T1R == rf_type)) { ++ entry = create_proc_read_entry("rf_reg_dump3", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rf_reg_dump3, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("rf_reg_dump4", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rf_reg_dump4, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ } ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++ entry = create_proc_read_entry("all_sta_info", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_all_sta_info, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++#endif ++ ++ entry = create_proc_read_entry("best_channel", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_best_channel, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("rx_signal", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rx_signal, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_rx_signal; ++ entry = create_proc_read_entry("ht_enable", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_ht_enable, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_ht_enable; ++ ++ entry = create_proc_read_entry("cbw40_enable", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_cbw40_enable, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_cbw40_enable; ++ ++ entry = create_proc_read_entry("ampdu_enable", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_ampdu_enable, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_ampdu_enable; ++ ++ entry = create_proc_read_entry("rx_stbc", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rx_stbc, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_rx_stbc; ++ ++ entry = create_proc_read_entry("path_rssi", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_two_path_rssi, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry = create_proc_read_entry("rssi_disp", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rssi_disp, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_rssi_disp; ++} ++ ++void rtw_proc_remove_one(struct net_device *dev) ++{ ++ struct proc_dir_entry *dir_dev = NULL; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ u8 rf_type; ++ ++ dir_dev = padapter->dir_dev; ++ padapter->dir_dev = NULL; ++ ++ if (dir_dev) { ++ remove_proc_entry("write_reg", dir_dev); ++ remove_proc_entry("read_reg", dir_dev); ++ remove_proc_entry("fwstate", dir_dev); ++ remove_proc_entry("sec_info", dir_dev); ++ remove_proc_entry("mlmext_state", dir_dev); ++ remove_proc_entry("qos_option", dir_dev); ++ remove_proc_entry("ht_option", dir_dev); ++ remove_proc_entry("rf_info", dir_dev); ++ remove_proc_entry("ap_info", dir_dev); ++ remove_proc_entry("adapter_state", dir_dev); ++ remove_proc_entry("trx_info", dir_dev); ++ remove_proc_entry("mac_reg_dump1", dir_dev); ++ remove_proc_entry("mac_reg_dump2", dir_dev); ++ remove_proc_entry("mac_reg_dump3", dir_dev); ++ remove_proc_entry("bb_reg_dump1", dir_dev); ++ remove_proc_entry("bb_reg_dump2", dir_dev); ++ remove_proc_entry("bb_reg_dump3", dir_dev); ++ remove_proc_entry("rf_reg_dump1", dir_dev); ++ remove_proc_entry("rf_reg_dump2", dir_dev); ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ if ((RF_1T2R == rf_type) || (RF_1T1R == rf_type)) { ++ remove_proc_entry("rf_reg_dump3", dir_dev); ++ remove_proc_entry("rf_reg_dump4", dir_dev); ++ } ++#ifdef CONFIG_88EU_AP_MODE ++ remove_proc_entry("all_sta_info", dir_dev); ++#endif ++ ++ remove_proc_entry("best_channel", dir_dev); ++ remove_proc_entry("rx_signal", dir_dev); ++ remove_proc_entry("cbw40_enable", dir_dev); ++ remove_proc_entry("ht_enable", dir_dev); ++ remove_proc_entry("ampdu_enable", dir_dev); ++ remove_proc_entry("rx_stbc", dir_dev); ++ remove_proc_entry("path_rssi", dir_dev); ++ remove_proc_entry("rssi_disp", dir_dev); ++ remove_proc_entry(dev->name, rtw_proc); ++ dir_dev = NULL; ++ } else { ++ return; ++ } ++ rtw_proc_cnt--; ++ ++ if (rtw_proc_cnt == 0) { ++ if (rtw_proc) { ++ remove_proc_entry("ver_info", rtw_proc); ++ ++ remove_proc_entry(rtw_proc_name, init_net.proc_net); ++ rtw_proc = NULL; ++ } ++ } ++} ++#endif ++ ++static uint loadparam(struct adapter *padapter, struct net_device *pnetdev) ++{ ++ struct registry_priv *registry_par = &padapter->registrypriv; ++ ++ GlobalDebugLevel = rtw_debug; ++ registry_par->chip_version = (u8)rtw_chip_version; ++ registry_par->rfintfs = (u8)rtw_rfintfs; ++ registry_par->lbkmode = (u8)rtw_lbkmode; ++ registry_par->network_mode = (u8)rtw_network_mode; ++ ++ memcpy(registry_par->ssid.Ssid, "ANY", 3); ++ registry_par->ssid.SsidLength = 3; ++ ++ registry_par->channel = (u8)rtw_channel; ++ registry_par->wireless_mode = (u8)rtw_wireless_mode; ++ registry_par->vrtl_carrier_sense = (u8)rtw_vrtl_carrier_sense; ++ registry_par->vcs_type = (u8)rtw_vcs_type; ++ registry_par->rts_thresh = (u16)rtw_rts_thresh; ++ registry_par->frag_thresh = (u16)rtw_frag_thresh; ++ registry_par->preamble = (u8)rtw_preamble; ++ registry_par->scan_mode = (u8)rtw_scan_mode; ++ registry_par->adhoc_tx_pwr = (u8)rtw_adhoc_tx_pwr; ++ registry_par->soft_ap = (u8)rtw_soft_ap; ++ registry_par->smart_ps = (u8)rtw_smart_ps; ++ registry_par->power_mgnt = (u8)rtw_power_mgnt; ++ registry_par->ips_mode = (u8)rtw_ips_mode; ++ registry_par->radio_enable = (u8)rtw_radio_enable; ++ registry_par->long_retry_lmt = (u8)rtw_long_retry_lmt; ++ registry_par->short_retry_lmt = (u8)rtw_short_retry_lmt; ++ registry_par->busy_thresh = (u16)rtw_busy_thresh; ++ registry_par->ack_policy = (u8)rtw_ack_policy; ++ registry_par->mp_mode = (u8)rtw_mp_mode; ++ registry_par->software_encrypt = (u8)rtw_software_encrypt; ++ registry_par->software_decrypt = (u8)rtw_software_decrypt; ++ registry_par->acm_method = (u8)rtw_acm_method; ++ ++ /* UAPSD */ ++ registry_par->wmm_enable = (u8)rtw_wmm_enable; ++ registry_par->uapsd_enable = (u8)rtw_uapsd_enable; ++ registry_par->uapsd_max_sp = (u8)rtw_uapsd_max_sp; ++ registry_par->uapsd_acbk_en = (u8)rtw_uapsd_acbk_en; ++ registry_par->uapsd_acbe_en = (u8)rtw_uapsd_acbe_en; ++ registry_par->uapsd_acvi_en = (u8)rtw_uapsd_acvi_en; ++ registry_par->uapsd_acvo_en = (u8)rtw_uapsd_acvo_en; ++ ++ registry_par->led_enable = (u8)rtw_led_enable; ++ ++ registry_par->ht_enable = (u8)rtw_ht_enable; ++ registry_par->cbw40_enable = (u8)rtw_cbw40_enable; ++ registry_par->ampdu_enable = (u8)rtw_ampdu_enable; ++ registry_par->rx_stbc = (u8)rtw_rx_stbc; ++ registry_par->ampdu_amsdu = (u8)rtw_ampdu_amsdu; ++ registry_par->lowrate_two_xmit = (u8)rtw_lowrate_two_xmit; ++ registry_par->rf_config = (u8)rtw_rf_config; ++ registry_par->low_power = (u8)rtw_low_power; ++ registry_par->wifi_spec = (u8)rtw_wifi_spec; ++ registry_par->channel_plan = (u8)rtw_channel_plan; ++ registry_par->bAcceptAddbaReq = (u8)rtw_AcceptAddbaReq; ++ registry_par->antdiv_cfg = (u8)rtw_antdiv_cfg; ++ registry_par->antdiv_type = (u8)rtw_antdiv_type; ++ registry_par->hwpdn_mode = (u8)rtw_hwpdn_mode;/* 0:disable, 1:enable, 2:by EFUSE config */ ++ registry_par->hwpwrp_detect = (u8)rtw_hwpwrp_detect;/* 0:disable, 1:enable */ ++ registry_par->hw_wps_pbc = (u8)rtw_hw_wps_pbc; ++ ++ registry_par->max_roaming_times = (u8)rtw_max_roaming_times; ++ ++ registry_par->fw_iol = rtw_fw_iol; ++ ++ registry_par->enable80211d = (u8)rtw_80211d; ++ snprintf(registry_par->ifname, 16, "%s", ifname); ++ snprintf(registry_par->if2name, 16, "%s", if2name); ++ registry_par->notch_filter = (u8)rtw_notch_filter; ++ ++ return _SUCCESS; ++} ++ ++static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); ++ struct sockaddr *addr = p; ++ ++ if (!padapter->bup) ++ memcpy(padapter->eeprompriv.mac_addr, addr->sa_data, ETH_ALEN); ++ ++ return 0; ++} ++ ++static struct net_device_stats *rtw_net_get_stats(struct net_device *pnetdev) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ ++ padapter->stats.tx_packets = pxmitpriv->tx_pkts;/* pxmitpriv->tx_pkts++; */ ++ padapter->stats.rx_packets = precvpriv->rx_pkts;/* precvpriv->rx_pkts++; */ ++ padapter->stats.tx_dropped = pxmitpriv->tx_drop; ++ padapter->stats.rx_dropped = precvpriv->rx_drop; ++ padapter->stats.tx_bytes = pxmitpriv->tx_bytes; ++ padapter->stats.rx_bytes = precvpriv->rx_bytes; ++ return &padapter->stats; ++} ++ ++/* ++ * AC to queue mapping ++ * ++ * AC_VO -> queue 0 ++ * AC_VI -> queue 1 ++ * AC_BE -> queue 2 ++ * AC_BK -> queue 3 ++ */ ++static const u16 rtw_1d_to_queue[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; ++ ++/* Given a data frame determine the 802.1p/1d tag to use. */ ++static unsigned int rtw_classify8021d(struct sk_buff *skb) ++{ ++ unsigned int dscp; ++ ++ /* skb->priority values from 256->263 are magic values to ++ * directly indicate a specific 802.1d priority. This is used ++ * to allow 802.1d priority to be passed directly in from VLAN ++ * tags, etc. ++ */ ++ if (skb->priority >= 256 && skb->priority <= 263) ++ return skb->priority - 256; ++ ++ switch (skb->protocol) { ++ case htons(ETH_P_IP): ++ dscp = ip_hdr(skb)->tos & 0xfc; ++ break; ++ default: ++ return 0; ++ } ++ ++ return dscp >> 5; ++} ++ ++static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb, struct net_device *sb_dev) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ skb->priority = rtw_classify8021d(skb); ++ ++ if (pmlmepriv->acm_mask != 0) ++ skb->priority = qos_acm(pmlmepriv->acm_mask, skb->priority); ++ ++ return rtw_1d_to_queue[skb->priority]; ++} ++ ++u16 rtw_recv_select_queue(struct sk_buff *skb) ++{ ++ struct iphdr *piphdr; ++ unsigned int dscp; ++ __be16 eth_type; ++ u32 priority; ++ u8 *pdata = skb->data; ++ ++ memcpy(ð_type, pdata + (ETH_ALEN << 1), 2); ++ ++ switch (eth_type) { ++ case htons(ETH_P_IP): ++ piphdr = (struct iphdr *)(pdata + ETH_HLEN); ++ dscp = piphdr->tos & 0xfc; ++ priority = dscp >> 5; ++ break; ++ default: ++ priority = 0; ++ } ++ ++ return rtw_1d_to_queue[priority]; ++} ++ ++static const struct net_device_ops rtw_netdev_ops = { ++ .ndo_open = netdev_open, ++ .ndo_stop = netdev_close, ++ .ndo_start_xmit = rtw_xmit_entry, ++ .ndo_select_queue = rtw_select_queue, ++ .ndo_set_mac_address = rtw_net_set_mac_address, ++ .ndo_get_stats = rtw_net_get_stats, ++}; ++ ++int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname) ++{ ++ int err; ++ ++ err = dev_alloc_name(pnetdev, ifname); ++ if (err < 0) ++ return err; ++ ++ netif_carrier_off(pnetdev); ++ return 0; ++} ++ ++static const struct device_type wlan_type = { ++ .name = "wlan", ++}; ++ ++struct net_device *rtw_init_netdev(struct adapter *old_padapter) ++{ ++ struct adapter *padapter; ++ struct net_device *pnetdev; ++ ++ if (old_padapter) ++ pnetdev = rtw_alloc_etherdev_with_old_priv(sizeof(struct adapter), (void *)old_padapter); ++ else ++ pnetdev = rtw_alloc_etherdev(sizeof(struct adapter)); ++ ++ if (!pnetdev) ++ return NULL; ++ ++ pnetdev->dev.type = &wlan_type; ++ padapter = rtw_netdev_priv(pnetdev); ++ padapter->pnetdev = pnetdev; ++ DBG_88E("register rtw_netdev_ops to netdev_ops\n"); ++ pnetdev->netdev_ops = &rtw_netdev_ops; ++ pnetdev->watchdog_timeo = HZ * 3; /* 3 second timeout */ ++ pnetdev->wireless_handlers = (struct iw_handler_def *)&rtw_handlers_def; ++ ++ /* step 2. */ ++ loadparam(padapter, pnetdev); ++ ++ return pnetdev; ++} ++ ++u32 rtw_start_drv_threads(struct adapter *padapter) ++{ ++ u32 _status = _SUCCESS; ++ ++ padapter->cmdThread = kthread_run(rtw_cmd_thread, padapter, "RTW_CMD_THREAD"); ++ if (IS_ERR(padapter->cmdThread)) ++ _status = _FAIL; ++ else ++ _rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema); /* wait for cmd_thread to run */ ++ ++ rtw_hal_start_thread(padapter); ++ return _status; ++} ++ ++void rtw_stop_drv_threads(struct adapter *padapter) ++{ ++ /* Below is to termindate rtw_cmd_thread & event_thread... */ ++ up(&padapter->cmdpriv.cmd_queue_sema); ++ if (padapter->cmdThread) ++ _rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema); ++ ++ rtw_hal_stop_thread(padapter); ++} ++ ++static u8 rtw_init_default_value(struct adapter *padapter) ++{ ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ ++ /* xmit_priv */ ++ pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense; ++ pxmitpriv->vcs = pregistrypriv->vcs_type; ++ pxmitpriv->vcs_type = pregistrypriv->vcs_type; ++ pxmitpriv->frag_len = pregistrypriv->frag_thresh; ++ ++ /* mlme_priv */ ++ pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */ ++ pmlmepriv->scan_mode = SCAN_ACTIVE; ++ ++ /* ht_priv */ ++ pmlmepriv->htpriv.ampdu_enable = false;/* set to disabled */ ++ ++ /* security_priv */ ++ psecuritypriv->binstallGrpkey = _FAIL; ++ psecuritypriv->sw_encrypt = pregistrypriv->software_encrypt; ++ psecuritypriv->sw_decrypt = pregistrypriv->software_decrypt; ++ psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ ++ psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ psecuritypriv->dot11PrivacyKeyIndex = 0; ++ psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; ++ psecuritypriv->dot118021XGrpKeyid = 1; ++ psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; ++ psecuritypriv->ndisencryptstatus = Ndis802_11WEPDisabled; ++ ++ /* registry_priv */ ++ rtw_init_registrypriv_dev_network(padapter); ++ rtw_update_registrypriv_dev_network(padapter); ++ ++ /* hal_priv */ ++ rtw_hal_def_value_init(padapter); ++ ++ /* misc. */ ++ padapter->bReadPortCancel = false; ++ padapter->bWritePortCancel = false; ++ padapter->bRxRSSIDisplay = 0; ++ padapter->bNotifyChannelChange = 0; ++#ifdef CONFIG_88EU_P2P ++ padapter->bShowGetP2PState = 1; ++#endif ++ return _SUCCESS; ++} ++ ++u8 rtw_reset_drv_sw(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; ++ ++ /* hal_priv */ ++ rtw_hal_def_value_init(padapter); ++ padapter->bReadPortCancel = false; ++ padapter->bWritePortCancel = false; ++ padapter->bRxRSSIDisplay = 0; ++ pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */ ++ ++ padapter->xmitpriv.tx_pkts = 0; ++ padapter->recvpriv.rx_pkts = 0; ++ ++ pmlmepriv->LinkDetectInfo.bBusyTraffic = false; ++ ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING); ++ ++ rtw_hal_sreset_reset_value(padapter); ++ pwrctrlpriv->pwr_state_check_cnts = 0; ++ ++ /* mlmeextpriv */ ++ padapter->mlmeextpriv.sitesurvey_res.state = SCAN_DISABLE; ++ ++ rtw_set_signal_stat_timer(&padapter->recvpriv); ++ ++ return _SUCCESS; ++} ++ ++u8 rtw_init_drv_sw(struct adapter *padapter) ++{ ++ u8 ret8 = _SUCCESS; ++ ++ if ((rtw_init_cmd_priv(&padapter->cmdpriv)) == _FAIL) { ++ ret8 = _FAIL; ++ goto exit; ++ } ++ ++ padapter->cmdpriv.padapter = padapter; ++ ++ if ((rtw_init_evt_priv(&padapter->evtpriv)) == _FAIL) { ++ ret8 = _FAIL; ++ goto exit; ++ } ++ ++ if (rtw_init_mlme_priv(padapter) == _FAIL) { ++ ret8 = _FAIL; ++ goto exit; ++ } ++ ++#ifdef CONFIG_88EU_P2P ++ rtw_init_wifidirect_timers(padapter); ++ init_wifidirect_info(padapter, P2P_ROLE_DISABLE); ++ reset_global_wifidirect_info(padapter); ++#endif /* CONFIG_88EU_P2P */ ++ ++ if (init_mlme_ext_priv(padapter) == _FAIL) { ++ ret8 = _FAIL; ++ goto exit; ++ } ++ ++ if (_rtw_init_xmit_priv(&padapter->xmitpriv, padapter) == _FAIL) { ++ DBG_88E("Can't _rtw_init_xmit_priv\n"); ++ ret8 = _FAIL; ++ goto exit; ++ } ++ ++ if (_rtw_init_recv_priv(&padapter->recvpriv, padapter) == _FAIL) { ++ DBG_88E("Can't _rtw_init_recv_priv\n"); ++ ret8 = _FAIL; ++ goto exit; ++ } ++ ++ if (_rtw_init_sta_priv(&padapter->stapriv) == _FAIL) { ++ DBG_88E("Can't _rtw_init_sta_priv\n"); ++ ret8 = _FAIL; ++ goto exit; ++ } ++ ++ padapter->stapriv.padapter = padapter; ++ ++ rtw_init_bcmc_stainfo(padapter); ++ ++ rtw_init_pwrctrl_priv(padapter); ++ ++ if (init_mp_priv(padapter) == _FAIL) ++ DBG_88E("%s: initialize MP private data Fail!\n", __func__); ++ ++ ret8 = rtw_init_default_value(padapter); ++ ++ rtw_hal_dm_init(padapter); ++ rtw_hal_sw_led_init(padapter); ++ ++ rtw_hal_sreset_init(padapter); ++ ++ spin_lock_init(&padapter->br_ext_lock); ++ ++exit: ++ return ret8; ++} ++ ++void rtw_cancel_all_timer(struct adapter *padapter) ++{ ++ _cancel_timer_ex(&padapter->mlmepriv.assoc_timer); ++ ++ _cancel_timer_ex(&padapter->mlmepriv.scan_to_timer); ++ ++ _cancel_timer_ex(&padapter->mlmepriv.dynamic_chk_timer); ++ ++ /* cancel sw led timer */ ++ rtw_hal_sw_led_deinit(padapter); ++ ++ _cancel_timer_ex(&padapter->pwrctrlpriv.pwr_state_check_timer); ++ ++ _cancel_timer_ex(&padapter->recvpriv.signal_stat_timer); ++ /* cancel dm timer */ ++ rtw_hal_dm_deinit(padapter); ++} ++ ++u8 rtw_free_drv_sw(struct adapter *padapter) ++{ ++ /* we can call rtw_p2p_enable here, but: */ ++ /* 1. rtw_p2p_enable may have IO operation */ ++ /* 2. rtw_p2p_enable is bundled with wext interface */ ++ #ifdef CONFIG_88EU_P2P ++ { ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ++ _cancel_timer_ex(&pwdinfo->find_phase_timer); ++ _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); ++ _cancel_timer_ex(&pwdinfo->pre_tx_scan_timer); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE); ++ } ++ } ++ #endif ++ ++ free_mlme_ext_priv(&padapter->mlmeextpriv); ++ ++ rtw_free_cmd_priv(&padapter->cmdpriv); ++ ++ rtw_free_evt_priv(&padapter->evtpriv); ++ ++ rtw_free_mlme_priv(&padapter->mlmepriv); ++ _rtw_free_xmit_priv(&padapter->xmitpriv); ++ ++ _rtw_free_sta_priv(&padapter->stapriv); /* will free bcmc_stainfo here */ ++ ++ _rtw_free_recv_priv(&padapter->recvpriv); ++ ++ rtw_free_pwrctrl_priv(padapter); ++ ++ rtw_hal_free_data(padapter); ++ ++ /* free the old_pnetdev */ ++ if (padapter->rereg_nd_name_priv.old_pnetdev) { ++ free_netdev(padapter->rereg_nd_name_priv.old_pnetdev); ++ padapter->rereg_nd_name_priv.old_pnetdev = NULL; ++ } ++ ++ /* clear pbuddystruct adapter to avoid access wrong pointer. */ ++ if (padapter->pbuddy_adapter) ++ padapter->pbuddy_adapter->pbuddy_adapter = NULL; ++ ++ return _SUCCESS; ++} ++ ++void netdev_br_init(struct net_device *netdev) ++{ ++ struct adapter *adapter = (struct adapter *)rtw_netdev_priv(netdev); ++ ++ rcu_read_lock(); ++ ++ if (rcu_dereference(adapter->pnetdev->rx_handler_data)) { ++ struct net_device *br_netdev; ++ struct net *devnet = NULL; ++ ++ devnet = dev_net(netdev); ++ br_netdev = dev_get_by_name(devnet, CONFIG_BR_EXT_BRNAME); ++ if (br_netdev) { ++ memcpy(adapter->br_mac, br_netdev->dev_addr, ETH_ALEN); ++ dev_put(br_netdev); ++ } else { ++ pr_info("%s()-%d: dev_get_by_name(%s) failed!", ++ __func__, __LINE__, CONFIG_BR_EXT_BRNAME); ++ } ++ } ++ adapter->ethBrExtInfo.addPPPoETag = 1; ++ ++ rcu_read_unlock(); ++} ++ ++int _netdev_open(struct net_device *pnetdev) ++{ ++ uint status; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); ++ struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; ++ ++ DBG_88E("+88eu_drv - drv_open, bup =%d\n", padapter->bup); ++ ++ if (pwrctrlpriv->ps_flag) { ++ padapter->net_closed = false; ++ goto netdev_open_normal_process; ++ } ++ ++ if (!padapter->bup) { ++ padapter->bDriverStopped = false; ++ padapter->bSurpriseRemoved = false; ++ padapter->bCardDisableWOHSM = false; ++ ++ status = rtw_hal_init(padapter); ++ if (status == _FAIL) ++ goto netdev_open_error; ++ ++ pr_info("MAC Address = %pM\n", pnetdev->dev_addr); ++ ++ status = rtw_start_drv_threads(padapter); ++ if (status == _FAIL) { ++ pr_info("Initialize driver software resource Failed!\n"); ++ goto netdev_open_error; ++ } ++ ++ if (init_hw_mlme_ext(padapter) == _FAIL) { ++ pr_info("can't init mlme_ext_priv\n"); ++ goto netdev_open_error; ++ } ++ if (padapter->intf_start) ++ padapter->intf_start(padapter); ++ rtw_proc_init_one(pnetdev); ++ ++ rtw_led_control(padapter, LED_CTL_NO_LINK); ++ ++ padapter->bup = true; ++ } ++ padapter->net_closed = false; ++ ++ _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); ++ ++ padapter->pwrctrlpriv.bips_processing = false; ++ rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); ++ ++ if (!rtw_netif_queue_stopped(pnetdev)) ++ rtw_netif_start_queue(pnetdev); ++ else ++ rtw_netif_wake_queue(pnetdev); ++ ++ netdev_br_init(pnetdev); ++ ++netdev_open_normal_process: ++ DBG_88E("-88eu_drv - drv_open, bup =%d\n", padapter->bup); ++ return 0; ++ ++netdev_open_error: ++ padapter->bup = false; ++ netif_carrier_off(pnetdev); ++ rtw_netif_stop_queue(pnetdev); ++ DBG_88E("-88eu_drv - drv_open fail, bup =%d\n", padapter->bup); ++ return -1; ++} ++ ++int netdev_open(struct net_device *pnetdev) ++{ ++ int ret; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); ++ ++ _enter_critical_mutex(padapter->hw_init_mutex, NULL); ++ ret = _netdev_open(pnetdev); ++ _exit_critical_mutex(padapter->hw_init_mutex, NULL); ++ return ret; ++} ++ ++static int ips_netdrv_open(struct adapter *padapter) ++{ ++ int status = _SUCCESS; ++ padapter->net_closed = false; ++ DBG_88E("===> %s.........\n", __func__); ++ ++ padapter->bDriverStopped = false; ++ padapter->bSurpriseRemoved = false; ++ padapter->bCardDisableWOHSM = false; ++ ++ status = rtw_hal_init(padapter); ++ if (status == _FAIL) ++ goto netdev_open_error; ++ ++ if (padapter->intf_start) ++ padapter->intf_start(padapter); ++ ++ rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); ++ _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 5000); ++ ++ return _SUCCESS; ++ ++netdev_open_error: ++ DBG_88E("-ips_netdrv_open - drv_open failure, bup =%d\n", padapter->bup); ++ ++ return _FAIL; ++} ++ ++int rtw_ips_pwr_up(struct adapter *padapter) ++{ ++ int result; ++ u32 start_time = jiffies; ++ DBG_88E("===> rtw_ips_pwr_up..............\n"); ++ rtw_reset_drv_sw(padapter); ++ ++ result = ips_netdrv_open(padapter); ++ ++ rtw_led_control(padapter, LED_CTL_NO_LINK); ++ ++ DBG_88E("<=== rtw_ips_pwr_up.............. in %dms\n", rtw_get_passing_time_ms(start_time)); ++ return result; ++} ++ ++void rtw_ips_pwr_down(struct adapter *padapter) ++{ ++ u32 start_time = jiffies; ++ DBG_88E("===> rtw_ips_pwr_down...................\n"); ++ ++ padapter->bCardDisableWOHSM = true; ++ padapter->net_closed = true; ++ ++ rtw_led_control(padapter, LED_CTL_POWER_OFF); ++ ++ rtw_ips_dev_unload(padapter); ++ padapter->bCardDisableWOHSM = false; ++ DBG_88E("<=== rtw_ips_pwr_down..................... in %dms\n", rtw_get_passing_time_ms(start_time)); ++} ++ ++void rtw_ips_dev_unload(struct adapter *padapter) ++{ ++ DBG_88E("====> %s...\n", __func__); ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_FIFO_CLEARN_UP, NULL); ++ ++ if (padapter->intf_stop) ++ padapter->intf_stop(padapter); ++ ++ /* s5. */ ++ if (!padapter->bSurpriseRemoved) ++ rtw_hal_deinit(padapter); ++} ++ ++int pm_netdev_open(struct net_device *pnetdev, u8 bnormal) ++{ ++ int status; ++ ++ if (bnormal) ++ status = netdev_open(pnetdev); ++ else ++ status = (_SUCCESS == ips_netdrv_open((struct adapter *)rtw_netdev_priv(pnetdev))) ? (0) : (-1); ++ return status; ++} ++ ++int netdev_close(struct net_device *pnetdev) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); ++ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); ++ ++ if (padapter->pwrctrlpriv.bInternalAutoSuspend) { ++ if (padapter->pwrctrlpriv.rf_pwrstate == rf_off) ++ padapter->pwrctrlpriv.ps_flag = true; ++ } ++ padapter->net_closed = true; ++ ++ if (padapter->pwrctrlpriv.rf_pwrstate == rf_on) { ++ DBG_88E("(2)88eu_drv - drv_close, bup =%d, hw_init_completed =%d\n", ++ padapter->bup, padapter->hw_init_completed); ++ ++ /* s1. */ ++ if (pnetdev) { ++ if (!rtw_netif_queue_stopped(pnetdev)) ++ rtw_netif_stop_queue(pnetdev); ++ } ++ ++ /* s2. */ ++ LeaveAllPowerSaveMode(padapter); ++ rtw_disassoc_cmd(padapter, 500, false); ++ /* s2-2. indicate disconnect to os */ ++ rtw_indicate_disconnect(padapter); ++ /* s2-3. */ ++ rtw_free_assoc_resources(padapter, 1); ++ /* s2-4. */ ++ rtw_free_network_queue(padapter, true); ++ /* Close LED */ ++ rtw_led_control(padapter, LED_CTL_POWER_OFF); ++ } ++ ++ nat25_db_cleanup(padapter); ++ ++#ifdef CONFIG_88EU_P2P ++ rtw_p2p_enable(padapter, P2P_ROLE_DISABLE); ++#endif /* CONFIG_88EU_P2P */ ++ ++ kfree(dvobj->firmware.szFwBuffer); ++ dvobj->firmware.szFwBuffer = NULL; ++ ++ DBG_88E("-88eu_drv - drv_close, bup =%d\n", padapter->bup); ++ return 0; ++} +diff --git a/drivers/staging/r8188eu/os_dep/osdep_service.c b/drivers/staging/r8188eu/os_dep/osdep_service.c +new file mode 100644 +index 000000000000..95ac6086370b +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/osdep_service.c +@@ -0,0 +1,343 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _OSDEP_SERVICE_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/rtw_ioctl_set.h" ++ ++/* ++* Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE ++* @return: one of RTW_STATUS_CODE ++*/ ++inline int RTW_STATUS_CODE(int error_code) ++{ ++ if (error_code >= 0) ++ return _SUCCESS; ++ return _FAIL; ++} ++ ++u32 rtw_atoi(u8 *s) ++{ ++ int num = 0, flag = 0; ++ int i; ++ for (i = 0; i <= strlen(s); i++) { ++ if (s[i] >= '0' && s[i] <= '9') ++ num = num * 10 + s[i] - '0'; ++ else if (s[0] == '-' && i == 0) ++ flag = 1; ++ else ++ break; ++ } ++ if (flag == 1) ++ num = num * -1; ++ return num; ++} ++ ++void *rtw_malloc2d(int h, int w, int size) ++{ ++ int j; ++ ++ void **a = kzalloc(h * sizeof(void *) + h * w * size, GFP_KERNEL); ++ if (!a) ++ return NULL; ++ ++ for (j = 0; j < h; j++) ++ a[j] = ((char *)(a + h)) + j * w * size; ++ ++ return a; ++} ++ ++/* ++For the following list_xxx operations, ++caller must guarantee the atomic context. ++Otherwise, there will be racing condition. ++*/ ++/* ++Caller must check if the list is empty before calling rtw_list_delete ++*/ ++ ++u32 _rtw_down_sema(struct semaphore *sema) ++{ ++ if (down_interruptible(sema)) ++ return _FAIL; ++ else ++ return _SUCCESS; ++} ++ ++void _rtw_mutex_init(struct mutex *pmutex) ++{ ++ mutex_init(pmutex); ++} ++ ++void _rtw_mutex_free(struct mutex *pmutex) ++{ ++ mutex_destroy(pmutex); ++} ++ ++void _rtw_init_queue(struct __queue *pqueue) ++{ ++ INIT_LIST_HEAD(&pqueue->queue); ++ spin_lock_init(&pqueue->lock); ++} ++ ++inline u32 rtw_systime_to_ms(u32 systime) ++{ ++ return systime * 1000 / HZ; ++} ++ ++inline u32 rtw_ms_to_systime(u32 ms) ++{ ++ return ms * HZ / 1000; ++} ++ ++/* the input parameter start use the same unit as jiffies */ ++inline s32 rtw_get_passing_time_ms(u32 start) ++{ ++ return rtw_systime_to_ms(jiffies - start); ++} ++ ++void rtw_usleep_os(int us) ++{ ++ if (1 < (us / 1000)) ++ msleep(1); ++ else ++ msleep((us / 1000) + 1); ++} ++ ++#define RTW_SUSPEND_LOCK_NAME "rtw_wifi" ++ ++static const struct device_type wlan_type = { ++ .name = "wlan", ++}; ++ ++struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, ++ void *old_priv) ++{ ++ struct net_device *pnetdev; ++ struct rtw_netdev_priv_indicator *pnpi; ++ ++ pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4); ++ if (!pnetdev) ++ goto RETURN; ++ ++ pnetdev->dev.type = &wlan_type; ++ pnpi = netdev_priv(pnetdev); ++ pnpi->priv = old_priv; ++ pnpi->sizeof_priv = sizeof_priv; ++ ++RETURN: ++ return pnetdev; ++} ++ ++struct net_device *rtw_alloc_etherdev(int sizeof_priv) ++{ ++ struct net_device *pnetdev; ++ struct rtw_netdev_priv_indicator *pnpi; ++ ++ pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4); ++ if (!pnetdev) ++ goto RETURN; ++ ++ pnpi = netdev_priv(pnetdev); ++ ++ pnpi->priv = vzalloc(sizeof_priv); ++ if (!pnpi->priv) { ++ free_netdev(pnetdev); ++ pnetdev = NULL; ++ goto RETURN; ++ } ++ ++ pnpi->sizeof_priv = sizeof_priv; ++RETURN: ++ return pnetdev; ++} ++ ++void rtw_free_netdev(struct net_device *netdev) ++{ ++ struct rtw_netdev_priv_indicator *pnpi; ++ ++ if (!netdev) ++ goto RETURN; ++ ++ pnpi = netdev_priv(netdev); ++ ++ if (!pnpi->priv) ++ goto RETURN; ++ ++ vfree(pnpi->priv); ++ free_netdev(netdev); ++ ++RETURN: ++ return; ++} ++ ++int rtw_change_ifname(struct adapter *padapter, const char *ifname) ++{ ++ struct net_device *pnetdev; ++ struct net_device *cur_pnetdev; ++ struct rereg_nd_name_data *rereg_priv; ++ int ret; ++ ++ if (!padapter) ++ goto error; ++ ++ cur_pnetdev = padapter->pnetdev; ++ rereg_priv = &padapter->rereg_nd_name_priv; ++ ++ /* free the old_pnetdev */ ++ if (rereg_priv->old_pnetdev) { ++ free_netdev(rereg_priv->old_pnetdev); ++ rereg_priv->old_pnetdev = NULL; ++ } ++ ++ if (!rtnl_is_locked()) ++ unregister_netdev(cur_pnetdev); ++ else ++ unregister_netdevice(cur_pnetdev); ++ ++ rtw_proc_remove_one(cur_pnetdev); ++ ++ rereg_priv->old_pnetdev = cur_pnetdev; ++ ++ pnetdev = rtw_init_netdev(padapter); ++ if (!pnetdev) { ++ ret = -1; ++ goto error; ++ } ++ ++ SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter))); ++ ++ rtw_init_netdev_name(pnetdev, ifname); ++ ++ memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); ++ ++ if (!rtnl_is_locked()) ++ ret = register_netdev(pnetdev); ++ else ++ ret = register_netdevice(pnetdev); ++ if (ret != 0) ++ goto error; ++ ++ rtw_proc_init_one(pnetdev); ++ return 0; ++error: ++ return -1; ++} ++ ++void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len) ++{ ++ u32 dup_len = 0; ++ u8 *ori = NULL; ++ u8 *dup = NULL; ++ ++ if (!buf || !buf_len) ++ return; ++ ++ if (!src || !src_len) ++ goto keep_ori; ++ ++ /* duplicate src */ ++ dup = kmalloc(src_len, GFP_ATOMIC); ++ if (dup) { ++ dup_len = src_len; ++ memcpy(dup, src, dup_len); ++ } ++ ++keep_ori: ++ ori = *buf; ++ ++ /* replace buf with dup */ ++ *buf_len = 0; ++ *buf = dup; ++ *buf_len = dup_len; ++ ++ /* free ori */ ++ kfree(ori); ++} ++ ++/** ++ * rtw_cbuf_full - test if cbuf is full ++ * @cbuf: pointer of struct rtw_cbuf ++ * ++ * Returns: true if cbuf is full ++ */ ++inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf) ++{ ++ return (cbuf->write == cbuf->read - 1) ? true : false; ++} ++ ++/** ++ * rtw_cbuf_empty - test if cbuf is empty ++ * @cbuf: pointer of struct rtw_cbuf ++ * ++ * Returns: true if cbuf is empty ++ */ ++inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf) ++{ ++ return (cbuf->write == cbuf->read) ? true : false; ++} ++ ++/** ++ * rtw_cbuf_push - push a pointer into cbuf ++ * @cbuf: pointer of struct rtw_cbuf ++ * @buf: pointer to push in ++ * ++ * Lock free operation, be careful of the use scheme ++ * Returns: true push success ++ */ ++bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf) ++{ ++ if (rtw_cbuf_full(cbuf)) ++ return _FAIL; ++ ++ if (0) ++ DBG_88E("%s on %u\n", __func__, cbuf->write); ++ cbuf->bufs[cbuf->write] = buf; ++ cbuf->write = (cbuf->write + 1) % cbuf->size; ++ ++ return _SUCCESS; ++} ++ ++/** ++ * rtw_cbuf_pop - pop a pointer from cbuf ++ * @cbuf: pointer of struct rtw_cbuf ++ * ++ * Lock free operation, be careful of the use scheme ++ * Returns: pointer popped out ++ */ ++void *rtw_cbuf_pop(struct rtw_cbuf *cbuf) ++{ ++ void *buf; ++ if (rtw_cbuf_empty(cbuf)) ++ return NULL; ++ ++ if (0) ++ DBG_88E("%s on %u\n", __func__, cbuf->read); ++ buf = cbuf->bufs[cbuf->read]; ++ cbuf->read = (cbuf->read + 1) % cbuf->size; ++ ++ return buf; ++} ++ ++/** ++ * rtw_cbuf_alloc - allocate a rtw_cbuf with given size and do initialization ++ * @size: size of pointer ++ * ++ * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure ++ */ ++struct rtw_cbuf *rtw_cbuf_alloc(u32 size) ++{ ++ struct rtw_cbuf *cbuf; ++ ++ cbuf = kmalloc(sizeof(*cbuf) + sizeof(void *) * size, GFP_KERNEL); ++ ++ if (cbuf) { ++ cbuf->write = 0; ++ cbuf->read = 0; ++ cbuf->size = size; ++ } ++ return cbuf; ++} +diff --git a/drivers/staging/r8188eu/os_dep/recv_linux.c b/drivers/staging/r8188eu/os_dep/recv_linux.c +new file mode 100644 +index 000000000000..917a63e3e94c +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/recv_linux.c +@@ -0,0 +1,214 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RECV_OSDEP_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++ ++#include "../include/wifi.h" ++#include "../include/recv_osdep.h" ++ ++#include "../include/osdep_intf.h" ++#include "../include/usb_ops.h" ++ ++/* init os related resource in struct recv_priv */ ++int rtw_os_recv_resource_init(struct recv_priv *precvpriv, ++ struct adapter *padapter) ++{ ++ return _SUCCESS; ++} ++ ++/* alloc os related resource in struct recv_frame */ ++int rtw_os_recv_resource_alloc(struct adapter *padapter, ++ struct recv_frame *precvframe) ++{ ++ precvframe->pkt_newalloc = NULL; ++ precvframe->pkt = NULL; ++ return _SUCCESS; ++} ++ ++/* free os related resource in struct recv_frame */ ++void rtw_os_recv_resource_free(struct recv_priv *precvpriv) ++{ ++} ++ ++/* alloc os related resource in struct recv_buf */ ++int rtw_os_recvbuf_resource_alloc(struct adapter *padapter, ++ struct recv_buf *precvbuf) ++{ ++ int res = _SUCCESS; ++ ++ precvbuf->irp_pending = false; ++ precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!precvbuf->purb) ++ res = _FAIL; ++ precvbuf->pskb = NULL; ++ precvbuf->reuse = false; ++ precvbuf->pallocated_buf = NULL; ++ precvbuf->pbuf = NULL; ++ precvbuf->pdata = NULL; ++ precvbuf->phead = NULL; ++ precvbuf->ptail = NULL; ++ precvbuf->pend = NULL; ++ precvbuf->transfer_len = 0; ++ precvbuf->len = 0; ++ return res; ++} ++ ++/* free os related resource in struct recv_buf */ ++int rtw_os_recvbuf_resource_free(struct adapter *padapter, ++ struct recv_buf *precvbuf) ++{ ++ usb_free_urb(precvbuf->purb); ++ return _SUCCESS; ++} ++ ++void rtw_handle_tkip_mic_err(struct adapter *padapter, u8 bgroup) ++{ ++ union iwreq_data wrqu; ++ struct iw_michaelmicfailure ev; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ u32 cur_time = 0; ++ ++ if (psecuritypriv->last_mic_err_time == 0) { ++ psecuritypriv->last_mic_err_time = jiffies; ++ } else { ++ cur_time = jiffies; ++ ++ if (cur_time - psecuritypriv->last_mic_err_time < 60 * HZ) { ++ psecuritypriv->btkip_countermeasure = true; ++ psecuritypriv->last_mic_err_time = 0; ++ psecuritypriv->btkip_countermeasure_time = cur_time; ++ } else { ++ psecuritypriv->last_mic_err_time = jiffies; ++ } ++ } ++ ++ memset(&ev, 0x00, sizeof(ev)); ++ if (bgroup) ++ ev.flags |= IW_MICFAILURE_GROUP; ++ else ++ ev.flags |= IW_MICFAILURE_PAIRWISE; ++ ++ ev.src_addr.sa_family = ARPHRD_ETHER; ++ memcpy(ev.src_addr.sa_data, &pmlmepriv->assoc_bssid[0], ETH_ALEN); ++ memset(&wrqu, 0x00, sizeof(wrqu)); ++ wrqu.data.length = sizeof(ev); ++ wireless_send_event(padapter->pnetdev, IWEVMICHAELMICFAILURE, ++ &wrqu, (char *)&ev); ++} ++ ++void rtw_hostapd_mlme_rx(struct adapter *padapter, ++ struct recv_frame *precv_frame) ++{ ++} ++ ++int rtw_recv_indicatepkt(struct adapter *padapter, ++ struct recv_frame *precv_frame) ++{ ++ struct recv_priv *precvpriv; ++ struct __queue *pfree_recv_queue; ++ struct sk_buff *skb; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ precvpriv = &padapter->recvpriv; ++ pfree_recv_queue = &precvpriv->free_recv_queue; ++ ++ skb = precv_frame->pkt; ++ if (!skb) ++ goto _recv_indicatepkt_drop; ++ ++ skb->data = precv_frame->rx_data; ++ ++ skb_set_tail_pointer(skb, precv_frame->len); ++ ++ skb->len = precv_frame->len; ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ struct sk_buff *pskb2 = NULL; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ bool bmcast = is_multicast_ether_addr(pattrib->dst); ++ ++ if (memcmp(pattrib->dst, myid(&padapter->eeprompriv), ++ ETH_ALEN)) { ++ if (bmcast) { ++ psta = rtw_get_bcmc_stainfo(padapter); ++ pskb2 = skb_clone(skb, GFP_ATOMIC); ++ } else { ++ psta = rtw_get_stainfo(pstapriv, pattrib->dst); ++ } ++ ++ if (psta) { ++ struct net_device *pnetdev; ++ ++ pnetdev = (struct net_device *)padapter->pnetdev; ++ skb->dev = pnetdev; ++ skb_set_queue_mapping(skb, rtw_recv_select_queue(skb)); ++ ++ rtw_xmit_entry(skb, pnetdev); ++ ++ if (bmcast) ++ skb = pskb2; ++ else ++ goto _recv_indicatepkt_end; ++ } ++ } ++ } ++ ++ rcu_read_lock(); ++ rcu_dereference(padapter->pnetdev->rx_handler_data); ++ rcu_read_unlock(); ++ ++ skb->ip_summed = CHECKSUM_NONE; ++ skb->dev = padapter->pnetdev; ++ skb->protocol = eth_type_trans(skb, padapter->pnetdev); ++ ++ netif_rx(skb); ++ ++_recv_indicatepkt_end: ++ ++ /* pointers to NULL before rtw_free_recvframe() */ ++ precv_frame->pkt = NULL; ++ ++ rtw_free_recvframe(precv_frame, pfree_recv_queue); ++ ++ return _SUCCESS; ++ ++_recv_indicatepkt_drop: ++ ++ /* enqueue back to free_recv_queue */ ++ rtw_free_recvframe(precv_frame, pfree_recv_queue); ++ ++ return _FAIL; ++} ++ ++void rtw_os_read_port(struct adapter *padapter, struct recv_buf *precvbuf) ++{ ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ ++ precvbuf->ref_cnt--; ++ /* free skb in recv_buf */ ++ dev_kfree_skb_any(precvbuf->pskb); ++ precvbuf->pskb = NULL; ++ precvbuf->reuse = false; ++ if (!precvbuf->irp_pending) ++ rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, ++ (unsigned char *)precvbuf); ++} ++ ++static void _rtw_reordering_ctrl_timeout_handler(struct timer_list *t) ++{ ++ struct recv_reorder_ctrl *preorder_ctrl; ++ ++ preorder_ctrl = from_timer(preorder_ctrl, t, reordering_ctrl_timer); ++ rtw_reordering_ctrl_timeout_handler(preorder_ctrl); ++} ++ ++void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl) ++{ ++ timer_setup(&preorder_ctrl->reordering_ctrl_timer, _rtw_reordering_ctrl_timeout_handler, 0); ++} +diff --git a/drivers/staging/r8188eu/os_dep/usb_intf.c b/drivers/staging/r8188eu/os_dep/usb_intf.c +new file mode 100644 +index 000000000000..bb85ab77fd26 +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/usb_intf.c +@@ -0,0 +1,781 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _HCI_INTF_C_ ++ ++#include ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/xmit_osdep.h" ++#include "../include/hal_intf.h" ++#include "../include/osdep_intf.h" ++#include "../include/usb_vendor_req.h" ++#include "../include/usb_ops.h" ++#include "../include/usb_osintf.h" ++#include "../include/rtw_ioctl.h" ++ ++int ui_pid[3] = {0, 0, 0}; ++ ++static int rtw_suspend(struct usb_interface *intf, pm_message_t message); ++static int rtw_resume(struct usb_interface *intf); ++ ++static int rtw_drv_init(struct usb_interface *pusb_intf, const struct usb_device_id *pdid); ++static void rtw_dev_remove(struct usb_interface *pusb_intf); ++ ++#define USB_VENDER_ID_REALTEK 0x0bda ++ ++/* DID_USB_v916_20130116 */ ++static struct usb_device_id rtw_usb_id_tbl[] = { ++ /*=== Realtek demoboard ===*/ ++ {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8179)}, /* 8188EUS */ ++ {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0179)}, /* 8188ETV */ ++ {USB_DEVICE(USB_VENDER_ID_REALTEK, 0xf179)}, /* 8188FU */ ++ /*=== Customer ID ===*/ ++ /****** 8188EUS ********/ ++ {USB_DEVICE(0x07B8, 0x8179)}, /* Abocom - Abocom */ ++ {USB_DEVICE(0x0DF6, 0x0076)}, /* Sitecom N150 v2 */ ++ {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */ ++ {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */ ++ {USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */ ++ {USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */ ++ {USB_DEVICE(0x056E, 0x4008)}, /* Elecom WDC-150SU2M */ ++ {USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */ ++ {USB_DEVICE(0x2357, 0x0111)}, /* TP-Link TL-WN727N v5.21 */ ++ {USB_DEVICE(0x2C4E, 0x0102)}, /* MERCUSYS MW150US v2 */ ++ {USB_DEVICE(0x0B05, 0x18F0)}, /* ASUS USB-N10 Nano B1 */ ++ {USB_DEVICE(0x7392, 0xb811)}, /* Edimax EW-7811Un V2 */ ++ {} /* Terminating entry */ ++}; ++ ++MODULE_DEVICE_TABLE(usb, rtw_usb_id_tbl); ++ ++static struct specific_device_id specific_device_id_tbl[] = { ++ {} /* empty table for now */ ++}; ++ ++struct rtw_usb_drv { ++ struct usb_driver usbdrv; ++ int drv_registered; ++ struct mutex hw_init_mutex; ++}; ++ ++static struct rtw_usb_drv rtl8188e_usb_drv = { ++ .usbdrv.name = "r8188eu", ++ .usbdrv.probe = rtw_drv_init, ++ .usbdrv.disconnect = rtw_dev_remove, ++ .usbdrv.id_table = rtw_usb_id_tbl, ++ .usbdrv.suspend = rtw_suspend, ++ .usbdrv.resume = rtw_resume, ++ .usbdrv.reset_resume = rtw_resume, ++}; ++ ++static struct rtw_usb_drv *usb_drv = &rtl8188e_usb_drv; ++ ++static inline int RT_usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd) ++{ ++ return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN; ++} ++ ++static inline int RT_usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd) ++{ ++ return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT; ++} ++ ++static inline int RT_usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd) ++{ ++ return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT; ++} ++ ++static inline int RT_usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd) ++{ ++ return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK; ++} ++ ++static inline int RT_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd) ++{ ++ return RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_in(epd); ++} ++ ++static inline int RT_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd) ++{ ++ return RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_out(epd); ++} ++ ++static inline int usb_endpoint_is_int(const struct usb_endpoint_descriptor *epd) ++{ ++ return RT_usb_endpoint_xfer_int(epd) && RT_usb_endpoint_dir_in(epd); ++} ++ ++static inline int RT_usb_endpoint_num(const struct usb_endpoint_descriptor *epd) ++{ ++ return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; ++} ++ ++static u8 rtw_init_intf_priv(struct dvobj_priv *dvobj) ++{ ++ u8 rst = _SUCCESS; ++ ++ _rtw_mutex_init(&dvobj->usb_vendor_req_mutex); ++ ++ dvobj->usb_alloc_vendor_req_buf = kzalloc(MAX_USB_IO_CTL_SIZE, GFP_KERNEL); ++ if (!dvobj->usb_alloc_vendor_req_buf) { ++ DBG_88E("alloc usb_vendor_req_buf failed... /n"); ++ rst = _FAIL; ++ goto exit; ++ } ++ dvobj->usb_vendor_req_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(dvobj->usb_alloc_vendor_req_buf), ALIGNMENT_UNIT); ++exit: ++ return rst; ++} ++ ++static void rtw_deinit_intf_priv(struct dvobj_priv *dvobj) ++{ ++ kfree(dvobj->usb_alloc_vendor_req_buf); ++ _rtw_mutex_free(&dvobj->usb_vendor_req_mutex); ++} ++ ++static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf) ++{ ++ int i; ++ int status = _FAIL; ++ struct dvobj_priv *pdvobjpriv; ++ struct usb_host_config *phost_conf; ++ struct usb_config_descriptor *pconf_desc; ++ struct usb_host_interface *phost_iface; ++ struct usb_interface_descriptor *piface_desc; ++ struct usb_endpoint_descriptor *pendp_desc; ++ struct usb_device *pusbd; ++ ++ pdvobjpriv = kzalloc(sizeof(*pdvobjpriv), GFP_KERNEL); ++ if (!pdvobjpriv) ++ goto exit; ++ ++ pdvobjpriv->pusbintf = usb_intf; ++ pusbd = interface_to_usbdev(usb_intf); ++ pdvobjpriv->pusbdev = pusbd; ++ usb_set_intfdata(usb_intf, pdvobjpriv); ++ ++ pdvobjpriv->RtNumInPipes = 0; ++ pdvobjpriv->RtNumOutPipes = 0; ++ ++ phost_conf = pusbd->actconfig; ++ pconf_desc = &phost_conf->desc; ++ ++ phost_iface = &usb_intf->altsetting[0]; ++ piface_desc = &phost_iface->desc; ++ ++ pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces; ++ pdvobjpriv->InterfaceNumber = piface_desc->bInterfaceNumber; ++ pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints; ++ ++ for (i = 0; i < pdvobjpriv->nr_endpoint; i++) { ++ int ep_num; ++ pendp_desc = &phost_iface->endpoint[i].desc; ++ ++ ep_num = usb_endpoint_num(pendp_desc); ++ ++ if (usb_endpoint_is_bulk_in(pendp_desc)) { ++ pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = ep_num; ++ pdvobjpriv->RtNumInPipes++; ++ } else if (usb_endpoint_is_int_in(pendp_desc)) { ++ pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = ep_num; ++ pdvobjpriv->RtNumInPipes++; ++ } else if (usb_endpoint_is_bulk_out(pendp_desc)) { ++ pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] = ++ ep_num; ++ pdvobjpriv->RtNumOutPipes++; ++ } ++ pdvobjpriv->ep_num[i] = ep_num; ++ } ++ ++ if (pusbd->speed == USB_SPEED_HIGH) { ++ pdvobjpriv->ishighspeed = true; ++ DBG_88E("USB_SPEED_HIGH\n"); ++ } else { ++ pdvobjpriv->ishighspeed = false; ++ DBG_88E("NON USB_SPEED_HIGH\n"); ++ } ++ ++ if (rtw_init_intf_priv(pdvobjpriv) == _FAIL) ++ goto free_dvobj; ++ ++ /* 3 misc */ ++ sema_init(&pdvobjpriv->usb_suspend_sema, 0); ++ rtw_reset_continual_urb_error(pdvobjpriv); ++ ++ usb_get_dev(pusbd); ++ ++ status = _SUCCESS; ++ ++free_dvobj: ++ if (status != _SUCCESS && pdvobjpriv) { ++ usb_set_intfdata(usb_intf, NULL); ++ kfree(pdvobjpriv); ++ pdvobjpriv = NULL; ++ } ++exit: ++ return pdvobjpriv; ++} ++ ++static void usb_dvobj_deinit(struct usb_interface *usb_intf) ++{ ++ struct dvobj_priv *dvobj = usb_get_intfdata(usb_intf); ++ ++ usb_set_intfdata(usb_intf, NULL); ++ if (dvobj) { ++ /* Modify condition for 92DU DMDP 2010.11.18, by Thomas */ ++ if ((dvobj->NumInterfaces != 2 && ++ dvobj->NumInterfaces != 3) || ++ (dvobj->InterfaceNumber == 1)) { ++ if (interface_to_usbdev(usb_intf)->state != ++ USB_STATE_NOTATTACHED) { ++ /* If we didn't unplug usb dongle and ++ * remove/insert module, driver fails ++ * on sitesurvey for the first time when ++ * device is up . Reset usb port for sitesurvey ++ * fail issue. */ ++ DBG_88E("usb attached..., try to reset usb device\n"); ++ usb_reset_device(interface_to_usbdev(usb_intf)); ++ } ++ } ++ rtw_deinit_intf_priv(dvobj); ++ kfree(dvobj); ++ } ++ ++ usb_put_dev(interface_to_usbdev(usb_intf)); ++ ++} ++ ++static void chip_by_usb_id(struct adapter *padapter) ++{ ++ padapter->chip_type = NULL_CHIP_TYPE; ++ hal_set_hw_type(padapter); ++} ++ ++static void usb_intf_start(struct adapter *padapter) ++{ ++ rtw_hal_inirp_init(padapter); ++} ++ ++static void usb_intf_stop(struct adapter *padapter) ++{ ++ /* cancel in irp */ ++ rtw_hal_inirp_deinit(padapter); ++ ++ /* cancel out irp */ ++ rtw_write_port_cancel(padapter); ++ ++ /* todo:cancel other irps */ ++} ++ ++static void rtw_dev_unload(struct adapter *padapter) ++{ ++ if (padapter->bup) { ++ DBG_88E("===> rtw_dev_unload\n"); ++ padapter->bDriverStopped = true; ++ if (padapter->xmitpriv.ack_tx) ++ rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP); ++ /* s3. */ ++ if (padapter->intf_stop) ++ padapter->intf_stop(padapter); ++ /* s4. */ ++ if (!padapter->pwrctrlpriv.bInternalAutoSuspend) ++ rtw_stop_drv_threads(padapter); ++ ++ /* s5. */ ++ if (!padapter->bSurpriseRemoved) { ++ rtw_hal_deinit(padapter); ++ padapter->bSurpriseRemoved = true; ++ } ++ ++ padapter->bup = false; ++ } ++ ++ DBG_88E("<=== rtw_dev_unload\n"); ++} ++ ++static void process_spec_devid(const struct usb_device_id *pdid) ++{ ++ u16 vid, pid; ++ u32 flags; ++ int i; ++ int num = sizeof(specific_device_id_tbl) / ++ sizeof(struct specific_device_id); ++ ++ for (i = 0; i < num; i++) { ++ vid = specific_device_id_tbl[i].idVendor; ++ pid = specific_device_id_tbl[i].idProduct; ++ flags = specific_device_id_tbl[i].flags; ++ ++ if ((pdid->idVendor == vid) && (pdid->idProduct == pid) && ++ (flags & SPEC_DEV_ID_DISABLE_HT)) { ++ rtw_ht_enable = 0; ++ rtw_cbw40_enable = 0; ++ rtw_ampdu_enable = 0; ++ } ++ } ++} ++ ++int rtw_hw_suspend(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct net_device *pnetdev = padapter->pnetdev; ++ ++ ++ if (!padapter) ++ goto error_exit; ++ if ((!padapter->bup) || (padapter->bDriverStopped) || ++ (padapter->bSurpriseRemoved)) { ++ DBG_88E("padapter->bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n", ++ padapter->bup, padapter->bDriverStopped, ++ padapter->bSurpriseRemoved); ++ goto error_exit; ++ } ++ ++ LeaveAllPowerSaveMode(padapter); ++ ++ DBG_88E("==> rtw_hw_suspend\n"); ++ _enter_pwrlock(&pwrpriv->lock); ++ pwrpriv->bips_processing = true; ++ /* s1. */ ++ if (pnetdev) { ++ netif_carrier_off(pnetdev); ++ rtw_netif_stop_queue(pnetdev); ++ } ++ ++ /* s2. */ ++ rtw_disassoc_cmd(padapter, 500, false); ++ ++ /* s2-2. indicate disconnect to os */ ++ { ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ _clr_fwstate_(pmlmepriv, _FW_LINKED); ++ ++ rtw_led_control(padapter, LED_CTL_NO_LINK); ++ ++ rtw_os_indicate_disconnect(padapter); ++ ++ /* donnot enqueue cmd */ ++ rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 0); ++ } ++ } ++ /* s2-3. */ ++ rtw_free_assoc_resources(padapter, 1); ++ ++ /* s2-4. */ ++ rtw_free_network_queue(padapter, true); ++ rtw_ips_dev_unload(padapter); ++ pwrpriv->rf_pwrstate = rf_off; ++ pwrpriv->bips_processing = false; ++ ++ _exit_pwrlock(&pwrpriv->lock); ++ return 0; ++ ++error_exit: ++ DBG_88E("%s, failed\n", __func__); ++ return -1; ++} ++ ++int rtw_hw_resume(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrpriv; ++ struct net_device *pnetdev = padapter->pnetdev; ++ ++ if (!padapter) ++ goto error_exit; ++ pwrpriv = &padapter->pwrctrlpriv; ++ DBG_88E("==> rtw_hw_resume\n"); ++ _enter_pwrlock(&pwrpriv->lock); ++ pwrpriv->bips_processing = true; ++ rtw_reset_drv_sw(padapter); ++ ++ if (pm_netdev_open(pnetdev, false) != 0) { ++ _exit_pwrlock(&pwrpriv->lock); ++ goto error_exit; ++ } ++ ++ netif_device_attach(pnetdev); ++ netif_carrier_on(pnetdev); ++ ++ if (!netif_queue_stopped(pnetdev)) ++ netif_start_queue(pnetdev); ++ else ++ netif_wake_queue(pnetdev); ++ ++ pwrpriv->bkeepfwalive = false; ++ pwrpriv->brfoffbyhw = false; ++ ++ pwrpriv->rf_pwrstate = rf_on; ++ pwrpriv->bips_processing = false; ++ ++ _exit_pwrlock(&pwrpriv->lock); ++ ++ return 0; ++error_exit: ++ DBG_88E("%s, Open net dev failed\n", __func__); ++ return -1; ++} ++ ++static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) ++{ ++ struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); ++ struct adapter *padapter = dvobj->if1; ++ struct net_device *pnetdev = padapter->pnetdev; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ ++ int ret = 0; ++ u32 start_time = jiffies; ++ ++ ++ DBG_88E("==> %s (%s:%d)\n", __func__, current->comm, current->pid); ++ ++ if ((!padapter->bup) || (padapter->bDriverStopped) || ++ (padapter->bSurpriseRemoved)) { ++ DBG_88E("padapter->bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n", ++ padapter->bup, padapter->bDriverStopped, ++ padapter->bSurpriseRemoved); ++ goto exit; ++ } ++ ++ pwrpriv->bInSuspend = true; ++ rtw_cancel_all_timer(padapter); ++ LeaveAllPowerSaveMode(padapter); ++ ++ _enter_pwrlock(&pwrpriv->lock); ++ /* s1. */ ++ if (pnetdev) { ++ netif_carrier_off(pnetdev); ++ rtw_netif_stop_queue(pnetdev); ++ } ++ ++ /* s2. */ ++ rtw_disassoc_cmd(padapter, 0, false); ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && ++ check_fwstate(pmlmepriv, _FW_LINKED)) { ++ DBG_88E("%s:%d %s(%pM), length:%d assoc_ssid.length:%d\n", ++ __func__, __LINE__, ++ pmlmepriv->cur_network.network.Ssid.Ssid, ++ pmlmepriv->cur_network.network.MacAddress, ++ pmlmepriv->cur_network.network.Ssid.SsidLength, ++ pmlmepriv->assoc_ssid.SsidLength); ++ ++ pmlmepriv->to_roaming = 1; ++ } ++ /* s2-2. indicate disconnect to os */ ++ rtw_indicate_disconnect(padapter); ++ /* s2-3. */ ++ rtw_free_assoc_resources(padapter, 1); ++ /* s2-4. */ ++ rtw_free_network_queue(padapter, true); ++ ++ rtw_dev_unload(padapter); ++ _exit_pwrlock(&pwrpriv->lock); ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) ++ rtw_indicate_scan_done(padapter, 1); ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) ++ rtw_indicate_disconnect(padapter); ++ ++exit: ++ DBG_88E("<=== %s return %d.............. in %dms\n", __func__ ++ , ret, rtw_get_passing_time_ms(start_time)); ++ ++ return ret; ++} ++ ++static int rtw_resume(struct usb_interface *pusb_intf) ++{ ++ struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); ++ struct adapter *padapter = dvobj->if1; ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ int ret = 0; ++ ++ if (pwrpriv->bInternalAutoSuspend) ++ ret = rtw_resume_process(padapter); ++ else ++ ret = rtw_resume_process(padapter); ++ return ret; ++} ++ ++int rtw_resume_process(struct adapter *padapter) ++{ ++ struct net_device *pnetdev; ++ struct pwrctrl_priv *pwrpriv = NULL; ++ int ret = -1; ++ u32 start_time = jiffies; ++ ++ DBG_88E("==> %s (%s:%d)\n", __func__, current->comm, current->pid); ++ ++ if (padapter) { ++ pnetdev = padapter->pnetdev; ++ pwrpriv = &padapter->pwrctrlpriv; ++ } else { ++ goto exit; ++ } ++ ++ _enter_pwrlock(&pwrpriv->lock); ++ rtw_reset_drv_sw(padapter); ++ if (pwrpriv) ++ pwrpriv->bkeepfwalive = false; ++ ++ DBG_88E("bkeepfwalive(%x)\n", pwrpriv->bkeepfwalive); ++ if (pm_netdev_open(pnetdev, true) != 0) ++ goto exit; ++ ++ netif_device_attach(pnetdev); ++ netif_carrier_on(pnetdev); ++ ++ _exit_pwrlock(&pwrpriv->lock); ++ ++ if (padapter->pid[1] != 0) { ++ DBG_88E("pid[1]:%d\n", padapter->pid[1]); ++ rtw_signal_process(padapter->pid[1], SIGUSR2); ++ } ++ ++ rtw_roaming(padapter, NULL); ++ ++ ret = 0; ++exit: ++ if (pwrpriv) ++ pwrpriv->bInSuspend = false; ++ DBG_88E("<=== %s return %d.............. in %dms\n", __func__, ++ ret, rtw_get_passing_time_ms(start_time)); ++ ++ ++ return ret; ++} ++ ++/* ++ * drv_init() - a device potentially for us ++ * ++ * notes: drv_init() is called when the bus driver has located ++ * a card for us to support. ++ * We accept the new device by returning 0. ++ */ ++ ++static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj, ++ struct usb_interface *pusb_intf) ++{ ++ struct adapter *padapter = NULL; ++ struct net_device *pnetdev = NULL; ++ int status = _FAIL; ++ ++ padapter = vzalloc(sizeof(*padapter)); ++ if (!padapter) ++ goto exit; ++ padapter->dvobj = dvobj; ++ dvobj->if1 = padapter; ++ ++ padapter->bDriverStopped = true; ++ ++ padapter->hw_init_mutex = &usb_drv->hw_init_mutex; ++ ++ /* step 1-1., decide the chip_type via vid/pid */ ++ padapter->interface_type = RTW_USB; ++ chip_by_usb_id(padapter); ++ ++ if (rtw_handle_dualmac(padapter, 1) != _SUCCESS) ++ goto free_adapter; ++ ++ pnetdev = rtw_init_netdev(padapter); ++ if (!pnetdev) ++ goto handle_dualmac; ++ SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj)); ++ padapter = rtw_netdev_priv(pnetdev); ++ ++ /* step 2. hook HalFunc, allocate HalData */ ++ rtl8188eu_set_hal_ops(padapter); ++ ++ padapter->intf_start = &usb_intf_start; ++ padapter->intf_stop = &usb_intf_stop; ++ ++ /* step init_io_priv */ ++ rtw_init_io_priv(padapter, usb_set_intf_ops); ++ ++ /* step read_chip_version */ ++ rtw_hal_read_chip_version(padapter); ++ ++ /* step usb endpoint mapping */ ++ rtw_hal_chip_configure(padapter); ++ ++ /* step read efuse/eeprom data and get mac_addr */ ++ rtw_hal_read_chip_info(padapter); ++ ++ /* step 5. */ ++ if (rtw_init_drv_sw(padapter) == _FAIL) ++ goto free_hal_data; ++ ++#ifdef CONFIG_PM ++ if (padapter->pwrctrlpriv.bSupportRemoteWakeup) { ++ dvobj->pusbdev->do_remote_wakeup = 1; ++ pusb_intf->needs_remote_wakeup = 1; ++ device_init_wakeup(&pusb_intf->dev, 1); ++ DBG_88E("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~[%d]~~~\n", ++ device_may_wakeup(&pusb_intf->dev)); ++ } ++#endif ++ ++ /* 2012-07-11 Move here to prevent the 8723AS-VAU BT auto ++ * suspend influence */ ++ if (usb_autopm_get_interface(pusb_intf) < 0) ++ DBG_88E("can't get autopm:\n"); ++ ++ /* alloc dev name after read efuse. */ ++ rtw_init_netdev_name(pnetdev, padapter->registrypriv.ifname); ++ rtw_macaddr_cfg(padapter->eeprompriv.mac_addr); ++#ifdef CONFIG_88EU_P2P ++ rtw_init_wifidirect_addrs(padapter, padapter->eeprompriv.mac_addr, ++ padapter->eeprompriv.mac_addr); ++#endif ++ memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); ++ DBG_88E("MAC Address from pnetdev->dev_addr = %pM\n", ++ pnetdev->dev_addr); ++ ++ /* step 6. Tell the network stack we exist */ ++ if (register_netdev(pnetdev) != 0) ++ goto free_hal_data; ++ ++ DBG_88E("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n" ++ , padapter->bDriverStopped ++ , padapter->bSurpriseRemoved ++ , padapter->bup ++ , padapter->hw_init_completed ++ ); ++ ++ status = _SUCCESS; ++ ++free_hal_data: ++ if (status != _SUCCESS) ++ kfree(padapter->HalData); ++handle_dualmac: ++ if (status != _SUCCESS) ++ rtw_handle_dualmac(padapter, 0); ++free_adapter: ++ if (status != _SUCCESS) { ++ if (pnetdev) ++ rtw_free_netdev(pnetdev); ++ else if (padapter) ++ vfree(padapter); ++ padapter = NULL; ++ } ++exit: ++ return padapter; ++} ++ ++static void rtw_usb_if1_deinit(struct adapter *if1) ++{ ++ struct net_device *pnetdev = if1->pnetdev; ++ struct mlme_priv *pmlmepriv = &if1->mlmepriv; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ rtw_disassoc_cmd(if1, 0, false); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ free_mlme_ap_info(if1); ++#endif ++ ++ if (if1->DriverState != DRIVER_DISAPPEAR) { ++ if (pnetdev) { ++ /* will call netdev_close() */ ++ unregister_netdev(pnetdev); ++ rtw_proc_remove_one(pnetdev); ++ } ++ } ++ rtw_cancel_all_timer(if1); ++ ++ rtw_dev_unload(if1); ++ DBG_88E("+r871xu_dev_remove, hw_init_completed=%d\n", ++ if1->hw_init_completed); ++ rtw_handle_dualmac(if1, 0); ++ rtw_free_drv_sw(if1); ++ if (pnetdev) ++ rtw_free_netdev(pnetdev); ++} ++ ++static int rtw_drv_init(struct usb_interface *pusb_intf, const struct usb_device_id *pdid) ++{ ++ struct adapter *if1 = NULL; ++ struct dvobj_priv *dvobj; ++ ++ /* step 0. */ ++ process_spec_devid(pdid); ++ ++ /* Initialize dvobj_priv */ ++ dvobj = usb_dvobj_init(pusb_intf); ++ if (!dvobj) ++ goto err; ++ ++ if1 = rtw_usb_if1_init(dvobj, pusb_intf); ++ if (!if1) { ++ DBG_88E("rtw_init_primarystruct adapter Failed!\n"); ++ goto free_dvobj; ++ } ++ ++ if (ui_pid[1] != 0) { ++ DBG_88E("ui_pid[1]:%d\n", ui_pid[1]); ++ rtw_signal_process(ui_pid[1], SIGUSR2); ++ } ++ ++ return 0; ++ ++free_dvobj: ++ usb_dvobj_deinit(pusb_intf); ++err: ++ return -ENODEV; ++} ++ ++/* ++ * dev_remove() - our device is being removed ++*/ ++/* rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove() => how to recognize both */ ++static void rtw_dev_remove(struct usb_interface *pusb_intf) ++{ ++ struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); ++ struct adapter *padapter = dvobj->if1; ++ ++ DBG_88E("+rtw_dev_remove\n"); ++ ++ if (usb_drv->drv_registered) ++ padapter->bSurpriseRemoved = true; ++ ++ rtw_pm_set_ips(padapter, IPS_NONE); ++ rtw_pm_set_lps(padapter, PS_MODE_ACTIVE); ++ ++ LeaveAllPowerSaveMode(padapter); ++ ++ rtw_usb_if1_deinit(padapter); ++ ++ usb_dvobj_deinit(pusb_intf); ++ ++ DBG_88E("-r871xu_dev_remove, done\n"); ++} ++ ++static int __init rtw_drv_entry(void) ++{ ++ DBG_88E(DRV_NAME " driver version=%s\n", DRIVERVERSION); ++ ++ _rtw_mutex_init(&usb_drv->hw_init_mutex); ++ ++ usb_drv->drv_registered = true; ++ return usb_register(&usb_drv->usbdrv); ++} ++ ++static void __exit rtw_drv_halt(void) ++{ ++ DBG_88E("+rtw_drv_halt\n"); ++ ++ usb_drv->drv_registered = false; ++ usb_deregister(&usb_drv->usbdrv); ++ ++ _rtw_mutex_free(&usb_drv->hw_init_mutex); ++ DBG_88E("-rtw_drv_halt\n"); ++} ++ ++module_init(rtw_drv_entry); ++module_exit(rtw_drv_halt); +diff --git a/drivers/staging/r8188eu/os_dep/usb_ops_linux.c b/drivers/staging/r8188eu/os_dep/usb_ops_linux.c +new file mode 100644 +index 000000000000..62dd4a131534 +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/usb_ops_linux.c +@@ -0,0 +1,253 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _USB_OPS_LINUX_C_ ++ ++#include "../include/drv_types.h" ++#include "../include/usb_ops_linux.h" ++#include "../include/rtw_sreset.h" ++ ++unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr) ++{ ++ unsigned int pipe = 0, ep_num = 0; ++ struct usb_device *pusbd = pdvobj->pusbdev; ++ ++ if (addr == RECV_BULK_IN_ADDR) { ++ pipe = usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[0]); ++ } else if (addr == RECV_INT_IN_ADDR) { ++ pipe = usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[1]); ++ } else if (addr < HW_QUEUE_ENTRY) { ++ ep_num = pdvobj->Queue2Pipe[addr]; ++ pipe = usb_sndbulkpipe(pusbd, ep_num); ++ } ++ ++ return pipe; ++} ++ ++struct zero_bulkout_context { ++ void *pbuf; ++ void *purb; ++ void *pirp; ++ void *padapter; ++}; ++ ++void usb_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) ++{ ++} ++ ++void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) ++{ ++} ++ ++void usb_read_port_cancel(struct intf_hdl *pintfhdl) ++{ ++ int i; ++ struct recv_buf *precvbuf; ++ struct adapter *padapter = pintfhdl->padapter; ++ precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf; ++ ++ DBG_88E("%s\n", __func__); ++ ++ padapter->bReadPortCancel = true; ++ ++ for (i = 0; i < NR_RECVBUFF; i++) { ++ precvbuf->reuse = true; ++ if (precvbuf->purb) ++ usb_kill_urb(precvbuf->purb); ++ precvbuf++; ++ } ++} ++ ++static void usb_write_port_complete(struct urb *purb, struct pt_regs *regs) ++{ ++ struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context; ++ struct adapter *padapter = pxmitbuf->padapter; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct hal_data_8188e *haldata; ++ ++ switch (pxmitbuf->flags) { ++ case VO_QUEUE_INX: ++ pxmitpriv->voq_cnt--; ++ break; ++ case VI_QUEUE_INX: ++ pxmitpriv->viq_cnt--; ++ break; ++ case BE_QUEUE_INX: ++ pxmitpriv->beq_cnt--; ++ break; ++ case BK_QUEUE_INX: ++ pxmitpriv->bkq_cnt--; ++ break; ++ case HIGH_QUEUE_INX: ++#ifdef CONFIG_88EU_AP_MODE ++ rtw_chk_hi_queue_cmd(padapter); ++#endif ++ break; ++ default: ++ break; ++ } ++ ++ if (padapter->bSurpriseRemoved || padapter->bDriverStopped || ++ padapter->bWritePortCancel) { ++ DBG_88E("%s(): TX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bWritePortCancel(%d) pxmitbuf->ext_tag(%x)\n", ++ __func__, padapter->bDriverStopped, ++ padapter->bSurpriseRemoved, padapter->bReadPortCancel, ++ pxmitbuf->ext_tag); ++ ++ goto check_completion; ++ } ++ ++ if (purb->status) { ++ DBG_88E("###=> urb_write_port_complete status(%d)\n", purb->status); ++ if ((purb->status == -EPIPE) || (purb->status == -EPROTO)) { ++ sreset_set_wifi_error_status(padapter, USB_WRITE_PORT_FAIL); ++ } else if (purb->status == -EINPROGRESS) { ++ goto check_completion; ++ } else if (purb->status == -ENOENT) { ++ DBG_88E("%s: -ENOENT\n", __func__); ++ goto check_completion; ++ } else if (purb->status == -ECONNRESET) { ++ DBG_88E("%s: -ECONNRESET\n", __func__); ++ goto check_completion; ++ } else if (purb->status == -ESHUTDOWN) { ++ padapter->bDriverStopped = true; ++ goto check_completion; ++ } else { ++ padapter->bSurpriseRemoved = true; ++ DBG_88E("bSurpriseRemoved = true\n"); ++ ++ goto check_completion; ++ } ++ } ++ ++ haldata = GET_HAL_DATA(padapter); ++ haldata->srestpriv.last_tx_complete_time = jiffies; ++ ++check_completion: ++ rtw_sctx_done_err(&pxmitbuf->sctx, ++ purb->status ? RTW_SCTX_DONE_WRITE_PORT_ERR : ++ RTW_SCTX_DONE_SUCCESS); ++ ++ rtw_free_xmitbuf(pxmitpriv, pxmitbuf); ++ ++ tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); ++ ++} ++ ++u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) ++{ ++ unsigned long irqL; ++ unsigned int pipe; ++ int status; ++ u32 ret = _FAIL; ++ struct urb *purb = NULL; ++ struct adapter *padapter = (struct adapter *)pintfhdl->padapter; ++ struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct xmit_buf *pxmitbuf = (struct xmit_buf *)wmem; ++ struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data; ++ struct usb_device *pusbd = pdvobj->pusbdev; ++ ++ if ((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) || ++ (padapter->pwrctrlpriv.pnp_bstop_trx)) { ++ rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY); ++ goto exit; ++ } ++ ++ spin_lock_irqsave(&pxmitpriv->lock, irqL); ++ ++ switch (addr) { ++ case VO_QUEUE_INX: ++ pxmitpriv->voq_cnt++; ++ pxmitbuf->flags = VO_QUEUE_INX; ++ break; ++ case VI_QUEUE_INX: ++ pxmitpriv->viq_cnt++; ++ pxmitbuf->flags = VI_QUEUE_INX; ++ break; ++ case BE_QUEUE_INX: ++ pxmitpriv->beq_cnt++; ++ pxmitbuf->flags = BE_QUEUE_INX; ++ break; ++ case BK_QUEUE_INX: ++ pxmitpriv->bkq_cnt++; ++ pxmitbuf->flags = BK_QUEUE_INX; ++ break; ++ case HIGH_QUEUE_INX: ++ pxmitbuf->flags = HIGH_QUEUE_INX; ++ break; ++ default: ++ pxmitbuf->flags = MGT_QUEUE_INX; ++ break; ++ } ++ ++ spin_unlock_irqrestore(&pxmitpriv->lock, irqL); ++ ++ purb = pxmitbuf->pxmit_urb[0]; ++ ++ /* translate DMA FIFO addr to pipehandle */ ++ pipe = ffaddr2pipehdl(pdvobj, addr); ++ ++ usb_fill_bulk_urb(purb, pusbd, pipe, ++ pxmitframe->buf_addr, /* pxmitbuf->pbuf */ ++ cnt, ++ usb_write_port_complete, ++ pxmitbuf);/* context is pxmitbuf */ ++ ++ status = usb_submit_urb(purb, GFP_ATOMIC); ++ if (!status) { ++ struct hal_data_8188e *haldata = GET_HAL_DATA(padapter); ++ ++ haldata->srestpriv.last_tx_time = jiffies; ++ } else { ++ rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR); ++ DBG_88E("usb_write_port, status =%d\n", status); ++ ++ switch (status) { ++ case -ENODEV: ++ padapter->bDriverStopped = true; ++ break; ++ default: ++ break; ++ } ++ goto exit; ++ } ++ ++ ret = _SUCCESS; ++ ++/* We add the URB_ZERO_PACKET flag to urb so that the host will send the zero packet automatically. */ ++ ++exit: ++ if (ret != _SUCCESS) ++ rtw_free_xmitbuf(pxmitpriv, pxmitbuf); ++ ++ return ret; ++} ++ ++void usb_write_port_cancel(struct intf_hdl *pintfhdl) ++{ ++ int i, j; ++ struct adapter *padapter = pintfhdl->padapter; ++ struct xmit_buf *pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmitbuf; ++ ++ DBG_88E("%s\n", __func__); ++ ++ padapter->bWritePortCancel = true; ++ ++ for (i = 0; i < NR_XMITBUFF; i++) { ++ for (j = 0; j < 8; j++) { ++ if (pxmitbuf->pxmit_urb[j]) ++ usb_kill_urb(pxmitbuf->pxmit_urb[j]); ++ } ++ pxmitbuf++; ++ } ++ ++ pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmit_extbuf; ++ for (i = 0; i < NR_XMIT_EXTBUFF; i++) { ++ for (j = 0; j < 8; j++) { ++ if (pxmitbuf->pxmit_urb[j]) ++ usb_kill_urb(pxmitbuf->pxmit_urb[j]); ++ } ++ pxmitbuf++; ++ } ++} +diff --git a/drivers/staging/r8188eu/os_dep/xmit_linux.c b/drivers/staging/r8188eu/os_dep/xmit_linux.c +new file mode 100644 +index 000000000000..565ac5be7db3 +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/xmit_linux.c +@@ -0,0 +1,251 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _XMIT_OSDEP_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wifi.h" ++#include "../include/mlme_osdep.h" ++#include "../include/xmit_osdep.h" ++#include "../include/osdep_intf.h" ++#include "../include/usb_osintf.h" ++ ++uint rtw_remainder_len(struct pkt_file *pfile) ++{ ++ return pfile->buf_len - ((size_t)(pfile->cur_addr) - ++ (size_t)(pfile->buf_start)); ++} ++ ++void _rtw_open_pktfile(struct sk_buff *pktptr, struct pkt_file *pfile) ++{ ++ ++ if (!pktptr) { ++ pr_err("8188eu: pktptr is NULL\n"); ++ return; ++ } ++ if (!pfile) { ++ pr_err("8188eu: pfile is NULL\n"); ++ return; ++ } ++ pfile->pkt = pktptr; ++ pfile->cur_addr = pktptr->data; ++ pfile->buf_start = pktptr->data; ++ pfile->pkt_len = pktptr->len; ++ pfile->buf_len = pktptr->len; ++ ++ pfile->cur_buffer = pfile->buf_start; ++ ++} ++ ++uint _rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen) ++{ ++ uint len = 0; ++ ++ len = rtw_remainder_len(pfile); ++ len = (rlen > len) ? len : rlen; ++ ++ if (rmem) ++ skb_copy_bits(pfile->pkt, pfile->buf_len - pfile->pkt_len, rmem, len); ++ ++ pfile->cur_addr += len; ++ pfile->pkt_len -= len; ++ ++ return len; ++} ++ ++int rtw_endofpktfile(struct pkt_file *pfile) ++{ ++ ++ if (pfile->pkt_len == 0) { ++ ++ return true; ++ } ++ ++ return false; ++} ++ ++void rtw_set_tx_chksum_offload(struct sk_buff *pkt, struct pkt_attrib *pattrib) ++{ ++} ++ ++int rtw_os_xmit_resource_alloc(struct adapter *padapter, struct xmit_buf *pxmitbuf, u32 alloc_sz) ++{ ++ int i; ++ ++ pxmitbuf->pallocated_buf = kzalloc(alloc_sz, GFP_KERNEL); ++ if (!pxmitbuf->pallocated_buf) ++ return _FAIL; ++ ++ pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ); ++ pxmitbuf->dma_transfer_addr = 0; ++ ++ for (i = 0; i < 8; i++) { ++ pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL); ++ if (!pxmitbuf->pxmit_urb[i]) { ++ DBG_88E("pxmitbuf->pxmit_urb[i]==NULL"); ++ return _FAIL; ++ } ++ } ++ return _SUCCESS; ++} ++ ++void rtw_os_xmit_resource_free(struct adapter *padapter, ++ struct xmit_buf *pxmitbuf, u32 free_sz) ++{ ++ int i; ++ ++ for (i = 0; i < 8; i++) ++ usb_free_urb(pxmitbuf->pxmit_urb[i]); ++ ++ kfree(pxmitbuf->pallocated_buf); ++} ++ ++#define WMM_XMIT_THRESHOLD (NR_XMITFRAME * 2 / 5) ++ ++void rtw_os_pkt_complete(struct adapter *padapter, struct sk_buff *pkt) ++{ ++ u16 queue; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ queue = skb_get_queue_mapping(pkt); ++ if (padapter->registrypriv.wifi_spec) { ++ if (__netif_subqueue_stopped(padapter->pnetdev, queue) && ++ (pxmitpriv->hwxmits[queue].accnt < WMM_XMIT_THRESHOLD)) ++ netif_wake_subqueue(padapter->pnetdev, queue); ++ } else { ++ if (__netif_subqueue_stopped(padapter->pnetdev, queue)) ++ netif_wake_subqueue(padapter->pnetdev, queue); ++ } ++ ++ dev_kfree_skb_any(pkt); ++} ++ ++void rtw_os_xmit_complete(struct adapter *padapter, struct xmit_frame *pxframe) ++{ ++ if (pxframe->pkt) ++ rtw_os_pkt_complete(padapter, pxframe->pkt); ++ pxframe->pkt = NULL; ++} ++ ++void rtw_os_xmit_schedule(struct adapter *padapter) ++{ ++ struct xmit_priv *pxmitpriv; ++ ++ if (!padapter) ++ return; ++ ++ pxmitpriv = &padapter->xmitpriv; ++ ++ spin_lock_bh(&pxmitpriv->lock); ++ ++ if (rtw_txframes_pending(padapter)) ++ tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); ++ ++ spin_unlock_bh(&pxmitpriv->lock); ++} ++ ++static void rtw_check_xmit_resource(struct adapter *padapter, struct sk_buff *pkt) ++{ ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ u16 queue; ++ ++ queue = skb_get_queue_mapping(pkt); ++ if (padapter->registrypriv.wifi_spec) { ++ /* No free space for Tx, tx_worker is too slow */ ++ if (pxmitpriv->hwxmits[queue].accnt > WMM_XMIT_THRESHOLD) ++ netif_stop_subqueue(padapter->pnetdev, queue); ++ } else { ++ if (pxmitpriv->free_xmitframe_cnt <= 4) { ++ if (!netif_tx_queue_stopped(netdev_get_tx_queue(padapter->pnetdev, queue))) ++ netif_stop_subqueue(padapter->pnetdev, queue); ++ } ++ } ++} ++ ++static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb) ++{ ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct list_head *phead, *plist; ++ struct sk_buff *newskb; ++ struct sta_info *psta = NULL; ++ s32 res; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ phead = &pstapriv->asoc_list; ++ plist = phead->next; ++ ++ /* free sta asoc_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, asoc_list); ++ ++ plist = plist->next; ++ ++ /* avoid come from STA1 and send back STA1 */ ++ if (!memcmp(psta->hwaddr, &skb->data[6], 6)) ++ continue; ++ ++ newskb = skb_copy(skb, GFP_ATOMIC); ++ ++ if (newskb) { ++ memcpy(newskb->data, psta->hwaddr, 6); ++ res = rtw_xmit(padapter, &newskb); ++ if (res < 0) { ++ DBG_88E("%s()-%d: rtw_xmit() return error!\n", __func__, __LINE__); ++ pxmitpriv->tx_drop++; ++ dev_kfree_skb_any(newskb); ++ } else { ++ pxmitpriv->tx_pkts++; ++ } ++ } else { ++ DBG_88E("%s-%d: skb_copy() failed!\n", __func__, __LINE__); ++ pxmitpriv->tx_drop++; ++ ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ return false; /* Caller shall tx this multicast frame via normal way. */ ++ } ++ } ++ ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ dev_kfree_skb_any(skb); ++ return true; ++} ++ ++int rtw_xmit_entry(struct sk_buff *pkt, struct net_device *pnetdev) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ s32 res = 0; ++ ++ if (!rtw_if_up(padapter)) ++ goto drop_packet; ++ ++ rtw_check_xmit_resource(padapter, pkt); ++ ++ if (!rtw_mc2u_disable && check_fwstate(pmlmepriv, WIFI_AP_STATE) && ++ (IP_MCAST_MAC(pkt->data) || ICMPV6_MCAST_MAC(pkt->data)) && ++ (padapter->registrypriv.wifi_spec == 0)) { ++ if (pxmitpriv->free_xmitframe_cnt > (NR_XMITFRAME / 4)) { ++ res = rtw_mlcst2unicst(padapter, pkt); ++ if (res) ++ goto exit; ++ } ++ } ++ ++ res = rtw_xmit(padapter, &pkt); ++ if (res < 0) ++ goto drop_packet; ++ ++ pxmitpriv->tx_pkts++; ++ goto exit; ++ ++drop_packet: ++ pxmitpriv->tx_drop++; ++ dev_kfree_skb_any(pkt); ++ ++exit: ++ ++ return 0; ++} diff --git a/kernel/kernel/pspec.xml b/kernel/kernel/pspec.xml index f70c1d1f..fc528cae 100644 --- a/kernel/kernel/pspec.xml +++ b/kernel/kernel/pspec.xml @@ -33,10 +33,10 @@ - patches/linux/patch-5.15.81.xz + patches/linux/patch-5.15.86.xz - patches/aufs5/aufs5.15.41-20220620.patch + patches/aufs5/aufs5.15.41-20221219.patch patches/aufs5/aufs5-base.patch patches/aufs5/aufs5-kbuild.patch patches/aufs5/aufs5-loopback.patch @@ -94,15 +94,9 @@ patches/mageia/3rd-fix-kconfig.patch - - - - - - - - - + patches/mageia/net-wireless-rtw88-dont-check-CRC-of-VHT-SIG-B-in-802.11ac-signal.patch + patches/mageia/net-wireless-rtw89-add-Realtek-802.11ax-driver.patch + patches/mageia/net-wireless-rtw88-add-r8822be-alias.patch @@ -161,6 +155,17 @@ + + 2023-01-03 + 5.15.86 + Version bump. + security + + systemRestart + + Mustafa Cinasal + muscnsl@gmail.com + 2022-12-07 5.15.81 diff --git a/kernel/tools/cpupowertools/files/patches/aufs5/aufs5-loopback.patch b/kernel/tools/cpupowertools/files/patches/aufs5/aufs5-loopback.patch index 753437f3..e3897d08 100644 --- a/kernel/tools/cpupowertools/files/patches/aufs5/aufs5-loopback.patch +++ b/kernel/tools/cpupowertools/files/patches/aufs5/aufs5-loopback.patch @@ -153,7 +153,7 @@ index 04c88dd6eabd..0ff3ba22ee17 100644 void *key_data; diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c -index 99ceca144044..e49dfe855032 100644 +index c2924d055ebd..4efde401dbf4 100644 --- a/fs/aufs/f_op.c +++ b/fs/aufs/f_op.c @@ -304,7 +304,7 @@ static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter) diff --git a/kernel/tools/cpupowertools/files/patches/aufs5/aufs5.15.41-20220620.patch b/kernel/tools/cpupowertools/files/patches/aufs5/aufs5.15.41-20221219.patch similarity index 99% rename from kernel/tools/cpupowertools/files/patches/aufs5/aufs5.15.41-20220620.patch rename to kernel/tools/cpupowertools/files/patches/aufs5/aufs5.15.41-20221219.patch index ab061321..fa1ebf39 100644 --- a/kernel/tools/cpupowertools/files/patches/aufs5/aufs5.15.41-20220620.patch +++ b/kernel/tools/cpupowertools/files/patches/aufs5/aufs5.15.41-20221219.patch @@ -1,6 +1,6 @@ diff -Naur null/Documentation/ABI/testing/debugfs-aufs linux-5.15.41/Documentation/ABI/testing/debugfs-aufs --- /dev/null -+++ linux-5.15.41/Documentation/ABI/testing/debugfs-aufs 2022-09-06 12:51:51.030710012 +0300 ++++ linux-5.15.41/Documentation/ABI/testing/debugfs-aufs 2023-01-03 20:33:04.499529241 +0300 @@ -0,0 +1,55 @@ +What: /debug/aufs/si_/ +Date: March 2009 @@ -59,7 +59,7 @@ diff -Naur null/Documentation/ABI/testing/debugfs-aufs linux-5.15.41/Documentati + will be empty. About XINO files, see the aufs manual. diff -Naur null/Documentation/ABI/testing/sysfs-aufs linux-5.15.41/Documentation/ABI/testing/sysfs-aufs --- /dev/null -+++ linux-5.15.41/Documentation/ABI/testing/sysfs-aufs 2022-09-06 12:51:51.030710012 +0300 ++++ linux-5.15.41/Documentation/ABI/testing/sysfs-aufs 2023-01-03 20:33:04.499529241 +0300 @@ -0,0 +1,31 @@ +What: /sys/fs/aufs/si_/ +Date: March 2009 @@ -94,7 +94,7 @@ diff -Naur null/Documentation/ABI/testing/sysfs-aufs linux-5.15.41/Documentation + will be empty. About XINO files, see the aufs manual. diff -Naur null/Documentation/filesystems/aufs/design/01intro.txt linux-5.15.41/Documentation/filesystems/aufs/design/01intro.txt --- /dev/null -+++ linux-5.15.41/Documentation/filesystems/aufs/design/01intro.txt 2022-09-06 12:51:51.031709999 +0300 ++++ linux-5.15.41/Documentation/filesystems/aufs/design/01intro.txt 2023-01-03 20:33:04.499529241 +0300 @@ -0,0 +1,171 @@ + +# Copyright (C) 2005-2021 Junjiro R. Okajima @@ -269,7 +269,7 @@ diff -Naur null/Documentation/filesystems/aufs/design/01intro.txt linux-5.15.41/ +about it. But currently I have implemented it in kernel space. diff -Naur null/Documentation/filesystems/aufs/design/02struct.txt linux-5.15.41/Documentation/filesystems/aufs/design/02struct.txt --- /dev/null -+++ linux-5.15.41/Documentation/filesystems/aufs/design/02struct.txt 2022-09-06 12:51:51.031709999 +0300 ++++ linux-5.15.41/Documentation/filesystems/aufs/design/02struct.txt 2023-01-03 20:33:04.499529241 +0300 @@ -0,0 +1,258 @@ + +# Copyright (C) 2005-2021 Junjiro R. Okajima @@ -531,7 +531,7 @@ diff -Naur null/Documentation/filesystems/aufs/design/02struct.txt linux-5.15.41 +For this purpose, use "aumvdown" command in aufs-util.git. diff -Naur null/Documentation/filesystems/aufs/design/03atomic_open.txt linux-5.15.41/Documentation/filesystems/aufs/design/03atomic_open.txt --- /dev/null -+++ linux-5.15.41/Documentation/filesystems/aufs/design/03atomic_open.txt 2022-09-06 12:51:51.031709999 +0300 ++++ linux-5.15.41/Documentation/filesystems/aufs/design/03atomic_open.txt 2023-01-03 20:33:04.500529229 +0300 @@ -0,0 +1,85 @@ + +# Copyright (C) 2015-2021 Junjiro R. Okajima @@ -620,7 +620,7 @@ diff -Naur null/Documentation/filesystems/aufs/design/03atomic_open.txt linux-5. + be implemented in aufs, but not all I am afraid. diff -Naur null/Documentation/filesystems/aufs/design/03lookup.txt linux-5.15.41/Documentation/filesystems/aufs/design/03lookup.txt --- /dev/null -+++ linux-5.15.41/Documentation/filesystems/aufs/design/03lookup.txt 2022-09-06 12:51:51.031709999 +0300 ++++ linux-5.15.41/Documentation/filesystems/aufs/design/03lookup.txt 2023-01-03 20:33:04.500529229 +0300 @@ -0,0 +1,113 @@ + +# Copyright (C) 2005-2021 Junjiro R. Okajima @@ -737,7 +737,7 @@ diff -Naur null/Documentation/filesystems/aufs/design/03lookup.txt linux-5.15.41 + by over-mounting something (or another method). diff -Naur null/Documentation/filesystems/aufs/design/04branch.txt linux-5.15.41/Documentation/filesystems/aufs/design/04branch.txt --- /dev/null -+++ linux-5.15.41/Documentation/filesystems/aufs/design/04branch.txt 2022-09-06 12:51:51.031709999 +0300 ++++ linux-5.15.41/Documentation/filesystems/aufs/design/04branch.txt 2023-01-03 20:33:04.500529229 +0300 @@ -0,0 +1,74 @@ + +# Copyright (C) 2005-2021 Junjiro R. Okajima @@ -815,7 +815,7 @@ diff -Naur null/Documentation/filesystems/aufs/design/04branch.txt linux-5.15.41 + same named entry on the upper branch. diff -Naur null/Documentation/filesystems/aufs/design/05wbr_policy.txt linux-5.15.41/Documentation/filesystems/aufs/design/05wbr_policy.txt --- /dev/null -+++ linux-5.15.41/Documentation/filesystems/aufs/design/05wbr_policy.txt 2022-09-06 12:51:51.032709987 +0300 ++++ linux-5.15.41/Documentation/filesystems/aufs/design/05wbr_policy.txt 2023-01-03 20:33:04.500529229 +0300 @@ -0,0 +1,64 @@ + +# Copyright (C) 2005-2021 Junjiro R. Okajima @@ -883,7 +883,7 @@ diff -Naur null/Documentation/filesystems/aufs/design/05wbr_policy.txt linux-5.1 + copyup policy. diff -Naur null/Documentation/filesystems/aufs/design/06dirren.dot linux-5.15.41/Documentation/filesystems/aufs/design/06dirren.dot --- /dev/null -+++ linux-5.15.41/Documentation/filesystems/aufs/design/06dirren.dot 2022-09-06 12:51:51.032709987 +0300 ++++ linux-5.15.41/Documentation/filesystems/aufs/design/06dirren.dot 2023-01-03 20:33:04.500529229 +0300 @@ -0,0 +1,31 @@ + +// to view this graph, run dot(1) command in GRAPHVIZ. @@ -918,7 +918,7 @@ diff -Naur null/Documentation/filesystems/aufs/design/06dirren.dot linux-5.15.41 +} diff -Naur null/Documentation/filesystems/aufs/design/06dirren.txt linux-5.15.41/Documentation/filesystems/aufs/design/06dirren.txt --- /dev/null -+++ linux-5.15.41/Documentation/filesystems/aufs/design/06dirren.txt 2022-09-06 12:51:51.032709987 +0300 ++++ linux-5.15.41/Documentation/filesystems/aufs/design/06dirren.txt 2023-01-03 20:33:04.500529229 +0300 @@ -0,0 +1,102 @@ + +# Copyright (C) 2017-2021 Junjiro R. Okajima @@ -1024,7 +1024,7 @@ diff -Naur null/Documentation/filesystems/aufs/design/06dirren.txt linux-5.15.41 +equivalen to udba=reval case. diff -Naur null/Documentation/filesystems/aufs/design/06fhsm.txt linux-5.15.41/Documentation/filesystems/aufs/design/06fhsm.txt --- /dev/null -+++ linux-5.15.41/Documentation/filesystems/aufs/design/06fhsm.txt 2022-09-06 12:51:51.032709987 +0300 ++++ linux-5.15.41/Documentation/filesystems/aufs/design/06fhsm.txt 2023-01-03 20:33:04.500529229 +0300 @@ -0,0 +1,120 @@ + +# Copyright (C) 2011-2021 Junjiro R. Okajima @@ -1148,7 +1148,7 @@ diff -Naur null/Documentation/filesystems/aufs/design/06fhsm.txt linux-5.15.41/D +should restore the original file state after an error happens. diff -Naur null/Documentation/filesystems/aufs/design/06mmap.txt linux-5.15.41/Documentation/filesystems/aufs/design/06mmap.txt --- /dev/null -+++ linux-5.15.41/Documentation/filesystems/aufs/design/06mmap.txt 2022-09-06 12:51:51.032709987 +0300 ++++ linux-5.15.41/Documentation/filesystems/aufs/design/06mmap.txt 2023-01-03 20:33:04.500529229 +0300 @@ -0,0 +1,72 @@ + +# Copyright (C) 2005-2021 Junjiro R. Okajima @@ -1224,7 +1224,7 @@ diff -Naur null/Documentation/filesystems/aufs/design/06mmap.txt linux-5.15.41/D +I have to give up this "looks-smater" approach. diff -Naur null/Documentation/filesystems/aufs/design/06xattr.txt linux-5.15.41/Documentation/filesystems/aufs/design/06xattr.txt --- /dev/null -+++ linux-5.15.41/Documentation/filesystems/aufs/design/06xattr.txt 2022-09-06 12:51:51.032709987 +0300 ++++ linux-5.15.41/Documentation/filesystems/aufs/design/06xattr.txt 2023-01-03 20:33:04.500529229 +0300 @@ -0,0 +1,96 @@ + +# Copyright (C) 2014-2021 Junjiro R. Okajima @@ -1324,7 +1324,7 @@ diff -Naur null/Documentation/filesystems/aufs/design/06xattr.txt linux-5.15.41/ +now, aufs implements the branch attributes to ignore the error. diff -Naur null/Documentation/filesystems/aufs/design/07export.txt linux-5.15.41/Documentation/filesystems/aufs/design/07export.txt --- /dev/null -+++ linux-5.15.41/Documentation/filesystems/aufs/design/07export.txt 2022-09-06 12:51:51.032709987 +0300 ++++ linux-5.15.41/Documentation/filesystems/aufs/design/07export.txt 2023-01-03 20:33:04.500529229 +0300 @@ -0,0 +1,58 @@ + +# Copyright (C) 2005-2021 Junjiro R. Okajima @@ -1386,7 +1386,7 @@ diff -Naur null/Documentation/filesystems/aufs/design/07export.txt linux-5.15.41 + lookup_one_len(), vfs_getattr(), encode_fh() and others. diff -Naur null/Documentation/filesystems/aufs/design/08shwh.txt linux-5.15.41/Documentation/filesystems/aufs/design/08shwh.txt --- /dev/null -+++ linux-5.15.41/Documentation/filesystems/aufs/design/08shwh.txt 2022-09-06 12:51:51.032709987 +0300 ++++ linux-5.15.41/Documentation/filesystems/aufs/design/08shwh.txt 2023-01-03 20:33:04.500529229 +0300 @@ -0,0 +1,52 @@ + +# Copyright (C) 2005-2021 Junjiro R. Okajima @@ -1442,7 +1442,7 @@ diff -Naur null/Documentation/filesystems/aufs/design/08shwh.txt linux-5.15.41/D +initramfs will use it to replace the old one at the next boot. diff -Naur null/Documentation/filesystems/aufs/design/10dynop.txt linux-5.15.41/Documentation/filesystems/aufs/design/10dynop.txt --- /dev/null -+++ linux-5.15.41/Documentation/filesystems/aufs/design/10dynop.txt 2022-09-06 12:51:51.032709987 +0300 ++++ linux-5.15.41/Documentation/filesystems/aufs/design/10dynop.txt 2023-01-03 20:33:04.500529229 +0300 @@ -0,0 +1,47 @@ + +# Copyright (C) 2010-2021 Junjiro R. Okajima @@ -1493,7 +1493,7 @@ diff -Naur null/Documentation/filesystems/aufs/design/10dynop.txt linux-5.15.41/ +regular files only. diff -Naur null/Documentation/filesystems/aufs/README linux-5.15.41/Documentation/filesystems/aufs/README --- /dev/null -+++ linux-5.15.41/Documentation/filesystems/aufs/README 2022-09-06 12:51:51.031709999 +0300 ++++ linux-5.15.41/Documentation/filesystems/aufs/README 2023-01-03 20:33:04.499529241 +0300 @@ -0,0 +1,397 @@ + +Aufs5 -- advanced multi layered unification filesystem version 5.x @@ -1894,7 +1894,7 @@ diff -Naur null/Documentation/filesystems/aufs/README linux-5.15.41/Documentatio +# End: ; diff -Naur null/fs/aufs/aufs.h linux-5.15.41/fs/aufs/aufs.h --- /dev/null -+++ linux-5.15.41/fs/aufs/aufs.h 2022-09-06 12:51:51.034709962 +0300 ++++ linux-5.15.41/fs/aufs/aufs.h 2023-01-03 20:33:04.501529216 +0300 @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -1960,7 +1960,7 @@ diff -Naur null/fs/aufs/aufs.h linux-5.15.41/fs/aufs/aufs.h +#endif /* __AUFS_H__ */ diff -Naur null/fs/aufs/branch.c linux-5.15.41/fs/aufs/branch.c --- /dev/null -+++ linux-5.15.41/fs/aufs/branch.c 2022-09-06 12:51:51.034709962 +0300 ++++ linux-5.15.41/fs/aufs/branch.c 2023-01-03 20:33:04.502529204 +0300 @@ -0,0 +1,1427 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -3391,7 +3391,7 @@ diff -Naur null/fs/aufs/branch.c linux-5.15.41/fs/aufs/branch.c +} diff -Naur null/fs/aufs/branch.h linux-5.15.41/fs/aufs/branch.h --- /dev/null -+++ linux-5.15.41/fs/aufs/branch.h 2022-09-06 12:51:51.034709962 +0300 ++++ linux-5.15.41/fs/aufs/branch.h 2023-01-03 20:33:04.502529204 +0300 @@ -0,0 +1,375 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -3770,7 +3770,7 @@ diff -Naur null/fs/aufs/branch.h linux-5.15.41/fs/aufs/branch.h +#endif /* __AUFS_BRANCH_H__ */ diff -Naur null/fs/aufs/conf.mk linux-5.15.41/fs/aufs/conf.mk --- /dev/null -+++ linux-5.15.41/fs/aufs/conf.mk 2022-09-06 12:51:51.035709949 +0300 ++++ linux-5.15.41/fs/aufs/conf.mk 2023-01-03 20:33:04.502529204 +0300 @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: GPL-2.0 + @@ -3814,7 +3814,7 @@ diff -Naur null/fs/aufs/conf.mk linux-5.15.41/fs/aufs/conf.mk +-include ${srctree}/${src}/conf_priv.mk diff -Naur null/fs/aufs/cpup.c linux-5.15.41/fs/aufs/cpup.c --- /dev/null -+++ linux-5.15.41/fs/aufs/cpup.c 2022-09-06 12:51:51.035709949 +0300 ++++ linux-5.15.41/fs/aufs/cpup.c 2023-01-03 20:33:04.502529204 +0300 @@ -0,0 +1,1459 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -4407,7 +4407,7 @@ diff -Naur null/fs/aufs/cpup.c linux-5.15.41/fs/aufs/cpup.c + * regardless 'acl' option, reset all ACL. + * All ACL will be copied up later from the original entry on the lower branch. + */ -+static int au_reset_acl(struct inode *h_dir, struct path *h_path, umode_t mode) ++static int au_reset_acl(struct path *h_path, umode_t mode) +{ + int err; + struct dentry *h_dentry; @@ -4529,7 +4529,7 @@ diff -Naur null/fs/aufs/cpup.c linux-5.15.41/fs/aufs/cpup.c + err = -EIO; + } + if (!err) -+ err = au_reset_acl(h_dir, &h_path, mode); ++ err = au_reset_acl(&h_path, mode); + + mnt_flags = au_mntflags(sb); + if (!au_opt_test(mnt_flags, UDBA_NONE) @@ -5277,7 +5277,7 @@ diff -Naur null/fs/aufs/cpup.c linux-5.15.41/fs/aufs/cpup.c +} diff -Naur null/fs/aufs/cpup.h linux-5.15.41/fs/aufs/cpup.h --- /dev/null -+++ linux-5.15.41/fs/aufs/cpup.h 2022-09-06 12:51:51.035709949 +0300 ++++ linux-5.15.41/fs/aufs/cpup.h 2023-01-03 20:33:04.502529204 +0300 @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -5381,7 +5381,7 @@ diff -Naur null/fs/aufs/cpup.h linux-5.15.41/fs/aufs/cpup.h +#endif /* __AUFS_CPUP_H__ */ diff -Naur null/fs/aufs/dbgaufs.c linux-5.15.41/fs/aufs/dbgaufs.c --- /dev/null -+++ linux-5.15.41/fs/aufs/dbgaufs.c 2022-09-06 12:51:51.035709949 +0300 ++++ linux-5.15.41/fs/aufs/dbgaufs.c 2023-01-03 20:33:04.502529204 +0300 @@ -0,0 +1,526 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -5911,7 +5911,7 @@ diff -Naur null/fs/aufs/dbgaufs.c linux-5.15.41/fs/aufs/dbgaufs.c +} diff -Naur null/fs/aufs/dbgaufs.h linux-5.15.41/fs/aufs/dbgaufs.h --- /dev/null -+++ linux-5.15.41/fs/aufs/dbgaufs.h 2022-09-06 12:51:51.035709949 +0300 ++++ linux-5.15.41/fs/aufs/dbgaufs.h 2023-01-03 20:33:04.502529204 +0300 @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -5968,7 +5968,7 @@ diff -Naur null/fs/aufs/dbgaufs.h linux-5.15.41/fs/aufs/dbgaufs.h +#endif /* __DBGAUFS_H__ */ diff -Naur null/fs/aufs/dcsub.c linux-5.15.41/fs/aufs/dcsub.c --- /dev/null -+++ linux-5.15.41/fs/aufs/dcsub.c 2022-09-06 12:51:51.035709949 +0300 ++++ linux-5.15.41/fs/aufs/dcsub.c 2023-01-03 20:33:04.502529204 +0300 @@ -0,0 +1,225 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -6197,7 +6197,7 @@ diff -Naur null/fs/aufs/dcsub.c linux-5.15.41/fs/aufs/dcsub.c +} diff -Naur null/fs/aufs/dcsub.h linux-5.15.41/fs/aufs/dcsub.h --- /dev/null -+++ linux-5.15.41/fs/aufs/dcsub.h 2022-09-06 12:51:51.035709949 +0300 ++++ linux-5.15.41/fs/aufs/dcsub.h 2023-01-03 20:33:04.502529204 +0300 @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -6338,7 +6338,7 @@ diff -Naur null/fs/aufs/dcsub.h linux-5.15.41/fs/aufs/dcsub.h +#endif /* __AUFS_DCSUB_H__ */ diff -Naur null/fs/aufs/debug.c linux-5.15.41/fs/aufs/debug.c --- /dev/null -+++ linux-5.15.41/fs/aufs/debug.c 2022-09-06 12:51:51.036709937 +0300 ++++ linux-5.15.41/fs/aufs/debug.c 2023-01-03 20:33:04.502529204 +0300 @@ -0,0 +1,444 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -6786,7 +6786,7 @@ diff -Naur null/fs/aufs/debug.c linux-5.15.41/fs/aufs/debug.c +} diff -Naur null/fs/aufs/debug.h linux-5.15.41/fs/aufs/debug.h --- /dev/null -+++ linux-5.15.41/fs/aufs/debug.h 2022-09-06 12:51:51.036709937 +0300 ++++ linux-5.15.41/fs/aufs/debug.h 2023-01-03 20:33:04.503529191 +0300 @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -7016,7 +7016,7 @@ diff -Naur null/fs/aufs/debug.h linux-5.15.41/fs/aufs/debug.h +#endif /* __AUFS_DEBUG_H__ */ diff -Naur null/fs/aufs/dentry.c linux-5.15.41/fs/aufs/dentry.c --- /dev/null -+++ linux-5.15.41/fs/aufs/dentry.c 2022-09-06 12:51:51.036709937 +0300 ++++ linux-5.15.41/fs/aufs/dentry.c 2023-01-03 20:33:04.503529191 +0300 @@ -0,0 +1,1168 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -8188,7 +8188,7 @@ diff -Naur null/fs/aufs/dentry.c linux-5.15.41/fs/aufs/dentry.c +}; diff -Naur null/fs/aufs/dentry.h linux-5.15.41/fs/aufs/dentry.h --- /dev/null -+++ linux-5.15.41/fs/aufs/dentry.h 2022-09-06 12:51:51.036709937 +0300 ++++ linux-5.15.41/fs/aufs/dentry.h 2023-01-03 20:33:04.503529191 +0300 @@ -0,0 +1,269 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -8461,7 +8461,7 @@ diff -Naur null/fs/aufs/dentry.h linux-5.15.41/fs/aufs/dentry.h +#endif /* __AUFS_DENTRY_H__ */ diff -Naur null/fs/aufs/dinfo.c linux-5.15.41/fs/aufs/dinfo.c --- /dev/null -+++ linux-5.15.41/fs/aufs/dinfo.c 2022-09-06 12:51:51.037709924 +0300 ++++ linux-5.15.41/fs/aufs/dinfo.c 2023-01-03 20:33:04.503529191 +0300 @@ -0,0 +1,554 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -9019,7 +9019,7 @@ diff -Naur null/fs/aufs/dinfo.c linux-5.15.41/fs/aufs/dinfo.c +} diff -Naur null/fs/aufs/dir.c linux-5.15.41/fs/aufs/dir.c --- /dev/null -+++ linux-5.15.41/fs/aufs/dir.c 2022-09-06 12:51:51.037709924 +0300 ++++ linux-5.15.41/fs/aufs/dir.c 2023-01-03 20:33:04.503529191 +0300 @@ -0,0 +1,765 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -9788,7 +9788,7 @@ diff -Naur null/fs/aufs/dir.c linux-5.15.41/fs/aufs/dir.c +}; diff -Naur null/fs/aufs/dir.h linux-5.15.41/fs/aufs/dir.h --- /dev/null -+++ linux-5.15.41/fs/aufs/dir.h 2022-09-06 12:51:51.037709924 +0300 ++++ linux-5.15.41/fs/aufs/dir.h 2023-01-03 20:33:04.503529191 +0300 @@ -0,0 +1,134 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -9926,7 +9926,7 @@ diff -Naur null/fs/aufs/dir.h linux-5.15.41/fs/aufs/dir.h +#endif /* __AUFS_DIR_H__ */ diff -Naur null/fs/aufs/dirren.c linux-5.15.41/fs/aufs/dirren.c --- /dev/null -+++ linux-5.15.41/fs/aufs/dirren.c 2022-09-06 12:51:51.037709924 +0300 ++++ linux-5.15.41/fs/aufs/dirren.c 2023-01-03 20:33:04.503529191 +0300 @@ -0,0 +1,1315 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -11245,7 +11245,7 @@ diff -Naur null/fs/aufs/dirren.c linux-5.15.41/fs/aufs/dirren.c +} diff -Naur null/fs/aufs/dirren.h linux-5.15.41/fs/aufs/dirren.h --- /dev/null -+++ linux-5.15.41/fs/aufs/dirren.h 2022-09-06 12:51:51.037709924 +0300 ++++ linux-5.15.41/fs/aufs/dirren.h 2023-01-03 20:33:04.503529191 +0300 @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -11389,7 +11389,7 @@ diff -Naur null/fs/aufs/dirren.h linux-5.15.41/fs/aufs/dirren.h +#endif /* __AUFS_DIRREN_H__ */ diff -Naur null/fs/aufs/dynop.c linux-5.15.41/fs/aufs/dynop.c --- /dev/null -+++ linux-5.15.41/fs/aufs/dynop.c 2022-09-06 12:51:51.037709924 +0300 ++++ linux-5.15.41/fs/aufs/dynop.c 2023-01-03 20:33:04.504529179 +0300 @@ -0,0 +1,368 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -11761,7 +11761,7 @@ diff -Naur null/fs/aufs/dynop.c linux-5.15.41/fs/aufs/dynop.c +} diff -Naur null/fs/aufs/dynop.h linux-5.15.41/fs/aufs/dynop.h --- /dev/null -+++ linux-5.15.41/fs/aufs/dynop.h 2022-09-06 12:51:51.038709912 +0300 ++++ linux-5.15.41/fs/aufs/dynop.h 2023-01-03 20:33:04.504529179 +0300 @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -11842,7 +11842,7 @@ diff -Naur null/fs/aufs/dynop.h linux-5.15.41/fs/aufs/dynop.h +#endif /* __AUFS_DYNOP_H__ */ diff -Naur null/fs/aufs/export.c linux-5.15.41/fs/aufs/export.c --- /dev/null -+++ linux-5.15.41/fs/aufs/export.c 2022-09-06 12:51:51.038709912 +0300 ++++ linux-5.15.41/fs/aufs/export.c 2023-01-03 20:33:04.504529179 +0300 @@ -0,0 +1,830 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -12676,7 +12676,7 @@ diff -Naur null/fs/aufs/export.c linux-5.15.41/fs/aufs/export.c +} diff -Naur null/fs/aufs/fhsm.c linux-5.15.41/fs/aufs/fhsm.c --- /dev/null -+++ linux-5.15.41/fs/aufs/fhsm.c 2022-09-06 12:51:51.038709912 +0300 ++++ linux-5.15.41/fs/aufs/fhsm.c 2023-01-03 20:33:04.504529179 +0300 @@ -0,0 +1,427 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -13107,7 +13107,7 @@ diff -Naur null/fs/aufs/fhsm.c linux-5.15.41/fs/aufs/fhsm.c +} diff -Naur null/fs/aufs/file.c linux-5.15.41/fs/aufs/file.c --- /dev/null -+++ linux-5.15.41/fs/aufs/file.c 2022-09-06 12:51:51.039709899 +0300 ++++ linux-5.15.41/fs/aufs/file.c 2023-01-03 20:33:04.504529179 +0300 @@ -0,0 +1,863 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -13974,7 +13974,7 @@ diff -Naur null/fs/aufs/file.c linux-5.15.41/fs/aufs/file.c +}; diff -Naur null/fs/aufs/file.h linux-5.15.41/fs/aufs/file.h --- /dev/null -+++ linux-5.15.41/fs/aufs/file.h 2022-09-06 12:51:51.039709899 +0300 ++++ linux-5.15.41/fs/aufs/file.h 2023-01-03 20:33:04.504529179 +0300 @@ -0,0 +1,342 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -14320,7 +14320,7 @@ diff -Naur null/fs/aufs/file.h linux-5.15.41/fs/aufs/file.h +#endif /* __AUFS_FILE_H__ */ diff -Naur null/fs/aufs/finfo.c linux-5.15.41/fs/aufs/finfo.c --- /dev/null -+++ linux-5.15.41/fs/aufs/finfo.c 2022-09-06 12:51:51.039709899 +0300 ++++ linux-5.15.41/fs/aufs/finfo.c 2023-01-03 20:33:04.504529179 +0300 @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -14473,8 +14473,8 @@ diff -Naur null/fs/aufs/finfo.c linux-5.15.41/fs/aufs/finfo.c +} diff -Naur null/fs/aufs/f_op.c linux-5.15.41/fs/aufs/f_op.c --- /dev/null -+++ linux-5.15.41/fs/aufs/f_op.c 2022-09-06 12:51:51.038709912 +0300 -@@ -0,0 +1,771 @@ ++++ linux-5.15.41/fs/aufs/f_op.c 2023-01-03 20:33:04.504529179 +0300 +@@ -0,0 +1,775 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2021 Junjiro R. Okajima @@ -14920,6 +14920,10 @@ diff -Naur null/fs/aufs/f_op.c linux-5.15.41/fs/aufs/f_op.c + lockdep_off(); + err = vfs_fallocate(h_file, mode, offset, len); + lockdep_on(); ++ /* ++ * we don't need to call file_modifed() here since au_write_post() ++ * is equivalent and copies-up all timestamps and permission bits. ++ */ + au_write_post(inode, h_file, &wpre, /*written*/1); + +out: @@ -15248,7 +15252,7 @@ diff -Naur null/fs/aufs/f_op.c linux-5.15.41/fs/aufs/f_op.c +}; diff -Naur null/fs/aufs/fsctx.c linux-5.15.41/fs/aufs/fsctx.c --- /dev/null -+++ linux-5.15.41/fs/aufs/fsctx.c 2022-09-06 12:51:51.039709899 +0300 ++++ linux-5.15.41/fs/aufs/fsctx.c 2023-01-03 20:33:04.505529166 +0300 @@ -0,0 +1,1242 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -16494,7 +16498,7 @@ diff -Naur null/fs/aufs/fsctx.c linux-5.15.41/fs/aufs/fsctx.c +} diff -Naur null/fs/aufs/fstype.h linux-5.15.41/fs/aufs/fstype.h --- /dev/null -+++ linux-5.15.41/fs/aufs/fstype.h 2022-09-06 12:51:51.039709899 +0300 ++++ linux-5.15.41/fs/aufs/fstype.h 2023-01-03 20:33:04.505529166 +0300 @@ -0,0 +1,401 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -16899,7 +16903,7 @@ diff -Naur null/fs/aufs/fstype.h linux-5.15.41/fs/aufs/fstype.h +#endif /* __AUFS_FSTYPE_H__ */ diff -Naur null/fs/aufs/hbl.h linux-5.15.41/fs/aufs/hbl.h --- /dev/null -+++ linux-5.15.41/fs/aufs/hbl.h 2022-09-06 12:51:51.039709899 +0300 ++++ linux-5.15.41/fs/aufs/hbl.h 2023-01-03 20:33:04.505529166 +0300 @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -16968,7 +16972,7 @@ diff -Naur null/fs/aufs/hbl.h linux-5.15.41/fs/aufs/hbl.h +#endif /* __AUFS_HBL_H__ */ diff -Naur null/fs/aufs/hfsnotify.c linux-5.15.41/fs/aufs/hfsnotify.c --- /dev/null -+++ linux-5.15.41/fs/aufs/hfsnotify.c 2022-09-06 12:51:51.040709887 +0300 ++++ linux-5.15.41/fs/aufs/hfsnotify.c 2023-01-03 20:33:04.505529166 +0300 @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -17260,7 +17264,7 @@ diff -Naur null/fs/aufs/hfsnotify.c linux-5.15.41/fs/aufs/hfsnotify.c +}; diff -Naur null/fs/aufs/hfsplus.c linux-5.15.41/fs/aufs/hfsplus.c --- /dev/null -+++ linux-5.15.41/fs/aufs/hfsplus.c 2022-09-06 12:51:51.040709887 +0300 ++++ linux-5.15.41/fs/aufs/hfsplus.c 2023-01-03 20:33:04.505529166 +0300 @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -17324,7 +17328,7 @@ diff -Naur null/fs/aufs/hfsplus.c linux-5.15.41/fs/aufs/hfsplus.c +} diff -Naur null/fs/aufs/hnotify.c linux-5.15.41/fs/aufs/hnotify.c --- /dev/null -+++ linux-5.15.41/fs/aufs/hnotify.c 2022-09-06 12:51:51.040709887 +0300 ++++ linux-5.15.41/fs/aufs/hnotify.c 2023-01-03 20:33:04.505529166 +0300 @@ -0,0 +1,715 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -18043,7 +18047,7 @@ diff -Naur null/fs/aufs/hnotify.c linux-5.15.41/fs/aufs/hnotify.c +} diff -Naur null/fs/aufs/iinfo.c linux-5.15.41/fs/aufs/iinfo.c --- /dev/null -+++ linux-5.15.41/fs/aufs/iinfo.c 2022-09-06 12:51:51.041709874 +0300 ++++ linux-5.15.41/fs/aufs/iinfo.c 2023-01-03 20:33:04.506529154 +0300 @@ -0,0 +1,286 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -18333,7 +18337,7 @@ diff -Naur null/fs/aufs/iinfo.c linux-5.15.41/fs/aufs/iinfo.c +} diff -Naur null/fs/aufs/inode.c linux-5.15.41/fs/aufs/inode.c --- /dev/null -+++ linux-5.15.41/fs/aufs/inode.c 2022-09-06 12:51:51.041709874 +0300 ++++ linux-5.15.41/fs/aufs/inode.c 2023-01-03 20:33:04.506529154 +0300 @@ -0,0 +1,531 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -18868,7 +18872,7 @@ diff -Naur null/fs/aufs/inode.c linux-5.15.41/fs/aufs/inode.c +} diff -Naur null/fs/aufs/inode.h linux-5.15.41/fs/aufs/inode.h --- /dev/null -+++ linux-5.15.41/fs/aufs/inode.h 2022-09-06 12:51:51.042709862 +0300 ++++ linux-5.15.41/fs/aufs/inode.h 2023-01-03 20:33:04.506529154 +0300 @@ -0,0 +1,705 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -19577,7 +19581,7 @@ diff -Naur null/fs/aufs/inode.h linux-5.15.41/fs/aufs/inode.h +#endif /* __AUFS_INODE_H__ */ diff -Naur null/fs/aufs/ioctl.c linux-5.15.41/fs/aufs/ioctl.c --- /dev/null -+++ linux-5.15.41/fs/aufs/ioctl.c 2022-09-06 12:51:51.042709862 +0300 ++++ linux-5.15.41/fs/aufs/ioctl.c 2023-01-03 20:33:04.506529154 +0300 @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -19801,7 +19805,7 @@ diff -Naur null/fs/aufs/ioctl.c linux-5.15.41/fs/aufs/ioctl.c +#endif diff -Naur null/fs/aufs/i_op_add.c linux-5.15.41/fs/aufs/i_op_add.c --- /dev/null -+++ linux-5.15.41/fs/aufs/i_op_add.c 2022-09-06 12:51:51.041709874 +0300 ++++ linux-5.15.41/fs/aufs/i_op_add.c 2023-01-03 20:33:04.505529166 +0300 @@ -0,0 +1,941 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -20746,7 +20750,7 @@ diff -Naur null/fs/aufs/i_op_add.c linux-5.15.41/fs/aufs/i_op_add.c +} diff -Naur null/fs/aufs/i_op.c linux-5.15.41/fs/aufs/i_op.c --- /dev/null -+++ linux-5.15.41/fs/aufs/i_op.c 2022-09-06 12:51:51.040709887 +0300 ++++ linux-5.15.41/fs/aufs/i_op.c 2023-01-03 20:33:04.505529166 +0300 @@ -0,0 +1,1512 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -22262,7 +22266,7 @@ diff -Naur null/fs/aufs/i_op.c linux-5.15.41/fs/aufs/i_op.c +}; diff -Naur null/fs/aufs/i_op_del.c linux-5.15.41/fs/aufs/i_op_del.c --- /dev/null -+++ linux-5.15.41/fs/aufs/i_op_del.c 2022-09-06 12:51:51.041709874 +0300 ++++ linux-5.15.41/fs/aufs/i_op_del.c 2023-01-03 20:33:04.506529154 +0300 @@ -0,0 +1,522 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -22788,7 +22792,7 @@ diff -Naur null/fs/aufs/i_op_del.c linux-5.15.41/fs/aufs/i_op_del.c +} diff -Naur null/fs/aufs/i_op_ren.c linux-5.15.41/fs/aufs/i_op_ren.c --- /dev/null -+++ linux-5.15.41/fs/aufs/i_op_ren.c 2022-09-06 12:51:51.041709874 +0300 ++++ linux-5.15.41/fs/aufs/i_op_ren.c 2023-01-03 20:33:04.506529154 +0300 @@ -0,0 +1,1257 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -24049,7 +24053,7 @@ diff -Naur null/fs/aufs/i_op_ren.c linux-5.15.41/fs/aufs/i_op_ren.c +} diff -Naur null/fs/aufs/Kconfig linux-5.15.41/fs/aufs/Kconfig --- /dev/null -+++ linux-5.15.41/fs/aufs/Kconfig 2022-09-06 12:51:51.034709962 +0300 ++++ linux-5.15.41/fs/aufs/Kconfig 2023-01-03 20:33:04.501529216 +0300 @@ -0,0 +1,199 @@ +# SPDX-License-Identifier: GPL-2.0 +config AUFS_FS @@ -24252,7 +24256,7 @@ diff -Naur null/fs/aufs/Kconfig linux-5.15.41/fs/aufs/Kconfig +endif diff -Naur null/fs/aufs/lcnt.h linux-5.15.41/fs/aufs/lcnt.h --- /dev/null -+++ linux-5.15.41/fs/aufs/lcnt.h 2022-09-06 12:51:51.042709862 +0300 ++++ linux-5.15.41/fs/aufs/lcnt.h 2023-01-03 20:33:04.506529154 +0300 @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -24442,7 +24446,7 @@ diff -Naur null/fs/aufs/lcnt.h linux-5.15.41/fs/aufs/lcnt.h +#endif /* __AUFS_LCNT_H__ */ diff -Naur null/fs/aufs/loop.c linux-5.15.41/fs/aufs/loop.c --- /dev/null -+++ linux-5.15.41/fs/aufs/loop.c 2022-09-06 12:51:51.042709862 +0300 ++++ linux-5.15.41/fs/aufs/loop.c 2023-01-03 20:33:04.506529154 +0300 @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -24594,7 +24598,7 @@ diff -Naur null/fs/aufs/loop.c linux-5.15.41/fs/aufs/loop.c +} diff -Naur null/fs/aufs/loop.h linux-5.15.41/fs/aufs/loop.h --- /dev/null -+++ linux-5.15.41/fs/aufs/loop.h 2022-09-06 12:51:51.042709862 +0300 ++++ linux-5.15.41/fs/aufs/loop.h 2023-01-03 20:33:04.506529154 +0300 @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -24653,7 +24657,7 @@ diff -Naur null/fs/aufs/loop.h linux-5.15.41/fs/aufs/loop.h +#endif /* __AUFS_LOOP_H__ */ diff -Naur null/fs/aufs/magic.mk linux-5.15.41/fs/aufs/magic.mk --- /dev/null -+++ linux-5.15.41/fs/aufs/magic.mk 2022-09-06 12:51:51.042709862 +0300 ++++ linux-5.15.41/fs/aufs/magic.mk 2023-01-03 20:33:04.507529141 +0300 @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0 + @@ -24688,7 +24692,7 @@ diff -Naur null/fs/aufs/magic.mk linux-5.15.41/fs/aufs/magic.mk +endif diff -Naur null/fs/aufs/Makefile linux-5.15.41/fs/aufs/Makefile --- /dev/null -+++ linux-5.15.41/fs/aufs/Makefile 2022-09-06 12:51:51.034709962 +0300 ++++ linux-5.15.41/fs/aufs/Makefile 2023-01-03 20:33:04.501529216 +0300 @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: GPL-2.0 + @@ -24738,7 +24742,7 @@ diff -Naur null/fs/aufs/Makefile linux-5.15.41/fs/aufs/Makefile +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o diff -Naur null/fs/aufs/module.c linux-5.15.41/fs/aufs/module.c --- /dev/null -+++ linux-5.15.41/fs/aufs/module.c 2022-09-06 12:51:51.042709862 +0300 ++++ linux-5.15.41/fs/aufs/module.c 2023-01-03 20:33:04.507529141 +0300 @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -25015,7 +25019,7 @@ diff -Naur null/fs/aufs/module.c linux-5.15.41/fs/aufs/module.c +module_exit(aufs_exit); diff -Naur null/fs/aufs/module.h linux-5.15.41/fs/aufs/module.h --- /dev/null -+++ linux-5.15.41/fs/aufs/module.h 2022-09-06 12:51:51.042709862 +0300 ++++ linux-5.15.41/fs/aufs/module.h 2023-01-03 20:33:04.507529141 +0300 @@ -0,0 +1,166 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -25185,7 +25189,7 @@ diff -Naur null/fs/aufs/module.h linux-5.15.41/fs/aufs/module.h +#endif /* __AUFS_MODULE_H__ */ diff -Naur null/fs/aufs/mvdown.c linux-5.15.41/fs/aufs/mvdown.c --- /dev/null -+++ linux-5.15.41/fs/aufs/mvdown.c 2022-09-06 12:51:51.043709849 +0300 ++++ linux-5.15.41/fs/aufs/mvdown.c 2023-01-03 20:33:04.507529141 +0300 @@ -0,0 +1,706 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -25895,7 +25899,7 @@ diff -Naur null/fs/aufs/mvdown.c linux-5.15.41/fs/aufs/mvdown.c +} diff -Naur null/fs/aufs/opts.c linux-5.15.41/fs/aufs/opts.c --- /dev/null -+++ linux-5.15.41/fs/aufs/opts.c 2022-09-06 12:51:51.043709849 +0300 ++++ linux-5.15.41/fs/aufs/opts.c 2023-01-03 20:33:04.507529141 +0300 @@ -0,0 +1,1032 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -26931,7 +26935,7 @@ diff -Naur null/fs/aufs/opts.c linux-5.15.41/fs/aufs/opts.c +} diff -Naur null/fs/aufs/opts.h linux-5.15.41/fs/aufs/opts.h --- /dev/null -+++ linux-5.15.41/fs/aufs/opts.h 2022-09-06 12:51:51.043709849 +0300 ++++ linux-5.15.41/fs/aufs/opts.h 2023-01-03 20:33:04.507529141 +0300 @@ -0,0 +1,263 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -27198,7 +27202,7 @@ diff -Naur null/fs/aufs/opts.h linux-5.15.41/fs/aufs/opts.h +#endif /* __AUFS_OPTS_H__ */ diff -Naur null/fs/aufs/plink.c linux-5.15.41/fs/aufs/plink.c --- /dev/null -+++ linux-5.15.41/fs/aufs/plink.c 2022-09-06 12:51:51.043709849 +0300 ++++ linux-5.15.41/fs/aufs/plink.c 2023-01-03 20:33:04.507529141 +0300 @@ -0,0 +1,516 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -27718,7 +27722,7 @@ diff -Naur null/fs/aufs/plink.c linux-5.15.41/fs/aufs/plink.c +} diff -Naur null/fs/aufs/poll.c linux-5.15.41/fs/aufs/poll.c --- /dev/null -+++ linux-5.15.41/fs/aufs/poll.c 2022-09-06 12:51:51.044709837 +0300 ++++ linux-5.15.41/fs/aufs/poll.c 2023-01-03 20:33:04.507529141 +0300 @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -27773,7 +27777,7 @@ diff -Naur null/fs/aufs/poll.c linux-5.15.41/fs/aufs/poll.c +} diff -Naur null/fs/aufs/posix_acl.c linux-5.15.41/fs/aufs/posix_acl.c --- /dev/null -+++ linux-5.15.41/fs/aufs/posix_acl.c 2022-09-06 12:51:51.044709837 +0300 ++++ linux-5.15.41/fs/aufs/posix_acl.c 2023-01-03 20:33:04.508529129 +0300 @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -27888,7 +27892,7 @@ diff -Naur null/fs/aufs/posix_acl.c linux-5.15.41/fs/aufs/posix_acl.c +} diff -Naur null/fs/aufs/procfs.c linux-5.15.41/fs/aufs/procfs.c --- /dev/null -+++ linux-5.15.41/fs/aufs/procfs.c 2022-09-06 12:51:51.044709837 +0300 ++++ linux-5.15.41/fs/aufs/procfs.c 2023-01-03 20:33:04.508529129 +0300 @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -28062,7 +28066,7 @@ diff -Naur null/fs/aufs/procfs.c linux-5.15.41/fs/aufs/procfs.c +} diff -Naur null/fs/aufs/rdu.c linux-5.15.41/fs/aufs/rdu.c --- /dev/null -+++ linux-5.15.41/fs/aufs/rdu.c 2022-09-06 12:51:51.044709837 +0300 ++++ linux-5.15.41/fs/aufs/rdu.c 2023-01-03 20:33:04.508529129 +0300 @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -28450,7 +28454,7 @@ diff -Naur null/fs/aufs/rdu.c linux-5.15.41/fs/aufs/rdu.c +#endif diff -Naur null/fs/aufs/rwsem.h linux-5.15.41/fs/aufs/rwsem.h --- /dev/null -+++ linux-5.15.41/fs/aufs/rwsem.h 2022-09-06 12:51:51.044709837 +0300 ++++ linux-5.15.41/fs/aufs/rwsem.h 2023-01-03 20:33:04.508529129 +0300 @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -28539,7 +28543,7 @@ diff -Naur null/fs/aufs/rwsem.h linux-5.15.41/fs/aufs/rwsem.h +#endif /* __AUFS_RWSEM_H__ */ diff -Naur null/fs/aufs/sbinfo.c linux-5.15.41/fs/aufs/sbinfo.c --- /dev/null -+++ linux-5.15.41/fs/aufs/sbinfo.c 2022-09-06 12:51:51.044709837 +0300 ++++ linux-5.15.41/fs/aufs/sbinfo.c 2023-01-03 20:33:04.508529129 +0300 @@ -0,0 +1,316 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -28859,7 +28863,7 @@ diff -Naur null/fs/aufs/sbinfo.c linux-5.15.41/fs/aufs/sbinfo.c +} diff -Naur null/fs/aufs/super.c linux-5.15.41/fs/aufs/super.c --- /dev/null -+++ linux-5.15.41/fs/aufs/super.c 2022-09-06 12:51:51.044709837 +0300 ++++ linux-5.15.41/fs/aufs/super.c 2023-01-03 20:33:04.508529129 +0300 @@ -0,0 +1,871 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -29734,7 +29738,7 @@ diff -Naur null/fs/aufs/super.c linux-5.15.41/fs/aufs/super.c +}; diff -Naur null/fs/aufs/super.h linux-5.15.41/fs/aufs/super.h --- /dev/null -+++ linux-5.15.41/fs/aufs/super.h 2022-09-06 12:51:51.045709824 +0300 ++++ linux-5.15.41/fs/aufs/super.h 2023-01-03 20:33:04.508529129 +0300 @@ -0,0 +1,592 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -30330,7 +30334,7 @@ diff -Naur null/fs/aufs/super.h linux-5.15.41/fs/aufs/super.h +#endif /* __AUFS_SUPER_H__ */ diff -Naur null/fs/aufs/sysaufs.c linux-5.15.41/fs/aufs/sysaufs.c --- /dev/null -+++ linux-5.15.41/fs/aufs/sysaufs.c 2022-09-06 12:51:51.045709824 +0300 ++++ linux-5.15.41/fs/aufs/sysaufs.c 2023-01-03 20:33:04.508529129 +0300 @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -30427,7 +30431,7 @@ diff -Naur null/fs/aufs/sysaufs.c linux-5.15.41/fs/aufs/sysaufs.c +} diff -Naur null/fs/aufs/sysaufs.h linux-5.15.41/fs/aufs/sysaufs.h --- /dev/null -+++ linux-5.15.41/fs/aufs/sysaufs.h 2022-09-06 12:51:51.045709824 +0300 ++++ linux-5.15.41/fs/aufs/sysaufs.h 2023-01-03 20:33:04.508529129 +0300 @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -30533,7 +30537,7 @@ diff -Naur null/fs/aufs/sysaufs.h linux-5.15.41/fs/aufs/sysaufs.h +#endif /* __SYSAUFS_H__ */ diff -Naur null/fs/aufs/sysfs.c linux-5.15.41/fs/aufs/sysfs.c --- /dev/null -+++ linux-5.15.41/fs/aufs/sysfs.c 2022-09-06 12:51:51.045709824 +0300 ++++ linux-5.15.41/fs/aufs/sysfs.c 2023-01-03 20:33:04.508529129 +0300 @@ -0,0 +1,374 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -30911,7 +30915,7 @@ diff -Naur null/fs/aufs/sysfs.c linux-5.15.41/fs/aufs/sysfs.c +} diff -Naur null/fs/aufs/sysrq.c linux-5.15.41/fs/aufs/sysrq.c --- /dev/null -+++ linux-5.15.41/fs/aufs/sysrq.c 2022-09-06 12:51:51.045709824 +0300 ++++ linux-5.15.41/fs/aufs/sysrq.c 2023-01-03 20:33:04.508529129 +0300 @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -31064,7 +31068,7 @@ diff -Naur null/fs/aufs/sysrq.c linux-5.15.41/fs/aufs/sysrq.c +} diff -Naur null/fs/aufs/vdir.c linux-5.15.41/fs/aufs/vdir.c --- /dev/null -+++ linux-5.15.41/fs/aufs/vdir.c 2022-09-06 12:51:51.045709824 +0300 ++++ linux-5.15.41/fs/aufs/vdir.c 2023-01-03 20:33:04.509529116 +0300 @@ -0,0 +1,896 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -31964,7 +31968,7 @@ diff -Naur null/fs/aufs/vdir.c linux-5.15.41/fs/aufs/vdir.c +} diff -Naur null/fs/aufs/vfsub.c linux-5.15.41/fs/aufs/vfsub.c --- /dev/null -+++ linux-5.15.41/fs/aufs/vfsub.c 2022-09-06 12:51:51.045709824 +0300 ++++ linux-5.15.41/fs/aufs/vfsub.c 2023-01-03 20:33:04.509529116 +0300 @@ -0,0 +1,918 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -32886,7 +32890,7 @@ diff -Naur null/fs/aufs/vfsub.c linux-5.15.41/fs/aufs/vfsub.c +} diff -Naur null/fs/aufs/vfsub.h linux-5.15.41/fs/aufs/vfsub.h --- /dev/null -+++ linux-5.15.41/fs/aufs/vfsub.h 2022-09-06 12:51:51.046709812 +0300 ++++ linux-5.15.41/fs/aufs/vfsub.h 2023-01-03 20:33:04.509529116 +0300 @@ -0,0 +1,358 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -33248,7 +33252,7 @@ diff -Naur null/fs/aufs/vfsub.h linux-5.15.41/fs/aufs/vfsub.h +#endif /* __AUFS_VFSUB_H__ */ diff -Naur null/fs/aufs/wbr_policy.c linux-5.15.41/fs/aufs/wbr_policy.c --- /dev/null -+++ linux-5.15.41/fs/aufs/wbr_policy.c 2022-09-06 12:51:51.046709812 +0300 ++++ linux-5.15.41/fs/aufs/wbr_policy.c 2023-01-03 20:33:04.509529116 +0300 @@ -0,0 +1,830 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -34082,7 +34086,7 @@ diff -Naur null/fs/aufs/wbr_policy.c linux-5.15.41/fs/aufs/wbr_policy.c +}; diff -Naur null/fs/aufs/whout.c linux-5.15.41/fs/aufs/whout.c --- /dev/null -+++ linux-5.15.41/fs/aufs/whout.c 2022-09-06 12:51:51.046709812 +0300 ++++ linux-5.15.41/fs/aufs/whout.c 2023-01-03 20:33:04.509529116 +0300 @@ -0,0 +1,1072 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -35158,7 +35162,7 @@ diff -Naur null/fs/aufs/whout.c linux-5.15.41/fs/aufs/whout.c +} diff -Naur null/fs/aufs/whout.h linux-5.15.41/fs/aufs/whout.h --- /dev/null -+++ linux-5.15.41/fs/aufs/whout.h 2022-09-06 12:51:51.046709812 +0300 ++++ linux-5.15.41/fs/aufs/whout.h 2023-01-03 20:33:04.509529116 +0300 @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -35249,7 +35253,7 @@ diff -Naur null/fs/aufs/whout.h linux-5.15.41/fs/aufs/whout.h +#endif /* __AUFS_WHOUT_H__ */ diff -Naur null/fs/aufs/wkq.c linux-5.15.41/fs/aufs/wkq.c --- /dev/null -+++ linux-5.15.41/fs/aufs/wkq.c 2022-09-06 12:51:51.046709812 +0300 ++++ linux-5.15.41/fs/aufs/wkq.c 2023-01-03 20:33:04.509529116 +0300 @@ -0,0 +1,372 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -35625,7 +35629,7 @@ diff -Naur null/fs/aufs/wkq.c linux-5.15.41/fs/aufs/wkq.c +} diff -Naur null/fs/aufs/wkq.h linux-5.15.41/fs/aufs/wkq.h --- /dev/null -+++ linux-5.15.41/fs/aufs/wkq.h 2022-09-06 12:51:51.047709799 +0300 ++++ linux-5.15.41/fs/aufs/wkq.h 2023-01-03 20:33:04.510529104 +0300 @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -35718,7 +35722,7 @@ diff -Naur null/fs/aufs/wkq.h linux-5.15.41/fs/aufs/wkq.h +#endif /* __AUFS_WKQ_H__ */ diff -Naur null/fs/aufs/xattr.c linux-5.15.41/fs/aufs/xattr.c --- /dev/null -+++ linux-5.15.41/fs/aufs/xattr.c 2022-09-06 12:51:51.047709799 +0300 ++++ linux-5.15.41/fs/aufs/xattr.c 2023-01-03 20:33:04.510529104 +0300 @@ -0,0 +1,368 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -36090,7 +36094,7 @@ diff -Naur null/fs/aufs/xattr.c linux-5.15.41/fs/aufs/xattr.c +} diff -Naur null/fs/aufs/xino.c linux-5.15.41/fs/aufs/xino.c --- /dev/null -+++ linux-5.15.41/fs/aufs/xino.c 2022-09-06 12:51:51.047709799 +0300 ++++ linux-5.15.41/fs/aufs/xino.c 2023-01-03 20:33:04.510529104 +0300 @@ -0,0 +1,1926 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -38020,7 +38024,7 @@ diff -Naur null/fs/aufs/xino.c linux-5.15.41/fs/aufs/xino.c +} diff -Naur null/include/uapi/linux/aufs_type.h linux-5.15.41/include/uapi/linux/aufs_type.h --- /dev/null -+++ linux-5.15.41/include/uapi/linux/aufs_type.h 2022-09-06 12:51:51.048709787 +0300 ++++ linux-5.15.41/include/uapi/linux/aufs_type.h 2023-01-03 20:33:04.510529104 +0300 @@ -0,0 +1,452 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* @@ -38064,7 +38068,7 @@ diff -Naur null/include/uapi/linux/aufs_type.h linux-5.15.41/include/uapi/linux/ +#include +#endif /* __KERNEL__ */ + -+#define AUFS_VERSION "5.15.41-20220620" ++#define AUFS_VERSION "5.15.41-20221219" + +/* todo? move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') diff --git a/kernel/tools/cpupowertools/files/patches/linux/patch-5.15.67.xz b/kernel/tools/cpupowertools/files/patches/linux/patch-5.15.67.xz deleted file mode 100644 index 8334395f..00000000 Binary files a/kernel/tools/cpupowertools/files/patches/linux/patch-5.15.67.xz and /dev/null differ diff --git a/kernel/tools/cpupowertools/files/patches/linux/patch-5.15.74.xz b/kernel/tools/cpupowertools/files/patches/linux/patch-5.15.74.xz deleted file mode 100644 index 0dea52eb..00000000 Binary files a/kernel/tools/cpupowertools/files/patches/linux/patch-5.15.74.xz and /dev/null differ diff --git a/kernel/tools/cpupowertools/files/patches/linux/patch-5.15.81.xz b/kernel/tools/cpupowertools/files/patches/linux/patch-5.15.81.xz deleted file mode 100644 index ece5544e..00000000 Binary files a/kernel/tools/cpupowertools/files/patches/linux/patch-5.15.81.xz and /dev/null differ diff --git a/kernel/tools/cpupowertools/files/patches/linux/patch-5.15.86.xz b/kernel/tools/cpupowertools/files/patches/linux/patch-5.15.86.xz new file mode 100644 index 00000000..516faf1c Binary files /dev/null and b/kernel/tools/cpupowertools/files/patches/linux/patch-5.15.86.xz differ diff --git a/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-rtw88-8822c-update-rx-settings-to-prevent-potential-hw-deadlock.patch b/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-rtw88-8822c-update-rx-settings-to-prevent-potential-hw-deadlock.patch new file mode 100644 index 00000000..16ca2f1c --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-rtw88-8822c-update-rx-settings-to-prevent-potential-hw-deadlock.patch @@ -0,0 +1,74 @@ +From c1afb26727d9e507d3e17a9890e7aaf7fc85cd55 Mon Sep 17 00:00:00 2001 +From: Po-Hao Huang +Date: Fri, 17 Dec 2021 09:27:08 +0800 +Subject: rtw88: 8822c: update rx settings to prevent potential hw deadlock + +These settings enables mac to detect and recover when rx fifo +circuit deadlock occurs. Previous version missed this, so we fix it. + +Signed-off-by: Po-Hao Huang +Signed-off-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20211217012708.8623-1-pkshih@realtek.com +--- + drivers/net/wireless/realtek/rtw88/main.c | 2 +- + drivers/net/wireless/realtek/rtw88/rtw8821c.h | 2 +- + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 2 +- + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 2 +- + 4 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c +index 78fcbc20942db..274e0af959177 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -1869,7 +1869,7 @@ int rtw_core_init(struct rtw_dev *rtwdev) + + /* default rx filter setting */ + rtwdev->hal.rcr = BIT_APP_FCS | BIT_APP_MIC | BIT_APP_ICV | +- BIT_HTC_LOC_CTRL | BIT_APP_PHYSTS | ++ BIT_PKTCTL_DLEN | BIT_HTC_LOC_CTRL | BIT_APP_PHYSTS | + BIT_AB | BIT_AM | BIT_APM; + + ret = rtw_load_firmware(rtwdev, RTW_NORMAL_FW); +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireless/realtek/rtw88/rtw8821c.h +index 112faa60f653e..d9fbddd7b0f35 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h +@@ -131,7 +131,7 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data) + #define WLAN_TX_FUNC_CFG2 0x30 + #define WLAN_MAC_OPT_NORM_FUNC1 0x98 + #define WLAN_MAC_OPT_LB_FUNC1 0x80 +-#define WLAN_MAC_OPT_FUNC2 0x30810041 ++#define WLAN_MAC_OPT_FUNC2 0xb0810041 + + #define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \ + (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \ +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +index a4cbcc6bdcd14..dd4fbb82750d5 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -205,7 +205,7 @@ static void rtw8822b_phy_set_param(struct rtw_dev *rtwdev) + #define WLAN_TX_FUNC_CFG2 0x30 + #define WLAN_MAC_OPT_NORM_FUNC1 0x98 + #define WLAN_MAC_OPT_LB_FUNC1 0x80 +-#define WLAN_MAC_OPT_FUNC2 0x30810041 ++#define WLAN_MAC_OPT_FUNC2 0xb0810041 + + #define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \ + (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \ +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +index a8b95dcdb8e90..e01d61b5d104b 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -1962,7 +1962,7 @@ static void rtw8822c_phy_set_param(struct rtw_dev *rtwdev) + #define WLAN_TX_FUNC_CFG2 0x30 + #define WLAN_MAC_OPT_NORM_FUNC1 0x98 + #define WLAN_MAC_OPT_LB_FUNC1 0x80 +-#define WLAN_MAC_OPT_FUNC2 0x30810041 ++#define WLAN_MAC_OPT_FUNC2 0xb0810041 + #define WLAN_MAC_INT_MIG_CFG 0x33330000 + + #define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \ +-- +cgit 1.2.3-1.el7 + diff --git a/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-rtw88-add-r8822be-alias.patch b/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-rtw88-add-r8822be-alias.patch new file mode 100644 index 00000000..8e44bd0c --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-rtw88-add-r8822be-alias.patch @@ -0,0 +1,14 @@ + +The staging driver rtlwifi/r8822be.ko.xz is being replaced by the new rtw88 driver. + +Add a module alias to keep upgrade path. + +Signed-off-by: Thomas Backlund + +--- a/drivers/net/wireless/realtek/rtw88/rtw8822be.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822be.c +@@ -28,3 +28,4 @@ module_pci_driver(rtw_8822be_driver); + MODULE_AUTHOR("Realtek Corporation"); + MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822be driver"); + MODULE_LICENSE("Dual BSD/GPL"); ++MODULE_ALIAS("r8822be"); diff --git a/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-rtw88-dont-check-CRC-of-VHT-SIG-B-in-802.11ac-signal.patch b/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-rtw88-dont-check-CRC-of-VHT-SIG-B-in-802.11ac-signal.patch new file mode 100644 index 00000000..6e9e1060 --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-rtw88-dont-check-CRC-of-VHT-SIG-B-in-802.11ac-signal.patch @@ -0,0 +1,143 @@ +From a3fd1f9aa79a7d3885faa486acb02c838533f332 Mon Sep 17 00:00:00 2001 +From: Chin-Yen Lee +Date: Fri, 17 Dec 2021 09:24:21 +0800 +Subject: rtw88: don't check CRC of VHT-SIG-B in 802.11ac signal + +Currently all realtek wifi chip is set to check CRC of VHT-SIG-B +in 802.11ac signal, but some AP don't calculate the CRC and packets +from these AP can't be received and lead to disconnection. +We disable the check defaultly to avoid this case. + +Signed-off-by: Chin-Yen Lee +Signed-off-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20211217012421.7859-1-pkshih@realtek.com +--- + drivers/net/wireless/realtek/rtw88/bf.c | 14 +++++++++----- + drivers/net/wireless/realtek/rtw88/bf.h | 7 +++++-- + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 3 ++- + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 2 ++ + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 2 ++ + 5 files changed, 20 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/bf.c b/drivers/net/wireless/realtek/rtw88/bf.c +index aff70e4ae0288..df750b3a35e9d 100644 +--- a/drivers/net/wireless/realtek/rtw88/bf.c ++++ b/drivers/net/wireless/realtek/rtw88/bf.c +@@ -130,7 +130,8 @@ void rtw_bf_cfg_sounding(struct rtw_dev *rtwdev, struct rtw_vif *vif, + BIT_WMAC_USE_NDPARATE | + (csi_rsc << 13); + +- rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_SOUNDING); ++ rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM, ++ RTW_SND_CTRL_SOUNDING); + rtw_write8(rtwdev, REG_SND_PTCL_CTRL + 3, 0x26); + rtw_write8_clr(rtwdev, REG_RXFLTMAP1, BIT_RXFLTMAP1_BF_REPORT_POLL); + rtw_write8_clr(rtwdev, REG_RXFLTMAP4, BIT_RXFLTMAP4_BF_REPORT_POLL); +@@ -177,7 +178,7 @@ void rtw_bf_del_bfer_entry_mu(struct rtw_dev *rtwdev) + + void rtw_bf_del_sounding(struct rtw_dev *rtwdev) + { +- rtw_write8(rtwdev, REG_SND_PTCL_CTRL, 0); ++ rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM, 0); + } + + void rtw_bf_enable_bfee_su(struct rtw_dev *rtwdev, struct rtw_vif *vif, +@@ -204,7 +205,8 @@ void rtw_bf_enable_bfee_su(struct rtw_dev *rtwdev, struct rtw_vif *vif, + } + + /* Sounding protocol control */ +- rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_SOUNDING); ++ rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM, ++ RTW_SND_CTRL_SOUNDING); + + /* MAC address/Partial AID of Beamformer */ + for (i = 0; i < ETH_ALEN; i++) +@@ -273,7 +275,8 @@ void rtw_bf_remove_bfee_su(struct rtw_dev *rtwdev, + struct rtw_bf_info *bfinfo = &rtwdev->bf_info; + + rtw_dbg(rtwdev, RTW_DBG_BF, "remove as a su bfee\n"); +- rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_REMOVE); ++ rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM, ++ RTW_SND_CTRL_REMOVE); + + switch (bfee->su_reg_index) { + case 0: +@@ -298,7 +301,8 @@ void rtw_bf_remove_bfee_mu(struct rtw_dev *rtwdev, + { + struct rtw_bf_info *bfinfo = &rtwdev->bf_info; + +- rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_REMOVE); ++ rtw_write8_mask(rtwdev, REG_SND_PTCL_CTRL, BIT_MASK_BEAMFORM, ++ RTW_SND_CTRL_REMOVE); + + rtw_bf_del_bfer_entry_mu(rtwdev); + +diff --git a/drivers/net/wireless/realtek/rtw88/bf.h b/drivers/net/wireless/realtek/rtw88/bf.h +index 17855edb5006a..7b40c2c038560 100644 +--- a/drivers/net/wireless/realtek/rtw88/bf.h ++++ b/drivers/net/wireless/realtek/rtw88/bf.h +@@ -13,6 +13,9 @@ + #define REG_ASSOCIATED_BFMER1_INFO 0x06EC + #define REG_TX_CSI_RPT_PARAM_BW20 0x06F4 + #define REG_SND_PTCL_CTRL 0x0718 ++#define BIT_DIS_CHK_VHTSIGB_CRC BIT(6) ++#define BIT_DIS_CHK_VHTSIGA_CRC BIT(5) ++#define BIT_MASK_BEAMFORM (GENMASK(4, 0) | BIT(7)) + #define REG_MU_TX_CTL 0x14C0 + #define REG_MU_STA_GID_VLD 0x14C4 + #define REG_MU_STA_USER_POS_INFO 0x14C8 +@@ -42,8 +45,8 @@ + #define BIT_RXFLTMAP4_BF_REPORT_POLL BIT(4) + + #define RTW_NDP_RX_STANDBY_TIME 0x70 +-#define RTW_SND_CTRL_REMOVE 0xD8 +-#define RTW_SND_CTRL_SOUNDING 0xDB ++#define RTW_SND_CTRL_REMOVE 0x98 ++#define RTW_SND_CTRL_SOUNDING 0x9B + + enum csi_seg_len { + HAL_CSI_SEG_4K = 0, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +index 80a6f4da6acd9..db078df63f855 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -223,7 +223,8 @@ static int rtw8821c_mac_init(struct rtw_dev *rtwdev) + rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1); + rtw_write8(rtwdev, REG_ACKTO_CCK, 0x40); + rtw_write8_set(rtwdev, REG_WMAC_TRXPTCL_CTL_H, BIT(1)); +- rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL, BIT(6)); ++ rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL, ++ BIT_DIS_CHK_VHTSIGB_CRC); + rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2); + rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, WLAN_MAC_OPT_NORM_FUNC1); + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +index c409c8c29ec8b..a4cbcc6bdcd14 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -262,6 +262,8 @@ static int rtw8822b_mac_init(struct rtw_dev *rtwdev) + rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1); + rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2); + rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, WLAN_MAC_OPT_NORM_FUNC1); ++ rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL, ++ BIT_DIS_CHK_VHTSIGB_CRC); + + return 0; + } +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +index 46b881e8e4feb..a8b95dcdb8e90 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -2102,6 +2102,8 @@ static int rtw8822c_mac_init(struct rtw_dev *rtwdev) + BIT_RXPSF_CONT_ERRCHKEN); + value16 = BIT_SET_RXPSF_ERRTHR(value16, 0x07); + rtw_write16(rtwdev, REG_RXPSF_CTRL, value16); ++ rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL, ++ BIT_DIS_CHK_VHTSIGB_CRC); + + /* Interrupt migration configuration */ + rtw_write32(rtwdev, REG_INT_MIG, WLAN_MAC_INT_MIG_CFG); +-- +cgit 1.2.3-1.el7 + diff --git a/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-rtw89-add-Realtek-802.11ax-driver.patch b/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-rtw89-add-Realtek-802.11ax-driver.patch new file mode 100644 index 00000000..29008c27 --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-rtw89-add-Realtek-802.11ax-driver.patch @@ -0,0 +1,91474 @@ +From e3ec7017f6a20d12ddd9fe23d345ebb7b8c104dd Mon Sep 17 00:00:00 2001 +From: Ping-Ke Shih +Date: Mon, 11 Oct 2021 14:47:27 +0300 +Subject: [PATCH] rtw89: add Realtek 802.11ax driver + +This driver named rtw89, which is the next generation of rtw88, supports +Realtek 8852AE 802.11ax 2x2 chip whose new features are OFDMA, DBCC, +Spatial reuse, TWT and BSS coloring; now some of them aren't implemented +though. + +The chip architecture is entirely different from the chips supported by +rtw88 like RTL8822CE 802.11ac chip. First of all, register address ranges +are totally redefined, so it's impossible to reuse register definition. To +communicate with firmware, new H2C/C2H format is proposed. In order to have +better utilization, TX DMA flow is changed to two stages DMA. To provide +rich RX status information, additional RX PPDU packets are added. + +Since there are so many differences mentioned above, we decide to propose +a new driver. It has many authors, they are listed in alphabetic order: + +Chin-Yen Lee +Ping-Ke Shih +Po Hao Huang +Tzu-En Huang +Vincent Fann +Yan-Hsuan Chuang +Zong-Zhe Yang + +Tested-by: Aaron Ma +Tested-by: Brian Norris +Signed-off-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20211008035627.19463-1-pkshih@realtek.com +--- + drivers/net/wireless/realtek/Kconfig | 1 + + drivers/net/wireless/realtek/Makefile | 1 + + drivers/net/wireless/realtek/rtw89/Kconfig | 50 + + drivers/net/wireless/realtek/rtw89/Makefile | 25 + + drivers/net/wireless/realtek/rtw89/cam.c | 695 + + drivers/net/wireless/realtek/rtw89/cam.h | 165 + + drivers/net/wireless/realtek/rtw89/coex.c | 5716 ++ + drivers/net/wireless/realtek/rtw89/coex.h | 181 + + drivers/net/wireless/realtek/rtw89/core.c | 2502 + + drivers/net/wireless/realtek/rtw89/core.h | 3384 ++ + drivers/net/wireless/realtek/rtw89/debug.c | 2489 + + drivers/net/wireless/realtek/rtw89/debug.h | 77 + + drivers/net/wireless/realtek/rtw89/efuse.c | 188 + + drivers/net/wireless/realtek/rtw89/efuse.h | 13 + + drivers/net/wireless/realtek/rtw89/fw.c | 1641 + + drivers/net/wireless/realtek/rtw89/fw.h | 1378 + + drivers/net/wireless/realtek/rtw89/mac.c | 3838 ++ + drivers/net/wireless/realtek/rtw89/mac.h | 860 + + drivers/net/wireless/realtek/rtw89/mac80211.c | 676 + + drivers/net/wireless/realtek/rtw89/pci.c | 3060 + + drivers/net/wireless/realtek/rtw89/pci.h | 635 + + drivers/net/wireless/realtek/rtw89/phy.c | 2868 + + drivers/net/wireless/realtek/rtw89/phy.h | 311 + + drivers/net/wireless/realtek/rtw89/ps.c | 150 + + drivers/net/wireless/realtek/rtw89/ps.h | 16 + + drivers/net/wireless/realtek/rtw89/reg.h | 2159 + + drivers/net/wireless/realtek/rtw89/regd.c | 353 + + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 2036 + + drivers/net/wireless/realtek/rtw89/rtw8852a.h | 109 + + .../net/wireless/realtek/rtw89/rtw8852a_rfk.c | 3911 ++ + .../net/wireless/realtek/rtw89/rtw8852a_rfk.h | 24 + + .../realtek/rtw89/rtw8852a_rfk_table.c | 1607 + + .../realtek/rtw89/rtw8852a_rfk_table.h | 133 + + .../wireless/realtek/rtw89/rtw8852a_table.c | 48725 ++++++++++++++++ + .../wireless/realtek/rtw89/rtw8852a_table.h | 28 + + drivers/net/wireless/realtek/rtw89/sar.c | 190 + + drivers/net/wireless/realtek/rtw89/sar.h | 26 + + drivers/net/wireless/realtek/rtw89/ser.c | 491 + + drivers/net/wireless/realtek/rtw89/ser.h | 15 + + drivers/net/wireless/realtek/rtw89/txrx.h | 358 + + drivers/net/wireless/realtek/rtw89/util.h | 17 + + 41 files changed, 91102 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw89/Kconfig + create mode 100644 drivers/net/wireless/realtek/rtw89/Makefile + create mode 100644 drivers/net/wireless/realtek/rtw89/cam.c + create mode 100644 drivers/net/wireless/realtek/rtw89/cam.h + create mode 100644 drivers/net/wireless/realtek/rtw89/coex.c + create mode 100644 drivers/net/wireless/realtek/rtw89/coex.h + create mode 100644 drivers/net/wireless/realtek/rtw89/core.c + create mode 100644 drivers/net/wireless/realtek/rtw89/core.h + create mode 100644 drivers/net/wireless/realtek/rtw89/debug.c + create mode 100644 drivers/net/wireless/realtek/rtw89/debug.h + create mode 100644 drivers/net/wireless/realtek/rtw89/efuse.c + create mode 100644 drivers/net/wireless/realtek/rtw89/efuse.h + create mode 100644 drivers/net/wireless/realtek/rtw89/fw.c + create mode 100644 drivers/net/wireless/realtek/rtw89/fw.h + create mode 100644 drivers/net/wireless/realtek/rtw89/mac.c + create mode 100644 drivers/net/wireless/realtek/rtw89/mac.h + create mode 100644 drivers/net/wireless/realtek/rtw89/mac80211.c + create mode 100644 drivers/net/wireless/realtek/rtw89/pci.c + create mode 100644 drivers/net/wireless/realtek/rtw89/pci.h + create mode 100644 drivers/net/wireless/realtek/rtw89/phy.c + create mode 100644 drivers/net/wireless/realtek/rtw89/phy.h + create mode 100644 drivers/net/wireless/realtek/rtw89/ps.c + create mode 100644 drivers/net/wireless/realtek/rtw89/ps.h + create mode 100644 drivers/net/wireless/realtek/rtw89/reg.h + create mode 100644 drivers/net/wireless/realtek/rtw89/regd.c + create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a.c + create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a.h + create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c + create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h + create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.c + create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.h + create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a_table.c + create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852a_table.h + create mode 100644 drivers/net/wireless/realtek/rtw89/sar.c + create mode 100644 drivers/net/wireless/realtek/rtw89/sar.h + create mode 100644 drivers/net/wireless/realtek/rtw89/ser.c + create mode 100644 drivers/net/wireless/realtek/rtw89/ser.h + create mode 100644 drivers/net/wireless/realtek/rtw89/txrx.h + create mode 100644 drivers/net/wireless/realtek/rtw89/util.h + +diff --git a/drivers/net/wireless/realtek/Kconfig b/drivers/net/wireless/realtek/Kconfig +index 474843277fa1..4a1f0e64df03 100644 +--- a/drivers/net/wireless/realtek/Kconfig ++++ b/drivers/net/wireless/realtek/Kconfig +@@ -16,5 +16,6 @@ source "drivers/net/wireless/realtek/rtl818x/Kconfig" + source "drivers/net/wireless/realtek/rtlwifi/Kconfig" + source "drivers/net/wireless/realtek/rtl8xxxu/Kconfig" + source "drivers/net/wireless/realtek/rtw88/Kconfig" ++source "drivers/net/wireless/realtek/rtw89/Kconfig" + + endif # WLAN_VENDOR_REALTEK +diff --git a/drivers/net/wireless/realtek/Makefile b/drivers/net/wireless/realtek/Makefile +index 888b5d594e79..ab25419f56c6 100644 +--- a/drivers/net/wireless/realtek/Makefile ++++ b/drivers/net/wireless/realtek/Makefile +@@ -8,4 +8,5 @@ obj-$(CONFIG_RTL8187) += rtl818x/ + obj-$(CONFIG_RTLWIFI) += rtlwifi/ + obj-$(CONFIG_RTL8XXXU) += rtl8xxxu/ + obj-$(CONFIG_RTW88) += rtw88/ ++obj-$(CONFIG_RTW89) += rtw89/ + +diff --git a/drivers/net/wireless/realtek/rtw89/Kconfig b/drivers/net/wireless/realtek/rtw89/Kconfig +new file mode 100644 +index 000000000000..37e5def24d9f +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/Kconfig +@@ -0,0 +1,50 @@ ++# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++menuconfig RTW89 ++ tristate "Realtek 802.11ax wireless chips support" ++ depends on MAC80211 ++ help ++ This module adds support for mac80211-based wireless drivers that ++ enables Realtek IEEE 802.11ax wireless chipsets. ++ ++ If you choose to build a module, it'll be called rtw89. ++ ++if RTW89 ++ ++config RTW89_CORE ++ tristate ++ ++config RTW89_PCI ++ tristate ++ ++config RTW89_8852AE ++ tristate "Realtek 8852AE PCI wireless network adapter" ++ depends on PCI ++ select RTW89_CORE ++ select RTW89_PCI ++ help ++ Select this option will enable support for 8852AE chipset ++ ++ 802.11ax PCIe wireless network adapter ++ ++config RTW89_DEBUG ++ bool ++ ++config RTW89_DEBUGMSG ++ bool "Realtek rtw89 debug message support" ++ depends on RTW89_CORE ++ select RTW89_DEBUG ++ help ++ Enable debug message support ++ ++ If unsure, say Y to simplify debug problems ++ ++config RTW89_DEBUGFS ++ bool "Realtek rtw89 debugfs support" ++ depends on RTW89_CORE ++ select RTW89_DEBUG ++ help ++ Enable debugfs support ++ ++ If unsure, say Y to simplify debug problems ++ ++endif +diff --git a/drivers/net/wireless/realtek/rtw89/Makefile b/drivers/net/wireless/realtek/rtw89/Makefile +new file mode 100644 +index 000000000000..077e8fe23f60 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/Makefile +@@ -0,0 +1,25 @@ ++# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++ ++obj-$(CONFIG_RTW89_CORE) += rtw89_core.o ++rtw89_core-y += core.o \ ++ mac80211.o \ ++ mac.o \ ++ phy.o \ ++ fw.o \ ++ rtw8852a.o \ ++ rtw8852a_table.o \ ++ rtw8852a_rfk.o \ ++ rtw8852a_rfk_table.o \ ++ cam.o \ ++ efuse.o \ ++ regd.o \ ++ sar.o \ ++ coex.o \ ++ ps.o \ ++ ser.o ++ ++rtw89_core-$(CONFIG_RTW89_DEBUG) += debug.o ++ ++obj-$(CONFIG_RTW89_PCI) += rtw89_pci.o ++rtw89_pci-y := pci.o ++ +diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c +new file mode 100644 +index 000000000000..c1e8c76c6aca +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/cam.c +@@ -0,0 +1,695 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "cam.h" ++#include "debug.h" ++#include "fw.h" ++#include "mac.h" ++ ++static struct sk_buff * ++rtw89_cam_get_sec_key_cmd(struct rtw89_dev *rtwdev, ++ struct rtw89_sec_cam_entry *sec_cam, ++ bool ext_key) ++{ ++ struct sk_buff *skb; ++ u32 cmd_len = H2C_SEC_CAM_LEN; ++ u32 key32[4]; ++ u8 *cmd; ++ int i, j; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(cmd_len); ++ if (!skb) ++ return NULL; ++ ++ skb_put_zero(skb, cmd_len); ++ ++ for (i = 0; i < 4; i++) { ++ j = i * 4; ++ j += ext_key ? 16 : 0; ++ key32[i] = FIELD_PREP(GENMASK(7, 0), sec_cam->key[j + 0]) | ++ FIELD_PREP(GENMASK(15, 8), sec_cam->key[j + 1]) | ++ FIELD_PREP(GENMASK(23, 16), sec_cam->key[j + 2]) | ++ FIELD_PREP(GENMASK(31, 24), sec_cam->key[j + 3]); ++ } ++ ++ cmd = skb->data; ++ RTW89_SET_FWCMD_SEC_IDX(cmd, sec_cam->sec_cam_idx + (ext_key ? 1 : 0)); ++ RTW89_SET_FWCMD_SEC_OFFSET(cmd, sec_cam->offset); ++ RTW89_SET_FWCMD_SEC_LEN(cmd, sec_cam->len); ++ RTW89_SET_FWCMD_SEC_TYPE(cmd, sec_cam->type); ++ RTW89_SET_FWCMD_SEC_EXT_KEY(cmd, ext_key); ++ RTW89_SET_FWCMD_SEC_SPP_MODE(cmd, sec_cam->spp_mode); ++ RTW89_SET_FWCMD_SEC_KEY0(cmd, key32[0]); ++ RTW89_SET_FWCMD_SEC_KEY1(cmd, key32[1]); ++ RTW89_SET_FWCMD_SEC_KEY2(cmd, key32[2]); ++ RTW89_SET_FWCMD_SEC_KEY3(cmd, key32[3]); ++ ++ return skb; ++} ++ ++static int rtw89_cam_send_sec_key_cmd(struct rtw89_dev *rtwdev, ++ struct rtw89_sec_cam_entry *sec_cam) ++{ ++ struct sk_buff *skb, *ext_skb; ++ int ret; ++ ++ skb = rtw89_cam_get_sec_key_cmd(rtwdev, sec_cam, false); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to get sec key command\n"); ++ return -ENOMEM; ++ } ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, ++ FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, ++ H2C_CL_MAC_SEC_CAM, ++ H2C_FUNC_MAC_SEC_UPD, 1, 0, ++ H2C_SEC_CAM_LEN); ++ ret = rtw89_h2c_tx(rtwdev, skb, false); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to send sec key h2c: %d\n", ret); ++ dev_kfree_skb(skb); ++ return ret; ++ } ++ ++ if (!sec_cam->ext_key) ++ return 0; ++ ++ ext_skb = rtw89_cam_get_sec_key_cmd(rtwdev, sec_cam, true); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to get ext sec key command\n"); ++ return -ENOMEM; ++ } ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, ext_skb, ++ FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, ++ H2C_CL_MAC_SEC_CAM, ++ H2C_FUNC_MAC_SEC_UPD, ++ 1, 0, H2C_SEC_CAM_LEN); ++ ret = rtw89_h2c_tx(rtwdev, ext_skb, false); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to send ext sec key h2c: %d\n", ret); ++ dev_kfree_skb(ext_skb); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int rtw89_cam_get_avail_sec_cam(struct rtw89_dev *rtwdev, ++ u8 *sec_cam_idx, bool ext_key) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_cam_info *cam_info = &rtwdev->cam_info; ++ u8 sec_cam_num = chip->scam_num; ++ u8 idx = 0; ++ ++ if (!ext_key) { ++ idx = find_first_zero_bit(cam_info->sec_cam_map, sec_cam_num); ++ if (idx >= sec_cam_num) ++ return -EBUSY; ++ ++ set_bit(idx, cam_info->sec_cam_map); ++ *sec_cam_idx = idx; ++ ++ return 0; ++ } ++ ++again: ++ idx = find_next_zero_bit(cam_info->sec_cam_map, sec_cam_num, idx); ++ if (idx >= sec_cam_num - 1) ++ return -EBUSY; ++ /* ext keys need two cam entries for 256-bit key */ ++ if (test_bit(idx + 1, cam_info->sec_cam_map)) { ++ idx++; ++ goto again; ++ } ++ ++ set_bit(idx, cam_info->sec_cam_map); ++ set_bit(idx + 1, cam_info->sec_cam_map); ++ *sec_cam_idx = idx; ++ ++ return 0; ++} ++ ++static int rtw89_cam_get_addr_cam_key_idx(struct rtw89_addr_cam_entry *addr_cam, ++ struct rtw89_sec_cam_entry *sec_cam, ++ struct ieee80211_key_conf *key, ++ u8 *key_idx) ++{ ++ u8 idx; ++ ++ /* RTW89_ADDR_CAM_SEC_NONE : not enabled ++ * RTW89_ADDR_CAM_SEC_ALL_UNI : 0 - 6 unicast ++ * RTW89_ADDR_CAM_SEC_NORMAL : 0 - 1 unicast, 2 - 4 group, 5 - 6 BIP ++ * RTW89_ADDR_CAM_SEC_4GROUP : 0 - 1 unicast, 2 - 5 group, 6 BIP ++ */ ++ switch (addr_cam->sec_ent_mode) { ++ case RTW89_ADDR_CAM_SEC_NONE: ++ return -EINVAL; ++ case RTW89_ADDR_CAM_SEC_ALL_UNI: ++ if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) ++ return -EINVAL; ++ idx = find_first_zero_bit(addr_cam->sec_cam_map, ++ RTW89_SEC_CAM_IN_ADDR_CAM); ++ if (idx >= RTW89_SEC_CAM_IN_ADDR_CAM) ++ return -EBUSY; ++ *key_idx = idx; ++ break; ++ case RTW89_ADDR_CAM_SEC_NORMAL: ++ if (sec_cam->type == RTW89_SEC_KEY_TYPE_BIP_CCMP128) { ++ idx = find_next_zero_bit(addr_cam->sec_cam_map, ++ RTW89_SEC_CAM_IN_ADDR_CAM, 5); ++ if (idx > 6) ++ return -EBUSY; ++ *key_idx = idx; ++ break; ++ } ++ ++ if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { ++ idx = find_next_zero_bit(addr_cam->sec_cam_map, ++ RTW89_SEC_CAM_IN_ADDR_CAM, 0); ++ if (idx > 1) ++ return -EBUSY; ++ *key_idx = idx; ++ break; ++ } ++ ++ /* Group keys */ ++ idx = find_next_zero_bit(addr_cam->sec_cam_map, ++ RTW89_SEC_CAM_IN_ADDR_CAM, 2); ++ if (idx > 4) ++ return -EBUSY; ++ *key_idx = idx; ++ break; ++ case RTW89_ADDR_CAM_SEC_4GROUP: ++ if (sec_cam->type == RTW89_SEC_KEY_TYPE_BIP_CCMP128) { ++ if (test_bit(6, addr_cam->sec_cam_map)) ++ return -EINVAL; ++ *key_idx = 6; ++ break; ++ } ++ ++ if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { ++ idx = find_next_zero_bit(addr_cam->sec_cam_map, ++ RTW89_SEC_CAM_IN_ADDR_CAM, 0); ++ if (idx > 1) ++ return -EBUSY; ++ *key_idx = idx; ++ break; ++ } ++ ++ /* Group keys */ ++ idx = find_next_zero_bit(addr_cam->sec_cam_map, ++ RTW89_SEC_CAM_IN_ADDR_CAM, 2); ++ if (idx > 5) ++ return -EBUSY; ++ *key_idx = idx; ++ break; ++ } ++ ++ return 0; ++} ++ ++static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ struct ieee80211_key_conf *key, ++ struct rtw89_sec_cam_entry *sec_cam) ++{ ++ struct rtw89_vif *rtwvif; ++ struct rtw89_addr_cam_entry *addr_cam; ++ u8 key_idx = 0; ++ int ret; ++ ++ if (!vif) { ++ rtw89_err(rtwdev, "No iface for adding sec cam\n"); ++ return -EINVAL; ++ } ++ ++ rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ addr_cam = &rtwvif->addr_cam; ++ ret = rtw89_cam_get_addr_cam_key_idx(addr_cam, sec_cam, key, &key_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to get addr cam key idx %d, %d\n", ++ addr_cam->sec_ent_mode, sec_cam->type); ++ return ret; ++ } ++ ++ key->hw_key_idx = key_idx; ++ addr_cam->sec_ent_keyid[key_idx] = key->keyidx; ++ addr_cam->sec_ent[key_idx] = sec_cam->sec_cam_idx; ++ addr_cam->sec_entries[key_idx] = sec_cam; ++ set_bit(key_idx, addr_cam->sec_cam_map); ++ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to update addr cam sec entry: %d\n", ++ ret); ++ clear_bit(key_idx, addr_cam->sec_cam_map); ++ addr_cam->sec_entries[key_idx] = NULL; ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int rtw89_cam_sec_key_install(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ struct ieee80211_key_conf *key, ++ u8 hw_key_type, bool ext_key) ++{ ++ struct rtw89_sec_cam_entry *sec_cam = NULL; ++ struct rtw89_cam_info *cam_info = &rtwdev->cam_info; ++ u8 sec_cam_idx; ++ int ret; ++ ++ /* maximum key length 256-bit */ ++ if (key->keylen > 32) { ++ rtw89_err(rtwdev, "invalid sec key length %d\n", key->keylen); ++ return -EINVAL; ++ } ++ ++ ret = rtw89_cam_get_avail_sec_cam(rtwdev, &sec_cam_idx, ext_key); ++ if (ret) { ++ rtw89_warn(rtwdev, "no available sec cam: %d ext: %d\n", ++ ret, ext_key); ++ return ret; ++ } ++ ++ sec_cam = kzalloc(sizeof(*sec_cam), GFP_KERNEL); ++ if (!sec_cam) { ++ ret = -ENOMEM; ++ goto err_release_cam; ++ } ++ ++ sec_cam->sec_cam_idx = sec_cam_idx; ++ sec_cam->type = hw_key_type; ++ sec_cam->len = RTW89_SEC_CAM_LEN; ++ sec_cam->ext_key = ext_key; ++ memcpy(sec_cam->key, key->key, key->keylen); ++ ret = rtw89_cam_send_sec_key_cmd(rtwdev, sec_cam); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to send sec key cmd: %d\n", ret); ++ goto err_release_cam; ++ } ++ ++ /* associate with addr cam */ ++ ret = rtw89_cam_attach_sec_cam(rtwdev, vif, sta, key, sec_cam); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to attach sec cam: %d\n", ret); ++ goto err_release_cam; ++ } ++ ++ return 0; ++ ++err_release_cam: ++ kfree(sec_cam); ++ clear_bit(sec_cam_idx, cam_info->sec_cam_map); ++ if (ext_key) ++ clear_bit(sec_cam_idx + 1, cam_info->sec_cam_map); ++ ++ return ret; ++} ++ ++int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ struct ieee80211_key_conf *key) ++{ ++ u8 hw_key_type; ++ bool ext_key = false; ++ int ret; ++ ++ switch (key->cipher) { ++ case WLAN_CIPHER_SUITE_WEP40: ++ hw_key_type = RTW89_SEC_KEY_TYPE_WEP40; ++ break; ++ case WLAN_CIPHER_SUITE_WEP104: ++ hw_key_type = RTW89_SEC_KEY_TYPE_WEP104; ++ break; ++ case WLAN_CIPHER_SUITE_CCMP: ++ hw_key_type = RTW89_SEC_KEY_TYPE_CCMP128; ++ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; ++ break; ++ case WLAN_CIPHER_SUITE_CCMP_256: ++ hw_key_type = RTW89_SEC_KEY_TYPE_CCMP256; ++ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; ++ ext_key = true; ++ break; ++ case WLAN_CIPHER_SUITE_GCMP: ++ hw_key_type = RTW89_SEC_KEY_TYPE_GCMP128; ++ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; ++ break; ++ case WLAN_CIPHER_SUITE_GCMP_256: ++ hw_key_type = RTW89_SEC_KEY_TYPE_GCMP256; ++ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; ++ ext_key = true; ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; ++ ++ ret = rtw89_cam_sec_key_install(rtwdev, vif, sta, key, hw_key_type, ++ ext_key); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to install key type %d ext %d: %d\n", ++ hw_key_type, ext_key, ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ struct ieee80211_key_conf *key, ++ bool inform_fw) ++{ ++ struct rtw89_cam_info *cam_info = &rtwdev->cam_info; ++ struct rtw89_vif *rtwvif; ++ struct rtw89_addr_cam_entry *addr_cam; ++ struct rtw89_sec_cam_entry *sec_cam; ++ u8 key_idx = key->hw_key_idx; ++ u8 sec_cam_idx; ++ int ret = 0; ++ ++ if (!vif) { ++ rtw89_err(rtwdev, "No iface for deleting sec cam\n"); ++ return -EINVAL; ++ } ++ ++ rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ addr_cam = &rtwvif->addr_cam; ++ sec_cam = addr_cam->sec_entries[key_idx]; ++ if (!sec_cam) ++ return -EINVAL; ++ ++ /* detach sec cam from addr cam */ ++ clear_bit(key_idx, addr_cam->sec_cam_map); ++ addr_cam->sec_entries[key_idx] = NULL; ++ if (inform_fw) { ++ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif); ++ if (ret) ++ rtw89_err(rtwdev, "failed to update cam del key: %d\n", ret); ++ } ++ ++ /* clear valid bit in addr cam will disable sec cam, ++ * so we don't need to send H2C command again ++ */ ++ sec_cam_idx = sec_cam->sec_cam_idx; ++ clear_bit(sec_cam_idx, cam_info->sec_cam_map); ++ if (sec_cam->ext_key) ++ clear_bit(sec_cam_idx + 1, cam_info->sec_cam_map); ++ ++ kfree(sec_cam); ++ ++ return ret; ++} ++ ++static void rtw89_cam_reset_key_iter(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ struct ieee80211_key_conf *key, ++ void *data) ++{ ++ struct rtw89_dev *rtwdev = (struct rtw89_dev *)data; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ ++ rtw89_cam_sec_key_del(rtwdev, vif, sta, key, false); ++ rtw89_cam_deinit(rtwdev, rtwvif); ++} ++ ++void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ struct rtw89_cam_info *cam_info = &rtwdev->cam_info; ++ struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam; ++ struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam; ++ ++ addr_cam->valid = false; ++ bssid_cam->valid = false; ++ clear_bit(addr_cam->addr_cam_idx, cam_info->addr_cam_map); ++ clear_bit(bssid_cam->bssid_cam_idx, cam_info->bssid_cam_map); ++} ++ ++void rtw89_cam_reset_keys(struct rtw89_dev *rtwdev) ++{ ++ rcu_read_lock(); ++ ieee80211_iter_keys_rcu(rtwdev->hw, NULL, rtw89_cam_reset_key_iter, rtwdev); ++ rcu_read_unlock(); ++} ++ ++static int rtw89_cam_get_avail_addr_cam(struct rtw89_dev *rtwdev, ++ u8 *addr_cam_idx) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_cam_info *cam_info = &rtwdev->cam_info; ++ u8 addr_cam_num = chip->acam_num; ++ u8 idx; ++ ++ idx = find_first_zero_bit(cam_info->addr_cam_map, addr_cam_num); ++ if (idx >= addr_cam_num) ++ return -EBUSY; ++ ++ set_bit(idx, cam_info->addr_cam_map); ++ *addr_cam_idx = idx; ++ ++ return 0; ++} ++ ++static int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam; ++ u8 addr_cam_idx; ++ int i; ++ int ret; ++ ++ ret = rtw89_cam_get_avail_addr_cam(rtwdev, &addr_cam_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to get available addr cam\n"); ++ return ret; ++ } ++ ++ addr_cam->addr_cam_idx = addr_cam_idx; ++ addr_cam->len = ADDR_CAM_ENT_SIZE; ++ addr_cam->offset = 0; ++ addr_cam->valid = true; ++ addr_cam->addr_mask = 0; ++ addr_cam->mask_sel = RTW89_NO_MSK; ++ bitmap_zero(addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM); ++ ether_addr_copy(addr_cam->sma, rtwvif->mac_addr); ++ ++ for (i = 0; i < RTW89_SEC_CAM_IN_ADDR_CAM; i++) { ++ addr_cam->sec_ent_keyid[i] = 0; ++ addr_cam->sec_ent[i] = 0; ++ } ++ ++ return 0; ++} ++ ++static int rtw89_cam_get_avail_bssid_cam(struct rtw89_dev *rtwdev, ++ u8 *bssid_cam_idx) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_cam_info *cam_info = &rtwdev->cam_info; ++ u8 bssid_cam_num = chip->bcam_num; ++ u8 idx; ++ ++ idx = find_first_zero_bit(cam_info->bssid_cam_map, bssid_cam_num); ++ if (idx >= bssid_cam_num) ++ return -EBUSY; ++ ++ set_bit(idx, cam_info->bssid_cam_map); ++ *bssid_cam_idx = idx; ++ ++ return 0; ++} ++ ++static int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam; ++ u8 bssid_cam_idx; ++ int ret; ++ ++ ret = rtw89_cam_get_avail_bssid_cam(rtwdev, &bssid_cam_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to get available bssid cam\n"); ++ return ret; ++ } ++ ++ bssid_cam->bssid_cam_idx = bssid_cam_idx; ++ bssid_cam->phy_idx = rtwvif->phy_idx; ++ bssid_cam->len = BSSID_CAM_ENT_SIZE; ++ bssid_cam->offset = 0; ++ bssid_cam->valid = true; ++ ether_addr_copy(bssid_cam->bssid, rtwvif->bssid); ++ ++ return 0; ++} ++ ++void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam; ++ struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam; ++ ++ if (vif->type == NL80211_IFTYPE_STATION) ++ ether_addr_copy(addr_cam->tma, rtwvif->bssid); ++ ether_addr_copy(bssid_cam->bssid, rtwvif->bssid); ++} ++ ++int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam; ++ struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam; ++ int ret; ++ ++ ret = rtw89_cam_init_addr_cam(rtwdev, rtwvif); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to init addr cam\n"); ++ return ret; ++ } ++ ++ ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to init bssid cam\n"); ++ return ret; ++ } ++ ++ /* associate addr cam with bssid cam */ ++ addr_cam->bssid_cam_idx = bssid_cam->bssid_cam_idx; ++ ++ return 0; ++} ++ ++int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, u8 *cmd) ++{ ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam; ++ u8 bss_color = vif->bss_conf.he_bss_color.color; ++ ++ FWCMD_SET_ADDR_BSSID_IDX(cmd, bssid_cam->bssid_cam_idx); ++ FWCMD_SET_ADDR_BSSID_OFFSET(cmd, bssid_cam->offset); ++ FWCMD_SET_ADDR_BSSID_LEN(cmd, bssid_cam->len); ++ FWCMD_SET_ADDR_BSSID_VALID(cmd, bssid_cam->valid); ++ FWCMD_SET_ADDR_BSSID_BB_SEL(cmd, bssid_cam->phy_idx); ++ FWCMD_SET_ADDR_BSSID_BSS_COLOR(cmd, bss_color); ++ ++ FWCMD_SET_ADDR_BSSID_BSSID0(cmd, bssid_cam->bssid[0]); ++ FWCMD_SET_ADDR_BSSID_BSSID1(cmd, bssid_cam->bssid[1]); ++ FWCMD_SET_ADDR_BSSID_BSSID2(cmd, bssid_cam->bssid[2]); ++ FWCMD_SET_ADDR_BSSID_BSSID3(cmd, bssid_cam->bssid[3]); ++ FWCMD_SET_ADDR_BSSID_BSSID4(cmd, bssid_cam->bssid[4]); ++ FWCMD_SET_ADDR_BSSID_BSSID5(cmd, bssid_cam->bssid[5]); ++ ++ return 0; ++} ++ ++static u8 rtw89_cam_addr_hash(u8 start, u8 *addr) ++{ ++ u8 hash = 0; ++ u8 i; ++ ++ for (i = start; i < ETH_ALEN; i++) ++ hash ^= addr[i]; ++ ++ return hash; ++} ++ ++void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, ++ u8 *cmd) ++{ ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ struct ieee80211_sta *sta; ++ struct rtw89_sta *rtwsta; ++ struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam; ++ u8 sma_hash, tma_hash, addr_msk_start; ++ u8 sma_start = 0; ++ u8 tma_start = 0; ++ ++ if (addr_cam->addr_mask != 0) { ++ addr_msk_start = __ffs(addr_cam->addr_mask); ++ if (addr_cam->mask_sel == RTW89_SMA) ++ sma_start = addr_msk_start; ++ else if (addr_cam->mask_sel == RTW89_TMA) ++ tma_start = addr_msk_start; ++ } ++ sma_hash = rtw89_cam_addr_hash(sma_start, rtwvif->mac_addr); ++ tma_hash = rtw89_cam_addr_hash(tma_start, addr_cam->tma); ++ ++ FWCMD_SET_ADDR_IDX(cmd, addr_cam->addr_cam_idx); ++ FWCMD_SET_ADDR_OFFSET(cmd, addr_cam->offset); ++ FWCMD_SET_ADDR_LEN(cmd, addr_cam->len); ++ ++ FWCMD_SET_ADDR_VALID(cmd, addr_cam->valid); ++ FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif->net_type); ++ FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif->bcn_hit_cond); ++ FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif->hit_rule); ++ FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif->phy_idx); ++ FWCMD_SET_ADDR_ADDR_MASK(cmd, addr_cam->addr_mask); ++ FWCMD_SET_ADDR_MASK_SEL(cmd, addr_cam->mask_sel); ++ FWCMD_SET_ADDR_SMA_HASH(cmd, sma_hash); ++ FWCMD_SET_ADDR_TMA_HASH(cmd, tma_hash); ++ ++ FWCMD_SET_ADDR_BSSID_CAM_IDX(cmd, addr_cam->bssid_cam_idx); ++ ++ FWCMD_SET_ADDR_SMA0(cmd, rtwvif->mac_addr[0]); ++ FWCMD_SET_ADDR_SMA1(cmd, rtwvif->mac_addr[1]); ++ FWCMD_SET_ADDR_SMA2(cmd, rtwvif->mac_addr[2]); ++ FWCMD_SET_ADDR_SMA3(cmd, rtwvif->mac_addr[3]); ++ FWCMD_SET_ADDR_SMA4(cmd, rtwvif->mac_addr[4]); ++ FWCMD_SET_ADDR_SMA5(cmd, rtwvif->mac_addr[5]); ++ ++ FWCMD_SET_ADDR_TMA0(cmd, addr_cam->tma[0]); ++ FWCMD_SET_ADDR_TMA1(cmd, addr_cam->tma[1]); ++ FWCMD_SET_ADDR_TMA2(cmd, addr_cam->tma[2]); ++ FWCMD_SET_ADDR_TMA3(cmd, addr_cam->tma[3]); ++ FWCMD_SET_ADDR_TMA4(cmd, addr_cam->tma[4]); ++ FWCMD_SET_ADDR_TMA5(cmd, addr_cam->tma[5]); ++ ++ FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif->port); ++ FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif->port); ++ FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif->trigger); ++ FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif->lsig_txop); ++ FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif->tgt_ind); ++ FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif->frm_tgt_ind); ++ ++ if (vif->type == NL80211_IFTYPE_STATION) { ++ sta = rtwvif->mgd.ap; ++ if (sta) { ++ rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ FWCMD_SET_ADDR_MACID(cmd, rtwsta->mac_id); ++ FWCMD_SET_ADDR_AID12(cmd, vif->bss_conf.aid & 0xfff); ++ } ++ } ++ FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif->wowlan_pattern); ++ FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif->wowlan_uc); ++ FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif->wowlan_magic); ++ FWCMD_SET_ADDR_WAPI(cmd, addr_cam->wapi); ++ FWCMD_SET_ADDR_SEC_ENT_MODE(cmd, addr_cam->sec_ent_mode); ++ FWCMD_SET_ADDR_SEC_ENT0_KEYID(cmd, addr_cam->sec_ent_keyid[0]); ++ FWCMD_SET_ADDR_SEC_ENT1_KEYID(cmd, addr_cam->sec_ent_keyid[1]); ++ FWCMD_SET_ADDR_SEC_ENT2_KEYID(cmd, addr_cam->sec_ent_keyid[2]); ++ FWCMD_SET_ADDR_SEC_ENT3_KEYID(cmd, addr_cam->sec_ent_keyid[3]); ++ FWCMD_SET_ADDR_SEC_ENT4_KEYID(cmd, addr_cam->sec_ent_keyid[4]); ++ FWCMD_SET_ADDR_SEC_ENT5_KEYID(cmd, addr_cam->sec_ent_keyid[5]); ++ FWCMD_SET_ADDR_SEC_ENT6_KEYID(cmd, addr_cam->sec_ent_keyid[6]); ++ ++ FWCMD_SET_ADDR_SEC_ENT_VALID(cmd, addr_cam->sec_cam_map[0] & 0xff); ++ FWCMD_SET_ADDR_SEC_ENT0(cmd, addr_cam->sec_ent[0]); ++ FWCMD_SET_ADDR_SEC_ENT1(cmd, addr_cam->sec_ent[1]); ++ FWCMD_SET_ADDR_SEC_ENT2(cmd, addr_cam->sec_ent[2]); ++ FWCMD_SET_ADDR_SEC_ENT3(cmd, addr_cam->sec_ent[3]); ++ FWCMD_SET_ADDR_SEC_ENT4(cmd, addr_cam->sec_ent[4]); ++ FWCMD_SET_ADDR_SEC_ENT5(cmd, addr_cam->sec_ent[5]); ++ FWCMD_SET_ADDR_SEC_ENT6(cmd, addr_cam->sec_ent[6]); ++} +diff --git a/drivers/net/wireless/realtek/rtw89/cam.h b/drivers/net/wireless/realtek/rtw89/cam.h +new file mode 100644 +index 000000000000..90a20a5375c6 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/cam.h +@@ -0,0 +1,165 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_CAM_H__ ++#define __RTW89_CAM_H__ ++ ++#include "core.h" ++ ++#define RTW89_SEC_CAM_LEN 20 ++ ++#define FWCMD_SET_ADDR_IDX(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 1, value, GENMASK(7, 0)) ++#define FWCMD_SET_ADDR_OFFSET(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 1, value, GENMASK(15, 8)) ++#define FWCMD_SET_ADDR_LEN(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 1, value, GENMASK(23, 16)) ++#define FWCMD_SET_ADDR_VALID(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 2, value, BIT(0)) ++#define FWCMD_SET_ADDR_NET_TYPE(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(2, 1)) ++#define FWCMD_SET_ADDR_BCN_HIT_COND(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(4, 3)) ++#define FWCMD_SET_ADDR_HIT_RULE(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(6, 5)) ++#define FWCMD_SET_ADDR_BB_SEL(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 2, value, BIT(7)) ++#define FWCMD_SET_ADDR_ADDR_MASK(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(13, 8)) ++#define FWCMD_SET_ADDR_MASK_SEL(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(15, 14)) ++#define FWCMD_SET_ADDR_SMA_HASH(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(23, 16)) ++#define FWCMD_SET_ADDR_TMA_HASH(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(31, 24)) ++#define FWCMD_SET_ADDR_BSSID_CAM_IDX(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 3, value, GENMASK(5, 0)) ++#define FWCMD_SET_ADDR_SMA0(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(7, 0)) ++#define FWCMD_SET_ADDR_SMA1(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(15, 8)) ++#define FWCMD_SET_ADDR_SMA2(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(23, 16)) ++#define FWCMD_SET_ADDR_SMA3(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(31, 24)) ++#define FWCMD_SET_ADDR_SMA4(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(7, 0)) ++#define FWCMD_SET_ADDR_SMA5(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(15, 8)) ++#define FWCMD_SET_ADDR_TMA0(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(23, 16)) ++#define FWCMD_SET_ADDR_TMA1(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(31, 24)) ++#define FWCMD_SET_ADDR_TMA2(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(7, 0)) ++#define FWCMD_SET_ADDR_TMA3(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(15, 8)) ++#define FWCMD_SET_ADDR_TMA4(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(23, 16)) ++#define FWCMD_SET_ADDR_TMA5(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(31, 24)) ++#define FWCMD_SET_ADDR_MACID(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(7, 0)) ++#define FWCMD_SET_ADDR_PORT_INT(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(10, 8)) ++#define FWCMD_SET_ADDR_TSF_SYNC(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(13, 11)) ++#define FWCMD_SET_ADDR_TF_TRS(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 8, value, BIT(14)) ++#define FWCMD_SET_ADDR_LSIG_TXOP(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 8, value, BIT(15)) ++#define FWCMD_SET_ADDR_TGT_IND(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(26, 24)) ++#define FWCMD_SET_ADDR_FRM_TGT_IND(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(29, 27)) ++#define FWCMD_SET_ADDR_AID12(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(11, 0)) ++#define FWCMD_SET_ADDR_AID12_0(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(7, 0)) ++#define FWCMD_SET_ADDR_AID12_1(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(11, 8)) ++#define FWCMD_SET_ADDR_WOL_PATTERN(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(12)) ++#define FWCMD_SET_ADDR_WOL_UC(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(13)) ++#define FWCMD_SET_ADDR_WOL_MAGIC(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(14)) ++#define FWCMD_SET_ADDR_WAPI(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(15)) ++#define FWCMD_SET_ADDR_SEC_ENT_MODE(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(17, 16)) ++#define FWCMD_SET_ADDR_SEC_ENT0_KEYID(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(19, 18)) ++#define FWCMD_SET_ADDR_SEC_ENT1_KEYID(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(21, 20)) ++#define FWCMD_SET_ADDR_SEC_ENT2_KEYID(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(23, 22)) ++#define FWCMD_SET_ADDR_SEC_ENT3_KEYID(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(25, 24)) ++#define FWCMD_SET_ADDR_SEC_ENT4_KEYID(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(27, 26)) ++#define FWCMD_SET_ADDR_SEC_ENT5_KEYID(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(29, 28)) ++#define FWCMD_SET_ADDR_SEC_ENT6_KEYID(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(31, 30)) ++#define FWCMD_SET_ADDR_SEC_ENT_VALID(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(7, 0)) ++#define FWCMD_SET_ADDR_SEC_ENT0(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(15, 8)) ++#define FWCMD_SET_ADDR_SEC_ENT1(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(23, 16)) ++#define FWCMD_SET_ADDR_SEC_ENT2(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(31, 24)) ++#define FWCMD_SET_ADDR_SEC_ENT3(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(7, 0)) ++#define FWCMD_SET_ADDR_SEC_ENT4(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(15, 8)) ++#define FWCMD_SET_ADDR_SEC_ENT5(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(23, 16)) ++#define FWCMD_SET_ADDR_SEC_ENT6(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(31, 24)) ++#define FWCMD_SET_ADDR_BSSID_IDX(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 12, value, GENMASK(7, 0)) ++#define FWCMD_SET_ADDR_BSSID_OFFSET(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 12, value, GENMASK(15, 8)) ++#define FWCMD_SET_ADDR_BSSID_LEN(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 12, value, GENMASK(23, 16)) ++#define FWCMD_SET_ADDR_BSSID_VALID(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 13, value, BIT(0)) ++#define FWCMD_SET_ADDR_BSSID_BB_SEL(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 13, value, BIT(1)) ++#define FWCMD_SET_ADDR_BSSID_BSS_COLOR(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 13, value, GENMASK(13, 8)) ++#define FWCMD_SET_ADDR_BSSID_BSSID0(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 13, value, GENMASK(23, 16)) ++#define FWCMD_SET_ADDR_BSSID_BSSID1(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 13, value, GENMASK(31, 24)) ++#define FWCMD_SET_ADDR_BSSID_BSSID2(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(7, 0)) ++#define FWCMD_SET_ADDR_BSSID_BSSID3(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(15, 8)) ++#define FWCMD_SET_ADDR_BSSID_BSSID4(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(23, 16)) ++#define FWCMD_SET_ADDR_BSSID_BSSID5(cmd, value) \ ++ le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(31, 24)) ++ ++int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); ++void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); ++void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *vif, u8 *cmd); ++int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *vif, u8 *cmd); ++int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ struct ieee80211_key_conf *key); ++int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ struct ieee80211_key_conf *key, ++ bool inform_fw); ++void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif); ++void rtw89_cam_reset_keys(struct rtw89_dev *rtwdev); ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +new file mode 100644 +index 000000000000..abe4b6549ab2 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -0,0 +1,5716 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "coex.h" ++#include "debug.h" ++#include "fw.h" ++#include "mac.h" ++#include "ps.h" ++#include "reg.h" ++ ++#define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/ ++ ++enum btc_fbtc_tdma_template { ++ CXTD_OFF = 0x0, ++ CXTD_OFF_B2, ++ CXTD_OFF_EXT, ++ CXTD_FIX, ++ CXTD_PFIX, ++ CXTD_AUTO, ++ CXTD_PAUTO, ++ CXTD_AUTO2, ++ CXTD_PAUTO2, ++ CXTD_MAX, ++}; ++ ++enum btc_fbtc_tdma_type { ++ CXTDMA_OFF = 0x0, ++ CXTDMA_FIX = 0x1, ++ CXTDMA_AUTO = 0x2, ++ CXTDMA_AUTO2 = 0x3, ++ CXTDMA_MAX ++}; ++ ++enum btc_fbtc_tdma_rx_flow_ctrl { ++ CXFLC_OFF = 0x0, ++ CXFLC_NULLP = 0x1, ++ CXFLC_QOSNULL = 0x2, ++ CXFLC_CTS = 0x3, ++ CXFLC_MAX ++}; ++ ++enum btc_fbtc_tdma_wlan_tx_pause { ++ CXTPS_OFF = 0x0, /* no wl tx pause*/ ++ CXTPS_ON = 0x1, ++ CXTPS_MAX ++}; ++ ++enum btc_mlme_state { ++ MLME_NO_LINK, ++ MLME_LINKING, ++ MLME_LINKED, ++}; ++ ++#define FCXONESLOT_VER 1 ++struct btc_fbtc_1slot { ++ u8 fver; ++ u8 sid; /* slot id */ ++ struct rtw89_btc_fbtc_slot slot; ++} __packed; ++ ++static const struct rtw89_btc_fbtc_tdma t_def[] = { ++ [CXTD_OFF] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, ++ [CXTD_OFF_B2] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 1, 0, 0}, ++ [CXTD_OFF_EXT] = { CXTDMA_OFF, CXFLC_OFF, CXTPS_OFF, 0, 0, 3, 0, 0}, ++ [CXTD_FIX] = { CXTDMA_FIX, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, ++ [CXTD_PFIX] = { CXTDMA_FIX, CXFLC_NULLP, CXTPS_ON, 0, 5, 0, 0, 0}, ++ [CXTD_AUTO] = { CXTDMA_AUTO, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, ++ [CXTD_PAUTO] = { CXTDMA_AUTO, CXFLC_NULLP, CXTPS_ON, 0, 5, 0, 0, 0}, ++ [CXTD_AUTO2] = {CXTDMA_AUTO2, CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0}, ++ [CXTD_PAUTO2] = {CXTDMA_AUTO2, CXFLC_NULLP, CXTPS_ON, 0, 5, 0, 0, 0} ++}; ++ ++#define __DEF_FBTC_SLOT(__dur, __cxtbl, __cxtype) \ ++ { .dur = cpu_to_le16(__dur), .cxtbl = cpu_to_le32(__cxtbl), \ ++ .cxtype = cpu_to_le16(__cxtype),} ++ ++static const struct rtw89_btc_fbtc_slot s_def[] = { ++ [CXST_OFF] = __DEF_FBTC_SLOT(100, 0x55555555, SLOT_MIX), ++ [CXST_B2W] = __DEF_FBTC_SLOT(5, 0x5a5a5a5a, SLOT_ISO), ++ [CXST_W1] = __DEF_FBTC_SLOT(70, 0x5a5a5a5a, SLOT_ISO), ++ [CXST_W2] = __DEF_FBTC_SLOT(70, 0x5a5a5aaa, SLOT_ISO), ++ [CXST_W2B] = __DEF_FBTC_SLOT(15, 0x5a5a5a5a, SLOT_ISO), ++ [CXST_B1] = __DEF_FBTC_SLOT(100, 0x55555555, SLOT_MIX), ++ [CXST_B2] = __DEF_FBTC_SLOT(7, 0x6a5a5a5a, SLOT_MIX), ++ [CXST_B3] = __DEF_FBTC_SLOT(5, 0x55555555, SLOT_MIX), ++ [CXST_B4] = __DEF_FBTC_SLOT(50, 0x55555555, SLOT_MIX), ++ [CXST_LK] = __DEF_FBTC_SLOT(20, 0x5a5a5a5a, SLOT_ISO), ++ [CXST_BLK] = __DEF_FBTC_SLOT(250, 0x55555555, SLOT_MIX), ++ [CXST_E2G] = __DEF_FBTC_SLOT(20, 0x6a5a5a5a, SLOT_MIX), ++ [CXST_E5G] = __DEF_FBTC_SLOT(20, 0xffffffff, SLOT_MIX), ++ [CXST_EBT] = __DEF_FBTC_SLOT(20, 0x55555555, SLOT_MIX), ++ [CXST_ENULL] = __DEF_FBTC_SLOT(7, 0xaaaaaaaa, SLOT_ISO), ++ [CXST_WLK] = __DEF_FBTC_SLOT(250, 0x6a5a6a5a, SLOT_MIX), ++ [CXST_W1FDD] = __DEF_FBTC_SLOT(35, 0xfafafafa, SLOT_ISO), ++ [CXST_B1FDD] = __DEF_FBTC_SLOT(100, 0xffffffff, SLOT_MIX), ++}; ++ ++static const u32 cxtbl[] = { ++ 0xffffffff, /* 0 */ ++ 0xaaaaaaaa, /* 1 */ ++ 0x55555555, /* 2 */ ++ 0x66555555, /* 3 */ ++ 0x66556655, /* 4 */ ++ 0x5a5a5a5a, /* 5 */ ++ 0x5a5a5aaa, /* 6 */ ++ 0xaa5a5a5a, /* 7 */ ++ 0x6a5a5a5a, /* 8 */ ++ 0x6a5a5aaa, /* 9 */ ++ 0x6a5a6a5a, /* 10 */ ++ 0x6a5a6aaa, /* 11 */ ++ 0x6afa5afa, /* 12 */ ++ 0xaaaa5aaa, /* 13 */ ++ 0xaaffffaa, /* 14 */ ++ 0xaa5555aa, /* 15 */ ++ 0xfafafafa, /* 16 */ ++ 0xffffddff, /* 17 */ ++ 0xdaffdaff, /* 18 */ ++ 0xfafadafa /* 19 */ ++}; ++ ++struct rtw89_btc_btf_tlv { ++ u8 type; ++ u8 len; ++ u8 val[1]; ++} __packed; ++ ++enum btc_btf_set_report_en { ++ RPT_EN_TDMA = BIT(0), ++ RPT_EN_CYCLE = BIT(1), ++ RPT_EN_MREG = BIT(2), ++ RPT_EN_BT_VER_INFO = BIT(3), ++ RPT_EN_BT_SCAN_INFO = BIT(4), ++ RPT_EN_BT_AFH_MAP = BIT(5), ++ RPT_EN_BT_DEVICE_INFO = BIT(6), ++ RPT_EN_WL_ALL = GENMASK(2, 0), ++ RPT_EN_BT_ALL = GENMASK(6, 3), ++ RPT_EN_ALL = GENMASK(6, 0), ++}; ++ ++#define BTF_SET_REPORT_VER 1 ++struct rtw89_btc_btf_set_report { ++ u8 fver; ++ __le32 enable; ++ __le32 para; ++} __packed; ++ ++#define BTF_SET_SLOT_TABLE_VER 1 ++struct rtw89_btc_btf_set_slot_table { ++ u8 fver; ++ u8 tbl_num; ++ u8 buf[]; ++} __packed; ++ ++#define BTF_SET_MON_REG_VER 1 ++struct rtw89_btc_btf_set_mon_reg { ++ u8 fver; ++ u8 reg_num; ++ u8 buf[]; ++} __packed; ++ ++enum btc_btf_set_cx_policy { ++ CXPOLICY_TDMA = 0x0, ++ CXPOLICY_SLOT = 0x1, ++ CXPOLICY_TYPE = 0x2, ++ CXPOLICY_MAX, ++}; ++ ++enum btc_b2w_scoreboard { ++ BTC_BSCB_ACT = BIT(0), ++ BTC_BSCB_ON = BIT(1), ++ BTC_BSCB_WHQL = BIT(2), ++ BTC_BSCB_BT_S1 = BIT(3), ++ BTC_BSCB_A2DP_ACT = BIT(4), ++ BTC_BSCB_RFK_RUN = BIT(5), ++ BTC_BSCB_RFK_REQ = BIT(6), ++ BTC_BSCB_LPS = BIT(7), ++ BTC_BSCB_WLRFK = BIT(11), ++ BTC_BSCB_BT_HILNA = BIT(13), ++ BTC_BSCB_BT_CONNECT = BIT(16), ++ BTC_BSCB_PATCH_CODE = BIT(30), ++ BTC_BSCB_ALL = GENMASK(30, 0), ++}; ++ ++enum btc_phymap { ++ BTC_PHY_0 = BIT(0), ++ BTC_PHY_1 = BIT(1), ++ BTC_PHY_ALL = BIT(0) | BIT(1), ++}; ++ ++enum btc_cx_state_map { ++ BTC_WIDLE = 0, ++ BTC_WBUSY_BNOSCAN, ++ BTC_WBUSY_BSCAN, ++ BTC_WSCAN_BNOSCAN, ++ BTC_WSCAN_BSCAN, ++ BTC_WLINKING ++}; ++ ++enum btc_ant_phase { ++ BTC_ANT_WPOWERON = 0, ++ BTC_ANT_WINIT, ++ BTC_ANT_WONLY, ++ BTC_ANT_WOFF, ++ BTC_ANT_W2G, ++ BTC_ANT_W5G, ++ BTC_ANT_W25G, ++ BTC_ANT_FREERUN, ++ BTC_ANT_WRFK, ++ BTC_ANT_BRFK, ++ BTC_ANT_MAX ++}; ++ ++enum btc_plt { ++ BTC_PLT_NONE = 0, ++ BTC_PLT_LTE_RX = BIT(0), ++ BTC_PLT_GNT_BT_TX = BIT(1), ++ BTC_PLT_GNT_BT_RX = BIT(2), ++ BTC_PLT_GNT_WL = BIT(3), ++ BTC_PLT_BT = BIT(1) | BIT(2), ++ BTC_PLT_ALL = 0xf ++}; ++ ++enum btc_cx_poicy_main_type { ++ BTC_CXP_OFF = 0, ++ BTC_CXP_OFFB, ++ BTC_CXP_OFFE, ++ BTC_CXP_FIX, ++ BTC_CXP_PFIX, ++ BTC_CXP_AUTO, ++ BTC_CXP_PAUTO, ++ BTC_CXP_AUTO2, ++ BTC_CXP_PAUTO2, ++ BTC_CXP_MANUAL, ++ BTC_CXP_USERDEF0, ++ BTC_CXP_MAIN_MAX ++}; ++ ++enum btc_cx_poicy_type { ++ /* TDMA off + pri: BT > WL */ ++ BTC_CXP_OFF_BT = (BTC_CXP_OFF << 8) | 0, ++ ++ /* TDMA off + pri: WL > BT */ ++ BTC_CXP_OFF_WL = (BTC_CXP_OFF << 8) | 1, ++ ++ /* TDMA off + pri: BT = WL */ ++ BTC_CXP_OFF_EQ0 = (BTC_CXP_OFF << 8) | 2, ++ ++ /* TDMA off + pri: BT = WL > BT_Lo */ ++ BTC_CXP_OFF_EQ1 = (BTC_CXP_OFF << 8) | 3, ++ ++ /* TDMA off + pri: WL = BT, BT_Rx > WL_Lo_Tx */ ++ BTC_CXP_OFF_EQ2 = (BTC_CXP_OFF << 8) | 4, ++ ++ /* TDMA off + pri: WL_Rx = BT, BT_HI > WL_Tx > BT_Lo */ ++ BTC_CXP_OFF_EQ3 = (BTC_CXP_OFF << 8) | 5, ++ ++ /* TDMA off + pri: BT_Hi > WL > BT_Lo */ ++ BTC_CXP_OFF_BWB0 = (BTC_CXP_OFF << 8) | 6, ++ ++ /* TDMA off + pri: WL_Hi-Tx > BT_Hi_Rx, BT_Hi > WL > BT_Lo */ ++ BTC_CXP_OFF_BWB1 = (BTC_CXP_OFF << 8) | 7, ++ ++ /* TDMA off+Bcn-Protect + pri: WL_Hi-Tx > BT_Hi_Rx, BT_Hi > WL > BT_Lo*/ ++ BTC_CXP_OFFB_BWB0 = (BTC_CXP_OFFB << 8) | 0, ++ ++ /* TDMA off + Ext-Ctrl + pri: default */ ++ BTC_CXP_OFFE_DEF = (BTC_CXP_OFFE << 8) | 0, ++ ++ /* TDMA off + Ext-Ctrl + pri: E2G-slot block all BT */ ++ BTC_CXP_OFFE_DEF2 = (BTC_CXP_OFFE << 8) | 1, ++ ++ /* TDMA Fix slot-0: W1:B1 = 30:30 */ ++ BTC_CXP_FIX_TD3030 = (BTC_CXP_FIX << 8) | 0, ++ ++ /* TDMA Fix slot-1: W1:B1 = 50:50 */ ++ BTC_CXP_FIX_TD5050 = (BTC_CXP_FIX << 8) | 1, ++ ++ /* TDMA Fix slot-2: W1:B1 = 20:30 */ ++ BTC_CXP_FIX_TD2030 = (BTC_CXP_FIX << 8) | 2, ++ ++ /* TDMA Fix slot-3: W1:B1 = 40:10 */ ++ BTC_CXP_FIX_TD4010 = (BTC_CXP_FIX << 8) | 3, ++ ++ /* TDMA Fix slot-4: W1:B1 = 70:10 */ ++ BTC_CXP_FIX_TD7010 = (BTC_CXP_FIX << 8) | 4, ++ ++ /* TDMA Fix slot-5: W1:B1 = 20:60 */ ++ BTC_CXP_FIX_TD2060 = (BTC_CXP_FIX << 8) | 5, ++ ++ /* TDMA Fix slot-6: W1:B1 = 30:60 */ ++ BTC_CXP_FIX_TD3060 = (BTC_CXP_FIX << 8) | 6, ++ ++ /* TDMA Fix slot-7: W1:B1 = 20:80 */ ++ BTC_CXP_FIX_TD2080 = (BTC_CXP_FIX << 8) | 7, ++ ++ /* TDMA Fix slot-8: W1:B1 = user-define */ ++ BTC_CXP_FIX_TDW1B1 = (BTC_CXP_FIX << 8) | 8, ++ ++ /* TDMA Fix slot-9: W1:B1 = 40:20 */ ++ BTC_CXP_FIX_TD4020 = (BTC_CXP_FIX << 8) | 9, ++ ++ /* PS-TDMA Fix slot-0: W1:B1 = 30:30 */ ++ BTC_CXP_PFIX_TD3030 = (BTC_CXP_PFIX << 8) | 0, ++ ++ /* PS-TDMA Fix slot-1: W1:B1 = 50:50 */ ++ BTC_CXP_PFIX_TD5050 = (BTC_CXP_PFIX << 8) | 1, ++ ++ /* PS-TDMA Fix slot-2: W1:B1 = 20:30 */ ++ BTC_CXP_PFIX_TD2030 = (BTC_CXP_PFIX << 8) | 2, ++ ++ /* PS-TDMA Fix slot-3: W1:B1 = 20:60 */ ++ BTC_CXP_PFIX_TD2060 = (BTC_CXP_PFIX << 8) | 3, ++ ++ /* PS-TDMA Fix slot-4: W1:B1 = 30:70 */ ++ BTC_CXP_PFIX_TD3070 = (BTC_CXP_PFIX << 8) | 4, ++ ++ /* PS-TDMA Fix slot-5: W1:B1 = 20:80 */ ++ BTC_CXP_PFIX_TD2080 = (BTC_CXP_PFIX << 8) | 5, ++ ++ /* PS-TDMA Fix slot-6: W1:B1 = user-define */ ++ BTC_CXP_PFIX_TDW1B1 = (BTC_CXP_PFIX << 8) | 6, ++ ++ /* TDMA Auto slot-0: W1:B1 = 50:200 */ ++ BTC_CXP_AUTO_TD50200 = (BTC_CXP_AUTO << 8) | 0, ++ ++ /* TDMA Auto slot-1: W1:B1 = 60:200 */ ++ BTC_CXP_AUTO_TD60200 = (BTC_CXP_AUTO << 8) | 1, ++ ++ /* TDMA Auto slot-2: W1:B1 = 20:200 */ ++ BTC_CXP_AUTO_TD20200 = (BTC_CXP_AUTO << 8) | 2, ++ ++ /* TDMA Auto slot-3: W1:B1 = user-define */ ++ BTC_CXP_AUTO_TDW1B1 = (BTC_CXP_AUTO << 8) | 3, ++ ++ /* PS-TDMA Auto slot-0: W1:B1 = 50:200 */ ++ BTC_CXP_PAUTO_TD50200 = (BTC_CXP_PAUTO << 8) | 0, ++ ++ /* PS-TDMA Auto slot-1: W1:B1 = 60:200 */ ++ BTC_CXP_PAUTO_TD60200 = (BTC_CXP_PAUTO << 8) | 1, ++ ++ /* PS-TDMA Auto slot-2: W1:B1 = 20:200 */ ++ BTC_CXP_PAUTO_TD20200 = (BTC_CXP_PAUTO << 8) | 2, ++ ++ /* PS-TDMA Auto slot-3: W1:B1 = user-define */ ++ BTC_CXP_PAUTO_TDW1B1 = (BTC_CXP_PAUTO << 8) | 3, ++ ++ /* TDMA Auto slot2-0: W1:B4 = 30:50 */ ++ BTC_CXP_AUTO2_TD3050 = (BTC_CXP_AUTO2 << 8) | 0, ++ ++ /* TDMA Auto slot2-1: W1:B4 = 30:70 */ ++ BTC_CXP_AUTO2_TD3070 = (BTC_CXP_AUTO2 << 8) | 1, ++ ++ /* TDMA Auto slot2-2: W1:B4 = 50:50 */ ++ BTC_CXP_AUTO2_TD5050 = (BTC_CXP_AUTO2 << 8) | 2, ++ ++ /* TDMA Auto slot2-3: W1:B4 = 60:60 */ ++ BTC_CXP_AUTO2_TD6060 = (BTC_CXP_AUTO2 << 8) | 3, ++ ++ /* TDMA Auto slot2-4: W1:B4 = 20:80 */ ++ BTC_CXP_AUTO2_TD2080 = (BTC_CXP_AUTO2 << 8) | 4, ++ ++ /* TDMA Auto slot2-5: W1:B4 = user-define */ ++ BTC_CXP_AUTO2_TDW1B4 = (BTC_CXP_AUTO2 << 8) | 5, ++ ++ /* PS-TDMA Auto slot2-0: W1:B4 = 30:50 */ ++ BTC_CXP_PAUTO2_TD3050 = (BTC_CXP_PAUTO2 << 8) | 0, ++ ++ /* PS-TDMA Auto slot2-1: W1:B4 = 30:70 */ ++ BTC_CXP_PAUTO2_TD3070 = (BTC_CXP_PAUTO2 << 8) | 1, ++ ++ /* PS-TDMA Auto slot2-2: W1:B4 = 50:50 */ ++ BTC_CXP_PAUTO2_TD5050 = (BTC_CXP_PAUTO2 << 8) | 2, ++ ++ /* PS-TDMA Auto slot2-3: W1:B4 = 60:60 */ ++ BTC_CXP_PAUTO2_TD6060 = (BTC_CXP_PAUTO2 << 8) | 3, ++ ++ /* PS-TDMA Auto slot2-4: W1:B4 = 20:80 */ ++ BTC_CXP_PAUTO2_TD2080 = (BTC_CXP_PAUTO2 << 8) | 4, ++ ++ /* PS-TDMA Auto slot2-5: W1:B4 = user-define */ ++ BTC_CXP_PAUTO2_TDW1B4 = (BTC_CXP_PAUTO2 << 8) | 5, ++ ++ BTC_CXP_MAX = 0xffff ++}; ++ ++enum btc_wl_rfk_result { ++ BTC_WRFK_REJECT = 0, ++ BTC_WRFK_ALLOW = 1, ++}; ++ ++enum btc_coex_info_map_en { ++ BTC_COEX_INFO_CX = BIT(0), ++ BTC_COEX_INFO_WL = BIT(1), ++ BTC_COEX_INFO_BT = BIT(2), ++ BTC_COEX_INFO_DM = BIT(3), ++ BTC_COEX_INFO_MREG = BIT(4), ++ BTC_COEX_INFO_SUMMARY = BIT(5), ++ BTC_COEX_INFO_ALL = GENMASK(7, 0), ++}; ++ ++#define BTC_CXP_MASK GENMASK(15, 8) ++ ++enum btc_w2b_scoreboard { ++ BTC_WSCB_ACTIVE = BIT(0), ++ BTC_WSCB_ON = BIT(1), ++ BTC_WSCB_SCAN = BIT(2), ++ BTC_WSCB_UNDERTEST = BIT(3), ++ BTC_WSCB_RXGAIN = BIT(4), ++ BTC_WSCB_WLBUSY = BIT(7), ++ BTC_WSCB_EXTFEM = BIT(8), ++ BTC_WSCB_TDMA = BIT(9), ++ BTC_WSCB_FIX2M = BIT(10), ++ BTC_WSCB_WLRFK = BIT(11), ++ BTC_WSCB_BTRFK_GNT = BIT(12), /* not used, use mailbox to inform BT */ ++ BTC_WSCB_BT_HILNA = BIT(13), ++ BTC_WSCB_BTLOG = BIT(14), ++ BTC_WSCB_ALL = GENMASK(23, 0), ++}; ++ ++enum btc_wl_link_mode { ++ BTC_WLINK_NOLINK = 0x0, ++ BTC_WLINK_2G_STA, ++ BTC_WLINK_2G_AP, ++ BTC_WLINK_2G_GO, ++ BTC_WLINK_2G_GC, ++ BTC_WLINK_2G_SCC, ++ BTC_WLINK_2G_MCC, ++ BTC_WLINK_25G_MCC, ++ BTC_WLINK_25G_DBCC, ++ BTC_WLINK_5G, ++ BTC_WLINK_2G_NAN, ++ BTC_WLINK_OTHER, ++ BTC_WLINK_MAX ++}; ++ ++enum btc_bt_hid_type { ++ BTC_HID_218 = BIT(0), ++ BTC_HID_418 = BIT(1), ++ BTC_HID_BLE = BIT(2), ++ BTC_HID_RCU = BIT(3), ++ BTC_HID_RCU_VOICE = BIT(4), ++ BTC_HID_OTHER_LEGACY = BIT(5) ++}; ++ ++enum btc_reset_module { ++ BTC_RESET_CX = BIT(0), ++ BTC_RESET_DM = BIT(1), ++ BTC_RESET_CTRL = BIT(2), ++ BTC_RESET_CXDM = BIT(0) | BIT(1), ++ BTC_RESET_BTINFO = BIT(3), ++ BTC_RESET_MDINFO = BIT(4), ++ BTC_RESET_ALL = GENMASK(7, 0), ++}; ++ ++enum btc_gnt_state { ++ BTC_GNT_HW = 0, ++ BTC_GNT_SW_LO, ++ BTC_GNT_SW_HI, ++ BTC_GNT_MAX ++}; ++ ++enum btc_wl_max_tx_time { ++ BTC_MAX_TX_TIME_L1 = 500, ++ BTC_MAX_TX_TIME_L2 = 1000, ++ BTC_MAX_TX_TIME_L3 = 2000, ++ BTC_MAX_TX_TIME_DEF = 5280 ++}; ++ ++enum btc_wl_max_tx_retry { ++ BTC_MAX_TX_RETRY_L1 = 7, ++ BTC_MAX_TX_RETRY_L2 = 15, ++ BTC_MAX_TX_RETRY_DEF = 31, ++}; ++ ++enum btc_reason_and_action { ++ BTC_RSN_NONE, ++ BTC_RSN_NTFY_INIT, ++ BTC_RSN_NTFY_SWBAND, ++ BTC_RSN_NTFY_WL_STA, ++ BTC_RSN_NTFY_RADIO_STATE, ++ BTC_RSN_UPDATE_BT_SCBD, ++ BTC_RSN_NTFY_WL_RFK, ++ BTC_RSN_UPDATE_BT_INFO, ++ BTC_RSN_NTFY_SCAN_START, ++ BTC_RSN_NTFY_SCAN_FINISH, ++ BTC_RSN_NTFY_SPECIFIC_PACKET, ++ BTC_RSN_NTFY_POWEROFF, ++ BTC_RSN_NTFY_ROLE_INFO, ++ BTC_RSN_CMD_SET_COEX, ++ BTC_RSN_ACT1_WORK, ++ BTC_RSN_BT_DEVINFO_WORK, ++ BTC_RSN_RFK_CHK_WORK, ++ BTC_RSN_NUM, ++ BTC_ACT_NONE = 100, ++ BTC_ACT_WL_ONLY, ++ BTC_ACT_WL_5G, ++ BTC_ACT_WL_OTHER, ++ BTC_ACT_WL_IDLE, ++ BTC_ACT_WL_NC, ++ BTC_ACT_WL_RFK, ++ BTC_ACT_WL_INIT, ++ BTC_ACT_WL_OFF, ++ BTC_ACT_FREERUN, ++ BTC_ACT_BT_WHQL, ++ BTC_ACT_BT_RFK, ++ BTC_ACT_BT_OFF, ++ BTC_ACT_BT_IDLE, ++ BTC_ACT_BT_HFP, ++ BTC_ACT_BT_HID, ++ BTC_ACT_BT_A2DP, ++ BTC_ACT_BT_A2DPSINK, ++ BTC_ACT_BT_PAN, ++ BTC_ACT_BT_A2DP_HID, ++ BTC_ACT_BT_A2DP_PAN, ++ BTC_ACT_BT_PAN_HID, ++ BTC_ACT_BT_A2DP_PAN_HID, ++ BTC_ACT_WL_25G_MCC, ++ BTC_ACT_WL_2G_MCC, ++ BTC_ACT_WL_2G_SCC, ++ BTC_ACT_WL_2G_AP, ++ BTC_ACT_WL_2G_GO, ++ BTC_ACT_WL_2G_GC, ++ BTC_ACT_WL_2G_NAN, ++ BTC_ACT_LAST, ++ BTC_ACT_NUM = BTC_ACT_LAST - BTC_ACT_NONE, ++ BTC_ACT_EXT_BIT = BIT(14), ++ BTC_POLICY_EXT_BIT = BIT(15), ++}; ++ ++#define BTC_FREERUN_ANTISO_MIN 30 ++#define BTC_TDMA_BTHID_MAX 2 ++#define BTC_BLINK_NOCONNECT 0 ++ ++static void _run_coex(struct rtw89_dev *rtwdev, ++ enum btc_reason_and_action reason); ++static void _write_scbd(struct rtw89_dev *rtwdev, u32 val, bool state); ++static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update); ++ ++static void _send_fw_cmd(struct rtw89_dev *rtwdev, u8 h2c_class, u8 h2c_func, ++ void *param, u16 len) ++{ ++ rtw89_fw_h2c_raw_with_hdr(rtwdev, h2c_class, h2c_func, param, len, ++ false, true); ++} ++ ++static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; ++ struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info; ++ u8 i; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s\n", __func__); ++ ++ if (type & BTC_RESET_CX) ++ memset(cx, 0, sizeof(*cx)); ++ else if (type & BTC_RESET_BTINFO) /* only for BT enable */ ++ memset(bt, 0, sizeof(*bt)); ++ ++ if (type & BTC_RESET_CTRL) { ++ memset(&btc->ctrl, 0, sizeof(btc->ctrl)); ++ btc->ctrl.trace_step = FCXDEF_STEP; ++ } ++ ++ /* Init Coex variables that are not zero */ ++ if (type & BTC_RESET_DM) { ++ memset(&btc->dm, 0, sizeof(btc->dm)); ++ memset(bt_linfo->rssi_state, 0, sizeof(bt_linfo->rssi_state)); ++ ++ for (i = 0; i < RTW89_MAX_HW_PORT_NUM; i++) ++ memset(wl_linfo[i].rssi_state, 0, ++ sizeof(wl_linfo[i].rssi_state)); ++ ++ /* set the slot_now table to original */ ++ btc->dm.tdma_now = t_def[CXTD_OFF]; ++ btc->dm.tdma = t_def[CXTD_OFF]; ++ memcpy(&btc->dm.slot_now, s_def, sizeof(btc->dm.slot_now)); ++ memcpy(&btc->dm.slot, s_def, sizeof(btc->dm.slot)); ++ ++ btc->policy_len = 0; ++ btc->bt_req_len = 0; ++ ++ btc->dm.coex_info_map = BTC_COEX_INFO_ALL; ++ btc->dm.wl_tx_limit.tx_time = BTC_MAX_TX_TIME_DEF; ++ btc->dm.wl_tx_limit.tx_retry = BTC_MAX_TX_RETRY_DEF; ++ } ++ ++ if (type & BTC_RESET_MDINFO) ++ memset(&btc->mdinfo, 0, sizeof(btc->mdinfo)); ++} ++ ++#define BTC_FWINFO_BUF 1024 ++ ++#define BTC_RPT_HDR_SIZE 3 ++#define BTC_CHK_WLSLOT_DRIFT_MAX 15 ++#define BTC_CHK_HANG_MAX 3 ++ ++static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 type, u32 cnt) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_bt_info *bt = &cx->bt; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): type:%d cnt:%d\n", ++ __func__, type, cnt); ++ ++ switch (type) { ++ case BTC_DCNT_RPT_FREEZE: ++ if (dm->cnt_dm[BTC_DCNT_RPT] == cnt && btc->fwinfo.rpt_en_map) ++ dm->cnt_dm[BTC_DCNT_RPT_FREEZE]++; ++ else ++ dm->cnt_dm[BTC_DCNT_RPT_FREEZE] = 0; ++ ++ if (dm->cnt_dm[BTC_DCNT_RPT_FREEZE] >= BTC_CHK_HANG_MAX) ++ dm->error.map.wl_fw_hang = true; ++ else ++ dm->error.map.wl_fw_hang = false; ++ ++ dm->cnt_dm[BTC_DCNT_RPT] = cnt; ++ break; ++ case BTC_DCNT_CYCLE_FREEZE: ++ if (dm->cnt_dm[BTC_DCNT_CYCLE] == cnt && ++ (dm->tdma_now.type != CXTDMA_OFF || ++ dm->tdma_now.ext_ctrl == CXECTL_EXT)) ++ dm->cnt_dm[BTC_DCNT_CYCLE_FREEZE]++; ++ else ++ dm->cnt_dm[BTC_DCNT_CYCLE_FREEZE] = 0; ++ ++ if (dm->cnt_dm[BTC_DCNT_CYCLE_FREEZE] >= BTC_CHK_HANG_MAX) ++ dm->error.map.cycle_hang = true; ++ else ++ dm->error.map.cycle_hang = false; ++ ++ dm->cnt_dm[BTC_DCNT_CYCLE] = cnt; ++ break; ++ case BTC_DCNT_W1_FREEZE: ++ if (dm->cnt_dm[BTC_DCNT_W1] == cnt && ++ dm->tdma_now.type != CXTDMA_OFF) ++ dm->cnt_dm[BTC_DCNT_W1_FREEZE]++; ++ else ++ dm->cnt_dm[BTC_DCNT_W1_FREEZE] = 0; ++ ++ if (dm->cnt_dm[BTC_DCNT_W1_FREEZE] >= BTC_CHK_HANG_MAX) ++ dm->error.map.w1_hang = true; ++ else ++ dm->error.map.w1_hang = false; ++ ++ dm->cnt_dm[BTC_DCNT_W1] = cnt; ++ break; ++ case BTC_DCNT_B1_FREEZE: ++ if (dm->cnt_dm[BTC_DCNT_B1] == cnt && ++ dm->tdma_now.type != CXTDMA_OFF) ++ dm->cnt_dm[BTC_DCNT_B1_FREEZE]++; ++ else ++ dm->cnt_dm[BTC_DCNT_B1_FREEZE] = 0; ++ ++ if (dm->cnt_dm[BTC_DCNT_B1_FREEZE] >= BTC_CHK_HANG_MAX) ++ dm->error.map.b1_hang = true; ++ else ++ dm->error.map.b1_hang = false; ++ ++ dm->cnt_dm[BTC_DCNT_B1] = cnt; ++ break; ++ case BTC_DCNT_TDMA_NONSYNC: ++ if (cnt != 0) /* if tdma not sync between drv/fw */ ++ dm->cnt_dm[BTC_DCNT_TDMA_NONSYNC]++; ++ else ++ dm->cnt_dm[BTC_DCNT_TDMA_NONSYNC] = 0; ++ ++ if (dm->cnt_dm[BTC_DCNT_TDMA_NONSYNC] >= BTC_CHK_HANG_MAX) ++ dm->error.map.tdma_no_sync = true; ++ else ++ dm->error.map.tdma_no_sync = false; ++ break; ++ case BTC_DCNT_SLOT_NONSYNC: ++ if (cnt != 0) /* if slot not sync between drv/fw */ ++ dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC]++; ++ else ++ dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC] = 0; ++ ++ if (dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC] >= BTC_CHK_HANG_MAX) ++ dm->error.map.tdma_no_sync = true; ++ else ++ dm->error.map.tdma_no_sync = false; ++ break; ++ case BTC_DCNT_BTCNT_FREEZE: ++ cnt = cx->cnt_bt[BTC_BCNT_HIPRI_RX] + ++ cx->cnt_bt[BTC_BCNT_HIPRI_TX] + ++ cx->cnt_bt[BTC_BCNT_LOPRI_RX] + ++ cx->cnt_bt[BTC_BCNT_LOPRI_TX]; ++ ++ if (cnt == 0) ++ dm->cnt_dm[BTC_DCNT_BTCNT_FREEZE]++; ++ else ++ dm->cnt_dm[BTC_DCNT_BTCNT_FREEZE] = 0; ++ ++ if ((dm->cnt_dm[BTC_DCNT_BTCNT_FREEZE] >= BTC_CHK_HANG_MAX && ++ bt->enable.now) || (!dm->cnt_dm[BTC_DCNT_BTCNT_FREEZE] && ++ !bt->enable.now)) ++ _update_bt_scbd(rtwdev, false); ++ break; ++ case BTC_DCNT_WL_SLOT_DRIFT: ++ if (cnt >= BTC_CHK_WLSLOT_DRIFT_MAX) ++ dm->cnt_dm[BTC_DCNT_WL_SLOT_DRIFT]++; ++ else ++ dm->cnt_dm[BTC_DCNT_WL_SLOT_DRIFT] = 0; ++ ++ if (dm->cnt_dm[BTC_DCNT_WL_SLOT_DRIFT] >= BTC_CHK_HANG_MAX) ++ dm->error.map.wl_slot_drift = true; ++ else ++ dm->error.map.wl_slot_drift = false; ++ break; ++ } ++} ++ ++static void _update_bt_report(struct rtw89_dev *rtwdev, u8 rpt_type, u8 *pfinfo) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; ++ struct rtw89_btc_bt_a2dp_desc *a2dp = &bt_linfo->a2dp_desc; ++ struct rtw89_btc_fbtc_btver *pver = NULL; ++ struct rtw89_btc_fbtc_btscan *pscan = NULL; ++ struct rtw89_btc_fbtc_btafh *pafh = NULL; ++ struct rtw89_btc_fbtc_btdevinfo *pdev = NULL; ++ ++ pver = (struct rtw89_btc_fbtc_btver *)pfinfo; ++ pscan = (struct rtw89_btc_fbtc_btscan *)pfinfo; ++ pafh = (struct rtw89_btc_fbtc_btafh *)pfinfo; ++ pdev = (struct rtw89_btc_fbtc_btdevinfo *)pfinfo; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): rpt_type:%d\n", ++ __func__, rpt_type); ++ ++ switch (rpt_type) { ++ case BTC_RPT_TYPE_BT_VER: ++ bt->ver_info.fw = le32_to_cpu(pver->fw_ver); ++ bt->ver_info.fw_coex = le32_get_bits(pver->coex_ver, GENMASK(7, 0)); ++ bt->feature = le32_to_cpu(pver->feature); ++ break; ++ case BTC_RPT_TYPE_BT_SCAN: ++ memcpy(bt->scan_info, pscan->scan, BTC_SCAN_MAX1); ++ break; ++ case BTC_RPT_TYPE_BT_AFH: ++ memcpy(&bt_linfo->afh_map[0], pafh->afh_l, 4); ++ memcpy(&bt_linfo->afh_map[4], pafh->afh_m, 4); ++ memcpy(&bt_linfo->afh_map[8], pafh->afh_h, 2); ++ break; ++ case BTC_RPT_TYPE_BT_DEVICE: ++ a2dp->device_name = le32_to_cpu(pdev->dev_name); ++ a2dp->vendor_id = le16_to_cpu(pdev->vendor_id); ++ a2dp->flush_time = le32_to_cpu(pdev->flush_time); ++ break; ++ default: ++ break; ++ } ++} ++ ++struct rtw89_btc_fbtc_cysta_cpu { ++ u8 fver; ++ u8 rsvd; ++ u16 cycles; ++ u16 cycles_a2dp[CXT_FLCTRL_MAX]; ++ u16 a2dpept; ++ u16 a2dpeptto; ++ u16 tavg_cycle[CXT_MAX]; ++ u16 tmax_cycle[CXT_MAX]; ++ u16 tmaxdiff_cycle[CXT_MAX]; ++ u16 tavg_a2dp[CXT_FLCTRL_MAX]; ++ u16 tmax_a2dp[CXT_FLCTRL_MAX]; ++ u16 tavg_a2dpept; ++ u16 tmax_a2dpept; ++ u16 tavg_lk; ++ u16 tmax_lk; ++ u32 slot_cnt[CXST_MAX]; ++ u32 bcn_cnt[CXBCN_MAX]; ++ u32 leakrx_cnt; ++ u32 collision_cnt; ++ u32 skip_cnt; ++ u32 exception; ++ u32 except_cnt; ++ u16 tslot_cycle[BTC_CYCLE_SLOT_MAX]; ++}; ++ ++static void rtw89_btc_fbtc_cysta_to_cpu(const struct rtw89_btc_fbtc_cysta *src, ++ struct rtw89_btc_fbtc_cysta_cpu *dst) ++{ ++ static_assert(sizeof(*src) == sizeof(*dst)); ++ ++#define __CPY_U8(_x) ({dst->_x = src->_x; }) ++#define __CPY_LE16(_x) ({dst->_x = le16_to_cpu(src->_x); }) ++#define __CPY_LE16S(_x) ({int _i; for (_i = 0; _i < ARRAY_SIZE(dst->_x); _i++) \ ++ dst->_x[_i] = le16_to_cpu(src->_x[_i]); }) ++#define __CPY_LE32(_x) ({dst->_x = le32_to_cpu(src->_x); }) ++#define __CPY_LE32S(_x) ({int _i; for (_i = 0; _i < ARRAY_SIZE(dst->_x); _i++) \ ++ dst->_x[_i] = le32_to_cpu(src->_x[_i]); }) ++ ++ __CPY_U8(fver); ++ __CPY_U8(rsvd); ++ __CPY_LE16(cycles); ++ __CPY_LE16S(cycles_a2dp); ++ __CPY_LE16(a2dpept); ++ __CPY_LE16(a2dpeptto); ++ __CPY_LE16S(tavg_cycle); ++ __CPY_LE16S(tmax_cycle); ++ __CPY_LE16S(tmaxdiff_cycle); ++ __CPY_LE16S(tavg_a2dp); ++ __CPY_LE16S(tmax_a2dp); ++ __CPY_LE16(tavg_a2dpept); ++ __CPY_LE16(tmax_a2dpept); ++ __CPY_LE16(tavg_lk); ++ __CPY_LE16(tmax_lk); ++ __CPY_LE32S(slot_cnt); ++ __CPY_LE32S(bcn_cnt); ++ __CPY_LE32(leakrx_cnt); ++ __CPY_LE32(collision_cnt); ++ __CPY_LE32(skip_cnt); ++ __CPY_LE32(exception); ++ __CPY_LE32(except_cnt); ++ __CPY_LE16S(tslot_cycle); ++ ++#undef __CPY_U8 ++#undef __CPY_LE16 ++#undef __CPY_LE16S ++#undef __CPY_LE32 ++#undef __CPY_LE32S ++} ++ ++#define BTC_LEAK_AP_TH 10 ++#define BTC_CYSTA_CHK_PERIOD 100 ++ ++struct rtw89_btc_prpt { ++ u8 type; ++ __le16 len; ++ u8 content[]; ++} __packed; ++ ++static u32 _chk_btc_report(struct rtw89_dev *rtwdev, ++ struct rtw89_btc_btf_fwinfo *pfwinfo, ++ u8 *prptbuf, u32 index) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_fbtc_rpt_ctrl *prpt = NULL; ++ struct rtw89_btc_fbtc_cysta *pcysta_le32 = NULL; ++ struct rtw89_btc_fbtc_cysta_cpu pcysta[1]; ++ struct rtw89_btc_prpt *btc_prpt = NULL; ++ struct rtw89_btc_fbtc_slot *rtp_slot = NULL; ++ u8 rpt_type = 0, *rpt_content = NULL, *pfinfo = NULL; ++ u16 wl_slot_set = 0; ++ u32 trace_step = btc->ctrl.trace_step, rpt_len = 0, diff_t; ++ u8 i; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): index:%d\n", ++ __func__, index); ++ ++ if (!prptbuf) { ++ pfwinfo->err[BTFRE_INVALID_INPUT]++; ++ return 0; ++ } ++ ++ btc_prpt = (struct rtw89_btc_prpt *)&prptbuf[index]; ++ rpt_type = btc_prpt->type; ++ rpt_len = le16_to_cpu(btc_prpt->len); ++ rpt_content = btc_prpt->content; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): rpt_type:%d\n", ++ __func__, rpt_type); ++ ++ switch (rpt_type) { ++ case BTC_RPT_TYPE_CTRL: ++ pcinfo = &pfwinfo->rpt_ctrl.cinfo; ++ pfinfo = (u8 *)(&pfwinfo->rpt_ctrl.finfo); ++ pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo); ++ pcinfo->req_fver = BTCRPT_VER; ++ pcinfo->rx_len = rpt_len; ++ pcinfo->rx_cnt++; ++ break; ++ case BTC_RPT_TYPE_TDMA: ++ pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo; ++ pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_tdma.finfo); ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo); ++ pcinfo->req_fver = FCXTDMA_VER; ++ pcinfo->rx_len = rpt_len; ++ pcinfo->rx_cnt++; ++ break; ++ case BTC_RPT_TYPE_SLOT: ++ pcinfo = &pfwinfo->rpt_fbtc_slots.cinfo; ++ pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_slots.finfo); ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo); ++ pcinfo->req_fver = FCXSLOTS_VER; ++ pcinfo->rx_len = rpt_len; ++ pcinfo->rx_cnt++; ++ break; ++ case BTC_RPT_TYPE_CYSTA: ++ pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; ++ pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_cysta.finfo); ++ pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo; ++ rtw89_btc_fbtc_cysta_to_cpu(pcysta_le32, pcysta); ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo); ++ pcinfo->req_fver = FCXCYSTA_VER; ++ pcinfo->rx_len = rpt_len; ++ pcinfo->rx_cnt++; ++ break; ++ case BTC_RPT_TYPE_STEP: ++ pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; ++ pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_step.finfo); ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo.step[0]) * ++ trace_step + 8; ++ pcinfo->req_fver = FCXSTEP_VER; ++ pcinfo->rx_len = rpt_len; ++ pcinfo->rx_cnt++; ++ break; ++ case BTC_RPT_TYPE_NULLSTA: ++ pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo; ++ pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_nullsta.finfo); ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo); ++ pcinfo->req_fver = FCXNULLSTA_VER; ++ pcinfo->rx_len = rpt_len; ++ pcinfo->rx_cnt++; ++ break; ++ case BTC_RPT_TYPE_MREG: ++ pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; ++ pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_mregval.finfo); ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo); ++ pcinfo->req_fver = FCXMREG_VER; ++ pcinfo->rx_len = rpt_len; ++ pcinfo->rx_cnt++; ++ break; ++ case BTC_RPT_TYPE_GPIO_DBG: ++ pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; ++ pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_gpio_dbg.finfo); ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo); ++ pcinfo->req_fver = FCXGPIODBG_VER; ++ pcinfo->rx_len = rpt_len; ++ pcinfo->rx_cnt++; ++ break; ++ case BTC_RPT_TYPE_BT_VER: ++ pcinfo = &pfwinfo->rpt_fbtc_btver.cinfo; ++ pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_btver.finfo); ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo); ++ pcinfo->req_fver = FCX_BTVER_VER; ++ pcinfo->rx_len = rpt_len; ++ pcinfo->rx_cnt++; ++ break; ++ case BTC_RPT_TYPE_BT_SCAN: ++ pcinfo = &pfwinfo->rpt_fbtc_btscan.cinfo; ++ pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_btscan.finfo); ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo); ++ pcinfo->req_fver = FCX_BTSCAN_VER; ++ pcinfo->rx_len = rpt_len; ++ pcinfo->rx_cnt++; ++ break; ++ case BTC_RPT_TYPE_BT_AFH: ++ pcinfo = &pfwinfo->rpt_fbtc_btafh.cinfo; ++ pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_btafh.finfo); ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo); ++ pcinfo->req_fver = FCX_BTAFH_VER; ++ pcinfo->rx_len = rpt_len; ++ pcinfo->rx_cnt++; ++ break; ++ case BTC_RPT_TYPE_BT_DEVICE: ++ pcinfo = &pfwinfo->rpt_fbtc_btdev.cinfo; ++ pfinfo = (u8 *)(&pfwinfo->rpt_fbtc_btdev.finfo); ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btdev.finfo); ++ pcinfo->req_fver = FCX_BTDEVINFO_VER; ++ pcinfo->rx_len = rpt_len; ++ pcinfo->rx_cnt++; ++ break; ++ default: ++ pfwinfo->err[BTFRE_UNDEF_TYPE]++; ++ return 0; ++ } ++ ++ if (rpt_len != pcinfo->req_len) { ++ if (rpt_type < BTC_RPT_TYPE_MAX) ++ pfwinfo->len_mismch |= (0x1 << rpt_type); ++ else ++ pfwinfo->len_mismch |= BIT(31); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): %d rpt_len:%d!=req_len:%d\n", ++ __func__, rpt_type, rpt_len, pcinfo->req_len); ++ ++ pcinfo->valid = 0; ++ return 0; ++ } else if (!pfinfo || !rpt_content || !pcinfo->req_len) { ++ pfwinfo->err[BTFRE_EXCEPTION]++; ++ pcinfo->valid = 0; ++ return 0; ++ } ++ ++ memcpy(pfinfo, rpt_content, pcinfo->req_len); ++ pcinfo->valid = 1; ++ ++ if (rpt_type == BTC_RPT_TYPE_TDMA) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): check %d %zu\n", __func__, ++ BTC_DCNT_TDMA_NONSYNC, sizeof(dm->tdma_now)); ++ ++ if (memcmp(&dm->tdma_now, &pfwinfo->rpt_fbtc_tdma.finfo, ++ sizeof(dm->tdma_now)) != 0) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): %d tdma_now %x %x %x %x %x %x %x %x\n", ++ __func__, BTC_DCNT_TDMA_NONSYNC, ++ dm->tdma_now.type, dm->tdma_now.rxflctrl, ++ dm->tdma_now.txpause, dm->tdma_now.wtgle_n, ++ dm->tdma_now.leak_n, dm->tdma_now.ext_ctrl, ++ dm->tdma_now.rsvd0, dm->tdma_now.rsvd1); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): %d rpt_fbtc_tdma %x %x %x %x %x %x %x %x\n", ++ __func__, BTC_DCNT_TDMA_NONSYNC, ++ pfwinfo->rpt_fbtc_tdma.finfo.type, ++ pfwinfo->rpt_fbtc_tdma.finfo.rxflctrl, ++ pfwinfo->rpt_fbtc_tdma.finfo.txpause, ++ pfwinfo->rpt_fbtc_tdma.finfo.wtgle_n, ++ pfwinfo->rpt_fbtc_tdma.finfo.leak_n, ++ pfwinfo->rpt_fbtc_tdma.finfo.ext_ctrl, ++ pfwinfo->rpt_fbtc_tdma.finfo.rsvd0, ++ pfwinfo->rpt_fbtc_tdma.finfo.rsvd1); ++ } ++ ++ _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, ++ memcmp(&dm->tdma_now, ++ &pfwinfo->rpt_fbtc_tdma.finfo, ++ sizeof(dm->tdma_now))); ++ } ++ ++ if (rpt_type == BTC_RPT_TYPE_SLOT) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): check %d %zu\n", ++ __func__, BTC_DCNT_SLOT_NONSYNC, ++ sizeof(dm->slot_now)); ++ ++ if (memcmp(dm->slot_now, pfwinfo->rpt_fbtc_slots.finfo.slot, ++ sizeof(dm->slot_now)) != 0) { ++ for (i = 0; i < CXST_MAX; i++) { ++ rtp_slot = ++ &pfwinfo->rpt_fbtc_slots.finfo.slot[i]; ++ if (memcmp(&dm->slot_now[i], rtp_slot, ++ sizeof(dm->slot_now[i])) != 0) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): %d slot_now[%d] dur=0x%04x tbl=%08x type=0x%04x\n", ++ __func__, ++ BTC_DCNT_SLOT_NONSYNC, i, ++ dm->slot_now[i].dur, ++ dm->slot_now[i].cxtbl, ++ dm->slot_now[i].cxtype); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): %d rpt_fbtc_slots[%d] dur=0x%04x tbl=%08x type=0x%04x\n", ++ __func__, ++ BTC_DCNT_SLOT_NONSYNC, i, ++ rtp_slot->dur, ++ rtp_slot->cxtbl, ++ rtp_slot->cxtype); ++ } ++ } ++ } ++ _chk_btc_err(rtwdev, BTC_DCNT_SLOT_NONSYNC, ++ memcmp(dm->slot_now, ++ pfwinfo->rpt_fbtc_slots.finfo.slot, ++ sizeof(dm->slot_now))); ++ } ++ ++ if (rpt_type == BTC_RPT_TYPE_CYSTA && ++ pcysta->cycles >= BTC_CYSTA_CHK_PERIOD) { ++ /* Check Leak-AP */ ++ if (pcysta->slot_cnt[CXST_LK] != 0 && ++ pcysta->leakrx_cnt != 0 && dm->tdma_now.rxflctrl) { ++ if (pcysta->slot_cnt[CXST_LK] < ++ BTC_LEAK_AP_TH * pcysta->leakrx_cnt) ++ dm->leak_ap = 1; ++ } ++ ++ /* Check diff time between WL slot and W1/E2G slot */ ++ if (dm->tdma_now.type == CXTDMA_OFF && ++ dm->tdma_now.ext_ctrl == CXECTL_EXT) ++ wl_slot_set = le16_to_cpu(dm->slot_now[CXST_E2G].dur); ++ else ++ wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); ++ ++ if (pcysta->tavg_cycle[CXT_WL] > wl_slot_set) { ++ diff_t = pcysta->tavg_cycle[CXT_WL] - wl_slot_set; ++ _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t); ++ } ++ } ++ ++ if (rpt_type == BTC_RPT_TYPE_CTRL) { ++ prpt = &pfwinfo->rpt_ctrl.finfo; ++ btc->fwinfo.rpt_en_map = prpt->rpt_enable; ++ wl->ver_info.fw_coex = prpt->wl_fw_coex_ver; ++ wl->ver_info.fw = prpt->wl_fw_ver; ++ dm->wl_fw_cx_offload = !!(prpt->wl_fw_cx_offload); ++ } ++ ++ if (rpt_type >= BTC_RPT_TYPE_BT_VER && ++ rpt_type <= BTC_RPT_TYPE_BT_DEVICE) ++ _update_bt_report(rtwdev, rpt_type, pfinfo); ++ ++ return (rpt_len + BTC_RPT_HDR_SIZE); ++} ++ ++static void _parse_btc_report(struct rtw89_dev *rtwdev, ++ struct rtw89_btc_btf_fwinfo *pfwinfo, ++ u8 *pbuf, u32 buf_len) ++{ ++ struct rtw89_btc_prpt *btc_prpt = NULL; ++ u32 index = 0, rpt_len = 0; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): buf_len:%d\n", ++ __func__, buf_len); ++ ++ while (pbuf) { ++ btc_prpt = (struct rtw89_btc_prpt *)&pbuf[index]; ++ if (index + 2 >= BTC_FWINFO_BUF) ++ break; ++ /* At least 3 bytes: type(1) & len(2) */ ++ rpt_len = le16_to_cpu(btc_prpt->len); ++ if ((index + rpt_len + BTC_RPT_HDR_SIZE) > buf_len) ++ break; ++ ++ rpt_len = _chk_btc_report(rtwdev, pfwinfo, pbuf, index); ++ if (!rpt_len) ++ break; ++ index += rpt_len; ++ } ++} ++ ++#define BTC_TLV_HDR_LEN 2 ++ ++static void _append_tdma(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_btf_tlv *tlv = NULL; ++ struct rtw89_btc_fbtc_tdma *v = NULL; ++ u16 len = btc->policy_len; ++ ++ if (!btc->update_policy_force && ++ !memcmp(&dm->tdma, &dm->tdma_now, sizeof(dm->tdma))) { ++ rtw89_debug(rtwdev, ++ RTW89_DBG_BTC, "[BTC], %s(): tdma no change!\n", ++ __func__); ++ return; ++ } ++ ++ tlv = (struct rtw89_btc_btf_tlv *)&btc->policy[len]; ++ v = (struct rtw89_btc_fbtc_tdma *)&tlv->val[0]; ++ tlv->type = CXPOLICY_TDMA; ++ tlv->len = sizeof(*v); ++ ++ memcpy(v, &dm->tdma, sizeof(*v)); ++ btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): type:%d, rxflctrl=%d, txpause=%d, wtgle_n=%d, leak_n=%d, ext_ctrl=%d\n", ++ __func__, dm->tdma.type, dm->tdma.rxflctrl, ++ dm->tdma.txpause, dm->tdma.wtgle_n, dm->tdma.leak_n, ++ dm->tdma.ext_ctrl); ++} ++ ++static void _append_slot(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_btf_tlv *tlv = NULL; ++ struct btc_fbtc_1slot *v = NULL; ++ u16 len = 0; ++ u8 i, cnt = 0; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): A:btc->policy_len = %d\n", ++ __func__, btc->policy_len); ++ ++ for (i = 0; i < CXST_MAX; i++) { ++ if (!btc->update_policy_force && ++ !memcmp(&dm->slot[i], &dm->slot_now[i], ++ sizeof(dm->slot[i]))) ++ continue; ++ ++ len = btc->policy_len; ++ ++ tlv = (struct rtw89_btc_btf_tlv *)&btc->policy[len]; ++ v = (struct btc_fbtc_1slot *)&tlv->val[0]; ++ tlv->type = CXPOLICY_SLOT; ++ tlv->len = sizeof(*v); ++ ++ v->fver = FCXONESLOT_VER; ++ v->sid = i; ++ v->slot = dm->slot[i]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): slot-%d: dur=%d, table=0x%08x, type=%d\n", ++ __func__, i, dm->slot[i].dur, dm->slot[i].cxtbl, ++ dm->slot[i].cxtype); ++ cnt++; ++ ++ btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v); ++ } ++ ++ if (cnt > 0) ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): slot update (cnt=%d)!!\n", ++ __func__, cnt); ++} ++ ++static void rtw89_btc_fw_en_rpt(struct rtw89_dev *rtwdev, ++ u32 rpt_map, bool rpt_state) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_btf_fwinfo *fwinfo = &btc->fwinfo; ++ struct rtw89_btc_btf_set_report r = {0}; ++ u32 val = 0; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): rpt_map=%x, rpt_state=%x\n", ++ __func__, rpt_map, rpt_state); ++ ++ if (rpt_state) ++ val = fwinfo->rpt_en_map | rpt_map; ++ else ++ val = fwinfo->rpt_en_map & ~rpt_map; ++ ++ if (val == fwinfo->rpt_en_map) ++ return; ++ ++ fwinfo->rpt_en_map = val; ++ ++ r.fver = BTF_SET_REPORT_VER; ++ r.enable = cpu_to_le32(val); ++ r.para = cpu_to_le32(rpt_state); ++ ++ _send_fw_cmd(rtwdev, BTFC_SET, SET_REPORT_EN, &r, sizeof(r)); ++} ++ ++static void rtw89_btc_fw_set_slots(struct rtw89_dev *rtwdev, u8 num, ++ struct rtw89_btc_fbtc_slot *s) ++{ ++ struct rtw89_btc_btf_set_slot_table *tbl = NULL; ++ u8 *ptr = NULL; ++ u16 n = 0; ++ ++ n = sizeof(*s) * num + sizeof(*tbl); ++ tbl = kmalloc(n, GFP_KERNEL); ++ if (!tbl) ++ return; ++ ++ tbl->fver = BTF_SET_SLOT_TABLE_VER; ++ tbl->tbl_num = num; ++ ptr = &tbl->buf[0]; ++ memcpy(ptr, s, num * sizeof(*s)); ++ ++ _send_fw_cmd(rtwdev, BTFC_SET, SET_SLOT_TABLE, tbl, n); ++ ++ kfree(tbl); ++} ++ ++static void btc_fw_set_monreg(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_btc_btf_set_mon_reg *monreg = NULL; ++ u8 n, *ptr = NULL, ulen; ++ u16 sz = 0; ++ ++ n = chip->mon_reg_num; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): mon_reg_num=%d\n", __func__, n); ++ if (n > CXMREG_MAX) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): mon reg count %d > %d\n", ++ __func__, n, CXMREG_MAX); ++ return; ++ } ++ ++ ulen = sizeof(struct rtw89_btc_fbtc_mreg); ++ sz = (ulen * n) + sizeof(*monreg); ++ monreg = kmalloc(sz, GFP_KERNEL); ++ if (!monreg) ++ return; ++ ++ monreg->fver = BTF_SET_MON_REG_VER; ++ monreg->reg_num = n; ++ ptr = &monreg->buf[0]; ++ memcpy(ptr, chip->mon_reg, n * ulen); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): sz=%d ulen=%d n=%d\n", ++ __func__, sz, ulen, n); ++ ++ _send_fw_cmd(rtwdev, BTFC_SET, SET_MREG_TABLE, (u8 *)monreg, sz); ++ kfree(monreg); ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, 1); ++} ++ ++static void _update_dm_step(struct rtw89_dev *rtwdev, ++ enum btc_reason_and_action reason_or_action) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ ++ /* use ring-structure to store dm step */ ++ dm->dm_step.step[dm->dm_step.step_pos] = reason_or_action; ++ dm->dm_step.step_pos++; ++ ++ if (dm->dm_step.step_pos >= ARRAY_SIZE(dm->dm_step.step)) { ++ dm->dm_step.step_pos = 0; ++ dm->dm_step.step_ov = true; ++ } ++} ++ ++static void _fw_set_policy(struct rtw89_dev *rtwdev, u16 policy_type, ++ enum btc_reason_and_action action) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ ++ dm->run_action = action; ++ ++ _update_dm_step(rtwdev, action | BTC_ACT_EXT_BIT); ++ _update_dm_step(rtwdev, policy_type | BTC_POLICY_EXT_BIT); ++ ++ btc->policy_len = 0; ++ btc->policy_type = policy_type; ++ ++ _append_tdma(rtwdev); ++ _append_slot(rtwdev); ++ ++ if (btc->policy_len == 0 || btc->policy_len > RTW89_BTC_POLICY_MAXLEN) ++ return; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): action = %d -> policy type/len: 0x%04x/%d\n", ++ __func__, action, policy_type, btc->policy_len); ++ ++ if (dm->tdma.rxflctrl == CXFLC_NULLP || ++ dm->tdma.rxflctrl == CXFLC_QOSNULL) ++ btc->lps = 1; ++ else ++ btc->lps = 0; ++ ++ if (btc->lps == 1) ++ rtw89_set_coex_ctrl_lps(rtwdev, btc->lps); ++ ++ _send_fw_cmd(rtwdev, BTFC_SET, SET_CX_POLICY, ++ btc->policy, btc->policy_len); ++ ++ memcpy(&dm->tdma_now, &dm->tdma, sizeof(dm->tdma_now)); ++ memcpy(&dm->slot_now, &dm->slot, sizeof(dm->slot_now)); ++ ++ if (btc->update_policy_force) ++ btc->update_policy_force = false; ++ ++ if (btc->lps == 0) ++ rtw89_set_coex_ctrl_lps(rtwdev, btc->lps); ++} ++ ++static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 type) ++{ ++ switch (type) { ++ case CXDRVINFO_INIT: ++ rtw89_fw_h2c_cxdrv_init(rtwdev); ++ break; ++ case CXDRVINFO_ROLE: ++ rtw89_fw_h2c_cxdrv_role(rtwdev); ++ break; ++ case CXDRVINFO_CTRL: ++ rtw89_fw_h2c_cxdrv_ctrl(rtwdev); ++ break; ++ case CXDRVINFO_RFK: ++ rtw89_fw_h2c_cxdrv_rfk(rtwdev); ++ break; ++ default: ++ break; ++ } ++} ++ ++static ++void btc_fw_event(struct rtw89_dev *rtwdev, u8 evt_id, void *data, u32 len) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): evt_id:%d len:%d\n", ++ __func__, evt_id, len); ++ ++ if (!len || !data) ++ return; ++ ++ switch (evt_id) { ++ case BTF_EVNT_RPT: ++ _parse_btc_report(rtwdev, pfwinfo, data, len); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void _set_gnt_wl(struct rtw89_dev *rtwdev, u8 phy_map, u8 state) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_mac_ax_gnt *g = dm->gnt.band; ++ u8 i; ++ ++ if (phy_map > BTC_PHY_ALL) ++ return; ++ ++ for (i = 0; i < RTW89_PHY_MAX; i++) { ++ if (!(phy_map & BIT(i))) ++ continue; ++ ++ switch (state) { ++ case BTC_GNT_HW: ++ g[i].gnt_wl_sw_en = 0; ++ g[i].gnt_wl = 0; ++ break; ++ case BTC_GNT_SW_LO: ++ g[i].gnt_wl_sw_en = 1; ++ g[i].gnt_wl = 0; ++ break; ++ case BTC_GNT_SW_HI: ++ g[i].gnt_wl_sw_en = 1; ++ g[i].gnt_wl = 1; ++ break; ++ } ++ } ++ ++ rtw89_mac_cfg_gnt(rtwdev, &dm->gnt); ++} ++ ++#define BTC_TDMA_WLROLE_MAX 2 ++ ++static void _set_bt_ignore_wlan_act(struct rtw89_dev *rtwdev, u8 enable) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): set bt %s wlan_act\n", __func__, ++ enable ? "ignore" : "do not ignore"); ++ ++ _send_fw_cmd(rtwdev, BTFC_SET, SET_BT_IGNORE_WLAN_ACT, &enable, 1); ++} ++ ++#define WL_TX_POWER_NO_BTC_CTRL GENMASK(31, 0) ++#define WL_TX_POWER_ALL_TIME GENMASK(15, 0) ++#define WL_TX_POWER_WITH_BT GENMASK(31, 16) ++#define WL_TX_POWER_INT_PART GENMASK(8, 2) ++#define WL_TX_POWER_FRA_PART GENMASK(1, 0) ++#define B_BTC_WL_TX_POWER_SIGN BIT(7) ++#define B_TSSI_WL_TX_POWER_SIGN BIT(8) ++ ++static void _set_wl_tx_power(struct rtw89_dev *rtwdev, u32 level) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ u32 pwr_val; ++ ++ if (wl->rf_para.tx_pwr_freerun == level) ++ return; ++ ++ wl->rf_para.tx_pwr_freerun = level; ++ btc->dm.rf_trx_para.wl_tx_power = level; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): level = %d\n", ++ __func__, level); ++ ++ if (level == RTW89_BTC_WL_DEF_TX_PWR) { ++ pwr_val = WL_TX_POWER_NO_BTC_CTRL; ++ } else { /* only apply "force tx power" */ ++ pwr_val = FIELD_PREP(WL_TX_POWER_INT_PART, level); ++ if (pwr_val > RTW89_BTC_WL_DEF_TX_PWR) ++ pwr_val = RTW89_BTC_WL_DEF_TX_PWR; ++ ++ if (level & B_BTC_WL_TX_POWER_SIGN) ++ pwr_val |= B_TSSI_WL_TX_POWER_SIGN; ++ pwr_val |= WL_TX_POWER_WITH_BT; ++ } ++ ++ chip->ops->btc_set_wl_txpwr_ctrl(rtwdev, pwr_val); ++} ++ ++static void _set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ ++ if (wl->rf_para.rx_gain_freerun == level) ++ return; ++ ++ wl->rf_para.rx_gain_freerun = level; ++ btc->dm.rf_trx_para.wl_rx_gain = level; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): level = %d\n", ++ __func__, level); ++} ++ ++static void _set_bt_tx_power(struct rtw89_dev *rtwdev, u8 level) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ u8 buf; ++ ++ if (bt->rf_para.tx_pwr_freerun == level) ++ return; ++ ++ bt->rf_para.tx_pwr_freerun = level; ++ btc->dm.rf_trx_para.bt_tx_power = level; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): level = %d\n", ++ __func__, level); ++ ++ buf = (s8)(-level); ++ _send_fw_cmd(rtwdev, BTFC_SET, SET_BT_TX_PWR, &buf, 1); ++} ++ ++#define BTC_BT_RX_NORMAL_LVL 7 ++ ++static void _set_bt_rx_gain(struct rtw89_dev *rtwdev, u8 level) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ ++ if (bt->rf_para.rx_gain_freerun == level || ++ level > BTC_BT_RX_NORMAL_LVL) ++ return; ++ ++ bt->rf_para.rx_gain_freerun = level; ++ btc->dm.rf_trx_para.bt_rx_gain = level; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): level = %d\n", ++ __func__, level); ++ ++ if (level == BTC_BT_RX_NORMAL_LVL) ++ _write_scbd(rtwdev, BTC_WSCB_RXGAIN, false); ++ else ++ _write_scbd(rtwdev, BTC_WSCB_RXGAIN, true); ++ ++ _send_fw_cmd(rtwdev, BTFC_SET, SET_BT_LNA_CONSTRAIN, &level, 1); ++} ++ ++static void _set_rf_trx_para(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ struct rtw89_btc_rf_trx_para para; ++ u32 wl_stb_chg = 0; ++ u8 level_id = 0; ++ ++ if (!dm->freerun) { ++ dm->trx_para_level = 0; ++ chip->ops->btc_bt_aci_imp(rtwdev); ++ } ++ ++ level_id = (u8)dm->trx_para_level; ++ ++ if (level_id >= chip->rf_para_dlink_num || ++ level_id >= chip->rf_para_ulink_num) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): invalid level_id: %d\n", ++ __func__, level_id); ++ return; ++ } ++ ++ if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) ++ para = chip->rf_para_ulink[level_id]; ++ else ++ para = chip->rf_para_dlink[level_id]; ++ ++ if (para.wl_tx_power != RTW89_BTC_WL_DEF_TX_PWR) ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): wl_tx_power=%d\n", ++ __func__, para.wl_tx_power); ++ _set_wl_tx_power(rtwdev, para.wl_tx_power); ++ _set_wl_rx_gain(rtwdev, para.wl_rx_gain); ++ _set_bt_tx_power(rtwdev, para.bt_tx_power); ++ _set_bt_rx_gain(rtwdev, para.bt_rx_gain); ++ ++ if (bt->enable.now == 0 || wl->status.map.rf_off == 1 || ++ wl->status.map.lps == 1) ++ wl_stb_chg = 0; ++ else ++ wl_stb_chg = 1; ++ ++ if (wl_stb_chg != dm->wl_stb_chg) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): wl_stb_chg=%d\n", ++ __func__, wl_stb_chg); ++ dm->wl_stb_chg = wl_stb_chg; ++ chip->ops->btc_wl_s1_standby(rtwdev, dm->wl_stb_chg); ++ } ++} ++ ++static void _update_btc_state_map(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_wl_info *wl = &cx->wl; ++ struct rtw89_btc_bt_info *bt = &cx->bt; ++ struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; ++ ++ if (wl->status.map.connecting || wl->status.map._4way || ++ wl->status.map.roaming) { ++ cx->state_map = BTC_WLINKING; ++ } else if (wl->status.map.scan) { /* wl scan */ ++ if (bt_linfo->status.map.inq_pag) ++ cx->state_map = BTC_WSCAN_BSCAN; ++ else ++ cx->state_map = BTC_WSCAN_BNOSCAN; ++ } else if (wl->status.map.busy) { /* only busy */ ++ if (bt_linfo->status.map.inq_pag) ++ cx->state_map = BTC_WBUSY_BSCAN; ++ else ++ cx->state_map = BTC_WBUSY_BNOSCAN; ++ } else { /* wl idle */ ++ cx->state_map = BTC_WIDLE; ++ } ++} ++ ++static void _set_bt_afh_info(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ struct rtw89_btc_bt_link_info *b = &bt->link_info; ++ struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; ++ u8 en = 0, i, ch = 0, bw = 0; ++ ++ if (btc->ctrl.manual || wl->status.map.scan) ++ return; ++ ++ /* TODO if include module->ant.type == BTC_ANT_SHARED */ ++ if (wl->status.map.rf_off || bt->whql_test || ++ wl_rinfo->link_mode == BTC_WLINK_NOLINK || ++ wl_rinfo->link_mode == BTC_WLINK_5G || ++ wl_rinfo->connect_cnt > BTC_TDMA_WLROLE_MAX) { ++ en = false; ++ } else if (wl_rinfo->link_mode == BTC_WLINK_2G_MCC || ++ wl_rinfo->link_mode == BTC_WLINK_2G_SCC) { ++ en = true; ++ /* get p2p channel */ ++ for (i = 0; i < RTW89_MAX_HW_PORT_NUM; i++) { ++ if (wl_rinfo->active_role[i].role == ++ RTW89_WIFI_ROLE_P2P_GO || ++ wl_rinfo->active_role[i].role == ++ RTW89_WIFI_ROLE_P2P_CLIENT) { ++ ch = wl_rinfo->active_role[i].ch; ++ bw = wl_rinfo->active_role[i].bw; ++ break; ++ } ++ } ++ } else { ++ en = true; ++ /* get 2g channel */ ++ for (i = 0; i < RTW89_MAX_HW_PORT_NUM; i++) { ++ if (wl_rinfo->active_role[i].connected && ++ wl_rinfo->active_role[i].band == RTW89_BAND_2G) { ++ ch = wl_rinfo->active_role[i].ch; ++ bw = wl_rinfo->active_role[i].bw; ++ break; ++ } ++ } ++ } ++ ++ switch (bw) { ++ case RTW89_CHANNEL_WIDTH_20: ++ bw = 20 + chip->afh_guard_ch * 2; ++ break; ++ case RTW89_CHANNEL_WIDTH_40: ++ bw = 40 + chip->afh_guard_ch * 2; ++ break; ++ case RTW89_CHANNEL_WIDTH_5: ++ bw = 5 + chip->afh_guard_ch * 2; ++ break; ++ case RTW89_CHANNEL_WIDTH_10: ++ bw = 10 + chip->afh_guard_ch * 2; ++ break; ++ default: ++ bw = 0; ++ en = false; /* turn off AFH info if BW > 40 */ ++ break; ++ } ++ ++ if (wl->afh_info.en == en && ++ wl->afh_info.ch == ch && ++ wl->afh_info.bw == bw && ++ b->profile_cnt.last == b->profile_cnt.now) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): return because no change!\n", ++ __func__); ++ return; ++ } ++ ++ wl->afh_info.en = en; ++ wl->afh_info.ch = ch; ++ wl->afh_info.bw = bw; ++ ++ _send_fw_cmd(rtwdev, BTFC_SET, SET_BT_WL_CH_INFO, &wl->afh_info, 3); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): en=%d, ch=%d, bw=%d\n", ++ __func__, en, ch, bw); ++ btc->cx.cnt_wl[BTC_WCNT_CH_UPDATE]++; ++} ++ ++static bool _check_freerun(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; ++ struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; ++ struct rtw89_btc_bt_hid_desc *hid = &bt_linfo->hid_desc; ++ ++ if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { ++ btc->dm.trx_para_level = 0; ++ return false; ++ } ++ ++ /* The below is dedicated antenna case */ ++ if (wl_rinfo->connect_cnt > BTC_TDMA_WLROLE_MAX) { ++ btc->dm.trx_para_level = 5; ++ return true; ++ } ++ ++ if (bt_linfo->profile_cnt.now == 0) { ++ btc->dm.trx_para_level = 5; ++ return true; ++ } ++ ++ if (hid->pair_cnt > BTC_TDMA_BTHID_MAX) { ++ btc->dm.trx_para_level = 5; ++ return true; ++ } ++ ++ /* TODO get isolation by BT psd */ ++ if (btc->mdinfo.ant.isolation >= BTC_FREERUN_ANTISO_MIN) { ++ btc->dm.trx_para_level = 5; ++ return true; ++ } ++ ++ if (!wl->status.map.busy) {/* wl idle -> freerun */ ++ btc->dm.trx_para_level = 5; ++ return true; ++ } else if (wl->rssi_level > 1) {/* WL rssi < 50% (-60dBm) */ ++ btc->dm.trx_para_level = 0; ++ return false; ++ } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) { ++ if (wl->rssi_level == 0 && bt_linfo->rssi > 31) { ++ btc->dm.trx_para_level = 6; ++ return true; ++ } else if (wl->rssi_level == 1 && bt_linfo->rssi > 36) { ++ btc->dm.trx_para_level = 7; ++ return true; ++ } ++ btc->dm.trx_para_level = 0; ++ return false; ++ } else if (wl->status.map.traffic_dir & BIT(RTW89_TFC_DL)) { ++ if (bt_linfo->rssi > 28) { ++ btc->dm.trx_para_level = 6; ++ return true; ++ } ++ } ++ ++ btc->dm.trx_para_level = 0; ++ return false; ++} ++ ++#define _tdma_set_flctrl(btc, flc) ({(btc)->dm.tdma.rxflctrl = flc; }) ++#define _tdma_set_tog(btc, wtg) ({(btc)->dm.tdma.wtgle_n = wtg; }) ++#define _tdma_set_lek(btc, lek) ({(btc)->dm.tdma.leak_n = lek; }) ++ ++#define _slot_set(btc, sid, dura, tbl, type) \ ++ do { \ ++ typeof(sid) _sid = (sid); \ ++ typeof(btc) _btc = (btc); \ ++ _btc->dm.slot[_sid].dur = cpu_to_le16(dura);\ ++ _btc->dm.slot[_sid].cxtbl = cpu_to_le32(tbl); \ ++ _btc->dm.slot[_sid].cxtype = cpu_to_le16(type); \ ++ } while (0) ++ ++#define _slot_set_dur(btc, sid, dura) (btc)->dm.slot[sid].dur = cpu_to_le16(dura) ++#define _slot_set_tbl(btc, sid, tbl) (btc)->dm.slot[sid].cxtbl = cpu_to_le32(tbl) ++#define _slot_set_type(btc, sid, type) (btc)->dm.slot[sid].cxtype = cpu_to_le16(type) ++ ++struct btc_btinfo_lb2 { ++ u8 connect: 1; ++ u8 sco_busy: 1; ++ u8 inq_pag: 1; ++ u8 acl_busy: 1; ++ u8 hfp: 1; ++ u8 hid: 1; ++ u8 a2dp: 1; ++ u8 pan: 1; ++}; ++ ++struct btc_btinfo_lb3 { ++ u8 retry: 4; ++ u8 cqddr: 1; ++ u8 inq: 1; ++ u8 mesh_busy: 1; ++ u8 pag: 1; ++}; ++ ++struct btc_btinfo_hb0 { ++ s8 rssi; ++}; ++ ++struct btc_btinfo_hb1 { ++ u8 ble_connect: 1; ++ u8 reinit: 1; ++ u8 relink: 1; ++ u8 igno_wl: 1; ++ u8 voice: 1; ++ u8 ble_scan: 1; ++ u8 role_sw: 1; ++ u8 multi_link: 1; ++}; ++ ++struct btc_btinfo_hb2 { ++ u8 pan_active: 1; ++ u8 afh_update: 1; ++ u8 a2dp_active: 1; ++ u8 slave: 1; ++ u8 hid_slot: 2; ++ u8 hid_cnt: 2; ++}; ++ ++struct btc_btinfo_hb3 { ++ u8 a2dp_bitpool: 6; ++ u8 tx_3m: 1; ++ u8 a2dp_sink: 1; ++}; ++ ++union btc_btinfo { ++ u8 val; ++ struct btc_btinfo_lb2 lb2; ++ struct btc_btinfo_lb3 lb3; ++ struct btc_btinfo_hb0 hb0; ++ struct btc_btinfo_hb1 hb1; ++ struct btc_btinfo_hb2 hb2; ++ struct btc_btinfo_hb3 hb3; ++}; ++ ++static void _set_policy(struct rtw89_dev *rtwdev, u16 policy_type, ++ enum btc_reason_and_action action) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_fbtc_tdma *t = &dm->tdma; ++ struct rtw89_btc_fbtc_slot *s = dm->slot; ++ u8 type; ++ u32 tbl_w1, tbl_b1, tbl_b4; ++ ++ if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { ++ if (btc->cx.wl.status.map._4way) ++ tbl_w1 = cxtbl[1]; ++ else ++ tbl_w1 = cxtbl[8]; ++ tbl_b1 = cxtbl[3]; ++ tbl_b4 = cxtbl[3]; ++ } else { ++ tbl_w1 = cxtbl[16]; ++ tbl_b1 = cxtbl[17]; ++ tbl_b4 = cxtbl[17]; ++ } ++ ++ type = (u8)((policy_type & BTC_CXP_MASK) >> 8); ++ btc->bt_req_en = false; ++ ++ switch (type) { ++ case BTC_CXP_USERDEF0: ++ *t = t_def[CXTD_OFF]; ++ s[CXST_OFF] = s_def[CXST_OFF]; ++ _slot_set_tbl(btc, CXST_OFF, cxtbl[2]); ++ btc->update_policy_force = true; ++ break; ++ case BTC_CXP_OFF: /* TDMA off */ ++ _write_scbd(rtwdev, BTC_WSCB_TDMA, false); ++ *t = t_def[CXTD_OFF]; ++ s[CXST_OFF] = s_def[CXST_OFF]; ++ ++ switch (policy_type) { ++ case BTC_CXP_OFF_BT: ++ _slot_set_tbl(btc, CXST_OFF, cxtbl[2]); ++ break; ++ case BTC_CXP_OFF_WL: ++ _slot_set_tbl(btc, CXST_OFF, cxtbl[1]); ++ break; ++ case BTC_CXP_OFF_EQ0: ++ _slot_set_tbl(btc, CXST_OFF, cxtbl[0]); ++ break; ++ case BTC_CXP_OFF_EQ1: ++ _slot_set_tbl(btc, CXST_OFF, cxtbl[16]); ++ break; ++ case BTC_CXP_OFF_EQ2: ++ _slot_set_tbl(btc, CXST_OFF, cxtbl[17]); ++ break; ++ case BTC_CXP_OFF_EQ3: ++ _slot_set_tbl(btc, CXST_OFF, cxtbl[18]); ++ break; ++ case BTC_CXP_OFF_BWB0: ++ _slot_set_tbl(btc, CXST_OFF, cxtbl[5]); ++ break; ++ case BTC_CXP_OFF_BWB1: ++ _slot_set_tbl(btc, CXST_OFF, cxtbl[8]); ++ break; ++ } ++ break; ++ case BTC_CXP_OFFB: /* TDMA off + beacon protect */ ++ _write_scbd(rtwdev, BTC_WSCB_TDMA, false); ++ *t = t_def[CXTD_OFF_B2]; ++ s[CXST_OFF] = s_def[CXST_OFF]; ++ switch (policy_type) { ++ case BTC_CXP_OFFB_BWB0: ++ _slot_set_tbl(btc, CXST_OFF, cxtbl[8]); ++ break; ++ } ++ break; ++ case BTC_CXP_OFFE: /* TDMA off + beacon protect + Ext_control */ ++ btc->bt_req_en = true; ++ _write_scbd(rtwdev, BTC_WSCB_TDMA, true); ++ *t = t_def[CXTD_OFF_EXT]; ++ switch (policy_type) { ++ case BTC_CXP_OFFE_DEF: ++ s[CXST_E2G] = s_def[CXST_E2G]; ++ s[CXST_E5G] = s_def[CXST_E5G]; ++ s[CXST_EBT] = s_def[CXST_EBT]; ++ s[CXST_ENULL] = s_def[CXST_ENULL]; ++ break; ++ case BTC_CXP_OFFE_DEF2: ++ _slot_set(btc, CXST_E2G, 20, cxtbl[1], SLOT_ISO); ++ s[CXST_E5G] = s_def[CXST_E5G]; ++ s[CXST_EBT] = s_def[CXST_EBT]; ++ s[CXST_ENULL] = s_def[CXST_ENULL]; ++ break; ++ } ++ break; ++ case BTC_CXP_FIX: /* TDMA Fix-Slot */ ++ _write_scbd(rtwdev, BTC_WSCB_TDMA, true); ++ *t = t_def[CXTD_FIX]; ++ switch (policy_type) { ++ case BTC_CXP_FIX_TD3030: ++ _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_FIX_TD5050: ++ _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_FIX_TD2030: ++ _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_FIX_TD4010: ++ _slot_set(btc, CXST_W1, 40, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_FIX_TD4020: ++ _slot_set(btc, CXST_W1, 40, cxtbl[1], SLOT_MIX); ++ _slot_set(btc, CXST_B1, 20, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_FIX_TD7010: ++ _slot_set(btc, CXST_W1, 70, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 10, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_FIX_TD2060: ++ _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_FIX_TD3060: ++ _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_FIX_TD2080: ++ _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_FIX_TDW1B1: /* W1:B1 = user-define */ ++ _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], ++ tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], ++ tbl_b1, SLOT_MIX); ++ break; ++ } ++ break; ++ case BTC_CXP_PFIX: /* PS-TDMA Fix-Slot */ ++ _write_scbd(rtwdev, BTC_WSCB_TDMA, true); ++ *t = t_def[CXTD_PFIX]; ++ if (btc->cx.wl.role_info.role_map.role.ap) ++ _tdma_set_flctrl(btc, CXFLC_QOSNULL); ++ ++ switch (policy_type) { ++ case BTC_CXP_PFIX_TD3030: ++ _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_PFIX_TD5050: ++ _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 50, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_PFIX_TD2030: ++ _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 30, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_PFIX_TD2060: ++ _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_PFIX_TD3070: ++ _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 60, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_PFIX_TD2080: ++ _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 80, tbl_b1, SLOT_MIX); ++ break; ++ } ++ break; ++ case BTC_CXP_AUTO: /* TDMA Auto-Slot */ ++ _write_scbd(rtwdev, BTC_WSCB_TDMA, true); ++ *t = t_def[CXTD_AUTO]; ++ switch (policy_type) { ++ case BTC_CXP_AUTO_TD50200: ++ _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_AUTO_TD60200: ++ _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_AUTO_TD20200: ++ _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_AUTO_TDW1B1: /* W1:B1 = user-define */ ++ _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], ++ tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], ++ tbl_b1, SLOT_MIX); ++ break; ++ } ++ break; ++ case BTC_CXP_PAUTO: /* PS-TDMA Auto-Slot */ ++ _write_scbd(rtwdev, BTC_WSCB_TDMA, true); ++ *t = t_def[CXTD_PAUTO]; ++ switch (policy_type) { ++ case BTC_CXP_PAUTO_TD50200: ++ _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_PAUTO_TD60200: ++ _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_PAUTO_TD20200: ++ _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ break; ++ case BTC_CXP_PAUTO_TDW1B1: ++ _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], ++ tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, dm->slot_dur[CXST_B1], ++ tbl_b1, SLOT_MIX); ++ break; ++ } ++ break; ++ case BTC_CXP_AUTO2: /* TDMA Auto-Slot2 */ ++ _write_scbd(rtwdev, BTC_WSCB_TDMA, true); ++ *t = t_def[CXTD_AUTO2]; ++ switch (policy_type) { ++ case BTC_CXP_AUTO2_TD3050: ++ _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); ++ break; ++ case BTC_CXP_AUTO2_TD3070: ++ _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX); ++ break; ++ case BTC_CXP_AUTO2_TD5050: ++ _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); ++ break; ++ case BTC_CXP_AUTO2_TD6060: ++ _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX); ++ break; ++ case BTC_CXP_AUTO2_TD2080: ++ _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX); ++ break; ++ case BTC_CXP_AUTO2_TDW1B4: /* W1:B1 = user-define */ ++ _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], ++ tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4], ++ tbl_b4, SLOT_MIX); ++ break; ++ } ++ break; ++ case BTC_CXP_PAUTO2: /* PS-TDMA Auto-Slot2 */ ++ _write_scbd(rtwdev, BTC_WSCB_TDMA, true); ++ *t = t_def[CXTD_PAUTO2]; ++ switch (policy_type) { ++ case BTC_CXP_PAUTO2_TD3050: ++ _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); ++ break; ++ case BTC_CXP_PAUTO2_TD3070: ++ _slot_set(btc, CXST_W1, 30, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ _slot_set(btc, CXST_B4, 70, tbl_b4, SLOT_MIX); ++ break; ++ case BTC_CXP_PAUTO2_TD5050: ++ _slot_set(btc, CXST_W1, 50, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ _slot_set(btc, CXST_B4, 50, tbl_b4, SLOT_MIX); ++ break; ++ case BTC_CXP_PAUTO2_TD6060: ++ _slot_set(btc, CXST_W1, 60, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ _slot_set(btc, CXST_B4, 60, tbl_b4, SLOT_MIX); ++ break; ++ case BTC_CXP_PAUTO2_TD2080: ++ _slot_set(btc, CXST_W1, 20, tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B1, 200, tbl_b1, SLOT_MIX); ++ _slot_set(btc, CXST_B4, 80, tbl_b4, SLOT_MIX); ++ break; ++ case BTC_CXP_PAUTO2_TDW1B4: /* W1:B1 = user-define */ ++ _slot_set(btc, CXST_W1, dm->slot_dur[CXST_W1], ++ tbl_w1, SLOT_ISO); ++ _slot_set(btc, CXST_B4, dm->slot_dur[CXST_B4], ++ tbl_b4, SLOT_MIX); ++ break; ++ } ++ break; ++ } ++ ++ _fw_set_policy(rtwdev, policy_type, action); ++} ++ ++static void _set_gnt_bt(struct rtw89_dev *rtwdev, u8 phy_map, u8 state) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_mac_ax_gnt *g = dm->gnt.band; ++ u8 i; ++ ++ if (phy_map > BTC_PHY_ALL) ++ return; ++ ++ for (i = 0; i < RTW89_PHY_MAX; i++) { ++ if (!(phy_map & BIT(i))) ++ continue; ++ ++ switch (state) { ++ case BTC_GNT_HW: ++ g[i].gnt_bt_sw_en = 0; ++ g[i].gnt_bt = 0; ++ break; ++ case BTC_GNT_SW_LO: ++ g[i].gnt_bt_sw_en = 1; ++ g[i].gnt_bt = 0; ++ break; ++ case BTC_GNT_SW_HI: ++ g[i].gnt_bt_sw_en = 1; ++ g[i].gnt_bt = 1; ++ break; ++ } ++ } ++ ++ rtw89_mac_cfg_gnt(rtwdev, &dm->gnt); ++} ++ ++static void _set_bt_plut(struct rtw89_dev *rtwdev, u8 phy_map, ++ u8 tx_val, u8 rx_val) ++{ ++ struct rtw89_mac_ax_plt plt; ++ ++ plt.band = RTW89_MAC_0; ++ plt.tx = tx_val; ++ plt.rx = rx_val; ++ ++ if (phy_map & BTC_PHY_0) ++ rtw89_mac_cfg_plt(rtwdev, &plt); ++ ++ if (!rtwdev->dbcc_en) ++ return; ++ ++ plt.band = RTW89_MAC_1; ++ if (phy_map & BTC_PHY_1) ++ rtw89_mac_cfg_plt(rtwdev, &plt); ++} ++ ++static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec, ++ u8 phy_map, u8 type) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_bt_info *bt = &cx->bt; ++ struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; ++ u8 gnt_wl_ctrl, gnt_bt_ctrl, plt_ctrl, i, b2g = 0; ++ u32 ant_path_type; ++ ++ ant_path_type = ((phy_map << 8) + type); ++ ++ if (btc->dm.run_reason == BTC_RSN_NTFY_POWEROFF || ++ btc->dm.run_reason == BTC_RSN_NTFY_RADIO_STATE || ++ btc->dm.run_reason == BTC_RSN_CMD_SET_COEX) ++ force_exec = FC_EXEC; ++ ++ if (!force_exec && ant_path_type == dm->set_ant_path) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): return by no change!!\n", ++ __func__); ++ return; ++ } else if (bt->rfk_info.map.run) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): return by bt rfk!!\n", __func__); ++ return; ++ } else if (btc->dm.run_reason != BTC_RSN_NTFY_WL_RFK && ++ wl->rfk_info.state != BTC_WRFK_STOP) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): return by wl rfk!!\n", __func__); ++ return; ++ } ++ ++ dm->set_ant_path = ant_path_type; ++ ++ rtw89_debug(rtwdev, ++ RTW89_DBG_BTC, ++ "[BTC], %s(): path=0x%x, set_type=0x%x\n", ++ __func__, phy_map, dm->set_ant_path & 0xff); ++ ++ switch (type) { ++ case BTC_ANT_WPOWERON: ++ rtw89_mac_cfg_ctrl_path(rtwdev, false); ++ break; ++ case BTC_ANT_WINIT: ++ if (bt->enable.now) { ++ _set_gnt_wl(rtwdev, phy_map, BTC_GNT_SW_LO); ++ _set_gnt_bt(rtwdev, phy_map, BTC_GNT_SW_HI); ++ } else { ++ _set_gnt_wl(rtwdev, phy_map, BTC_GNT_SW_HI); ++ _set_gnt_bt(rtwdev, phy_map, BTC_GNT_SW_LO); ++ } ++ rtw89_mac_cfg_ctrl_path(rtwdev, true); ++ _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_BT, BTC_PLT_BT); ++ break; ++ case BTC_ANT_WONLY: ++ _set_gnt_wl(rtwdev, phy_map, BTC_GNT_SW_HI); ++ _set_gnt_bt(rtwdev, phy_map, BTC_GNT_SW_LO); ++ rtw89_mac_cfg_ctrl_path(rtwdev, true); ++ _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE); ++ break; ++ case BTC_ANT_WOFF: ++ rtw89_mac_cfg_ctrl_path(rtwdev, false); ++ _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE); ++ break; ++ case BTC_ANT_W2G: ++ rtw89_mac_cfg_ctrl_path(rtwdev, true); ++ if (rtwdev->dbcc_en) { ++ for (i = 0; i < RTW89_PHY_MAX; i++) { ++ b2g = (wl_dinfo->real_band[i] == RTW89_BAND_2G); ++ ++ gnt_wl_ctrl = b2g ? BTC_GNT_HW : BTC_GNT_SW_HI; ++ _set_gnt_wl(rtwdev, BIT(i), gnt_wl_ctrl); ++ ++ gnt_bt_ctrl = b2g ? BTC_GNT_HW : BTC_GNT_SW_HI; ++ /* BT should control by GNT_BT if WL_2G at S0 */ ++ if (i == 1 && ++ wl_dinfo->real_band[0] == RTW89_BAND_2G && ++ wl_dinfo->real_band[1] == RTW89_BAND_5G) ++ gnt_bt_ctrl = BTC_GNT_HW; ++ _set_gnt_bt(rtwdev, BIT(i), gnt_bt_ctrl); ++ ++ plt_ctrl = b2g ? BTC_PLT_BT : BTC_PLT_NONE; ++ _set_bt_plut(rtwdev, BIT(i), ++ plt_ctrl, plt_ctrl); ++ } ++ } else { ++ _set_gnt_wl(rtwdev, phy_map, BTC_GNT_HW); ++ _set_gnt_bt(rtwdev, phy_map, BTC_GNT_HW); ++ _set_bt_plut(rtwdev, BTC_PHY_ALL, ++ BTC_PLT_BT, BTC_PLT_BT); ++ } ++ break; ++ case BTC_ANT_W5G: ++ rtw89_mac_cfg_ctrl_path(rtwdev, true); ++ _set_gnt_wl(rtwdev, phy_map, BTC_GNT_SW_HI); ++ _set_gnt_bt(rtwdev, phy_map, BTC_GNT_HW); ++ _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE); ++ break; ++ case BTC_ANT_W25G: ++ rtw89_mac_cfg_ctrl_path(rtwdev, true); ++ _set_gnt_wl(rtwdev, phy_map, BTC_GNT_HW); ++ _set_gnt_bt(rtwdev, phy_map, BTC_GNT_HW); ++ _set_bt_plut(rtwdev, BTC_PHY_ALL, ++ BTC_PLT_GNT_WL, BTC_PLT_GNT_WL); ++ break; ++ case BTC_ANT_FREERUN: ++ rtw89_mac_cfg_ctrl_path(rtwdev, true); ++ _set_gnt_wl(rtwdev, phy_map, BTC_GNT_SW_HI); ++ _set_gnt_bt(rtwdev, phy_map, BTC_GNT_SW_HI); ++ _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE); ++ break; ++ case BTC_ANT_WRFK: ++ rtw89_mac_cfg_ctrl_path(rtwdev, true); ++ _set_gnt_wl(rtwdev, phy_map, BTC_GNT_SW_HI); ++ _set_gnt_bt(rtwdev, phy_map, BTC_GNT_SW_LO); ++ _set_bt_plut(rtwdev, phy_map, BTC_PLT_NONE, BTC_PLT_NONE); ++ break; ++ case BTC_ANT_BRFK: ++ rtw89_mac_cfg_ctrl_path(rtwdev, false); ++ _set_gnt_wl(rtwdev, phy_map, BTC_GNT_SW_LO); ++ _set_gnt_bt(rtwdev, phy_map, BTC_GNT_SW_HI); ++ _set_bt_plut(rtwdev, phy_map, BTC_PLT_NONE, BTC_PLT_NONE); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void _action_wl_only(struct rtw89_dev *rtwdev) ++{ ++ _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WONLY); ++ _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_ONLY); ++} ++ ++static void _action_wl_init(struct rtw89_dev *rtwdev) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); ++ ++ _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WINIT); ++ _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_INIT); ++} ++ ++static void _action_wl_off(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); ++ ++ if (wl->status.map.rf_off || btc->dm.bt_only) ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_WOFF); ++ ++ _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_OFF); ++} ++ ++static void _action_freerun(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); ++ ++ _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_FREERUN); ++ _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_FREERUN); ++ ++ btc->dm.freerun = true; ++} ++ ++static void _action_bt_whql(struct rtw89_dev *rtwdev) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); ++ ++ _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_WHQL); ++} ++ ++static void _action_bt_off(struct rtw89_dev *rtwdev) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); ++ ++ _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WONLY); ++ _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_OFF); ++} ++ ++static void _action_bt_idle(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_bt_link_info *b = &btc->cx.bt.link_info; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { /* shared-antenna */ ++ switch (btc->cx.state_map) { ++ case BTC_WBUSY_BNOSCAN: /*wl-busy + bt idle*/ ++ if (b->profile_cnt.now > 0) ++ _set_policy(rtwdev, BTC_CXP_FIX_TD4010, ++ BTC_ACT_BT_IDLE); ++ else ++ _set_policy(rtwdev, BTC_CXP_FIX_TD4020, ++ BTC_ACT_BT_IDLE); ++ break; ++ case BTC_WBUSY_BSCAN: /*wl-busy + bt-inq */ ++ _set_policy(rtwdev, BTC_CXP_PFIX_TD5050, ++ BTC_ACT_BT_IDLE); ++ break; ++ case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-idle */ ++ if (b->profile_cnt.now > 0) ++ _set_policy(rtwdev, BTC_CXP_FIX_TD4010, ++ BTC_ACT_BT_IDLE); ++ else ++ _set_policy(rtwdev, BTC_CXP_FIX_TD4020, ++ BTC_ACT_BT_IDLE); ++ break; ++ case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq */ ++ _set_policy(rtwdev, BTC_CXP_FIX_TD5050, ++ BTC_ACT_BT_IDLE); ++ break; ++ case BTC_WLINKING: /* wl-connecting + bt-inq or bt-idle */ ++ _set_policy(rtwdev, BTC_CXP_FIX_TD7010, ++ BTC_ACT_BT_IDLE); ++ break; ++ case BTC_WIDLE: /* wl-idle + bt-idle */ ++ _set_policy(rtwdev, BTC_CXP_OFF_BWB1, BTC_ACT_BT_IDLE); ++ break; ++ } ++ } else { /* dedicated-antenna */ ++ _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_BT_IDLE); ++ } ++} ++ ++static void _action_bt_hfp(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { ++ if (btc->cx.wl.status.map._4way) ++ _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_BT_HFP); ++ else ++ _set_policy(rtwdev, BTC_CXP_OFF_BWB0, BTC_ACT_BT_HFP); ++ } else { ++ _set_policy(rtwdev, BTC_CXP_OFF_EQ2, BTC_ACT_BT_HFP); ++ } ++} ++ ++static void _action_bt_hid(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ if (btc->mdinfo.ant.type == BTC_ANT_SHARED) /* shared-antenna */ ++ if (btc->cx.wl.status.map._4way) ++ _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_BT_HID); ++ else ++ _set_policy(rtwdev, BTC_CXP_OFF_BWB0, BTC_ACT_BT_HID); ++ else /* dedicated-antenna */ ++ _set_policy(rtwdev, BTC_CXP_OFF_EQ3, BTC_ACT_BT_HID); ++} ++ ++static void _action_bt_a2dp(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info; ++ struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ switch (btc->cx.state_map) { ++ case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP */ ++ if (a2dp.vendor_id == 0x4c || dm->leak_ap) { ++ dm->slot_dur[CXST_W1] = 40; ++ dm->slot_dur[CXST_B1] = 200; ++ _set_policy(rtwdev, ++ BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP); ++ } else { ++ _set_policy(rtwdev, ++ BTC_CXP_PAUTO_TD50200, BTC_ACT_BT_A2DP); ++ } ++ break; ++ case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP */ ++ _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3050, BTC_ACT_BT_A2DP); ++ break; ++ case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP */ ++ _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050, BTC_ACT_BT_A2DP); ++ break; ++ case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP */ ++ case BTC_WLINKING: /* wl-connecting + bt-A2DP */ ++ if (a2dp.vendor_id == 0x4c || dm->leak_ap) { ++ dm->slot_dur[CXST_W1] = 40; ++ dm->slot_dur[CXST_B1] = 200; ++ _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, ++ BTC_ACT_BT_A2DP); ++ } else { ++ _set_policy(rtwdev, BTC_CXP_AUTO_TD50200, ++ BTC_ACT_BT_A2DP); ++ } ++ break; ++ case BTC_WIDLE: /* wl-idle + bt-A2DP */ ++ _set_policy(rtwdev, BTC_CXP_AUTO_TD20200, BTC_ACT_BT_A2DP); ++ break; ++ } ++} ++ ++static void _action_bt_a2dpsink(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ switch (btc->cx.state_map) { ++ case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2dp_Sink */ ++ _set_policy(rtwdev, BTC_CXP_PFIX_TD2030, BTC_ACT_BT_A2DPSINK); ++ break; ++ case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2dp_Sink */ ++ _set_policy(rtwdev, BTC_CXP_PFIX_TD2060, BTC_ACT_BT_A2DPSINK); ++ break; ++ case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2dp_Sink */ ++ _set_policy(rtwdev, BTC_CXP_FIX_TD2030, BTC_ACT_BT_A2DPSINK); ++ break; ++ case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2dp_Sink */ ++ _set_policy(rtwdev, BTC_CXP_FIX_TD2060, BTC_ACT_BT_A2DPSINK); ++ break; ++ case BTC_WLINKING: /* wl-connecting + bt-A2dp_Sink */ ++ _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_A2DPSINK); ++ break; ++ case BTC_WIDLE: /* wl-idle + bt-A2dp_Sink */ ++ _set_policy(rtwdev, BTC_CXP_FIX_TD2080, BTC_ACT_BT_A2DPSINK); ++ break; ++ } ++} ++ ++static void _action_bt_pan(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ switch (btc->cx.state_map) { ++ case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-PAN */ ++ _set_policy(rtwdev, BTC_CXP_PFIX_TD5050, BTC_ACT_BT_PAN); ++ break; ++ case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-PAN */ ++ _set_policy(rtwdev, BTC_CXP_PFIX_TD3070, BTC_ACT_BT_PAN); ++ break; ++ case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-PAN */ ++ _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_PAN); ++ break; ++ case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-PAN */ ++ _set_policy(rtwdev, BTC_CXP_FIX_TD3060, BTC_ACT_BT_PAN); ++ break; ++ case BTC_WLINKING: /* wl-connecting + bt-PAN */ ++ _set_policy(rtwdev, BTC_CXP_FIX_TD4020, BTC_ACT_BT_PAN); ++ break; ++ case BTC_WIDLE: /* wl-idle + bt-pan */ ++ _set_policy(rtwdev, BTC_CXP_PFIX_TD2080, BTC_ACT_BT_PAN); ++ break; ++ } ++} ++ ++static void _action_bt_a2dp_hid(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info; ++ struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ switch (btc->cx.state_map) { ++ case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+HID */ ++ case BTC_WIDLE: /* wl-idle + bt-A2DP */ ++ if (a2dp.vendor_id == 0x4c || dm->leak_ap) { ++ dm->slot_dur[CXST_W1] = 40; ++ dm->slot_dur[CXST_B1] = 200; ++ _set_policy(rtwdev, ++ BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP_HID); ++ } else { ++ _set_policy(rtwdev, ++ BTC_CXP_PAUTO_TD50200, BTC_ACT_BT_A2DP_HID); ++ } ++ break; ++ case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+HID */ ++ _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3050, BTC_ACT_BT_A2DP_HID); ++ break; ++ ++ case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+HID */ ++ _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050, BTC_ACT_BT_A2DP_HID); ++ break; ++ case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+HID */ ++ case BTC_WLINKING: /* wl-connecting + bt-A2DP+HID */ ++ if (a2dp.vendor_id == 0x4c || dm->leak_ap) { ++ dm->slot_dur[CXST_W1] = 40; ++ dm->slot_dur[CXST_B1] = 200; ++ _set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, ++ BTC_ACT_BT_A2DP_HID); ++ } else { ++ _set_policy(rtwdev, BTC_CXP_AUTO_TD50200, ++ BTC_ACT_BT_A2DP_HID); ++ } ++ break; ++ } ++} ++ ++static void _action_bt_a2dp_pan(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ switch (btc->cx.state_map) { ++ case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+PAN */ ++ _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, BTC_ACT_BT_A2DP_PAN); ++ break; ++ case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+PAN */ ++ _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, BTC_ACT_BT_A2DP_PAN); ++ break; ++ case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+PAN */ ++ _set_policy(rtwdev, BTC_CXP_AUTO2_TD5050, BTC_ACT_BT_A2DP_PAN); ++ break; ++ case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+PAN */ ++ _set_policy(rtwdev, BTC_CXP_AUTO2_TD3070, BTC_ACT_BT_A2DP_PAN); ++ break; ++ case BTC_WLINKING: /* wl-connecting + bt-A2DP+PAN */ ++ _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050, BTC_ACT_BT_A2DP_PAN); ++ break; ++ case BTC_WIDLE: /* wl-idle + bt-A2DP+PAN */ ++ _set_policy(rtwdev, BTC_CXP_PAUTO2_TD2080, BTC_ACT_BT_A2DP_PAN); ++ break; ++ } ++} ++ ++static void _action_bt_pan_hid(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ switch (btc->cx.state_map) { ++ case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-PAN+HID */ ++ _set_policy(rtwdev, BTC_CXP_PFIX_TD3030, BTC_ACT_BT_PAN_HID); ++ break; ++ case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-PAN+HID */ ++ _set_policy(rtwdev, BTC_CXP_PFIX_TD3070, BTC_ACT_BT_PAN_HID); ++ break; ++ case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-PAN+HID */ ++ _set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_PAN_HID); ++ break; ++ case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-PAN+HID */ ++ _set_policy(rtwdev, BTC_CXP_FIX_TD3060, BTC_ACT_BT_PAN_HID); ++ break; ++ case BTC_WLINKING: /* wl-connecting + bt-PAN+HID */ ++ _set_policy(rtwdev, BTC_CXP_FIX_TD4010, BTC_ACT_BT_PAN_HID); ++ break; ++ case BTC_WIDLE: /* wl-idle + bt-PAN+HID */ ++ _set_policy(rtwdev, BTC_CXP_PFIX_TD2080, BTC_ACT_BT_PAN_HID); ++ break; ++ } ++} ++ ++static void _action_bt_a2dp_pan_hid(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ switch (btc->cx.state_map) { ++ case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+PAN+HID */ ++ _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, ++ BTC_ACT_BT_A2DP_PAN_HID); ++ break; ++ case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+PAN+HID */ ++ _set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, ++ BTC_ACT_BT_A2DP_PAN_HID); ++ break; ++ case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+PAN+HID */ ++ _set_policy(rtwdev, BTC_CXP_AUTO2_TD3070, ++ BTC_ACT_BT_A2DP_PAN_HID); ++ break; ++ case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+PAN+HID */ ++ case BTC_WLINKING: /* wl-connecting + bt-A2DP+PAN+HID */ ++ _set_policy(rtwdev, BTC_CXP_AUTO2_TD3050, ++ BTC_ACT_BT_A2DP_PAN_HID); ++ break; ++ case BTC_WIDLE: /* wl-idle + bt-A2DP+PAN+HID */ ++ _set_policy(rtwdev, BTC_CXP_PAUTO2_TD2080, ++ BTC_ACT_BT_A2DP_PAN_HID); ++ break; ++ } ++} ++ ++static void _action_wl_5g(struct rtw89_dev *rtwdev) ++{ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W5G); ++ _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_5G); ++} ++ ++static void _action_wl_other(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ if (btc->mdinfo.ant.type == BTC_ANT_SHARED) ++ _set_policy(rtwdev, BTC_CXP_OFFB_BWB0, BTC_ACT_WL_OTHER); ++ else ++ _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_OTHER); ++} ++ ++static void _action_wl_nc(struct rtw89_dev *rtwdev) ++{ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_NC); ++} ++ ++static void _action_wl_rfk(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_rfk_info rfk = btc->cx.wl.rfk_info; ++ ++ if (rfk.state != BTC_WRFK_START) ++ return; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): band = %d\n", ++ __func__, rfk.band); ++ ++ _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK); ++ _set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_WL_RFK); ++} ++ ++static void _set_btg_ctrl(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; ++ struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; ++ bool is_btg = false; ++ ++ if (btc->ctrl.manual) ++ return; ++ ++ /* notify halbb ignore GNT_BT or not for WL BB Rx-AGC control */ ++ if (wl_rinfo->link_mode == BTC_WLINK_5G) /* always 0 if 5G */ ++ is_btg = false; ++ else if (wl_rinfo->link_mode == BTC_WLINK_25G_DBCC && ++ wl_dinfo->real_band[RTW89_PHY_1] != RTW89_BAND_2G) ++ is_btg = false; ++ else ++ is_btg = true; ++ ++ if (btc->dm.run_reason != BTC_RSN_NTFY_INIT && ++ is_btg == btc->dm.wl_btg_rx) ++ return; ++ ++ btc->dm.wl_btg_rx = is_btg; ++ ++ if (wl_rinfo->link_mode == BTC_WLINK_25G_MCC) ++ return; ++ ++ rtw89_ctrl_btg(rtwdev, is_btg); ++} ++ ++struct rtw89_txtime_data { ++ struct rtw89_dev *rtwdev; ++ int type; ++ u32 tx_time; ++ u8 tx_retry; ++ u16 enable; ++ bool reenable; ++}; ++ ++static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta) ++{ ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_txtime_data *iter_data = ++ (struct rtw89_txtime_data *)data; ++ struct rtw89_dev *rtwdev = iter_data->rtwdev; ++ struct rtw89_vif *rtwvif = rtwsta->rtwvif; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_wl_info *wl = &cx->wl; ++ struct rtw89_btc_wl_link_info *plink = NULL; ++ u8 port = rtwvif->port; ++ u32 tx_time = iter_data->tx_time; ++ u8 tx_retry = iter_data->tx_retry; ++ u16 enable = iter_data->enable; ++ bool reenable = iter_data->reenable; ++ ++ plink = &wl->link_info[port]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): port = %d\n", __func__, port); ++ ++ if (!plink->connected) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): connected = %d\n", ++ __func__, plink->connected); ++ return; ++ } ++ ++ /* backup the original tx time before tx-limit on */ ++ if (reenable) { ++ rtw89_mac_get_tx_time(rtwdev, rtwsta, &plink->tx_time); ++ rtw89_mac_get_tx_retry_limit(rtwdev, rtwsta, &plink->tx_retry); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): reenable, tx_time=%d tx_retry= %d\n", ++ __func__, plink->tx_time, plink->tx_retry); ++ } ++ ++ /* restore the original tx time if no tx-limit */ ++ if (!enable) { ++ rtw89_mac_set_tx_time(rtwdev, rtwsta, true, plink->tx_time); ++ rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta, true, ++ plink->tx_retry); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): restore, tx_time=%d tx_retry= %d\n", ++ __func__, plink->tx_time, plink->tx_retry); ++ ++ } else { ++ rtw89_mac_set_tx_time(rtwdev, rtwsta, false, tx_time); ++ rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta, false, tx_retry); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): set, tx_time=%d tx_retry= %d\n", ++ __func__, tx_time, tx_retry); ++ } ++} ++ ++static void _set_wl_tx_limit(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_wl_info *wl = &cx->wl; ++ struct rtw89_btc_bt_info *bt = &cx->bt; ++ struct rtw89_btc_bt_link_info *b = &bt->link_info; ++ struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc; ++ struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc; ++ struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; ++ struct rtw89_txtime_data data = {.rtwdev = rtwdev}; ++ u8 mode = wl_rinfo->link_mode; ++ u8 tx_retry = 0; ++ u32 tx_time = 0; ++ u16 enable = 0; ++ bool reenable = false; ++ ++ if (btc->ctrl.manual) ++ return; ++ ++ if (btc->dm.freerun || btc->ctrl.igno_bt || b->profile_cnt.now == 0 || ++ mode == BTC_WLINK_5G || mode == BTC_WLINK_NOLINK) { ++ enable = 0; ++ tx_time = BTC_MAX_TX_TIME_DEF; ++ tx_retry = BTC_MAX_TX_RETRY_DEF; ++ } else if ((hfp->exist && hid->exist) || hid->pair_cnt > 1) { ++ enable = 1; ++ tx_time = BTC_MAX_TX_TIME_L2; ++ tx_retry = BTC_MAX_TX_RETRY_L1; ++ } else if (hfp->exist || hid->exist) { ++ enable = 1; ++ tx_time = BTC_MAX_TX_TIME_L3; ++ tx_retry = BTC_MAX_TX_RETRY_L1; ++ } else { ++ enable = 0; ++ tx_time = BTC_MAX_TX_TIME_DEF; ++ tx_retry = BTC_MAX_TX_RETRY_DEF; ++ } ++ ++ if (dm->wl_tx_limit.enable == enable && ++ dm->wl_tx_limit.tx_time == tx_time && ++ dm->wl_tx_limit.tx_retry == tx_retry) ++ return; ++ ++ if (!dm->wl_tx_limit.enable && enable) ++ reenable = true; ++ ++ dm->wl_tx_limit.enable = enable; ++ dm->wl_tx_limit.tx_time = tx_time; ++ dm->wl_tx_limit.tx_retry = tx_retry; ++ ++ data.enable = enable; ++ data.tx_time = tx_time; ++ data.tx_retry = tx_retry; ++ data.reenable = reenable; ++ ++ ieee80211_iterate_stations_atomic(rtwdev->hw, ++ rtw89_tx_time_iter, ++ &data); ++} ++ ++static void _set_bt_rx_agc(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; ++ struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ bool bt_hi_lna_rx = false; ++ ++ if (wl_rinfo->link_mode != BTC_WLINK_NOLINK && btc->dm.wl_btg_rx) ++ bt_hi_lna_rx = true; ++ ++ if (bt_hi_lna_rx == bt->hi_lna_rx) ++ return; ++ ++ _write_scbd(rtwdev, BTC_WSCB_BT_HILNA, bt_hi_lna_rx); ++} ++ ++/* TODO add these functions */ ++static void _action_common(struct rtw89_dev *rtwdev) ++{ ++ _set_btg_ctrl(rtwdev); ++ _set_wl_tx_limit(rtwdev); ++ _set_bt_afh_info(rtwdev); ++ _set_bt_rx_agc(rtwdev); ++ _set_rf_trx_para(rtwdev); ++} ++ ++static void _action_by_bt(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; ++ struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc; ++ struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; ++ struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc; ++ u8 profile_map = 0; ++ ++ if (bt_linfo->hfp_desc.exist) ++ profile_map |= BTC_BT_HFP; ++ ++ if (bt_linfo->hid_desc.exist) ++ profile_map |= BTC_BT_HID; ++ ++ if (bt_linfo->a2dp_desc.exist) ++ profile_map |= BTC_BT_A2DP; ++ ++ if (bt_linfo->pan_desc.exist) ++ profile_map |= BTC_BT_PAN; ++ ++ switch (profile_map) { ++ case BTC_BT_NOPROFILE: ++ if (_check_freerun(rtwdev)) ++ _action_freerun(rtwdev); ++ else if (a2dp.active || pan.active) ++ _action_bt_pan(rtwdev); ++ else ++ _action_bt_idle(rtwdev); ++ break; ++ case BTC_BT_HFP: ++ if (_check_freerun(rtwdev)) ++ _action_freerun(rtwdev); ++ else ++ _action_bt_hfp(rtwdev); ++ break; ++ case BTC_BT_HFP | BTC_BT_HID: ++ case BTC_BT_HID: ++ if (_check_freerun(rtwdev)) ++ _action_freerun(rtwdev); ++ else ++ _action_bt_hid(rtwdev); ++ break; ++ case BTC_BT_A2DP: ++ if (_check_freerun(rtwdev)) ++ _action_freerun(rtwdev); ++ else if (a2dp.sink) ++ _action_bt_a2dpsink(rtwdev); ++ else if (bt_linfo->multi_link.now && !hid.pair_cnt) ++ _action_bt_a2dp_pan(rtwdev); ++ else ++ _action_bt_a2dp(rtwdev); ++ break; ++ case BTC_BT_PAN: ++ _action_bt_pan(rtwdev); ++ break; ++ case BTC_BT_A2DP | BTC_BT_HFP: ++ case BTC_BT_A2DP | BTC_BT_HID: ++ case BTC_BT_A2DP | BTC_BT_HFP | BTC_BT_HID: ++ if (_check_freerun(rtwdev)) ++ _action_freerun(rtwdev); ++ else ++ _action_bt_a2dp_hid(rtwdev); ++ break; ++ case BTC_BT_A2DP | BTC_BT_PAN: ++ _action_bt_a2dp_pan(rtwdev); ++ break; ++ case BTC_BT_PAN | BTC_BT_HFP: ++ case BTC_BT_PAN | BTC_BT_HID: ++ case BTC_BT_PAN | BTC_BT_HFP | BTC_BT_HID: ++ _action_bt_pan_hid(rtwdev); ++ break; ++ case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HID: ++ case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HFP: ++ default: ++ _action_bt_a2dp_pan_hid(rtwdev); ++ break; ++ } ++} ++ ++static void _action_wl_2g_sta(struct rtw89_dev *rtwdev) ++{ ++ _action_by_bt(rtwdev); ++} ++ ++static void _action_wl_scan(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; ++ ++ if (rtwdev->dbcc_en) { ++ if (wl_dinfo->real_band[RTW89_PHY_0] != RTW89_BAND_2G && ++ wl_dinfo->real_band[RTW89_PHY_1] != RTW89_BAND_2G) ++ _action_wl_5g(rtwdev); ++ else ++ _action_by_bt(rtwdev); ++ } else { ++ if (wl->scan_info.band[RTW89_PHY_0] != RTW89_BAND_2G) ++ _action_wl_5g(rtwdev); ++ else ++ _action_by_bt(rtwdev); ++ } ++} ++ ++static void _action_wl_25g_mcc(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W25G); ++ ++ if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { ++ if (btc->cx.bt.link_info.profile_cnt.now == 0) ++ _set_policy(rtwdev, BTC_CXP_OFFE_DEF2, ++ BTC_ACT_WL_25G_MCC); ++ else ++ _set_policy(rtwdev, BTC_CXP_OFFE_DEF, ++ BTC_ACT_WL_25G_MCC); ++ } else { /* dedicated-antenna */ ++ _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_25G_MCC); ++ } ++} ++ ++static void _action_wl_2g_mcc(struct rtw89_dev *rtwdev) ++{ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { /* shared-antenna */ ++ if (btc->cx.bt.link_info.profile_cnt.now == 0) ++ _set_policy(rtwdev, BTC_CXP_OFFE_DEF2, ++ BTC_ACT_WL_2G_MCC); ++ else ++ _set_policy(rtwdev, BTC_CXP_OFFE_DEF, ++ BTC_ACT_WL_2G_MCC); ++ } else { /* dedicated-antenna */ ++ _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_MCC); ++ } ++} ++ ++static void _action_wl_2g_scc(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { /* shared-antenna */ ++ if (btc->cx.bt.link_info.profile_cnt.now == 0) ++ _set_policy(rtwdev, ++ BTC_CXP_OFFE_DEF2, BTC_ACT_WL_2G_SCC); ++ else ++ _set_policy(rtwdev, ++ BTC_CXP_OFFE_DEF, BTC_ACT_WL_2G_SCC); ++ } else { /* dedicated-antenna */ ++ _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_SCC); ++ } ++} ++ ++static void _action_wl_2g_ap(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { ++ if (btc->cx.bt.link_info.profile_cnt.now == 0) ++ _set_policy(rtwdev, BTC_CXP_OFFE_DEF2, ++ BTC_ACT_WL_2G_AP); ++ else ++ _set_policy(rtwdev, BTC_CXP_OFFE_DEF, BTC_ACT_WL_2G_AP); ++ } else {/* dedicated-antenna */ ++ _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_AP); ++ } ++} ++ ++static void _action_wl_2g_go(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { /* shared-antenna */ ++ if (btc->cx.bt.link_info.profile_cnt.now == 0) ++ _set_policy(rtwdev, ++ BTC_CXP_OFFE_DEF2, BTC_ACT_WL_2G_GO); ++ else ++ _set_policy(rtwdev, ++ BTC_CXP_OFFE_DEF, BTC_ACT_WL_2G_GO); ++ } else { /* dedicated-antenna */ ++ _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_GO); ++ } ++} ++ ++static void _action_wl_2g_gc(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { /* shared-antenna */ ++ _action_by_bt(rtwdev); ++ } else {/* dedicated-antenna */ ++ _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_GC); ++ } ++} ++ ++static void _action_wl_2g_nan(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ++ ++ if (btc->mdinfo.ant.type == BTC_ANT_SHARED) { /* shared-antenna */ ++ if (btc->cx.bt.link_info.profile_cnt.now == 0) ++ _set_policy(rtwdev, ++ BTC_CXP_OFFE_DEF2, BTC_ACT_WL_2G_NAN); ++ else ++ _set_policy(rtwdev, ++ BTC_CXP_OFFE_DEF, BTC_ACT_WL_2G_NAN); ++ } else { /* dedicated-antenna */ ++ _set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_2G_NAN); ++ } ++} ++ ++static u32 _read_scbd(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ u32 scbd_val = 0; ++ ++ if (!chip->scbd) ++ return 0; ++ ++ scbd_val = rtw89_mac_get_sb(rtwdev); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], read scbd: 0x%08x\n", ++ scbd_val); ++ ++ btc->cx.cnt_bt[BTC_BCNT_SCBDREAD]++; ++ return scbd_val; ++} ++ ++static void _write_scbd(struct rtw89_dev *rtwdev, u32 val, bool state) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ u32 scbd_val = 0; ++ ++ if (!chip->scbd) ++ return; ++ ++ scbd_val = state ? wl->scbd | val : wl->scbd & ~val; ++ ++ if (scbd_val == wl->scbd) ++ return; ++ rtw89_mac_cfg_sb(rtwdev, scbd_val); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], write scbd: 0x%08x\n", ++ scbd_val); ++ wl->scbd = scbd_val; ++ ++ btc->cx.cnt_wl[BTC_WCNT_SCBDUPDATE]++; ++} ++ ++static u8 ++_update_rssi_state(struct rtw89_dev *rtwdev, u8 pre_state, u8 rssi, u8 thresh) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ u8 next_state, tol = chip->rssi_tol; ++ ++ if (pre_state == BTC_RSSI_ST_LOW || ++ pre_state == BTC_RSSI_ST_STAY_LOW) { ++ if (rssi >= (thresh + tol)) ++ next_state = BTC_RSSI_ST_HIGH; ++ else ++ next_state = BTC_RSSI_ST_STAY_LOW; ++ } else { ++ if (rssi < thresh) ++ next_state = BTC_RSSI_ST_LOW; ++ else ++ next_state = BTC_RSSI_ST_STAY_HIGH; ++ } ++ ++ return next_state; ++} ++ ++static ++void _update_dbcc_band(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ btc->cx.wl.dbcc_info.real_band[phy_idx] = ++ btc->cx.wl.scan_info.phy_map & BIT(phy_idx) ? ++ btc->cx.wl.dbcc_info.scan_band[phy_idx] : ++ btc->cx.wl.dbcc_info.op_band[phy_idx]; ++} ++ ++static void _update_wl_info(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info; ++ struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; ++ struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; ++ u8 i, cnt_connect = 0, cnt_connecting = 0, cnt_active = 0; ++ u8 cnt_2g = 0, cnt_5g = 0, phy; ++ u32 wl_2g_ch[2] = {0}, wl_5g_ch[2] = {0}; ++ bool b2g = false, b5g = false, client_joined = false; ++ ++ memset(wl_rinfo, 0, sizeof(*wl_rinfo)); ++ ++ for (i = 0; i < RTW89_MAX_HW_PORT_NUM; i++) { ++ /* check if role active? */ ++ if (!wl_linfo[i].active) ++ continue; ++ ++ cnt_active++; ++ wl_rinfo->active_role[cnt_active - 1].role = wl_linfo[i].role; ++ wl_rinfo->active_role[cnt_active - 1].pid = wl_linfo[i].pid; ++ wl_rinfo->active_role[cnt_active - 1].phy = wl_linfo[i].phy; ++ wl_rinfo->active_role[cnt_active - 1].band = wl_linfo[i].band; ++ wl_rinfo->active_role[cnt_active - 1].noa = (u8)wl_linfo[i].noa; ++ wl_rinfo->active_role[cnt_active - 1].connected = 0; ++ ++ wl->port_id[wl_linfo[i].role] = wl_linfo[i].pid; ++ ++ phy = wl_linfo[i].phy; ++ ++ /* check dbcc role */ ++ if (rtwdev->dbcc_en && phy < RTW89_PHY_MAX) { ++ wl_dinfo->role[phy] = wl_linfo[i].role; ++ wl_dinfo->op_band[phy] = wl_linfo[i].band; ++ _update_dbcc_band(rtwdev, phy); ++ _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); ++ } ++ ++ if (wl_linfo[i].connected == MLME_NO_LINK) { ++ continue; ++ } else if (wl_linfo[i].connected == MLME_LINKING) { ++ cnt_connecting++; ++ } else { ++ cnt_connect++; ++ if ((wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO || ++ wl_linfo[i].role == RTW89_WIFI_ROLE_AP) && ++ wl_linfo[i].client_cnt > 1) ++ client_joined = true; ++ } ++ ++ wl_rinfo->role_map.val |= BIT(wl_linfo[i].role); ++ wl_rinfo->active_role[cnt_active - 1].ch = wl_linfo[i].ch; ++ wl_rinfo->active_role[cnt_active - 1].bw = wl_linfo[i].bw; ++ wl_rinfo->active_role[cnt_active - 1].connected = 1; ++ ++ /* only care 2 roles + BT coex */ ++ if (wl_linfo[i].band != RTW89_BAND_2G) { ++ if (cnt_5g <= ARRAY_SIZE(wl_5g_ch) - 1) ++ wl_5g_ch[cnt_5g] = wl_linfo[i].ch; ++ cnt_5g++; ++ b5g = true; ++ } else { ++ if (cnt_2g <= ARRAY_SIZE(wl_2g_ch) - 1) ++ wl_2g_ch[cnt_2g] = wl_linfo[i].ch; ++ cnt_2g++; ++ b2g = true; ++ } ++ } ++ ++ wl_rinfo->connect_cnt = cnt_connect; ++ ++ /* Be careful to change the following sequence!! */ ++ if (cnt_connect == 0) { ++ wl_rinfo->link_mode = BTC_WLINK_NOLINK; ++ wl_rinfo->role_map.role.none = 1; ++ } else if (!b2g && b5g) { ++ wl_rinfo->link_mode = BTC_WLINK_5G; ++ } else if (wl_rinfo->role_map.role.nan) { ++ wl_rinfo->link_mode = BTC_WLINK_2G_NAN; ++ } else if (cnt_connect > BTC_TDMA_WLROLE_MAX) { ++ wl_rinfo->link_mode = BTC_WLINK_OTHER; ++ } else if (b2g && b5g && cnt_connect == 2) { ++ if (rtwdev->dbcc_en) { ++ switch (wl_dinfo->role[RTW89_PHY_0]) { ++ case RTW89_WIFI_ROLE_STATION: ++ wl_rinfo->link_mode = BTC_WLINK_2G_STA; ++ break; ++ case RTW89_WIFI_ROLE_P2P_GO: ++ wl_rinfo->link_mode = BTC_WLINK_2G_GO; ++ break; ++ case RTW89_WIFI_ROLE_P2P_CLIENT: ++ wl_rinfo->link_mode = BTC_WLINK_2G_GC; ++ break; ++ case RTW89_WIFI_ROLE_AP: ++ wl_rinfo->link_mode = BTC_WLINK_2G_AP; ++ break; ++ default: ++ wl_rinfo->link_mode = BTC_WLINK_OTHER; ++ break; ++ } ++ } else { ++ wl_rinfo->link_mode = BTC_WLINK_25G_MCC; ++ } ++ } else if (!b5g && cnt_connect == 2) { ++ if (wl_rinfo->role_map.role.station && ++ (wl_rinfo->role_map.role.p2p_go || ++ wl_rinfo->role_map.role.p2p_gc || ++ wl_rinfo->role_map.role.ap)) { ++ if (wl_2g_ch[0] == wl_2g_ch[1]) ++ wl_rinfo->link_mode = BTC_WLINK_2G_SCC; ++ else ++ wl_rinfo->link_mode = BTC_WLINK_2G_MCC; ++ } else { ++ wl_rinfo->link_mode = BTC_WLINK_2G_MCC; ++ } ++ } else if (!b5g && cnt_connect == 1) { ++ if (wl_rinfo->role_map.role.station) ++ wl_rinfo->link_mode = BTC_WLINK_2G_STA; ++ else if (wl_rinfo->role_map.role.ap) ++ wl_rinfo->link_mode = BTC_WLINK_2G_AP; ++ else if (wl_rinfo->role_map.role.p2p_go) ++ wl_rinfo->link_mode = BTC_WLINK_2G_GO; ++ else if (wl_rinfo->role_map.role.p2p_gc) ++ wl_rinfo->link_mode = BTC_WLINK_2G_GC; ++ else ++ wl_rinfo->link_mode = BTC_WLINK_OTHER; ++ } ++ ++ /* if no client_joined, don't care P2P-GO/AP role */ ++ if (wl_rinfo->role_map.role.p2p_go || wl_rinfo->role_map.role.ap) { ++ if (!client_joined) { ++ if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC || ++ wl_rinfo->link_mode == BTC_WLINK_2G_MCC) { ++ wl_rinfo->link_mode = BTC_WLINK_2G_STA; ++ wl_rinfo->connect_cnt = 1; ++ } else if (wl_rinfo->link_mode == BTC_WLINK_2G_GO || ++ wl_rinfo->link_mode == BTC_WLINK_2G_AP) { ++ wl_rinfo->link_mode = BTC_WLINK_NOLINK; ++ wl_rinfo->connect_cnt = 0; ++ } ++ } ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], cnt_connect = %d, link_mode = %d\n", ++ cnt_connect, wl_rinfo->link_mode); ++ ++ _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); ++} ++ ++#define BTC_CHK_HANG_MAX 3 ++#define BTC_SCB_INV_VALUE GENMASK(31, 0) ++ ++void rtw89_coex_act1_work(struct work_struct *work) ++{ ++ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, ++ coex_act1_work.work); ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &rtwdev->btc.dm; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_wl_info *wl = &cx->wl; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__); ++ dm->cnt_notify[BTC_NCNT_TIMER]++; ++ if (wl->status.map._4way) ++ wl->status.map._4way = false; ++ if (wl->status.map.connecting) ++ wl->status.map.connecting = false; ++ ++ _run_coex(rtwdev, BTC_RSN_ACT1_WORK); ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++void rtw89_coex_bt_devinfo_work(struct work_struct *work) ++{ ++ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, ++ coex_bt_devinfo_work.work); ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &rtwdev->btc.dm; ++ struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__); ++ dm->cnt_notify[BTC_NCNT_TIMER]++; ++ a2dp->play_latency = 0; ++ _run_coex(rtwdev, BTC_RSN_BT_DEVINFO_WORK); ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++void rtw89_coex_rfk_chk_work(struct work_struct *work) ++{ ++ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, ++ coex_rfk_chk_work.work); ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &rtwdev->btc.dm; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_wl_info *wl = &cx->wl; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__); ++ dm->cnt_notify[BTC_NCNT_TIMER]++; ++ if (wl->rfk_info.state != BTC_WRFK_STOP) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): RFK timeout\n", __func__); ++ cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]++; ++ dm->error.map.wl_rfk_timeout = true; ++ wl->rfk_info.state = BTC_WRFK_STOP; ++ _write_scbd(rtwdev, BTC_WSCB_WLRFK, false); ++ _run_coex(rtwdev, BTC_RSN_RFK_CHK_WORK); ++ } ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ u32 val; ++ bool status_change = false; ++ ++ if (!chip->scbd) ++ return; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s\n", __func__); ++ ++ val = _read_scbd(rtwdev); ++ if (val == BTC_SCB_INV_VALUE) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): return by invalid scbd value\n", ++ __func__); ++ return; ++ } ++ ++ if (!(val & BTC_BSCB_ON) || ++ btc->dm.cnt_dm[BTC_DCNT_BTCNT_FREEZE] >= BTC_CHK_HANG_MAX) ++ bt->enable.now = 0; ++ else ++ bt->enable.now = 1; ++ ++ if (bt->enable.now != bt->enable.last) ++ status_change = true; ++ ++ /* reset bt info if bt re-enable */ ++ if (bt->enable.now && !bt->enable.last) { ++ _reset_btc_var(rtwdev, BTC_RESET_BTINFO); ++ cx->cnt_bt[BTC_BCNT_REENABLE]++; ++ bt->enable.now = 1; ++ } ++ ++ bt->enable.last = bt->enable.now; ++ bt->scbd = val; ++ bt->mbx_avl = !!(val & BTC_BSCB_ACT); ++ ++ if (bt->whql_test != !!(val & BTC_BSCB_WHQL)) ++ status_change = true; ++ ++ bt->whql_test = !!(val & BTC_BSCB_WHQL); ++ bt->btg_type = val & BTC_BSCB_BT_S1 ? BTC_BT_BTG : BTC_BT_ALONE; ++ bt->link_info.a2dp_desc.active = !!(val & BTC_BSCB_A2DP_ACT); ++ ++ /* if rfk run 1->0 */ ++ if (bt->rfk_info.map.run && !(val & BTC_BSCB_RFK_RUN)) ++ status_change = true; ++ ++ bt->rfk_info.map.run = !!(val & BTC_BSCB_RFK_RUN); ++ bt->rfk_info.map.req = !!(val & BTC_BSCB_RFK_REQ); ++ bt->hi_lna_rx = !!(val & BTC_BSCB_BT_HILNA); ++ bt->link_info.status.map.connect = !!(val & BTC_BSCB_BT_CONNECT); ++ bt->run_patch_code = !!(val & BTC_BSCB_PATCH_CODE); ++ ++ if (!only_update && status_change) ++ _run_coex(rtwdev, BTC_RSN_UPDATE_BT_SCBD); ++} ++ ++static bool _chk_wl_rfk_request(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_bt_info *bt = &cx->bt; ++ ++ _update_bt_scbd(rtwdev, true); ++ ++ cx->cnt_wl[BTC_WCNT_RFK_REQ]++; ++ ++ if ((bt->rfk_info.map.run || bt->rfk_info.map.req) && ++ !bt->rfk_info.map.timeout) { ++ cx->cnt_wl[BTC_WCNT_RFK_REJECT]++; ++ } else { ++ cx->cnt_wl[BTC_WCNT_RFK_GO]++; ++ return true; ++ } ++ return false; ++} ++ ++static ++void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &rtwdev->btc.dm; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; ++ u8 mode = wl_rinfo->link_mode; ++ ++ lockdep_assert_held(&rtwdev->mutex); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): reason=%d, mode=%d\n", ++ __func__, reason, mode); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): wl_only=%d, bt_only=%d\n", ++ __func__, dm->wl_only, dm->bt_only); ++ ++ dm->run_reason = reason; ++ _update_dm_step(rtwdev, reason); ++ _update_btc_state_map(rtwdev); ++ ++ /* Be careful to change the following function sequence!! */ ++ if (btc->ctrl.manual) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): return for Manual CTRL!!\n", ++ __func__); ++ return; ++ } ++ ++ if (btc->ctrl.igno_bt && ++ (reason == BTC_RSN_UPDATE_BT_INFO || ++ reason == BTC_RSN_UPDATE_BT_SCBD)) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): return for Stop Coex DM!!\n", ++ __func__); ++ return; ++ } ++ ++ if (!wl->status.map.init_ok) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): return for WL init fail!!\n", ++ __func__); ++ return; ++ } ++ ++ if (wl->status.map.rf_off_pre == wl->status.map.rf_off && ++ wl->status.map.lps_pre == wl->status.map.lps && ++ (reason == BTC_RSN_NTFY_POWEROFF || ++ reason == BTC_RSN_NTFY_RADIO_STATE)) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): return for WL rf off state no change!!\n", ++ __func__); ++ return; ++ } ++ ++ dm->cnt_dm[BTC_DCNT_RUN]++; ++ ++ if (btc->ctrl.always_freerun) { ++ _action_freerun(rtwdev); ++ btc->ctrl.igno_bt = true; ++ goto exit; ++ } ++ ++ if (dm->wl_only) { ++ _action_wl_only(rtwdev); ++ btc->ctrl.igno_bt = true; ++ goto exit; ++ } ++ ++ if (wl->status.map.rf_off || wl->status.map.lps || dm->bt_only) { ++ _action_wl_off(rtwdev); ++ btc->ctrl.igno_bt = true; ++ goto exit; ++ } ++ ++ btc->ctrl.igno_bt = false; ++ dm->freerun = false; ++ ++ if (reason == BTC_RSN_NTFY_INIT) { ++ _action_wl_init(rtwdev); ++ goto exit; ++ } ++ ++ if (!cx->bt.enable.now && !cx->other.type) { ++ _action_bt_off(rtwdev); ++ goto exit; ++ } ++ ++ if (cx->bt.whql_test) { ++ _action_bt_whql(rtwdev); ++ goto exit; ++ } ++ ++ if (wl->rfk_info.state != BTC_WRFK_STOP) { ++ _action_wl_rfk(rtwdev); ++ goto exit; ++ } ++ ++ if (cx->state_map == BTC_WLINKING) { ++ if (mode == BTC_WLINK_NOLINK || mode == BTC_WLINK_2G_STA || ++ mode == BTC_WLINK_5G) { ++ _action_wl_scan(rtwdev); ++ goto exit; ++ } ++ } ++ ++ if (wl->status.map.scan) { ++ _action_wl_scan(rtwdev); ++ goto exit; ++ } ++ ++ switch (mode) { ++ case BTC_WLINK_NOLINK: ++ _action_wl_nc(rtwdev); ++ break; ++ case BTC_WLINK_2G_STA: ++ _action_wl_2g_sta(rtwdev); ++ break; ++ case BTC_WLINK_2G_AP: ++ _action_wl_2g_ap(rtwdev); ++ break; ++ case BTC_WLINK_2G_GO: ++ _action_wl_2g_go(rtwdev); ++ break; ++ case BTC_WLINK_2G_GC: ++ _action_wl_2g_gc(rtwdev); ++ break; ++ case BTC_WLINK_2G_SCC: ++ _action_wl_2g_scc(rtwdev); ++ break; ++ case BTC_WLINK_2G_MCC: ++ _action_wl_2g_mcc(rtwdev); ++ break; ++ case BTC_WLINK_25G_MCC: ++ _action_wl_25g_mcc(rtwdev); ++ break; ++ case BTC_WLINK_5G: ++ _action_wl_5g(rtwdev); ++ break; ++ case BTC_WLINK_2G_NAN: ++ _action_wl_2g_nan(rtwdev); ++ break; ++ default: ++ _action_wl_other(rtwdev); ++ break; ++ } ++ ++exit: ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): exit\n", __func__); ++ _action_common(rtwdev); ++} ++ ++void rtw89_btc_ntfy_poweron(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); ++ btc->dm.cnt_notify[BTC_NCNT_POWER_ON]++; ++} ++ ++void rtw89_btc_ntfy_poweroff(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__); ++ btc->dm.cnt_notify[BTC_NCNT_POWER_OFF]++; ++ ++ btc->cx.wl.status.map.rf_off = 1; ++ ++ _write_scbd(rtwdev, BTC_WSCB_ALL, false); ++ _run_coex(rtwdev, BTC_RSN_NTFY_POWEROFF); ++ ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, 0); ++ ++ btc->cx.wl.status.map.rf_off_pre = btc->cx.wl.status.map.rf_off; ++} ++ ++static void _set_init_info(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ ++ dm->init_info.wl_only = (u8)dm->wl_only; ++ dm->init_info.bt_only = (u8)dm->bt_only; ++ dm->init_info.wl_init_ok = (u8)wl->status.map.init_ok; ++ dm->init_info.dbcc_en = rtwdev->dbcc_en; ++ dm->init_info.cx_other = btc->cx.other.type; ++ dm->init_info.wl_guard_ch = chip->afh_guard_ch; ++ dm->init_info.module = btc->mdinfo; ++} ++ ++void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &rtwdev->btc.dm; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ _reset_btc_var(rtwdev, BTC_RESET_ALL); ++ btc->dm.run_reason = BTC_RSN_NONE; ++ btc->dm.run_action = BTC_ACT_NONE; ++ btc->ctrl.igno_bt = true; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): mode=%d\n", __func__, mode); ++ ++ dm->cnt_notify[BTC_NCNT_INIT_COEX]++; ++ dm->wl_only = mode == BTC_MODE_WL ? 1 : 0; ++ dm->bt_only = mode == BTC_MODE_BT ? 1 : 0; ++ wl->status.map.rf_off = mode == BTC_MODE_WLOFF ? 1 : 0; ++ ++ chip->ops->btc_set_rfe(rtwdev); ++ chip->ops->btc_init_cfg(rtwdev); ++ ++ if (!wl->status.map.init_ok) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): return for WL init fail!!\n", ++ __func__); ++ dm->error.map.init = true; ++ return; ++ } ++ ++ _write_scbd(rtwdev, ++ BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG, true); ++ _update_bt_scbd(rtwdev, true); ++ if (rtw89_mac_get_ctrl_path(rtwdev)) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): PTA owner warning!!\n", ++ __func__); ++ dm->error.map.pta_owner = true; ++ } ++ ++ _set_init_info(rtwdev); ++ _set_wl_tx_power(rtwdev, RTW89_BTC_WL_DEF_TX_PWR); ++ rtw89_btc_fw_set_slots(rtwdev, CXST_MAX, dm->slot); ++ btc_fw_set_monreg(rtwdev); ++ _fw_set_drv_info(rtwdev, CXDRVINFO_INIT); ++ _fw_set_drv_info(rtwdev, CXDRVINFO_CTRL); ++ ++ _run_coex(rtwdev, BTC_RSN_NTFY_INIT); ++} ++ ++void rtw89_btc_ntfy_scan_start(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): phy_idx=%d, band=%d\n", ++ __func__, phy_idx, band); ++ btc->dm.cnt_notify[BTC_NCNT_SCAN_START]++; ++ wl->status.map.scan = true; ++ wl->scan_info.band[phy_idx] = band; ++ wl->scan_info.phy_map |= BIT(phy_idx); ++ _fw_set_drv_info(rtwdev, CXDRVINFO_SCAN); ++ ++ if (rtwdev->dbcc_en) { ++ wl->dbcc_info.scan_band[phy_idx] = band; ++ _update_dbcc_band(rtwdev, phy_idx); ++ _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); ++ } ++ ++ _run_coex(rtwdev, BTC_RSN_NTFY_SCAN_START); ++} ++ ++void rtw89_btc_ntfy_scan_finish(struct rtw89_dev *rtwdev, u8 phy_idx) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): phy_idx=%d\n", __func__, phy_idx); ++ btc->dm.cnt_notify[BTC_NCNT_SCAN_FINISH]++; ++ ++ wl->status.map.scan = false; ++ wl->scan_info.phy_map &= ~BIT(phy_idx); ++ _fw_set_drv_info(rtwdev, CXDRVINFO_SCAN); ++ ++ if (rtwdev->dbcc_en) { ++ _update_dbcc_band(rtwdev, phy_idx); ++ _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); ++ } ++ ++ _run_coex(rtwdev, BTC_RSN_NTFY_SCAN_FINISH); ++} ++ ++void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): phy_idx=%d, band=%d\n", ++ __func__, phy_idx, band); ++ btc->dm.cnt_notify[BTC_NCNT_SWITCH_BAND]++; ++ ++ wl->scan_info.band[phy_idx] = band; ++ wl->scan_info.phy_map |= BIT(phy_idx); ++ _fw_set_drv_info(rtwdev, CXDRVINFO_SCAN); ++ ++ if (rtwdev->dbcc_en) { ++ wl->dbcc_info.scan_band[phy_idx] = band; ++ _update_dbcc_band(rtwdev, phy_idx); ++ _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC); ++ } ++ _run_coex(rtwdev, BTC_RSN_NTFY_SWBAND); ++} ++ ++void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev, ++ enum btc_pkt_type pkt_type) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_wl_info *wl = &cx->wl; ++ struct rtw89_btc_bt_link_info *b = &cx->bt.link_info; ++ struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc; ++ struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc; ++ u32 cnt; ++ u32 delay = RTW89_COEX_ACT1_WORK_PERIOD; ++ bool delay_work = false; ++ ++ switch (pkt_type) { ++ case PACKET_DHCP: ++ cnt = ++cx->cnt_wl[BTC_WCNT_DHCP]; ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): DHCP cnt=%d\n", __func__, cnt); ++ wl->status.map.connecting = true; ++ delay_work = true; ++ break; ++ case PACKET_EAPOL: ++ cnt = ++cx->cnt_wl[BTC_WCNT_EAPOL]; ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): EAPOL cnt=%d\n", __func__, cnt); ++ wl->status.map._4way = true; ++ delay_work = true; ++ if (hfp->exist || hid->exist) ++ delay /= 2; ++ break; ++ case PACKET_EAPOL_END: ++ cnt = ++cx->cnt_wl[BTC_WCNT_EAPOL]; ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): EAPOL_End cnt=%d\n", ++ __func__, cnt); ++ wl->status.map._4way = false; ++ cancel_delayed_work(&rtwdev->coex_act1_work); ++ break; ++ case PACKET_ARP: ++ cnt = ++cx->cnt_wl[BTC_WCNT_ARP]; ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): ARP cnt=%d\n", __func__, cnt); ++ return; ++ case PACKET_ICMP: ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): ICMP pkt\n", __func__); ++ return; ++ default: ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): unknown packet type %d\n", ++ __func__, pkt_type); ++ return; ++ } ++ ++ if (delay_work) { ++ cancel_delayed_work(&rtwdev->coex_act1_work); ++ ieee80211_queue_delayed_work(rtwdev->hw, ++ &rtwdev->coex_act1_work, delay); ++ } ++ ++ btc->dm.cnt_notify[BTC_NCNT_SPECIAL_PACKET]++; ++ _run_coex(rtwdev, BTC_RSN_NTFY_SPECIFIC_PACKET); ++} ++ ++void rtw89_btc_ntfy_eapol_packet_work(struct work_struct *work) ++{ ++ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, ++ btc.eapol_notify_work); ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_EAPOL); ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++void rtw89_btc_ntfy_arp_packet_work(struct work_struct *work) ++{ ++ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, ++ btc.arp_notify_work); ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_ARP); ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++void rtw89_btc_ntfy_dhcp_packet_work(struct work_struct *work) ++{ ++ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, ++ btc.dhcp_notify_work); ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_DHCP); ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++void rtw89_btc_ntfy_icmp_packet_work(struct work_struct *work) ++{ ++ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, ++ btc.icmp_notify_work); ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_ICMP); ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_bt_info *bt = &cx->bt; ++ struct rtw89_btc_bt_link_info *b = &bt->link_info; ++ struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc; ++ struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc; ++ struct rtw89_btc_bt_a2dp_desc *a2dp = &b->a2dp_desc; ++ struct rtw89_btc_bt_pan_desc *pan = &b->pan_desc; ++ union btc_btinfo btinfo; ++ ++ if (buf[BTC_BTINFO_L1] != 6) ++ return; ++ ++ if (!memcmp(bt->raw_info, buf, BTC_BTINFO_MAX)) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): return by bt-info duplicate!!\n", ++ __func__); ++ cx->cnt_bt[BTC_BCNT_INFOSAME]++; ++ return; ++ } ++ ++ memcpy(bt->raw_info, buf, BTC_BTINFO_MAX); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): bt_info[2]=0x%02x\n", ++ __func__, bt->raw_info[2]); ++ ++ /* reset to mo-connect before update */ ++ b->status.val = BTC_BLINK_NOCONNECT; ++ b->profile_cnt.last = b->profile_cnt.now; ++ b->relink.last = b->relink.now; ++ a2dp->exist_last = a2dp->exist; ++ b->multi_link.last = b->multi_link.now; ++ bt->inq_pag.last = bt->inq_pag.now; ++ b->profile_cnt.now = 0; ++ hid->type = 0; ++ ++ /* parse raw info low-Byte2 */ ++ btinfo.val = bt->raw_info[BTC_BTINFO_L2]; ++ b->status.map.connect = btinfo.lb2.connect; ++ b->status.map.sco_busy = btinfo.lb2.sco_busy; ++ b->status.map.acl_busy = btinfo.lb2.acl_busy; ++ b->status.map.inq_pag = btinfo.lb2.inq_pag; ++ bt->inq_pag.now = btinfo.lb2.inq_pag; ++ cx->cnt_bt[BTC_BCNT_INQPAG] += !!(bt->inq_pag.now && !bt->inq_pag.last); ++ ++ hfp->exist = btinfo.lb2.hfp; ++ b->profile_cnt.now += (u8)hfp->exist; ++ hid->exist = btinfo.lb2.hid; ++ b->profile_cnt.now += (u8)hid->exist; ++ a2dp->exist = btinfo.lb2.a2dp; ++ b->profile_cnt.now += (u8)a2dp->exist; ++ pan->active = btinfo.lb2.pan; ++ ++ /* parse raw info low-Byte3 */ ++ btinfo.val = bt->raw_info[BTC_BTINFO_L3]; ++ if (btinfo.lb3.retry != 0) ++ cx->cnt_bt[BTC_BCNT_RETRY]++; ++ b->cqddr = btinfo.lb3.cqddr; ++ cx->cnt_bt[BTC_BCNT_INQ] += !!(btinfo.lb3.inq && !bt->inq); ++ bt->inq = btinfo.lb3.inq; ++ cx->cnt_bt[BTC_BCNT_PAGE] += !!(btinfo.lb3.pag && !bt->pag); ++ bt->pag = btinfo.lb3.pag; ++ ++ b->status.map.mesh_busy = btinfo.lb3.mesh_busy; ++ /* parse raw info high-Byte0 */ ++ btinfo.val = bt->raw_info[BTC_BTINFO_H0]; ++ /* raw val is dBm unit, translate from -100~ 0dBm to 0~100%*/ ++ b->rssi = chip->ops->btc_get_bt_rssi(rtwdev, btinfo.hb0.rssi); ++ ++ /* parse raw info high-Byte1 */ ++ btinfo.val = bt->raw_info[BTC_BTINFO_H1]; ++ b->status.map.ble_connect = btinfo.hb1.ble_connect; ++ if (btinfo.hb1.ble_connect) ++ hid->type |= (hid->exist ? BTC_HID_BLE : BTC_HID_RCU); ++ ++ cx->cnt_bt[BTC_BCNT_REINIT] += !!(btinfo.hb1.reinit && !bt->reinit); ++ bt->reinit = btinfo.hb1.reinit; ++ cx->cnt_bt[BTC_BCNT_RELINK] += !!(btinfo.hb1.relink && !b->relink.now); ++ b->relink.now = btinfo.hb1.relink; ++ cx->cnt_bt[BTC_BCNT_IGNOWL] += !!(btinfo.hb1.igno_wl && !bt->igno_wl); ++ bt->igno_wl = btinfo.hb1.igno_wl; ++ ++ if (bt->igno_wl && !cx->wl.status.map.rf_off) ++ _set_bt_ignore_wlan_act(rtwdev, false); ++ ++ hid->type |= (btinfo.hb1.voice ? BTC_HID_RCU_VOICE : 0); ++ bt->ble_scan_en = btinfo.hb1.ble_scan; ++ ++ cx->cnt_bt[BTC_BCNT_ROLESW] += !!(btinfo.hb1.role_sw && !b->role_sw); ++ b->role_sw = btinfo.hb1.role_sw; ++ ++ b->multi_link.now = btinfo.hb1.multi_link; ++ ++ /* parse raw info high-Byte2 */ ++ btinfo.val = bt->raw_info[BTC_BTINFO_H2]; ++ pan->exist = btinfo.hb2.pan_active; ++ b->profile_cnt.now += (u8)pan->exist; ++ ++ cx->cnt_bt[BTC_BCNT_AFH] += !!(btinfo.hb2.afh_update && !b->afh_update); ++ b->afh_update = btinfo.hb2.afh_update; ++ a2dp->active = btinfo.hb2.a2dp_active; ++ b->slave_role = btinfo.hb2.slave; ++ hid->slot_info = btinfo.hb2.hid_slot; ++ hid->pair_cnt = btinfo.hb2.hid_cnt; ++ hid->type |= (hid->slot_info == BTC_HID_218 ? ++ BTC_HID_218 : BTC_HID_418); ++ /* parse raw info high-Byte3 */ ++ btinfo.val = bt->raw_info[BTC_BTINFO_H3]; ++ a2dp->bitpool = btinfo.hb3.a2dp_bitpool; ++ ++ if (b->tx_3m != (u32)btinfo.hb3.tx_3m) ++ cx->cnt_bt[BTC_BCNT_RATECHG]++; ++ b->tx_3m = (u32)btinfo.hb3.tx_3m; ++ ++ a2dp->sink = btinfo.hb3.a2dp_sink; ++ ++ if (b->profile_cnt.now || b->status.map.ble_connect) ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, 1); ++ else ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, 0); ++ ++ if (!a2dp->exist_last && a2dp->exist) { ++ a2dp->vendor_id = 0; ++ a2dp->flush_time = 0; ++ a2dp->play_latency = 1; ++ ieee80211_queue_delayed_work(rtwdev->hw, ++ &rtwdev->coex_bt_devinfo_work, ++ RTW89_COEX_BT_DEVINFO_WORK_PERIOD); ++ } ++ ++ if (a2dp->exist && (a2dp->flush_time == 0 || a2dp->vendor_id == 0 || ++ a2dp->play_latency == 1)) ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, 1); ++ else ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, 0); ++ ++ _run_coex(rtwdev, BTC_RSN_UPDATE_BT_INFO); ++} ++ ++enum btc_wl_mode { ++ BTC_WL_MODE_HT = 0, ++ BTC_WL_MODE_VHT = 1, ++ BTC_WL_MODE_HE = 2, ++ BTC_WL_MODE_NUM, ++}; ++ ++void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ struct rtw89_sta *rtwsta, enum btc_role_state state) ++{ ++ struct rtw89_hal *hal = &rtwdev->hal; ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta); ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_wl_link_info r = {0}; ++ struct rtw89_btc_wl_link_info *wlinfo = NULL; ++ u8 mode = 0; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], state=%d\n", state); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], role is STA=%d\n", ++ vif->type == NL80211_IFTYPE_STATION); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], port=%d\n", rtwvif->port); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], band=%d ch=%d bw=%d\n", ++ hal->current_band_type, hal->current_channel, ++ hal->current_band_width); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], associated=%d\n", ++ state == BTC_ROLE_MSTS_STA_CONN_END); ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], bcn_period=%d dtim_period=%d\n", ++ vif->bss_conf.beacon_int, vif->bss_conf.dtim_period); ++ ++ if (rtwsta) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], STA mac_id=%d\n", ++ rtwsta->mac_id); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], STA support HE=%d VHT=%d HT=%d\n", ++ sta->he_cap.has_he, ++ sta->vht_cap.vht_supported, ++ sta->ht_cap.ht_supported); ++ if (sta->he_cap.has_he) ++ mode |= BIT(BTC_WL_MODE_HE); ++ if (sta->vht_cap.vht_supported) ++ mode |= BIT(BTC_WL_MODE_VHT); ++ if (sta->ht_cap.ht_supported) ++ mode |= BIT(BTC_WL_MODE_HT); ++ ++ r.mode = mode; ++ } ++ ++ if (rtwvif->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX) ++ return; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], wifi_role=%d\n", rtwvif->wifi_role); ++ ++ r.role = rtwvif->wifi_role; ++ r.phy = rtwvif->phy_idx; ++ r.pid = rtwvif->port; ++ r.active = true; ++ r.connected = MLME_LINKED; ++ r.bcn_period = vif->bss_conf.beacon_int; ++ r.dtim_period = vif->bss_conf.dtim_period; ++ r.band = hal->current_band_type; ++ r.ch = hal->current_channel; ++ r.bw = hal->current_band_width; ++ ether_addr_copy(r.mac_addr, rtwvif->mac_addr); ++ ++ if (rtwsta && vif->type == NL80211_IFTYPE_STATION) ++ r.mac_id = rtwsta->mac_id; ++ ++ btc->dm.cnt_notify[BTC_NCNT_ROLE_INFO]++; ++ ++ wlinfo = &wl->link_info[r.pid]; ++ ++ memcpy(wlinfo, &r, sizeof(*wlinfo)); ++ _update_wl_info(rtwdev); ++ ++ if (wlinfo->role == RTW89_WIFI_ROLE_STATION && ++ wlinfo->connected == MLME_NO_LINK) ++ btc->dm.leak_ap = 0; ++ ++ if (state == BTC_ROLE_MSTS_STA_CONN_START) ++ wl->status.map.connecting = 1; ++ else ++ wl->status.map.connecting = 0; ++ ++ if (state == BTC_ROLE_MSTS_STA_DIS_CONN) ++ wl->status.map._4way = false; ++ ++ _run_coex(rtwdev, BTC_RSN_NTFY_ROLE_INFO); ++} ++ ++void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_state) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): rf_state = %d\n", ++ __func__, rf_state); ++ btc->dm.cnt_notify[BTC_NCNT_RADIO_STATE]++; ++ ++ switch (rf_state) { ++ case BTC_RFCTRL_WL_OFF: ++ wl->status.map.rf_off = 1; ++ wl->status.map.lps = 0; ++ break; ++ case BTC_RFCTRL_FW_CTRL: ++ wl->status.map.rf_off = 0; ++ wl->status.map.lps = 1; ++ break; ++ case BTC_RFCTRL_WL_ON: ++ default: ++ wl->status.map.rf_off = 0; ++ wl->status.map.lps = 0; ++ break; ++ } ++ ++ if (rf_state == BTC_RFCTRL_WL_ON) { ++ rtw89_btc_fw_en_rpt(rtwdev, ++ RPT_EN_MREG | RPT_EN_BT_VER_INFO, true); ++ _write_scbd(rtwdev, BTC_WSCB_ACTIVE, true); ++ _update_bt_scbd(rtwdev, true); ++ chip->ops->btc_init_cfg(rtwdev); ++ } else { ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, false); ++ _write_scbd(rtwdev, BTC_WSCB_ACTIVE | BTC_WSCB_WLBUSY, false); ++ } ++ ++ _run_coex(rtwdev, BTC_RSN_NTFY_RADIO_STATE); ++ ++ wl->status.map.rf_off_pre = wl->status.map.rf_off; ++ wl->status.map.lps_pre = wl->status.map.lps; ++} ++ ++static bool _ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_path, ++ enum btc_wl_rfk_type type, ++ enum btc_wl_rfk_state state) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_wl_info *wl = &cx->wl; ++ bool result = BTC_WRFK_REJECT; ++ ++ wl->rfk_info.type = type; ++ wl->rfk_info.path_map = FIELD_GET(BTC_RFK_PATH_MAP, phy_path); ++ wl->rfk_info.phy_map = FIELD_GET(BTC_RFK_PHY_MAP, phy_path); ++ wl->rfk_info.band = FIELD_GET(BTC_RFK_BAND_MAP, phy_path); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s()_start: phy=0x%x, path=0x%x, type=%d, state=%d\n", ++ __func__, wl->rfk_info.phy_map, wl->rfk_info.path_map, ++ type, state); ++ ++ switch (state) { ++ case BTC_WRFK_START: ++ result = _chk_wl_rfk_request(rtwdev); ++ wl->rfk_info.state = result ? BTC_WRFK_START : BTC_WRFK_STOP; ++ ++ _write_scbd(rtwdev, BTC_WSCB_WLRFK, result); ++ ++ btc->dm.cnt_notify[BTC_NCNT_WL_RFK]++; ++ break; ++ case BTC_WRFK_ONESHOT_START: ++ case BTC_WRFK_ONESHOT_STOP: ++ if (wl->rfk_info.state == BTC_WRFK_STOP) { ++ result = BTC_WRFK_REJECT; ++ } else { ++ result = BTC_WRFK_ALLOW; ++ wl->rfk_info.state = state; ++ } ++ break; ++ case BTC_WRFK_STOP: ++ result = BTC_WRFK_ALLOW; ++ wl->rfk_info.state = BTC_WRFK_STOP; ++ ++ _write_scbd(rtwdev, BTC_WSCB_WLRFK, false); ++ cancel_delayed_work(&rtwdev->coex_rfk_chk_work); ++ break; ++ default: ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s() warning state=%d\n", __func__, state); ++ break; ++ } ++ ++ if (result == BTC_WRFK_ALLOW) { ++ if (wl->rfk_info.state == BTC_WRFK_START || ++ wl->rfk_info.state == BTC_WRFK_STOP) ++ _run_coex(rtwdev, BTC_RSN_NTFY_WL_RFK); ++ ++ if (wl->rfk_info.state == BTC_WRFK_START) ++ ieee80211_queue_delayed_work(rtwdev->hw, ++ &rtwdev->coex_rfk_chk_work, ++ RTW89_COEX_RFK_CHK_WORK_PERIOD); ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s()_finish: rfk_cnt=%d, result=%d\n", ++ __func__, btc->dm.cnt_notify[BTC_NCNT_WL_RFK], result); ++ ++ return result == BTC_WRFK_ALLOW; ++} ++ ++void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map, ++ enum btc_wl_rfk_type type, ++ enum btc_wl_rfk_state state) ++{ ++ u8 band; ++ bool allow; ++ int ret; ++ ++ band = FIELD_GET(BTC_RFK_BAND_MAP, phy_map); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[RFK] RFK notify (%s / PHY%u / K_type = %u / path_idx = %lu / process = %s)\n", ++ band == RTW89_BAND_2G ? "2G" : ++ band == RTW89_BAND_5G ? "5G" : "6G", ++ !!(FIELD_GET(BTC_RFK_PHY_MAP, phy_map) & BIT(RTW89_PHY_1)), ++ type, ++ FIELD_GET(BTC_RFK_PATH_MAP, phy_map), ++ state == BTC_WRFK_STOP ? "RFK_STOP" : ++ state == BTC_WRFK_START ? "RFK_START" : ++ state == BTC_WRFK_ONESHOT_START ? "ONE-SHOT_START" : ++ "ONE-SHOT_STOP"); ++ ++ if (state != BTC_WRFK_START || rtwdev->is_bt_iqk_timeout) { ++ _ntfy_wl_rfk(rtwdev, phy_map, type, state); ++ return; ++ } ++ ++ ret = read_poll_timeout(_ntfy_wl_rfk, allow, allow, 40, 100000, false, ++ rtwdev, phy_map, type, state); ++ if (ret) { ++ rtw89_warn(rtwdev, "RFK notify timeout\n"); ++ rtwdev->is_bt_iqk_timeout = true; ++ } ++} ++ ++struct rtw89_btc_wl_sta_iter_data { ++ struct rtw89_dev *rtwdev; ++ u8 busy_all; ++ u8 dir_all; ++ u8 rssi_map_all; ++ bool is_sta_change; ++ bool is_traffic_change; ++}; ++ ++static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta) ++{ ++ struct rtw89_btc_wl_sta_iter_data *iter_data = ++ (struct rtw89_btc_wl_sta_iter_data *)data; ++ struct rtw89_dev *rtwdev = iter_data->rtwdev; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_wl_link_info *link_info = NULL; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_traffic_stats *link_info_t = NULL; ++ struct rtw89_vif *rtwvif = rtwsta->rtwvif; ++ struct rtw89_traffic_stats *stats = &rtwvif->stats; ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ u32 last_tx_rate, last_rx_rate; ++ u16 last_tx_lvl, last_rx_lvl; ++ u8 port = rtwvif->port; ++ u8 rssi; ++ u8 busy = 0; ++ u8 dir = 0; ++ u8 rssi_map = 0; ++ u8 i = 0; ++ bool is_sta_change = false, is_traffic_change = false; ++ ++ rssi = ewma_rssi_read(&rtwsta->avg_rssi) >> RSSI_FACTOR; ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], rssi=%d\n", rssi); ++ ++ link_info = &wl->link_info[port]; ++ link_info->stat.traffic = rtwvif->stats; ++ link_info_t = &link_info->stat.traffic; ++ ++ if (link_info->connected == MLME_NO_LINK) { ++ link_info->rx_rate_drop_cnt = 0; ++ return; ++ } ++ ++ link_info->stat.rssi = rssi; ++ for (i = 0; i < BTC_WL_RSSI_THMAX; i++) { ++ link_info->rssi_state[i] = ++ _update_rssi_state(rtwdev, ++ link_info->rssi_state[i], ++ link_info->stat.rssi, ++ chip->wl_rssi_thres[i]); ++ if (BTC_RSSI_LOW(link_info->rssi_state[i])) ++ rssi_map |= BIT(i); ++ ++ if (btc->mdinfo.ant.type == BTC_ANT_DEDICATED && ++ BTC_RSSI_CHANGE(link_info->rssi_state[i])) ++ is_sta_change = true; ++ } ++ iter_data->rssi_map_all |= rssi_map; ++ ++ last_tx_rate = link_info_t->tx_rate; ++ last_rx_rate = link_info_t->rx_rate; ++ last_tx_lvl = (u16)link_info_t->tx_tfc_lv; ++ last_rx_lvl = (u16)link_info_t->rx_tfc_lv; ++ ++ if (stats->tx_tfc_lv != RTW89_TFC_IDLE || ++ stats->rx_tfc_lv != RTW89_TFC_IDLE) ++ busy = 1; ++ ++ if (stats->tx_tfc_lv > stats->rx_tfc_lv) ++ dir = RTW89_TFC_UL; ++ else ++ dir = RTW89_TFC_DL; ++ ++ link_info = &wl->link_info[port]; ++ if (link_info->busy != busy || link_info->dir != dir) { ++ is_sta_change = true; ++ link_info->busy = busy; ++ link_info->dir = dir; ++ } ++ ++ iter_data->busy_all |= busy; ++ iter_data->dir_all |= BIT(dir); ++ ++ if (rtwsta->rx_hw_rate <= RTW89_HW_RATE_CCK2 && ++ last_rx_rate > RTW89_HW_RATE_CCK2 && ++ link_info_t->rx_tfc_lv > RTW89_TFC_IDLE) ++ link_info->rx_rate_drop_cnt++; ++ ++ if (last_tx_rate != rtwsta->ra_report.hw_rate || ++ last_rx_rate != rtwsta->rx_hw_rate || ++ last_tx_lvl != link_info_t->tx_tfc_lv || ++ last_rx_lvl != link_info_t->rx_tfc_lv) ++ is_traffic_change = true; ++ ++ link_info_t->tx_rate = rtwsta->ra_report.hw_rate; ++ link_info_t->rx_rate = rtwsta->rx_hw_rate; ++ ++ wl->role_info.active_role[port].tx_lvl = (u16)stats->tx_tfc_lv; ++ wl->role_info.active_role[port].rx_lvl = (u16)stats->rx_tfc_lv; ++ wl->role_info.active_role[port].tx_rate = rtwsta->ra_report.hw_rate; ++ wl->role_info.active_role[port].rx_rate = rtwsta->rx_hw_rate; ++ ++ if (is_sta_change) ++ iter_data->is_sta_change = true; ++ ++ if (is_traffic_change) ++ iter_data->is_traffic_change = true; ++} ++ ++#define BTC_NHM_CHK_INTVL 20 ++ ++void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_wl_sta_iter_data data = {.rtwdev = rtwdev}; ++ u8 i; ++ ++ ieee80211_iterate_stations_atomic(rtwdev->hw, ++ rtw89_btc_ntfy_wl_sta_iter, ++ &data); ++ ++ wl->rssi_level = 0; ++ btc->dm.cnt_notify[BTC_NCNT_WL_STA]++; ++ for (i = BTC_WL_RSSI_THMAX; i > 0; i--) { ++ /* set RSSI level 4 ~ 0 if rssi bit map match */ ++ if (data.rssi_map_all & BIT(i - 1)) { ++ wl->rssi_level = i; ++ break; ++ } ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): busy=%d\n", ++ __func__, !!wl->status.map.busy); ++ ++ _write_scbd(rtwdev, BTC_WSCB_WLBUSY, (!!wl->status.map.busy)); ++ ++ if (data.is_traffic_change) ++ _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); ++ if (data.is_sta_change) { ++ wl->status.map.busy = data.busy_all; ++ wl->status.map.traffic_dir = data.dir_all; ++ _run_coex(rtwdev, BTC_RSN_NTFY_WL_STA); ++ } else if (btc->dm.cnt_notify[BTC_NCNT_WL_STA] >= ++ btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST] + BTC_NHM_CHK_INTVL) { ++ btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST] = ++ btc->dm.cnt_notify[BTC_NCNT_WL_STA]; ++ } else if (btc->dm.cnt_notify[BTC_NCNT_WL_STA] < ++ btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST]) { ++ btc->dm.cnt_dm[BTC_DCNT_WL_STA_LAST] = ++ btc->dm.cnt_notify[BTC_NCNT_WL_STA]; ++ } ++} ++ ++void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, ++ u32 len, u8 class, u8 func) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; ++ u8 *buf = &skb->data[RTW89_C2H_HEADER_LEN]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): C2H BT len:%d class:%d fun:%d\n", ++ __func__, len, class, func); ++ ++ if (class != BTFC_FW_EVENT) ++ return; ++ ++ switch (func) { ++ case BTF_EVNT_RPT: ++ case BTF_EVNT_BUF_OVERFLOW: ++ pfwinfo->event[func]++; ++ /* Don't need rtw89_leave_ps_mode() */ ++ btc_fw_event(rtwdev, func, buf, len); ++ break; ++ case BTF_EVNT_BT_INFO: ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], handle C2H BT INFO with data %8ph\n", buf); ++ btc->cx.cnt_bt[BTC_BCNT_INFOUPDATE]++; ++ rtw89_leave_ps_mode(rtwdev); ++ _update_bt_info(rtwdev, buf, len); ++ break; ++ case BTF_EVNT_BT_SCBD: ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], handle C2H BT SCBD with data %8ph\n", buf); ++ btc->cx.cnt_bt[BTC_BCNT_SCBDUPDATE]++; ++ rtw89_leave_ps_mode(rtwdev); ++ _update_bt_scbd(rtwdev, false); ++ break; ++ case BTF_EVNT_BT_PSD: ++ break; ++ case BTF_EVNT_BT_REG: ++ btc->dbg.rb_done = true; ++ btc->dbg.rb_val = le32_to_cpu(*((__le32 *)buf)); ++ ++ break; ++ case BTF_EVNT_C2H_LOOPBACK: ++ btc->dbg.rb_done = true; ++ btc->dbg.rb_val = buf[0]; ++ break; ++ case BTF_EVNT_CX_RUNINFO: ++ btc->dm.cnt_dm[BTC_DCNT_CX_RUNINFO]++; ++ break; ++ } ++} ++ ++#define BTC_CX_FW_OFFLOAD 0 ++ ++static void _show_cx_info(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ u32 ver_main = 0, ver_sub = 0, ver_hotfix = 0, id_branch = 0; ++ ++ if (!(dm->coex_info_map & BTC_COEX_INFO_CX)) ++ return; ++ ++ dm->cnt_notify[BTC_NCNT_SHOW_COEX_INFO]++; ++ ++ seq_printf(m, "========== [BTC COEX INFO (%d)] ==========\n", ++ chip->chip_id); ++ ++ ver_main = FIELD_GET(GENMASK(31, 24), chip->para_ver); ++ ver_sub = FIELD_GET(GENMASK(23, 16), chip->para_ver); ++ ver_hotfix = FIELD_GET(GENMASK(15, 8), chip->para_ver); ++ id_branch = FIELD_GET(GENMASK(7, 0), chip->para_ver); ++ seq_printf(m, " %-15s : Coex:%d.%d.%d(branch:%d), ", ++ "[coex_version]", ver_main, ver_sub, ver_hotfix, id_branch); ++ ++ if (dm->wl_fw_cx_offload != BTC_CX_FW_OFFLOAD) ++ dm->error.map.offload_mismatch = true; ++ else ++ dm->error.map.offload_mismatch = false; ++ ++ ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw_coex); ++ ver_sub = FIELD_GET(GENMASK(23, 16), wl->ver_info.fw_coex); ++ ver_hotfix = FIELD_GET(GENMASK(15, 8), wl->ver_info.fw_coex); ++ id_branch = FIELD_GET(GENMASK(7, 0), wl->ver_info.fw_coex); ++ seq_printf(m, "WL_FW_coex:%d.%d.%d(branch:%d)", ++ ver_main, ver_sub, ver_hotfix, id_branch); ++ ++ ver_main = FIELD_GET(GENMASK(31, 24), chip->wlcx_desired); ++ ver_sub = FIELD_GET(GENMASK(23, 16), chip->wlcx_desired); ++ ver_hotfix = FIELD_GET(GENMASK(15, 8), chip->wlcx_desired); ++ seq_printf(m, "(%s, desired:%d.%d.%d), ", ++ (wl->ver_info.fw_coex >= chip->wlcx_desired ? ++ "Match" : "Mis-Match"), ver_main, ver_sub, ver_hotfix); ++ ++ seq_printf(m, "BT_FW_coex:%d(%s, desired:%d)\n", ++ bt->ver_info.fw_coex, ++ (bt->ver_info.fw_coex >= chip->btcx_desired ? ++ "Match" : "Mis-Match"), chip->btcx_desired); ++ ++ if (bt->enable.now && bt->ver_info.fw == 0) ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, true); ++ else ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, false); ++ ++ ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw); ++ ver_sub = FIELD_GET(GENMASK(23, 16), wl->ver_info.fw); ++ ver_hotfix = FIELD_GET(GENMASK(15, 8), wl->ver_info.fw); ++ id_branch = FIELD_GET(GENMASK(7, 0), wl->ver_info.fw); ++ seq_printf(m, " %-15s : WL_FW:%d.%d.%d.%d, BT_FW:0x%x(%s)\n", ++ "[sub_module]", ++ ver_main, ver_sub, ver_hotfix, id_branch, ++ bt->ver_info.fw, bt->run_patch_code ? "patch" : "ROM"); ++ ++ seq_printf(m, " %-15s : cv:%x, rfe_type:0x%x, ant_iso:%d, ant_pg:%d, %s", ++ "[hw_info]", btc->mdinfo.cv, btc->mdinfo.rfe_type, ++ btc->mdinfo.ant.isolation, btc->mdinfo.ant.num, ++ (btc->mdinfo.ant.num > 1 ? "" : (btc->mdinfo.ant.single_pos ? ++ "1Ant_Pos:S1, " : "1Ant_Pos:S0, "))); ++ ++ seq_printf(m, "3rd_coex:%d, dbcc:%d, tx_num:%d, rx_num:%d\n", ++ btc->cx.other.type, rtwdev->dbcc_en, hal->tx_nss, ++ hal->rx_nss); ++} ++ ++static void _show_wl_role_info(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_link_info *plink = NULL; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; ++ struct rtw89_traffic_stats *t; ++ u8 i; ++ ++ if (rtwdev->dbcc_en) { ++ seq_printf(m, ++ " %-15s : PHY0_band(op:%d/scan:%d/real:%d), ", ++ "[dbcc_info]", wl_dinfo->op_band[RTW89_PHY_0], ++ wl_dinfo->scan_band[RTW89_PHY_0], ++ wl_dinfo->real_band[RTW89_PHY_0]); ++ seq_printf(m, ++ "PHY1_band(op:%d/scan:%d/real:%d)\n", ++ wl_dinfo->op_band[RTW89_PHY_1], ++ wl_dinfo->scan_band[RTW89_PHY_1], ++ wl_dinfo->real_band[RTW89_PHY_1]); ++ } ++ ++ for (i = 0; i < RTW89_MAX_HW_PORT_NUM; i++) { ++ plink = &btc->cx.wl.link_info[i]; ++ ++ if (!plink->active) ++ continue; ++ ++ seq_printf(m, ++ " [port_%d] : role=%d(phy-%d), connect=%d(client_cnt=%d), mode=%d, center_ch=%d, bw=%d", ++ plink->pid, (u32)plink->role, plink->phy, ++ (u32)plink->connected, plink->client_cnt - 1, ++ (u32)plink->mode, plink->ch, (u32)plink->bw); ++ ++ if (plink->connected == MLME_NO_LINK) ++ continue; ++ ++ seq_printf(m, ++ ", mac_id=%d, max_tx_time=%dus, max_tx_retry=%d\n", ++ plink->mac_id, plink->tx_time, plink->tx_retry); ++ ++ seq_printf(m, ++ " [port_%d] : rssi=-%ddBm(%d), busy=%d, dir=%s, ", ++ plink->pid, 110 - plink->stat.rssi, ++ plink->stat.rssi, plink->busy, ++ plink->dir == RTW89_TFC_UL ? "UL" : "DL"); ++ ++ t = &plink->stat.traffic; ++ ++ seq_printf(m, ++ "tx[rate:%d/busy_level:%d], ", ++ (u32)t->tx_rate, t->tx_tfc_lv); ++ ++ seq_printf(m, "rx[rate:%d/busy_level:%d/drop:%d]\n", ++ (u32)t->rx_rate, ++ t->rx_tfc_lv, plink->rx_rate_drop_cnt); ++ } ++} ++ ++static void _show_wl_info(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_wl_info *wl = &cx->wl; ++ struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; ++ ++ if (!(btc->dm.coex_info_map & BTC_COEX_INFO_WL)) ++ return; ++ ++ seq_puts(m, "========== [WL Status] ==========\n"); ++ ++ seq_printf(m, " %-15s : link_mode:%d, ", ++ "[status]", (u32)wl_rinfo->link_mode); ++ ++ seq_printf(m, ++ "rf_off:%s, power_save:%s, scan:%s(band:%d/phy_map:0x%x), ", ++ wl->status.map.rf_off ? "Y" : "N", ++ wl->status.map.lps ? "Y" : "N", ++ wl->status.map.scan ? "Y" : "N", ++ wl->scan_info.band[RTW89_PHY_0], wl->scan_info.phy_map); ++ ++ seq_printf(m, ++ "connecting:%s, roam:%s, 4way:%s, init_ok:%s\n", ++ wl->status.map.connecting ? "Y" : "N", ++ wl->status.map.roaming ? "Y" : "N", ++ wl->status.map._4way ? "Y" : "N", ++ wl->status.map.init_ok ? "Y" : "N"); ++ ++ _show_wl_role_info(rtwdev, m); ++} ++ ++enum btc_bt_a2dp_type { ++ BTC_A2DP_LEGACY = 0, ++ BTC_A2DP_TWS_SNIFF = 1, ++ BTC_A2DP_TWS_RELAY = 2, ++}; ++ ++static void _show_bt_profile_info(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info; ++ struct rtw89_btc_bt_hfp_desc hfp = bt_linfo->hfp_desc; ++ struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc; ++ struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc; ++ struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc; ++ ++ if (hfp.exist) { ++ seq_printf(m, " %-15s : type:%s, sut_pwr:%d, golden-rx:%d", ++ "[HFP]", (hfp.type == 0 ? "SCO" : "eSCO"), ++ bt_linfo->sut_pwr_level[0], ++ bt_linfo->golden_rx_shift[0]); ++ } ++ ++ if (hid.exist) { ++ seq_printf(m, ++ "\n\r %-15s : type:%s%s%s%s%s pair-cnt:%d, sut_pwr:%d, golden-rx:%d\n", ++ "[HID]", ++ hid.type & BTC_HID_218 ? "2/18," : "", ++ hid.type & BTC_HID_418 ? "4/18," : "", ++ hid.type & BTC_HID_BLE ? "BLE," : "", ++ hid.type & BTC_HID_RCU ? "RCU," : "", ++ hid.type & BTC_HID_RCU_VOICE ? "RCU-Voice," : "", ++ hid.pair_cnt, bt_linfo->sut_pwr_level[1], ++ bt_linfo->golden_rx_shift[1]); ++ } ++ ++ if (a2dp.exist) { ++ seq_printf(m, ++ " %-15s : type:%s, bit-pool:%d, flush-time:%d, ", ++ "[A2DP]", ++ a2dp.type == BTC_A2DP_LEGACY ? "Legacy" : "TWS", ++ a2dp.bitpool, a2dp.flush_time); ++ ++ seq_printf(m, ++ "vid:0x%x, Dev-name:0x%x, sut_pwr:%d, golden-rx:%d\n", ++ a2dp.vendor_id, a2dp.device_name, ++ bt_linfo->sut_pwr_level[2], ++ bt_linfo->golden_rx_shift[2]); ++ } ++ ++ if (pan.exist) { ++ seq_printf(m, " %-15s : sut_pwr:%d, golden-rx:%d\n", ++ "[PAN]", ++ bt_linfo->sut_pwr_level[3], ++ bt_linfo->golden_rx_shift[3]); ++ } ++} ++ ++static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_bt_info *bt = &cx->bt; ++ struct rtw89_btc_wl_info *wl = &cx->wl; ++ struct rtw89_btc_module *module = &btc->mdinfo; ++ struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; ++ u8 *afh = bt_linfo->afh_map; ++ u16 polt_cnt = 0; ++ ++ if (!(btc->dm.coex_info_map & BTC_COEX_INFO_BT)) ++ return; ++ ++ seq_puts(m, "========== [BT Status] ==========\n"); ++ ++ seq_printf(m, " %-15s : enable:%s, btg:%s%s, connect:%s, ", ++ "[status]", bt->enable.now ? "Y" : "N", ++ bt->btg_type ? "Y" : "N", ++ (bt->enable.now && (bt->btg_type != module->bt_pos) ? ++ "(efuse-mismatch!!)" : ""), ++ (bt_linfo->status.map.connect ? "Y" : "N")); ++ ++ seq_printf(m, "igno_wl:%s, mailbox_avl:%s, rfk_state:0x%x\n", ++ bt->igno_wl ? "Y" : "N", ++ bt->mbx_avl ? "Y" : "N", bt->rfk_info.val); ++ ++ seq_printf(m, " %-15s : profile:%s%s%s%s%s ", ++ "[profile]", ++ (bt_linfo->profile_cnt.now == 0) ? "None," : "", ++ bt_linfo->hfp_desc.exist ? "HFP," : "", ++ bt_linfo->hid_desc.exist ? "HID," : "", ++ bt_linfo->a2dp_desc.exist ? ++ (bt_linfo->a2dp_desc.sink ? "A2DP_sink," : "A2DP,") : "", ++ bt_linfo->pan_desc.exist ? "PAN," : ""); ++ ++ seq_printf(m, ++ "multi-link:%s, role:%s, ble-connect:%s, CQDDR:%s, A2DP_active:%s, PAN_active:%s\n", ++ bt_linfo->multi_link.now ? "Y" : "N", ++ bt_linfo->slave_role ? "Slave" : "Master", ++ bt_linfo->status.map.ble_connect ? "Y" : "N", ++ bt_linfo->cqddr ? "Y" : "N", ++ bt_linfo->a2dp_desc.active ? "Y" : "N", ++ bt_linfo->pan_desc.active ? "Y" : "N"); ++ ++ seq_printf(m, ++ " %-15s : rssi:%ddBm, tx_rate:%dM, %s%s%s", ++ "[link]", bt_linfo->rssi - 100, ++ bt_linfo->tx_3m ? 3 : 2, ++ bt_linfo->status.map.inq_pag ? " inq-page!!" : "", ++ bt_linfo->status.map.acl_busy ? " acl_busy!!" : "", ++ bt_linfo->status.map.mesh_busy ? " mesh_busy!!" : ""); ++ ++ seq_printf(m, ++ "%s afh_map[%02x%02x_%02x%02x_%02x%02x_%02x%02x_%02x%02x], ", ++ bt_linfo->relink.now ? " ReLink!!" : "", ++ afh[0], afh[1], afh[2], afh[3], afh[4], ++ afh[5], afh[6], afh[7], afh[8], afh[9]); ++ ++ seq_printf(m, "wl_ch_map[en:%d/ch:%d/bw:%d]\n", ++ wl->afh_info.en, wl->afh_info.ch, wl->afh_info.bw); ++ ++ seq_printf(m, ++ " %-15s : retry:%d, relink:%d, rate_chg:%d, reinit:%d, reenable:%d, ", ++ "[stat_cnt]", cx->cnt_bt[BTC_BCNT_RETRY], ++ cx->cnt_bt[BTC_BCNT_RELINK], cx->cnt_bt[BTC_BCNT_RATECHG], ++ cx->cnt_bt[BTC_BCNT_REINIT], cx->cnt_bt[BTC_BCNT_REENABLE]); ++ ++ seq_printf(m, ++ "role-switch:%d, afh:%d, inq_page:%d(inq:%d/page:%d), igno_wl:%d\n", ++ cx->cnt_bt[BTC_BCNT_ROLESW], cx->cnt_bt[BTC_BCNT_AFH], ++ cx->cnt_bt[BTC_BCNT_INQPAG], cx->cnt_bt[BTC_BCNT_INQ], ++ cx->cnt_bt[BTC_BCNT_PAGE], cx->cnt_bt[BTC_BCNT_IGNOWL]); ++ ++ _show_bt_profile_info(rtwdev, m); ++ ++ seq_printf(m, ++ " %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)\n", ++ "[bt_info]", bt->raw_info[2], bt->raw_info[3], ++ bt->raw_info[4], bt->raw_info[5], bt->raw_info[6], ++ bt->raw_info[7], ++ bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply", ++ cx->cnt_bt[BTC_BCNT_INFOUPDATE], ++ cx->cnt_bt[BTC_BCNT_INFOSAME]); ++ ++ if (wl->status.map.lps || wl->status.map.rf_off) ++ return; ++ ++ chip->ops->btc_update_bt_cnt(rtwdev); ++ _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_FREEZE, 0); ++ ++ seq_printf(m, ++ " %-15s : Hi-rx = %d, Hi-tx = %d, Lo-rx = %d, Lo-tx = %d (bt_polut_wl_tx = %d)\n", ++ "[trx_req_cnt]", cx->cnt_bt[BTC_BCNT_HIPRI_RX], ++ cx->cnt_bt[BTC_BCNT_HIPRI_TX], cx->cnt_bt[BTC_BCNT_LOPRI_RX], ++ cx->cnt_bt[BTC_BCNT_LOPRI_TX], polt_cnt); ++} ++ ++#define CASE_BTC_RSN_STR(e) case BTC_RSN_ ## e: return #e ++#define CASE_BTC_ACT_STR(e) case BTC_ACT_ ## e | BTC_ACT_EXT_BIT: return #e ++#define CASE_BTC_POLICY_STR(e) \ ++ case BTC_CXP_ ## e | BTC_POLICY_EXT_BIT: return #e ++ ++static const char *steps_to_str(u16 step) ++{ ++ switch (step) { ++ CASE_BTC_RSN_STR(NONE); ++ CASE_BTC_RSN_STR(NTFY_INIT); ++ CASE_BTC_RSN_STR(NTFY_SWBAND); ++ CASE_BTC_RSN_STR(NTFY_WL_STA); ++ CASE_BTC_RSN_STR(NTFY_RADIO_STATE); ++ CASE_BTC_RSN_STR(UPDATE_BT_SCBD); ++ CASE_BTC_RSN_STR(NTFY_WL_RFK); ++ CASE_BTC_RSN_STR(UPDATE_BT_INFO); ++ CASE_BTC_RSN_STR(NTFY_SCAN_START); ++ CASE_BTC_RSN_STR(NTFY_SCAN_FINISH); ++ CASE_BTC_RSN_STR(NTFY_SPECIFIC_PACKET); ++ CASE_BTC_RSN_STR(NTFY_POWEROFF); ++ CASE_BTC_RSN_STR(NTFY_ROLE_INFO); ++ CASE_BTC_RSN_STR(CMD_SET_COEX); ++ CASE_BTC_RSN_STR(ACT1_WORK); ++ CASE_BTC_RSN_STR(BT_DEVINFO_WORK); ++ CASE_BTC_RSN_STR(RFK_CHK_WORK); ++ ++ CASE_BTC_ACT_STR(NONE); ++ CASE_BTC_ACT_STR(WL_ONLY); ++ CASE_BTC_ACT_STR(WL_5G); ++ CASE_BTC_ACT_STR(WL_OTHER); ++ CASE_BTC_ACT_STR(WL_IDLE); ++ CASE_BTC_ACT_STR(WL_NC); ++ CASE_BTC_ACT_STR(WL_RFK); ++ CASE_BTC_ACT_STR(WL_INIT); ++ CASE_BTC_ACT_STR(WL_OFF); ++ CASE_BTC_ACT_STR(FREERUN); ++ CASE_BTC_ACT_STR(BT_WHQL); ++ CASE_BTC_ACT_STR(BT_RFK); ++ CASE_BTC_ACT_STR(BT_OFF); ++ CASE_BTC_ACT_STR(BT_IDLE); ++ CASE_BTC_ACT_STR(BT_HFP); ++ CASE_BTC_ACT_STR(BT_HID); ++ CASE_BTC_ACT_STR(BT_A2DP); ++ CASE_BTC_ACT_STR(BT_A2DPSINK); ++ CASE_BTC_ACT_STR(BT_PAN); ++ CASE_BTC_ACT_STR(BT_A2DP_HID); ++ CASE_BTC_ACT_STR(BT_A2DP_PAN); ++ CASE_BTC_ACT_STR(BT_PAN_HID); ++ CASE_BTC_ACT_STR(BT_A2DP_PAN_HID); ++ CASE_BTC_ACT_STR(WL_25G_MCC); ++ CASE_BTC_ACT_STR(WL_2G_MCC); ++ CASE_BTC_ACT_STR(WL_2G_SCC); ++ CASE_BTC_ACT_STR(WL_2G_AP); ++ CASE_BTC_ACT_STR(WL_2G_GO); ++ CASE_BTC_ACT_STR(WL_2G_GC); ++ CASE_BTC_ACT_STR(WL_2G_NAN); ++ ++ CASE_BTC_POLICY_STR(OFF_BT); ++ CASE_BTC_POLICY_STR(OFF_WL); ++ CASE_BTC_POLICY_STR(OFF_EQ0); ++ CASE_BTC_POLICY_STR(OFF_EQ1); ++ CASE_BTC_POLICY_STR(OFF_EQ2); ++ CASE_BTC_POLICY_STR(OFF_EQ3); ++ CASE_BTC_POLICY_STR(OFF_BWB0); ++ CASE_BTC_POLICY_STR(OFF_BWB1); ++ CASE_BTC_POLICY_STR(OFFB_BWB0); ++ CASE_BTC_POLICY_STR(OFFE_DEF); ++ CASE_BTC_POLICY_STR(OFFE_DEF2); ++ CASE_BTC_POLICY_STR(FIX_TD3030); ++ CASE_BTC_POLICY_STR(FIX_TD5050); ++ CASE_BTC_POLICY_STR(FIX_TD2030); ++ CASE_BTC_POLICY_STR(FIX_TD4010); ++ CASE_BTC_POLICY_STR(FIX_TD7010); ++ CASE_BTC_POLICY_STR(FIX_TD2060); ++ CASE_BTC_POLICY_STR(FIX_TD3060); ++ CASE_BTC_POLICY_STR(FIX_TD2080); ++ CASE_BTC_POLICY_STR(FIX_TDW1B1); ++ CASE_BTC_POLICY_STR(FIX_TD4020); ++ CASE_BTC_POLICY_STR(PFIX_TD3030); ++ CASE_BTC_POLICY_STR(PFIX_TD5050); ++ CASE_BTC_POLICY_STR(PFIX_TD2030); ++ CASE_BTC_POLICY_STR(PFIX_TD2060); ++ CASE_BTC_POLICY_STR(PFIX_TD3070); ++ CASE_BTC_POLICY_STR(PFIX_TD2080); ++ CASE_BTC_POLICY_STR(PFIX_TDW1B1); ++ CASE_BTC_POLICY_STR(AUTO_TD50200); ++ CASE_BTC_POLICY_STR(AUTO_TD60200); ++ CASE_BTC_POLICY_STR(AUTO_TD20200); ++ CASE_BTC_POLICY_STR(AUTO_TDW1B1); ++ CASE_BTC_POLICY_STR(PAUTO_TD50200); ++ CASE_BTC_POLICY_STR(PAUTO_TD60200); ++ CASE_BTC_POLICY_STR(PAUTO_TD20200); ++ CASE_BTC_POLICY_STR(PAUTO_TDW1B1); ++ CASE_BTC_POLICY_STR(AUTO2_TD3050); ++ CASE_BTC_POLICY_STR(AUTO2_TD3070); ++ CASE_BTC_POLICY_STR(AUTO2_TD5050); ++ CASE_BTC_POLICY_STR(AUTO2_TD6060); ++ CASE_BTC_POLICY_STR(AUTO2_TD2080); ++ CASE_BTC_POLICY_STR(AUTO2_TDW1B4); ++ CASE_BTC_POLICY_STR(PAUTO2_TD3050); ++ CASE_BTC_POLICY_STR(PAUTO2_TD3070); ++ CASE_BTC_POLICY_STR(PAUTO2_TD5050); ++ CASE_BTC_POLICY_STR(PAUTO2_TD6060); ++ CASE_BTC_POLICY_STR(PAUTO2_TD2080); ++ CASE_BTC_POLICY_STR(PAUTO2_TDW1B4); ++ default: ++ return "unknown step"; ++ } ++} ++ ++static ++void seq_print_segment(struct seq_file *m, const char *prefix, u16 *data, ++ u8 len, u8 seg_len, u8 start_idx, u8 ring_len) ++{ ++ u8 i; ++ u8 cur_index; ++ ++ for (i = 0; i < len ; i++) { ++ if ((i % seg_len) == 0) ++ seq_printf(m, " %-15s : ", prefix); ++ cur_index = (start_idx + i) % ring_len; ++ if (i % 3 == 0) ++ seq_printf(m, "-> %-20s", ++ steps_to_str(*(data + cur_index))); ++ else if (i % 3 == 1) ++ seq_printf(m, "-> %-15s", ++ steps_to_str(*(data + cur_index))); ++ else ++ seq_printf(m, "-> %-13s", ++ steps_to_str(*(data + cur_index))); ++ if (i == (len - 1) || (i % seg_len) == (seg_len - 1)) ++ seq_puts(m, "\n"); ++ } ++} ++ ++static void _show_dm_step(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ u8 start_idx; ++ u8 len; ++ ++ len = dm->dm_step.step_ov ? RTW89_BTC_DM_MAXSTEP : dm->dm_step.step_pos; ++ start_idx = dm->dm_step.step_ov ? dm->dm_step.step_pos : 0; ++ ++ seq_print_segment(m, "[dm_steps]", dm->dm_step.step, len, 6, start_idx, ++ ARRAY_SIZE(dm->dm_step.step)); ++} ++ ++static void _show_dm_info(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_module *module = &btc->mdinfo; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ ++ if (!(dm->coex_info_map & BTC_COEX_INFO_DM)) ++ return; ++ ++ seq_printf(m, "========== [Mechanism Status %s] ==========\n", ++ (btc->ctrl.manual ? "(Manual)" : "(Auto)")); ++ ++ seq_printf(m, ++ " %-15s : type:%s, reason:%s(), action:%s(), ant_path:%ld, run_cnt:%d\n", ++ "[status]", ++ module->ant.type == BTC_ANT_SHARED ? "shared" : "dedicated", ++ steps_to_str(dm->run_reason), ++ steps_to_str(dm->run_action | BTC_ACT_EXT_BIT), ++ FIELD_GET(GENMASK(7, 0), dm->set_ant_path), ++ dm->cnt_dm[BTC_DCNT_RUN]); ++ ++ _show_dm_step(rtwdev, m); ++ ++ seq_printf(m, " %-15s : wl_only:%d, bt_only:%d, igno_bt:%d, free_run:%d, wl_ps_ctrl:%d, wl_mimo_ps:%d, ", ++ "[dm_flag]", dm->wl_only, dm->bt_only, btc->ctrl.igno_bt, ++ dm->freerun, btc->lps, dm->wl_mimo_ps); ++ ++ seq_printf(m, "leak_ap:%d, fw_offload:%s%s\n", dm->leak_ap, ++ (BTC_CX_FW_OFFLOAD ? "Y" : "N"), ++ (dm->wl_fw_cx_offload == BTC_CX_FW_OFFLOAD ? ++ "" : "(Mis-Match!!)")); ++ ++ if (dm->rf_trx_para.wl_tx_power == 0xff) ++ seq_printf(m, ++ " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:orig, ", ++ "[trx_ctrl]", wl->rssi_level, dm->trx_para_level); ++ ++ else ++ seq_printf(m, ++ " %-15s : wl_rssi_lvl:%d, para_lvl:%d, wl_tx_pwr:%d, ", ++ "[trx_ctrl]", wl->rssi_level, dm->trx_para_level, ++ dm->rf_trx_para.wl_tx_power); ++ ++ seq_printf(m, ++ "wl_rx_lvl:%d, bt_tx_pwr_dec:%d, bt_rx_lna:%d(%s-tbl), wl_btg_rx:%d\n", ++ dm->rf_trx_para.wl_rx_gain, dm->rf_trx_para.bt_tx_power, ++ dm->rf_trx_para.bt_rx_gain, ++ (bt->hi_lna_rx ? "Hi" : "Ori"), dm->wl_btg_rx); ++ ++ seq_printf(m, ++ " %-15s : wl_tx_limit[en:%d/max_t:%dus/max_retry:%d], bt_slot_reg:%d-TU\n", ++ "[dm_ctrl]", dm->wl_tx_limit.enable, dm->wl_tx_limit.tx_time, ++ dm->wl_tx_limit.tx_retry, btc->bt_req_len); ++} ++ ++static void _show_error(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; ++ struct rtw89_btc_fbtc_cysta *pcysta = NULL; ++ ++ pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; ++ ++ if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW] == 0 && ++ pcysta->except_cnt == 0 && ++ !pfwinfo->len_mismch && !pfwinfo->fver_mismch) ++ return; ++ ++ seq_printf(m, " %-15s : ", "[error]"); ++ ++ if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]) { ++ seq_printf(m, ++ "overflow-cnt: %d, ", ++ pfwinfo->event[BTF_EVNT_BUF_OVERFLOW]); ++ } ++ ++ if (pfwinfo->len_mismch) { ++ seq_printf(m, ++ "len-mismatch: 0x%x, ", ++ pfwinfo->len_mismch); ++ } ++ ++ if (pfwinfo->fver_mismch) { ++ seq_printf(m, ++ "fver-mismatch: 0x%x, ", ++ pfwinfo->fver_mismch); ++ } ++ ++ /* cycle statistics exceptions */ ++ if (pcysta->exception || pcysta->except_cnt) { ++ seq_printf(m, ++ "exception-type: 0x%x, exception-cnt = %d", ++ pcysta->exception, pcysta->except_cnt); ++ } ++ seq_puts(m, "\n"); ++} ++ ++static void _show_fbtc_tdma(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; ++ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; ++ struct rtw89_btc_fbtc_tdma *t = NULL; ++ struct rtw89_btc_fbtc_slot *s = NULL; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ u8 i, cnt = 0; ++ ++ pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo; ++ if (!pcinfo->valid) ++ return; ++ ++ t = &pfwinfo->rpt_fbtc_tdma.finfo; ++ ++ seq_printf(m, ++ " %-15s : ", "[tdma_policy]"); ++ seq_printf(m, ++ "type:%d, rx_flow_ctrl:%d, tx_pause:%d, ", ++ (u32)t->type, ++ t->rxflctrl, t->txpause); ++ ++ seq_printf(m, ++ "wl_toggle_n:%d, leak_n:%d, ext_ctrl:%d, ", ++ t->wtgle_n, t->leak_n, t->ext_ctrl); ++ ++ seq_printf(m, ++ "policy_type:%d", ++ (u32)btc->policy_type); ++ ++ s = pfwinfo->rpt_fbtc_slots.finfo.slot; ++ ++ for (i = 0; i < CXST_MAX; i++) { ++ if (dm->update_slot_map == BIT(CXST_MAX) - 1) ++ break; ++ ++ if (!(dm->update_slot_map & BIT(i))) ++ continue; ++ ++ if (cnt % 6 == 0) ++ seq_printf(m, ++ " %-15s : %d[%d/0x%x/%d]", ++ "[slot_policy]", ++ (u32)i, ++ s[i].dur, s[i].cxtbl, s[i].cxtype); ++ else ++ seq_printf(m, ++ ", %d[%d/0x%x/%d]", ++ (u32)i, ++ s[i].dur, s[i].cxtbl, s[i].cxtype); ++ if (cnt % 6 == 5) ++ seq_puts(m, "\n"); ++ cnt++; ++ } ++ seq_puts(m, "\n"); ++} ++ ++static void _show_fbtc_slots(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; ++ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; ++ struct rtw89_btc_fbtc_slots *pslots = NULL; ++ struct rtw89_btc_fbtc_slot s; ++ u8 i = 0; ++ ++ pcinfo = &pfwinfo->rpt_fbtc_slots.cinfo; ++ if (!pcinfo->valid) ++ return; ++ ++ pslots = &pfwinfo->rpt_fbtc_slots.finfo; ++ ++ for (i = 0; i < CXST_MAX; i++) { ++ s = pslots->slot[i]; ++ if (i % 6 == 0) ++ seq_printf(m, ++ " %-15s : %02d[%03d/0x%x/%d]", ++ "[slot_list]", ++ (u32)i, ++ s.dur, s.cxtbl, s.cxtype); ++ else ++ seq_printf(m, ++ ", %02d[%03d/0x%x/%d]", ++ (u32)i, ++ s.dur, s.cxtbl, s.cxtype); ++ if (i % 6 == 5) ++ seq_puts(m, "\n"); ++ } ++} ++ ++static void _show_fbtc_cysta(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; ++ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; ++ struct rtw89_btc_fbtc_cysta *pcysta_le32 = NULL; ++ struct rtw89_btc_fbtc_cysta_cpu pcysta[1]; ++ union rtw89_btc_fbtc_rxflct r; ++ u8 i, cnt = 0, slot_pair; ++ u16 cycle, c_begin, c_end, store_index; ++ ++ pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; ++ if (!pcinfo->valid) ++ return; ++ ++ pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo; ++ rtw89_btc_fbtc_cysta_to_cpu(pcysta_le32, pcysta); ++ seq_printf(m, ++ " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", ++ "[cycle_cnt]", pcysta->cycles, pcysta->bcn_cnt[CXBCN_ALL], ++ pcysta->bcn_cnt[CXBCN_ALL_OK], ++ pcysta->bcn_cnt[CXBCN_BT_SLOT], ++ pcysta->bcn_cnt[CXBCN_BT_OK]); ++ ++ _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, (u32)pcysta->cycles); ++ ++ for (i = 0; i < CXST_MAX; i++) { ++ if (!pcysta->slot_cnt[i]) ++ continue; ++ seq_printf(m, ++ ", %d:%d", (u32)i, pcysta->slot_cnt[i]); ++ } ++ ++ if (dm->tdma_now.rxflctrl) { ++ seq_printf(m, ++ ", leak_rx:%d", pcysta->leakrx_cnt); ++ } ++ ++ if (pcysta->collision_cnt) { ++ seq_printf(m, ++ ", collision:%d", pcysta->collision_cnt); ++ } ++ ++ if (pcysta->skip_cnt) { ++ seq_printf(m, ++ ", skip:%d", pcysta->skip_cnt); ++ } ++ seq_puts(m, "\n"); ++ ++ _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, pcysta->slot_cnt[CXST_W1]); ++ _chk_btc_err(rtwdev, BTC_DCNT_B1_FREEZE, pcysta->slot_cnt[CXST_B1]); ++ ++ seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", ++ "[cycle_time]", ++ pcysta->tavg_cycle[CXT_WL], ++ pcysta->tavg_cycle[CXT_BT], ++ pcysta->tavg_lk / 1000, pcysta->tavg_lk % 1000); ++ seq_printf(m, ++ ", max_t[wl:%d/bt:%d/lk:%d.%03d]", ++ pcysta->tmax_cycle[CXT_WL], ++ pcysta->tmax_cycle[CXT_BT], ++ pcysta->tmax_lk / 1000, pcysta->tmax_lk % 1000); ++ seq_printf(m, ++ ", maxdiff_t[wl:%d/bt:%d]\n", ++ pcysta->tmaxdiff_cycle[CXT_WL], ++ pcysta->tmaxdiff_cycle[CXT_BT]); ++ ++ if (pcysta->cycles == 0) ++ return; ++ ++ /* 1 cycle record 1 wl-slot and 1 bt-slot */ ++ slot_pair = BTC_CYCLE_SLOT_MAX / 2; ++ ++ if (pcysta->cycles <= slot_pair) ++ c_begin = 1; ++ else ++ c_begin = pcysta->cycles - slot_pair + 1; ++ ++ c_end = pcysta->cycles; ++ ++ for (cycle = c_begin; cycle <= c_end; cycle++) { ++ cnt++; ++ store_index = ((cycle - 1) % slot_pair) * 2; ++ ++ if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 1) ++ seq_printf(m, ++ " %-15s : ->b%02d->w%02d", "[cycle_step]", ++ pcysta->tslot_cycle[store_index], ++ pcysta->tslot_cycle[store_index + 1]); ++ else ++ seq_printf(m, ++ "->b%02d->w%02d", ++ pcysta->tslot_cycle[store_index], ++ pcysta->tslot_cycle[store_index + 1]); ++ if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end) ++ seq_puts(m, "\n"); ++ } ++ ++ if (a2dp->exist) { ++ seq_printf(m, ++ " %-15s : a2dp_ept:%d, a2dp_late:%d", ++ "[a2dp_t_sta]", ++ pcysta->a2dpept, pcysta->a2dpeptto); ++ ++ seq_printf(m, ++ ", avg_t:%d, max_t:%d", ++ pcysta->tavg_a2dpept, pcysta->tmax_a2dpept); ++ r.val = dm->tdma_now.rxflctrl; ++ ++ if (r.type && r.tgln_n) { ++ seq_printf(m, ++ ", cycle[PSTDMA:%d/TDMA:%d], ", ++ pcysta->cycles_a2dp[CXT_FLCTRL_ON], ++ pcysta->cycles_a2dp[CXT_FLCTRL_OFF]); ++ ++ seq_printf(m, ++ "avg_t[PSTDMA:%d/TDMA:%d], ", ++ pcysta->tavg_a2dp[CXT_FLCTRL_ON], ++ pcysta->tavg_a2dp[CXT_FLCTRL_OFF]); ++ ++ seq_printf(m, ++ "max_t[PSTDMA:%d/TDMA:%d]", ++ pcysta->tmax_a2dp[CXT_FLCTRL_ON], ++ pcysta->tmax_a2dp[CXT_FLCTRL_OFF]); ++ } ++ seq_puts(m, "\n"); ++ } ++} ++ ++static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; ++ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; ++ struct rtw89_btc_fbtc_cynullsta *ns = NULL; ++ u8 i = 0; ++ ++ if (!btc->dm.tdma_now.rxflctrl) ++ return; ++ ++ pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo; ++ if (!pcinfo->valid) ++ return; ++ ++ ns = &pfwinfo->rpt_fbtc_nullsta.finfo; ++ ++ seq_printf(m, " %-15s : ", "[null_sta]"); ++ ++ for (i = 0; i < 2; i++) { ++ if (i != 0) ++ seq_printf(m, ", null-%d", i); ++ else ++ seq_printf(m, "null-%d", i); ++ seq_printf(m, "[ok:%d/", le32_to_cpu(ns->result[i][1])); ++ seq_printf(m, "fail:%d/", le32_to_cpu(ns->result[i][0])); ++ seq_printf(m, "on_time:%d/", le32_to_cpu(ns->result[i][2])); ++ seq_printf(m, "retry:%d/", le32_to_cpu(ns->result[i][3])); ++ seq_printf(m, "avg_t:%d.%03d/", ++ le32_to_cpu(ns->avg_t[i]) / 1000, ++ le32_to_cpu(ns->avg_t[i]) % 1000); ++ seq_printf(m, "max_t:%d.%03d]", ++ le32_to_cpu(ns->max_t[i]) / 1000, ++ le32_to_cpu(ns->max_t[i]) % 1000); ++ } ++ seq_puts(m, "\n"); ++} ++ ++static void _show_fbtc_step(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; ++ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; ++ struct rtw89_btc_fbtc_steps *pstep = NULL; ++ u8 type, val, cnt = 0, state = 0; ++ bool outloop = false; ++ u16 i, diff_t, n_start = 0, n_stop = 0; ++ u16 pos_old, pos_new; ++ ++ pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; ++ if (!pcinfo->valid) ++ return; ++ ++ pstep = &pfwinfo->rpt_fbtc_step.finfo; ++ pos_old = le16_to_cpu(pstep->pos_old); ++ pos_new = le16_to_cpu(pstep->pos_new); ++ ++ if (pcinfo->req_fver != pstep->fver) ++ return; ++ ++ /* store step info by using ring instead of FIFO*/ ++ do { ++ switch (state) { ++ case 0: ++ n_start = pos_old; ++ if (pos_new >= pos_old) ++ n_stop = pos_new; ++ else ++ n_stop = btc->ctrl.trace_step - 1; ++ ++ state = 1; ++ break; ++ case 1: ++ for (i = n_start; i <= n_stop; i++) { ++ type = pstep->step[i].type; ++ val = pstep->step[i].val; ++ diff_t = le16_to_cpu(pstep->step[i].difft); ++ ++ if (type == CXSTEP_NONE || type >= CXSTEP_MAX) ++ continue; ++ ++ if (cnt % 10 == 0) ++ seq_printf(m, " %-15s : ", "[steps]"); ++ ++ seq_printf(m, "-> %s(%02d)(%02d)", ++ (type == CXSTEP_SLOT ? "SLT" : ++ "EVT"), (u32)val, diff_t); ++ if (cnt % 10 == 9) ++ seq_puts(m, "\n"); ++ cnt++; ++ } ++ ++ state = 2; ++ break; ++ case 2: ++ if (pos_new < pos_old && n_start != 0) { ++ n_start = 0; ++ n_stop = pos_new; ++ state = 1; ++ } else { ++ outloop = true; ++ } ++ break; ++ } ++ } while (!outloop); ++} ++ ++static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ if (!(btc->dm.coex_info_map & BTC_COEX_INFO_DM)) ++ return; ++ ++ _show_error(rtwdev, m); ++ _show_fbtc_tdma(rtwdev, m); ++ _show_fbtc_slots(rtwdev, m); ++ _show_fbtc_cysta(rtwdev, m); ++ _show_fbtc_nullsta(rtwdev, m); ++ _show_fbtc_step(rtwdev, m); ++} ++ ++static void _show_mreg(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; ++ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; ++ struct rtw89_btc_fbtc_mreg_val *pmreg = NULL; ++ struct rtw89_btc_fbtc_gpio_dbg *gdbg = NULL; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ struct rtw89_mac_ax_gnt gnt[2] = {0}; ++ u8 i = 0, type = 0, cnt = 0; ++ u32 val, offset; ++ ++ if (!(btc->dm.coex_info_map & BTC_COEX_INFO_MREG)) ++ return; ++ ++ seq_puts(m, "========== [HW Status] ==========\n"); ++ ++ seq_printf(m, ++ " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n", ++ "[scoreboard]", wl->scbd, cx->cnt_wl[BTC_WCNT_SCBDUPDATE], ++ bt->scbd, cx->cnt_bt[BTC_BCNT_SCBDREAD], ++ cx->cnt_bt[BTC_BCNT_SCBDUPDATE]); ++ ++ /* To avoid I/O if WL LPS or power-off */ ++ if (!wl->status.map.lps && !wl->status.map.rf_off) { ++ rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_1, &val); ++ if (val & (B_AX_GNT_BT_RFC_S0_SW_VAL | ++ B_AX_GNT_BT_BB_S0_SW_VAL)) ++ gnt[0].gnt_bt = true; ++ if (val & (B_AX_GNT_BT_RFC_S0_SW_CTRL | ++ B_AX_GNT_BT_BB_S0_SW_CTRL)) ++ gnt[0].gnt_bt_sw_en = true; ++ if (val & (B_AX_GNT_WL_RFC_S0_SW_VAL | ++ B_AX_GNT_WL_BB_S0_SW_VAL)) ++ gnt[0].gnt_wl = true; ++ if (val & (B_AX_GNT_WL_RFC_S0_SW_CTRL | ++ B_AX_GNT_WL_BB_S0_SW_CTRL)) ++ gnt[0].gnt_wl_sw_en = true; ++ ++ if (val & (B_AX_GNT_BT_RFC_S1_SW_VAL | ++ B_AX_GNT_BT_BB_S1_SW_VAL)) ++ gnt[1].gnt_bt = true; ++ if (val & (B_AX_GNT_BT_RFC_S1_SW_CTRL | ++ B_AX_GNT_BT_BB_S1_SW_CTRL)) ++ gnt[1].gnt_bt_sw_en = true; ++ if (val & (B_AX_GNT_WL_RFC_S1_SW_VAL | ++ B_AX_GNT_WL_BB_S1_SW_VAL)) ++ gnt[1].gnt_wl = true; ++ if (val & (B_AX_GNT_WL_RFC_S1_SW_CTRL | ++ B_AX_GNT_WL_BB_S1_SW_CTRL)) ++ gnt[1].gnt_wl_sw_en = true; ++ ++ seq_printf(m, ++ " %-15s : pta_owner:%s, phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d], ", ++ "[gnt_status]", ++ (rtw89_mac_get_ctrl_path(rtwdev) ? "WL" : "BT"), ++ (gnt[0].gnt_wl_sw_en ? "SW" : "HW"), gnt[0].gnt_wl, ++ (gnt[0].gnt_bt_sw_en ? "SW" : "HW"), gnt[0].gnt_bt); ++ ++ seq_printf(m, "phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]\n", ++ (gnt[1].gnt_wl_sw_en ? "SW" : "HW"), gnt[1].gnt_wl, ++ (gnt[1].gnt_bt_sw_en ? "SW" : "HW"), gnt[1].gnt_bt); ++ } ++ ++ pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; ++ if (!pcinfo->valid) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): stop due rpt_fbtc_mregval.cinfo\n", ++ __func__); ++ return; ++ } ++ ++ pmreg = &pfwinfo->rpt_fbtc_mregval.finfo; ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): rpt_fbtc_mregval reg_num = %d\n", ++ __func__, pmreg->reg_num); ++ ++ for (i = 0; i < pmreg->reg_num; i++) { ++ type = (u8)le16_to_cpu(chip->mon_reg[i].type); ++ offset = le32_to_cpu(chip->mon_reg[i].offset); ++ val = le32_to_cpu(pmreg->mreg_val[i]); ++ ++ if (cnt % 6 == 0) ++ seq_printf(m, " %-15s : %d_0x%04x=0x%08x", ++ "[reg]", (u32)type, offset, val); ++ else ++ seq_printf(m, ", %d_0x%04x=0x%08x", (u32)type, ++ offset, val); ++ if (cnt % 6 == 5) ++ seq_puts(m, "\n"); ++ cnt++; ++ } ++ ++ pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; ++ if (!pcinfo->valid) { ++ rtw89_debug(rtwdev, RTW89_DBG_BTC, ++ "[BTC], %s(): stop due rpt_fbtc_gpio_dbg.cinfo\n", ++ __func__); ++ return; ++ } ++ ++ gdbg = &pfwinfo->rpt_fbtc_gpio_dbg.finfo; ++ if (!gdbg->en_map) ++ return; ++ ++ seq_printf(m, " %-15s : enable_map:0x%08x", ++ "[gpio_dbg]", gdbg->en_map); ++ ++ for (i = 0; i < BTC_DBG_MAX1; i++) { ++ if (!(gdbg->en_map & BIT(i))) ++ continue; ++ seq_printf(m, ", %d->GPIO%d", (u32)i, gdbg->gpio_map[i]); ++ } ++ seq_puts(m, "\n"); ++} ++ ++static void _show_summary(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; ++ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; ++ struct rtw89_btc_fbtc_rpt_ctrl *prptctrl = NULL; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_wl_info *wl = &cx->wl; ++ struct rtw89_btc_bt_info *bt = &cx->bt; ++ u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; ++ u8 i; ++ ++ if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) ++ return; ++ ++ seq_puts(m, "========== [Statistics] ==========\n"); ++ ++ pcinfo = &pfwinfo->rpt_ctrl.cinfo; ++ if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { ++ prptctrl = &pfwinfo->rpt_ctrl.finfo; ++ ++ seq_printf(m, ++ " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ", ++ "[summary]", pfwinfo->cnt_h2c, ++ pfwinfo->cnt_h2c_fail, prptctrl->h2c_cnt, ++ pfwinfo->cnt_c2h, prptctrl->c2h_cnt); ++ ++ seq_printf(m, ++ "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x, dm_error_map:0x%x", ++ pfwinfo->event[BTF_EVNT_RPT], prptctrl->rpt_cnt, ++ prptctrl->rpt_enable, dm->error.val); ++ ++ _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, ++ pfwinfo->event[BTF_EVNT_RPT]); ++ ++ if (dm->error.map.wl_fw_hang) ++ seq_puts(m, " (WL FW Hang!!)"); ++ seq_puts(m, "\n"); ++ seq_printf(m, ++ " %-15s : send_ok:%d, send_fail:%d, recv:%d", ++ "[mailbox]", prptctrl->mb_send_ok_cnt, ++ prptctrl->mb_send_fail_cnt, prptctrl->mb_recv_cnt); ++ ++ seq_printf(m, ++ "(A2DP_empty:%d, A2DP_flowstop:%d, A2DP_full:%d)\n", ++ prptctrl->mb_a2dp_empty_cnt, ++ prptctrl->mb_a2dp_flct_cnt, ++ prptctrl->mb_a2dp_full_cnt); ++ ++ seq_printf(m, ++ " %-15s : wl_rfk[req:%d/go:%d/reject:%d/timeout:%d]", ++ "[RFK]", cx->cnt_wl[BTC_WCNT_RFK_REQ], ++ cx->cnt_wl[BTC_WCNT_RFK_GO], ++ cx->cnt_wl[BTC_WCNT_RFK_REJECT], ++ cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); ++ ++ seq_printf(m, ++ ", bt_rfk[req:%d/go:%d/reject:%d/timeout:%d/fail:%d]\n", ++ prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REQ], ++ prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_GO], ++ prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_REJECT], ++ prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_TIMEOUT], ++ prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_FAIL]); ++ ++ if (prptctrl->bt_rfk_cnt[BTC_BCNT_RFK_TIMEOUT] > 0) ++ bt->rfk_info.map.timeout = 1; ++ else ++ bt->rfk_info.map.timeout = 0; ++ ++ dm->error.map.wl_rfk_timeout = bt->rfk_info.map.timeout; ++ } else { ++ seq_printf(m, ++ " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d, rpt_cnt=%d, rpt_map=0x%x", ++ "[summary]", pfwinfo->cnt_h2c, ++ pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h, ++ pfwinfo->event[BTF_EVNT_RPT], ++ btc->fwinfo.rpt_en_map); ++ seq_puts(m, " (WL FW report invalid!!)\n"); ++ } ++ ++ for (i = 0; i < BTC_NCNT_NUM; i++) ++ cnt_sum += dm->cnt_notify[i]; ++ ++ seq_printf(m, ++ " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", ++ "[notify_cnt]", cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], ++ cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); ++ ++ seq_printf(m, ++ "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d\n", ++ cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], ++ cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], ++ cnt[BTC_NCNT_WL_STA]); ++ ++ seq_printf(m, ++ " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", ++ "[notify_cnt]", cnt[BTC_NCNT_SCAN_START], ++ cnt[BTC_NCNT_SCAN_FINISH], cnt[BTC_NCNT_SWITCH_BAND], ++ cnt[BTC_NCNT_SPECIAL_PACKET]); ++ ++ seq_printf(m, ++ "timer=%d, control=%d, customerize=%d\n", ++ cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], ++ cnt[BTC_NCNT_CUSTOMERIZE]); ++} ++ ++void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ struct rtw89_fw_suit *fw_suit = &rtwdev->fw.normal; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ struct rtw89_btc_bt_info *bt = &cx->bt; ++ ++ seq_puts(m, "=========================================\n"); ++ seq_printf(m, "WL FW / BT FW %d.%d.%d.%d / NA\n", ++ fw_suit->major_ver, fw_suit->minor_ver, ++ fw_suit->sub_ver, fw_suit->sub_idex); ++ seq_printf(m, "manual %d\n", btc->ctrl.manual); ++ ++ seq_puts(m, "=========================================\n"); ++ ++ seq_printf(m, "\n\r %-15s : raw_data[%02x %02x %02x %02x %02x %02x] (type:%s/cnt:%d/same:%d)", ++ "[bt_info]", ++ bt->raw_info[2], bt->raw_info[3], ++ bt->raw_info[4], bt->raw_info[5], ++ bt->raw_info[6], bt->raw_info[7], ++ bt->raw_info[0] == BTC_BTINFO_AUTO ? "auto" : "reply", ++ cx->cnt_bt[BTC_BCNT_INFOUPDATE], ++ cx->cnt_bt[BTC_BCNT_INFOSAME]); ++ ++ seq_puts(m, "\n=========================================\n"); ++ ++ _show_cx_info(rtwdev, m); ++ _show_wl_info(rtwdev, m); ++ _show_bt_info(rtwdev, m); ++ _show_dm_info(rtwdev, m); ++ _show_fw_dm_msg(rtwdev, m); ++ _show_mreg(rtwdev, m); ++ _show_summary(rtwdev, m); ++} +diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h +new file mode 100644 +index 000000000000..4b4565d15c9e +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/coex.h +@@ -0,0 +1,181 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_COEX_H__ ++#define __RTW89_COEX_H__ ++ ++#include "core.h" ++ ++enum btc_mode { ++ BTC_MODE_NORMAL, ++ BTC_MODE_WL, ++ BTC_MODE_BT, ++ BTC_MODE_WLOFF, ++ BTC_MODE_MAX ++}; ++ ++enum btc_wl_rfk_type { ++ BTC_WRFKT_IQK = 0, ++ BTC_WRFKT_LCK = 1, ++ BTC_WRFKT_DPK = 2, ++ BTC_WRFKT_TXGAPK = 3, ++ BTC_WRFKT_DACK = 4, ++ BTC_WRFKT_RXDCK = 5, ++ BTC_WRFKT_TSSI = 6, ++}; ++ ++#define NM_EXEC false ++#define FC_EXEC true ++ ++#define RTW89_COEX_ACT1_WORK_PERIOD round_jiffies_relative(HZ * 4) ++#define RTW89_COEX_BT_DEVINFO_WORK_PERIOD round_jiffies_relative(HZ * 16) ++#define RTW89_COEX_RFK_CHK_WORK_PERIOD msecs_to_jiffies(300) ++#define BTC_RFK_PATH_MAP GENMASK(3, 0) ++#define BTC_RFK_PHY_MAP GENMASK(5, 4) ++#define BTC_RFK_BAND_MAP GENMASK(7, 6) ++ ++enum btc_wl_rfk_state { ++ BTC_WRFK_STOP = 0, ++ BTC_WRFK_START = 1, ++ BTC_WRFK_ONESHOT_START = 2, ++ BTC_WRFK_ONESHOT_STOP = 3, ++}; ++ ++enum btc_pri { ++ BTC_PRI_MASK_RX_RESP = 0, ++ BTC_PRI_MASK_TX_RESP, ++ BTC_PRI_MASK_BEACON, ++ BTC_PRI_MASK_RX_CCK, ++ BTC_PRI_MASK_TX_MNGQ, ++ BTC_PRI_MASK_MAX, ++}; ++ ++enum btc_bt_trs { ++ BTC_BT_SS_GROUP = 0x0, ++ BTC_BT_TX_GROUP = 0x2, ++ BTC_BT_RX_GROUP = 0x3, ++ BTC_BT_MAX_GROUP, ++}; ++ ++enum btc_rssi_st { ++ BTC_RSSI_ST_LOW = 0x0, ++ BTC_RSSI_ST_HIGH, ++ BTC_RSSI_ST_STAY_LOW, ++ BTC_RSSI_ST_STAY_HIGH, ++ BTC_RSSI_ST_MAX ++}; ++ ++#define BTC_RSSI_HIGH(_rssi_) \ ++ ({typeof(_rssi_) __rssi = (_rssi_); \ ++ ((__rssi == BTC_RSSI_ST_HIGH || \ ++ __rssi == BTC_RSSI_ST_STAY_HIGH) ? 1 : 0); }) ++ ++#define BTC_RSSI_LOW(_rssi_) \ ++ ({typeof(_rssi_) __rssi = (_rssi_); \ ++ ((__rssi == BTC_RSSI_ST_LOW || \ ++ __rssi == BTC_RSSI_ST_STAY_LOW) ? 1 : 0); }) ++ ++#define BTC_RSSI_CHANGE(_rssi_) \ ++ ({typeof(_rssi_) __rssi = (_rssi_); \ ++ ((__rssi == BTC_RSSI_ST_LOW || \ ++ __rssi == BTC_RSSI_ST_HIGH) ? 1 : 0); }) ++ ++enum btc_ant { ++ BTC_ANT_SHARED = 0, ++ BTC_ANT_DEDICATED, ++ BTC_ANTTYPE_MAX ++}; ++ ++enum btc_bt_btg { ++ BTC_BT_ALONE = 0, ++ BTC_BT_BTG ++}; ++ ++enum btc_switch { ++ BTC_SWITCH_INTERNAL = 0, ++ BTC_SWITCH_EXTERNAL ++}; ++ ++enum btc_pkt_type { ++ PACKET_DHCP, ++ PACKET_ARP, ++ PACKET_EAPOL, ++ PACKET_EAPOL_END, ++ PACKET_ICMP, ++ PACKET_MAX ++}; ++ ++enum btc_bt_mailbox_id { ++ BTC_BTINFO_REPLY = 0x23, ++ BTC_BTINFO_AUTO = 0x27 ++}; ++ ++enum btc_role_state { ++ BTC_ROLE_START, ++ BTC_ROLE_STOP, ++ BTC_ROLE_CHG_TYPE, ++ BTC_ROLE_MSTS_STA_CONN_START, ++ BTC_ROLE_MSTS_STA_CONN_END, ++ BTC_ROLE_MSTS_STA_DIS_CONN, ++ BTC_ROLE_MSTS_AP_START, ++ BTC_ROLE_MSTS_AP_STOP, ++ BTC_ROLE_STATE_UNKNOWN ++}; ++ ++enum btc_rfctrl { ++ BTC_RFCTRL_WL_OFF, ++ BTC_RFCTRL_WL_ON, ++ BTC_RFCTRL_FW_CTRL, ++ BTC_RFCTRL_MAX ++}; ++ ++void rtw89_btc_ntfy_poweron(struct rtw89_dev *rtwdev); ++void rtw89_btc_ntfy_poweroff(struct rtw89_dev *rtwdev); ++void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode); ++void rtw89_btc_ntfy_scan_start(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band); ++void rtw89_btc_ntfy_scan_finish(struct rtw89_dev *rtwdev, u8 phy_idx); ++void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band); ++void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev, ++ enum btc_pkt_type pkt_type); ++void rtw89_btc_ntfy_eapol_packet_work(struct work_struct *work); ++void rtw89_btc_ntfy_arp_packet_work(struct work_struct *work); ++void rtw89_btc_ntfy_dhcp_packet_work(struct work_struct *work); ++void rtw89_btc_ntfy_icmp_packet_work(struct work_struct *work); ++void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ struct rtw89_sta *rtwsta, enum btc_role_state state); ++void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_state); ++void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map, ++ enum btc_wl_rfk_type type, ++ enum btc_wl_rfk_state state); ++void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev); ++void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, ++ u32 len, u8 class, u8 func); ++void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m); ++void rtw89_coex_act1_work(struct work_struct *work); ++void rtw89_coex_bt_devinfo_work(struct work_struct *work); ++void rtw89_coex_rfk_chk_work(struct work_struct *work); ++void rtw89_coex_power_on(struct rtw89_dev *rtwdev); ++ ++static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, ++ enum rtw89_rf_path_bit paths) ++{ ++ struct rtw89_hal *hal = &rtwdev->hal; ++ u8 phy_map; ++ ++ phy_map = FIELD_PREP(BTC_RFK_PATH_MAP, paths) | ++ FIELD_PREP(BTC_RFK_PHY_MAP, BIT(phy_idx)) | ++ FIELD_PREP(BTC_RFK_BAND_MAP, hal->current_band_type); ++ ++ return phy_map; ++} ++ ++static inline u8 rtw89_btc_path_phymap(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, ++ enum rtw89_rf_path path) ++{ ++ return rtw89_btc_phymap(rtwdev, phy_idx, BIT(path)); ++} ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +new file mode 100644 +index 000000000000..06fb6e5b1b37 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -0,0 +1,2502 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "coex.h" ++#include "core.h" ++#include "efuse.h" ++#include "fw.h" ++#include "mac.h" ++#include "phy.h" ++#include "ps.h" ++#include "reg.h" ++#include "sar.h" ++#include "ser.h" ++#include "txrx.h" ++#include "util.h" ++ ++static bool rtw89_disable_ps_mode; ++module_param_named(disable_ps_mode, rtw89_disable_ps_mode, bool, 0644); ++MODULE_PARM_DESC(disable_ps_mode, "Set Y to disable low power mode"); ++ ++static struct ieee80211_channel rtw89_channels_2ghz[] = { ++ { .center_freq = 2412, .hw_value = 1, }, ++ { .center_freq = 2417, .hw_value = 2, }, ++ { .center_freq = 2422, .hw_value = 3, }, ++ { .center_freq = 2427, .hw_value = 4, }, ++ { .center_freq = 2432, .hw_value = 5, }, ++ { .center_freq = 2437, .hw_value = 6, }, ++ { .center_freq = 2442, .hw_value = 7, }, ++ { .center_freq = 2447, .hw_value = 8, }, ++ { .center_freq = 2452, .hw_value = 9, }, ++ { .center_freq = 2457, .hw_value = 10, }, ++ { .center_freq = 2462, .hw_value = 11, }, ++ { .center_freq = 2467, .hw_value = 12, }, ++ { .center_freq = 2472, .hw_value = 13, }, ++ { .center_freq = 2484, .hw_value = 14, }, ++}; ++ ++static struct ieee80211_channel rtw89_channels_5ghz[] = { ++ {.center_freq = 5180, .hw_value = 36,}, ++ {.center_freq = 5200, .hw_value = 40,}, ++ {.center_freq = 5220, .hw_value = 44,}, ++ {.center_freq = 5240, .hw_value = 48,}, ++ {.center_freq = 5260, .hw_value = 52,}, ++ {.center_freq = 5280, .hw_value = 56,}, ++ {.center_freq = 5300, .hw_value = 60,}, ++ {.center_freq = 5320, .hw_value = 64,}, ++ {.center_freq = 5500, .hw_value = 100,}, ++ {.center_freq = 5520, .hw_value = 104,}, ++ {.center_freq = 5540, .hw_value = 108,}, ++ {.center_freq = 5560, .hw_value = 112,}, ++ {.center_freq = 5580, .hw_value = 116,}, ++ {.center_freq = 5600, .hw_value = 120,}, ++ {.center_freq = 5620, .hw_value = 124,}, ++ {.center_freq = 5640, .hw_value = 128,}, ++ {.center_freq = 5660, .hw_value = 132,}, ++ {.center_freq = 5680, .hw_value = 136,}, ++ {.center_freq = 5700, .hw_value = 140,}, ++ {.center_freq = 5720, .hw_value = 144,}, ++ {.center_freq = 5745, .hw_value = 149,}, ++ {.center_freq = 5765, .hw_value = 153,}, ++ {.center_freq = 5785, .hw_value = 157,}, ++ {.center_freq = 5805, .hw_value = 161,}, ++ {.center_freq = 5825, .hw_value = 165, ++ .flags = IEEE80211_CHAN_NO_HT40MINUS}, ++}; ++ ++static struct ieee80211_rate rtw89_bitrates[] = { ++ { .bitrate = 10, .hw_value = 0x00, }, ++ { .bitrate = 20, .hw_value = 0x01, }, ++ { .bitrate = 55, .hw_value = 0x02, }, ++ { .bitrate = 110, .hw_value = 0x03, }, ++ { .bitrate = 60, .hw_value = 0x04, }, ++ { .bitrate = 90, .hw_value = 0x05, }, ++ { .bitrate = 120, .hw_value = 0x06, }, ++ { .bitrate = 180, .hw_value = 0x07, }, ++ { .bitrate = 240, .hw_value = 0x08, }, ++ { .bitrate = 360, .hw_value = 0x09, }, ++ { .bitrate = 480, .hw_value = 0x0a, }, ++ { .bitrate = 540, .hw_value = 0x0b, }, ++}; ++ ++u16 rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate) ++{ ++ struct ieee80211_rate rate; ++ ++ if (unlikely(rpt_rate >= ARRAY_SIZE(rtw89_bitrates))) { ++ rtw89_info(rtwdev, "invalid rpt rate %d\n", rpt_rate); ++ return 0; ++ } ++ ++ rate = rtw89_bitrates[rpt_rate]; ++ ++ return rate.bitrate; ++} ++ ++static struct ieee80211_supported_band rtw89_sband_2ghz = { ++ .band = NL80211_BAND_2GHZ, ++ .channels = rtw89_channels_2ghz, ++ .n_channels = ARRAY_SIZE(rtw89_channels_2ghz), ++ .bitrates = rtw89_bitrates, ++ .n_bitrates = ARRAY_SIZE(rtw89_bitrates), ++ .ht_cap = {0}, ++ .vht_cap = {0}, ++}; ++ ++static struct ieee80211_supported_band rtw89_sband_5ghz = { ++ .band = NL80211_BAND_5GHZ, ++ .channels = rtw89_channels_5ghz, ++ .n_channels = ARRAY_SIZE(rtw89_channels_5ghz), ++ ++ /* 5G has no CCK rates, 1M/2M/5.5M/11M */ ++ .bitrates = rtw89_bitrates + 4, ++ .n_bitrates = ARRAY_SIZE(rtw89_bitrates) - 4, ++ .ht_cap = {0}, ++ .vht_cap = {0}, ++}; ++ ++static void rtw89_traffic_stats_accu(struct rtw89_dev *rtwdev, ++ struct rtw89_traffic_stats *stats, ++ struct sk_buff *skb, bool tx) ++{ ++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; ++ ++ if (!ieee80211_is_data(hdr->frame_control)) ++ return; ++ ++ if (is_broadcast_ether_addr(hdr->addr1) || ++ is_multicast_ether_addr(hdr->addr1)) ++ return; ++ ++ if (tx) { ++ stats->tx_cnt++; ++ stats->tx_unicast += skb->len; ++ } else { ++ stats->rx_cnt++; ++ stats->rx_unicast += skb->len; ++ } ++} ++ ++static void rtw89_get_channel_params(struct cfg80211_chan_def *chandef, ++ struct rtw89_channel_params *chan_param) ++{ ++ struct ieee80211_channel *channel = chandef->chan; ++ enum nl80211_chan_width width = chandef->width; ++ u8 *cch_by_bw = chan_param->cch_by_bw; ++ u32 primary_freq, center_freq; ++ u8 center_chan; ++ u8 bandwidth = RTW89_CHANNEL_WIDTH_20; ++ u8 primary_chan_idx = 0; ++ u8 i; ++ ++ center_chan = channel->hw_value; ++ primary_freq = channel->center_freq; ++ center_freq = chandef->center_freq1; ++ ++ /* assign the center channel used while 20M bw is selected */ ++ cch_by_bw[RTW89_CHANNEL_WIDTH_20] = channel->hw_value; ++ ++ switch (width) { ++ case NL80211_CHAN_WIDTH_20_NOHT: ++ case NL80211_CHAN_WIDTH_20: ++ bandwidth = RTW89_CHANNEL_WIDTH_20; ++ primary_chan_idx = RTW89_SC_DONT_CARE; ++ break; ++ case NL80211_CHAN_WIDTH_40: ++ bandwidth = RTW89_CHANNEL_WIDTH_40; ++ if (primary_freq > center_freq) { ++ primary_chan_idx = RTW89_SC_20_UPPER; ++ center_chan -= 2; ++ } else { ++ primary_chan_idx = RTW89_SC_20_LOWER; ++ center_chan += 2; ++ } ++ break; ++ case NL80211_CHAN_WIDTH_80: ++ bandwidth = RTW89_CHANNEL_WIDTH_80; ++ if (primary_freq > center_freq) { ++ if (primary_freq - center_freq == 10) { ++ primary_chan_idx = RTW89_SC_20_UPPER; ++ center_chan -= 2; ++ } else { ++ primary_chan_idx = RTW89_SC_20_UPMOST; ++ center_chan -= 6; ++ } ++ /* assign the center channel used ++ * while 40M bw is selected ++ */ ++ cch_by_bw[RTW89_CHANNEL_WIDTH_40] = center_chan + 4; ++ } else { ++ if (center_freq - primary_freq == 10) { ++ primary_chan_idx = RTW89_SC_20_LOWER; ++ center_chan += 2; ++ } else { ++ primary_chan_idx = RTW89_SC_20_LOWEST; ++ center_chan += 6; ++ } ++ /* assign the center channel used ++ * while 40M bw is selected ++ */ ++ cch_by_bw[RTW89_CHANNEL_WIDTH_40] = center_chan - 4; ++ } ++ break; ++ default: ++ center_chan = 0; ++ break; ++ } ++ ++ chan_param->center_chan = center_chan; ++ chan_param->primary_chan = channel->hw_value; ++ chan_param->bandwidth = bandwidth; ++ chan_param->pri_ch_idx = primary_chan_idx; ++ ++ /* assign the center channel used while current bw is selected */ ++ cch_by_bw[bandwidth] = center_chan; ++ ++ for (i = bandwidth + 1; i <= RTW89_MAX_CHANNEL_WIDTH; i++) ++ cch_by_bw[i] = 0; ++} ++ ++void rtw89_set_channel(struct rtw89_dev *rtwdev) ++{ ++ struct ieee80211_hw *hw = rtwdev->hw; ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ struct rtw89_channel_params ch_param; ++ struct rtw89_channel_help_params bak; ++ u8 center_chan, bandwidth; ++ u8 band_type; ++ bool band_changed; ++ u8 i; ++ ++ rtw89_get_channel_params(&hw->conf.chandef, &ch_param); ++ if (WARN(ch_param.center_chan == 0, "Invalid channel\n")) ++ return; ++ ++ center_chan = ch_param.center_chan; ++ bandwidth = ch_param.bandwidth; ++ band_type = center_chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G; ++ band_changed = hal->current_band_type != band_type || ++ hal->current_channel == 0; ++ ++ hal->current_band_width = bandwidth; ++ hal->current_channel = center_chan; ++ hal->current_primary_channel = ch_param.primary_chan; ++ hal->current_band_type = band_type; ++ ++ switch (center_chan) { ++ case 1 ... 14: ++ hal->current_subband = RTW89_CH_2G; ++ break; ++ case 36 ... 64: ++ hal->current_subband = RTW89_CH_5G_BAND_1; ++ break; ++ case 100 ... 144: ++ hal->current_subband = RTW89_CH_5G_BAND_3; ++ break; ++ case 149 ... 177: ++ hal->current_subband = RTW89_CH_5G_BAND_4; ++ break; ++ } ++ ++ for (i = RTW89_CHANNEL_WIDTH_20; i <= RTW89_MAX_CHANNEL_WIDTH; i++) ++ hal->cch_by_bw[i] = ch_param.cch_by_bw[i]; ++ ++ rtw89_chip_set_channel_prepare(rtwdev, &bak); ++ ++ chip->ops->set_channel(rtwdev, &ch_param); ++ ++ rtw89_chip_set_txpwr(rtwdev); ++ ++ rtw89_chip_set_channel_done(rtwdev, &bak); ++ ++ if (band_changed) { ++ rtw89_btc_ntfy_switch_band(rtwdev, RTW89_PHY_0, hal->current_band_type); ++ rtw89_chip_rfk_band_changed(rtwdev); ++ } ++} ++ ++static enum rtw89_core_tx_type ++rtw89_core_get_tx_type(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb) ++{ ++ struct ieee80211_hdr *hdr = (void *)skb->data; ++ __le16 fc = hdr->frame_control; ++ ++ if (ieee80211_is_mgmt(fc) || ieee80211_is_nullfunc(fc)) ++ return RTW89_CORE_TX_TYPE_MGMT; ++ ++ return RTW89_CORE_TX_TYPE_DATA; ++} ++ ++static void ++rtw89_core_tx_update_ampdu_info(struct rtw89_dev *rtwdev, ++ struct rtw89_core_tx_request *tx_req, u8 tid) ++{ ++ struct ieee80211_sta *sta = tx_req->sta; ++ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; ++ struct rtw89_sta *rtwsta; ++ u8 ampdu_num; ++ ++ if (!sta) { ++ rtw89_warn(rtwdev, "cannot set ampdu info without sta\n"); ++ return; ++ } ++ ++ rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ ++ ampdu_num = (u8)((rtwsta->ampdu_params[tid].agg_num ? ++ rtwsta->ampdu_params[tid].agg_num : ++ 4 << sta->ht_cap.ampdu_factor) - 1); ++ ++ desc_info->agg_en = true; ++ desc_info->ampdu_density = sta->ht_cap.ampdu_density; ++ desc_info->ampdu_num = ampdu_num; ++} ++ ++static void ++rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ struct ieee80211_vif *vif = tx_req->vif; ++ struct ieee80211_tx_info *info; ++ struct ieee80211_key_conf *key; ++ struct rtw89_vif *rtwvif; ++ struct rtw89_addr_cam_entry *addr_cam; ++ struct rtw89_sec_cam_entry *sec_cam; ++ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; ++ struct sk_buff *skb = tx_req->skb; ++ u8 sec_type = RTW89_SEC_KEY_TYPE_NONE; ++ ++ if (!vif) { ++ rtw89_warn(rtwdev, "cannot set sec key without vif\n"); ++ return; ++ } ++ ++ rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ addr_cam = &rtwvif->addr_cam; ++ ++ info = IEEE80211_SKB_CB(skb); ++ key = info->control.hw_key; ++ sec_cam = addr_cam->sec_entries[key->hw_key_idx]; ++ if (!sec_cam) { ++ rtw89_warn(rtwdev, "sec cam entry is empty\n"); ++ return; ++ } ++ ++ switch (key->cipher) { ++ case WLAN_CIPHER_SUITE_WEP40: ++ sec_type = RTW89_SEC_KEY_TYPE_WEP40; ++ break; ++ case WLAN_CIPHER_SUITE_WEP104: ++ sec_type = RTW89_SEC_KEY_TYPE_WEP104; ++ break; ++ case WLAN_CIPHER_SUITE_TKIP: ++ sec_type = RTW89_SEC_KEY_TYPE_TKIP; ++ break; ++ case WLAN_CIPHER_SUITE_CCMP: ++ sec_type = RTW89_SEC_KEY_TYPE_CCMP128; ++ break; ++ case WLAN_CIPHER_SUITE_CCMP_256: ++ sec_type = RTW89_SEC_KEY_TYPE_CCMP256; ++ break; ++ case WLAN_CIPHER_SUITE_GCMP: ++ sec_type = RTW89_SEC_KEY_TYPE_GCMP128; ++ break; ++ case WLAN_CIPHER_SUITE_GCMP_256: ++ sec_type = RTW89_SEC_KEY_TYPE_GCMP256; ++ break; ++ default: ++ rtw89_warn(rtwdev, "key cipher not supported %d\n", key->cipher); ++ return; ++ } ++ ++ desc_info->sec_en = true; ++ desc_info->sec_type = sec_type; ++ desc_info->sec_cam_idx = sec_cam->sec_cam_idx; ++} ++ ++static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ struct sk_buff *skb = tx_req->skb; ++ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); ++ struct ieee80211_vif *vif = tx_info->control.vif; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ u16 lowest_rate = hal->current_band_type == RTW89_BAND_2G ? ++ RTW89_HW_RATE_CCK1 : RTW89_HW_RATE_OFDM6; ++ ++ if (!vif || !vif->bss_conf.basic_rates || !tx_req->sta) ++ return lowest_rate; ++ ++ return __ffs(vif->bss_conf.basic_rates) + lowest_rate; ++} ++ ++static void ++rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; ++ u8 qsel, ch_dma; ++ ++ qsel = RTW89_TX_QSEL_B0_MGMT; ++ ch_dma = rtw89_core_get_ch_dma(rtwdev, qsel); ++ ++ desc_info->qsel = RTW89_TX_QSEL_B0_MGMT; ++ desc_info->ch_dma = ch_dma; ++ ++ /* fixed data rate for mgmt frames */ ++ desc_info->en_wd_info = true; ++ desc_info->use_rate = true; ++ desc_info->dis_data_fb = true; ++ desc_info->data_rate = rtw89_core_get_mgmt_rate(rtwdev, tx_req); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXRX, ++ "tx mgmt frame with rate 0x%x on channel %d (bw %d)\n", ++ desc_info->data_rate, rtwdev->hal.current_channel, ++ rtwdev->hal.current_band_width); ++} ++ ++static void ++rtw89_core_tx_update_h2c_info(struct rtw89_dev *rtwdev, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; ++ ++ desc_info->is_bmc = false; ++ desc_info->wd_page = false; ++ desc_info->ch_dma = RTW89_DMA_H2C; ++} ++ ++static void rtw89_core_get_no_ul_ofdma_htc(struct rtw89_dev *rtwdev, __le32 *htc) ++{ ++ static const u8 rtw89_bandwidth_to_om[] = { ++ [RTW89_CHANNEL_WIDTH_20] = HTC_OM_CHANNEL_WIDTH_20, ++ [RTW89_CHANNEL_WIDTH_40] = HTC_OM_CHANNEL_WIDTH_40, ++ [RTW89_CHANNEL_WIDTH_80] = HTC_OM_CHANNEL_WIDTH_80, ++ [RTW89_CHANNEL_WIDTH_160] = HTC_OM_CHANNEL_WIDTH_160_OR_80_80, ++ [RTW89_CHANNEL_WIDTH_80_80] = HTC_OM_CHANNEL_WIDTH_160_OR_80_80, ++ }; ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ u8 om_bandwidth; ++ ++ if (!chip->dis_2g_40m_ul_ofdma || ++ hal->current_band_type != RTW89_BAND_2G || ++ hal->current_band_width != RTW89_CHANNEL_WIDTH_40) ++ return; ++ ++ om_bandwidth = hal->current_band_width < ARRAY_SIZE(rtw89_bandwidth_to_om) ? ++ rtw89_bandwidth_to_om[hal->current_band_width] : 0; ++ *htc = le32_encode_bits(RTW89_HTC_VARIANT_HE, RTW89_HTC_MASK_VARIANT) | ++ le32_encode_bits(RTW89_HTC_VARIANT_HE_CID_OM, RTW89_HTC_MASK_CTL_ID) | ++ le32_encode_bits(hal->rx_nss - 1, RTW89_HTC_MASK_HTC_OM_RX_NSS) | ++ le32_encode_bits(om_bandwidth, RTW89_HTC_MASK_HTC_OM_CH_WIDTH) | ++ le32_encode_bits(1, RTW89_HTC_MASK_HTC_OM_UL_MU_DIS) | ++ le32_encode_bits(hal->tx_nss - 1, RTW89_HTC_MASK_HTC_OM_TX_NSTS) | ++ le32_encode_bits(0, RTW89_HTC_MASK_HTC_OM_ER_SU_DIS) | ++ le32_encode_bits(0, RTW89_HTC_MASK_HTC_OM_DL_MU_MIMO_RR) | ++ le32_encode_bits(0, RTW89_HTC_MASK_HTC_OM_UL_MU_DATA_DIS); ++} ++ ++static bool ++__rtw89_core_tx_check_he_qos_htc(struct rtw89_dev *rtwdev, ++ struct rtw89_core_tx_request *tx_req, ++ enum btc_pkt_type pkt_type) ++{ ++ struct ieee80211_sta *sta = tx_req->sta; ++ struct sk_buff *skb = tx_req->skb; ++ struct ieee80211_hdr *hdr = (void *)skb->data; ++ __le16 fc = hdr->frame_control; ++ ++ /* AP IOT issue with EAPoL, ARP and DHCP */ ++ if (pkt_type < PACKET_MAX) ++ return false; ++ ++ if (!sta || !sta->he_cap.has_he) ++ return false; ++ ++ if (!ieee80211_is_data_qos(fc)) ++ return false; ++ ++ if (skb_headroom(skb) < IEEE80211_HT_CTL_LEN) ++ return false; ++ ++ return true; ++} ++ ++static void ++__rtw89_core_tx_adjust_he_qos_htc(struct rtw89_dev *rtwdev, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ struct ieee80211_sta *sta = tx_req->sta; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct sk_buff *skb = tx_req->skb; ++ struct ieee80211_hdr *hdr = (void *)skb->data; ++ __le16 fc = hdr->frame_control; ++ void *data; ++ __le32 *htc; ++ u8 *qc; ++ int hdr_len; ++ ++ hdr_len = ieee80211_has_a4(fc) ? 32 : 26; ++ data = skb_push(skb, IEEE80211_HT_CTL_LEN); ++ memmove(data, data + IEEE80211_HT_CTL_LEN, hdr_len); ++ ++ hdr = data; ++ htc = data + hdr_len; ++ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_ORDER); ++ *htc = rtwsta->htc_template ? rtwsta->htc_template : ++ le32_encode_bits(RTW89_HTC_VARIANT_HE, RTW89_HTC_MASK_VARIANT) | ++ le32_encode_bits(RTW89_HTC_VARIANT_HE_CID_CAS, RTW89_HTC_MASK_CTL_ID); ++ ++ qc = data + hdr_len - IEEE80211_QOS_CTL_LEN; ++ qc[0] |= IEEE80211_QOS_CTL_EOSP; ++} ++ ++static void ++rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev, ++ struct rtw89_core_tx_request *tx_req, ++ enum btc_pkt_type pkt_type) ++{ ++ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; ++ struct ieee80211_vif *vif = tx_req->vif; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ ++ if (!__rtw89_core_tx_check_he_qos_htc(rtwdev, tx_req, pkt_type)) ++ goto desc_bk; ++ ++ __rtw89_core_tx_adjust_he_qos_htc(rtwdev, tx_req); ++ ++ desc_info->pkt_size += IEEE80211_HT_CTL_LEN; ++ desc_info->a_ctrl_bsr = true; ++ ++desc_bk: ++ if (!rtwvif || rtwvif->last_a_ctrl == desc_info->a_ctrl_bsr) ++ return; ++ ++ rtwvif->last_a_ctrl = desc_info->a_ctrl_bsr; ++ desc_info->bk = true; ++} ++ ++static void ++rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ struct ieee80211_vif *vif = tx_req->vif; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; ++ struct sk_buff *skb = tx_req->skb; ++ u8 tid, tid_indicate; ++ u8 qsel, ch_dma; ++ ++ tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; ++ tid_indicate = rtw89_core_get_tid_indicate(rtwdev, tid); ++ qsel = rtw89_core_get_qsel(rtwdev, tid); ++ ch_dma = rtw89_core_get_ch_dma(rtwdev, qsel); ++ ++ desc_info->ch_dma = ch_dma; ++ desc_info->tid_indicate = tid_indicate; ++ desc_info->qsel = qsel; ++ ++ /* enable wd_info for AMPDU */ ++ desc_info->en_wd_info = true; ++ ++ if (IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_AMPDU) ++ rtw89_core_tx_update_ampdu_info(rtwdev, tx_req, tid); ++ if (IEEE80211_SKB_CB(skb)->control.hw_key) ++ rtw89_core_tx_update_sec_key(rtwdev, tx_req); ++ ++ if (rate_pattern->enable) ++ desc_info->data_retry_lowest_rate = rate_pattern->rate; ++ else if (hal->current_band_type == RTW89_BAND_2G) ++ desc_info->data_retry_lowest_rate = RTW89_HW_RATE_CCK1; ++ else ++ desc_info->data_retry_lowest_rate = RTW89_HW_RATE_OFDM6; ++} ++ ++static enum btc_pkt_type ++rtw89_core_tx_btc_spec_pkt_notify(struct rtw89_dev *rtwdev, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ struct sk_buff *skb = tx_req->skb; ++ struct udphdr *udphdr; ++ ++ if (IEEE80211_SKB_CB(skb)->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) { ++ ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.eapol_notify_work); ++ return PACKET_EAPOL; ++ } ++ ++ if (skb->protocol == htons(ETH_P_ARP)) { ++ ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.arp_notify_work); ++ return PACKET_ARP; ++ } ++ ++ if (skb->protocol == htons(ETH_P_IP) && ++ ip_hdr(skb)->protocol == IPPROTO_UDP) { ++ udphdr = udp_hdr(skb); ++ if (((udphdr->source == htons(67) && udphdr->dest == htons(68)) || ++ (udphdr->source == htons(68) && udphdr->dest == htons(67))) && ++ skb->len > 282) { ++ ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.dhcp_notify_work); ++ return PACKET_DHCP; ++ } ++ } ++ ++ if (skb->protocol == htons(ETH_P_IP) && ++ ip_hdr(skb)->protocol == IPPROTO_ICMP) { ++ ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.icmp_notify_work); ++ return PACKET_ICMP; ++ } ++ ++ return PACKET_MAX; ++} ++ ++static void ++rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; ++ struct sk_buff *skb = tx_req->skb; ++ struct ieee80211_hdr *hdr = (void *)skb->data; ++ enum rtw89_core_tx_type tx_type; ++ enum btc_pkt_type pkt_type; ++ bool is_bmc; ++ u16 seq; ++ ++ seq = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; ++ if (tx_req->tx_type != RTW89_CORE_TX_TYPE_FWCMD) { ++ tx_type = rtw89_core_get_tx_type(rtwdev, skb); ++ tx_req->tx_type = tx_type; ++ } ++ is_bmc = (is_broadcast_ether_addr(hdr->addr1) || ++ is_multicast_ether_addr(hdr->addr1)); ++ ++ desc_info->seq = seq; ++ desc_info->pkt_size = skb->len; ++ desc_info->is_bmc = is_bmc; ++ desc_info->wd_page = true; ++ ++ switch (tx_req->tx_type) { ++ case RTW89_CORE_TX_TYPE_MGMT: ++ rtw89_core_tx_update_mgmt_info(rtwdev, tx_req); ++ break; ++ case RTW89_CORE_TX_TYPE_DATA: ++ rtw89_core_tx_update_data_info(rtwdev, tx_req); ++ pkt_type = rtw89_core_tx_btc_spec_pkt_notify(rtwdev, tx_req); ++ rtw89_core_tx_update_he_qos_htc(rtwdev, tx_req, pkt_type); ++ break; ++ case RTW89_CORE_TX_TYPE_FWCMD: ++ rtw89_core_tx_update_h2c_info(rtwdev, tx_req); ++ break; ++ } ++} ++ ++void rtw89_core_tx_kick_off(struct rtw89_dev *rtwdev, u8 qsel) ++{ ++ u8 ch_dma; ++ ++ ch_dma = rtw89_core_get_ch_dma(rtwdev, qsel); ++ ++ rtw89_hci_tx_kick_off(rtwdev, ch_dma); ++} ++ ++int rtw89_h2c_tx(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb, bool fwdl) ++{ ++ struct rtw89_core_tx_request tx_req = {0}; ++ u32 cnt; ++ int ret; ++ ++ tx_req.skb = skb; ++ tx_req.tx_type = RTW89_CORE_TX_TYPE_FWCMD; ++ if (fwdl) ++ tx_req.desc_info.fw_dl = true; ++ ++ rtw89_core_tx_update_desc_info(rtwdev, &tx_req); ++ ++ if (!fwdl) ++ rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "H2C: ", skb->data, skb->len); ++ ++ cnt = rtw89_hci_check_and_reclaim_tx_resource(rtwdev, RTW89_TXCH_CH12); ++ if (cnt == 0) { ++ rtw89_err(rtwdev, "no tx fwcmd resource\n"); ++ return -ENOSPC; ++ } ++ ++ ret = rtw89_hci_tx_write(rtwdev, &tx_req); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to transmit skb to HCI\n"); ++ return ret; ++ } ++ rtw89_hci_tx_kick_off(rtwdev, RTW89_TXCH_CH12); ++ ++ return 0; ++} ++ ++int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel) ++{ ++ struct rtw89_core_tx_request tx_req = {0}; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ int ret; ++ ++ tx_req.skb = skb; ++ tx_req.sta = sta; ++ tx_req.vif = vif; ++ ++ rtw89_traffic_stats_accu(rtwdev, &rtwdev->stats, skb, true); ++ rtw89_traffic_stats_accu(rtwdev, &rtwvif->stats, skb, true); ++ rtw89_core_tx_update_desc_info(rtwdev, &tx_req); ++ ret = rtw89_hci_tx_write(rtwdev, &tx_req); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to transmit skb to HCI\n"); ++ return ret; ++ } ++ ++ if (qsel) ++ *qsel = tx_req.desc_info.qsel; ++ ++ return 0; ++} ++ ++static __le32 rtw89_build_txwd_body0(struct rtw89_tx_desc_info *desc_info) ++{ ++ u32 dword = FIELD_PREP(RTW89_TXWD_BODY0_WP_OFFSET, desc_info->wp_offset) | ++ FIELD_PREP(RTW89_TXWD_BODY0_WD_INFO_EN, desc_info->en_wd_info) | ++ FIELD_PREP(RTW89_TXWD_BODY0_CHANNEL_DMA, desc_info->ch_dma) | ++ FIELD_PREP(RTW89_TXWD_BODY0_HDR_LLC_LEN, desc_info->hdr_llc_len) | ++ FIELD_PREP(RTW89_TXWD_BODY0_WD_PAGE, desc_info->wd_page) | ++ FIELD_PREP(RTW89_TXWD_BODY0_FW_DL, desc_info->fw_dl); ++ ++ return cpu_to_le32(dword); ++} ++ ++static __le32 rtw89_build_txwd_body2(struct rtw89_tx_desc_info *desc_info) ++{ ++ u32 dword = FIELD_PREP(RTW89_TXWD_BODY2_TID_INDICATE, desc_info->tid_indicate) | ++ FIELD_PREP(RTW89_TXWD_BODY2_QSEL, desc_info->qsel) | ++ FIELD_PREP(RTW89_TXWD_BODY2_TXPKT_SIZE, desc_info->pkt_size); ++ ++ return cpu_to_le32(dword); ++} ++ ++static __le32 rtw89_build_txwd_body3(struct rtw89_tx_desc_info *desc_info) ++{ ++ u32 dword = FIELD_PREP(RTW89_TXWD_BODY3_SW_SEQ, desc_info->seq) | ++ FIELD_PREP(RTW89_TXWD_BODY3_AGG_EN, desc_info->agg_en) | ++ FIELD_PREP(RTW89_TXWD_BODY3_BK, desc_info->bk); ++ ++ return cpu_to_le32(dword); ++} ++ ++static __le32 rtw89_build_txwd_info0(struct rtw89_tx_desc_info *desc_info) ++{ ++ u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_USE_RATE, desc_info->use_rate) | ++ FIELD_PREP(RTW89_TXWD_INFO0_DATA_RATE, desc_info->data_rate) | ++ FIELD_PREP(RTW89_TXWD_INFO0_DISDATAFB, desc_info->dis_data_fb); ++ ++ return cpu_to_le32(dword); ++} ++ ++static __le32 rtw89_build_txwd_info1(struct rtw89_tx_desc_info *desc_info) ++{ ++ u32 dword = FIELD_PREP(RTW89_TXWD_INFO1_MAX_AGGNUM, desc_info->ampdu_num) | ++ FIELD_PREP(RTW89_TXWD_INFO1_A_CTRL_BSR, desc_info->a_ctrl_bsr) | ++ FIELD_PREP(RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE, ++ desc_info->data_retry_lowest_rate); ++ ++ return cpu_to_le32(dword); ++} ++ ++static __le32 rtw89_build_txwd_info2(struct rtw89_tx_desc_info *desc_info) ++{ ++ u32 dword = FIELD_PREP(RTW89_TXWD_INFO2_AMPDU_DENSITY, desc_info->ampdu_density) | ++ FIELD_PREP(RTW89_TXWD_INFO2_SEC_TYPE, desc_info->sec_type) | ++ FIELD_PREP(RTW89_TXWD_INFO2_SEC_HW_ENC, desc_info->sec_en) | ++ FIELD_PREP(RTW89_TXWD_INFO2_SEC_CAM_IDX, desc_info->sec_cam_idx); ++ ++ return cpu_to_le32(dword); ++} ++ ++static __le32 rtw89_build_txwd_info4(struct rtw89_tx_desc_info *desc_info) ++{ ++ u32 dword = FIELD_PREP(RTW89_TXWD_INFO4_RTS_EN, 1) | ++ FIELD_PREP(RTW89_TXWD_INFO4_HW_RTS_EN, 1); ++ ++ return cpu_to_le32(dword); ++} ++ ++void rtw89_core_fill_txdesc(struct rtw89_dev *rtwdev, ++ struct rtw89_tx_desc_info *desc_info, ++ void *txdesc) ++{ ++ struct rtw89_txwd_body *txwd_body = (struct rtw89_txwd_body *)txdesc; ++ struct rtw89_txwd_info *txwd_info; ++ ++ txwd_body->dword0 = rtw89_build_txwd_body0(desc_info); ++ txwd_body->dword2 = rtw89_build_txwd_body2(desc_info); ++ txwd_body->dword3 = rtw89_build_txwd_body3(desc_info); ++ ++ if (!desc_info->en_wd_info) ++ return; ++ ++ txwd_info = (struct rtw89_txwd_info *)(txwd_body + 1); ++ txwd_info->dword0 = rtw89_build_txwd_info0(desc_info); ++ txwd_info->dword1 = rtw89_build_txwd_info1(desc_info); ++ txwd_info->dword2 = rtw89_build_txwd_info2(desc_info); ++ txwd_info->dword4 = rtw89_build_txwd_info4(desc_info); ++ ++} ++EXPORT_SYMBOL(rtw89_core_fill_txdesc); ++ ++static int rtw89_core_rx_process_mac_ppdu(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb, ++ struct rtw89_rx_phy_ppdu *phy_ppdu) ++{ ++ bool rx_cnt_valid = false; ++ u8 plcp_size = 0; ++ u8 usr_num = 0; ++ u8 *phy_sts; ++ ++ rx_cnt_valid = RTW89_GET_RXINFO_RX_CNT_VLD(skb->data); ++ plcp_size = RTW89_GET_RXINFO_PLCP_LEN(skb->data) << 3; ++ usr_num = RTW89_GET_RXINFO_USR_NUM(skb->data); ++ if (usr_num > RTW89_PPDU_MAX_USR) { ++ rtw89_warn(rtwdev, "Invalid user number in mac info\n"); ++ return -EINVAL; ++ } ++ ++ phy_sts = skb->data + RTW89_PPDU_MAC_INFO_SIZE; ++ phy_sts += usr_num * RTW89_PPDU_MAC_INFO_USR_SIZE; ++ /* 8-byte alignment */ ++ if (usr_num & BIT(0)) ++ phy_sts += RTW89_PPDU_MAC_INFO_USR_SIZE; ++ if (rx_cnt_valid) ++ phy_sts += RTW89_PPDU_MAC_RX_CNT_SIZE; ++ phy_sts += plcp_size; ++ ++ phy_ppdu->buf = phy_sts; ++ phy_ppdu->len = skb->data + skb->len - phy_sts; ++ ++ return 0; ++} ++ ++static void rtw89_core_rx_process_phy_ppdu_iter(void *data, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_rx_phy_ppdu *phy_ppdu = (struct rtw89_rx_phy_ppdu *)data; ++ ++ if (rtwsta->mac_id == phy_ppdu->mac_id && phy_ppdu->to_self) ++ ewma_rssi_add(&rtwsta->avg_rssi, phy_ppdu->rssi_avg); ++} ++ ++#define VAR_LEN 0xff ++#define VAR_LEN_UNIT 8 ++static u16 rtw89_core_get_phy_status_ie_len(struct rtw89_dev *rtwdev, u8 *addr) ++{ ++ static const u8 physts_ie_len_tab[32] = { ++ 16, 32, 24, 24, 8, 8, 8, 8, VAR_LEN, 8, VAR_LEN, 176, VAR_LEN, ++ VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, 16, 24, VAR_LEN, ++ VAR_LEN, VAR_LEN, 0, 24, 24, 24, 24, 32, 32, 32, 32 ++ }; ++ u16 ie_len; ++ u8 ie; ++ ++ ie = RTW89_GET_PHY_STS_IE_TYPE(addr); ++ if (physts_ie_len_tab[ie] != VAR_LEN) ++ ie_len = physts_ie_len_tab[ie]; ++ else ++ ie_len = RTW89_GET_PHY_STS_IE_LEN(addr) * VAR_LEN_UNIT; ++ ++ return ie_len; ++} ++ ++static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev, u8 *addr, ++ struct rtw89_rx_phy_ppdu *phy_ppdu) ++{ ++ s16 cfo; ++ ++ /* sign conversion for S(12,2) */ ++ cfo = sign_extend32(RTW89_GET_PHY_STS_IE0_CFO(addr), 11); ++ rtw89_phy_cfo_parse(rtwdev, cfo, phy_ppdu); ++} ++ ++static int rtw89_core_process_phy_status_ie(struct rtw89_dev *rtwdev, u8 *addr, ++ struct rtw89_rx_phy_ppdu *phy_ppdu) ++{ ++ u8 ie; ++ ++ ie = RTW89_GET_PHY_STS_IE_TYPE(addr); ++ switch (ie) { ++ case RTW89_PHYSTS_IE01_CMN_OFDM: ++ rtw89_core_parse_phy_status_ie01(rtwdev, addr, phy_ppdu); ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++static void rtw89_core_update_phy_ppdu(struct rtw89_rx_phy_ppdu *phy_ppdu) ++{ ++ s8 *rssi = phy_ppdu->rssi; ++ u8 *buf = phy_ppdu->buf; ++ ++ phy_ppdu->rssi_avg = RTW89_GET_PHY_STS_RSSI_AVG(buf); ++ rssi[RF_PATH_A] = RTW89_RSSI_RAW_TO_DBM(RTW89_GET_PHY_STS_RSSI_A(buf)); ++ rssi[RF_PATH_B] = RTW89_RSSI_RAW_TO_DBM(RTW89_GET_PHY_STS_RSSI_B(buf)); ++ rssi[RF_PATH_C] = RTW89_RSSI_RAW_TO_DBM(RTW89_GET_PHY_STS_RSSI_C(buf)); ++ rssi[RF_PATH_D] = RTW89_RSSI_RAW_TO_DBM(RTW89_GET_PHY_STS_RSSI_D(buf)); ++} ++ ++static int rtw89_core_rx_process_phy_ppdu(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_phy_ppdu *phy_ppdu) ++{ ++ if (RTW89_GET_PHY_STS_LEN(phy_ppdu->buf) << 3 != phy_ppdu->len) { ++ rtw89_warn(rtwdev, "phy ppdu len mismatch\n"); ++ return -EINVAL; ++ } ++ rtw89_core_update_phy_ppdu(phy_ppdu); ++ ieee80211_iterate_stations_atomic(rtwdev->hw, ++ rtw89_core_rx_process_phy_ppdu_iter, ++ phy_ppdu); ++ ++ return 0; ++} ++ ++static int rtw89_core_rx_parse_phy_sts(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_phy_ppdu *phy_ppdu) ++{ ++ u16 ie_len; ++ u8 *pos, *end; ++ ++ if (!phy_ppdu->to_self) ++ return 0; ++ ++ pos = (u8 *)phy_ppdu->buf + PHY_STS_HDR_LEN; ++ end = (u8 *)phy_ppdu->buf + phy_ppdu->len; ++ while (pos < end) { ++ ie_len = rtw89_core_get_phy_status_ie_len(rtwdev, pos); ++ rtw89_core_process_phy_status_ie(rtwdev, pos, phy_ppdu); ++ pos += ie_len; ++ if (pos > end || ie_len == 0) { ++ rtw89_debug(rtwdev, RTW89_DBG_TXRX, ++ "phy status parse failed\n"); ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ ++static void rtw89_core_rx_process_phy_sts(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_phy_ppdu *phy_ppdu) ++{ ++ int ret; ++ ++ ret = rtw89_core_rx_parse_phy_sts(rtwdev, phy_ppdu); ++ if (ret) ++ rtw89_debug(rtwdev, RTW89_DBG_TXRX, "parse phy sts failed\n"); ++ else ++ phy_ppdu->valid = true; ++} ++ ++static u8 rtw89_rxdesc_to_nl_he_gi(struct rtw89_dev *rtwdev, ++ const struct rtw89_rx_desc_info *desc_info, ++ bool rx_status) ++{ ++ switch (desc_info->gi_ltf) { ++ case RTW89_GILTF_SGI_4XHE08: ++ case RTW89_GILTF_2XHE08: ++ case RTW89_GILTF_1XHE08: ++ return NL80211_RATE_INFO_HE_GI_0_8; ++ case RTW89_GILTF_2XHE16: ++ case RTW89_GILTF_1XHE16: ++ return NL80211_RATE_INFO_HE_GI_1_6; ++ case RTW89_GILTF_LGI_4XHE32: ++ return NL80211_RATE_INFO_HE_GI_3_2; ++ default: ++ rtw89_warn(rtwdev, "invalid gi_ltf=%d", desc_info->gi_ltf); ++ return rx_status ? NL80211_RATE_INFO_HE_GI_3_2 : U8_MAX; ++ } ++} ++ ++static bool rtw89_core_rx_ppdu_match(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_desc_info *desc_info, ++ struct ieee80211_rx_status *status) ++{ ++ u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; ++ u8 data_rate_mode, bw, rate_idx = MASKBYTE0, gi_ltf; ++ u16 data_rate; ++ bool ret; ++ ++ data_rate = desc_info->data_rate; ++ data_rate_mode = GET_DATA_RATE_MODE(data_rate); ++ if (data_rate_mode == DATA_RATE_MODE_NON_HT) { ++ rate_idx = GET_DATA_RATE_NOT_HT_IDX(data_rate); ++ /* No 4 CCK rates for 5G */ ++ if (status->band == NL80211_BAND_5GHZ) ++ rate_idx -= 4; ++ } else if (data_rate_mode == DATA_RATE_MODE_HT) { ++ rate_idx = GET_DATA_RATE_HT_IDX(data_rate); ++ } else if (data_rate_mode == DATA_RATE_MODE_VHT) { ++ rate_idx = GET_DATA_RATE_VHT_HE_IDX(data_rate); ++ } else if (data_rate_mode == DATA_RATE_MODE_HE) { ++ rate_idx = GET_DATA_RATE_VHT_HE_IDX(data_rate); ++ } else { ++ rtw89_warn(rtwdev, "invalid RX rate mode %d\n", data_rate_mode); ++ } ++ ++ if (desc_info->bw == RTW89_CHANNEL_WIDTH_80) ++ bw = RATE_INFO_BW_80; ++ else if (desc_info->bw == RTW89_CHANNEL_WIDTH_40) ++ bw = RATE_INFO_BW_40; ++ else ++ bw = RATE_INFO_BW_20; ++ ++ gi_ltf = rtw89_rxdesc_to_nl_he_gi(rtwdev, desc_info, false); ++ ret = rtwdev->ppdu_sts.curr_rx_ppdu_cnt[band] == desc_info->ppdu_cnt && ++ status->rate_idx == rate_idx && ++ status->he_gi == gi_ltf && ++ status->bw == bw; ++ ++ return ret; ++} ++ ++struct rtw89_vif_rx_stats_iter_data { ++ struct rtw89_dev *rtwdev; ++ struct rtw89_rx_phy_ppdu *phy_ppdu; ++ struct rtw89_rx_desc_info *desc_info; ++ struct sk_buff *skb; ++ const u8 *bssid; ++}; ++ ++static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, ++ struct ieee80211_vif *vif) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ struct rtw89_vif_rx_stats_iter_data *iter_data = data; ++ struct rtw89_dev *rtwdev = iter_data->rtwdev; ++ struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.cur_pkt_stat; ++ struct rtw89_rx_desc_info *desc_info = iter_data->desc_info; ++ struct sk_buff *skb = iter_data->skb; ++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; ++ const u8 *bssid = iter_data->bssid; ++ ++ if (!ether_addr_equal(vif->bss_conf.bssid, bssid)) ++ return; ++ ++ if (ieee80211_is_beacon(hdr->frame_control)) ++ pkt_stat->beacon_nr++; ++ ++ if (!ether_addr_equal(vif->addr, hdr->addr1)) ++ return; ++ ++ if (desc_info->data_rate < RTW89_HW_RATE_NR) ++ pkt_stat->rx_rate_cnt[desc_info->data_rate]++; ++ ++ rtw89_traffic_stats_accu(rtwdev, &rtwvif->stats, skb, false); ++} ++ ++static void rtw89_core_rx_stats(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_phy_ppdu *phy_ppdu, ++ struct rtw89_rx_desc_info *desc_info, ++ struct sk_buff *skb) ++{ ++ struct rtw89_vif_rx_stats_iter_data iter_data; ++ ++ rtw89_traffic_stats_accu(rtwdev, &rtwdev->stats, skb, false); ++ ++ iter_data.rtwdev = rtwdev; ++ iter_data.phy_ppdu = phy_ppdu; ++ iter_data.desc_info = desc_info; ++ iter_data.skb = skb; ++ iter_data.bssid = get_hdr_bssid((struct ieee80211_hdr *)skb->data); ++ rtw89_iterate_vifs_bh(rtwdev, rtw89_vif_rx_stats_iter, &iter_data); ++} ++ ++static void rtw89_core_rx_pending_skb(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_phy_ppdu *phy_ppdu, ++ struct rtw89_rx_desc_info *desc_info, ++ struct sk_buff *skb) ++{ ++ u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; ++ int curr = rtwdev->ppdu_sts.curr_rx_ppdu_cnt[band]; ++ struct sk_buff *skb_ppdu = NULL, *tmp; ++ struct ieee80211_rx_status *rx_status; ++ ++ if (curr > RTW89_MAX_PPDU_CNT) ++ return; ++ ++ skb_queue_walk_safe(&rtwdev->ppdu_sts.rx_queue[band], skb_ppdu, tmp) { ++ skb_unlink(skb_ppdu, &rtwdev->ppdu_sts.rx_queue[band]); ++ rx_status = IEEE80211_SKB_RXCB(skb_ppdu); ++ if (rtw89_core_rx_ppdu_match(rtwdev, desc_info, rx_status)) ++ rtw89_chip_query_ppdu(rtwdev, phy_ppdu, rx_status); ++ rtw89_core_rx_stats(rtwdev, phy_ppdu, desc_info, skb_ppdu); ++ ieee80211_rx_napi(rtwdev->hw, NULL, skb_ppdu, &rtwdev->napi); ++ rtwdev->napi_budget_countdown--; ++ } ++} ++ ++static void rtw89_core_rx_process_ppdu_sts(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_desc_info *desc_info, ++ struct sk_buff *skb) ++{ ++ struct rtw89_rx_phy_ppdu phy_ppdu = {.buf = skb->data, .valid = false, ++ .len = skb->len, ++ .to_self = desc_info->addr1_match, ++ .mac_id = desc_info->mac_id}; ++ int ret; ++ ++ if (desc_info->mac_info_valid) ++ rtw89_core_rx_process_mac_ppdu(rtwdev, skb, &phy_ppdu); ++ ret = rtw89_core_rx_process_phy_ppdu(rtwdev, &phy_ppdu); ++ if (ret) ++ rtw89_debug(rtwdev, RTW89_DBG_TXRX, "process ppdu failed\n"); ++ ++ rtw89_core_rx_process_phy_sts(rtwdev, &phy_ppdu); ++ rtw89_core_rx_pending_skb(rtwdev, &phy_ppdu, desc_info, skb); ++ dev_kfree_skb_any(skb); ++} ++ ++static void rtw89_core_rx_process_report(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_desc_info *desc_info, ++ struct sk_buff *skb) ++{ ++ switch (desc_info->pkt_type) { ++ case RTW89_CORE_RX_TYPE_C2H: ++ rtw89_fw_c2h_irqsafe(rtwdev, skb); ++ break; ++ case RTW89_CORE_RX_TYPE_PPDU_STAT: ++ rtw89_core_rx_process_ppdu_sts(rtwdev, desc_info, skb); ++ break; ++ default: ++ rtw89_debug(rtwdev, RTW89_DBG_TXRX, "unhandled pkt_type=%d\n", ++ desc_info->pkt_type); ++ dev_kfree_skb_any(skb); ++ break; ++ } ++} ++ ++void rtw89_core_query_rxdesc(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_desc_info *desc_info, ++ u8 *data, u32 data_offset) ++{ ++ struct rtw89_rxdesc_short *rxd_s; ++ struct rtw89_rxdesc_long *rxd_l; ++ u8 shift_len, drv_info_len; ++ ++ rxd_s = (struct rtw89_rxdesc_short *)(data + data_offset); ++ desc_info->pkt_size = RTW89_GET_RXWD_PKT_SIZE(rxd_s); ++ desc_info->drv_info_size = RTW89_GET_RXWD_DRV_INFO_SIZE(rxd_s); ++ desc_info->long_rxdesc = RTW89_GET_RXWD_LONG_RXD(rxd_s); ++ desc_info->pkt_type = RTW89_GET_RXWD_RPKT_TYPE(rxd_s); ++ desc_info->mac_info_valid = RTW89_GET_RXWD_MAC_INFO_VALID(rxd_s); ++ desc_info->bw = RTW89_GET_RXWD_BW(rxd_s); ++ desc_info->data_rate = RTW89_GET_RXWD_DATA_RATE(rxd_s); ++ desc_info->gi_ltf = RTW89_GET_RXWD_GI_LTF(rxd_s); ++ desc_info->user_id = RTW89_GET_RXWD_USER_ID(rxd_s); ++ desc_info->sr_en = RTW89_GET_RXWD_SR_EN(rxd_s); ++ desc_info->ppdu_cnt = RTW89_GET_RXWD_PPDU_CNT(rxd_s); ++ desc_info->ppdu_type = RTW89_GET_RXWD_PPDU_TYPE(rxd_s); ++ desc_info->free_run_cnt = RTW89_GET_RXWD_FREE_RUN_CNT(rxd_s); ++ desc_info->icv_err = RTW89_GET_RXWD_ICV_ERR(rxd_s); ++ desc_info->crc32_err = RTW89_GET_RXWD_CRC32_ERR(rxd_s); ++ desc_info->hw_dec = RTW89_GET_RXWD_HW_DEC(rxd_s); ++ desc_info->sw_dec = RTW89_GET_RXWD_SW_DEC(rxd_s); ++ desc_info->addr1_match = RTW89_GET_RXWD_A1_MATCH(rxd_s); ++ ++ shift_len = desc_info->shift << 1; /* 2-byte unit */ ++ drv_info_len = desc_info->drv_info_size << 3; /* 8-byte unit */ ++ desc_info->offset = data_offset + shift_len + drv_info_len; ++ desc_info->ready = true; ++ ++ if (!desc_info->long_rxdesc) ++ return; ++ ++ rxd_l = (struct rtw89_rxdesc_long *)(data + data_offset); ++ desc_info->frame_type = RTW89_GET_RXWD_TYPE(rxd_l); ++ desc_info->addr_cam_valid = RTW89_GET_RXWD_ADDR_CAM_VLD(rxd_l); ++ desc_info->addr_cam_id = RTW89_GET_RXWD_ADDR_CAM_ID(rxd_l); ++ desc_info->sec_cam_id = RTW89_GET_RXWD_SEC_CAM_ID(rxd_l); ++ desc_info->mac_id = RTW89_GET_RXWD_MAC_ID(rxd_l); ++ desc_info->rx_pl_id = RTW89_GET_RXWD_RX_PL_ID(rxd_l); ++} ++EXPORT_SYMBOL(rtw89_core_query_rxdesc); ++ ++struct rtw89_core_iter_rx_status { ++ struct rtw89_dev *rtwdev; ++ struct ieee80211_rx_status *rx_status; ++ struct rtw89_rx_desc_info *desc_info; ++ u8 mac_id; ++}; ++ ++static ++void rtw89_core_stats_sta_rx_status_iter(void *data, struct ieee80211_sta *sta) ++{ ++ struct rtw89_core_iter_rx_status *iter_data = ++ (struct rtw89_core_iter_rx_status *)data; ++ struct ieee80211_rx_status *rx_status = iter_data->rx_status; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_rx_desc_info *desc_info = iter_data->desc_info; ++ u8 mac_id = iter_data->mac_id; ++ ++ if (mac_id != rtwsta->mac_id) ++ return; ++ ++ rtwsta->rx_status = *rx_status; ++ rtwsta->rx_hw_rate = desc_info->data_rate; ++} ++ ++static void rtw89_core_stats_sta_rx_status(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_desc_info *desc_info, ++ struct ieee80211_rx_status *rx_status) ++{ ++ struct rtw89_core_iter_rx_status iter_data; ++ ++ if (!desc_info->addr1_match || !desc_info->long_rxdesc) ++ return; ++ ++ if (desc_info->frame_type != RTW89_RX_TYPE_DATA) ++ return; ++ ++ iter_data.rtwdev = rtwdev; ++ iter_data.rx_status = rx_status; ++ iter_data.desc_info = desc_info; ++ iter_data.mac_id = desc_info->mac_id; ++ ieee80211_iterate_stations_atomic(rtwdev->hw, ++ rtw89_core_stats_sta_rx_status_iter, ++ &iter_data); ++} ++ ++static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_desc_info *desc_info, ++ struct ieee80211_rx_status *rx_status) ++{ ++ struct ieee80211_hw *hw = rtwdev->hw; ++ u16 data_rate; ++ u8 data_rate_mode; ++ ++ /* currently using single PHY */ ++ rx_status->freq = hw->conf.chandef.chan->center_freq; ++ rx_status->band = hw->conf.chandef.chan->band; ++ ++ if (desc_info->icv_err || desc_info->crc32_err) ++ rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; ++ ++ if (desc_info->hw_dec && ++ !(desc_info->sw_dec || desc_info->icv_err)) ++ rx_status->flag |= RX_FLAG_DECRYPTED; ++ ++ if (desc_info->bw == RTW89_CHANNEL_WIDTH_80) ++ rx_status->bw = RATE_INFO_BW_80; ++ else if (desc_info->bw == RTW89_CHANNEL_WIDTH_40) ++ rx_status->bw = RATE_INFO_BW_40; ++ else ++ rx_status->bw = RATE_INFO_BW_20; ++ ++ data_rate = desc_info->data_rate; ++ data_rate_mode = GET_DATA_RATE_MODE(data_rate); ++ if (data_rate_mode == DATA_RATE_MODE_NON_HT) { ++ rx_status->encoding = RX_ENC_LEGACY; ++ rx_status->rate_idx = GET_DATA_RATE_NOT_HT_IDX(data_rate); ++ /* No 4 CCK rates for 5G */ ++ if (rx_status->band == NL80211_BAND_5GHZ) ++ rx_status->rate_idx -= 4; ++ if (rtwdev->scanning) ++ rx_status->rate_idx = min_t(u8, rx_status->rate_idx, ++ ARRAY_SIZE(rtw89_bitrates) - 5); ++ } else if (data_rate_mode == DATA_RATE_MODE_HT) { ++ rx_status->encoding = RX_ENC_HT; ++ rx_status->rate_idx = GET_DATA_RATE_HT_IDX(data_rate); ++ if (desc_info->gi_ltf) ++ rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; ++ } else if (data_rate_mode == DATA_RATE_MODE_VHT) { ++ rx_status->encoding = RX_ENC_VHT; ++ rx_status->rate_idx = GET_DATA_RATE_VHT_HE_IDX(data_rate); ++ rx_status->nss = GET_DATA_RATE_NSS(data_rate) + 1; ++ if (desc_info->gi_ltf) ++ rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; ++ } else if (data_rate_mode == DATA_RATE_MODE_HE) { ++ rx_status->encoding = RX_ENC_HE; ++ rx_status->rate_idx = GET_DATA_RATE_VHT_HE_IDX(data_rate); ++ rx_status->nss = GET_DATA_RATE_NSS(data_rate) + 1; ++ } else { ++ rtw89_warn(rtwdev, "invalid RX rate mode %d\n", data_rate_mode); ++ } ++ ++ /* he_gi is used to match ppdu, so we always fill it. */ ++ rx_status->he_gi = rtw89_rxdesc_to_nl_he_gi(rtwdev, desc_info, true); ++ rx_status->flag |= RX_FLAG_MACTIME_START; ++ rx_status->mactime = desc_info->free_run_cnt; ++ ++ rtw89_core_stats_sta_rx_status(rtwdev, desc_info, rx_status); ++} ++ ++static enum rtw89_ps_mode rtw89_update_ps_mode(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (rtw89_disable_ps_mode || !chip->ps_mode_supported) ++ return RTW89_PS_MODE_NONE; ++ ++ if (chip->ps_mode_supported & BIT(RTW89_PS_MODE_PWR_GATED)) ++ return RTW89_PS_MODE_PWR_GATED; ++ ++ if (chip->ps_mode_supported & BIT(RTW89_PS_MODE_CLK_GATED)) ++ return RTW89_PS_MODE_CLK_GATED; ++ ++ if (chip->ps_mode_supported & BIT(RTW89_PS_MODE_RFOFF)) ++ return RTW89_PS_MODE_RFOFF; ++ ++ return RTW89_PS_MODE_NONE; ++} ++ ++static void rtw89_core_flush_ppdu_rx_queue(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_desc_info *desc_info) ++{ ++ struct rtw89_ppdu_sts_info *ppdu_sts = &rtwdev->ppdu_sts; ++ u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; ++ struct sk_buff *skb_ppdu, *tmp; ++ ++ skb_queue_walk_safe(&ppdu_sts->rx_queue[band], skb_ppdu, tmp) { ++ skb_unlink(skb_ppdu, &ppdu_sts->rx_queue[band]); ++ rtw89_core_rx_stats(rtwdev, NULL, desc_info, skb_ppdu); ++ ieee80211_rx_napi(rtwdev->hw, NULL, skb_ppdu, &rtwdev->napi); ++ rtwdev->napi_budget_countdown--; ++ } ++} ++ ++void rtw89_core_rx(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_desc_info *desc_info, ++ struct sk_buff *skb) ++{ ++ struct ieee80211_rx_status *rx_status; ++ struct rtw89_ppdu_sts_info *ppdu_sts = &rtwdev->ppdu_sts; ++ u8 ppdu_cnt = desc_info->ppdu_cnt; ++ u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0; ++ ++ if (desc_info->pkt_type != RTW89_CORE_RX_TYPE_WIFI) { ++ rtw89_core_rx_process_report(rtwdev, desc_info, skb); ++ return; ++ } ++ ++ if (ppdu_sts->curr_rx_ppdu_cnt[band] != ppdu_cnt) { ++ rtw89_core_flush_ppdu_rx_queue(rtwdev, desc_info); ++ ppdu_sts->curr_rx_ppdu_cnt[band] = ppdu_cnt; ++ } ++ ++ rx_status = IEEE80211_SKB_RXCB(skb); ++ memset(rx_status, 0, sizeof(*rx_status)); ++ rtw89_core_update_rx_status(rtwdev, desc_info, rx_status); ++ if (desc_info->long_rxdesc && ++ BIT(desc_info->frame_type) & PPDU_FILTER_BITMAP) { ++ skb_queue_tail(&ppdu_sts->rx_queue[band], skb); ++ } else { ++ rtw89_core_rx_stats(rtwdev, NULL, desc_info, skb); ++ ieee80211_rx_napi(rtwdev->hw, NULL, skb, &rtwdev->napi); ++ rtwdev->napi_budget_countdown--; ++ } ++} ++EXPORT_SYMBOL(rtw89_core_rx); ++ ++void rtw89_core_napi_start(struct rtw89_dev *rtwdev) ++{ ++ if (test_and_set_bit(RTW89_FLAG_NAPI_RUNNING, rtwdev->flags)) ++ return; ++ ++ napi_enable(&rtwdev->napi); ++} ++EXPORT_SYMBOL(rtw89_core_napi_start); ++ ++void rtw89_core_napi_stop(struct rtw89_dev *rtwdev) ++{ ++ if (!test_and_clear_bit(RTW89_FLAG_NAPI_RUNNING, rtwdev->flags)) ++ return; ++ ++ napi_synchronize(&rtwdev->napi); ++ napi_disable(&rtwdev->napi); ++} ++EXPORT_SYMBOL(rtw89_core_napi_stop); ++ ++void rtw89_core_napi_init(struct rtw89_dev *rtwdev) ++{ ++ init_dummy_netdev(&rtwdev->netdev); ++ netif_napi_add(&rtwdev->netdev, &rtwdev->napi, ++ rtwdev->hci.ops->napi_poll, NAPI_POLL_WEIGHT); ++} ++EXPORT_SYMBOL(rtw89_core_napi_init); ++ ++void rtw89_core_napi_deinit(struct rtw89_dev *rtwdev) ++{ ++ rtw89_core_napi_stop(rtwdev); ++ netif_napi_del(&rtwdev->napi); ++} ++EXPORT_SYMBOL(rtw89_core_napi_deinit); ++ ++static void rtw89_core_ba_work(struct work_struct *work) ++{ ++ struct rtw89_dev *rtwdev = ++ container_of(work, struct rtw89_dev, ba_work); ++ struct rtw89_txq *rtwtxq, *tmp; ++ int ret; ++ ++ spin_lock_bh(&rtwdev->ba_lock); ++ list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->ba_list, list) { ++ struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); ++ struct ieee80211_sta *sta = txq->sta; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ u8 tid = txq->tid; ++ ++ if (!sta) { ++ rtw89_warn(rtwdev, "cannot start BA without sta\n"); ++ goto skip_ba_work; ++ } ++ ++ if (rtwsta->disassoc) { ++ rtw89_debug(rtwdev, RTW89_DBG_TXRX, ++ "cannot start BA with disassoc sta\n"); ++ goto skip_ba_work; ++ } ++ ++ ret = ieee80211_start_tx_ba_session(sta, tid, 0); ++ if (ret) { ++ rtw89_debug(rtwdev, RTW89_DBG_TXRX, ++ "failed to setup BA session for %pM:%2d: %d\n", ++ sta->addr, tid, ret); ++ if (ret == -EINVAL) ++ set_bit(RTW89_TXQ_F_BLOCK_BA, &rtwtxq->flags); ++ } ++skip_ba_work: ++ list_del_init(&rtwtxq->list); ++ } ++ spin_unlock_bh(&rtwdev->ba_lock); ++} ++ ++static void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_txq *rtwtxq, *tmp; ++ ++ spin_lock_bh(&rtwdev->ba_lock); ++ list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->ba_list, list) { ++ struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); ++ ++ if (sta == txq->sta) ++ list_del_init(&rtwtxq->list); ++ } ++ spin_unlock_bh(&rtwdev->ba_lock); ++} ++ ++static void rtw89_core_txq_check_agg(struct rtw89_dev *rtwdev, ++ struct rtw89_txq *rtwtxq, ++ struct sk_buff *skb) ++{ ++ struct ieee80211_hw *hw = rtwdev->hw; ++ struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); ++ struct ieee80211_sta *sta = txq->sta; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ ++ if (unlikely(skb_get_queue_mapping(skb) == IEEE80211_AC_VO)) ++ return; ++ ++ if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) ++ return; ++ ++ if (unlikely(!sta)) ++ return; ++ ++ if (unlikely(test_bit(RTW89_TXQ_F_BLOCK_BA, &rtwtxq->flags))) ++ return; ++ ++ if (test_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags)) { ++ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_AMPDU; ++ return; ++ } ++ ++ spin_lock_bh(&rtwdev->ba_lock); ++ if (!rtwsta->disassoc && list_empty(&rtwtxq->list)) { ++ list_add_tail(&rtwtxq->list, &rtwdev->ba_list); ++ ieee80211_queue_work(hw, &rtwdev->ba_work); ++ } ++ spin_unlock_bh(&rtwdev->ba_lock); ++} ++ ++static void rtw89_core_txq_push(struct rtw89_dev *rtwdev, ++ struct rtw89_txq *rtwtxq, ++ unsigned long frame_cnt, ++ unsigned long byte_cnt) ++{ ++ struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); ++ struct ieee80211_vif *vif = txq->vif; ++ struct ieee80211_sta *sta = txq->sta; ++ struct sk_buff *skb; ++ unsigned long i; ++ int ret; ++ ++ for (i = 0; i < frame_cnt; i++) { ++ skb = ieee80211_tx_dequeue_ni(rtwdev->hw, txq); ++ if (!skb) { ++ rtw89_debug(rtwdev, RTW89_DBG_TXRX, "dequeue a NULL skb\n"); ++ return; ++ } ++ rtw89_core_txq_check_agg(rtwdev, rtwtxq, skb); ++ ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, NULL); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to push txq: %d\n", ret); ++ ieee80211_free_txskb(rtwdev->hw, skb); ++ break; ++ } ++ } ++} ++ ++static u32 rtw89_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, u8 tid) ++{ ++ u8 qsel, ch_dma; ++ ++ qsel = rtw89_core_get_qsel(rtwdev, tid); ++ ch_dma = rtw89_core_get_ch_dma(rtwdev, qsel); ++ ++ return rtw89_hci_check_and_reclaim_tx_resource(rtwdev, ch_dma); ++} ++ ++static bool rtw89_core_txq_agg_wait(struct rtw89_dev *rtwdev, ++ struct ieee80211_txq *txq, ++ unsigned long *frame_cnt, ++ bool *sched_txq, bool *reinvoke) ++{ ++ struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv; ++ struct ieee80211_sta *sta = txq->sta; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ ++ if (!sta || rtwsta->max_agg_wait <= 0) ++ return false; ++ ++ if (rtwdev->stats.tx_tfc_lv <= RTW89_TFC_MID) ++ return false; ++ ++ if (*frame_cnt > 1) { ++ *frame_cnt -= 1; ++ *sched_txq = true; ++ *reinvoke = true; ++ rtwtxq->wait_cnt = 1; ++ return false; ++ } ++ ++ if (*frame_cnt == 1 && rtwtxq->wait_cnt < rtwsta->max_agg_wait) { ++ *reinvoke = true; ++ rtwtxq->wait_cnt++; ++ return true; ++ } ++ ++ rtwtxq->wait_cnt = 0; ++ return false; ++} ++ ++static void rtw89_core_txq_schedule(struct rtw89_dev *rtwdev, u8 ac, bool *reinvoke) ++{ ++ struct ieee80211_hw *hw = rtwdev->hw; ++ struct ieee80211_txq *txq; ++ struct rtw89_txq *rtwtxq; ++ unsigned long frame_cnt; ++ unsigned long byte_cnt; ++ u32 tx_resource; ++ bool sched_txq; ++ ++ ieee80211_txq_schedule_start(hw, ac); ++ while ((txq = ieee80211_next_txq(hw, ac))) { ++ rtwtxq = (struct rtw89_txq *)txq->drv_priv; ++ tx_resource = rtw89_check_and_reclaim_tx_resource(rtwdev, txq->tid); ++ sched_txq = false; ++ ++ ieee80211_txq_get_depth(txq, &frame_cnt, &byte_cnt); ++ if (rtw89_core_txq_agg_wait(rtwdev, txq, &frame_cnt, &sched_txq, reinvoke)) { ++ ieee80211_return_txq(hw, txq, true); ++ continue; ++ } ++ frame_cnt = min_t(unsigned long, frame_cnt, tx_resource); ++ rtw89_core_txq_push(rtwdev, rtwtxq, frame_cnt, byte_cnt); ++ ieee80211_return_txq(hw, txq, sched_txq); ++ if (frame_cnt != 0) ++ rtw89_core_tx_kick_off(rtwdev, rtw89_core_get_qsel(rtwdev, txq->tid)); ++ } ++ ieee80211_txq_schedule_end(hw, ac); ++} ++ ++static void rtw89_core_txq_work(struct work_struct *w) ++{ ++ struct rtw89_dev *rtwdev = container_of(w, struct rtw89_dev, txq_work); ++ bool reinvoke = false; ++ u8 ac; ++ ++ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) ++ rtw89_core_txq_schedule(rtwdev, ac, &reinvoke); ++ ++ if (reinvoke) { ++ /* reinvoke to process the last frame */ ++ mod_delayed_work(rtwdev->txq_wq, &rtwdev->txq_reinvoke_work, 1); ++ } ++} ++ ++static void rtw89_core_txq_reinvoke_work(struct work_struct *w) ++{ ++ struct rtw89_dev *rtwdev = container_of(w, struct rtw89_dev, ++ txq_reinvoke_work.work); ++ ++ queue_work(rtwdev->txq_wq, &rtwdev->txq_work); ++} ++ ++static enum rtw89_tfc_lv rtw89_get_traffic_level(struct rtw89_dev *rtwdev, ++ u32 throughput, u64 cnt) ++{ ++ if (cnt < 100) ++ return RTW89_TFC_IDLE; ++ if (throughput > 50) ++ return RTW89_TFC_HIGH; ++ if (throughput > 10) ++ return RTW89_TFC_MID; ++ if (throughput > 2) ++ return RTW89_TFC_LOW; ++ return RTW89_TFC_ULTRA_LOW; ++} ++ ++static bool rtw89_traffic_stats_calc(struct rtw89_dev *rtwdev, ++ struct rtw89_traffic_stats *stats) ++{ ++ enum rtw89_tfc_lv tx_tfc_lv = stats->tx_tfc_lv; ++ enum rtw89_tfc_lv rx_tfc_lv = stats->rx_tfc_lv; ++ ++ stats->tx_throughput_raw = (u32)(stats->tx_unicast >> RTW89_TP_SHIFT); ++ stats->rx_throughput_raw = (u32)(stats->rx_unicast >> RTW89_TP_SHIFT); ++ ++ ewma_tp_add(&stats->tx_ewma_tp, stats->tx_throughput_raw); ++ ewma_tp_add(&stats->rx_ewma_tp, stats->rx_throughput_raw); ++ ++ stats->tx_throughput = ewma_tp_read(&stats->tx_ewma_tp); ++ stats->rx_throughput = ewma_tp_read(&stats->rx_ewma_tp); ++ stats->tx_tfc_lv = rtw89_get_traffic_level(rtwdev, stats->tx_throughput, ++ stats->tx_cnt); ++ stats->rx_tfc_lv = rtw89_get_traffic_level(rtwdev, stats->rx_throughput, ++ stats->rx_cnt); ++ stats->tx_avg_len = stats->tx_cnt ? ++ DIV_ROUND_DOWN_ULL(stats->tx_unicast, stats->tx_cnt) : 0; ++ stats->rx_avg_len = stats->rx_cnt ? ++ DIV_ROUND_DOWN_ULL(stats->rx_unicast, stats->rx_cnt) : 0; ++ ++ stats->tx_unicast = 0; ++ stats->rx_unicast = 0; ++ stats->tx_cnt = 0; ++ stats->rx_cnt = 0; ++ ++ if (tx_tfc_lv != stats->tx_tfc_lv || rx_tfc_lv != stats->rx_tfc_lv) ++ return true; ++ ++ return false; ++} ++ ++static bool rtw89_traffic_stats_track(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_vif *rtwvif; ++ bool tfc_changed; ++ ++ tfc_changed = rtw89_traffic_stats_calc(rtwdev, &rtwdev->stats); ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ rtw89_traffic_stats_calc(rtwdev, &rtwvif->stats); ++ ++ return tfc_changed; ++} ++ ++static void rtw89_vif_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION) ++ return; ++ ++ if (rtwvif->stats.tx_tfc_lv == RTW89_TFC_IDLE && ++ rtwvif->stats.rx_tfc_lv == RTW89_TFC_IDLE) ++ rtw89_enter_lps(rtwdev, rtwvif->mac_id); ++} ++ ++static void rtw89_enter_lps_track(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_vif *rtwvif; ++ ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ rtw89_vif_enter_lps(rtwdev, rtwvif); ++} ++ ++void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, ++ struct rtw89_traffic_stats *stats) ++{ ++ stats->tx_unicast = 0; ++ stats->rx_unicast = 0; ++ stats->tx_cnt = 0; ++ stats->rx_cnt = 0; ++ ewma_tp_init(&stats->tx_ewma_tp); ++ ewma_tp_init(&stats->rx_ewma_tp); ++} ++ ++static void rtw89_track_work(struct work_struct *work) ++{ ++ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, ++ track_work.work); ++ bool tfc_changed; ++ ++ mutex_lock(&rtwdev->mutex); ++ ++ if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) ++ goto out; ++ ++ ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work, ++ RTW89_TRACK_WORK_PERIOD); ++ ++ tfc_changed = rtw89_traffic_stats_track(rtwdev); ++ if (rtwdev->scanning) ++ goto out; ++ ++ rtw89_leave_lps(rtwdev); ++ ++ if (tfc_changed) { ++ rtw89_hci_recalc_int_mit(rtwdev); ++ rtw89_btc_ntfy_wl_sta(rtwdev); ++ } ++ rtw89_mac_bf_monitor_track(rtwdev); ++ rtw89_phy_stat_track(rtwdev); ++ rtw89_phy_env_monitor_track(rtwdev); ++ rtw89_phy_dig(rtwdev); ++ rtw89_chip_rfk_track(rtwdev); ++ rtw89_phy_ra_update(rtwdev); ++ rtw89_phy_cfo_track(rtwdev); ++ ++ if (rtwdev->lps_enabled && !rtwdev->btc.lps) ++ rtw89_enter_lps_track(rtwdev); ++ ++out: ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size) ++{ ++ unsigned long bit; ++ ++ bit = find_first_zero_bit(addr, size); ++ if (bit < size) ++ set_bit(bit, addr); ++ ++ return bit; ++} ++ ++void rtw89_core_release_bit_map(unsigned long *addr, u8 bit) ++{ ++ clear_bit(bit, addr); ++} ++ ++void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits) ++{ ++ bitmap_zero(addr, nbits); ++} ++ ++#define RTW89_TYPE_MAPPING(_type) \ ++ case NL80211_IFTYPE_ ## _type: \ ++ rtwvif->wifi_role = RTW89_WIFI_ROLE_ ## _type; \ ++ break ++void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ ++ switch (vif->type) { ++ RTW89_TYPE_MAPPING(ADHOC); ++ RTW89_TYPE_MAPPING(STATION); ++ RTW89_TYPE_MAPPING(AP); ++ RTW89_TYPE_MAPPING(MONITOR); ++ RTW89_TYPE_MAPPING(MESH_POINT); ++ default: ++ WARN_ON(1); ++ break; ++ } ++ ++ switch (vif->type) { ++ case NL80211_IFTYPE_AP: ++ case NL80211_IFTYPE_MESH_POINT: ++ rtwvif->net_type = RTW89_NET_TYPE_AP_MODE; ++ rtwvif->self_role = RTW89_SELF_ROLE_AP; ++ break; ++ case NL80211_IFTYPE_ADHOC: ++ rtwvif->net_type = RTW89_NET_TYPE_AD_HOC; ++ rtwvif->self_role = RTW89_SELF_ROLE_CLIENT; ++ break; ++ case NL80211_IFTYPE_STATION: ++ if (assoc) { ++ rtwvif->net_type = RTW89_NET_TYPE_INFRA; ++ rtwvif->trigger = vif->bss_conf.he_support; ++ } else { ++ rtwvif->net_type = RTW89_NET_TYPE_NO_LINK; ++ rtwvif->trigger = false; ++ } ++ rtwvif->self_role = RTW89_SELF_ROLE_CLIENT; ++ rtwvif->addr_cam.sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL; ++ break; ++ default: ++ WARN_ON(1); ++ break; ++ } ++} ++ ++int rtw89_core_sta_add(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ int i; ++ ++ rtwsta->rtwvif = rtwvif; ++ rtwsta->prev_rssi = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(sta->txq); i++) ++ rtw89_core_txq_init(rtwdev, sta->txq[i]); ++ ++ ewma_rssi_init(&rtwsta->avg_rssi); ++ ++ if (vif->type == NL80211_IFTYPE_STATION) { ++ rtwvif->mgd.ap = sta; ++ rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, ++ BTC_ROLE_MSTS_STA_CONN_START); ++ rtw89_chip_rfk_channel(rtwdev); ++ } ++ ++ return 0; ++} ++ ++int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ ++ rtwdev->total_sta_assoc--; ++ rtwsta->disassoc = true; ++ ++ return 0; ++} ++ ++int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ int ret; ++ ++ rtw89_mac_bf_monitor_calc(rtwdev, sta, true); ++ rtw89_mac_bf_disassoc(rtwdev, vif, sta); ++ rtw89_core_free_sta_pending_ba(rtwdev, sta); ++ ++ rtw89_vif_type_mapping(vif, false); ++ ++ ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, sta); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to send h2c cmac table\n"); ++ return ret; ++ } ++ ++ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, 1); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to send h2c join info\n"); ++ return ret; ++ } ++ ++ /* update cam aid mac_id net_type */ ++ rtw89_fw_h2c_cam(rtwdev, rtwvif); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to send h2c cam\n"); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ int ret; ++ ++ rtw89_vif_type_mapping(vif, true); ++ ++ ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, sta); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to send h2c cmac table\n"); ++ return ret; ++ } ++ ++ /* for station mode, assign the mac_id from itself */ ++ if (vif->type == NL80211_IFTYPE_STATION) ++ rtwsta->mac_id = rtwvif->mac_id; ++ ++ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, 0); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to send h2c join info\n"); ++ return ret; ++ } ++ ++ /* update cam aid mac_id net_type */ ++ rtw89_fw_h2c_cam(rtwdev, rtwvif); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to send h2c cam\n"); ++ return ret; ++ } ++ ++ ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwsta->mac_id); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to send h2c general packet\n"); ++ return ret; ++ } ++ ++ rtwdev->total_sta_assoc++; ++ rtw89_phy_ra_assoc(rtwdev, sta); ++ rtw89_mac_bf_assoc(rtwdev, vif, sta); ++ rtw89_mac_bf_monitor_calc(rtwdev, sta, false); ++ ++ if (vif->type == NL80211_IFTYPE_STATION) { ++ rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, ++ BTC_ROLE_MSTS_STA_CONN_END); ++ rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template); ++ } ++ ++ return ret; ++} ++ ++int rtw89_core_sta_remove(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ ++ if (vif->type == NL80211_IFTYPE_STATION) ++ rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, ++ BTC_ROLE_MSTS_STA_DIS_CONN); ++ ++ return 0; ++} ++ ++static void rtw89_init_ht_cap(struct rtw89_dev *rtwdev, ++ struct ieee80211_sta_ht_cap *ht_cap) ++{ ++ static const __le16 highest[RF_PATH_MAX] = { ++ cpu_to_le16(150), cpu_to_le16(300), cpu_to_le16(450), cpu_to_le16(600), ++ }; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ u8 nss = hal->rx_nss; ++ int i; ++ ++ ht_cap->ht_supported = true; ++ ht_cap->cap = 0; ++ ht_cap->cap |= IEEE80211_HT_CAP_SGI_20 | ++ IEEE80211_HT_CAP_MAX_AMSDU | ++ IEEE80211_HT_CAP_TX_STBC | ++ (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); ++ ht_cap->cap |= IEEE80211_HT_CAP_LDPC_CODING; ++ ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 | ++ IEEE80211_HT_CAP_DSSSCCK40 | ++ IEEE80211_HT_CAP_SGI_40; ++ ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; ++ ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; ++ ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; ++ for (i = 0; i < nss; i++) ++ ht_cap->mcs.rx_mask[i] = 0xFF; ++ ht_cap->mcs.rx_mask[4] = 0x01; ++ ht_cap->mcs.rx_highest = highest[nss - 1]; ++} ++ ++static void rtw89_init_vht_cap(struct rtw89_dev *rtwdev, ++ struct ieee80211_sta_vht_cap *vht_cap) ++{ ++ static const __le16 highest[RF_PATH_MAX] = { ++ cpu_to_le16(433), cpu_to_le16(867), cpu_to_le16(1300), cpu_to_le16(1733), ++ }; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ u16 tx_mcs_map = 0, rx_mcs_map = 0; ++ u8 sts_cap = 3; ++ int i; ++ ++ for (i = 0; i < 8; i++) { ++ if (i < hal->tx_nss) ++ tx_mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); ++ else ++ tx_mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); ++ if (i < hal->rx_nss) ++ rx_mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); ++ else ++ rx_mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); ++ } ++ ++ vht_cap->vht_supported = true; ++ vht_cap->cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | ++ IEEE80211_VHT_CAP_SHORT_GI_80 | ++ IEEE80211_VHT_CAP_RXSTBC_1 | ++ IEEE80211_VHT_CAP_HTC_VHT | ++ IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK | ++ 0; ++ vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; ++ vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; ++ vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE | ++ IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; ++ vht_cap->cap |= sts_cap << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; ++ vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(rx_mcs_map); ++ vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(tx_mcs_map); ++ vht_cap->vht_mcs.rx_highest = highest[hal->rx_nss - 1]; ++ vht_cap->vht_mcs.tx_highest = highest[hal->tx_nss - 1]; ++} ++ ++#define RTW89_SBAND_IFTYPES_NR 2 ++ ++static void rtw89_init_he_cap(struct rtw89_dev *rtwdev, ++ enum nl80211_band band, ++ struct ieee80211_supported_band *sband) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ struct ieee80211_sband_iftype_data *iftype_data; ++ bool no_ng16 = (chip->chip_id == RTL8852A && hal->cv == CHIP_CBV) || ++ (chip->chip_id == RTL8852B && hal->cv == CHIP_CAV); ++ u16 mcs_map = 0; ++ int i; ++ int nss = hal->rx_nss; ++ int idx = 0; ++ ++ iftype_data = kcalloc(RTW89_SBAND_IFTYPES_NR, sizeof(*iftype_data), GFP_KERNEL); ++ if (!iftype_data) ++ return; ++ ++ for (i = 0; i < 8; i++) { ++ if (i < nss) ++ mcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); ++ else ++ mcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); ++ } ++ ++ for (i = 0; i < NUM_NL80211_IFTYPES; i++) { ++ struct ieee80211_sta_he_cap *he_cap; ++ u8 *mac_cap_info; ++ u8 *phy_cap_info; ++ ++ switch (i) { ++ case NL80211_IFTYPE_STATION: ++ case NL80211_IFTYPE_AP: ++ break; ++ default: ++ continue; ++ } ++ ++ if (idx >= RTW89_SBAND_IFTYPES_NR) { ++ rtw89_warn(rtwdev, "run out of iftype_data\n"); ++ break; ++ } ++ ++ iftype_data[idx].types_mask = BIT(i); ++ he_cap = &iftype_data[idx].he_cap; ++ mac_cap_info = he_cap->he_cap_elem.mac_cap_info; ++ phy_cap_info = he_cap->he_cap_elem.phy_cap_info; ++ ++ he_cap->has_he = true; ++ if (i == NL80211_IFTYPE_AP) ++ mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE; ++ if (i == NL80211_IFTYPE_STATION) ++ mac_cap_info[1] = IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US; ++ mac_cap_info[2] = IEEE80211_HE_MAC_CAP2_ALL_ACK | ++ IEEE80211_HE_MAC_CAP2_BSR; ++ mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2; ++ if (i == NL80211_IFTYPE_AP) ++ mac_cap_info[3] |= IEEE80211_HE_MAC_CAP3_OMI_CONTROL; ++ mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_OPS | ++ IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU; ++ if (i == NL80211_IFTYPE_STATION) ++ mac_cap_info[5] = IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX; ++ phy_cap_info[0] = IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G | ++ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; ++ phy_cap_info[1] = IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A | ++ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD | ++ IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US; ++ phy_cap_info[2] = IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US | ++ IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ | ++ IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ | ++ IEEE80211_HE_PHY_CAP2_DOPPLER_TX; ++ phy_cap_info[3] = IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM; ++ if (i == NL80211_IFTYPE_STATION) ++ phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_16_QAM | ++ IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_2; ++ if (i == NL80211_IFTYPE_AP) ++ phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU; ++ phy_cap_info[4] = IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE | ++ IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4; ++ phy_cap_info[5] = no_ng16 ? 0 : ++ IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK | ++ IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK; ++ phy_cap_info[6] = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU | ++ IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | ++ IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB | ++ IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE; ++ phy_cap_info[7] = IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP | ++ IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI | ++ IEEE80211_HE_PHY_CAP7_MAX_NC_1; ++ phy_cap_info[8] = IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI | ++ IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI | ++ IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_996; ++ phy_cap_info[9] = IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM | ++ IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU | ++ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB | ++ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB | ++ IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US; ++ if (i == NL80211_IFTYPE_STATION) ++ phy_cap_info[9] |= IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU; ++ he_cap->he_mcs_nss_supp.rx_mcs_80 = cpu_to_le16(mcs_map); ++ he_cap->he_mcs_nss_supp.tx_mcs_80 = cpu_to_le16(mcs_map); ++ ++ idx++; ++ } ++ ++ sband->iftype_data = iftype_data; ++ sband->n_iftype_data = idx; ++} ++ ++static int rtw89_core_set_supported_band(struct rtw89_dev *rtwdev) ++{ ++ struct ieee80211_hw *hw = rtwdev->hw; ++ struct ieee80211_supported_band *sband_2ghz = NULL, *sband_5ghz = NULL; ++ u32 size = sizeof(struct ieee80211_supported_band); ++ ++ sband_2ghz = kmemdup(&rtw89_sband_2ghz, size, GFP_KERNEL); ++ if (!sband_2ghz) ++ goto err; ++ rtw89_init_ht_cap(rtwdev, &sband_2ghz->ht_cap); ++ rtw89_init_he_cap(rtwdev, NL80211_BAND_2GHZ, sband_2ghz); ++ hw->wiphy->bands[NL80211_BAND_2GHZ] = sband_2ghz; ++ ++ sband_5ghz = kmemdup(&rtw89_sband_5ghz, size, GFP_KERNEL); ++ if (!sband_5ghz) ++ goto err; ++ rtw89_init_ht_cap(rtwdev, &sband_5ghz->ht_cap); ++ rtw89_init_vht_cap(rtwdev, &sband_5ghz->vht_cap); ++ rtw89_init_he_cap(rtwdev, NL80211_BAND_5GHZ, sband_5ghz); ++ hw->wiphy->bands[NL80211_BAND_5GHZ] = sband_5ghz; ++ ++ return 0; ++ ++err: ++ hw->wiphy->bands[NL80211_BAND_2GHZ] = NULL; ++ hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL; ++ if (sband_2ghz) ++ kfree(sband_2ghz->iftype_data); ++ if (sband_5ghz) ++ kfree(sband_5ghz->iftype_data); ++ kfree(sband_2ghz); ++ kfree(sband_5ghz); ++ return -ENOMEM; ++} ++ ++static void rtw89_core_clr_supported_band(struct rtw89_dev *rtwdev) ++{ ++ struct ieee80211_hw *hw = rtwdev->hw; ++ ++ kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]->iftype_data); ++ kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]->iftype_data); ++ kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]); ++ kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]); ++ hw->wiphy->bands[NL80211_BAND_2GHZ] = NULL; ++ hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL; ++} ++ ++static void rtw89_core_ppdu_sts_init(struct rtw89_dev *rtwdev) ++{ ++ int i; ++ ++ for (i = 0; i < RTW89_PHY_MAX; i++) ++ skb_queue_head_init(&rtwdev->ppdu_sts.rx_queue[i]); ++ for (i = 0; i < RTW89_PHY_MAX; i++) ++ rtwdev->ppdu_sts.curr_rx_ppdu_cnt[i] = U8_MAX; ++} ++ ++int rtw89_core_start(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ rtwdev->mac.qta_mode = RTW89_QTA_SCC; ++ ret = rtw89_mac_init(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "mac init fail, ret:%d\n", ret); ++ return ret; ++ } ++ ++ rtw89_btc_ntfy_poweron(rtwdev); ++ ++ /* efuse process */ ++ ++ /* pre-config BB/RF, BB reset/RFC reset */ ++ rtw89_mac_disable_bb_rf(rtwdev); ++ rtw89_mac_enable_bb_rf(rtwdev); ++ rtw89_phy_init_bb_reg(rtwdev); ++ rtw89_phy_init_rf_reg(rtwdev); ++ ++ rtw89_btc_ntfy_init(rtwdev, BTC_MODE_NORMAL); ++ ++ rtw89_phy_dm_init(rtwdev); ++ ++ rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); ++ rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0); ++ ++ ret = rtw89_hci_start(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to start hci\n"); ++ return ret; ++ } ++ ++ ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work, ++ RTW89_TRACK_WORK_PERIOD); ++ ++ set_bit(RTW89_FLAG_RUNNING, rtwdev->flags); ++ ++ rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_ON); ++ rtw89_fw_h2c_fw_log(rtwdev, rtwdev->fw.fw_log_enable); ++ ++ return 0; ++} ++ ++void rtw89_core_stop(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ ++ /* Prvent to stop twice; enter_ips and ops_stop */ ++ if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) ++ return; ++ ++ rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_OFF); ++ ++ clear_bit(RTW89_FLAG_RUNNING, rtwdev->flags); ++ ++ mutex_unlock(&rtwdev->mutex); ++ ++ cancel_work_sync(&rtwdev->c2h_work); ++ cancel_work_sync(&btc->eapol_notify_work); ++ cancel_work_sync(&btc->arp_notify_work); ++ cancel_work_sync(&btc->dhcp_notify_work); ++ cancel_work_sync(&btc->icmp_notify_work); ++ cancel_delayed_work_sync(&rtwdev->txq_reinvoke_work); ++ cancel_delayed_work_sync(&rtwdev->track_work); ++ cancel_delayed_work_sync(&rtwdev->coex_act1_work); ++ cancel_delayed_work_sync(&rtwdev->coex_bt_devinfo_work); ++ cancel_delayed_work_sync(&rtwdev->coex_rfk_chk_work); ++ cancel_delayed_work_sync(&rtwdev->cfo_track_work); ++ ++ mutex_lock(&rtwdev->mutex); ++ ++ rtw89_btc_ntfy_poweroff(rtwdev); ++ rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1, true); ++ rtw89_mac_flush_txq(rtwdev, BIT(rtwdev->hw->queues) - 1, true); ++ rtw89_hci_stop(rtwdev); ++ rtw89_hci_deinit(rtwdev); ++ rtw89_mac_pwr_off(rtwdev); ++ rtw89_hci_reset(rtwdev); ++} ++ ++int rtw89_core_init(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ int ret; ++ ++ INIT_LIST_HEAD(&rtwdev->ba_list); ++ INIT_LIST_HEAD(&rtwdev->rtwvifs_list); ++ INIT_LIST_HEAD(&rtwdev->early_h2c_list); ++ INIT_WORK(&rtwdev->ba_work, rtw89_core_ba_work); ++ INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work); ++ INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work); ++ INIT_DELAYED_WORK(&rtwdev->track_work, rtw89_track_work); ++ INIT_DELAYED_WORK(&rtwdev->coex_act1_work, rtw89_coex_act1_work); ++ INIT_DELAYED_WORK(&rtwdev->coex_bt_devinfo_work, rtw89_coex_bt_devinfo_work); ++ INIT_DELAYED_WORK(&rtwdev->coex_rfk_chk_work, rtw89_coex_rfk_chk_work); ++ INIT_DELAYED_WORK(&rtwdev->cfo_track_work, rtw89_phy_cfo_track_work); ++ rtwdev->txq_wq = alloc_workqueue("rtw89_tx_wq", WQ_UNBOUND | WQ_HIGHPRI, 0); ++ spin_lock_init(&rtwdev->ba_lock); ++ mutex_init(&rtwdev->mutex); ++ mutex_init(&rtwdev->rf_mutex); ++ rtwdev->total_sta_assoc = 0; ++ ++ INIT_WORK(&rtwdev->c2h_work, rtw89_fw_c2h_work); ++ skb_queue_head_init(&rtwdev->c2h_queue); ++ rtw89_core_ppdu_sts_init(rtwdev); ++ rtw89_traffic_stats_init(rtwdev, &rtwdev->stats); ++ ++ rtwdev->ps_mode = rtw89_update_ps_mode(rtwdev); ++ rtwdev->hal.rx_fltr = DEFAULT_AX_RX_FLTR; ++ ++ INIT_WORK(&btc->eapol_notify_work, rtw89_btc_ntfy_eapol_packet_work); ++ INIT_WORK(&btc->arp_notify_work, rtw89_btc_ntfy_arp_packet_work); ++ INIT_WORK(&btc->dhcp_notify_work, rtw89_btc_ntfy_dhcp_packet_work); ++ INIT_WORK(&btc->icmp_notify_work, rtw89_btc_ntfy_icmp_packet_work); ++ ++ ret = rtw89_load_firmware(rtwdev); ++ if (ret) { ++ rtw89_warn(rtwdev, "no firmware loaded\n"); ++ return ret; ++ } ++ rtw89_ser_init(rtwdev); ++ ++ return 0; ++} ++EXPORT_SYMBOL(rtw89_core_init); ++ ++void rtw89_core_deinit(struct rtw89_dev *rtwdev) ++{ ++ rtw89_ser_deinit(rtwdev); ++ rtw89_unload_firmware(rtwdev); ++ rtw89_fw_free_all_early_h2c(rtwdev); ++ ++ destroy_workqueue(rtwdev->txq_wq); ++ mutex_destroy(&rtwdev->rf_mutex); ++ mutex_destroy(&rtwdev->mutex); ++} ++EXPORT_SYMBOL(rtw89_core_deinit); ++ ++static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev) ++{ ++ u8 cv; ++ ++ cv = rtw89_read32_mask(rtwdev, R_AX_SYS_CFG1, B_AX_CHIP_VER_MASK); ++ if (cv <= CHIP_CBV) { ++ if (rtw89_read32(rtwdev, R_AX_GPIO0_7_FUNC_SEL) == RTW89_R32_DEAD) ++ cv = CHIP_CAV; ++ else ++ cv = CHIP_CBV; ++ } ++ ++ rtwdev->hal.cv = cv; ++} ++ ++static int rtw89_chip_efuse_info_setup(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ ret = rtw89_mac_partial_init(rtwdev); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_parse_efuse_map(rtwdev); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_parse_phycap_map(rtwdev); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_mac_setup_phycap(rtwdev); ++ if (ret) ++ return ret; ++ ++ rtw89_mac_pwr_off(rtwdev); ++ ++ return 0; ++} ++ ++static int rtw89_chip_board_info_setup(struct rtw89_dev *rtwdev) ++{ ++ rtw89_chip_fem_setup(rtwdev); ++ ++ return 0; ++} ++ ++int rtw89_chip_info_setup(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ rtw89_read_chip_ver(rtwdev); ++ ++ ret = rtw89_wait_firmware_completion(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to wait firmware completion\n"); ++ return ret; ++ } ++ ++ ret = rtw89_fw_recognize(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to recognize firmware\n"); ++ return ret; ++ } ++ ++ ret = rtw89_chip_efuse_info_setup(rtwdev); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_chip_board_info_setup(rtwdev); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++EXPORT_SYMBOL(rtw89_chip_info_setup); ++ ++static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) ++{ ++ struct ieee80211_hw *hw = rtwdev->hw; ++ struct rtw89_efuse *efuse = &rtwdev->efuse; ++ int ret; ++ int tx_headroom = IEEE80211_HT_CTL_LEN; ++ ++ hw->vif_data_size = sizeof(struct rtw89_vif); ++ hw->sta_data_size = sizeof(struct rtw89_sta); ++ hw->txq_data_size = sizeof(struct rtw89_txq); ++ ++ SET_IEEE80211_PERM_ADDR(hw, efuse->addr); ++ ++ hw->extra_tx_headroom = tx_headroom; ++ hw->queues = IEEE80211_NUM_ACS; ++ hw->max_rx_aggregation_subframes = RTW89_MAX_RX_AGG_NUM; ++ hw->max_tx_aggregation_subframes = RTW89_MAX_TX_AGG_NUM; ++ ++ ieee80211_hw_set(hw, SIGNAL_DBM); ++ ieee80211_hw_set(hw, HAS_RATE_CONTROL); ++ ieee80211_hw_set(hw, MFP_CAPABLE); ++ ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); ++ ieee80211_hw_set(hw, AMPDU_AGGREGATION); ++ ieee80211_hw_set(hw, RX_INCLUDES_FCS); ++ ieee80211_hw_set(hw, TX_AMSDU); ++ ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); ++ ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); ++ ieee80211_hw_set(hw, SUPPORTS_PS); ++ ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); ++ ++ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); ++ hw->wiphy->available_antennas_tx = BIT(rtwdev->chip->rf_path_num) - 1; ++ hw->wiphy->available_antennas_rx = BIT(rtwdev->chip->rf_path_num) - 1; ++ ++ hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; ++ ++ wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); ++ ++ ret = rtw89_core_set_supported_band(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to set supported band\n"); ++ return ret; ++ } ++ ++ hw->wiphy->reg_notifier = rtw89_regd_notifier; ++ hw->wiphy->sar_capa = &rtw89_sar_capa; ++ ++ ret = ieee80211_register_hw(hw); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to register hw\n"); ++ goto err; ++ } ++ ++ ret = rtw89_regd_init(rtwdev, rtw89_regd_notifier); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to init regd\n"); ++ goto err; ++ } ++ ++ return 0; ++ ++err: ++ return ret; ++} ++ ++static void rtw89_core_unregister_hw(struct rtw89_dev *rtwdev) ++{ ++ struct ieee80211_hw *hw = rtwdev->hw; ++ ++ ieee80211_unregister_hw(hw); ++ rtw89_core_clr_supported_band(rtwdev); ++} ++ ++int rtw89_core_register(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ ret = rtw89_core_register_hw(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to register core hw\n"); ++ return ret; ++ } ++ ++ rtw89_debugfs_init(rtwdev); ++ ++ return 0; ++} ++EXPORT_SYMBOL(rtw89_core_register); ++ ++void rtw89_core_unregister(struct rtw89_dev *rtwdev) ++{ ++ rtw89_core_unregister_hw(rtwdev); ++} ++EXPORT_SYMBOL(rtw89_core_unregister); ++ ++MODULE_AUTHOR("Realtek Corporation"); ++MODULE_DESCRIPTION("Realtek 802.11ax wireless core module"); ++MODULE_LICENSE("Dual BSD/GPL"); +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +new file mode 100644 +index 000000000000..c2885e4dd882 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -0,0 +1,3384 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_CORE_H__ ++#define __RTW89_CORE_H__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct rtw89_dev; ++ ++extern const struct ieee80211_ops rtw89_ops; ++extern const struct rtw89_chip_info rtw8852a_chip_info; ++ ++#define MASKBYTE0 0xff ++#define MASKBYTE1 0xff00 ++#define MASKBYTE2 0xff0000 ++#define MASKBYTE3 0xff000000 ++#define MASKBYTE4 0xff00000000ULL ++#define MASKHWORD 0xffff0000 ++#define MASKLWORD 0x0000ffff ++#define MASKDWORD 0xffffffff ++#define RFREG_MASK 0xfffff ++#define INV_RF_DATA 0xffffffff ++ ++#define RTW89_TRACK_WORK_PERIOD round_jiffies_relative(HZ * 2) ++#define CFO_TRACK_MAX_USER 64 ++#define MAX_RSSI 110 ++#define RSSI_FACTOR 1 ++#define RTW89_RSSI_RAW_TO_DBM(rssi) ((s8)((rssi) >> RSSI_FACTOR) - MAX_RSSI) ++#define RTW89_MAX_HW_PORT_NUM 5 ++ ++#define RTW89_HTC_MASK_VARIANT GENMASK(1, 0) ++#define RTW89_HTC_VARIANT_HE 3 ++#define RTW89_HTC_MASK_CTL_ID GENMASK(5, 2) ++#define RTW89_HTC_VARIANT_HE_CID_OM 1 ++#define RTW89_HTC_VARIANT_HE_CID_CAS 6 ++#define RTW89_HTC_MASK_CTL_INFO GENMASK(31, 6) ++ ++#define RTW89_HTC_MASK_HTC_OM_RX_NSS GENMASK(8, 6) ++enum htc_om_channel_width { ++ HTC_OM_CHANNEL_WIDTH_20 = 0, ++ HTC_OM_CHANNEL_WIDTH_40 = 1, ++ HTC_OM_CHANNEL_WIDTH_80 = 2, ++ HTC_OM_CHANNEL_WIDTH_160_OR_80_80 = 3, ++}; ++#define RTW89_HTC_MASK_HTC_OM_CH_WIDTH GENMASK(10, 9) ++#define RTW89_HTC_MASK_HTC_OM_UL_MU_DIS BIT(11) ++#define RTW89_HTC_MASK_HTC_OM_TX_NSTS GENMASK(14, 12) ++#define RTW89_HTC_MASK_HTC_OM_ER_SU_DIS BIT(15) ++#define RTW89_HTC_MASK_HTC_OM_DL_MU_MIMO_RR BIT(16) ++#define RTW89_HTC_MASK_HTC_OM_UL_MU_DATA_DIS BIT(17) ++ ++enum rtw89_subband { ++ RTW89_CH_2G = 0, ++ RTW89_CH_5G_BAND_1 = 1, ++ /* RTW89_CH_5G_BAND_2 = 2, unused */ ++ RTW89_CH_5G_BAND_3 = 3, ++ RTW89_CH_5G_BAND_4 = 4, ++ ++ RTW89_SUBBAND_NR, ++}; ++ ++enum rtw89_hci_type { ++ RTW89_HCI_TYPE_PCIE, ++ RTW89_HCI_TYPE_USB, ++ RTW89_HCI_TYPE_SDIO, ++}; ++ ++enum rtw89_core_chip_id { ++ RTL8852A, ++ RTL8852B, ++ RTL8852C, ++}; ++ ++enum rtw89_cv { ++ CHIP_CAV, ++ CHIP_CBV, ++ CHIP_CCV, ++ CHIP_CDV, ++ CHIP_CEV, ++ CHIP_CFV, ++ CHIP_CV_MAX, ++ CHIP_CV_INVALID = CHIP_CV_MAX, ++}; ++ ++enum rtw89_core_tx_type { ++ RTW89_CORE_TX_TYPE_DATA, ++ RTW89_CORE_TX_TYPE_MGMT, ++ RTW89_CORE_TX_TYPE_FWCMD, ++}; ++ ++enum rtw89_core_rx_type { ++ RTW89_CORE_RX_TYPE_WIFI = 0, ++ RTW89_CORE_RX_TYPE_PPDU_STAT = 1, ++ RTW89_CORE_RX_TYPE_CHAN_INFO = 2, ++ RTW89_CORE_RX_TYPE_BB_SCOPE = 3, ++ RTW89_CORE_RX_TYPE_F2P_TXCMD = 4, ++ RTW89_CORE_RX_TYPE_SS2FW = 5, ++ RTW89_CORE_RX_TYPE_TX_REPORT = 6, ++ RTW89_CORE_RX_TYPE_TX_REL_HOST = 7, ++ RTW89_CORE_RX_TYPE_DFS_REPORT = 8, ++ RTW89_CORE_RX_TYPE_TX_REL_CPU = 9, ++ RTW89_CORE_RX_TYPE_C2H = 10, ++ RTW89_CORE_RX_TYPE_CSI = 11, ++ RTW89_CORE_RX_TYPE_CQI = 12, ++}; ++ ++enum rtw89_txq_flags { ++ RTW89_TXQ_F_AMPDU = 0, ++ RTW89_TXQ_F_BLOCK_BA = 1, ++}; ++ ++enum rtw89_net_type { ++ RTW89_NET_TYPE_NO_LINK = 0, ++ RTW89_NET_TYPE_AD_HOC = 1, ++ RTW89_NET_TYPE_INFRA = 2, ++ RTW89_NET_TYPE_AP_MODE = 3, ++}; ++ ++enum rtw89_wifi_role { ++ RTW89_WIFI_ROLE_NONE, ++ RTW89_WIFI_ROLE_STATION, ++ RTW89_WIFI_ROLE_AP, ++ RTW89_WIFI_ROLE_AP_VLAN, ++ RTW89_WIFI_ROLE_ADHOC, ++ RTW89_WIFI_ROLE_ADHOC_MASTER, ++ RTW89_WIFI_ROLE_MESH_POINT, ++ RTW89_WIFI_ROLE_MONITOR, ++ RTW89_WIFI_ROLE_P2P_DEVICE, ++ RTW89_WIFI_ROLE_P2P_CLIENT, ++ RTW89_WIFI_ROLE_P2P_GO, ++ RTW89_WIFI_ROLE_NAN, ++ RTW89_WIFI_ROLE_MLME_MAX ++}; ++ ++enum rtw89_upd_mode { ++ RTW89_VIF_CREATE, ++ RTW89_VIF_REMOVE, ++ RTW89_VIF_TYPE_CHANGE, ++ RTW89_VIF_INFO_CHANGE, ++ RTW89_VIF_CON_DISCONN ++}; ++ ++enum rtw89_self_role { ++ RTW89_SELF_ROLE_CLIENT, ++ RTW89_SELF_ROLE_AP, ++ RTW89_SELF_ROLE_AP_CLIENT ++}; ++ ++enum rtw89_msk_sO_el { ++ RTW89_NO_MSK, ++ RTW89_SMA, ++ RTW89_TMA, ++ RTW89_BSSID ++}; ++ ++enum rtw89_sch_tx_sel { ++ RTW89_SCH_TX_SEL_ALL, ++ RTW89_SCH_TX_SEL_HIQ, ++ RTW89_SCH_TX_SEL_MG0, ++ RTW89_SCH_TX_SEL_MACID, ++}; ++ ++/* RTW89_ADDR_CAM_SEC_NONE : not enabled ++ * RTW89_ADDR_CAM_SEC_ALL_UNI : 0 - 6 unicast ++ * RTW89_ADDR_CAM_SEC_NORMAL : 0 - 1 unicast, 2 - 4 group, 5 - 6 BIP ++ * RTW89_ADDR_CAM_SEC_4GROUP : 0 - 1 unicast, 2 - 5 group, 6 BIP ++ */ ++enum rtw89_add_cam_sec_mode { ++ RTW89_ADDR_CAM_SEC_NONE = 0, ++ RTW89_ADDR_CAM_SEC_ALL_UNI = 1, ++ RTW89_ADDR_CAM_SEC_NORMAL = 2, ++ RTW89_ADDR_CAM_SEC_4GROUP = 3, ++}; ++ ++enum rtw89_sec_key_type { ++ RTW89_SEC_KEY_TYPE_NONE = 0, ++ RTW89_SEC_KEY_TYPE_WEP40 = 1, ++ RTW89_SEC_KEY_TYPE_WEP104 = 2, ++ RTW89_SEC_KEY_TYPE_TKIP = 3, ++ RTW89_SEC_KEY_TYPE_WAPI = 4, ++ RTW89_SEC_KEY_TYPE_GCMSMS4 = 5, ++ RTW89_SEC_KEY_TYPE_CCMP128 = 6, ++ RTW89_SEC_KEY_TYPE_CCMP256 = 7, ++ RTW89_SEC_KEY_TYPE_GCMP128 = 8, ++ RTW89_SEC_KEY_TYPE_GCMP256 = 9, ++ RTW89_SEC_KEY_TYPE_BIP_CCMP128 = 10, ++}; ++ ++enum rtw89_port { ++ RTW89_PORT_0 = 0, ++ RTW89_PORT_1 = 1, ++ RTW89_PORT_2 = 2, ++ RTW89_PORT_3 = 3, ++ RTW89_PORT_4 = 4, ++ RTW89_PORT_NUM ++}; ++ ++enum rtw89_band { ++ RTW89_BAND_2G = 0, ++ RTW89_BAND_5G = 1, ++ RTW89_BAND_MAX, ++}; ++ ++enum rtw89_hw_rate { ++ RTW89_HW_RATE_CCK1 = 0x0, ++ RTW89_HW_RATE_CCK2 = 0x1, ++ RTW89_HW_RATE_CCK5_5 = 0x2, ++ RTW89_HW_RATE_CCK11 = 0x3, ++ RTW89_HW_RATE_OFDM6 = 0x4, ++ RTW89_HW_RATE_OFDM9 = 0x5, ++ RTW89_HW_RATE_OFDM12 = 0x6, ++ RTW89_HW_RATE_OFDM18 = 0x7, ++ RTW89_HW_RATE_OFDM24 = 0x8, ++ RTW89_HW_RATE_OFDM36 = 0x9, ++ RTW89_HW_RATE_OFDM48 = 0xA, ++ RTW89_HW_RATE_OFDM54 = 0xB, ++ RTW89_HW_RATE_MCS0 = 0x80, ++ RTW89_HW_RATE_MCS1 = 0x81, ++ RTW89_HW_RATE_MCS2 = 0x82, ++ RTW89_HW_RATE_MCS3 = 0x83, ++ RTW89_HW_RATE_MCS4 = 0x84, ++ RTW89_HW_RATE_MCS5 = 0x85, ++ RTW89_HW_RATE_MCS6 = 0x86, ++ RTW89_HW_RATE_MCS7 = 0x87, ++ RTW89_HW_RATE_MCS8 = 0x88, ++ RTW89_HW_RATE_MCS9 = 0x89, ++ RTW89_HW_RATE_MCS10 = 0x8A, ++ RTW89_HW_RATE_MCS11 = 0x8B, ++ RTW89_HW_RATE_MCS12 = 0x8C, ++ RTW89_HW_RATE_MCS13 = 0x8D, ++ RTW89_HW_RATE_MCS14 = 0x8E, ++ RTW89_HW_RATE_MCS15 = 0x8F, ++ RTW89_HW_RATE_MCS16 = 0x90, ++ RTW89_HW_RATE_MCS17 = 0x91, ++ RTW89_HW_RATE_MCS18 = 0x92, ++ RTW89_HW_RATE_MCS19 = 0x93, ++ RTW89_HW_RATE_MCS20 = 0x94, ++ RTW89_HW_RATE_MCS21 = 0x95, ++ RTW89_HW_RATE_MCS22 = 0x96, ++ RTW89_HW_RATE_MCS23 = 0x97, ++ RTW89_HW_RATE_MCS24 = 0x98, ++ RTW89_HW_RATE_MCS25 = 0x99, ++ RTW89_HW_RATE_MCS26 = 0x9A, ++ RTW89_HW_RATE_MCS27 = 0x9B, ++ RTW89_HW_RATE_MCS28 = 0x9C, ++ RTW89_HW_RATE_MCS29 = 0x9D, ++ RTW89_HW_RATE_MCS30 = 0x9E, ++ RTW89_HW_RATE_MCS31 = 0x9F, ++ RTW89_HW_RATE_VHT_NSS1_MCS0 = 0x100, ++ RTW89_HW_RATE_VHT_NSS1_MCS1 = 0x101, ++ RTW89_HW_RATE_VHT_NSS1_MCS2 = 0x102, ++ RTW89_HW_RATE_VHT_NSS1_MCS3 = 0x103, ++ RTW89_HW_RATE_VHT_NSS1_MCS4 = 0x104, ++ RTW89_HW_RATE_VHT_NSS1_MCS5 = 0x105, ++ RTW89_HW_RATE_VHT_NSS1_MCS6 = 0x106, ++ RTW89_HW_RATE_VHT_NSS1_MCS7 = 0x107, ++ RTW89_HW_RATE_VHT_NSS1_MCS8 = 0x108, ++ RTW89_HW_RATE_VHT_NSS1_MCS9 = 0x109, ++ RTW89_HW_RATE_VHT_NSS2_MCS0 = 0x110, ++ RTW89_HW_RATE_VHT_NSS2_MCS1 = 0x111, ++ RTW89_HW_RATE_VHT_NSS2_MCS2 = 0x112, ++ RTW89_HW_RATE_VHT_NSS2_MCS3 = 0x113, ++ RTW89_HW_RATE_VHT_NSS2_MCS4 = 0x114, ++ RTW89_HW_RATE_VHT_NSS2_MCS5 = 0x115, ++ RTW89_HW_RATE_VHT_NSS2_MCS6 = 0x116, ++ RTW89_HW_RATE_VHT_NSS2_MCS7 = 0x117, ++ RTW89_HW_RATE_VHT_NSS2_MCS8 = 0x118, ++ RTW89_HW_RATE_VHT_NSS2_MCS9 = 0x119, ++ RTW89_HW_RATE_VHT_NSS3_MCS0 = 0x120, ++ RTW89_HW_RATE_VHT_NSS3_MCS1 = 0x121, ++ RTW89_HW_RATE_VHT_NSS3_MCS2 = 0x122, ++ RTW89_HW_RATE_VHT_NSS3_MCS3 = 0x123, ++ RTW89_HW_RATE_VHT_NSS3_MCS4 = 0x124, ++ RTW89_HW_RATE_VHT_NSS3_MCS5 = 0x125, ++ RTW89_HW_RATE_VHT_NSS3_MCS6 = 0x126, ++ RTW89_HW_RATE_VHT_NSS3_MCS7 = 0x127, ++ RTW89_HW_RATE_VHT_NSS3_MCS8 = 0x128, ++ RTW89_HW_RATE_VHT_NSS3_MCS9 = 0x129, ++ RTW89_HW_RATE_VHT_NSS4_MCS0 = 0x130, ++ RTW89_HW_RATE_VHT_NSS4_MCS1 = 0x131, ++ RTW89_HW_RATE_VHT_NSS4_MCS2 = 0x132, ++ RTW89_HW_RATE_VHT_NSS4_MCS3 = 0x133, ++ RTW89_HW_RATE_VHT_NSS4_MCS4 = 0x134, ++ RTW89_HW_RATE_VHT_NSS4_MCS5 = 0x135, ++ RTW89_HW_RATE_VHT_NSS4_MCS6 = 0x136, ++ RTW89_HW_RATE_VHT_NSS4_MCS7 = 0x137, ++ RTW89_HW_RATE_VHT_NSS4_MCS8 = 0x138, ++ RTW89_HW_RATE_VHT_NSS4_MCS9 = 0x139, ++ RTW89_HW_RATE_HE_NSS1_MCS0 = 0x180, ++ RTW89_HW_RATE_HE_NSS1_MCS1 = 0x181, ++ RTW89_HW_RATE_HE_NSS1_MCS2 = 0x182, ++ RTW89_HW_RATE_HE_NSS1_MCS3 = 0x183, ++ RTW89_HW_RATE_HE_NSS1_MCS4 = 0x184, ++ RTW89_HW_RATE_HE_NSS1_MCS5 = 0x185, ++ RTW89_HW_RATE_HE_NSS1_MCS6 = 0x186, ++ RTW89_HW_RATE_HE_NSS1_MCS7 = 0x187, ++ RTW89_HW_RATE_HE_NSS1_MCS8 = 0x188, ++ RTW89_HW_RATE_HE_NSS1_MCS9 = 0x189, ++ RTW89_HW_RATE_HE_NSS1_MCS10 = 0x18A, ++ RTW89_HW_RATE_HE_NSS1_MCS11 = 0x18B, ++ RTW89_HW_RATE_HE_NSS2_MCS0 = 0x190, ++ RTW89_HW_RATE_HE_NSS2_MCS1 = 0x191, ++ RTW89_HW_RATE_HE_NSS2_MCS2 = 0x192, ++ RTW89_HW_RATE_HE_NSS2_MCS3 = 0x193, ++ RTW89_HW_RATE_HE_NSS2_MCS4 = 0x194, ++ RTW89_HW_RATE_HE_NSS2_MCS5 = 0x195, ++ RTW89_HW_RATE_HE_NSS2_MCS6 = 0x196, ++ RTW89_HW_RATE_HE_NSS2_MCS7 = 0x197, ++ RTW89_HW_RATE_HE_NSS2_MCS8 = 0x198, ++ RTW89_HW_RATE_HE_NSS2_MCS9 = 0x199, ++ RTW89_HW_RATE_HE_NSS2_MCS10 = 0x19A, ++ RTW89_HW_RATE_HE_NSS2_MCS11 = 0x19B, ++ RTW89_HW_RATE_HE_NSS3_MCS0 = 0x1A0, ++ RTW89_HW_RATE_HE_NSS3_MCS1 = 0x1A1, ++ RTW89_HW_RATE_HE_NSS3_MCS2 = 0x1A2, ++ RTW89_HW_RATE_HE_NSS3_MCS3 = 0x1A3, ++ RTW89_HW_RATE_HE_NSS3_MCS4 = 0x1A4, ++ RTW89_HW_RATE_HE_NSS3_MCS5 = 0x1A5, ++ RTW89_HW_RATE_HE_NSS3_MCS6 = 0x1A6, ++ RTW89_HW_RATE_HE_NSS3_MCS7 = 0x1A7, ++ RTW89_HW_RATE_HE_NSS3_MCS8 = 0x1A8, ++ RTW89_HW_RATE_HE_NSS3_MCS9 = 0x1A9, ++ RTW89_HW_RATE_HE_NSS3_MCS10 = 0x1AA, ++ RTW89_HW_RATE_HE_NSS3_MCS11 = 0x1AB, ++ RTW89_HW_RATE_HE_NSS4_MCS0 = 0x1B0, ++ RTW89_HW_RATE_HE_NSS4_MCS1 = 0x1B1, ++ RTW89_HW_RATE_HE_NSS4_MCS2 = 0x1B2, ++ RTW89_HW_RATE_HE_NSS4_MCS3 = 0x1B3, ++ RTW89_HW_RATE_HE_NSS4_MCS4 = 0x1B4, ++ RTW89_HW_RATE_HE_NSS4_MCS5 = 0x1B5, ++ RTW89_HW_RATE_HE_NSS4_MCS6 = 0x1B6, ++ RTW89_HW_RATE_HE_NSS4_MCS7 = 0x1B7, ++ RTW89_HW_RATE_HE_NSS4_MCS8 = 0x1B8, ++ RTW89_HW_RATE_HE_NSS4_MCS9 = 0x1B9, ++ RTW89_HW_RATE_HE_NSS4_MCS10 = 0x1BA, ++ RTW89_HW_RATE_HE_NSS4_MCS11 = 0x1BB, ++ RTW89_HW_RATE_NR, ++ ++ RTW89_HW_RATE_MASK_MOD = GENMASK(8, 7), ++ RTW89_HW_RATE_MASK_VAL = GENMASK(6, 0), ++}; ++ ++/* 2G channels, ++ * 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ++ */ ++#define RTW89_2G_CH_NUM 14 ++ ++/* 5G channels, ++ * 36, 38, 40, 42, 44, 46, 48, 50, ++ * 52, 54, 56, 58, 60, 62, 64, ++ * 100, 102, 104, 106, 108, 110, 112, 114, ++ * 116, 118, 120, 122, 124, 126, 128, 130, ++ * 132, 134, 136, 138, 140, 142, 144, ++ * 149, 151, 153, 155, 157, 159, 161, 163, ++ * 165, 167, 169, 171, 173, 175, 177 ++ */ ++#define RTW89_5G_CH_NUM 53 ++ ++enum rtw89_rate_section { ++ RTW89_RS_CCK, ++ RTW89_RS_OFDM, ++ RTW89_RS_MCS, /* for HT/VHT/HE */ ++ RTW89_RS_HEDCM, ++ RTW89_RS_OFFSET, ++ RTW89_RS_MAX, ++ RTW89_RS_LMT_NUM = RTW89_RS_MCS + 1, ++}; ++ ++enum rtw89_rate_max { ++ RTW89_RATE_CCK_MAX = 4, ++ RTW89_RATE_OFDM_MAX = 8, ++ RTW89_RATE_MCS_MAX = 12, ++ RTW89_RATE_HEDCM_MAX = 4, /* for HEDCM MCS0/1/3/4 */ ++ RTW89_RATE_OFFSET_MAX = 5, /* for HE(HEDCM)/VHT/HT/OFDM/CCK offset */ ++}; ++ ++enum rtw89_nss { ++ RTW89_NSS_1 = 0, ++ RTW89_NSS_2 = 1, ++ /* HE DCM only support 1ss and 2ss */ ++ RTW89_NSS_HEDCM_MAX = RTW89_NSS_2 + 1, ++ RTW89_NSS_3 = 2, ++ RTW89_NSS_4 = 3, ++ RTW89_NSS_MAX, ++}; ++ ++enum rtw89_ntx { ++ RTW89_1TX = 0, ++ RTW89_2TX = 1, ++ RTW89_NTX_NUM, ++}; ++ ++enum rtw89_beamforming_type { ++ RTW89_NONBF = 0, ++ RTW89_BF = 1, ++ RTW89_BF_NUM, ++}; ++ ++enum rtw89_regulation_type { ++ RTW89_WW = 0, ++ RTW89_ETSI = 1, ++ RTW89_FCC = 2, ++ RTW89_MKK = 3, ++ RTW89_NA = 4, ++ RTW89_IC = 5, ++ RTW89_KCC = 6, ++ RTW89_NCC = 7, ++ RTW89_CHILE = 8, ++ RTW89_ACMA = 9, ++ RTW89_MEXICO = 10, ++ RTW89_UKRAINE = 11, ++ RTW89_CN = 12, ++ RTW89_REGD_NUM, ++}; ++ ++extern const u8 rtw89_rs_idx_max[RTW89_RS_MAX]; ++extern const u8 rtw89_rs_nss_max[RTW89_RS_MAX]; ++ ++struct rtw89_txpwr_byrate { ++ s8 cck[RTW89_RATE_CCK_MAX]; ++ s8 ofdm[RTW89_RATE_OFDM_MAX]; ++ s8 mcs[RTW89_NSS_MAX][RTW89_RATE_MCS_MAX]; ++ s8 hedcm[RTW89_NSS_HEDCM_MAX][RTW89_RATE_HEDCM_MAX]; ++ s8 offset[RTW89_RATE_OFFSET_MAX]; ++}; ++ ++enum rtw89_bandwidth_section_num { ++ RTW89_BW20_SEC_NUM = 8, ++ RTW89_BW40_SEC_NUM = 4, ++ RTW89_BW80_SEC_NUM = 2, ++}; ++ ++struct rtw89_txpwr_limit { ++ s8 cck_20m[RTW89_BF_NUM]; ++ s8 cck_40m[RTW89_BF_NUM]; ++ s8 ofdm[RTW89_BF_NUM]; ++ s8 mcs_20m[RTW89_BW20_SEC_NUM][RTW89_BF_NUM]; ++ s8 mcs_40m[RTW89_BW40_SEC_NUM][RTW89_BF_NUM]; ++ s8 mcs_80m[RTW89_BW80_SEC_NUM][RTW89_BF_NUM]; ++ s8 mcs_160m[RTW89_BF_NUM]; ++ s8 mcs_40m_0p5[RTW89_BF_NUM]; ++ s8 mcs_40m_2p5[RTW89_BF_NUM]; ++}; ++ ++#define RTW89_RU_SEC_NUM 8 ++ ++struct rtw89_txpwr_limit_ru { ++ s8 ru26[RTW89_RU_SEC_NUM]; ++ s8 ru52[RTW89_RU_SEC_NUM]; ++ s8 ru106[RTW89_RU_SEC_NUM]; ++}; ++ ++struct rtw89_rate_desc { ++ enum rtw89_nss nss; ++ enum rtw89_rate_section rs; ++ u8 idx; ++}; ++ ++#define PHY_STS_HDR_LEN 8 ++#define RF_PATH_MAX 4 ++#define RTW89_MAX_PPDU_CNT 8 ++struct rtw89_rx_phy_ppdu { ++ u8 *buf; ++ u32 len; ++ u8 rssi_avg; ++ s8 rssi[RF_PATH_MAX]; ++ u8 mac_id; ++ bool to_self; ++ bool valid; ++}; ++ ++enum rtw89_mac_idx { ++ RTW89_MAC_0 = 0, ++ RTW89_MAC_1 = 1, ++}; ++ ++enum rtw89_phy_idx { ++ RTW89_PHY_0 = 0, ++ RTW89_PHY_1 = 1, ++ RTW89_PHY_MAX ++}; ++ ++enum rtw89_rf_path { ++ RF_PATH_A = 0, ++ RF_PATH_B = 1, ++ RF_PATH_C = 2, ++ RF_PATH_D = 3, ++ RF_PATH_AB, ++ RF_PATH_AC, ++ RF_PATH_AD, ++ RF_PATH_BC, ++ RF_PATH_BD, ++ RF_PATH_CD, ++ RF_PATH_ABC, ++ RF_PATH_ABD, ++ RF_PATH_ACD, ++ RF_PATH_BCD, ++ RF_PATH_ABCD, ++}; ++ ++enum rtw89_rf_path_bit { ++ RF_A = BIT(0), ++ RF_B = BIT(1), ++ RF_C = BIT(2), ++ RF_D = BIT(3), ++ ++ RF_AB = (RF_A | RF_B), ++ RF_AC = (RF_A | RF_C), ++ RF_AD = (RF_A | RF_D), ++ RF_BC = (RF_B | RF_C), ++ RF_BD = (RF_B | RF_D), ++ RF_CD = (RF_C | RF_D), ++ ++ RF_ABC = (RF_A | RF_B | RF_C), ++ RF_ABD = (RF_A | RF_B | RF_D), ++ RF_ACD = (RF_A | RF_C | RF_D), ++ RF_BCD = (RF_B | RF_C | RF_D), ++ ++ RF_ABCD = (RF_A | RF_B | RF_C | RF_D), ++}; ++ ++enum rtw89_bandwidth { ++ RTW89_CHANNEL_WIDTH_20 = 0, ++ RTW89_CHANNEL_WIDTH_40 = 1, ++ RTW89_CHANNEL_WIDTH_80 = 2, ++ RTW89_CHANNEL_WIDTH_160 = 3, ++ RTW89_CHANNEL_WIDTH_80_80 = 4, ++ RTW89_CHANNEL_WIDTH_5 = 5, ++ RTW89_CHANNEL_WIDTH_10 = 6, ++}; ++ ++enum rtw89_ps_mode { ++ RTW89_PS_MODE_NONE = 0, ++ RTW89_PS_MODE_RFOFF = 1, ++ RTW89_PS_MODE_CLK_GATED = 2, ++ RTW89_PS_MODE_PWR_GATED = 3, ++}; ++ ++#define RTW89_MAX_CHANNEL_WIDTH RTW89_CHANNEL_WIDTH_80 ++#define RTW89_2G_BW_NUM (RTW89_CHANNEL_WIDTH_40 + 1) ++#define RTW89_5G_BW_NUM (RTW89_CHANNEL_WIDTH_80 + 1) ++#define RTW89_PPE_BW_NUM (RTW89_CHANNEL_WIDTH_80 + 1) ++ ++enum rtw89_ru_bandwidth { ++ RTW89_RU26 = 0, ++ RTW89_RU52 = 1, ++ RTW89_RU106 = 2, ++ RTW89_RU_NUM, ++}; ++ ++enum rtw89_sc_offset { ++ RTW89_SC_DONT_CARE = 0, ++ RTW89_SC_20_UPPER = 1, ++ RTW89_SC_20_LOWER = 2, ++ RTW89_SC_20_UPMOST = 3, ++ RTW89_SC_20_LOWEST = 4, ++ RTW89_SC_40_UPPER = 9, ++ RTW89_SC_40_LOWER = 10, ++}; ++ ++struct rtw89_channel_params { ++ u8 center_chan; ++ u8 primary_chan; ++ u8 bandwidth; ++ u8 pri_ch_idx; ++ u8 cch_by_bw[RTW89_MAX_CHANNEL_WIDTH + 1]; ++}; ++ ++struct rtw89_channel_help_params { ++ u16 tx_en; ++}; ++ ++struct rtw89_port_reg { ++ u32 port_cfg; ++ u32 tbtt_prohib; ++ u32 bcn_area; ++ u32 bcn_early; ++ u32 tbtt_early; ++ u32 tbtt_agg; ++ u32 bcn_space; ++ u32 bcn_forcetx; ++ u32 bcn_err_cnt; ++ u32 bcn_err_flag; ++ u32 dtim_ctrl; ++ u32 tbtt_shift; ++ u32 bcn_cnt_tmr; ++ u32 tsftr_l; ++ u32 tsftr_h; ++}; ++ ++struct rtw89_txwd_body { ++ __le32 dword0; ++ __le32 dword1; ++ __le32 dword2; ++ __le32 dword3; ++ __le32 dword4; ++ __le32 dword5; ++} __packed; ++ ++struct rtw89_txwd_info { ++ __le32 dword0; ++ __le32 dword1; ++ __le32 dword2; ++ __le32 dword3; ++ __le32 dword4; ++ __le32 dword5; ++} __packed; ++ ++struct rtw89_rx_desc_info { ++ u16 pkt_size; ++ u8 pkt_type; ++ u8 drv_info_size; ++ u8 shift; ++ u8 wl_hd_iv_len; ++ bool long_rxdesc; ++ bool bb_sel; ++ bool mac_info_valid; ++ u16 data_rate; ++ u8 gi_ltf; ++ u8 bw; ++ u32 free_run_cnt; ++ u8 user_id; ++ bool sr_en; ++ u8 ppdu_cnt; ++ u8 ppdu_type; ++ bool icv_err; ++ bool crc32_err; ++ bool hw_dec; ++ bool sw_dec; ++ bool addr1_match; ++ u8 frag; ++ u16 seq; ++ u8 frame_type; ++ u8 rx_pl_id; ++ bool addr_cam_valid; ++ u8 addr_cam_id; ++ u8 sec_cam_id; ++ u8 mac_id; ++ u16 offset; ++ bool ready; ++}; ++ ++struct rtw89_rxdesc_short { ++ __le32 dword0; ++ __le32 dword1; ++ __le32 dword2; ++ __le32 dword3; ++} __packed; ++ ++struct rtw89_rxdesc_long { ++ __le32 dword0; ++ __le32 dword1; ++ __le32 dword2; ++ __le32 dword3; ++ __le32 dword4; ++ __le32 dword5; ++ __le32 dword6; ++ __le32 dword7; ++} __packed; ++ ++struct rtw89_tx_desc_info { ++ u16 pkt_size; ++ u8 wp_offset; ++ u8 qsel; ++ u8 ch_dma; ++ u8 hdr_llc_len; ++ bool is_bmc; ++ bool en_wd_info; ++ bool wd_page; ++ bool use_rate; ++ bool dis_data_fb; ++ bool tid_indicate; ++ bool agg_en; ++ bool bk; ++ u8 ampdu_density; ++ u8 ampdu_num; ++ bool sec_en; ++ u8 sec_type; ++ u8 sec_cam_idx; ++ u16 data_rate; ++ u16 data_retry_lowest_rate; ++ bool fw_dl; ++ u16 seq; ++ bool a_ctrl_bsr; ++}; ++ ++struct rtw89_core_tx_request { ++ enum rtw89_core_tx_type tx_type; ++ ++ struct sk_buff *skb; ++ struct ieee80211_vif *vif; ++ struct ieee80211_sta *sta; ++ struct rtw89_tx_desc_info desc_info; ++}; ++ ++struct rtw89_txq { ++ struct list_head list; ++ unsigned long flags; ++ int wait_cnt; ++}; ++ ++struct rtw89_mac_ax_gnt { ++ u8 gnt_bt_sw_en; ++ u8 gnt_bt; ++ u8 gnt_wl_sw_en; ++ u8 gnt_wl; ++}; ++ ++#define RTW89_MAC_AX_COEX_GNT_NR 2 ++struct rtw89_mac_ax_coex_gnt { ++ struct rtw89_mac_ax_gnt band[RTW89_MAC_AX_COEX_GNT_NR]; ++}; ++ ++enum rtw89_btc_ncnt { ++ BTC_NCNT_POWER_ON = 0x0, ++ BTC_NCNT_POWER_OFF, ++ BTC_NCNT_INIT_COEX, ++ BTC_NCNT_SCAN_START, ++ BTC_NCNT_SCAN_FINISH, ++ BTC_NCNT_SPECIAL_PACKET, ++ BTC_NCNT_SWITCH_BAND, ++ BTC_NCNT_RFK_TIMEOUT, ++ BTC_NCNT_SHOW_COEX_INFO, ++ BTC_NCNT_ROLE_INFO, ++ BTC_NCNT_CONTROL, ++ BTC_NCNT_RADIO_STATE, ++ BTC_NCNT_CUSTOMERIZE, ++ BTC_NCNT_WL_RFK, ++ BTC_NCNT_WL_STA, ++ BTC_NCNT_FWINFO, ++ BTC_NCNT_TIMER, ++ BTC_NCNT_NUM ++}; ++ ++enum rtw89_btc_btinfo { ++ BTC_BTINFO_L0 = 0, ++ BTC_BTINFO_L1, ++ BTC_BTINFO_L2, ++ BTC_BTINFO_L3, ++ BTC_BTINFO_H0, ++ BTC_BTINFO_H1, ++ BTC_BTINFO_H2, ++ BTC_BTINFO_H3, ++ BTC_BTINFO_MAX ++}; ++ ++enum rtw89_btc_dcnt { ++ BTC_DCNT_RUN = 0x0, ++ BTC_DCNT_CX_RUNINFO, ++ BTC_DCNT_RPT, ++ BTC_DCNT_RPT_FREEZE, ++ BTC_DCNT_CYCLE, ++ BTC_DCNT_CYCLE_FREEZE, ++ BTC_DCNT_W1, ++ BTC_DCNT_W1_FREEZE, ++ BTC_DCNT_B1, ++ BTC_DCNT_B1_FREEZE, ++ BTC_DCNT_TDMA_NONSYNC, ++ BTC_DCNT_SLOT_NONSYNC, ++ BTC_DCNT_BTCNT_FREEZE, ++ BTC_DCNT_WL_SLOT_DRIFT, ++ BTC_DCNT_WL_STA_LAST, ++ BTC_DCNT_NUM, ++}; ++ ++enum rtw89_btc_wl_state_cnt { ++ BTC_WCNT_SCANAP = 0x0, ++ BTC_WCNT_DHCP, ++ BTC_WCNT_EAPOL, ++ BTC_WCNT_ARP, ++ BTC_WCNT_SCBDUPDATE, ++ BTC_WCNT_RFK_REQ, ++ BTC_WCNT_RFK_GO, ++ BTC_WCNT_RFK_REJECT, ++ BTC_WCNT_RFK_TIMEOUT, ++ BTC_WCNT_CH_UPDATE, ++ BTC_WCNT_NUM ++}; ++ ++enum rtw89_btc_bt_state_cnt { ++ BTC_BCNT_RETRY = 0x0, ++ BTC_BCNT_REINIT, ++ BTC_BCNT_REENABLE, ++ BTC_BCNT_SCBDREAD, ++ BTC_BCNT_RELINK, ++ BTC_BCNT_IGNOWL, ++ BTC_BCNT_INQPAG, ++ BTC_BCNT_INQ, ++ BTC_BCNT_PAGE, ++ BTC_BCNT_ROLESW, ++ BTC_BCNT_AFH, ++ BTC_BCNT_INFOUPDATE, ++ BTC_BCNT_INFOSAME, ++ BTC_BCNT_SCBDUPDATE, ++ BTC_BCNT_HIPRI_TX, ++ BTC_BCNT_HIPRI_RX, ++ BTC_BCNT_LOPRI_TX, ++ BTC_BCNT_LOPRI_RX, ++ BTC_BCNT_RATECHG, ++ BTC_BCNT_NUM ++}; ++ ++enum rtw89_btc_bt_profile { ++ BTC_BT_NOPROFILE = 0, ++ BTC_BT_HFP = BIT(0), ++ BTC_BT_HID = BIT(1), ++ BTC_BT_A2DP = BIT(2), ++ BTC_BT_PAN = BIT(3), ++ BTC_PROFILE_MAX = 4, ++}; ++ ++struct rtw89_btc_ant_info { ++ u8 type; /* shared, dedicated */ ++ u8 num; ++ u8 isolation; ++ ++ u8 single_pos: 1;/* Single antenna at S0 or S1 */ ++ u8 diversity: 1; ++}; ++ ++enum rtw89_tfc_dir { ++ RTW89_TFC_UL, ++ RTW89_TFC_DL, ++}; ++ ++struct rtw89_btc_wl_smap { ++ u32 busy: 1; ++ u32 scan: 1; ++ u32 connecting: 1; ++ u32 roaming: 1; ++ u32 _4way: 1; ++ u32 rf_off: 1; ++ u32 lps: 1; ++ u32 ips: 1; ++ u32 init_ok: 1; ++ u32 traffic_dir : 2; ++ u32 rf_off_pre: 1; ++ u32 lps_pre: 1; ++}; ++ ++enum rtw89_tfc_lv { ++ RTW89_TFC_IDLE, ++ RTW89_TFC_ULTRA_LOW, ++ RTW89_TFC_LOW, ++ RTW89_TFC_MID, ++ RTW89_TFC_HIGH, ++}; ++ ++#define RTW89_TP_SHIFT 18 /* bytes/2s --> Mbps */ ++DECLARE_EWMA(tp, 10, 2); ++ ++struct rtw89_traffic_stats { ++ /* units in bytes */ ++ u64 tx_unicast; ++ u64 rx_unicast; ++ u32 tx_avg_len; ++ u32 rx_avg_len; ++ ++ /* count for packets */ ++ u64 tx_cnt; ++ u64 rx_cnt; ++ ++ /* units in Mbps */ ++ u32 tx_throughput; ++ u32 rx_throughput; ++ u32 tx_throughput_raw; ++ u32 rx_throughput_raw; ++ enum rtw89_tfc_lv tx_tfc_lv; ++ enum rtw89_tfc_lv rx_tfc_lv; ++ struct ewma_tp tx_ewma_tp; ++ struct ewma_tp rx_ewma_tp; ++ ++ u16 tx_rate; ++ u16 rx_rate; ++}; ++ ++struct rtw89_btc_statistic { ++ u8 rssi; /* 0%~110% (dBm = rssi -110) */ ++ struct rtw89_traffic_stats traffic; ++}; ++ ++#define BTC_WL_RSSI_THMAX 4 ++ ++struct rtw89_btc_wl_link_info { ++ struct rtw89_btc_statistic stat; ++ enum rtw89_tfc_dir dir; ++ u8 rssi_state[BTC_WL_RSSI_THMAX]; ++ u8 mac_addr[ETH_ALEN]; ++ u8 busy; ++ u8 ch; ++ u8 bw; ++ u8 band; ++ u8 role; ++ u8 pid; ++ u8 phy; ++ u8 dtim_period; ++ u8 mode; ++ ++ u8 mac_id; ++ u8 tx_retry; ++ ++ u32 bcn_period; ++ u32 busy_t; ++ u32 tx_time; ++ u32 client_cnt; ++ u32 rx_rate_drop_cnt; ++ ++ u32 active: 1; ++ u32 noa: 1; ++ u32 client_ps: 1; ++ u32 connected: 2; ++}; ++ ++union rtw89_btc_wl_state_map { ++ u32 val; ++ struct rtw89_btc_wl_smap map; ++}; ++ ++struct rtw89_btc_bt_hfp_desc { ++ u32 exist: 1; ++ u32 type: 2; ++ u32 rsvd: 29; ++}; ++ ++struct rtw89_btc_bt_hid_desc { ++ u32 exist: 1; ++ u32 slot_info: 2; ++ u32 pair_cnt: 2; ++ u32 type: 8; ++ u32 rsvd: 19; ++}; ++ ++struct rtw89_btc_bt_a2dp_desc { ++ u8 exist: 1; ++ u8 exist_last: 1; ++ u8 play_latency: 1; ++ u8 type: 3; ++ u8 active: 1; ++ u8 sink: 1; ++ ++ u8 bitpool; ++ u16 vendor_id; ++ u32 device_name; ++ u32 flush_time; ++}; ++ ++struct rtw89_btc_bt_pan_desc { ++ u32 exist: 1; ++ u32 type: 1; ++ u32 active: 1; ++ u32 rsvd: 29; ++}; ++ ++struct rtw89_btc_bt_rfk_info { ++ u32 run: 1; ++ u32 req: 1; ++ u32 timeout: 1; ++ u32 rsvd: 29; ++}; ++ ++union rtw89_btc_bt_rfk_info_map { ++ u32 val; ++ struct rtw89_btc_bt_rfk_info map; ++}; ++ ++struct rtw89_btc_bt_ver_info { ++ u32 fw_coex; /* match with which coex_ver */ ++ u32 fw; ++}; ++ ++struct rtw89_btc_bool_sta_chg { ++ u32 now: 1; ++ u32 last: 1; ++ u32 remain: 1; ++ u32 srvd: 29; ++}; ++ ++struct rtw89_btc_u8_sta_chg { ++ u8 now; ++ u8 last; ++ u8 remain; ++ u8 rsvd; ++}; ++ ++struct rtw89_btc_wl_scan_info { ++ u8 band[RTW89_PHY_MAX]; ++ u8 phy_map; ++ u8 rsvd; ++}; ++ ++struct rtw89_btc_wl_dbcc_info { ++ u8 op_band[RTW89_PHY_MAX]; /* op band in each phy */ ++ u8 scan_band[RTW89_PHY_MAX]; /* scan band in each phy */ ++ u8 real_band[RTW89_PHY_MAX]; ++ u8 role[RTW89_PHY_MAX]; /* role in each phy */ ++}; ++ ++struct rtw89_btc_wl_active_role { ++ u8 connected: 1; ++ u8 pid: 3; ++ u8 phy: 1; ++ u8 noa: 1; ++ u8 band: 2; ++ ++ u8 client_ps: 1; ++ u8 bw: 7; ++ ++ u8 role; ++ u8 ch; ++ ++ u16 tx_lvl; ++ u16 rx_lvl; ++ u16 tx_rate; ++ u16 rx_rate; ++}; ++ ++struct rtw89_btc_wl_role_info_bpos { ++ u16 none: 1; ++ u16 station: 1; ++ u16 ap: 1; ++ u16 vap: 1; ++ u16 adhoc: 1; ++ u16 adhoc_master: 1; ++ u16 mesh: 1; ++ u16 moniter: 1; ++ u16 p2p_device: 1; ++ u16 p2p_gc: 1; ++ u16 p2p_go: 1; ++ u16 nan: 1; ++}; ++ ++union rtw89_btc_wl_role_info_map { ++ u16 val; ++ struct rtw89_btc_wl_role_info_bpos role; ++}; ++ ++struct rtw89_btc_wl_role_info { /* struct size must be n*4 bytes */ ++ u8 connect_cnt; ++ u8 link_mode; ++ union rtw89_btc_wl_role_info_map role_map; ++ struct rtw89_btc_wl_active_role active_role[RTW89_MAX_HW_PORT_NUM]; ++}; ++ ++struct rtw89_btc_wl_ver_info { ++ u32 fw_coex; /* match with which coex_ver */ ++ u32 fw; ++ u32 mac; ++ u32 bb; ++ u32 rf; ++}; ++ ++struct rtw89_btc_wl_afh_info { ++ u8 en; ++ u8 ch; ++ u8 bw; ++ u8 rsvd; ++} __packed; ++ ++struct rtw89_btc_wl_rfk_info { ++ u32 state: 2; ++ u32 path_map: 4; ++ u32 phy_map: 2; ++ u32 band: 2; ++ u32 type: 8; ++ u32 rsvd: 14; ++}; ++ ++struct rtw89_btc_bt_smap { ++ u32 connect: 1; ++ u32 ble_connect: 1; ++ u32 acl_busy: 1; ++ u32 sco_busy: 1; ++ u32 mesh_busy: 1; ++ u32 inq_pag: 1; ++}; ++ ++union rtw89_btc_bt_state_map { ++ u32 val; ++ struct rtw89_btc_bt_smap map; ++}; ++ ++#define BTC_BT_RSSI_THMAX 4 ++#define BTC_BT_AFH_GROUP 12 ++ ++struct rtw89_btc_bt_link_info { ++ struct rtw89_btc_u8_sta_chg profile_cnt; ++ struct rtw89_btc_bool_sta_chg multi_link; ++ struct rtw89_btc_bool_sta_chg relink; ++ struct rtw89_btc_bt_hfp_desc hfp_desc; ++ struct rtw89_btc_bt_hid_desc hid_desc; ++ struct rtw89_btc_bt_a2dp_desc a2dp_desc; ++ struct rtw89_btc_bt_pan_desc pan_desc; ++ union rtw89_btc_bt_state_map status; ++ ++ u8 sut_pwr_level[BTC_PROFILE_MAX]; ++ u8 golden_rx_shift[BTC_PROFILE_MAX]; ++ u8 rssi_state[BTC_BT_RSSI_THMAX]; ++ u8 afh_map[BTC_BT_AFH_GROUP]; ++ ++ u32 role_sw: 1; ++ u32 slave_role: 1; ++ u32 afh_update: 1; ++ u32 cqddr: 1; ++ u32 rssi: 8; ++ u32 tx_3m: 1; ++ u32 rsvd: 19; ++}; ++ ++struct rtw89_btc_3rdcx_info { ++ u8 type; /* 0: none, 1:zigbee, 2:LTE */ ++ u8 hw_coex; ++ u16 rsvd; ++}; ++ ++struct rtw89_btc_dm_emap { ++ u32 init: 1; ++ u32 pta_owner: 1; ++ u32 wl_rfk_timeout: 1; ++ u32 bt_rfk_timeout: 1; ++ ++ u32 wl_fw_hang: 1; ++ u32 offload_mismatch: 1; ++ u32 cycle_hang: 1; ++ u32 w1_hang: 1; ++ ++ u32 b1_hang: 1; ++ u32 tdma_no_sync: 1; ++ u32 wl_slot_drift: 1; ++}; ++ ++union rtw89_btc_dm_error_map { ++ u32 val; ++ struct rtw89_btc_dm_emap map; ++}; ++ ++struct rtw89_btc_rf_para { ++ u32 tx_pwr_freerun; ++ u32 rx_gain_freerun; ++ u32 tx_pwr_perpkt; ++ u32 rx_gain_perpkt; ++}; ++ ++struct rtw89_btc_wl_info { ++ struct rtw89_btc_wl_link_info link_info[RTW89_MAX_HW_PORT_NUM]; ++ struct rtw89_btc_wl_rfk_info rfk_info; ++ struct rtw89_btc_wl_ver_info ver_info; ++ struct rtw89_btc_wl_afh_info afh_info; ++ struct rtw89_btc_wl_role_info role_info; ++ struct rtw89_btc_wl_scan_info scan_info; ++ struct rtw89_btc_wl_dbcc_info dbcc_info; ++ struct rtw89_btc_rf_para rf_para; ++ union rtw89_btc_wl_state_map status; ++ ++ u8 port_id[RTW89_WIFI_ROLE_MLME_MAX]; ++ u8 rssi_level; ++ ++ u32 scbd; ++}; ++ ++struct rtw89_btc_module { ++ struct rtw89_btc_ant_info ant; ++ u8 rfe_type; ++ u8 cv; ++ ++ u8 bt_solo: 1; ++ u8 bt_pos: 1; ++ u8 switch_type: 1; ++ ++ u8 rsvd; ++}; ++ ++#define RTW89_BTC_DM_MAXSTEP 30 ++#define RTW89_BTC_DM_CNT_MAX (RTW89_BTC_DM_MAXSTEP * 8) ++ ++struct rtw89_btc_dm_step { ++ u16 step[RTW89_BTC_DM_MAXSTEP]; ++ u8 step_pos; ++ bool step_ov; ++}; ++ ++struct rtw89_btc_init_info { ++ struct rtw89_btc_module module; ++ u8 wl_guard_ch; ++ ++ u8 wl_only: 1; ++ u8 wl_init_ok: 1; ++ u8 dbcc_en: 1; ++ u8 cx_other: 1; ++ u8 bt_only: 1; ++ ++ u16 rsvd; ++}; ++ ++struct rtw89_btc_wl_tx_limit_para { ++ u16 enable; ++ u32 tx_time; /* unit: us */ ++ u16 tx_retry; ++}; ++ ++struct rtw89_btc_bt_scan_info { ++ u16 win; ++ u16 intvl; ++ u32 enable: 1; ++ u32 interlace: 1; ++ u32 rsvd: 30; ++}; ++ ++enum rtw89_btc_bt_scan_type { ++ BTC_SCAN_INQ = 0, ++ BTC_SCAN_PAGE, ++ BTC_SCAN_BLE, ++ BTC_SCAN_INIT, ++ BTC_SCAN_TV, ++ BTC_SCAN_ADV, ++ BTC_SCAN_MAX1, ++}; ++ ++struct rtw89_btc_bt_info { ++ struct rtw89_btc_bt_link_info link_info; ++ struct rtw89_btc_bt_scan_info scan_info[BTC_SCAN_MAX1]; ++ struct rtw89_btc_bt_ver_info ver_info; ++ struct rtw89_btc_bool_sta_chg enable; ++ struct rtw89_btc_bool_sta_chg inq_pag; ++ struct rtw89_btc_rf_para rf_para; ++ union rtw89_btc_bt_rfk_info_map rfk_info; ++ ++ u8 raw_info[BTC_BTINFO_MAX]; /* raw bt info from mailbox */ ++ ++ u32 scbd; ++ u32 feature; ++ ++ u32 mbx_avl: 1; ++ u32 whql_test: 1; ++ u32 igno_wl: 1; ++ u32 reinit: 1; ++ u32 ble_scan_en: 1; ++ u32 btg_type: 1; ++ u32 inq: 1; ++ u32 pag: 1; ++ u32 run_patch_code: 1; ++ u32 hi_lna_rx: 1; ++ u32 rsvd: 22; ++}; ++ ++struct rtw89_btc_cx { ++ struct rtw89_btc_wl_info wl; ++ struct rtw89_btc_bt_info bt; ++ struct rtw89_btc_3rdcx_info other; ++ u32 state_map; ++ u32 cnt_bt[BTC_BCNT_NUM]; ++ u32 cnt_wl[BTC_WCNT_NUM]; ++}; ++ ++struct rtw89_btc_fbtc_tdma { ++ u8 type; ++ u8 rxflctrl; ++ u8 txpause; ++ u8 wtgle_n; ++ u8 leak_n; ++ u8 ext_ctrl; ++ u8 rsvd0; ++ u8 rsvd1; ++} __packed; ++ ++#define CXMREG_MAX 30 ++#define FCXMAX_STEP 255 /*STEP trace record cnt, Max:65535, default:255*/ ++#define BTCRPT_VER 1 ++#define BTC_CYCLE_SLOT_MAX 48 /* must be even number, non-zero */ ++ ++enum rtw89_btc_bt_rfk_counter { ++ BTC_BCNT_RFK_REQ = 0, ++ BTC_BCNT_RFK_GO = 1, ++ BTC_BCNT_RFK_REJECT = 2, ++ BTC_BCNT_RFK_FAIL = 3, ++ BTC_BCNT_RFK_TIMEOUT = 4, ++ BTC_BCNT_RFK_MAX ++}; ++ ++struct rtw89_btc_fbtc_rpt_ctrl { ++ u16 fver; ++ u16 rpt_cnt; /* tmr counters */ ++ u32 wl_fw_coex_ver; /* match which driver's coex version */ ++ u32 wl_fw_cx_offload; ++ u32 wl_fw_ver; ++ u32 rpt_enable; ++ u32 rpt_para; /* ms */ ++ u32 mb_send_fail_cnt; /* fw send mailbox fail counter */ ++ u32 mb_send_ok_cnt; /* fw send mailbox ok counter */ ++ u32 mb_recv_cnt; /* fw recv mailbox counter */ ++ u32 mb_a2dp_empty_cnt; /* a2dp empty count */ ++ u32 mb_a2dp_flct_cnt; /* a2dp empty flow control counter */ ++ u32 mb_a2dp_full_cnt; /* a2dp empty full counter */ ++ u32 bt_rfk_cnt[BTC_BCNT_RFK_MAX]; ++ u32 c2h_cnt; /* fw send c2h counter */ ++ u32 h2c_cnt; /* fw recv h2c counter */ ++} __packed; ++ ++enum rtw89_fbtc_ext_ctrl_type { ++ CXECTL_OFF = 0x0, /* tdma off */ ++ CXECTL_B2 = 0x1, /* allow B2 (beacon-early) */ ++ CXECTL_EXT = 0x2, ++ CXECTL_MAX ++}; ++ ++union rtw89_btc_fbtc_rxflct { ++ u8 val; ++ u8 type: 3; ++ u8 tgln_n: 5; ++}; ++ ++enum rtw89_btc_cxst_state { ++ CXST_OFF = 0x0, ++ CXST_B2W = 0x1, ++ CXST_W1 = 0x2, ++ CXST_W2 = 0x3, ++ CXST_W2B = 0x4, ++ CXST_B1 = 0x5, ++ CXST_B2 = 0x6, ++ CXST_B3 = 0x7, ++ CXST_B4 = 0x8, ++ CXST_LK = 0x9, ++ CXST_BLK = 0xa, ++ CXST_E2G = 0xb, ++ CXST_E5G = 0xc, ++ CXST_EBT = 0xd, ++ CXST_ENULL = 0xe, ++ CXST_WLK = 0xf, ++ CXST_W1FDD = 0x10, ++ CXST_B1FDD = 0x11, ++ CXST_MAX = 0x12, ++}; ++ ++enum { ++ CXBCN_ALL = 0x0, ++ CXBCN_ALL_OK, ++ CXBCN_BT_SLOT, ++ CXBCN_BT_OK, ++ CXBCN_MAX ++}; ++ ++enum btc_slot_type { ++ SLOT_MIX = 0x0, /* accept BT Lower-Pri Tx/Rx request 0x778 = 1 */ ++ SLOT_ISO = 0x1, /* no accept BT Lower-Pri Tx/Rx request 0x778 = d*/ ++ CXSTYPE_NUM, ++}; ++ ++enum { /* TIME */ ++ CXT_BT = 0x0, ++ CXT_WL = 0x1, ++ CXT_MAX ++}; ++ ++enum { /* TIME-A2DP */ ++ CXT_FLCTRL_OFF = 0x0, ++ CXT_FLCTRL_ON = 0x1, ++ CXT_FLCTRL_MAX ++}; ++ ++enum { /* STEP TYPE */ ++ CXSTEP_NONE = 0x0, ++ CXSTEP_EVNT = 0x1, ++ CXSTEP_SLOT = 0x2, ++ CXSTEP_MAX, ++}; ++ ++#define FCXGPIODBG_VER 1 ++#define BTC_DBG_MAX1 32 ++struct rtw89_btc_fbtc_gpio_dbg { ++ u8 fver; ++ u8 rsvd; ++ u16 rsvd2; ++ u32 en_map; /* which debug signal (see btc_wl_gpio_debug) is enable */ ++ u32 pre_state; /* the debug signal is 1 or 0 */ ++ u8 gpio_map[BTC_DBG_MAX1]; /*the debug signals to GPIO-Position */ ++} __packed; ++ ++#define FCXMREG_VER 1 ++struct rtw89_btc_fbtc_mreg_val { ++ u8 fver; ++ u8 reg_num; ++ __le16 rsvd; ++ __le32 mreg_val[CXMREG_MAX]; ++} __packed; ++ ++#define RTW89_DEF_FBTC_MREG(__type, __bytes, __offset) \ ++ { .type = cpu_to_le16(__type), .bytes = cpu_to_le16(__bytes), \ ++ .offset = cpu_to_le32(__offset), } ++ ++struct rtw89_btc_fbtc_mreg { ++ __le16 type; ++ __le16 bytes; ++ __le32 offset; ++} __packed; ++ ++struct rtw89_btc_fbtc_slot { ++ __le16 dur; ++ __le32 cxtbl; ++ __le16 cxtype; ++} __packed; ++ ++#define FCXSLOTS_VER 1 ++struct rtw89_btc_fbtc_slots { ++ u8 fver; ++ u8 tbl_num; ++ __le16 rsvd; ++ __le32 update_map; ++ struct rtw89_btc_fbtc_slot slot[CXST_MAX]; ++} __packed; ++ ++#define FCXSTEP_VER 2 ++struct rtw89_btc_fbtc_step { ++ u8 type; ++ u8 val; ++ __le16 difft; ++} __packed; ++ ++struct rtw89_btc_fbtc_steps { ++ u8 fver; ++ u8 rsvd; ++ __le16 cnt; ++ __le16 pos_old; ++ __le16 pos_new; ++ struct rtw89_btc_fbtc_step step[FCXMAX_STEP]; ++} __packed; ++ ++#define FCXCYSTA_VER 2 ++struct rtw89_btc_fbtc_cysta { /* statistics for cycles */ ++ u8 fver; ++ u8 rsvd; ++ __le16 cycles; /* total cycle number */ ++ __le16 cycles_a2dp[CXT_FLCTRL_MAX]; ++ __le16 a2dpept; /* a2dp empty cnt */ ++ __le16 a2dpeptto; /* a2dp empty timeout cnt*/ ++ __le16 tavg_cycle[CXT_MAX]; /* avg wl/bt cycle time */ ++ __le16 tmax_cycle[CXT_MAX]; /* max wl/bt cycle time */ ++ __le16 tmaxdiff_cycle[CXT_MAX]; /* max wl-wl bt-bt cycle diff time */ ++ __le16 tavg_a2dp[CXT_FLCTRL_MAX]; /* avg a2dp PSTDMA/TDMA time */ ++ __le16 tmax_a2dp[CXT_FLCTRL_MAX]; /* max a2dp PSTDMA/TDMA time */ ++ __le16 tavg_a2dpept; /* avg a2dp empty time */ ++ __le16 tmax_a2dpept; /* max a2dp empty time */ ++ __le16 tavg_lk; /* avg leak-slot time */ ++ __le16 tmax_lk; /* max leak-slot time */ ++ __le32 slot_cnt[CXST_MAX]; /* slot count */ ++ __le32 bcn_cnt[CXBCN_MAX]; ++ __le32 leakrx_cnt; /* the rximr occur at leak slot */ ++ __le32 collision_cnt; /* counter for event/timer occur at same time */ ++ __le32 skip_cnt; ++ __le32 exception; ++ __le32 except_cnt; ++ __le16 tslot_cycle[BTC_CYCLE_SLOT_MAX]; ++} __packed; ++ ++#define FCXNULLSTA_VER 1 ++struct rtw89_btc_fbtc_cynullsta { /* cycle null statistics */ ++ u8 fver; ++ u8 rsvd; ++ __le16 rsvd2; ++ __le32 max_t[2]; /* max_t for 0:null0/1:null1 */ ++ __le32 avg_t[2]; /* avg_t for 0:null0/1:null1 */ ++ __le32 result[2][4]; /* 0:fail, 1:ok, 2:on_time, 3:retry */ ++} __packed; ++ ++#define FCX_BTVER_VER 1 ++struct rtw89_btc_fbtc_btver { ++ u8 fver; ++ u8 rsvd; ++ __le16 rsvd2; ++ __le32 coex_ver; /*bit[15:8]->shared, bit[7:0]->non-shared */ ++ __le32 fw_ver; ++ __le32 feature; ++} __packed; ++ ++#define FCX_BTSCAN_VER 1 ++struct rtw89_btc_fbtc_btscan { ++ u8 fver; ++ u8 rsvd; ++ __le16 rsvd2; ++ u8 scan[6]; ++} __packed; ++ ++#define FCX_BTAFH_VER 1 ++struct rtw89_btc_fbtc_btafh { ++ u8 fver; ++ u8 rsvd; ++ __le16 rsvd2; ++ u8 afh_l[4]; /*bit0:2402, bit1: 2403.... bit31:2433 */ ++ u8 afh_m[4]; /*bit0:2434, bit1: 2435.... bit31:2465 */ ++ u8 afh_h[4]; /*bit0:2466, bit1:2467......bit14:2480 */ ++} __packed; ++ ++#define FCX_BTDEVINFO_VER 1 ++struct rtw89_btc_fbtc_btdevinfo { ++ u8 fver; ++ u8 rsvd; ++ __le16 vendor_id; ++ __le32 dev_name; /* only 24 bits valid */ ++ __le32 flush_time; ++} __packed; ++ ++#define RTW89_BTC_WL_DEF_TX_PWR GENMASK(7, 0) ++struct rtw89_btc_rf_trx_para { ++ u32 wl_tx_power; /* absolute Tx power (dBm), 0xff-> no BTC control */ ++ u32 wl_rx_gain; /* rx gain table index (TBD.) */ ++ u8 bt_tx_power; /* decrease Tx power (dB) */ ++ u8 bt_rx_gain; /* LNA constrain level */ ++}; ++ ++struct rtw89_btc_dm { ++ struct rtw89_btc_fbtc_slot slot[CXST_MAX]; ++ struct rtw89_btc_fbtc_slot slot_now[CXST_MAX]; ++ struct rtw89_btc_fbtc_tdma tdma; ++ struct rtw89_btc_fbtc_tdma tdma_now; ++ struct rtw89_mac_ax_coex_gnt gnt; ++ struct rtw89_btc_init_info init_info; /* pass to wl_fw if offload */ ++ struct rtw89_btc_rf_trx_para rf_trx_para; ++ struct rtw89_btc_wl_tx_limit_para wl_tx_limit; ++ struct rtw89_btc_dm_step dm_step; ++ union rtw89_btc_dm_error_map error; ++ u32 cnt_dm[BTC_DCNT_NUM]; ++ u32 cnt_notify[BTC_NCNT_NUM]; ++ ++ u32 update_slot_map; ++ u32 set_ant_path; ++ ++ u32 wl_only: 1; ++ u32 wl_fw_cx_offload: 1; ++ u32 freerun: 1; ++ u32 wl_ps_ctrl: 2; ++ u32 wl_mimo_ps: 1; ++ u32 leak_ap: 1; ++ u32 noisy_level: 3; ++ u32 coex_info_map: 8; ++ u32 bt_only: 1; ++ u32 wl_btg_rx: 1; ++ u32 trx_para_level: 8; ++ u32 wl_stb_chg: 1; ++ u32 rsvd: 3; ++ ++ u16 slot_dur[CXST_MAX]; ++ ++ u8 run_reason; ++ u8 run_action; ++}; ++ ++struct rtw89_btc_ctrl { ++ u32 manual: 1; ++ u32 igno_bt: 1; ++ u32 always_freerun: 1; ++ u32 trace_step: 16; ++ u32 rsvd: 12; ++}; ++ ++struct rtw89_btc_dbg { ++ /* cmd "rb" */ ++ bool rb_done; ++ u32 rb_val; ++}; ++ ++#define FCXTDMA_VER 1 ++ ++enum rtw89_btc_btf_fw_event { ++ BTF_EVNT_RPT = 0, ++ BTF_EVNT_BT_INFO = 1, ++ BTF_EVNT_BT_SCBD = 2, ++ BTF_EVNT_BT_REG = 3, ++ BTF_EVNT_CX_RUNINFO = 4, ++ BTF_EVNT_BT_PSD = 5, ++ BTF_EVNT_BUF_OVERFLOW, ++ BTF_EVNT_C2H_LOOPBACK, ++ BTF_EVNT_MAX, ++}; ++ ++enum btf_fw_event_report { ++ BTC_RPT_TYPE_CTRL = 0x0, ++ BTC_RPT_TYPE_TDMA, ++ BTC_RPT_TYPE_SLOT, ++ BTC_RPT_TYPE_CYSTA, ++ BTC_RPT_TYPE_STEP, ++ BTC_RPT_TYPE_NULLSTA, ++ BTC_RPT_TYPE_MREG, ++ BTC_RPT_TYPE_GPIO_DBG, ++ BTC_RPT_TYPE_BT_VER, ++ BTC_RPT_TYPE_BT_SCAN, ++ BTC_RPT_TYPE_BT_AFH, ++ BTC_RPT_TYPE_BT_DEVICE, ++ BTC_RPT_TYPE_TEST, ++ BTC_RPT_TYPE_MAX = 31 ++}; ++ ++enum rtw_btc_btf_reg_type { ++ REG_MAC = 0x0, ++ REG_BB = 0x1, ++ REG_RF = 0x2, ++ REG_BT_RF = 0x3, ++ REG_BT_MODEM = 0x4, ++ REG_BT_BLUEWIZE = 0x5, ++ REG_BT_VENDOR = 0x6, ++ REG_BT_LE = 0x7, ++ REG_MAX_TYPE, ++}; ++ ++struct rtw89_btc_rpt_cmn_info { ++ u32 rx_cnt; ++ u32 rx_len; ++ u32 req_len; /* expected rsp len */ ++ u8 req_fver; /* expected rsp fver */ ++ u8 rsp_fver; /* fver from fw */ ++ u8 valid; ++} __packed; ++ ++struct rtw89_btc_report_ctrl_state { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_rpt_ctrl finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_tdma { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_tdma finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_slots { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_slots finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_cysta { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_cysta finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_step { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_steps finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_nullsta { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_cynullsta finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_mreg { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_mreg_val finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_gpio_dbg { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_gpio_dbg finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_btver { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_btver finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_btscan { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_btscan finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_btafh { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_btafh finfo; /* info from fw */ ++}; ++ ++struct rtw89_btc_rpt_fbtc_btdev { ++ struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ ++ struct rtw89_btc_fbtc_btdevinfo finfo; /* info from fw */ ++}; ++ ++enum rtw89_btc_btfre_type { ++ BTFRE_INVALID_INPUT = 0x0, /* invalid input parameters */ ++ BTFRE_UNDEF_TYPE, ++ BTFRE_EXCEPTION, ++ BTFRE_MAX, ++}; ++ ++struct rtw89_btc_btf_fwinfo { ++ u32 cnt_c2h; ++ u32 cnt_h2c; ++ u32 cnt_h2c_fail; ++ u32 event[BTF_EVNT_MAX]; ++ ++ u32 err[BTFRE_MAX]; ++ u32 len_mismch; ++ u32 fver_mismch; ++ u32 rpt_en_map; ++ ++ struct rtw89_btc_report_ctrl_state rpt_ctrl; ++ struct rtw89_btc_rpt_fbtc_tdma rpt_fbtc_tdma; ++ struct rtw89_btc_rpt_fbtc_slots rpt_fbtc_slots; ++ struct rtw89_btc_rpt_fbtc_cysta rpt_fbtc_cysta; ++ struct rtw89_btc_rpt_fbtc_step rpt_fbtc_step; ++ struct rtw89_btc_rpt_fbtc_nullsta rpt_fbtc_nullsta; ++ struct rtw89_btc_rpt_fbtc_mreg rpt_fbtc_mregval; ++ struct rtw89_btc_rpt_fbtc_gpio_dbg rpt_fbtc_gpio_dbg; ++ struct rtw89_btc_rpt_fbtc_btver rpt_fbtc_btver; ++ struct rtw89_btc_rpt_fbtc_btscan rpt_fbtc_btscan; ++ struct rtw89_btc_rpt_fbtc_btafh rpt_fbtc_btafh; ++ struct rtw89_btc_rpt_fbtc_btdev rpt_fbtc_btdev; ++}; ++ ++#define RTW89_BTC_POLICY_MAXLEN 512 ++ ++struct rtw89_btc { ++ struct rtw89_btc_cx cx; ++ struct rtw89_btc_dm dm; ++ struct rtw89_btc_ctrl ctrl; ++ struct rtw89_btc_module mdinfo; ++ struct rtw89_btc_btf_fwinfo fwinfo; ++ struct rtw89_btc_dbg dbg; ++ ++ struct work_struct eapol_notify_work; ++ struct work_struct arp_notify_work; ++ struct work_struct dhcp_notify_work; ++ struct work_struct icmp_notify_work; ++ ++ u32 bt_req_len; ++ ++ u8 policy[RTW89_BTC_POLICY_MAXLEN]; ++ u16 policy_len; ++ u16 policy_type; ++ bool bt_req_en; ++ bool update_policy_force; ++ bool lps; ++}; ++ ++enum rtw89_ra_mode { ++ RTW89_RA_MODE_CCK = BIT(0), ++ RTW89_RA_MODE_OFDM = BIT(1), ++ RTW89_RA_MODE_HT = BIT(2), ++ RTW89_RA_MODE_VHT = BIT(3), ++ RTW89_RA_MODE_HE = BIT(4), ++}; ++ ++enum rtw89_ra_report_mode { ++ RTW89_RA_RPT_MODE_LEGACY, ++ RTW89_RA_RPT_MODE_HT, ++ RTW89_RA_RPT_MODE_VHT, ++ RTW89_RA_RPT_MODE_HE, ++}; ++ ++enum rtw89_dig_noisy_level { ++ RTW89_DIG_NOISY_LEVEL0 = -1, ++ RTW89_DIG_NOISY_LEVEL1 = 0, ++ RTW89_DIG_NOISY_LEVEL2 = 1, ++ RTW89_DIG_NOISY_LEVEL3 = 2, ++ RTW89_DIG_NOISY_LEVEL_MAX = 3, ++}; ++ ++enum rtw89_gi_ltf { ++ RTW89_GILTF_LGI_4XHE32 = 0, ++ RTW89_GILTF_SGI_4XHE08 = 1, ++ RTW89_GILTF_2XHE16 = 2, ++ RTW89_GILTF_2XHE08 = 3, ++ RTW89_GILTF_1XHE16 = 4, ++ RTW89_GILTF_1XHE08 = 5, ++ RTW89_GILTF_MAX ++}; ++ ++enum rtw89_rx_frame_type { ++ RTW89_RX_TYPE_MGNT = 0, ++ RTW89_RX_TYPE_CTRL = 1, ++ RTW89_RX_TYPE_DATA = 2, ++ RTW89_RX_TYPE_RSVD = 3, ++}; ++ ++struct rtw89_ra_info { ++ u8 is_dis_ra:1; ++ /* Bit0 : CCK ++ * Bit1 : OFDM ++ * Bit2 : HT ++ * Bit3 : VHT ++ * Bit4 : HE ++ */ ++ u8 mode_ctrl:5; ++ u8 bw_cap:2; ++ u8 macid; ++ u8 dcm_cap:1; ++ u8 er_cap:1; ++ u8 init_rate_lv:2; ++ u8 upd_all:1; ++ u8 en_sgi:1; ++ u8 ldpc_cap:1; ++ u8 stbc_cap:1; ++ u8 ss_num:3; ++ u8 giltf:3; ++ u8 upd_bw_nss_mask:1; ++ u8 upd_mask:1; ++ u64 ra_mask; /* 63 bits ra_mask + 1 bit CSI ctrl */ ++ /* BFee CSI */ ++ u8 band_num; ++ u8 ra_csi_rate_en:1; ++ u8 fixed_csi_rate_en:1; ++ u8 cr_tbl_sel:1; ++ u8 rsvd2:5; ++ u8 csi_mcs_ss_idx; ++ u8 csi_mode:2; ++ u8 csi_gi_ltf:3; ++ u8 csi_bw:3; ++}; ++ ++#define RTW89_PPDU_MAX_USR 4 ++#define RTW89_PPDU_MAC_INFO_USR_SIZE 4 ++#define RTW89_PPDU_MAC_INFO_SIZE 8 ++#define RTW89_PPDU_MAC_RX_CNT_SIZE 96 ++ ++#define RTW89_MAX_RX_AGG_NUM 64 ++#define RTW89_MAX_TX_AGG_NUM 128 ++ ++struct rtw89_ampdu_params { ++ u16 agg_num; ++ bool amsdu; ++}; ++ ++struct rtw89_ra_report { ++ struct rate_info txrate; ++ u32 bit_rate; ++ u16 hw_rate; ++}; ++ ++DECLARE_EWMA(rssi, 10, 16); ++ ++struct rtw89_sta { ++ u8 mac_id; ++ bool disassoc; ++ struct rtw89_vif *rtwvif; ++ struct rtw89_ra_info ra; ++ struct rtw89_ra_report ra_report; ++ int max_agg_wait; ++ u8 prev_rssi; ++ struct ewma_rssi avg_rssi; ++ struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS]; ++ struct ieee80211_rx_status rx_status; ++ u16 rx_hw_rate; ++ __le32 htc_template; ++ ++ bool use_cfg_mask; ++ struct cfg80211_bitrate_mask mask; ++ ++ bool cctl_tx_time; ++ u32 ampdu_max_time:4; ++ bool cctl_tx_retry_limit; ++ u32 data_tx_cnt_lmt:6; ++}; ++ ++#define RTW89_MAX_ADDR_CAM_NUM 128 ++#define RTW89_MAX_BSSID_CAM_NUM 20 ++#define RTW89_MAX_SEC_CAM_NUM 128 ++#define RTW89_SEC_CAM_IN_ADDR_CAM 7 ++ ++struct rtw89_addr_cam_entry { ++ u8 addr_cam_idx; ++ u8 offset; ++ u8 len; ++ u8 valid : 1; ++ u8 addr_mask : 6; ++ u8 wapi : 1; ++ u8 mask_sel : 2; ++ u8 bssid_cam_idx: 6; ++ u8 tma[ETH_ALEN]; ++ u8 sma[ETH_ALEN]; ++ ++ u8 sec_ent_mode; ++ DECLARE_BITMAP(sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM); ++ u8 sec_ent_keyid[RTW89_SEC_CAM_IN_ADDR_CAM]; ++ u8 sec_ent[RTW89_SEC_CAM_IN_ADDR_CAM]; ++ struct rtw89_sec_cam_entry *sec_entries[RTW89_SEC_CAM_IN_ADDR_CAM]; ++}; ++ ++struct rtw89_bssid_cam_entry { ++ u8 bssid[ETH_ALEN]; ++ u8 phy_idx; ++ u8 bssid_cam_idx; ++ u8 offset; ++ u8 len; ++ u8 valid : 1; ++ u8 num; ++}; ++ ++struct rtw89_sec_cam_entry { ++ u8 sec_cam_idx; ++ u8 offset; ++ u8 len; ++ u8 type : 4; ++ u8 ext_key : 1; ++ u8 spp_mode : 1; ++ /* 256 bits */ ++ u8 key[32]; ++}; ++ ++struct rtw89_efuse { ++ bool valid; ++ u8 xtal_cap; ++ u8 addr[ETH_ALEN]; ++ u8 rfe_type; ++ char country_code[2]; ++}; ++ ++struct rtw89_phy_rate_pattern { ++ u64 ra_mask; ++ u16 rate; ++ u8 ra_mode; ++ bool enable; ++}; ++ ++struct rtw89_vif { ++ struct list_head list; ++ u8 mac_id; ++ u8 port; ++ u8 mac_addr[ETH_ALEN]; ++ u8 bssid[ETH_ALEN]; ++ u8 phy_idx; ++ u8 mac_idx; ++ u8 net_type; ++ u8 wifi_role; ++ u8 self_role; ++ u8 wmm; ++ u8 bcn_hit_cond; ++ u8 hit_rule; ++ bool trigger; ++ bool lsig_txop; ++ u8 tgt_ind; ++ u8 frm_tgt_ind; ++ bool wowlan_pattern; ++ bool wowlan_uc; ++ bool wowlan_magic; ++ bool is_hesta; ++ bool last_a_ctrl; ++ union { ++ struct { ++ struct ieee80211_sta *ap; ++ } mgd; ++ struct { ++ struct list_head sta_list; ++ } ap; ++ }; ++ struct rtw89_addr_cam_entry addr_cam; ++ struct rtw89_bssid_cam_entry bssid_cam; ++ struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS]; ++ struct rtw89_traffic_stats stats; ++ struct rtw89_phy_rate_pattern rate_pattern; ++}; ++ ++enum rtw89_lv1_rcvy_step { ++ RTW89_LV1_RCVY_STEP_1, ++ RTW89_LV1_RCVY_STEP_2, ++}; ++ ++struct rtw89_hci_ops { ++ int (*tx_write)(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req); ++ void (*tx_kick_off)(struct rtw89_dev *rtwdev, u8 txch); ++ void (*flush_queues)(struct rtw89_dev *rtwdev, u32 queues, bool drop); ++ void (*reset)(struct rtw89_dev *rtwdev); ++ int (*start)(struct rtw89_dev *rtwdev); ++ void (*stop)(struct rtw89_dev *rtwdev); ++ void (*recalc_int_mit)(struct rtw89_dev *rtwdev); ++ ++ u8 (*read8)(struct rtw89_dev *rtwdev, u32 addr); ++ u16 (*read16)(struct rtw89_dev *rtwdev, u32 addr); ++ u32 (*read32)(struct rtw89_dev *rtwdev, u32 addr); ++ void (*write8)(struct rtw89_dev *rtwdev, u32 addr, u8 data); ++ void (*write16)(struct rtw89_dev *rtwdev, u32 addr, u16 data); ++ void (*write32)(struct rtw89_dev *rtwdev, u32 addr, u32 data); ++ ++ int (*mac_pre_init)(struct rtw89_dev *rtwdev); ++ int (*mac_post_init)(struct rtw89_dev *rtwdev); ++ int (*deinit)(struct rtw89_dev *rtwdev); ++ ++ u32 (*check_and_reclaim_tx_resource)(struct rtw89_dev *rtwdev, u8 txch); ++ int (*mac_lv1_rcvy)(struct rtw89_dev *rtwdev, enum rtw89_lv1_rcvy_step step); ++ void (*dump_err_status)(struct rtw89_dev *rtwdev); ++ int (*napi_poll)(struct napi_struct *napi, int budget); ++}; ++ ++struct rtw89_hci_info { ++ const struct rtw89_hci_ops *ops; ++ enum rtw89_hci_type type; ++ u32 rpwm_addr; ++ u32 cpwm_addr; ++}; ++ ++struct rtw89_chip_ops { ++ void (*bb_reset)(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx); ++ void (*bb_sethw)(struct rtw89_dev *rtwdev); ++ u32 (*read_rf)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask); ++ bool (*write_rf)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask, u32 data); ++ void (*set_channel)(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_params *param); ++ void (*set_channel_help)(struct rtw89_dev *rtwdev, bool enter, ++ struct rtw89_channel_help_params *p); ++ int (*read_efuse)(struct rtw89_dev *rtwdev, u8 *log_map); ++ int (*read_phycap)(struct rtw89_dev *rtwdev, u8 *phycap_map); ++ void (*fem_setup)(struct rtw89_dev *rtwdev); ++ void (*rfk_init)(struct rtw89_dev *rtwdev); ++ void (*rfk_channel)(struct rtw89_dev *rtwdev); ++ void (*rfk_band_changed)(struct rtw89_dev *rtwdev); ++ void (*rfk_scan)(struct rtw89_dev *rtwdev, bool start); ++ void (*rfk_track)(struct rtw89_dev *rtwdev); ++ void (*power_trim)(struct rtw89_dev *rtwdev); ++ void (*set_txpwr)(struct rtw89_dev *rtwdev); ++ void (*set_txpwr_ctrl)(struct rtw89_dev *rtwdev); ++ int (*init_txpwr_unit)(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); ++ u8 (*get_thermal)(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path); ++ void (*ctrl_btg)(struct rtw89_dev *rtwdev, bool btg); ++ void (*query_ppdu)(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_phy_ppdu *phy_ppdu, ++ struct ieee80211_rx_status *status); ++ void (*bb_ctrl_btc_preagc)(struct rtw89_dev *rtwdev, bool bt_en); ++ void (*set_txpwr_ul_tb_offset)(struct rtw89_dev *rtwdev, ++ s16 pw_ofst, enum rtw89_mac_idx mac_idx); ++ ++ void (*btc_set_rfe)(struct rtw89_dev *rtwdev); ++ void (*btc_init_cfg)(struct rtw89_dev *rtwdev); ++ void (*btc_set_wl_pri)(struct rtw89_dev *rtwdev, u8 map, bool state); ++ void (*btc_set_wl_txpwr_ctrl)(struct rtw89_dev *rtwdev, u32 txpwr_val); ++ s8 (*btc_get_bt_rssi)(struct rtw89_dev *rtwdev, s8 val); ++ void (*btc_bt_aci_imp)(struct rtw89_dev *rtwdev); ++ void (*btc_update_bt_cnt)(struct rtw89_dev *rtwdev); ++ void (*btc_wl_s1_standby)(struct rtw89_dev *rtwdev, bool state); ++}; ++ ++enum rtw89_dma_ch { ++ RTW89_DMA_ACH0 = 0, ++ RTW89_DMA_ACH1 = 1, ++ RTW89_DMA_ACH2 = 2, ++ RTW89_DMA_ACH3 = 3, ++ RTW89_DMA_ACH4 = 4, ++ RTW89_DMA_ACH5 = 5, ++ RTW89_DMA_ACH6 = 6, ++ RTW89_DMA_ACH7 = 7, ++ RTW89_DMA_B0MG = 8, ++ RTW89_DMA_B0HI = 9, ++ RTW89_DMA_B1MG = 10, ++ RTW89_DMA_B1HI = 11, ++ RTW89_DMA_H2C = 12, ++ RTW89_DMA_CH_NUM = 13 ++}; ++ ++enum rtw89_qta_mode { ++ RTW89_QTA_SCC, ++ RTW89_QTA_DLFW, ++ ++ /* keep last */ ++ RTW89_QTA_INVALID, ++}; ++ ++struct rtw89_hfc_ch_cfg { ++ u16 min; ++ u16 max; ++#define grp_0 0 ++#define grp_1 1 ++#define grp_num 2 ++ u8 grp; ++}; ++ ++struct rtw89_hfc_ch_info { ++ u16 aval; ++ u16 used; ++}; ++ ++struct rtw89_hfc_pub_cfg { ++ u16 grp0; ++ u16 grp1; ++ u16 pub_max; ++ u16 wp_thrd; ++}; ++ ++struct rtw89_hfc_pub_info { ++ u16 g0_used; ++ u16 g1_used; ++ u16 g0_aval; ++ u16 g1_aval; ++ u16 pub_aval; ++ u16 wp_aval; ++}; ++ ++struct rtw89_hfc_prec_cfg { ++ u16 ch011_prec; ++ u16 h2c_prec; ++ u16 wp_ch07_prec; ++ u16 wp_ch811_prec; ++ u8 ch011_full_cond; ++ u8 h2c_full_cond; ++ u8 wp_ch07_full_cond; ++ u8 wp_ch811_full_cond; ++}; ++ ++struct rtw89_hfc_param { ++ bool en; ++ bool h2c_en; ++ u8 mode; ++ const struct rtw89_hfc_ch_cfg *ch_cfg; ++ struct rtw89_hfc_ch_info ch_info[RTW89_DMA_CH_NUM]; ++ struct rtw89_hfc_pub_cfg pub_cfg; ++ struct rtw89_hfc_pub_info pub_info; ++ struct rtw89_hfc_prec_cfg prec_cfg; ++}; ++ ++struct rtw89_hfc_param_ini { ++ const struct rtw89_hfc_ch_cfg *ch_cfg; ++ const struct rtw89_hfc_pub_cfg *pub_cfg; ++ const struct rtw89_hfc_prec_cfg *prec_cfg; ++ u8 mode; ++}; ++ ++struct rtw89_dle_size { ++ u16 pge_size; ++ u16 lnk_pge_num; ++ u16 unlnk_pge_num; ++}; ++ ++struct rtw89_wde_quota { ++ u16 hif; ++ u16 wcpu; ++ u16 pkt_in; ++ u16 cpu_io; ++}; ++ ++struct rtw89_ple_quota { ++ u16 cma0_tx; ++ u16 cma1_tx; ++ u16 c2h; ++ u16 h2c; ++ u16 wcpu; ++ u16 mpdu_proc; ++ u16 cma0_dma; ++ u16 cma1_dma; ++ u16 bb_rpt; ++ u16 wd_rel; ++ u16 cpu_io; ++}; ++ ++struct rtw89_dle_mem { ++ enum rtw89_qta_mode mode; ++ const struct rtw89_dle_size *wde_size; ++ const struct rtw89_dle_size *ple_size; ++ const struct rtw89_wde_quota *wde_min_qt; ++ const struct rtw89_wde_quota *wde_max_qt; ++ const struct rtw89_ple_quota *ple_min_qt; ++ const struct rtw89_ple_quota *ple_max_qt; ++}; ++ ++struct rtw89_reg_def { ++ u32 addr; ++ u32 mask; ++}; ++ ++struct rtw89_reg2_def { ++ u32 addr; ++ u32 data; ++}; ++ ++struct rtw89_reg3_def { ++ u32 addr; ++ u32 mask; ++ u32 data; ++}; ++ ++struct rtw89_reg5_def { ++ u8 flag; /* recognized by parsers */ ++ u8 path; ++ u32 addr; ++ u32 mask; ++ u32 data; ++}; ++ ++struct rtw89_phy_table { ++ const struct rtw89_reg2_def *regs; ++ u32 n_regs; ++ enum rtw89_rf_path rf_path; ++}; ++ ++struct rtw89_txpwr_table { ++ const void *data; ++ u32 size; ++ void (*load)(struct rtw89_dev *rtwdev, ++ const struct rtw89_txpwr_table *tbl); ++}; ++ ++struct rtw89_chip_info { ++ enum rtw89_core_chip_id chip_id; ++ const struct rtw89_chip_ops *ops; ++ const char *fw_name; ++ u32 fifo_size; ++ u16 max_amsdu_limit; ++ bool dis_2g_40m_ul_ofdma; ++ const struct rtw89_hfc_param_ini *hfc_param_ini; ++ const struct rtw89_dle_mem *dle_mem; ++ u32 rf_base_addr[2]; ++ u8 rf_path_num; ++ u8 tx_nss; ++ u8 rx_nss; ++ u8 acam_num; ++ u8 bcam_num; ++ u8 scam_num; ++ ++ u8 sec_ctrl_efuse_size; ++ u32 physical_efuse_size; ++ u32 logical_efuse_size; ++ u32 limit_efuse_size; ++ u32 phycap_addr; ++ u32 phycap_size; ++ ++ const struct rtw89_pwr_cfg * const *pwr_on_seq; ++ const struct rtw89_pwr_cfg * const *pwr_off_seq; ++ const struct rtw89_phy_table *bb_table; ++ const struct rtw89_phy_table *rf_table[RF_PATH_MAX]; ++ const struct rtw89_phy_table *nctl_table; ++ const struct rtw89_txpwr_table *byr_table; ++ const struct rtw89_phy_dig_gain_table *dig_table; ++ const s8 (*txpwr_lmt_2g)[RTW89_2G_BW_NUM][RTW89_NTX_NUM] ++ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] ++ [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; ++ const s8 (*txpwr_lmt_5g)[RTW89_5G_BW_NUM][RTW89_NTX_NUM] ++ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] ++ [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; ++ const s8 (*txpwr_lmt_ru_2g)[RTW89_RU_NUM][RTW89_NTX_NUM] ++ [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; ++ const s8 (*txpwr_lmt_ru_5g)[RTW89_RU_NUM][RTW89_NTX_NUM] ++ [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; ++ ++ u8 txpwr_factor_rf; ++ u8 txpwr_factor_mac; ++ ++ u32 para_ver; ++ u32 wlcx_desired; ++ u8 btcx_desired; ++ u8 scbd; ++ u8 mailbox; ++ ++ u8 afh_guard_ch; ++ const u8 *wl_rssi_thres; ++ const u8 *bt_rssi_thres; ++ u8 rssi_tol; ++ ++ u8 mon_reg_num; ++ const struct rtw89_btc_fbtc_mreg *mon_reg; ++ u8 rf_para_ulink_num; ++ const struct rtw89_btc_rf_trx_para *rf_para_ulink; ++ u8 rf_para_dlink_num; ++ const struct rtw89_btc_rf_trx_para *rf_para_dlink; ++ u8 ps_mode_supported; ++}; ++ ++enum rtw89_hcifc_mode { ++ RTW89_HCIFC_POH = 0, ++ RTW89_HCIFC_STF = 1, ++ RTW89_HCIFC_SDIO = 2, ++ ++ /* keep last */ ++ RTW89_HCIFC_MODE_INVALID, ++}; ++ ++struct rtw89_dle_info { ++ enum rtw89_qta_mode qta_mode; ++ u16 wde_pg_size; ++ u16 ple_pg_size; ++ u16 c0_rx_qta; ++ u16 c1_rx_qta; ++}; ++ ++enum rtw89_host_rpr_mode { ++ RTW89_RPR_MODE_POH = 0, ++ RTW89_RPR_MODE_STF ++}; ++ ++struct rtw89_mac_info { ++ struct rtw89_dle_info dle_info; ++ struct rtw89_hfc_param hfc_param; ++ enum rtw89_qta_mode qta_mode; ++ u8 rpwm_seq_num; ++ u8 cpwm_seq_num; ++}; ++ ++enum rtw89_fw_type { ++ RTW89_FW_NORMAL = 1, ++ RTW89_FW_WOWLAN = 3, ++}; ++ ++struct rtw89_fw_suit { ++ const u8 *data; ++ u32 size; ++ u8 major_ver; ++ u8 minor_ver; ++ u8 sub_ver; ++ u8 sub_idex; ++ u16 build_year; ++ u16 build_mon; ++ u16 build_date; ++ u16 build_hour; ++ u16 build_min; ++ u8 cmd_ver; ++}; ++ ++#define RTW89_FW_VER_CODE(major, minor, sub, idx) \ ++ (((major) << 24) | ((minor) << 16) | ((sub) << 8) | (idx)) ++#define RTW89_FW_SUIT_VER_CODE(s) \ ++ RTW89_FW_VER_CODE((s)->major_ver, (s)->minor_ver, (s)->sub_ver, (s)->sub_idex) ++ ++struct rtw89_fw_info { ++ const struct firmware *firmware; ++ struct rtw89_dev *rtwdev; ++ struct completion completion; ++ u8 h2c_seq; ++ u8 rec_seq; ++ struct rtw89_fw_suit normal; ++ struct rtw89_fw_suit wowlan; ++ bool fw_log_enable; ++ bool old_ht_ra_format; ++}; ++ ++struct rtw89_cam_info { ++ DECLARE_BITMAP(addr_cam_map, RTW89_MAX_ADDR_CAM_NUM); ++ DECLARE_BITMAP(bssid_cam_map, RTW89_MAX_BSSID_CAM_NUM); ++ DECLARE_BITMAP(sec_cam_map, RTW89_MAX_SEC_CAM_NUM); ++}; ++ ++enum rtw89_sar_sources { ++ RTW89_SAR_SOURCE_NONE, ++ RTW89_SAR_SOURCE_COMMON, ++ ++ RTW89_SAR_SOURCE_NR, ++}; ++ ++struct rtw89_sar_cfg_common { ++ bool set[RTW89_SUBBAND_NR]; ++ s32 cfg[RTW89_SUBBAND_NR]; ++}; ++ ++struct rtw89_sar_info { ++ /* used to decide how to acces SAR cfg union */ ++ enum rtw89_sar_sources src; ++ ++ /* reserved for different knids of SAR cfg struct. ++ * supposed that a single cfg struct cannot handle various SAR sources. ++ */ ++ union { ++ struct rtw89_sar_cfg_common cfg_common; ++ }; ++}; ++ ++struct rtw89_hal { ++ u32 rx_fltr; ++ u8 cv; ++ u8 current_channel; ++ u8 current_primary_channel; ++ enum rtw89_subband current_subband; ++ u8 current_band_width; ++ u8 current_band_type; ++ /* center channel for different available bandwidth, ++ * val of (bw > current_band_width) is invalid ++ */ ++ u8 cch_by_bw[RTW89_MAX_CHANNEL_WIDTH + 1]; ++ u32 sw_amsdu_max_size; ++ u32 antenna_tx; ++ u32 antenna_rx; ++ u8 tx_nss; ++ u8 rx_nss; ++}; ++ ++#define RTW89_MAX_MAC_ID_NUM 128 ++ ++enum rtw89_flags { ++ RTW89_FLAG_POWERON, ++ RTW89_FLAG_FW_RDY, ++ RTW89_FLAG_RUNNING, ++ RTW89_FLAG_BFEE_MON, ++ RTW89_FLAG_BFEE_EN, ++ RTW89_FLAG_NAPI_RUNNING, ++ RTW89_FLAG_LEISURE_PS, ++ RTW89_FLAG_LOW_POWER_MODE, ++ RTW89_FLAG_INACTIVE_PS, ++ ++ NUM_OF_RTW89_FLAGS, ++}; ++ ++struct rtw89_pkt_stat { ++ u16 beacon_nr; ++ u32 rx_rate_cnt[RTW89_HW_RATE_NR]; ++}; ++ ++DECLARE_EWMA(thermal, 4, 4); ++ ++struct rtw89_phy_stat { ++ struct ewma_thermal avg_thermal[RF_PATH_MAX]; ++ struct rtw89_pkt_stat cur_pkt_stat; ++ struct rtw89_pkt_stat last_pkt_stat; ++}; ++ ++#define RTW89_DACK_PATH_NR 2 ++#define RTW89_DACK_IDX_NR 2 ++#define RTW89_DACK_MSBK_NR 16 ++struct rtw89_dack_info { ++ bool dack_done; ++ u8 msbk_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR][RTW89_DACK_MSBK_NR]; ++ u8 dadck_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR]; ++ u16 addck_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR]; ++ u16 biask_d[RTW89_DACK_PATH_NR][RTW89_DACK_IDX_NR]; ++ u32 dack_cnt; ++ bool addck_timeout[RTW89_DACK_PATH_NR]; ++ bool dadck_timeout[RTW89_DACK_PATH_NR]; ++ bool msbk_timeout[RTW89_DACK_PATH_NR]; ++}; ++ ++#define RTW89_IQK_CHS_NR 2 ++#define RTW89_IQK_PATH_NR 4 ++struct rtw89_iqk_info { ++ bool lok_cor_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; ++ bool lok_fin_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; ++ bool iqk_tx_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; ++ bool iqk_rx_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; ++ u32 iqk_fail_cnt; ++ bool is_iqk_init; ++ u32 iqk_channel[RTW89_IQK_CHS_NR]; ++ u8 iqk_band[RTW89_IQK_PATH_NR]; ++ u8 iqk_ch[RTW89_IQK_PATH_NR]; ++ u8 iqk_bw[RTW89_IQK_PATH_NR]; ++ u8 kcount; ++ u8 iqk_times; ++ u8 version; ++ u32 nb_txcfir[RTW89_IQK_PATH_NR]; ++ u32 nb_rxcfir[RTW89_IQK_PATH_NR]; ++ u32 bp_txkresult[RTW89_IQK_PATH_NR]; ++ u32 bp_rxkresult[RTW89_IQK_PATH_NR]; ++ u32 bp_iqkenable[RTW89_IQK_PATH_NR]; ++ bool is_wb_txiqk[RTW89_IQK_PATH_NR]; ++ bool is_wb_rxiqk[RTW89_IQK_PATH_NR]; ++ bool is_nbiqk; ++ bool iqk_fft_en; ++ bool iqk_xym_en; ++ bool iqk_sram_en; ++ bool iqk_cfir_en; ++ u8 thermal[RTW89_IQK_PATH_NR]; ++ bool thermal_rek_en; ++ u32 syn1to2; ++ u8 iqk_mcc_ch[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR]; ++ u8 iqk_table_idx[RTW89_IQK_PATH_NR]; ++}; ++ ++#define RTW89_DPK_RF_PATH 2 ++#define RTW89_DPK_AVG_THERMAL_NUM 8 ++#define RTW89_DPK_BKUP_NUM 2 ++struct rtw89_dpk_bkup_para { ++ enum rtw89_band band; ++ enum rtw89_bandwidth bw; ++ u8 ch; ++ bool path_ok; ++ u8 txagc_dpk; ++ u8 ther_dpk; ++ u8 gs; ++ u16 pwsf; ++}; ++ ++struct rtw89_dpk_info { ++ bool is_dpk_enable; ++ bool is_dpk_reload_en; ++ u16 dc_i[RTW89_DPK_RF_PATH]; ++ u16 dc_q[RTW89_DPK_RF_PATH]; ++ u8 corr_val[RTW89_DPK_RF_PATH]; ++ u8 corr_idx[RTW89_DPK_RF_PATH]; ++ u8 cur_idx[RTW89_DPK_RF_PATH]; ++ struct rtw89_dpk_bkup_para bp[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM]; ++}; ++ ++struct rtw89_fem_info { ++ bool elna_2g; ++ bool elna_5g; ++ bool epa_2g; ++ bool epa_5g; ++}; ++ ++struct rtw89_phy_ch_info { ++ u8 rssi_min; ++ u16 rssi_min_macid; ++ u8 pre_rssi_min; ++ u8 rssi_max; ++ u16 rssi_max_macid; ++ u8 rxsc_160; ++ u8 rxsc_80; ++ u8 rxsc_40; ++ u8 rxsc_20; ++ u8 rxsc_l; ++ u8 is_noisy; ++}; ++ ++struct rtw89_agc_gaincode_set { ++ u8 lna_idx; ++ u8 tia_idx; ++ u8 rxb_idx; ++}; ++ ++#define IGI_RSSI_TH_NUM 5 ++#define FA_TH_NUM 4 ++#define LNA_GAIN_NUM 7 ++#define TIA_GAIN_NUM 2 ++struct rtw89_dig_info { ++ struct rtw89_agc_gaincode_set cur_gaincode; ++ bool force_gaincode_idx_en; ++ struct rtw89_agc_gaincode_set force_gaincode; ++ u8 igi_rssi_th[IGI_RSSI_TH_NUM]; ++ u16 fa_th[FA_TH_NUM]; ++ u8 igi_rssi; ++ u8 igi_fa_rssi; ++ u8 fa_rssi_ofst; ++ u8 dyn_igi_max; ++ u8 dyn_igi_min; ++ bool dyn_pd_th_en; ++ u8 dyn_pd_th_max; ++ u8 pd_low_th_ofst; ++ u8 ib_pbk; ++ s8 ib_pkpwr; ++ s8 lna_gain_a[LNA_GAIN_NUM]; ++ s8 lna_gain_g[LNA_GAIN_NUM]; ++ s8 *lna_gain; ++ s8 tia_gain_a[TIA_GAIN_NUM]; ++ s8 tia_gain_g[TIA_GAIN_NUM]; ++ s8 *tia_gain; ++ bool is_linked_pre; ++ bool bypass_dig; ++}; ++ ++enum rtw89_multi_cfo_mode { ++ RTW89_PKT_BASED_AVG_MODE = 0, ++ RTW89_ENTRY_BASED_AVG_MODE = 1, ++ RTW89_TP_BASED_AVG_MODE = 2, ++}; ++ ++enum rtw89_phy_cfo_status { ++ RTW89_PHY_DCFO_STATE_NORMAL = 0, ++ RTW89_PHY_DCFO_STATE_ENHANCE = 1, ++ RTW89_PHY_DCFO_STATE_MAX ++}; ++ ++struct rtw89_cfo_tracking_info { ++ u16 cfo_timer_ms; ++ bool cfo_trig_by_timer_en; ++ enum rtw89_phy_cfo_status phy_cfo_status; ++ u8 phy_cfo_trk_cnt; ++ bool is_adjust; ++ enum rtw89_multi_cfo_mode rtw89_multi_cfo_mode; ++ bool apply_compensation; ++ u8 crystal_cap; ++ u8 crystal_cap_default; ++ u8 def_x_cap; ++ s8 x_cap_ofst; ++ u32 sta_cfo_tolerance; ++ s32 cfo_tail[CFO_TRACK_MAX_USER]; ++ u16 cfo_cnt[CFO_TRACK_MAX_USER]; ++ s32 cfo_avg_pre; ++ s32 cfo_avg[CFO_TRACK_MAX_USER]; ++ s32 pre_cfo_avg[CFO_TRACK_MAX_USER]; ++ u32 packet_count; ++ u32 packet_count_pre; ++ s32 residual_cfo_acc; ++ u8 phy_cfotrk_state; ++ u8 phy_cfotrk_cnt; ++}; ++ ++/* 2GL, 2GH, 5GL1, 5GH1, 5GM1, 5GM2, 5GH1, 5GH2 */ ++#define TSSI_TRIM_CH_GROUP_NUM 8 ++ ++#define TSSI_CCK_CH_GROUP_NUM 6 ++#define TSSI_MCS_2G_CH_GROUP_NUM 5 ++#define TSSI_MCS_5G_CH_GROUP_NUM 14 ++#define TSSI_MCS_CH_GROUP_NUM \ ++ (TSSI_MCS_2G_CH_GROUP_NUM + TSSI_MCS_5G_CH_GROUP_NUM) ++ ++struct rtw89_tssi_info { ++ u8 thermal[RF_PATH_MAX]; ++ s8 tssi_trim[RF_PATH_MAX][TSSI_TRIM_CH_GROUP_NUM]; ++ s8 tssi_cck[RF_PATH_MAX][TSSI_CCK_CH_GROUP_NUM]; ++ s8 tssi_mcs[RF_PATH_MAX][TSSI_MCS_CH_GROUP_NUM]; ++ s8 extra_ofst[RF_PATH_MAX]; ++ bool tssi_tracking_check[RF_PATH_MAX]; ++ u8 default_txagc_offset[RF_PATH_MAX]; ++ u32 base_thermal[RF_PATH_MAX]; ++}; ++ ++struct rtw89_power_trim_info { ++ bool pg_thermal_trim; ++ bool pg_pa_bias_trim; ++ u8 thermal_trim[RF_PATH_MAX]; ++ u8 pa_bias_trim[RF_PATH_MAX]; ++}; ++ ++struct rtw89_regulatory { ++ char alpha2[3]; ++ u8 txpwr_regd[RTW89_BAND_MAX]; ++}; ++ ++enum rtw89_ifs_clm_application { ++ RTW89_IFS_CLM_INIT = 0, ++ RTW89_IFS_CLM_BACKGROUND = 1, ++ RTW89_IFS_CLM_ACS = 2, ++ RTW89_IFS_CLM_DIG = 3, ++ RTW89_IFS_CLM_TDMA_DIG = 4, ++ RTW89_IFS_CLM_DBG = 5, ++ RTW89_IFS_CLM_DBG_MANUAL = 6 ++}; ++ ++enum rtw89_env_racing_lv { ++ RTW89_RAC_RELEASE = 0, ++ RTW89_RAC_LV_1 = 1, ++ RTW89_RAC_LV_2 = 2, ++ RTW89_RAC_LV_3 = 3, ++ RTW89_RAC_LV_4 = 4, ++ RTW89_RAC_MAX_NUM = 5 ++}; ++ ++struct rtw89_ccx_para_info { ++ enum rtw89_env_racing_lv rac_lv; ++ u16 mntr_time; ++ u8 nhm_manual_th_ofst; ++ u8 nhm_manual_th0; ++ enum rtw89_ifs_clm_application ifs_clm_app; ++ u32 ifs_clm_manual_th_times; ++ u32 ifs_clm_manual_th0; ++ u8 fahm_manual_th_ofst; ++ u8 fahm_manual_th0; ++ u8 fahm_numer_opt; ++ u8 fahm_denom_opt; ++}; ++ ++enum rtw89_ccx_edcca_opt_sc_idx { ++ RTW89_CCX_EDCCA_SEG0_P0 = 0, ++ RTW89_CCX_EDCCA_SEG0_S1 = 1, ++ RTW89_CCX_EDCCA_SEG0_S2 = 2, ++ RTW89_CCX_EDCCA_SEG0_S3 = 3, ++ RTW89_CCX_EDCCA_SEG1_P0 = 4, ++ RTW89_CCX_EDCCA_SEG1_S1 = 5, ++ RTW89_CCX_EDCCA_SEG1_S2 = 6, ++ RTW89_CCX_EDCCA_SEG1_S3 = 7 ++}; ++ ++enum rtw89_ccx_edcca_opt_bw_idx { ++ RTW89_CCX_EDCCA_BW20_0 = 0, ++ RTW89_CCX_EDCCA_BW20_1 = 1, ++ RTW89_CCX_EDCCA_BW20_2 = 2, ++ RTW89_CCX_EDCCA_BW20_3 = 3, ++ RTW89_CCX_EDCCA_BW20_4 = 4, ++ RTW89_CCX_EDCCA_BW20_5 = 5, ++ RTW89_CCX_EDCCA_BW20_6 = 6, ++ RTW89_CCX_EDCCA_BW20_7 = 7 ++}; ++ ++#define RTW89_NHM_TH_NUM 11 ++#define RTW89_FAHM_TH_NUM 11 ++#define RTW89_NHM_RPT_NUM 12 ++#define RTW89_FAHM_RPT_NUM 12 ++#define RTW89_IFS_CLM_NUM 4 ++struct rtw89_env_monitor_info { ++ u32 ccx_trigger_time; ++ u64 start_time; ++ u8 ccx_rpt_stamp; ++ u8 ccx_watchdog_result; ++ bool ccx_ongoing; ++ u8 ccx_rac_lv; ++ bool ccx_manual_ctrl; ++ u8 ccx_pre_rssi; ++ u16 clm_mntr_time; ++ u16 nhm_mntr_time; ++ u16 ifs_clm_mntr_time; ++ enum rtw89_ifs_clm_application ifs_clm_app; ++ u16 fahm_mntr_time; ++ u16 edcca_clm_mntr_time; ++ u16 ccx_period; ++ u8 ccx_unit_idx; ++ enum rtw89_ccx_edcca_opt_bw_idx ccx_edcca_opt_bw_idx; ++ u8 nhm_th[RTW89_NHM_TH_NUM]; ++ u16 ifs_clm_th_l[RTW89_IFS_CLM_NUM]; ++ u16 ifs_clm_th_h[RTW89_IFS_CLM_NUM]; ++ u8 fahm_numer_opt; ++ u8 fahm_denom_opt; ++ u8 fahm_th[RTW89_FAHM_TH_NUM]; ++ u16 clm_result; ++ u16 nhm_result[RTW89_NHM_RPT_NUM]; ++ u8 nhm_wgt[RTW89_NHM_RPT_NUM]; ++ u16 nhm_tx_cnt; ++ u16 nhm_cca_cnt; ++ u16 nhm_idle_cnt; ++ u16 ifs_clm_tx; ++ u16 ifs_clm_edcca_excl_cca; ++ u16 ifs_clm_ofdmfa; ++ u16 ifs_clm_ofdmcca_excl_fa; ++ u16 ifs_clm_cckfa; ++ u16 ifs_clm_cckcca_excl_fa; ++ u16 ifs_clm_total_ifs; ++ u8 ifs_clm_his[RTW89_IFS_CLM_NUM]; ++ u16 ifs_clm_avg[RTW89_IFS_CLM_NUM]; ++ u16 ifs_clm_cca[RTW89_IFS_CLM_NUM]; ++ u16 fahm_result[RTW89_FAHM_RPT_NUM]; ++ u16 fahm_denom_result; ++ u16 edcca_clm_result; ++ u8 clm_ratio; ++ u8 nhm_rpt[RTW89_NHM_RPT_NUM]; ++ u8 nhm_tx_ratio; ++ u8 nhm_cca_ratio; ++ u8 nhm_idle_ratio; ++ u8 nhm_ratio; ++ u16 nhm_result_sum; ++ u8 nhm_pwr; ++ u8 ifs_clm_tx_ratio; ++ u8 ifs_clm_edcca_excl_cca_ratio; ++ u8 ifs_clm_cck_fa_ratio; ++ u8 ifs_clm_ofdm_fa_ratio; ++ u8 ifs_clm_cck_cca_excl_fa_ratio; ++ u8 ifs_clm_ofdm_cca_excl_fa_ratio; ++ u16 ifs_clm_cck_fa_permil; ++ u16 ifs_clm_ofdm_fa_permil; ++ u32 ifs_clm_ifs_avg[RTW89_IFS_CLM_NUM]; ++ u32 ifs_clm_cca_avg[RTW89_IFS_CLM_NUM]; ++ u8 fahm_rpt[RTW89_FAHM_RPT_NUM]; ++ u16 fahm_result_sum; ++ u8 fahm_ratio; ++ u8 fahm_denom_ratio; ++ u8 fahm_pwr; ++ u8 edcca_clm_ratio; ++}; ++ ++enum rtw89_ser_rcvy_step { ++ RTW89_SER_DRV_STOP_TX, ++ RTW89_SER_DRV_STOP_RX, ++ RTW89_SER_DRV_STOP_RUN, ++ RTW89_SER_HAL_STOP_DMA, ++ RTW89_NUM_OF_SER_FLAGS ++}; ++ ++struct rtw89_ser { ++ u8 state; ++ u8 alarm_event; ++ ++ struct work_struct ser_hdl_work; ++ struct delayed_work ser_alarm_work; ++ struct state_ent *st_tbl; ++ struct event_ent *ev_tbl; ++ struct list_head msg_q; ++ spinlock_t msg_q_lock; /* lock when read/write ser msg */ ++ DECLARE_BITMAP(flags, RTW89_NUM_OF_SER_FLAGS); ++}; ++ ++enum rtw89_mac_ax_ps_mode { ++ RTW89_MAC_AX_PS_MODE_ACTIVE = 0, ++ RTW89_MAC_AX_PS_MODE_LEGACY = 1, ++ RTW89_MAC_AX_PS_MODE_WMMPS = 2, ++ RTW89_MAC_AX_PS_MODE_MAX = 3, ++}; ++ ++enum rtw89_last_rpwm_mode { ++ RTW89_LAST_RPWM_PS = 0x0, ++ RTW89_LAST_RPWM_ACTIVE = 0x6, ++}; ++ ++struct rtw89_lps_parm { ++ u8 macid; ++ u8 psmode; /* enum rtw89_mac_ax_ps_mode */ ++ u8 lastrpwm; /* enum rtw89_last_rpwm_mode */ ++}; ++ ++struct rtw89_ppdu_sts_info { ++ struct sk_buff_head rx_queue[RTW89_PHY_MAX]; ++ u8 curr_rx_ppdu_cnt[RTW89_PHY_MAX]; ++}; ++ ++struct rtw89_early_h2c { ++ struct list_head list; ++ u8 *h2c; ++ u16 h2c_len; ++}; ++ ++struct rtw89_dev { ++ struct ieee80211_hw *hw; ++ struct device *dev; ++ ++ bool dbcc_en; ++ const struct rtw89_chip_info *chip; ++ struct rtw89_hal hal; ++ struct rtw89_mac_info mac; ++ struct rtw89_fw_info fw; ++ struct rtw89_hci_info hci; ++ struct rtw89_efuse efuse; ++ struct rtw89_traffic_stats stats; ++ ++ /* ensures exclusive access from mac80211 callbacks */ ++ struct mutex mutex; ++ struct list_head rtwvifs_list; ++ /* used to protect rf read write */ ++ struct mutex rf_mutex; ++ struct workqueue_struct *txq_wq; ++ struct work_struct txq_work; ++ struct delayed_work txq_reinvoke_work; ++ /* used to protect ba_list */ ++ spinlock_t ba_lock; ++ /* txqs to setup ba session */ ++ struct list_head ba_list; ++ struct work_struct ba_work; ++ ++ struct rtw89_cam_info cam_info; ++ ++ struct sk_buff_head c2h_queue; ++ struct work_struct c2h_work; ++ ++ struct list_head early_h2c_list; ++ ++ struct rtw89_ser ser; ++ ++ DECLARE_BITMAP(hw_port, RTW89_MAX_HW_PORT_NUM); ++ DECLARE_BITMAP(mac_id_map, RTW89_MAX_MAC_ID_NUM); ++ DECLARE_BITMAP(flags, NUM_OF_RTW89_FLAGS); ++ ++ struct rtw89_phy_stat phystat; ++ struct rtw89_dack_info dack; ++ struct rtw89_iqk_info iqk; ++ struct rtw89_dpk_info dpk; ++ bool is_tssi_mode[RF_PATH_MAX]; ++ bool is_bt_iqk_timeout; ++ ++ struct rtw89_fem_info fem; ++ struct rtw89_txpwr_byrate byr[RTW89_BAND_MAX]; ++ struct rtw89_tssi_info tssi; ++ struct rtw89_power_trim_info pwr_trim; ++ ++ struct rtw89_cfo_tracking_info cfo_tracking; ++ struct rtw89_env_monitor_info env_monitor; ++ struct rtw89_dig_info dig; ++ struct rtw89_phy_ch_info ch_info; ++ struct delayed_work track_work; ++ struct delayed_work coex_act1_work; ++ struct delayed_work coex_bt_devinfo_work; ++ struct delayed_work coex_rfk_chk_work; ++ struct delayed_work cfo_track_work; ++ struct rtw89_ppdu_sts_info ppdu_sts; ++ u8 total_sta_assoc; ++ bool scanning; ++ ++ const struct rtw89_regulatory *regd; ++ struct rtw89_sar_info sar; ++ ++ struct rtw89_btc btc; ++ enum rtw89_ps_mode ps_mode; ++ bool lps_enabled; ++ ++ /* napi structure */ ++ struct net_device netdev; ++ struct napi_struct napi; ++ int napi_budget_countdown; ++ ++ /* HCI related data, keep last */ ++ u8 priv[0] __aligned(sizeof(void *)); ++}; ++ ++static inline int rtw89_hci_tx_write(struct rtw89_dev *rtwdev, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ return rtwdev->hci.ops->tx_write(rtwdev, tx_req); ++} ++ ++static inline void rtw89_hci_reset(struct rtw89_dev *rtwdev) ++{ ++ rtwdev->hci.ops->reset(rtwdev); ++} ++ ++static inline int rtw89_hci_start(struct rtw89_dev *rtwdev) ++{ ++ return rtwdev->hci.ops->start(rtwdev); ++} ++ ++static inline void rtw89_hci_stop(struct rtw89_dev *rtwdev) ++{ ++ rtwdev->hci.ops->stop(rtwdev); ++} ++ ++static inline int rtw89_hci_deinit(struct rtw89_dev *rtwdev) ++{ ++ return rtwdev->hci.ops->deinit(rtwdev); ++} ++ ++static inline void rtw89_hci_recalc_int_mit(struct rtw89_dev *rtwdev) ++{ ++ rtwdev->hci.ops->recalc_int_mit(rtwdev); ++} ++ ++static inline u32 rtw89_hci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, u8 txch) ++{ ++ return rtwdev->hci.ops->check_and_reclaim_tx_resource(rtwdev, txch); ++} ++ ++static inline void rtw89_hci_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch) ++{ ++ return rtwdev->hci.ops->tx_kick_off(rtwdev, txch); ++} ++ ++static inline void rtw89_hci_flush_queues(struct rtw89_dev *rtwdev, u32 queues, ++ bool drop) ++{ ++ if (rtwdev->hci.ops->flush_queues) ++ return rtwdev->hci.ops->flush_queues(rtwdev, queues, drop); ++} ++ ++static inline u8 rtw89_read8(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ return rtwdev->hci.ops->read8(rtwdev, addr); ++} ++ ++static inline u16 rtw89_read16(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ return rtwdev->hci.ops->read16(rtwdev, addr); ++} ++ ++static inline u32 rtw89_read32(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ return rtwdev->hci.ops->read32(rtwdev, addr); ++} ++ ++static inline void rtw89_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) ++{ ++ rtwdev->hci.ops->write8(rtwdev, addr, data); ++} ++ ++static inline void rtw89_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) ++{ ++ rtwdev->hci.ops->write16(rtwdev, addr, data); ++} ++ ++static inline void rtw89_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) ++{ ++ rtwdev->hci.ops->write32(rtwdev, addr, data); ++} ++ ++static inline void ++rtw89_write8_set(struct rtw89_dev *rtwdev, u32 addr, u8 bit) ++{ ++ u8 val; ++ ++ val = rtw89_read8(rtwdev, addr); ++ rtw89_write8(rtwdev, addr, val | bit); ++} ++ ++static inline void ++rtw89_write16_set(struct rtw89_dev *rtwdev, u32 addr, u16 bit) ++{ ++ u16 val; ++ ++ val = rtw89_read16(rtwdev, addr); ++ rtw89_write16(rtwdev, addr, val | bit); ++} ++ ++static inline void ++rtw89_write32_set(struct rtw89_dev *rtwdev, u32 addr, u32 bit) ++{ ++ u32 val; ++ ++ val = rtw89_read32(rtwdev, addr); ++ rtw89_write32(rtwdev, addr, val | bit); ++} ++ ++static inline void ++rtw89_write8_clr(struct rtw89_dev *rtwdev, u32 addr, u8 bit) ++{ ++ u8 val; ++ ++ val = rtw89_read8(rtwdev, addr); ++ rtw89_write8(rtwdev, addr, val & ~bit); ++} ++ ++static inline void ++rtw89_write16_clr(struct rtw89_dev *rtwdev, u32 addr, u16 bit) ++{ ++ u16 val; ++ ++ val = rtw89_read16(rtwdev, addr); ++ rtw89_write16(rtwdev, addr, val & ~bit); ++} ++ ++static inline void ++rtw89_write32_clr(struct rtw89_dev *rtwdev, u32 addr, u32 bit) ++{ ++ u32 val; ++ ++ val = rtw89_read32(rtwdev, addr); ++ rtw89_write32(rtwdev, addr, val & ~bit); ++} ++ ++static inline u32 ++rtw89_read32_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask) ++{ ++ u32 shift = __ffs(mask); ++ u32 orig; ++ u32 ret; ++ ++ orig = rtw89_read32(rtwdev, addr); ++ ret = (orig & mask) >> shift; ++ ++ return ret; ++} ++ ++static inline u16 ++rtw89_read16_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask) ++{ ++ u32 shift = __ffs(mask); ++ u32 orig; ++ u32 ret; ++ ++ orig = rtw89_read16(rtwdev, addr); ++ ret = (orig & mask) >> shift; ++ ++ return ret; ++} ++ ++static inline u8 ++rtw89_read8_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask) ++{ ++ u32 shift = __ffs(mask); ++ u32 orig; ++ u32 ret; ++ ++ orig = rtw89_read8(rtwdev, addr); ++ ret = (orig & mask) >> shift; ++ ++ return ret; ++} ++ ++static inline void ++rtw89_write32_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u32 data) ++{ ++ u32 shift = __ffs(mask); ++ u32 orig; ++ u32 set; ++ ++ WARN(addr & 0x3, "should be 4-byte aligned, addr = 0x%08x\n", addr); ++ ++ orig = rtw89_read32(rtwdev, addr); ++ set = (orig & ~mask) | ((data << shift) & mask); ++ rtw89_write32(rtwdev, addr, set); ++} ++ ++static inline void ++rtw89_write16_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u16 data) ++{ ++ u32 shift; ++ u16 orig, set; ++ ++ mask &= 0xffff; ++ shift = __ffs(mask); ++ ++ orig = rtw89_read16(rtwdev, addr); ++ set = (orig & ~mask) | ((data << shift) & mask); ++ rtw89_write16(rtwdev, addr, set); ++} ++ ++static inline void ++rtw89_write8_mask(struct rtw89_dev *rtwdev, u32 addr, u32 mask, u8 data) ++{ ++ u32 shift; ++ u8 orig, set; ++ ++ mask &= 0xff; ++ shift = __ffs(mask); ++ ++ orig = rtw89_read8(rtwdev, addr); ++ set = (orig & ~mask) | ((data << shift) & mask); ++ rtw89_write8(rtwdev, addr, set); ++} ++ ++static inline u32 ++rtw89_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask) ++{ ++ u32 val; ++ ++ mutex_lock(&rtwdev->rf_mutex); ++ val = rtwdev->chip->ops->read_rf(rtwdev, rf_path, addr, mask); ++ mutex_unlock(&rtwdev->rf_mutex); ++ ++ return val; ++} ++ ++static inline void ++rtw89_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask, u32 data) ++{ ++ mutex_lock(&rtwdev->rf_mutex); ++ rtwdev->chip->ops->write_rf(rtwdev, rf_path, addr, mask, data); ++ mutex_unlock(&rtwdev->rf_mutex); ++} ++ ++static inline struct ieee80211_txq *rtw89_txq_to_txq(struct rtw89_txq *rtwtxq) ++{ ++ void *p = rtwtxq; ++ ++ return container_of(p, struct ieee80211_txq, drv_priv); ++} ++ ++static inline void rtw89_core_txq_init(struct rtw89_dev *rtwdev, ++ struct ieee80211_txq *txq) ++{ ++ struct rtw89_txq *rtwtxq; ++ ++ if (!txq) ++ return; ++ ++ rtwtxq = (struct rtw89_txq *)txq->drv_priv; ++ INIT_LIST_HEAD(&rtwtxq->list); ++} ++ ++static inline struct ieee80211_vif *rtwvif_to_vif(struct rtw89_vif *rtwvif) ++{ ++ void *p = rtwvif; ++ ++ return container_of(p, struct ieee80211_vif, drv_priv); ++} ++ ++static inline struct ieee80211_sta *rtwsta_to_sta(struct rtw89_sta *rtwsta) ++{ ++ void *p = rtwsta; ++ ++ return container_of(p, struct ieee80211_sta, drv_priv); ++} ++ ++static inline ++void rtw89_chip_set_channel_prepare(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_help_params *p) ++{ ++ rtwdev->chip->ops->set_channel_help(rtwdev, true, p); ++} ++ ++static inline ++void rtw89_chip_set_channel_done(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_help_params *p) ++{ ++ rtwdev->chip->ops->set_channel_help(rtwdev, false, p); ++} ++ ++static inline void rtw89_chip_fem_setup(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->fem_setup) ++ chip->ops->fem_setup(rtwdev); ++} ++ ++static inline void rtw89_chip_bb_sethw(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->bb_sethw) ++ chip->ops->bb_sethw(rtwdev); ++} ++ ++static inline void rtw89_chip_rfk_init(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->rfk_init) ++ chip->ops->rfk_init(rtwdev); ++} ++ ++static inline void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->rfk_channel) ++ chip->ops->rfk_channel(rtwdev); ++} ++ ++static inline void rtw89_chip_rfk_band_changed(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->rfk_band_changed) ++ chip->ops->rfk_band_changed(rtwdev); ++} ++ ++static inline void rtw89_chip_rfk_scan(struct rtw89_dev *rtwdev, bool start) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->rfk_scan) ++ chip->ops->rfk_scan(rtwdev, start); ++} ++ ++static inline void rtw89_chip_rfk_track(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->rfk_track) ++ chip->ops->rfk_track(rtwdev); ++} ++ ++static inline void rtw89_chip_set_txpwr_ctrl(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->set_txpwr_ctrl) ++ chip->ops->set_txpwr_ctrl(rtwdev); ++} ++ ++static inline void rtw89_chip_set_txpwr(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ u8 ch = rtwdev->hal.current_channel; ++ ++ if (!ch) ++ return; ++ ++ if (chip->ops->set_txpwr) ++ chip->ops->set_txpwr(rtwdev); ++} ++ ++static inline void rtw89_chip_power_trim(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->power_trim) ++ chip->ops->power_trim(rtwdev); ++} ++ ++static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->init_txpwr_unit) ++ chip->ops->init_txpwr_unit(rtwdev, phy_idx); ++} ++ ++static inline u8 rtw89_chip_get_thermal(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path rf_path) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (!chip->ops->get_thermal) ++ return 0x10; ++ ++ return chip->ops->get_thermal(rtwdev, rf_path); ++} ++ ++static inline void rtw89_chip_query_ppdu(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_phy_ppdu *phy_ppdu, ++ struct ieee80211_rx_status *status) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->query_ppdu) ++ chip->ops->query_ppdu(rtwdev, phy_ppdu, status); ++} ++ ++static inline void rtw89_chip_bb_ctrl_btc_preagc(struct rtw89_dev *rtwdev, ++ bool bt_en) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->bb_ctrl_btc_preagc) ++ chip->ops->bb_ctrl_btc_preagc(rtwdev, bt_en); ++} ++ ++static inline ++void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (!vif->bss_conf.he_support || !vif->bss_conf.assoc) ++ return; ++ ++ if (chip->ops->set_txpwr_ul_tb_offset) ++ chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif->mac_idx); ++} ++ ++static inline void rtw89_load_txpwr_table(struct rtw89_dev *rtwdev, ++ const struct rtw89_txpwr_table *tbl) ++{ ++ tbl->load(rtwdev, tbl); ++} ++ ++static inline u8 rtw89_regd_get(struct rtw89_dev *rtwdev, u8 band) ++{ ++ return rtwdev->regd->txpwr_regd[band]; ++} ++ ++static inline void rtw89_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ if (chip->ops->ctrl_btg) ++ chip->ops->ctrl_btg(rtwdev, btg); ++} ++ ++static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) ++{ ++ __le16 fc = hdr->frame_control; ++ ++ if (ieee80211_has_tods(fc)) ++ return hdr->addr1; ++ else if (ieee80211_has_fromds(fc)) ++ return hdr->addr2; ++ else ++ return hdr->addr3; ++} ++ ++static inline bool rtw89_sta_has_beamformer_cap(struct ieee80211_sta *sta) ++{ ++ if ((sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || ++ (sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) || ++ (sta->he_cap.he_cap_elem.phy_cap_info[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) || ++ (sta->he_cap.he_cap_elem.phy_cap_info[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) ++ return true; ++ return false; ++} ++ ++static inline struct rtw89_fw_suit *rtw89_fw_suit_get(struct rtw89_dev *rtwdev, ++ enum rtw89_fw_type type) ++{ ++ struct rtw89_fw_info *fw_info = &rtwdev->fw; ++ ++ if (type == RTW89_FW_WOWLAN) ++ return &fw_info->wowlan; ++ return &fw_info->normal; ++} ++ ++int rtw89_core_tx_write(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, struct sk_buff *skb, int *qsel); ++int rtw89_h2c_tx(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb, bool fwdl); ++void rtw89_core_tx_kick_off(struct rtw89_dev *rtwdev, u8 qsel); ++void rtw89_core_fill_txdesc(struct rtw89_dev *rtwdev, ++ struct rtw89_tx_desc_info *desc_info, ++ void *txdesc); ++void rtw89_core_rx(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_desc_info *desc_info, ++ struct sk_buff *skb); ++void rtw89_core_query_rxdesc(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_desc_info *desc_info, ++ u8 *data, u32 data_offset); ++void rtw89_core_napi_start(struct rtw89_dev *rtwdev); ++void rtw89_core_napi_stop(struct rtw89_dev *rtwdev); ++void rtw89_core_napi_init(struct rtw89_dev *rtwdev); ++void rtw89_core_napi_deinit(struct rtw89_dev *rtwdev); ++int rtw89_core_sta_add(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++int rtw89_core_sta_remove(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++int rtw89_core_init(struct rtw89_dev *rtwdev); ++void rtw89_core_deinit(struct rtw89_dev *rtwdev); ++int rtw89_core_register(struct rtw89_dev *rtwdev); ++void rtw89_core_unregister(struct rtw89_dev *rtwdev); ++void rtw89_set_channel(struct rtw89_dev *rtwdev); ++u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size); ++void rtw89_core_release_bit_map(unsigned long *addr, u8 bit); ++void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits); ++void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc); ++int rtw89_chip_info_setup(struct rtw89_dev *rtwdev); ++u16 rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate); ++int rtw89_regd_init(struct rtw89_dev *rtwdev, ++ void (*reg_notifier)(struct wiphy *wiphy, struct regulatory_request *request)); ++void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request); ++void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, ++ struct rtw89_traffic_stats *stats); ++int rtw89_core_start(struct rtw89_dev *rtwdev); ++void rtw89_core_stop(struct rtw89_dev *rtwdev); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c +new file mode 100644 +index 000000000000..29eb188c888c +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/debug.c +@@ -0,0 +1,2489 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "coex.h" ++#include "debug.h" ++#include "fw.h" ++#include "mac.h" ++#include "ps.h" ++#include "reg.h" ++#include "sar.h" ++ ++#ifdef CONFIG_RTW89_DEBUGMSG ++unsigned int rtw89_debug_mask; ++EXPORT_SYMBOL(rtw89_debug_mask); ++module_param_named(debug_mask, rtw89_debug_mask, uint, 0644); ++MODULE_PARM_DESC(debug_mask, "Debugging mask"); ++#endif ++ ++#ifdef CONFIG_RTW89_DEBUGFS ++struct rtw89_debugfs_priv { ++ struct rtw89_dev *rtwdev; ++ int (*cb_read)(struct seq_file *m, void *v); ++ ssize_t (*cb_write)(struct file *filp, const char __user *buffer, ++ size_t count, loff_t *loff); ++ union { ++ u32 cb_data; ++ struct { ++ u32 addr; ++ u8 len; ++ } read_reg; ++ struct { ++ u32 addr; ++ u32 mask; ++ u8 path; ++ } read_rf; ++ struct { ++ u8 ss_dbg:1; ++ u8 dle_dbg:1; ++ u8 dmac_dbg:1; ++ u8 cmac_dbg:1; ++ u8 dbg_port:1; ++ } dbgpkg_en; ++ struct { ++ u32 start; ++ u32 len; ++ u8 sel; ++ } mac_mem; ++ }; ++}; ++ ++static int rtw89_debugfs_single_show(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ ++ return debugfs_priv->cb_read(m, v); ++} ++ ++static ssize_t rtw89_debugfs_single_write(struct file *filp, ++ const char __user *buffer, ++ size_t count, loff_t *loff) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; ++ ++ return debugfs_priv->cb_write(filp, buffer, count, loff); ++} ++ ++static ssize_t rtw89_debugfs_seq_file_write(struct file *filp, ++ const char __user *buffer, ++ size_t count, loff_t *loff) ++{ ++ struct seq_file *seqpriv = (struct seq_file *)filp->private_data; ++ struct rtw89_debugfs_priv *debugfs_priv = seqpriv->private; ++ ++ return debugfs_priv->cb_write(filp, buffer, count, loff); ++} ++ ++static int rtw89_debugfs_single_open(struct inode *inode, struct file *filp) ++{ ++ return single_open(filp, rtw89_debugfs_single_show, inode->i_private); ++} ++ ++static int rtw89_debugfs_close(struct inode *inode, struct file *filp) ++{ ++ return 0; ++} ++ ++static const struct file_operations file_ops_single_r = { ++ .owner = THIS_MODULE, ++ .open = rtw89_debugfs_single_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static const struct file_operations file_ops_common_rw = { ++ .owner = THIS_MODULE, ++ .open = rtw89_debugfs_single_open, ++ .release = single_release, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .write = rtw89_debugfs_seq_file_write, ++}; ++ ++static const struct file_operations file_ops_single_w = { ++ .owner = THIS_MODULE, ++ .write = rtw89_debugfs_single_write, ++ .open = simple_open, ++ .release = rtw89_debugfs_close, ++}; ++ ++static ssize_t ++rtw89_debug_priv_read_reg_select(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct seq_file *m = (struct seq_file *)filp->private_data; ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ char buf[32]; ++ size_t buf_size; ++ u32 addr, len; ++ int num; ++ ++ buf_size = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, buf_size)) ++ return -EFAULT; ++ ++ buf[buf_size] = '\0'; ++ num = sscanf(buf, "%x %x", &addr, &len); ++ if (num != 2) { ++ rtw89_info(rtwdev, "invalid format: \n"); ++ return -EINVAL; ++ } ++ ++ debugfs_priv->read_reg.addr = addr; ++ debugfs_priv->read_reg.len = len; ++ ++ rtw89_info(rtwdev, "select read %d bytes from 0x%08x\n", len, addr); ++ ++ return count; ++} ++ ++static int rtw89_debug_priv_read_reg_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ u32 addr, data; ++ u8 len; ++ ++ len = debugfs_priv->read_reg.len; ++ addr = debugfs_priv->read_reg.addr; ++ ++ switch (len) { ++ case 1: ++ data = rtw89_read8(rtwdev, addr); ++ break; ++ case 2: ++ data = rtw89_read16(rtwdev, addr); ++ break; ++ case 4: ++ data = rtw89_read32(rtwdev, addr); ++ break; ++ default: ++ rtw89_info(rtwdev, "invalid read reg len %d\n", len); ++ return -EINVAL; ++ } ++ ++ seq_printf(m, "get %d bytes at 0x%08x=0x%08x\n", len, addr, data); ++ ++ return 0; ++} ++ ++static ssize_t rtw89_debug_priv_write_reg_set(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ char buf[32]; ++ size_t buf_size; ++ u32 addr, val, len; ++ int num; ++ ++ buf_size = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, buf_size)) ++ return -EFAULT; ++ ++ buf[buf_size] = '\0'; ++ num = sscanf(buf, "%x %x %x", &addr, &val, &len); ++ if (num != 3) { ++ rtw89_info(rtwdev, "invalid format: \n"); ++ return -EINVAL; ++ } ++ ++ switch (len) { ++ case 1: ++ rtw89_info(rtwdev, "reg write8 0x%08x: 0x%02x\n", addr, val); ++ rtw89_write8(rtwdev, addr, (u8)val); ++ break; ++ case 2: ++ rtw89_info(rtwdev, "reg write16 0x%08x: 0x%04x\n", addr, val); ++ rtw89_write16(rtwdev, addr, (u16)val); ++ break; ++ case 4: ++ rtw89_info(rtwdev, "reg write32 0x%08x: 0x%08x\n", addr, val); ++ rtw89_write32(rtwdev, addr, (u32)val); ++ break; ++ default: ++ rtw89_info(rtwdev, "invalid read write len %d\n", len); ++ break; ++ } ++ ++ return count; ++} ++ ++static ssize_t ++rtw89_debug_priv_read_rf_select(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct seq_file *m = (struct seq_file *)filp->private_data; ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ char buf[32]; ++ size_t buf_size; ++ u32 addr, mask; ++ u8 path; ++ int num; ++ ++ buf_size = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, buf_size)) ++ return -EFAULT; ++ ++ buf[buf_size] = '\0'; ++ num = sscanf(buf, "%hhd %x %x", &path, &addr, &mask); ++ if (num != 3) { ++ rtw89_info(rtwdev, "invalid format: \n"); ++ return -EINVAL; ++ } ++ ++ if (path >= rtwdev->chip->rf_path_num) { ++ rtw89_info(rtwdev, "wrong rf path\n"); ++ return -EINVAL; ++ } ++ debugfs_priv->read_rf.addr = addr; ++ debugfs_priv->read_rf.mask = mask; ++ debugfs_priv->read_rf.path = path; ++ ++ rtw89_info(rtwdev, "select read rf path %d from 0x%08x\n", path, addr); ++ ++ return count; ++} ++ ++static int rtw89_debug_priv_read_rf_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ u32 addr, data, mask; ++ u8 path; ++ ++ addr = debugfs_priv->read_rf.addr; ++ mask = debugfs_priv->read_rf.mask; ++ path = debugfs_priv->read_rf.path; ++ ++ data = rtw89_read_rf(rtwdev, path, addr, mask); ++ ++ seq_printf(m, "path %d, rf register 0x%08x=0x%08x\n", path, addr, data); ++ ++ return 0; ++} ++ ++static ssize_t rtw89_debug_priv_write_rf_set(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ char buf[32]; ++ size_t buf_size; ++ u32 addr, val, mask; ++ u8 path; ++ int num; ++ ++ buf_size = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, buf_size)) ++ return -EFAULT; ++ ++ buf[buf_size] = '\0'; ++ num = sscanf(buf, "%hhd %x %x %x", &path, &addr, &mask, &val); ++ if (num != 4) { ++ rtw89_info(rtwdev, "invalid format: \n"); ++ return -EINVAL; ++ } ++ ++ if (path >= rtwdev->chip->rf_path_num) { ++ rtw89_info(rtwdev, "wrong rf path\n"); ++ return -EINVAL; ++ } ++ ++ rtw89_info(rtwdev, "path %d, rf register write 0x%08x=0x%08x (mask = 0x%08x)\n", ++ path, addr, val, mask); ++ rtw89_write_rf(rtwdev, path, addr, mask, val); ++ ++ return count; ++} ++ ++static int rtw89_debug_priv_rf_reg_dump_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ u32 addr, offset, data; ++ u8 path; ++ ++ for (path = 0; path < chip->rf_path_num; path++) { ++ seq_printf(m, "RF path %d:\n\n", path); ++ for (addr = 0; addr < 0x100; addr += 4) { ++ seq_printf(m, "0x%08x: ", addr); ++ for (offset = 0; offset < 4; offset++) { ++ data = rtw89_read_rf(rtwdev, path, ++ addr + offset, RFREG_MASK); ++ seq_printf(m, "0x%05x ", data); ++ } ++ seq_puts(m, "\n"); ++ } ++ seq_puts(m, "\n"); ++ } ++ ++ return 0; ++} ++ ++struct txpwr_ent { ++ const char *txt; ++ u8 len; ++}; ++ ++struct txpwr_map { ++ const struct txpwr_ent *ent; ++ u8 size; ++ u32 addr_from; ++ u32 addr_to; ++}; ++ ++#define __GEN_TXPWR_ENT2(_t, _e0, _e1) \ ++ { .len = 2, .txt = _t "\t- " _e0 " " _e1 } ++ ++#define __GEN_TXPWR_ENT4(_t, _e0, _e1, _e2, _e3) \ ++ { .len = 4, .txt = _t "\t- " _e0 " " _e1 " " _e2 " " _e3 } ++ ++#define __GEN_TXPWR_ENT8(_t, _e0, _e1, _e2, _e3, _e4, _e5, _e6, _e7) \ ++ { .len = 8, .txt = _t "\t- " \ ++ _e0 " " _e1 " " _e2 " " _e3 " " \ ++ _e4 " " _e5 " " _e6 " " _e7 } ++ ++static const struct txpwr_ent __txpwr_ent_byr[] = { ++ __GEN_TXPWR_ENT4("CCK ", "1M ", "2M ", "5.5M ", "11M "), ++ __GEN_TXPWR_ENT4("LEGACY ", "6M ", "9M ", "12M ", "18M "), ++ __GEN_TXPWR_ENT4("LEGACY ", "24M ", "36M ", "48M ", "54M "), ++ /* 1NSS */ ++ __GEN_TXPWR_ENT4("MCS_1NSS ", "MCS0 ", "MCS1 ", "MCS2 ", "MCS3 "), ++ __GEN_TXPWR_ENT4("MCS_1NSS ", "MCS4 ", "MCS5 ", "MCS6 ", "MCS7 "), ++ __GEN_TXPWR_ENT4("MCS_1NSS ", "MCS8 ", "MCS9 ", "MCS10", "MCS11"), ++ __GEN_TXPWR_ENT4("HEDCM_1NSS", "MCS0 ", "MCS1 ", "MCS3 ", "MCS4 "), ++ /* 2NSS */ ++ __GEN_TXPWR_ENT4("MCS_2NSS ", "MCS0 ", "MCS1 ", "MCS2 ", "MCS3 "), ++ __GEN_TXPWR_ENT4("MCS_2NSS ", "MCS4 ", "MCS5 ", "MCS6 ", "MCS7 "), ++ __GEN_TXPWR_ENT4("MCS_2NSS ", "MCS8 ", "MCS9 ", "MCS10", "MCS11"), ++ __GEN_TXPWR_ENT4("HEDCM_2NSS", "MCS0 ", "MCS1 ", "MCS3 ", "MCS4 "), ++}; ++ ++static_assert((ARRAY_SIZE(__txpwr_ent_byr) * 4) == ++ (R_AX_PWR_BY_RATE_MAX - R_AX_PWR_BY_RATE + 4)); ++ ++static const struct txpwr_map __txpwr_map_byr = { ++ .ent = __txpwr_ent_byr, ++ .size = ARRAY_SIZE(__txpwr_ent_byr), ++ .addr_from = R_AX_PWR_BY_RATE, ++ .addr_to = R_AX_PWR_BY_RATE_MAX, ++}; ++ ++static const struct txpwr_ent __txpwr_ent_lmt[] = { ++ /* 1TX */ ++ __GEN_TXPWR_ENT2("CCK_1TX_20M ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("CCK_1TX_40M ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("OFDM_1TX ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_0 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_1 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_2 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_3 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_4 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_5 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_6 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_20M_7 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_40M_0 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_40M_1 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_40M_2 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_40M_3 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_80M_0 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_80M_1 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_160M ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_40M_0p5", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_1TX_40M_2p5", "NON_BF", "BF"), ++ /* 2TX */ ++ __GEN_TXPWR_ENT2("CCK_2TX_20M ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("CCK_2TX_40M ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("OFDM_2TX ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_0 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_1 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_2 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_3 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_4 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_5 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_6 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_20M_7 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_40M_0 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_40M_1 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_40M_2 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_40M_3 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_80M_0 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_80M_1 ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_160M ", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_40M_0p5", "NON_BF", "BF"), ++ __GEN_TXPWR_ENT2("MCS_2TX_40M_2p5", "NON_BF", "BF"), ++}; ++ ++static_assert((ARRAY_SIZE(__txpwr_ent_lmt) * 2) == ++ (R_AX_PWR_LMT_MAX - R_AX_PWR_LMT + 4)); ++ ++static const struct txpwr_map __txpwr_map_lmt = { ++ .ent = __txpwr_ent_lmt, ++ .size = ARRAY_SIZE(__txpwr_ent_lmt), ++ .addr_from = R_AX_PWR_LMT, ++ .addr_to = R_AX_PWR_LMT_MAX, ++}; ++ ++static const struct txpwr_ent __txpwr_ent_lmt_ru[] = { ++ /* 1TX */ ++ __GEN_TXPWR_ENT8("1TX", "RU26__0", "RU26__1", "RU26__2", "RU26__3", ++ "RU26__4", "RU26__5", "RU26__6", "RU26__7"), ++ __GEN_TXPWR_ENT8("1TX", "RU52__0", "RU52__1", "RU52__2", "RU52__3", ++ "RU52__4", "RU52__5", "RU52__6", "RU52__7"), ++ __GEN_TXPWR_ENT8("1TX", "RU106_0", "RU106_1", "RU106_2", "RU106_3", ++ "RU106_4", "RU106_5", "RU106_6", "RU106_7"), ++ /* 2TX */ ++ __GEN_TXPWR_ENT8("2TX", "RU26__0", "RU26__1", "RU26__2", "RU26__3", ++ "RU26__4", "RU26__5", "RU26__6", "RU26__7"), ++ __GEN_TXPWR_ENT8("2TX", "RU52__0", "RU52__1", "RU52__2", "RU52__3", ++ "RU52__4", "RU52__5", "RU52__6", "RU52__7"), ++ __GEN_TXPWR_ENT8("2TX", "RU106_0", "RU106_1", "RU106_2", "RU106_3", ++ "RU106_4", "RU106_5", "RU106_6", "RU106_7"), ++}; ++ ++static_assert((ARRAY_SIZE(__txpwr_ent_lmt_ru) * 8) == ++ (R_AX_PWR_RU_LMT_MAX - R_AX_PWR_RU_LMT + 4)); ++ ++static const struct txpwr_map __txpwr_map_lmt_ru = { ++ .ent = __txpwr_ent_lmt_ru, ++ .size = ARRAY_SIZE(__txpwr_ent_lmt_ru), ++ .addr_from = R_AX_PWR_RU_LMT, ++ .addr_to = R_AX_PWR_RU_LMT_MAX, ++}; ++ ++static u8 __print_txpwr_ent(struct seq_file *m, const struct txpwr_ent *ent, ++ const u8 *buf, const u8 cur) ++{ ++ char *fmt; ++ ++ switch (ent->len) { ++ case 2: ++ fmt = "%s\t| %3d, %3d,\tdBm\n"; ++ seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1]); ++ return 2; ++ case 4: ++ fmt = "%s\t| %3d, %3d, %3d, %3d,\tdBm\n"; ++ seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1], ++ buf[cur + 2], buf[cur + 3]); ++ return 4; ++ case 8: ++ fmt = "%s\t| %3d, %3d, %3d, %3d, %3d, %3d, %3d, %3d,\tdBm\n"; ++ seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1], ++ buf[cur + 2], buf[cur + 3], buf[cur + 4], ++ buf[cur + 5], buf[cur + 6], buf[cur + 7]); ++ return 8; ++ default: ++ return 0; ++ } ++} ++ ++static int __print_txpwr_map(struct seq_file *m, struct rtw89_dev *rtwdev, ++ const struct txpwr_map *map) ++{ ++ u8 fct = rtwdev->chip->txpwr_factor_mac; ++ u8 *buf, cur, i; ++ u32 val, addr; ++ int ret; ++ ++ buf = vzalloc(map->addr_to - map->addr_from + 4); ++ if (!buf) ++ return -ENOMEM; ++ ++ for (addr = map->addr_from; addr <= map->addr_to; addr += 4) { ++ ret = rtw89_mac_txpwr_read32(rtwdev, RTW89_PHY_0, addr, &val); ++ if (ret) ++ val = MASKDWORD; ++ ++ cur = addr - map->addr_from; ++ for (i = 0; i < 4; i++, val >>= 8) ++ buf[cur + i] = FIELD_GET(MASKBYTE0, val) >> fct; ++ } ++ ++ for (cur = 0, i = 0; i < map->size; i++) ++ cur += __print_txpwr_ent(m, &map->ent[i], buf, cur); ++ ++ vfree(buf); ++ return 0; ++} ++ ++#define case_REGD(_regd) \ ++ case RTW89_ ## _regd: \ ++ seq_puts(m, #_regd "\n"); \ ++ break ++ ++static void __print_regd(struct seq_file *m, struct rtw89_dev *rtwdev) ++{ ++ u8 band = rtwdev->hal.current_band_type; ++ u8 regd = rtw89_regd_get(rtwdev, band); ++ ++ switch (regd) { ++ default: ++ seq_printf(m, "UNKNOWN: %d\n", regd); ++ break; ++ case_REGD(WW); ++ case_REGD(ETSI); ++ case_REGD(FCC); ++ case_REGD(MKK); ++ case_REGD(NA); ++ case_REGD(IC); ++ case_REGD(KCC); ++ case_REGD(NCC); ++ case_REGD(CHILE); ++ case_REGD(ACMA); ++ case_REGD(MEXICO); ++ case_REGD(UKRAINE); ++ case_REGD(CN); ++ } ++} ++ ++#undef case_REGD ++ ++static int rtw89_debug_priv_txpwr_table_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ int ret = 0; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ ++ seq_puts(m, "[Regulatory] "); ++ __print_regd(m, rtwdev); ++ ++ seq_puts(m, "[SAR]\n"); ++ rtw89_print_sar(m, rtwdev); ++ ++ seq_puts(m, "\n[TX power byrate]\n"); ++ ret = __print_txpwr_map(m, rtwdev, &__txpwr_map_byr); ++ if (ret) ++ goto err; ++ ++ seq_puts(m, "\n[TX power limit]\n"); ++ ret = __print_txpwr_map(m, rtwdev, &__txpwr_map_lmt); ++ if (ret) ++ goto err; ++ ++ seq_puts(m, "\n[TX power limit_ru]\n"); ++ ret = __print_txpwr_map(m, rtwdev, &__txpwr_map_lmt_ru); ++ if (ret) ++ goto err; ++ ++err: ++ mutex_unlock(&rtwdev->mutex); ++ return ret; ++} ++ ++static ssize_t ++rtw89_debug_priv_mac_reg_dump_select(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct seq_file *m = (struct seq_file *)filp->private_data; ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ char buf[32]; ++ size_t buf_size; ++ int sel; ++ int ret; ++ ++ buf_size = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, buf_size)) ++ return -EFAULT; ++ ++ buf[buf_size] = '\0'; ++ ret = kstrtoint(buf, 0, &sel); ++ if (ret) ++ return ret; ++ ++ if (sel < RTW89_DBG_SEL_MAC_00 || sel > RTW89_DBG_SEL_RFC) { ++ rtw89_info(rtwdev, "invalid args: %d\n", sel); ++ return -EINVAL; ++ } ++ ++ debugfs_priv->cb_data = sel; ++ rtw89_info(rtwdev, "select mac page dump %d\n", debugfs_priv->cb_data); ++ ++ return count; ++} ++ ++#define RTW89_MAC_PAGE_SIZE 0x100 ++ ++static int rtw89_debug_priv_mac_reg_dump_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ enum rtw89_debug_mac_reg_sel reg_sel = debugfs_priv->cb_data; ++ u32 start, end; ++ u32 i, j, k, page; ++ u32 val; ++ ++ switch (reg_sel) { ++ case RTW89_DBG_SEL_MAC_00: ++ seq_puts(m, "Debug selected MAC page 0x00\n"); ++ start = 0x000; ++ end = 0x014; ++ break; ++ case RTW89_DBG_SEL_MAC_40: ++ seq_puts(m, "Debug selected MAC page 0x40\n"); ++ start = 0x040; ++ end = 0x07f; ++ break; ++ case RTW89_DBG_SEL_MAC_80: ++ seq_puts(m, "Debug selected MAC page 0x80\n"); ++ start = 0x080; ++ end = 0x09f; ++ break; ++ case RTW89_DBG_SEL_MAC_C0: ++ seq_puts(m, "Debug selected MAC page 0xc0\n"); ++ start = 0x0c0; ++ end = 0x0df; ++ break; ++ case RTW89_DBG_SEL_MAC_E0: ++ seq_puts(m, "Debug selected MAC page 0xe0\n"); ++ start = 0x0e0; ++ end = 0x0ff; ++ break; ++ case RTW89_DBG_SEL_BB: ++ seq_puts(m, "Debug selected BB register\n"); ++ start = 0x100; ++ end = 0x17f; ++ break; ++ case RTW89_DBG_SEL_IQK: ++ seq_puts(m, "Debug selected IQK register\n"); ++ start = 0x180; ++ end = 0x1bf; ++ break; ++ case RTW89_DBG_SEL_RFC: ++ seq_puts(m, "Debug selected RFC register\n"); ++ start = 0x1c0; ++ end = 0x1ff; ++ break; ++ default: ++ seq_puts(m, "Selected invalid register page\n"); ++ return -EINVAL; ++ } ++ ++ for (i = start; i <= end; i++) { ++ page = i << 8; ++ for (j = page; j < page + RTW89_MAC_PAGE_SIZE; j += 16) { ++ seq_printf(m, "%08xh : ", 0x18600000 + j); ++ for (k = 0; k < 4; k++) { ++ val = rtw89_read32(rtwdev, j + (k << 2)); ++ seq_printf(m, "%08x ", val); ++ } ++ seq_puts(m, "\n"); ++ } ++ } ++ ++ return 0; ++} ++ ++static ssize_t ++rtw89_debug_priv_mac_mem_dump_select(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct seq_file *m = (struct seq_file *)filp->private_data; ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ char buf[32]; ++ size_t buf_size; ++ u32 sel, start_addr, len; ++ int num; ++ ++ buf_size = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, buf_size)) ++ return -EFAULT; ++ ++ buf[buf_size] = '\0'; ++ num = sscanf(buf, "%x %x %x", &sel, &start_addr, &len); ++ if (num != 3) { ++ rtw89_info(rtwdev, "invalid format: \n"); ++ return -EINVAL; ++ } ++ ++ debugfs_priv->mac_mem.sel = sel; ++ debugfs_priv->mac_mem.start = start_addr; ++ debugfs_priv->mac_mem.len = len; ++ ++ rtw89_info(rtwdev, "select mem %d start %d len %d\n", ++ sel, start_addr, len); ++ ++ return count; ++} ++ ++static const u32 mac_mem_base_addr_table[RTW89_MAC_MEM_MAX] = { ++ [RTW89_MAC_MEM_SHARED_BUF] = SHARED_BUF_BASE_ADDR, ++ [RTW89_MAC_MEM_DMAC_TBL] = DMAC_TBL_BASE_ADDR, ++ [RTW89_MAC_MEM_SHCUT_MACHDR] = SHCUT_MACHDR_BASE_ADDR, ++ [RTW89_MAC_MEM_STA_SCHED] = STA_SCHED_BASE_ADDR, ++ [RTW89_MAC_MEM_RXPLD_FLTR_CAM] = RXPLD_FLTR_CAM_BASE_ADDR, ++ [RTW89_MAC_MEM_SECURITY_CAM] = SECURITY_CAM_BASE_ADDR, ++ [RTW89_MAC_MEM_WOW_CAM] = WOW_CAM_BASE_ADDR, ++ [RTW89_MAC_MEM_CMAC_TBL] = CMAC_TBL_BASE_ADDR, ++ [RTW89_MAC_MEM_ADDR_CAM] = ADDR_CAM_BASE_ADDR, ++ [RTW89_MAC_MEM_BA_CAM] = BA_CAM_BASE_ADDR, ++ [RTW89_MAC_MEM_BCN_IE_CAM0] = BCN_IE_CAM0_BASE_ADDR, ++ [RTW89_MAC_MEM_BCN_IE_CAM1] = BCN_IE_CAM1_BASE_ADDR, ++}; ++ ++static void rtw89_debug_dump_mac_mem(struct seq_file *m, ++ struct rtw89_dev *rtwdev, ++ u8 sel, u32 start_addr, u32 len) ++{ ++ u32 base_addr, start_page, residue; ++ u32 i, j, p, pages; ++ u32 dump_len, remain; ++ u32 val; ++ ++ remain = len; ++ pages = len / MAC_MEM_DUMP_PAGE_SIZE + 1; ++ start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE; ++ residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE; ++ base_addr = mac_mem_base_addr_table[sel]; ++ base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE; ++ ++ for (p = 0; p < pages; p++) { ++ dump_len = min_t(u32, remain, MAC_MEM_DUMP_PAGE_SIZE); ++ rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, base_addr); ++ for (i = R_AX_INDIR_ACCESS_ENTRY + residue; ++ i < R_AX_INDIR_ACCESS_ENTRY + dump_len;) { ++ seq_printf(m, "%08xh:", i); ++ for (j = 0; ++ j < 4 && i < R_AX_INDIR_ACCESS_ENTRY + dump_len; ++ j++, i += 4) { ++ val = rtw89_read32(rtwdev, i); ++ seq_printf(m, " %08x", val); ++ remain -= 4; ++ } ++ seq_puts(m, "\n"); ++ } ++ base_addr += MAC_MEM_DUMP_PAGE_SIZE; ++ } ++} ++ ++static int ++rtw89_debug_priv_mac_mem_dump_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ rtw89_debug_dump_mac_mem(m, rtwdev, ++ debugfs_priv->mac_mem.sel, ++ debugfs_priv->mac_mem.start, ++ debugfs_priv->mac_mem.len); ++ mutex_unlock(&rtwdev->mutex); ++ ++ return 0; ++} ++ ++static ssize_t ++rtw89_debug_priv_mac_dbg_port_dump_select(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct seq_file *m = (struct seq_file *)filp->private_data; ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ char buf[32]; ++ size_t buf_size; ++ int sel, set; ++ int num; ++ bool enable; ++ ++ buf_size = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, buf_size)) ++ return -EFAULT; ++ ++ buf[buf_size] = '\0'; ++ num = sscanf(buf, "%d %d", &sel, &set); ++ if (num != 2) { ++ rtw89_info(rtwdev, "invalid format: \n"); ++ return -EINVAL; ++ } ++ ++ enable = set == 0 ? false : true; ++ switch (sel) { ++ case 0: ++ debugfs_priv->dbgpkg_en.ss_dbg = enable; ++ break; ++ case 1: ++ debugfs_priv->dbgpkg_en.dle_dbg = enable; ++ break; ++ case 2: ++ debugfs_priv->dbgpkg_en.dmac_dbg = enable; ++ break; ++ case 3: ++ debugfs_priv->dbgpkg_en.cmac_dbg = enable; ++ break; ++ case 4: ++ debugfs_priv->dbgpkg_en.dbg_port = enable; ++ break; ++ default: ++ rtw89_info(rtwdev, "invalid args: sel %d set %d\n", sel, set); ++ return -EINVAL; ++ } ++ ++ rtw89_info(rtwdev, "%s debug port dump %d\n", ++ enable ? "Enable" : "Disable", sel); ++ ++ return count; ++} ++ ++static int rtw89_debug_mac_dump_ss_dbg(struct rtw89_dev *rtwdev, ++ struct seq_file *m) ++{ ++ return 0; ++} ++ ++static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev, ++ struct seq_file *m) ++{ ++#define DLE_DFI_DUMP(__type, __target, __sel) \ ++({ \ ++ u32 __ctrl; \ ++ u32 __reg_ctrl = R_AX_##__type##_DBG_FUN_INTF_CTL; \ ++ u32 __reg_data = R_AX_##__type##_DBG_FUN_INTF_DATA; \ ++ u32 __data, __val32; \ ++ int __ret; \ ++ \ ++ __ctrl = FIELD_PREP(B_AX_##__type##_DFI_TRGSEL_MASK, \ ++ DLE_DFI_TYPE_##__target) | \ ++ FIELD_PREP(B_AX_##__type##_DFI_ADDR_MASK, __sel) | \ ++ B_AX_WDE_DFI_ACTIVE; \ ++ rtw89_write32(rtwdev, __reg_ctrl, __ctrl); \ ++ __ret = read_poll_timeout(rtw89_read32, __val32, \ ++ !(__val32 & B_AX_##__type##_DFI_ACTIVE), \ ++ 1000, 50000, false, \ ++ rtwdev, __reg_ctrl); \ ++ if (__ret) { \ ++ rtw89_err(rtwdev, "failed to dump DLE %s %s %d\n", \ ++ #__type, #__target, __sel); \ ++ return __ret; \ ++ } \ ++ \ ++ __data = rtw89_read32(rtwdev, __reg_data); \ ++ __data; \ ++}) ++ ++#define DLE_DFI_FREE_PAGE_DUMP(__m, __type) \ ++({ \ ++ u32 __freepg, __pubpg; \ ++ u32 __freepg_head, __freepg_tail, __pubpg_num; \ ++ \ ++ __freepg = DLE_DFI_DUMP(__type, FREEPG, 0); \ ++ __pubpg = DLE_DFI_DUMP(__type, FREEPG, 1); \ ++ __freepg_head = FIELD_GET(B_AX_DLE_FREE_HEADPG, __freepg); \ ++ __freepg_tail = FIELD_GET(B_AX_DLE_FREE_TAILPG, __freepg); \ ++ __pubpg_num = FIELD_GET(B_AX_DLE_PUB_PGNUM, __pubpg); \ ++ seq_printf(__m, "[%s] freepg head: %d\n", \ ++ #__type, __freepg_head); \ ++ seq_printf(__m, "[%s] freepg tail: %d\n", \ ++ #__type, __freepg_tail); \ ++ seq_printf(__m, "[%s] pubpg num : %d\n", \ ++ #__type, __pubpg_num); \ ++}) ++ ++#define case_QUOTA(__m, __type, __id) \ ++ case __type##_QTAID_##__id: \ ++ val32 = DLE_DFI_DUMP(__type, QUOTA, __type##_QTAID_##__id); \ ++ rsv_pgnum = FIELD_GET(B_AX_DLE_RSV_PGNUM, val32); \ ++ use_pgnum = FIELD_GET(B_AX_DLE_USE_PGNUM, val32); \ ++ seq_printf(__m, "[%s][%s] rsv_pgnum: %d\n", \ ++ #__type, #__id, rsv_pgnum); \ ++ seq_printf(__m, "[%s][%s] use_pgnum: %d\n", \ ++ #__type, #__id, use_pgnum); \ ++ break ++ u32 quota_id; ++ u32 val32; ++ u16 rsv_pgnum, use_pgnum; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL); ++ if (ret) { ++ seq_puts(m, "[DLE] : DMAC not enabled\n"); ++ return ret; ++ } ++ ++ DLE_DFI_FREE_PAGE_DUMP(m, WDE); ++ DLE_DFI_FREE_PAGE_DUMP(m, PLE); ++ for (quota_id = 0; quota_id <= WDE_QTAID_CPUIO; quota_id++) { ++ switch (quota_id) { ++ case_QUOTA(m, WDE, HOST_IF); ++ case_QUOTA(m, WDE, WLAN_CPU); ++ case_QUOTA(m, WDE, DATA_CPU); ++ case_QUOTA(m, WDE, PKTIN); ++ case_QUOTA(m, WDE, CPUIO); ++ } ++ } ++ for (quota_id = 0; quota_id <= PLE_QTAID_CPUIO; quota_id++) { ++ switch (quota_id) { ++ case_QUOTA(m, PLE, B0_TXPL); ++ case_QUOTA(m, PLE, B1_TXPL); ++ case_QUOTA(m, PLE, C2H); ++ case_QUOTA(m, PLE, H2C); ++ case_QUOTA(m, PLE, WLAN_CPU); ++ case_QUOTA(m, PLE, MPDU); ++ case_QUOTA(m, PLE, CMAC0_RX); ++ case_QUOTA(m, PLE, CMAC1_RX); ++ case_QUOTA(m, PLE, CMAC1_BBRPT); ++ case_QUOTA(m, PLE, WDRLS); ++ case_QUOTA(m, PLE, CPUIO); ++ } ++ } ++ ++ return 0; ++ ++#undef case_QUOTA ++#undef DLE_DFI_DUMP ++#undef DLE_DFI_FREE_PAGE_DUMP ++} ++ ++static int rtw89_debug_mac_dump_dmac_dbg(struct rtw89_dev *rtwdev, ++ struct seq_file *m) ++{ ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL); ++ if (ret) { ++ seq_puts(m, "[DMAC] : DMAC not enabled\n"); ++ return ret; ++ } ++ ++ seq_printf(m, "R_AX_DMAC_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR)); ++ seq_printf(m, "[0]R_AX_WDRLS_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR)); ++ seq_printf(m, "[1]R_AX_SEC_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_ERR_IMR_ISR)); ++ seq_printf(m, "[2.1]R_AX_MPDU_TX_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR)); ++ seq_printf(m, "[2.2]R_AX_MPDU_RX_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR)); ++ seq_printf(m, "[3]R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR)); ++ seq_printf(m, "[4]R_AX_WDE_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); ++ seq_printf(m, "[5.1]R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); ++ seq_printf(m, "[5.2]R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1)); ++ seq_printf(m, "[6]R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); ++ seq_printf(m, "[7]R_AX_PKTIN_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); ++ seq_printf(m, "[8.1]R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR)); ++ seq_printf(m, "[8.2]R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); ++ seq_printf(m, "[8.3]R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); ++ seq_printf(m, "[10]R_AX_CPUIO_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_CPUIO_ERR_ISR)); ++ seq_printf(m, "[11.1]R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); ++ seq_printf(m, "[11.2]R_AX_BBRPT_CHINFO_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR_ISR)); ++ seq_printf(m, "[11.3]R_AX_BBRPT_DFS_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR_ISR)); ++ seq_printf(m, "[11.4]R_AX_LA_ERRFLAG=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_LA_ERRFLAG)); ++ ++ return 0; ++} ++ ++static int rtw89_debug_mac_dump_cmac_dbg(struct rtw89_dev *rtwdev, ++ struct seq_file *m) ++{ ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_CMAC_SEL); ++ if (ret) { ++ seq_puts(m, "[CMAC] : CMAC 0 not enabled\n"); ++ return ret; ++ } ++ ++ seq_printf(m, "R_AX_CMAC_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR)); ++ seq_printf(m, "[0]R_AX_SCHEDULE_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR)); ++ seq_printf(m, "[1]R_AX_PTCL_ISR0=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PTCL_ISR0)); ++ seq_printf(m, "[3]R_AX_DLE_CTRL=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_DLE_CTRL)); ++ seq_printf(m, "[4]R_AX_PHYINFO_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR)); ++ seq_printf(m, "[5]R_AX_TXPWR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPWR_ISR)); ++ seq_printf(m, "[6]R_AX_RMAC_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RMAC_ERR_ISR)); ++ seq_printf(m, "[7]R_AX_TMAC_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR)); ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, 1, RTW89_CMAC_SEL); ++ if (ret) { ++ seq_puts(m, "[CMAC] : CMAC 1 not enabled\n"); ++ return ret; ++ } ++ ++ seq_printf(m, "R_AX_CMAC_ERR_ISR_C1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR_C1)); ++ seq_printf(m, "[0]R_AX_SCHEDULE_ERR_ISR_C1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR_C1)); ++ seq_printf(m, "[1]R_AX_PTCL_ISR0_C1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PTCL_ISR0_C1)); ++ seq_printf(m, "[3]R_AX_DLE_CTRL_C1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_DLE_CTRL_C1)); ++ seq_printf(m, "[4]R_AX_PHYINFO_ERR_ISR_C1=0x%02x\n", ++ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR_C1)); ++ seq_printf(m, "[5]R_AX_TXPWR_ISR_C1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPWR_ISR_C1)); ++ seq_printf(m, "[6]R_AX_RMAC_ERR_ISR_C1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RMAC_ERR_ISR_C1)); ++ seq_printf(m, "[7]R_AX_TMAC_ERR_IMR_ISR_C1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR_C1)); ++ ++ return 0; ++} ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c0 = { ++ .sel_addr = R_AX_PTCL_DBG, ++ .sel_byte = 1, ++ .sel_msk = B_AX_PTCL_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x3F, ++ .rd_addr = R_AX_PTCL_DBG_INFO, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PTCL_DBG_INFO_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c1 = { ++ .sel_addr = R_AX_PTCL_DBG_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_PTCL_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x3F, ++ .rd_addr = R_AX_PTCL_DBG_INFO_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PTCL_DBG_INFO_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_sch_c0 = { ++ .sel_addr = R_AX_SCH_DBG_SEL, ++ .sel_byte = 1, ++ .sel_msk = B_AX_SCH_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x2F, ++ .rd_addr = R_AX_SCH_DBG, ++ .rd_byte = 4, ++ .rd_msk = B_AX_SCHEDULER_DBG_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_sch_c1 = { ++ .sel_addr = R_AX_SCH_DBG_SEL_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_SCH_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x2F, ++ .rd_addr = R_AX_SCH_DBG_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_SCHEDULER_DBG_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_tmac_c0 = { ++ .sel_addr = R_AX_MACTX_DBG_SEL_CNT, ++ .sel_byte = 1, ++ .sel_msk = B_AX_DBGSEL_MACTX_MASK, ++ .srt = 0x00, ++ .end = 0x19, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_tmac_c1 = { ++ .sel_addr = R_AX_MACTX_DBG_SEL_CNT_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_DBGSEL_MACTX_MASK, ++ .srt = 0x00, ++ .end = 0x19, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_rmac_c0 = { ++ .sel_addr = R_AX_RX_DEBUG_SELECT, ++ .sel_byte = 1, ++ .sel_msk = B_AX_DEBUG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x58, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_rmac_c1 = { ++ .sel_addr = R_AX_RX_DEBUG_SELECT_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_DEBUG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x58, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_rmacst_c0 = { ++ .sel_addr = R_AX_RX_STATE_MONITOR, ++ .sel_byte = 1, ++ .sel_msk = B_AX_STATE_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x17, ++ .rd_addr = R_AX_RX_STATE_MONITOR, ++ .rd_byte = 4, ++ .rd_msk = B_AX_RX_STATE_MONITOR_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_rmacst_c1 = { ++ .sel_addr = R_AX_RX_STATE_MONITOR_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_STATE_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x17, ++ .rd_addr = R_AX_RX_STATE_MONITOR_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_RX_STATE_MONITOR_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_rmac_plcp_c0 = { ++ .sel_addr = R_AX_RMAC_PLCP_MON, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PCLP_MON_SEL_MASK, ++ .srt = 0x0, ++ .end = 0xF, ++ .rd_addr = R_AX_RMAC_PLCP_MON, ++ .rd_byte = 4, ++ .rd_msk = B_AX_RMAC_PLCP_MON_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_rmac_plcp_c1 = { ++ .sel_addr = R_AX_RMAC_PLCP_MON_C1, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PCLP_MON_SEL_MASK, ++ .srt = 0x0, ++ .end = 0xF, ++ .rd_addr = R_AX_RMAC_PLCP_MON_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_RMAC_PLCP_MON_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_trxptcl_c0 = { ++ .sel_addr = R_AX_DBGSEL_TRXPTCL, ++ .sel_byte = 1, ++ .sel_msk = B_AX_DBGSEL_TRXPTCL_MASK, ++ .srt = 0x08, ++ .end = 0x10, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_trxptcl_c1 = { ++ .sel_addr = R_AX_DBGSEL_TRXPTCL_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_DBGSEL_TRXPTCL_MASK, ++ .srt = 0x08, ++ .end = 0x10, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_tx_infol_c0 = { ++ .sel_addr = R_AX_WMAC_TX_CTRL_DEBUG, ++ .sel_byte = 1, ++ .sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x07, ++ .rd_addr = R_AX_WMAC_TX_INFO0_DEBUG, ++ .rd_byte = 4, ++ .rd_msk = B_AX_TX_CTRL_INFO_P0_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_tx_infoh_c0 = { ++ .sel_addr = R_AX_WMAC_TX_CTRL_DEBUG, ++ .sel_byte = 1, ++ .sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x07, ++ .rd_addr = R_AX_WMAC_TX_INFO1_DEBUG, ++ .rd_byte = 4, ++ .rd_msk = B_AX_TX_CTRL_INFO_P1_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_tx_infol_c1 = { ++ .sel_addr = R_AX_WMAC_TX_CTRL_DEBUG_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x07, ++ .rd_addr = R_AX_WMAC_TX_INFO0_DEBUG_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_TX_CTRL_INFO_P0_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_tx_infoh_c1 = { ++ .sel_addr = R_AX_WMAC_TX_CTRL_DEBUG_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x07, ++ .rd_addr = R_AX_WMAC_TX_INFO1_DEBUG_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_TX_CTRL_INFO_P1_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infol_c0 = { ++ .sel_addr = R_AX_WMAC_TX_TF_INFO_0, ++ .sel_byte = 1, ++ .sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x04, ++ .rd_addr = R_AX_WMAC_TX_TF_INFO_1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WMAC_TX_TF_INFO_P0_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infoh_c0 = { ++ .sel_addr = R_AX_WMAC_TX_TF_INFO_0, ++ .sel_byte = 1, ++ .sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x04, ++ .rd_addr = R_AX_WMAC_TX_TF_INFO_2, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WMAC_TX_TF_INFO_P1_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infol_c1 = { ++ .sel_addr = R_AX_WMAC_TX_TF_INFO_0_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x04, ++ .rd_addr = R_AX_WMAC_TX_TF_INFO_1_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WMAC_TX_TF_INFO_P0_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infoh_c1 = { ++ .sel_addr = R_AX_WMAC_TX_TF_INFO_0_C1, ++ .sel_byte = 1, ++ .sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x04, ++ .rd_addr = R_AX_WMAC_TX_TF_INFO_2_C1, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WMAC_TX_TF_INFO_P1_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_freepg = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80000000, ++ .end = 0x80000001, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_quota = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80010000, ++ .end = 0x80010004, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_pagellt = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80020000, ++ .end = 0x80020FFF, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_pktinfo = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80030000, ++ .end = 0x80030FFF, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_prepkt = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80040000, ++ .end = 0x80040FFF, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_nxtpkt = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80050000, ++ .end = 0x80050FFF, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_qlnktbl = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80060000, ++ .end = 0x80060453, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_qempty = { ++ .sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_WDE_DFI_DATA_MASK, ++ .srt = 0x80070000, ++ .end = 0x80070011, ++ .rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_WDE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_freepg = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80000000, ++ .end = 0x80000001, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_quota = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80010000, ++ .end = 0x8001000A, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_pagellt = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80020000, ++ .end = 0x80020DBF, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_pktinfo = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80030000, ++ .end = 0x80030DBF, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_prepkt = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80040000, ++ .end = 0x80040DBF, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_nxtpkt = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80050000, ++ .end = 0x80050DBF, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_qlnktbl = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80060000, ++ .end = 0x80060041, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_qempty = { ++ .sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_PLE_DFI_DATA_MASK, ++ .srt = 0x80070000, ++ .end = 0x80070001, ++ .rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_PLE_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pktinfo = { ++ .sel_addr = R_AX_DBG_FUN_INTF_CTL, ++ .sel_byte = 4, ++ .sel_msk = B_AX_DFI_DATA_MASK, ++ .srt = 0x80000000, ++ .end = 0x8000017f, ++ .rd_addr = R_AX_DBG_FUN_INTF_DATA, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DFI_DATA_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pcie_txdma = { ++ .sel_addr = R_AX_PCIE_DBG_CTRL, ++ .sel_byte = 2, ++ .sel_msk = B_AX_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x03, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pcie_rxdma = { ++ .sel_addr = R_AX_PCIE_DBG_CTRL, ++ .sel_byte = 2, ++ .sel_msk = B_AX_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x04, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pcie_cvt = { ++ .sel_addr = R_AX_PCIE_DBG_CTRL, ++ .sel_byte = 2, ++ .sel_msk = B_AX_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x01, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pcie_cxpl = { ++ .sel_addr = R_AX_PCIE_DBG_CTRL, ++ .sel_byte = 2, ++ .sel_msk = B_AX_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x05, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pcie_io = { ++ .sel_addr = R_AX_PCIE_DBG_CTRL, ++ .sel_byte = 2, ++ .sel_msk = B_AX_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x05, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pcie_misc = { ++ .sel_addr = R_AX_PCIE_DBG_CTRL, ++ .sel_byte = 2, ++ .sel_msk = B_AX_DBG_SEL_MASK, ++ .srt = 0x00, ++ .end = 0x06, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info dbg_port_pcie_misc2 = { ++ .sel_addr = R_AX_DBG_CTRL, ++ .sel_byte = 1, ++ .sel_msk = B_AX_DBG_SEL0, ++ .srt = 0x34, ++ .end = 0x3C, ++ .rd_addr = R_AX_DBG_PORT_SEL, ++ .rd_byte = 4, ++ .rd_msk = B_AX_DEBUG_ST_MASK ++}; ++ ++static const struct rtw89_mac_dbg_port_info * ++rtw89_debug_mac_dbg_port_sel(struct seq_file *m, ++ struct rtw89_dev *rtwdev, u32 sel) ++{ ++ const struct rtw89_mac_dbg_port_info *info; ++ u32 val32; ++ u16 val16; ++ u8 val8; ++ ++ switch (sel) { ++ case RTW89_DBG_PORT_SEL_PTCL_C0: ++ info = &dbg_port_ptcl_c0; ++ val16 = rtw89_read16(rtwdev, R_AX_PTCL_DBG); ++ val16 |= B_AX_PTCL_DBG_EN; ++ rtw89_write16(rtwdev, R_AX_PTCL_DBG, val16); ++ seq_puts(m, "Enable PTCL C0 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PTCL_C1: ++ info = &dbg_port_ptcl_c1; ++ val16 = rtw89_read16(rtwdev, R_AX_PTCL_DBG_C1); ++ val16 |= B_AX_PTCL_DBG_EN; ++ rtw89_write16(rtwdev, R_AX_PTCL_DBG_C1, val16); ++ seq_puts(m, "Enable PTCL C1 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_SCH_C0: ++ info = &dbg_port_sch_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_SCH_DBG_SEL); ++ val32 |= B_AX_SCH_DBG_EN; ++ rtw89_write32(rtwdev, R_AX_SCH_DBG_SEL, val32); ++ seq_puts(m, "Enable SCH C0 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_SCH_C1: ++ info = &dbg_port_sch_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_SCH_DBG_SEL_C1); ++ val32 |= B_AX_SCH_DBG_EN; ++ rtw89_write32(rtwdev, R_AX_SCH_DBG_SEL_C1, val32); ++ seq_puts(m, "Enable SCH C1 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TMAC_C0: ++ info = &dbg_port_tmac_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL); ++ val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_TMAC, ++ B_AX_DBGSEL_TRXPTCL_MASK); ++ rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C0, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C0, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); ++ val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); ++ rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); ++ seq_puts(m, "Enable TMAC C0 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TMAC_C1: ++ info = &dbg_port_tmac_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1); ++ val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_TMAC, ++ B_AX_DBGSEL_TRXPTCL_MASK); ++ rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C1, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C1, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); ++ val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); ++ rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); ++ seq_puts(m, "Enable TMAC C1 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_RMAC_C0: ++ info = &dbg_port_rmac_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL); ++ val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_RMAC, ++ B_AX_DBGSEL_TRXPTCL_MASK); ++ rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C0, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C0, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); ++ val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); ++ rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); ++ ++ val8 = rtw89_read8(rtwdev, R_AX_DBGSEL_TRXPTCL); ++ val8 = u8_replace_bits(val8, RMAC_CMAC_DBG_SEL, ++ B_AX_DBGSEL_TRXPTCL_MASK); ++ rtw89_write8(rtwdev, R_AX_DBGSEL_TRXPTCL, val8); ++ seq_puts(m, "Enable RMAC C0 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_RMAC_C1: ++ info = &dbg_port_rmac_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1); ++ val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_RMAC, ++ B_AX_DBGSEL_TRXPTCL_MASK); ++ rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C1, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C1, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); ++ val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); ++ rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); ++ ++ val8 = rtw89_read8(rtwdev, R_AX_DBGSEL_TRXPTCL_C1); ++ val8 = u8_replace_bits(val8, RMAC_CMAC_DBG_SEL, ++ B_AX_DBGSEL_TRXPTCL_MASK); ++ rtw89_write8(rtwdev, R_AX_DBGSEL_TRXPTCL_C1, val8); ++ seq_puts(m, "Enable RMAC C1 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_RMACST_C0: ++ info = &dbg_port_rmacst_c0; ++ seq_puts(m, "Enable RMAC state C0 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_RMACST_C1: ++ info = &dbg_port_rmacst_c1; ++ seq_puts(m, "Enable RMAC state C1 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_RMAC_PLCP_C0: ++ info = &dbg_port_rmac_plcp_c0; ++ seq_puts(m, "Enable RMAC PLCP C0 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_RMAC_PLCP_C1: ++ info = &dbg_port_rmac_plcp_c1; ++ seq_puts(m, "Enable RMAC PLCP C1 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TRXPTCL_C0: ++ info = &dbg_port_trxptcl_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C0, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C0, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); ++ val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); ++ rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); ++ seq_puts(m, "Enable TRXPTCL C0 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TRXPTCL_C1: ++ info = &dbg_port_trxptcl_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C1, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C1, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ ++ val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1); ++ val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK); ++ rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); ++ seq_puts(m, "Enable TRXPTCL C1 dbgport.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TX_INFOL_C0: ++ info = &dbg_port_tx_infol_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1, val32); ++ seq_puts(m, "Enable tx infol dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TX_INFOH_C0: ++ info = &dbg_port_tx_infoh_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1, val32); ++ seq_puts(m, "Enable tx infoh dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TX_INFOL_C1: ++ info = &dbg_port_tx_infol_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); ++ seq_puts(m, "Enable tx infol dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TX_INFOH_C1: ++ info = &dbg_port_tx_infoh_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); ++ seq_puts(m, "Enable tx infoh dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TXTF_INFOL_C0: ++ info = &dbg_port_txtf_infol_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1, val32); ++ seq_puts(m, "Enable tx tf infol dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TXTF_INFOH_C0: ++ info = &dbg_port_txtf_infoh_c0; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1, val32); ++ seq_puts(m, "Enable tx tf infoh dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TXTF_INFOL_C1: ++ info = &dbg_port_txtf_infol_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); ++ seq_puts(m, "Enable tx tf infol dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_TXTF_INFOH_C1: ++ info = &dbg_port_txtf_infoh_c1; ++ val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1); ++ val32 |= B_AX_TCR_FORCE_READ_TXDFIFO; ++ rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); ++ seq_puts(m, "Enable tx tf infoh dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG: ++ info = &dbg_port_wde_bufmgn_freepg; ++ seq_puts(m, "Enable wde bufmgn freepg dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_BUFMGN_QUOTA: ++ info = &dbg_port_wde_bufmgn_quota; ++ seq_puts(m, "Enable wde bufmgn quota dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_BUFMGN_PAGELLT: ++ info = &dbg_port_wde_bufmgn_pagellt; ++ seq_puts(m, "Enable wde bufmgn pagellt dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_BUFMGN_PKTINFO: ++ info = &dbg_port_wde_bufmgn_pktinfo; ++ seq_puts(m, "Enable wde bufmgn pktinfo dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_QUEMGN_PREPKT: ++ info = &dbg_port_wde_quemgn_prepkt; ++ seq_puts(m, "Enable wde quemgn prepkt dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_QUEMGN_NXTPKT: ++ info = &dbg_port_wde_quemgn_nxtpkt; ++ seq_puts(m, "Enable wde quemgn nxtpkt dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_QUEMGN_QLNKTBL: ++ info = &dbg_port_wde_quemgn_qlnktbl; ++ seq_puts(m, "Enable wde quemgn qlnktbl dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_WDE_QUEMGN_QEMPTY: ++ info = &dbg_port_wde_quemgn_qempty; ++ seq_puts(m, "Enable wde quemgn qempty dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_BUFMGN_FREEPG: ++ info = &dbg_port_ple_bufmgn_freepg; ++ seq_puts(m, "Enable ple bufmgn freepg dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_BUFMGN_QUOTA: ++ info = &dbg_port_ple_bufmgn_quota; ++ seq_puts(m, "Enable ple bufmgn quota dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_BUFMGN_PAGELLT: ++ info = &dbg_port_ple_bufmgn_pagellt; ++ seq_puts(m, "Enable ple bufmgn pagellt dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_BUFMGN_PKTINFO: ++ info = &dbg_port_ple_bufmgn_pktinfo; ++ seq_puts(m, "Enable ple bufmgn pktinfo dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_QUEMGN_PREPKT: ++ info = &dbg_port_ple_quemgn_prepkt; ++ seq_puts(m, "Enable ple quemgn prepkt dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_QUEMGN_NXTPKT: ++ info = &dbg_port_ple_quemgn_nxtpkt; ++ seq_puts(m, "Enable ple quemgn nxtpkt dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_QUEMGN_QLNKTBL: ++ info = &dbg_port_ple_quemgn_qlnktbl; ++ seq_puts(m, "Enable ple quemgn qlnktbl dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PLE_QUEMGN_QEMPTY: ++ info = &dbg_port_ple_quemgn_qempty; ++ seq_puts(m, "Enable ple quemgn qempty dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PKTINFO: ++ info = &dbg_port_pktinfo; ++ seq_puts(m, "Enable pktinfo dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PCIE_TXDMA: ++ info = &dbg_port_pcie_txdma; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, PCIE_TXDMA_DBG_SEL, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, PCIE_TXDMA_DBG_SEL, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ seq_puts(m, "Enable pcie txdma dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PCIE_RXDMA: ++ info = &dbg_port_pcie_rxdma; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, PCIE_RXDMA_DBG_SEL, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, PCIE_RXDMA_DBG_SEL, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ seq_puts(m, "Enable pcie rxdma dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PCIE_CVT: ++ info = &dbg_port_pcie_cvt; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, PCIE_CVT_DBG_SEL, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, PCIE_CVT_DBG_SEL, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ seq_puts(m, "Enable pcie cvt dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PCIE_CXPL: ++ info = &dbg_port_pcie_cxpl; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, PCIE_CXPL_DBG_SEL, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, PCIE_CXPL_DBG_SEL, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ seq_puts(m, "Enable pcie cxpl dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PCIE_IO: ++ info = &dbg_port_pcie_io; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, PCIE_IO_DBG_SEL, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, PCIE_IO_DBG_SEL, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ seq_puts(m, "Enable pcie io dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PCIE_MISC: ++ info = &dbg_port_pcie_misc; ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL); ++ val32 = u32_replace_bits(val32, PCIE_MISC_DBG_SEL, B_AX_DBG_SEL0); ++ val32 = u32_replace_bits(val32, PCIE_MISC_DBG_SEL, B_AX_DBG_SEL1); ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); ++ seq_puts(m, "Enable pcie misc dump.\n"); ++ break; ++ case RTW89_DBG_PORT_SEL_PCIE_MISC2: ++ info = &dbg_port_pcie_misc2; ++ val16 = rtw89_read16(rtwdev, R_AX_PCIE_DBG_CTRL); ++ val16 = u16_replace_bits(val16, PCIE_MISC2_DBG_SEL, ++ B_AX_DBG_SEL_MASK); ++ rtw89_write16(rtwdev, R_AX_PCIE_DBG_CTRL, val16); ++ seq_puts(m, "Enable pcie misc2 dump.\n"); ++ break; ++ default: ++ seq_puts(m, "Dbg port select err\n"); ++ return NULL; ++ } ++ ++ return info; ++} ++ ++static bool is_dbg_port_valid(struct rtw89_dev *rtwdev, u32 sel) ++{ ++ if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE && ++ sel >= RTW89_DBG_PORT_SEL_PCIE_TXDMA && ++ sel <= RTW89_DBG_PORT_SEL_PCIE_MISC2) ++ return false; ++ if (rtwdev->chip->chip_id == RTL8852B && ++ sel >= RTW89_DBG_PORT_SEL_PTCL_C1 && ++ sel <= RTW89_DBG_PORT_SEL_TXTF_INFOH_C1) ++ return false; ++ if (rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL) && ++ sel >= RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG && ++ sel <= RTW89_DBG_PORT_SEL_PKTINFO) ++ return false; ++ if (rtw89_mac_check_mac_en(rtwdev, 0, RTW89_CMAC_SEL) && ++ sel >= RTW89_DBG_PORT_SEL_PTCL_C0 && ++ sel <= RTW89_DBG_PORT_SEL_TXTF_INFOH_C0) ++ return false; ++ if (rtw89_mac_check_mac_en(rtwdev, 1, RTW89_CMAC_SEL) && ++ sel >= RTW89_DBG_PORT_SEL_PTCL_C1 && ++ sel <= RTW89_DBG_PORT_SEL_TXTF_INFOH_C1) ++ return false; ++ ++ return true; ++} ++ ++static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev, ++ struct seq_file *m, u32 sel) ++{ ++ const struct rtw89_mac_dbg_port_info *info; ++ u8 val8; ++ u16 val16; ++ u32 val32; ++ u32 i; ++ ++ info = rtw89_debug_mac_dbg_port_sel(m, rtwdev, sel); ++ if (!info) { ++ rtw89_err(rtwdev, "failed to select debug port %d\n", sel); ++ return -EINVAL; ++ } ++ ++#define case_DBG_SEL(__sel) \ ++ case RTW89_DBG_PORT_SEL_##__sel: \ ++ seq_puts(m, "Dump debug port " #__sel ":\n"); \ ++ break ++ ++ switch (sel) { ++ case_DBG_SEL(PTCL_C0); ++ case_DBG_SEL(PTCL_C1); ++ case_DBG_SEL(SCH_C0); ++ case_DBG_SEL(SCH_C1); ++ case_DBG_SEL(TMAC_C0); ++ case_DBG_SEL(TMAC_C1); ++ case_DBG_SEL(RMAC_C0); ++ case_DBG_SEL(RMAC_C1); ++ case_DBG_SEL(RMACST_C0); ++ case_DBG_SEL(RMACST_C1); ++ case_DBG_SEL(TRXPTCL_C0); ++ case_DBG_SEL(TRXPTCL_C1); ++ case_DBG_SEL(TX_INFOL_C0); ++ case_DBG_SEL(TX_INFOH_C0); ++ case_DBG_SEL(TX_INFOL_C1); ++ case_DBG_SEL(TX_INFOH_C1); ++ case_DBG_SEL(TXTF_INFOL_C0); ++ case_DBG_SEL(TXTF_INFOH_C0); ++ case_DBG_SEL(TXTF_INFOL_C1); ++ case_DBG_SEL(TXTF_INFOH_C1); ++ case_DBG_SEL(WDE_BUFMGN_FREEPG); ++ case_DBG_SEL(WDE_BUFMGN_QUOTA); ++ case_DBG_SEL(WDE_BUFMGN_PAGELLT); ++ case_DBG_SEL(WDE_BUFMGN_PKTINFO); ++ case_DBG_SEL(WDE_QUEMGN_PREPKT); ++ case_DBG_SEL(WDE_QUEMGN_NXTPKT); ++ case_DBG_SEL(WDE_QUEMGN_QLNKTBL); ++ case_DBG_SEL(WDE_QUEMGN_QEMPTY); ++ case_DBG_SEL(PLE_BUFMGN_FREEPG); ++ case_DBG_SEL(PLE_BUFMGN_QUOTA); ++ case_DBG_SEL(PLE_BUFMGN_PAGELLT); ++ case_DBG_SEL(PLE_BUFMGN_PKTINFO); ++ case_DBG_SEL(PLE_QUEMGN_PREPKT); ++ case_DBG_SEL(PLE_QUEMGN_NXTPKT); ++ case_DBG_SEL(PLE_QUEMGN_QLNKTBL); ++ case_DBG_SEL(PLE_QUEMGN_QEMPTY); ++ case_DBG_SEL(PKTINFO); ++ case_DBG_SEL(PCIE_TXDMA); ++ case_DBG_SEL(PCIE_RXDMA); ++ case_DBG_SEL(PCIE_CVT); ++ case_DBG_SEL(PCIE_CXPL); ++ case_DBG_SEL(PCIE_IO); ++ case_DBG_SEL(PCIE_MISC); ++ case_DBG_SEL(PCIE_MISC2); ++ } ++ ++#undef case_DBG_SEL ++ ++ seq_printf(m, "Sel addr = 0x%X\n", info->sel_addr); ++ seq_printf(m, "Read addr = 0x%X\n", info->rd_addr); ++ ++ for (i = info->srt; i <= info->end; i++) { ++ switch (info->sel_byte) { ++ case 1: ++ default: ++ rtw89_write8_mask(rtwdev, info->sel_addr, ++ info->sel_msk, i); ++ seq_printf(m, "0x%02X: ", i); ++ break; ++ case 2: ++ rtw89_write16_mask(rtwdev, info->sel_addr, ++ info->sel_msk, i); ++ seq_printf(m, "0x%04X: ", i); ++ break; ++ case 4: ++ rtw89_write32_mask(rtwdev, info->sel_addr, ++ info->sel_msk, i); ++ seq_printf(m, "0x%04X: ", i); ++ break; ++ } ++ ++ udelay(10); ++ ++ switch (info->rd_byte) { ++ case 1: ++ default: ++ val8 = rtw89_read8_mask(rtwdev, ++ info->rd_addr, info->rd_msk); ++ seq_printf(m, "0x%02X\n", val8); ++ break; ++ case 2: ++ val16 = rtw89_read16_mask(rtwdev, ++ info->rd_addr, info->rd_msk); ++ seq_printf(m, "0x%04X\n", val16); ++ break; ++ case 4: ++ val32 = rtw89_read32_mask(rtwdev, ++ info->rd_addr, info->rd_msk); ++ seq_printf(m, "0x%08X\n", val32); ++ break; ++ } ++ } ++ ++ return 0; ++} ++ ++static int rtw89_debug_mac_dump_dbg_port(struct rtw89_dev *rtwdev, ++ struct seq_file *m) ++{ ++ u32 sel; ++ int ret = 0; ++ ++ for (sel = RTW89_DBG_PORT_SEL_PTCL_C0; ++ sel < RTW89_DBG_PORT_SEL_LAST; sel++) { ++ if (!is_dbg_port_valid(rtwdev, sel)) ++ continue; ++ ret = rtw89_debug_mac_dbg_port_dump(rtwdev, m, sel); ++ if (ret) { ++ rtw89_err(rtwdev, ++ "failed to dump debug port %d\n", sel); ++ break; ++ } ++ } ++ ++ return ret; ++} ++ ++static int ++rtw89_debug_priv_mac_dbg_port_dump_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ ++ if (debugfs_priv->dbgpkg_en.ss_dbg) ++ rtw89_debug_mac_dump_ss_dbg(rtwdev, m); ++ if (debugfs_priv->dbgpkg_en.dle_dbg) ++ rtw89_debug_mac_dump_dle_dbg(rtwdev, m); ++ if (debugfs_priv->dbgpkg_en.dmac_dbg) ++ rtw89_debug_mac_dump_dmac_dbg(rtwdev, m); ++ if (debugfs_priv->dbgpkg_en.cmac_dbg) ++ rtw89_debug_mac_dump_cmac_dbg(rtwdev, m); ++ if (debugfs_priv->dbgpkg_en.dbg_port) ++ rtw89_debug_mac_dump_dbg_port(rtwdev, m); ++ ++ return 0; ++}; ++ ++static u8 *rtw89_hex2bin_user(struct rtw89_dev *rtwdev, ++ const char __user *user_buf, size_t count) ++{ ++ char *buf; ++ u8 *bin; ++ int num; ++ int err = 0; ++ ++ buf = memdup_user(user_buf, count); ++ if (IS_ERR(buf)) ++ return buf; ++ ++ num = count / 2; ++ bin = kmalloc(num, GFP_KERNEL); ++ if (!bin) { ++ err = -EFAULT; ++ goto out; ++ } ++ ++ if (hex2bin(bin, buf, num)) { ++ rtw89_info(rtwdev, "valid format: H1H2H3...\n"); ++ kfree(bin); ++ err = -EINVAL; ++ } ++ ++out: ++ kfree(buf); ++ ++ return err ? ERR_PTR(err) : bin; ++} ++ ++static ssize_t rtw89_debug_priv_send_h2c_set(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ u8 *h2c; ++ u16 h2c_len = count / 2; ++ ++ h2c = rtw89_hex2bin_user(rtwdev, user_buf, count); ++ if (IS_ERR(h2c)) ++ return -EFAULT; ++ ++ rtw89_fw_h2c_raw(rtwdev, h2c, h2c_len); ++ ++ kfree(h2c); ++ ++ return count; ++} ++ ++static int ++rtw89_debug_priv_early_h2c_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ struct rtw89_early_h2c *early_h2c; ++ int seq = 0; ++ ++ mutex_lock(&rtwdev->mutex); ++ list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) ++ seq_printf(m, "%d: %*ph\n", ++seq, early_h2c->h2c_len, early_h2c->h2c); ++ mutex_unlock(&rtwdev->mutex); ++ ++ return 0; ++} ++ ++static ssize_t ++rtw89_debug_priv_early_h2c_set(struct file *filp, const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct seq_file *m = (struct seq_file *)filp->private_data; ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ struct rtw89_early_h2c *early_h2c; ++ u8 *h2c; ++ u16 h2c_len = count / 2; ++ ++ h2c = rtw89_hex2bin_user(rtwdev, user_buf, count); ++ if (IS_ERR(h2c)) ++ return -EFAULT; ++ ++ if (h2c_len >= 2 && h2c[0] == 0x00 && h2c[1] == 0x00) { ++ kfree(h2c); ++ rtw89_fw_free_all_early_h2c(rtwdev); ++ goto out; ++ } ++ ++ early_h2c = kmalloc(sizeof(*early_h2c), GFP_KERNEL); ++ if (!early_h2c) { ++ kfree(h2c); ++ return -EFAULT; ++ } ++ ++ early_h2c->h2c = h2c; ++ early_h2c->h2c_len = h2c_len; ++ ++ mutex_lock(&rtwdev->mutex); ++ list_add_tail(&early_h2c->list, &rtwdev->early_h2c_list); ++ mutex_unlock(&rtwdev->mutex); ++ ++out: ++ return count; ++} ++ ++static int rtw89_debug_priv_btc_info_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ ++ rtw89_btc_dump_info(rtwdev, m); ++ ++ return 0; ++} ++ ++static ssize_t rtw89_debug_priv_btc_manual_set(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ bool btc_manual; ++ ++ if (kstrtobool_from_user(user_buf, count, &btc_manual)) ++ goto out; ++ ++ btc->ctrl.manual = btc_manual; ++out: ++ return count; ++} ++ ++static ssize_t rtw89_debug_fw_log_btc_manual_set(struct file *filp, ++ const char __user *user_buf, ++ size_t count, loff_t *loff) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ struct rtw89_fw_info *fw_info = &rtwdev->fw; ++ bool fw_log_manual; ++ ++ if (kstrtobool_from_user(user_buf, count, &fw_log_manual)) ++ goto out; ++ ++ mutex_lock(&rtwdev->mutex); ++ fw_info->fw_log_enable = fw_log_manual; ++ rtw89_fw_h2c_fw_log(rtwdev, fw_log_manual); ++ mutex_unlock(&rtwdev->mutex); ++out: ++ return count; ++} ++ ++static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) ++{ ++ static const char * const he_gi_str[] = { ++ [NL80211_RATE_INFO_HE_GI_0_8] = "0.8", ++ [NL80211_RATE_INFO_HE_GI_1_6] = "1.6", ++ [NL80211_RATE_INFO_HE_GI_3_2] = "3.2", ++ }; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rate_info *rate = &rtwsta->ra_report.txrate; ++ struct ieee80211_rx_status *status = &rtwsta->rx_status; ++ struct seq_file *m = (struct seq_file *)data; ++ u8 rssi; ++ ++ seq_printf(m, "TX rate [%d]: ", rtwsta->mac_id); ++ ++ if (rate->flags & RATE_INFO_FLAGS_MCS) ++ seq_printf(m, "HT MCS-%d%s", rate->mcs, ++ rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : ""); ++ else if (rate->flags & RATE_INFO_FLAGS_VHT_MCS) ++ seq_printf(m, "VHT %dSS MCS-%d%s", rate->nss, rate->mcs, ++ rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : ""); ++ else if (rate->flags & RATE_INFO_FLAGS_HE_MCS) ++ seq_printf(m, "HE %dSS MCS-%d GI:%s", rate->nss, rate->mcs, ++ rate->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ? ++ he_gi_str[rate->he_gi] : "N/A"); ++ else ++ seq_printf(m, "Legacy %d", rate->legacy); ++ seq_printf(m, "\t(hw_rate=0x%x)", rtwsta->ra_report.hw_rate); ++ seq_printf(m, "\t==> agg_wait=%d (%d)\n", rtwsta->max_agg_wait, ++ sta->max_rc_amsdu_len); ++ ++ seq_printf(m, "RX rate [%d]: ", rtwsta->mac_id); ++ ++ switch (status->encoding) { ++ case RX_ENC_LEGACY: ++ seq_printf(m, "Legacy %d", status->rate_idx + ++ (status->band == NL80211_BAND_5GHZ ? 4 : 0)); ++ break; ++ case RX_ENC_HT: ++ seq_printf(m, "HT MCS-%d%s", status->rate_idx, ++ status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : ""); ++ break; ++ case RX_ENC_VHT: ++ seq_printf(m, "VHT %dSS MCS-%d%s", status->nss, status->rate_idx, ++ status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : ""); ++ break; ++ case RX_ENC_HE: ++ seq_printf(m, "HE %dSS MCS-%d GI:%s", status->nss, status->rate_idx, ++ status->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ? ++ he_gi_str[rate->he_gi] : "N/A"); ++ break; ++ } ++ seq_printf(m, "\t(hw_rate=0x%x)\n", rtwsta->rx_hw_rate); ++ ++ rssi = ewma_rssi_read(&rtwsta->avg_rssi); ++ seq_printf(m, "RSSI: %d dBm (raw=%d, prev=%d)\n", ++ RTW89_RSSI_RAW_TO_DBM(rssi), rssi, rtwsta->prev_rssi); ++} ++ ++static void ++rtw89_debug_append_rx_rate(struct seq_file *m, struct rtw89_pkt_stat *pkt_stat, ++ enum rtw89_hw_rate first_rate, int len) ++{ ++ int i; ++ ++ for (i = 0; i < len; i++) ++ seq_printf(m, "%s%u", i == 0 ? "" : ", ", ++ pkt_stat->rx_rate_cnt[first_rate + i]); ++} ++ ++static const struct rtw89_rx_rate_cnt_info { ++ enum rtw89_hw_rate first_rate; ++ int len; ++ const char *rate_mode; ++} rtw89_rx_rate_cnt_infos[] = { ++ {RTW89_HW_RATE_CCK1, 4, "Legacy:"}, ++ {RTW89_HW_RATE_OFDM6, 8, "OFDM:"}, ++ {RTW89_HW_RATE_MCS0, 8, "HT 0:"}, ++ {RTW89_HW_RATE_MCS8, 8, "HT 1:"}, ++ {RTW89_HW_RATE_VHT_NSS1_MCS0, 10, "VHT 1SS:"}, ++ {RTW89_HW_RATE_VHT_NSS2_MCS0, 10, "VHT 2SS:"}, ++ {RTW89_HW_RATE_HE_NSS1_MCS0, 12, "HE 1SS:"}, ++ {RTW89_HW_RATE_HE_NSS2_MCS0, 12, "HE 2ss:"}, ++}; ++ ++static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v) ++{ ++ struct rtw89_debugfs_priv *debugfs_priv = m->private; ++ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ struct rtw89_traffic_stats *stats = &rtwdev->stats; ++ struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.last_pkt_stat; ++ const struct rtw89_rx_rate_cnt_info *info; ++ int i; ++ ++ seq_printf(m, "TP TX: %u [%u] Mbps (lv: %d), RX: %u [%u] Mbps (lv: %d)\n", ++ stats->tx_throughput, stats->tx_throughput_raw, stats->tx_tfc_lv, ++ stats->rx_throughput, stats->rx_throughput_raw, stats->rx_tfc_lv); ++ seq_printf(m, "Beacon: %u\n", pkt_stat->beacon_nr); ++ seq_printf(m, "Avg packet length: TX=%u, RX=%u\n", stats->tx_avg_len, ++ stats->rx_avg_len); ++ ++ seq_puts(m, "RX count:\n"); ++ for (i = 0; i < ARRAY_SIZE(rtw89_rx_rate_cnt_infos); i++) { ++ info = &rtw89_rx_rate_cnt_infos[i]; ++ seq_printf(m, "%10s [", info->rate_mode); ++ rtw89_debug_append_rx_rate(m, pkt_stat, ++ info->first_rate, info->len); ++ seq_puts(m, "]\n"); ++ } ++ ++ ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_info_get_iter, m); ++ ++ return 0; ++} ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_read_reg = { ++ .cb_read = rtw89_debug_priv_read_reg_get, ++ .cb_write = rtw89_debug_priv_read_reg_select, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_write_reg = { ++ .cb_write = rtw89_debug_priv_write_reg_set, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_read_rf = { ++ .cb_read = rtw89_debug_priv_read_rf_get, ++ .cb_write = rtw89_debug_priv_read_rf_select, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_write_rf = { ++ .cb_write = rtw89_debug_priv_write_rf_set, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_rf_reg_dump = { ++ .cb_read = rtw89_debug_priv_rf_reg_dump_get, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_txpwr_table = { ++ .cb_read = rtw89_debug_priv_txpwr_table_get, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_mac_reg_dump = { ++ .cb_read = rtw89_debug_priv_mac_reg_dump_get, ++ .cb_write = rtw89_debug_priv_mac_reg_dump_select, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_mac_mem_dump = { ++ .cb_read = rtw89_debug_priv_mac_mem_dump_get, ++ .cb_write = rtw89_debug_priv_mac_mem_dump_select, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_mac_dbg_port_dump = { ++ .cb_read = rtw89_debug_priv_mac_dbg_port_dump_get, ++ .cb_write = rtw89_debug_priv_mac_dbg_port_dump_select, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_send_h2c = { ++ .cb_write = rtw89_debug_priv_send_h2c_set, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_early_h2c = { ++ .cb_read = rtw89_debug_priv_early_h2c_get, ++ .cb_write = rtw89_debug_priv_early_h2c_set, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_btc_info = { ++ .cb_read = rtw89_debug_priv_btc_info_get, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_btc_manual = { ++ .cb_write = rtw89_debug_priv_btc_manual_set, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_fw_log_manual = { ++ .cb_write = rtw89_debug_fw_log_btc_manual_set, ++}; ++ ++static struct rtw89_debugfs_priv rtw89_debug_priv_phy_info = { ++ .cb_read = rtw89_debug_priv_phy_info_get, ++}; ++ ++#define rtw89_debugfs_add(name, mode, fopname, parent) \ ++ do { \ ++ rtw89_debug_priv_ ##name.rtwdev = rtwdev; \ ++ if (!debugfs_create_file(#name, mode, \ ++ parent, &rtw89_debug_priv_ ##name, \ ++ &file_ops_ ##fopname)) \ ++ pr_debug("Unable to initialize debugfs:%s\n", #name); \ ++ } while (0) ++ ++#define rtw89_debugfs_add_w(name) \ ++ rtw89_debugfs_add(name, S_IFREG | 0222, single_w, debugfs_topdir) ++#define rtw89_debugfs_add_rw(name) \ ++ rtw89_debugfs_add(name, S_IFREG | 0666, common_rw, debugfs_topdir) ++#define rtw89_debugfs_add_r(name) \ ++ rtw89_debugfs_add(name, S_IFREG | 0444, single_r, debugfs_topdir) ++ ++void rtw89_debugfs_init(struct rtw89_dev *rtwdev) ++{ ++ struct dentry *debugfs_topdir; ++ ++ debugfs_topdir = debugfs_create_dir("rtw89", ++ rtwdev->hw->wiphy->debugfsdir); ++ ++ rtw89_debugfs_add_rw(read_reg); ++ rtw89_debugfs_add_w(write_reg); ++ rtw89_debugfs_add_rw(read_rf); ++ rtw89_debugfs_add_w(write_rf); ++ rtw89_debugfs_add_r(rf_reg_dump); ++ rtw89_debugfs_add_r(txpwr_table); ++ rtw89_debugfs_add_rw(mac_reg_dump); ++ rtw89_debugfs_add_rw(mac_mem_dump); ++ rtw89_debugfs_add_rw(mac_dbg_port_dump); ++ rtw89_debugfs_add_w(send_h2c); ++ rtw89_debugfs_add_rw(early_h2c); ++ rtw89_debugfs_add_r(btc_info); ++ rtw89_debugfs_add_w(btc_manual); ++ rtw89_debugfs_add_w(fw_log_manual); ++ rtw89_debugfs_add_r(phy_info); ++} ++#endif ++ ++#ifdef CONFIG_RTW89_DEBUGMSG ++void __rtw89_debug(struct rtw89_dev *rtwdev, ++ enum rtw89_debug_mask mask, ++ const char *fmt, ...) ++{ ++ struct va_format vaf = { ++ .fmt = fmt, ++ }; ++ ++ va_list args; ++ ++ va_start(args, fmt); ++ vaf.va = &args; ++ ++ if (rtw89_debug_mask & mask) ++ dev_printk(KERN_DEBUG, rtwdev->dev, "%pV", &vaf); ++ ++ va_end(args); ++} ++EXPORT_SYMBOL(__rtw89_debug); ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/debug.h b/drivers/net/wireless/realtek/rtw89/debug.h +new file mode 100644 +index 000000000000..f14b726c1a9f +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/debug.h +@@ -0,0 +1,77 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_DEBUG_H__ ++#define __RTW89_DEBUG_H__ ++ ++#include "core.h" ++ ++enum rtw89_debug_mask { ++ RTW89_DBG_TXRX = BIT(0), ++ RTW89_DBG_RFK = BIT(1), ++ RTW89_DBG_RFK_TRACK = BIT(2), ++ RTW89_DBG_CFO = BIT(3), ++ RTW89_DBG_TSSI = BIT(4), ++ RTW89_DBG_TXPWR = BIT(5), ++ RTW89_DBG_HCI = BIT(6), ++ RTW89_DBG_RA = BIT(7), ++ RTW89_DBG_REGD = BIT(8), ++ RTW89_DBG_PHY_TRACK = BIT(9), ++ RTW89_DBG_DIG = BIT(10), ++ RTW89_DBG_SER = BIT(11), ++ RTW89_DBG_FW = BIT(12), ++ RTW89_DBG_BTC = BIT(13), ++ RTW89_DBG_BF = BIT(14), ++}; ++ ++enum rtw89_debug_mac_reg_sel { ++ RTW89_DBG_SEL_MAC_00, ++ RTW89_DBG_SEL_MAC_40, ++ RTW89_DBG_SEL_MAC_80, ++ RTW89_DBG_SEL_MAC_C0, ++ RTW89_DBG_SEL_MAC_E0, ++ RTW89_DBG_SEL_BB, ++ RTW89_DBG_SEL_IQK, ++ RTW89_DBG_SEL_RFC, ++}; ++ ++#ifdef CONFIG_RTW89_DEBUGFS ++void rtw89_debugfs_init(struct rtw89_dev *rtwdev); ++#else ++static inline void rtw89_debugfs_init(struct rtw89_dev *rtwdev) {} ++#endif ++ ++#define rtw89_info(rtwdev, a...) dev_info((rtwdev)->dev, ##a) ++#define rtw89_warn(rtwdev, a...) dev_warn((rtwdev)->dev, ##a) ++#define rtw89_err(rtwdev, a...) dev_err((rtwdev)->dev, ##a) ++ ++#ifdef CONFIG_RTW89_DEBUGMSG ++extern unsigned int rtw89_debug_mask; ++#define rtw89_debug(rtwdev, a...) __rtw89_debug(rtwdev, ##a) ++ ++__printf(3, 4) ++void __rtw89_debug(struct rtw89_dev *rtwdev, ++ enum rtw89_debug_mask mask, ++ const char *fmt, ...); ++static inline void rtw89_hex_dump(struct rtw89_dev *rtwdev, ++ enum rtw89_debug_mask mask, ++ const char *prefix_str, ++ const void *buf, size_t len) ++{ ++ if (!(rtw89_debug_mask & mask)) ++ return; ++ ++ print_hex_dump_bytes(prefix_str, DUMP_PREFIX_OFFSET, buf, len); ++} ++#else ++static inline void rtw89_debug(struct rtw89_dev *rtwdev, ++ enum rtw89_debug_mask mask, ++ const char *fmt, ...) {} ++static inline void rtw89_hex_dump(struct rtw89_dev *rtwdev, ++ enum rtw89_debug_mask mask, ++ const char *prefix_str, ++ const void *buf, size_t len) {} ++#endif ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/efuse.c b/drivers/net/wireless/realtek/rtw89/efuse.c +new file mode 100644 +index 000000000000..c0b80f3da56c +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/efuse.c +@@ -0,0 +1,188 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "debug.h" ++#include "efuse.h" ++#include "reg.h" ++ ++enum rtw89_efuse_bank { ++ RTW89_EFUSE_BANK_WIFI, ++ RTW89_EFUSE_BANK_BT, ++}; ++ ++static int rtw89_switch_efuse_bank(struct rtw89_dev *rtwdev, ++ enum rtw89_efuse_bank bank) ++{ ++ u8 val; ++ ++ val = rtw89_read32_mask(rtwdev, R_AX_EFUSE_CTRL_1, ++ B_AX_EF_CELL_SEL_MASK); ++ if (bank == val) ++ return 0; ++ ++ rtw89_write32_mask(rtwdev, R_AX_EFUSE_CTRL_1, B_AX_EF_CELL_SEL_MASK, ++ bank); ++ ++ val = rtw89_read32_mask(rtwdev, R_AX_EFUSE_CTRL_1, ++ B_AX_EF_CELL_SEL_MASK); ++ if (bank == val) ++ return 0; ++ ++ return -EBUSY; ++} ++ ++static int rtw89_dump_physical_efuse_map(struct rtw89_dev *rtwdev, u8 *map, ++ u32 dump_addr, u32 dump_size) ++{ ++ u32 efuse_ctl; ++ u32 addr; ++ int ret; ++ ++ rtw89_switch_efuse_bank(rtwdev, RTW89_EFUSE_BANK_WIFI); ++ ++ for (addr = dump_addr; addr < dump_addr + dump_size; addr++) { ++ efuse_ctl = u32_encode_bits(addr, B_AX_EF_ADDR_MASK); ++ rtw89_write32(rtwdev, R_AX_EFUSE_CTRL, efuse_ctl & ~B_AX_EF_RDY); ++ ++ ret = read_poll_timeout_atomic(rtw89_read32, efuse_ctl, ++ efuse_ctl & B_AX_EF_RDY, 1, 1000000, ++ true, rtwdev, R_AX_EFUSE_CTRL); ++ if (ret) ++ return -EBUSY; ++ ++ *map++ = (u8)(efuse_ctl & 0xff); ++ } ++ ++ return 0; ++} ++ ++#define invalid_efuse_header(hdr1, hdr2) \ ++ ((hdr1) == 0xff || (hdr2) == 0xff) ++#define invalid_efuse_content(word_en, i) \ ++ (((word_en) & BIT(i)) != 0x0) ++#define get_efuse_blk_idx(hdr1, hdr2) \ ++ ((((hdr2) & 0xf0) >> 4) | (((hdr1) & 0x0f) << 4)) ++#define block_idx_to_logical_idx(blk_idx, i) \ ++ (((blk_idx) << 3) + ((i) << 1)) ++static int rtw89_dump_logical_efuse_map(struct rtw89_dev *rtwdev, u8 *phy_map, ++ u8 *log_map) ++{ ++ u32 physical_size = rtwdev->chip->physical_efuse_size; ++ u32 logical_size = rtwdev->chip->logical_efuse_size; ++ u8 sec_ctrl_size = rtwdev->chip->sec_ctrl_efuse_size; ++ u32 phy_idx = sec_ctrl_size; ++ u32 log_idx; ++ u8 hdr1, hdr2; ++ u8 blk_idx; ++ u8 word_en; ++ int i; ++ ++ while (phy_idx < physical_size - sec_ctrl_size) { ++ hdr1 = phy_map[phy_idx]; ++ hdr2 = phy_map[phy_idx + 1]; ++ if (invalid_efuse_header(hdr1, hdr2)) ++ break; ++ ++ blk_idx = get_efuse_blk_idx(hdr1, hdr2); ++ word_en = hdr2 & 0xf; ++ phy_idx += 2; ++ ++ for (i = 0; i < 4; i++) { ++ if (invalid_efuse_content(word_en, i)) ++ continue; ++ ++ log_idx = block_idx_to_logical_idx(blk_idx, i); ++ if (phy_idx + 1 > physical_size - sec_ctrl_size - 1 || ++ log_idx + 1 > logical_size) ++ return -EINVAL; ++ ++ log_map[log_idx] = phy_map[phy_idx]; ++ log_map[log_idx + 1] = phy_map[phy_idx + 1]; ++ phy_idx += 2; ++ } ++ } ++ return 0; ++} ++ ++int rtw89_parse_efuse_map(struct rtw89_dev *rtwdev) ++{ ++ u32 phy_size = rtwdev->chip->physical_efuse_size; ++ u32 log_size = rtwdev->chip->logical_efuse_size; ++ u8 *phy_map = NULL; ++ u8 *log_map = NULL; ++ int ret; ++ ++ if (rtw89_read16(rtwdev, R_AX_SYS_WL_EFUSE_CTRL) & B_AX_AUTOLOAD_SUS) ++ rtwdev->efuse.valid = true; ++ else ++ rtw89_warn(rtwdev, "failed to check efuse autoload\n"); ++ ++ phy_map = kmalloc(phy_size, GFP_KERNEL); ++ log_map = kmalloc(log_size, GFP_KERNEL); ++ ++ if (!phy_map || !log_map) { ++ ret = -ENOMEM; ++ goto out_free; ++ } ++ ++ ret = rtw89_dump_physical_efuse_map(rtwdev, phy_map, 0, phy_size); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to dump efuse physical map\n"); ++ goto out_free; ++ } ++ ++ memset(log_map, 0xff, log_size); ++ ret = rtw89_dump_logical_efuse_map(rtwdev, phy_map, log_map); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to dump efuse logical map\n"); ++ goto out_free; ++ } ++ ++ rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "log_map: ", log_map, log_size); ++ ++ ret = rtwdev->chip->ops->read_efuse(rtwdev, log_map); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to read efuse map\n"); ++ goto out_free; ++ } ++ ++out_free: ++ kfree(log_map); ++ kfree(phy_map); ++ ++ return ret; ++} ++ ++int rtw89_parse_phycap_map(struct rtw89_dev *rtwdev) ++{ ++ u32 phycap_addr = rtwdev->chip->phycap_addr; ++ u32 phycap_size = rtwdev->chip->phycap_size; ++ u8 *phycap_map = NULL; ++ int ret = 0; ++ ++ if (!phycap_size) ++ return 0; ++ ++ phycap_map = kmalloc(phycap_size, GFP_KERNEL); ++ if (!phycap_map) ++ return -ENOMEM; ++ ++ ret = rtw89_dump_physical_efuse_map(rtwdev, phycap_map, ++ phycap_addr, phycap_size); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to dump phycap map\n"); ++ goto out_free; ++ } ++ ++ ret = rtwdev->chip->ops->read_phycap(rtwdev, phycap_map); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to read phycap map\n"); ++ goto out_free; ++ } ++ ++out_free: ++ kfree(phycap_map); ++ ++ return ret; ++} +diff --git a/drivers/net/wireless/realtek/rtw89/efuse.h b/drivers/net/wireless/realtek/rtw89/efuse.h +new file mode 100644 +index 000000000000..622ff95e7476 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/efuse.h +@@ -0,0 +1,13 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_EFUSE_H__ ++#define __RTW89_EFUSE_H__ ++ ++#include "core.h" ++ ++int rtw89_parse_efuse_map(struct rtw89_dev *rtwdev); ++int rtw89_parse_phycap_map(struct rtw89_dev *rtwdev); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +new file mode 100644 +index 000000000000..212aaf577d3c +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -0,0 +1,1641 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "cam.h" ++#include "coex.h" ++#include "debug.h" ++#include "fw.h" ++#include "mac.h" ++#include "phy.h" ++#include "reg.h" ++ ++static struct sk_buff *rtw89_fw_h2c_alloc_skb(u32 len, bool header) ++{ ++ struct sk_buff *skb; ++ u32 header_len = 0; ++ ++ if (header) ++ header_len = H2C_HEADER_LEN; ++ ++ skb = dev_alloc_skb(len + header_len + 24); ++ if (!skb) ++ return NULL; ++ skb_reserve(skb, header_len + 24); ++ memset(skb->data, 0, len); ++ ++ return skb; ++} ++ ++struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(u32 len) ++{ ++ return rtw89_fw_h2c_alloc_skb(len, true); ++} ++ ++struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(u32 len) ++{ ++ return rtw89_fw_h2c_alloc_skb(len, false); ++} ++ ++static u8 _fw_get_rdy(struct rtw89_dev *rtwdev) ++{ ++ u8 val = rtw89_read8(rtwdev, R_AX_WCPU_FW_CTRL); ++ ++ return FIELD_GET(B_AX_WCPU_FWDL_STS_MASK, val); ++} ++ ++#define FWDL_WAIT_CNT 400000 ++int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev) ++{ ++ u8 val; ++ int ret; ++ ++ ret = read_poll_timeout_atomic(_fw_get_rdy, val, ++ val == RTW89_FWDL_WCPU_FW_INIT_RDY, ++ 1, FWDL_WAIT_CNT, false, rtwdev); ++ if (ret) { ++ switch (val) { ++ case RTW89_FWDL_CHECKSUM_FAIL: ++ rtw89_err(rtwdev, "fw checksum fail\n"); ++ return -EINVAL; ++ ++ case RTW89_FWDL_SECURITY_FAIL: ++ rtw89_err(rtwdev, "fw security fail\n"); ++ return -EINVAL; ++ ++ case RTW89_FWDL_CV_NOT_MATCH: ++ rtw89_err(rtwdev, "fw cv not match\n"); ++ return -EINVAL; ++ ++ default: ++ return -EBUSY; ++ } ++ } ++ ++ set_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); ++ ++ return 0; ++} ++ ++static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, ++ struct rtw89_fw_bin_info *info) ++{ ++ struct rtw89_fw_hdr_section_info *section_info; ++ const u8 *fw_end = fw + len; ++ const u8 *bin; ++ u32 i; ++ ++ if (!info) ++ return -EINVAL; ++ ++ info->section_num = GET_FW_HDR_SEC_NUM(fw); ++ info->hdr_len = RTW89_FW_HDR_SIZE + ++ info->section_num * RTW89_FW_SECTION_HDR_SIZE; ++ SET_FW_HDR_PART_SIZE(fw, FWDL_SECTION_PER_PKT_LEN); ++ ++ bin = fw + info->hdr_len; ++ ++ /* jump to section header */ ++ fw += RTW89_FW_HDR_SIZE; ++ section_info = info->section_info; ++ for (i = 0; i < info->section_num; i++) { ++ section_info->len = GET_FWSECTION_HDR_SEC_SIZE(fw); ++ if (GET_FWSECTION_HDR_CHECKSUM(fw)) ++ section_info->len += FWDL_SECTION_CHKSUM_LEN; ++ section_info->redl = GET_FWSECTION_HDR_REDL(fw); ++ section_info->dladdr = ++ GET_FWSECTION_HDR_DL_ADDR(fw) & 0x1fffffff; ++ section_info->addr = bin; ++ bin += section_info->len; ++ fw += RTW89_FW_SECTION_HDR_SIZE; ++ section_info++; ++ } ++ ++ if (fw_end != bin) { ++ rtw89_err(rtwdev, "[ERR]fw bin size\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static ++int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, ++ struct rtw89_fw_suit *fw_suit) ++{ ++ struct rtw89_fw_info *fw_info = &rtwdev->fw; ++ const u8 *mfw = fw_info->firmware->data; ++ u32 mfw_len = fw_info->firmware->size; ++ const struct rtw89_mfw_hdr *mfw_hdr = (const struct rtw89_mfw_hdr *)mfw; ++ const struct rtw89_mfw_info *mfw_info; ++ int i; ++ ++ if (mfw_hdr->sig != RTW89_MFW_SIG) { ++ rtw89_debug(rtwdev, RTW89_DBG_FW, "use legacy firmware\n"); ++ /* legacy firmware support normal type only */ ++ if (type != RTW89_FW_NORMAL) ++ return -EINVAL; ++ fw_suit->data = mfw; ++ fw_suit->size = mfw_len; ++ return 0; ++ } ++ ++ for (i = 0; i < mfw_hdr->fw_nr; i++) { ++ mfw_info = &mfw_hdr->info[i]; ++ if (mfw_info->cv != rtwdev->hal.cv || ++ mfw_info->type != type || ++ mfw_info->mp) ++ continue; ++ ++ fw_suit->data = mfw + le32_to_cpu(mfw_info->shift); ++ fw_suit->size = le32_to_cpu(mfw_info->size); ++ return 0; ++ } ++ ++ rtw89_err(rtwdev, "no suitable firmware found\n"); ++ return -ENOENT; ++} ++ ++static void rtw89_fw_update_ver(struct rtw89_dev *rtwdev, ++ enum rtw89_fw_type type, ++ struct rtw89_fw_suit *fw_suit) ++{ ++ const u8 *hdr = fw_suit->data; ++ ++ fw_suit->major_ver = GET_FW_HDR_MAJOR_VERSION(hdr); ++ fw_suit->minor_ver = GET_FW_HDR_MINOR_VERSION(hdr); ++ fw_suit->sub_ver = GET_FW_HDR_SUBVERSION(hdr); ++ fw_suit->sub_idex = GET_FW_HDR_SUBINDEX(hdr); ++ fw_suit->build_year = GET_FW_HDR_YEAR(hdr); ++ fw_suit->build_mon = GET_FW_HDR_MONTH(hdr); ++ fw_suit->build_date = GET_FW_HDR_DATE(hdr); ++ fw_suit->build_hour = GET_FW_HDR_HOUR(hdr); ++ fw_suit->build_min = GET_FW_HDR_MIN(hdr); ++ fw_suit->cmd_ver = GET_FW_HDR_CMD_VERSERION(hdr); ++ ++ rtw89_info(rtwdev, ++ "Firmware version %u.%u.%u.%u, cmd version %u, type %u\n", ++ fw_suit->major_ver, fw_suit->minor_ver, fw_suit->sub_ver, ++ fw_suit->sub_idex, fw_suit->cmd_ver, type); ++} ++ ++static ++int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type) ++{ ++ struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); ++ int ret; ++ ++ ret = rtw89_mfw_recognize(rtwdev, type, fw_suit); ++ if (ret) ++ return ret; ++ ++ rtw89_fw_update_ver(rtwdev, type, fw_suit); ++ ++ return 0; ++} ++ ++static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, RTW89_FW_NORMAL); ++ ++ if (chip->chip_id == RTL8852A && ++ RTW89_FW_SUIT_VER_CODE(fw_suit) <= RTW89_FW_VER_CODE(0, 13, 29, 0)) ++ rtwdev->fw.old_ht_ra_format = true; ++} ++ ++int rtw89_fw_recognize(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL); ++ if (ret) ++ return ret; ++ ++ /* It still works if wowlan firmware isn't existing. */ ++ __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN); ++ ++ rtw89_fw_recognize_features(rtwdev); ++ ++ return 0; ++} ++ ++void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb, ++ u8 type, u8 cat, u8 class, u8 func, ++ bool rack, bool dack, u32 len) ++{ ++ struct fwcmd_hdr *hdr; ++ ++ hdr = (struct fwcmd_hdr *)skb_push(skb, 8); ++ ++ if (!(rtwdev->fw.h2c_seq % 4)) ++ rack = true; ++ hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) | ++ FIELD_PREP(H2C_HDR_CAT, cat) | ++ FIELD_PREP(H2C_HDR_CLASS, class) | ++ FIELD_PREP(H2C_HDR_FUNC, func) | ++ FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq)); ++ ++ hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN, ++ len + H2C_HEADER_LEN) | ++ (rack ? H2C_HDR_REC_ACK : 0) | ++ (dack ? H2C_HDR_DONE_ACK : 0)); ++ ++ rtwdev->fw.h2c_seq++; ++} ++ ++static void rtw89_h2c_pkt_set_hdr_fwdl(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb, ++ u8 type, u8 cat, u8 class, u8 func, ++ u32 len) ++{ ++ struct fwcmd_hdr *hdr; ++ ++ hdr = (struct fwcmd_hdr *)skb_push(skb, 8); ++ ++ hdr->hdr0 = cpu_to_le32(FIELD_PREP(H2C_HDR_DEL_TYPE, type) | ++ FIELD_PREP(H2C_HDR_CAT, cat) | ++ FIELD_PREP(H2C_HDR_CLASS, class) | ++ FIELD_PREP(H2C_HDR_FUNC, func) | ++ FIELD_PREP(H2C_HDR_H2C_SEQ, rtwdev->fw.h2c_seq)); ++ ++ hdr->hdr1 = cpu_to_le32(FIELD_PREP(H2C_HDR_TOTAL_LEN, ++ len + H2C_HEADER_LEN)); ++} ++ ++static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 len) ++{ ++ struct sk_buff *skb; ++ u32 ret = 0; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(len); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw hdr dl\n"); ++ return -ENOMEM; ++ } ++ ++ skb_put_data(skb, fw, len); ++ rtw89_h2c_pkt_set_hdr_fwdl(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_FWDL, ++ H2C_FUNC_MAC_FWHDR_DL, len); ++ ++ ret = rtw89_h2c_tx(rtwdev, skb, false); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ ret = -1; ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return ret; ++} ++ ++static int rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 len) ++{ ++ u8 val; ++ int ret; ++ ++ ret = __rtw89_fw_download_hdr(rtwdev, fw, len); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]FW header download\n"); ++ return ret; ++ } ++ ++ ret = read_poll_timeout_atomic(rtw89_read8, val, val & B_AX_FWDL_PATH_RDY, ++ 1, FWDL_WAIT_CNT, false, ++ rtwdev, R_AX_WCPU_FW_CTRL); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]FWDL path ready\n"); ++ return ret; ++ } ++ ++ rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0); ++ rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); ++ ++ return 0; ++} ++ ++static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev, ++ struct rtw89_fw_hdr_section_info *info) ++{ ++ struct sk_buff *skb; ++ const u8 *section = info->addr; ++ u32 residue_len = info->len; ++ u32 pkt_len; ++ int ret; ++ ++ while (residue_len) { ++ if (residue_len >= FWDL_SECTION_PER_PKT_LEN) ++ pkt_len = FWDL_SECTION_PER_PKT_LEN; ++ else ++ pkt_len = residue_len; ++ ++ skb = rtw89_fw_h2c_alloc_skb_no_hdr(pkt_len); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); ++ return -ENOMEM; ++ } ++ skb_put_data(skb, section, pkt_len); ++ ++ ret = rtw89_h2c_tx(rtwdev, skb, true); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ ret = -1; ++ goto fail; ++ } ++ ++ section += pkt_len; ++ residue_len -= pkt_len; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return ret; ++} ++ ++static int rtw89_fw_download_main(struct rtw89_dev *rtwdev, const u8 *fw, ++ struct rtw89_fw_bin_info *info) ++{ ++ struct rtw89_fw_hdr_section_info *section_info = info->section_info; ++ u8 section_num = info->section_num; ++ int ret; ++ ++ while (section_num--) { ++ ret = __rtw89_fw_download_main(rtwdev, section_info); ++ if (ret) ++ return ret; ++ section_info++; ++ } ++ ++ mdelay(5); ++ ++ ret = rtw89_fw_check_rdy(rtwdev); ++ if (ret) { ++ rtw89_warn(rtwdev, "download firmware fail\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void rtw89_fw_prog_cnt_dump(struct rtw89_dev *rtwdev) ++{ ++ u32 val32; ++ u16 index; ++ ++ rtw89_write32(rtwdev, R_AX_DBG_CTRL, ++ FIELD_PREP(B_AX_DBG_SEL0, FW_PROG_CNTR_DBG_SEL) | ++ FIELD_PREP(B_AX_DBG_SEL1, FW_PROG_CNTR_DBG_SEL)); ++ rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_SEL_0XC0_MASK, MAC_DBG_SEL); ++ ++ for (index = 0; index < 15; index++) { ++ val32 = rtw89_read32(rtwdev, R_AX_DBG_PORT_SEL); ++ rtw89_err(rtwdev, "[ERR]fw PC = 0x%x\n", val32); ++ fsleep(10); ++ } ++} ++ ++static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev) ++{ ++ u32 val32; ++ u16 val16; ++ ++ val32 = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL); ++ rtw89_err(rtwdev, "[ERR]fwdl 0x1E0 = 0x%x\n", val32); ++ ++ val16 = rtw89_read16(rtwdev, R_AX_BOOT_DBG + 2); ++ rtw89_err(rtwdev, "[ERR]fwdl 0x83F2 = 0x%x\n", val16); ++ ++ rtw89_fw_prog_cnt_dump(rtwdev); ++} ++ ++int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type) ++{ ++ struct rtw89_fw_info *fw_info = &rtwdev->fw; ++ struct rtw89_fw_suit *fw_suit = rtw89_fw_suit_get(rtwdev, type); ++ struct rtw89_fw_bin_info info; ++ const u8 *fw = fw_suit->data; ++ u32 len = fw_suit->size; ++ u8 val; ++ int ret; ++ ++ if (!fw || !len) { ++ rtw89_err(rtwdev, "fw type %d isn't recognized\n", type); ++ return -ENOENT; ++ } ++ ++ ret = rtw89_fw_hdr_parser(rtwdev, fw, len, &info); ++ if (ret) { ++ rtw89_err(rtwdev, "parse fw header fail\n"); ++ goto fwdl_err; ++ } ++ ++ ret = read_poll_timeout_atomic(rtw89_read8, val, val & B_AX_H2C_PATH_RDY, ++ 1, FWDL_WAIT_CNT, false, ++ rtwdev, R_AX_WCPU_FW_CTRL); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]H2C path ready\n"); ++ goto fwdl_err; ++ } ++ ++ ret = rtw89_fw_download_hdr(rtwdev, fw, info.hdr_len); ++ if (ret) { ++ ret = -EBUSY; ++ goto fwdl_err; ++ } ++ ++ ret = rtw89_fw_download_main(rtwdev, fw, &info); ++ if (ret) { ++ ret = -EBUSY; ++ goto fwdl_err; ++ } ++ ++ fw_info->h2c_seq = 0; ++ fw_info->rec_seq = 0; ++ rtwdev->mac.rpwm_seq_num = RPWM_SEQ_NUM_MAX; ++ rtwdev->mac.cpwm_seq_num = CPWM_SEQ_NUM_MAX; ++ ++ return ret; ++ ++fwdl_err: ++ rtw89_fw_dl_fail_dump(rtwdev); ++ return ret; ++} ++ ++int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_fw_info *fw = &rtwdev->fw; ++ ++ wait_for_completion(&fw->completion); ++ if (!fw->firmware) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static void rtw89_load_firmware_cb(const struct firmware *firmware, void *context) ++{ ++ struct rtw89_fw_info *fw = context; ++ struct rtw89_dev *rtwdev = fw->rtwdev; ++ ++ if (!firmware || !firmware->data) { ++ rtw89_err(rtwdev, "failed to request firmware\n"); ++ complete_all(&fw->completion); ++ return; ++ } ++ ++ fw->firmware = firmware; ++ complete_all(&fw->completion); ++} ++ ++int rtw89_load_firmware(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_fw_info *fw = &rtwdev->fw; ++ const char *fw_name = rtwdev->chip->fw_name; ++ int ret; ++ ++ fw->rtwdev = rtwdev; ++ init_completion(&fw->completion); ++ ++ ret = request_firmware_nowait(THIS_MODULE, true, fw_name, rtwdev->dev, ++ GFP_KERNEL, fw, rtw89_load_firmware_cb); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to async firmware request\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++void rtw89_unload_firmware(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_fw_info *fw = &rtwdev->fw; ++ ++ rtw89_wait_firmware_completion(rtwdev); ++ ++ if (fw->firmware) ++ release_firmware(fw->firmware); ++} ++ ++#define H2C_CAM_LEN 60 ++int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_CAM_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_CAM_LEN); ++ rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif, skb->data); ++ rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif, skb->data); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, ++ H2C_CL_MAC_ADDR_CAM_UPDATE, ++ H2C_FUNC_MAC_ADDR_CAM_UPD, 0, 1, ++ H2C_CAM_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_BA_CAM_LEN 4 ++int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, bool valid, u8 macid, ++ struct ieee80211_ampdu_params *params) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_BA_CAM_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_BA_CAM_LEN); ++ SET_BA_CAM_MACID(skb->data, macid); ++ if (!valid) ++ goto end; ++ SET_BA_CAM_VALID(skb->data, valid); ++ SET_BA_CAM_TID(skb->data, params->tid); ++ if (params->buf_size > 64) ++ SET_BA_CAM_BMAP_SIZE(skb->data, 4); ++ else ++ SET_BA_CAM_BMAP_SIZE(skb->data, 0); ++ /* If init req is set, hw will set the ssn */ ++ SET_BA_CAM_INIT_REQ(skb->data, 0); ++ SET_BA_CAM_SSN(skb->data, params->ssn); ++ ++end: ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, ++ H2C_CL_BA_CAM, ++ H2C_FUNC_MAC_BA_CAM, 0, 1, ++ H2C_BA_CAM_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_LOG_CFG_LEN 12 ++int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable) ++{ ++ struct sk_buff *skb; ++ u32 comp = enable ? BIT(RTW89_FW_LOG_COMP_INIT) | BIT(RTW89_FW_LOG_COMP_TASK) | ++ BIT(RTW89_FW_LOG_COMP_PS) | BIT(RTW89_FW_LOG_COMP_ERROR) : 0; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LOG_CFG_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw log cfg\n"); ++ return -ENOMEM; ++ } ++ ++ skb_put(skb, H2C_LOG_CFG_LEN); ++ SET_LOG_CFG_LEVEL(skb->data, RTW89_FW_LOG_LEVEL_SER); ++ SET_LOG_CFG_PATH(skb->data, BIT(RTW89_FW_LOG_LEVEL_C2H)); ++ SET_LOG_CFG_COMP(skb->data, comp); ++ SET_LOG_CFG_COMP_EXT(skb->data, 0); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, ++ H2C_CL_FW_INFO, ++ H2C_FUNC_LOG_CFG, 0, 0, ++ H2C_LOG_CFG_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_GENERAL_PKT_LEN 6 ++#define H2C_GENERAL_PKT_ID_UND 0xff ++int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_GENERAL_PKT_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_GENERAL_PKT_LEN); ++ SET_GENERAL_PKT_MACID(skb->data, macid); ++ SET_GENERAL_PKT_PROBRSP_ID(skb->data, H2C_GENERAL_PKT_ID_UND); ++ SET_GENERAL_PKT_PSPOLL_ID(skb->data, H2C_GENERAL_PKT_ID_UND); ++ SET_GENERAL_PKT_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND); ++ SET_GENERAL_PKT_QOS_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND); ++ SET_GENERAL_PKT_CTS2SELF_ID(skb->data, H2C_GENERAL_PKT_ID_UND); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, ++ H2C_CL_FW_INFO, ++ H2C_FUNC_MAC_GENERAL_PKT, 0, 1, ++ H2C_GENERAL_PKT_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_LPS_PARM_LEN 8 ++int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, ++ struct rtw89_lps_parm *lps_param) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LPS_PARM_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_LPS_PARM_LEN); ++ ++ SET_LPS_PARM_MACID(skb->data, lps_param->macid); ++ SET_LPS_PARM_PSMODE(skb->data, lps_param->psmode); ++ SET_LPS_PARM_LASTRPWM(skb->data, lps_param->lastrpwm); ++ SET_LPS_PARM_RLBM(skb->data, 1); ++ SET_LPS_PARM_SMARTPS(skb->data, 1); ++ SET_LPS_PARM_AWAKEINTERVAL(skb->data, 1); ++ SET_LPS_PARM_VOUAPSD(skb->data, 0); ++ SET_LPS_PARM_VIUAPSD(skb->data, 0); ++ SET_LPS_PARM_BEUAPSD(skb->data, 0); ++ SET_LPS_PARM_BKUAPSD(skb->data, 0); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, ++ H2C_CL_MAC_PS, ++ H2C_FUNC_MAC_LPS_PARM, 0, 1, ++ H2C_LPS_PARM_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_CMC_TBL_LEN 68 ++int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, u8 macid) ++{ ++ struct rtw89_hal *hal = &rtwdev->hal; ++ struct sk_buff *skb; ++ u8 ntx_path = hal->antenna_tx ? hal->antenna_tx : RF_B; ++ u8 map_b = hal->antenna_tx == RF_AB ? 1 : 0; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_CMC_TBL_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_CMC_TBL_LEN); ++ SET_CTRL_INFO_MACID(skb->data, macid); ++ SET_CTRL_INFO_OPERATION(skb->data, 1); ++ SET_CMC_TBL_TXPWR_MODE(skb->data, 0); ++ SET_CMC_TBL_NTX_PATH_EN(skb->data, ntx_path); ++ SET_CMC_TBL_PATH_MAP_A(skb->data, 0); ++ SET_CMC_TBL_PATH_MAP_B(skb->data, map_b); ++ SET_CMC_TBL_PATH_MAP_C(skb->data, 0); ++ SET_CMC_TBL_PATH_MAP_D(skb->data, 0); ++ SET_CMC_TBL_ANTSEL_A(skb->data, 0); ++ SET_CMC_TBL_ANTSEL_B(skb->data, 0); ++ SET_CMC_TBL_ANTSEL_C(skb->data, 0); ++ SET_CMC_TBL_ANTSEL_D(skb->data, 0); ++ SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0); ++ SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, ++ H2C_FUNC_MAC_CCTLINFO_UD, 0, 1, ++ H2C_CMC_TBL_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++static void __get_sta_he_pkt_padding(struct rtw89_dev *rtwdev, ++ struct ieee80211_sta *sta, u8 *pads) ++{ ++ bool ppe_th; ++ u8 ppe16, ppe8; ++ u8 nss = min(sta->rx_nss, rtwdev->hal.tx_nss) - 1; ++ u8 ppe_thres_hdr = sta->he_cap.ppe_thres[0]; ++ u8 ru_bitmap; ++ u8 n, idx, sh; ++ u16 ppe; ++ int i; ++ ++ if (!sta->he_cap.has_he) ++ return; ++ ++ ppe_th = FIELD_GET(IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT, ++ sta->he_cap.he_cap_elem.phy_cap_info[6]); ++ if (!ppe_th) { ++ u8 pad; ++ ++ pad = FIELD_GET(IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_MASK, ++ sta->he_cap.he_cap_elem.phy_cap_info[9]); ++ ++ for (i = 0; i < RTW89_PPE_BW_NUM; i++) ++ pads[i] = pad; ++ } ++ ++ ru_bitmap = FIELD_GET(IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK, ppe_thres_hdr); ++ n = hweight8(ru_bitmap); ++ n = 7 + (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) * nss; ++ ++ for (i = 0; i < RTW89_PPE_BW_NUM; i++) { ++ if (!(ru_bitmap & BIT(i))) { ++ pads[i] = 1; ++ continue; ++ } ++ ++ idx = n >> 3; ++ sh = n & 7; ++ n += IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2; ++ ++ ppe = le16_to_cpu(*((__le16 *)&sta->he_cap.ppe_thres[idx])); ++ ppe16 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; ++ sh += IEEE80211_PPE_THRES_INFO_PPET_SIZE; ++ ppe8 = (ppe >> sh) & IEEE80211_PPE_THRES_NSS_MASK; ++ ++ if (ppe16 != 7 && ppe8 == 7) ++ pads[i] = 2; ++ else if (ppe8 != 7) ++ pads[i] = 1; ++ else ++ pads[i] = 0; ++ } ++} ++ ++int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_hal *hal = &rtwdev->hal; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ struct sk_buff *skb; ++ u8 pads[RTW89_PPE_BW_NUM]; ++ ++ memset(pads, 0, sizeof(pads)); ++ __get_sta_he_pkt_padding(rtwdev, sta, pads); ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_CMC_TBL_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_CMC_TBL_LEN); ++ SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id); ++ SET_CTRL_INFO_OPERATION(skb->data, 1); ++ SET_CMC_TBL_DISRTSFB(skb->data, 1); ++ SET_CMC_TBL_DISDATAFB(skb->data, 1); ++ if (hal->current_band_type == RTW89_BAND_2G) ++ SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, RTW89_HW_RATE_CCK1); ++ else ++ SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, RTW89_HW_RATE_OFDM6); ++ SET_CMC_TBL_RTS_TXCNT_LMT_SEL(skb->data, 0); ++ SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 0); ++ if (vif->type == NL80211_IFTYPE_STATION) ++ SET_CMC_TBL_ULDL(skb->data, 1); ++ else ++ SET_CMC_TBL_ULDL(skb->data, 0); ++ SET_CMC_TBL_MULTI_PORT_ID(skb->data, rtwvif->port); ++ SET_CMC_TBL_NOMINAL_PKT_PADDING(skb->data, pads[RTW89_CHANNEL_WIDTH_20]); ++ SET_CMC_TBL_NOMINAL_PKT_PADDING40(skb->data, pads[RTW89_CHANNEL_WIDTH_40]); ++ SET_CMC_TBL_NOMINAL_PKT_PADDING80(skb->data, pads[RTW89_CHANNEL_WIDTH_80]); ++ SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(skb->data, sta->he_cap.has_he); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, ++ H2C_FUNC_MAC_CCTLINFO_UD, 0, 1, ++ H2C_CMC_TBL_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, ++ struct rtw89_sta *rtwsta) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_CMC_TBL_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_CMC_TBL_LEN); ++ SET_CTRL_INFO_MACID(skb->data, rtwsta->mac_id); ++ SET_CTRL_INFO_OPERATION(skb->data, 1); ++ if (rtwsta->cctl_tx_time) { ++ SET_CMC_TBL_AMPDU_TIME_SEL(skb->data, 1); ++ SET_CMC_TBL_AMPDU_MAX_TIME(skb->data, rtwsta->ampdu_max_time); ++ } ++ if (rtwsta->cctl_tx_retry_limit) { ++ SET_CMC_TBL_DATA_TXCNT_LMT_SEL(skb->data, 1); ++ SET_CMC_TBL_DATA_TX_CNT_LMT(skb->data, rtwsta->data_tx_cnt_lmt); ++ } ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG, ++ H2C_FUNC_MAC_CCTLINFO_UD, 0, 1, ++ H2C_CMC_TBL_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_VIF_MAINTAIN_LEN 4 ++int rtw89_fw_h2c_vif_maintain(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, ++ enum rtw89_upd_mode upd_mode) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_VIF_MAINTAIN_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_VIF_MAINTAIN_LEN); ++ SET_FWROLE_MAINTAIN_MACID(skb->data, rtwvif->mac_id); ++ SET_FWROLE_MAINTAIN_SELF_ROLE(skb->data, rtwvif->self_role); ++ SET_FWROLE_MAINTAIN_UPD_MODE(skb->data, upd_mode); ++ SET_FWROLE_MAINTAIN_WIFI_ROLE(skb->data, rtwvif->wifi_role); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, ++ H2C_FUNC_MAC_FWROLE_MAINTAIN, 0, 1, ++ H2C_VIF_MAINTAIN_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_JOIN_INFO_LEN 4 ++int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u8 dis_conn) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_JOIN_INFO_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_JOIN_INFO_LEN); ++ SET_JOININFO_MACID(skb->data, rtwvif->mac_id); ++ SET_JOININFO_OP(skb->data, dis_conn); ++ SET_JOININFO_BAND(skb->data, rtwvif->mac_idx); ++ SET_JOININFO_WMM(skb->data, rtwvif->wmm); ++ SET_JOININFO_TGR(skb->data, rtwvif->trigger); ++ SET_JOININFO_ISHESTA(skb->data, 0); ++ SET_JOININFO_DLBW(skb->data, 0); ++ SET_JOININFO_TF_MAC_PAD(skb->data, 0); ++ SET_JOININFO_DL_T_PE(skb->data, 0); ++ SET_JOININFO_PORT_ID(skb->data, rtwvif->port); ++ SET_JOININFO_NET_TYPE(skb->data, rtwvif->net_type); ++ SET_JOININFO_WIFI_ROLE(skb->data, rtwvif->wifi_role); ++ SET_JOININFO_SELF_ROLE(skb->data, rtwvif->self_role); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_MEDIA_RPT, ++ H2C_FUNC_MAC_JOININFO, 0, 1, ++ H2C_JOIN_INFO_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp, ++ bool pause) ++{ ++ struct rtw89_fw_macid_pause_grp h2c = {{0}}; ++ u8 len = sizeof(struct rtw89_fw_macid_pause_grp); ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_JOIN_INFO_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); ++ return -ENOMEM; ++ } ++ h2c.mask_grp[grp] = cpu_to_le32(BIT(sh)); ++ if (pause) ++ h2c.pause_grp[grp] = cpu_to_le32(BIT(sh)); ++ skb_put_data(skb, &h2c, len); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, ++ H2C_FUNC_MAC_MACID_PAUSE, 1, 0, ++ len); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_EDCA_LEN 12 ++int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u8 ac, u32 val) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_EDCA_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c edca\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_EDCA_LEN); ++ RTW89_SET_EDCA_SEL(skb->data, 0); ++ RTW89_SET_EDCA_BAND(skb->data, rtwvif->mac_idx); ++ RTW89_SET_EDCA_WMM(skb->data, 0); ++ RTW89_SET_EDCA_AC(skb->data, ac); ++ RTW89_SET_EDCA_PARAM(skb->data, val); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, ++ H2C_FUNC_USR_EDCA, 0, 1, ++ H2C_EDCA_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_OFLD_CFG_LEN 8 ++int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev) ++{ ++ static const u8 cfg[] = {0x09, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00}; ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_OFLD_CFG_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c ofld\n"); ++ return -ENOMEM; ++ } ++ skb_put_data(skb, cfg, H2C_OFLD_CFG_LEN); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, ++ H2C_FUNC_OFLD_CFG, 0, 1, ++ H2C_OFLD_CFG_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_RA_LEN 16 ++int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi) ++{ ++ struct sk_buff *skb; ++ u8 *cmd; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_RA_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c join\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_RA_LEN); ++ cmd = skb->data; ++ rtw89_debug(rtwdev, RTW89_DBG_RA, ++ "ra cmd msk: %llx ", ra->ra_mask); ++ ++ RTW89_SET_FWCMD_RA_MODE(cmd, ra->mode_ctrl); ++ RTW89_SET_FWCMD_RA_BW_CAP(cmd, ra->bw_cap); ++ RTW89_SET_FWCMD_RA_MACID(cmd, ra->macid); ++ RTW89_SET_FWCMD_RA_DCM(cmd, ra->dcm_cap); ++ RTW89_SET_FWCMD_RA_ER(cmd, ra->er_cap); ++ RTW89_SET_FWCMD_RA_INIT_RATE_LV(cmd, ra->init_rate_lv); ++ RTW89_SET_FWCMD_RA_UPD_ALL(cmd, ra->upd_all); ++ RTW89_SET_FWCMD_RA_SGI(cmd, ra->en_sgi); ++ RTW89_SET_FWCMD_RA_LDPC(cmd, ra->ldpc_cap); ++ RTW89_SET_FWCMD_RA_STBC(cmd, ra->stbc_cap); ++ RTW89_SET_FWCMD_RA_SS_NUM(cmd, ra->ss_num); ++ RTW89_SET_FWCMD_RA_GILTF(cmd, ra->giltf); ++ RTW89_SET_FWCMD_RA_UPD_BW_NSS_MASK(cmd, ra->upd_bw_nss_mask); ++ RTW89_SET_FWCMD_RA_UPD_MASK(cmd, ra->upd_mask); ++ RTW89_SET_FWCMD_RA_MASK_0(cmd, FIELD_GET(MASKBYTE0, ra->ra_mask)); ++ RTW89_SET_FWCMD_RA_MASK_1(cmd, FIELD_GET(MASKBYTE1, ra->ra_mask)); ++ RTW89_SET_FWCMD_RA_MASK_2(cmd, FIELD_GET(MASKBYTE2, ra->ra_mask)); ++ RTW89_SET_FWCMD_RA_MASK_3(cmd, FIELD_GET(MASKBYTE3, ra->ra_mask)); ++ RTW89_SET_FWCMD_RA_MASK_4(cmd, FIELD_GET(MASKBYTE4, ra->ra_mask)); ++ ++ if (csi) { ++ RTW89_SET_FWCMD_RA_BFEE_CSI_CTL(cmd, 1); ++ RTW89_SET_FWCMD_RA_BAND_NUM(cmd, ra->band_num); ++ RTW89_SET_FWCMD_RA_CR_TBL_SEL(cmd, ra->cr_tbl_sel); ++ RTW89_SET_FWCMD_RA_FIXED_CSI_RATE_EN(cmd, ra->fixed_csi_rate_en); ++ RTW89_SET_FWCMD_RA_RA_CSI_RATE_EN(cmd, ra->ra_csi_rate_en); ++ RTW89_SET_FWCMD_RA_FIXED_CSI_MCS_SS_IDX(cmd, ra->csi_mcs_ss_idx); ++ RTW89_SET_FWCMD_RA_FIXED_CSI_MODE(cmd, ra->csi_mode); ++ RTW89_SET_FWCMD_RA_FIXED_CSI_GI_LTF(cmd, ra->csi_gi_ltf); ++ RTW89_SET_FWCMD_RA_FIXED_CSI_BW(cmd, ra->csi_bw); ++ } ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RA, ++ H2C_FUNC_OUTSRC_RA_MACIDCFG, 0, 0, ++ H2C_RA_LEN); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_LEN_CXDRVHDR 2 ++#define H2C_LEN_CXDRVINFO_INIT (12 + H2C_LEN_CXDRVHDR) ++int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_init_info *init_info = &dm->init_info; ++ struct rtw89_btc_module *module = &init_info->module; ++ struct rtw89_btc_ant_info *ant = &module->ant; ++ struct sk_buff *skb; ++ u8 *cmd; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LEN_CXDRVINFO_INIT); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_init\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_LEN_CXDRVINFO_INIT); ++ cmd = skb->data; ++ ++ RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_INIT); ++ RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_INIT - H2C_LEN_CXDRVHDR); ++ ++ RTW89_SET_FWCMD_CXINIT_ANT_TYPE(cmd, ant->type); ++ RTW89_SET_FWCMD_CXINIT_ANT_NUM(cmd, ant->num); ++ RTW89_SET_FWCMD_CXINIT_ANT_ISO(cmd, ant->isolation); ++ RTW89_SET_FWCMD_CXINIT_ANT_POS(cmd, ant->single_pos); ++ RTW89_SET_FWCMD_CXINIT_ANT_DIVERSITY(cmd, ant->diversity); ++ ++ RTW89_SET_FWCMD_CXINIT_MOD_RFE(cmd, module->rfe_type); ++ RTW89_SET_FWCMD_CXINIT_MOD_CV(cmd, module->cv); ++ RTW89_SET_FWCMD_CXINIT_MOD_BT_SOLO(cmd, module->bt_solo); ++ RTW89_SET_FWCMD_CXINIT_MOD_BT_POS(cmd, module->bt_pos); ++ RTW89_SET_FWCMD_CXINIT_MOD_SW_TYPE(cmd, module->switch_type); ++ ++ RTW89_SET_FWCMD_CXINIT_WL_GCH(cmd, init_info->wl_guard_ch); ++ RTW89_SET_FWCMD_CXINIT_WL_ONLY(cmd, init_info->wl_only); ++ RTW89_SET_FWCMD_CXINIT_WL_INITOK(cmd, init_info->wl_init_ok); ++ RTW89_SET_FWCMD_CXINIT_DBCC_EN(cmd, init_info->dbcc_en); ++ RTW89_SET_FWCMD_CXINIT_CX_OTHER(cmd, init_info->cx_other); ++ RTW89_SET_FWCMD_CXINIT_BT_ONLY(cmd, init_info->bt_only); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_OUTSRC, BTFC_SET, ++ SET_DRV_INFO, 0, 0, ++ H2C_LEN_CXDRVINFO_INIT); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_LEN_CXDRVINFO_ROLE (4 + 12 * RTW89_MAX_HW_PORT_NUM + H2C_LEN_CXDRVHDR) ++int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_wl_role_info *role_info = &wl->role_info; ++ struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; ++ struct rtw89_btc_wl_active_role *active = role_info->active_role; ++ struct sk_buff *skb; ++ u8 *cmd; ++ int i; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LEN_CXDRVINFO_ROLE); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_LEN_CXDRVINFO_ROLE); ++ cmd = skb->data; ++ ++ RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE); ++ RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE - H2C_LEN_CXDRVHDR); ++ ++ RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); ++ RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); ++ ++ RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none); ++ RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station); ++ RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap); ++ RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap); ++ RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc); ++ RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master); ++ RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh); ++ RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter); ++ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device); ++ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc); ++ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go); ++ RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan); ++ ++ for (i = 0; i < RTW89_MAX_HW_PORT_NUM; i++, active++) { ++ RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i); ++ RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i); ++ } ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_OUTSRC, BTFC_SET, ++ SET_DRV_INFO, 0, 0, ++ H2C_LEN_CXDRVINFO_ROLE); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR) ++int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_ctrl *ctrl = &btc->ctrl; ++ struct sk_buff *skb; ++ u8 *cmd; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LEN_CXDRVINFO_CTRL); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_LEN_CXDRVINFO_CTRL); ++ cmd = skb->data; ++ ++ RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_CTRL); ++ RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_CTRL - H2C_LEN_CXDRVHDR); ++ ++ RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, ctrl->manual); ++ RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, ctrl->igno_bt); ++ RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, ctrl->always_freerun); ++ RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, ctrl->trace_step); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_OUTSRC, BTFC_SET, ++ SET_DRV_INFO, 0, 0, ++ H2C_LEN_CXDRVINFO_CTRL); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++#define H2C_LEN_CXDRVINFO_RFK (4 + H2C_LEN_CXDRVHDR) ++int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_wl_info *wl = &btc->cx.wl; ++ struct rtw89_btc_wl_rfk_info *rfk_info = &wl->rfk_info; ++ struct sk_buff *skb; ++ u8 *cmd; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(H2C_LEN_CXDRVINFO_RFK); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); ++ return -ENOMEM; ++ } ++ skb_put(skb, H2C_LEN_CXDRVINFO_RFK); ++ cmd = skb->data; ++ ++ RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_RFK); ++ RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_RFK - H2C_LEN_CXDRVHDR); ++ ++ RTW89_SET_FWCMD_CXRFK_STATE(cmd, rfk_info->state); ++ RTW89_SET_FWCMD_CXRFK_PATH_MAP(cmd, rfk_info->path_map); ++ RTW89_SET_FWCMD_CXRFK_PHY_MAP(cmd, rfk_info->phy_map); ++ RTW89_SET_FWCMD_CXRFK_BAND(cmd, rfk_info->band); ++ RTW89_SET_FWCMD_CXRFK_TYPE(cmd, rfk_info->type); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_OUTSRC, BTFC_SET, ++ SET_DRV_INFO, 0, 0, ++ H2C_LEN_CXDRVINFO_RFK); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, ++ struct rtw89_fw_h2c_rf_reg_info *info, ++ u16 len, u8 page) ++{ ++ struct sk_buff *skb; ++ u8 class = info->rf_path == RF_PATH_A ? ++ H2C_CL_OUTSRC_RF_REG_A : H2C_CL_OUTSRC_RF_REG_B; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(len); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c rf reg\n"); ++ return -ENOMEM; ++ } ++ skb_put_data(skb, info->rtw89_phy_config_rf_h2c[page], len); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_OUTSRC, class, page, 0, 0, ++ len); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, ++ u8 h2c_class, u8 h2c_func, u8 *buf, u16 len, ++ bool rack, bool dack) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(len); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for raw with hdr\n"); ++ return -ENOMEM; ++ } ++ skb_put_data(skb, buf, len); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_OUTSRC, h2c_class, h2c_func, rack, dack, ++ len); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len) ++{ ++ struct sk_buff *skb; ++ ++ skb = rtw89_fw_h2c_alloc_skb_no_hdr(len); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for h2c raw\n"); ++ return -ENOMEM; ++ } ++ skb_put_data(skb, buf, len); ++ ++ if (rtw89_h2c_tx(rtwdev, skb, false)) { ++ rtw89_err(rtwdev, "failed to send h2c\n"); ++ goto fail; ++ } ++ ++ return 0; ++fail: ++ dev_kfree_skb_any(skb); ++ ++ return -EBUSY; ++} ++ ++void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_early_h2c *early_h2c; ++ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) { ++ rtw89_fw_h2c_raw(rtwdev, early_h2c->h2c, early_h2c->h2c_len); ++ } ++} ++ ++void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_early_h2c *early_h2c, *tmp; ++ ++ mutex_lock(&rtwdev->mutex); ++ list_for_each_entry_safe(early_h2c, tmp, &rtwdev->early_h2c_list, list) { ++ list_del(&early_h2c->list); ++ kfree(early_h2c->h2c); ++ kfree(early_h2c); ++ } ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h) ++{ ++ skb_queue_tail(&rtwdev->c2h_queue, c2h); ++ ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work); ++} ++ ++static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb) ++{ ++ u8 category = RTW89_GET_C2H_CATEGORY(skb->data); ++ u8 class = RTW89_GET_C2H_CLASS(skb->data); ++ u8 func = RTW89_GET_C2H_FUNC(skb->data); ++ u16 len = RTW89_GET_C2H_LEN(skb->data); ++ bool dump = true; ++ ++ if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) ++ return; ++ ++ switch (category) { ++ case RTW89_C2H_CAT_TEST: ++ break; ++ case RTW89_C2H_CAT_MAC: ++ rtw89_mac_c2h_handle(rtwdev, skb, len, class, func); ++ if (class == RTW89_MAC_C2H_CLASS_INFO && ++ func == RTW89_MAC_C2H_FUNC_C2H_LOG) ++ dump = false; ++ break; ++ case RTW89_C2H_CAT_OUTSRC: ++ if (class >= RTW89_PHY_C2H_CLASS_BTC_MIN && ++ class <= RTW89_PHY_C2H_CLASS_BTC_MAX) ++ rtw89_btc_c2h_handle(rtwdev, skb, len, class, func); ++ else ++ rtw89_phy_c2h_handle(rtwdev, skb, len, class, func); ++ break; ++ } ++ ++ if (dump) ++ rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "C2H: ", skb->data, skb->len); ++} ++ ++void rtw89_fw_c2h_work(struct work_struct *work) ++{ ++ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, ++ c2h_work); ++ struct sk_buff *skb, *tmp; ++ ++ skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) { ++ skb_unlink(skb, &rtwdev->c2h_queue); ++ mutex_lock(&rtwdev->mutex); ++ rtw89_fw_c2h_cmd_handle(rtwdev, skb); ++ mutex_unlock(&rtwdev->mutex); ++ dev_kfree_skb_any(skb); ++ } ++} ++ ++static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev, ++ struct rtw89_mac_h2c_info *info) ++{ ++ static const u32 h2c_reg[RTW89_H2CREG_MAX] = { ++ R_AX_H2CREG_DATA0, R_AX_H2CREG_DATA1, ++ R_AX_H2CREG_DATA2, R_AX_H2CREG_DATA3 ++ }; ++ u8 i, val, len; ++ int ret; ++ ++ ret = read_poll_timeout(rtw89_read8, val, val == 0, 1000, 5000, false, ++ rtwdev, R_AX_H2CREG_CTRL); ++ if (ret) { ++ rtw89_warn(rtwdev, "FW does not process h2c registers\n"); ++ return ret; ++ } ++ ++ len = DIV_ROUND_UP(info->content_len + RTW89_H2CREG_HDR_LEN, ++ sizeof(info->h2creg[0])); ++ ++ RTW89_SET_H2CREG_HDR_FUNC(&info->h2creg[0], info->id); ++ RTW89_SET_H2CREG_HDR_LEN(&info->h2creg[0], len); ++ for (i = 0; i < RTW89_H2CREG_MAX; i++) ++ rtw89_write32(rtwdev, h2c_reg[i], info->h2creg[i]); ++ ++ rtw89_write8(rtwdev, R_AX_H2CREG_CTRL, B_AX_H2CREG_TRIGGER); ++ ++ return 0; ++} ++ ++static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev, ++ struct rtw89_mac_c2h_info *info) ++{ ++ static const u32 c2h_reg[RTW89_C2HREG_MAX] = { ++ R_AX_C2HREG_DATA0, R_AX_C2HREG_DATA1, ++ R_AX_C2HREG_DATA2, R_AX_C2HREG_DATA3 ++ }; ++ u32 ret; ++ u8 i, val; ++ ++ info->id = RTW89_FWCMD_C2HREG_FUNC_NULL; ++ ++ ret = read_poll_timeout_atomic(rtw89_read8, val, val, 1, ++ RTW89_C2H_TIMEOUT, false, rtwdev, ++ R_AX_C2HREG_CTRL); ++ if (ret) { ++ rtw89_warn(rtwdev, "c2h reg timeout\n"); ++ return ret; ++ } ++ ++ for (i = 0; i < RTW89_C2HREG_MAX; i++) ++ info->c2hreg[i] = rtw89_read32(rtwdev, c2h_reg[i]); ++ ++ rtw89_write8(rtwdev, R_AX_C2HREG_CTRL, 0); ++ ++ info->id = RTW89_GET_C2H_HDR_FUNC(*info->c2hreg); ++ info->content_len = (RTW89_GET_C2H_HDR_LEN(*info->c2hreg) << 2) - ++ RTW89_C2HREG_HDR_LEN; ++ ++ return 0; ++} ++ ++int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev, ++ struct rtw89_mac_h2c_info *h2c_info, ++ struct rtw89_mac_c2h_info *c2h_info) ++{ ++ u32 ret; ++ ++ if (h2c_info && h2c_info->id != RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE) ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ if (!h2c_info && !c2h_info) ++ return -EINVAL; ++ ++ if (!h2c_info) ++ goto recv_c2h; ++ ++ ret = rtw89_fw_write_h2c_reg(rtwdev, h2c_info); ++ if (ret) ++ return ret; ++ ++recv_c2h: ++ if (!c2h_info) ++ return 0; ++ ++ ret = rtw89_fw_read_c2h_reg(rtwdev, c2h_info); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev) ++{ ++ if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) { ++ rtw89_err(rtwdev, "[ERR]pwr is off\n"); ++ return; ++ } ++ ++ rtw89_info(rtwdev, "FW status = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM0)); ++ rtw89_info(rtwdev, "FW BADADDR = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM1)); ++ rtw89_info(rtwdev, "FW EPC/RA = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM2)); ++ rtw89_info(rtwdev, "FW MISC = 0x%x\n", rtw89_read32(rtwdev, R_AX_UDM3)); ++ rtw89_info(rtwdev, "R_AX_HALT_C2H = 0x%x\n", ++ rtw89_read32(rtwdev, R_AX_HALT_C2H)); ++ rtw89_info(rtwdev, "R_AX_SER_DBG_INFO = 0x%x\n", ++ rtw89_read32(rtwdev, R_AX_SER_DBG_INFO)); ++ ++ rtw89_fw_prog_cnt_dump(rtwdev); ++} +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +new file mode 100644 +index 000000000000..7ee0d9323310 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -0,0 +1,1378 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_FW_H__ ++#define __RTW89_FW_H__ ++ ++#include "core.h" ++ ++enum rtw89_fw_dl_status { ++ RTW89_FWDL_INITIAL_STATE = 0, ++ RTW89_FWDL_FWDL_ONGOING = 1, ++ RTW89_FWDL_CHECKSUM_FAIL = 2, ++ RTW89_FWDL_SECURITY_FAIL = 3, ++ RTW89_FWDL_CV_NOT_MATCH = 4, ++ RTW89_FWDL_RSVD0 = 5, ++ RTW89_FWDL_WCPU_FWDL_RDY = 6, ++ RTW89_FWDL_WCPU_FW_INIT_RDY = 7 ++}; ++ ++#define RTW89_GET_C2H_HDR_FUNC(info) \ ++ u32_get_bits(info, GENMASK(6, 0)) ++#define RTW89_GET_C2H_HDR_LEN(info) \ ++ u32_get_bits(info, GENMASK(11, 8)) ++ ++#define RTW89_SET_H2CREG_HDR_FUNC(info, val) \ ++ u32p_replace_bits(info, val, GENMASK(6, 0)) ++#define RTW89_SET_H2CREG_HDR_LEN(info, val) \ ++ u32p_replace_bits(info, val, GENMASK(11, 8)) ++ ++#define RTW89_H2CREG_MAX 4 ++#define RTW89_C2HREG_MAX 4 ++#define RTW89_C2HREG_HDR_LEN 2 ++#define RTW89_H2CREG_HDR_LEN 2 ++#define RTW89_C2H_TIMEOUT 1000000 ++struct rtw89_mac_c2h_info { ++ u8 id; ++ u8 content_len; ++ u32 c2hreg[RTW89_C2HREG_MAX]; ++}; ++ ++struct rtw89_mac_h2c_info { ++ u8 id; ++ u8 content_len; ++ u32 h2creg[RTW89_H2CREG_MAX]; ++}; ++ ++enum rtw89_mac_h2c_type { ++ RTW89_FWCMD_H2CREG_FUNC_H2CREG_LB = 0, ++ RTW89_FWCMD_H2CREG_FUNC_CNSL_CMD, ++ RTW89_FWCMD_H2CREG_FUNC_FWERR, ++ RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE, ++ RTW89_FWCMD_H2CREG_FUNC_GETPKT_INFORM, ++ RTW89_FWCMD_H2CREG_FUNC_SCH_TX_EN ++}; ++ ++enum rtw89_mac_c2h_type { ++ RTW89_FWCMD_C2HREG_FUNC_C2HREG_LB = 0, ++ RTW89_FWCMD_C2HREG_FUNC_ERR_RPT, ++ RTW89_FWCMD_C2HREG_FUNC_ERR_MSG, ++ RTW89_FWCMD_C2HREG_FUNC_PHY_CAP, ++ RTW89_FWCMD_C2HREG_FUNC_TX_PAUSE_RPT, ++ RTW89_FWCMD_C2HREG_FUNC_NULL = 0xFF ++}; ++ ++struct rtw89_c2h_phy_cap { ++ u32 func:7; ++ u32 ack:1; ++ u32 len:4; ++ u32 seq:4; ++ u32 rx_nss:8; ++ u32 bw:8; ++ ++ u32 tx_nss:8; ++ u32 prot:8; ++ u32 nic:8; ++ u32 wl_func:8; ++ ++ u32 hw_type:8; ++} __packed; ++ ++enum rtw89_fw_c2h_category { ++ RTW89_C2H_CAT_TEST, ++ RTW89_C2H_CAT_MAC, ++ RTW89_C2H_CAT_OUTSRC, ++}; ++ ++enum rtw89_fw_log_level { ++ RTW89_FW_LOG_LEVEL_OFF, ++ RTW89_FW_LOG_LEVEL_CRT, ++ RTW89_FW_LOG_LEVEL_SER, ++ RTW89_FW_LOG_LEVEL_WARN, ++ RTW89_FW_LOG_LEVEL_LOUD, ++ RTW89_FW_LOG_LEVEL_TR, ++}; ++ ++enum rtw89_fw_log_path { ++ RTW89_FW_LOG_LEVEL_UART, ++ RTW89_FW_LOG_LEVEL_C2H, ++ RTW89_FW_LOG_LEVEL_SNI, ++}; ++ ++enum rtw89_fw_log_comp { ++ RTW89_FW_LOG_COMP_VER, ++ RTW89_FW_LOG_COMP_INIT, ++ RTW89_FW_LOG_COMP_TASK, ++ RTW89_FW_LOG_COMP_CNS, ++ RTW89_FW_LOG_COMP_H2C, ++ RTW89_FW_LOG_COMP_C2H, ++ RTW89_FW_LOG_COMP_TX, ++ RTW89_FW_LOG_COMP_RX, ++ RTW89_FW_LOG_COMP_IPSEC, ++ RTW89_FW_LOG_COMP_TIMER, ++ RTW89_FW_LOG_COMP_DBGPKT, ++ RTW89_FW_LOG_COMP_PS, ++ RTW89_FW_LOG_COMP_ERROR, ++ RTW89_FW_LOG_COMP_WOWLAN, ++ RTW89_FW_LOG_COMP_SECURE_BOOT, ++ RTW89_FW_LOG_COMP_BTC, ++ RTW89_FW_LOG_COMP_BB, ++ RTW89_FW_LOG_COMP_TWT, ++ RTW89_FW_LOG_COMP_RF, ++ RTW89_FW_LOG_COMP_MCC = 20, ++}; ++ ++#define FWDL_SECTION_MAX_NUM 10 ++#define FWDL_SECTION_CHKSUM_LEN 8 ++#define FWDL_SECTION_PER_PKT_LEN 2020 ++ ++struct rtw89_fw_hdr_section_info { ++ u8 redl; ++ const u8 *addr; ++ u32 len; ++ u32 dladdr; ++}; ++ ++struct rtw89_fw_bin_info { ++ u8 section_num; ++ u32 hdr_len; ++ struct rtw89_fw_hdr_section_info section_info[FWDL_SECTION_MAX_NUM]; ++}; ++ ++struct rtw89_fw_macid_pause_grp { ++ __le32 pause_grp[4]; ++ __le32 mask_grp[4]; ++} __packed; ++ ++struct rtw89_h2creg_sch_tx_en { ++ u8 func:7; ++ u8 ack:1; ++ u8 total_len:4; ++ u8 seq_num:4; ++ u16 tx_en:16; ++ u16 mask:16; ++ u8 band:1; ++ u16 rsvd:15; ++} __packed; ++ ++#define RTW89_SET_FWCMD_RA_IS_DIS(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(0)) ++#define RTW89_SET_FWCMD_RA_MODE(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(5, 1)) ++#define RTW89_SET_FWCMD_RA_BW_CAP(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(7, 6)) ++#define RTW89_SET_FWCMD_RA_MACID(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(15, 8)) ++#define RTW89_SET_FWCMD_RA_DCM(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(16)) ++#define RTW89_SET_FWCMD_RA_ER(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(17)) ++#define RTW89_SET_FWCMD_RA_INIT_RATE_LV(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(19, 18)) ++#define RTW89_SET_FWCMD_RA_UPD_ALL(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(20)) ++#define RTW89_SET_FWCMD_RA_SGI(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(21)) ++#define RTW89_SET_FWCMD_RA_LDPC(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(22)) ++#define RTW89_SET_FWCMD_RA_STBC(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(23)) ++#define RTW89_SET_FWCMD_RA_SS_NUM(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(26, 24)) ++#define RTW89_SET_FWCMD_RA_GILTF(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(29, 27)) ++#define RTW89_SET_FWCMD_RA_UPD_BW_NSS_MASK(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(30)) ++#define RTW89_SET_FWCMD_RA_UPD_MASK(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(31)) ++#define RTW89_SET_FWCMD_RA_MASK_0(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_RA_MASK_1(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(15, 8)) ++#define RTW89_SET_FWCMD_RA_MASK_2(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(23, 16)) ++#define RTW89_SET_FWCMD_RA_MASK_3(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(31, 24)) ++#define RTW89_SET_FWCMD_RA_MASK_4(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x02, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_RA_BFEE_CSI_CTL(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x02, val, BIT(31)) ++#define RTW89_SET_FWCMD_RA_BAND_NUM(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_RA_RA_CSI_RATE_EN(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, BIT(8)) ++#define RTW89_SET_FWCMD_RA_FIXED_CSI_RATE_EN(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, BIT(9)) ++#define RTW89_SET_FWCMD_RA_CR_TBL_SEL(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, BIT(10)) ++#define RTW89_SET_FWCMD_RA_FIXED_CSI_MCS_SS_IDX(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(23, 16)) ++#define RTW89_SET_FWCMD_RA_FIXED_CSI_MODE(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(25, 24)) ++#define RTW89_SET_FWCMD_RA_FIXED_CSI_GI_LTF(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(28, 26)) ++#define RTW89_SET_FWCMD_RA_FIXED_CSI_BW(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(31, 29)) ++ ++#define RTW89_SET_FWCMD_SEC_IDX(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_SEC_OFFSET(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(15, 8)) ++#define RTW89_SET_FWCMD_SEC_LEN(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(23, 16)) ++#define RTW89_SET_FWCMD_SEC_TYPE(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(3, 0)) ++#define RTW89_SET_FWCMD_SEC_EXT_KEY(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, BIT(4)) ++#define RTW89_SET_FWCMD_SEC_SPP_MODE(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, BIT(5)) ++#define RTW89_SET_FWCMD_SEC_KEY0(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x02, val, GENMASK(31, 0)) ++#define RTW89_SET_FWCMD_SEC_KEY1(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x03, val, GENMASK(31, 0)) ++#define RTW89_SET_FWCMD_SEC_KEY2(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x04, val, GENMASK(31, 0)) ++#define RTW89_SET_FWCMD_SEC_KEY3(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x05, val, GENMASK(31, 0)) ++ ++#define RTW89_SET_EDCA_SEL(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(1, 0)) ++#define RTW89_SET_EDCA_BAND(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(3)) ++#define RTW89_SET_EDCA_WMM(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, BIT(4)) ++#define RTW89_SET_EDCA_AC(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x00, val, GENMASK(6, 5)) ++#define RTW89_SET_EDCA_PARAM(cmd, val) \ ++ le32p_replace_bits((__le32 *)(cmd) + 0x01, val, GENMASK(31, 0)) ++#define FW_EDCA_PARAM_TXOPLMT_MSK GENMASK(26, 16) ++#define FW_EDCA_PARAM_CWMAX_MSK GENMASK(15, 12) ++#define FW_EDCA_PARAM_CWMIN_MSK GENMASK(11, 8) ++#define FW_EDCA_PARAM_AIFS_MSK GENMASK(7, 0) ++ ++#define GET_FWSECTION_HDR_SEC_SIZE(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 1), GENMASK(23, 0)) ++#define GET_FWSECTION_HDR_CHECKSUM(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 1), BIT(28)) ++#define GET_FWSECTION_HDR_REDL(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 1), BIT(29)) ++#define GET_FWSECTION_HDR_DL_ADDR(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr)), GENMASK(31, 0)) ++ ++#define GET_FW_HDR_MAJOR_VERSION(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 1), GENMASK(7, 0)) ++#define GET_FW_HDR_MINOR_VERSION(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 1), GENMASK(15, 8)) ++#define GET_FW_HDR_SUBVERSION(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 1), GENMASK(23, 16)) ++#define GET_FW_HDR_SUBINDEX(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 1), GENMASK(31, 24)) ++#define GET_FW_HDR_MONTH(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 4), GENMASK(7, 0)) ++#define GET_FW_HDR_DATE(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 4), GENMASK(15, 8)) ++#define GET_FW_HDR_HOUR(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 4), GENMASK(23, 16)) ++#define GET_FW_HDR_MIN(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 4), GENMASK(31, 24)) ++#define GET_FW_HDR_YEAR(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 5), GENMASK(31, 0)) ++#define GET_FW_HDR_SEC_NUM(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 6), GENMASK(15, 8)) ++#define GET_FW_HDR_CMD_VERSERION(fwhdr) \ ++ le32_get_bits(*((__le32 *)(fwhdr) + 7), GENMASK(31, 24)) ++#define SET_FW_HDR_PART_SIZE(fwhdr, val) \ ++ le32p_replace_bits((__le32 *)(fwhdr) + 7, val, GENMASK(15, 0)) ++ ++#define SET_CTRL_INFO_MACID(table, val) \ ++ le32p_replace_bits((__le32 *)(table) + 0, val, GENMASK(6, 0)) ++#define SET_CTRL_INFO_OPERATION(table, val) \ ++ le32p_replace_bits((__le32 *)(table) + 0, val, BIT(7)) ++#define SET_CMC_TBL_MASK_DATARATE GENMASK(8, 0) ++#define SET_CMC_TBL_DATARATE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(8, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DATARATE, \ ++ GENMASK(8, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_FORCE_TXOP BIT(0) ++#define SET_CMC_TBL_FORCE_TXOP(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(9)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_FORCE_TXOP, \ ++ BIT(9)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_BW GENMASK(1, 0) ++#define SET_CMC_TBL_DATA_BW(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(11, 10)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DATA_BW, \ ++ GENMASK(11, 10)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_GI_LTF GENMASK(2, 0) ++#define SET_CMC_TBL_DATA_GI_LTF(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(14, 12)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DATA_GI_LTF, \ ++ GENMASK(14, 12)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DARF_TC_INDEX BIT(0) ++#define SET_CMC_TBL_DARF_TC_INDEX(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(15)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DARF_TC_INDEX, \ ++ BIT(15)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ARFR_CTRL GENMASK(3, 0) ++#define SET_CMC_TBL_ARFR_CTRL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(19, 16)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_ARFR_CTRL, \ ++ GENMASK(19, 16)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ACQ_RPT_EN BIT(0) ++#define SET_CMC_TBL_ACQ_RPT_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(20)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_ACQ_RPT_EN, \ ++ BIT(20)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_MGQ_RPT_EN BIT(0) ++#define SET_CMC_TBL_MGQ_RPT_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(21)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_MGQ_RPT_EN, \ ++ BIT(21)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ULQ_RPT_EN BIT(0) ++#define SET_CMC_TBL_ULQ_RPT_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(22)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_ULQ_RPT_EN, \ ++ BIT(22)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_TWTQ_RPT_EN BIT(0) ++#define SET_CMC_TBL_TWTQ_RPT_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(23)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_TWTQ_RPT_EN, \ ++ BIT(23)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DISRTSFB BIT(0) ++#define SET_CMC_TBL_DISRTSFB(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(25)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DISRTSFB, \ ++ BIT(25)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DISDATAFB BIT(0) ++#define SET_CMC_TBL_DISDATAFB(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(26)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_DISDATAFB, \ ++ BIT(26)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_TRYRATE BIT(0) ++#define SET_CMC_TBL_TRYRATE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, BIT(27)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_TRYRATE, \ ++ BIT(27)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_AMPDU_DENSITY GENMASK(3, 0) ++#define SET_CMC_TBL_AMPDU_DENSITY(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 1, val, GENMASK(31, 28)); \ ++ le32p_replace_bits((__le32 *)(table) + 9, SET_CMC_TBL_MASK_AMPDU_DENSITY, \ ++ GENMASK(31, 28)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_RTY_LOWEST_RATE GENMASK(8, 0) ++#define SET_CMC_TBL_DATA_RTY_LOWEST_RATE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, GENMASK(8, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_DATA_RTY_LOWEST_RATE, \ ++ GENMASK(8, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_AMPDU_TIME_SEL BIT(0) ++#define SET_CMC_TBL_AMPDU_TIME_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, BIT(9)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_AMPDU_TIME_SEL, \ ++ BIT(9)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_AMPDU_LEN_SEL BIT(0) ++#define SET_CMC_TBL_AMPDU_LEN_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, BIT(10)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_AMPDU_LEN_SEL, \ ++ BIT(10)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_RTS_TXCNT_LMT_SEL BIT(0) ++#define SET_CMC_TBL_RTS_TXCNT_LMT_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, BIT(11)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_RTS_TXCNT_LMT_SEL, \ ++ BIT(11)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_RTS_TXCNT_LMT GENMASK(3, 0) ++#define SET_CMC_TBL_RTS_TXCNT_LMT(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, GENMASK(15, 12)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_RTS_TXCNT_LMT, \ ++ GENMASK(15, 12)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_RTSRATE GENMASK(8, 0) ++#define SET_CMC_TBL_RTSRATE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, GENMASK(24, 16)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_RTSRATE, \ ++ GENMASK(24, 16)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_VCS_STBC BIT(0) ++#define SET_CMC_TBL_VCS_STBC(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, BIT(27)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_VCS_STBC, \ ++ BIT(27)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_RTS_RTY_LOWEST_RATE GENMASK(3, 0) ++#define SET_CMC_TBL_RTS_RTY_LOWEST_RATE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 2, val, GENMASK(31, 28)); \ ++ le32p_replace_bits((__le32 *)(table) + 10, SET_CMC_TBL_MASK_RTS_RTY_LOWEST_RATE, \ ++ GENMASK(31, 28)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_TX_CNT_LMT GENMASK(5, 0) ++#define SET_CMC_TBL_DATA_TX_CNT_LMT(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(5, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_DATA_TX_CNT_LMT, \ ++ GENMASK(5, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_TXCNT_LMT_SEL BIT(0) ++#define SET_CMC_TBL_DATA_TXCNT_LMT_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, BIT(6)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_DATA_TXCNT_LMT_SEL, \ ++ BIT(6)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_MAX_AGG_NUM_SEL BIT(0) ++#define SET_CMC_TBL_MAX_AGG_NUM_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, BIT(7)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_MAX_AGG_NUM_SEL, \ ++ BIT(7)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_RTS_EN BIT(0) ++#define SET_CMC_TBL_RTS_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, BIT(8)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_RTS_EN, \ ++ BIT(8)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CTS2SELF_EN BIT(0) ++#define SET_CMC_TBL_CTS2SELF_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, BIT(9)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_CTS2SELF_EN, \ ++ BIT(9)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CCA_RTS GENMASK(1, 0) ++#define SET_CMC_TBL_CCA_RTS(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(11, 10)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_CCA_RTS, \ ++ GENMASK(11, 10)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_HW_RTS_EN BIT(0) ++#define SET_CMC_TBL_HW_RTS_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, BIT(12)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_HW_RTS_EN, \ ++ BIT(12)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_RTS_DROP_DATA_MODE GENMASK(1, 0) ++#define SET_CMC_TBL_RTS_DROP_DATA_MODE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(14, 13)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_RTS_DROP_DATA_MODE, \ ++ GENMASK(14, 13)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_AMPDU_MAX_LEN GENMASK(10, 0) ++#define SET_CMC_TBL_AMPDU_MAX_LEN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(26, 16)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_AMPDU_MAX_LEN, \ ++ GENMASK(26, 16)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_UL_MU_DIS BIT(0) ++#define SET_CMC_TBL_UL_MU_DIS(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, BIT(27)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_UL_MU_DIS, \ ++ BIT(27)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_AMPDU_MAX_TIME GENMASK(3, 0) ++#define SET_CMC_TBL_AMPDU_MAX_TIME(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 3, val, GENMASK(31, 28)); \ ++ le32p_replace_bits((__le32 *)(table) + 11, SET_CMC_TBL_MASK_AMPDU_MAX_TIME, \ ++ GENMASK(31, 28)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_MAX_AGG_NUM GENMASK(7, 0) ++#define SET_CMC_TBL_MAX_AGG_NUM(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(7, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_MAX_AGG_NUM, \ ++ GENMASK(7, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_BA_BMAP GENMASK(1, 0) ++#define SET_CMC_TBL_BA_BMAP(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(9, 8)); \ ++ le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_BA_BMAP, \ ++ GENMASK(9, 8)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_VO_LFTIME_SEL GENMASK(2, 0) ++#define SET_CMC_TBL_VO_LFTIME_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(18, 16)); \ ++ le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_VO_LFTIME_SEL, \ ++ GENMASK(18, 16)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_VI_LFTIME_SEL GENMASK(2, 0) ++#define SET_CMC_TBL_VI_LFTIME_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(21, 19)); \ ++ le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_VI_LFTIME_SEL, \ ++ GENMASK(21, 19)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_BE_LFTIME_SEL GENMASK(2, 0) ++#define SET_CMC_TBL_BE_LFTIME_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(24, 22)); \ ++ le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_BE_LFTIME_SEL, \ ++ GENMASK(24, 22)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_BK_LFTIME_SEL GENMASK(2, 0) ++#define SET_CMC_TBL_BK_LFTIME_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(27, 25)); \ ++ le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_BK_LFTIME_SEL, \ ++ GENMASK(27, 25)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_SECTYPE GENMASK(3, 0) ++#define SET_CMC_TBL_SECTYPE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 4, val, GENMASK(31, 28)); \ ++ le32p_replace_bits((__le32 *)(table) + 12, SET_CMC_TBL_MASK_SECTYPE, \ ++ GENMASK(31, 28)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_MULTI_PORT_ID GENMASK(2, 0) ++#define SET_CMC_TBL_MULTI_PORT_ID(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(2, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_MULTI_PORT_ID, \ ++ GENMASK(2, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_BMC BIT(0) ++#define SET_CMC_TBL_BMC(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(3)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_BMC, \ ++ BIT(3)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_MBSSID GENMASK(3, 0) ++#define SET_CMC_TBL_MBSSID(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(7, 4)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_MBSSID, \ ++ GENMASK(7, 4)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_NAVUSEHDR BIT(0) ++#define SET_CMC_TBL_NAVUSEHDR(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(8)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_NAVUSEHDR, \ ++ BIT(8)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_TXPWR_MODE GENMASK(2, 0) ++#define SET_CMC_TBL_TXPWR_MODE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(11, 9)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_TXPWR_MODE, \ ++ GENMASK(11, 9)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_DCM BIT(0) ++#define SET_CMC_TBL_DATA_DCM(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(12)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_DATA_DCM, \ ++ BIT(12)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_ER BIT(0) ++#define SET_CMC_TBL_DATA_ER(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(13)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_DATA_ER, \ ++ BIT(13)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_LDPC BIT(0) ++#define SET_CMC_TBL_DATA_LDPC(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(14)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_DATA_LDPC, \ ++ BIT(14)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_STBC BIT(0) ++#define SET_CMC_TBL_DATA_STBC(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(15)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_DATA_STBC, \ ++ BIT(15)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_A_CTRL_BQR BIT(0) ++#define SET_CMC_TBL_A_CTRL_BQR(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(16)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_A_CTRL_BQR, \ ++ BIT(16)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_A_CTRL_UPH BIT(0) ++#define SET_CMC_TBL_A_CTRL_UPH(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(17)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_A_CTRL_UPH, \ ++ BIT(17)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_A_CTRL_BSR BIT(0) ++#define SET_CMC_TBL_A_CTRL_BSR(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(18)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_A_CTRL_BSR, \ ++ BIT(18)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_A_CTRL_CAS BIT(0) ++#define SET_CMC_TBL_A_CTRL_CAS(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(19)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_A_CTRL_CAS, \ ++ BIT(19)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DATA_BW_ER BIT(0) ++#define SET_CMC_TBL_DATA_BW_ER(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(20)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_DATA_BW_ER, \ ++ BIT(20)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_LSIG_TXOP_EN BIT(0) ++#define SET_CMC_TBL_LSIG_TXOP_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(21)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_LSIG_TXOP_EN, \ ++ BIT(21)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CTRL_CNT_VLD BIT(0) ++#define SET_CMC_TBL_CTRL_CNT_VLD(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, BIT(27)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_CTRL_CNT_VLD, \ ++ BIT(27)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CTRL_CNT GENMASK(3, 0) ++#define SET_CMC_TBL_CTRL_CNT(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 5, val, GENMASK(31, 28)); \ ++ le32p_replace_bits((__le32 *)(table) + 13, SET_CMC_TBL_MASK_CTRL_CNT, \ ++ GENMASK(31, 28)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_RESP_REF_RATE GENMASK(8, 0) ++#define SET_CMC_TBL_RESP_REF_RATE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(8, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_RESP_REF_RATE, \ ++ GENMASK(8, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ALL_ACK_SUPPORT BIT(0) ++#define SET_CMC_TBL_ALL_ACK_SUPPORT(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, BIT(12)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ALL_ACK_SUPPORT, \ ++ BIT(12)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_BSR_QUEUE_SIZE_FORMAT BIT(0) ++#define SET_CMC_TBL_BSR_QUEUE_SIZE_FORMAT(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, BIT(13)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_BSR_QUEUE_SIZE_FORMAT, \ ++ BIT(13)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_NTX_PATH_EN GENMASK(3, 0) ++#define SET_CMC_TBL_NTX_PATH_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(19, 16)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_NTX_PATH_EN, \ ++ GENMASK(19, 16)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_PATH_MAP_A GENMASK(1, 0) ++#define SET_CMC_TBL_PATH_MAP_A(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(21, 20)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_PATH_MAP_A, \ ++ GENMASK(21, 20)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_PATH_MAP_B GENMASK(1, 0) ++#define SET_CMC_TBL_PATH_MAP_B(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(23, 22)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_PATH_MAP_B, \ ++ GENMASK(23, 22)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_PATH_MAP_C GENMASK(1, 0) ++#define SET_CMC_TBL_PATH_MAP_C(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(25, 24)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_PATH_MAP_C, \ ++ GENMASK(25, 24)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_PATH_MAP_D GENMASK(1, 0) ++#define SET_CMC_TBL_PATH_MAP_D(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, GENMASK(27, 26)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_PATH_MAP_D, \ ++ GENMASK(27, 26)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ANTSEL_A BIT(0) ++#define SET_CMC_TBL_ANTSEL_A(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, BIT(28)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ANTSEL_A, \ ++ BIT(28)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ANTSEL_B BIT(0) ++#define SET_CMC_TBL_ANTSEL_B(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, BIT(29)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ANTSEL_B, \ ++ BIT(29)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ANTSEL_C BIT(0) ++#define SET_CMC_TBL_ANTSEL_C(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, BIT(30)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ANTSEL_C, \ ++ BIT(30)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ANTSEL_D BIT(0) ++#define SET_CMC_TBL_ANTSEL_D(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 6, val, BIT(31)); \ ++ le32p_replace_bits((__le32 *)(table) + 14, SET_CMC_TBL_MASK_ANTSEL_D, \ ++ BIT(31)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ADDR_CAM_INDEX GENMASK(7, 0) ++#define SET_CMC_TBL_ADDR_CAM_INDEX(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(7, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_ADDR_CAM_INDEX, \ ++ GENMASK(7, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_PAID GENMASK(8, 0) ++#define SET_CMC_TBL_PAID(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(16, 8)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_PAID, \ ++ GENMASK(16, 8)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_ULDL BIT(0) ++#define SET_CMC_TBL_ULDL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, BIT(17)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_ULDL, \ ++ BIT(17)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_DOPPLER_CTRL GENMASK(1, 0) ++#define SET_CMC_TBL_DOPPLER_CTRL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(19, 18)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_DOPPLER_CTRL, \ ++ GENMASK(19, 18)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING GENMASK(1, 0) ++#define SET_CMC_TBL_NOMINAL_PKT_PADDING(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(21, 20)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, \ ++ GENMASK(21, 20)); \ ++} while (0) ++#define SET_CMC_TBL_NOMINAL_PKT_PADDING40(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(23, 22)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, \ ++ GENMASK(23, 22)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_TXPWR_TOLERENCE GENMASK(3, 0) ++#define SET_CMC_TBL_TXPWR_TOLERENCE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(27, 24)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_TXPWR_TOLERENCE, \ ++ GENMASK(27, 24)); \ ++} while (0) ++#define SET_CMC_TBL_NOMINAL_PKT_PADDING80(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 7, val, GENMASK(31, 30)); \ ++ le32p_replace_bits((__le32 *)(table) + 15, SET_CMC_TBL_MASK_NOMINAL_PKT_PADDING, \ ++ GENMASK(31, 30)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_NC GENMASK(2, 0) ++#define SET_CMC_TBL_NC(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(2, 0)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_NC, \ ++ GENMASK(2, 0)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_NR GENMASK(2, 0) ++#define SET_CMC_TBL_NR(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(5, 3)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_NR, \ ++ GENMASK(5, 3)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_NG GENMASK(1, 0) ++#define SET_CMC_TBL_NG(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(7, 6)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_NG, \ ++ GENMASK(7, 6)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CB GENMASK(1, 0) ++#define SET_CMC_TBL_CB(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(9, 8)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CB, \ ++ GENMASK(9, 8)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CS GENMASK(1, 0) ++#define SET_CMC_TBL_CS(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(11, 10)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CS, \ ++ GENMASK(11, 10)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_TXBF_EN BIT(0) ++#define SET_CMC_TBL_CSI_TXBF_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, BIT(12)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_TXBF_EN, \ ++ BIT(12)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_STBC_EN BIT(0) ++#define SET_CMC_TBL_CSI_STBC_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, BIT(13)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_STBC_EN, \ ++ BIT(13)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_LDPC_EN BIT(0) ++#define SET_CMC_TBL_CSI_LDPC_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, BIT(14)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_LDPC_EN, \ ++ BIT(14)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_PARA_EN BIT(0) ++#define SET_CMC_TBL_CSI_PARA_EN(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, BIT(15)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_PARA_EN, \ ++ BIT(15)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_FIX_RATE GENMASK(8, 0) ++#define SET_CMC_TBL_CSI_FIX_RATE(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(24, 16)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_FIX_RATE, \ ++ GENMASK(24, 16)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_GI_LTF GENMASK(2, 0) ++#define SET_CMC_TBL_CSI_GI_LTF(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(27, 25)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_GI_LTF, \ ++ GENMASK(27, 25)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_GID_SEL BIT(0) ++#define SET_CMC_TBL_CSI_GID_SEL(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, BIT(29)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_GID_SEL, \ ++ BIT(29)); \ ++} while (0) ++#define SET_CMC_TBL_MASK_CSI_BW GENMASK(1, 0) ++#define SET_CMC_TBL_CSI_BW(table, val) \ ++do { \ ++ le32p_replace_bits((__le32 *)(table) + 8, val, GENMASK(31, 30)); \ ++ le32p_replace_bits((__le32 *)(table) + 16, SET_CMC_TBL_MASK_CSI_BW, \ ++ GENMASK(31, 30)); \ ++} while (0) ++ ++#define SET_FWROLE_MAINTAIN_MACID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0)) ++#define SET_FWROLE_MAINTAIN_SELF_ROLE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(9, 8)) ++#define SET_FWROLE_MAINTAIN_UPD_MODE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(12, 10)) ++#define SET_FWROLE_MAINTAIN_WIFI_ROLE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(16, 13)) ++ ++#define SET_JOININFO_MACID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0)) ++#define SET_JOININFO_OP(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(8)) ++#define SET_JOININFO_BAND(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(9)) ++#define SET_JOININFO_WMM(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(11, 10)) ++#define SET_JOININFO_TGR(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(12)) ++#define SET_JOININFO_ISHESTA(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(13)) ++#define SET_JOININFO_DLBW(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 14)) ++#define SET_JOININFO_TF_MAC_PAD(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(17, 16)) ++#define SET_JOININFO_DL_T_PE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(20, 18)) ++#define SET_JOININFO_PORT_ID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(23, 21)) ++#define SET_JOININFO_NET_TYPE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(25, 24)) ++#define SET_JOININFO_WIFI_ROLE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(29, 26)) ++#define SET_JOININFO_SELF_ROLE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 30)) ++ ++#define SET_GENERAL_PKT_MACID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0)) ++#define SET_GENERAL_PKT_PROBRSP_ID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)) ++#define SET_GENERAL_PKT_PSPOLL_ID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(23, 16)) ++#define SET_GENERAL_PKT_NULL_ID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)) ++#define SET_GENERAL_PKT_QOS_NULL_ID(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(7, 0)) ++#define SET_GENERAL_PKT_CTS2SELF_ID(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(15, 8)) ++ ++#define SET_LOG_CFG_LEVEL(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0)) ++#define SET_LOG_CFG_PATH(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)) ++#define SET_LOG_CFG_COMP(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(31, 0)) ++#define SET_LOG_CFG_COMP_EXT(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 2, val, GENMASK(31, 0)) ++ ++#define SET_BA_CAM_VALID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(0)) ++#define SET_BA_CAM_INIT_REQ(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(1)) ++#define SET_BA_CAM_ENTRY_IDX(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(3, 2)) ++#define SET_BA_CAM_TID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 4)) ++#define SET_BA_CAM_MACID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)) ++#define SET_BA_CAM_BMAP_SIZE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(19, 16)) ++#define SET_BA_CAM_SSN(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 20)) ++ ++#define SET_LPS_PARM_MACID(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0)) ++#define SET_LPS_PARM_PSMODE(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)) ++#define SET_LPS_PARM_RLBM(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(19, 16)) ++#define SET_LPS_PARM_SMARTPS(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(23, 20)) ++#define SET_LPS_PARM_AWAKEINTERVAL(h2c, val) \ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)) ++#define SET_LPS_PARM_VOUAPSD(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, BIT(0)) ++#define SET_LPS_PARM_VIUAPSD(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, BIT(1)) ++#define SET_LPS_PARM_BEUAPSD(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, BIT(2)) ++#define SET_LPS_PARM_BKUAPSD(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, BIT(3)) ++#define SET_LPS_PARM_LASTRPWM(h2c, val) \ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(15, 8)) ++ ++enum rtw89_btc_btf_h2c_class { ++ BTFC_SET = 0x10, ++ BTFC_GET = 0x11, ++ BTFC_FW_EVENT = 0x12, ++}; ++ ++enum rtw89_btc_btf_set { ++ SET_REPORT_EN = 0x0, ++ SET_SLOT_TABLE, ++ SET_MREG_TABLE, ++ SET_CX_POLICY, ++ SET_GPIO_DBG, ++ SET_DRV_INFO, ++ SET_DRV_EVENT, ++ SET_BT_WREG_ADDR, ++ SET_BT_WREG_VAL, ++ SET_BT_RREG_ADDR, ++ SET_BT_WL_CH_INFO, ++ SET_BT_INFO_REPORT, ++ SET_BT_IGNORE_WLAN_ACT, ++ SET_BT_TX_PWR, ++ SET_BT_LNA_CONSTRAIN, ++ SET_BT_GOLDEN_RX_RANGE, ++ SET_BT_PSD_REPORT, ++ SET_H2C_TEST, ++ SET_MAX1, ++}; ++ ++enum rtw89_btc_cxdrvinfo { ++ CXDRVINFO_INIT = 0, ++ CXDRVINFO_ROLE, ++ CXDRVINFO_DBCC, ++ CXDRVINFO_SMAP, ++ CXDRVINFO_RFK, ++ CXDRVINFO_RUN, ++ CXDRVINFO_CTRL, ++ CXDRVINFO_SCAN, ++ CXDRVINFO_MAX, ++}; ++ ++#define RTW89_SET_FWCMD_CXHDR_TYPE(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 0, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXHDR_LEN(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 1, val, GENMASK(7, 0)) ++ ++#define RTW89_SET_FWCMD_CXINIT_ANT_TYPE(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 2, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXINIT_ANT_NUM(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 3, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXINIT_ANT_ISO(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 4, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXINIT_ANT_POS(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 5, val, BIT(0)) ++#define RTW89_SET_FWCMD_CXINIT_ANT_DIVERSITY(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 5, val, BIT(1)) ++#define RTW89_SET_FWCMD_CXINIT_MOD_RFE(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 6, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXINIT_MOD_CV(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 7, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXINIT_MOD_BT_SOLO(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 8, val, BIT(0)) ++#define RTW89_SET_FWCMD_CXINIT_MOD_BT_POS(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 8, val, BIT(1)) ++#define RTW89_SET_FWCMD_CXINIT_MOD_SW_TYPE(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 8, val, BIT(2)) ++#define RTW89_SET_FWCMD_CXINIT_WL_GCH(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 10, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXINIT_WL_ONLY(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 11, val, BIT(0)) ++#define RTW89_SET_FWCMD_CXINIT_WL_INITOK(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 11, val, BIT(1)) ++#define RTW89_SET_FWCMD_CXINIT_DBCC_EN(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 11, val, BIT(2)) ++#define RTW89_SET_FWCMD_CXINIT_CX_OTHER(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 11, val, BIT(3)) ++#define RTW89_SET_FWCMD_CXINIT_BT_ONLY(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 11, val, BIT(4)) ++ ++#define RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 2, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, val) \ ++ u8p_replace_bits((u8 *)(cmd) + 3, val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(0)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(1)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(2)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(3)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(4)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(5)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(6)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(7)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(8)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(9)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(10)) ++#define RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, val) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + 4), val, BIT(11)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (6 + 12 * (n)), val, BIT(0)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (6 + 12 * (n)), val, GENMASK(3, 1)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (6 + 12 * (n)), val, BIT(4)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (6 + 12 * (n)), val, BIT(5)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (6 + 12 * (n)), val, GENMASK(7, 6)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (7 + 12 * (n)), val, BIT(0)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (7 + 12 * (n)), val, GENMASK(7, 1)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (8 + 12 * (n)), val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, val, n) \ ++ u8p_replace_bits((u8 *)(cmd) + (9 + 12 * (n)), val, GENMASK(7, 0)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, val, n) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + (10 + 12 * (n))), val, GENMASK(15, 0)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, val, n) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + (12 + 12 * (n))), val, GENMASK(15, 0)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, val, n) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + (14 + 12 * (n))), val, GENMASK(15, 0)) ++#define RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, val, n) \ ++ le16p_replace_bits((__le16 *)((u8 *)(cmd) + (16 + 12 * (n))), val, GENMASK(15, 0)) ++ ++#define RTW89_SET_FWCMD_CXCTRL_MANUAL(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, BIT(0)) ++#define RTW89_SET_FWCMD_CXCTRL_IGNORE_BT(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, BIT(1)) ++#define RTW89_SET_FWCMD_CXCTRL_ALWAYS_FREERUN(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, BIT(2)) ++#define RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(18, 3)) ++ ++#define RTW89_SET_FWCMD_CXRFK_STATE(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(1, 0)) ++#define RTW89_SET_FWCMD_CXRFK_PATH_MAP(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(5, 2)) ++#define RTW89_SET_FWCMD_CXRFK_PHY_MAP(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(7, 6)) ++#define RTW89_SET_FWCMD_CXRFK_BAND(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(9, 8)) ++#define RTW89_SET_FWCMD_CXRFK_TYPE(cmd, val) \ ++ le32p_replace_bits((__le32 *)((u8 *)(cmd) + 2), val, GENMASK(17, 10)) ++ ++#define RTW89_C2H_HEADER_LEN 8 ++ ++#define RTW89_GET_C2H_CATEGORY(c2h) \ ++ le32_get_bits(*((__le32 *)c2h), GENMASK(1, 0)) ++#define RTW89_GET_C2H_CLASS(c2h) \ ++ le32_get_bits(*((__le32 *)c2h), GENMASK(7, 2)) ++#define RTW89_GET_C2H_FUNC(c2h) \ ++ le32_get_bits(*((__le32 *)c2h), GENMASK(15, 8)) ++#define RTW89_GET_C2H_LEN(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 1), GENMASK(13, 0)) ++ ++#define RTW89_GET_C2H_LOG_SRT_PRT(c2h) (char *)((__le32 *)(c2h) + 2) ++#define RTW89_GET_C2H_LOG_LEN(len) ((len) - RTW89_C2H_HEADER_LEN) ++ ++#define RTW89_GET_MAC_C2H_DONE_ACK_CAT(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(1, 0)) ++#define RTW89_GET_MAC_C2H_DONE_ACK_CLASS(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(7, 2)) ++#define RTW89_GET_MAC_C2H_DONE_ACK_FUNC(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(15, 8)) ++#define RTW89_GET_MAC_C2H_DONE_ACK_H2C_RETURN(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(23, 16)) ++#define RTW89_GET_MAC_C2H_DONE_ACK_H2C_SEQ(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(31, 24)) ++ ++#define RTW89_GET_MAC_C2H_REV_ACK_CAT(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(1, 0)) ++#define RTW89_GET_MAC_C2H_REV_ACK_CLASS(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(7, 2)) ++#define RTW89_GET_MAC_C2H_REV_ACK_FUNC(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(15, 8)) ++#define RTW89_GET_MAC_C2H_REV_ACK_H2C_SEQ(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(23, 16)) ++ ++#define RTW89_GET_PHY_C2H_RA_RPT_MACID(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(15, 0)) ++#define RTW89_GET_PHY_C2H_RA_RPT_RETRY_RATIO(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 2), GENMASK(23, 16)) ++#define RTW89_GET_PHY_C2H_RA_RPT_MCSNSS(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 3), GENMASK(6, 0)) ++#define RTW89_GET_PHY_C2H_RA_RPT_MD_SEL(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 3), GENMASK(9, 8)) ++#define RTW89_GET_PHY_C2H_RA_RPT_GILTF(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 3), GENMASK(12, 10)) ++#define RTW89_GET_PHY_C2H_RA_RPT_BW(c2h) \ ++ le32_get_bits(*((__le32 *)(c2h) + 3), GENMASK(14, 13)) ++ ++/* VHT, HE, HT-old: [6:4]: NSS, [3:0]: MCS ++ * HT-new: [6:5]: NA, [4:0]: MCS ++ */ ++#define RTW89_RA_RATE_MASK_NSS GENMASK(6, 4) ++#define RTW89_RA_RATE_MASK_MCS GENMASK(3, 0) ++#define RTW89_RA_RATE_MASK_HT_MCS GENMASK(4, 0) ++#define RTW89_MK_HT_RATE(nss, mcs) (FIELD_PREP(GENMASK(4, 3), nss) | \ ++ FIELD_PREP(GENMASK(2, 0), mcs)) ++ ++#define RTW89_FW_HDR_SIZE 32 ++#define RTW89_FW_SECTION_HDR_SIZE 16 ++ ++#define RTW89_MFW_SIG 0xFF ++ ++struct rtw89_mfw_info { ++ u8 cv; ++ u8 type; /* enum rtw89_fw_type */ ++ u8 mp; ++ u8 rsvd; ++ __le32 shift; ++ __le32 size; ++ u8 rsvd2[4]; ++} __packed; ++ ++struct rtw89_mfw_hdr { ++ u8 sig; /* RTW89_MFW_SIG */ ++ u8 fw_nr; ++ u8 rsvd[14]; ++ struct rtw89_mfw_info info[]; ++} __packed; ++ ++struct fwcmd_hdr { ++ __le32 hdr0; ++ __le32 hdr1; ++}; ++ ++#define RTW89_H2C_RF_PAGE_SIZE 500 ++#define RTW89_H2C_RF_PAGE_NUM 3 ++struct rtw89_fw_h2c_rf_reg_info { ++ enum rtw89_rf_path rf_path; ++ __le32 rtw89_phy_config_rf_h2c[RTW89_H2C_RF_PAGE_NUM][RTW89_H2C_RF_PAGE_SIZE]; ++ u16 curr_idx; ++}; ++ ++#define H2C_SEC_CAM_LEN 24 ++ ++#define H2C_HEADER_LEN 8 ++#define H2C_HDR_CAT GENMASK(1, 0) ++#define H2C_HDR_CLASS GENMASK(7, 2) ++#define H2C_HDR_FUNC GENMASK(15, 8) ++#define H2C_HDR_DEL_TYPE GENMASK(19, 16) ++#define H2C_HDR_H2C_SEQ GENMASK(31, 24) ++#define H2C_HDR_TOTAL_LEN GENMASK(13, 0) ++#define H2C_HDR_REC_ACK BIT(14) ++#define H2C_HDR_DONE_ACK BIT(15) ++ ++#define FWCMD_TYPE_H2C 0 ++ ++#define H2C_CAT_MAC 0x1 ++ ++/* CLASS 0 - FW INFO */ ++#define H2C_CL_FW_INFO 0x0 ++#define H2C_FUNC_LOG_CFG 0x0 ++#define H2C_FUNC_MAC_GENERAL_PKT 0x1 ++ ++/* CLASS 2 - PS */ ++#define H2C_CL_MAC_PS 0x2 ++#define H2C_FUNC_MAC_LPS_PARM 0x0 ++ ++/* CLASS 3 - FW download */ ++#define H2C_CL_MAC_FWDL 0x3 ++#define H2C_FUNC_MAC_FWHDR_DL 0x0 ++ ++/* CLASS 5 - Frame Exchange */ ++#define H2C_CL_MAC_FR_EXCHG 0x5 ++#define H2C_FUNC_MAC_CCTLINFO_UD 0x2 ++ ++/* CLASS 6 - Address CAM */ ++#define H2C_CL_MAC_ADDR_CAM_UPDATE 0x6 ++#define H2C_FUNC_MAC_ADDR_CAM_UPD 0x0 ++ ++/* CLASS 8 - Media Status Report */ ++#define H2C_CL_MAC_MEDIA_RPT 0x8 ++#define H2C_FUNC_MAC_JOININFO 0x0 ++#define H2C_FUNC_MAC_FWROLE_MAINTAIN 0x4 ++ ++/* CLASS 9 - FW offload */ ++#define H2C_CL_MAC_FW_OFLD 0x9 ++#define H2C_FUNC_MAC_MACID_PAUSE 0x8 ++#define H2C_FUNC_USR_EDCA 0xF ++#define H2C_FUNC_OFLD_CFG 0x14 ++ ++/* CLASS 10 - Security CAM */ ++#define H2C_CL_MAC_SEC_CAM 0xa ++#define H2C_FUNC_MAC_SEC_UPD 0x1 ++ ++/* CLASS 12 - BA CAM */ ++#define H2C_CL_BA_CAM 0xc ++#define H2C_FUNC_MAC_BA_CAM 0x0 ++ ++#define H2C_CAT_OUTSRC 0x2 ++ ++#define H2C_CL_OUTSRC_RA 0x1 ++#define H2C_FUNC_OUTSRC_RA_MACIDCFG 0x0 ++ ++#define H2C_CL_OUTSRC_RF_REG_A 0x8 ++#define H2C_CL_OUTSRC_RF_REG_B 0x9 ++ ++int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev); ++int rtw89_fw_recognize(struct rtw89_dev *rtwdev); ++int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type); ++int rtw89_load_firmware(struct rtw89_dev *rtwdev); ++void rtw89_unload_firmware(struct rtw89_dev *rtwdev); ++int rtw89_wait_firmware_completion(struct rtw89_dev *rtwdev); ++void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb, ++ u8 type, u8 cat, u8 class, u8 func, ++ bool rack, bool dack, u32 len); ++int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, u8 macid); ++int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev, ++ struct rtw89_sta *rtwsta); ++int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); ++void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h); ++void rtw89_fw_c2h_work(struct work_struct *work); ++int rtw89_fw_h2c_vif_maintain(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, ++ enum rtw89_upd_mode upd_mode); ++int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u8 dis_conn); ++int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp, ++ bool pause); ++int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u8 ac, u32 val); ++int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev); ++int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi); ++int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev); ++int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev); ++int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev); ++int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev); ++int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, ++ struct rtw89_fw_h2c_rf_reg_info *info, ++ u16 len, u8 page); ++int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, ++ u8 h2c_class, u8 h2c_func, u8 *buf, u16 len, ++ bool rack, bool dack); ++int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len); ++void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev); ++void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev); ++int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid); ++int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, bool valid, u8 macid, ++ struct ieee80211_ampdu_params *params); ++int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev, ++ struct rtw89_lps_parm *lps_param); ++struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(u32 len); ++struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(u32 len); ++int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev, ++ struct rtw89_mac_h2c_info *h2c_info, ++ struct rtw89_mac_c2h_info *c2h_info); ++int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable); ++void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +new file mode 100644 +index 000000000000..0171a5a7b1de +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -0,0 +1,3838 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "cam.h" ++#include "debug.h" ++#include "fw.h" ++#include "mac.h" ++#include "ps.h" ++#include "reg.h" ++#include "util.h" ++ ++int rtw89_mac_check_mac_en(struct rtw89_dev *rtwdev, u8 mac_idx, ++ enum rtw89_mac_hwmod_sel sel) ++{ ++ u32 val, r_val; ++ ++ if (sel == RTW89_DMAC_SEL) { ++ r_val = rtw89_read32(rtwdev, R_AX_DMAC_FUNC_EN); ++ val = (B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN); ++ } else if (sel == RTW89_CMAC_SEL && mac_idx == 0) { ++ r_val = rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN); ++ val = B_AX_CMAC_EN; ++ } else if (sel == RTW89_CMAC_SEL && mac_idx == 1) { ++ r_val = rtw89_read32(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND); ++ val = B_AX_CMAC1_FEN; ++ } else { ++ return -EINVAL; ++ } ++ if (r_val == RTW89_R32_EA || r_val == RTW89_R32_DEAD || ++ (val & r_val) != val) ++ return -EFAULT; ++ ++ return 0; ++} ++ ++int rtw89_mac_write_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 val) ++{ ++ u8 lte_ctrl; ++ int ret; ++ ++ ret = read_poll_timeout(rtw89_read8, lte_ctrl, (lte_ctrl & BIT(5)) != 0, ++ 50, 50000, false, rtwdev, R_AX_LTE_CTRL + 3); ++ if (ret) ++ rtw89_err(rtwdev, "[ERR]lte not ready(W)\n"); ++ ++ rtw89_write32(rtwdev, R_AX_LTE_WDATA, val); ++ rtw89_write32(rtwdev, R_AX_LTE_CTRL, 0xC00F0000 | offset); ++ ++ return ret; ++} ++ ++int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val) ++{ ++ u8 lte_ctrl; ++ int ret; ++ ++ ret = read_poll_timeout(rtw89_read8, lte_ctrl, (lte_ctrl & BIT(5)) != 0, ++ 50, 50000, false, rtwdev, R_AX_LTE_CTRL + 3); ++ if (ret) ++ rtw89_err(rtwdev, "[ERR]lte not ready(W)\n"); ++ ++ rtw89_write32(rtwdev, R_AX_LTE_CTRL, 0x800F0000 | offset); ++ *val = rtw89_read32(rtwdev, R_AX_LTE_RDATA); ++ ++ return ret; ++} ++ ++static ++int dle_dfi_ctrl(struct rtw89_dev *rtwdev, struct rtw89_mac_dle_dfi_ctrl *ctrl) ++{ ++ u32 ctrl_reg, data_reg, ctrl_data; ++ u32 val; ++ int ret; ++ ++ switch (ctrl->type) { ++ case DLE_CTRL_TYPE_WDE: ++ ctrl_reg = R_AX_WDE_DBG_FUN_INTF_CTL; ++ data_reg = R_AX_WDE_DBG_FUN_INTF_DATA; ++ ctrl_data = FIELD_PREP(B_AX_WDE_DFI_TRGSEL_MASK, ctrl->target) | ++ FIELD_PREP(B_AX_WDE_DFI_ADDR_MASK, ctrl->addr) | ++ B_AX_WDE_DFI_ACTIVE; ++ break; ++ case DLE_CTRL_TYPE_PLE: ++ ctrl_reg = R_AX_PLE_DBG_FUN_INTF_CTL; ++ data_reg = R_AX_PLE_DBG_FUN_INTF_DATA; ++ ctrl_data = FIELD_PREP(B_AX_PLE_DFI_TRGSEL_MASK, ctrl->target) | ++ FIELD_PREP(B_AX_PLE_DFI_ADDR_MASK, ctrl->addr) | ++ B_AX_PLE_DFI_ACTIVE; ++ break; ++ default: ++ rtw89_warn(rtwdev, "[ERR] dfi ctrl type %d\n", ctrl->type); ++ return -EINVAL; ++ } ++ ++ rtw89_write32(rtwdev, ctrl_reg, ctrl_data); ++ ++ ret = read_poll_timeout_atomic(rtw89_read32, val, !(val & B_AX_WDE_DFI_ACTIVE), ++ 1, 1000, false, rtwdev, ctrl_reg); ++ if (ret) { ++ rtw89_warn(rtwdev, "[ERR] dle dfi ctrl 0x%X set 0x%X timeout\n", ++ ctrl_reg, ctrl_data); ++ return ret; ++ } ++ ++ ctrl->out_data = rtw89_read32(rtwdev, data_reg); ++ return 0; ++} ++ ++static int dle_dfi_quota(struct rtw89_dev *rtwdev, ++ struct rtw89_mac_dle_dfi_quota *quota) ++{ ++ struct rtw89_mac_dle_dfi_ctrl ctrl; ++ int ret; ++ ++ ctrl.type = quota->dle_type; ++ ctrl.target = DLE_DFI_TYPE_QUOTA; ++ ctrl.addr = quota->qtaid; ++ ret = dle_dfi_ctrl(rtwdev, &ctrl); ++ if (ret) { ++ rtw89_warn(rtwdev, "[ERR]dle_dfi_ctrl %d\n", ret); ++ return ret; ++ } ++ ++ quota->rsv_pgnum = FIELD_GET(B_AX_DLE_RSV_PGNUM, ctrl.out_data); ++ quota->use_pgnum = FIELD_GET(B_AX_DLE_USE_PGNUM, ctrl.out_data); ++ return 0; ++} ++ ++static int dle_dfi_qempty(struct rtw89_dev *rtwdev, ++ struct rtw89_mac_dle_dfi_qempty *qempty) ++{ ++ struct rtw89_mac_dle_dfi_ctrl ctrl; ++ u32 ret; ++ ++ ctrl.type = qempty->dle_type; ++ ctrl.target = DLE_DFI_TYPE_QEMPTY; ++ ctrl.addr = qempty->grpsel; ++ ret = dle_dfi_ctrl(rtwdev, &ctrl); ++ if (ret) { ++ rtw89_warn(rtwdev, "[ERR]dle_dfi_ctrl %d\n", ret); ++ return ret; ++ } ++ ++ qempty->qempty = FIELD_GET(B_AX_DLE_QEMPTY_GRP, ctrl.out_data); ++ return 0; ++} ++ ++static void dump_err_status_dispatcher(struct rtw89_dev *rtwdev) ++{ ++ rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ALWAYS_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ALWAYS_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); ++ rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ALWAYS_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ALWAYS_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); ++ rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ALWAYS_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ALWAYS_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR)); ++} ++ ++static void rtw89_mac_dump_qta_lost(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_mac_dle_dfi_qempty qempty; ++ struct rtw89_mac_dle_dfi_quota quota; ++ struct rtw89_mac_dle_dfi_ctrl ctrl; ++ u32 val, not_empty, i; ++ int ret; ++ ++ qempty.dle_type = DLE_CTRL_TYPE_PLE; ++ qempty.grpsel = 0; ++ ret = dle_dfi_qempty(rtwdev, &qempty); ++ if (ret) ++ rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__); ++ else ++ rtw89_info(rtwdev, "DLE group0 empty: 0x%x\n", qempty.qempty); ++ ++ for (not_empty = ~qempty.qempty, i = 0; not_empty != 0; not_empty >>= 1, i++) { ++ if (!(not_empty & BIT(0))) ++ continue; ++ ctrl.type = DLE_CTRL_TYPE_PLE; ++ ctrl.target = DLE_DFI_TYPE_QLNKTBL; ++ ctrl.addr = (QLNKTBL_ADDR_INFO_SEL_0 ? QLNKTBL_ADDR_INFO_SEL : 0) | ++ FIELD_PREP(QLNKTBL_ADDR_TBL_IDX_MASK, i); ++ ret = dle_dfi_ctrl(rtwdev, &ctrl); ++ if (ret) ++ rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__); ++ else ++ rtw89_info(rtwdev, "qidx%d pktcnt = %ld\n", i, ++ FIELD_GET(QLNKTBL_DATA_SEL1_PKT_CNT_MASK, ++ ctrl.out_data)); ++ } ++ ++ quota.dle_type = DLE_CTRL_TYPE_PLE; ++ quota.qtaid = 6; ++ ret = dle_dfi_quota(rtwdev, "a); ++ if (ret) ++ rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__); ++ else ++ rtw89_info(rtwdev, "quota6 rsv/use: 0x%x/0x%x\n", ++ quota.rsv_pgnum, quota.use_pgnum); ++ ++ val = rtw89_read32(rtwdev, R_AX_PLE_QTA6_CFG); ++ rtw89_info(rtwdev, "[PLE][CMAC0_RX]min_pgnum=0x%lx\n", ++ FIELD_GET(B_AX_PLE_Q6_MIN_SIZE_MASK, val)); ++ rtw89_info(rtwdev, "[PLE][CMAC0_RX]max_pgnum=0x%lx\n", ++ FIELD_GET(B_AX_PLE_Q6_MAX_SIZE_MASK, val)); ++ ++ dump_err_status_dispatcher(rtwdev); ++} ++ ++static void rtw89_mac_dump_l0_to_l1(struct rtw89_dev *rtwdev, ++ enum mac_ax_err_info err) ++{ ++ u32 dbg, event; ++ ++ dbg = rtw89_read32(rtwdev, R_AX_SER_DBG_INFO); ++ event = FIELD_GET(B_AX_L0_TO_L1_EVENT_MASK, dbg); ++ ++ switch (event) { ++ case MAC_AX_L0_TO_L1_RX_QTA_LOST: ++ rtw89_info(rtwdev, "quota lost!\n"); ++ rtw89_mac_dump_qta_lost(rtwdev); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void rtw89_mac_dump_err_status(struct rtw89_dev *rtwdev, ++ enum mac_ax_err_info err) ++{ ++ u32 dmac_err, cmac_err; ++ ++ if (err != MAC_AX_ERR_L1_ERR_DMAC && ++ err != MAC_AX_ERR_L0_PROMOTE_TO_L1) ++ return; ++ ++ rtw89_info(rtwdev, "--->\nerr=0x%x\n", err); ++ rtw89_info(rtwdev, "R_AX_SER_DBG_INFO =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SER_DBG_INFO)); ++ ++ cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR); ++ rtw89_info(rtwdev, "R_AX_CMAC_ERR_ISR =0x%08x\n", cmac_err); ++ dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR); ++ rtw89_info(rtwdev, "R_AX_DMAC_ERR_ISR =0x%08x\n", dmac_err); ++ ++ if (dmac_err) { ++ rtw89_info(rtwdev, "R_AX_WDE_ERR_FLAG_CFG =0x%08x ", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG)); ++ rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_CFG =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG)); ++ } ++ ++ if (dmac_err & B_AX_WDRLS_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_WDRLS_ERR_IMR =0x%08x ", ++ rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_WDRLS_ERR_ISR =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR)); ++ } ++ ++ if (dmac_err & B_AX_WSEC_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_SEC_ERR_IMR_ISR =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_DEBUG)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D00 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D04 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D10 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D14 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D18 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D20 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D24 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D28 =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT)); ++ rtw89_info(rtwdev, "SEC_local_Register 0x9D2C =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT)); ++ } ++ ++ if (dmac_err & B_AX_MPDU_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_MPDU_TX_ERR_IMR =0x%08x ", ++ rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_MPDU_TX_ERR_ISR =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR)); ++ rtw89_info(rtwdev, "R_AX_MPDU_RX_ERR_IMR =0x%08x ", ++ rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_MPDU_RX_ERR_ISR =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR)); ++ } ++ ++ if (dmac_err & B_AX_STA_SCHEDULER_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_IMR =0x%08x ", ++ rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_ISR= 0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR)); ++ } ++ ++ if (dmac_err & B_AX_WDE_DLE_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_WDE_ERR_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_WDE_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); ++ rtw89_info(rtwdev, "R_AX_PLE_ERR_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); ++ dump_err_status_dispatcher(rtwdev); ++ } ++ ++ if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); ++ rtw89_info(rtwdev, "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1)); ++ } ++ ++ if (dmac_err & B_AX_PLE_DLE_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_WDE_ERR_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_WDE_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); ++ rtw89_info(rtwdev, "R_AX_PLE_ERR_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); ++ rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_0=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0)); ++ rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1)); ++ rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_2=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2)); ++ rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS)); ++ rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_0=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0)); ++ rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1)); ++ rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_2=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2)); ++ rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS)); ++ rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_0=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0)); ++ rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1)); ++ rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_2=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2)); ++ dump_err_status_dispatcher(rtwdev); ++ } ++ ++ if (dmac_err & B_AX_PKTIN_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_PKTIN_ERR_IMR =0x%08x ", ++ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_PKTIN_ERR_ISR =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); ++ rtw89_info(rtwdev, "R_AX_PKTIN_ERR_IMR =0x%08x ", ++ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_PKTIN_ERR_ISR =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); ++ } ++ ++ if (dmac_err & B_AX_DISPATCH_ERR_FLAG) ++ dump_err_status_dispatcher(rtwdev); ++ ++ if (dmac_err & B_AX_DLE_CPUIO_ERR_FLAG) { ++ rtw89_info(rtwdev, "R_AX_CPUIO_ERR_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_CPUIO_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_CPUIO_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_CPUIO_ERR_ISR)); ++ } ++ ++ if (dmac_err & BIT(11)) { ++ rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); ++ } ++ ++ if (cmac_err & B_AX_SCHEDULE_TOP_ERR_IND) { ++ rtw89_info(rtwdev, "R_AX_SCHEDULE_ERR_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR)); ++ rtw89_info(rtwdev, "R_AX_SCHEDULE_ERR_ISR=0x%04x\n", ++ rtw89_read16(rtwdev, R_AX_SCHEDULE_ERR_ISR)); ++ } ++ ++ if (cmac_err & B_AX_PTCL_TOP_ERR_IND) { ++ rtw89_info(rtwdev, "R_AX_PTCL_IMR0=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_PTCL_IMR0)); ++ rtw89_info(rtwdev, "R_AX_PTCL_ISR0=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PTCL_ISR0)); ++ } ++ ++ if (cmac_err & B_AX_DMA_TOP_ERR_IND) { ++ rtw89_info(rtwdev, "R_AX_DLE_CTRL=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_DLE_CTRL)); ++ } ++ ++ if (cmac_err & B_AX_PHYINTF_ERR_IND) { ++ rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR)); ++ } ++ ++ if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) { ++ rtw89_info(rtwdev, "R_AX_TXPWR_IMR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_TXPWR_IMR)); ++ rtw89_info(rtwdev, "R_AX_TXPWR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPWR_ISR)); ++ } ++ ++ if (cmac_err & B_AX_WMAC_RX_ERR_IND) { ++ rtw89_info(rtwdev, "R_AX_DBGSEL_TRXPTCL=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL)); ++ rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR)); ++ } ++ ++ if (cmac_err & B_AX_WMAC_TX_ERR_IND) { ++ rtw89_info(rtwdev, "R_AX_TMAC_ERR_IMR_ISR=0x%08x ", ++ rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR)); ++ rtw89_info(rtwdev, "R_AX_DBGSEL_TRXPTCL=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL)); ++ } ++ ++ rtwdev->hci.ops->dump_err_status(rtwdev); ++ ++ if (err == MAC_AX_ERR_L0_PROMOTE_TO_L1) ++ rtw89_mac_dump_l0_to_l1(rtwdev, err); ++ ++ rtw89_info(rtwdev, "<---\n"); ++} ++ ++u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev) ++{ ++ u32 err; ++ int ret; ++ ++ ret = read_poll_timeout(rtw89_read32, err, (err != 0), 1000, 100000, ++ false, rtwdev, R_AX_HALT_C2H_CTRL); ++ if (ret) { ++ rtw89_warn(rtwdev, "Polling FW err status fail\n"); ++ return ret; ++ } ++ ++ err = rtw89_read32(rtwdev, R_AX_HALT_C2H); ++ rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); ++ ++ rtw89_fw_st_dbg_dump(rtwdev); ++ rtw89_mac_dump_err_status(rtwdev, err); ++ ++ return err; ++} ++EXPORT_SYMBOL(rtw89_mac_get_err_status); ++ ++int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err) ++{ ++ u32 halt; ++ int ret = 0; ++ ++ if (err > MAC_AX_SET_ERR_MAX) { ++ rtw89_err(rtwdev, "Bad set-err-status value 0x%08x\n", err); ++ return -EINVAL; ++ } ++ ++ ret = read_poll_timeout(rtw89_read32, halt, (halt == 0x0), 1000, ++ 100000, false, rtwdev, R_AX_HALT_H2C_CTRL); ++ if (ret) { ++ rtw89_err(rtwdev, "FW doesn't receive previous msg\n"); ++ return -EFAULT; ++ } ++ ++ rtw89_write32(rtwdev, R_AX_HALT_H2C, err); ++ rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, B_AX_HALT_H2C_TRIGGER); ++ ++ return 0; ++} ++EXPORT_SYMBOL(rtw89_mac_set_err_status); ++ ++const struct rtw89_hfc_prec_cfg rtw_hfc_preccfg_pcie = { ++ 2, 40, 0, 0, 1, 0, 0, 0 ++}; ++ ++static int hfc_reset_param(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ struct rtw89_hfc_param_ini param_ini = {NULL}; ++ u8 qta_mode = rtwdev->mac.dle_info.qta_mode; ++ ++ switch (rtwdev->hci.type) { ++ case RTW89_HCI_TYPE_PCIE: ++ param_ini = rtwdev->chip->hfc_param_ini[qta_mode]; ++ param->en = 0; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ if (param_ini.pub_cfg) ++ param->pub_cfg = *param_ini.pub_cfg; ++ ++ if (param_ini.prec_cfg) { ++ param->prec_cfg = *param_ini.prec_cfg; ++ rtwdev->hal.sw_amsdu_max_size = ++ param->prec_cfg.wp_ch07_prec * HFC_PAGE_UNIT; ++ } ++ ++ if (param_ini.ch_cfg) ++ param->ch_cfg = param_ini.ch_cfg; ++ ++ memset(¶m->ch_info, 0, sizeof(param->ch_info)); ++ memset(¶m->pub_info, 0, sizeof(param->pub_info)); ++ param->mode = param_ini.mode; ++ ++ return 0; ++} ++ ++static int hfc_ch_cfg_chk(struct rtw89_dev *rtwdev, u8 ch) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ const struct rtw89_hfc_ch_cfg *ch_cfg = param->ch_cfg; ++ const struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; ++ const struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; ++ ++ if (ch >= RTW89_DMA_CH_NUM) ++ return -EINVAL; ++ ++ if ((ch_cfg[ch].min && ch_cfg[ch].min < prec_cfg->ch011_prec) || ++ ch_cfg[ch].max > pub_cfg->pub_max) ++ return -EINVAL; ++ if (ch_cfg[ch].grp >= grp_num) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int hfc_pub_info_chk(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ const struct rtw89_hfc_pub_cfg *cfg = ¶m->pub_cfg; ++ struct rtw89_hfc_pub_info *info = ¶m->pub_info; ++ ++ if (info->g0_used + info->g1_used + info->pub_aval != cfg->pub_max) { ++ if (rtwdev->chip->chip_id == RTL8852A) ++ return 0; ++ else ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++static int hfc_pub_cfg_chk(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ const struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; ++ ++ if (pub_cfg->grp0 + pub_cfg->grp1 != pub_cfg->pub_max) ++ return 0; ++ ++ return 0; ++} ++ ++static int hfc_ch_ctrl(struct rtw89_dev *rtwdev, u8 ch) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ const struct rtw89_hfc_ch_cfg *cfg = param->ch_cfg; ++ int ret = 0; ++ u32 val = 0; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ ret = hfc_ch_cfg_chk(rtwdev, ch); ++ if (ret) ++ return ret; ++ ++ if (ch > RTW89_DMA_B1HI) ++ return -EINVAL; ++ ++ val = u32_encode_bits(cfg[ch].min, B_AX_MIN_PG_MASK) | ++ u32_encode_bits(cfg[ch].max, B_AX_MAX_PG_MASK) | ++ (cfg[ch].grp ? B_AX_GRP : 0); ++ rtw89_write32(rtwdev, R_AX_ACH0_PAGE_CTRL + ch * 4, val); ++ ++ return 0; ++} ++ ++static int hfc_upd_ch_info(struct rtw89_dev *rtwdev, u8 ch) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ struct rtw89_hfc_ch_info *info = param->ch_info; ++ const struct rtw89_hfc_ch_cfg *cfg = param->ch_cfg; ++ u32 val; ++ u32 ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ if (ch > RTW89_DMA_H2C) ++ return -EINVAL; ++ ++ val = rtw89_read32(rtwdev, R_AX_ACH0_PAGE_INFO + ch * 4); ++ info[ch].aval = u32_get_bits(val, B_AX_AVAL_PG_MASK); ++ if (ch < RTW89_DMA_H2C) ++ info[ch].used = u32_get_bits(val, B_AX_USE_PG_MASK); ++ else ++ info[ch].used = cfg[ch].min - info[ch].aval; ++ ++ return 0; ++} ++ ++static int hfc_pub_ctrl(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_hfc_pub_cfg *cfg = &rtwdev->mac.hfc_param.pub_cfg; ++ u32 val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ ret = hfc_pub_cfg_chk(rtwdev); ++ if (ret) ++ return ret; ++ ++ val = u32_encode_bits(cfg->grp0, B_AX_PUBPG_G0_MASK) | ++ u32_encode_bits(cfg->grp1, B_AX_PUBPG_G1_MASK); ++ rtw89_write32(rtwdev, R_AX_PUB_PAGE_CTRL1, val); ++ ++ val = u32_encode_bits(cfg->wp_thrd, B_AX_WP_THRD_MASK); ++ rtw89_write32(rtwdev, R_AX_WP_PAGE_CTRL2, val); ++ ++ return 0; ++} ++ ++static int hfc_upd_mix_info(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; ++ struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; ++ struct rtw89_hfc_pub_info *info = ¶m->pub_info; ++ u32 val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ val = rtw89_read32(rtwdev, R_AX_PUB_PAGE_INFO1); ++ info->g0_used = u32_get_bits(val, B_AX_G0_USE_PG_MASK); ++ info->g1_used = u32_get_bits(val, B_AX_G1_USE_PG_MASK); ++ val = rtw89_read32(rtwdev, R_AX_PUB_PAGE_INFO3); ++ info->g0_aval = u32_get_bits(val, B_AX_G0_AVAL_PG_MASK); ++ info->g1_aval = u32_get_bits(val, B_AX_G1_AVAL_PG_MASK); ++ info->pub_aval = ++ u32_get_bits(rtw89_read32(rtwdev, R_AX_PUB_PAGE_INFO2), ++ B_AX_PUB_AVAL_PG_MASK); ++ info->wp_aval = ++ u32_get_bits(rtw89_read32(rtwdev, R_AX_WP_PAGE_INFO1), ++ B_AX_WP_AVAL_PG_MASK); ++ ++ val = rtw89_read32(rtwdev, R_AX_HCI_FC_CTRL); ++ param->en = val & B_AX_HCI_FC_EN ? 1 : 0; ++ param->h2c_en = val & B_AX_HCI_FC_CH12_EN ? 1 : 0; ++ param->mode = u32_get_bits(val, B_AX_HCI_FC_MODE_MASK); ++ prec_cfg->ch011_full_cond = ++ u32_get_bits(val, B_AX_HCI_FC_WD_FULL_COND_MASK); ++ prec_cfg->h2c_full_cond = ++ u32_get_bits(val, B_AX_HCI_FC_CH12_FULL_COND_MASK); ++ prec_cfg->wp_ch07_full_cond = ++ u32_get_bits(val, B_AX_HCI_FC_WP_CH07_FULL_COND_MASK); ++ prec_cfg->wp_ch811_full_cond = ++ u32_get_bits(val, B_AX_HCI_FC_WP_CH811_FULL_COND_MASK); ++ ++ val = rtw89_read32(rtwdev, R_AX_CH_PAGE_CTRL); ++ prec_cfg->ch011_prec = u32_get_bits(val, B_AX_PREC_PAGE_CH011_MASK); ++ prec_cfg->h2c_prec = u32_get_bits(val, B_AX_PREC_PAGE_CH12_MASK); ++ ++ val = rtw89_read32(rtwdev, R_AX_PUB_PAGE_CTRL2); ++ pub_cfg->pub_max = u32_get_bits(val, B_AX_PUBPG_ALL_MASK); ++ ++ val = rtw89_read32(rtwdev, R_AX_WP_PAGE_CTRL1); ++ prec_cfg->wp_ch07_prec = u32_get_bits(val, B_AX_PREC_PAGE_WP_CH07_MASK); ++ prec_cfg->wp_ch811_prec = u32_get_bits(val, B_AX_PREC_PAGE_WP_CH811_MASK); ++ ++ val = rtw89_read32(rtwdev, R_AX_WP_PAGE_CTRL2); ++ pub_cfg->wp_thrd = u32_get_bits(val, B_AX_WP_THRD_MASK); ++ ++ val = rtw89_read32(rtwdev, R_AX_PUB_PAGE_CTRL1); ++ pub_cfg->grp0 = u32_get_bits(val, B_AX_PUBPG_G0_MASK); ++ pub_cfg->grp1 = u32_get_bits(val, B_AX_PUBPG_G1_MASK); ++ ++ ret = hfc_pub_info_chk(rtwdev); ++ if (param->en && ret) ++ return ret; ++ ++ return 0; ++} ++ ++static void hfc_h2c_cfg(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ const struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; ++ u32 val; ++ ++ val = u32_encode_bits(prec_cfg->h2c_prec, B_AX_PREC_PAGE_CH12_MASK); ++ rtw89_write32(rtwdev, R_AX_CH_PAGE_CTRL, val); ++ ++ rtw89_write32_mask(rtwdev, R_AX_HCI_FC_CTRL, ++ B_AX_HCI_FC_CH12_FULL_COND_MASK, ++ prec_cfg->h2c_full_cond); ++} ++ ++static void hfc_mix_cfg(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ const struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; ++ const struct rtw89_hfc_prec_cfg *prec_cfg = ¶m->prec_cfg; ++ u32 val; ++ ++ val = u32_encode_bits(prec_cfg->ch011_prec, B_AX_PREC_PAGE_CH011_MASK) | ++ u32_encode_bits(prec_cfg->h2c_prec, B_AX_PREC_PAGE_CH12_MASK); ++ rtw89_write32(rtwdev, R_AX_CH_PAGE_CTRL, val); ++ ++ val = u32_encode_bits(pub_cfg->pub_max, B_AX_PUBPG_ALL_MASK); ++ rtw89_write32(rtwdev, R_AX_PUB_PAGE_CTRL2, val); ++ ++ val = u32_encode_bits(prec_cfg->wp_ch07_prec, ++ B_AX_PREC_PAGE_WP_CH07_MASK) | ++ u32_encode_bits(prec_cfg->wp_ch811_prec, ++ B_AX_PREC_PAGE_WP_CH811_MASK); ++ rtw89_write32(rtwdev, R_AX_WP_PAGE_CTRL1, val); ++ ++ val = u32_replace_bits(rtw89_read32(rtwdev, R_AX_HCI_FC_CTRL), ++ param->mode, B_AX_HCI_FC_MODE_MASK); ++ val = u32_replace_bits(val, prec_cfg->ch011_full_cond, ++ B_AX_HCI_FC_WD_FULL_COND_MASK); ++ val = u32_replace_bits(val, prec_cfg->h2c_full_cond, ++ B_AX_HCI_FC_CH12_FULL_COND_MASK); ++ val = u32_replace_bits(val, prec_cfg->wp_ch07_full_cond, ++ B_AX_HCI_FC_WP_CH07_FULL_COND_MASK); ++ val = u32_replace_bits(val, prec_cfg->wp_ch811_full_cond, ++ B_AX_HCI_FC_WP_CH811_FULL_COND_MASK); ++ rtw89_write32(rtwdev, R_AX_HCI_FC_CTRL, val); ++} ++ ++static void hfc_func_en(struct rtw89_dev *rtwdev, bool en, bool h2c_en) ++{ ++ struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param; ++ u32 val; ++ ++ val = rtw89_read32(rtwdev, R_AX_HCI_FC_CTRL); ++ param->en = en; ++ param->h2c_en = h2c_en; ++ val = en ? (val | B_AX_HCI_FC_EN) : (val & ~B_AX_HCI_FC_EN); ++ val = h2c_en ? (val | B_AX_HCI_FC_CH12_EN) : ++ (val & ~B_AX_HCI_FC_CH12_EN); ++ rtw89_write32(rtwdev, R_AX_HCI_FC_CTRL, val); ++} ++ ++static int hfc_init(struct rtw89_dev *rtwdev, bool reset, bool en, bool h2c_en) ++{ ++ u8 ch; ++ u32 ret = 0; ++ ++ if (reset) ++ ret = hfc_reset_param(rtwdev); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ hfc_func_en(rtwdev, false, false); ++ ++ if (!en && h2c_en) { ++ hfc_h2c_cfg(rtwdev); ++ hfc_func_en(rtwdev, en, h2c_en); ++ return ret; ++ } ++ ++ for (ch = RTW89_DMA_ACH0; ch < RTW89_DMA_H2C; ch++) { ++ ret = hfc_ch_ctrl(rtwdev, ch); ++ if (ret) ++ return ret; ++ } ++ ++ ret = hfc_pub_ctrl(rtwdev); ++ if (ret) ++ return ret; ++ ++ hfc_mix_cfg(rtwdev); ++ if (en || h2c_en) { ++ hfc_func_en(rtwdev, en, h2c_en); ++ udelay(10); ++ } ++ for (ch = RTW89_DMA_ACH0; ch < RTW89_DMA_H2C; ch++) { ++ ret = hfc_upd_ch_info(rtwdev, ch); ++ if (ret) ++ return ret; ++ } ++ ret = hfc_upd_mix_info(rtwdev); ++ ++ return ret; ++} ++ ++#define PWR_POLL_CNT 2000 ++static int pwr_cmd_poll(struct rtw89_dev *rtwdev, ++ const struct rtw89_pwr_cfg *cfg) ++{ ++ u8 val = 0; ++ int ret; ++ u32 addr = cfg->base == PWR_INTF_MSK_SDIO ? ++ cfg->addr | SDIO_LOCAL_BASE_ADDR : cfg->addr; ++ ++ ret = read_poll_timeout(rtw89_read8, val, !((val ^ cfg->val) & cfg->msk), ++ 1000, 1000 * PWR_POLL_CNT, false, rtwdev, addr); ++ ++ if (!ret) ++ return 0; ++ ++ rtw89_warn(rtwdev, "[ERR] Polling timeout\n"); ++ rtw89_warn(rtwdev, "[ERR] addr: %X, %X\n", addr, cfg->addr); ++ rtw89_warn(rtwdev, "[ERR] val: %X, %X\n", val, cfg->val); ++ ++ return -EBUSY; ++} ++ ++static int rtw89_mac_sub_pwr_seq(struct rtw89_dev *rtwdev, u8 cv_msk, ++ u8 intf_msk, const struct rtw89_pwr_cfg *cfg) ++{ ++ const struct rtw89_pwr_cfg *cur_cfg; ++ u32 addr; ++ u8 val; ++ ++ for (cur_cfg = cfg; cur_cfg->cmd != PWR_CMD_END; cur_cfg++) { ++ if (!(cur_cfg->intf_msk & intf_msk) || ++ !(cur_cfg->cv_msk & cv_msk)) ++ continue; ++ ++ switch (cur_cfg->cmd) { ++ case PWR_CMD_WRITE: ++ addr = cur_cfg->addr; ++ ++ if (cur_cfg->base == PWR_BASE_SDIO) ++ addr |= SDIO_LOCAL_BASE_ADDR; ++ ++ val = rtw89_read8(rtwdev, addr); ++ val &= ~(cur_cfg->msk); ++ val |= (cur_cfg->val & cur_cfg->msk); ++ ++ rtw89_write8(rtwdev, addr, val); ++ break; ++ case PWR_CMD_POLL: ++ if (pwr_cmd_poll(rtwdev, cur_cfg)) ++ return -EBUSY; ++ break; ++ case PWR_CMD_DELAY: ++ if (cur_cfg->val == PWR_DELAY_US) ++ udelay(cur_cfg->addr); ++ else ++ fsleep(cur_cfg->addr * 1000); ++ break; ++ default: ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ ++static int rtw89_mac_pwr_seq(struct rtw89_dev *rtwdev, ++ const struct rtw89_pwr_cfg * const *cfg_seq) ++{ ++ int ret; ++ ++ for (; *cfg_seq; cfg_seq++) { ++ ret = rtw89_mac_sub_pwr_seq(rtwdev, BIT(rtwdev->hal.cv), ++ PWR_INTF_MSK_PCIE, *cfg_seq); ++ if (ret) ++ return -EBUSY; ++ } ++ ++ return 0; ++} ++ ++static enum rtw89_rpwm_req_pwr_state ++rtw89_mac_get_req_pwr_state(struct rtw89_dev *rtwdev) ++{ ++ enum rtw89_rpwm_req_pwr_state state; ++ ++ switch (rtwdev->ps_mode) { ++ case RTW89_PS_MODE_RFOFF: ++ state = RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFOFF; ++ break; ++ case RTW89_PS_MODE_CLK_GATED: ++ state = RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED; ++ break; ++ case RTW89_PS_MODE_PWR_GATED: ++ state = RTW89_MAC_RPWM_REQ_PWR_STATE_PWR_GATED; ++ break; ++ default: ++ state = RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE; ++ break; ++ } ++ return state; ++} ++ ++static void rtw89_mac_send_rpwm(struct rtw89_dev *rtwdev, ++ enum rtw89_rpwm_req_pwr_state req_pwr_state) ++{ ++ u16 request; ++ ++ request = rtw89_read16(rtwdev, R_AX_RPWM); ++ request ^= request | PS_RPWM_TOGGLE; ++ ++ rtwdev->mac.rpwm_seq_num = (rtwdev->mac.rpwm_seq_num + 1) & ++ RPWM_SEQ_NUM_MAX; ++ request |= FIELD_PREP(PS_RPWM_SEQ_NUM, rtwdev->mac.rpwm_seq_num); ++ ++ request |= req_pwr_state; ++ ++ if (req_pwr_state < RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED) ++ request |= PS_RPWM_ACK; ++ ++ rtw89_write16(rtwdev, rtwdev->hci.rpwm_addr, request); ++} ++ ++static int rtw89_mac_check_cpwm_state(struct rtw89_dev *rtwdev, ++ enum rtw89_rpwm_req_pwr_state req_pwr_state) ++{ ++ bool request_deep_mode; ++ bool in_deep_mode; ++ u8 rpwm_req_num; ++ u8 cpwm_rsp_seq; ++ u8 cpwm_seq; ++ u8 cpwm_status; ++ ++ if (req_pwr_state >= RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED) ++ request_deep_mode = true; ++ else ++ request_deep_mode = false; ++ ++ if (rtw89_read32_mask(rtwdev, R_AX_LDM, B_AX_EN_32K)) ++ in_deep_mode = true; ++ else ++ in_deep_mode = false; ++ ++ if (request_deep_mode != in_deep_mode) ++ return -EPERM; ++ ++ if (request_deep_mode) ++ return 0; ++ ++ rpwm_req_num = rtwdev->mac.rpwm_seq_num; ++ cpwm_rsp_seq = rtw89_read16_mask(rtwdev, R_AX_CPWM, ++ PS_CPWM_RSP_SEQ_NUM); ++ ++ if (rpwm_req_num != cpwm_rsp_seq) ++ return -EPERM; ++ ++ rtwdev->mac.cpwm_seq_num = (rtwdev->mac.cpwm_seq_num + 1) & ++ CPWM_SEQ_NUM_MAX; ++ ++ cpwm_seq = rtw89_read16_mask(rtwdev, R_AX_CPWM, PS_CPWM_SEQ_NUM); ++ if (cpwm_seq != rtwdev->mac.cpwm_seq_num) ++ return -EPERM; ++ ++ cpwm_status = rtw89_read16_mask(rtwdev, R_AX_CPWM, PS_CPWM_STATE); ++ if (cpwm_status != req_pwr_state) ++ return -EPERM; ++ ++ return 0; ++} ++ ++void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter) ++{ ++ enum rtw89_rpwm_req_pwr_state state; ++ int ret; ++ ++ if (enter) ++ state = rtw89_mac_get_req_pwr_state(rtwdev); ++ else ++ state = RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE; ++ ++ rtw89_mac_send_rpwm(rtwdev, state); ++ ret = read_poll_timeout_atomic(rtw89_mac_check_cpwm_state, ret, !ret, ++ 1000, 15000, false, rtwdev, state); ++ if (ret) ++ rtw89_err(rtwdev, "firmware failed to ack for %s ps mode\n", ++ enter ? "entering" : "leaving"); ++} ++ ++static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on) ++{ ++#define PWR_ACT 1 ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ const struct rtw89_pwr_cfg * const *cfg_seq; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ int ret; ++ u8 val; ++ ++ if (on) ++ cfg_seq = chip->pwr_on_seq; ++ else ++ cfg_seq = chip->pwr_off_seq; ++ ++ if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) ++ __rtw89_leave_ps_mode(rtwdev); ++ ++ val = rtw89_read32_mask(rtwdev, R_AX_IC_PWR_STATE, B_AX_WLMAC_PWR_STE_MASK); ++ if (on && val == PWR_ACT) { ++ rtw89_err(rtwdev, "MAC has already powered on\n"); ++ return -EBUSY; ++ } ++ ++ ret = rtw89_mac_pwr_seq(rtwdev, cfg_seq); ++ if (ret) ++ return ret; ++ ++ if (on) { ++ set_bit(RTW89_FLAG_POWERON, rtwdev->flags); ++ rtw89_write8(rtwdev, R_AX_SCOREBOARD + 3, MAC_AX_NOTIFY_TP_MAJOR); ++ } else { ++ clear_bit(RTW89_FLAG_POWERON, rtwdev->flags); ++ clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); ++ rtw89_write8(rtwdev, R_AX_SCOREBOARD + 3, MAC_AX_NOTIFY_PWR_MAJOR); ++ hal->current_channel = 0; ++ } ++ ++ return 0; ++#undef PWR_ACT ++} ++ ++void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev) ++{ ++ rtw89_mac_power_switch(rtwdev, false); ++} ++ ++static int cmac_func_en(struct rtw89_dev *rtwdev, u8 mac_idx, bool en) ++{ ++ u32 func_en = 0; ++ u32 ck_en = 0; ++ u32 c1pc_en = 0; ++ u32 addrl_func_en[] = {R_AX_CMAC_FUNC_EN, R_AX_CMAC_FUNC_EN_C1}; ++ u32 addrl_ck_en[] = {R_AX_CK_EN, R_AX_CK_EN_C1}; ++ ++ func_en = B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN | ++ B_AX_PHYINTF_EN | B_AX_CMAC_DMA_EN | B_AX_PTCLTOP_EN | ++ B_AX_SCHEDULER_EN | B_AX_TMAC_EN | B_AX_RMAC_EN; ++ ck_en = B_AX_CMAC_CKEN | B_AX_PHYINTF_CKEN | B_AX_CMAC_DMA_CKEN | ++ B_AX_PTCLTOP_CKEN | B_AX_SCHEDULER_CKEN | B_AX_TMAC_CKEN | ++ B_AX_RMAC_CKEN; ++ c1pc_en = B_AX_R_SYM_WLCMAC1_PC_EN | ++ B_AX_R_SYM_WLCMAC1_P1_PC_EN | ++ B_AX_R_SYM_WLCMAC1_P2_PC_EN | ++ B_AX_R_SYM_WLCMAC1_P3_PC_EN | ++ B_AX_R_SYM_WLCMAC1_P4_PC_EN; ++ ++ if (en) { ++ if (mac_idx == RTW89_MAC_1) { ++ rtw89_write32_set(rtwdev, R_AX_AFE_CTRL1, c1pc_en); ++ rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, ++ B_AX_R_SYM_ISO_CMAC12PP); ++ rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, ++ B_AX_CMAC1_FEN); ++ } ++ rtw89_write32_set(rtwdev, addrl_ck_en[mac_idx], ck_en); ++ rtw89_write32_set(rtwdev, addrl_func_en[mac_idx], func_en); ++ } else { ++ rtw89_write32_clr(rtwdev, addrl_func_en[mac_idx], func_en); ++ rtw89_write32_clr(rtwdev, addrl_ck_en[mac_idx], ck_en); ++ if (mac_idx == RTW89_MAC_1) { ++ rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, ++ B_AX_CMAC1_FEN); ++ rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, ++ B_AX_R_SYM_ISO_CMAC12PP); ++ rtw89_write32_clr(rtwdev, R_AX_AFE_CTRL1, c1pc_en); ++ } ++ } ++ ++ return 0; ++} ++ ++static int dmac_func_en(struct rtw89_dev *rtwdev) ++{ ++ u32 val32; ++ u32 ret = 0; ++ ++ val32 = (B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MAC_SEC_EN | ++ B_AX_DISPATCHER_EN | B_AX_DLE_CPUIO_EN | B_AX_PKT_IN_EN | ++ B_AX_DMAC_TBL_EN | B_AX_PKT_BUF_EN | B_AX_STA_SCH_EN | ++ B_AX_TXPKT_CTRL_EN | B_AX_WD_RLS_EN | B_AX_MPDU_PROC_EN); ++ rtw89_write32(rtwdev, R_AX_DMAC_FUNC_EN, val32); ++ ++ val32 = (B_AX_MAC_SEC_CLK_EN | B_AX_DISPATCHER_CLK_EN | ++ B_AX_DLE_CPUIO_CLK_EN | B_AX_PKT_IN_CLK_EN | ++ B_AX_STA_SCH_CLK_EN | B_AX_TXPKT_CTRL_CLK_EN | ++ B_AX_WD_RLS_CLK_EN); ++ rtw89_write32(rtwdev, R_AX_DMAC_CLK_EN, val32); ++ ++ return ret; ++} ++ ++static int chip_func_en(struct rtw89_dev *rtwdev) ++{ ++ rtw89_write32_set(rtwdev, R_AX_SPSLDO_ON_CTRL0, B_AX_OCP_L1_MASK); ++ ++ return 0; ++} ++ ++static int rtw89_mac_sys_init(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ ret = dmac_func_en(rtwdev); ++ if (ret) ++ return ret; ++ ++ ret = cmac_func_en(rtwdev, 0, true); ++ if (ret) ++ return ret; ++ ++ ret = chip_func_en(rtwdev); ++ if (ret) ++ return ret; ++ ++ return ret; ++} ++ ++/* PCIE 64 */ ++const struct rtw89_dle_size wde_size0 = { ++ RTW89_WDE_PG_64, 4095, 1, ++}; ++ ++/* DLFW */ ++const struct rtw89_dle_size wde_size4 = { ++ RTW89_WDE_PG_64, 0, 4096, ++}; ++ ++/* PCIE */ ++const struct rtw89_dle_size ple_size0 = { ++ RTW89_PLE_PG_128, 1520, 16, ++}; ++ ++/* DLFW */ ++const struct rtw89_dle_size ple_size4 = { ++ RTW89_PLE_PG_128, 64, 1472, ++}; ++ ++/* PCIE 64 */ ++const struct rtw89_wde_quota wde_qt0 = { ++ 3792, 196, 0, 107, ++}; ++ ++/* DLFW */ ++const struct rtw89_wde_quota wde_qt4 = { ++ 0, 0, 0, 0, ++}; ++ ++/* PCIE SCC */ ++const struct rtw89_ple_quota ple_qt4 = { ++ 264, 0, 16, 20, 26, 13, 356, 0, 32, 40, 8, ++}; ++ ++/* PCIE SCC */ ++const struct rtw89_ple_quota ple_qt5 = { ++ 264, 0, 32, 20, 64, 13, 1101, 0, 64, 128, 120, ++}; ++ ++/* DLFW */ ++const struct rtw89_ple_quota ple_qt13 = { ++ 0, 0, 16, 48, 0, 0, 0, 0, 0, 0, 0 ++}; ++ ++static const struct rtw89_dle_mem *get_dle_mem_cfg(struct rtw89_dev *rtwdev, ++ enum rtw89_qta_mode mode) ++{ ++ struct rtw89_mac_info *mac = &rtwdev->mac; ++ const struct rtw89_dle_mem *cfg; ++ ++ cfg = &rtwdev->chip->dle_mem[mode]; ++ if (!cfg) ++ return NULL; ++ ++ if (cfg->mode != mode) { ++ rtw89_warn(rtwdev, "qta mode unmatch!\n"); ++ return NULL; ++ } ++ ++ mac->dle_info.wde_pg_size = cfg->wde_size->pge_size; ++ mac->dle_info.ple_pg_size = cfg->ple_size->pge_size; ++ mac->dle_info.qta_mode = mode; ++ mac->dle_info.c0_rx_qta = cfg->ple_min_qt->cma0_dma; ++ mac->dle_info.c1_rx_qta = cfg->ple_min_qt->cma1_dma; ++ ++ return cfg; ++} ++ ++static inline u32 dle_used_size(const struct rtw89_dle_size *wde, ++ const struct rtw89_dle_size *ple) ++{ ++ return wde->pge_size * (wde->lnk_pge_num + wde->unlnk_pge_num) + ++ ple->pge_size * (ple->lnk_pge_num + ple->unlnk_pge_num); ++} ++ ++static void dle_func_en(struct rtw89_dev *rtwdev, bool enable) ++{ ++ if (enable) ++ rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN, ++ B_AX_DLE_WDE_EN | B_AX_DLE_PLE_EN); ++ else ++ rtw89_write32_clr(rtwdev, R_AX_DMAC_FUNC_EN, ++ B_AX_DLE_WDE_EN | B_AX_DLE_PLE_EN); ++} ++ ++static void dle_clk_en(struct rtw89_dev *rtwdev, bool enable) ++{ ++ if (enable) ++ rtw89_write32_set(rtwdev, R_AX_DMAC_CLK_EN, ++ B_AX_DLE_WDE_CLK_EN | B_AX_DLE_PLE_CLK_EN); ++ else ++ rtw89_write32_clr(rtwdev, R_AX_DMAC_CLK_EN, ++ B_AX_DLE_WDE_CLK_EN | B_AX_DLE_PLE_CLK_EN); ++} ++ ++static int dle_mix_cfg(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg) ++{ ++ const struct rtw89_dle_size *size_cfg; ++ u32 val; ++ u8 bound = 0; ++ ++ val = rtw89_read32(rtwdev, R_AX_WDE_PKTBUF_CFG); ++ size_cfg = cfg->wde_size; ++ ++ switch (size_cfg->pge_size) { ++ default: ++ case RTW89_WDE_PG_64: ++ val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_64, ++ B_AX_WDE_PAGE_SEL_MASK); ++ break; ++ case RTW89_WDE_PG_128: ++ val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_128, ++ B_AX_WDE_PAGE_SEL_MASK); ++ break; ++ case RTW89_WDE_PG_256: ++ rtw89_err(rtwdev, "[ERR]WDE DLE doesn't support 256 byte!\n"); ++ return -EINVAL; ++ } ++ ++ val = u32_replace_bits(val, bound, B_AX_WDE_START_BOUND_MASK); ++ val = u32_replace_bits(val, size_cfg->lnk_pge_num, ++ B_AX_WDE_FREE_PAGE_NUM_MASK); ++ rtw89_write32(rtwdev, R_AX_WDE_PKTBUF_CFG, val); ++ ++ val = rtw89_read32(rtwdev, R_AX_PLE_PKTBUF_CFG); ++ bound = (size_cfg->lnk_pge_num + size_cfg->unlnk_pge_num) ++ * size_cfg->pge_size / DLE_BOUND_UNIT; ++ size_cfg = cfg->ple_size; ++ ++ switch (size_cfg->pge_size) { ++ default: ++ case RTW89_PLE_PG_64: ++ rtw89_err(rtwdev, "[ERR]PLE DLE doesn't support 64 byte!\n"); ++ return -EINVAL; ++ case RTW89_PLE_PG_128: ++ val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_128, ++ B_AX_PLE_PAGE_SEL_MASK); ++ break; ++ case RTW89_PLE_PG_256: ++ val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_256, ++ B_AX_PLE_PAGE_SEL_MASK); ++ break; ++ } ++ ++ val = u32_replace_bits(val, bound, B_AX_PLE_START_BOUND_MASK); ++ val = u32_replace_bits(val, size_cfg->lnk_pge_num, ++ B_AX_PLE_FREE_PAGE_NUM_MASK); ++ rtw89_write32(rtwdev, R_AX_PLE_PKTBUF_CFG, val); ++ ++ return 0; ++} ++ ++#define INVALID_QT_WCPU U16_MAX ++#define SET_QUOTA_VAL(_min_x, _max_x, _module, _idx) \ ++ do { \ ++ val = ((_min_x) & \ ++ B_AX_ ## _module ## _MIN_SIZE_MASK) | \ ++ (((_max_x) << 16) & \ ++ B_AX_ ## _module ## _MAX_SIZE_MASK); \ ++ rtw89_write32(rtwdev, \ ++ R_AX_ ## _module ## _QTA ## _idx ## _CFG, \ ++ val); \ ++ } while (0) ++#define SET_QUOTA(_x, _module, _idx) \ ++ SET_QUOTA_VAL(min_cfg->_x, max_cfg->_x, _module, _idx) ++ ++static void wde_quota_cfg(struct rtw89_dev *rtwdev, ++ const struct rtw89_wde_quota *min_cfg, ++ const struct rtw89_wde_quota *max_cfg, ++ u16 ext_wde_min_qt_wcpu) ++{ ++ u16 min_qt_wcpu = ext_wde_min_qt_wcpu != INVALID_QT_WCPU ? ++ ext_wde_min_qt_wcpu : min_cfg->wcpu; ++ u32 val; ++ ++ SET_QUOTA(hif, WDE, 0); ++ SET_QUOTA_VAL(min_qt_wcpu, max_cfg->wcpu, WDE, 1); ++ SET_QUOTA(pkt_in, WDE, 3); ++ SET_QUOTA(cpu_io, WDE, 4); ++} ++ ++static void ple_quota_cfg(struct rtw89_dev *rtwdev, ++ const struct rtw89_ple_quota *min_cfg, ++ const struct rtw89_ple_quota *max_cfg) ++{ ++ u32 val; ++ ++ SET_QUOTA(cma0_tx, PLE, 0); ++ SET_QUOTA(cma1_tx, PLE, 1); ++ SET_QUOTA(c2h, PLE, 2); ++ SET_QUOTA(h2c, PLE, 3); ++ SET_QUOTA(wcpu, PLE, 4); ++ SET_QUOTA(mpdu_proc, PLE, 5); ++ SET_QUOTA(cma0_dma, PLE, 6); ++ SET_QUOTA(cma1_dma, PLE, 7); ++ SET_QUOTA(bb_rpt, PLE, 8); ++ SET_QUOTA(wd_rel, PLE, 9); ++ SET_QUOTA(cpu_io, PLE, 10); ++} ++ ++#undef SET_QUOTA ++ ++static void dle_quota_cfg(struct rtw89_dev *rtwdev, ++ const struct rtw89_dle_mem *cfg, ++ u16 ext_wde_min_qt_wcpu) ++{ ++ wde_quota_cfg(rtwdev, cfg->wde_min_qt, cfg->wde_max_qt, ext_wde_min_qt_wcpu); ++ ple_quota_cfg(rtwdev, cfg->ple_min_qt, cfg->ple_max_qt); ++} ++ ++static int dle_init(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode, ++ enum rtw89_qta_mode ext_mode) ++{ ++ const struct rtw89_dle_mem *cfg, *ext_cfg; ++ u16 ext_wde_min_qt_wcpu = INVALID_QT_WCPU; ++ int ret = 0; ++ u32 ini; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ cfg = get_dle_mem_cfg(rtwdev, mode); ++ if (!cfg) { ++ rtw89_err(rtwdev, "[ERR]get_dle_mem_cfg\n"); ++ ret = -EINVAL; ++ goto error; ++ } ++ ++ if (mode == RTW89_QTA_DLFW) { ++ ext_cfg = get_dle_mem_cfg(rtwdev, ext_mode); ++ if (!ext_cfg) { ++ rtw89_err(rtwdev, "[ERR]get_dle_ext_mem_cfg %d\n", ++ ext_mode); ++ ret = -EINVAL; ++ goto error; ++ } ++ ext_wde_min_qt_wcpu = ext_cfg->wde_min_qt->wcpu; ++ } ++ ++ if (dle_used_size(cfg->wde_size, cfg->ple_size) != rtwdev->chip->fifo_size) { ++ rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n"); ++ ret = -EINVAL; ++ goto error; ++ } ++ ++ dle_func_en(rtwdev, false); ++ dle_clk_en(rtwdev, true); ++ ++ ret = dle_mix_cfg(rtwdev, cfg); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] dle mix cfg\n"); ++ goto error; ++ } ++ dle_quota_cfg(rtwdev, cfg, ext_wde_min_qt_wcpu); ++ ++ dle_func_en(rtwdev, true); ++ ++ ret = read_poll_timeout(rtw89_read32, ini, ++ (ini & WDE_MGN_INI_RDY) == WDE_MGN_INI_RDY, 1, ++ 2000, false, rtwdev, R_AX_WDE_INI_STATUS); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]WDE cfg ready\n"); ++ return ret; ++ } ++ ++ ret = read_poll_timeout(rtw89_read32, ini, ++ (ini & WDE_MGN_INI_RDY) == WDE_MGN_INI_RDY, 1, ++ 2000, false, rtwdev, R_AX_PLE_INI_STATUS); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]PLE cfg ready\n"); ++ return ret; ++ } ++ ++ return 0; ++error: ++ dle_func_en(rtwdev, false); ++ rtw89_err(rtwdev, "[ERR]trxcfg wde 0x8900 = %x\n", ++ rtw89_read32(rtwdev, R_AX_WDE_INI_STATUS)); ++ rtw89_err(rtwdev, "[ERR]trxcfg ple 0x8D00 = %x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_INI_STATUS)); ++ ++ return ret; ++} ++ ++static bool dle_is_txq_empty(struct rtw89_dev *rtwdev) ++{ ++ u32 msk32; ++ u32 val32; ++ ++ msk32 = B_AX_WDE_EMPTY_QUE_CMAC0_ALL_AC | B_AX_WDE_EMPTY_QUE_CMAC0_MBH | ++ B_AX_WDE_EMPTY_QUE_CMAC1_MBH | B_AX_WDE_EMPTY_QUE_CMAC0_WMM0 | ++ B_AX_WDE_EMPTY_QUE_CMAC0_WMM1 | B_AX_WDE_EMPTY_QUE_OTHERS | ++ B_AX_PLE_EMPTY_QUE_DMAC_MPDU_TX | B_AX_PLE_EMPTY_QTA_DMAC_H2C | ++ B_AX_PLE_EMPTY_QUE_DMAC_SEC_TX | B_AX_WDE_EMPTY_QUE_DMAC_PKTIN | ++ B_AX_WDE_EMPTY_QTA_DMAC_HIF | B_AX_WDE_EMPTY_QTA_DMAC_WLAN_CPU | ++ B_AX_WDE_EMPTY_QTA_DMAC_PKTIN | B_AX_WDE_EMPTY_QTA_DMAC_CPUIO | ++ B_AX_PLE_EMPTY_QTA_DMAC_B0_TXPL | ++ B_AX_PLE_EMPTY_QTA_DMAC_B1_TXPL | ++ B_AX_PLE_EMPTY_QTA_DMAC_MPDU_TX | ++ B_AX_PLE_EMPTY_QTA_DMAC_CPUIO | ++ B_AX_WDE_EMPTY_QTA_DMAC_DATA_CPU | ++ B_AX_PLE_EMPTY_QTA_DMAC_WLAN_CPU; ++ val32 = rtw89_read32(rtwdev, R_AX_DLE_EMPTY0); ++ ++ if ((val32 & msk32) == msk32) ++ return true; ++ ++ return false; ++} ++ ++static int sta_sch_init(struct rtw89_dev *rtwdev) ++{ ++ u32 p_val; ++ u8 val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ val = rtw89_read8(rtwdev, R_AX_SS_CTRL); ++ val |= B_AX_SS_EN; ++ rtw89_write8(rtwdev, R_AX_SS_CTRL, val); ++ ++ ret = read_poll_timeout(rtw89_read32, p_val, p_val & B_AX_SS_INIT_DONE_1, ++ 1, TRXCFG_WAIT_CNT, false, rtwdev, R_AX_SS_CTRL); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]STA scheduler init\n"); ++ return ret; ++ } ++ ++ rtw89_write32_set(rtwdev, R_AX_SS_CTRL, B_AX_SS_WARM_INIT_FLG); ++ ++ return 0; ++} ++ ++static int mpdu_proc_init(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ rtw89_write32(rtwdev, R_AX_ACTION_FWD0, TRXCFG_MPDU_PROC_ACT_FRWD); ++ rtw89_write32(rtwdev, R_AX_TF_FWD, TRXCFG_MPDU_PROC_TF_FRWD); ++ rtw89_write32_set(rtwdev, R_AX_MPDU_PROC, ++ B_AX_APPEND_FCS | B_AX_A_ICV_ERR); ++ rtw89_write32(rtwdev, R_AX_CUT_AMSDU_CTRL, TRXCFG_MPDU_PROC_CUT_CTRL); ++ ++ return 0; ++} ++ ++static int sec_eng_init(struct rtw89_dev *rtwdev) ++{ ++ u32 val = 0; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) ++ return ret; ++ ++ val = rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL); ++ /* init clock */ ++ val |= (B_AX_CLK_EN_CGCMP | B_AX_CLK_EN_WAPI | B_AX_CLK_EN_WEP_TKIP); ++ /* init TX encryption */ ++ val |= (B_AX_SEC_TX_ENC | B_AX_SEC_RX_DEC); ++ val |= (B_AX_MC_DEC | B_AX_BC_DEC); ++ val &= ~B_AX_TX_PARTIAL_MODE; ++ rtw89_write32(rtwdev, R_AX_SEC_ENG_CTRL, val); ++ ++ /* init MIC ICV append */ ++ val = rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC); ++ val |= (B_AX_APPEND_ICV | B_AX_APPEND_MIC); ++ ++ /* option init */ ++ rtw89_write32(rtwdev, R_AX_SEC_MPDU_PROC, val); ++ ++ return 0; ++} ++ ++static int dmac_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ int ret; ++ ++ ret = dle_init(rtwdev, rtwdev->mac.qta_mode, RTW89_QTA_INVALID); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]DLE init %d\n", ret); ++ return ret; ++ } ++ ++ ret = hfc_init(rtwdev, true, true, true); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]HCI FC init %d\n", ret); ++ return ret; ++ } ++ ++ ret = sta_sch_init(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]STA SCH init %d\n", ret); ++ return ret; ++ } ++ ++ ret = mpdu_proc_init(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]MPDU Proc init %d\n", ret); ++ return ret; ++ } ++ ++ ret = sec_eng_init(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]Security Engine init %d\n", ret); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++static int addr_cam_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 val, reg; ++ u16 p_val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_ADDR_CAM_CTRL, mac_idx); ++ ++ val = rtw89_read32(rtwdev, reg); ++ val |= u32_encode_bits(0x7f, B_AX_ADDR_CAM_RANGE_MASK) | ++ B_AX_ADDR_CAM_CLR | B_AX_ADDR_CAM_EN; ++ rtw89_write32(rtwdev, reg, val); ++ ++ ret = read_poll_timeout(rtw89_read16, p_val, !(p_val & B_AX_ADDR_CAM_CLR), ++ 1, TRXCFG_WAIT_CNT, false, rtwdev, B_AX_ADDR_CAM_CLR); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]ADDR_CAM reset\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int scheduler_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 ret; ++ u32 reg; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_PREBKF_CFG_0, mac_idx); ++ rtw89_write32_mask(rtwdev, reg, B_AX_PREBKF_TIME_MASK, SCH_PREBKF_24US); ++ ++ return 0; ++} ++ ++static int rtw89_mac_typ_fltr_opt(struct rtw89_dev *rtwdev, ++ enum rtw89_machdr_frame_type type, ++ enum rtw89_mac_fwd_target fwd_target, ++ u8 mac_idx) ++{ ++ u32 reg; ++ u32 val; ++ ++ switch (fwd_target) { ++ case RTW89_FWD_DONT_CARE: ++ val = RX_FLTR_FRAME_DROP; ++ break; ++ case RTW89_FWD_TO_HOST: ++ val = RX_FLTR_FRAME_TO_HOST; ++ break; ++ case RTW89_FWD_TO_WLAN_CPU: ++ val = RX_FLTR_FRAME_TO_WLCPU; ++ break; ++ default: ++ rtw89_err(rtwdev, "[ERR]set rx filter fwd target err\n"); ++ return -EINVAL; ++ } ++ ++ switch (type) { ++ case RTW89_MGNT: ++ reg = rtw89_mac_reg_by_idx(R_AX_MGNT_FLTR, mac_idx); ++ break; ++ case RTW89_CTRL: ++ reg = rtw89_mac_reg_by_idx(R_AX_CTRL_FLTR, mac_idx); ++ break; ++ case RTW89_DATA: ++ reg = rtw89_mac_reg_by_idx(R_AX_DATA_FLTR, mac_idx); ++ break; ++ default: ++ rtw89_err(rtwdev, "[ERR]set rx filter type err\n"); ++ return -EINVAL; ++ } ++ rtw89_write32(rtwdev, reg, val); ++ ++ return 0; ++} ++ ++static int rx_fltr_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ int ret, i; ++ u32 mac_ftlr, plcp_ftlr; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ for (i = RTW89_MGNT; i <= RTW89_DATA; i++) { ++ ret = rtw89_mac_typ_fltr_opt(rtwdev, i, RTW89_FWD_TO_HOST, ++ mac_idx); ++ if (ret) ++ return ret; ++ } ++ mac_ftlr = rtwdev->hal.rx_fltr; ++ plcp_ftlr = B_AX_CCK_CRC_CHK | B_AX_CCK_SIG_CHK | ++ B_AX_LSIG_PARITY_CHK_EN | B_AX_SIGA_CRC_CHK | ++ B_AX_VHT_SU_SIGB_CRC_CHK | B_AX_VHT_MU_SIGB_CRC_CHK | ++ B_AX_HE_SIGB_CRC_CHK; ++ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, mac_idx), ++ mac_ftlr); ++ rtw89_write16(rtwdev, rtw89_mac_reg_by_idx(R_AX_PLCP_HDR_FLTR, mac_idx), ++ plcp_ftlr); ++ ++ return 0; ++} ++ ++static void _patch_dis_resp_chk(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 reg, val32; ++ u32 b_rsp_chk_nav, b_rsp_chk_cca; ++ ++ b_rsp_chk_nav = B_AX_RSP_CHK_TXNAV | B_AX_RSP_CHK_INTRA_NAV | ++ B_AX_RSP_CHK_BASIC_NAV; ++ b_rsp_chk_cca = B_AX_RSP_CHK_SEC_CCA_80 | B_AX_RSP_CHK_SEC_CCA_40 | ++ B_AX_RSP_CHK_SEC_CCA_20 | B_AX_RSP_CHK_BTCCA | ++ B_AX_RSP_CHK_EDCCA | B_AX_RSP_CHK_CCA; ++ ++ switch (rtwdev->chip->chip_id) { ++ case RTL8852A: ++ case RTL8852B: ++ reg = rtw89_mac_reg_by_idx(R_AX_RSP_CHK_SIG, mac_idx); ++ val32 = rtw89_read32(rtwdev, reg) & ~b_rsp_chk_nav; ++ rtw89_write32(rtwdev, reg, val32); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_0, mac_idx); ++ val32 = rtw89_read32(rtwdev, reg) & ~b_rsp_chk_cca; ++ rtw89_write32(rtwdev, reg, val32); ++ break; ++ default: ++ reg = rtw89_mac_reg_by_idx(R_AX_RSP_CHK_SIG, mac_idx); ++ val32 = rtw89_read32(rtwdev, reg) | b_rsp_chk_nav; ++ rtw89_write32(rtwdev, reg, val32); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_0, mac_idx); ++ val32 = rtw89_read32(rtwdev, reg) | b_rsp_chk_cca; ++ rtw89_write32(rtwdev, reg, val32); ++ break; ++ } ++} ++ ++static int cca_ctrl_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 val, reg; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_CCA_CONTROL, mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val |= (B_AX_TB_CHK_BASIC_NAV | B_AX_TB_CHK_BTCCA | ++ B_AX_TB_CHK_EDCCA | B_AX_TB_CHK_CCA_P20 | ++ B_AX_SIFS_CHK_BTCCA | B_AX_SIFS_CHK_CCA_P20 | ++ B_AX_CTN_CHK_INTRA_NAV | ++ B_AX_CTN_CHK_BASIC_NAV | B_AX_CTN_CHK_BTCCA | ++ B_AX_CTN_CHK_EDCCA | B_AX_CTN_CHK_CCA_S80 | ++ B_AX_CTN_CHK_CCA_S40 | B_AX_CTN_CHK_CCA_S20 | ++ B_AX_CTN_CHK_CCA_P20 | B_AX_SIFS_CHK_EDCCA); ++ val &= ~(B_AX_TB_CHK_TX_NAV | B_AX_TB_CHK_CCA_S80 | ++ B_AX_TB_CHK_CCA_S40 | B_AX_TB_CHK_CCA_S20 | ++ B_AX_SIFS_CHK_CCA_S80 | B_AX_SIFS_CHK_CCA_S40 | ++ B_AX_SIFS_CHK_CCA_S20 | B_AX_CTN_CHK_TXNAV); ++ ++ rtw89_write32(rtwdev, reg, val); ++ ++ _patch_dis_resp_chk(rtwdev, mac_idx); ++ ++ return 0; ++} ++ ++static int spatial_reuse_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 reg; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ reg = rtw89_mac_reg_by_idx(R_AX_RX_SR_CTRL, mac_idx); ++ rtw89_write8_clr(rtwdev, reg, B_AX_SR_EN); ++ ++ return 0; ++} ++ ++static int tmac_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 reg; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_MAC_LOOPBACK, mac_idx); ++ rtw89_write32_clr(rtwdev, reg, B_AX_MACLBK_EN); ++ ++ return 0; ++} ++ ++static int trxptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 reg, val, sifs; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_0, mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val &= ~B_AX_WMAC_SPEC_SIFS_CCK_MASK; ++ val |= FIELD_PREP(B_AX_WMAC_SPEC_SIFS_CCK_MASK, WMAC_SPEC_SIFS_CCK); ++ ++ switch (rtwdev->chip->chip_id) { ++ case RTL8852A: ++ sifs = WMAC_SPEC_SIFS_OFDM_52A; ++ break; ++ case RTL8852B: ++ sifs = WMAC_SPEC_SIFS_OFDM_52B; ++ break; ++ default: ++ sifs = WMAC_SPEC_SIFS_OFDM_52C; ++ break; ++ } ++ val &= ~B_AX_WMAC_SPEC_SIFS_OFDM_MASK; ++ val |= FIELD_PREP(B_AX_WMAC_SPEC_SIFS_OFDM_MASK, sifs); ++ rtw89_write32(rtwdev, reg, val); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_RXTRIG_TEST_USER_2, mac_idx); ++ rtw89_write32_set(rtwdev, reg, B_AX_RXTRIG_FCSCHK_EN); ++ ++ return 0; ++} ++ ++static int rmac_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++#define TRXCFG_RMAC_CCA_TO 32 ++#define TRXCFG_RMAC_DATA_TO 15 ++#define RX_MAX_LEN_UNIT 512 ++#define PLD_RLS_MAX_PG 127 ++ int ret; ++ u32 reg, rx_max_len, rx_qta; ++ u16 val; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_RESPBA_CAM_CTRL, mac_idx); ++ rtw89_write8_set(rtwdev, reg, B_AX_SSN_SEL); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_DLK_PROTECT_CTL, mac_idx); ++ val = rtw89_read16(rtwdev, reg); ++ val = u16_replace_bits(val, TRXCFG_RMAC_DATA_TO, ++ B_AX_RX_DLK_DATA_TIME_MASK); ++ val = u16_replace_bits(val, TRXCFG_RMAC_CCA_TO, ++ B_AX_RX_DLK_CCA_TIME_MASK); ++ rtw89_write16(rtwdev, reg, val); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_RCR, mac_idx); ++ rtw89_write8_mask(rtwdev, reg, B_AX_CH_EN_MASK, 0x1); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, mac_idx); ++ if (mac_idx == RTW89_MAC_0) ++ rx_qta = rtwdev->mac.dle_info.c0_rx_qta; ++ else ++ rx_qta = rtwdev->mac.dle_info.c1_rx_qta; ++ rx_qta = rx_qta > PLD_RLS_MAX_PG ? PLD_RLS_MAX_PG : rx_qta; ++ rx_max_len = (rx_qta - 1) * rtwdev->mac.dle_info.ple_pg_size / ++ RX_MAX_LEN_UNIT; ++ rx_max_len = rx_max_len > B_AX_RX_MPDU_MAX_LEN_SIZE ? ++ B_AX_RX_MPDU_MAX_LEN_SIZE : rx_max_len; ++ rtw89_write32_mask(rtwdev, reg, B_AX_RX_MPDU_MAX_LEN_MASK, rx_max_len); ++ ++ if (rtwdev->chip->chip_id == RTL8852A && ++ rtwdev->hal.cv == CHIP_CBV) { ++ rtw89_write16_mask(rtwdev, ++ rtw89_mac_reg_by_idx(R_AX_DLK_PROTECT_CTL, mac_idx), ++ B_AX_RX_DLK_CCA_TIME_MASK, 0); ++ rtw89_write16_set(rtwdev, rtw89_mac_reg_by_idx(R_AX_RCR, mac_idx), ++ BIT(12)); ++ } ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_PLCP_HDR_FLTR, mac_idx); ++ rtw89_write8_clr(rtwdev, reg, B_AX_VHT_SU_SIGB_CRC_CHK); ++ ++ return ret; ++} ++ ++static int cmac_com_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 val, reg; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE, mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val = u32_replace_bits(val, 0, B_AX_TXSC_20M_MASK); ++ val = u32_replace_bits(val, 0, B_AX_TXSC_40M_MASK); ++ val = u32_replace_bits(val, 0, B_AX_TXSC_80M_MASK); ++ rtw89_write32(rtwdev, reg, val); ++ ++ return 0; ++} ++ ++static bool is_qta_dbcc(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode) ++{ ++ const struct rtw89_dle_mem *cfg; ++ ++ cfg = get_dle_mem_cfg(rtwdev, mode); ++ if (!cfg) { ++ rtw89_err(rtwdev, "[ERR]get_dle_mem_cfg\n"); ++ return false; ++ } ++ ++ return (cfg->ple_min_qt->cma1_dma && cfg->ple_max_qt->cma1_dma); ++} ++ ++static int ptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 val, reg; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) { ++ reg = rtw89_mac_reg_by_idx(R_AX_SIFS_SETTING, mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val = u32_replace_bits(val, S_AX_CTS2S_TH_1K, ++ B_AX_HW_CTS2SELF_PKT_LEN_TH_MASK); ++ val |= B_AX_HW_CTS2SELF_EN; ++ rtw89_write32(rtwdev, reg, val); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_PTCL_FSM_MON, mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val = u32_replace_bits(val, S_AX_PTCL_TO_2MS, B_AX_PTCL_TX_ARB_TO_THR_MASK); ++ val &= ~B_AX_PTCL_TX_ARB_TO_MODE; ++ rtw89_write32(rtwdev, reg, val); ++ } ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_SIFS_SETTING, mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val = u32_replace_bits(val, S_AX_CTS2S_TH_SEC_256B, B_AX_HW_CTS2SELF_PKT_LEN_TH_TWW_MASK); ++ val |= B_AX_HW_CTS2SELF_EN; ++ rtw89_write32(rtwdev, reg, val); ++ ++ return 0; ++} ++ ++static int cmac_init(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ int ret; ++ ++ ret = scheduler_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d SCH init %d\n", mac_idx, ret); ++ return ret; ++ } ++ ++ ret = addr_cam_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d ADDR_CAM reset %d\n", mac_idx, ++ ret); ++ return ret; ++ } ++ ++ ret = rx_fltr_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d RX filter init %d\n", mac_idx, ++ ret); ++ return ret; ++ } ++ ++ ret = cca_ctrl_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d CCA CTRL init %d\n", mac_idx, ++ ret); ++ return ret; ++ } ++ ++ ret = spatial_reuse_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d Spatial Reuse init %d\n", ++ mac_idx, ret); ++ return ret; ++ } ++ ++ ret = tmac_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d TMAC init %d\n", mac_idx, ret); ++ return ret; ++ } ++ ++ ret = trxptcl_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d TRXPTCL init %d\n", mac_idx, ret); ++ return ret; ++ } ++ ++ ret = rmac_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d RMAC init %d\n", mac_idx, ret); ++ return ret; ++ } ++ ++ ret = cmac_com_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d Com init %d\n", mac_idx, ret); ++ return ret; ++ } ++ ++ ret = ptcl_init(rtwdev, mac_idx); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d PTCL init %d\n", mac_idx, ret); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++static int rtw89_mac_read_phycap(struct rtw89_dev *rtwdev, ++ struct rtw89_mac_c2h_info *c2h_info) ++{ ++ struct rtw89_mac_h2c_info h2c_info = {0}; ++ u32 ret; ++ ++ h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE; ++ h2c_info.content_len = 0; ++ ++ ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, c2h_info); ++ if (ret) ++ return ret; ++ ++ if (c2h_info->id != RTW89_FWCMD_C2HREG_FUNC_PHY_CAP) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_hal *hal = &rtwdev->hal; ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_mac_c2h_info c2h_info = {0}; ++ struct rtw89_c2h_phy_cap *cap = ++ (struct rtw89_c2h_phy_cap *)&c2h_info.c2hreg[0]; ++ u32 ret; ++ ++ ret = rtw89_mac_read_phycap(rtwdev, &c2h_info); ++ if (ret) ++ return ret; ++ ++ hal->tx_nss = cap->tx_nss ? ++ min_t(u8, cap->tx_nss, chip->tx_nss) : chip->tx_nss; ++ hal->rx_nss = cap->rx_nss ? ++ min_t(u8, cap->rx_nss, chip->rx_nss) : chip->rx_nss; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_FW, ++ "phycap hal/phy/chip: tx_nss=0x%x/0x%x/0x%x rx_nss=0x%x/0x%x/0x%x\n", ++ hal->tx_nss, cap->tx_nss, chip->tx_nss, ++ hal->rx_nss, cap->rx_nss, chip->rx_nss); ++ ++ return 0; ++} ++ ++static int rtw89_hw_sch_tx_en_h2c(struct rtw89_dev *rtwdev, u8 band, ++ u16 tx_en_u16, u16 mask_u16) ++{ ++ u32 ret; ++ struct rtw89_mac_c2h_info c2h_info = {0}; ++ struct rtw89_mac_h2c_info h2c_info = {0}; ++ struct rtw89_h2creg_sch_tx_en *h2creg = ++ (struct rtw89_h2creg_sch_tx_en *)h2c_info.h2creg; ++ ++ h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_SCH_TX_EN; ++ h2c_info.content_len = sizeof(*h2creg) - RTW89_H2CREG_HDR_LEN; ++ h2creg->tx_en = tx_en_u16; ++ h2creg->mask = mask_u16; ++ h2creg->band = band; ++ ++ ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info); ++ if (ret) ++ return ret; ++ ++ if (c2h_info.id != RTW89_FWCMD_C2HREG_FUNC_TX_PAUSE_RPT) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int rtw89_set_hw_sch_tx_en(struct rtw89_dev *rtwdev, u8 mac_idx, ++ u16 tx_en, u16 tx_en_mask) ++{ ++ u32 reg = rtw89_mac_reg_by_idx(R_AX_CTN_TXEN, mac_idx); ++ u16 val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) ++ return rtw89_hw_sch_tx_en_h2c(rtwdev, mac_idx, ++ tx_en, tx_en_mask); ++ ++ val = rtw89_read16(rtwdev, reg); ++ val = (val & ~tx_en_mask) | (tx_en & tx_en_mask); ++ rtw89_write16(rtwdev, reg, val); ++ ++ return 0; ++} ++ ++int rtw89_mac_stop_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, ++ u16 *tx_en, enum rtw89_sch_tx_sel sel) ++{ ++ int ret; ++ ++ *tx_en = rtw89_read16(rtwdev, ++ rtw89_mac_reg_by_idx(R_AX_CTN_TXEN, mac_idx)); ++ ++ switch (sel) { ++ case RTW89_SCH_TX_SEL_ALL: ++ ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, 0, 0xffff); ++ if (ret) ++ return ret; ++ break; ++ case RTW89_SCH_TX_SEL_HIQ: ++ ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, ++ 0, B_AX_CTN_TXEN_HGQ); ++ if (ret) ++ return ret; ++ break; ++ case RTW89_SCH_TX_SEL_MG0: ++ ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, ++ 0, B_AX_CTN_TXEN_MGQ); ++ if (ret) ++ return ret; ++ break; ++ case RTW89_SCH_TX_SEL_MACID: ++ ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, 0, 0xffff); ++ if (ret) ++ return ret; ++ break; ++ default: ++ return 0; ++ } ++ ++ return 0; ++} ++ ++int rtw89_mac_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u16 tx_en) ++{ ++ int ret; ++ ++ ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, tx_en, 0xffff); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static u16 rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, ++ bool wd) ++{ ++ u32 val, reg; ++ int ret; ++ ++ reg = wd ? R_AX_WD_BUF_REQ : R_AX_PL_BUF_REQ; ++ val = buf_len; ++ val |= B_AX_WD_BUF_REQ_EXEC; ++ rtw89_write32(rtwdev, reg, val); ++ ++ reg = wd ? R_AX_WD_BUF_STATUS : R_AX_PL_BUF_STATUS; ++ ++ ret = read_poll_timeout(rtw89_read32, val, val & B_AX_WD_BUF_STAT_DONE, ++ 1, 2000, false, rtwdev, reg); ++ if (ret) ++ return 0xffff; ++ ++ return FIELD_GET(B_AX_WD_BUF_STAT_PKTID_MASK, val); ++} ++ ++static int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev, ++ struct rtw89_cpuio_ctrl *ctrl_para, ++ bool wd) ++{ ++ u32 val, cmd_type, reg; ++ int ret; ++ ++ cmd_type = ctrl_para->cmd_type; ++ ++ reg = wd ? R_AX_WD_CPUQ_OP_2 : R_AX_PL_CPUQ_OP_2; ++ val = 0; ++ val = u32_replace_bits(val, ctrl_para->start_pktid, ++ B_AX_WD_CPUQ_OP_STRT_PKTID_MASK); ++ val = u32_replace_bits(val, ctrl_para->end_pktid, ++ B_AX_WD_CPUQ_OP_END_PKTID_MASK); ++ rtw89_write32(rtwdev, reg, val); ++ ++ reg = wd ? R_AX_WD_CPUQ_OP_1 : R_AX_PL_CPUQ_OP_1; ++ val = 0; ++ val = u32_replace_bits(val, ctrl_para->src_pid, ++ B_AX_CPUQ_OP_SRC_PID_MASK); ++ val = u32_replace_bits(val, ctrl_para->src_qid, ++ B_AX_CPUQ_OP_SRC_QID_MASK); ++ val = u32_replace_bits(val, ctrl_para->dst_pid, ++ B_AX_CPUQ_OP_DST_PID_MASK); ++ val = u32_replace_bits(val, ctrl_para->dst_qid, ++ B_AX_CPUQ_OP_DST_QID_MASK); ++ rtw89_write32(rtwdev, reg, val); ++ ++ reg = wd ? R_AX_WD_CPUQ_OP_0 : R_AX_PL_CPUQ_OP_0; ++ val = 0; ++ val = u32_replace_bits(val, cmd_type, ++ B_AX_CPUQ_OP_CMD_TYPE_MASK); ++ val = u32_replace_bits(val, ctrl_para->macid, ++ B_AX_CPUQ_OP_MACID_MASK); ++ val = u32_replace_bits(val, ctrl_para->pkt_num, ++ B_AX_CPUQ_OP_PKTNUM_MASK); ++ val |= B_AX_WD_CPUQ_OP_EXEC; ++ rtw89_write32(rtwdev, reg, val); ++ ++ reg = wd ? R_AX_WD_CPUQ_OP_STATUS : R_AX_PL_CPUQ_OP_STATUS; ++ ++ ret = read_poll_timeout(rtw89_read32, val, val & B_AX_WD_CPUQ_OP_STAT_DONE, ++ 1, 2000, false, rtwdev, reg); ++ if (ret) ++ return ret; ++ ++ if (cmd_type == CPUIO_OP_CMD_GET_1ST_PID || ++ cmd_type == CPUIO_OP_CMD_GET_NEXT_PID) ++ ctrl_para->pktid = FIELD_GET(B_AX_WD_CPUQ_OP_PKTID_MASK, val); ++ ++ return 0; ++} ++ ++static int dle_quota_change(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode) ++{ ++ const struct rtw89_dle_mem *cfg; ++ struct rtw89_cpuio_ctrl ctrl_para = {0}; ++ u16 pkt_id; ++ int ret; ++ ++ cfg = get_dle_mem_cfg(rtwdev, mode); ++ if (!cfg) { ++ rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n"); ++ return -EINVAL; ++ } ++ ++ if (dle_used_size(cfg->wde_size, cfg->ple_size) != rtwdev->chip->fifo_size) { ++ rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n"); ++ return -EINVAL; ++ } ++ ++ dle_quota_cfg(rtwdev, cfg, INVALID_QT_WCPU); ++ ++ pkt_id = rtw89_mac_dle_buf_req(rtwdev, 0x20, true); ++ if (pkt_id == 0xffff) { ++ rtw89_err(rtwdev, "[ERR]WDE DLE buf req\n"); ++ return -ENOMEM; ++ } ++ ++ ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD; ++ ctrl_para.start_pktid = pkt_id; ++ ctrl_para.end_pktid = pkt_id; ++ ctrl_para.pkt_num = 0; ++ ctrl_para.dst_pid = WDE_DLE_PORT_ID_WDRLS; ++ ctrl_para.dst_qid = WDE_DLE_QUEID_NO_REPORT; ++ ret = rtw89_mac_set_cpuio(rtwdev, &ctrl_para, true); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]WDE DLE enqueue to head\n"); ++ return -EFAULT; ++ } ++ ++ pkt_id = rtw89_mac_dle_buf_req(rtwdev, 0x20, false); ++ if (pkt_id == 0xffff) { ++ rtw89_err(rtwdev, "[ERR]PLE DLE buf req\n"); ++ return -ENOMEM; ++ } ++ ++ ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD; ++ ctrl_para.start_pktid = pkt_id; ++ ctrl_para.end_pktid = pkt_id; ++ ctrl_para.pkt_num = 0; ++ ctrl_para.dst_pid = PLE_DLE_PORT_ID_PLRLS; ++ ctrl_para.dst_qid = PLE_DLE_QUEID_NO_REPORT; ++ ret = rtw89_mac_set_cpuio(rtwdev, &ctrl_para, false); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]PLE DLE enqueue to head\n"); ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++static int band_idle_ck_b(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ int ret; ++ u32 reg; ++ u8 val; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_PTCL_TX_CTN_SEL, mac_idx); ++ ++ ret = read_poll_timeout(rtw89_read8, val, ++ (val & B_AX_PTCL_TX_ON_STAT) == 0, ++ SW_CVR_DUR_US, ++ SW_CVR_DUR_US * PTCL_IDLE_POLL_CNT, ++ false, rtwdev, reg); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int band1_enable(struct rtw89_dev *rtwdev) ++{ ++ int ret, i; ++ u32 sleep_bak[4] = {0}; ++ u32 pause_bak[4] = {0}; ++ u16 tx_en; ++ ++ ret = rtw89_mac_stop_sch_tx(rtwdev, 0, &tx_en, RTW89_SCH_TX_SEL_ALL); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]stop sch tx %d\n", ret); ++ return ret; ++ } ++ ++ for (i = 0; i < 4; i++) { ++ sleep_bak[i] = rtw89_read32(rtwdev, R_AX_MACID_SLEEP_0 + i * 4); ++ pause_bak[i] = rtw89_read32(rtwdev, R_AX_SS_MACID_PAUSE_0 + i * 4); ++ rtw89_write32(rtwdev, R_AX_MACID_SLEEP_0 + i * 4, U32_MAX); ++ rtw89_write32(rtwdev, R_AX_SS_MACID_PAUSE_0 + i * 4, U32_MAX); ++ } ++ ++ ret = band_idle_ck_b(rtwdev, 0); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]tx idle poll %d\n", ret); ++ return ret; ++ } ++ ++ ret = dle_quota_change(rtwdev, rtwdev->mac.qta_mode); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]DLE quota change %d\n", ret); ++ return ret; ++ } ++ ++ for (i = 0; i < 4; i++) { ++ rtw89_write32(rtwdev, R_AX_MACID_SLEEP_0 + i * 4, sleep_bak[i]); ++ rtw89_write32(rtwdev, R_AX_SS_MACID_PAUSE_0 + i * 4, pause_bak[i]); ++ } ++ ++ ret = rtw89_mac_resume_sch_tx(rtwdev, 0, tx_en); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC1 resume sch tx %d\n", ret); ++ return ret; ++ } ++ ++ ret = cmac_func_en(rtwdev, 1, true); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC1 func en %d\n", ret); ++ return ret; ++ } ++ ++ ret = cmac_init(rtwdev, 1); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC1 init %d\n", ret); ++ return ret; ++ } ++ ++ rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, ++ B_AX_R_SYM_FEN_WLBBFUN_1 | B_AX_R_SYM_FEN_WLBBGLB_1); ++ ++ return 0; ++} ++ ++static int rtw89_mac_enable_imr(struct rtw89_dev *rtwdev, u8 mac_idx, ++ enum rtw89_mac_hwmod_sel sel) ++{ ++ u32 reg, val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, sel); ++ if (ret) { ++ rtw89_err(rtwdev, "MAC%d mac_idx%d is not ready\n", ++ sel, mac_idx); ++ return ret; ++ } ++ ++ if (sel == RTW89_DMAC_SEL) { ++ rtw89_write32_clr(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR, ++ B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN | ++ B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR_INT_EN | ++ B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR_INT_EN); ++ rtw89_write32_clr(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1, ++ B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN | ++ B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR_INT_EN); ++ rtw89_write32_clr(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR, ++ B_AX_HDT_PKT_FAIL_DBG_INT_EN | ++ B_AX_HDT_OFFSET_UNMATCH_INT_EN); ++ rtw89_write32_clr(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR, ++ B_AX_CPU_SHIFT_EN_ERR_INT_EN); ++ rtw89_write32_clr(rtwdev, R_AX_PLE_ERR_IMR, ++ B_AX_PLE_GETNPG_STRPG_ERR_INT_EN); ++ rtw89_write32_clr(rtwdev, R_AX_WDRLS_ERR_IMR, ++ B_AX_WDRLS_PLEBREQ_TO_ERR_INT_EN); ++ rtw89_write32_set(rtwdev, R_AX_HD0IMR, B_AX_WDT_PTFM_INT_EN); ++ rtw89_write32_clr(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR, ++ B_AX_TXPKTCTL_USRCTL_NOINIT_ERR_INT_EN); ++ } else if (sel == RTW89_CMAC_SEL) { ++ reg = rtw89_mac_reg_by_idx(R_AX_SCHEDULE_ERR_IMR, mac_idx); ++ rtw89_write32_clr(rtwdev, reg, ++ B_AX_SORT_NON_IDLE_ERR_INT_EN); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_DLE_CTRL, mac_idx); ++ rtw89_write32_clr(rtwdev, reg, ++ B_AX_NO_RESERVE_PAGE_ERR_IMR | ++ B_AX_RXDATA_FSM_HANG_ERROR_IMR); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_PTCL_IMR0, mac_idx); ++ val = B_AX_F2PCMD_USER_ALLC_ERR_INT_EN | ++ B_AX_TX_RECORD_PKTID_ERR_INT_EN | ++ B_AX_FSM_TIMEOUT_ERR_INT_EN; ++ rtw89_write32(rtwdev, reg, val); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_PHYINFO_ERR_IMR, mac_idx); ++ rtw89_write32_set(rtwdev, reg, ++ B_AX_PHY_TXON_TIMEOUT_INT_EN | ++ B_AX_CCK_CCA_TIMEOUT_INT_EN | ++ B_AX_OFDM_CCA_TIMEOUT_INT_EN | ++ B_AX_DATA_ON_TIMEOUT_INT_EN | ++ B_AX_STS_ON_TIMEOUT_INT_EN | ++ B_AX_CSI_ON_TIMEOUT_INT_EN); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_RMAC_ERR_ISR, mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val |= (B_AX_RMAC_RX_CSI_TIMEOUT_INT_EN | ++ B_AX_RMAC_RX_TIMEOUT_INT_EN | ++ B_AX_RMAC_CSI_TIMEOUT_INT_EN); ++ val &= ~(B_AX_RMAC_CCA_TO_IDLE_TIMEOUT_INT_EN | ++ B_AX_RMAC_DATA_ON_TO_IDLE_TIMEOUT_INT_EN | ++ B_AX_RMAC_CCA_TIMEOUT_INT_EN | ++ B_AX_RMAC_DATA_ON_TIMEOUT_INT_EN); ++ rtw89_write32(rtwdev, reg, val); ++ } else { ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int rtw89_mac_dbcc_enable(struct rtw89_dev *rtwdev, bool enable) ++{ ++ int ret = 0; ++ ++ if (enable) { ++ ret = band1_enable(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] band1_enable %d\n", ret); ++ return ret; ++ } ++ ++ ret = rtw89_mac_enable_imr(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] enable CMAC1 IMR %d\n", ret); ++ return ret; ++ } ++ } else { ++ rtw89_err(rtwdev, "[ERR] disable dbcc is not implemented not\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int set_host_rpr(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) { ++ rtw89_write32_mask(rtwdev, R_AX_WDRLS_CFG, ++ B_AX_WDRLS_MODE_MASK, RTW89_RPR_MODE_POH); ++ rtw89_write32_set(rtwdev, R_AX_RLSRPT0_CFG0, ++ B_AX_RLSRPT0_FLTR_MAP_MASK); ++ } else { ++ rtw89_write32_mask(rtwdev, R_AX_WDRLS_CFG, ++ B_AX_WDRLS_MODE_MASK, RTW89_RPR_MODE_STF); ++ rtw89_write32_clr(rtwdev, R_AX_RLSRPT0_CFG0, ++ B_AX_RLSRPT0_FLTR_MAP_MASK); ++ } ++ ++ rtw89_write32_mask(rtwdev, R_AX_RLSRPT0_CFG1, B_AX_RLSRPT0_AGGNUM_MASK, 30); ++ rtw89_write32_mask(rtwdev, R_AX_RLSRPT0_CFG1, B_AX_RLSRPT0_TO_MASK, 255); ++ ++ return 0; ++} ++ ++static int rtw89_mac_trx_init(struct rtw89_dev *rtwdev) ++{ ++ enum rtw89_qta_mode qta_mode = rtwdev->mac.qta_mode; ++ int ret; ++ ++ ret = dmac_init(rtwdev, 0); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]DMAC init %d\n", ret); ++ return ret; ++ } ++ ++ ret = cmac_init(rtwdev, 0); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]CMAC%d init %d\n", 0, ret); ++ return ret; ++ } ++ ++ if (is_qta_dbcc(rtwdev, qta_mode)) { ++ ret = rtw89_mac_dbcc_enable(rtwdev, true); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]dbcc_enable init %d\n", ret); ++ return ret; ++ } ++ } ++ ++ ret = rtw89_mac_enable_imr(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] enable DMAC IMR %d\n", ret); ++ return ret; ++ } ++ ++ ret = rtw89_mac_enable_imr(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] to enable CMAC0 IMR %d\n", ret); ++ return ret; ++ } ++ ++ ret = set_host_rpr(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] set host rpr %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev) ++{ ++ clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); ++ ++ rtw89_write32_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_WCPU_EN); ++ rtw89_write32_clr(rtwdev, R_AX_SYS_CLK_CTRL, B_AX_CPU_CLK_EN); ++} ++ ++static int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, ++ bool dlfw) ++{ ++ u32 val; ++ int ret; ++ ++ if (rtw89_read32(rtwdev, R_AX_PLATFORM_ENABLE) & B_AX_WCPU_EN) ++ return -EFAULT; ++ ++ rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0); ++ rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); ++ ++ rtw89_write32_set(rtwdev, R_AX_SYS_CLK_CTRL, B_AX_CPU_CLK_EN); ++ ++ val = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL); ++ val &= ~(B_AX_WCPU_FWDL_EN | B_AX_H2C_PATH_RDY | B_AX_FWDL_PATH_RDY); ++ val = u32_replace_bits(val, RTW89_FWDL_INITIAL_STATE, ++ B_AX_WCPU_FWDL_STS_MASK); ++ ++ if (dlfw) ++ val |= B_AX_WCPU_FWDL_EN; ++ ++ rtw89_write32(rtwdev, R_AX_WCPU_FW_CTRL, val); ++ rtw89_write16_mask(rtwdev, R_AX_BOOT_REASON, B_AX_BOOT_REASON_MASK, ++ boot_reason); ++ rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_WCPU_EN); ++ ++ if (!dlfw) { ++ mdelay(5); ++ ++ ret = rtw89_fw_check_rdy(rtwdev); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int rtw89_mac_fw_dl_pre_init(struct rtw89_dev *rtwdev) ++{ ++ u32 val; ++ int ret; ++ ++ val = B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_DISPATCHER_EN | ++ B_AX_PKT_BUF_EN; ++ rtw89_write32(rtwdev, R_AX_DMAC_FUNC_EN, val); ++ ++ val = B_AX_DISPATCHER_CLK_EN; ++ rtw89_write32(rtwdev, R_AX_DMAC_CLK_EN, val); ++ ++ ret = dle_init(rtwdev, RTW89_QTA_DLFW, rtwdev->mac.qta_mode); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]DLE pre init %d\n", ret); ++ return ret; ++ } ++ ++ ret = hfc_init(rtwdev, true, false, true); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]HCI FC pre init %d\n", ret); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++static void rtw89_mac_hci_func_en(struct rtw89_dev *rtwdev) ++{ ++ rtw89_write32_set(rtwdev, R_AX_HCI_FUNC_EN, ++ B_AX_HCI_TXDMA_EN | B_AX_HCI_RXDMA_EN); ++} ++ ++void rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev) ++{ ++ rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN, ++ B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); ++ rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, ++ B_AX_WLRF1_CTRL_7 | B_AX_WLRF1_CTRL_1 | ++ B_AX_WLRF_CTRL_7 | B_AX_WLRF_CTRL_1); ++ rtw89_write8_set(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_ALL_CYCLE); ++} ++ ++void rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev) ++{ ++ rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, ++ B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN); ++ rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, ++ B_AX_WLRF1_CTRL_7 | B_AX_WLRF1_CTRL_1 | ++ B_AX_WLRF_CTRL_7 | B_AX_WLRF_CTRL_1); ++ rtw89_write8_clr(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_ALL_CYCLE); ++} ++ ++int rtw89_mac_partial_init(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ ret = rtw89_mac_power_switch(rtwdev, true); ++ if (ret) { ++ rtw89_mac_power_switch(rtwdev, false); ++ ret = rtw89_mac_power_switch(rtwdev, true); ++ if (ret) ++ return ret; ++ } ++ ++ rtw89_mac_hci_func_en(rtwdev); ++ ++ if (rtwdev->hci.ops->mac_pre_init) { ++ ret = rtwdev->hci.ops->mac_pre_init(rtwdev); ++ if (ret) ++ return ret; ++ } ++ ++ ret = rtw89_mac_fw_dl_pre_init(rtwdev); ++ if (ret) ++ return ret; ++ ++ rtw89_mac_disable_cpu(rtwdev); ++ ret = rtw89_mac_enable_cpu(rtwdev, 0, true); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_fw_download(rtwdev, RTW89_FW_NORMAL); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++int rtw89_mac_init(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ ret = rtw89_mac_partial_init(rtwdev); ++ if (ret) ++ goto fail; ++ ++ rtw89_mac_enable_bb_rf(rtwdev); ++ if (ret) ++ goto fail; ++ ++ ret = rtw89_mac_sys_init(rtwdev); ++ if (ret) ++ goto fail; ++ ++ ret = rtw89_mac_trx_init(rtwdev); ++ if (ret) ++ goto fail; ++ ++ if (rtwdev->hci.ops->mac_post_init) { ++ ret = rtwdev->hci.ops->mac_post_init(rtwdev); ++ if (ret) ++ goto fail; ++ } ++ ++ rtw89_fw_send_all_early_h2c(rtwdev); ++ rtw89_fw_h2c_set_ofld_cfg(rtwdev); ++ ++ return ret; ++fail: ++ rtw89_mac_power_switch(rtwdev, false); ++ ++ return ret; ++} ++ ++static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid) ++{ ++ u8 i; ++ ++ for (i = 0; i < 4; i++) { ++ rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, ++ DMAC_TBL_BASE_ADDR + (macid << 4) + (i << 2)); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, 0); ++ } ++} ++ ++static void rtw89_mac_cmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid) ++{ ++ rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, ++ CMAC_TBL_BASE_ADDR + macid * CCTL_INFO_SIZE); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, 0x4); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 4, 0x400A0004); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 8, 0); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 12, 0); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 16, 0); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 20, 0xE43000B); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 24, 0); ++ rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 28, 0xB8109); ++} ++ ++static int rtw89_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause) ++{ ++ u8 sh = FIELD_GET(GENMASK(4, 0), macid); ++ u8 grp = macid >> 5; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ rtw89_fw_h2c_macid_pause(rtwdev, sh, grp, pause); ++ ++ return 0; ++} ++ ++static const struct rtw89_port_reg rtw_port_base = { ++ .port_cfg = R_AX_PORT_CFG_P0, ++ .tbtt_prohib = R_AX_TBTT_PROHIB_P0, ++ .bcn_area = R_AX_BCN_AREA_P0, ++ .bcn_early = R_AX_BCNERLYINT_CFG_P0, ++ .tbtt_early = R_AX_TBTTERLYINT_CFG_P0, ++ .tbtt_agg = R_AX_TBTT_AGG_P0, ++ .bcn_space = R_AX_BCN_SPACE_CFG_P0, ++ .bcn_forcetx = R_AX_BCN_FORCETX_P0, ++ .bcn_err_cnt = R_AX_BCN_ERR_CNT_P0, ++ .bcn_err_flag = R_AX_BCN_ERR_FLAG_P0, ++ .dtim_ctrl = R_AX_DTIM_CTRL_P0, ++ .tbtt_shift = R_AX_TBTT_SHIFT_P0, ++ .bcn_cnt_tmr = R_AX_BCN_CNT_TMR_P0, ++ .tsftr_l = R_AX_TSFTR_LOW_P0, ++ .tsftr_h = R_AX_TSFTR_HIGH_P0 ++}; ++ ++#define BCN_INTERVAL 100 ++#define BCN_ERLY_DEF 160 ++#define BCN_SETUP_DEF 2 ++#define BCN_HOLD_DEF 200 ++#define BCN_MASK_DEF 0 ++#define TBTT_ERLY_DEF 5 ++#define BCN_SET_UNIT 32 ++#define BCN_ERLY_SET_DLY (10 * 2) ++ ++static void rtw89_mac_port_cfg_func_sw(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ if (!rtw89_read32_port_mask(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN)) ++ return; ++ ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK); ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 1); ++ rtw89_write16_port_clr(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK); ++ rtw89_write16_port_clr(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK); ++ ++ msleep(vif->bss_conf.beacon_int + 1); ++ ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN | ++ B_AX_BRK_SETUP); ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TSFTR_RST); ++ rtw89_write32_port(rtwdev, rtwvif, p->bcn_cnt_tmr, 0); ++} ++ ++static void rtw89_mac_port_cfg_tx_rpt(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, bool en) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ if (en) ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TXBCN_RPT_EN); ++ else ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TXBCN_RPT_EN); ++} ++ ++static void rtw89_mac_port_cfg_rx_rpt(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, bool en) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ if (en) ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_RXBCN_RPT_EN); ++ else ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_RXBCN_RPT_EN); ++} ++ ++static void rtw89_mac_port_cfg_net_type(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->port_cfg, B_AX_NET_TYPE_MASK, ++ rtwvif->net_type); ++} ++ ++static void rtw89_mac_port_cfg_bcn_prct(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ bool en = rtwvif->net_type != RTW89_NET_TYPE_NO_LINK; ++ u32 bits = B_AX_TBTT_PROHIB_EN | B_AX_BRK_SETUP; ++ ++ if (en) ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, bits); ++ else ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, bits); ++} ++ ++static void rtw89_mac_port_cfg_rx_sw(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ bool en = rtwvif->net_type == RTW89_NET_TYPE_INFRA || ++ rtwvif->net_type == RTW89_NET_TYPE_AD_HOC; ++ u32 bit = B_AX_RX_BSSID_FIT_EN; ++ ++ if (en) ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, bit); ++ else ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, bit); ++} ++ ++static void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ bool en = rtwvif->net_type == RTW89_NET_TYPE_INFRA || ++ rtwvif->net_type == RTW89_NET_TYPE_AD_HOC; ++ ++ if (en) ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TSF_UDT_EN); ++ else ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TSF_UDT_EN); ++} ++ ++static void rtw89_mac_port_cfg_tx_sw(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ bool en = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || ++ rtwvif->net_type == RTW89_NET_TYPE_AD_HOC; ++ ++ if (en) ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN); ++ else ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN); ++} ++ ++static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ u16 bcn_int = vif->bss_conf.beacon_int ? vif->bss_conf.beacon_int : BCN_INTERVAL; ++ ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_space, B_AX_BCN_SPACE_MASK, ++ bcn_int); ++} ++ ++static void rtw89_mac_port_cfg_bcn_setup_time(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, ++ B_AX_TBTT_SETUP_MASK, BCN_SETUP_DEF); ++} ++ ++static void rtw89_mac_port_cfg_bcn_hold_time(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, ++ B_AX_TBTT_HOLD_MASK, BCN_HOLD_DEF); ++} ++ ++static void rtw89_mac_port_cfg_bcn_mask_area(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_area, ++ B_AX_BCN_MSK_AREA_MASK, BCN_MASK_DEF); ++} ++ ++static void rtw89_mac_port_cfg_tbtt_early(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_early, ++ B_AX_TBTTERLY_MASK, TBTT_ERLY_DEF); ++} ++ ++static void rtw89_mac_port_cfg_bss_color(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ static const u32 masks[RTW89_PORT_NUM] = { ++ B_AX_BSS_COLOB_AX_PORT_0_MASK, B_AX_BSS_COLOB_AX_PORT_1_MASK, ++ B_AX_BSS_COLOB_AX_PORT_2_MASK, B_AX_BSS_COLOB_AX_PORT_3_MASK, ++ B_AX_BSS_COLOB_AX_PORT_4_MASK, ++ }; ++ u8 port = rtwvif->port; ++ u32 reg_base; ++ u32 reg; ++ u8 bss_color; ++ ++ bss_color = vif->bss_conf.he_bss_color.color; ++ reg_base = port >= 4 ? R_AX_PTCL_BSS_COLOR_1 : R_AX_PTCL_BSS_COLOR_0; ++ reg = rtw89_mac_reg_by_idx(reg_base, rtwvif->mac_idx); ++ rtw89_write32_mask(rtwdev, reg, masks[port], bss_color); ++} ++ ++static void rtw89_mac_port_cfg_mbssid(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ u8 port = rtwvif->port; ++ u32 reg; ++ ++ if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) ++ return; ++ ++ if (port == 0) { ++ reg = rtw89_mac_reg_by_idx(R_AX_MBSSID_CTRL, rtwvif->mac_idx); ++ rtw89_write32_clr(rtwdev, reg, B_AX_P0MB_ALL_MASK); ++ } ++} ++ ++static void rtw89_mac_port_cfg_hiq_drop(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ u8 port = rtwvif->port; ++ u32 reg; ++ u32 val; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_MBSSID_DROP_0, rtwvif->mac_idx); ++ val = rtw89_read32(rtwdev, reg); ++ val &= ~FIELD_PREP(B_AX_PORT_DROP_4_0_MASK, BIT(port)); ++ if (port == 0) ++ val &= ~BIT(0); ++ rtw89_write32(rtwdev, reg, val); ++} ++ ++static void rtw89_mac_port_cfg_func_en(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN); ++} ++ ++static void rtw89_mac_port_cfg_bcn_early(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ ++ rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK, ++ BCN_ERLY_DEF); ++} ++ ++int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ int ret; ++ ++ ret = rtw89_mac_port_update(rtwdev, rtwvif); ++ if (ret) ++ return ret; ++ ++ rtw89_mac_dmac_tbl_init(rtwdev, rtwvif->mac_id); ++ rtw89_mac_cmac_tbl_init(rtwdev, rtwvif->mac_id); ++ ++ ret = rtw89_set_macid_pause(rtwdev, rtwvif->mac_id, false); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_fw_h2c_vif_maintain(rtwdev, rtwvif, RTW89_VIF_CREATE); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_cam_init(rtwdev, rtwvif); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_fw_h2c_default_cmac_tbl(rtwdev, rtwvif->mac_id); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ int ret; ++ ++ ret = rtw89_fw_h2c_vif_maintain(rtwdev, rtwvif, RTW89_VIF_REMOVE); ++ if (ret) ++ return ret; ++ ++ rtw89_cam_deinit(rtwdev, rtwvif); ++ ++ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ u8 port = rtwvif->port; ++ ++ if (port >= RTW89_PORT_NUM) ++ return -EINVAL; ++ ++ rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_tx_rpt(rtwdev, rtwvif, false); ++ rtw89_mac_port_cfg_rx_rpt(rtwdev, rtwvif, false); ++ rtw89_mac_port_cfg_net_type(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_bcn_prct(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_rx_sw(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_bcn_setup_time(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_bcn_hold_time(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_bcn_mask_area(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_tbtt_early(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_hiq_drop(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_func_en(rtwdev, rtwvif); ++ fsleep(BCN_ERLY_SET_DLY); ++ rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif); ++ ++ return 0; ++} ++ ++int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ int ret; ++ ++ rtwvif->mac_id = rtw89_core_acquire_bit_map(rtwdev->mac_id_map, ++ RTW89_MAX_MAC_ID_NUM); ++ if (rtwvif->mac_id == RTW89_MAX_MAC_ID_NUM) ++ return -ENOSPC; ++ ++ ret = rtw89_mac_vif_init(rtwdev, rtwvif); ++ if (ret) ++ goto release_mac_id; ++ ++ return 0; ++ ++release_mac_id: ++ rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwvif->mac_id); ++ ++ return ret; ++} ++ ++int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ int ret; ++ ++ ret = rtw89_mac_vif_deinit(rtwdev, rtwvif); ++ rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwvif->mac_id); ++ ++ return ret; ++} ++ ++static void ++rtw89_mac_c2h_macid_pause(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) ++{ ++} ++ ++static void ++rtw89_mac_c2h_rec_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_FW, ++ "C2H rev ack recv, cat: %d, class: %d, func: %d, seq : %d\n", ++ RTW89_GET_MAC_C2H_REV_ACK_CAT(c2h->data), ++ RTW89_GET_MAC_C2H_REV_ACK_CLASS(c2h->data), ++ RTW89_GET_MAC_C2H_REV_ACK_FUNC(c2h->data), ++ RTW89_GET_MAC_C2H_REV_ACK_H2C_SEQ(c2h->data)); ++} ++ ++static void ++rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_FW, ++ "C2H done ack recv, cat: %d, class: %d, func: %d, ret: %d, seq : %d\n", ++ RTW89_GET_MAC_C2H_DONE_ACK_CAT(c2h->data), ++ RTW89_GET_MAC_C2H_DONE_ACK_CLASS(c2h->data), ++ RTW89_GET_MAC_C2H_DONE_ACK_FUNC(c2h->data), ++ RTW89_GET_MAC_C2H_DONE_ACK_H2C_RETURN(c2h->data), ++ RTW89_GET_MAC_C2H_DONE_ACK_H2C_SEQ(c2h->data)); ++} ++ ++static void ++rtw89_mac_c2h_log(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) ++{ ++ rtw89_info(rtwdev, "%*s", RTW89_GET_C2H_LOG_LEN(len), ++ RTW89_GET_C2H_LOG_SRT_PRT(c2h->data)); ++} ++ ++static ++void (* const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev, ++ struct sk_buff *c2h, u32 len) = { ++ [RTW89_MAC_C2H_FUNC_EFUSE_DUMP] = NULL, ++ [RTW89_MAC_C2H_FUNC_READ_RSP] = NULL, ++ [RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP] = NULL, ++ [RTW89_MAC_C2H_FUNC_BCN_RESEND] = NULL, ++ [RTW89_MAC_C2H_FUNC_MACID_PAUSE] = rtw89_mac_c2h_macid_pause, ++}; ++ ++static ++void (* const rtw89_mac_c2h_info_handler[])(struct rtw89_dev *rtwdev, ++ struct sk_buff *c2h, u32 len) = { ++ [RTW89_MAC_C2H_FUNC_REC_ACK] = rtw89_mac_c2h_rec_ack, ++ [RTW89_MAC_C2H_FUNC_DONE_ACK] = rtw89_mac_c2h_done_ack, ++ [RTW89_MAC_C2H_FUNC_C2H_LOG] = rtw89_mac_c2h_log, ++}; ++ ++void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, ++ u32 len, u8 class, u8 func) ++{ ++ void (*handler)(struct rtw89_dev *rtwdev, ++ struct sk_buff *c2h, u32 len) = NULL; ++ ++ switch (class) { ++ case RTW89_MAC_C2H_CLASS_INFO: ++ if (func < RTW89_MAC_C2H_FUNC_INFO_MAX) ++ handler = rtw89_mac_c2h_info_handler[func]; ++ break; ++ case RTW89_MAC_C2H_CLASS_OFLD: ++ if (func < RTW89_MAC_C2H_FUNC_OFLD_MAX) ++ handler = rtw89_mac_c2h_ofld_handler[func]; ++ break; ++ case RTW89_MAC_C2H_CLASS_FWDBG: ++ return; ++ default: ++ rtw89_info(rtwdev, "c2h class %d not support\n", class); ++ return; ++ } ++ if (!handler) { ++ rtw89_info(rtwdev, "c2h class %d func %d not support\n", class, ++ func); ++ return; ++ } ++ handler(rtwdev, skb, len); ++} ++ ++bool rtw89_mac_get_txpwr_cr(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, ++ u32 reg_base, u32 *cr) ++{ ++ const struct rtw89_dle_mem *dle_mem = rtwdev->chip->dle_mem; ++ enum rtw89_qta_mode mode = dle_mem->mode; ++ u32 addr = rtw89_mac_reg_by_idx(reg_base, phy_idx); ++ ++ if (addr < R_AX_PWR_RATE_CTRL || addr > CMAC1_END_ADDR) { ++ rtw89_err(rtwdev, "[TXPWR] addr=0x%x exceed txpwr cr\n", ++ addr); ++ goto error; ++ } ++ ++ if (addr >= CMAC1_START_ADDR && addr <= CMAC1_END_ADDR) ++ if (mode == RTW89_QTA_SCC) { ++ rtw89_err(rtwdev, ++ "[TXPWR] addr=0x%x but hw not enable\n", ++ addr); ++ goto error; ++ } ++ ++ *cr = addr; ++ return true; ++ ++error: ++ rtw89_err(rtwdev, "[TXPWR] check txpwr cr 0x%x(phy%d) fail\n", ++ addr, phy_idx); ++ ++ return false; ++} ++ ++int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) ++{ ++ u32 reg = rtw89_mac_reg_by_idx(R_AX_PPDU_STAT, mac_idx); ++ int ret = 0; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ if (!enable) { ++ rtw89_write32_clr(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN); ++ return ret; ++ } ++ ++ rtw89_write32(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN | ++ B_AX_APP_MAC_INFO_RPT | ++ B_AX_APP_RX_CNT_RPT | B_AX_APP_PLCP_HDR_RPT | ++ B_AX_PPDU_STAT_RPT_CRC32); ++ rtw89_write32_mask(rtwdev, R_AX_HW_RPT_FWD, B_AX_FWD_PPDU_STAT_MASK, ++ RTW89_PRPT_DEST_HOST); ++ ++ return ret; ++} ++ ++void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++#define MAC_AX_TIME_TH_SH 5 ++#define MAC_AX_LEN_TH_SH 4 ++#define MAC_AX_TIME_TH_MAX 255 ++#define MAC_AX_LEN_TH_MAX 255 ++#define MAC_AX_TIME_TH_DEF 88 ++#define MAC_AX_LEN_TH_DEF 4080 ++ struct ieee80211_hw *hw = rtwdev->hw; ++ u32 rts_threshold = hw->wiphy->rts_threshold; ++ u32 time_th, len_th; ++ u32 reg; ++ ++ if (rts_threshold == (u32)-1) { ++ time_th = MAC_AX_TIME_TH_DEF; ++ len_th = MAC_AX_LEN_TH_DEF; ++ } else { ++ time_th = MAC_AX_TIME_TH_MAX << MAC_AX_TIME_TH_SH; ++ len_th = rts_threshold; ++ } ++ ++ time_th = min_t(u32, time_th >> MAC_AX_TIME_TH_SH, MAC_AX_TIME_TH_MAX); ++ len_th = min_t(u32, len_th >> MAC_AX_LEN_TH_SH, MAC_AX_LEN_TH_MAX); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_AGG_LEN_HT_0, mac_idx); ++ rtw89_write16_mask(rtwdev, reg, B_AX_RTS_TXTIME_TH_MASK, time_th); ++ rtw89_write16_mask(rtwdev, reg, B_AX_RTS_LEN_TH_MASK, len_th); ++} ++ ++void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop) ++{ ++ bool empty; ++ int ret; ++ ++ if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) ++ return; ++ ++ ret = read_poll_timeout(dle_is_txq_empty, empty, empty, ++ 10000, 200000, false, rtwdev); ++ if (ret && !drop && (rtwdev->total_sta_assoc || rtwdev->scanning)) ++ rtw89_info(rtwdev, "timed out to flush queues\n"); ++} ++ ++int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex) ++{ ++ u8 val; ++ u16 val16; ++ u32 val32; ++ int ret; ++ ++ rtw89_write8_set(rtwdev, R_AX_GPIO_MUXCFG, B_AX_ENBT); ++ rtw89_write8_set(rtwdev, R_AX_BTC_FUNC_EN, B_AX_PTA_WL_TX_EN); ++ rtw89_write8_set(rtwdev, R_AX_BT_COEX_CFG_2 + 1, B_AX_GNT_BT_POLARITY >> 8); ++ rtw89_write8_set(rtwdev, R_AX_CSR_MODE, B_AX_STATIS_BT_EN | B_AX_WL_ACT_MSK); ++ rtw89_write8_set(rtwdev, R_AX_CSR_MODE + 2, B_AX_BT_CNT_RST >> 16); ++ rtw89_write8_clr(rtwdev, R_AX_TRXPTCL_RESP_0 + 3, B_AX_RSP_CHK_BTCCA >> 24); ++ ++ val16 = rtw89_read16(rtwdev, R_AX_CCA_CFG_0); ++ val16 = (val16 | B_AX_BTCCA_EN) & ~B_AX_BTCCA_BRK_TXOP_EN; ++ rtw89_write16(rtwdev, R_AX_CCA_CFG_0, val16); ++ ++ ret = rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_2, &val32); ++ if (ret) { ++ rtw89_err(rtwdev, "Read R_AX_LTE_SW_CFG_2 fail!\n"); ++ return ret; ++ } ++ val32 = val32 & B_AX_WL_RX_CTRL; ++ ret = rtw89_mac_write_lte(rtwdev, R_AX_LTE_SW_CFG_2, val32); ++ if (ret) { ++ rtw89_err(rtwdev, "Write R_AX_LTE_SW_CFG_2 fail!\n"); ++ return ret; ++ } ++ ++ switch (coex->pta_mode) { ++ case RTW89_MAC_AX_COEX_RTK_MODE: ++ val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG); ++ val &= ~B_AX_BTMODE_MASK; ++ val |= FIELD_PREP(B_AX_BTMODE_MASK, MAC_AX_BT_MODE_0_3); ++ rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG, val); ++ ++ val = rtw89_read8(rtwdev, R_AX_TDMA_MODE); ++ rtw89_write8(rtwdev, R_AX_TDMA_MODE, val | B_AX_RTK_BT_ENABLE); ++ ++ val = rtw89_read8(rtwdev, R_AX_BT_COEX_CFG_5); ++ val &= ~B_AX_BT_RPT_SAMPLE_RATE_MASK; ++ val |= FIELD_PREP(B_AX_BT_RPT_SAMPLE_RATE_MASK, MAC_AX_RTK_RATE); ++ rtw89_write8(rtwdev, R_AX_BT_COEX_CFG_5, val); ++ break; ++ case RTW89_MAC_AX_COEX_CSR_MODE: ++ val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG); ++ val &= ~B_AX_BTMODE_MASK; ++ val |= FIELD_PREP(B_AX_BTMODE_MASK, MAC_AX_BT_MODE_2); ++ rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG, val); ++ ++ val16 = rtw89_read16(rtwdev, R_AX_CSR_MODE); ++ val16 &= ~B_AX_BT_PRI_DETECT_TO_MASK; ++ val16 |= FIELD_PREP(B_AX_BT_PRI_DETECT_TO_MASK, MAC_AX_CSR_PRI_TO); ++ val16 &= ~B_AX_BT_TRX_INIT_DETECT_MASK; ++ val16 |= FIELD_PREP(B_AX_BT_TRX_INIT_DETECT_MASK, MAC_AX_CSR_TRX_TO); ++ val16 &= ~B_AX_BT_STAT_DELAY_MASK; ++ val16 |= FIELD_PREP(B_AX_BT_STAT_DELAY_MASK, MAC_AX_CSR_DELAY); ++ val16 |= B_AX_ENHANCED_BT; ++ rtw89_write16(rtwdev, R_AX_CSR_MODE, val16); ++ ++ rtw89_write8(rtwdev, R_AX_BT_COEX_CFG_2, MAC_AX_CSR_RATE); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ switch (coex->direction) { ++ case RTW89_MAC_AX_COEX_INNER: ++ val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG + 1); ++ val = (val & ~BIT(2)) | BIT(1); ++ rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG + 1, val); ++ break; ++ case RTW89_MAC_AX_COEX_OUTPUT: ++ val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG + 1); ++ val = val | BIT(1) | BIT(0); ++ rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG + 1, val); ++ break; ++ case RTW89_MAC_AX_COEX_INPUT: ++ val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG + 1); ++ val = val & ~(BIT(2) | BIT(1)); ++ rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG + 1, val); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++int rtw89_mac_cfg_gnt(struct rtw89_dev *rtwdev, ++ const struct rtw89_mac_ax_coex_gnt *gnt_cfg) ++{ ++ u32 val, ret; ++ ++ ret = rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_1, &val); ++ if (ret) { ++ rtw89_err(rtwdev, "Read LTE fail!\n"); ++ return ret; ++ } ++ val = (gnt_cfg->band[0].gnt_bt ? ++ B_AX_GNT_BT_RFC_S0_SW_VAL | B_AX_GNT_BT_BB_S0_SW_VAL : 0) | ++ (gnt_cfg->band[0].gnt_bt_sw_en ? ++ B_AX_GNT_BT_RFC_S0_SW_CTRL | B_AX_GNT_BT_BB_S0_SW_CTRL : 0) | ++ (gnt_cfg->band[0].gnt_wl ? ++ B_AX_GNT_WL_RFC_S0_SW_VAL | B_AX_GNT_WL_BB_S0_SW_VAL : 0) | ++ (gnt_cfg->band[0].gnt_wl_sw_en ? ++ B_AX_GNT_WL_RFC_S0_SW_CTRL | B_AX_GNT_WL_BB_S0_SW_CTRL : 0) | ++ (gnt_cfg->band[1].gnt_bt ? ++ B_AX_GNT_BT_RFC_S1_SW_VAL | B_AX_GNT_BT_BB_S1_SW_VAL : 0) | ++ (gnt_cfg->band[1].gnt_bt_sw_en ? ++ B_AX_GNT_BT_RFC_S1_SW_CTRL | B_AX_GNT_BT_BB_S1_SW_CTRL : 0) | ++ (gnt_cfg->band[1].gnt_wl ? ++ B_AX_GNT_WL_RFC_S1_SW_VAL | B_AX_GNT_WL_BB_S1_SW_VAL : 0) | ++ (gnt_cfg->band[1].gnt_wl_sw_en ? ++ B_AX_GNT_WL_RFC_S1_SW_CTRL | B_AX_GNT_WL_BB_S1_SW_CTRL : 0); ++ ret = rtw89_mac_write_lte(rtwdev, R_AX_LTE_SW_CFG_1, val); ++ if (ret) { ++ rtw89_err(rtwdev, "Write LTE fail!\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++int rtw89_mac_cfg_plt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt) ++{ ++ u32 reg; ++ u8 val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, plt->band, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_BT_PLT, plt->band); ++ val = (plt->tx & RTW89_MAC_AX_PLT_LTE_RX ? B_AX_TX_PLT_GNT_LTE_RX : 0) | ++ (plt->tx & RTW89_MAC_AX_PLT_GNT_BT_TX ? B_AX_TX_PLT_GNT_BT_TX : 0) | ++ (plt->tx & RTW89_MAC_AX_PLT_GNT_BT_RX ? B_AX_TX_PLT_GNT_BT_RX : 0) | ++ (plt->tx & RTW89_MAC_AX_PLT_GNT_WL ? B_AX_TX_PLT_GNT_WL : 0) | ++ (plt->rx & RTW89_MAC_AX_PLT_LTE_RX ? B_AX_RX_PLT_GNT_LTE_RX : 0) | ++ (plt->rx & RTW89_MAC_AX_PLT_GNT_BT_TX ? B_AX_RX_PLT_GNT_BT_TX : 0) | ++ (plt->rx & RTW89_MAC_AX_PLT_GNT_BT_RX ? B_AX_RX_PLT_GNT_BT_RX : 0) | ++ (plt->rx & RTW89_MAC_AX_PLT_GNT_WL ? B_AX_RX_PLT_GNT_WL : 0); ++ rtw89_write8(rtwdev, reg, val); ++ ++ return 0; ++} ++ ++void rtw89_mac_cfg_sb(struct rtw89_dev *rtwdev, u32 val) ++{ ++ u32 fw_sb; ++ ++ fw_sb = rtw89_read32(rtwdev, R_AX_SCOREBOARD); ++ fw_sb = FIELD_GET(B_MAC_AX_SB_FW_MASK, fw_sb); ++ fw_sb = fw_sb & ~B_MAC_AX_BTGS1_NOTIFY; ++ if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) ++ fw_sb = fw_sb | MAC_AX_NOTIFY_PWR_MAJOR; ++ else ++ fw_sb = fw_sb | MAC_AX_NOTIFY_TP_MAJOR; ++ val = FIELD_GET(B_MAC_AX_SB_DRV_MASK, val); ++ val = B_AX_TOGGLE | ++ FIELD_PREP(B_MAC_AX_SB_DRV_MASK, val) | ++ FIELD_PREP(B_MAC_AX_SB_FW_MASK, fw_sb); ++ rtw89_write32(rtwdev, R_AX_SCOREBOARD, val); ++ fsleep(1000); /* avoid BT FW loss information */ ++} ++ ++u32 rtw89_mac_get_sb(struct rtw89_dev *rtwdev) ++{ ++ return rtw89_read32(rtwdev, R_AX_SCOREBOARD); ++} ++ ++int rtw89_mac_cfg_ctrl_path(struct rtw89_dev *rtwdev, bool wl) ++{ ++ u8 val = rtw89_read8(rtwdev, R_AX_SYS_SDIO_CTRL + 3); ++ ++ val = wl ? val | BIT(2) : val & ~BIT(2); ++ rtw89_write8(rtwdev, R_AX_SYS_SDIO_CTRL + 3, val); ++ ++ return 0; ++} ++ ++bool rtw89_mac_get_ctrl_path(struct rtw89_dev *rtwdev) ++{ ++ u8 val = rtw89_read8(rtwdev, R_AX_SYS_SDIO_CTRL + 3); ++ ++ return FIELD_GET(B_AX_LTE_MUX_CTRL_PATH >> 24, val); ++} ++ ++static void rtw89_mac_bfee_ctrl(struct rtw89_dev *rtwdev, u8 mac_idx, bool en) ++{ ++ u32 reg; ++ u32 mask = B_AX_BFMEE_HT_NDPA_EN | B_AX_BFMEE_VHT_NDPA_EN | ++ B_AX_BFMEE_HE_NDPA_EN; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BF, "set bfee ndpa_en to %d\n", en); ++ reg = rtw89_mac_reg_by_idx(R_AX_BFMEE_RESP_OPTION, mac_idx); ++ if (en) { ++ set_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags); ++ rtw89_write32_set(rtwdev, reg, mask); ++ } else { ++ clear_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags); ++ rtw89_write32_clr(rtwdev, reg, mask); ++ } ++} ++ ++static int rtw89_mac_init_bfee(struct rtw89_dev *rtwdev, u8 mac_idx) ++{ ++ u32 reg; ++ u32 val32; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ /* AP mode set tx gid to 63 */ ++ /* STA mode set tx gid to 0(default) */ ++ reg = rtw89_mac_reg_by_idx(R_AX_BFMER_CTRL_0, mac_idx); ++ rtw89_write32_set(rtwdev, reg, B_AX_BFMER_NDP_BFEN); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_RRSC, mac_idx); ++ rtw89_write32(rtwdev, reg, CSI_RRSC_BMAP); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_BFMEE_RESP_OPTION, mac_idx); ++ val32 = FIELD_PREP(B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK, BFRP_RX_STANDBY_TIMER); ++ val32 |= FIELD_PREP(B_AX_BFMEE_NDP_RX_STANDBY_TIMER_MASK, NDP_RX_STANDBY_TIMER); ++ rtw89_write32(rtwdev, reg, val32); ++ rtw89_mac_bfee_ctrl(rtwdev, mac_idx, true); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); ++ rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL | ++ B_AX_BFMEE_USE_NSTS | ++ B_AX_BFMEE_CSI_GID_SEL | ++ B_AX_BFMEE_CSI_FORCE_RETE_EN); ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_RATE, mac_idx); ++ rtw89_write32(rtwdev, reg, ++ u32_encode_bits(CSI_INIT_RATE_HT, B_AX_BFMEE_HT_CSI_RATE_MASK) | ++ u32_encode_bits(CSI_INIT_RATE_VHT, B_AX_BFMEE_VHT_CSI_RATE_MASK) | ++ u32_encode_bits(CSI_INIT_RATE_HE, B_AX_BFMEE_HE_CSI_RATE_MASK)); ++ ++ return 0; ++} ++ ++static int rtw89_mac_set_csi_para_reg(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ u8 mac_idx = rtwvif->mac_idx; ++ u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1; ++ u8 port_sel = rtwvif->port; ++ u8 sound_dim = 3, t; ++ u8 *phy_cap = sta->he_cap.he_cap_elem.phy_cap_info; ++ u32 reg; ++ u16 val; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ if ((phy_cap[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) || ++ (phy_cap[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) { ++ ldpc_en &= !!(phy_cap[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD); ++ stbc_en &= !!(phy_cap[2] & IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ); ++ t = FIELD_GET(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK, ++ phy_cap[5]); ++ sound_dim = min(sound_dim, t); ++ } ++ if ((sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || ++ (sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) { ++ ldpc_en &= !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); ++ stbc_en &= !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK); ++ t = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK, ++ sta->vht_cap.cap); ++ sound_dim = min(sound_dim, t); ++ } ++ nc = min(nc, sound_dim); ++ nr = min(nr, sound_dim); ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); ++ rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL); ++ ++ val = FIELD_PREP(B_AX_BFMEE_CSIINFO0_NC_MASK, nc) | ++ FIELD_PREP(B_AX_BFMEE_CSIINFO0_NR_MASK, nr) | ++ FIELD_PREP(B_AX_BFMEE_CSIINFO0_NG_MASK, ng) | ++ FIELD_PREP(B_AX_BFMEE_CSIINFO0_CB_MASK, cb) | ++ FIELD_PREP(B_AX_BFMEE_CSIINFO0_CS_MASK, cs) | ++ FIELD_PREP(B_AX_BFMEE_CSIINFO0_LDPC_EN, ldpc_en) | ++ FIELD_PREP(B_AX_BFMEE_CSIINFO0_STBC_EN, stbc_en); ++ ++ if (port_sel == 0) ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); ++ else ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_1, mac_idx); ++ ++ rtw89_write16(rtwdev, reg, val); ++ ++ return 0; ++} ++ ++static int rtw89_mac_csi_rrsc(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M); ++ u32 reg; ++ u8 mac_idx = rtwvif->mac_idx; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ if (sta->he_cap.has_he) { ++ rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) | ++ BIT(RTW89_MAC_BF_RRSC_HE_MSC3) | ++ BIT(RTW89_MAC_BF_RRSC_HE_MSC5)); ++ } ++ if (sta->vht_cap.vht_supported) { ++ rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) | ++ BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) | ++ BIT(RTW89_MAC_BF_RRSC_VHT_MSC5)); ++ } ++ if (sta->ht_cap.ht_supported) { ++ rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) | ++ BIT(RTW89_MAC_BF_RRSC_HT_MSC3) | ++ BIT(RTW89_MAC_BF_RRSC_HT_MSC5)); ++ } ++ reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); ++ rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL); ++ rtw89_write32_clr(rtwdev, reg, B_AX_BFMEE_CSI_FORCE_RETE_EN); ++ rtw89_write32(rtwdev, ++ rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_RRSC, mac_idx), ++ rrsc); ++ ++ return 0; ++} ++ ++void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ ++ if (rtw89_sta_has_beamformer_cap(sta)) { ++ rtw89_debug(rtwdev, RTW89_DBG_BF, ++ "initialize bfee for new association\n"); ++ rtw89_mac_init_bfee(rtwdev, rtwvif->mac_idx); ++ rtw89_mac_set_csi_para_reg(rtwdev, vif, sta); ++ rtw89_mac_csi_rrsc(rtwdev, vif, sta); ++ } ++} ++ ++void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ ++ rtw89_mac_bfee_ctrl(rtwdev, rtwvif->mac_idx, false); ++} ++ ++void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ++ struct ieee80211_bss_conf *conf) ++{ ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ u8 mac_idx = rtwvif->mac_idx; ++ __le32 *p; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BF, "update bf GID table\n"); ++ ++ p = (__le32 *)conf->mu_group.membership; ++ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION_EN0, mac_idx), ++ le32_to_cpu(p[0])); ++ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION_EN1, mac_idx), ++ le32_to_cpu(p[1])); ++ ++ p = (__le32 *)conf->mu_group.position; ++ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION0, mac_idx), ++ le32_to_cpu(p[0])); ++ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION1, mac_idx), ++ le32_to_cpu(p[1])); ++ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION2, mac_idx), ++ le32_to_cpu(p[2])); ++ rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION3, mac_idx), ++ le32_to_cpu(p[3])); ++} ++ ++struct rtw89_mac_bf_monitor_iter_data { ++ struct rtw89_dev *rtwdev; ++ struct ieee80211_sta *down_sta; ++ int count; ++}; ++ ++static ++void rtw89_mac_bf_monitor_calc_iter(void *data, struct ieee80211_sta *sta) ++{ ++ struct rtw89_mac_bf_monitor_iter_data *iter_data = ++ (struct rtw89_mac_bf_monitor_iter_data *)data; ++ struct ieee80211_sta *down_sta = iter_data->down_sta; ++ int *count = &iter_data->count; ++ ++ if (down_sta == sta) ++ return; ++ ++ if (rtw89_sta_has_beamformer_cap(sta)) ++ (*count)++; ++} ++ ++void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev, ++ struct ieee80211_sta *sta, bool disconnect) ++{ ++ struct rtw89_mac_bf_monitor_iter_data data; ++ ++ data.rtwdev = rtwdev; ++ data.down_sta = disconnect ? sta : NULL; ++ data.count = 0; ++ ieee80211_iterate_stations_atomic(rtwdev->hw, ++ rtw89_mac_bf_monitor_calc_iter, ++ &data); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_BF, "bfee STA count=%d\n", data.count); ++ if (data.count) ++ set_bit(RTW89_FLAG_BFEE_MON, rtwdev->flags); ++ else ++ clear_bit(RTW89_FLAG_BFEE_MON, rtwdev->flags); ++} ++ ++void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_traffic_stats *stats = &rtwdev->stats; ++ struct rtw89_vif *rtwvif; ++ bool en = stats->tx_tfc_lv > stats->rx_tfc_lv ? false : true; ++ bool old = test_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags); ++ ++ if (en == old) ++ return; ++ ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ rtw89_mac_bfee_ctrl(rtwdev, rtwvif->mac_idx, en); ++} ++ ++static int ++__rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, ++ u32 tx_time) ++{ ++#define MAC_AX_DFLT_TX_TIME 5280 ++ u8 mac_idx = rtwsta->rtwvif->mac_idx; ++ u32 max_tx_time = tx_time == 0 ? MAC_AX_DFLT_TX_TIME : tx_time; ++ u32 reg; ++ int ret = 0; ++ ++ if (rtwsta->cctl_tx_time) { ++ rtwsta->ampdu_max_time = (max_tx_time - 512) >> 9; ++ ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta); ++ } else { ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to check cmac in set txtime\n"); ++ return ret; ++ } ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_AMPDU_AGG_LIMIT, mac_idx); ++ rtw89_write32_mask(rtwdev, reg, B_AX_AMPDU_MAX_TIME_MASK, ++ max_tx_time >> 5); ++ } ++ ++ return ret; ++} ++ ++int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, ++ bool resume, u32 tx_time) ++{ ++ int ret = 0; ++ ++ if (!resume) { ++ rtwsta->cctl_tx_time = true; ++ ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta, tx_time); ++ } else { ++ ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta, tx_time); ++ rtwsta->cctl_tx_time = false; ++ } ++ ++ return ret; ++} ++ ++int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, ++ u32 *tx_time) ++{ ++ u8 mac_idx = rtwsta->rtwvif->mac_idx; ++ u32 reg; ++ int ret = 0; ++ ++ if (rtwsta->cctl_tx_time) { ++ *tx_time = (rtwsta->ampdu_max_time + 1) << 9; ++ } else { ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to check cmac in tx_time\n"); ++ return ret; ++ } ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_AMPDU_AGG_LIMIT, mac_idx); ++ *tx_time = rtw89_read32_mask(rtwdev, reg, B_AX_AMPDU_MAX_TIME_MASK) << 5; ++ } ++ ++ return ret; ++} ++ ++int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev, ++ struct rtw89_sta *rtwsta, ++ bool resume, u8 tx_retry) ++{ ++ int ret = 0; ++ ++ rtwsta->data_tx_cnt_lmt = tx_retry; ++ ++ if (!resume) { ++ rtwsta->cctl_tx_retry_limit = true; ++ ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta); ++ } else { ++ ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta); ++ rtwsta->cctl_tx_retry_limit = false; ++ } ++ ++ return ret; ++} ++ ++int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev, ++ struct rtw89_sta *rtwsta, u8 *tx_retry) ++{ ++ u8 mac_idx = rtwsta->rtwvif->mac_idx; ++ u32 reg; ++ int ret = 0; ++ ++ if (rtwsta->cctl_tx_retry_limit) { ++ *tx_retry = rtwsta->data_tx_cnt_lmt; ++ } else { ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to check cmac in rty_lmt\n"); ++ return ret; ++ } ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_TXCNT, mac_idx); ++ *tx_retry = rtw89_read32_mask(rtwdev, reg, B_AX_L_TXCNT_LMT_MASK); ++ } ++ ++ return ret; ++} ++ ++int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, bool en) ++{ ++ u8 mac_idx = rtwvif->mac_idx; ++ u16 set = B_AX_MUEDCA_EN_0 | B_AX_SET_MUEDCATIMER_TF_0; ++ u32 reg; ++ u32 ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ reg = rtw89_mac_reg_by_idx(R_AX_MUEDCA_EN, mac_idx); ++ if (en) ++ rtw89_write16_set(rtwdev, reg, set); ++ else ++ rtw89_write16_clr(rtwdev, reg, set); ++ ++ return 0; ++} +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +new file mode 100644 +index 000000000000..6f3db8a2a9c2 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -0,0 +1,860 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_MAC_H__ ++#define __RTW89_MAC_H__ ++ ++#include "core.h" ++ ++#define MAC_MEM_DUMP_PAGE_SIZE 0x40000 ++#define ADDR_CAM_ENT_SIZE 0x40 ++#define BSSID_CAM_ENT_SIZE 0x08 ++#define HFC_PAGE_UNIT 64 ++ ++enum rtw89_mac_hwmod_sel { ++ RTW89_DMAC_SEL = 0, ++ RTW89_CMAC_SEL = 1, ++ ++ RTW89_MAC_INVALID, ++}; ++ ++enum rtw89_mac_fwd_target { ++ RTW89_FWD_DONT_CARE = 0, ++ RTW89_FWD_TO_HOST = 1, ++ RTW89_FWD_TO_WLAN_CPU = 2 ++}; ++ ++enum rtw89_mac_wd_dma_intvl { ++ RTW89_MAC_WD_DMA_INTVL_0S, ++ RTW89_MAC_WD_DMA_INTVL_256NS, ++ RTW89_MAC_WD_DMA_INTVL_512NS, ++ RTW89_MAC_WD_DMA_INTVL_768NS, ++ RTW89_MAC_WD_DMA_INTVL_1US, ++ RTW89_MAC_WD_DMA_INTVL_1_5US, ++ RTW89_MAC_WD_DMA_INTVL_2US, ++ RTW89_MAC_WD_DMA_INTVL_4US, ++ RTW89_MAC_WD_DMA_INTVL_8US, ++ RTW89_MAC_WD_DMA_INTVL_16US, ++ RTW89_MAC_WD_DMA_INTVL_DEF = 0xFE ++}; ++ ++enum rtw89_mac_multi_tag_num { ++ RTW89_MAC_TAG_NUM_1, ++ RTW89_MAC_TAG_NUM_2, ++ RTW89_MAC_TAG_NUM_3, ++ RTW89_MAC_TAG_NUM_4, ++ RTW89_MAC_TAG_NUM_5, ++ RTW89_MAC_TAG_NUM_6, ++ RTW89_MAC_TAG_NUM_7, ++ RTW89_MAC_TAG_NUM_8, ++ RTW89_MAC_TAG_NUM_DEF = 0xFE ++}; ++ ++enum rtw89_mac_lbc_tmr { ++ RTW89_MAC_LBC_TMR_8US = 0, ++ RTW89_MAC_LBC_TMR_16US, ++ RTW89_MAC_LBC_TMR_32US, ++ RTW89_MAC_LBC_TMR_64US, ++ RTW89_MAC_LBC_TMR_128US, ++ RTW89_MAC_LBC_TMR_256US, ++ RTW89_MAC_LBC_TMR_512US, ++ RTW89_MAC_LBC_TMR_1MS, ++ RTW89_MAC_LBC_TMR_2MS, ++ RTW89_MAC_LBC_TMR_4MS, ++ RTW89_MAC_LBC_TMR_8MS, ++ RTW89_MAC_LBC_TMR_DEF = 0xFE ++}; ++ ++enum rtw89_mac_cpuio_op_cmd_type { ++ CPUIO_OP_CMD_GET_1ST_PID = 0, ++ CPUIO_OP_CMD_GET_NEXT_PID = 1, ++ CPUIO_OP_CMD_ENQ_TO_TAIL = 4, ++ CPUIO_OP_CMD_ENQ_TO_HEAD = 5, ++ CPUIO_OP_CMD_DEQ = 8, ++ CPUIO_OP_CMD_DEQ_ENQ_ALL = 9, ++ CPUIO_OP_CMD_DEQ_ENQ_TO_TAIL = 12 ++}; ++ ++enum rtw89_mac_wde_dle_port_id { ++ WDE_DLE_PORT_ID_DISPATCH = 0, ++ WDE_DLE_PORT_ID_PKTIN = 1, ++ WDE_DLE_PORT_ID_CMAC0 = 3, ++ WDE_DLE_PORT_ID_CMAC1 = 4, ++ WDE_DLE_PORT_ID_CPU_IO = 6, ++ WDE_DLE_PORT_ID_WDRLS = 7, ++ WDE_DLE_PORT_ID_END = 8 ++}; ++ ++enum rtw89_mac_wde_dle_queid_wdrls { ++ WDE_DLE_QUEID_TXOK = 0, ++ WDE_DLE_QUEID_DROP_RETRY_LIMIT = 1, ++ WDE_DLE_QUEID_DROP_LIFETIME_TO = 2, ++ WDE_DLE_QUEID_DROP_MACID_DROP = 3, ++ WDE_DLE_QUEID_NO_REPORT = 4 ++}; ++ ++enum rtw89_mac_ple_dle_port_id { ++ PLE_DLE_PORT_ID_DISPATCH = 0, ++ PLE_DLE_PORT_ID_MPDU = 1, ++ PLE_DLE_PORT_ID_SEC = 2, ++ PLE_DLE_PORT_ID_CMAC0 = 3, ++ PLE_DLE_PORT_ID_CMAC1 = 4, ++ PLE_DLE_PORT_ID_WDRLS = 5, ++ PLE_DLE_PORT_ID_CPU_IO = 6, ++ PLE_DLE_PORT_ID_PLRLS = 7, ++ PLE_DLE_PORT_ID_END = 8 ++}; ++ ++enum rtw89_mac_ple_dle_queid_plrls { ++ PLE_DLE_QUEID_NO_REPORT = 0x0 ++}; ++ ++enum rtw89_machdr_frame_type { ++ RTW89_MGNT = 0, ++ RTW89_CTRL = 1, ++ RTW89_DATA = 2, ++}; ++ ++enum rtw89_mac_dle_dfi_type { ++ DLE_DFI_TYPE_FREEPG = 0, ++ DLE_DFI_TYPE_QUOTA = 1, ++ DLE_DFI_TYPE_PAGELLT = 2, ++ DLE_DFI_TYPE_PKTINFO = 3, ++ DLE_DFI_TYPE_PREPKTLLT = 4, ++ DLE_DFI_TYPE_NXTPKTLLT = 5, ++ DLE_DFI_TYPE_QLNKTBL = 6, ++ DLE_DFI_TYPE_QEMPTY = 7, ++}; ++ ++enum rtw89_mac_dle_wde_quota_id { ++ WDE_QTAID_HOST_IF = 0, ++ WDE_QTAID_WLAN_CPU = 1, ++ WDE_QTAID_DATA_CPU = 2, ++ WDE_QTAID_PKTIN = 3, ++ WDE_QTAID_CPUIO = 4, ++}; ++ ++enum rtw89_mac_dle_ple_quota_id { ++ PLE_QTAID_B0_TXPL = 0, ++ PLE_QTAID_B1_TXPL = 1, ++ PLE_QTAID_C2H = 2, ++ PLE_QTAID_H2C = 3, ++ PLE_QTAID_WLAN_CPU = 4, ++ PLE_QTAID_MPDU = 5, ++ PLE_QTAID_CMAC0_RX = 6, ++ PLE_QTAID_CMAC1_RX = 7, ++ PLE_QTAID_CMAC1_BBRPT = 8, ++ PLE_QTAID_WDRLS = 9, ++ PLE_QTAID_CPUIO = 10, ++}; ++ ++enum rtw89_mac_dle_ctrl_type { ++ DLE_CTRL_TYPE_WDE = 0, ++ DLE_CTRL_TYPE_PLE = 1, ++ DLE_CTRL_TYPE_NUM = 2, ++}; ++ ++enum rtw89_mac_ax_l0_to_l1_event { ++ MAC_AX_L0_TO_L1_CHIF_IDLE = 0, ++ MAC_AX_L0_TO_L1_CMAC_DMA_IDLE = 1, ++ MAC_AX_L0_TO_L1_RLS_PKID = 2, ++ MAC_AX_L0_TO_L1_PTCL_IDLE = 3, ++ MAC_AX_L0_TO_L1_RX_QTA_LOST = 4, ++ MAC_AX_L0_TO_L1_DLE_STAT_HANG = 5, ++ MAC_AX_L0_TO_L1_PCIE_STUCK = 6, ++ MAC_AX_L0_TO_L1_EVENT_MAX = 15, ++}; ++ ++enum rtw89_mac_dbg_port_sel { ++ /* CMAC 0 related */ ++ RTW89_DBG_PORT_SEL_PTCL_C0 = 0, ++ RTW89_DBG_PORT_SEL_SCH_C0, ++ RTW89_DBG_PORT_SEL_TMAC_C0, ++ RTW89_DBG_PORT_SEL_RMAC_C0, ++ RTW89_DBG_PORT_SEL_RMACST_C0, ++ RTW89_DBG_PORT_SEL_RMAC_PLCP_C0, ++ RTW89_DBG_PORT_SEL_TRXPTCL_C0, ++ RTW89_DBG_PORT_SEL_TX_INFOL_C0, ++ RTW89_DBG_PORT_SEL_TX_INFOH_C0, ++ RTW89_DBG_PORT_SEL_TXTF_INFOL_C0, ++ RTW89_DBG_PORT_SEL_TXTF_INFOH_C0, ++ /* CMAC 1 related */ ++ RTW89_DBG_PORT_SEL_PTCL_C1, ++ RTW89_DBG_PORT_SEL_SCH_C1, ++ RTW89_DBG_PORT_SEL_TMAC_C1, ++ RTW89_DBG_PORT_SEL_RMAC_C1, ++ RTW89_DBG_PORT_SEL_RMACST_C1, ++ RTW89_DBG_PORT_SEL_RMAC_PLCP_C1, ++ RTW89_DBG_PORT_SEL_TRXPTCL_C1, ++ RTW89_DBG_PORT_SEL_TX_INFOL_C1, ++ RTW89_DBG_PORT_SEL_TX_INFOH_C1, ++ RTW89_DBG_PORT_SEL_TXTF_INFOL_C1, ++ RTW89_DBG_PORT_SEL_TXTF_INFOH_C1, ++ /* DLE related */ ++ RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG, ++ RTW89_DBG_PORT_SEL_WDE_BUFMGN_QUOTA, ++ RTW89_DBG_PORT_SEL_WDE_BUFMGN_PAGELLT, ++ RTW89_DBG_PORT_SEL_WDE_BUFMGN_PKTINFO, ++ RTW89_DBG_PORT_SEL_WDE_QUEMGN_PREPKT, ++ RTW89_DBG_PORT_SEL_WDE_QUEMGN_NXTPKT, ++ RTW89_DBG_PORT_SEL_WDE_QUEMGN_QLNKTBL, ++ RTW89_DBG_PORT_SEL_WDE_QUEMGN_QEMPTY, ++ RTW89_DBG_PORT_SEL_PLE_BUFMGN_FREEPG, ++ RTW89_DBG_PORT_SEL_PLE_BUFMGN_QUOTA, ++ RTW89_DBG_PORT_SEL_PLE_BUFMGN_PAGELLT, ++ RTW89_DBG_PORT_SEL_PLE_BUFMGN_PKTINFO, ++ RTW89_DBG_PORT_SEL_PLE_QUEMGN_PREPKT, ++ RTW89_DBG_PORT_SEL_PLE_QUEMGN_NXTPKT, ++ RTW89_DBG_PORT_SEL_PLE_QUEMGN_QLNKTBL, ++ RTW89_DBG_PORT_SEL_PLE_QUEMGN_QEMPTY, ++ RTW89_DBG_PORT_SEL_PKTINFO, ++ /* PCIE related */ ++ RTW89_DBG_PORT_SEL_PCIE_TXDMA, ++ RTW89_DBG_PORT_SEL_PCIE_RXDMA, ++ RTW89_DBG_PORT_SEL_PCIE_CVT, ++ RTW89_DBG_PORT_SEL_PCIE_CXPL, ++ RTW89_DBG_PORT_SEL_PCIE_IO, ++ RTW89_DBG_PORT_SEL_PCIE_MISC, ++ RTW89_DBG_PORT_SEL_PCIE_MISC2, ++ ++ /* keep last */ ++ RTW89_DBG_PORT_SEL_LAST, ++ RTW89_DBG_PORT_SEL_MAX = RTW89_DBG_PORT_SEL_LAST, ++ RTW89_DBG_PORT_SEL_INVALID = RTW89_DBG_PORT_SEL_LAST, ++}; ++ ++/* SRAM mem dump */ ++#define R_AX_INDIR_ACCESS_ENTRY 0x40000 ++ ++#define STA_SCHED_BASE_ADDR 0x18808000 ++#define RXPLD_FLTR_CAM_BASE_ADDR 0x18813000 ++#define SECURITY_CAM_BASE_ADDR 0x18814000 ++#define WOW_CAM_BASE_ADDR 0x18815000 ++#define CMAC_TBL_BASE_ADDR 0x18840000 ++#define ADDR_CAM_BASE_ADDR 0x18850000 ++#define BSSID_CAM_BASE_ADDR 0x18853000 ++#define BA_CAM_BASE_ADDR 0x18854000 ++#define BCN_IE_CAM0_BASE_ADDR 0x18855000 ++#define SHARED_BUF_BASE_ADDR 0x18700000 ++#define DMAC_TBL_BASE_ADDR 0x18800000 ++#define SHCUT_MACHDR_BASE_ADDR 0x18800800 ++#define BCN_IE_CAM1_BASE_ADDR 0x188A0000 ++ ++#define CCTL_INFO_SIZE 32 ++ ++enum rtw89_mac_mem_sel { ++ RTW89_MAC_MEM_SHARED_BUF, ++ RTW89_MAC_MEM_DMAC_TBL, ++ RTW89_MAC_MEM_SHCUT_MACHDR, ++ RTW89_MAC_MEM_STA_SCHED, ++ RTW89_MAC_MEM_RXPLD_FLTR_CAM, ++ RTW89_MAC_MEM_SECURITY_CAM, ++ RTW89_MAC_MEM_WOW_CAM, ++ RTW89_MAC_MEM_CMAC_TBL, ++ RTW89_MAC_MEM_ADDR_CAM, ++ RTW89_MAC_MEM_BA_CAM, ++ RTW89_MAC_MEM_BCN_IE_CAM0, ++ RTW89_MAC_MEM_BCN_IE_CAM1, ++ ++ /* keep last */ ++ RTW89_MAC_MEM_LAST, ++ RTW89_MAC_MEM_MAX = RTW89_MAC_MEM_LAST, ++ RTW89_MAC_MEM_INVALID = RTW89_MAC_MEM_LAST, ++}; ++ ++enum rtw89_rpwm_req_pwr_state { ++ RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE = 0, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFON = 1, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_BAND1_RFON = 2, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFOFF = 3, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_BAND1_RFOFF = 4, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED = 5, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_PWR_GATED = 6, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_HIOE_PWR_GATED = 7, ++ RTW89_MAC_RPWM_REQ_PWR_STATE_MAX, ++}; ++ ++struct rtw89_pwr_cfg { ++ u16 addr; ++ u8 cv_msk; ++ u8 intf_msk; ++ u8 base:4; ++ u8 cmd:4; ++ u8 msk; ++ u8 val; ++}; ++ ++enum rtw89_mac_c2h_ofld_func { ++ RTW89_MAC_C2H_FUNC_EFUSE_DUMP, ++ RTW89_MAC_C2H_FUNC_READ_RSP, ++ RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP, ++ RTW89_MAC_C2H_FUNC_BCN_RESEND, ++ RTW89_MAC_C2H_FUNC_MACID_PAUSE, ++ RTW89_MAC_C2H_FUNC_OFLD_MAX, ++}; ++ ++enum rtw89_mac_c2h_info_func { ++ RTW89_MAC_C2H_FUNC_REC_ACK, ++ RTW89_MAC_C2H_FUNC_DONE_ACK, ++ RTW89_MAC_C2H_FUNC_C2H_LOG, ++ RTW89_MAC_C2H_FUNC_INFO_MAX, ++}; ++ ++enum rtw89_mac_c2h_class { ++ RTW89_MAC_C2H_CLASS_INFO, ++ RTW89_MAC_C2H_CLASS_OFLD, ++ RTW89_MAC_C2H_CLASS_TWT, ++ RTW89_MAC_C2H_CLASS_WOW, ++ RTW89_MAC_C2H_CLASS_MCC, ++ RTW89_MAC_C2H_CLASS_FWDBG, ++ RTW89_MAC_C2H_CLASS_MAX, ++}; ++ ++struct rtw89_mac_ax_coex { ++#define RTW89_MAC_AX_COEX_RTK_MODE 0 ++#define RTW89_MAC_AX_COEX_CSR_MODE 1 ++ u8 pta_mode; ++#define RTW89_MAC_AX_COEX_INNER 0 ++#define RTW89_MAC_AX_COEX_OUTPUT 1 ++#define RTW89_MAC_AX_COEX_INPUT 2 ++ u8 direction; ++}; ++ ++struct rtw89_mac_ax_plt { ++#define RTW89_MAC_AX_PLT_LTE_RX BIT(0) ++#define RTW89_MAC_AX_PLT_GNT_BT_TX BIT(1) ++#define RTW89_MAC_AX_PLT_GNT_BT_RX BIT(2) ++#define RTW89_MAC_AX_PLT_GNT_WL BIT(3) ++ u8 band; ++ u8 tx; ++ u8 rx; ++}; ++ ++enum rtw89_mac_bf_rrsc_rate { ++ RTW89_MAC_BF_RRSC_6M = 0, ++ RTW89_MAC_BF_RRSC_9M = 1, ++ RTW89_MAC_BF_RRSC_12M, ++ RTW89_MAC_BF_RRSC_18M, ++ RTW89_MAC_BF_RRSC_24M, ++ RTW89_MAC_BF_RRSC_36M, ++ RTW89_MAC_BF_RRSC_48M, ++ RTW89_MAC_BF_RRSC_54M, ++ RTW89_MAC_BF_RRSC_HT_MSC0, ++ RTW89_MAC_BF_RRSC_HT_MSC1, ++ RTW89_MAC_BF_RRSC_HT_MSC2, ++ RTW89_MAC_BF_RRSC_HT_MSC3, ++ RTW89_MAC_BF_RRSC_HT_MSC4, ++ RTW89_MAC_BF_RRSC_HT_MSC5, ++ RTW89_MAC_BF_RRSC_HT_MSC6, ++ RTW89_MAC_BF_RRSC_HT_MSC7, ++ RTW89_MAC_BF_RRSC_VHT_MSC0, ++ RTW89_MAC_BF_RRSC_VHT_MSC1, ++ RTW89_MAC_BF_RRSC_VHT_MSC2, ++ RTW89_MAC_BF_RRSC_VHT_MSC3, ++ RTW89_MAC_BF_RRSC_VHT_MSC4, ++ RTW89_MAC_BF_RRSC_VHT_MSC5, ++ RTW89_MAC_BF_RRSC_VHT_MSC6, ++ RTW89_MAC_BF_RRSC_VHT_MSC7, ++ RTW89_MAC_BF_RRSC_HE_MSC0, ++ RTW89_MAC_BF_RRSC_HE_MSC1, ++ RTW89_MAC_BF_RRSC_HE_MSC2, ++ RTW89_MAC_BF_RRSC_HE_MSC3, ++ RTW89_MAC_BF_RRSC_HE_MSC4, ++ RTW89_MAC_BF_RRSC_HE_MSC5, ++ RTW89_MAC_BF_RRSC_HE_MSC6, ++ RTW89_MAC_BF_RRSC_HE_MSC7 = 31, ++ RTW89_MAC_BF_RRSC_MAX = 32 ++}; ++ ++#define RTW89_R32_EA 0xEAEAEAEA ++#define RTW89_R32_DEAD 0xDEADBEEF ++#define MAC_REG_POOL_COUNT 10 ++#define ACCESS_CMAC(_addr) \ ++ ({typeof(_addr) __addr = (_addr); \ ++ __addr >= R_AX_CMAC_REG_START && __addr <= R_AX_CMAC_REG_END; }) ++ ++#define PTCL_IDLE_POLL_CNT 10000 ++#define SW_CVR_DUR_US 8 ++#define SW_CVR_CNT 8 ++ ++#define DLE_BOUND_UNIT (8 * 1024) ++#define DLE_WAIT_CNT 2000 ++#define TRXCFG_WAIT_CNT 2000 ++ ++#define RTW89_WDE_PG_64 64 ++#define RTW89_WDE_PG_128 128 ++#define RTW89_WDE_PG_256 256 ++ ++#define S_AX_WDE_PAGE_SEL_64 0 ++#define S_AX_WDE_PAGE_SEL_128 1 ++#define S_AX_WDE_PAGE_SEL_256 2 ++ ++#define RTW89_PLE_PG_64 64 ++#define RTW89_PLE_PG_128 128 ++#define RTW89_PLE_PG_256 256 ++ ++#define S_AX_PLE_PAGE_SEL_64 0 ++#define S_AX_PLE_PAGE_SEL_128 1 ++#define S_AX_PLE_PAGE_SEL_256 2 ++ ++#define SDIO_LOCAL_BASE_ADDR 0x80000000 ++ ++#define PWR_CMD_WRITE 0 ++#define PWR_CMD_POLL 1 ++#define PWR_CMD_DELAY 2 ++#define PWR_CMD_END 3 ++ ++#define PWR_INTF_MSK_SDIO BIT(0) ++#define PWR_INTF_MSK_USB BIT(1) ++#define PWR_INTF_MSK_PCIE BIT(2) ++#define PWR_INTF_MSK_ALL 0x7 ++ ++#define PWR_BASE_MAC 0 ++#define PWR_BASE_USB 1 ++#define PWR_BASE_PCIE 2 ++#define PWR_BASE_SDIO 3 ++ ++#define PWR_CV_MSK_A BIT(0) ++#define PWR_CV_MSK_B BIT(1) ++#define PWR_CV_MSK_C BIT(2) ++#define PWR_CV_MSK_D BIT(3) ++#define PWR_CV_MSK_E BIT(4) ++#define PWR_CV_MSK_F BIT(5) ++#define PWR_CV_MSK_G BIT(6) ++#define PWR_CV_MSK_TEST BIT(7) ++#define PWR_CV_MSK_ALL 0xFF ++ ++#define PWR_DELAY_US 0 ++#define PWR_DELAY_MS 1 ++ ++/* STA scheduler */ ++#define SS_MACID_SH 8 ++#define SS_TX_LEN_MSK 0x1FFFFF ++#define SS_CTRL1_R_TX_LEN 5 ++#define SS_CTRL1_R_NEXT_LINK 20 ++#define SS_LINK_SIZE 256 ++ ++/* MAC debug port */ ++#define TMAC_DBG_SEL_C0 0xA5 ++#define RMAC_DBG_SEL_C0 0xA6 ++#define TRXPTCL_DBG_SEL_C0 0xA7 ++#define TMAC_DBG_SEL_C1 0xB5 ++#define RMAC_DBG_SEL_C1 0xB6 ++#define TRXPTCL_DBG_SEL_C1 0xB7 ++#define FW_PROG_CNTR_DBG_SEL 0xF2 ++#define PCIE_TXDMA_DBG_SEL 0x30 ++#define PCIE_RXDMA_DBG_SEL 0x31 ++#define PCIE_CVT_DBG_SEL 0x32 ++#define PCIE_CXPL_DBG_SEL 0x33 ++#define PCIE_IO_DBG_SEL 0x37 ++#define PCIE_MISC_DBG_SEL 0x38 ++#define PCIE_MISC2_DBG_SEL 0x00 ++#define MAC_DBG_SEL 1 ++#define RMAC_CMAC_DBG_SEL 1 ++ ++/* TRXPTCL dbg port sel */ ++#define TRXPTRL_DBG_SEL_TMAC 0 ++#define TRXPTRL_DBG_SEL_RMAC 1 ++ ++struct rtw89_cpuio_ctrl { ++ u16 pkt_num; ++ u16 start_pktid; ++ u16 end_pktid; ++ u8 cmd_type; ++ u8 macid; ++ u8 src_pid; ++ u8 src_qid; ++ u8 dst_pid; ++ u8 dst_qid; ++ u16 pktid; ++}; ++ ++struct rtw89_mac_dbg_port_info { ++ u32 sel_addr; ++ u8 sel_byte; ++ u32 sel_msk; ++ u32 srt; ++ u32 end; ++ u32 rd_addr; ++ u8 rd_byte; ++ u32 rd_msk; ++}; ++ ++#define QLNKTBL_ADDR_INFO_SEL BIT(0) ++#define QLNKTBL_ADDR_INFO_SEL_0 0 ++#define QLNKTBL_ADDR_INFO_SEL_1 1 ++#define QLNKTBL_ADDR_TBL_IDX_MASK GENMASK(10, 1) ++#define QLNKTBL_DATA_SEL1_PKT_CNT_MASK GENMASK(11, 0) ++ ++struct rtw89_mac_dle_dfi_ctrl { ++ enum rtw89_mac_dle_ctrl_type type; ++ u32 target; ++ u32 addr; ++ u32 out_data; ++}; ++ ++struct rtw89_mac_dle_dfi_quota { ++ enum rtw89_mac_dle_ctrl_type dle_type; ++ u32 qtaid; ++ u16 rsv_pgnum; ++ u16 use_pgnum; ++}; ++ ++struct rtw89_mac_dle_dfi_qempty { ++ enum rtw89_mac_dle_ctrl_type dle_type; ++ u32 grpsel; ++ u32 qempty; ++}; ++ ++/* Define DBG and recovery enum */ ++enum mac_ax_err_info { ++ /* Get error info */ ++ ++ /* L0 */ ++ MAC_AX_ERR_L0_ERR_CMAC0 = 0x0001, ++ MAC_AX_ERR_L0_ERR_CMAC1 = 0x0002, ++ MAC_AX_ERR_L0_RESET_DONE = 0x0003, ++ MAC_AX_ERR_L0_PROMOTE_TO_L1 = 0x0010, ++ ++ /* L1 */ ++ MAC_AX_ERR_L1_ERR_DMAC = 0x1000, ++ MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE = 0x1001, ++ MAC_AX_ERR_L1_RESET_RECOVERY_DONE = 0x1002, ++ MAC_AX_ERR_L1_PROMOTE_TO_L2 = 0x1010, ++ MAC_AX_ERR_L1_RCVY_STOP_DONE = 0x1011, ++ ++ /* L2 */ ++ /* address hole (master) */ ++ MAC_AX_ERR_L2_ERR_AH_DMA = 0x2000, ++ MAC_AX_ERR_L2_ERR_AH_HCI = 0x2010, ++ MAC_AX_ERR_L2_ERR_AH_RLX4081 = 0x2020, ++ MAC_AX_ERR_L2_ERR_AH_IDDMA = 0x2030, ++ MAC_AX_ERR_L2_ERR_AH_HIOE = 0x2040, ++ MAC_AX_ERR_L2_ERR_AH_IPSEC = 0x2050, ++ MAC_AX_ERR_L2_ERR_AH_RX4281 = 0x2060, ++ MAC_AX_ERR_L2_ERR_AH_OTHERS = 0x2070, ++ ++ /* AHB bridge timeout (master) */ ++ MAC_AX_ERR_L2_ERR_AHB_TO_DMA = 0x2100, ++ MAC_AX_ERR_L2_ERR_AHB_TO_HCI = 0x2110, ++ MAC_AX_ERR_L2_ERR_AHB_TO_RLX4081 = 0x2120, ++ MAC_AX_ERR_L2_ERR_AHB_TO_IDDMA = 0x2130, ++ MAC_AX_ERR_L2_ERR_AHB_TO_HIOE = 0x2140, ++ MAC_AX_ERR_L2_ERR_AHB_TO_IPSEC = 0x2150, ++ MAC_AX_ERR_L2_ERR_AHB_TO_RX4281 = 0x2160, ++ MAC_AX_ERR_L2_ERR_AHB_TO_OTHERS = 0x2170, ++ ++ /* APB_SA bridge timeout (master + slave) */ ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WVA = 0x2200, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_UART = 0x2201, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_CPULOCAL = 0x2202, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_AXIDMA = 0x2203, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_HIOE = 0x2204, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_IDDMA = 0x2205, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_IPSEC = 0x2206, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WON = 0x2207, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WDMAC = 0x2208, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_WCMAC = 0x2209, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_DMA_OTHERS = 0x220A, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_WVA = 0x2210, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_UART = 0x2211, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_CPULOCAL = 0x2212, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_AXIDMA = 0x2213, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_HIOE = 0x2214, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_IDDMA = 0x2215, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_IPSEC = 0x2216, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_WDMAC = 0x2218, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_WCMAC = 0x2219, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HCI_OTHERS = 0x221A, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WVA = 0x2220, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_UART = 0x2221, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_CPULOCAL = 0x2222, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_AXIDMA = 0x2223, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_HIOE = 0x2224, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_IDDMA = 0x2225, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_IPSEC = 0x2226, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WON = 0x2227, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WDMAC = 0x2228, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_WCMAC = 0x2229, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RLX4081_OTHERS = 0x222A, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WVA = 0x2230, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_UART = 0x2231, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_CPULOCAL = 0x2232, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_AXIDMA = 0x2233, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_HIOE = 0x2234, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_IDDMA = 0x2235, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_IPSEC = 0x2236, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WON = 0x2237, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WDMAC = 0x2238, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_WCMAC = 0x2239, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IDDMA_OTHERS = 0x223A, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WVA = 0x2240, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_UART = 0x2241, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_CPULOCAL = 0x2242, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_AXIDMA = 0x2243, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_HIOE = 0x2244, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_IDDMA = 0x2245, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_IPSEC = 0x2246, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WON = 0x2247, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WDMAC = 0x2248, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_WCMAC = 0x2249, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_HIOE_OTHERS = 0x224A, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WVA = 0x2250, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_UART = 0x2251, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_CPULOCAL = 0x2252, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_AXIDMA = 0x2253, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_HIOE = 0x2254, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_IDDMA = 0x2255, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_IPSEC = 0x2256, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WON = 0x2257, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WDMAC = 0x2258, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_WCMAC = 0x2259, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_IPSEC_OTHERS = 0x225A, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WVA = 0x2260, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_UART = 0x2261, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_CPULOCAL = 0x2262, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_AXIDMA = 0x2263, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_HIOE = 0x2264, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_IDDMA = 0x2265, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_IPSEC = 0x2266, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WON = 0x2267, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WDMAC = 0x2268, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_WCMAC = 0x2269, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_RX4281_OTHERS = 0x226A, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WVA = 0x2270, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_UART = 0x2271, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_CPULOCAL = 0x2272, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_AXIDMA = 0x2273, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_HIOE = 0x2274, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_IDDMA = 0x2275, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_IPSEC = 0x2276, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WON = 0x2277, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WDMAC = 0x2278, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_WCMAC = 0x2279, ++ MAC_AX_ERR_L2_ERR_APB_SA_TO_OTHERS_OTHERS = 0x227A, ++ ++ /* APB_BBRF bridge timeout (master) */ ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_DMA = 0x2300, ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_HCI = 0x2310, ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_RLX4081 = 0x2320, ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_IDDMA = 0x2330, ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_HIOE = 0x2340, ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_IPSEC = 0x2350, ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_RX4281 = 0x2360, ++ MAC_AX_ERR_L2_ERR_APB_BBRF_TO_OTHERS = 0x2370, ++ MAC_AX_ERR_L2_RESET_DONE = 0x2400, ++ MAC_AX_ERR_CPU_EXCEPTION = 0x3000, ++ MAC_AX_GET_ERR_MAX, ++ MAC_AX_DUMP_SHAREBUFF_INDICATOR = 0x80000000, ++ ++ /* set error info */ ++ MAC_AX_ERR_L1_DISABLE_EN = 0x0001, ++ MAC_AX_ERR_L1_RCVY_EN = 0x0002, ++ MAC_AX_ERR_L1_RCVY_STOP_REQ = 0x0003, ++ MAC_AX_ERR_L1_RCVY_START_REQ = 0x0004, ++ MAC_AX_ERR_L0_CFG_NOTIFY = 0x0010, ++ MAC_AX_ERR_L0_CFG_DIS_NOTIFY = 0x0011, ++ MAC_AX_ERR_L0_CFG_HANDSHAKE = 0x0012, ++ MAC_AX_ERR_L0_RCVY_EN = 0x0013, ++ MAC_AX_SET_ERR_MAX, ++}; ++ ++extern const struct rtw89_hfc_prec_cfg rtw_hfc_preccfg_pcie; ++extern const struct rtw89_dle_size wde_size0; ++extern const struct rtw89_dle_size wde_size4; ++extern const struct rtw89_dle_size ple_size0; ++extern const struct rtw89_dle_size ple_size4; ++extern const struct rtw89_wde_quota wde_qt0; ++extern const struct rtw89_wde_quota wde_qt4; ++extern const struct rtw89_ple_quota ple_qt4; ++extern const struct rtw89_ple_quota ple_qt5; ++extern const struct rtw89_ple_quota ple_qt13; ++ ++static inline u32 rtw89_mac_reg_by_idx(u32 reg_base, u8 band) ++{ ++ return band == 0 ? reg_base : (reg_base + 0x2000); ++} ++ ++static inline u32 rtw89_mac_reg_by_port(u32 base, u8 port, u8 mac_idx) ++{ ++ return rtw89_mac_reg_by_idx(base + port * 0x40, mac_idx); ++} ++ ++static inline u32 ++rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u32 base, u32 mask) ++{ ++ u32 reg; ++ ++ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); ++ return rtw89_read32_mask(rtwdev, reg, mask); ++} ++ ++static inline void ++rtw89_write32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base, ++ u32 data) ++{ ++ u32 reg; ++ ++ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); ++ rtw89_write32(rtwdev, reg, data); ++} ++ ++static inline void ++rtw89_write32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u32 base, u32 mask, u32 data) ++{ ++ u32 reg; ++ ++ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); ++ rtw89_write32_mask(rtwdev, reg, mask, data); ++} ++ ++static inline void ++rtw89_write16_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u32 base, u32 mask, u16 data) ++{ ++ u32 reg; ++ ++ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); ++ rtw89_write16_mask(rtwdev, reg, mask, data); ++} ++ ++static inline void ++rtw89_write32_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u32 base, u32 bit) ++{ ++ u32 reg; ++ ++ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); ++ rtw89_write32_clr(rtwdev, reg, bit); ++} ++ ++static inline void ++rtw89_write16_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u32 base, u16 bit) ++{ ++ u32 reg; ++ ++ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); ++ rtw89_write16_clr(rtwdev, reg, bit); ++} ++ ++static inline void ++rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u32 base, u32 bit) ++{ ++ u32 reg; ++ ++ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); ++ rtw89_write32_set(rtwdev, reg, bit); ++} ++ ++void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev); ++int rtw89_mac_partial_init(struct rtw89_dev *rtwdev); ++int rtw89_mac_init(struct rtw89_dev *rtwdev); ++int rtw89_mac_check_mac_en(struct rtw89_dev *rtwdev, u8 band, ++ enum rtw89_mac_hwmod_sel sel); ++int rtw89_mac_write_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 val); ++int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val); ++int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); ++int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); ++int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); ++void rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev); ++void rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev); ++u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev); ++int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err); ++void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, ++ u32 len, u8 class, u8 func); ++int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev); ++int rtw89_mac_stop_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, ++ u16 *tx_en, enum rtw89_sch_tx_sel sel); ++int rtw89_mac_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u16 tx_en); ++int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_ids, bool enable); ++void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx); ++void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop); ++int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex); ++int rtw89_mac_cfg_gnt(struct rtw89_dev *rtwdev, ++ const struct rtw89_mac_ax_coex_gnt *gnt_cfg); ++int rtw89_mac_cfg_plt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt); ++void rtw89_mac_cfg_sb(struct rtw89_dev *rtwdev, u32 val); ++u32 rtw89_mac_get_sb(struct rtw89_dev *rtwdev); ++bool rtw89_mac_get_ctrl_path(struct rtw89_dev *rtwdev); ++int rtw89_mac_cfg_ctrl_path(struct rtw89_dev *rtwdev, bool wl); ++bool rtw89_mac_get_txpwr_cr(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, ++ u32 reg_base, u32 *cr); ++void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter); ++void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta); ++void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, ++ struct ieee80211_bss_conf *conf); ++void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev, ++ struct ieee80211_sta *sta, bool disconnect); ++void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev); ++int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); ++int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); ++int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, bool en); ++ ++static inline void rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev) ++{ ++ if (!test_bit(RTW89_FLAG_BFEE_MON, rtwdev->flags)) ++ return; ++ ++ _rtw89_mac_bf_monitor_track(rtwdev); ++} ++ ++static inline int rtw89_mac_txpwr_read32(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, ++ u32 reg_base, u32 *val) ++{ ++ u32 cr; ++ ++ if (!rtw89_mac_get_txpwr_cr(rtwdev, phy_idx, reg_base, &cr)) ++ return -EINVAL; ++ ++ *val = rtw89_read32(rtwdev, cr); ++ return 0; ++} ++ ++static inline int rtw89_mac_txpwr_write32(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, ++ u32 reg_base, u32 val) ++{ ++ u32 cr; ++ ++ if (!rtw89_mac_get_txpwr_cr(rtwdev, phy_idx, reg_base, &cr)) ++ return -EINVAL; ++ ++ rtw89_write32(rtwdev, cr, val); ++ return 0; ++} ++ ++static inline int rtw89_mac_txpwr_write32_mask(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, ++ u32 reg_base, u32 mask, u32 val) ++{ ++ u32 cr; ++ ++ if (!rtw89_mac_get_txpwr_cr(rtwdev, phy_idx, reg_base, &cr)) ++ return -EINVAL; ++ ++ rtw89_write32_mask(rtwdev, cr, mask, val); ++ return 0; ++} ++ ++int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, ++ bool resume, u32 tx_time); ++int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, ++ u32 *tx_time); ++int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev, ++ struct rtw89_sta *rtwsta, ++ bool resume, u8 tx_retry); ++int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev, ++ struct rtw89_sta *rtwsta, u8 *tx_retry); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c +new file mode 100644 +index 000000000000..16dc6fb7dbb0 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/mac80211.c +@@ -0,0 +1,676 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "cam.h" ++#include "coex.h" ++#include "debug.h" ++#include "fw.h" ++#include "mac.h" ++#include "phy.h" ++#include "ps.h" ++#include "reg.h" ++#include "sar.h" ++#include "ser.h" ++ ++static void rtw89_ops_tx(struct ieee80211_hw *hw, ++ struct ieee80211_tx_control *control, ++ struct sk_buff *skb) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ struct ieee80211_vif *vif = info->control.vif; ++ struct ieee80211_sta *sta = control->sta; ++ int ret, qsel; ++ ++ ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to transmit skb: %d\n", ret); ++ ieee80211_free_txskb(hw, skb); ++ } ++ rtw89_core_tx_kick_off(rtwdev, qsel); ++} ++ ++static void rtw89_ops_wake_tx_queue(struct ieee80211_hw *hw, ++ struct ieee80211_txq *txq) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ ieee80211_schedule_txq(hw, txq); ++ queue_work(rtwdev->txq_wq, &rtwdev->txq_work); ++} ++ ++static int rtw89_ops_start(struct ieee80211_hw *hw) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ int ret; ++ ++ mutex_lock(&rtwdev->mutex); ++ ret = rtw89_core_start(rtwdev); ++ mutex_unlock(&rtwdev->mutex); ++ ++ return ret; ++} ++ ++static void rtw89_ops_stop(struct ieee80211_hw *hw) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_core_stop(rtwdev); ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ ++ if ((changed & IEEE80211_CONF_CHANGE_IDLE) && ++ !(hw->conf.flags & IEEE80211_CONF_IDLE)) ++ rtw89_leave_ips(rtwdev); ++ ++ if (changed & IEEE80211_CONF_CHANGE_PS) { ++ if (hw->conf.flags & IEEE80211_CONF_PS) { ++ rtwdev->lps_enabled = true; ++ } else { ++ rtw89_leave_lps(rtwdev); ++ rtwdev->lps_enabled = false; ++ } ++ } ++ ++ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) ++ rtw89_set_channel(rtwdev); ++ ++ if ((changed & IEEE80211_CONF_CHANGE_IDLE) && ++ (hw->conf.flags & IEEE80211_CONF_IDLE)) ++ rtw89_enter_ips(rtwdev); ++ ++ mutex_unlock(&rtwdev->mutex); ++ ++ return 0; ++} ++ ++static int rtw89_ops_add_interface(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ int ret = 0; ++ ++ mutex_lock(&rtwdev->mutex); ++ list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list); ++ rtw89_leave_ps_mode(rtwdev); ++ ++ rtw89_traffic_stats_init(rtwdev, &rtwvif->stats); ++ rtw89_vif_type_mapping(vif, false); ++ rtwvif->port = rtw89_core_acquire_bit_map(rtwdev->hw_port, ++ RTW89_MAX_HW_PORT_NUM); ++ if (rtwvif->port == RTW89_MAX_HW_PORT_NUM) { ++ ret = -ENOSPC; ++ goto out; ++ } ++ ++ rtwvif->bcn_hit_cond = 0; ++ rtwvif->mac_idx = RTW89_MAC_0; ++ rtwvif->phy_idx = RTW89_PHY_0; ++ rtwvif->hit_rule = 0; ++ ether_addr_copy(rtwvif->mac_addr, vif->addr); ++ ++ ret = rtw89_mac_add_vif(rtwdev, rtwvif); ++ if (ret) { ++ rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port); ++ goto out; ++ } ++ ++ rtw89_core_txq_init(rtwdev, vif->txq); ++ ++ rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_START); ++out: ++ mutex_unlock(&rtwdev->mutex); ++ ++ return ret; ++} ++ ++static void rtw89_ops_remove_interface(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_STOP); ++ rtw89_mac_remove_vif(rtwdev, rtwvif); ++ rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port); ++ list_del_init(&rtwvif->list); ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static void rtw89_ops_configure_filter(struct ieee80211_hw *hw, ++ unsigned int changed_flags, ++ unsigned int *new_flags, ++ u64 multicast) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ ++ *new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL | ++ FIF_BCN_PRBRESP_PROMISC; ++ ++ if (changed_flags & FIF_ALLMULTI) { ++ if (*new_flags & FIF_ALLMULTI) ++ rtwdev->hal.rx_fltr &= ~B_AX_A_MC; ++ else ++ rtwdev->hal.rx_fltr |= B_AX_A_MC; ++ } ++ if (changed_flags & FIF_FCSFAIL) { ++ if (*new_flags & FIF_FCSFAIL) ++ rtwdev->hal.rx_fltr |= B_AX_A_CRC32_ERR; ++ else ++ rtwdev->hal.rx_fltr &= ~B_AX_A_CRC32_ERR; ++ } ++ if (changed_flags & FIF_OTHER_BSS) { ++ if (*new_flags & FIF_OTHER_BSS) ++ rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH; ++ else ++ rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH; ++ } ++ if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { ++ if (*new_flags & FIF_BCN_PRBRESP_PROMISC) { ++ rtwdev->hal.rx_fltr &= ~B_AX_A_BCN_CHK_EN; ++ rtwdev->hal.rx_fltr &= ~B_AX_A_BC; ++ rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH; ++ } else { ++ rtwdev->hal.rx_fltr |= B_AX_A_BCN_CHK_EN; ++ rtwdev->hal.rx_fltr |= B_AX_A_BC; ++ rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH; ++ } ++ } ++ ++ rtw89_write32_mask(rtwdev, ++ rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0), ++ B_AX_RX_FLTR_CFG_MASK, ++ rtwdev->hal.rx_fltr); ++ if (!rtwdev->dbcc_en) ++ goto out; ++ rtw89_write32_mask(rtwdev, ++ rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_1), ++ B_AX_RX_FLTR_CFG_MASK, ++ rtwdev->hal.rx_fltr); ++ ++out: ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = { ++ [IEEE80211_AC_VO] = 3, ++ [IEEE80211_AC_VI] = 2, ++ [IEEE80211_AC_BE] = 0, ++ [IEEE80211_AC_BK] = 1, ++}; ++ ++static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, u8 aifsn) ++{ ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ u8 slot_time; ++ u8 sifs; ++ ++ slot_time = vif->bss_conf.use_short_slot ? 9 : 20; ++ sifs = rtwdev->hal.current_band_type == RTW89_BAND_5G ? 16 : 10; ++ ++ return aifsn * slot_time + sifs; ++} ++ ++static void ____rtw89_conf_tx_edca(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, u16 ac) ++{ ++ struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac]; ++ u32 val; ++ u8 ecw_max, ecw_min; ++ u8 aifs; ++ ++ /* 2^ecw - 1 = cw; ecw = log2(cw + 1) */ ++ ecw_max = ilog2(params->cw_max + 1); ++ ecw_min = ilog2(params->cw_min + 1); ++ aifs = rtw89_aifsn_to_aifs(rtwdev, rtwvif, params->aifs); ++ val = FIELD_PREP(FW_EDCA_PARAM_TXOPLMT_MSK, params->txop) | ++ FIELD_PREP(FW_EDCA_PARAM_CWMAX_MSK, ecw_max) | ++ FIELD_PREP(FW_EDCA_PARAM_CWMIN_MSK, ecw_min) | ++ FIELD_PREP(FW_EDCA_PARAM_AIFS_MSK, aifs); ++ rtw89_fw_h2c_set_edca(rtwdev, rtwvif, ac_to_fw_idx[ac], val); ++} ++ ++static const u32 ac_to_mu_edca_param[IEEE80211_NUM_ACS] = { ++ [IEEE80211_AC_VO] = R_AX_MUEDCA_VO_PARAM_0, ++ [IEEE80211_AC_VI] = R_AX_MUEDCA_VI_PARAM_0, ++ [IEEE80211_AC_BE] = R_AX_MUEDCA_BE_PARAM_0, ++ [IEEE80211_AC_BK] = R_AX_MUEDCA_BK_PARAM_0, ++}; ++ ++static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, u16 ac) ++{ ++ struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac]; ++ struct ieee80211_he_mu_edca_param_ac_rec *mu_edca; ++ u8 aifs, aifsn; ++ u16 timer_32us; ++ u32 reg; ++ u32 val; ++ ++ if (!params->mu_edca) ++ return; ++ ++ mu_edca = ¶ms->mu_edca_param_rec; ++ aifsn = FIELD_GET(GENMASK(3, 0), mu_edca->aifsn); ++ aifs = aifsn ? rtw89_aifsn_to_aifs(rtwdev, rtwvif, aifsn) : 0; ++ timer_32us = mu_edca->mu_edca_timer << 8; ++ ++ val = FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_TIMER_MASK, timer_32us) | ++ FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_CW_MASK, mu_edca->ecw_min_max) | ++ FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_AIFS_MASK, aifs); ++ reg = rtw89_mac_reg_by_idx(ac_to_mu_edca_param[ac], rtwvif->mac_idx); ++ rtw89_write32(rtwdev, reg, val); ++ ++ rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif, true); ++} ++ ++static void __rtw89_conf_tx(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, u16 ac) ++{ ++ ____rtw89_conf_tx_edca(rtwdev, rtwvif, ac); ++ ____rtw89_conf_tx_mu_edca(rtwdev, rtwvif, ac); ++} ++ ++static void rtw89_conf_tx(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif) ++{ ++ u16 ac; ++ ++ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) ++ __rtw89_conf_tx(rtwdev, rtwvif, ac); ++} ++ ++static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ struct ieee80211_bss_conf *conf) ++{ ++ struct ieee80211_sta *sta; ++ ++ if (vif->type != NL80211_IFTYPE_STATION) ++ return; ++ ++ sta = ieee80211_find_sta(vif, conf->bssid); ++ if (!sta) { ++ rtw89_err(rtwdev, "can't find sta to set sta_assoc state\n"); ++ return; ++ } ++ rtw89_core_sta_assoc(rtwdev, vif, sta); ++} ++ ++static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_bss_conf *conf, ++ u32 changed) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ ++ if (changed & BSS_CHANGED_ASSOC) { ++ if (conf->assoc) { ++ rtw89_station_mode_sta_assoc(rtwdev, vif, conf); ++ rtw89_phy_set_bss_color(rtwdev, vif); ++ rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif); ++ rtw89_mac_port_update(rtwdev, rtwvif); ++ } ++ } ++ ++ if (changed & BSS_CHANGED_BSSID) { ++ ether_addr_copy(rtwvif->bssid, conf->bssid); ++ rtw89_cam_bssid_changed(rtwdev, rtwvif); ++ rtw89_fw_h2c_cam(rtwdev, rtwvif); ++ } ++ ++ if (changed & BSS_CHANGED_ERP_SLOT) ++ rtw89_conf_tx(rtwdev, rtwvif); ++ ++ if (changed & BSS_CHANGED_HE_BSS_COLOR) ++ rtw89_phy_set_bss_color(rtwdev, vif); ++ ++ if (changed & BSS_CHANGED_MU_GROUPS) ++ rtw89_mac_bf_set_gid_table(rtwdev, vif, conf); ++ ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static int rtw89_ops_conf_tx(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, u16 ac, ++ const struct ieee80211_tx_queue_params *params) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ rtwvif->tx_params[ac] = *params; ++ __rtw89_conf_tx(rtwdev, rtwvif, ac); ++ mutex_unlock(&rtwdev->mutex); ++ ++ return 0; ++} ++ ++static int __rtw89_ops_sta_state(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ enum ieee80211_sta_state old_state, ++ enum ieee80211_sta_state new_state) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ if (old_state == IEEE80211_STA_NOTEXIST && ++ new_state == IEEE80211_STA_NONE) ++ return rtw89_core_sta_add(rtwdev, vif, sta); ++ ++ if (old_state == IEEE80211_STA_AUTH && ++ new_state == IEEE80211_STA_ASSOC) { ++ if (vif->type == NL80211_IFTYPE_STATION) ++ return 0; /* defer to bss_info_changed to have vif info */ ++ return rtw89_core_sta_assoc(rtwdev, vif, sta); ++ } ++ ++ if (old_state == IEEE80211_STA_ASSOC && ++ new_state == IEEE80211_STA_AUTH) ++ return rtw89_core_sta_disassoc(rtwdev, vif, sta); ++ ++ if (old_state == IEEE80211_STA_AUTH && ++ new_state == IEEE80211_STA_NONE) ++ return rtw89_core_sta_disconnect(rtwdev, vif, sta); ++ ++ if (old_state == IEEE80211_STA_NONE && ++ new_state == IEEE80211_STA_NOTEXIST) ++ return rtw89_core_sta_remove(rtwdev, vif, sta); ++ ++ return 0; ++} ++ ++static int rtw89_ops_sta_state(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ enum ieee80211_sta_state old_state, ++ enum ieee80211_sta_state new_state) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ int ret; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ ret = __rtw89_ops_sta_state(hw, vif, sta, old_state, new_state); ++ mutex_unlock(&rtwdev->mutex); ++ ++ return ret; ++} ++ ++static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ struct ieee80211_key_conf *key) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ int ret = 0; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ ++ switch (cmd) { ++ case SET_KEY: ++ rtw89_btc_ntfy_specific_packet(rtwdev, PACKET_EAPOL_END); ++ ret = rtw89_cam_sec_key_add(rtwdev, vif, sta, key); ++ if (ret && ret != -EOPNOTSUPP) { ++ rtw89_err(rtwdev, "failed to add key to sec cam\n"); ++ goto out; ++ } ++ break; ++ case DISABLE_KEY: ++ rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1, ++ false); ++ rtw89_mac_flush_txq(rtwdev, BIT(rtwdev->hw->queues) - 1, false); ++ ret = rtw89_cam_sec_key_del(rtwdev, vif, sta, key, true); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to remove key from sec cam\n"); ++ goto out; ++ } ++ break; ++ } ++ ++out: ++ mutex_unlock(&rtwdev->mutex); ++ ++ return ret; ++} ++ ++static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_ampdu_params *params) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct ieee80211_sta *sta = params->sta; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ u16 tid = params->tid; ++ struct ieee80211_txq *txq = sta->txq[tid]; ++ struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv; ++ ++ switch (params->action) { ++ case IEEE80211_AMPDU_TX_START: ++ return IEEE80211_AMPDU_TX_START_IMMEDIATE; ++ case IEEE80211_AMPDU_TX_STOP_CONT: ++ case IEEE80211_AMPDU_TX_STOP_FLUSH: ++ case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: ++ mutex_lock(&rtwdev->mutex); ++ clear_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags); ++ rtw89_fw_h2c_ba_cam(rtwdev, false, rtwsta->mac_id, params); ++ mutex_unlock(&rtwdev->mutex); ++ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); ++ break; ++ case IEEE80211_AMPDU_TX_OPERATIONAL: ++ mutex_lock(&rtwdev->mutex); ++ set_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags); ++ rtwsta->ampdu_params[tid].agg_num = params->buf_size; ++ rtwsta->ampdu_params[tid].amsdu = params->amsdu; ++ rtw89_leave_ps_mode(rtwdev); ++ rtw89_fw_h2c_ba_cam(rtwdev, true, rtwsta->mac_id, params); ++ mutex_unlock(&rtwdev->mutex); ++ break; ++ case IEEE80211_AMPDU_RX_START: ++ case IEEE80211_AMPDU_RX_STOP: ++ break; ++ default: ++ WARN_ON(1); ++ return -ENOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static int rtw89_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags)) ++ rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0); ++ mutex_unlock(&rtwdev->mutex); ++ ++ return 0; ++} ++ ++static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ struct station_info *sinfo) ++{ ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ ++ sinfo->txrate = rtwsta->ra_report.txrate; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); ++} ++ ++static void rtw89_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ++ u32 queues, bool drop) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_lps(rtwdev); ++ rtw89_hci_flush_queues(rtwdev, queues, drop); ++ rtw89_mac_flush_txq(rtwdev, queues, drop); ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++struct rtw89_iter_bitrate_mask_data { ++ struct rtw89_dev *rtwdev; ++ struct ieee80211_vif *vif; ++ const struct cfg80211_bitrate_mask *mask; ++}; ++ ++static void rtw89_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta) ++{ ++ struct rtw89_iter_bitrate_mask_data *br_data = data; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif); ++ ++ if (vif != br_data->vif) ++ return; ++ ++ rtwsta->use_cfg_mask = true; ++ rtwsta->mask = *br_data->mask; ++ rtw89_phy_ra_updata_sta(br_data->rtwdev, sta); ++} ++ ++static void rtw89_ra_mask_info_update(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ const struct cfg80211_bitrate_mask *mask) ++{ ++ struct rtw89_iter_bitrate_mask_data br_data = { .rtwdev = rtwdev, ++ .vif = vif, ++ .mask = mask}; ++ ++ ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_ra_mask_info_update_iter, ++ &br_data); ++} ++ ++static int rtw89_ops_set_bitrate_mask(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ const struct cfg80211_bitrate_mask *mask) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_phy_rate_pattern_vif(rtwdev, vif, mask); ++ rtw89_ra_mask_info_update(rtwdev, vif, mask); ++ mutex_unlock(&rtwdev->mutex); ++ ++ return 0; ++} ++ ++static ++int rtw89_ops_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ ++ if (rx_ant != hw->wiphy->available_antennas_rx) ++ return -EINVAL; ++ ++ mutex_lock(&rtwdev->mutex); ++ hal->antenna_tx = tx_ant; ++ hal->antenna_rx = rx_ant; ++ mutex_unlock(&rtwdev->mutex); ++ ++ return 0; ++} ++ ++static ++int rtw89_ops_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ ++ *tx_ant = hal->antenna_tx; ++ *rx_ant = hal->antenna_rx; ++ ++ return 0; ++} ++ ++static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ const u8 *mac_addr) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtwdev->scanning = true; ++ rtw89_leave_lps(rtwdev); ++ rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, hal->current_band_type); ++ rtw89_chip_rfk_scan(rtwdev, true); ++ rtw89_hci_recalc_int_mit(rtwdev); ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_chip_rfk_scan(rtwdev, false); ++ rtw89_btc_ntfy_scan_finish(rtwdev, RTW89_PHY_0); ++ rtwdev->scanning = false; ++ rtwdev->dig.bypass_dig = true; ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static void rtw89_ops_reconfig_complete(struct ieee80211_hw *hw, ++ enum ieee80211_reconfig_type reconfig_type) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ if (reconfig_type == IEEE80211_RECONFIG_TYPE_RESTART) ++ rtw89_ser_recfg_done(rtwdev); ++} ++ ++const struct ieee80211_ops rtw89_ops = { ++ .tx = rtw89_ops_tx, ++ .wake_tx_queue = rtw89_ops_wake_tx_queue, ++ .start = rtw89_ops_start, ++ .stop = rtw89_ops_stop, ++ .config = rtw89_ops_config, ++ .add_interface = rtw89_ops_add_interface, ++ .remove_interface = rtw89_ops_remove_interface, ++ .configure_filter = rtw89_ops_configure_filter, ++ .bss_info_changed = rtw89_ops_bss_info_changed, ++ .conf_tx = rtw89_ops_conf_tx, ++ .sta_state = rtw89_ops_sta_state, ++ .set_key = rtw89_ops_set_key, ++ .ampdu_action = rtw89_ops_ampdu_action, ++ .set_rts_threshold = rtw89_ops_set_rts_threshold, ++ .sta_statistics = rtw89_ops_sta_statistics, ++ .flush = rtw89_ops_flush, ++ .set_bitrate_mask = rtw89_ops_set_bitrate_mask, ++ .set_antenna = rtw89_ops_set_antenna, ++ .get_antenna = rtw89_ops_get_antenna, ++ .sw_scan_start = rtw89_ops_sw_scan_start, ++ .sw_scan_complete = rtw89_ops_sw_scan_complete, ++ .reconfig_complete = rtw89_ops_reconfig_complete, ++ .set_sar_specs = rtw89_ops_set_sar_specs, ++}; ++EXPORT_SYMBOL(rtw89_ops); +diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c +new file mode 100644 +index 000000000000..e9731012bca9 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/pci.c +@@ -0,0 +1,3060 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2020 Realtek Corporation ++ */ ++ ++#include ++ ++#include "mac.h" ++#include "pci.h" ++#include "reg.h" ++#include "ser.h" ++ ++static bool rtw89_pci_disable_clkreq; ++static bool rtw89_pci_disable_aspm_l1; ++static bool rtw89_pci_disable_l1ss; ++module_param_named(disable_clkreq, rtw89_pci_disable_clkreq, bool, 0644); ++module_param_named(disable_aspm_l1, rtw89_pci_disable_aspm_l1, bool, 0644); ++module_param_named(disable_aspm_l1ss, rtw89_pci_disable_l1ss, bool, 0644); ++MODULE_PARM_DESC(disable_clkreq, "Set Y to disable PCI clkreq support"); ++MODULE_PARM_DESC(disable_aspm_l1, "Set Y to disable PCI ASPM L1 support"); ++MODULE_PARM_DESC(disable_aspm_l1ss, "Set Y to disable PCI L1SS support"); ++ ++static int rtw89_pci_rst_bdram_pcie(struct rtw89_dev *rtwdev) ++{ ++ u32 val; ++ int ret; ++ ++ rtw89_write32(rtwdev, R_AX_PCIE_INIT_CFG1, ++ rtw89_read32(rtwdev, R_AX_PCIE_INIT_CFG1) | B_AX_RST_BDRAM); ++ ++ ret = read_poll_timeout_atomic(rtw89_read32, val, !(val & B_AX_RST_BDRAM), ++ 1, RTW89_PCI_POLL_BDRAM_RST_CNT, false, ++ rtwdev, R_AX_PCIE_INIT_CFG1); ++ ++ if (ret) ++ return -EBUSY; ++ ++ return 0; ++} ++ ++static u32 rtw89_pci_dma_recalc(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_dma_ring *bd_ring, ++ u32 cur_idx, bool tx) ++{ ++ u32 cnt, cur_rp, wp, rp, len; ++ ++ rp = bd_ring->rp; ++ wp = bd_ring->wp; ++ len = bd_ring->len; ++ ++ cur_rp = FIELD_GET(TXBD_HW_IDX_MASK, cur_idx); ++ if (tx) ++ cnt = cur_rp >= rp ? cur_rp - rp : len - (rp - cur_rp); ++ else ++ cnt = cur_rp >= wp ? cur_rp - wp : len - (wp - cur_rp); ++ ++ bd_ring->rp = cur_rp; ++ ++ return cnt; ++} ++ ++static u32 rtw89_pci_txbd_recalc(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; ++ u32 addr_idx = bd_ring->addr_idx; ++ u32 cnt, idx; ++ ++ idx = rtw89_read32(rtwdev, addr_idx); ++ cnt = rtw89_pci_dma_recalc(rtwdev, bd_ring, idx, true); ++ ++ return cnt; ++} ++ ++static void rtw89_pci_release_fwcmd(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci, ++ u32 cnt, bool release_all) ++{ ++ struct rtw89_pci_tx_data *tx_data; ++ struct sk_buff *skb; ++ u32 qlen; ++ ++ while (cnt--) { ++ skb = skb_dequeue(&rtwpci->h2c_queue); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to pre-release fwcmd\n"); ++ return; ++ } ++ skb_queue_tail(&rtwpci->h2c_release_queue, skb); ++ } ++ ++ qlen = skb_queue_len(&rtwpci->h2c_release_queue); ++ if (!release_all) ++ qlen = qlen > RTW89_PCI_MULTITAG ? qlen - RTW89_PCI_MULTITAG : 0; ++ ++ while (qlen--) { ++ skb = skb_dequeue(&rtwpci->h2c_release_queue); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to release fwcmd\n"); ++ return; ++ } ++ tx_data = RTW89_PCI_TX_SKB_CB(skb); ++ dma_unmap_single(&rtwpci->pdev->dev, tx_data->dma, skb->len, ++ DMA_TO_DEVICE); ++ dev_kfree_skb_any(skb); ++ } ++} ++ ++static void rtw89_pci_reclaim_tx_fwcmd(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci) ++{ ++ struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[RTW89_TXCH_CH12]; ++ u32 cnt; ++ ++ cnt = rtw89_pci_txbd_recalc(rtwdev, tx_ring); ++ if (!cnt) ++ return; ++ rtw89_pci_release_fwcmd(rtwdev, rtwpci, cnt, false); ++} ++ ++static u32 rtw89_pci_rxbd_recalc(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_rx_ring *rx_ring) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; ++ u32 addr_idx = bd_ring->addr_idx; ++ u32 cnt, idx; ++ ++ idx = rtw89_read32(rtwdev, addr_idx); ++ cnt = rtw89_pci_dma_recalc(rtwdev, bd_ring, idx, false); ++ ++ return cnt; ++} ++ ++static void rtw89_pci_sync_skb_for_cpu(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb) ++{ ++ struct rtw89_pci_rx_info *rx_info; ++ dma_addr_t dma; ++ ++ rx_info = RTW89_PCI_RX_SKB_CB(skb); ++ dma = rx_info->dma; ++ dma_sync_single_for_cpu(rtwdev->dev, dma, RTW89_PCI_RX_BUF_SIZE, ++ DMA_FROM_DEVICE); ++} ++ ++static void rtw89_pci_sync_skb_for_device(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb) ++{ ++ struct rtw89_pci_rx_info *rx_info; ++ dma_addr_t dma; ++ ++ rx_info = RTW89_PCI_RX_SKB_CB(skb); ++ dma = rx_info->dma; ++ dma_sync_single_for_device(rtwdev->dev, dma, RTW89_PCI_RX_BUF_SIZE, ++ DMA_FROM_DEVICE); ++} ++ ++static int rtw89_pci_rxbd_info_update(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb) ++{ ++ struct rtw89_pci_rxbd_info *rxbd_info; ++ struct rtw89_pci_rx_info *rx_info = RTW89_PCI_RX_SKB_CB(skb); ++ ++ rxbd_info = (struct rtw89_pci_rxbd_info *)skb->data; ++ rx_info->fs = le32_get_bits(rxbd_info->dword, RTW89_PCI_RXBD_FS); ++ rx_info->ls = le32_get_bits(rxbd_info->dword, RTW89_PCI_RXBD_LS); ++ rx_info->len = le32_get_bits(rxbd_info->dword, RTW89_PCI_RXBD_WRITE_SIZE); ++ rx_info->tag = le32_get_bits(rxbd_info->dword, RTW89_PCI_RXBD_TAG); ++ ++ return 0; ++} ++ ++static bool ++rtw89_skb_put_rx_data(struct rtw89_dev *rtwdev, bool fs, bool ls, ++ struct sk_buff *new, ++ const struct sk_buff *skb, u32 offset, ++ const struct rtw89_pci_rx_info *rx_info, ++ const struct rtw89_rx_desc_info *desc_info) ++{ ++ u32 copy_len = rx_info->len - offset; ++ ++ if (unlikely(skb_tailroom(new) < copy_len)) { ++ rtw89_debug(rtwdev, RTW89_DBG_TXRX, ++ "invalid rx data length bd_len=%d desc_len=%d offset=%d (fs=%d ls=%d)\n", ++ rx_info->len, desc_info->pkt_size, offset, fs, ls); ++ rtw89_hex_dump(rtwdev, RTW89_DBG_TXRX, "rx_data: ", ++ skb->data, rx_info->len); ++ /* length of a single segment skb is desc_info->pkt_size */ ++ if (fs && ls) { ++ copy_len = desc_info->pkt_size; ++ } else { ++ rtw89_info(rtwdev, "drop rx data due to invalid length\n"); ++ return false; ++ } ++ } ++ ++ skb_put_data(new, skb->data + offset, copy_len); ++ ++ return true; ++} ++ ++static u32 rtw89_pci_rxbd_deliver_skbs(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_rx_ring *rx_ring) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; ++ struct rtw89_pci_rx_info *rx_info; ++ struct rtw89_rx_desc_info *desc_info = &rx_ring->diliver_desc; ++ struct sk_buff *new = rx_ring->diliver_skb; ++ struct sk_buff *skb; ++ u32 rxinfo_size = sizeof(struct rtw89_pci_rxbd_info); ++ u32 offset; ++ u32 cnt = 1; ++ bool fs, ls; ++ int ret; ++ ++ skb = rx_ring->buf[bd_ring->wp]; ++ rtw89_pci_sync_skb_for_cpu(rtwdev, skb); ++ ++ ret = rtw89_pci_rxbd_info_update(rtwdev, skb); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to update %d RXBD info: %d\n", ++ bd_ring->wp, ret); ++ goto err_sync_device; ++ } ++ ++ rx_info = RTW89_PCI_RX_SKB_CB(skb); ++ fs = rx_info->fs; ++ ls = rx_info->ls; ++ ++ if (fs) { ++ if (new) { ++ rtw89_err(rtwdev, "skb should not be ready before first segment start\n"); ++ goto err_sync_device; ++ } ++ if (desc_info->ready) { ++ rtw89_warn(rtwdev, "desc info should not be ready before first segment start\n"); ++ goto err_sync_device; ++ } ++ ++ rtw89_core_query_rxdesc(rtwdev, desc_info, skb->data, rxinfo_size); ++ ++ new = dev_alloc_skb(desc_info->pkt_size); ++ if (!new) ++ goto err_sync_device; ++ ++ rx_ring->diliver_skb = new; ++ ++ /* first segment has RX desc */ ++ offset = desc_info->offset; ++ offset += desc_info->long_rxdesc ? sizeof(struct rtw89_rxdesc_long) : ++ sizeof(struct rtw89_rxdesc_short); ++ } else { ++ offset = sizeof(struct rtw89_pci_rxbd_info); ++ if (!new) { ++ rtw89_warn(rtwdev, "no last skb\n"); ++ goto err_sync_device; ++ } ++ } ++ if (!rtw89_skb_put_rx_data(rtwdev, fs, ls, new, skb, offset, rx_info, desc_info)) ++ goto err_sync_device; ++ rtw89_pci_sync_skb_for_device(rtwdev, skb); ++ rtw89_pci_rxbd_increase(rx_ring, 1); ++ ++ if (!desc_info->ready) { ++ rtw89_warn(rtwdev, "no rx desc information\n"); ++ goto err_free_resource; ++ } ++ if (ls) { ++ rtw89_core_rx(rtwdev, desc_info, new); ++ rx_ring->diliver_skb = NULL; ++ desc_info->ready = false; ++ } ++ ++ return cnt; ++ ++err_sync_device: ++ rtw89_pci_sync_skb_for_device(rtwdev, skb); ++ rtw89_pci_rxbd_increase(rx_ring, 1); ++err_free_resource: ++ if (new) ++ dev_kfree_skb_any(new); ++ rx_ring->diliver_skb = NULL; ++ desc_info->ready = false; ++ ++ return cnt; ++} ++ ++static void rtw89_pci_rxbd_deliver(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_rx_ring *rx_ring, ++ u32 cnt) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; ++ u32 rx_cnt; ++ ++ while (cnt && rtwdev->napi_budget_countdown > 0) { ++ rx_cnt = rtw89_pci_rxbd_deliver_skbs(rtwdev, rx_ring); ++ if (!rx_cnt) { ++ rtw89_err(rtwdev, "failed to deliver RXBD skb\n"); ++ ++ /* skip the rest RXBD bufs */ ++ rtw89_pci_rxbd_increase(rx_ring, cnt); ++ break; ++ } ++ ++ cnt -= rx_cnt; ++ } ++ ++ rtw89_write16(rtwdev, bd_ring->addr_idx, bd_ring->wp); ++} ++ ++static int rtw89_pci_poll_rxq_dma(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci, int budget) ++{ ++ struct rtw89_pci_rx_ring *rx_ring; ++ int countdown = rtwdev->napi_budget_countdown; ++ u32 cnt; ++ ++ rx_ring = &rtwpci->rx_rings[RTW89_RXCH_RXQ]; ++ ++ cnt = rtw89_pci_rxbd_recalc(rtwdev, rx_ring); ++ if (!cnt) ++ return 0; ++ ++ cnt = min_t(u32, budget, cnt); ++ ++ rtw89_pci_rxbd_deliver(rtwdev, rx_ring, cnt); ++ ++ /* In case of flushing pending SKBs, the countdown may exceed. */ ++ if (rtwdev->napi_budget_countdown <= 0) ++ return budget; ++ ++ return budget - countdown; ++} ++ ++static void rtw89_pci_tx_status(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring, ++ struct sk_buff *skb, u8 tx_status) ++{ ++ struct ieee80211_tx_info *info; ++ ++ info = IEEE80211_SKB_CB(skb); ++ ieee80211_tx_info_clear_status(info); ++ ++ if (info->flags & IEEE80211_TX_CTL_NO_ACK) ++ info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; ++ if (tx_status == RTW89_TX_DONE) { ++ info->flags |= IEEE80211_TX_STAT_ACK; ++ tx_ring->tx_acked++; ++ } else { ++ if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) ++ rtw89_debug(rtwdev, RTW89_DBG_FW, ++ "failed to TX of status %x\n", tx_status); ++ switch (tx_status) { ++ case RTW89_TX_RETRY_LIMIT: ++ tx_ring->tx_retry_lmt++; ++ break; ++ case RTW89_TX_LIFE_TIME: ++ tx_ring->tx_life_time++; ++ break; ++ case RTW89_TX_MACID_DROP: ++ tx_ring->tx_mac_id_drop++; ++ break; ++ default: ++ rtw89_warn(rtwdev, "invalid TX status %x\n", tx_status); ++ break; ++ } ++ } ++ ++ ieee80211_tx_status_ni(rtwdev->hw, skb); ++} ++ ++static void rtw89_pci_reclaim_txbd(struct rtw89_dev *rtwdev, struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_tx_wd *txwd; ++ u32 cnt; ++ ++ cnt = rtw89_pci_txbd_recalc(rtwdev, tx_ring); ++ while (cnt--) { ++ txwd = list_first_entry_or_null(&tx_ring->busy_pages, struct rtw89_pci_tx_wd, list); ++ if (!txwd) { ++ rtw89_warn(rtwdev, "No busy txwd pages available\n"); ++ break; ++ } ++ ++ list_del_init(&txwd->list); ++ } ++} ++ ++static void rtw89_pci_release_busy_txwd(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; ++ struct rtw89_pci_tx_wd *txwd; ++ int i; ++ ++ for (i = 0; i < wd_ring->page_num; i++) { ++ txwd = list_first_entry_or_null(&tx_ring->busy_pages, struct rtw89_pci_tx_wd, list); ++ if (!txwd) ++ break; ++ ++ list_del_init(&txwd->list); ++ } ++} ++ ++static void rtw89_pci_release_txwd_skb(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring, ++ struct rtw89_pci_tx_wd *txwd, u16 seq, ++ u8 tx_status) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_data *tx_data; ++ struct sk_buff *skb, *tmp; ++ u8 txch = tx_ring->txch; ++ ++ if (!list_empty(&txwd->list)) { ++ rtw89_warn(rtwdev, "queue %d txwd %d is not idle\n", ++ txch, seq); ++ return; ++ } ++ ++ /* currently, support for only one frame */ ++ if (skb_queue_len(&txwd->queue) != 1) { ++ rtw89_warn(rtwdev, "empty pending queue %d page %d\n", ++ txch, seq); ++ return; ++ } ++ ++ skb_queue_walk_safe(&txwd->queue, skb, tmp) { ++ skb_unlink(skb, &txwd->queue); ++ ++ tx_data = RTW89_PCI_TX_SKB_CB(skb); ++ dma_unmap_single(&rtwpci->pdev->dev, tx_data->dma, skb->len, ++ DMA_TO_DEVICE); ++ ++ rtw89_pci_tx_status(rtwdev, tx_ring, skb, tx_status); ++ } ++ ++ rtw89_pci_enqueue_txwd(tx_ring, txwd); ++} ++ ++static void rtw89_pci_release_rpp(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_rpp_fmt *rpp) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring; ++ struct rtw89_pci_tx_wd_ring *wd_ring; ++ struct rtw89_pci_tx_wd *txwd; ++ u16 seq; ++ u8 qsel, tx_status, txch; ++ ++ seq = le32_get_bits(rpp->dword, RTW89_PCI_RPP_SEQ); ++ qsel = le32_get_bits(rpp->dword, RTW89_PCI_RPP_QSEL); ++ tx_status = le32_get_bits(rpp->dword, RTW89_PCI_RPP_TX_STATUS); ++ txch = rtw89_core_get_ch_dma(rtwdev, qsel); ++ ++ if (txch == RTW89_TXCH_CH12) { ++ rtw89_warn(rtwdev, "should no fwcmd release report\n"); ++ return; ++ } ++ ++ tx_ring = &rtwpci->tx_rings[txch]; ++ rtw89_pci_reclaim_txbd(rtwdev, tx_ring); ++ wd_ring = &tx_ring->wd_ring; ++ txwd = &wd_ring->pages[seq]; ++ ++ rtw89_pci_release_txwd_skb(rtwdev, tx_ring, txwd, seq, tx_status); ++} ++ ++static void rtw89_pci_release_pending_txwd_skb(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; ++ struct rtw89_pci_tx_wd *txwd; ++ int i; ++ ++ for (i = 0; i < wd_ring->page_num; i++) { ++ txwd = &wd_ring->pages[i]; ++ ++ if (!list_empty(&txwd->list)) ++ continue; ++ ++ rtw89_pci_release_txwd_skb(rtwdev, tx_ring, txwd, i, RTW89_TX_MACID_DROP); ++ } ++} ++ ++static u32 rtw89_pci_release_tx_skbs(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_rx_ring *rx_ring, ++ u32 max_cnt) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; ++ struct rtw89_pci_rx_info *rx_info; ++ struct rtw89_pci_rpp_fmt *rpp; ++ struct rtw89_rx_desc_info desc_info = {}; ++ struct sk_buff *skb; ++ u32 cnt = 0; ++ u32 rpp_size = sizeof(struct rtw89_pci_rpp_fmt); ++ u32 rxinfo_size = sizeof(struct rtw89_pci_rxbd_info); ++ u32 offset; ++ int ret; ++ ++ skb = rx_ring->buf[bd_ring->wp]; ++ rtw89_pci_sync_skb_for_cpu(rtwdev, skb); ++ ++ ret = rtw89_pci_rxbd_info_update(rtwdev, skb); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to update %d RXBD info: %d\n", ++ bd_ring->wp, ret); ++ goto err_sync_device; ++ } ++ ++ rx_info = RTW89_PCI_RX_SKB_CB(skb); ++ if (!rx_info->fs || !rx_info->ls) { ++ rtw89_err(rtwdev, "cannot process RP frame not set FS/LS\n"); ++ return cnt; ++ } ++ ++ rtw89_core_query_rxdesc(rtwdev, &desc_info, skb->data, rxinfo_size); ++ ++ /* first segment has RX desc */ ++ offset = desc_info.offset; ++ offset += desc_info.long_rxdesc ? sizeof(struct rtw89_rxdesc_long) : ++ sizeof(struct rtw89_rxdesc_short); ++ for (; offset + rpp_size <= rx_info->len; offset += rpp_size) { ++ rpp = (struct rtw89_pci_rpp_fmt *)(skb->data + offset); ++ rtw89_pci_release_rpp(rtwdev, rpp); ++ } ++ ++ rtw89_pci_sync_skb_for_device(rtwdev, skb); ++ rtw89_pci_rxbd_increase(rx_ring, 1); ++ cnt++; ++ ++ return cnt; ++ ++err_sync_device: ++ rtw89_pci_sync_skb_for_device(rtwdev, skb); ++ return 0; ++} ++ ++static void rtw89_pci_release_tx(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_rx_ring *rx_ring, ++ u32 cnt) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; ++ u32 release_cnt; ++ ++ while (cnt) { ++ release_cnt = rtw89_pci_release_tx_skbs(rtwdev, rx_ring, cnt); ++ if (!release_cnt) { ++ rtw89_err(rtwdev, "failed to release TX skbs\n"); ++ ++ /* skip the rest RXBD bufs */ ++ rtw89_pci_rxbd_increase(rx_ring, cnt); ++ break; ++ } ++ ++ cnt -= release_cnt; ++ } ++ ++ rtw89_write16(rtwdev, bd_ring->addr_idx, bd_ring->wp); ++} ++ ++static int rtw89_pci_poll_rpq_dma(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci, int budget) ++{ ++ struct rtw89_pci_rx_ring *rx_ring; ++ u32 cnt; ++ int work_done; ++ ++ rx_ring = &rtwpci->rx_rings[RTW89_RXCH_RPQ]; ++ ++ spin_lock_bh(&rtwpci->trx_lock); ++ ++ cnt = rtw89_pci_rxbd_recalc(rtwdev, rx_ring); ++ if (cnt == 0) ++ goto out_unlock; ++ ++ rtw89_pci_release_tx(rtwdev, rx_ring, cnt); ++ ++out_unlock: ++ spin_unlock_bh(&rtwpci->trx_lock); ++ ++ /* always release all RPQ */ ++ work_done = min_t(int, cnt, budget); ++ rtwdev->napi_budget_countdown -= work_done; ++ ++ return work_done; ++} ++ ++static void rtw89_pci_isr_rxd_unavail(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci) ++{ ++ struct rtw89_pci_rx_ring *rx_ring; ++ struct rtw89_pci_dma_ring *bd_ring; ++ u32 reg_idx; ++ u16 hw_idx, hw_idx_next, host_idx; ++ int i; ++ ++ for (i = 0; i < RTW89_RXCH_NUM; i++) { ++ rx_ring = &rtwpci->rx_rings[i]; ++ bd_ring = &rx_ring->bd_ring; ++ ++ reg_idx = rtw89_read32(rtwdev, bd_ring->addr_idx); ++ hw_idx = FIELD_GET(TXBD_HW_IDX_MASK, reg_idx); ++ host_idx = FIELD_GET(TXBD_HOST_IDX_MASK, reg_idx); ++ hw_idx_next = (hw_idx + 1) % bd_ring->len; ++ ++ if (hw_idx_next == host_idx) ++ rtw89_warn(rtwdev, "%d RXD unavailable\n", i); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXRX, ++ "%d RXD unavailable, idx=0x%08x, len=%d\n", ++ i, reg_idx, bd_ring->len); ++ } ++} ++ ++static void rtw89_pci_recognize_intrs(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci, ++ struct rtw89_pci_isrs *isrs) ++{ ++ isrs->halt_c2h_isrs = rtw89_read32(rtwdev, R_AX_HISR0) & rtwpci->halt_c2h_intrs; ++ isrs->isrs[0] = rtw89_read32(rtwdev, R_AX_PCIE_HISR00) & rtwpci->intrs[0]; ++ isrs->isrs[1] = rtw89_read32(rtwdev, R_AX_PCIE_HISR10) & rtwpci->intrs[1]; ++ ++ rtw89_write32(rtwdev, R_AX_HISR0, isrs->halt_c2h_isrs); ++ rtw89_write32(rtwdev, R_AX_PCIE_HISR00, isrs->isrs[0]); ++ rtw89_write32(rtwdev, R_AX_PCIE_HISR10, isrs->isrs[1]); ++} ++ ++static void rtw89_pci_clear_isr0(struct rtw89_dev *rtwdev, u32 isr00) ++{ ++ /* write 1 clear */ ++ rtw89_write32(rtwdev, R_AX_PCIE_HISR00, isr00); ++} ++ ++static void rtw89_pci_enable_intr(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci) ++{ ++ rtw89_write32(rtwdev, R_AX_HIMR0, rtwpci->halt_c2h_intrs); ++ rtw89_write32(rtwdev, R_AX_PCIE_HIMR00, rtwpci->intrs[0]); ++ rtw89_write32(rtwdev, R_AX_PCIE_HIMR10, rtwpci->intrs[1]); ++} ++ ++static void rtw89_pci_disable_intr(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci) ++{ ++ rtw89_write32(rtwdev, R_AX_HIMR0, 0); ++ rtw89_write32(rtwdev, R_AX_PCIE_HIMR00, 0); ++ rtw89_write32(rtwdev, R_AX_PCIE_HIMR10, 0); ++} ++ ++static irqreturn_t rtw89_pci_interrupt_threadfn(int irq, void *dev) ++{ ++ struct rtw89_dev *rtwdev = dev; ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_isrs isrs; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&rtwpci->irq_lock, flags); ++ rtw89_pci_recognize_intrs(rtwdev, rtwpci, &isrs); ++ spin_unlock_irqrestore(&rtwpci->irq_lock, flags); ++ ++ if (unlikely(isrs.isrs[0] & B_AX_RDU_INT)) ++ rtw89_pci_isr_rxd_unavail(rtwdev, rtwpci); ++ ++ if (unlikely(isrs.halt_c2h_isrs & B_AX_HALT_C2H_INT_EN)) ++ rtw89_ser_notify(rtwdev, rtw89_mac_get_err_status(rtwdev)); ++ ++ if (likely(rtwpci->running)) { ++ local_bh_disable(); ++ napi_schedule(&rtwdev->napi); ++ local_bh_enable(); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t rtw89_pci_interrupt_handler(int irq, void *dev) ++{ ++ struct rtw89_dev *rtwdev = dev; ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ unsigned long flags; ++ irqreturn_t irqret = IRQ_WAKE_THREAD; ++ ++ spin_lock_irqsave(&rtwpci->irq_lock, flags); ++ ++ /* If interrupt event is on the road, it is still trigger interrupt ++ * even we have done pci_stop() to turn off IMR. ++ */ ++ if (unlikely(!rtwpci->running)) { ++ irqret = IRQ_HANDLED; ++ goto exit; ++ } ++ ++ rtw89_pci_disable_intr(rtwdev, rtwpci); ++exit: ++ spin_unlock_irqrestore(&rtwpci->irq_lock, flags); ++ ++ return irqret; ++} ++ ++#define case_TXCHADDRS(txch) \ ++ case RTW89_TXCH_##txch: \ ++ *addr_num = R_AX_##txch##_TXBD_NUM; \ ++ *addr_idx = R_AX_##txch##_TXBD_IDX; \ ++ *addr_bdram = R_AX_##txch##_BDRAM_CTRL; \ ++ *addr_desa_l = R_AX_##txch##_TXBD_DESA_L; \ ++ *addr_desa_h = R_AX_##txch##_TXBD_DESA_H; \ ++ break ++ ++static int rtw89_pci_get_txch_addrs(enum rtw89_tx_channel txch, ++ u32 *addr_num, ++ u32 *addr_idx, ++ u32 *addr_bdram, ++ u32 *addr_desa_l, ++ u32 *addr_desa_h) ++{ ++ switch (txch) { ++ case_TXCHADDRS(ACH0); ++ case_TXCHADDRS(ACH1); ++ case_TXCHADDRS(ACH2); ++ case_TXCHADDRS(ACH3); ++ case_TXCHADDRS(ACH4); ++ case_TXCHADDRS(ACH5); ++ case_TXCHADDRS(ACH6); ++ case_TXCHADDRS(ACH7); ++ case_TXCHADDRS(CH8); ++ case_TXCHADDRS(CH9); ++ case_TXCHADDRS(CH10); ++ case_TXCHADDRS(CH11); ++ case_TXCHADDRS(CH12); ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++#undef case_TXCHADDRS ++ ++#define case_RXCHADDRS(rxch) \ ++ case RTW89_RXCH_##rxch: \ ++ *addr_num = R_AX_##rxch##_RXBD_NUM; \ ++ *addr_idx = R_AX_##rxch##_RXBD_IDX; \ ++ *addr_desa_l = R_AX_##rxch##_RXBD_DESA_L; \ ++ *addr_desa_h = R_AX_##rxch##_RXBD_DESA_H; \ ++ break ++ ++static int rtw89_pci_get_rxch_addrs(enum rtw89_rx_channel rxch, ++ u32 *addr_num, ++ u32 *addr_idx, ++ u32 *addr_desa_l, ++ u32 *addr_desa_h) ++{ ++ switch (rxch) { ++ case_RXCHADDRS(RXQ); ++ case_RXCHADDRS(RPQ); ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++#undef case_RXCHADDRS ++ ++static u32 rtw89_pci_get_avail_txbd_num(struct rtw89_pci_tx_ring *ring) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &ring->bd_ring; ++ ++ /* reserved 1 desc check ring is full or not */ ++ if (bd_ring->rp > bd_ring->wp) ++ return bd_ring->rp - bd_ring->wp - 1; ++ ++ return bd_ring->len - (bd_ring->wp - bd_ring->rp) - 1; ++} ++ ++static ++u32 __rtw89_pci_check_and_reclaim_tx_fwcmd_resource(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[RTW89_TXCH_CH12]; ++ u32 cnt; ++ ++ spin_lock_bh(&rtwpci->trx_lock); ++ rtw89_pci_reclaim_tx_fwcmd(rtwdev, rtwpci); ++ cnt = rtw89_pci_get_avail_txbd_num(tx_ring); ++ spin_unlock_bh(&rtwpci->trx_lock); ++ ++ return cnt; ++} ++ ++static u32 __rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, ++ u8 txch) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[txch]; ++ struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; ++ u32 bd_cnt, wd_cnt, min_cnt = 0; ++ struct rtw89_pci_rx_ring *rx_ring; ++ u32 cnt; ++ ++ rx_ring = &rtwpci->rx_rings[RTW89_RXCH_RPQ]; ++ ++ spin_lock_bh(&rtwpci->trx_lock); ++ bd_cnt = rtw89_pci_get_avail_txbd_num(tx_ring); ++ wd_cnt = wd_ring->curr_num; ++ ++ if (wd_cnt == 0 || bd_cnt == 0) { ++ cnt = rtw89_pci_rxbd_recalc(rtwdev, rx_ring); ++ if (!cnt) ++ goto out_unlock; ++ rtw89_pci_release_tx(rtwdev, rx_ring, cnt); ++ } ++ ++ bd_cnt = rtw89_pci_get_avail_txbd_num(tx_ring); ++ wd_cnt = wd_ring->curr_num; ++ min_cnt = min(bd_cnt, wd_cnt); ++ if (min_cnt == 0) ++ rtw89_warn(rtwdev, "still no tx resource after reclaim\n"); ++ ++out_unlock: ++ spin_unlock_bh(&rtwpci->trx_lock); ++ ++ return min_cnt; ++} ++ ++static u32 rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, ++ u8 txch) ++{ ++ if (txch == RTW89_TXCH_CH12) ++ return __rtw89_pci_check_and_reclaim_tx_fwcmd_resource(rtwdev); ++ ++ return __rtw89_pci_check_and_reclaim_tx_resource(rtwdev, txch); ++} ++ ++static void __rtw89_pci_tx_kick_off(struct rtw89_dev *rtwdev, struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; ++ u32 host_idx, addr; ++ ++ addr = bd_ring->addr_idx; ++ host_idx = bd_ring->wp; ++ rtw89_write16(rtwdev, addr, host_idx); ++} ++ ++static void rtw89_pci_tx_bd_ring_update(struct rtw89_dev *rtwdev, struct rtw89_pci_tx_ring *tx_ring, ++ int n_txbd) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; ++ u32 host_idx, len; ++ ++ len = bd_ring->len; ++ host_idx = bd_ring->wp + n_txbd; ++ host_idx = host_idx < len ? host_idx : host_idx - len; ++ ++ bd_ring->wp = host_idx; ++} ++ ++static void rtw89_pci_ops_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[txch]; ++ ++ spin_lock_bh(&rtwpci->trx_lock); ++ __rtw89_pci_tx_kick_off(rtwdev, tx_ring); ++ spin_unlock_bh(&rtwpci->trx_lock); ++} ++ ++static void __pci_flush_txch(struct rtw89_dev *rtwdev, u8 txch, bool drop) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[txch]; ++ struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; ++ u32 cur_idx, cur_rp; ++ u8 i; ++ ++ /* Because the time taked by the I/O is a bit dynamic, it's hard to ++ * define a reasonable fixed total timeout to use read_poll_timeout* ++ * helper. Instead, we can ensure a reasonable polling times, so we ++ * just use for loop with udelay here. ++ */ ++ for (i = 0; i < 60; i++) { ++ cur_idx = rtw89_read32(rtwdev, bd_ring->addr_idx); ++ cur_rp = FIELD_GET(TXBD_HW_IDX_MASK, cur_idx); ++ if (cur_rp == bd_ring->wp) ++ return; ++ ++ udelay(1); ++ } ++ ++ if (!drop) ++ rtw89_info(rtwdev, "timed out to flush pci txch: %d\n", txch); ++} ++ ++static void __rtw89_pci_ops_flush_txchs(struct rtw89_dev *rtwdev, u32 txchs, ++ bool drop) ++{ ++ u8 i; ++ ++ for (i = 0; i < RTW89_TXCH_NUM; i++) { ++ /* It may be unnecessary to flush FWCMD queue. */ ++ if (i == RTW89_TXCH_CH12) ++ continue; ++ ++ if (txchs & BIT(i)) ++ __pci_flush_txch(rtwdev, i, drop); ++ } ++} ++ ++static void rtw89_pci_ops_flush_queues(struct rtw89_dev *rtwdev, u32 queues, ++ bool drop) ++{ ++ __rtw89_pci_ops_flush_txchs(rtwdev, BIT(RTW89_TXCH_NUM) - 1, drop); ++} ++ ++static int rtw89_pci_txwd_submit(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring, ++ struct rtw89_pci_tx_wd *txwd, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; ++ struct rtw89_txwd_body *txwd_body; ++ struct rtw89_txwd_info *txwd_info; ++ struct rtw89_pci_tx_wp_info *txwp_info; ++ struct rtw89_pci_tx_addr_info_32 *txaddr_info; ++ struct pci_dev *pdev = rtwpci->pdev; ++ struct sk_buff *skb = tx_req->skb; ++ struct rtw89_pci_tx_data *tx_data = RTW89_PCI_TX_SKB_CB(skb); ++ bool en_wd_info = desc_info->en_wd_info; ++ u32 txwd_len; ++ u32 txwp_len; ++ u32 txaddr_info_len; ++ dma_addr_t dma; ++ int ret; ++ ++ rtw89_core_fill_txdesc(rtwdev, desc_info, txwd->vaddr); ++ ++ dma = dma_map_single(&pdev->dev, skb->data, skb->len, DMA_TO_DEVICE); ++ if (dma_mapping_error(&pdev->dev, dma)) { ++ rtw89_err(rtwdev, "failed to map skb dma data\n"); ++ ret = -EBUSY; ++ goto err; ++ } ++ ++ tx_data->dma = dma; ++ ++ txaddr_info_len = sizeof(*txaddr_info); ++ txwp_len = sizeof(*txwp_info); ++ txwd_len = sizeof(*txwd_body); ++ txwd_len += en_wd_info ? sizeof(*txwd_info) : 0; ++ ++ txwp_info = txwd->vaddr + txwd_len; ++ txwp_info->seq0 = cpu_to_le16(txwd->seq | RTW89_PCI_TXWP_VALID); ++ txwp_info->seq1 = 0; ++ txwp_info->seq2 = 0; ++ txwp_info->seq3 = 0; ++ ++ tx_ring->tx_cnt++; ++ txaddr_info = txwd->vaddr + txwd_len + txwp_len; ++ txaddr_info->length = cpu_to_le16(skb->len); ++ txaddr_info->option = cpu_to_le16(RTW89_PCI_ADDR_MSDU_LS | ++ RTW89_PCI_ADDR_NUM(1)); ++ txaddr_info->dma = cpu_to_le32(dma); ++ ++ txwd->len = txwd_len + txwp_len + txaddr_info_len; ++ ++ skb_queue_tail(&txwd->queue, skb); ++ ++ return 0; ++ ++err: ++ return ret; ++} ++ ++static int rtw89_pci_fwcmd_submit(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring, ++ struct rtw89_pci_tx_bd_32 *txbd, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; ++ struct rtw89_txwd_body *txwd_body; ++ struct pci_dev *pdev = rtwpci->pdev; ++ struct sk_buff *skb = tx_req->skb; ++ struct rtw89_pci_tx_data *tx_data = RTW89_PCI_TX_SKB_CB(skb); ++ dma_addr_t dma; ++ ++ txwd_body = (struct rtw89_txwd_body *)skb_push(skb, sizeof(*txwd_body)); ++ memset(txwd_body, 0, sizeof(*txwd_body)); ++ rtw89_core_fill_txdesc(rtwdev, desc_info, txwd_body); ++ ++ dma = dma_map_single(&pdev->dev, skb->data, skb->len, DMA_TO_DEVICE); ++ if (dma_mapping_error(&pdev->dev, dma)) { ++ rtw89_err(rtwdev, "failed to map fwcmd dma data\n"); ++ return -EBUSY; ++ } ++ ++ tx_data->dma = dma; ++ txbd->option = cpu_to_le16(RTW89_PCI_TXBD_OPTION_LS); ++ txbd->length = cpu_to_le16(skb->len); ++ txbd->dma = cpu_to_le32(tx_data->dma); ++ skb_queue_tail(&rtwpci->h2c_queue, skb); ++ ++ rtw89_pci_tx_bd_ring_update(rtwdev, tx_ring, 1); ++ ++ return 0; ++} ++ ++static int rtw89_pci_txbd_submit(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring, ++ struct rtw89_pci_tx_bd_32 *txbd, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ struct rtw89_pci_tx_wd *txwd; ++ int ret; ++ ++ /* FWCMD queue doesn't have wd pages. Instead, it submits the CMD ++ * buffer with WD BODY only. So here we don't need to check the free ++ * pages of the wd ring. ++ */ ++ if (tx_ring->txch == RTW89_TXCH_CH12) ++ return rtw89_pci_fwcmd_submit(rtwdev, tx_ring, txbd, tx_req); ++ ++ txwd = rtw89_pci_dequeue_txwd(tx_ring); ++ if (!txwd) { ++ rtw89_err(rtwdev, "no available TXWD\n"); ++ ret = -ENOSPC; ++ goto err; ++ } ++ ++ ret = rtw89_pci_txwd_submit(rtwdev, tx_ring, txwd, tx_req); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to submit TXWD %d\n", txwd->seq); ++ goto err_enqueue_wd; ++ } ++ ++ list_add_tail(&txwd->list, &tx_ring->busy_pages); ++ ++ txbd->option = cpu_to_le16(RTW89_PCI_TXBD_OPTION_LS); ++ txbd->length = cpu_to_le16(txwd->len); ++ txbd->dma = cpu_to_le32(txwd->paddr); ++ ++ rtw89_pci_tx_bd_ring_update(rtwdev, tx_ring, 1); ++ ++ return 0; ++ ++err_enqueue_wd: ++ rtw89_pci_enqueue_txwd(tx_ring, txwd); ++err: ++ return ret; ++} ++ ++static int rtw89_pci_tx_write(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req, ++ u8 txch) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring; ++ struct rtw89_pci_tx_bd_32 *txbd; ++ u32 n_avail_txbd; ++ int ret = 0; ++ ++ /* check the tx type and dma channel for fw cmd queue */ ++ if ((txch == RTW89_TXCH_CH12 || ++ tx_req->tx_type == RTW89_CORE_TX_TYPE_FWCMD) && ++ (txch != RTW89_TXCH_CH12 || ++ tx_req->tx_type != RTW89_CORE_TX_TYPE_FWCMD)) { ++ rtw89_err(rtwdev, "only fw cmd uses dma channel 12\n"); ++ return -EINVAL; ++ } ++ ++ tx_ring = &rtwpci->tx_rings[txch]; ++ spin_lock_bh(&rtwpci->trx_lock); ++ ++ n_avail_txbd = rtw89_pci_get_avail_txbd_num(tx_ring); ++ if (n_avail_txbd == 0) { ++ rtw89_err(rtwdev, "no available TXBD\n"); ++ ret = -ENOSPC; ++ goto err_unlock; ++ } ++ ++ txbd = rtw89_pci_get_next_txbd(tx_ring); ++ ret = rtw89_pci_txbd_submit(rtwdev, tx_ring, txbd, tx_req); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to submit TXBD\n"); ++ goto err_unlock; ++ } ++ ++ spin_unlock_bh(&rtwpci->trx_lock); ++ return 0; ++ ++err_unlock: ++ spin_unlock_bh(&rtwpci->trx_lock); ++ return ret; ++} ++ ++static int rtw89_pci_ops_tx_write(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) ++{ ++ struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; ++ int ret; ++ ++ ret = rtw89_pci_tx_write(rtwdev, tx_req, desc_info->ch_dma); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to TX Queue %d\n", desc_info->ch_dma); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static const struct rtw89_pci_bd_ram bd_ram_table[RTW89_TXCH_NUM] = { ++ [RTW89_TXCH_ACH0] = {.start_idx = 0, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_ACH1] = {.start_idx = 5, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_ACH2] = {.start_idx = 10, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_ACH3] = {.start_idx = 15, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_ACH4] = {.start_idx = 20, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_ACH5] = {.start_idx = 25, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_ACH6] = {.start_idx = 30, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_ACH7] = {.start_idx = 35, .max_num = 5, .min_num = 2}, ++ [RTW89_TXCH_CH8] = {.start_idx = 40, .max_num = 5, .min_num = 1}, ++ [RTW89_TXCH_CH9] = {.start_idx = 45, .max_num = 5, .min_num = 1}, ++ [RTW89_TXCH_CH10] = {.start_idx = 50, .max_num = 5, .min_num = 1}, ++ [RTW89_TXCH_CH11] = {.start_idx = 55, .max_num = 5, .min_num = 1}, ++ [RTW89_TXCH_CH12] = {.start_idx = 60, .max_num = 4, .min_num = 1}, ++}; ++ ++static void rtw89_pci_reset_trx_rings(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring; ++ struct rtw89_pci_rx_ring *rx_ring; ++ struct rtw89_pci_dma_ring *bd_ring; ++ const struct rtw89_pci_bd_ram *bd_ram; ++ u32 addr_num; ++ u32 addr_bdram; ++ u32 addr_desa_l; ++ u32 val32; ++ int i; ++ ++ for (i = 0; i < RTW89_TXCH_NUM; i++) { ++ tx_ring = &rtwpci->tx_rings[i]; ++ bd_ring = &tx_ring->bd_ring; ++ bd_ram = &bd_ram_table[i]; ++ addr_num = bd_ring->addr_num; ++ addr_bdram = bd_ring->addr_bdram; ++ addr_desa_l = bd_ring->addr_desa_l; ++ bd_ring->wp = 0; ++ bd_ring->rp = 0; ++ ++ val32 = FIELD_PREP(BDRAM_SIDX_MASK, bd_ram->start_idx) | ++ FIELD_PREP(BDRAM_MAX_MASK, bd_ram->max_num) | ++ FIELD_PREP(BDRAM_MIN_MASK, bd_ram->min_num); ++ ++ rtw89_write16(rtwdev, addr_num, bd_ring->len); ++ rtw89_write32(rtwdev, addr_bdram, val32); ++ rtw89_write32(rtwdev, addr_desa_l, bd_ring->dma); ++ } ++ ++ for (i = 0; i < RTW89_RXCH_NUM; i++) { ++ rx_ring = &rtwpci->rx_rings[i]; ++ bd_ring = &rx_ring->bd_ring; ++ addr_num = bd_ring->addr_num; ++ addr_desa_l = bd_ring->addr_desa_l; ++ bd_ring->wp = 0; ++ bd_ring->rp = 0; ++ rx_ring->diliver_skb = NULL; ++ rx_ring->diliver_desc.ready = false; ++ ++ rtw89_write16(rtwdev, addr_num, bd_ring->len); ++ rtw89_write32(rtwdev, addr_desa_l, bd_ring->dma); ++ } ++} ++ ++static void rtw89_pci_release_tx_ring(struct rtw89_dev *rtwdev, ++ struct rtw89_pci_tx_ring *tx_ring) ++{ ++ rtw89_pci_release_busy_txwd(rtwdev, tx_ring); ++ rtw89_pci_release_pending_txwd_skb(rtwdev, tx_ring); ++} ++ ++static void rtw89_pci_ops_reset(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ int txch; ++ ++ rtw89_pci_reset_trx_rings(rtwdev); ++ ++ spin_lock_bh(&rtwpci->trx_lock); ++ for (txch = 0; txch < RTW89_TXCH_NUM; txch++) { ++ if (txch == RTW89_TXCH_CH12) { ++ rtw89_pci_release_fwcmd(rtwdev, rtwpci, ++ skb_queue_len(&rtwpci->h2c_queue), true); ++ continue; ++ } ++ rtw89_pci_release_tx_ring(rtwdev, &rtwpci->tx_rings[txch]); ++ } ++ spin_unlock_bh(&rtwpci->trx_lock); ++} ++ ++static int rtw89_pci_ops_start(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ unsigned long flags; ++ ++ rtw89_core_napi_start(rtwdev); ++ ++ spin_lock_irqsave(&rtwpci->irq_lock, flags); ++ rtwpci->running = true; ++ rtw89_pci_enable_intr(rtwdev, rtwpci); ++ spin_unlock_irqrestore(&rtwpci->irq_lock, flags); ++ ++ return 0; ++} ++ ++static void rtw89_pci_ops_stop(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct pci_dev *pdev = rtwpci->pdev; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&rtwpci->irq_lock, flags); ++ rtwpci->running = false; ++ rtw89_pci_disable_intr(rtwdev, rtwpci); ++ spin_unlock_irqrestore(&rtwpci->irq_lock, flags); ++ ++ synchronize_irq(pdev->irq); ++ rtw89_core_napi_stop(rtwdev); ++} ++ ++static void rtw89_pci_ops_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data); ++ ++static u32 rtw89_pci_ops_read32_cmac(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ u32 val = readl(rtwpci->mmap + addr); ++ int count; ++ ++ for (count = 0; ; count++) { ++ if (val != RTW89_R32_DEAD) ++ return val; ++ if (count >= MAC_REG_POOL_COUNT) { ++ rtw89_warn(rtwdev, "addr %#x = %#x\n", addr, val); ++ return RTW89_R32_DEAD; ++ } ++ rtw89_pci_ops_write32(rtwdev, R_AX_CK_EN, B_AX_CMAC_ALLCKEN); ++ val = readl(rtwpci->mmap + addr); ++ } ++ ++ return val; ++} ++ ++static u8 rtw89_pci_ops_read8(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ u32 addr32, val32, shift; ++ ++ if (!ACCESS_CMAC(addr)) ++ return readb(rtwpci->mmap + addr); ++ ++ addr32 = addr & ~0x3; ++ shift = (addr & 0x3) * 8; ++ val32 = rtw89_pci_ops_read32_cmac(rtwdev, addr32); ++ return val32 >> shift; ++} ++ ++static u16 rtw89_pci_ops_read16(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ u32 addr32, val32, shift; ++ ++ if (!ACCESS_CMAC(addr)) ++ return readw(rtwpci->mmap + addr); ++ ++ addr32 = addr & ~0x3; ++ shift = (addr & 0x3) * 8; ++ val32 = rtw89_pci_ops_read32_cmac(rtwdev, addr32); ++ return val32 >> shift; ++} ++ ++static u32 rtw89_pci_ops_read32(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ ++ if (!ACCESS_CMAC(addr)) ++ return readl(rtwpci->mmap + addr); ++ ++ return rtw89_pci_ops_read32_cmac(rtwdev, addr); ++} ++ ++static void rtw89_pci_ops_write8(struct rtw89_dev *rtwdev, u32 addr, u8 data) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ ++ writeb(data, rtwpci->mmap + addr); ++} ++ ++static void rtw89_pci_ops_write16(struct rtw89_dev *rtwdev, u32 addr, u16 data) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ ++ writew(data, rtwpci->mmap + addr); ++} ++ ++static void rtw89_pci_ops_write32(struct rtw89_dev *rtwdev, u32 addr, u32 data) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ ++ writel(data, rtwpci->mmap + addr); ++} ++ ++static void rtw89_pci_ctrl_dma_all(struct rtw89_dev *rtwdev, bool enable) ++{ ++ if (enable) { ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, ++ B_AX_TXHCI_EN | B_AX_RXHCI_EN); ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP1, ++ B_AX_STOP_PCIEIO); ++ } else { ++ rtw89_write32_set(rtwdev, R_AX_PCIE_DMA_STOP1, ++ B_AX_STOP_PCIEIO); ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, ++ B_AX_TXHCI_EN | B_AX_RXHCI_EN); ++ } ++} ++ ++static int rtw89_pci_check_mdio(struct rtw89_dev *rtwdev, u8 addr, u8 speed, u16 rw_bit) ++{ ++ u16 val; ++ ++ rtw89_write8(rtwdev, R_AX_MDIO_CFG, addr & 0x1F); ++ ++ val = rtw89_read16(rtwdev, R_AX_MDIO_CFG); ++ switch (speed) { ++ case PCIE_PHY_GEN1: ++ if (addr < 0x20) ++ val = u16_replace_bits(val, MDIO_PG0_G1, B_AX_MDIO_PHY_ADDR_MASK); ++ else ++ val = u16_replace_bits(val, MDIO_PG1_G1, B_AX_MDIO_PHY_ADDR_MASK); ++ break; ++ case PCIE_PHY_GEN2: ++ if (addr < 0x20) ++ val = u16_replace_bits(val, MDIO_PG0_G2, B_AX_MDIO_PHY_ADDR_MASK); ++ else ++ val = u16_replace_bits(val, MDIO_PG1_G2, B_AX_MDIO_PHY_ADDR_MASK); ++ break; ++ default: ++ rtw89_err(rtwdev, "[ERR]Error Speed %d!\n", speed); ++ return -EINVAL; ++ }; ++ rtw89_write16(rtwdev, R_AX_MDIO_CFG, val); ++ rtw89_write16_set(rtwdev, R_AX_MDIO_CFG, rw_bit); ++ ++ return read_poll_timeout(rtw89_read16, val, !(val & rw_bit), 10, 2000, ++ false, rtwdev, R_AX_MDIO_CFG); ++} ++ ++static int ++rtw89_read16_mdio(struct rtw89_dev *rtwdev, u8 addr, u8 speed, u16 *val) ++{ ++ int ret; ++ ++ ret = rtw89_pci_check_mdio(rtwdev, addr, speed, B_AX_MDIO_RFLAG); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]MDIO R16 0x%X fail ret=%d!\n", addr, ret); ++ return ret; ++ } ++ *val = rtw89_read16(rtwdev, R_AX_MDIO_RDATA); ++ ++ return 0; ++} ++ ++static int ++rtw89_write16_mdio(struct rtw89_dev *rtwdev, u8 addr, u16 data, u8 speed) ++{ ++ int ret; ++ ++ rtw89_write16(rtwdev, R_AX_MDIO_WDATA, data); ++ ret = rtw89_pci_check_mdio(rtwdev, addr, speed, B_AX_MDIO_WFLAG); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]MDIO W16 0x%X = %x fail ret=%d!\n", addr, data, ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int rtw89_write16_mdio_set(struct rtw89_dev *rtwdev, u8 addr, u16 mask, u8 speed) ++{ ++ int ret; ++ u16 val; ++ ++ ret = rtw89_read16_mdio(rtwdev, addr, speed, &val); ++ if (ret) ++ return ret; ++ ret = rtw89_write16_mdio(rtwdev, addr, val | mask, speed); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int rtw89_write16_mdio_clr(struct rtw89_dev *rtwdev, u8 addr, u16 mask, u8 speed) ++{ ++ int ret; ++ u16 val; ++ ++ ret = rtw89_read16_mdio(rtwdev, addr, speed, &val); ++ if (ret) ++ return ret; ++ ret = rtw89_write16_mdio(rtwdev, addr, val & ~mask, speed); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int rtw89_dbi_write8(struct rtw89_dev *rtwdev, u16 addr, u8 data) ++{ ++ u16 write_addr; ++ u16 remainder = addr & ~(B_AX_DBI_ADDR_MSK | B_AX_DBI_WREN_MSK); ++ u8 flag; ++ int ret; ++ ++ write_addr = addr & B_AX_DBI_ADDR_MSK; ++ write_addr |= u16_encode_bits(BIT(remainder), B_AX_DBI_WREN_MSK); ++ rtw89_write8(rtwdev, R_AX_DBI_WDATA + remainder, data); ++ rtw89_write16(rtwdev, R_AX_DBI_FLAG, write_addr); ++ rtw89_write8(rtwdev, R_AX_DBI_FLAG + 2, B_AX_DBI_WFLAG >> 16); ++ ++ ret = read_poll_timeout_atomic(rtw89_read8, flag, !flag, 10, ++ 10 * RTW89_PCI_WR_RETRY_CNT, false, ++ rtwdev, R_AX_DBI_FLAG + 2); ++ if (ret) ++ WARN(flag, "failed to write to DBI register, addr=0x%04x\n", ++ addr); ++ ++ return ret; ++} ++ ++static int rtw89_dbi_read8(struct rtw89_dev *rtwdev, u16 addr, u8 *value) ++{ ++ u16 read_addr = addr & B_AX_DBI_ADDR_MSK; ++ u8 flag; ++ int ret; ++ ++ rtw89_write16(rtwdev, R_AX_DBI_FLAG, read_addr); ++ rtw89_write8(rtwdev, R_AX_DBI_FLAG + 2, B_AX_DBI_RFLAG >> 16); ++ ++ ret = read_poll_timeout_atomic(rtw89_read8, flag, !flag, 10, ++ 10 * RTW89_PCI_WR_RETRY_CNT, false, ++ rtwdev, R_AX_DBI_FLAG + 2); ++ ++ if (!ret) { ++ read_addr = R_AX_DBI_RDATA + (addr & 3); ++ *value = rtw89_read8(rtwdev, read_addr); ++ } else { ++ WARN(1, "failed to read DBI register, addr=0x%04x\n", addr); ++ ret = -EIO; ++ } ++ ++ return ret; ++} ++ ++static int rtw89_dbi_write8_set(struct rtw89_dev *rtwdev, u16 addr, u8 bit) ++{ ++ u8 value; ++ int ret; ++ ++ ret = rtw89_dbi_read8(rtwdev, addr, &value); ++ if (ret) ++ return ret; ++ ++ value |= bit; ++ ret = rtw89_dbi_write8(rtwdev, addr, value); ++ ++ return ret; ++} ++ ++static int rtw89_dbi_write8_clr(struct rtw89_dev *rtwdev, u16 addr, u8 bit) ++{ ++ u8 value; ++ int ret; ++ ++ ret = rtw89_dbi_read8(rtwdev, addr, &value); ++ if (ret) ++ return ret; ++ ++ value &= ~bit; ++ ret = rtw89_dbi_write8(rtwdev, addr, value); ++ ++ return ret; ++} ++ ++static int ++__get_target(struct rtw89_dev *rtwdev, u16 *target, enum rtw89_pcie_phy phy_rate) ++{ ++ u16 val, tar; ++ int ret; ++ ++ /* Enable counter */ ++ ret = rtw89_read16_mdio(rtwdev, RAC_CTRL_PPR_V1, phy_rate, &val); ++ if (ret) ++ return ret; ++ ret = rtw89_write16_mdio(rtwdev, RAC_CTRL_PPR_V1, val & ~B_AX_CLK_CALIB_EN, ++ phy_rate); ++ if (ret) ++ return ret; ++ ret = rtw89_write16_mdio(rtwdev, RAC_CTRL_PPR_V1, val | B_AX_CLK_CALIB_EN, ++ phy_rate); ++ if (ret) ++ return ret; ++ ++ fsleep(300); ++ ++ ret = rtw89_read16_mdio(rtwdev, RAC_CTRL_PPR_V1, phy_rate, &tar); ++ if (ret) ++ return ret; ++ ret = rtw89_write16_mdio(rtwdev, RAC_CTRL_PPR_V1, val & ~B_AX_CLK_CALIB_EN, ++ phy_rate); ++ if (ret) ++ return ret; ++ ++ tar = tar & 0x0FFF; ++ if (tar == 0 || tar == 0x0FFF) { ++ rtw89_err(rtwdev, "[ERR]Get target failed.\n"); ++ return -EINVAL; ++ } ++ ++ *target = tar; ++ ++ return 0; ++} ++ ++static int rtw89_pci_auto_refclk_cal(struct rtw89_dev *rtwdev, bool autook_en) ++{ ++ enum rtw89_pcie_phy phy_rate; ++ u16 val16, mgn_set, div_set, tar; ++ u8 val8, bdr_ori; ++ bool l1_flag = false; ++ int ret = 0; ++ ++ if ((rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv == CHIP_CBV) || ++ rtwdev->chip->chip_id == RTL8852C) ++ return 0; ++ ++ ret = rtw89_dbi_read8(rtwdev, RTW89_PCIE_PHY_RATE, &val8); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]dbi_r8_pcie %X\n", RTW89_PCIE_PHY_RATE); ++ return ret; ++ } ++ ++ if (FIELD_GET(RTW89_PCIE_PHY_RATE_MASK, val8) == 0x1) { ++ phy_rate = PCIE_PHY_GEN1; ++ } else if (FIELD_GET(RTW89_PCIE_PHY_RATE_MASK, val8) == 0x2) { ++ phy_rate = PCIE_PHY_GEN2; ++ } else { ++ rtw89_err(rtwdev, "[ERR]PCIe PHY rate %#x not support\n", val8); ++ return -EOPNOTSUPP; ++ } ++ /* Disable L1BD */ ++ ret = rtw89_dbi_read8(rtwdev, RTW89_PCIE_L1_CTRL, &bdr_ori); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]dbi_r8_pcie %X\n", RTW89_PCIE_L1_CTRL); ++ return ret; ++ } ++ ++ if (bdr_ori & RTW89_PCIE_BIT_L1) { ++ ret = rtw89_dbi_write8(rtwdev, RTW89_PCIE_L1_CTRL, ++ bdr_ori & ~RTW89_PCIE_BIT_L1); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]dbi_w8_pcie %X\n", RTW89_PCIE_L1_CTRL); ++ return ret; ++ } ++ l1_flag = true; ++ } ++ ++ ret = rtw89_read16_mdio(rtwdev, RAC_CTRL_PPR_V1, phy_rate, &val16); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]mdio_r16_pcie %X\n", RAC_CTRL_PPR_V1); ++ goto end; ++ } ++ ++ if (val16 & B_AX_CALIB_EN) { ++ ret = rtw89_write16_mdio(rtwdev, RAC_CTRL_PPR_V1, ++ val16 & ~B_AX_CALIB_EN, phy_rate); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]mdio_w16_pcie %X\n", RAC_CTRL_PPR_V1); ++ goto end; ++ } ++ } ++ ++ if (!autook_en) ++ goto end; ++ /* Set div */ ++ ret = rtw89_write16_mdio_clr(rtwdev, RAC_CTRL_PPR_V1, B_AX_DIV, phy_rate); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]mdio_w16_pcie %X\n", RAC_CTRL_PPR_V1); ++ goto end; ++ } ++ ++ /* Obtain div and margin */ ++ ret = __get_target(rtwdev, &tar, phy_rate); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]1st get target fail %d\n", ret); ++ goto end; ++ } ++ ++ mgn_set = tar * INTF_INTGRA_HOSTREF_V1 / INTF_INTGRA_MINREF_V1 - tar; ++ ++ if (mgn_set >= 128) { ++ div_set = 0x0003; ++ mgn_set = 0x000F; ++ } else if (mgn_set >= 64) { ++ div_set = 0x0003; ++ mgn_set >>= 3; ++ } else if (mgn_set >= 32) { ++ div_set = 0x0002; ++ mgn_set >>= 2; ++ } else if (mgn_set >= 16) { ++ div_set = 0x0001; ++ mgn_set >>= 1; ++ } else if (mgn_set == 0) { ++ rtw89_err(rtwdev, "[ERR]cal mgn is 0,tar = %d\n", tar); ++ goto end; ++ } else { ++ div_set = 0x0000; ++ } ++ ++ ret = rtw89_read16_mdio(rtwdev, RAC_CTRL_PPR_V1, phy_rate, &val16); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]mdio_r16_pcie %X\n", RAC_CTRL_PPR_V1); ++ goto end; ++ } ++ ++ val16 |= u16_encode_bits(div_set, B_AX_DIV); ++ ++ ret = rtw89_write16_mdio(rtwdev, RAC_CTRL_PPR_V1, val16, phy_rate); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]mdio_w16_pcie %X\n", RAC_CTRL_PPR_V1); ++ goto end; ++ } ++ ++ ret = __get_target(rtwdev, &tar, phy_rate); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]2nd get target fail %d\n", ret); ++ goto end; ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_HCI, "[TRACE]target = 0x%X, div = 0x%X, margin = 0x%X\n", ++ tar, div_set, mgn_set); ++ ret = rtw89_write16_mdio(rtwdev, RAC_SET_PPR_V1, ++ (tar & 0x0FFF) | (mgn_set << 12), phy_rate); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]mdio_w16_pcie %X\n", RAC_SET_PPR_V1); ++ goto end; ++ } ++ ++ /* Enable function */ ++ ret = rtw89_write16_mdio_set(rtwdev, RAC_CTRL_PPR_V1, B_AX_CALIB_EN, phy_rate); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]mdio_w16_pcie %X\n", RAC_CTRL_PPR_V1); ++ goto end; ++ } ++ ++ /* CLK delay = 0 */ ++ ret = rtw89_dbi_write8(rtwdev, RTW89_PCIE_CLK_CTRL, PCIE_CLKDLY_HW_0); ++ ++end: ++ /* Set L1BD to ori */ ++ if (l1_flag) { ++ ret = rtw89_dbi_write8(rtwdev, RTW89_PCIE_L1_CTRL, bdr_ori); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR]dbi_w8_pcie %X\n", RTW89_PCIE_L1_CTRL); ++ return ret; ++ } ++ } ++ ++ return ret; ++} ++ ++static int rtw89_pci_deglitch_setting(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ if (rtwdev->chip->chip_id != RTL8852A) ++ return 0; ++ ++ ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA24, B_AX_DEGLITCH, ++ PCIE_PHY_GEN1); ++ if (ret) ++ return ret; ++ ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA24, B_AX_DEGLITCH, ++ PCIE_PHY_GEN2); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static void rtw89_pci_rxdma_prefth(struct rtw89_dev *rtwdev) ++{ ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_DIS_RXDMA_PRE); ++} ++ ++static void rtw89_pci_l1off_pwroff(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->chip->chip_id == RTL8852C) ++ return; ++ ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_PS_CTRL, B_AX_L1OFF_PWR_OFF_EN); ++} ++ ++static u32 rtw89_pci_l2_rxen_lat(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ if (rtwdev->chip->chip_id == RTL8852C) ++ return 0; ++ ++ ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA26, B_AX_RXEN, ++ PCIE_PHY_GEN1); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_write16_mdio_clr(rtwdev, RAC_ANA26, B_AX_RXEN, ++ PCIE_PHY_GEN2); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static void rtw89_pci_aphy_pwrcut(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->chip->chip_id != RTL8852A) ++ return; ++ ++ rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_PSUS_OFF_CAPC_EN); ++} ++ ++static void rtw89_pci_hci_ldo(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->chip->chip_id != RTL8852A) ++ return; ++ ++ rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL, ++ B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); ++ rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, ++ B_AX_PCIE_DIS_WLSUS_AFT_PDN); ++} ++ ++static void rtw89_pci_set_sic(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->chip->chip_id == RTL8852C) ++ return; ++ ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_EXP_CTRL, ++ B_AX_SIC_EN_FORCE_CLKREQ); ++} ++ ++static void rtw89_pci_set_dbg(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->chip->chip_id == RTL8852C) ++ return; ++ ++ rtw89_write32_set(rtwdev, R_AX_PCIE_DBG_CTRL, ++ B_AX_ASFF_FULL_NO_STK | B_AX_EN_STUCK_DBG); ++ ++ if (rtwdev->chip->chip_id == RTL8852A) ++ rtw89_write32_set(rtwdev, R_AX_PCIE_EXP_CTRL, ++ B_AX_EN_CHKDSC_NO_RX_STUCK); ++} ++ ++static void rtw89_pci_clr_idx_all(struct rtw89_dev *rtwdev) ++{ ++ u32 val = B_AX_CLR_ACH0_IDX | B_AX_CLR_ACH1_IDX | B_AX_CLR_ACH2_IDX | ++ B_AX_CLR_ACH3_IDX | B_AX_CLR_CH8_IDX | B_AX_CLR_CH9_IDX | ++ B_AX_CLR_CH12_IDX; ++ ++ if (rtwdev->chip->chip_id == RTL8852A) ++ val |= B_AX_CLR_ACH4_IDX | B_AX_CLR_ACH5_IDX | ++ B_AX_CLR_ACH6_IDX | B_AX_CLR_ACH7_IDX; ++ /* clear DMA indexes */ ++ rtw89_write32_set(rtwdev, R_AX_TXBD_RWPTR_CLR1, val); ++ if (rtwdev->chip->chip_id == RTL8852A) ++ rtw89_write32_set(rtwdev, R_AX_TXBD_RWPTR_CLR2, ++ B_AX_CLR_CH10_IDX | B_AX_CLR_CH11_IDX); ++ rtw89_write32_set(rtwdev, R_AX_RXBD_RWPTR_CLR, ++ B_AX_CLR_RXQ_IDX | B_AX_CLR_RPQ_IDX); ++} ++ ++static int rtw89_pci_ops_deinit(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->chip->chip_id == RTL8852A) { ++ /* ltr sw trigger */ ++ rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_APP_LTR_IDLE); ++ } ++ rtw89_pci_ctrl_dma_all(rtwdev, false); ++ rtw89_pci_clr_idx_all(rtwdev); ++ ++ return 0; ++} ++ ++static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev) ++{ ++ u32 dma_busy; ++ u32 check; ++ u32 lbc; ++ int ret; ++ ++ rtw89_pci_rxdma_prefth(rtwdev); ++ rtw89_pci_l1off_pwroff(rtwdev); ++ rtw89_pci_deglitch_setting(rtwdev); ++ ret = rtw89_pci_l2_rxen_lat(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] pcie l2 rxen lat %d\n", ret); ++ return ret; ++ } ++ ++ rtw89_pci_aphy_pwrcut(rtwdev); ++ rtw89_pci_hci_ldo(rtwdev); ++ ++ ret = rtw89_pci_auto_refclk_cal(rtwdev, false); ++ if (ret) { ++ rtw89_err(rtwdev, "[ERR] pcie autok fail %d\n", ret); ++ return ret; ++ } ++ ++ rtw89_pci_set_sic(rtwdev); ++ rtw89_pci_set_dbg(rtwdev); ++ ++ if (rtwdev->chip->chip_id == RTL8852A) ++ rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, ++ B_AX_PCIE_AUXCLK_GATE); ++ ++ lbc = rtw89_read32(rtwdev, R_AX_LBC_WATCHDOG); ++ lbc = u32_replace_bits(lbc, RTW89_MAC_LBC_TMR_128US, B_AX_LBC_TIMER); ++ lbc |= B_AX_LBC_FLAG | B_AX_LBC_EN; ++ rtw89_write32(rtwdev, R_AX_LBC_WATCHDOG, lbc); ++ ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, ++ B_AX_PCIE_TXRST_KEEP_REG | B_AX_PCIE_RXRST_KEEP_REG); ++ rtw89_write32_set(rtwdev, R_AX_PCIE_DMA_STOP1, B_AX_STOP_WPDMA); ++ ++ /* stop DMA activities */ ++ rtw89_pci_ctrl_dma_all(rtwdev, false); ++ ++ /* check PCI at idle state */ ++ check = B_AX_PCIEIO_BUSY | B_AX_PCIEIO_TX_BUSY | B_AX_PCIEIO_RX_BUSY; ++ ret = read_poll_timeout(rtw89_read32, dma_busy, (dma_busy & check) == 0, ++ 100, 3000, false, rtwdev, R_AX_PCIE_DMA_BUSY1); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to poll io busy\n"); ++ return ret; ++ } ++ ++ rtw89_pci_clr_idx_all(rtwdev); ++ ++ /* configure TX/RX op modes */ ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_TX_TRUNC_MODE | ++ B_AX_RX_TRUNC_MODE); ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_RXBD_MODE); ++ rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_PCIE_MAX_TXDMA_MASK, 7); ++ rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_PCIE_MAX_RXDMA_MASK, 3); ++ /* multi-tag mode */ ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, B_AX_LATENCY_CONTROL); ++ rtw89_write32_mask(rtwdev, R_AX_PCIE_EXP_CTRL, B_AX_MAX_TAG_NUM, ++ RTW89_MAC_TAG_NUM_8); ++ rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG2, B_AX_WD_ITVL_IDLE, ++ RTW89_MAC_WD_DMA_INTVL_256NS); ++ rtw89_write32_mask(rtwdev, R_AX_PCIE_INIT_CFG2, B_AX_WD_ITVL_ACT, ++ RTW89_MAC_WD_DMA_INTVL_256NS); ++ ++ /* fill TRX BD indexes */ ++ rtw89_pci_ops_reset(rtwdev); ++ ++ ret = rtw89_pci_rst_bdram_pcie(rtwdev); ++ if (ret) { ++ rtw89_warn(rtwdev, "reset bdram busy\n"); ++ return ret; ++ } ++ ++ /* enable FW CMD queue to download firmware */ ++ rtw89_write32_set(rtwdev, R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_ALL); ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP1, B_AX_STOP_CH12); ++ rtw89_write32_set(rtwdev, R_AX_PCIE_DMA_STOP2, B_AX_TX_STOP2_ALL); ++ ++ /* start DMA activities */ ++ rtw89_pci_ctrl_dma_all(rtwdev, true); ++ ++ return 0; ++} ++ ++static int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev) ++{ ++ u32 val; ++ ++ val = rtw89_read32(rtwdev, R_AX_LTR_CTRL_0); ++ if (rtw89_pci_ltr_is_err_reg_val(val)) ++ return -EINVAL; ++ val = rtw89_read32(rtwdev, R_AX_LTR_CTRL_1); ++ if (rtw89_pci_ltr_is_err_reg_val(val)) ++ return -EINVAL; ++ val = rtw89_read32(rtwdev, R_AX_LTR_IDLE_LATENCY); ++ if (rtw89_pci_ltr_is_err_reg_val(val)) ++ return -EINVAL; ++ val = rtw89_read32(rtwdev, R_AX_LTR_ACTIVE_LATENCY); ++ if (rtw89_pci_ltr_is_err_reg_val(val)) ++ return -EINVAL; ++ ++ rtw89_write32_clr(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_HW_EN); ++ rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_EN); ++ rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_SPACE_IDX_MASK, ++ PCI_LTR_SPC_500US); ++ rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_0, B_AX_LTR_IDLE_TIMER_IDX_MASK, ++ PCI_LTR_IDLE_TIMER_800US); ++ rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_1, B_AX_LTR_RX0_TH_MASK, 0x28); ++ rtw89_write32_mask(rtwdev, R_AX_LTR_CTRL_1, B_AX_LTR_RX1_TH_MASK, 0x28); ++ rtw89_write32(rtwdev, R_AX_LTR_IDLE_LATENCY, 0x88e088e0); ++ rtw89_write32(rtwdev, R_AX_LTR_ACTIVE_LATENCY, 0x880b880b); ++ ++ return 0; ++} ++ ++static int rtw89_pci_ops_mac_post_init(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ ret = rtw89_pci_ltr_set(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "pci ltr set fail\n"); ++ return ret; ++ } ++ if (rtwdev->chip->chip_id == RTL8852A) { ++ /* ltr sw trigger */ ++ rtw89_write32_set(rtwdev, R_AX_LTR_CTRL_0, B_AX_APP_LTR_ACT); ++ } ++ /* ADDR info 8-byte mode */ ++ rtw89_write32_set(rtwdev, R_AX_TX_ADDRESS_INFO_MODE_SETTING, ++ B_AX_HOST_ADDR_INFO_8B_SEL); ++ rtw89_write32_clr(rtwdev, R_AX_PKTIN_SETTING, B_AX_WD_ADDR_INFO_LENGTH); ++ ++ /* enable DMA for all queues */ ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP1, B_AX_TX_STOP1_ALL); ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP2, B_AX_TX_STOP2_ALL); ++ ++ /* Release PCI IO */ ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP1, ++ B_AX_STOP_WPDMA | B_AX_STOP_PCIEIO); ++ ++ return 0; ++} ++ ++static int rtw89_pci_claim_device(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ int ret; ++ ++ ret = pci_enable_device(pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to enable pci device\n"); ++ return ret; ++ } ++ ++ pci_set_master(pdev); ++ pci_set_drvdata(pdev, rtwdev->hw); ++ ++ rtwpci->pdev = pdev; ++ ++ return 0; ++} ++ ++static void rtw89_pci_declaim_device(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ pci_clear_master(pdev); ++ pci_disable_device(pdev); ++} ++ ++static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ unsigned long resource_len; ++ u8 bar_id = 2; ++ int ret; ++ ++ ret = pci_request_regions(pdev, KBUILD_MODNAME); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to request pci regions\n"); ++ goto err; ++ } ++ ++ ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to set dma mask to 32-bit\n"); ++ goto err_release_regions; ++ } ++ ++ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to set consistent dma mask to 32-bit\n"); ++ goto err_release_regions; ++ } ++ ++ resource_len = pci_resource_len(pdev, bar_id); ++ rtwpci->mmap = pci_iomap(pdev, bar_id, resource_len); ++ if (!rtwpci->mmap) { ++ rtw89_err(rtwdev, "failed to map pci io\n"); ++ ret = -EIO; ++ goto err_release_regions; ++ } ++ ++ return 0; ++ ++err_release_regions: ++ pci_release_regions(pdev); ++err: ++ return ret; ++} ++ ++static void rtw89_pci_clear_mapping(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ ++ if (rtwpci->mmap) { ++ pci_iounmap(pdev, rtwpci->mmap); ++ pci_release_regions(pdev); ++ } ++} ++ ++static void rtw89_pci_free_tx_wd_ring(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev, ++ struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; ++ u8 *head = wd_ring->head; ++ dma_addr_t dma = wd_ring->dma; ++ u32 page_size = wd_ring->page_size; ++ u32 page_num = wd_ring->page_num; ++ u32 ring_sz = page_size * page_num; ++ ++ dma_free_coherent(&pdev->dev, ring_sz, head, dma); ++ wd_ring->head = NULL; ++} ++ ++static void rtw89_pci_free_tx_ring(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev, ++ struct rtw89_pci_tx_ring *tx_ring) ++{ ++ int ring_sz; ++ u8 *head; ++ dma_addr_t dma; ++ ++ head = tx_ring->bd_ring.head; ++ dma = tx_ring->bd_ring.dma; ++ ring_sz = tx_ring->bd_ring.desc_size * tx_ring->bd_ring.len; ++ dma_free_coherent(&pdev->dev, ring_sz, head, dma); ++ ++ tx_ring->bd_ring.head = NULL; ++} ++ ++static void rtw89_pci_free_tx_rings(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring; ++ int i; ++ ++ for (i = 0; i < RTW89_TXCH_NUM; i++) { ++ tx_ring = &rtwpci->tx_rings[i]; ++ rtw89_pci_free_tx_wd_ring(rtwdev, pdev, tx_ring); ++ rtw89_pci_free_tx_ring(rtwdev, pdev, tx_ring); ++ } ++} ++ ++static void rtw89_pci_free_rx_ring(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev, ++ struct rtw89_pci_rx_ring *rx_ring) ++{ ++ struct rtw89_pci_rx_info *rx_info; ++ struct sk_buff *skb; ++ dma_addr_t dma; ++ u32 buf_sz; ++ u8 *head; ++ int ring_sz = rx_ring->bd_ring.desc_size * rx_ring->bd_ring.len; ++ int i; ++ ++ buf_sz = rx_ring->buf_sz; ++ for (i = 0; i < rx_ring->bd_ring.len; i++) { ++ skb = rx_ring->buf[i]; ++ if (!skb) ++ continue; ++ ++ rx_info = RTW89_PCI_RX_SKB_CB(skb); ++ dma = rx_info->dma; ++ dma_unmap_single(&pdev->dev, dma, buf_sz, DMA_FROM_DEVICE); ++ dev_kfree_skb(skb); ++ rx_ring->buf[i] = NULL; ++ } ++ ++ head = rx_ring->bd_ring.head; ++ dma = rx_ring->bd_ring.dma; ++ dma_free_coherent(&pdev->dev, ring_sz, head, dma); ++ ++ rx_ring->bd_ring.head = NULL; ++} ++ ++static void rtw89_pci_free_rx_rings(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_rx_ring *rx_ring; ++ int i; ++ ++ for (i = 0; i < RTW89_RXCH_NUM; i++) { ++ rx_ring = &rtwpci->rx_rings[i]; ++ rtw89_pci_free_rx_ring(rtwdev, pdev, rx_ring); ++ } ++} ++ ++static void rtw89_pci_free_trx_rings(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ rtw89_pci_free_rx_rings(rtwdev, pdev); ++ rtw89_pci_free_tx_rings(rtwdev, pdev); ++} ++ ++static int rtw89_pci_init_rx_bd(struct rtw89_dev *rtwdev, struct pci_dev *pdev, ++ struct rtw89_pci_rx_ring *rx_ring, ++ struct sk_buff *skb, int buf_sz, u32 idx) ++{ ++ struct rtw89_pci_rx_info *rx_info; ++ struct rtw89_pci_rx_bd_32 *rx_bd; ++ dma_addr_t dma; ++ ++ if (!skb) ++ return -EINVAL; ++ ++ dma = dma_map_single(&pdev->dev, skb->data, buf_sz, DMA_FROM_DEVICE); ++ if (dma_mapping_error(&pdev->dev, dma)) ++ return -EBUSY; ++ ++ rx_info = RTW89_PCI_RX_SKB_CB(skb); ++ rx_bd = RTW89_PCI_RX_BD(rx_ring, idx); ++ ++ memset(rx_bd, 0, sizeof(*rx_bd)); ++ rx_bd->buf_size = cpu_to_le16(buf_sz); ++ rx_bd->dma = cpu_to_le32(dma); ++ rx_info->dma = dma; ++ ++ return 0; ++} ++ ++static int rtw89_pci_alloc_tx_wd_ring(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev, ++ struct rtw89_pci_tx_ring *tx_ring, ++ enum rtw89_tx_channel txch) ++{ ++ struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; ++ struct rtw89_pci_tx_wd *txwd; ++ dma_addr_t dma; ++ dma_addr_t cur_paddr; ++ u8 *head; ++ u8 *cur_vaddr; ++ u32 page_size = RTW89_PCI_TXWD_PAGE_SIZE; ++ u32 page_num = RTW89_PCI_TXWD_NUM_MAX; ++ u32 ring_sz = page_size * page_num; ++ u32 page_offset; ++ int i; ++ ++ /* FWCMD queue doesn't use txwd as pages */ ++ if (txch == RTW89_TXCH_CH12) ++ return 0; ++ ++ head = dma_alloc_coherent(&pdev->dev, ring_sz, &dma, GFP_KERNEL); ++ if (!head) ++ return -ENOMEM; ++ ++ INIT_LIST_HEAD(&wd_ring->free_pages); ++ wd_ring->head = head; ++ wd_ring->dma = dma; ++ wd_ring->page_size = page_size; ++ wd_ring->page_num = page_num; ++ ++ page_offset = 0; ++ for (i = 0; i < page_num; i++) { ++ txwd = &wd_ring->pages[i]; ++ cur_paddr = dma + page_offset; ++ cur_vaddr = head + page_offset; ++ ++ skb_queue_head_init(&txwd->queue); ++ INIT_LIST_HEAD(&txwd->list); ++ txwd->paddr = cur_paddr; ++ txwd->vaddr = cur_vaddr; ++ txwd->len = page_size; ++ txwd->seq = i; ++ rtw89_pci_enqueue_txwd(tx_ring, txwd); ++ ++ page_offset += page_size; ++ } ++ ++ return 0; ++} ++ ++static int rtw89_pci_alloc_tx_ring(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev, ++ struct rtw89_pci_tx_ring *tx_ring, ++ u32 desc_size, u32 len, ++ enum rtw89_tx_channel txch) ++{ ++ int ring_sz = desc_size * len; ++ u8 *head; ++ dma_addr_t dma; ++ u32 addr_num; ++ u32 addr_idx; ++ u32 addr_bdram; ++ u32 addr_desa_l; ++ u32 addr_desa_h; ++ int ret; ++ ++ ret = rtw89_pci_alloc_tx_wd_ring(rtwdev, pdev, tx_ring, txch); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to alloc txwd ring of txch %d\n", txch); ++ goto err; ++ } ++ ++ ret = rtw89_pci_get_txch_addrs(txch, &addr_num, &addr_idx, &addr_bdram, ++ &addr_desa_l, &addr_desa_h); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to get address of txch %d", txch); ++ goto err_free_wd_ring; ++ } ++ ++ head = dma_alloc_coherent(&pdev->dev, ring_sz, &dma, GFP_KERNEL); ++ if (!head) { ++ ret = -ENOMEM; ++ goto err_free_wd_ring; ++ } ++ ++ INIT_LIST_HEAD(&tx_ring->busy_pages); ++ tx_ring->bd_ring.head = head; ++ tx_ring->bd_ring.dma = dma; ++ tx_ring->bd_ring.len = len; ++ tx_ring->bd_ring.desc_size = desc_size; ++ tx_ring->bd_ring.addr_num = addr_num; ++ tx_ring->bd_ring.addr_idx = addr_idx; ++ tx_ring->bd_ring.addr_bdram = addr_bdram; ++ tx_ring->bd_ring.addr_desa_l = addr_desa_l; ++ tx_ring->bd_ring.addr_desa_h = addr_desa_h; ++ tx_ring->bd_ring.wp = 0; ++ tx_ring->bd_ring.rp = 0; ++ tx_ring->txch = txch; ++ ++ return 0; ++ ++err_free_wd_ring: ++ rtw89_pci_free_tx_wd_ring(rtwdev, pdev, tx_ring); ++err: ++ return ret; ++} ++ ++static int rtw89_pci_alloc_tx_rings(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_tx_ring *tx_ring; ++ u32 desc_size; ++ u32 len; ++ u32 i, tx_allocated; ++ int ret; ++ ++ for (i = 0; i < RTW89_TXCH_NUM; i++) { ++ tx_ring = &rtwpci->tx_rings[i]; ++ desc_size = sizeof(struct rtw89_pci_tx_bd_32); ++ len = RTW89_PCI_TXBD_NUM_MAX; ++ ret = rtw89_pci_alloc_tx_ring(rtwdev, pdev, tx_ring, ++ desc_size, len, i); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to alloc tx ring %d\n", i); ++ goto err_free; ++ } ++ } ++ ++ return 0; ++ ++err_free: ++ tx_allocated = i; ++ for (i = 0; i < tx_allocated; i++) { ++ tx_ring = &rtwpci->tx_rings[i]; ++ rtw89_pci_free_tx_ring(rtwdev, pdev, tx_ring); ++ } ++ ++ return ret; ++} ++ ++static int rtw89_pci_alloc_rx_ring(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev, ++ struct rtw89_pci_rx_ring *rx_ring, ++ u32 desc_size, u32 len, u32 rxch) ++{ ++ struct sk_buff *skb; ++ u8 *head; ++ dma_addr_t dma; ++ u32 addr_num; ++ u32 addr_idx; ++ u32 addr_desa_l; ++ u32 addr_desa_h; ++ int ring_sz = desc_size * len; ++ int buf_sz = RTW89_PCI_RX_BUF_SIZE; ++ int i, allocated; ++ int ret; ++ ++ ret = rtw89_pci_get_rxch_addrs(rxch, &addr_num, &addr_idx, ++ &addr_desa_l, &addr_desa_h); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to get address of rxch %d", rxch); ++ return ret; ++ } ++ ++ head = dma_alloc_coherent(&pdev->dev, ring_sz, &dma, GFP_KERNEL); ++ if (!head) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ rx_ring->bd_ring.head = head; ++ rx_ring->bd_ring.dma = dma; ++ rx_ring->bd_ring.len = len; ++ rx_ring->bd_ring.desc_size = desc_size; ++ rx_ring->bd_ring.addr_num = addr_num; ++ rx_ring->bd_ring.addr_idx = addr_idx; ++ rx_ring->bd_ring.addr_desa_l = addr_desa_l; ++ rx_ring->bd_ring.addr_desa_h = addr_desa_h; ++ rx_ring->bd_ring.wp = 0; ++ rx_ring->bd_ring.rp = 0; ++ rx_ring->buf_sz = buf_sz; ++ rx_ring->diliver_skb = NULL; ++ rx_ring->diliver_desc.ready = false; ++ ++ for (i = 0; i < len; i++) { ++ skb = dev_alloc_skb(buf_sz); ++ if (!skb) { ++ ret = -ENOMEM; ++ goto err_free; ++ } ++ ++ memset(skb->data, 0, buf_sz); ++ rx_ring->buf[i] = skb; ++ ret = rtw89_pci_init_rx_bd(rtwdev, pdev, rx_ring, skb, ++ buf_sz, i); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to init rx buf %d\n", i); ++ dev_kfree_skb_any(skb); ++ rx_ring->buf[i] = NULL; ++ goto err_free; ++ } ++ } ++ ++ return 0; ++ ++err_free: ++ allocated = i; ++ for (i = 0; i < allocated; i++) { ++ skb = rx_ring->buf[i]; ++ if (!skb) ++ continue; ++ dma = *((dma_addr_t *)skb->cb); ++ dma_unmap_single(&pdev->dev, dma, buf_sz, DMA_FROM_DEVICE); ++ dev_kfree_skb(skb); ++ rx_ring->buf[i] = NULL; ++ } ++ ++ head = rx_ring->bd_ring.head; ++ dma = rx_ring->bd_ring.dma; ++ dma_free_coherent(&pdev->dev, ring_sz, head, dma); ++ ++ rx_ring->bd_ring.head = NULL; ++err: ++ return ret; ++} ++ ++static int rtw89_pci_alloc_rx_rings(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct rtw89_pci_rx_ring *rx_ring; ++ u32 desc_size; ++ u32 len; ++ int i, rx_allocated; ++ int ret; ++ ++ for (i = 0; i < RTW89_RXCH_NUM; i++) { ++ rx_ring = &rtwpci->rx_rings[i]; ++ desc_size = sizeof(struct rtw89_pci_rx_bd_32); ++ len = RTW89_PCI_RXBD_NUM_MAX; ++ ret = rtw89_pci_alloc_rx_ring(rtwdev, pdev, rx_ring, ++ desc_size, len, i); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to alloc rx ring %d\n", i); ++ goto err_free; ++ } ++ } ++ ++ return 0; ++ ++err_free: ++ rx_allocated = i; ++ for (i = 0; i < rx_allocated; i++) { ++ rx_ring = &rtwpci->rx_rings[i]; ++ rtw89_pci_free_rx_ring(rtwdev, pdev, rx_ring); ++ } ++ ++ return ret; ++} ++ ++static int rtw89_pci_alloc_trx_rings(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ int ret; ++ ++ ret = rtw89_pci_alloc_tx_rings(rtwdev, pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to alloc dma tx rings\n"); ++ goto err; ++ } ++ ++ ret = rtw89_pci_alloc_rx_rings(rtwdev, pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to alloc dma rx rings\n"); ++ goto err_free_tx_rings; ++ } ++ ++ return 0; ++ ++err_free_tx_rings: ++ rtw89_pci_free_tx_rings(rtwdev, pdev); ++err: ++ return ret; ++} ++ ++static void rtw89_pci_h2c_init(struct rtw89_dev *rtwdev, ++ struct rtw89_pci *rtwpci) ++{ ++ skb_queue_head_init(&rtwpci->h2c_queue); ++ skb_queue_head_init(&rtwpci->h2c_release_queue); ++} ++ ++static int rtw89_pci_setup_resource(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ int ret; ++ ++ ret = rtw89_pci_setup_mapping(rtwdev, pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to setup pci mapping\n"); ++ goto err; ++ } ++ ++ ret = rtw89_pci_alloc_trx_rings(rtwdev, pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to alloc pci trx rings\n"); ++ goto err_pci_unmap; ++ } ++ ++ rtw89_pci_h2c_init(rtwdev, rtwpci); ++ ++ spin_lock_init(&rtwpci->irq_lock); ++ spin_lock_init(&rtwpci->trx_lock); ++ ++ return 0; ++ ++err_pci_unmap: ++ rtw89_pci_clear_mapping(rtwdev, pdev); ++err: ++ return ret; ++} ++ ++static void rtw89_pci_clear_resource(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ ++ rtw89_pci_free_trx_rings(rtwdev, pdev); ++ rtw89_pci_clear_mapping(rtwdev, pdev); ++ rtw89_pci_release_fwcmd(rtwdev, rtwpci, ++ skb_queue_len(&rtwpci->h2c_queue), true); ++} ++ ++static void rtw89_pci_default_intr_mask(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ ++ rtwpci->halt_c2h_intrs = B_AX_HALT_C2H_INT_EN | 0; ++ rtwpci->intrs[0] = B_AX_TXDMA_STUCK_INT_EN | ++ B_AX_RXDMA_INT_EN | ++ B_AX_RXP1DMA_INT_EN | ++ B_AX_RPQDMA_INT_EN | ++ B_AX_RXDMA_STUCK_INT_EN | ++ B_AX_RDU_INT_EN | ++ B_AX_RPQBD_FULL_INT_EN | ++ B_AX_HS0ISR_IND_INT_EN; ++ ++ rtwpci->intrs[1] = B_AX_HC10ISR_IND_INT_EN; ++} ++ ++static int rtw89_pci_request_irq(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ unsigned long flags = 0; ++ int ret; ++ ++ flags |= PCI_IRQ_LEGACY | PCI_IRQ_MSI; ++ ret = pci_alloc_irq_vectors(pdev, 1, 1, flags); ++ if (ret < 0) { ++ rtw89_err(rtwdev, "failed to alloc irq vectors, ret %d\n", ret); ++ goto err; ++ } ++ ++ ret = devm_request_threaded_irq(rtwdev->dev, pdev->irq, ++ rtw89_pci_interrupt_handler, ++ rtw89_pci_interrupt_threadfn, ++ IRQF_SHARED, KBUILD_MODNAME, rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to request threaded irq\n"); ++ goto err_free_vector; ++ } ++ ++ rtw89_pci_default_intr_mask(rtwdev); ++ ++ return 0; ++ ++err_free_vector: ++ pci_free_irq_vectors(pdev); ++err: ++ return ret; ++} ++ ++static void rtw89_pci_free_irq(struct rtw89_dev *rtwdev, ++ struct pci_dev *pdev) ++{ ++ devm_free_irq(rtwdev->dev, pdev->irq, rtwdev); ++ pci_free_irq_vectors(pdev); ++} ++ ++static void rtw89_pci_clkreq_set(struct rtw89_dev *rtwdev, bool enable) ++{ ++ int ret; ++ ++ if (rtw89_pci_disable_clkreq) ++ return; ++ ++ ret = rtw89_dbi_write8(rtwdev, RTW89_PCIE_CLK_CTRL, ++ PCIE_CLKDLY_HW_30US); ++ if (ret) ++ rtw89_err(rtwdev, "failed to set CLKREQ Delay\n"); ++ ++ if (enable) ++ ret = rtw89_dbi_write8_set(rtwdev, RTW89_PCIE_L1_CTRL, ++ RTW89_PCIE_BIT_CLK); ++ else ++ ret = rtw89_dbi_write8_clr(rtwdev, RTW89_PCIE_L1_CTRL, ++ RTW89_PCIE_BIT_CLK); ++ if (ret) ++ rtw89_err(rtwdev, "failed to %s CLKREQ_L1, ret=%d", ++ enable ? "set" : "unset", ret); ++} ++ ++static void rtw89_pci_aspm_set(struct rtw89_dev *rtwdev, bool enable) ++{ ++ u8 value = 0; ++ int ret; ++ ++ if (rtw89_pci_disable_aspm_l1) ++ return; ++ ++ ret = rtw89_dbi_read8(rtwdev, RTW89_PCIE_ASPM_CTRL, &value); ++ if (ret) ++ rtw89_err(rtwdev, "failed to read ASPM Delay\n"); ++ ++ value &= ~(RTW89_L1DLY_MASK | RTW89_L0DLY_MASK); ++ value |= FIELD_PREP(RTW89_L1DLY_MASK, PCIE_L1DLY_16US) | ++ FIELD_PREP(RTW89_L0DLY_MASK, PCIE_L0SDLY_4US); ++ ++ ret = rtw89_dbi_write8(rtwdev, RTW89_PCIE_ASPM_CTRL, value); ++ if (ret) ++ rtw89_err(rtwdev, "failed to read ASPM Delay\n"); ++ ++ if (enable) ++ ret = rtw89_dbi_write8_set(rtwdev, RTW89_PCIE_L1_CTRL, ++ RTW89_PCIE_BIT_L1); ++ else ++ ret = rtw89_dbi_write8_clr(rtwdev, RTW89_PCIE_L1_CTRL, ++ RTW89_PCIE_BIT_L1); ++ if (ret) ++ rtw89_err(rtwdev, "failed to %s ASPM L1, ret=%d", ++ enable ? "set" : "unset", ret); ++} ++ ++static void rtw89_pci_recalc_int_mit(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_traffic_stats *stats = &rtwdev->stats; ++ enum rtw89_tfc_lv tx_tfc_lv = stats->tx_tfc_lv; ++ enum rtw89_tfc_lv rx_tfc_lv = stats->rx_tfc_lv; ++ u32 val = 0; ++ ++ if (!rtwdev->scanning && ++ (tx_tfc_lv >= RTW89_TFC_HIGH || rx_tfc_lv >= RTW89_TFC_HIGH)) ++ val = B_AX_RXMIT_RXP2_SEL | B_AX_RXMIT_RXP1_SEL | ++ FIELD_PREP(B_AX_RXCOUNTER_MATCH_MASK, RTW89_PCI_RXBD_NUM_MAX / 2) | ++ FIELD_PREP(B_AX_RXTIMER_UNIT_MASK, AX_RXTIMER_UNIT_64US) | ++ FIELD_PREP(B_AX_RXTIMER_MATCH_MASK, 2048 / 64); ++ ++ rtw89_write32(rtwdev, R_AX_INT_MIT_RX, val); ++} ++ ++static void rtw89_pci_link_cfg(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct pci_dev *pdev = rtwpci->pdev; ++ u16 link_ctrl; ++ int ret; ++ ++ /* Though there is standard PCIE configuration space to set the ++ * link control register, but by Realtek's design, driver should ++ * check if host supports CLKREQ/ASPM to enable the HW module. ++ * ++ * These functions are implemented by two HW modules associated, ++ * one is responsible to access PCIE configuration space to ++ * follow the host settings, and another is in charge of doing ++ * CLKREQ/ASPM mechanisms, it is default disabled. Because sometimes ++ * the host does not support it, and due to some reasons or wrong ++ * settings (ex. CLKREQ# not Bi-Direction), it could lead to device ++ * loss if HW misbehaves on the link. ++ * ++ * Hence it's designed that driver should first check the PCIE ++ * configuration space is sync'ed and enabled, then driver can turn ++ * on the other module that is actually working on the mechanism. ++ */ ++ ret = pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &link_ctrl); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to read PCI cap, ret=%d\n", ret); ++ return; ++ } ++ ++ if (link_ctrl & PCI_EXP_LNKCTL_CLKREQ_EN) ++ rtw89_pci_clkreq_set(rtwdev, true); ++ ++ if (link_ctrl & PCI_EXP_LNKCTL_ASPM_L1) ++ rtw89_pci_aspm_set(rtwdev, true); ++} ++ ++static void rtw89_pci_l1ss_set(struct rtw89_dev *rtwdev, bool enable) ++{ ++ int ret; ++ ++ if (enable) ++ ret = rtw89_dbi_write8_set(rtwdev, RTW89_PCIE_TIMER_CTRL, ++ RTW89_PCIE_BIT_L1SUB); ++ else ++ ret = rtw89_dbi_write8_clr(rtwdev, RTW89_PCIE_TIMER_CTRL, ++ RTW89_PCIE_BIT_L1SUB); ++ if (ret) ++ rtw89_err(rtwdev, "failed to %s L1SS, ret=%d", ++ enable ? "set" : "unset", ret); ++} ++ ++static void rtw89_pci_l1ss_cfg(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ struct pci_dev *pdev = rtwpci->pdev; ++ u32 l1ss_cap_ptr, l1ss_ctrl; ++ ++ if (rtw89_pci_disable_l1ss) ++ return; ++ ++ l1ss_cap_ptr = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); ++ if (!l1ss_cap_ptr) ++ return; ++ ++ pci_read_config_dword(pdev, l1ss_cap_ptr + PCI_L1SS_CTL1, &l1ss_ctrl); ++ ++ if (l1ss_ctrl & PCI_L1SS_CTL1_L1SS_MASK) ++ rtw89_pci_l1ss_set(rtwdev, true); ++} ++ ++static void rtw89_pci_ctrl_dma_all_pcie(struct rtw89_dev *rtwdev, u8 en) ++{ ++ u32 val32; ++ ++ if (en == MAC_AX_FUNC_EN) { ++ val32 = B_AX_STOP_PCIEIO; ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_DMA_STOP1, val32); ++ ++ val32 = B_AX_TXHCI_EN | B_AX_RXHCI_EN; ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, val32); ++ } else { ++ val32 = B_AX_STOP_PCIEIO; ++ rtw89_write32_set(rtwdev, R_AX_PCIE_DMA_STOP1, val32); ++ ++ val32 = B_AX_TXHCI_EN | B_AX_RXHCI_EN; ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, val32); ++ } ++} ++ ++static int rtw89_pci_poll_io_idle(struct rtw89_dev *rtwdev) ++{ ++ int ret = 0; ++ u32 sts; ++ u32 busy = B_AX_PCIEIO_BUSY | B_AX_PCIEIO_TX_BUSY | B_AX_PCIEIO_RX_BUSY; ++ ++ ret = read_poll_timeout_atomic(rtw89_read32, sts, (sts & busy) == 0x0, ++ 10, 1000, false, rtwdev, ++ R_AX_PCIE_DMA_BUSY1); ++ if (ret) { ++ rtw89_err(rtwdev, "pci dmach busy1 0x%X\n", ++ rtw89_read32(rtwdev, R_AX_PCIE_DMA_BUSY1)); ++ return -EINVAL; ++ } ++ return ret; ++} ++ ++static int rtw89_pci_lv1rst_stop_dma(struct rtw89_dev *rtwdev) ++{ ++ u32 val, dma_rst = 0; ++ int ret; ++ ++ rtw89_pci_ctrl_dma_all_pcie(rtwdev, MAC_AX_FUNC_DIS); ++ ret = rtw89_pci_poll_io_idle(rtwdev); ++ if (ret) { ++ val = rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG); ++ rtw89_debug(rtwdev, RTW89_DBG_HCI, ++ "[PCIe] poll_io_idle fail, before 0x%08x: 0x%08x\n", ++ R_AX_DBG_ERR_FLAG, val); ++ if (val & B_AX_TX_STUCK || val & B_AX_PCIE_TXBD_LEN0) ++ dma_rst |= B_AX_HCI_TXDMA_EN; ++ if (val & B_AX_RX_STUCK) ++ dma_rst |= B_AX_HCI_RXDMA_EN; ++ val = rtw89_read32(rtwdev, R_AX_HCI_FUNC_EN); ++ rtw89_write32(rtwdev, R_AX_HCI_FUNC_EN, val & ~dma_rst); ++ rtw89_write32(rtwdev, R_AX_HCI_FUNC_EN, val | dma_rst); ++ ret = rtw89_pci_poll_io_idle(rtwdev); ++ val = rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG); ++ rtw89_debug(rtwdev, RTW89_DBG_HCI, ++ "[PCIe] poll_io_idle fail, after 0x%08x: 0x%08x\n", ++ R_AX_DBG_ERR_FLAG, val); ++ } ++ ++ return ret; ++} ++ ++static void rtw89_pci_ctrl_hci_dma_en(struct rtw89_dev *rtwdev, u8 en) ++{ ++ u32 val32; ++ ++ if (en == MAC_AX_FUNC_EN) { ++ val32 = B_AX_HCI_TXDMA_EN | B_AX_HCI_RXDMA_EN; ++ rtw89_write32_set(rtwdev, R_AX_HCI_FUNC_EN, val32); ++ } else { ++ val32 = B_AX_HCI_TXDMA_EN | B_AX_HCI_RXDMA_EN; ++ rtw89_write32_clr(rtwdev, R_AX_HCI_FUNC_EN, val32); ++ } ++} ++ ++static int rtw89_pci_rst_bdram(struct rtw89_dev *rtwdev) ++{ ++ int ret = 0; ++ u32 val32, sts; ++ ++ val32 = B_AX_RST_BDRAM; ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, val32); ++ ++ ret = read_poll_timeout_atomic(rtw89_read32, sts, ++ (sts & B_AX_RST_BDRAM) == 0x0, 1, 100, ++ true, rtwdev, R_AX_PCIE_INIT_CFG1); ++ return ret; ++} ++ ++static int rtw89_pci_lv1rst_start_dma(struct rtw89_dev *rtwdev) ++{ ++ u32 ret; ++ ++ rtw89_pci_ctrl_hci_dma_en(rtwdev, MAC_AX_FUNC_DIS); ++ rtw89_pci_ctrl_hci_dma_en(rtwdev, MAC_AX_FUNC_EN); ++ rtw89_pci_clr_idx_all(rtwdev); ++ ++ ret = rtw89_pci_rst_bdram(rtwdev); ++ if (ret) ++ return ret; ++ ++ rtw89_pci_ctrl_dma_all_pcie(rtwdev, MAC_AX_FUNC_EN); ++ return ret; ++} ++ ++static int rtw89_pci_ops_mac_lv1_recovery(struct rtw89_dev *rtwdev, ++ enum rtw89_lv1_rcvy_step step) ++{ ++ int ret; ++ ++ switch (step) { ++ case RTW89_LV1_RCVY_STEP_1: ++ ret = rtw89_pci_lv1rst_stop_dma(rtwdev); ++ if (ret) ++ rtw89_err(rtwdev, "lv1 rcvy pci stop dma fail\n"); ++ ++ break; ++ ++ case RTW89_LV1_RCVY_STEP_2: ++ ret = rtw89_pci_lv1rst_start_dma(rtwdev); ++ if (ret) ++ rtw89_err(rtwdev, "lv1 rcvy pci start dma fail\n"); ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ return ret; ++} ++ ++static void rtw89_pci_ops_dump_err_status(struct rtw89_dev *rtwdev) ++{ ++ rtw89_info(rtwdev, "R_AX_RPQ_RXBD_IDX =0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX)); ++ rtw89_info(rtwdev, "R_AX_DBG_ERR_FLAG=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_DBG_ERR_FLAG)); ++ rtw89_info(rtwdev, "R_AX_LBC_WATCHDOG=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_LBC_WATCHDOG)); ++} ++ ++static int rtw89_pci_napi_poll(struct napi_struct *napi, int budget) ++{ ++ struct rtw89_dev *rtwdev = container_of(napi, struct rtw89_dev, napi); ++ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; ++ unsigned long flags; ++ int work_done; ++ ++ rtwdev->napi_budget_countdown = budget; ++ ++ rtw89_pci_clear_isr0(rtwdev, B_AX_RPQDMA_INT | B_AX_RPQBD_FULL_INT); ++ work_done = rtw89_pci_poll_rpq_dma(rtwdev, rtwpci, rtwdev->napi_budget_countdown); ++ if (work_done == budget) ++ return budget; ++ ++ rtw89_pci_clear_isr0(rtwdev, B_AX_RXP1DMA_INT | B_AX_RXDMA_INT | B_AX_RDU_INT); ++ work_done += rtw89_pci_poll_rxq_dma(rtwdev, rtwpci, rtwdev->napi_budget_countdown); ++ if (work_done < budget && napi_complete_done(napi, work_done)) { ++ spin_lock_irqsave(&rtwpci->irq_lock, flags); ++ if (likely(rtwpci->running)) ++ rtw89_pci_enable_intr(rtwdev, rtwpci); ++ spin_unlock_irqrestore(&rtwpci->irq_lock, flags); ++ } ++ ++ return work_done; ++} ++ ++static int __maybe_unused rtw89_pci_suspend(struct device *dev) ++{ ++ struct ieee80211_hw *hw = dev_get_drvdata(dev); ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, ++ B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); ++ rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); ++ rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST); ++ rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); ++ rtw89_write32_set(rtwdev, R_AX_PCIE_INIT_CFG1, ++ B_AX_PCIE_PERST_KEEP_REG | B_AX_PCIE_TRAIN_KEEP_REG); ++ ++ return 0; ++} ++ ++static void rtw89_pci_l2_hci_ldo(struct rtw89_dev *rtwdev) ++{ ++ if (rtwdev->chip->chip_id == RTL8852C) ++ return; ++ ++ /* Hardware need write the reg twice to ensure the setting work */ ++ rtw89_dbi_write8_set(rtwdev, RTW89_PCIE_RST_MSTATE, ++ RTW89_PCIE_BIT_CFG_RST_MSTATE); ++ rtw89_dbi_write8_set(rtwdev, RTW89_PCIE_RST_MSTATE, ++ RTW89_PCIE_BIT_CFG_RST_MSTATE); ++} ++ ++static int __maybe_unused rtw89_pci_resume(struct device *dev) ++{ ++ struct ieee80211_hw *hw = dev_get_drvdata(dev); ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ rtw89_write32_set(rtwdev, R_AX_SYS_SDIO_CTRL, ++ B_AX_PCIE_DIS_L2_CTRL_LDO_HCI); ++ rtw89_write32_set(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); ++ rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST); ++ rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_WLOCK_1C_BIT6); ++ rtw89_write32_clr(rtwdev, R_AX_PCIE_INIT_CFG1, ++ B_AX_PCIE_PERST_KEEP_REG | B_AX_PCIE_TRAIN_KEEP_REG); ++ rtw89_pci_l2_hci_ldo(rtwdev); ++ rtw89_pci_link_cfg(rtwdev); ++ rtw89_pci_l1ss_cfg(rtwdev); ++ ++ return 0; ++} ++ ++SIMPLE_DEV_PM_OPS(rtw89_pm_ops, rtw89_pci_suspend, rtw89_pci_resume); ++EXPORT_SYMBOL(rtw89_pm_ops); ++ ++static const struct rtw89_hci_ops rtw89_pci_ops = { ++ .tx_write = rtw89_pci_ops_tx_write, ++ .tx_kick_off = rtw89_pci_ops_tx_kick_off, ++ .flush_queues = rtw89_pci_ops_flush_queues, ++ .reset = rtw89_pci_ops_reset, ++ .start = rtw89_pci_ops_start, ++ .stop = rtw89_pci_ops_stop, ++ .recalc_int_mit = rtw89_pci_recalc_int_mit, ++ ++ .read8 = rtw89_pci_ops_read8, ++ .read16 = rtw89_pci_ops_read16, ++ .read32 = rtw89_pci_ops_read32, ++ .write8 = rtw89_pci_ops_write8, ++ .write16 = rtw89_pci_ops_write16, ++ .write32 = rtw89_pci_ops_write32, ++ ++ .mac_pre_init = rtw89_pci_ops_mac_pre_init, ++ .mac_post_init = rtw89_pci_ops_mac_post_init, ++ .deinit = rtw89_pci_ops_deinit, ++ ++ .check_and_reclaim_tx_resource = rtw89_pci_check_and_reclaim_tx_resource, ++ .mac_lv1_rcvy = rtw89_pci_ops_mac_lv1_recovery, ++ .dump_err_status = rtw89_pci_ops_dump_err_status, ++ .napi_poll = rtw89_pci_napi_poll, ++}; ++ ++static int rtw89_pci_probe(struct pci_dev *pdev, ++ const struct pci_device_id *id) ++{ ++ struct ieee80211_hw *hw; ++ struct rtw89_dev *rtwdev; ++ int driver_data_size; ++ int ret; ++ ++ driver_data_size = sizeof(struct rtw89_dev) + sizeof(struct rtw89_pci); ++ hw = ieee80211_alloc_hw(driver_data_size, &rtw89_ops); ++ if (!hw) { ++ dev_err(&pdev->dev, "failed to allocate hw\n"); ++ return -ENOMEM; ++ } ++ ++ rtwdev = hw->priv; ++ rtwdev->hw = hw; ++ rtwdev->dev = &pdev->dev; ++ rtwdev->hci.ops = &rtw89_pci_ops; ++ rtwdev->hci.type = RTW89_HCI_TYPE_PCIE; ++ rtwdev->hci.rpwm_addr = R_AX_PCIE_HRPWM; ++ rtwdev->hci.cpwm_addr = R_AX_CPWM; ++ ++ SET_IEEE80211_DEV(rtwdev->hw, &pdev->dev); ++ ++ switch (id->driver_data) { ++ case RTL8852A: ++ rtwdev->chip = &rtw8852a_chip_info; ++ break; ++ default: ++ return -ENOENT; ++ } ++ ++ ret = rtw89_core_init(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to initialise core\n"); ++ goto err_release_hw; ++ } ++ ++ ret = rtw89_pci_claim_device(rtwdev, pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to claim pci device\n"); ++ goto err_core_deinit; ++ } ++ ++ ret = rtw89_pci_setup_resource(rtwdev, pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to setup pci resource\n"); ++ goto err_declaim_pci; ++ } ++ ++ ret = rtw89_chip_info_setup(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to setup chip information\n"); ++ goto err_clear_resource; ++ } ++ ++ rtw89_pci_link_cfg(rtwdev); ++ rtw89_pci_l1ss_cfg(rtwdev); ++ ++ ret = rtw89_core_register(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to register core\n"); ++ goto err_clear_resource; ++ } ++ ++ rtw89_core_napi_init(rtwdev); ++ ++ ret = rtw89_pci_request_irq(rtwdev, pdev); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to request pci irq\n"); ++ goto err_unregister; ++ } ++ ++ return 0; ++ ++err_unregister: ++ rtw89_core_napi_deinit(rtwdev); ++ rtw89_core_unregister(rtwdev); ++err_clear_resource: ++ rtw89_pci_clear_resource(rtwdev, pdev); ++err_declaim_pci: ++ rtw89_pci_declaim_device(rtwdev, pdev); ++err_core_deinit: ++ rtw89_core_deinit(rtwdev); ++err_release_hw: ++ ieee80211_free_hw(hw); ++ ++ return ret; ++} ++ ++static void rtw89_pci_remove(struct pci_dev *pdev) ++{ ++ struct ieee80211_hw *hw = pci_get_drvdata(pdev); ++ struct rtw89_dev *rtwdev; ++ ++ rtwdev = hw->priv; ++ ++ rtw89_pci_free_irq(rtwdev, pdev); ++ rtw89_core_napi_deinit(rtwdev); ++ rtw89_core_unregister(rtwdev); ++ rtw89_pci_clear_resource(rtwdev, pdev); ++ rtw89_pci_declaim_device(rtwdev, pdev); ++ rtw89_core_deinit(rtwdev); ++ ieee80211_free_hw(hw); ++} ++ ++static const struct pci_device_id rtw89_pci_id_table[] = { ++ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8852), .driver_data = RTL8852A }, ++ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xa85a), .driver_data = RTL8852A }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(pci, rtw89_pci_id_table); ++ ++static struct pci_driver rtw89_pci_driver = { ++ .name = "rtw89_pci", ++ .id_table = rtw89_pci_id_table, ++ .probe = rtw89_pci_probe, ++ .remove = rtw89_pci_remove, ++ .driver.pm = &rtw89_pm_ops, ++}; ++module_pci_driver(rtw89_pci_driver); ++ ++MODULE_AUTHOR("Realtek Corporation"); ++MODULE_DESCRIPTION("Realtek 802.11ax wireless PCI driver"); ++MODULE_LICENSE("Dual BSD/GPL"); +diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h +new file mode 100644 +index 000000000000..34333c441aea +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/pci.h +@@ -0,0 +1,635 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_PCI_H__ ++#define __RTW89_PCI_H__ ++ ++#include "txrx.h" ++ ++#define MDIO_PG0_G1 0 ++#define MDIO_PG1_G1 1 ++#define MDIO_PG0_G2 2 ++#define MDIO_PG1_G2 3 ++#define RAC_ANA10 0x10 ++#define RAC_ANA19 0x19 ++#define RAC_ANA1F 0x1F ++#define RAC_ANA24 0x24 ++#define B_AX_DEGLITCH GENMASK(11, 8) ++#define RAC_ANA26 0x26 ++#define B_AX_RXEN GENMASK(15, 14) ++#define RAC_CTRL_PPR_V1 0x30 ++#define B_AX_CLK_CALIB_EN BIT(12) ++#define B_AX_CALIB_EN BIT(13) ++#define B_AX_DIV GENMASK(15, 14) ++#define RAC_SET_PPR_V1 0x31 ++ ++#define R_AX_DBI_FLAG 0x1090 ++#define B_AX_DBI_RFLAG BIT(17) ++#define B_AX_DBI_WFLAG BIT(16) ++#define B_AX_DBI_WREN_MSK GENMASK(15, 12) ++#define B_AX_DBI_ADDR_MSK GENMASK(11, 2) ++#define R_AX_DBI_WDATA 0x1094 ++#define R_AX_DBI_RDATA 0x1098 ++ ++#define R_AX_MDIO_WDATA 0x10A4 ++#define R_AX_MDIO_RDATA 0x10A6 ++ ++#define RTW89_PCI_WR_RETRY_CNT 20 ++ ++/* Interrupts */ ++#define R_AX_HIMR0 0x01A0 ++#define B_AX_HALT_C2H_INT_EN BIT(21) ++#define R_AX_HISR0 0x01A4 ++ ++#define R_AX_MDIO_CFG 0x10A0 ++#define B_AX_MDIO_PHY_ADDR_MASK GENMASK(13, 12) ++#define B_AX_MDIO_RFLAG BIT(9) ++#define B_AX_MDIO_WFLAG BIT(8) ++#define B_AX_MDIO_ADDR_MASK GENMASK(4, 0) ++ ++#define R_AX_PCIE_HIMR00 0x10B0 ++#define B_AX_HC00ISR_IND_INT_EN BIT(27) ++#define B_AX_HD1ISR_IND_INT_EN BIT(26) ++#define B_AX_HD0ISR_IND_INT_EN BIT(25) ++#define B_AX_HS0ISR_IND_INT_EN BIT(24) ++#define B_AX_RETRAIN_INT_EN BIT(21) ++#define B_AX_RPQBD_FULL_INT_EN BIT(20) ++#define B_AX_RDU_INT_EN BIT(19) ++#define B_AX_RXDMA_STUCK_INT_EN BIT(18) ++#define B_AX_TXDMA_STUCK_INT_EN BIT(17) ++#define B_AX_PCIE_HOTRST_INT_EN BIT(16) ++#define B_AX_PCIE_FLR_INT_EN BIT(15) ++#define B_AX_PCIE_PERST_INT_EN BIT(14) ++#define B_AX_TXDMA_CH12_INT_EN BIT(13) ++#define B_AX_TXDMA_CH9_INT_EN BIT(12) ++#define B_AX_TXDMA_CH8_INT_EN BIT(11) ++#define B_AX_TXDMA_ACH7_INT_EN BIT(10) ++#define B_AX_TXDMA_ACH6_INT_EN BIT(9) ++#define B_AX_TXDMA_ACH5_INT_EN BIT(8) ++#define B_AX_TXDMA_ACH4_INT_EN BIT(7) ++#define B_AX_TXDMA_ACH3_INT_EN BIT(6) ++#define B_AX_TXDMA_ACH2_INT_EN BIT(5) ++#define B_AX_TXDMA_ACH1_INT_EN BIT(4) ++#define B_AX_TXDMA_ACH0_INT_EN BIT(3) ++#define B_AX_RPQDMA_INT_EN BIT(2) ++#define B_AX_RXP1DMA_INT_EN BIT(1) ++#define B_AX_RXDMA_INT_EN BIT(0) ++ ++#define R_AX_PCIE_HISR00 0x10B4 ++#define B_AX_HC00ISR_IND_INT BIT(27) ++#define B_AX_HD1ISR_IND_INT BIT(26) ++#define B_AX_HD0ISR_IND_INT BIT(25) ++#define B_AX_HS0ISR_IND_INT BIT(24) ++#define B_AX_RETRAIN_INT BIT(21) ++#define B_AX_RPQBD_FULL_INT BIT(20) ++#define B_AX_RDU_INT BIT(19) ++#define B_AX_RXDMA_STUCK_INT BIT(18) ++#define B_AX_TXDMA_STUCK_INT BIT(17) ++#define B_AX_PCIE_HOTRST_INT BIT(16) ++#define B_AX_PCIE_FLR_INT BIT(15) ++#define B_AX_PCIE_PERST_INT BIT(14) ++#define B_AX_TXDMA_CH12_INT BIT(13) ++#define B_AX_TXDMA_CH9_INT BIT(12) ++#define B_AX_TXDMA_CH8_INT BIT(11) ++#define B_AX_TXDMA_ACH7_INT BIT(10) ++#define B_AX_TXDMA_ACH6_INT BIT(9) ++#define B_AX_TXDMA_ACH5_INT BIT(8) ++#define B_AX_TXDMA_ACH4_INT BIT(7) ++#define B_AX_TXDMA_ACH3_INT BIT(6) ++#define B_AX_TXDMA_ACH2_INT BIT(5) ++#define B_AX_TXDMA_ACH1_INT BIT(4) ++#define B_AX_TXDMA_ACH0_INT BIT(3) ++#define B_AX_RPQDMA_INT BIT(2) ++#define B_AX_RXP1DMA_INT BIT(1) ++#define B_AX_RXDMA_INT BIT(0) ++ ++#define R_AX_PCIE_HIMR10 0x13B0 ++#define B_AX_HC10ISR_IND_INT_EN BIT(28) ++#define B_AX_TXDMA_CH11_INT_EN BIT(12) ++#define B_AX_TXDMA_CH10_INT_EN BIT(11) ++ ++#define R_AX_PCIE_HISR10 0x13B4 ++#define B_AX_HC10ISR_IND_INT BIT(28) ++#define B_AX_TXDMA_CH11_INT BIT(12) ++#define B_AX_TXDMA_CH10_INT BIT(11) ++ ++/* TX/RX */ ++#define R_AX_RXQ_RXBD_IDX 0x1050 ++#define R_AX_RPQ_RXBD_IDX 0x1054 ++#define R_AX_ACH0_TXBD_IDX 0x1058 ++#define R_AX_ACH1_TXBD_IDX 0x105C ++#define R_AX_ACH2_TXBD_IDX 0x1060 ++#define R_AX_ACH3_TXBD_IDX 0x1064 ++#define R_AX_ACH4_TXBD_IDX 0x1068 ++#define R_AX_ACH5_TXBD_IDX 0x106C ++#define R_AX_ACH6_TXBD_IDX 0x1070 ++#define R_AX_ACH7_TXBD_IDX 0x1074 ++#define R_AX_CH8_TXBD_IDX 0x1078 /* Management Queue band 0 */ ++#define R_AX_CH9_TXBD_IDX 0x107C /* HI Queue band 0 */ ++#define R_AX_CH10_TXBD_IDX 0x137C /* Management Queue band 1 */ ++#define R_AX_CH11_TXBD_IDX 0x1380 /* HI Queue band 1 */ ++#define R_AX_CH12_TXBD_IDX 0x1080 /* FWCMD Queue */ ++#define TXBD_HW_IDX_MASK GENMASK(27, 16) ++#define TXBD_HOST_IDX_MASK GENMASK(11, 0) ++ ++#define R_AX_ACH0_TXBD_DESA_L 0x1110 ++#define R_AX_ACH0_TXBD_DESA_H 0x1114 ++#define R_AX_ACH1_TXBD_DESA_L 0x1118 ++#define R_AX_ACH1_TXBD_DESA_H 0x111C ++#define R_AX_ACH2_TXBD_DESA_L 0x1120 ++#define R_AX_ACH2_TXBD_DESA_H 0x1124 ++#define R_AX_ACH3_TXBD_DESA_L 0x1128 ++#define R_AX_ACH3_TXBD_DESA_H 0x112C ++#define R_AX_ACH4_TXBD_DESA_L 0x1130 ++#define R_AX_ACH4_TXBD_DESA_H 0x1134 ++#define R_AX_ACH5_TXBD_DESA_L 0x1138 ++#define R_AX_ACH5_TXBD_DESA_H 0x113C ++#define R_AX_ACH6_TXBD_DESA_L 0x1140 ++#define R_AX_ACH6_TXBD_DESA_H 0x1144 ++#define R_AX_ACH7_TXBD_DESA_L 0x1148 ++#define R_AX_ACH7_TXBD_DESA_H 0x114C ++#define R_AX_CH8_TXBD_DESA_L 0x1150 ++#define R_AX_CH8_TXBD_DESA_H 0x1154 ++#define R_AX_CH9_TXBD_DESA_L 0x1158 ++#define R_AX_CH9_TXBD_DESA_H 0x115C ++#define R_AX_CH10_TXBD_DESA_L 0x1358 ++#define R_AX_CH10_TXBD_DESA_H 0x135C ++#define R_AX_CH11_TXBD_DESA_L 0x1360 ++#define R_AX_CH11_TXBD_DESA_H 0x1364 ++#define R_AX_CH12_TXBD_DESA_L 0x1160 ++#define R_AX_CH12_TXBD_DESA_H 0x1164 ++#define R_AX_RXQ_RXBD_DESA_L 0x1100 ++#define R_AX_RXQ_RXBD_DESA_H 0x1104 ++#define R_AX_RPQ_RXBD_DESA_L 0x1108 ++#define R_AX_RPQ_RXBD_DESA_H 0x110C ++#define B_AX_DESC_NUM_MSK GENMASK(11, 0) ++ ++#define R_AX_RXQ_RXBD_NUM 0x1020 ++#define R_AX_RPQ_RXBD_NUM 0x1022 ++#define R_AX_ACH0_TXBD_NUM 0x1024 ++#define R_AX_ACH1_TXBD_NUM 0x1026 ++#define R_AX_ACH2_TXBD_NUM 0x1028 ++#define R_AX_ACH3_TXBD_NUM 0x102A ++#define R_AX_ACH4_TXBD_NUM 0x102C ++#define R_AX_ACH5_TXBD_NUM 0x102E ++#define R_AX_ACH6_TXBD_NUM 0x1030 ++#define R_AX_ACH7_TXBD_NUM 0x1032 ++#define R_AX_CH8_TXBD_NUM 0x1034 ++#define R_AX_CH9_TXBD_NUM 0x1036 ++#define R_AX_CH10_TXBD_NUM 0x1338 ++#define R_AX_CH11_TXBD_NUM 0x133A ++#define R_AX_CH12_TXBD_NUM 0x1038 ++ ++#define R_AX_ACH0_BDRAM_CTRL 0x1200 ++#define R_AX_ACH1_BDRAM_CTRL 0x1204 ++#define R_AX_ACH2_BDRAM_CTRL 0x1208 ++#define R_AX_ACH3_BDRAM_CTRL 0x120C ++#define R_AX_ACH4_BDRAM_CTRL 0x1210 ++#define R_AX_ACH5_BDRAM_CTRL 0x1214 ++#define R_AX_ACH6_BDRAM_CTRL 0x1218 ++#define R_AX_ACH7_BDRAM_CTRL 0x121C ++#define R_AX_CH8_BDRAM_CTRL 0x1220 ++#define R_AX_CH9_BDRAM_CTRL 0x1224 ++#define R_AX_CH10_BDRAM_CTRL 0x1320 ++#define R_AX_CH11_BDRAM_CTRL 0x1324 ++#define R_AX_CH12_BDRAM_CTRL 0x1228 ++#define BDRAM_SIDX_MASK GENMASK(7, 0) ++#define BDRAM_MAX_MASK GENMASK(15, 8) ++#define BDRAM_MIN_MASK GENMASK(23, 16) ++ ++#define R_AX_PCIE_INIT_CFG1 0x1000 ++#define B_AX_PCIE_RXRST_KEEP_REG BIT(23) ++#define B_AX_PCIE_TXRST_KEEP_REG BIT(22) ++#define B_AX_PCIE_PERST_KEEP_REG BIT(21) ++#define B_AX_PCIE_FLR_KEEP_REG BIT(20) ++#define B_AX_PCIE_TRAIN_KEEP_REG BIT(19) ++#define B_AX_RXBD_MODE BIT(18) ++#define B_AX_PCIE_MAX_RXDMA_MASK GENMASK(16, 14) ++#define B_AX_RXHCI_EN BIT(13) ++#define B_AX_LATENCY_CONTROL BIT(12) ++#define B_AX_TXHCI_EN BIT(11) ++#define B_AX_PCIE_MAX_TXDMA_MASK GENMASK(10, 8) ++#define B_AX_TX_TRUNC_MODE BIT(5) ++#define B_AX_RX_TRUNC_MODE BIT(4) ++#define B_AX_RST_BDRAM BIT(3) ++#define B_AX_DIS_RXDMA_PRE BIT(2) ++ ++#define R_AX_TXDMA_ADDR_H 0x10F0 ++#define R_AX_RXDMA_ADDR_H 0x10F4 ++ ++#define R_AX_PCIE_DMA_STOP1 0x1010 ++#define B_AX_STOP_PCIEIO BIT(20) ++#define B_AX_STOP_WPDMA BIT(19) ++#define B_AX_STOP_CH12 BIT(18) ++#define B_AX_STOP_CH9 BIT(17) ++#define B_AX_STOP_CH8 BIT(16) ++#define B_AX_STOP_ACH7 BIT(15) ++#define B_AX_STOP_ACH6 BIT(14) ++#define B_AX_STOP_ACH5 BIT(13) ++#define B_AX_STOP_ACH4 BIT(12) ++#define B_AX_STOP_ACH3 BIT(11) ++#define B_AX_STOP_ACH2 BIT(10) ++#define B_AX_STOP_ACH1 BIT(9) ++#define B_AX_STOP_ACH0 BIT(8) ++#define B_AX_STOP_RPQ BIT(1) ++#define B_AX_STOP_RXQ BIT(0) ++#define B_AX_TX_STOP1_ALL GENMASK(18, 8) ++ ++#define R_AX_PCIE_DMA_STOP2 0x1310 ++#define B_AX_STOP_CH11 BIT(1) ++#define B_AX_STOP_CH10 BIT(0) ++#define B_AX_TX_STOP2_ALL GENMASK(1, 0) ++ ++#define R_AX_TXBD_RWPTR_CLR1 0x1014 ++#define B_AX_CLR_CH12_IDX BIT(10) ++#define B_AX_CLR_CH9_IDX BIT(9) ++#define B_AX_CLR_CH8_IDX BIT(8) ++#define B_AX_CLR_ACH7_IDX BIT(7) ++#define B_AX_CLR_ACH6_IDX BIT(6) ++#define B_AX_CLR_ACH5_IDX BIT(5) ++#define B_AX_CLR_ACH4_IDX BIT(4) ++#define B_AX_CLR_ACH3_IDX BIT(3) ++#define B_AX_CLR_ACH2_IDX BIT(2) ++#define B_AX_CLR_ACH1_IDX BIT(1) ++#define B_AX_CLR_ACH0_IDX BIT(0) ++#define B_AX_TXBD_CLR1_ALL GENMASK(10, 0) ++ ++#define R_AX_RXBD_RWPTR_CLR 0x1018 ++#define B_AX_CLR_RPQ_IDX BIT(1) ++#define B_AX_CLR_RXQ_IDX BIT(0) ++#define B_AX_RXBD_CLR_ALL GENMASK(1, 0) ++ ++#define R_AX_TXBD_RWPTR_CLR2 0x1314 ++#define B_AX_CLR_CH11_IDX BIT(1) ++#define B_AX_CLR_CH10_IDX BIT(0) ++#define B_AX_TXBD_CLR2_ALL GENMASK(1, 0) ++ ++#define R_AX_PCIE_DMA_BUSY1 0x101C ++#define B_AX_PCIEIO_RX_BUSY BIT(22) ++#define B_AX_PCIEIO_TX_BUSY BIT(21) ++#define B_AX_PCIEIO_BUSY BIT(20) ++#define B_AX_WPDMA_BUSY BIT(19) ++ ++#define R_AX_PCIE_DMA_BUSY2 0x131C ++#define B_AX_CH11_BUSY BIT(1) ++#define B_AX_CH10_BUSY BIT(0) ++ ++/* Configure */ ++#define R_AX_PCIE_INIT_CFG1 0x1000 ++#define B_AX_PCIE_RXRST_KEEP_REG BIT(23) ++#define B_AX_PCIE_TXRST_KEEP_REG BIT(22) ++#define B_AX_DIS_RXDMA_PRE BIT(2) ++ ++#define R_AX_PCIE_INIT_CFG2 0x1004 ++#define B_AX_WD_ITVL_IDLE GENMASK(27, 24) ++#define B_AX_WD_ITVL_ACT GENMASK(19, 16) ++ ++#define R_AX_PCIE_PS_CTRL 0x1008 ++#define B_AX_L1OFF_PWR_OFF_EN BIT(5) ++ ++#define R_AX_INT_MIT_RX 0x10D4 ++#define B_AX_RXMIT_RXP2_SEL BIT(19) ++#define B_AX_RXMIT_RXP1_SEL BIT(18) ++#define B_AX_RXTIMER_UNIT_MASK GENMASK(17, 16) ++#define AX_RXTIMER_UNIT_64US 0 ++#define AX_RXTIMER_UNIT_128US 1 ++#define AX_RXTIMER_UNIT_256US 2 ++#define AX_RXTIMER_UNIT_512US 3 ++#define B_AX_RXCOUNTER_MATCH_MASK GENMASK(15, 8) ++#define B_AX_RXTIMER_MATCH_MASK GENMASK(7, 0) ++ ++#define R_AX_DBG_ERR_FLAG 0x11C4 ++#define B_AX_PCIE_RPQ_FULL BIT(29) ++#define B_AX_PCIE_RXQ_FULL BIT(28) ++#define B_AX_CPL_STATUS_MASK GENMASK(27, 25) ++#define B_AX_RX_STUCK BIT(22) ++#define B_AX_TX_STUCK BIT(21) ++#define B_AX_PCIEDBG_TXERR0 BIT(16) ++#define B_AX_PCIE_RXP1_ERR0 BIT(4) ++#define B_AX_PCIE_TXBD_LEN0 BIT(1) ++#define B_AX_PCIE_TXBD_4KBOUD_LENERR BIT(0) ++ ++#define R_AX_LBC_WATCHDOG 0x11D8 ++#define B_AX_LBC_TIMER GENMASK(7, 4) ++#define B_AX_LBC_FLAG BIT(1) ++#define B_AX_LBC_EN BIT(0) ++ ++#define R_AX_PCIE_EXP_CTRL 0x13F0 ++#define B_AX_EN_CHKDSC_NO_RX_STUCK BIT(20) ++#define B_AX_MAX_TAG_NUM GENMASK(18, 16) ++#define B_AX_SIC_EN_FORCE_CLKREQ BIT(4) ++ ++#define R_AX_PCIE_RX_PREF_ADV 0x13F4 ++#define B_AX_RXDMA_PREF_ADV_EN BIT(0) ++ ++#define RTW89_PCI_TXBD_NUM_MAX 256 ++#define RTW89_PCI_RXBD_NUM_MAX 256 ++#define RTW89_PCI_TXWD_NUM_MAX 512 ++#define RTW89_PCI_TXWD_PAGE_SIZE 128 ++#define RTW89_PCI_ADDRINFO_MAX 4 ++#define RTW89_PCI_RX_BUF_SIZE 11460 ++ ++#define RTW89_PCI_POLL_BDRAM_RST_CNT 100 ++#define RTW89_PCI_MULTITAG 8 ++ ++/* PCIE CFG register */ ++#define RTW89_PCIE_ASPM_CTRL 0x070F ++#define RTW89_L1DLY_MASK GENMASK(5, 3) ++#define RTW89_L0DLY_MASK GENMASK(2, 0) ++#define RTW89_PCIE_TIMER_CTRL 0x0718 ++#define RTW89_PCIE_BIT_L1SUB BIT(5) ++#define RTW89_PCIE_L1_CTRL 0x0719 ++#define RTW89_PCIE_BIT_CLK BIT(4) ++#define RTW89_PCIE_BIT_L1 BIT(3) ++#define RTW89_PCIE_CLK_CTRL 0x0725 ++#define RTW89_PCIE_RST_MSTATE 0x0B48 ++#define RTW89_PCIE_BIT_CFG_RST_MSTATE BIT(0) ++#define RTW89_PCIE_PHY_RATE 0x82 ++#define RTW89_PCIE_PHY_RATE_MASK GENMASK(1, 0) ++#define INTF_INTGRA_MINREF_V1 90 ++#define INTF_INTGRA_HOSTREF_V1 100 ++ ++enum rtw89_pcie_phy { ++ PCIE_PHY_GEN1, ++ PCIE_PHY_GEN2, ++ PCIE_PHY_GEN1_UNDEFINE = 0x7F, ++}; ++ ++enum mac_ax_func_sw { ++ MAC_AX_FUNC_DIS, ++ MAC_AX_FUNC_EN, ++}; ++ ++enum rtw89_pcie_l0sdly { ++ PCIE_L0SDLY_1US = 0, ++ PCIE_L0SDLY_2US = 1, ++ PCIE_L0SDLY_3US = 2, ++ PCIE_L0SDLY_4US = 3, ++ PCIE_L0SDLY_5US = 4, ++ PCIE_L0SDLY_6US = 5, ++ PCIE_L0SDLY_7US = 6, ++}; ++ ++enum rtw89_pcie_l1dly { ++ PCIE_L1DLY_16US = 4, ++ PCIE_L1DLY_32US = 5, ++ PCIE_L1DLY_64US = 6, ++ PCIE_L1DLY_HW_INFI = 7, ++}; ++ ++enum rtw89_pcie_clkdly_hw { ++ PCIE_CLKDLY_HW_0 = 0, ++ PCIE_CLKDLY_HW_30US = 0x1, ++ PCIE_CLKDLY_HW_50US = 0x2, ++ PCIE_CLKDLY_HW_100US = 0x3, ++ PCIE_CLKDLY_HW_150US = 0x4, ++ PCIE_CLKDLY_HW_200US = 0x5, ++}; ++ ++struct rtw89_pci_bd_ram { ++ u8 start_idx; ++ u8 max_num; ++ u8 min_num; ++}; ++ ++struct rtw89_pci_tx_data { ++ dma_addr_t dma; ++}; ++ ++struct rtw89_pci_rx_info { ++ dma_addr_t dma; ++ u32 fs:1, ls:1, tag:11, len:14; ++}; ++ ++#define RTW89_PCI_TXBD_OPTION_LS BIT(14) ++ ++struct rtw89_pci_tx_bd_32 { ++ __le16 length; ++ __le16 option; ++ __le32 dma; ++} __packed; ++ ++#define RTW89_PCI_TXWP_VALID BIT(15) ++ ++struct rtw89_pci_tx_wp_info { ++ __le16 seq0; ++ __le16 seq1; ++ __le16 seq2; ++ __le16 seq3; ++} __packed; ++ ++#define RTW89_PCI_ADDR_MSDU_LS BIT(15) ++#define RTW89_PCI_ADDR_LS BIT(14) ++#define RTW89_PCI_ADDR_HIGH(a) (((a) << 6) & GENMASK(13, 6)) ++#define RTW89_PCI_ADDR_NUM(x) ((x) & GENMASK(5, 0)) ++ ++struct rtw89_pci_tx_addr_info_32 { ++ __le16 length; ++ __le16 option; ++ __le32 dma; ++} __packed; ++ ++#define RTW89_PCI_RPP_POLLUTED BIT(31) ++#define RTW89_PCI_RPP_SEQ GENMASK(30, 16) ++#define RTW89_PCI_RPP_TX_STATUS GENMASK(15, 13) ++#define RTW89_TX_DONE 0x0 ++#define RTW89_TX_RETRY_LIMIT 0x1 ++#define RTW89_TX_LIFE_TIME 0x2 ++#define RTW89_TX_MACID_DROP 0x3 ++#define RTW89_PCI_RPP_QSEL GENMASK(12, 8) ++#define RTW89_PCI_RPP_MACID GENMASK(7, 0) ++ ++struct rtw89_pci_rpp_fmt { ++ __le32 dword; ++} __packed; ++ ++struct rtw89_pci_rx_bd_32 { ++ __le16 buf_size; ++ __le16 rsvd; ++ __le32 dma; ++} __packed; ++ ++#define RTW89_PCI_RXBD_FS BIT(15) ++#define RTW89_PCI_RXBD_LS BIT(14) ++#define RTW89_PCI_RXBD_WRITE_SIZE GENMASK(13, 0) ++#define RTW89_PCI_RXBD_TAG GENMASK(28, 16) ++ ++struct rtw89_pci_rxbd_info { ++ __le32 dword; ++}; ++ ++struct rtw89_pci_tx_wd { ++ struct list_head list; ++ struct sk_buff_head queue; ++ ++ void *vaddr; ++ dma_addr_t paddr; ++ u32 len; ++ u32 seq; ++}; ++ ++struct rtw89_pci_dma_ring { ++ void *head; ++ u8 desc_size; ++ dma_addr_t dma; ++ ++ u32 addr_num; ++ u32 addr_idx; ++ u32 addr_bdram; ++ u32 addr_desa_l; ++ u32 addr_desa_h; ++ ++ u32 len; ++ u32 wp; /* host idx */ ++ u32 rp; /* hw idx */ ++}; ++ ++struct rtw89_pci_tx_wd_ring { ++ void *head; ++ dma_addr_t dma; ++ ++ struct rtw89_pci_tx_wd pages[RTW89_PCI_TXWD_NUM_MAX]; ++ struct list_head free_pages; ++ ++ u32 page_size; ++ u32 page_num; ++ u32 curr_num; ++}; ++ ++#define RTW89_RX_TAG_MAX 0x1fff ++ ++struct rtw89_pci_tx_ring { ++ struct rtw89_pci_tx_wd_ring wd_ring; ++ struct rtw89_pci_dma_ring bd_ring; ++ struct list_head busy_pages; ++ u8 txch; ++ bool dma_enabled; ++ u16 tag; /* range from 0x0001 ~ 0x1fff */ ++ ++ u64 tx_cnt; ++ u64 tx_acked; ++ u64 tx_retry_lmt; ++ u64 tx_life_time; ++ u64 tx_mac_id_drop; ++}; ++ ++struct rtw89_pci_rx_ring { ++ struct rtw89_pci_dma_ring bd_ring; ++ struct sk_buff *buf[RTW89_PCI_RXBD_NUM_MAX]; ++ u32 buf_sz; ++ struct sk_buff *diliver_skb; ++ struct rtw89_rx_desc_info diliver_desc; ++}; ++ ++struct rtw89_pci_isrs { ++ u32 halt_c2h_isrs; ++ u32 isrs[2]; ++}; ++ ++struct rtw89_pci { ++ struct pci_dev *pdev; ++ ++ /* protect HW irq related registers */ ++ spinlock_t irq_lock; ++ /* protect TRX resources (exclude RXQ) */ ++ spinlock_t trx_lock; ++ bool running; ++ struct rtw89_pci_tx_ring tx_rings[RTW89_TXCH_NUM]; ++ struct rtw89_pci_rx_ring rx_rings[RTW89_RXCH_NUM]; ++ struct sk_buff_head h2c_queue; ++ struct sk_buff_head h2c_release_queue; ++ ++ u32 halt_c2h_intrs; ++ u32 intrs[2]; ++ void __iomem *mmap; ++}; ++ ++static inline struct rtw89_pci_rx_info *RTW89_PCI_RX_SKB_CB(struct sk_buff *skb) ++{ ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ ++ BUILD_BUG_ON(sizeof(struct rtw89_pci_tx_data) > ++ sizeof(info->status.status_driver_data)); ++ ++ return (struct rtw89_pci_rx_info *)skb->cb; ++} ++ ++static inline struct rtw89_pci_rx_bd_32 * ++RTW89_PCI_RX_BD(struct rtw89_pci_rx_ring *rx_ring, u32 idx) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; ++ u8 *head = bd_ring->head; ++ u32 desc_size = bd_ring->desc_size; ++ u32 offset = idx * desc_size; ++ ++ return (struct rtw89_pci_rx_bd_32 *)(head + offset); ++} ++ ++static inline void ++rtw89_pci_rxbd_increase(struct rtw89_pci_rx_ring *rx_ring, u32 cnt) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &rx_ring->bd_ring; ++ ++ bd_ring->wp += cnt; ++ ++ if (bd_ring->wp >= bd_ring->len) ++ bd_ring->wp -= bd_ring->len; ++} ++ ++static inline struct rtw89_pci_tx_data *RTW89_PCI_TX_SKB_CB(struct sk_buff *skb) ++{ ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ ++ return (struct rtw89_pci_tx_data *)info->status.status_driver_data; ++} ++ ++static inline struct rtw89_pci_tx_bd_32 * ++rtw89_pci_get_next_txbd(struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_dma_ring *bd_ring = &tx_ring->bd_ring; ++ struct rtw89_pci_tx_bd_32 *tx_bd, *head; ++ ++ head = bd_ring->head; ++ tx_bd = head + bd_ring->wp; ++ ++ return tx_bd; ++} ++ ++static inline struct rtw89_pci_tx_wd * ++rtw89_pci_dequeue_txwd(struct rtw89_pci_tx_ring *tx_ring) ++{ ++ struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; ++ struct rtw89_pci_tx_wd *txwd; ++ ++ txwd = list_first_entry_or_null(&wd_ring->free_pages, ++ struct rtw89_pci_tx_wd, list); ++ if (!txwd) ++ return NULL; ++ ++ list_del_init(&txwd->list); ++ txwd->len = 0; ++ wd_ring->curr_num--; ++ ++ return txwd; ++} ++ ++static inline void ++rtw89_pci_enqueue_txwd(struct rtw89_pci_tx_ring *tx_ring, ++ struct rtw89_pci_tx_wd *txwd) ++{ ++ struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring; ++ ++ memset(txwd->vaddr, 0, wd_ring->page_size); ++ list_add_tail(&txwd->list, &wd_ring->free_pages); ++ wd_ring->curr_num++; ++} ++ ++static inline bool rtw89_pci_ltr_is_err_reg_val(u32 val) ++{ ++ return val == 0xffffffff || val == 0xeaeaeaea; ++} ++ ++extern const struct dev_pm_ops rtw89_pm_ops; ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c +new file mode 100644 +index 000000000000..53c36cc82c57 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/phy.c +@@ -0,0 +1,2868 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "debug.h" ++#include "fw.h" ++#include "phy.h" ++#include "ps.h" ++#include "reg.h" ++#include "sar.h" ++#include "coex.h" ++ ++static u16 get_max_amsdu_len(struct rtw89_dev *rtwdev, ++ const struct rtw89_ra_report *report) ++{ ++ const struct rate_info *txrate = &report->txrate; ++ u32 bit_rate = report->bit_rate; ++ u8 mcs; ++ ++ /* lower than ofdm, do not aggregate */ ++ if (bit_rate < 550) ++ return 1; ++ ++ /* prevent hardware rate fallback to G mode rate */ ++ if (txrate->flags & RATE_INFO_FLAGS_MCS) ++ mcs = txrate->mcs & 0x07; ++ else if (txrate->flags & (RATE_INFO_FLAGS_VHT_MCS | RATE_INFO_FLAGS_HE_MCS)) ++ mcs = txrate->mcs; ++ else ++ mcs = 0; ++ ++ if (mcs <= 2) ++ return 1; ++ ++ /* lower than 20M vht 2ss mcs8, make it small */ ++ if (bit_rate < 1800) ++ return 1200; ++ ++ /* lower than 40M vht 2ss mcs9, make it medium */ ++ if (bit_rate < 4000) ++ return 2600; ++ ++ /* not yet 80M vht 2ss mcs8/9, make it twice regular packet size */ ++ if (bit_rate < 7000) ++ return 3500; ++ ++ return rtwdev->chip->max_amsdu_limit; ++} ++ ++static u64 get_mcs_ra_mask(u16 mcs_map, u8 highest_mcs, u8 gap) ++{ ++ u64 ra_mask = 0; ++ u8 mcs_cap; ++ int i, nss; ++ ++ for (i = 0, nss = 12; i < 4; i++, mcs_map >>= 2, nss += 12) { ++ mcs_cap = mcs_map & 0x3; ++ switch (mcs_cap) { ++ case 2: ++ ra_mask |= GENMASK_ULL(highest_mcs, 0) << nss; ++ break; ++ case 1: ++ ra_mask |= GENMASK_ULL(highest_mcs - gap, 0) << nss; ++ break; ++ case 0: ++ ra_mask |= GENMASK_ULL(highest_mcs - gap * 2, 0) << nss; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ return ra_mask; ++} ++ ++static u64 get_he_ra_mask(struct ieee80211_sta *sta) ++{ ++ struct ieee80211_sta_he_cap cap = sta->he_cap; ++ u16 mcs_map; ++ ++ switch (sta->bandwidth) { ++ case IEEE80211_STA_RX_BW_160: ++ if (cap.he_cap_elem.phy_cap_info[0] & ++ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) ++ mcs_map = le16_to_cpu(cap.he_mcs_nss_supp.rx_mcs_80p80); ++ else ++ mcs_map = le16_to_cpu(cap.he_mcs_nss_supp.rx_mcs_160); ++ break; ++ default: ++ mcs_map = le16_to_cpu(cap.he_mcs_nss_supp.rx_mcs_80); ++ } ++ ++ /* MCS11, MCS9, MCS7 */ ++ return get_mcs_ra_mask(mcs_map, 11, 2); ++} ++ ++#define RA_FLOOR_TABLE_SIZE 7 ++#define RA_FLOOR_UP_GAP 3 ++static u64 rtw89_phy_ra_mask_rssi(struct rtw89_dev *rtwdev, u8 rssi, ++ u8 ratr_state) ++{ ++ u8 rssi_lv_t[RA_FLOOR_TABLE_SIZE] = {30, 44, 48, 52, 56, 60, 100}; ++ u8 rssi_lv = 0; ++ u8 i; ++ ++ rssi >>= 1; ++ for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) { ++ if (i >= ratr_state) ++ rssi_lv_t[i] += RA_FLOOR_UP_GAP; ++ if (rssi < rssi_lv_t[i]) { ++ rssi_lv = i; ++ break; ++ } ++ } ++ if (rssi_lv == 0) ++ return 0xffffffffffffffffULL; ++ else if (rssi_lv == 1) ++ return 0xfffffffffffffff0ULL; ++ else if (rssi_lv == 2) ++ return 0xffffffffffffffe0ULL; ++ else if (rssi_lv == 3) ++ return 0xffffffffffffffc0ULL; ++ else if (rssi_lv == 4) ++ return 0xffffffffffffff80ULL; ++ else if (rssi_lv >= 5) ++ return 0xffffffffffffff00ULL; ++ ++ return 0xffffffffffffffffULL; ++} ++ ++static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta) ++{ ++ struct rtw89_hal *hal = &rtwdev->hal; ++ struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta); ++ struct cfg80211_bitrate_mask *mask = &rtwsta->mask; ++ enum nl80211_band band; ++ u64 cfg_mask; ++ ++ if (!rtwsta->use_cfg_mask) ++ return -1; ++ ++ switch (hal->current_band_type) { ++ case RTW89_BAND_2G: ++ band = NL80211_BAND_2GHZ; ++ cfg_mask = u64_encode_bits(mask->control[NL80211_BAND_2GHZ].legacy, ++ RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES); ++ break; ++ case RTW89_BAND_5G: ++ band = NL80211_BAND_5GHZ; ++ cfg_mask = u64_encode_bits(mask->control[NL80211_BAND_5GHZ].legacy, ++ RA_MASK_OFDM_RATES); ++ break; ++ default: ++ rtw89_warn(rtwdev, "unhandled band type %d\n", hal->current_band_type); ++ return -1; ++ } ++ ++ if (sta->he_cap.has_he) { ++ cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[0], ++ RA_MASK_HE_1SS_RATES); ++ cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[1], ++ RA_MASK_HE_2SS_RATES); ++ } else if (sta->vht_cap.vht_supported) { ++ cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[0], ++ RA_MASK_VHT_1SS_RATES); ++ cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[1], ++ RA_MASK_VHT_2SS_RATES); ++ } else if (sta->ht_cap.ht_supported) { ++ cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[0], ++ RA_MASK_HT_1SS_RATES); ++ cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[1], ++ RA_MASK_HT_2SS_RATES); ++ } ++ ++ return cfg_mask; ++} ++ ++static const u64 ++rtw89_ra_mask_ht_rates[4] = {RA_MASK_HT_1SS_RATES, RA_MASK_HT_2SS_RATES, ++ RA_MASK_HT_3SS_RATES, RA_MASK_HT_4SS_RATES}; ++static const u64 ++rtw89_ra_mask_vht_rates[4] = {RA_MASK_VHT_1SS_RATES, RA_MASK_VHT_2SS_RATES, ++ RA_MASK_VHT_3SS_RATES, RA_MASK_VHT_4SS_RATES}; ++static const u64 ++rtw89_ra_mask_he_rates[4] = {RA_MASK_HE_1SS_RATES, RA_MASK_HE_2SS_RATES, ++ RA_MASK_HE_3SS_RATES, RA_MASK_HE_4SS_RATES}; ++ ++static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, ++ struct ieee80211_sta *sta, bool csi) ++{ ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_vif *rtwvif = rtwsta->rtwvif; ++ struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern; ++ struct rtw89_ra_info *ra = &rtwsta->ra; ++ const u64 *high_rate_masks = rtw89_ra_mask_ht_rates; ++ u8 rssi = ewma_rssi_read(&rtwsta->avg_rssi); ++ u64 high_rate_mask = 0; ++ u64 ra_mask = 0; ++ u8 mode = 0; ++ u8 csi_mode = RTW89_RA_RPT_MODE_LEGACY; ++ u8 bw_mode = 0; ++ u8 stbc_en = 0; ++ u8 ldpc_en = 0; ++ u8 i; ++ bool sgi = false; ++ ++ memset(ra, 0, sizeof(*ra)); ++ /* Set the ra mask from sta's capability */ ++ if (sta->he_cap.has_he) { ++ mode |= RTW89_RA_MODE_HE; ++ csi_mode = RTW89_RA_RPT_MODE_HE; ++ ra_mask |= get_he_ra_mask(sta); ++ high_rate_masks = rtw89_ra_mask_he_rates; ++ if (sta->he_cap.he_cap_elem.phy_cap_info[2] & ++ IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ) ++ stbc_en = 1; ++ if (sta->he_cap.he_cap_elem.phy_cap_info[1] & ++ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD) ++ ldpc_en = 1; ++ } else if (sta->vht_cap.vht_supported) { ++ u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map); ++ ++ mode |= RTW89_RA_MODE_VHT; ++ csi_mode = RTW89_RA_RPT_MODE_VHT; ++ /* MCS9, MCS8, MCS7 */ ++ ra_mask |= get_mcs_ra_mask(mcs_map, 9, 1); ++ high_rate_masks = rtw89_ra_mask_vht_rates; ++ if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK) ++ stbc_en = 1; ++ if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) ++ ldpc_en = 1; ++ } else if (sta->ht_cap.ht_supported) { ++ mode |= RTW89_RA_MODE_HT; ++ csi_mode = RTW89_RA_RPT_MODE_HT; ++ ra_mask |= ((u64)sta->ht_cap.mcs.rx_mask[3] << 48) | ++ ((u64)sta->ht_cap.mcs.rx_mask[2] << 36) | ++ (sta->ht_cap.mcs.rx_mask[1] << 24) | ++ (sta->ht_cap.mcs.rx_mask[0] << 12); ++ high_rate_masks = rtw89_ra_mask_ht_rates; ++ if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) ++ stbc_en = 1; ++ if (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) ++ ldpc_en = 1; ++ } ++ ++ if (rtwdev->hal.current_band_type == RTW89_BAND_2G) { ++ if (sta->supp_rates[NL80211_BAND_2GHZ] <= 0xf) ++ mode |= RTW89_RA_MODE_CCK; ++ else ++ mode |= RTW89_RA_MODE_CCK | RTW89_RA_MODE_OFDM; ++ } else { ++ mode |= RTW89_RA_MODE_OFDM; ++ } ++ ++ if (mode >= RTW89_RA_MODE_HT) { ++ for (i = 0; i < rtwdev->hal.tx_nss; i++) ++ high_rate_mask |= high_rate_masks[i]; ++ ra_mask &= high_rate_mask; ++ if (mode & RTW89_RA_MODE_OFDM) ++ ra_mask |= RA_MASK_SUBOFDM_RATES; ++ if (mode & RTW89_RA_MODE_CCK) ++ ra_mask |= RA_MASK_SUBCCK_RATES; ++ } else if (mode & RTW89_RA_MODE_OFDM) { ++ if (mode & RTW89_RA_MODE_CCK) ++ ra_mask |= RA_MASK_SUBCCK_RATES; ++ ra_mask |= RA_MASK_OFDM_RATES; ++ } else { ++ ra_mask = RA_MASK_CCK_RATES; ++ } ++ ++ if (mode != RTW89_RA_MODE_CCK) { ++ ra_mask &= rtw89_phy_ra_mask_rssi(rtwdev, rssi, 0); ++ ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta); ++ } ++ ++ switch (sta->bandwidth) { ++ case IEEE80211_STA_RX_BW_80: ++ bw_mode = RTW89_CHANNEL_WIDTH_80; ++ sgi = sta->vht_cap.vht_supported && ++ (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); ++ break; ++ case IEEE80211_STA_RX_BW_40: ++ bw_mode = RTW89_CHANNEL_WIDTH_40; ++ sgi = sta->ht_cap.ht_supported && ++ (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40); ++ break; ++ default: ++ bw_mode = RTW89_CHANNEL_WIDTH_20; ++ sgi = sta->ht_cap.ht_supported && ++ (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20); ++ break; ++ } ++ ++ if (sta->he_cap.he_cap_elem.phy_cap_info[3] & ++ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM) ++ ra->dcm_cap = 1; ++ ++ if (rate_pattern->enable) { ++ ra_mask = rtw89_phy_ra_mask_cfg(rtwdev, rtwsta); ++ ra_mask &= rate_pattern->ra_mask; ++ mode = rate_pattern->ra_mode; ++ } ++ ++ ra->bw_cap = bw_mode; ++ ra->mode_ctrl = mode; ++ ra->macid = rtwsta->mac_id; ++ ra->stbc_cap = stbc_en; ++ ra->ldpc_cap = ldpc_en; ++ ra->ss_num = min(sta->rx_nss, rtwdev->hal.tx_nss) - 1; ++ ra->en_sgi = sgi; ++ ra->ra_mask = ra_mask; ++ ++ if (!csi) ++ return; ++ ++ ra->fixed_csi_rate_en = false; ++ ra->ra_csi_rate_en = true; ++ ra->cr_tbl_sel = false; ++ ra->band_num = rtwvif->phy_idx; ++ ra->csi_bw = bw_mode; ++ ra->csi_gi_ltf = RTW89_GILTF_LGI_4XHE32; ++ ra->csi_mcs_ss_idx = 5; ++ ra->csi_mode = csi_mode; ++} ++ ++void rtw89_phy_ra_updata_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) ++{ ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_ra_info *ra = &rtwsta->ra; ++ ++ rtw89_phy_ra_sta_update(rtwdev, sta, false); ++ ra->upd_mask = 1; ++ rtw89_debug(rtwdev, RTW89_DBG_RA, ++ "ra updat: macid = %d, bw = %d, nss = %d, gi = %d %d", ++ ra->macid, ++ ra->bw_cap, ++ ra->ss_num, ++ ra->en_sgi, ++ ra->giltf); ++ ++ rtw89_fw_h2c_ra(rtwdev, ra, false); ++} ++ ++static bool __check_rate_pattern(struct rtw89_phy_rate_pattern *next, ++ u16 rate_base, u64 ra_mask, u8 ra_mode, ++ u32 rate_ctrl, u32 ctrl_skip, bool force) ++{ ++ u8 n, c; ++ ++ if (rate_ctrl == ctrl_skip) ++ return true; ++ ++ n = hweight32(rate_ctrl); ++ if (n == 0) ++ return true; ++ ++ if (force && n != 1) ++ return false; ++ ++ if (next->enable) ++ return false; ++ ++ c = __fls(rate_ctrl); ++ next->rate = rate_base + c; ++ next->ra_mode = ra_mode; ++ next->ra_mask = ra_mask; ++ next->enable = true; ++ ++ return true; ++} ++ ++void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ const struct cfg80211_bitrate_mask *mask) ++{ ++ struct ieee80211_supported_band *sband; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ struct rtw89_phy_rate_pattern next_pattern = {0}; ++ static const u16 hw_rate_he[] = {RTW89_HW_RATE_HE_NSS1_MCS0, ++ RTW89_HW_RATE_HE_NSS2_MCS0, ++ RTW89_HW_RATE_HE_NSS3_MCS0, ++ RTW89_HW_RATE_HE_NSS4_MCS0}; ++ static const u16 hw_rate_vht[] = {RTW89_HW_RATE_VHT_NSS1_MCS0, ++ RTW89_HW_RATE_VHT_NSS2_MCS0, ++ RTW89_HW_RATE_VHT_NSS3_MCS0, ++ RTW89_HW_RATE_VHT_NSS4_MCS0}; ++ static const u16 hw_rate_ht[] = {RTW89_HW_RATE_MCS0, ++ RTW89_HW_RATE_MCS8, ++ RTW89_HW_RATE_MCS16, ++ RTW89_HW_RATE_MCS24}; ++ u8 band = rtwdev->hal.current_band_type; ++ u8 tx_nss = rtwdev->hal.tx_nss; ++ u8 i; ++ ++ for (i = 0; i < tx_nss; i++) ++ if (!__check_rate_pattern(&next_pattern, hw_rate_he[i], ++ RA_MASK_HE_RATES, RTW89_RA_MODE_HE, ++ mask->control[band].he_mcs[i], ++ 0, true)) ++ goto out; ++ ++ for (i = 0; i < tx_nss; i++) ++ if (!__check_rate_pattern(&next_pattern, hw_rate_vht[i], ++ RA_MASK_VHT_RATES, RTW89_RA_MODE_VHT, ++ mask->control[band].vht_mcs[i], ++ 0, true)) ++ goto out; ++ ++ for (i = 0; i < tx_nss; i++) ++ if (!__check_rate_pattern(&next_pattern, hw_rate_ht[i], ++ RA_MASK_HT_RATES, RTW89_RA_MODE_HT, ++ mask->control[band].ht_mcs[i], ++ 0, true)) ++ goto out; ++ ++ /* lagacy cannot be empty for nl80211_parse_tx_bitrate_mask, and ++ * require at least one basic rate for ieee80211_set_bitrate_mask, ++ * so the decision just depends on if all bitrates are set or not. ++ */ ++ sband = rtwdev->hw->wiphy->bands[band]; ++ if (band == RTW89_BAND_2G) { ++ if (!__check_rate_pattern(&next_pattern, RTW89_HW_RATE_CCK1, ++ RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES, ++ RTW89_RA_MODE_CCK | RTW89_RA_MODE_OFDM, ++ mask->control[band].legacy, ++ BIT(sband->n_bitrates) - 1, false)) ++ goto out; ++ } else { ++ if (!__check_rate_pattern(&next_pattern, RTW89_HW_RATE_OFDM6, ++ RA_MASK_OFDM_RATES, RTW89_RA_MODE_OFDM, ++ mask->control[band].legacy, ++ BIT(sband->n_bitrates) - 1, false)) ++ goto out; ++ } ++ ++ if (!next_pattern.enable) ++ goto out; ++ ++ rtwvif->rate_pattern = next_pattern; ++ rtw89_debug(rtwdev, RTW89_DBG_RA, ++ "configure pattern: rate 0x%x, mask 0x%llx, mode 0x%x\n", ++ next_pattern.rate, ++ next_pattern.ra_mask, ++ next_pattern.ra_mode); ++ return; ++ ++out: ++ rtwvif->rate_pattern.enable = false; ++ rtw89_debug(rtwdev, RTW89_DBG_RA, "unset rate pattern\n"); ++} ++ ++static void rtw89_phy_ra_updata_sta_iter(void *data, struct ieee80211_sta *sta) ++{ ++ struct rtw89_dev *rtwdev = (struct rtw89_dev *)data; ++ ++ rtw89_phy_ra_updata_sta(rtwdev, sta); ++} ++ ++void rtw89_phy_ra_update(struct rtw89_dev *rtwdev) ++{ ++ ieee80211_iterate_stations_atomic(rtwdev->hw, ++ rtw89_phy_ra_updata_sta_iter, ++ rtwdev); ++} ++ ++void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) ++{ ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_ra_info *ra = &rtwsta->ra; ++ u8 rssi = ewma_rssi_read(&rtwsta->avg_rssi) >> RSSI_FACTOR; ++ bool csi = rtw89_sta_has_beamformer_cap(sta); ++ ++ rtw89_phy_ra_sta_update(rtwdev, sta, csi); ++ ++ if (rssi > 40) ++ ra->init_rate_lv = 1; ++ else if (rssi > 20) ++ ra->init_rate_lv = 2; ++ else if (rssi > 1) ++ ra->init_rate_lv = 3; ++ else ++ ra->init_rate_lv = 0; ++ ra->upd_all = 1; ++ rtw89_debug(rtwdev, RTW89_DBG_RA, ++ "ra assoc: macid = %d, mode = %d, bw = %d, nss = %d, lv = %d", ++ ra->macid, ++ ra->mode_ctrl, ++ ra->bw_cap, ++ ra->ss_num, ++ ra->init_rate_lv); ++ rtw89_debug(rtwdev, RTW89_DBG_RA, ++ "ra assoc: dcm = %d, er = %d, ldpc = %d, stbc = %d, gi = %d %d", ++ ra->dcm_cap, ++ ra->er_cap, ++ ra->ldpc_cap, ++ ra->stbc_cap, ++ ra->en_sgi, ++ ra->giltf); ++ ++ rtw89_fw_h2c_ra(rtwdev, ra, csi); ++} ++ ++u8 rtw89_phy_get_txsc(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_params *param, ++ enum rtw89_bandwidth dbw) ++{ ++ enum rtw89_bandwidth cbw = param->bandwidth; ++ u8 pri_ch = param->primary_chan; ++ u8 central_ch = param->center_chan; ++ u8 txsc_idx = 0; ++ u8 tmp = 0; ++ ++ if (cbw == dbw || cbw == RTW89_CHANNEL_WIDTH_20) ++ return txsc_idx; ++ ++ switch (cbw) { ++ case RTW89_CHANNEL_WIDTH_40: ++ txsc_idx = pri_ch > central_ch ? 1 : 2; ++ break; ++ case RTW89_CHANNEL_WIDTH_80: ++ if (dbw == RTW89_CHANNEL_WIDTH_20) { ++ if (pri_ch > central_ch) ++ txsc_idx = (pri_ch - central_ch) >> 1; ++ else ++ txsc_idx = ((central_ch - pri_ch) >> 1) + 1; ++ } else { ++ txsc_idx = pri_ch > central_ch ? 9 : 10; ++ } ++ break; ++ case RTW89_CHANNEL_WIDTH_160: ++ if (pri_ch > central_ch) ++ tmp = (pri_ch - central_ch) >> 1; ++ else ++ tmp = ((central_ch - pri_ch) >> 1) + 1; ++ ++ if (dbw == RTW89_CHANNEL_WIDTH_20) { ++ txsc_idx = tmp; ++ } else if (dbw == RTW89_CHANNEL_WIDTH_40) { ++ if (tmp == 1 || tmp == 3) ++ txsc_idx = 9; ++ else if (tmp == 5 || tmp == 7) ++ txsc_idx = 11; ++ else if (tmp == 2 || tmp == 4) ++ txsc_idx = 10; ++ else if (tmp == 6 || tmp == 8) ++ txsc_idx = 12; ++ else ++ return 0xff; ++ } else { ++ txsc_idx = pri_ch > central_ch ? 13 : 14; ++ } ++ break; ++ case RTW89_CHANNEL_WIDTH_80_80: ++ if (dbw == RTW89_CHANNEL_WIDTH_20) { ++ if (pri_ch > central_ch) ++ txsc_idx = (10 - (pri_ch - central_ch)) >> 1; ++ else ++ txsc_idx = ((central_ch - pri_ch) >> 1) + 5; ++ } else if (dbw == RTW89_CHANNEL_WIDTH_40) { ++ txsc_idx = pri_ch > central_ch ? 10 : 12; ++ } else { ++ txsc_idx = 14; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ return txsc_idx; ++} ++ ++u32 rtw89_phy_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ const u32 *base_addr = chip->rf_base_addr; ++ u32 val, direct_addr; ++ ++ if (rf_path >= rtwdev->chip->rf_path_num) { ++ rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path); ++ return INV_RF_DATA; ++ } ++ ++ addr &= 0xff; ++ direct_addr = base_addr[rf_path] + (addr << 2); ++ mask &= RFREG_MASK; ++ ++ val = rtw89_phy_read32_mask(rtwdev, direct_addr, mask); ++ ++ return val; ++} ++EXPORT_SYMBOL(rtw89_phy_read_rf); ++ ++bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask, u32 data) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ const u32 *base_addr = chip->rf_base_addr; ++ u32 direct_addr; ++ ++ if (rf_path >= rtwdev->chip->rf_path_num) { ++ rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path); ++ return false; ++ } ++ ++ addr &= 0xff; ++ direct_addr = base_addr[rf_path] + (addr << 2); ++ mask &= RFREG_MASK; ++ ++ rtw89_phy_write32_mask(rtwdev, direct_addr, mask, data); ++ ++ /* delay to ensure writing properly */ ++ udelay(1); ++ ++ return true; ++} ++EXPORT_SYMBOL(rtw89_phy_write_rf); ++ ++static void rtw89_phy_bb_reset(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ chip->ops->bb_reset(rtwdev, phy_idx); ++} ++ ++static void rtw89_phy_config_bb_reg(struct rtw89_dev *rtwdev, ++ const struct rtw89_reg2_def *reg, ++ enum rtw89_rf_path rf_path, ++ void *extra_data) ++{ ++ if (reg->addr == 0xfe) ++ mdelay(50); ++ else if (reg->addr == 0xfd) ++ mdelay(5); ++ else if (reg->addr == 0xfc) ++ mdelay(1); ++ else if (reg->addr == 0xfb) ++ udelay(50); ++ else if (reg->addr == 0xfa) ++ udelay(5); ++ else if (reg->addr == 0xf9) ++ udelay(1); ++ else ++ rtw89_phy_write32(rtwdev, reg->addr, reg->data); ++} ++ ++static void ++rtw89_phy_cofig_rf_reg_store(struct rtw89_dev *rtwdev, ++ const struct rtw89_reg2_def *reg, ++ enum rtw89_rf_path rf_path, ++ struct rtw89_fw_h2c_rf_reg_info *info) ++{ ++ u16 idx = info->curr_idx % RTW89_H2C_RF_PAGE_SIZE; ++ u8 page = info->curr_idx / RTW89_H2C_RF_PAGE_SIZE; ++ ++ info->rtw89_phy_config_rf_h2c[page][idx] = ++ cpu_to_le32((reg->addr << 20) | reg->data); ++ info->curr_idx++; ++} ++ ++static int rtw89_phy_config_rf_reg_fw(struct rtw89_dev *rtwdev, ++ struct rtw89_fw_h2c_rf_reg_info *info) ++{ ++ u16 page = info->curr_idx / RTW89_H2C_RF_PAGE_SIZE; ++ u16 len = (info->curr_idx % RTW89_H2C_RF_PAGE_SIZE) * 4; ++ u8 i; ++ int ret = 0; ++ ++ if (page > RTW89_H2C_RF_PAGE_NUM) { ++ rtw89_warn(rtwdev, ++ "rf reg h2c total page num %d larger than %d (RTW89_H2C_RF_PAGE_NUM)\n", ++ page, RTW89_H2C_RF_PAGE_NUM); ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < page; i++) { ++ ret = rtw89_fw_h2c_rf_reg(rtwdev, info, ++ RTW89_H2C_RF_PAGE_SIZE * 4, i); ++ if (ret) ++ return ret; ++ } ++ ret = rtw89_fw_h2c_rf_reg(rtwdev, info, len, i); ++ if (ret) ++ return ret; ++ info->curr_idx = 0; ++ ++ return 0; ++} ++ ++static void rtw89_phy_config_rf_reg(struct rtw89_dev *rtwdev, ++ const struct rtw89_reg2_def *reg, ++ enum rtw89_rf_path rf_path, ++ void *extra_data) ++{ ++ if (reg->addr == 0xfe) { ++ mdelay(50); ++ } else if (reg->addr == 0xfd) { ++ mdelay(5); ++ } else if (reg->addr == 0xfc) { ++ mdelay(1); ++ } else if (reg->addr == 0xfb) { ++ udelay(50); ++ } else if (reg->addr == 0xfa) { ++ udelay(5); ++ } else if (reg->addr == 0xf9) { ++ udelay(1); ++ } else { ++ rtw89_write_rf(rtwdev, rf_path, reg->addr, 0xfffff, reg->data); ++ rtw89_phy_cofig_rf_reg_store(rtwdev, reg, rf_path, ++ (struct rtw89_fw_h2c_rf_reg_info *)extra_data); ++ } ++} ++ ++static int rtw89_phy_sel_headline(struct rtw89_dev *rtwdev, ++ const struct rtw89_phy_table *table, ++ u32 *headline_size, u32 *headline_idx, ++ u8 rfe, u8 cv) ++{ ++ const struct rtw89_reg2_def *reg; ++ u32 headline; ++ u32 compare, target; ++ u8 rfe_para, cv_para; ++ u8 cv_max = 0; ++ bool case_matched = false; ++ u32 i; ++ ++ for (i = 0; i < table->n_regs; i++) { ++ reg = &table->regs[i]; ++ headline = get_phy_headline(reg->addr); ++ if (headline != PHY_HEADLINE_VALID) ++ break; ++ } ++ *headline_size = i; ++ if (*headline_size == 0) ++ return 0; ++ ++ /* case 1: RFE match, CV match */ ++ compare = get_phy_compare(rfe, cv); ++ for (i = 0; i < *headline_size; i++) { ++ reg = &table->regs[i]; ++ target = get_phy_target(reg->addr); ++ if (target == compare) { ++ *headline_idx = i; ++ return 0; ++ } ++ } ++ ++ /* case 2: RFE match, CV don't care */ ++ compare = get_phy_compare(rfe, PHY_COND_DONT_CARE); ++ for (i = 0; i < *headline_size; i++) { ++ reg = &table->regs[i]; ++ target = get_phy_target(reg->addr); ++ if (target == compare) { ++ *headline_idx = i; ++ return 0; ++ } ++ } ++ ++ /* case 3: RFE match, CV max in table */ ++ for (i = 0; i < *headline_size; i++) { ++ reg = &table->regs[i]; ++ rfe_para = get_phy_cond_rfe(reg->addr); ++ cv_para = get_phy_cond_cv(reg->addr); ++ if (rfe_para == rfe) { ++ if (cv_para >= cv_max) { ++ cv_max = cv_para; ++ *headline_idx = i; ++ case_matched = true; ++ } ++ } ++ } ++ ++ if (case_matched) ++ return 0; ++ ++ /* case 4: RFE don't care, CV max in table */ ++ for (i = 0; i < *headline_size; i++) { ++ reg = &table->regs[i]; ++ rfe_para = get_phy_cond_rfe(reg->addr); ++ cv_para = get_phy_cond_cv(reg->addr); ++ if (rfe_para == PHY_COND_DONT_CARE) { ++ if (cv_para >= cv_max) { ++ cv_max = cv_para; ++ *headline_idx = i; ++ case_matched = true; ++ } ++ } ++ } ++ ++ if (case_matched) ++ return 0; ++ ++ return -EINVAL; ++} ++ ++static void rtw89_phy_init_reg(struct rtw89_dev *rtwdev, ++ const struct rtw89_phy_table *table, ++ void (*config)(struct rtw89_dev *rtwdev, ++ const struct rtw89_reg2_def *reg, ++ enum rtw89_rf_path rf_path, ++ void *data), ++ void *extra_data) ++{ ++ const struct rtw89_reg2_def *reg; ++ enum rtw89_rf_path rf_path = table->rf_path; ++ u8 rfe = rtwdev->efuse.rfe_type; ++ u8 cv = rtwdev->hal.cv; ++ u32 i; ++ u32 headline_size = 0, headline_idx = 0; ++ u32 target = 0, cfg_target; ++ u8 cond; ++ bool is_matched = true; ++ bool target_found = false; ++ int ret; ++ ++ ret = rtw89_phy_sel_headline(rtwdev, table, &headline_size, ++ &headline_idx, rfe, cv); ++ if (ret) { ++ rtw89_err(rtwdev, "invalid PHY package: %d/%d\n", rfe, cv); ++ return; ++ } ++ ++ cfg_target = get_phy_target(table->regs[headline_idx].addr); ++ for (i = headline_size; i < table->n_regs; i++) { ++ reg = &table->regs[i]; ++ cond = get_phy_cond(reg->addr); ++ switch (cond) { ++ case PHY_COND_BRANCH_IF: ++ case PHY_COND_BRANCH_ELIF: ++ target = get_phy_target(reg->addr); ++ break; ++ case PHY_COND_BRANCH_ELSE: ++ is_matched = false; ++ if (!target_found) { ++ rtw89_warn(rtwdev, "failed to load CR %x/%x\n", ++ reg->addr, reg->data); ++ return; ++ } ++ break; ++ case PHY_COND_BRANCH_END: ++ is_matched = true; ++ target_found = false; ++ break; ++ case PHY_COND_CHECK: ++ if (target_found) { ++ is_matched = false; ++ break; ++ } ++ ++ if (target == cfg_target) { ++ is_matched = true; ++ target_found = true; ++ } else { ++ is_matched = false; ++ target_found = false; ++ } ++ break; ++ default: ++ if (is_matched) ++ config(rtwdev, reg, rf_path, extra_data); ++ break; ++ } ++ } ++} ++ ++void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ const struct rtw89_phy_table *bb_table = chip->bb_table; ++ ++ rtw89_phy_init_reg(rtwdev, bb_table, rtw89_phy_config_bb_reg, NULL); ++ rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_0); ++ rtw89_phy_bb_reset(rtwdev, RTW89_PHY_0); ++} ++ ++static u32 rtw89_phy_nctl_poll(struct rtw89_dev *rtwdev) ++{ ++ rtw89_phy_write32(rtwdev, 0x8080, 0x4); ++ udelay(1); ++ return rtw89_phy_read32(rtwdev, 0x8080); ++} ++ ++void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ const struct rtw89_phy_table *rf_table; ++ struct rtw89_fw_h2c_rf_reg_info *rf_reg_info; ++ u8 path; ++ ++ rf_reg_info = kzalloc(sizeof(*rf_reg_info), GFP_KERNEL); ++ if (!rf_reg_info) ++ return; ++ ++ for (path = RF_PATH_A; path < chip->rf_path_num; path++) { ++ rf_reg_info->rf_path = path; ++ rf_table = chip->rf_table[path]; ++ rtw89_phy_init_reg(rtwdev, rf_table, rtw89_phy_config_rf_reg, ++ (void *)rf_reg_info); ++ if (rtw89_phy_config_rf_reg_fw(rtwdev, rf_reg_info)) ++ rtw89_warn(rtwdev, "rf path %d reg h2c config failed\n", ++ path); ++ } ++ kfree(rf_reg_info); ++} ++ ++static void rtw89_phy_init_rf_nctl(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ const struct rtw89_phy_table *nctl_table; ++ u32 val; ++ int ret; ++ ++ /* IQK/DPK clock & reset */ ++ rtw89_phy_write32_set(rtwdev, 0x0c60, 0x3); ++ rtw89_phy_write32_set(rtwdev, 0x0c6c, 0x1); ++ rtw89_phy_write32_set(rtwdev, 0x58ac, 0x8000000); ++ rtw89_phy_write32_set(rtwdev, 0x78ac, 0x8000000); ++ ++ /* check 0x8080 */ ++ rtw89_phy_write32(rtwdev, 0x8000, 0x8); ++ ++ ret = read_poll_timeout(rtw89_phy_nctl_poll, val, val == 0x4, 10, ++ 1000, false, rtwdev); ++ if (ret) ++ rtw89_err(rtwdev, "failed to poll nctl block\n"); ++ ++ nctl_table = chip->nctl_table; ++ rtw89_phy_init_reg(rtwdev, nctl_table, rtw89_phy_config_bb_reg, NULL); ++} ++ ++static u32 rtw89_phy0_phy1_offset(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ u32 phy_page = addr >> 8; ++ u32 ofst = 0; ++ ++ switch (phy_page) { ++ case 0x6: ++ case 0x7: ++ case 0x8: ++ case 0x9: ++ case 0xa: ++ case 0xb: ++ case 0xc: ++ case 0xd: ++ case 0x19: ++ case 0x1a: ++ case 0x1b: ++ ofst = 0x2000; ++ break; ++ default: ++ /* warning case */ ++ ofst = 0; ++ break; ++ } ++ ++ if (phy_page >= 0x40 && phy_page <= 0x4f) ++ ofst = 0x2000; ++ ++ return ofst; ++} ++ ++void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, ++ u32 data, enum rtw89_phy_idx phy_idx) ++{ ++ if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1) ++ addr += rtw89_phy0_phy1_offset(rtwdev, addr); ++ rtw89_phy_write32_mask(rtwdev, addr, mask, data); ++} ++ ++void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask, ++ u32 val) ++{ ++ rtw89_phy_write32_idx(rtwdev, addr, mask, val, RTW89_PHY_0); ++ ++ if (!rtwdev->dbcc_en) ++ return; ++ ++ rtw89_phy_write32_idx(rtwdev, addr, mask, val, RTW89_PHY_1); ++} ++ ++void rtw89_phy_write_reg3_tbl(struct rtw89_dev *rtwdev, ++ const struct rtw89_phy_reg3_tbl *tbl) ++{ ++ const struct rtw89_reg3_def *reg3; ++ int i; ++ ++ for (i = 0; i < tbl->size; i++) { ++ reg3 = &tbl->reg3[i]; ++ rtw89_phy_write32_mask(rtwdev, reg3->addr, reg3->mask, reg3->data); ++ } ++} ++ ++const u8 rtw89_rs_idx_max[] = { ++ [RTW89_RS_CCK] = RTW89_RATE_CCK_MAX, ++ [RTW89_RS_OFDM] = RTW89_RATE_OFDM_MAX, ++ [RTW89_RS_MCS] = RTW89_RATE_MCS_MAX, ++ [RTW89_RS_HEDCM] = RTW89_RATE_HEDCM_MAX, ++ [RTW89_RS_OFFSET] = RTW89_RATE_OFFSET_MAX, ++}; ++ ++const u8 rtw89_rs_nss_max[] = { ++ [RTW89_RS_CCK] = 1, ++ [RTW89_RS_OFDM] = 1, ++ [RTW89_RS_MCS] = RTW89_NSS_MAX, ++ [RTW89_RS_HEDCM] = RTW89_NSS_HEDCM_MAX, ++ [RTW89_RS_OFFSET] = 1, ++}; ++ ++static const u8 _byr_of_rs[] = { ++ [RTW89_RS_CCK] = offsetof(struct rtw89_txpwr_byrate, cck), ++ [RTW89_RS_OFDM] = offsetof(struct rtw89_txpwr_byrate, ofdm), ++ [RTW89_RS_MCS] = offsetof(struct rtw89_txpwr_byrate, mcs), ++ [RTW89_RS_HEDCM] = offsetof(struct rtw89_txpwr_byrate, hedcm), ++ [RTW89_RS_OFFSET] = offsetof(struct rtw89_txpwr_byrate, offset), ++}; ++ ++#define _byr_seek(rs, raw) ((s8 *)(raw) + _byr_of_rs[rs]) ++#define _byr_idx(rs, nss, idx) ((nss) * rtw89_rs_idx_max[rs] + (idx)) ++#define _byr_chk(rs, nss, idx) \ ++ ((nss) < rtw89_rs_nss_max[rs] && (idx) < rtw89_rs_idx_max[rs]) ++ ++void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev, ++ const struct rtw89_txpwr_table *tbl) ++{ ++ const struct rtw89_txpwr_byrate_cfg *cfg = tbl->data; ++ const struct rtw89_txpwr_byrate_cfg *end = cfg + tbl->size; ++ s8 *byr; ++ u32 data; ++ u8 i, idx; ++ ++ for (; cfg < end; cfg++) { ++ byr = _byr_seek(cfg->rs, &rtwdev->byr[cfg->band]); ++ data = cfg->data; ++ ++ for (i = 0; i < cfg->len; i++, data >>= 8) { ++ idx = _byr_idx(cfg->rs, cfg->nss, (cfg->shf + i)); ++ byr[idx] = (s8)(data & 0xff); ++ } ++ } ++} ++ ++#define _phy_txpwr_rf_to_mac(rtwdev, txpwr_rf) \ ++({ \ ++ const struct rtw89_chip_info *__c = (rtwdev)->chip; \ ++ (txpwr_rf) >> (__c->txpwr_factor_rf - __c->txpwr_factor_mac); \ ++}) ++ ++s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, ++ const struct rtw89_rate_desc *rate_desc) ++{ ++ enum rtw89_band band = rtwdev->hal.current_band_type; ++ s8 *byr; ++ u8 idx; ++ ++ if (rate_desc->rs == RTW89_RS_CCK) ++ band = RTW89_BAND_2G; ++ ++ if (!_byr_chk(rate_desc->rs, rate_desc->nss, rate_desc->idx)) { ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, ++ "[TXPWR] unknown byrate desc rs=%d nss=%d idx=%d\n", ++ rate_desc->rs, rate_desc->nss, rate_desc->idx); ++ ++ return 0; ++ } ++ ++ byr = _byr_seek(rate_desc->rs, &rtwdev->byr[band]); ++ idx = _byr_idx(rate_desc->rs, rate_desc->nss, rate_desc->idx); ++ ++ return _phy_txpwr_rf_to_mac(rtwdev, byr[idx]); ++} ++ ++static u8 rtw89_channel_to_idx(struct rtw89_dev *rtwdev, u8 channel) ++{ ++ switch (channel) { ++ case 1 ... 14: ++ return channel - 1; ++ case 36 ... 64: ++ return (channel - 36) / 2; ++ case 100 ... 144: ++ return ((channel - 100) / 2) + 15; ++ case 149 ... 177: ++ return ((channel - 149) / 2) + 38; ++ default: ++ rtw89_warn(rtwdev, "unknown channel: %d\n", channel); ++ return 0; ++ } ++} ++ ++s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, ++ u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ u8 ch_idx = rtw89_channel_to_idx(rtwdev, ch); ++ u8 band = rtwdev->hal.current_band_type; ++ u8 regd = rtw89_regd_get(rtwdev, band); ++ s8 lmt = 0, sar; ++ ++ switch (band) { ++ case RTW89_BAND_2G: ++ lmt = (*chip->txpwr_lmt_2g)[bw][ntx][rs][bf][regd][ch_idx]; ++ break; ++ case RTW89_BAND_5G: ++ lmt = (*chip->txpwr_lmt_5g)[bw][ntx][rs][bf][regd][ch_idx]; ++ break; ++ default: ++ rtw89_warn(rtwdev, "unknown band type: %d\n", band); ++ return 0; ++ } ++ ++ lmt = _phy_txpwr_rf_to_mac(rtwdev, lmt); ++ sar = rtw89_query_sar(rtwdev); ++ ++ return min(lmt, sar); ++} ++ ++#define __fill_txpwr_limit_nonbf_bf(ptr, bw, ntx, rs, ch) \ ++ do { \ ++ u8 __i; \ ++ for (__i = 0; __i < RTW89_BF_NUM; __i++) \ ++ ptr[__i] = rtw89_phy_read_txpwr_limit(rtwdev, \ ++ bw, ntx, \ ++ rs, __i, \ ++ (ch)); \ ++ } while (0) ++ ++static void rtw89_phy_fill_txpwr_limit_20m(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit *lmt, ++ u8 ntx, u8 ch) ++{ ++ __fill_txpwr_limit_nonbf_bf(lmt->cck_20m, RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_CCK, ch); ++ __fill_txpwr_limit_nonbf_bf(lmt->cck_40m, RTW89_CHANNEL_WIDTH_40, ++ ntx, RTW89_RS_CCK, ch); ++ __fill_txpwr_limit_nonbf_bf(lmt->ofdm, RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_OFDM, ch); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_MCS, ch); ++} ++ ++static void rtw89_phy_fill_txpwr_limit_40m(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit *lmt, ++ u8 ntx, u8 ch) ++{ ++ __fill_txpwr_limit_nonbf_bf(lmt->cck_20m, RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_CCK, ch - 2); ++ __fill_txpwr_limit_nonbf_bf(lmt->cck_40m, RTW89_CHANNEL_WIDTH_40, ++ ntx, RTW89_RS_CCK, ch); ++ __fill_txpwr_limit_nonbf_bf(lmt->ofdm, RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_OFDM, ch - 2); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_MCS, ch - 2); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_MCS, ch + 2); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], RTW89_CHANNEL_WIDTH_40, ++ ntx, RTW89_RS_MCS, ch); ++} ++ ++static void rtw89_phy_fill_txpwr_limit_80m(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit *lmt, ++ u8 ntx, u8 ch) ++{ ++ s8 val_0p5_n[RTW89_BF_NUM]; ++ s8 val_0p5_p[RTW89_BF_NUM]; ++ u8 i; ++ ++ __fill_txpwr_limit_nonbf_bf(lmt->ofdm, RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_OFDM, ch - 6); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_MCS, ch - 6); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_MCS, ch - 2); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[2], RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_MCS, ch + 2); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[3], RTW89_CHANNEL_WIDTH_20, ++ ntx, RTW89_RS_MCS, ch + 6); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], RTW89_CHANNEL_WIDTH_40, ++ ntx, RTW89_RS_MCS, ch - 4); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[1], RTW89_CHANNEL_WIDTH_40, ++ ntx, RTW89_RS_MCS, ch + 4); ++ __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[0], RTW89_CHANNEL_WIDTH_80, ++ ntx, RTW89_RS_MCS, ch); ++ ++ __fill_txpwr_limit_nonbf_bf(val_0p5_n, RTW89_CHANNEL_WIDTH_40, ++ ntx, RTW89_RS_MCS, ch - 4); ++ __fill_txpwr_limit_nonbf_bf(val_0p5_p, RTW89_CHANNEL_WIDTH_40, ++ ntx, RTW89_RS_MCS, ch + 4); ++ ++ for (i = 0; i < RTW89_BF_NUM; i++) ++ lmt->mcs_40m_0p5[i] = min_t(s8, val_0p5_n[i], val_0p5_p[i]); ++} ++ ++void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit *lmt, ++ u8 ntx) ++{ ++ u8 ch = rtwdev->hal.current_channel; ++ u8 bw = rtwdev->hal.current_band_width; ++ ++ memset(lmt, 0, sizeof(*lmt)); ++ ++ switch (bw) { ++ case RTW89_CHANNEL_WIDTH_20: ++ rtw89_phy_fill_txpwr_limit_20m(rtwdev, lmt, ntx, ch); ++ break; ++ case RTW89_CHANNEL_WIDTH_40: ++ rtw89_phy_fill_txpwr_limit_40m(rtwdev, lmt, ntx, ch); ++ break; ++ case RTW89_CHANNEL_WIDTH_80: ++ rtw89_phy_fill_txpwr_limit_80m(rtwdev, lmt, ntx, ch); ++ break; ++ } ++} ++ ++static s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, ++ u8 ru, u8 ntx, u8 ch) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ u8 ch_idx = rtw89_channel_to_idx(rtwdev, ch); ++ u8 band = rtwdev->hal.current_band_type; ++ u8 regd = rtw89_regd_get(rtwdev, band); ++ s8 lmt_ru = 0, sar; ++ ++ switch (band) { ++ case RTW89_BAND_2G: ++ lmt_ru = (*chip->txpwr_lmt_ru_2g)[ru][ntx][regd][ch_idx]; ++ break; ++ case RTW89_BAND_5G: ++ lmt_ru = (*chip->txpwr_lmt_ru_5g)[ru][ntx][regd][ch_idx]; ++ break; ++ default: ++ rtw89_warn(rtwdev, "unknown band type: %d\n", band); ++ return 0; ++ } ++ ++ lmt_ru = _phy_txpwr_rf_to_mac(rtwdev, lmt_ru); ++ sar = rtw89_query_sar(rtwdev); ++ ++ return min(lmt_ru, sar); ++} ++ ++static void ++rtw89_phy_fill_txpwr_limit_ru_20m(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit_ru *lmt_ru, ++ u8 ntx, u8 ch) ++{ ++ lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, ++ ntx, ch); ++ lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, ++ ntx, ch); ++ lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, ++ ntx, ch); ++} ++ ++static void ++rtw89_phy_fill_txpwr_limit_ru_40m(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit_ru *lmt_ru, ++ u8 ntx, u8 ch) ++{ ++ lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, ++ ntx, ch - 2); ++ lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, ++ ntx, ch + 2); ++ lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, ++ ntx, ch - 2); ++ lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, ++ ntx, ch + 2); ++ lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, ++ ntx, ch - 2); ++ lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, ++ ntx, ch + 2); ++} ++ ++static void ++rtw89_phy_fill_txpwr_limit_ru_80m(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit_ru *lmt_ru, ++ u8 ntx, u8 ch) ++{ ++ lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, ++ ntx, ch - 6); ++ lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, ++ ntx, ch - 2); ++ lmt_ru->ru26[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, ++ ntx, ch + 2); ++ lmt_ru->ru26[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, ++ ntx, ch + 6); ++ lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, ++ ntx, ch - 6); ++ lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, ++ ntx, ch - 2); ++ lmt_ru->ru52[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, ++ ntx, ch + 2); ++ lmt_ru->ru52[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, ++ ntx, ch + 6); ++ lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, ++ ntx, ch - 6); ++ lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, ++ ntx, ch - 2); ++ lmt_ru->ru106[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, ++ ntx, ch + 2); ++ lmt_ru->ru106[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, ++ ntx, ch + 6); ++} ++ ++void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit_ru *lmt_ru, ++ u8 ntx) ++{ ++ u8 ch = rtwdev->hal.current_channel; ++ u8 bw = rtwdev->hal.current_band_width; ++ ++ memset(lmt_ru, 0, sizeof(*lmt_ru)); ++ ++ switch (bw) { ++ case RTW89_CHANNEL_WIDTH_20: ++ rtw89_phy_fill_txpwr_limit_ru_20m(rtwdev, lmt_ru, ntx, ch); ++ break; ++ case RTW89_CHANNEL_WIDTH_40: ++ rtw89_phy_fill_txpwr_limit_ru_40m(rtwdev, lmt_ru, ntx, ch); ++ break; ++ case RTW89_CHANNEL_WIDTH_80: ++ rtw89_phy_fill_txpwr_limit_ru_80m(rtwdev, lmt_ru, ntx, ch); ++ break; ++ } ++} ++ ++struct rtw89_phy_iter_ra_data { ++ struct rtw89_dev *rtwdev; ++ struct sk_buff *c2h; ++}; ++ ++static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) ++{ ++ struct rtw89_phy_iter_ra_data *ra_data = (struct rtw89_phy_iter_ra_data *)data; ++ struct rtw89_dev *rtwdev = ra_data->rtwdev; ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_ra_report *ra_report = &rtwsta->ra_report; ++ struct sk_buff *c2h = ra_data->c2h; ++ u8 mode, rate, bw, giltf, mac_id; ++ ++ mac_id = RTW89_GET_PHY_C2H_RA_RPT_MACID(c2h->data); ++ if (mac_id != rtwsta->mac_id) ++ return; ++ ++ memset(ra_report, 0, sizeof(*ra_report)); ++ ++ rate = RTW89_GET_PHY_C2H_RA_RPT_MCSNSS(c2h->data); ++ bw = RTW89_GET_PHY_C2H_RA_RPT_BW(c2h->data); ++ giltf = RTW89_GET_PHY_C2H_RA_RPT_GILTF(c2h->data); ++ mode = RTW89_GET_PHY_C2H_RA_RPT_MD_SEL(c2h->data); ++ ++ switch (mode) { ++ case RTW89_RA_RPT_MODE_LEGACY: ++ ra_report->txrate.legacy = rtw89_ra_report_to_bitrate(rtwdev, rate); ++ break; ++ case RTW89_RA_RPT_MODE_HT: ++ ra_report->txrate.flags |= RATE_INFO_FLAGS_MCS; ++ if (rtwdev->fw.old_ht_ra_format) ++ rate = RTW89_MK_HT_RATE(FIELD_GET(RTW89_RA_RATE_MASK_NSS, rate), ++ FIELD_GET(RTW89_RA_RATE_MASK_MCS, rate)); ++ else ++ rate = FIELD_GET(RTW89_RA_RATE_MASK_HT_MCS, rate); ++ ra_report->txrate.mcs = rate; ++ if (giltf) ++ ra_report->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; ++ break; ++ case RTW89_RA_RPT_MODE_VHT: ++ ra_report->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS; ++ ra_report->txrate.mcs = FIELD_GET(RTW89_RA_RATE_MASK_MCS, rate); ++ ra_report->txrate.nss = FIELD_GET(RTW89_RA_RATE_MASK_NSS, rate) + 1; ++ if (giltf) ++ ra_report->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; ++ break; ++ case RTW89_RA_RPT_MODE_HE: ++ ra_report->txrate.flags |= RATE_INFO_FLAGS_HE_MCS; ++ ra_report->txrate.mcs = FIELD_GET(RTW89_RA_RATE_MASK_MCS, rate); ++ ra_report->txrate.nss = FIELD_GET(RTW89_RA_RATE_MASK_NSS, rate) + 1; ++ if (giltf == RTW89_GILTF_2XHE08 || giltf == RTW89_GILTF_1XHE08) ++ ra_report->txrate.he_gi = NL80211_RATE_INFO_HE_GI_0_8; ++ else if (giltf == RTW89_GILTF_2XHE16 || giltf == RTW89_GILTF_1XHE16) ++ ra_report->txrate.he_gi = NL80211_RATE_INFO_HE_GI_1_6; ++ else ++ ra_report->txrate.he_gi = NL80211_RATE_INFO_HE_GI_3_2; ++ break; ++ } ++ ++ if (bw == RTW89_CHANNEL_WIDTH_80) ++ ra_report->txrate.bw = RATE_INFO_BW_80; ++ else if (bw == RTW89_CHANNEL_WIDTH_40) ++ ra_report->txrate.bw = RATE_INFO_BW_40; ++ else ++ ra_report->txrate.bw = RATE_INFO_BW_20; ++ ++ ra_report->bit_rate = cfg80211_calculate_bitrate(&ra_report->txrate); ++ ra_report->hw_rate = FIELD_PREP(RTW89_HW_RATE_MASK_MOD, mode) | ++ FIELD_PREP(RTW89_HW_RATE_MASK_VAL, rate); ++ sta->max_rc_amsdu_len = get_max_amsdu_len(rtwdev, ra_report); ++ rtwsta->max_agg_wait = sta->max_rc_amsdu_len / 1500 - 1; ++} ++ ++static void ++rtw89_phy_c2h_ra_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) ++{ ++ struct rtw89_phy_iter_ra_data ra_data; ++ ++ ra_data.rtwdev = rtwdev; ++ ra_data.c2h = c2h; ++ ieee80211_iterate_stations_atomic(rtwdev->hw, ++ rtw89_phy_c2h_ra_rpt_iter, ++ &ra_data); ++} ++ ++static ++void (* const rtw89_phy_c2h_ra_handler[])(struct rtw89_dev *rtwdev, ++ struct sk_buff *c2h, u32 len) = { ++ [RTW89_PHY_C2H_FUNC_STS_RPT] = rtw89_phy_c2h_ra_rpt, ++ [RTW89_PHY_C2H_FUNC_MU_GPTBL_RPT] = NULL, ++ [RTW89_PHY_C2H_FUNC_TXSTS] = NULL, ++}; ++ ++void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, ++ u32 len, u8 class, u8 func) ++{ ++ void (*handler)(struct rtw89_dev *rtwdev, ++ struct sk_buff *c2h, u32 len) = NULL; ++ ++ switch (class) { ++ case RTW89_PHY_C2H_CLASS_RA: ++ if (func < RTW89_PHY_C2H_FUNC_RA_MAX) ++ handler = rtw89_phy_c2h_ra_handler[func]; ++ break; ++ default: ++ rtw89_info(rtwdev, "c2h class %d not support\n", class); ++ return; ++ } ++ if (!handler) { ++ rtw89_info(rtwdev, "c2h class %d func %d not support\n", class, ++ func); ++ return; ++ } ++ handler(rtwdev, skb, len); ++} ++ ++static u8 rtw89_phy_cfo_get_xcap_reg(struct rtw89_dev *rtwdev, bool sc_xo) ++{ ++ u32 reg_mask; ++ ++ if (sc_xo) ++ reg_mask = B_AX_XTAL_SC_XO_MASK; ++ else ++ reg_mask = B_AX_XTAL_SC_XI_MASK; ++ ++ return (u8)rtw89_read32_mask(rtwdev, R_AX_XTAL_ON_CTRL0, reg_mask); ++} ++ ++static void rtw89_phy_cfo_set_xcap_reg(struct rtw89_dev *rtwdev, bool sc_xo, ++ u8 val) ++{ ++ u32 reg_mask; ++ ++ if (sc_xo) ++ reg_mask = B_AX_XTAL_SC_XO_MASK; ++ else ++ reg_mask = B_AX_XTAL_SC_XI_MASK; ++ ++ rtw89_write32_mask(rtwdev, R_AX_XTAL_ON_CTRL0, reg_mask, val); ++} ++ ++static void rtw89_phy_cfo_set_crystal_cap(struct rtw89_dev *rtwdev, ++ u8 crystal_cap, bool force) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ u8 sc_xi_val, sc_xo_val; ++ ++ if (!force && cfo->crystal_cap == crystal_cap) ++ return; ++ crystal_cap = clamp_t(u8, crystal_cap, 0, 127); ++ rtw89_phy_cfo_set_xcap_reg(rtwdev, true, crystal_cap); ++ rtw89_phy_cfo_set_xcap_reg(rtwdev, false, crystal_cap); ++ sc_xo_val = rtw89_phy_cfo_get_xcap_reg(rtwdev, true); ++ sc_xi_val = rtw89_phy_cfo_get_xcap_reg(rtwdev, false); ++ cfo->crystal_cap = sc_xi_val; ++ cfo->x_cap_ofst = (s8)((int)cfo->crystal_cap - cfo->def_x_cap); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Set sc_xi=0x%x\n", sc_xi_val); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Set sc_xo=0x%x\n", sc_xo_val); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Get xcap_ofst=%d\n", ++ cfo->x_cap_ofst); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Set xcap OK\n"); ++} ++ ++static void rtw89_phy_cfo_reset(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ u8 cap; ++ ++ cfo->def_x_cap = cfo->crystal_cap_default & B_AX_XTAL_SC_MASK; ++ cfo->is_adjust = false; ++ if (cfo->crystal_cap == cfo->def_x_cap) ++ return; ++ cap = cfo->crystal_cap; ++ cap += (cap > cfo->def_x_cap ? -1 : 1); ++ rtw89_phy_cfo_set_crystal_cap(rtwdev, cap, false); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "(0x%x) approach to dflt_val=(0x%x)\n", cfo->crystal_cap, ++ cfo->def_x_cap); ++} ++ ++static void rtw89_dcfo_comp(struct rtw89_dev *rtwdev, s32 curr_cfo) ++{ ++ bool is_linked = rtwdev->total_sta_assoc > 0; ++ s32 cfo_avg_312; ++ s32 dcfo_comp; ++ int sign; ++ ++ if (!is_linked) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "DCFO: is_linked=%d\n", ++ is_linked); ++ return; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "DCFO: curr_cfo=%d\n", curr_cfo); ++ if (curr_cfo == 0) ++ return; ++ dcfo_comp = rtw89_phy_read32_mask(rtwdev, R_DCFO, B_DCFO); ++ sign = curr_cfo > 0 ? 1 : -1; ++ cfo_avg_312 = (curr_cfo << 3) / 5 + sign * dcfo_comp; ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "DCFO: avg_cfo=%d\n", cfo_avg_312); ++ if (rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv == CHIP_CBV) ++ cfo_avg_312 = -cfo_avg_312; ++ rtw89_phy_set_phy_regs(rtwdev, R_DCFO_COMP_S0, B_DCFO_COMP_S0_MSK, ++ cfo_avg_312); ++} ++ ++static void rtw89_dcfo_comp_init(struct rtw89_dev *rtwdev) ++{ ++ rtw89_phy_set_phy_regs(rtwdev, R_DCFO_OPT, B_DCFO_OPT_EN, 1); ++ rtw89_phy_set_phy_regs(rtwdev, R_DCFO_WEIGHT, B_DCFO_WEIGHT_MSK, 8); ++ rtw89_write32_clr(rtwdev, R_AX_PWR_UL_CTRL2, B_AX_PWR_UL_CFO_MASK); ++} ++ ++static void rtw89_phy_cfo_init(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ struct rtw89_efuse *efuse = &rtwdev->efuse; ++ ++ cfo->crystal_cap_default = efuse->xtal_cap & B_AX_XTAL_SC_MASK; ++ cfo->crystal_cap = cfo->crystal_cap_default; ++ cfo->def_x_cap = cfo->crystal_cap; ++ cfo->is_adjust = false; ++ cfo->x_cap_ofst = 0; ++ cfo->rtw89_multi_cfo_mode = RTW89_TP_BASED_AVG_MODE; ++ cfo->apply_compensation = false; ++ cfo->residual_cfo_acc = 0; ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Default xcap=%0x\n", ++ cfo->crystal_cap_default); ++ rtw89_phy_cfo_set_crystal_cap(rtwdev, cfo->crystal_cap_default, true); ++ rtw89_phy_set_phy_regs(rtwdev, R_DCFO, B_DCFO, 1); ++ rtw89_dcfo_comp_init(rtwdev); ++ cfo->cfo_timer_ms = 2000; ++ cfo->cfo_trig_by_timer_en = false; ++ cfo->phy_cfo_trk_cnt = 0; ++ cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_NORMAL; ++} ++ ++static void rtw89_phy_cfo_crystal_cap_adjust(struct rtw89_dev *rtwdev, ++ s32 curr_cfo) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ s8 crystal_cap = cfo->crystal_cap; ++ s32 cfo_abs = abs(curr_cfo); ++ int sign; ++ ++ if (!cfo->is_adjust) { ++ if (cfo_abs > CFO_TRK_ENABLE_TH) ++ cfo->is_adjust = true; ++ } else { ++ if (cfo_abs < CFO_TRK_STOP_TH) ++ cfo->is_adjust = false; ++ } ++ if (!cfo->is_adjust) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Stop CFO tracking\n"); ++ return; ++ } ++ sign = curr_cfo > 0 ? 1 : -1; ++ if (cfo_abs > CFO_TRK_STOP_TH_4) ++ crystal_cap += 7 * sign; ++ else if (cfo_abs > CFO_TRK_STOP_TH_3) ++ crystal_cap += 5 * sign; ++ else if (cfo_abs > CFO_TRK_STOP_TH_2) ++ crystal_cap += 3 * sign; ++ else if (cfo_abs > CFO_TRK_STOP_TH_1) ++ crystal_cap += 1 * sign; ++ else ++ return; ++ rtw89_phy_cfo_set_crystal_cap(rtwdev, (u8)crystal_cap, false); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "X_cap{Curr,Default}={0x%x,0x%x}\n", ++ cfo->crystal_cap, cfo->def_x_cap); ++} ++ ++static s32 rtw89_phy_average_cfo_calc(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ s32 cfo_khz_all = 0; ++ s32 cfo_cnt_all = 0; ++ s32 cfo_all_avg = 0; ++ u8 i; ++ ++ if (rtwdev->total_sta_assoc != 1) ++ return 0; ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "one_entry_only\n"); ++ for (i = 0; i < CFO_TRACK_MAX_USER; i++) { ++ if (cfo->cfo_cnt[i] == 0) ++ continue; ++ cfo_khz_all += cfo->cfo_tail[i]; ++ cfo_cnt_all += cfo->cfo_cnt[i]; ++ cfo_all_avg = phy_div(cfo_khz_all, cfo_cnt_all); ++ cfo->pre_cfo_avg[i] = cfo->cfo_avg[i]; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "CFO track for macid = %d\n", i); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "Total cfo=%dK, pkt_cnt=%d, avg_cfo=%dK\n", ++ cfo_khz_all, cfo_cnt_all, cfo_all_avg); ++ return cfo_all_avg; ++} ++ ++static s32 rtw89_phy_multi_sta_cfo_calc(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ struct rtw89_traffic_stats *stats = &rtwdev->stats; ++ s32 target_cfo = 0; ++ s32 cfo_khz_all = 0; ++ s32 cfo_khz_all_tp_wgt = 0; ++ s32 cfo_avg = 0; ++ s32 max_cfo_lb = BIT(31); ++ s32 min_cfo_ub = GENMASK(30, 0); ++ u16 cfo_cnt_all = 0; ++ u8 active_entry_cnt = 0; ++ u8 sta_cnt = 0; ++ u32 tp_all = 0; ++ u8 i; ++ u8 cfo_tol = 0; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Multi entry cfo_trk\n"); ++ if (cfo->rtw89_multi_cfo_mode == RTW89_PKT_BASED_AVG_MODE) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Pkt based avg mode\n"); ++ for (i = 0; i < CFO_TRACK_MAX_USER; i++) { ++ if (cfo->cfo_cnt[i] == 0) ++ continue; ++ cfo_khz_all += cfo->cfo_tail[i]; ++ cfo_cnt_all += cfo->cfo_cnt[i]; ++ cfo_avg = phy_div(cfo_khz_all, (s32)cfo_cnt_all); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "Msta cfo=%d, pkt_cnt=%d, avg_cfo=%d\n", ++ cfo_khz_all, cfo_cnt_all, cfo_avg); ++ target_cfo = cfo_avg; ++ } ++ } else if (cfo->rtw89_multi_cfo_mode == RTW89_ENTRY_BASED_AVG_MODE) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Entry based avg mode\n"); ++ for (i = 0; i < CFO_TRACK_MAX_USER; i++) { ++ if (cfo->cfo_cnt[i] == 0) ++ continue; ++ cfo->cfo_avg[i] = phy_div(cfo->cfo_tail[i], ++ (s32)cfo->cfo_cnt[i]); ++ cfo_khz_all += cfo->cfo_avg[i]; ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "Macid=%d, cfo_avg=%d\n", i, ++ cfo->cfo_avg[i]); ++ } ++ sta_cnt = rtwdev->total_sta_assoc; ++ cfo_avg = phy_div(cfo_khz_all, (s32)sta_cnt); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "Msta cfo_acc=%d, ent_cnt=%d, avg_cfo=%d\n", ++ cfo_khz_all, sta_cnt, cfo_avg); ++ target_cfo = cfo_avg; ++ } else if (cfo->rtw89_multi_cfo_mode == RTW89_TP_BASED_AVG_MODE) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "TP based avg mode\n"); ++ cfo_tol = cfo->sta_cfo_tolerance; ++ for (i = 0; i < CFO_TRACK_MAX_USER; i++) { ++ sta_cnt++; ++ if (cfo->cfo_cnt[i] != 0) { ++ cfo->cfo_avg[i] = phy_div(cfo->cfo_tail[i], ++ (s32)cfo->cfo_cnt[i]); ++ active_entry_cnt++; ++ } else { ++ cfo->cfo_avg[i] = cfo->pre_cfo_avg[i]; ++ } ++ max_cfo_lb = max(cfo->cfo_avg[i] - cfo_tol, max_cfo_lb); ++ min_cfo_ub = min(cfo->cfo_avg[i] + cfo_tol, min_cfo_ub); ++ cfo_khz_all += cfo->cfo_avg[i]; ++ /* need tp for each entry */ ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "[%d] cfo_avg=%d, tp=tbd\n", ++ i, cfo->cfo_avg[i]); ++ if (sta_cnt >= rtwdev->total_sta_assoc) ++ break; ++ } ++ tp_all = stats->rx_throughput; /* need tp for each entry */ ++ cfo_avg = phy_div(cfo_khz_all_tp_wgt, (s32)tp_all); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Assoc sta cnt=%d\n", ++ sta_cnt); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Active sta cnt=%d\n", ++ active_entry_cnt); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "Msta cfo with tp_wgt=%d, avg_cfo=%d\n", ++ cfo_khz_all_tp_wgt, cfo_avg); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "cfo_lb=%d,cfo_ub=%d\n", ++ max_cfo_lb, min_cfo_ub); ++ if (max_cfo_lb <= min_cfo_ub) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "cfo win_size=%d\n", ++ min_cfo_ub - max_cfo_lb); ++ target_cfo = clamp(cfo_avg, max_cfo_lb, min_cfo_ub); ++ } else { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "No intersection of cfo torlence windows\n"); ++ target_cfo = phy_div(cfo_khz_all, (s32)sta_cnt); ++ } ++ for (i = 0; i < CFO_TRACK_MAX_USER; i++) ++ cfo->pre_cfo_avg[i] = cfo->cfo_avg[i]; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Target cfo=%d\n", target_cfo); ++ return target_cfo; ++} ++ ++static void rtw89_phy_cfo_statistics_reset(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ ++ memset(&cfo->cfo_tail, 0, sizeof(cfo->cfo_tail)); ++ memset(&cfo->cfo_cnt, 0, sizeof(cfo->cfo_cnt)); ++ cfo->packet_count = 0; ++ cfo->packet_count_pre = 0; ++ cfo->cfo_avg_pre = 0; ++} ++ ++static void rtw89_phy_cfo_dm(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ s32 new_cfo = 0; ++ bool x_cap_update = false; ++ u8 pre_x_cap = cfo->crystal_cap; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "CFO:total_sta_assoc=%d\n", ++ rtwdev->total_sta_assoc); ++ if (rtwdev->total_sta_assoc == 0) { ++ rtw89_phy_cfo_reset(rtwdev); ++ return; ++ } ++ if (cfo->packet_count == 0) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Pkt cnt = 0\n"); ++ return; ++ } ++ if (cfo->packet_count == cfo->packet_count_pre) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Pkt cnt doesn't change\n"); ++ return; ++ } ++ if (rtwdev->total_sta_assoc == 1) ++ new_cfo = rtw89_phy_average_cfo_calc(rtwdev); ++ else ++ new_cfo = rtw89_phy_multi_sta_cfo_calc(rtwdev); ++ if (new_cfo == 0) { ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "curr_cfo=0\n"); ++ return; ++ } ++ rtw89_phy_cfo_crystal_cap_adjust(rtwdev, new_cfo); ++ cfo->cfo_avg_pre = new_cfo; ++ x_cap_update = cfo->crystal_cap == pre_x_cap ? false : true; ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Xcap_up=%d\n", x_cap_update); ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, "Xcap: D:%x C:%x->%x, ofst=%d\n", ++ cfo->def_x_cap, pre_x_cap, cfo->crystal_cap, ++ cfo->x_cap_ofst); ++ if (x_cap_update) { ++ if (new_cfo > 0) ++ new_cfo -= CFO_SW_COMP_FINE_TUNE; ++ else ++ new_cfo += CFO_SW_COMP_FINE_TUNE; ++ } ++ rtw89_dcfo_comp(rtwdev, new_cfo); ++ rtw89_phy_cfo_statistics_reset(rtwdev); ++} ++ ++void rtw89_phy_cfo_track_work(struct work_struct *work) ++{ ++ struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, ++ cfo_track_work.work); ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ ++ mutex_lock(&rtwdev->mutex); ++ if (!cfo->cfo_trig_by_timer_en) ++ goto out; ++ rtw89_leave_ps_mode(rtwdev); ++ rtw89_phy_cfo_dm(rtwdev); ++ ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->cfo_track_work, ++ msecs_to_jiffies(cfo->cfo_timer_ms)); ++out: ++ mutex_unlock(&rtwdev->mutex); ++} ++ ++static void rtw89_phy_cfo_start_work(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ ++ ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->cfo_track_work, ++ msecs_to_jiffies(cfo->cfo_timer_ms)); ++} ++ ++void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ struct rtw89_traffic_stats *stats = &rtwdev->stats; ++ ++ switch (cfo->phy_cfo_status) { ++ case RTW89_PHY_DCFO_STATE_NORMAL: ++ if (stats->tx_throughput >= CFO_TP_UPPER) { ++ cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_ENHANCE; ++ cfo->cfo_trig_by_timer_en = true; ++ cfo->cfo_timer_ms = CFO_COMP_PERIOD; ++ rtw89_phy_cfo_start_work(rtwdev); ++ } ++ break; ++ case RTW89_PHY_DCFO_STATE_ENHANCE: ++ if (cfo->phy_cfo_trk_cnt >= CFO_PERIOD_CNT) { ++ cfo->phy_cfo_trk_cnt = 0; ++ cfo->cfo_trig_by_timer_en = false; ++ } ++ if (cfo->cfo_trig_by_timer_en == 1) ++ cfo->phy_cfo_trk_cnt++; ++ if (stats->tx_throughput <= CFO_TP_LOWER) { ++ cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_NORMAL; ++ cfo->phy_cfo_trk_cnt = 0; ++ cfo->cfo_trig_by_timer_en = false; ++ } ++ break; ++ default: ++ cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_NORMAL; ++ cfo->phy_cfo_trk_cnt = 0; ++ break; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_CFO, ++ "[CFO]WatchDog tp=%d,state=%d,timer_en=%d,trk_cnt=%d,thermal=%ld\n", ++ stats->tx_throughput, cfo->phy_cfo_status, ++ cfo->cfo_trig_by_timer_en, cfo->phy_cfo_trk_cnt, ++ ewma_thermal_read(&rtwdev->phystat.avg_thermal[0])); ++ if (cfo->cfo_trig_by_timer_en) ++ return; ++ rtw89_phy_cfo_dm(rtwdev); ++} ++ ++void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val, ++ struct rtw89_rx_phy_ppdu *phy_ppdu) ++{ ++ struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; ++ u8 macid = phy_ppdu->mac_id; ++ ++ cfo->cfo_tail[macid] += cfo_val; ++ cfo->cfo_cnt[macid]++; ++ cfo->packet_count++; ++} ++ ++static void rtw89_phy_stat_thermal_update(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_phy_stat *phystat = &rtwdev->phystat; ++ int i; ++ u8 th; ++ ++ for (i = 0; i < rtwdev->chip->rf_path_num; i++) { ++ th = rtw89_chip_get_thermal(rtwdev, i); ++ if (th) ++ ewma_thermal_add(&phystat->avg_thermal[i], th); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, ++ "path(%d) thermal cur=%u avg=%ld", i, th, ++ ewma_thermal_read(&phystat->avg_thermal[i])); ++ } ++} ++ ++struct rtw89_phy_iter_rssi_data { ++ struct rtw89_dev *rtwdev; ++ struct rtw89_phy_ch_info *ch_info; ++ bool rssi_changed; ++}; ++ ++static void rtw89_phy_stat_rssi_update_iter(void *data, ++ struct ieee80211_sta *sta) ++{ ++ struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_phy_iter_rssi_data *rssi_data = ++ (struct rtw89_phy_iter_rssi_data *)data; ++ struct rtw89_phy_ch_info *ch_info = rssi_data->ch_info; ++ unsigned long rssi_curr; ++ ++ rssi_curr = ewma_rssi_read(&rtwsta->avg_rssi); ++ ++ if (rssi_curr < ch_info->rssi_min) { ++ ch_info->rssi_min = rssi_curr; ++ ch_info->rssi_min_macid = rtwsta->mac_id; ++ } ++ ++ if (rtwsta->prev_rssi == 0) { ++ rtwsta->prev_rssi = rssi_curr; ++ } else if (abs((int)rtwsta->prev_rssi - (int)rssi_curr) > (3 << RSSI_FACTOR)) { ++ rtwsta->prev_rssi = rssi_curr; ++ rssi_data->rssi_changed = true; ++ } ++} ++ ++static void rtw89_phy_stat_rssi_update(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_phy_iter_rssi_data rssi_data = {0}; ++ ++ rssi_data.rtwdev = rtwdev; ++ rssi_data.ch_info = &rtwdev->ch_info; ++ rssi_data.ch_info->rssi_min = U8_MAX; ++ ieee80211_iterate_stations_atomic(rtwdev->hw, ++ rtw89_phy_stat_rssi_update_iter, ++ &rssi_data); ++ if (rssi_data.rssi_changed) ++ rtw89_btc_ntfy_wl_sta(rtwdev); ++} ++ ++static void rtw89_phy_stat_init(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_phy_stat *phystat = &rtwdev->phystat; ++ int i; ++ ++ for (i = 0; i < rtwdev->chip->rf_path_num; i++) ++ ewma_thermal_init(&phystat->avg_thermal[i]); ++ ++ rtw89_phy_stat_thermal_update(rtwdev); ++ ++ memset(&phystat->cur_pkt_stat, 0, sizeof(phystat->cur_pkt_stat)); ++ memset(&phystat->last_pkt_stat, 0, sizeof(phystat->last_pkt_stat)); ++} ++ ++void rtw89_phy_stat_track(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_phy_stat *phystat = &rtwdev->phystat; ++ ++ rtw89_phy_stat_thermal_update(rtwdev); ++ rtw89_phy_stat_rssi_update(rtwdev); ++ ++ phystat->last_pkt_stat = phystat->cur_pkt_stat; ++ memset(&phystat->cur_pkt_stat, 0, sizeof(phystat->cur_pkt_stat)); ++} ++ ++static u16 rtw89_phy_ccx_us_to_idx(struct rtw89_dev *rtwdev, u32 time_us) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ ++ return time_us >> (ilog2(CCX_US_BASE_RATIO) + env->ccx_unit_idx); ++} ++ ++static u32 rtw89_phy_ccx_idx_to_us(struct rtw89_dev *rtwdev, u16 idx) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ ++ return idx << (ilog2(CCX_US_BASE_RATIO) + env->ccx_unit_idx); ++} ++ ++static void rtw89_phy_ccx_top_setting_init(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ ++ env->ccx_manual_ctrl = false; ++ env->ccx_ongoing = false; ++ env->ccx_rac_lv = RTW89_RAC_RELEASE; ++ env->ccx_rpt_stamp = 0; ++ env->ccx_period = 0; ++ env->ccx_unit_idx = RTW89_CCX_32_US; ++ env->ccx_trigger_time = 0; ++ env->ccx_edcca_opt_bw_idx = RTW89_CCX_EDCCA_BW20_0; ++ ++ rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_CCX_EN_MSK, 1); ++ rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_CCX_TRIG_OPT_MSK, 1); ++ rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_MEASUREMENT_TRIG_MSK, 1); ++ rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_CCX_EDCCA_OPT_MSK, ++ RTW89_CCX_EDCCA_BW20_0); ++} ++ ++static u16 rtw89_phy_ccx_get_report(struct rtw89_dev *rtwdev, u16 report, ++ u16 score) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ u32 numer = 0; ++ u16 ret = 0; ++ ++ numer = report * score + (env->ccx_period >> 1); ++ if (env->ccx_period) ++ ret = numer / env->ccx_period; ++ ++ return ret >= score ? score - 1 : ret; ++} ++ ++static void rtw89_phy_ccx_ms_to_period_unit(struct rtw89_dev *rtwdev, ++ u16 time_ms, u32 *period, ++ u32 *unit_idx) ++{ ++ u32 idx; ++ u8 quotient; ++ ++ if (time_ms >= CCX_MAX_PERIOD) ++ time_ms = CCX_MAX_PERIOD; ++ ++ quotient = CCX_MAX_PERIOD_UNIT * time_ms / CCX_MAX_PERIOD; ++ ++ if (quotient < 4) ++ idx = RTW89_CCX_4_US; ++ else if (quotient < 8) ++ idx = RTW89_CCX_8_US; ++ else if (quotient < 16) ++ idx = RTW89_CCX_16_US; ++ else ++ idx = RTW89_CCX_32_US; ++ ++ *unit_idx = idx; ++ *period = (time_ms * MS_TO_4US_RATIO) >> idx; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "[Trigger Time] period:%d, unit_idx:%d\n", ++ *period, *unit_idx); ++} ++ ++static void rtw89_phy_ccx_racing_release(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "lv:(%d)->(0)\n", env->ccx_rac_lv); ++ ++ env->ccx_ongoing = false; ++ env->ccx_rac_lv = RTW89_RAC_RELEASE; ++ env->ifs_clm_app = RTW89_IFS_CLM_BACKGROUND; ++} ++ ++static bool rtw89_phy_ifs_clm_th_update_check(struct rtw89_dev *rtwdev, ++ struct rtw89_ccx_para_info *para) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ bool is_update = env->ifs_clm_app != para->ifs_clm_app; ++ u8 i = 0; ++ u16 *ifs_th_l = env->ifs_clm_th_l; ++ u16 *ifs_th_h = env->ifs_clm_th_h; ++ u32 ifs_th0_us = 0, ifs_th_times = 0; ++ u32 ifs_th_h_us[RTW89_IFS_CLM_NUM] = {0}; ++ ++ if (!is_update) ++ goto ifs_update_finished; ++ ++ switch (para->ifs_clm_app) { ++ case RTW89_IFS_CLM_INIT: ++ case RTW89_IFS_CLM_BACKGROUND: ++ case RTW89_IFS_CLM_ACS: ++ case RTW89_IFS_CLM_DBG: ++ case RTW89_IFS_CLM_DIG: ++ case RTW89_IFS_CLM_TDMA_DIG: ++ ifs_th0_us = IFS_CLM_TH0_UPPER; ++ ifs_th_times = IFS_CLM_TH_MUL; ++ break; ++ case RTW89_IFS_CLM_DBG_MANUAL: ++ ifs_th0_us = para->ifs_clm_manual_th0; ++ ifs_th_times = para->ifs_clm_manual_th_times; ++ break; ++ default: ++ break; ++ } ++ ++ /* Set sampling threshold for 4 different regions, unit in idx_cnt. ++ * low[i] = high[i-1] + 1 ++ * high[i] = high[i-1] * ifs_th_times ++ */ ++ ifs_th_l[IFS_CLM_TH_START_IDX] = 0; ++ ifs_th_h_us[IFS_CLM_TH_START_IDX] = ifs_th0_us; ++ ifs_th_h[IFS_CLM_TH_START_IDX] = rtw89_phy_ccx_us_to_idx(rtwdev, ++ ifs_th0_us); ++ for (i = 1; i < RTW89_IFS_CLM_NUM; i++) { ++ ifs_th_l[i] = ifs_th_h[i - 1] + 1; ++ ifs_th_h_us[i] = ifs_th_h_us[i - 1] * ifs_th_times; ++ ifs_th_h[i] = rtw89_phy_ccx_us_to_idx(rtwdev, ifs_th_h_us[i]); ++ } ++ ++ifs_update_finished: ++ if (!is_update) ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "No need to update IFS_TH\n"); ++ ++ return is_update; ++} ++ ++static void rtw89_phy_ifs_clm_set_th_reg(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ u8 i = 0; ++ ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T1, B_IFS_T1_TH_LOW_MSK, ++ env->ifs_clm_th_l[0]); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T2, B_IFS_T2_TH_LOW_MSK, ++ env->ifs_clm_th_l[1]); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T3, B_IFS_T3_TH_LOW_MSK, ++ env->ifs_clm_th_l[2]); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T4, B_IFS_T4_TH_LOW_MSK, ++ env->ifs_clm_th_l[3]); ++ ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T1, B_IFS_T1_TH_HIGH_MSK, ++ env->ifs_clm_th_h[0]); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T2, B_IFS_T2_TH_HIGH_MSK, ++ env->ifs_clm_th_h[1]); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T3, B_IFS_T3_TH_HIGH_MSK, ++ env->ifs_clm_th_h[2]); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T4, B_IFS_T4_TH_HIGH_MSK, ++ env->ifs_clm_th_h[3]); ++ ++ for (i = 0; i < RTW89_IFS_CLM_NUM; i++) ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "Update IFS_T%d_th{low, high} : {%d, %d}\n", ++ i + 1, env->ifs_clm_th_l[i], env->ifs_clm_th_h[i]); ++} ++ ++static void rtw89_phy_ifs_clm_setting_init(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ struct rtw89_ccx_para_info para = {0}; ++ ++ env->ifs_clm_app = RTW89_IFS_CLM_BACKGROUND; ++ env->ifs_clm_mntr_time = 0; ++ ++ para.ifs_clm_app = RTW89_IFS_CLM_INIT; ++ if (rtw89_phy_ifs_clm_th_update_check(rtwdev, ¶)) ++ rtw89_phy_ifs_clm_set_th_reg(rtwdev); ++ ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER, B_IFS_COLLECT_EN, ++ true); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T1, B_IFS_T1_EN_MSK, true); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T2, B_IFS_T2_EN_MSK, true); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T3, B_IFS_T3_EN_MSK, true); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_T4, B_IFS_T4_EN_MSK, true); ++} ++ ++static int rtw89_phy_ccx_racing_ctrl(struct rtw89_dev *rtwdev, ++ enum rtw89_env_racing_lv level) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ int ret = 0; ++ ++ if (level >= RTW89_RAC_MAX_NUM) { ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "[WARNING] Wrong LV=%d\n", level); ++ return -EINVAL; ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "ccx_ongoing=%d, level:(%d)->(%d)\n", env->ccx_ongoing, ++ env->ccx_rac_lv, level); ++ ++ if (env->ccx_ongoing) { ++ if (level <= env->ccx_rac_lv) ++ ret = -EINVAL; ++ else ++ env->ccx_ongoing = false; ++ } ++ ++ if (ret == 0) ++ env->ccx_rac_lv = level; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "ccx racing success=%d\n", ++ !ret); ++ ++ return ret; ++} ++ ++static void rtw89_phy_ccx_trigger(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER, B_IFS_COUNTER_CLR_MSK, 0); ++ rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_MEASUREMENT_TRIG_MSK, 0); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER, B_IFS_COUNTER_CLR_MSK, 1); ++ rtw89_phy_set_phy_regs(rtwdev, R_CCX, B_MEASUREMENT_TRIG_MSK, 1); ++ ++ env->ccx_rpt_stamp++; ++ env->ccx_ongoing = true; ++} ++ ++static void rtw89_phy_ifs_clm_get_utility(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ u8 i = 0; ++ u32 res = 0; ++ ++ env->ifs_clm_tx_ratio = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_tx, PERCENT); ++ env->ifs_clm_edcca_excl_cca_ratio = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_edcca_excl_cca, ++ PERCENT); ++ env->ifs_clm_cck_fa_ratio = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_cckfa, PERCENT); ++ env->ifs_clm_ofdm_fa_ratio = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_ofdmfa, PERCENT); ++ env->ifs_clm_cck_cca_excl_fa_ratio = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_cckcca_excl_fa, ++ PERCENT); ++ env->ifs_clm_ofdm_cca_excl_fa_ratio = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_ofdmcca_excl_fa, ++ PERCENT); ++ env->ifs_clm_cck_fa_permil = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_cckfa, PERMIL); ++ env->ifs_clm_ofdm_fa_permil = ++ rtw89_phy_ccx_get_report(rtwdev, env->ifs_clm_ofdmfa, PERMIL); ++ ++ for (i = 0; i < RTW89_IFS_CLM_NUM; i++) { ++ if (env->ifs_clm_his[i] > ENV_MNTR_IFSCLM_HIS_MAX) { ++ env->ifs_clm_ifs_avg[i] = ENV_MNTR_FAIL_DWORD; ++ } else { ++ env->ifs_clm_ifs_avg[i] = ++ rtw89_phy_ccx_idx_to_us(rtwdev, ++ env->ifs_clm_avg[i]); ++ } ++ ++ res = rtw89_phy_ccx_idx_to_us(rtwdev, env->ifs_clm_cca[i]); ++ res += env->ifs_clm_his[i] >> 1; ++ if (env->ifs_clm_his[i]) ++ res /= env->ifs_clm_his[i]; ++ else ++ res = 0; ++ env->ifs_clm_cca_avg[i] = res; ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "IFS-CLM ratio {Tx, EDCCA_exclu_cca} = {%d, %d}\n", ++ env->ifs_clm_tx_ratio, env->ifs_clm_edcca_excl_cca_ratio); ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "IFS-CLM FA ratio {CCK, OFDM} = {%d, %d}\n", ++ env->ifs_clm_cck_fa_ratio, env->ifs_clm_ofdm_fa_ratio); ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "IFS-CLM FA permil {CCK, OFDM} = {%d, %d}\n", ++ env->ifs_clm_cck_fa_permil, env->ifs_clm_ofdm_fa_permil); ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "IFS-CLM CCA_exclu_FA ratio {CCK, OFDM} = {%d, %d}\n", ++ env->ifs_clm_cck_cca_excl_fa_ratio, ++ env->ifs_clm_ofdm_cca_excl_fa_ratio); ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "Time:[his, ifs_avg(us), cca_avg(us)]\n"); ++ for (i = 0; i < RTW89_IFS_CLM_NUM; i++) ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "T%d:[%d, %d, %d]\n", ++ i + 1, env->ifs_clm_his[i], env->ifs_clm_ifs_avg[i], ++ env->ifs_clm_cca_avg[i]); ++} ++ ++static bool rtw89_phy_ifs_clm_get_result(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ u8 i = 0; ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_IFSCNT, B_IFSCNT_DONE_MSK) == 0) { ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "Get IFS_CLM report Fail\n"); ++ return false; ++ } ++ ++ env->ifs_clm_tx = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_TX_CNT, ++ B_IFS_CLM_TX_CNT_MSK); ++ env->ifs_clm_edcca_excl_cca = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_TX_CNT, ++ B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK); ++ env->ifs_clm_cckcca_excl_fa = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_CCA, ++ B_IFS_CLM_CCKCCA_EXCLUDE_FA_MSK); ++ env->ifs_clm_ofdmcca_excl_fa = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_CCA, ++ B_IFS_CLM_OFDMCCA_EXCLUDE_FA_MSK); ++ env->ifs_clm_cckfa = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_FA, ++ B_IFS_CLM_CCK_FA_MSK); ++ env->ifs_clm_ofdmfa = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CLM_FA, ++ B_IFS_CLM_OFDM_FA_MSK); ++ ++ env->ifs_clm_his[0] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_HIS, B_IFS_T1_HIS_MSK); ++ env->ifs_clm_his[1] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_HIS, B_IFS_T2_HIS_MSK); ++ env->ifs_clm_his[2] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_HIS, B_IFS_T3_HIS_MSK); ++ env->ifs_clm_his[3] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_HIS, B_IFS_T4_HIS_MSK); ++ ++ env->ifs_clm_avg[0] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_AVG_L, B_IFS_T1_AVG_MSK); ++ env->ifs_clm_avg[1] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_AVG_L, B_IFS_T2_AVG_MSK); ++ env->ifs_clm_avg[2] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_AVG_H, B_IFS_T3_AVG_MSK); ++ env->ifs_clm_avg[3] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_AVG_H, B_IFS_T4_AVG_MSK); ++ ++ env->ifs_clm_cca[0] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CCA_L, B_IFS_T1_CCA_MSK); ++ env->ifs_clm_cca[1] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CCA_L, B_IFS_T2_CCA_MSK); ++ env->ifs_clm_cca[2] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CCA_H, B_IFS_T3_CCA_MSK); ++ env->ifs_clm_cca[3] = ++ rtw89_phy_read32_mask(rtwdev, R_IFS_CCA_H, B_IFS_T4_CCA_MSK); ++ ++ env->ifs_clm_total_ifs = ++ rtw89_phy_read32_mask(rtwdev, R_IFSCNT, B_IFSCNT_TOTAL_CNT_MSK); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "IFS-CLM total_ifs = %d\n", ++ env->ifs_clm_total_ifs); ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "{Tx, EDCCA_exclu_cca} = {%d, %d}\n", ++ env->ifs_clm_tx, env->ifs_clm_edcca_excl_cca); ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "IFS-CLM FA{CCK, OFDM} = {%d, %d}\n", ++ env->ifs_clm_cckfa, env->ifs_clm_ofdmfa); ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "IFS-CLM CCA_exclu_FA{CCK, OFDM} = {%d, %d}\n", ++ env->ifs_clm_cckcca_excl_fa, env->ifs_clm_ofdmcca_excl_fa); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "Time:[his, avg, cca]\n"); ++ for (i = 0; i < RTW89_IFS_CLM_NUM; i++) ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "T%d:[%d, %d, %d]\n", i + 1, env->ifs_clm_his[i], ++ env->ifs_clm_avg[i], env->ifs_clm_cca[i]); ++ ++ rtw89_phy_ifs_clm_get_utility(rtwdev); ++ ++ return true; ++} ++ ++static int rtw89_phy_ifs_clm_set(struct rtw89_dev *rtwdev, ++ struct rtw89_ccx_para_info *para) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ u32 period = 0; ++ u32 unit_idx = 0; ++ ++ if (para->mntr_time == 0) { ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "[WARN] MNTR_TIME is 0\n"); ++ return -EINVAL; ++ } ++ ++ if (rtw89_phy_ccx_racing_ctrl(rtwdev, para->rac_lv)) ++ return -EINVAL; ++ ++ if (para->mntr_time != env->ifs_clm_mntr_time) { ++ rtw89_phy_ccx_ms_to_period_unit(rtwdev, para->mntr_time, ++ &period, &unit_idx); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER, ++ B_IFS_CLM_PERIOD_MSK, period); ++ rtw89_phy_set_phy_regs(rtwdev, R_IFS_COUNTER, ++ B_IFS_CLM_COUNTER_UNIT_MSK, unit_idx); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "Update IFS-CLM time ((%d)) -> ((%d))\n", ++ env->ifs_clm_mntr_time, para->mntr_time); ++ ++ env->ifs_clm_mntr_time = para->mntr_time; ++ env->ccx_period = (u16)period; ++ env->ccx_unit_idx = (u8)unit_idx; ++ } ++ ++ if (rtw89_phy_ifs_clm_th_update_check(rtwdev, para)) { ++ env->ifs_clm_app = para->ifs_clm_app; ++ rtw89_phy_ifs_clm_set_th_reg(rtwdev); ++ } ++ ++ return 0; ++} ++ ++void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ struct rtw89_ccx_para_info para = {0}; ++ u8 chk_result = RTW89_PHY_ENV_MON_CCX_FAIL; ++ ++ env->ccx_watchdog_result = RTW89_PHY_ENV_MON_CCX_FAIL; ++ if (env->ccx_manual_ctrl) { ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "CCX in manual ctrl\n"); ++ return; ++ } ++ ++ /* only ifs_clm for now */ ++ if (rtw89_phy_ifs_clm_get_result(rtwdev)) ++ env->ccx_watchdog_result |= RTW89_PHY_ENV_MON_IFS_CLM; ++ ++ rtw89_phy_ccx_racing_release(rtwdev); ++ para.mntr_time = 1900; ++ para.rac_lv = RTW89_RAC_LV_1; ++ para.ifs_clm_app = RTW89_IFS_CLM_BACKGROUND; ++ ++ if (rtw89_phy_ifs_clm_set(rtwdev, ¶) == 0) ++ chk_result |= RTW89_PHY_ENV_MON_IFS_CLM; ++ if (chk_result) ++ rtw89_phy_ccx_trigger(rtwdev); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, ++ "get_result=0x%x, chk_result:0x%x\n", ++ env->ccx_watchdog_result, chk_result); ++} ++ ++static void rtw89_phy_dig_read_gain_table(struct rtw89_dev *rtwdev, int type) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ const struct rtw89_phy_dig_gain_cfg *cfg; ++ const char *msg; ++ u8 i; ++ s8 gain_base; ++ s8 *gain_arr; ++ u32 tmp; ++ ++ switch (type) { ++ case RTW89_DIG_GAIN_LNA_G: ++ gain_arr = dig->lna_gain_g; ++ gain_base = LNA0_GAIN; ++ cfg = chip->dig_table->cfg_lna_g; ++ msg = "lna_gain_g"; ++ break; ++ case RTW89_DIG_GAIN_TIA_G: ++ gain_arr = dig->tia_gain_g; ++ gain_base = TIA0_GAIN_G; ++ cfg = chip->dig_table->cfg_tia_g; ++ msg = "tia_gain_g"; ++ break; ++ case RTW89_DIG_GAIN_LNA_A: ++ gain_arr = dig->lna_gain_a; ++ gain_base = LNA0_GAIN; ++ cfg = chip->dig_table->cfg_lna_a; ++ msg = "lna_gain_a"; ++ break; ++ case RTW89_DIG_GAIN_TIA_A: ++ gain_arr = dig->tia_gain_a; ++ gain_base = TIA0_GAIN_A; ++ cfg = chip->dig_table->cfg_tia_a; ++ msg = "tia_gain_a"; ++ break; ++ default: ++ return; ++ } ++ ++ for (i = 0; i < cfg->size; i++) { ++ tmp = rtw89_phy_read32_mask(rtwdev, cfg->table[i].addr, ++ cfg->table[i].mask); ++ tmp >>= DIG_GAIN_SHIFT; ++ gain_arr[i] = sign_extend32(tmp, U4_MAX_BIT) + gain_base; ++ gain_base += DIG_GAIN; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "%s[%d]=%d\n", ++ msg, i, gain_arr[i]); ++ } ++} ++ ++static void rtw89_phy_dig_update_gain_para(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ u32 tmp; ++ u8 i; ++ ++ tmp = rtw89_phy_read32_mask(rtwdev, R_PATH0_IB_PKPW, ++ B_PATH0_IB_PKPW_MSK); ++ dig->ib_pkpwr = sign_extend32(tmp >> DIG_GAIN_SHIFT, U8_MAX_BIT); ++ dig->ib_pbk = rtw89_phy_read32_mask(rtwdev, R_PATH0_IB_PBK, ++ B_PATH0_IB_PBK_MSK); ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "ib_pkpwr=%d, ib_pbk=%d\n", ++ dig->ib_pkpwr, dig->ib_pbk); ++ ++ for (i = RTW89_DIG_GAIN_LNA_G; i < RTW89_DIG_GAIN_MAX; i++) ++ rtw89_phy_dig_read_gain_table(rtwdev, i); ++} ++ ++static const u8 rssi_nolink = 22; ++static const u8 igi_rssi_th[IGI_RSSI_TH_NUM] = {68, 84, 90, 98, 104}; ++static const u16 fa_th_2g[FA_TH_NUM] = {22, 44, 66, 88}; ++static const u16 fa_th_5g[FA_TH_NUM] = {4, 8, 12, 16}; ++static const u16 fa_th_nolink[FA_TH_NUM] = {196, 352, 440, 528}; ++ ++static void rtw89_phy_dig_update_rssi_info(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_phy_ch_info *ch_info = &rtwdev->ch_info; ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ bool is_linked = rtwdev->total_sta_assoc > 0; ++ ++ if (is_linked) { ++ dig->igi_rssi = ch_info->rssi_min >> 1; ++ } else { ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "RSSI update : NO Link\n"); ++ dig->igi_rssi = rssi_nolink; ++ } ++} ++ ++static void rtw89_phy_dig_update_para(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ bool is_linked = rtwdev->total_sta_assoc > 0; ++ const u16 *fa_th_src = NULL; ++ ++ switch (rtwdev->hal.current_band_type) { ++ case RTW89_BAND_2G: ++ dig->lna_gain = dig->lna_gain_g; ++ dig->tia_gain = dig->tia_gain_g; ++ fa_th_src = is_linked ? fa_th_2g : fa_th_nolink; ++ dig->force_gaincode_idx_en = false; ++ dig->dyn_pd_th_en = true; ++ break; ++ case RTW89_BAND_5G: ++ default: ++ dig->lna_gain = dig->lna_gain_a; ++ dig->tia_gain = dig->tia_gain_a; ++ fa_th_src = is_linked ? fa_th_5g : fa_th_nolink; ++ dig->force_gaincode_idx_en = true; ++ dig->dyn_pd_th_en = true; ++ break; ++ } ++ memcpy(dig->fa_th, fa_th_src, sizeof(dig->fa_th)); ++ memcpy(dig->igi_rssi_th, igi_rssi_th, sizeof(dig->igi_rssi_th)); ++} ++ ++static const u8 pd_low_th_offset = 20, dynamic_igi_min = 0x20; ++static const u8 igi_max_performance_mode = 0x5a; ++static const u8 dynamic_pd_threshold_max; ++ ++static void rtw89_phy_dig_para_reset(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ ++ dig->cur_gaincode.lna_idx = LNA_IDX_MAX; ++ dig->cur_gaincode.tia_idx = TIA_IDX_MAX; ++ dig->cur_gaincode.rxb_idx = RXB_IDX_MAX; ++ dig->force_gaincode.lna_idx = LNA_IDX_MAX; ++ dig->force_gaincode.tia_idx = TIA_IDX_MAX; ++ dig->force_gaincode.rxb_idx = RXB_IDX_MAX; ++ ++ dig->dyn_igi_max = igi_max_performance_mode; ++ dig->dyn_igi_min = dynamic_igi_min; ++ dig->dyn_pd_th_max = dynamic_pd_threshold_max; ++ dig->pd_low_th_ofst = pd_low_th_offset; ++ dig->is_linked_pre = false; ++} ++ ++static void rtw89_phy_dig_init(struct rtw89_dev *rtwdev) ++{ ++ rtw89_phy_dig_update_gain_para(rtwdev); ++ rtw89_phy_dig_reset(rtwdev); ++} ++ ++static u8 rtw89_phy_dig_lna_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ u8 lna_idx; ++ ++ if (rssi < dig->igi_rssi_th[0]) ++ lna_idx = RTW89_DIG_GAIN_LNA_IDX6; ++ else if (rssi < dig->igi_rssi_th[1]) ++ lna_idx = RTW89_DIG_GAIN_LNA_IDX5; ++ else if (rssi < dig->igi_rssi_th[2]) ++ lna_idx = RTW89_DIG_GAIN_LNA_IDX4; ++ else if (rssi < dig->igi_rssi_th[3]) ++ lna_idx = RTW89_DIG_GAIN_LNA_IDX3; ++ else if (rssi < dig->igi_rssi_th[4]) ++ lna_idx = RTW89_DIG_GAIN_LNA_IDX2; ++ else ++ lna_idx = RTW89_DIG_GAIN_LNA_IDX1; ++ ++ return lna_idx; ++} ++ ++static u8 rtw89_phy_dig_tia_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ u8 tia_idx; ++ ++ if (rssi < dig->igi_rssi_th[0]) ++ tia_idx = RTW89_DIG_GAIN_TIA_IDX1; ++ else ++ tia_idx = RTW89_DIG_GAIN_TIA_IDX0; ++ ++ return tia_idx; ++} ++ ++#define IB_PBK_BASE 110 ++#define WB_RSSI_BASE 10 ++static u8 rtw89_phy_dig_rxb_idx_by_rssi(struct rtw89_dev *rtwdev, u8 rssi, ++ struct rtw89_agc_gaincode_set *set) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ s8 lna_gain = dig->lna_gain[set->lna_idx]; ++ s8 tia_gain = dig->tia_gain[set->tia_idx]; ++ s32 wb_rssi = rssi + lna_gain + tia_gain; ++ s32 rxb_idx_tmp = IB_PBK_BASE + WB_RSSI_BASE; ++ u8 rxb_idx; ++ ++ rxb_idx_tmp += dig->ib_pkpwr - dig->ib_pbk - wb_rssi; ++ rxb_idx = clamp_t(s32, rxb_idx_tmp, RXB_IDX_MIN, RXB_IDX_MAX); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "wb_rssi=%03d, rxb_idx_tmp=%03d\n", ++ wb_rssi, rxb_idx_tmp); ++ ++ return rxb_idx; ++} ++ ++static void rtw89_phy_dig_gaincode_by_rssi(struct rtw89_dev *rtwdev, u8 rssi, ++ struct rtw89_agc_gaincode_set *set) ++{ ++ set->lna_idx = rtw89_phy_dig_lna_idx_by_rssi(rtwdev, rssi); ++ set->tia_idx = rtw89_phy_dig_tia_idx_by_rssi(rtwdev, rssi); ++ set->rxb_idx = rtw89_phy_dig_rxb_idx_by_rssi(rtwdev, rssi, set); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, ++ "final_rssi=%03d, (lna,tia,rab)=(%d,%d,%02d)\n", ++ rssi, set->lna_idx, set->tia_idx, set->rxb_idx); ++} ++ ++#define IGI_OFFSET_MAX 25 ++#define IGI_OFFSET_MUL 2 ++static void rtw89_phy_dig_igi_offset_by_env(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ struct rtw89_env_monitor_info *env = &rtwdev->env_monitor; ++ enum rtw89_dig_noisy_level noisy_lv; ++ u8 igi_offset = dig->fa_rssi_ofst; ++ u16 fa_ratio = 0; ++ ++ fa_ratio = env->ifs_clm_cck_fa_permil + env->ifs_clm_ofdm_fa_permil; ++ ++ if (fa_ratio < dig->fa_th[0]) ++ noisy_lv = RTW89_DIG_NOISY_LEVEL0; ++ else if (fa_ratio < dig->fa_th[1]) ++ noisy_lv = RTW89_DIG_NOISY_LEVEL1; ++ else if (fa_ratio < dig->fa_th[2]) ++ noisy_lv = RTW89_DIG_NOISY_LEVEL2; ++ else if (fa_ratio < dig->fa_th[3]) ++ noisy_lv = RTW89_DIG_NOISY_LEVEL3; ++ else ++ noisy_lv = RTW89_DIG_NOISY_LEVEL_MAX; ++ ++ if (noisy_lv == RTW89_DIG_NOISY_LEVEL0 && igi_offset < 2) ++ igi_offset = 0; ++ else ++ igi_offset += noisy_lv * IGI_OFFSET_MUL; ++ ++ igi_offset = min_t(u8, igi_offset, IGI_OFFSET_MAX); ++ dig->fa_rssi_ofst = igi_offset; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, ++ "fa_th: [+6 (%d) +4 (%d) +2 (%d) 0 (%d) -2 ]\n", ++ dig->fa_th[3], dig->fa_th[2], dig->fa_th[1], dig->fa_th[0]); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, ++ "fa(CCK,OFDM,ALL)=(%d,%d,%d)%%, noisy_lv=%d, ofst=%d\n", ++ env->ifs_clm_cck_fa_permil, env->ifs_clm_ofdm_fa_permil, ++ env->ifs_clm_cck_fa_permil + env->ifs_clm_ofdm_fa_permil, ++ noisy_lv, igi_offset); ++} ++ ++static void rtw89_phy_dig_set_lna_idx(struct rtw89_dev *rtwdev, u8 lna_idx) ++{ ++ rtw89_phy_write32_mask(rtwdev, R_PATH0_LNA_INIT, ++ B_PATH0_LNA_INIT_IDX_MSK, lna_idx); ++ rtw89_phy_write32_mask(rtwdev, R_PATH1_LNA_INIT, ++ B_PATH1_LNA_INIT_IDX_MSK, lna_idx); ++} ++ ++static void rtw89_phy_dig_set_tia_idx(struct rtw89_dev *rtwdev, u8 tia_idx) ++{ ++ rtw89_phy_write32_mask(rtwdev, R_PATH0_TIA_INIT, ++ B_PATH0_TIA_INIT_IDX_MSK, tia_idx); ++ rtw89_phy_write32_mask(rtwdev, R_PATH1_TIA_INIT, ++ B_PATH1_TIA_INIT_IDX_MSK, tia_idx); ++} ++ ++static void rtw89_phy_dig_set_rxb_idx(struct rtw89_dev *rtwdev, u8 rxb_idx) ++{ ++ rtw89_phy_write32_mask(rtwdev, R_PATH0_RXB_INIT, ++ B_PATH0_RXB_INIT_IDX_MSK, rxb_idx); ++ rtw89_phy_write32_mask(rtwdev, R_PATH1_RXB_INIT, ++ B_PATH1_RXB_INIT_IDX_MSK, rxb_idx); ++} ++ ++static void rtw89_phy_dig_set_igi_cr(struct rtw89_dev *rtwdev, ++ const struct rtw89_agc_gaincode_set set) ++{ ++ rtw89_phy_dig_set_lna_idx(rtwdev, set.lna_idx); ++ rtw89_phy_dig_set_tia_idx(rtwdev, set.tia_idx); ++ rtw89_phy_dig_set_rxb_idx(rtwdev, set.rxb_idx); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "Set (lna,tia,rxb)=((%d,%d,%02d))\n", ++ set.lna_idx, set.tia_idx, set.rxb_idx); ++} ++ ++static const struct rtw89_reg_def sdagc_config[4] = { ++ {R_PATH0_P20_FOLLOW_BY_PAGCUGC, B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, ++ {R_PATH0_S20_FOLLOW_BY_PAGCUGC, B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, ++ {R_PATH1_P20_FOLLOW_BY_PAGCUGC, B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK}, ++ {R_PATH1_S20_FOLLOW_BY_PAGCUGC, B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK}, ++}; ++ ++static void rtw89_phy_dig_sdagc_follow_pagc_config(struct rtw89_dev *rtwdev, ++ bool enable) ++{ ++ u8 i = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(sdagc_config); i++) ++ rtw89_phy_write32_mask(rtwdev, sdagc_config[i].addr, ++ sdagc_config[i].mask, enable); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "sdagc_follow_pagc=%d\n", enable); ++} ++ ++static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, u8 rssi, ++ bool enable) ++{ ++ enum rtw89_bandwidth cbw = rtwdev->hal.current_band_width; ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ u8 final_rssi = 0, under_region = dig->pd_low_th_ofst; ++ u32 val = 0; ++ ++ under_region += PD_TH_SB_FLTR_CMP_VAL; ++ ++ switch (cbw) { ++ case RTW89_CHANNEL_WIDTH_40: ++ under_region += PD_TH_BW40_CMP_VAL; ++ break; ++ case RTW89_CHANNEL_WIDTH_80: ++ under_region += PD_TH_BW80_CMP_VAL; ++ break; ++ case RTW89_CHANNEL_WIDTH_20: ++ fallthrough; ++ default: ++ under_region += PD_TH_BW20_CMP_VAL; ++ break; ++ } ++ ++ dig->dyn_pd_th_max = dig->igi_rssi; ++ ++ final_rssi = min_t(u8, rssi, dig->igi_rssi); ++ final_rssi = clamp_t(u8, final_rssi, PD_TH_MIN_RSSI + under_region, ++ PD_TH_MAX_RSSI + under_region); ++ ++ if (enable) { ++ val = (final_rssi - under_region - PD_TH_MIN_RSSI) >> 1; ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, ++ "dyn_max=%d, final_rssi=%d, total=%d, PD_low=%d\n", ++ dig->igi_rssi, final_rssi, under_region, val); ++ } else { ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, ++ "Dynamic PD th dsiabled, Set PD_low_bd=0\n"); ++ } ++ ++ rtw89_phy_write32_mask(rtwdev, R_SEG0R_PD, B_SEG0R_PD_LOWER_BOUND_MSK, ++ val); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0R_PD, ++ B_SEG0R_PD_SPATIAL_REUSE_EN_MSK, enable); ++} ++ ++void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ ++ dig->bypass_dig = false; ++ rtw89_phy_dig_para_reset(rtwdev); ++ rtw89_phy_dig_set_igi_cr(rtwdev, dig->force_gaincode); ++ rtw89_phy_dig_dyn_pd_th(rtwdev, rssi_nolink, false); ++ rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, false); ++ rtw89_phy_dig_update_para(rtwdev); ++} ++ ++#define IGI_RSSI_MIN 10 ++void rtw89_phy_dig(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dig_info *dig = &rtwdev->dig; ++ bool is_linked = rtwdev->total_sta_assoc > 0; ++ ++ if (unlikely(dig->bypass_dig)) { ++ dig->bypass_dig = false; ++ return; ++ } ++ ++ if (!dig->is_linked_pre && is_linked) { ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "First connected\n"); ++ rtw89_phy_dig_update_para(rtwdev); ++ } else if (dig->is_linked_pre && !is_linked) { ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, "First disconnected\n"); ++ rtw89_phy_dig_update_para(rtwdev); ++ } ++ dig->is_linked_pre = is_linked; ++ ++ rtw89_phy_dig_igi_offset_by_env(rtwdev); ++ rtw89_phy_dig_update_rssi_info(rtwdev); ++ ++ dig->dyn_igi_min = (dig->igi_rssi > IGI_RSSI_MIN) ? ++ dig->igi_rssi - IGI_RSSI_MIN : 0; ++ dig->dyn_igi_max = dig->dyn_igi_min + IGI_OFFSET_MAX; ++ dig->igi_fa_rssi = dig->dyn_igi_min + dig->fa_rssi_ofst; ++ ++ dig->igi_fa_rssi = clamp(dig->igi_fa_rssi, dig->dyn_igi_min, ++ dig->dyn_igi_max); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, ++ "rssi=%03d, dyn(max,min)=(%d,%d), final_rssi=%d\n", ++ dig->igi_rssi, dig->dyn_igi_max, dig->dyn_igi_min, ++ dig->igi_fa_rssi); ++ ++ if (dig->force_gaincode_idx_en) { ++ rtw89_phy_dig_set_igi_cr(rtwdev, dig->force_gaincode); ++ rtw89_debug(rtwdev, RTW89_DBG_DIG, ++ "Force gaincode index enabled.\n"); ++ } else { ++ rtw89_phy_dig_gaincode_by_rssi(rtwdev, dig->igi_fa_rssi, ++ &dig->cur_gaincode); ++ rtw89_phy_dig_set_igi_cr(rtwdev, dig->cur_gaincode); ++ } ++ ++ rtw89_phy_dig_dyn_pd_th(rtwdev, dig->igi_fa_rssi, dig->dyn_pd_th_en); ++ ++ if (dig->dyn_pd_th_en && dig->igi_fa_rssi > dig->dyn_pd_th_max) ++ rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, true); ++ else ++ rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, false); ++} ++ ++static void rtw89_phy_env_monitor_init(struct rtw89_dev *rtwdev) ++{ ++ rtw89_phy_ccx_top_setting_init(rtwdev); ++ rtw89_phy_ifs_clm_setting_init(rtwdev); ++} ++ ++void rtw89_phy_dm_init(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ ++ rtw89_phy_stat_init(rtwdev); ++ ++ rtw89_chip_bb_sethw(rtwdev); ++ ++ rtw89_phy_env_monitor_init(rtwdev); ++ rtw89_phy_dig_init(rtwdev); ++ rtw89_phy_cfo_init(rtwdev); ++ ++ rtw89_phy_init_rf_nctl(rtwdev); ++ rtw89_chip_rfk_init(rtwdev); ++ rtw89_load_txpwr_table(rtwdev, chip->byr_table); ++ rtw89_chip_set_txpwr_ctrl(rtwdev); ++ rtw89_chip_power_trim(rtwdev); ++} ++ ++void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) ++{ ++ enum rtw89_phy_idx phy_idx = RTW89_PHY_0; ++ u8 bss_color; ++ ++ if (!vif->bss_conf.he_support || !vif->bss_conf.assoc) ++ return; ++ ++ bss_color = vif->bss_conf.he_bss_color.color; ++ ++ rtw89_phy_write32_idx(rtwdev, R_BSS_CLR_MAP, B_BSS_CLR_MAP_VLD0, 0x1, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_BSS_CLR_MAP, B_BSS_CLR_MAP_TGT, bss_color, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_BSS_CLR_MAP, B_BSS_CLR_MAP_STAID, ++ vif->bss_conf.aid, phy_idx); ++} +diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h +new file mode 100644 +index 000000000000..370129345e0f +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/phy.h +@@ -0,0 +1,311 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_PHY_H__ ++#define __RTW89_PHY_H__ ++ ++#include "core.h" ++ ++#define RTW89_PHY_ADDR_OFFSET 0x10000 ++ ++#define get_phy_headline(addr) FIELD_GET(GENMASK(31, 28), addr) ++#define PHY_HEADLINE_VALID 0xf ++#define get_phy_target(addr) FIELD_GET(GENMASK(27, 0), addr) ++#define get_phy_compare(rfe, cv) (FIELD_PREP(GENMASK(23, 16), rfe) | \ ++ FIELD_PREP(GENMASK(7, 0), cv)) ++ ++#define get_phy_cond(addr) FIELD_GET(GENMASK(31, 28), addr) ++#define get_phy_cond_rfe(addr) FIELD_GET(GENMASK(23, 16), addr) ++#define get_phy_cond_pkg(addr) FIELD_GET(GENMASK(15, 8), addr) ++#define get_phy_cond_cv(addr) FIELD_GET(GENMASK(7, 0), addr) ++#define phy_div(a, b) ({typeof(b) _b = (b); (_b) ? ((a) / (_b)) : 0; }) ++#define PHY_COND_BRANCH_IF 0x8 ++#define PHY_COND_BRANCH_ELIF 0x9 ++#define PHY_COND_BRANCH_ELSE 0xa ++#define PHY_COND_BRANCH_END 0xb ++#define PHY_COND_CHECK 0x4 ++#define PHY_COND_DONT_CARE 0xff ++ ++#define RA_MASK_CCK_RATES GENMASK_ULL(3, 0) ++#define RA_MASK_OFDM_RATES GENMASK_ULL(11, 4) ++#define RA_MASK_SUBCCK_RATES 0x5ULL ++#define RA_MASK_SUBOFDM_RATES 0x10ULL ++#define RA_MASK_HT_1SS_RATES GENMASK_ULL(19, 12) ++#define RA_MASK_HT_2SS_RATES GENMASK_ULL(31, 24) ++#define RA_MASK_HT_3SS_RATES GENMASK_ULL(43, 36) ++#define RA_MASK_HT_4SS_RATES GENMASK_ULL(55, 48) ++#define RA_MASK_HT_RATES GENMASK_ULL(55, 12) ++#define RA_MASK_VHT_1SS_RATES GENMASK_ULL(21, 12) ++#define RA_MASK_VHT_2SS_RATES GENMASK_ULL(33, 24) ++#define RA_MASK_VHT_3SS_RATES GENMASK_ULL(45, 36) ++#define RA_MASK_VHT_4SS_RATES GENMASK_ULL(57, 48) ++#define RA_MASK_VHT_RATES GENMASK_ULL(57, 12) ++#define RA_MASK_HE_1SS_RATES GENMASK_ULL(23, 12) ++#define RA_MASK_HE_2SS_RATES GENMASK_ULL(35, 24) ++#define RA_MASK_HE_3SS_RATES GENMASK_ULL(47, 36) ++#define RA_MASK_HE_4SS_RATES GENMASK_ULL(59, 48) ++#define RA_MASK_HE_RATES GENMASK_ULL(59, 12) ++ ++#define CFO_TRK_ENABLE_TH (2 << 2) ++#define CFO_TRK_STOP_TH_4 (30 << 2) ++#define CFO_TRK_STOP_TH_3 (20 << 2) ++#define CFO_TRK_STOP_TH_2 (10 << 2) ++#define CFO_TRK_STOP_TH_1 (00 << 2) ++#define CFO_TRK_STOP_TH (2 << 2) ++#define CFO_SW_COMP_FINE_TUNE (2 << 2) ++#define CFO_PERIOD_CNT 15 ++#define CFO_TP_UPPER 100 ++#define CFO_TP_LOWER 50 ++#define CFO_COMP_PERIOD 250 ++#define CFO_COMP_WEIGHT 8 ++#define MAX_CFO_TOLERANCE 30 ++ ++#define CCX_MAX_PERIOD 2097 ++#define CCX_MAX_PERIOD_UNIT 32 ++#define MS_TO_4US_RATIO 250 ++#define ENV_MNTR_FAIL_DWORD 0xffffffff ++#define ENV_MNTR_IFSCLM_HIS_MAX 127 ++#define PERMIL 1000 ++#define PERCENT 100 ++#define IFS_CLM_TH0_UPPER 64 ++#define IFS_CLM_TH_MUL 4 ++#define IFS_CLM_TH_START_IDX 0 ++ ++#define TIA0_GAIN_A 12 ++#define TIA0_GAIN_G 16 ++#define LNA0_GAIN (-24) ++#define U4_MAX_BIT 3 ++#define U8_MAX_BIT 7 ++#define DIG_GAIN_SHIFT 2 ++#define DIG_GAIN 8 ++ ++#define LNA_IDX_MAX 6 ++#define LNA_IDX_MIN 0 ++#define TIA_IDX_MAX 1 ++#define TIA_IDX_MIN 0 ++#define RXB_IDX_MAX 31 ++#define RXB_IDX_MIN 0 ++ ++#define PD_TH_MAX_RSSI 70 ++#define PD_TH_MIN_RSSI 8 ++#define PD_TH_BW80_CMP_VAL 6 ++#define PD_TH_BW40_CMP_VAL 3 ++#define PD_TH_BW20_CMP_VAL 0 ++#define PD_TH_CMP_VAL 3 ++#define PD_TH_SB_FLTR_CMP_VAL 7 ++ ++#define PHYSTS_MGNT BIT(RTW89_RX_TYPE_MGNT) ++#define PHYSTS_CTRL BIT(RTW89_RX_TYPE_CTRL) ++#define PHYSTS_DATA BIT(RTW89_RX_TYPE_DATA) ++#define PHYSTS_RSVD BIT(RTW89_RX_TYPE_RSVD) ++#define PPDU_FILTER_BITMAP (PHYSTS_MGNT | PHYSTS_DATA) ++ ++enum rtw89_phy_c2h_ra_func { ++ RTW89_PHY_C2H_FUNC_STS_RPT, ++ RTW89_PHY_C2H_FUNC_MU_GPTBL_RPT, ++ RTW89_PHY_C2H_FUNC_TXSTS, ++ RTW89_PHY_C2H_FUNC_RA_MAX, ++}; ++ ++enum rtw89_phy_c2h_class { ++ RTW89_PHY_C2H_CLASS_RUA, ++ RTW89_PHY_C2H_CLASS_RA, ++ RTW89_PHY_C2H_CLASS_DM, ++ RTW89_PHY_C2H_CLASS_BTC_MIN = 0x10, ++ RTW89_PHY_C2H_CLASS_BTC_MAX = 0x17, ++ RTW89_PHY_C2H_CLASS_MAX, ++}; ++ ++enum rtw89_env_monitor_result_level { ++ RTW89_PHY_ENV_MON_CCX_FAIL = 0, ++ RTW89_PHY_ENV_MON_NHM = BIT(0), ++ RTW89_PHY_ENV_MON_CLM = BIT(1), ++ RTW89_PHY_ENV_MON_FAHM = BIT(2), ++ RTW89_PHY_ENV_MON_IFS_CLM = BIT(3), ++ RTW89_PHY_ENV_MON_EDCCA_CLM = BIT(4), ++}; ++ ++#define CCX_US_BASE_RATIO 4 ++enum rtw89_ccx_unit { ++ RTW89_CCX_4_US = 0, ++ RTW89_CCX_8_US = 1, ++ RTW89_CCX_16_US = 2, ++ RTW89_CCX_32_US = 3 ++}; ++ ++enum rtw89_dig_gain_type { ++ RTW89_DIG_GAIN_LNA_G = 0, ++ RTW89_DIG_GAIN_TIA_G = 1, ++ RTW89_DIG_GAIN_LNA_A = 2, ++ RTW89_DIG_GAIN_TIA_A = 3, ++ RTW89_DIG_GAIN_MAX = 4 ++}; ++ ++enum rtw89_dig_gain_lna_idx { ++ RTW89_DIG_GAIN_LNA_IDX1 = 1, ++ RTW89_DIG_GAIN_LNA_IDX2 = 2, ++ RTW89_DIG_GAIN_LNA_IDX3 = 3, ++ RTW89_DIG_GAIN_LNA_IDX4 = 4, ++ RTW89_DIG_GAIN_LNA_IDX5 = 5, ++ RTW89_DIG_GAIN_LNA_IDX6 = 6 ++}; ++ ++enum rtw89_dig_gain_tia_idx { ++ RTW89_DIG_GAIN_TIA_IDX0 = 0, ++ RTW89_DIG_GAIN_TIA_IDX1 = 1 ++}; ++ ++struct rtw89_txpwr_byrate_cfg { ++ enum rtw89_band band; ++ enum rtw89_nss nss; ++ enum rtw89_rate_section rs; ++ u8 shf; ++ u8 len; ++ u32 data; ++}; ++ ++#define DELTA_SWINGIDX_SIZE 30 ++ ++struct rtw89_txpwr_track_cfg { ++ const u8 (*delta_swingidx_5gb_n)[DELTA_SWINGIDX_SIZE]; ++ const u8 (*delta_swingidx_5gb_p)[DELTA_SWINGIDX_SIZE]; ++ const u8 (*delta_swingidx_5ga_n)[DELTA_SWINGIDX_SIZE]; ++ const u8 (*delta_swingidx_5ga_p)[DELTA_SWINGIDX_SIZE]; ++ const u8 *delta_swingidx_2gb_n; ++ const u8 *delta_swingidx_2gb_p; ++ const u8 *delta_swingidx_2ga_n; ++ const u8 *delta_swingidx_2ga_p; ++ const u8 *delta_swingidx_2g_cck_b_n; ++ const u8 *delta_swingidx_2g_cck_b_p; ++ const u8 *delta_swingidx_2g_cck_a_n; ++ const u8 *delta_swingidx_2g_cck_a_p; ++}; ++ ++struct rtw89_phy_dig_gain_cfg { ++ const struct rtw89_reg_def *table; ++ u8 size; ++}; ++ ++struct rtw89_phy_dig_gain_table { ++ const struct rtw89_phy_dig_gain_cfg *cfg_lna_g; ++ const struct rtw89_phy_dig_gain_cfg *cfg_tia_g; ++ const struct rtw89_phy_dig_gain_cfg *cfg_lna_a; ++ const struct rtw89_phy_dig_gain_cfg *cfg_tia_a; ++}; ++ ++struct rtw89_phy_reg3_tbl { ++ const struct rtw89_reg3_def *reg3; ++ int size; ++}; ++ ++#define DECLARE_PHY_REG3_TBL(_name) \ ++const struct rtw89_phy_reg3_tbl _name ## _tbl = { \ ++ .reg3 = _name, \ ++ .size = ARRAY_SIZE(_name), \ ++} ++ ++static inline void rtw89_phy_write8(struct rtw89_dev *rtwdev, ++ u32 addr, u8 data) ++{ ++ rtw89_write8(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, data); ++} ++ ++static inline void rtw89_phy_write16(struct rtw89_dev *rtwdev, ++ u32 addr, u16 data) ++{ ++ rtw89_write16(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, data); ++} ++ ++static inline void rtw89_phy_write32(struct rtw89_dev *rtwdev, ++ u32 addr, u32 data) ++{ ++ rtw89_write32(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, data); ++} ++ ++static inline void rtw89_phy_write32_set(struct rtw89_dev *rtwdev, ++ u32 addr, u32 bits) ++{ ++ rtw89_write32_set(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, bits); ++} ++ ++static inline void rtw89_phy_write32_clr(struct rtw89_dev *rtwdev, ++ u32 addr, u32 bits) ++{ ++ rtw89_write32_clr(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, bits); ++} ++ ++static inline void rtw89_phy_write32_mask(struct rtw89_dev *rtwdev, ++ u32 addr, u32 mask, u32 data) ++{ ++ rtw89_write32_mask(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, mask, data); ++} ++ ++static inline u8 rtw89_phy_read8(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ return rtw89_read8(rtwdev, addr | RTW89_PHY_ADDR_OFFSET); ++} ++ ++static inline u16 rtw89_phy_read16(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ return rtw89_read16(rtwdev, addr | RTW89_PHY_ADDR_OFFSET); ++} ++ ++static inline u32 rtw89_phy_read32(struct rtw89_dev *rtwdev, u32 addr) ++{ ++ return rtw89_read32(rtwdev, addr | RTW89_PHY_ADDR_OFFSET); ++} ++ ++static inline u32 rtw89_phy_read32_mask(struct rtw89_dev *rtwdev, ++ u32 addr, u32 mask) ++{ ++ return rtw89_read32_mask(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, mask); ++} ++ ++void rtw89_phy_write_reg3_tbl(struct rtw89_dev *rtwdev, ++ const struct rtw89_phy_reg3_tbl *tbl); ++u8 rtw89_phy_get_txsc(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_params *param, ++ enum rtw89_bandwidth dbw); ++u32 rtw89_phy_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask); ++bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, ++ u32 addr, u32 mask, u32 data); ++void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev); ++void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev); ++void rtw89_phy_dm_init(struct rtw89_dev *rtwdev); ++void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, ++ u32 data, enum rtw89_phy_idx phy_idx); ++void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev, ++ const struct rtw89_txpwr_table *tbl); ++s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, ++ const struct rtw89_rate_desc *rate_desc); ++void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit *lmt, ++ u8 ntx); ++void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev, ++ struct rtw89_txpwr_limit_ru *lmt_ru, ++ u8 ntx); ++s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, ++ u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch); ++void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta); ++void rtw89_phy_ra_update(struct rtw89_dev *rtwdev); ++void rtw89_phy_ra_updata_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta); ++void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, ++ struct ieee80211_vif *vif, ++ const struct cfg80211_bitrate_mask *mask); ++void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, ++ u32 len, u8 class, u8 func); ++void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev); ++void rtw89_phy_cfo_track_work(struct work_struct *work); ++void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val, ++ struct rtw89_rx_phy_ppdu *phy_ppdu); ++void rtw89_phy_stat_track(struct rtw89_dev *rtwdev); ++void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev); ++void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask, ++ u32 val); ++void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev); ++void rtw89_phy_dig(struct rtw89_dev *rtwdev); ++void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c +new file mode 100644 +index 000000000000..7eaa01e41ef2 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/ps.c +@@ -0,0 +1,150 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "coex.h" ++#include "core.h" ++#include "debug.h" ++#include "fw.h" ++#include "mac.h" ++#include "ps.h" ++#include "reg.h" ++#include "util.h" ++ ++static int rtw89_fw_leave_lps_check(struct rtw89_dev *rtwdev, u8 macid) ++{ ++ u32 pwr_en_bit = 0xE; ++ u32 chk_msk = pwr_en_bit << (4 * macid); ++ u32 polling; ++ int ret; ++ ++ ret = read_poll_timeout_atomic(rtw89_read32_mask, polling, !polling, ++ 1000, 50000, false, rtwdev, ++ R_AX_PPWRBIT_SETTING, chk_msk); ++ if (ret) { ++ rtw89_info(rtwdev, "rtw89: failed to leave lps state\n"); ++ return -EBUSY; ++ } ++ ++ return 0; ++} ++ ++static void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev) ++{ ++ if (!rtwdev->ps_mode) ++ return; ++ ++ if (test_and_set_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags)) ++ return; ++ ++ rtw89_mac_power_mode_change(rtwdev, true); ++} ++ ++void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev) ++{ ++ if (!rtwdev->ps_mode) ++ return; ++ ++ if (test_and_clear_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags)) ++ rtw89_mac_power_mode_change(rtwdev, false); ++} ++ ++static void __rtw89_enter_lps(struct rtw89_dev *rtwdev, u8 mac_id) ++{ ++ struct rtw89_lps_parm lps_param = { ++ .macid = mac_id, ++ .psmode = RTW89_MAC_AX_PS_MODE_LEGACY, ++ .lastrpwm = RTW89_LAST_RPWM_PS, ++ }; ++ ++ rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_FW_CTRL); ++ rtw89_fw_h2c_lps_parm(rtwdev, &lps_param); ++} ++ ++static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, u8 mac_id) ++{ ++ struct rtw89_lps_parm lps_param = { ++ .macid = mac_id, ++ .psmode = RTW89_MAC_AX_PS_MODE_ACTIVE, ++ .lastrpwm = RTW89_LAST_RPWM_ACTIVE, ++ }; ++ ++ rtw89_fw_h2c_lps_parm(rtwdev, &lps_param); ++ rtw89_fw_leave_lps_check(rtwdev, 0); ++ rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_ON); ++} ++ ++void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev) ++{ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ __rtw89_leave_ps_mode(rtwdev); ++} ++ ++void rtw89_enter_lps(struct rtw89_dev *rtwdev, u8 mac_id) ++{ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ if (test_and_set_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags)) ++ return; ++ ++ __rtw89_enter_lps(rtwdev, mac_id); ++ __rtw89_enter_ps_mode(rtwdev); ++} ++ ++static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION) ++ return; ++ ++ __rtw89_leave_ps_mode(rtwdev); ++ __rtw89_leave_lps(rtwdev, rtwvif->mac_id); ++} ++ ++void rtw89_leave_lps(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_vif *rtwvif; ++ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ if (!test_and_clear_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags)) ++ return; ++ ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ rtw89_leave_lps_vif(rtwdev, rtwvif); ++} ++ ++void rtw89_enter_ips(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_vif *rtwvif; ++ ++ set_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags); ++ ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ rtw89_mac_vif_deinit(rtwdev, rtwvif); ++ ++ rtw89_core_stop(rtwdev); ++} ++ ++void rtw89_leave_ips(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_vif *rtwvif; ++ int ret; ++ ++ ret = rtw89_core_start(rtwdev); ++ if (ret) ++ rtw89_err(rtwdev, "failed to leave idle state\n"); ++ ++ rtw89_set_channel(rtwdev); ++ ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ rtw89_mac_vif_init(rtwdev, rtwvif); ++ ++ clear_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags); ++} ++ ++void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl) ++{ ++ if (btc_ctrl) ++ rtw89_leave_lps(rtwdev); ++} +diff --git a/drivers/net/wireless/realtek/rtw89/ps.h b/drivers/net/wireless/realtek/rtw89/ps.h +new file mode 100644 +index 000000000000..a184b68994aa +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/ps.h +@@ -0,0 +1,16 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_PS_H_ ++#define __RTW89_PS_H_ ++ ++void rtw89_enter_lps(struct rtw89_dev *rtwdev, u8 mac_id); ++void rtw89_leave_lps(struct rtw89_dev *rtwdev); ++void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev); ++void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev); ++void rtw89_enter_ips(struct rtw89_dev *rtwdev); ++void rtw89_leave_ips(struct rtw89_dev *rtwdev); ++void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +new file mode 100644 +index 000000000000..365d8c8ce57b +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -0,0 +1,2159 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_REG_H__ ++#define __RTW89_REG_H__ ++ ++#define R_AX_SYS_WL_EFUSE_CTRL 0x000A ++#define B_AX_AUTOLOAD_SUS BIT(5) ++ ++#define R_AX_SYS_FUNC_EN 0x0002 ++#define B_AX_FEN_BB_GLB_RSTN BIT(1) ++#define B_AX_FEN_BBRSTB BIT(0) ++ ++#define R_AX_SYS_PW_CTRL 0x0004 ++#define B_AX_PSUS_OFF_CAPC_EN BIT(14) ++ ++#define R_AX_SYS_CLK_CTRL 0x0008 ++#define B_AX_CPU_CLK_EN BIT(14) ++ ++#define R_AX_RSV_CTRL 0x001C ++#define B_AX_R_DIS_PRST BIT(6) ++#define B_AX_WLOCK_1C_BIT6 BIT(5) ++ ++#define R_AX_EFUSE_CTRL_1 0x0038 ++#define B_AX_EF_PGPD_MASK GENMASK(30, 28) ++#define B_AX_EF_RDT BIT(27) ++#define B_AX_EF_VDDQST_MASK GENMASK(26, 24) ++#define B_AX_EF_PGTS_MASK GENMASK(23, 20) ++#define B_AX_EF_PD_DIS BIT(11) ++#define B_AX_EF_POR BIT(10) ++#define B_AX_EF_CELL_SEL_MASK GENMASK(9, 8) ++ ++#define R_AX_SPSLDO_ON_CTRL0 0x0200 ++#define B_AX_OCP_L1_MASK GENMASK(15, 13) ++ ++#define R_AX_EFUSE_CTRL 0x0030 ++#define B_AX_EF_MODE_SEL_MASK GENMASK(31, 30) ++#define B_AX_EF_RDY BIT(29) ++#define B_AX_EF_COMP_RESULT BIT(28) ++#define B_AX_EF_ADDR_MASK GENMASK(26, 16) ++#define B_AX_EF_DATA_MASK GENMASK(15, 0) ++ ++#define R_AX_GPIO_MUXCFG 0x0040 ++#define B_AX_BOOT_MODE BIT(19) ++#define B_AX_WL_EECS_EXT_32K_SEL BIT(18) ++#define B_AX_WL_SEC_BONDING_OPT_STS BIT(17) ++#define B_AX_SECSIC_SEL BIT(16) ++#define B_AX_ENHTP BIT(14) ++#define B_AX_BT_AOD_GPIO3 BIT(13) ++#define B_AX_ENSIC BIT(12) ++#define B_AX_SIC_SWRST BIT(11) ++#define B_AX_PO_WIFI_PTA_PINS BIT(10) ++#define B_AX_PO_BT_PTA_PINS BIT(9) ++#define B_AX_ENUARTTX BIT(8) ++#define B_AX_BTMODE_MASK GENMASK(7, 6) ++#define MAC_AX_BT_MODE_0_3 0 ++#define MAC_AX_BT_MODE_2 2 ++#define B_AX_ENBT BIT(5) ++#define B_AX_EROM_EN BIT(4) ++#define B_AX_ENUARTRX BIT(2) ++#define B_AX_GPIOSEL_MASK GENMASK(1, 0) ++ ++#define R_AX_DBG_CTRL 0x0058 ++#define B_AX_DBG_SEL1_4BIT GENMASK(31, 30) ++#define B_AX_DBG_SEL1_16BIT BIT(27) ++#define B_AX_DBG_SEL1 GENMASK(23, 16) ++#define B_AX_DBG_SEL0_4BIT GENMASK(15, 14) ++#define B_AX_DBG_SEL0_16BIT BIT(11) ++#define B_AX_DBG_SEL0 GENMASK(7, 0) ++ ++#define R_AX_SYS_SDIO_CTRL 0x0070 ++#define B_AX_PCIE_DIS_L2_CTRL_LDO_HCI BIT(15) ++#define B_AX_PCIE_DIS_WLSUS_AFT_PDN BIT(14) ++#define B_AX_PCIE_AUXCLK_GATE BIT(11) ++#define B_AX_LTE_MUX_CTRL_PATH BIT(26) ++ ++#define R_AX_PLATFORM_ENABLE 0x0088 ++#define B_AX_WCPU_EN BIT(1) ++ ++#define R_AX_SCOREBOARD 0x00AC ++#define B_AX_TOGGLE BIT(31) ++#define B_MAC_AX_SB_FW_MASK GENMASK(30, 24) ++#define B_MAC_AX_SB_DRV_MASK GENMASK(23, 0) ++#define B_MAC_AX_BTGS1_NOTIFY BIT(0) ++#define MAC_AX_NOTIFY_TP_MAJOR 0x81 ++#define MAC_AX_NOTIFY_PWR_MAJOR 0x80 ++ ++#define R_AX_DBG_PORT_SEL 0x00C0 ++#define B_AX_DEBUG_ST_MASK GENMASK(31, 0) ++ ++#define R_AX_SYS_CFG1 0x00F0 ++#define B_AX_CHIP_VER_MASK GENMASK(15, 12) ++ ++#define R_AX_SYS_STATUS1 0x00F4 ++#define B_AX_SEL_0XC0_MASK GENMASK(17, 16) ++ ++#define R_AX_HALT_H2C_CTRL 0x0160 ++#define R_AX_HALT_H2C 0x0168 ++#define B_AX_HALT_H2C_TRIGGER BIT(0) ++#define R_AX_HALT_C2H_CTRL 0x0164 ++#define R_AX_HALT_C2H 0x016C ++ ++#define R_AX_WCPU_FW_CTRL 0x01E0 ++#define B_AX_WCPU_FWDL_STS_MASK GENMASK(7, 5) ++#define B_AX_FWDL_PATH_RDY BIT(2) ++#define B_AX_H2C_PATH_RDY BIT(1) ++#define B_AX_WCPU_FWDL_EN BIT(0) ++ ++#define R_AX_RPWM 0x01E4 ++#define R_AX_PCIE_HRPWM 0x10C0 ++#define PS_RPWM_TOGGLE BIT(15) ++#define PS_RPWM_ACK BIT(14) ++#define PS_RPWM_SEQ_NUM GENMASK(13, 12) ++#define PS_RPWM_STATE 0x7 ++#define RPWM_SEQ_NUM_MAX 3 ++#define PS_CPWM_SEQ_NUM GENMASK(13, 12) ++#define PS_CPWM_RSP_SEQ_NUM GENMASK(9, 8) ++#define PS_CPWM_STATE GENMASK(2, 0) ++#define CPWM_SEQ_NUM_MAX 3 ++ ++#define R_AX_BOOT_REASON 0x01E6 ++#define B_AX_BOOT_REASON_MASK GENMASK(2, 0) ++ ++#define R_AX_LDM 0x01E8 ++#define B_AX_EN_32K BIT(31) ++ ++#define R_AX_UDM0 0x01F0 ++#define R_AX_UDM1 0x01F4 ++#define R_AX_UDM2 0x01F8 ++#define R_AX_UDM3 0x01FC ++ ++#define R_AX_XTAL_ON_CTRL0 0x0280 ++#define B_AX_XTAL_SC_LPS BIT(31) ++#define B_AX_XTAL_SC_XO_MASK GENMASK(23, 17) ++#define B_AX_XTAL_SC_XI_MASK GENMASK(16, 10) ++#define B_AX_XTAL_SC_MASK GENMASK(6, 0) ++ ++#define R_AX_GPIO0_7_FUNC_SEL 0x02D0 ++ ++#define R_AX_WLRF_CTRL 0x02F0 ++#define B_AX_WLRF1_CTRL_7 BIT(15) ++#define B_AX_WLRF1_CTRL_1 BIT(9) ++#define B_AX_WLRF_CTRL_7 BIT(7) ++#define B_AX_WLRF_CTRL_1 BIT(1) ++ ++#define R_AX_IC_PWR_STATE 0x03F0 ++#define B_AX_WHOLE_SYS_PWR_STE_MASK GENMASK(25, 16) ++#define B_AX_WLMAC_PWR_STE_MASK GENMASK(9, 8) ++#define B_AX_UART_HCISYS_PWR_STE_MASK GENMASK(7, 6) ++#define B_AX_SDIO_HCISYS_PWR_STE_MASK GENMASK(5, 4) ++#define B_AX_USB_HCISYS_PWR_STE_MASK GENMASK(3, 2) ++#define B_AX_PCIE_HCISYS_PWR_STE_MASK GENMASK(1, 0) ++ ++#define R_AX_FILTER_MODEL_ADDR 0x0C04 ++ ++#define R_AX_PCIE_DBG_CTRL 0x11C0 ++#define B_AX_DBG_DUMMY_MASK GENMASK(23, 16) ++#define B_AX_DBG_SEL_MASK GENMASK(15, 13) ++#define B_AX_PCIE_DBG_SEL BIT(12) ++#define B_AX_MRD_TIMEOUT_EN BIT(10) ++#define B_AX_ASFF_FULL_NO_STK BIT(1) ++#define B_AX_EN_STUCK_DBG BIT(0) ++ ++#define R_AX_PHYREG_SET 0x8040 ++#define PHYREG_SET_ALL_CYCLE 0x8 ++ ++#define R_AX_HD0IMR 0x8110 ++#define B_AX_WDT_PTFM_INT_EN BIT(5) ++#define B_AX_CPWM_INT_EN BIT(2) ++#define B_AX_GT3_INT_EN BIT(1) ++#define B_AX_C2H_INT_EN BIT(0) ++#define R_AX_HD0ISR 0x8114 ++#define B_AX_C2H_INT BIT(0) ++ ++#define R_AX_H2CREG_DATA0 0x8140 ++#define R_AX_H2CREG_DATA1 0x8144 ++#define R_AX_H2CREG_DATA2 0x8148 ++#define R_AX_H2CREG_DATA3 0x814C ++#define R_AX_C2HREG_DATA0 0x8150 ++#define R_AX_C2HREG_DATA1 0x8154 ++#define R_AX_C2HREG_DATA2 0x8158 ++#define R_AX_C2HREG_DATA3 0x815C ++#define R_AX_H2CREG_CTRL 0x8160 ++#define B_AX_H2CREG_TRIGGER BIT(0) ++#define R_AX_C2HREG_CTRL 0x8164 ++#define B_AX_C2HREG_TRIGGER BIT(0) ++#define R_AX_CPWM 0x8170 ++ ++#define R_AX_HCI_FUNC_EN 0x8380 ++#define B_AX_HCI_RXDMA_EN BIT(1) ++#define B_AX_HCI_TXDMA_EN BIT(0) ++ ++#define R_AX_BOOT_DBG 0x83F0 ++ ++#define R_AX_DMAC_FUNC_EN 0x8400 ++#define B_AX_MAC_FUNC_EN BIT(30) ++#define B_AX_DMAC_FUNC_EN BIT(29) ++#define B_AX_MPDU_PROC_EN BIT(28) ++#define B_AX_WD_RLS_EN BIT(27) ++#define B_AX_DLE_WDE_EN BIT(26) ++#define B_AX_TXPKT_CTRL_EN BIT(25) ++#define B_AX_STA_SCH_EN BIT(24) ++#define B_AX_DLE_PLE_EN BIT(23) ++#define B_AX_PKT_BUF_EN BIT(22) ++#define B_AX_DMAC_TBL_EN BIT(21) ++#define B_AX_PKT_IN_EN BIT(20) ++#define B_AX_DLE_CPUIO_EN BIT(19) ++#define B_AX_DISPATCHER_EN BIT(18) ++#define B_AX_MAC_SEC_EN BIT(16) ++ ++#define R_AX_DMAC_CLK_EN 0x8404 ++#define B_AX_WD_RLS_CLK_EN BIT(27) ++#define B_AX_DLE_WDE_CLK_EN BIT(26) ++#define B_AX_TXPKT_CTRL_CLK_EN BIT(25) ++#define B_AX_STA_SCH_CLK_EN BIT(24) ++#define B_AX_DLE_PLE_CLK_EN BIT(23) ++#define B_AX_PKT_IN_CLK_EN BIT(20) ++#define B_AX_DLE_CPUIO_CLK_EN BIT(19) ++#define B_AX_DISPATCHER_CLK_EN BIT(18) ++#define B_AX_MAC_SEC_CLK_EN BIT(16) ++ ++#define PCI_LTR_IDLE_TIMER_1US 0 ++#define PCI_LTR_IDLE_TIMER_10US 1 ++#define PCI_LTR_IDLE_TIMER_100US 2 ++#define PCI_LTR_IDLE_TIMER_200US 3 ++#define PCI_LTR_IDLE_TIMER_400US 4 ++#define PCI_LTR_IDLE_TIMER_800US 5 ++#define PCI_LTR_IDLE_TIMER_1_6MS 6 ++#define PCI_LTR_IDLE_TIMER_3_2MS 7 ++#define PCI_LTR_IDLE_TIMER_R_ERR 0xFD ++#define PCI_LTR_IDLE_TIMER_DEF 0xFE ++#define PCI_LTR_IDLE_TIMER_IGNORE 0xFF ++ ++#define PCI_LTR_SPC_10US 0 ++#define PCI_LTR_SPC_100US 1 ++#define PCI_LTR_SPC_500US 2 ++#define PCI_LTR_SPC_1MS 3 ++#define PCI_LTR_SPC_R_ERR 0xFD ++#define PCI_LTR_SPC_DEF 0xFE ++#define PCI_LTR_SPC_IGNORE 0xFF ++ ++#define R_AX_LTR_CTRL_0 0x8410 ++#define B_AX_LTR_SPACE_IDX_MASK GENMASK(13, 12) ++#define B_AX_LTR_IDLE_TIMER_IDX_MASK GENMASK(10, 8) ++#define B_AX_APP_LTR_ACT BIT(5) ++#define B_AX_APP_LTR_IDLE BIT(4) ++#define B_AX_LTR_EN BIT(1) ++#define B_AX_LTR_HW_EN BIT(0) ++ ++#define R_AX_LTR_CTRL_1 0x8414 ++#define B_AX_LTR_RX1_TH_MASK GENMASK(27, 16) ++#define B_AX_LTR_RX0_TH_MASK GENMASK(11, 0) ++ ++#define R_AX_LTR_IDLE_LATENCY 0x8418 ++ ++#define R_AX_LTR_ACTIVE_LATENCY 0x841C ++ ++#define R_AX_SER_DBG_INFO 0x8424 ++#define B_AX_L0_TO_L1_EVENT_MASK GENMASK(31, 28) ++ ++#define R_AX_DLE_EMPTY0 0x8430 ++#define B_AX_PLE_EMPTY_QTA_DMAC_CPUIO BIT(26) ++#define B_AX_PLE_EMPTY_QTA_DMAC_MPDU_TX BIT(25) ++#define B_AX_PLE_EMPTY_QTA_DMAC_WLAN_CPU BIT(24) ++#define B_AX_PLE_EMPTY_QTA_DMAC_H2C BIT(23) ++#define B_AX_PLE_EMPTY_QTA_DMAC_B1_TXPL BIT(22) ++#define B_AX_PLE_EMPTY_QTA_DMAC_B0_TXPL BIT(21) ++#define B_AX_WDE_EMPTY_QTA_DMAC_CPUIO BIT(20) ++#define B_AX_WDE_EMPTY_QTA_DMAC_PKTIN BIT(19) ++#define B_AX_WDE_EMPTY_QTA_DMAC_DATA_CPU BIT(18) ++#define B_AX_WDE_EMPTY_QTA_DMAC_WLAN_CPU BIT(17) ++#define B_AX_WDE_EMPTY_QTA_DMAC_HIF BIT(16) ++#define B_AX_WDE_EMPTY_QUE_DMAC_PKTIN BIT(10) ++#define B_AX_PLE_EMPTY_QUE_DMAC_SEC_TX BIT(9) ++#define B_AX_PLE_EMPTY_QUE_DMAC_MPDU_TX BIT(8) ++#define B_AX_WDE_EMPTY_QUE_OTHERS BIT(7) ++#define B_AX_WDE_EMPTY_QUE_CMAC0_WMM1 BIT(4) ++#define B_AX_WDE_EMPTY_QUE_CMAC0_WMM0 BIT(3) ++#define B_AX_WDE_EMPTY_QUE_CMAC1_MBH BIT(2) ++#define B_AX_WDE_EMPTY_QUE_CMAC0_MBH BIT(1) ++#define B_AX_WDE_EMPTY_QUE_CMAC0_ALL_AC BIT(0) ++ ++#define R_AX_DMAC_ERR_ISR 0x8524 ++#define B_AX_DLE_CPUIO_ERR_FLAG BIT(10) ++#define B_AX_APB_BRIDGE_ERR_FLAG BIT(9) ++#define B_AX_DISPATCH_ERR_FLAG BIT(8) ++#define B_AX_PKTIN_ERR_FLAG BIT(7) ++#define B_AX_PLE_DLE_ERR_FLAG BIT(6) ++#define B_AX_TXPKTCTRL_ERR_FLAG BIT(5) ++#define B_AX_WDE_DLE_ERR_FLAG BIT(4) ++#define B_AX_STA_SCHEDULER_ERR_FLAG BIT(3) ++#define B_AX_MPDU_ERR_FLAG BIT(2) ++#define B_AX_WSEC_ERR_FLAG BIT(1) ++#define B_AX_WDRLS_ERR_FLAG BIT(0) ++ ++#define R_AX_DISPATCHER_GLOBAL_SETTING_0 0x8800 ++#define B_AX_PL_PAGE_128B_SEL BIT(9) ++#define B_AX_WD_PAGE_64B_SEL BIT(8) ++#define R_AX_OTHER_DISPATCHER_ERR_ISR 0x8804 ++#define R_AX_HOST_DISPATCHER_ERR_ISR 0x8808 ++#define R_AX_CPU_DISPATCHER_ERR_ISR 0x880C ++#define R_AX_TX_ADDRESS_INFO_MODE_SETTING 0x8810 ++#define B_AX_HOST_ADDR_INFO_8B_SEL BIT(0) ++ ++#define R_AX_HOST_DISPATCHER_ERR_IMR 0x8850 ++#define B_AX_HDT_OFFSET_UNMATCH_INT_EN BIT(7) ++#define B_AX_HDT_PKT_FAIL_DBG_INT_EN BIT(2) ++ ++#define R_AX_CPU_DISPATCHER_ERR_IMR 0x8854 ++#define B_AX_CPU_SHIFT_EN_ERR_INT_EN BIT(25) ++ ++#define R_AX_OTHER_DISPATCHER_ERR_IMR 0x8858 ++ ++#define R_AX_HCI_FC_CTRL 0x8A00 ++#define B_AX_HCI_FC_CH12_FULL_COND_MASK GENMASK(11, 10) ++#define B_AX_HCI_FC_WP_CH811_FULL_COND_MASK GENMASK(9, 8) ++#define B_AX_HCI_FC_WP_CH07_FULL_COND_MASK GENMASK(7, 6) ++#define B_AX_HCI_FC_WD_FULL_COND_MASK GENMASK(5, 4) ++#define B_AX_HCI_FC_CH12_EN BIT(3) ++#define B_AX_HCI_FC_MODE_MASK GENMASK(2, 1) ++#define B_AX_HCI_FC_EN BIT(0) ++ ++#define R_AX_CH_PAGE_CTRL 0x8A04 ++#define B_AX_PREC_PAGE_CH12_MASK GENMASK(24, 16) ++#define B_AX_PREC_PAGE_CH011_MASK GENMASK(8, 0) ++ ++#define B_AX_MAX_PG_MASK GENMASK(28, 16) ++#define B_AX_MIN_PG_MASK GENMASK(12, 0) ++#define B_AX_GRP BIT(31) ++#define R_AX_ACH0_PAGE_CTRL 0x8A10 ++#define R_AX_ACH1_PAGE_CTRL 0x8A14 ++#define R_AX_ACH2_PAGE_CTRL 0x8A18 ++#define R_AX_ACH3_PAGE_CTRL 0x8A1C ++#define R_AX_ACH4_PAGE_CTRL 0x8A20 ++#define R_AX_ACH5_PAGE_CTRL 0x8A24 ++#define R_AX_ACH6_PAGE_CTRL 0x8A28 ++#define R_AX_ACH7_PAGE_CTRL 0x8A2C ++#define R_AX_CH8_PAGE_CTRL 0x8A30 ++#define R_AX_CH9_PAGE_CTRL 0x8A34 ++#define R_AX_CH10_PAGE_CTRL 0x8A38 ++#define R_AX_CH11_PAGE_CTRL 0x8A3C ++ ++#define B_AX_AVAL_PG_MASK GENMASK(27, 16) ++#define B_AX_USE_PG_MASK GENMASK(12, 0) ++#define R_AX_ACH0_PAGE_INFO 0x8A50 ++#define R_AX_ACH1_PAGE_INFO 0x8A54 ++#define R_AX_ACH2_PAGE_INFO 0x8A58 ++#define R_AX_ACH3_PAGE_INFO 0x8A5C ++#define R_AX_ACH4_PAGE_INFO 0x8A60 ++#define R_AX_ACH5_PAGE_INFO 0x8A64 ++#define R_AX_ACH6_PAGE_INFO 0x8A68 ++#define R_AX_ACH7_PAGE_INFO 0x8A6C ++#define R_AX_CH8_PAGE_INFO 0x8A70 ++#define R_AX_CH9_PAGE_INFO 0x8A74 ++#define R_AX_CH10_PAGE_INFO 0x8A78 ++#define R_AX_CH11_PAGE_INFO 0x8A7C ++#define R_AX_CH12_PAGE_INFO 0x8A80 ++ ++#define R_AX_PUB_PAGE_INFO3 0x8A8C ++#define B_AX_G1_AVAL_PG_MASK GENMASK(28, 16) ++#define B_AX_G0_AVAL_PG_MASK GENMASK(12, 0) ++ ++#define R_AX_PUB_PAGE_CTRL1 0x8A90 ++#define B_AX_PUBPG_G1_MASK GENMASK(28, 16) ++#define B_AX_PUBPG_G0_MASK GENMASK(12, 0) ++ ++#define R_AX_PUB_PAGE_CTRL2 0x8A94 ++#define B_AX_PUBPG_ALL_MASK GENMASK(12, 0) ++ ++#define R_AX_PUB_PAGE_INFO1 0x8A98 ++#define B_AX_G1_USE_PG_MASK GENMASK(28, 16) ++#define B_AX_G0_USE_PG_MASK GENMASK(12, 0) ++ ++#define R_AX_PUB_PAGE_INFO2 0x8A9C ++#define B_AX_PUB_AVAL_PG_MASK GENMASK(12, 0) ++ ++#define R_AX_WP_PAGE_CTRL1 0x8AA0 ++#define B_AX_PREC_PAGE_WP_CH811_MASK GENMASK(24, 16) ++#define B_AX_PREC_PAGE_WP_CH07_MASK GENMASK(8, 0) ++ ++#define R_AX_WP_PAGE_CTRL2 0x8AA4 ++#define B_AX_WP_THRD_MASK GENMASK(12, 0) ++ ++#define R_AX_WP_PAGE_INFO1 0x8AA8 ++#define B_AX_WP_AVAL_PG_MASK GENMASK(28, 16) ++ ++#define R_AX_WDE_PKTBUF_CFG 0x8C08 ++#define B_AX_WDE_START_BOUND_MASK GENMASK(13, 8) ++#define B_AX_WDE_PAGE_SEL_MASK GENMASK(1, 0) ++#define B_AX_WDE_FREE_PAGE_NUM_MASK GENMASK(28, 16) ++#define R_AX_WDE_ERR_FLAG_CFG 0x8C34 ++#define R_AX_WDE_ERR_IMR 0x8C38 ++#define R_AX_WDE_ERR_ISR 0x8C3C ++ ++#define B_AX_WDE_MAX_SIZE_MASK GENMASK(27, 16) ++#define B_AX_WDE_MIN_SIZE_MASK GENMASK(11, 0) ++#define R_AX_WDE_QTA0_CFG 0x8C40 ++#define R_AX_WDE_QTA1_CFG 0x8C44 ++#define R_AX_WDE_QTA2_CFG 0x8C48 ++#define R_AX_WDE_QTA3_CFG 0x8C4C ++#define R_AX_WDE_QTA4_CFG 0x8C50 ++ ++#define B_AX_DLE_PUB_PGNUM GENMASK(12, 0) ++#define B_AX_DLE_FREE_HEADPG GENMASK(11, 0) ++#define B_AX_DLE_FREE_TAILPG GENMASK(27, 16) ++#define B_AX_DLE_USE_PGNUM GENMASK(27, 16) ++#define B_AX_DLE_RSV_PGNUM GENMASK(11, 0) ++#define B_AX_DLE_QEMPTY_GRP GENMASK(31, 0) ++ ++#define R_AX_WDE_INI_STATUS 0x8D00 ++#define B_AX_WDE_Q_MGN_INI_RDY BIT(1) ++#define B_AX_WDE_BUF_MGN_INI_RDY BIT(0) ++#define WDE_MGN_INI_RDY (B_AX_WDE_Q_MGN_INI_RDY | B_AX_WDE_BUF_MGN_INI_RDY) ++#define R_AX_WDE_DBG_FUN_INTF_CTL 0x8D10 ++#define B_AX_WDE_DFI_ACTIVE BIT(31) ++#define B_AX_WDE_DFI_TRGSEL_MASK GENMASK(19, 16) ++#define B_AX_WDE_DFI_ADDR_MASK GENMASK(15, 0) ++#define R_AX_WDE_DBG_FUN_INTF_DATA 0x8D14 ++#define B_AX_WDE_DFI_DATA_MASK GENMASK(31, 0) ++ ++#define R_AX_PLE_PKTBUF_CFG 0x9008 ++#define B_AX_PLE_START_BOUND_MASK GENMASK(13, 8) ++#define B_AX_PLE_PAGE_SEL_MASK GENMASK(1, 0) ++#define B_AX_PLE_FREE_PAGE_NUM_MASK GENMASK(28, 16) ++#define R_AX_PLE_ERR_FLAG_CFG 0x9034 ++ ++#define R_AX_PLE_ERR_IMR 0x9038 ++#define B_AX_PLE_GETNPG_STRPG_ERR_INT_EN BIT(5) ++ ++#define R_AX_PLE_ERR_FLAG_ISR 0x903C ++#define B_AX_PLE_MAX_SIZE_MASK GENMASK(27, 16) ++#define B_AX_PLE_MIN_SIZE_MASK GENMASK(11, 0) ++#define R_AX_PLE_QTA0_CFG 0x9040 ++#define R_AX_PLE_QTA1_CFG 0x9044 ++#define R_AX_PLE_QTA2_CFG 0x9048 ++#define R_AX_PLE_QTA3_CFG 0x904C ++#define R_AX_PLE_QTA4_CFG 0x9050 ++#define R_AX_PLE_QTA5_CFG 0x9054 ++#define R_AX_PLE_QTA6_CFG 0x9058 ++#define B_AX_PLE_Q6_MAX_SIZE_MASK GENMASK(27, 16) ++#define B_AX_PLE_Q6_MIN_SIZE_MASK GENMASK(11, 0) ++#define R_AX_PLE_QTA7_CFG 0x905C ++#define R_AX_PLE_QTA8_CFG 0x9060 ++#define R_AX_PLE_QTA9_CFG 0x9064 ++#define R_AX_PLE_QTA10_CFG 0x9068 ++ ++#define R_AX_PLE_INI_STATUS 0x9100 ++#define B_AX_PLE_Q_MGN_INI_RDY BIT(1) ++#define B_AX_PLE_BUF_MGN_INI_RDY BIT(0) ++#define PLE_MGN_INI_RDY (B_AX_PLE_Q_MGN_INI_RDY | B_AX_PLE_BUF_MGN_INI_RDY) ++#define R_AX_PLE_DBG_FUN_INTF_CTL 0x9110 ++#define B_AX_PLE_DFI_ACTIVE BIT(31) ++#define B_AX_PLE_DFI_TRGSEL_MASK GENMASK(19, 16) ++#define B_AX_PLE_DFI_ADDR_MASK GENMASK(15, 0) ++#define R_AX_PLE_DBG_FUN_INTF_DATA 0x9114 ++#define B_AX_PLE_DFI_DATA_MASK GENMASK(31, 0) ++ ++#define R_AX_WDRLS_CFG 0x9408 ++#define B_AX_RLSRPT_BUFREQ_TO_MASK GENMASK(15, 8) ++#define B_AX_WDRLS_MODE_MASK GENMASK(1, 0) ++ ++#define R_AX_RLSRPT0_CFG0 0x9410 ++#define B_AX_RLSRPT0_FLTR_MAP_MASK GENMASK(27, 24) ++#define B_AX_RLSRPT0_PKTTYPE_MASK GENMASK(19, 16) ++#define B_AX_RLSRPT0_PID_MASK GENMASK(10, 8) ++#define B_AX_RLSRPT0_QID_MASK GENMASK(5, 0) ++ ++#define R_AX_RLSRPT0_CFG1 0x9414 ++#define B_AX_RLSRPT0_TO_MASK GENMASK(23, 16) ++#define B_AX_RLSRPT0_AGGNUM_MASK GENMASK(7, 0) ++ ++#define R_AX_WDRLS_ERR_IMR 0x9430 ++#define B_AX_WDRLS_RPT1_FRZTO_ERR_INT_EN BIT(13) ++#define B_AX_WDRLS_RPT1_AGGNUM0_ERR_INT_EN BIT(12) ++#define B_AX_WDRLS_RPT0_FRZTO_ERR_INT_EN BIT(9) ++#define B_AX_WDRLS_RPT0_AGGNUM0_ERR_INT_EN BIT(8) ++#define B_AX_WDRLS_PLEBREQ_PKTID_ISNULL_ERR_INT_EN BIT(5) ++#define B_AX_WDRLS_PLEBREQ_TO_ERR_INT_EN BIT(4) ++#define B_AX_WDRLS_CTL_FRZTO_ERR_INT_EN BIT(2) ++#define B_AX_WDRLS_CTL_PLPKTID_ISNULL_ERR_INT_EN BIT(1) ++#define B_AX_WDRLS_CTL_WDPKTID_ISNULL_ERR_INT_EN BIT(0) ++#define R_AX_WDRLS_ERR_ISR 0x9434 ++ ++#define R_AX_BBRPT_COM_ERR_IMR_ISR 0x960C ++#define R_AX_BBRPT_CHINFO_ERR_IMR_ISR 0x962C ++#define R_AX_BBRPT_DFS_ERR_IMR_ISR 0x963C ++#define R_AX_LA_ERRFLAG 0x966C ++ ++#define R_AX_WD_BUF_REQ 0x9800 ++#define R_AX_PL_BUF_REQ 0x9820 ++#define B_AX_WD_BUF_REQ_EXEC BIT(31) ++#define B_AX_WD_BUF_REQ_QUOTA_ID_MASK GENMASK(23, 16) ++#define B_AX_WD_BUF_REQ_LEN_MASK GENMASK(15, 0) ++ ++#define R_AX_WD_BUF_STATUS 0x9804 ++#define R_AX_PL_BUF_STATUS 0x9824 ++#define B_AX_WD_BUF_STAT_DONE BIT(31) ++#define B_AX_WD_BUF_STAT_PKTID_MASK GENMASK(11, 0) ++ ++#define R_AX_WD_CPUQ_OP_0 0x9810 ++#define R_AX_PL_CPUQ_OP_0 0x9830 ++#define B_AX_WD_CPUQ_OP_EXEC BIT(31) ++#define B_AX_CPUQ_OP_CMD_TYPE_MASK GENMASK(27, 24) ++#define B_AX_CPUQ_OP_MACID_MASK GENMASK(23, 16) ++#define B_AX_CPUQ_OP_PKTNUM_MASK GENMASK(7, 0) ++ ++#define R_AX_WD_CPUQ_OP_1 0x9814 ++#define R_AX_PL_CPUQ_OP_1 0x9834 ++#define B_AX_CPUQ_OP_SRC_PID_MASK GENMASK(24, 22) ++#define B_AX_CPUQ_OP_SRC_QID_MASK GENMASK(21, 16) ++#define B_AX_CPUQ_OP_DST_PID_MASK GENMASK(8, 6) ++#define B_AX_CPUQ_OP_DST_QID_MASK GENMASK(5, 0) ++ ++#define R_AX_WD_CPUQ_OP_2 0x9818 ++#define R_AX_PL_CPUQ_OP_2 0x9838 ++#define B_AX_WD_CPUQ_OP_STRT_PKTID_MASK GENMASK(27, 16) ++#define B_AX_WD_CPUQ_OP_END_PKTID_MASK GENMASK(11, 0) ++ ++#define R_AX_WD_CPUQ_OP_STATUS 0x981C ++#define R_AX_PL_CPUQ_OP_STATUS 0x983C ++#define B_AX_WD_CPUQ_OP_STAT_DONE BIT(31) ++#define B_AX_WD_CPUQ_OP_PKTID_MASK GENMASK(11, 0) ++#define R_AX_CPUIO_ERR_IMR 0x9840 ++#define R_AX_CPUIO_ERR_ISR 0x9844 ++ ++#define R_AX_SEC_ERR_IMR_ISR 0x991C ++ ++#define R_AX_PKTIN_SETTING 0x9A00 ++#define B_AX_WD_ADDR_INFO_LENGTH BIT(1) ++#define R_AX_PKTIN_ERR_IMR 0x9A20 ++#define R_AX_PKTIN_ERR_ISR 0x9A24 ++ ++#define R_AX_MPDU_TX_ERR_ISR 0x9BF0 ++#define R_AX_MPDU_TX_ERR_IMR 0x9BF4 ++ ++#define R_AX_MPDU_PROC 0x9C00 ++#define B_AX_A_ICV_ERR BIT(1) ++#define B_AX_APPEND_FCS BIT(0) ++ ++#define R_AX_ACTION_FWD0 0x9C04 ++#define TRXCFG_MPDU_PROC_ACT_FRWD 0x02A95A95 ++ ++#define R_AX_TF_FWD 0x9C14 ++#define TRXCFG_MPDU_PROC_TF_FRWD 0x0000AA55 ++ ++#define R_AX_HW_RPT_FWD 0x9C18 ++#define B_AX_FWD_PPDU_STAT_MASK GENMASK(1, 0) ++#define RTW89_PRPT_DEST_HOST 1 ++#define RTW89_PRPT_DEST_WLCPU 2 ++ ++#define R_AX_CUT_AMSDU_CTRL 0x9C40 ++#define TRXCFG_MPDU_PROC_CUT_CTRL 0x010E05F0 ++ ++#define R_AX_MPDU_RX_ERR_ISR 0x9CF0 ++#define R_AX_MPDU_RX_ERR_IMR 0x9CF4 ++ ++#define R_AX_SEC_ENG_CTRL 0x9D00 ++#define B_AX_TX_PARTIAL_MODE BIT(11) ++#define B_AX_CLK_EN_CGCMP BIT(10) ++#define B_AX_CLK_EN_WAPI BIT(9) ++#define B_AX_CLK_EN_WEP_TKIP BIT(8) ++#define B_AX_BMC_MGNT_DEC BIT(5) ++#define B_AX_UC_MGNT_DEC BIT(4) ++#define B_AX_MC_DEC BIT(3) ++#define B_AX_BC_DEC BIT(2) ++#define B_AX_SEC_RX_DEC BIT(1) ++#define B_AX_SEC_TX_ENC BIT(0) ++ ++#define R_AX_SEC_MPDU_PROC 0x9D04 ++#define B_AX_APPEND_ICV BIT(1) ++#define B_AX_APPEND_MIC BIT(0) ++ ++#define R_AX_SEC_CAM_ACCESS 0x9D10 ++#define R_AX_SEC_CAM_RDATA 0x9D14 ++#define R_AX_SEC_CAM_WDATA 0x9D18 ++#define R_AX_SEC_DEBUG 0x9D1C ++#define R_AX_SEC_TX_DEBUG 0x9D20 ++#define R_AX_SEC_RX_DEBUG 0x9D24 ++#define R_AX_SEC_TRX_PKT_CNT 0x9D28 ++#define R_AX_SEC_TRX_BLK_CNT 0x9D2C ++ ++#define R_AX_SS_CTRL 0x9E10 ++#define B_AX_SS_INIT_DONE_1 BIT(31) ++#define B_AX_SS_WARM_INIT_FLG BIT(29) ++#define B_AX_SS_EN BIT(0) ++ ++#define R_AX_SS_MACID_PAUSE_0 0x9EB0 ++#define B_AX_SS_MACID31_0_PAUSE_SH 0 ++#define B_AX_SS_MACID31_0_PAUSE_MASK GENMASK(31, 0) ++ ++#define R_AX_SS_MACID_PAUSE_1 0x9EB4 ++#define B_AX_SS_MACID63_32_PAUSE_SH 0 ++#define B_AX_SS_MACID63_32_PAUSE_MASK GENMASK(31, 0) ++ ++#define R_AX_SS_MACID_PAUSE_2 0x9EB8 ++#define B_AX_SS_MACID95_64_PAUSE_SH 0 ++#define B_AX_SS_MACID95_64_PAUSE_MASK GENMASK(31, 0) ++ ++#define R_AX_SS_MACID_PAUSE_3 0x9EBC ++#define B_AX_SS_MACID127_96_PAUSE_SH 0 ++#define B_AX_SS_MACID127_96_PAUSE_MASK GENMASK(31, 0) ++ ++#define R_AX_STA_SCHEDULER_ERR_IMR 0x9EF0 ++#define R_AX_STA_SCHEDULER_ERR_ISR 0x9EF4 ++ ++#define R_AX_TXPKTCTL_ERR_IMR_ISR 0x9F1C ++#define R_AX_TXPKTCTL_ERR_IMR_ISR_B1 0x9F2C ++#define B_AX_TXPKTCTL_CMDPSR_FRZTO_ERR_INT_EN BIT(9) ++#define B_AX_TXPKTCTL_USRCTL_RLSBMPLEN_ERR_INT_EN BIT(3) ++#define B_AX_TXPKTCTL_USRCTL_RDNRLSCMD_ERR_INT_EN BIT(2) ++#define B_AX_TXPKTCTL_USRCTL_NOINIT_ERR_INT_EN BIT(1) ++ ++#define R_AX_DBG_FUN_INTF_CTL 0x9F30 ++#define B_AX_DFI_ACTIVE BIT(31) ++#define B_AX_DFI_TRGSEL_MASK GENMASK(19, 16) ++#define B_AX_DFI_ADDR_MASK GENMASK(15, 0) ++#define R_AX_DBG_FUN_INTF_DATA 0x9F34 ++#define B_AX_DFI_DATA_MASK GENMASK(31, 0) ++ ++#define R_AX_AFE_CTRL1 0x0024 ++ ++#define B_AX_R_SYM_WLCMAC1_P4_PC_EN BIT(4) ++#define B_AX_R_SYM_WLCMAC1_P3_PC_EN BIT(3) ++#define B_AX_R_SYM_WLCMAC1_P2_PC_EN BIT(2) ++#define B_AX_R_SYM_WLCMAC1_P1_PC_EN BIT(1) ++#define B_AX_R_SYM_WLCMAC1_PC_EN BIT(0) ++ ++#define R_AX_SYS_ISO_CTRL_EXTEND 0x0080 ++#define B_AX_CMAC1_FEN BIT(30) ++#define B_AX_R_SYM_FEN_WLBBGLB_1 BIT(17) ++#define B_AX_R_SYM_FEN_WLBBFUN_1 BIT(16) ++#define B_AX_R_SYM_ISO_CMAC12PP BIT(5) ++ ++#define R_AX_CMAC_REG_START 0xC000 ++ ++#define R_AX_CMAC_FUNC_EN 0xC000 ++#define R_AX_CMAC_FUNC_EN_C1 0xE000 ++#define B_AX_CMAC_CRPRT BIT(31) ++#define B_AX_CMAC_EN BIT(30) ++#define B_AX_CMAC_TXEN BIT(29) ++#define B_AX_CMAC_RXEN BIT(28) ++#define B_AX_FORCE_CMACREG_GCKEN BIT(15) ++#define B_AX_PHYINTF_EN BIT(5) ++#define B_AX_CMAC_DMA_EN BIT(4) ++#define B_AX_PTCLTOP_EN BIT(3) ++#define B_AX_SCHEDULER_EN BIT(2) ++#define B_AX_TMAC_EN BIT(1) ++#define B_AX_RMAC_EN BIT(0) ++ ++#define R_AX_CK_EN 0xC004 ++#define R_AX_CK_EN_C1 0xE004 ++#define B_AX_CMAC_ALLCKEN GENMASK(31, 0) ++#define B_AX_CMAC_CKEN BIT(30) ++#define B_AX_PHYINTF_CKEN BIT(5) ++#define B_AX_CMAC_DMA_CKEN BIT(4) ++#define B_AX_PTCLTOP_CKEN BIT(3) ++#define B_AX_SCHEDULER_CKEN BIT(2) ++#define B_AX_TMAC_CKEN BIT(1) ++#define B_AX_RMAC_CKEN BIT(0) ++ ++#define R_AX_WMAC_RFMOD 0xC010 ++#define R_AX_WMAC_RFMOD_C1 0xE010 ++#define B_AX_WMAC_RFMOD_MASK GENMASK(1, 0) ++ ++#define R_AX_GID_POSITION0 0xC070 ++#define R_AX_GID_POSITION0_C1 0xE070 ++#define R_AX_GID_POSITION1 0xC074 ++#define R_AX_GID_POSITION1_C1 0xE074 ++#define R_AX_GID_POSITION2 0xC078 ++#define R_AX_GID_POSITION2_C1 0xE078 ++#define R_AX_GID_POSITION3 0xC07C ++#define R_AX_GID_POSITION3_C1 0xE07C ++#define R_AX_GID_POSITION_EN0 0xC080 ++#define R_AX_GID_POSITION_EN0_C1 0xE080 ++#define R_AX_GID_POSITION_EN1 0xC084 ++#define R_AX_GID_POSITION_EN1_C1 0xE084 ++ ++#define R_AX_TX_SUB_CARRIER_VALUE 0xC088 ++#define R_AX_TX_SUB_CARRIER_VALUE_C1 0xE088 ++#define B_AX_TXSC_80M_MASK GENMASK(11, 8) ++#define B_AX_TXSC_40M_MASK GENMASK(7, 4) ++#define B_AX_TXSC_20M_MASK GENMASK(3, 0) ++ ++#define R_AX_CMAC_ERR_ISR 0xC164 ++#define R_AX_CMAC_ERR_ISR_C1 0xE164 ++#define B_AX_WMAC_TX_ERR_IND BIT(7) ++#define B_AX_WMAC_RX_ERR_IND BIT(6) ++#define B_AX_TXPWR_CTRL_ERR_IND BIT(5) ++#define B_AX_PHYINTF_ERR_IND BIT(4) ++#define B_AX_DMA_TOP_ERR_IND BIT(3) ++#define B_AX_PTCL_TOP_ERR_IND BIT(1) ++#define B_AX_SCHEDULE_TOP_ERR_IND BIT(0) ++ ++#define R_AX_MACID_SLEEP_0 0xC2C0 ++#define R_AX_MACID_SLEEP_0_C1 0xE2C0 ++#define B_AX_MACID31_0_SLEEP_SH 0 ++#define B_AX_MACID31_0_SLEEP_MASK GENMASK(31, 0) ++ ++#define R_AX_MACID_SLEEP_1 0xC2C4 ++#define R_AX_MACID_SLEEP_1_C1 0xE2C4 ++#define B_AX_MACID63_32_SLEEP_SH 0 ++#define B_AX_MACID63_32_SLEEP_MASK GENMASK(31, 0) ++ ++#define R_AX_MACID_SLEEP_2 0xC2C8 ++#define R_AX_MACID_SLEEP_2_C1 0xE2C8 ++#define B_AX_MACID95_64_SLEEP_SH 0 ++#define B_AX_MACID95_64_SLEEP_MASK GENMASK(31, 0) ++ ++#define R_AX_MACID_SLEEP_3 0xC2CC ++#define R_AX_MACID_SLEEP_3_C1 0xE2CC ++#define B_AX_MACID127_96_SLEEP_SH 0 ++#define B_AX_MACID127_96_SLEEP_MASK GENMASK(31, 0) ++ ++#define SCH_PREBKF_24US 0x18 ++#define R_AX_PREBKF_CFG_0 0xC338 ++#define R_AX_PREBKF_CFG_0_C1 0xE338 ++#define B_AX_PREBKF_TIME_MASK GENMASK(4, 0) ++ ++#define R_AX_CCA_CFG_0 0xC340 ++#define R_AX_CCA_CFG_0_C1 0xE340 ++#define B_AX_BTCCA_BRK_TXOP_EN BIT(9) ++#define B_AX_BTCCA_EN BIT(5) ++#define B_AX_EDCCA_EN BIT(4) ++#define B_AX_SEC80_EN BIT(3) ++#define B_AX_SEC40_EN BIT(2) ++#define B_AX_SEC20_EN BIT(1) ++#define B_AX_CCA_EN BIT(0) ++ ++#define R_AX_CTN_TXEN 0xC348 ++#define R_AX_CTN_TXEN_C1 0xE348 ++#define B_AX_CTN_TXEN_TWT_1 BIT(15) ++#define B_AX_CTN_TXEN_TWT_0 BIT(14) ++#define B_AX_CTN_TXEN_ULQ BIT(13) ++#define B_AX_CTN_TXEN_BCNQ BIT(12) ++#define B_AX_CTN_TXEN_HGQ BIT(11) ++#define B_AX_CTN_TXEN_CPUMGQ BIT(10) ++#define B_AX_CTN_TXEN_MGQ1 BIT(9) ++#define B_AX_CTN_TXEN_MGQ BIT(8) ++#define B_AX_CTN_TXEN_VO_1 BIT(7) ++#define B_AX_CTN_TXEN_VI_1 BIT(6) ++#define B_AX_CTN_TXEN_BK_1 BIT(5) ++#define B_AX_CTN_TXEN_BE_1 BIT(4) ++#define B_AX_CTN_TXEN_VO_0 BIT(3) ++#define B_AX_CTN_TXEN_VI_0 BIT(2) ++#define B_AX_CTN_TXEN_BK_0 BIT(1) ++#define B_AX_CTN_TXEN_BE_0 BIT(0) ++ ++#define R_AX_MUEDCA_BE_PARAM_0 0xC350 ++#define R_AX_MUEDCA_BE_PARAM_0_C1 0xE350 ++#define B_AX_MUEDCA_BE_PARAM_0_TIMER_MASK GENMASK(31, 16) ++#define B_AX_MUEDCA_BE_PARAM_0_CW_MASK GENMASK(15, 8) ++#define B_AX_MUEDCA_BE_PARAM_0_AIFS_MASK GENMASK(7, 0) ++ ++#define R_AX_MUEDCA_BK_PARAM_0 0xC354 ++#define R_AX_MUEDCA_BK_PARAM_0_C1 0xE354 ++#define R_AX_MUEDCA_VI_PARAM_0 0xC358 ++#define R_AX_MUEDCA_VI_PARAM_0_C1 0xE358 ++#define R_AX_MUEDCA_VO_PARAM_0 0xC35C ++#define R_AX_MUEDCA_VO_PARAM_0_C1 0xE35C ++ ++#define R_AX_MUEDCA_EN 0xC370 ++#define R_AX_MUEDCA_EN_C1 0xE370 ++#define B_AX_MUEDCA_WMM_SEL BIT(8) ++#define B_AX_SET_MUEDCATIMER_TF_0 BIT(4) ++#define B_AX_MUEDCA_EN_0 BIT(0) ++ ++#define R_AX_CCA_CONTROL 0xC390 ++#define R_AX_CCA_CONTROL_C1 0xE390 ++#define B_AX_TB_CHK_TX_NAV BIT(31) ++#define B_AX_TB_CHK_BASIC_NAV BIT(30) ++#define B_AX_TB_CHK_BTCCA BIT(29) ++#define B_AX_TB_CHK_EDCCA BIT(28) ++#define B_AX_TB_CHK_CCA_S80 BIT(27) ++#define B_AX_TB_CHK_CCA_S40 BIT(26) ++#define B_AX_TB_CHK_CCA_S20 BIT(25) ++#define B_AX_TB_CHK_CCA_P20 BIT(24) ++#define B_AX_SIFS_CHK_BTCCA BIT(21) ++#define B_AX_SIFS_CHK_EDCCA BIT(20) ++#define B_AX_SIFS_CHK_CCA_S80 BIT(19) ++#define B_AX_SIFS_CHK_CCA_S40 BIT(18) ++#define B_AX_SIFS_CHK_CCA_S20 BIT(17) ++#define B_AX_SIFS_CHK_CCA_P20 BIT(16) ++#define B_AX_CTN_CHK_TXNAV BIT(8) ++#define B_AX_CTN_CHK_INTRA_NAV BIT(7) ++#define B_AX_CTN_CHK_BASIC_NAV BIT(6) ++#define B_AX_CTN_CHK_BTCCA BIT(5) ++#define B_AX_CTN_CHK_EDCCA BIT(4) ++#define B_AX_CTN_CHK_CCA_S80 BIT(3) ++#define B_AX_CTN_CHK_CCA_S40 BIT(2) ++#define B_AX_CTN_CHK_CCA_S20 BIT(1) ++#define B_AX_CTN_CHK_CCA_P20 BIT(0) ++ ++#define R_AX_SCHEDULE_ERR_IMR 0xC3E8 ++#define R_AX_SCHEDULE_ERR_IMR_C1 0xE3E8 ++#define B_AX_SORT_NON_IDLE_ERR_INT_EN BIT(1) ++#define B_AX_FSM_TIMEOUT_ERR_INT_EN BIT(0) ++ ++#define R_AX_SCHEDULE_ERR_ISR 0xC3EC ++#define R_AX_SCHEDULE_ERR_ISR_C1 0xE3EC ++ ++#define R_AX_SCH_DBG_SEL 0xC3F4 ++#define R_AX_SCH_DBG_SEL_C1 0xE3F4 ++#define B_AX_SCH_DBG_EN BIT(16) ++#define B_AX_SCH_CFG_CMD_SEL GENMASK(15, 8) ++#define B_AX_SCH_DBG_SEL_MASK GENMASK(7, 0) ++ ++#define R_AX_SCH_DBG 0xC3F8 ++#define R_AX_SCH_DBG_C1 0xE3F8 ++#define B_AX_SCHEDULER_DBG_MASK GENMASK(31, 0) ++ ++#define R_AX_PORT_CFG_P0 0xC400 ++#define R_AX_PORT_CFG_P1 0xC440 ++#define R_AX_PORT_CFG_P2 0xC480 ++#define R_AX_PORT_CFG_P3 0xC4C0 ++#define R_AX_PORT_CFG_P4 0xC500 ++#define B_AX_BRK_SETUP BIT(16) ++#define B_AX_TBTT_UPD_SHIFT_SEL BIT(15) ++#define B_AX_BCN_DROP_ALLOW BIT(14) ++#define B_AX_TBTT_PROHIB_EN BIT(13) ++#define B_AX_BCNTX_EN BIT(12) ++#define B_AX_NET_TYPE_MASK GENMASK(11, 10) ++#define B_AX_BCN_FORCETX_EN BIT(9) ++#define B_AX_TXBCN_BTCCA_EN BIT(8) ++#define B_AX_BCNERR_CNT_EN BIT(7) ++#define B_AX_BCN_AGRES BIT(6) ++#define B_AX_TSFTR_RST BIT(5) ++#define B_AX_RX_BSSID_FIT_EN BIT(4) ++#define B_AX_TSF_UDT_EN BIT(3) ++#define B_AX_PORT_FUNC_EN BIT(2) ++#define B_AX_TXBCN_RPT_EN BIT(1) ++#define B_AX_RXBCN_RPT_EN BIT(0) ++ ++#define R_AX_TBTT_PROHIB_P0 0xC404 ++#define R_AX_TBTT_PROHIB_P1 0xC444 ++#define R_AX_TBTT_PROHIB_P2 0xC484 ++#define R_AX_TBTT_PROHIB_P3 0xC4C4 ++#define R_AX_TBTT_PROHIB_P4 0xC504 ++#define B_AX_TBTT_HOLD_MASK GENMASK(27, 16) ++#define B_AX_TBTT_SETUP_MASK GENMASK(7, 0) ++ ++#define R_AX_BCN_AREA_P0 0xC408 ++#define R_AX_BCN_AREA_P1 0xC448 ++#define R_AX_BCN_AREA_P2 0xC488 ++#define R_AX_BCN_AREA_P3 0xC4C8 ++#define R_AX_BCN_AREA_P4 0xC508 ++#define B_AX_BCN_MSK_AREA_MASK GENMASK(27, 16) ++#define B_AX_BCN_CTN_AREA_MASK GENMASK(11, 0) ++ ++#define R_AX_BCNERLYINT_CFG_P0 0xC40C ++#define R_AX_BCNERLYINT_CFG_P1 0xC44C ++#define R_AX_BCNERLYINT_CFG_P2 0xC48C ++#define R_AX_BCNERLYINT_CFG_P3 0xC4CC ++#define R_AX_BCNERLYINT_CFG_P4 0xC50C ++#define B_AX_BCNERLY_MASK GENMASK(11, 0) ++ ++#define R_AX_TBTTERLYINT_CFG_P0 0xC40E ++#define R_AX_TBTTERLYINT_CFG_P1 0xC44E ++#define R_AX_TBTTERLYINT_CFG_P2 0xC48E ++#define R_AX_TBTTERLYINT_CFG_P3 0xC4CE ++#define R_AX_TBTTERLYINT_CFG_P4 0xC50E ++#define B_AX_TBTTERLY_MASK GENMASK(11, 0) ++ ++#define R_AX_TBTT_AGG_P0 0xC412 ++#define R_AX_TBTT_AGG_P1 0xC452 ++#define R_AX_TBTT_AGG_P2 0xC492 ++#define R_AX_TBTT_AGG_P3 0xC4D2 ++#define R_AX_TBTT_AGG_P4 0xC512 ++#define B_AX_TBTT_AGG_NUM_MASK GENMASK(15, 8) ++ ++#define R_AX_BCN_SPACE_CFG_P0 0xC414 ++#define R_AX_BCN_SPACE_CFG_P1 0xC454 ++#define R_AX_BCN_SPACE_CFG_P2 0xC494 ++#define R_AX_BCN_SPACE_CFG_P3 0xC4D4 ++#define R_AX_BCN_SPACE_CFG_P4 0xC514 ++#define B_AX_SUB_BCN_SPACE_MASK GENMASK(23, 16) ++#define B_AX_BCN_SPACE_MASK GENMASK(15, 0) ++ ++#define R_AX_BCN_FORCETX_P0 0xC418 ++#define R_AX_BCN_FORCETX_P1 0xC458 ++#define R_AX_BCN_FORCETX_P2 0xC498 ++#define R_AX_BCN_FORCETX_P3 0xC4D8 ++#define R_AX_BCN_FORCETX_P4 0xC518 ++#define B_AX_FORCE_BCN_CURRCNT_MASK GENMASK(23, 16) ++#define B_AX_FORCE_BCN_NUM_MASK GENMASK(15, 0) ++#define B_AX_BCN_MAX_ERR_MASK GENMASK(7, 0) ++ ++#define R_AX_BCN_ERR_CNT_P0 0xC420 ++#define R_AX_BCN_ERR_CNT_P1 0xC460 ++#define R_AX_BCN_ERR_CNT_P2 0xC4A0 ++#define R_AX_BCN_ERR_CNT_P3 0xC4E0 ++#define R_AX_BCN_ERR_CNT_P4 0xC520 ++#define B_AX_BCN_ERR_CNT_SUM_MASK GENMASK(31, 24) ++#define B_AX_BCN_ERR_CNT_NAV_MASK GENMASK(23, 16) ++#define B_AX_BCN_ERR_CNT_EDCCA_MASK GENMASK(15, 0) ++#define B_AX_BCN_ERR_CNT_CCA_MASK GENMASK(7, 0) ++ ++#define R_AX_BCN_ERR_FLAG_P0 0xC424 ++#define R_AX_BCN_ERR_FLAG_P1 0xC464 ++#define R_AX_BCN_ERR_FLAG_P2 0xC4A4 ++#define R_AX_BCN_ERR_FLAG_P3 0xC4E4 ++#define R_AX_BCN_ERR_FLAG_P4 0xC524 ++#define B_AX_BCN_ERR_FLAG_OTHERS BIT(6) ++#define B_AX_BCN_ERR_FLAG_MAC BIT(5) ++#define B_AX_BCN_ERR_FLAG_TXON BIT(4) ++#define B_AX_BCN_ERR_FLAG_SRCHEND BIT(3) ++#define B_AX_BCN_ERR_FLAG_INVALID BIT(2) ++#define B_AX_BCN_ERR_FLAG_CMP BIT(1) ++#define B_AX_BCN_ERR_FLAG_LOCK BIT(0) ++ ++#define R_AX_DTIM_CTRL_P0 0xC426 ++#define R_AX_DTIM_CTRL_P1 0xC466 ++#define R_AX_DTIM_CTRL_P2 0xC4A6 ++#define R_AX_DTIM_CTRL_P3 0xC4E6 ++#define R_AX_DTIM_CTRL_P4 0xC526 ++#define B_AX_DTIM_NUM_MASK GENMASK(15, 0) ++#define B_AX_DTIM_CURRCNT_MASK GENMASK(7, 0) ++ ++#define R_AX_TBTT_SHIFT_P0 0xC428 ++#define R_AX_TBTT_SHIFT_P1 0xC468 ++#define R_AX_TBTT_SHIFT_P2 0xC4A8 ++#define R_AX_TBTT_SHIFT_P3 0xC4E8 ++#define R_AX_TBTT_SHIFT_P4 0xC528 ++#define B_AX_TBTT_SHIFT_OFST_MASK GENMASK(11, 0) ++ ++#define R_AX_BCN_CNT_TMR_P0 0xC434 ++#define R_AX_BCN_CNT_TMR_P1 0xC474 ++#define R_AX_BCN_CNT_TMR_P2 0xC4B4 ++#define R_AX_BCN_CNT_TMR_P3 0xC4F4 ++#define R_AX_BCN_CNT_TMR_P4 0xC534 ++#define B_AX_BCN_CNT_TMR_MASK GENMASK(31, 0) ++ ++#define R_AX_TSFTR_LOW_P0 0xC438 ++#define R_AX_TSFTR_LOW_P1 0xC478 ++#define R_AX_TSFTR_LOW_P2 0xC4B8 ++#define R_AX_TSFTR_LOW_P3 0xC4F8 ++#define R_AX_TSFTR_LOW_P4 0xC538 ++#define B_AX_TSFTR_LOW_MASK GENMASK(31, 0) ++ ++#define R_AX_TSFTR_HIGH_P0 0xC43C ++#define R_AX_TSFTR_HIGH_P1 0xC47C ++#define R_AX_TSFTR_HIGH_P2 0xC4BC ++#define R_AX_TSFTR_HIGH_P3 0xC4FC ++#define R_AX_TSFTR_HIGH_P4 0xC53C ++#define B_AX_TSFTR_HIGH_MASK GENMASK(31, 0) ++ ++#define R_AX_MBSSID_CTRL 0xC568 ++#define R_AX_MBSSID_CTRL_C1 0xE568 ++#define B_AX_P0MB_ALL_MASK GENMASK(23, 1) ++#define B_AX_P0MB_NUM_MASK GENMASK(19, 16) ++#define B_AX_P0MB15_EN BIT(15) ++#define B_AX_P0MB14_EN BIT(14) ++#define B_AX_P0MB13_EN BIT(13) ++#define B_AX_P0MB12_EN BIT(12) ++#define B_AX_P0MB11_EN BIT(11) ++#define B_AX_P0MB10_EN BIT(10) ++#define B_AX_P0MB9_EN BIT(9) ++#define B_AX_P0MB8_EN BIT(8) ++#define B_AX_P0MB7_EN BIT(7) ++#define B_AX_P0MB6_EN BIT(6) ++#define B_AX_P0MB5_EN BIT(5) ++#define B_AX_P0MB4_EN BIT(4) ++#define B_AX_P0MB3_EN BIT(3) ++#define B_AX_P0MB2_EN BIT(2) ++#define B_AX_P0MB1_EN BIT(1) ++ ++#define R_AX_AMPDU_AGG_LIMIT 0xC610 ++#define B_AX_AMPDU_MAX_TIME_MASK GENMASK(31, 24) ++#define B_AX_RA_TRY_RATE_AGG_LMT_MASK GENMASK(23, 16) ++#define B_AX_RTS_MAX_AGG_NUM_MASK GENMASK(15, 8) ++#define B_AX_MAX_AGG_NUM_MASK GENMASK(7, 0) ++ ++#define R_AX_AGG_LEN_HT_0 0xC614 ++#define R_AX_AGG_LEN_HT_0_C1 0xE614 ++#define B_AX_AMPDU_MAX_LEN_HT_MASK GENMASK(31, 16) ++#define B_AX_RTS_TXTIME_TH_MASK GENMASK(15, 8) ++#define B_AX_RTS_LEN_TH_MASK GENMASK(7, 0) ++ ++#define S_AX_CTS2S_TH_SEC_256B 1 ++#define R_AX_SIFS_SETTING 0xC624 ++#define R_AX_SIFS_SETTING_C1 0xE624 ++#define B_AX_HW_CTS2SELF_PKT_LEN_TH_MASK GENMASK(31, 24) ++#define B_AX_HW_CTS2SELF_PKT_LEN_TH_TWW_MASK GENMASK(23, 18) ++#define B_AX_HW_CTS2SELF_EN BIT(16) ++#define B_AX_SPEC_SIFS_OFDM_PTCL_SH 8 ++#define B_AX_SPEC_SIFS_OFDM_PTCL_MASK GENMASK(15, 8) ++#define B_AX_SPEC_SIFS_CCK_PTCL_MASK GENMASK(7, 0) ++#define S_AX_CTS2S_TH_1K 4 ++ ++#define R_AX_TXRATE_CHK 0xC628 ++#define R_AX_TXRATE_CHK_C1 0xE628 ++#define B_AX_DEFT_RATE_MASK GENMASK(15, 7) ++#define B_AX_BAND_MODE BIT(4) ++#define B_AX_MAX_TXNSS_MASK GENMASK(3, 2) ++#define B_AX_RTS_LIMIT_IN_OFDM6 BIT(1) ++#define B_AX_CHECK_CCK_EN BIT(0) ++ ++#define R_AX_TXCNT 0xC62C ++#define R_AX_TXCNT_C1 0xE62C ++#define B_AX_ADD_TXCNT_BY BIT(31) ++#define B_AX_S_TXCNT_LMT_MASK GENMASK(29, 24) ++#define B_AX_L_TXCNT_LMT_MASK GENMASK(21, 16) ++ ++#define R_AX_MBSSID_DROP_0 0xC63C ++#define R_AX_MBSSID_DROP_0_C1 0xE63C ++#define B_AX_GI_LTF_FB_SEL BIT(30) ++#define B_AX_RATE_SEL_MASK GENMASK(29, 24) ++#define B_AX_PORT_DROP_4_0_MASK GENMASK(20, 16) ++#define B_AX_MBSSID_DROP_15_0_MASK GENMASK(15, 0) ++ ++#define R_AX_BT_PLT 0xC67C ++#define R_AX_BT_PLT_C1 0xE67C ++#define B_AX_BT_PLT_PKT_CNT_MASK GENMASK(31, 16) ++#define B_AX_BT_PLT_RST BIT(9) ++#define B_AX_PLT_EN BIT(8) ++#define B_AX_RX_PLT_GNT_LTE_RX BIT(7) ++#define B_AX_RX_PLT_GNT_BT_RX BIT(6) ++#define B_AX_RX_PLT_GNT_BT_TX BIT(5) ++#define B_AX_RX_PLT_GNT_WL BIT(4) ++#define B_AX_TX_PLT_GNT_LTE_RX BIT(3) ++#define B_AX_TX_PLT_GNT_BT_RX BIT(2) ++#define B_AX_TX_PLT_GNT_BT_TX BIT(1) ++#define B_AX_TX_PLT_GNT_WL BIT(0) ++ ++#define R_AX_PTCL_BSS_COLOR_0 0xC6A0 ++#define R_AX_PTCL_BSS_COLOR_0_C1 0xE6A0 ++#define B_AX_BSS_COLOB_AX_PORT_3_MASK GENMASK(29, 24) ++#define B_AX_BSS_COLOB_AX_PORT_2_MASK GENMASK(21, 16) ++#define B_AX_BSS_COLOB_AX_PORT_1_MASK GENMASK(13, 8) ++#define B_AX_BSS_COLOB_AX_PORT_0_MASK GENMASK(5, 0) ++ ++#define R_AX_PTCL_BSS_COLOR_1 0xC6A4 ++#define R_AX_PTCL_BSS_COLOR_1_C1 0xE6A4 ++#define B_AX_BSS_COLOB_AX_PORT_4_MASK GENMASK(5, 0) ++ ++#define R_AX_PTCL_IMR0 0xC6C0 ++#define R_AX_PTCL_IMR0_C1 0xE6C0 ++#define B_AX_F2PCMD_USER_ALLC_ERR_INT_EN BIT(28) ++#define B_AX_TX_RECORD_PKTID_ERR_INT_EN BIT(23) ++ ++#define R_AX_PTCL_ISR0 0xC6C4 ++#define R_AX_PTCL_ISR0_C1 0xE6C4 ++ ++#define S_AX_PTCL_TO_2MS 0x3F ++#define R_AX_PTCL_FSM_MON 0xC6E8 ++#define R_AX_PTCL_FSM_MON_C1 0xE6E8 ++#define B_AX_PTCL_TX_ARB_TO_MODE BIT(6) ++#define B_AX_PTCL_TX_ARB_TO_THR_MASK GENMASK(5, 0) ++ ++#define R_AX_PTCL_TX_CTN_SEL 0xC6EC ++#define R_AX_PTCL_TX_CTN_SEL_C1 0xE6EC ++#define B_AX_PTCL_TX_ON_STAT BIT(7) ++ ++#define R_AX_PTCL_DBG_INFO 0xC6F0 ++#define R_AX_PTCL_DBG_INFO_C1 0xE6F0 ++#define B_AX_PTCL_DBG_INFO_MASK GENMASK(31, 0) ++#define R_AX_PTCL_DBG 0xC6F4 ++#define R_AX_PTCL_DBG_C1 0xE6F4 ++#define B_AX_PTCL_DBG_EN BIT(8) ++#define B_AX_PTCL_DBG_SEL_MASK GENMASK(7, 0) ++ ++#define R_AX_DLE_CTRL 0xC800 ++#define R_AX_DLE_CTRL_C1 0xE800 ++#define B_AX_NO_RESERVE_PAGE_ERR_IMR BIT(23) ++#define B_AX_RXDATA_FSM_HANG_ERROR_IMR BIT(15) ++#define R_AX_RXDMA_PKT_INFO_0 0xC814 ++#define R_AX_RXDMA_PKT_INFO_1 0xC818 ++#define R_AX_RXDMA_PKT_INFO_2 0xC81C ++ ++#define R_AX_TCR1 0xCA04 ++#define R_AX_TCR1_C1 0xEA04 ++#define B_AX_TXDFIFO_THRESHOLD GENMASK(31, 28) ++#define B_AX_TCR_CCK_LOCK_CLK BIT(27) ++#define B_AX_TCR_FORCE_READ_TXDFIFO BIT(26) ++#define B_AX_TCR_USTIME GENMASK(23, 16) ++#define B_AX_TCR_SMOOTH_VAL BIT(15) ++#define B_AX_TCR_SMOOTH_CTRL BIT(14) ++#define B_AX_CS_REQ_VAL BIT(13) ++#define B_AX_CS_REQ_SEL BIT(12) ++#define B_AX_TCR_ZLD_USTIME_AFTERPHYTXON GENMASK(11, 8) ++#define B_AX_TCR_TXTIMEOUT GENMASK(7, 0) ++ ++#define R_AX_PPWRBIT_SETTING 0xCA0C ++#define R_AX_PPWRBIT_SETTING_C1 0xEA0C ++ ++#define R_AX_MACTX_DBG_SEL_CNT 0xCA20 ++#define R_AX_MACTX_DBG_SEL_CNT_C1 0xEA20 ++#define B_AX_MACTX_MPDU_CNT GENMASK(31, 24) ++#define B_AX_MACTX_DMA_CNT GENMASK(23, 16) ++#define B_AX_LENGTH_ERR_FLAG_U3 BIT(11) ++#define B_AX_LENGTH_ERR_FLAG_U2 BIT(10) ++#define B_AX_LENGTH_ERR_FLAG_U1 BIT(9) ++#define B_AX_LENGTH_ERR_FLAG_U0 BIT(8) ++#define B_AX_DBGSEL_MACTX_MASK GENMASK(5, 0) ++ ++#define R_AX_WMAC_TX_CTRL_DEBUG 0xCAE4 ++#define R_AX_WMAC_TX_CTRL_DEBUG_C1 0xEAE4 ++#define B_AX_TX_CTRL_DEBUG_SEL_MASK GENMASK(3, 0) ++ ++#define R_AX_WMAC_TX_INFO0_DEBUG 0xCAE8 ++#define R_AX_WMAC_TX_INFO0_DEBUG_C1 0xEAE8 ++#define B_AX_TX_CTRL_INFO_P0_MASK GENMASK(31, 0) ++ ++#define R_AX_WMAC_TX_INFO1_DEBUG 0xCAEC ++#define R_AX_WMAC_TX_INFO1_DEBUG_C1 0xEAEC ++#define B_AX_TX_CTRL_INFO_P1_MASK GENMASK(31, 0) ++ ++#define R_AX_RSP_CHK_SIG 0xCC00 ++#define R_AX_RSP_CHK_SIG_C1 0xEC00 ++#define B_AX_RSP_STATIC_RTS_CHK_SERV_BW_EN BIT(30) ++#define B_AX_RSP_TBPPDU_CHK_PWR BIT(29) ++#define B_AX_RSP_CHK_BASIC_NAV BIT(21) ++#define B_AX_RSP_CHK_INTRA_NAV BIT(20) ++#define B_AX_RSP_CHK_TXNAV BIT(19) ++#define B_AX_TXDATA_END_PS_OPT BIT(18) ++#define B_AX_CHECK_SOUNDING_SEQ BIT(17) ++#define B_AX_RXBA_IGNOREA2 BIT(16) ++#define B_AX_ACKTO_CCK_MASK GENMASK(15, 8) ++#define B_AX_ACKTO_MASK GENMASK(7, 0) ++ ++#define R_AX_TRXPTCL_RESP_0 0xCC04 ++#define R_AX_TRXPTCL_RESP_0_C1 0xEC04 ++#define B_AX_WMAC_RESP_STBC_EN BIT(31) ++#define B_AX_WMAC_RXFTM_TXACK_SC BIT(30) ++#define B_AX_WMAC_RXFTM_TXACKBWEQ BIT(29) ++#define B_AX_RSP_CHK_SEC_CCA_80 BIT(28) ++#define B_AX_RSP_CHK_SEC_CCA_40 BIT(27) ++#define B_AX_RSP_CHK_SEC_CCA_20 BIT(26) ++#define B_AX_RSP_CHK_BTCCA BIT(25) ++#define B_AX_RSP_CHK_EDCCA BIT(24) ++#define B_AX_RSP_CHK_CCA BIT(23) ++#define B_AX_WMAC_LDPC_EN BIT(22) ++#define B_AX_WMAC_SGIEN BIT(21) ++#define B_AX_WMAC_SPLCPEN BIT(20) ++#define B_AX_WMAC_BESP_EARLY_TXBA BIT(17) ++#define B_AX_WMAC_SPEC_SIFS_OFDM_MASK GENMASK(15, 8) ++#define B_AX_WMAC_SPEC_SIFS_CCK_MASK GENMASK(7, 0) ++#define WMAC_SPEC_SIFS_OFDM_52A 0x15 ++#define WMAC_SPEC_SIFS_OFDM_52B 0x11 ++#define WMAC_SPEC_SIFS_OFDM_52C 0x11 ++#define WMAC_SPEC_SIFS_CCK 0xA ++ ++#define R_AX_MAC_LOOPBACK 0xCC20 ++#define R_AX_MAC_LOOPBACK_C1 0xEC20 ++#define B_AX_MACLBK_EN BIT(0) ++ ++#define R_AX_RXTRIG_TEST_USER_2 0xCCB0 ++#define R_AX_RXTRIG_TEST_USER_2_C1 0xECB0 ++#define B_AX_RXTRIG_MACID_MASK GENMASK(31, 24) ++#define B_AX_RXTRIG_RU26_DIS BIT(21) ++#define B_AX_RXTRIG_FCSCHK_EN BIT(20) ++#define B_AX_RXTRIG_PORT_SEL_MASK GENMASK(19, 17) ++#define B_AX_RXTRIG_EN BIT(16) ++#define B_AX_RXTRIG_USERINFO_2_MASK GENMASK(15, 0) ++ ++#define R_AX_WMAC_TX_TF_INFO_0 0xCCD0 ++#define R_AX_WMAC_TX_TF_INFO_0_C1 0xECD0 ++#define B_AX_WMAC_TX_TF_INFO_SEL_MASK GENMASK(2, 0) ++ ++#define R_AX_WMAC_TX_TF_INFO_1 0xCCD4 ++#define R_AX_WMAC_TX_TF_INFO_1_C1 0xECD4 ++#define B_AX_WMAC_TX_TF_INFO_P0_MASK GENMASK(31, 0) ++ ++#define R_AX_WMAC_TX_TF_INFO_2 0xCCD8 ++#define R_AX_WMAC_TX_TF_INFO_2_C1 0xECD8 ++#define B_AX_WMAC_TX_TF_INFO_P1_MASK GENMASK(31, 0) ++ ++#define R_AX_TMAC_ERR_IMR_ISR 0xCCEC ++#define R_AX_TMAC_ERR_IMR_ISR_C1 0xECEC ++ ++#define R_AX_DBGSEL_TRXPTCL 0xCCF4 ++#define R_AX_DBGSEL_TRXPTCL_C1 0xECF4 ++#define B_AX_DBGSEL_TRXPTCL_MASK GENMASK(7, 0) ++ ++#define R_AX_PHYINFO_ERR_IMR 0xCCFC ++#define R_AX_PHYINFO_ERR_IMR_C1 0xECFC ++#define B_AX_CSI_ON_TIMEOUT BIT(29) ++#define B_AX_STS_ON_TIMEOUT BIT(28) ++#define B_AX_DATA_ON_TIMEOUT BIT(27) ++#define B_AX_OFDM_CCA_TIMEOUT BIT(26) ++#define B_AX_CCK_CCA_TIMEOUT BIT(25) ++#define B_AXC_PHY_TXON_TIMEOUT BIT(24) ++#define B_AX_CSI_ON_TIMEOUT_INT_EN BIT(21) ++#define B_AX_STS_ON_TIMEOUT_INT_EN BIT(20) ++#define B_AX_DATA_ON_TIMEOUT_INT_EN BIT(19) ++#define B_AX_OFDM_CCA_TIMEOUT_INT_EN BIT(18) ++#define B_AX_CCK_CCA_TIMEOUT_INT_EN BIT(17) ++#define B_AX_PHY_TXON_TIMEOUT_INT_EN BIT(16) ++#define B_AX_PHYINTF_TIMEOUT_THR_MSAK GENMASK(5, 0) ++ ++#define R_AX_PHYINFO_ERR_ISR 0xCCFC ++#define R_AX_PHYINFO_ERR_ISR_C1 0xECFC ++ ++#define R_AX_BFMER_CTRL_0 0xCD78 ++#define R_AX_BFMER_CTRL_0_C1 0xED78 ++#define B_AX_BFMER_HE_CSI_OFFSET_MASK GENMASK(31, 24) ++#define B_AX_BFMER_VHT_CSI_OFFSET_MASK GENMASK(23, 16) ++#define B_AX_BFMER_HT_CSI_OFFSET_MASK GENMASK(15, 8) ++#define B_AX_BFMER_NDP_BFEN BIT(2) ++#define B_AX_BFMER_VHT_BFPRT_CHK BIT(0) ++ ++#define R_AX_BFMEE_RESP_OPTION 0xCD80 ++#define R_AX_BFMEE_RESP_OPTION_C1 0xED80 ++#define B_AX_BFMEE_NDP_RX_STANDBY_TIMER_MASK GENMASK(31, 24) ++#define B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK GENMASK(23, 20) ++#define B_AX_MU_BFRPTSEG_SEL_MASK GENMASK(18, 17) ++#define B_AX_BFMEE_NDP_RXSTDBY_SEL BIT(16) ++#define BFRP_RX_STANDBY_TIMER 0x0 ++#define NDP_RX_STANDBY_TIMER 0xFF ++#define B_AX_BFMEE_HE_NDPA_EN BIT(2) ++#define B_AX_BFMEE_VHT_NDPA_EN BIT(1) ++#define B_AX_BFMEE_HT_NDPA_EN BIT(0) ++ ++#define R_AX_TRXPTCL_RESP_CSI_CTRL_0 0xCD88 ++#define R_AX_TRXPTCL_RESP_CSI_CTRL_0_C1 0xED88 ++#define R_AX_TRXPTCL_RESP_CSI_CTRL_1 0xCD94 ++#define R_AX_TRXPTCL_RESP_CSI_CTRL_1_C1 0xED94 ++#define B_AX_BFMEE_CSISEQ_SEL BIT(29) ++#define B_AX_BFMEE_BFPARAM_SEL BIT(28) ++#define B_AX_BFMEE_OFDM_LEN_TH_MASK GENMASK(27, 24) ++#define B_AX_BFMEE_BF_PORT_SEL BIT(23) ++#define B_AX_BFMEE_USE_NSTS BIT(22) ++#define B_AX_BFMEE_CSI_RATE_FB_EN BIT(21) ++#define B_AX_BFMEE_CSI_GID_SEL BIT(20) ++#define B_AX_BFMEE_CSI_RSC_MASK GENMASK(19, 18) ++#define B_AX_BFMEE_CSI_FORCE_RETE_EN BIT(17) ++#define B_AX_BFMEE_CSI_USE_NDPARATE BIT(16) ++#define B_AX_BFMEE_CSI_WITHHTC_EN BIT(15) ++#define B_AX_BFMEE_CSIINFO0_BF_EN BIT(14) ++#define B_AX_BFMEE_CSIINFO0_STBC_EN BIT(13) ++#define B_AX_BFMEE_CSIINFO0_LDPC_EN BIT(12) ++#define B_AX_BFMEE_CSIINFO0_CS_MASK GENMASK(11, 10) ++#define B_AX_BFMEE_CSIINFO0_CB_MASK GENMASK(9, 8) ++#define B_AX_BFMEE_CSIINFO0_NG_MASK GENMASK(7, 6) ++#define B_AX_BFMEE_CSIINFO0_NR_MASK GENMASK(5, 3) ++#define B_AX_BFMEE_CSIINFO0_NC_MASK GENMASK(2, 0) ++ ++#define R_AX_TRXPTCL_RESP_CSI_RRSC 0xCD8C ++#define R_AX_TRXPTCL_RESP_CSI_RRSC_C1 0xED8C ++#define CSI_RRSC_BMAP 0x29292911 ++ ++#define R_AX_TRXPTCL_RESP_CSI_RATE 0xCD90 ++#define R_AX_TRXPTCL_RESP_CSI_RATE_C1 0xED90 ++#define B_AX_BFMEE_HE_CSI_RATE_MASK GENMASK(22, 16) ++#define B_AX_BFMEE_VHT_CSI_RATE_MASK GENMASK(14, 8) ++#define B_AX_BFMEE_HT_CSI_RATE_MASK GENMASK(6, 0) ++#define CSI_INIT_RATE_HE 0x3 ++#define CSI_INIT_RATE_VHT 0x3 ++#define CSI_INIT_RATE_HT 0x3 ++ ++#define R_AX_RCR 0xCE00 ++#define R_AX_RCR_C1 0xEE00 ++#define B_AX_STOP_RX_IN BIT(11) ++#define B_AX_DRV_INFO_SIZE_MASK GENMASK(10, 8) ++#define B_AX_CH_EN_MASK GENMASK(3, 0) ++ ++#define R_AX_DLK_PROTECT_CTL 0xCE02 ++#define R_AX_DLK_PROTECT_CTL_C1 0xEE02 ++#define B_AX_RX_DLK_CCA_TIME_MASK GENMASK(15, 8) ++#define B_AX_RX_DLK_DATA_TIME_MASK GENMASK(7, 4) ++ ++#define R_AX_PLCP_HDR_FLTR 0xCE04 ++#define R_AX_PLCP_HDR_FLTR_C1 0xEE04 ++#define B_AX_DIS_CHK_MIN_LEN BIT(8) ++#define B_AX_HE_SIGB_CRC_CHK BIT(6) ++#define B_AX_VHT_MU_SIGB_CRC_CHK BIT(5) ++#define B_AX_VHT_SU_SIGB_CRC_CHK BIT(4) ++#define B_AX_SIGA_CRC_CHK BIT(3) ++#define B_AX_LSIG_PARITY_CHK_EN BIT(2) ++#define B_AX_CCK_SIG_CHK BIT(1) ++#define B_AX_CCK_CRC_CHK BIT(0) ++ ++#define R_AX_RX_FLTR_OPT 0xCE20 ++#define R_AX_RX_FLTR_OPT_C1 0xEE20 ++#define B_AX_UID_FILTER_MASK GENMASK(31, 24) ++#define B_AX_UNSPT_FILTER_SH 22 ++#define B_AX_UNSPT_FILTER_MASK GENMASK(23, 22) ++#define B_AX_RX_MPDU_MAX_LEN_MASK GENMASK(21, 16) ++#define B_AX_RX_MPDU_MAX_LEN_SIZE 0x3f ++#define B_AX_A_FTM_REQ BIT(14) ++#define B_AX_A_ERR_PKT BIT(13) ++#define B_AX_A_UNSUP_PKT BIT(12) ++#define B_AX_A_CRC32_ERR BIT(11) ++#define B_AX_A_PWR_MGNT BIT(10) ++#define B_AX_A_BCN_CHK_RULE_MASK GENMASK(9, 8) ++#define B_AX_A_BCN_CHK_EN BIT(7) ++#define B_AX_A_MC_LIST_CAM_MATCH BIT(6) ++#define B_AX_A_BC_CAM_MATCH BIT(5) ++#define B_AX_A_UC_CAM_MATCH BIT(4) ++#define B_AX_A_MC BIT(3) ++#define B_AX_A_BC BIT(2) ++#define B_AX_A_A1_MATCH BIT(1) ++#define B_AX_SNIFFER_MODE BIT(0) ++#define DEFAULT_AX_RX_FLTR (B_AX_A_A1_MATCH | B_AX_A_BC | B_AX_A_MC | \ ++ B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH | \ ++ B_AX_A_PWR_MGNT | B_AX_A_FTM_REQ | \ ++ u32_encode_bits(3, B_AX_UID_FILTER_MASK) | \ ++ B_AX_A_BCN_CHK_EN) ++#define B_AX_RX_FLTR_CFG_MASK ((u32)~B_AX_RX_MPDU_MAX_LEN_MASK) ++ ++#define R_AX_CTRL_FLTR 0xCE24 ++#define R_AX_CTRL_FLTR_C1 0xEE24 ++#define R_AX_MGNT_FLTR 0xCE28 ++#define R_AX_MGNT_FLTR_C1 0xEE28 ++#define R_AX_DATA_FLTR 0xCE2C ++#define R_AX_DATA_FLTR_C1 0xEE2C ++#define RX_FLTR_FRAME_DROP 0x00000000 ++#define RX_FLTR_FRAME_TO_HOST 0x55555555 ++#define RX_FLTR_FRAME_TO_WLCPU 0xAAAAAAAA ++ ++#define R_AX_ADDR_CAM_CTRL 0xCE34 ++#define R_AX_ADDR_CAM_CTRL_C1 0xEE34 ++#define B_AX_ADDR_CAM_RANGE_MASK GENMASK(23, 16) ++#define B_AX_ADDR_CAM_CMPLIMT_MASK GENMASK(15, 12) ++#define B_AX_ADDR_CAM_CLR BIT(8) ++#define B_AX_ADDR_CAM_A2_B0_CHK BIT(2) ++#define B_AX_ADDR_CAM_SRCH_PERPKT BIT(1) ++#define B_AX_ADDR_CAM_EN BIT(0) ++ ++#define R_AX_RESPBA_CAM_CTRL 0xCE3C ++#define R_AX_RESPBA_CAM_CTRL_C1 0xEE3C ++#define B_AX_SSN_SEL BIT(2) ++ ++#define R_AX_PPDU_STAT 0xCE40 ++#define R_AX_PPDU_STAT_C1 0xEE40 ++#define B_AX_PPDU_STAT_RPT_TRIG BIT(8) ++#define B_AX_PPDU_STAT_RPT_CRC32 BIT(5) ++#define B_AX_PPDU_STAT_RPT_A1M BIT(4) ++#define B_AX_APP_PLCP_HDR_RPT BIT(3) ++#define B_AX_APP_RX_CNT_RPT BIT(2) ++#define B_AX_APP_MAC_INFO_RPT BIT(1) ++#define B_AX_PPDU_STAT_RPT_EN BIT(0) ++ ++#define R_AX_RX_SR_CTRL 0xCE4A ++#define R_AX_RX_SR_CTRL_C1 0xEE4A ++#define B_AX_SR_EN BIT(0) ++ ++#define R_AX_RX_STATE_MONITOR 0xCEF0 ++#define R_AX_RX_STATE_MONITOR_C1 0xEEF0 ++#define B_AX_RX_STATE_MONITOR_MASK GENMASK(31, 0) ++#define B_AX_STATE_CUR_MASK GENMASK(31, 16) ++#define B_AX_STATE_NXT_MASK GENMASK(13, 8) ++#define B_AX_STATE_UPD BIT(7) ++#define B_AX_STATE_SEL_MASK GENMASK(4, 0) ++ ++#define R_AX_RMAC_ERR_ISR 0xCEF4 ++#define R_AX_RMAC_ERR_ISR_C1 0xEEF4 ++#define B_AX_RXERR_INTPS_EN BIT(31) ++#define B_AX_RMAC_RX_CSI_TIMEOUT_INT_EN BIT(19) ++#define B_AX_RMAC_RX_TIMEOUT_INT_EN BIT(18) ++#define B_AX_RMAC_CSI_TIMEOUT_INT_EN BIT(17) ++#define B_AX_RMAC_DATA_ON_TIMEOUT_INT_EN BIT(16) ++#define B_AX_RMAC_CCA_TIMEOUT_INT_EN BIT(15) ++#define B_AX_RMAC_DMA_TIMEOUT_INT_EN BIT(14) ++#define B_AX_RMAC_DATA_ON_TO_IDLE_TIMEOUT_INT_EN BIT(13) ++#define B_AX_RMAC_CCA_TO_IDLE_TIMEOUT_INT_EN BIT(12) ++#define B_AX_RMAC_RX_CSI_TIMEOUT_FLAG BIT(7) ++#define B_AX_RMAC_RX_TIMEOUT_FLAG BIT(6) ++#define B_AX_BMAC_CSI_TIMEOUT_FLAG BIT(5) ++#define B_AX_BMAC_DATA_ON_TIMEOUT_FLAG BIT(4) ++#define B_AX_BMAC_CCA_TIMEOUT_FLAG BIT(3) ++#define B_AX_BMAC_DMA_TIMEOUT_FLAG BIT(2) ++#define B_AX_BMAC_DATA_ON_TO_IDLE_TIMEOUT_FLAG BIT(1) ++#define B_AX_BMAC_CCA_TO_IDLE_TIMEOUT_FLAG BIT(0) ++ ++#define R_AX_RMAC_PLCP_MON 0xCEF8 ++#define R_AX_RMAC_PLCP_MON_C1 0xEEF8 ++#define B_AX_RMAC_PLCP_MON_MASK GENMASK(31, 0) ++#define B_AX_PCLP_MON_SEL_MASK GENMASK(31, 28) ++#define B_AX_PCLP_MON_CONT_MASK GENMASK(27, 0) ++ ++#define R_AX_RX_DEBUG_SELECT 0xCEFC ++#define R_AX_RX_DEBUG_SELECT_C1 0xEEFC ++#define B_AX_DEBUG_SEL_MASK GENMASK(7, 0) ++ ++#define R_AX_PWR_RATE_CTRL 0xD200 ++#define R_AX_PWR_RATE_CTRL_C1 0xF200 ++#define B_AX_FORCE_PWR_BY_RATE_EN BIT(9) ++#define B_AX_FORCE_PWR_BY_RATE_VALUE_MASK GENMASK(8, 0) ++ ++#define R_AX_PWR_RATE_OFST_CTRL 0xD204 ++#define R_AX_PWR_COEXT_CTRL 0xD220 ++#define B_AX_TXAGC_BT_EN BIT(1) ++#define B_AX_TXAGC_BT_MASK GENMASK(11, 3) ++ ++#define R_AX_PWR_UL_CTRL0 0xD240 ++#define R_AX_PWR_UL_CTRL2 0xD248 ++#define B_AX_PWR_UL_CFO_MASK GENMASK(2, 0) ++#define B_AX_PWR_UL_CTRL2_MASK 0x07700007 ++#define R_AX_PWR_UL_TB_CTRL 0xD288 ++#define B_AX_PWR_UL_TB_CTRL_EN BIT(31) ++#define R_AX_PWR_UL_TB_1T 0xD28C ++#define B_AX_PWR_UL_TB_1T_MASK GENMASK(4, 0) ++#define R_AX_PWR_UL_TB_2T 0xD290 ++#define B_AX_PWR_UL_TB_2T_MASK GENMASK(4, 0) ++#define R_AX_PWR_BY_RATE_TABLE0 0xD2C0 ++#define R_AX_PWR_BY_RATE_TABLE10 0xD2E8 ++#define R_AX_PWR_BY_RATE R_AX_PWR_BY_RATE_TABLE0 ++#define R_AX_PWR_BY_RATE_MAX R_AX_PWR_BY_RATE_TABLE10 ++#define R_AX_PWR_LMT_TABLE0 0xD2EC ++#define R_AX_PWR_LMT_TABLE19 0xD338 ++#define R_AX_PWR_LMT R_AX_PWR_LMT_TABLE0 ++#define R_AX_PWR_LMT_MAX R_AX_PWR_LMT_TABLE19 ++#define R_AX_PWR_RU_LMT_TABLE0 0xD33C ++#define R_AX_PWR_RU_LMT_TABLE11 0xD368 ++#define R_AX_PWR_RU_LMT R_AX_PWR_RU_LMT_TABLE0 ++#define R_AX_PWR_RU_LMT_MAX R_AX_PWR_RU_LMT_TABLE11 ++#define R_AX_PWR_MACID_LMT_TABLE0 0xD36C ++#define R_AX_PWR_MACID_LMT_TABLE127 0xD568 ++ ++#define R_AX_TXPWR_IMR 0xD9E0 ++#define R_AX_TXPWR_IMR_C1 0xF9E0 ++#define R_AX_TXPWR_ISR 0xD9E4 ++#define R_AX_TXPWR_ISR_C1 0xF9E4 ++ ++#define R_AX_BTC_CFG 0xDA00 ++#define B_AX_DIS_BTC_CLK_G BIT(2) ++ ++#define R_AX_WL_PRI_MSK 0xDA10 ++#define B_AX_PTA_WL_PRI_MASK_BCNQ BIT(8) ++ ++#define R_AX_BTC_FUNC_EN 0xDA20 ++#define R_AX_BTC_FUNC_EN_C1 0xFA20 ++#define B_AX_PTA_WL_TX_EN BIT(1) ++#define B_AX_PTA_EDCCA_EN BIT(0) ++ ++#define R_BTC_BREAK_TABLE 0xDA2C ++#define BTC_BREAK_PARAM 0xf0ffffff ++ ++#define R_BTC_BT_COEX_MSK_TABLE 0xDA30 ++#define B_BTC_PRI_MASK_TX_RESP_V1 BIT(3) ++ ++#define R_AX_BT_COEX_CFG_2 0xDA34 ++#define R_AX_BT_COEX_CFG_2_C1 0xFA34 ++#define B_AX_GNT_BT_BYPASS_PRIORITY BIT(12) ++#define B_AX_GNT_BT_POLARITY BIT(8) ++#define B_AX_TIMER_MASK GENMASK(7, 0) ++#define MAC_AX_CSR_RATE 80 ++ ++#define R_AX_CSR_MODE 0xDA40 ++#define R_AX_CSR_MODE_C1 0xFA40 ++#define B_AX_BT_CNT_RST BIT(16) ++#define B_AX_BT_STAT_DELAY_MASK GENMASK(15, 12) ++#define MAC_AX_CSR_DELAY 0 ++#define B_AX_BT_TRX_INIT_DETECT_MASK GENMASK(11, 8) ++#define MAC_AX_CSR_TRX_TO 4 ++#define B_AX_BT_PRI_DETECT_TO_MASK GENMASK(7, 4) ++#define MAC_AX_CSR_PRI_TO 5 ++#define B_AX_WL_ACT_MSK BIT(3) ++#define B_AX_STATIS_BT_EN BIT(2) ++#define B_AX_WL_ACT_MASK_ENABLE BIT(1) ++#define B_AX_ENHANCED_BT BIT(0) ++ ++#define R_AX_BT_STAST_HIGH 0xDA44 ++#define B_AX_STATIS_BT_HI_RX_MASK GENMASK(31, 16) ++#define B_AX_STATIS_BT_HI_TX_MASK GENMASK(15, 0) ++#define R_AX_BT_STAST_LOW 0xDA48 ++#define B_AX_STATIS_BT_LO_TX_1_MASK GENMASK(15, 0) ++#define B_AX_STATIS_BT_LO_RX_1_MASK GENMASK(31, 16) ++ ++#define R_AX_TDMA_MODE 0xDA4C ++#define R_AX_TDMA_MODE_C1 0xFA4C ++#define B_AX_R_BT_CMD_RPT_MASK GENMASK(31, 16) ++#define B_AX_R_RPT_FROM_BT_MASK GENMASK(15, 8) ++#define B_AX_BT_HID_ISR_SET_MASK GENMASK(7, 6) ++#define B_AX_TDMA_BT_START_NOTIFY BIT(5) ++#define B_AX_ENABLE_TDMA_FW_MODE BIT(4) ++#define B_AX_ENABLE_PTA_TDMA_MODE BIT(3) ++#define B_AX_ENABLE_COEXIST_TAB_IN_TDMA BIT(2) ++#define B_AX_GPIO2_GPIO3_EXANGE_OR_NO_BT_CCA BIT(1) ++#define B_AX_RTK_BT_ENABLE BIT(0) ++ ++#define R_AX_BT_COEX_CFG_5 0xDA6C ++#define R_AX_BT_COEX_CFG_5_C1 0xFA6C ++#define B_AX_BT_TIME_MASK GENMASK(31, 6) ++#define B_AX_BT_RPT_SAMPLE_RATE_MASK GENMASK(5, 0) ++#define MAC_AX_RTK_RATE 5 ++ ++#define R_AX_LTE_CTRL 0xDAF0 ++#define R_AX_LTE_WDATA 0xDAF4 ++#define R_AX_LTE_RDATA 0xDAF8 ++ ++#define CMAC1_START_ADDR 0xE000 ++#define CMAC1_END_ADDR 0xFFFF ++#define R_AX_CMAC_REG_END 0xFFFF ++ ++#define R_AX_LTE_SW_CFG_1 0x0038 ++#define R_AX_LTE_SW_CFG_1_C1 0x2038 ++#define B_AX_GNT_BT_RFC_S1_SW_VAL BIT(31) ++#define B_AX_GNT_BT_RFC_S1_SW_CTRL BIT(30) ++#define B_AX_GNT_WL_RFC_S1_SW_VAL BIT(29) ++#define B_AX_GNT_WL_RFC_S1_SW_CTRL BIT(28) ++#define B_AX_GNT_BT_BB_S1_SW_VAL BIT(27) ++#define B_AX_GNT_BT_BB_S1_SW_CTRL BIT(26) ++#define B_AX_GNT_WL_BB_S1_SW_VAL BIT(25) ++#define B_AX_GNT_WL_BB_S1_SW_CTRL BIT(24) ++#define B_AX_BT_SW_CTRL_WL_PRIORITY BIT(19) ++#define B_AX_WL_SW_CTRL_WL_PRIORITY BIT(18) ++#define B_AX_LTE_PATTERN_2_EN BIT(17) ++#define B_AX_LTE_PATTERN_1_EN BIT(16) ++#define B_AX_GNT_BT_RFC_S0_SW_VAL BIT(15) ++#define B_AX_GNT_BT_RFC_S0_SW_CTRL BIT(14) ++#define B_AX_GNT_WL_RFC_S0_SW_VAL BIT(13) ++#define B_AX_GNT_WL_RFC_S0_SW_CTRL BIT(12) ++#define B_AX_GNT_BT_BB_S0_SW_VAL BIT(11) ++#define B_AX_GNT_BT_BB_S0_SW_CTRL BIT(10) ++#define B_AX_GNT_WL_BB_S0_SW_VAL BIT(9) ++#define B_AX_GNT_WL_BB_S0_SW_CTRL BIT(8) ++#define B_AX_LTECOEX_FUN_EN BIT(7) ++#define B_AX_LTECOEX_3WIRE_CTRL_MUX BIT(6) ++#define B_AX_LTECOEX_OP_MODE_SEL_MASK GENMASK(5, 4) ++#define B_AX_LTECOEX_UART_MUX BIT(3) ++#define B_AX_LTECOEX_UART_MODE_SEL_MASK GENMASK(2, 0) ++ ++#define R_AX_LTE_SW_CFG_2 0x003C ++#define R_AX_LTE_SW_CFG_2_C1 0x203C ++#define B_AX_WL_RX_CTRL BIT(8) ++#define B_AX_GNT_WL_RX_SW_VAL BIT(7) ++#define B_AX_GNT_WL_RX_SW_CTRL BIT(6) ++#define B_AX_GNT_WL_TX_SW_VAL BIT(5) ++#define B_AX_GNT_WL_TX_SW_CTRL BIT(4) ++#define B_AX_GNT_BT_RX_SW_VAL BIT(3) ++#define B_AX_GNT_BT_RX_SW_CTRL BIT(2) ++#define B_AX_GNT_BT_TX_SW_VAL BIT(1) ++#define B_AX_GNT_BT_TX_SW_CTRL BIT(0) ++ ++#define RR_MOD 0x00 ++#define RR_MOD_IQK GENMASK(19, 4) ++#define RR_MOD_DPK GENMASK(19, 5) ++#define RR_MOD_MASK GENMASK(19, 16) ++#define RR_MOD_V_DOWN 0x0 ++#define RR_MOD_V_STANDBY 0x1 ++#define RR_MOD_V_TX 0x2 ++#define RR_MOD_V_RX 0x3 ++#define RR_MOD_V_TXIQK 0x4 ++#define RR_MOD_V_DPK 0x5 ++#define RR_MOD_V_RXK1 0x6 ++#define RR_MOD_V_RXK2 0x7 ++#define RR_MOD_M_RXG GENMASK(13, 4) ++#define RR_MOD_M_RXBB GENMASK(9, 5) ++#define RR_MODOPT 0x01 ++#define RR_MODOPT_M_TXPWR GENMASK(5, 0) ++#define RR_WLSEL 0x02 ++#define RR_WLSEL_AG GENMASK(18, 16) ++#define RR_RSV1 0x05 ++#define RR_RSV1_RST BIT(0) ++#define RR_DTXLOK 0x08 ++#define RR_RSV2 0x09 ++#define RR_CFGCH 0x18 ++#define RR_BTC 0x1a ++#define RR_BTC_TXBB GENMASK(14, 12) ++#define RR_BTC_RXBB GENMASK(11, 10) ++#define RR_RCKC 0x1b ++#define RR_RCKC_CA GENMASK(14, 10) ++#define RR_RCKS 0x1c ++#define RR_RCKO 0x1d ++#define RR_RCKO_OFF GENMASK(13, 9) ++#define RR_RXKPLL 0x1e ++#define RR_RXKPLL_OFF GENMASK(5, 0) ++#define RR_RXKPLL_POW BIT(19) ++#define RR_RSV4 0x1f ++#define RR_RXK 0x20 ++#define RR_RXK_PLLEN BIT(5) ++#define RR_RXK_SEL5G BIT(7) ++#define RR_RXK_SEL2G BIT(8) ++#define RR_LUTWA 0x33 ++#define RR_LUTWA_MASK GENMASK(9, 0) ++#define RR_LUTWD1 0x3e ++#define RR_LUTWD0 0x3f ++#define RR_TM 0x42 ++#define RR_TM_TRI BIT(19) ++#define RR_TM_VAL GENMASK(6, 1) ++#define RR_TM2 0x43 ++#define RR_TM2_OFF GENMASK(19, 16) ++#define RR_TXG1 0x51 ++#define RR_TXG1_ATT2 BIT(19) ++#define RR_TXG1_ATT1 BIT(11) ++#define RR_TXG2 0x52 ++#define RR_TXG2_ATT0 BIT(11) ++#define RR_BSPAD 0x54 ++#define RR_TXGA 0x55 ++#define RR_TXGA_LOK_EN BIT(0) ++#define RR_TXGA_TRK_EN BIT(7) ++#define RR_GAINTX 0x56 ++#define RR_GAINTX_ALL GENMASK(15, 0) ++#define RR_GAINTX_PAD GENMASK(9, 5) ++#define RR_GAINTX_BB GENMASK(4, 0) ++#define RR_TXMO 0x58 ++#define RR_TXMO_COI GENMASK(19, 15) ++#define RR_TXMO_COQ GENMASK(14, 10) ++#define RR_TXMO_FII GENMASK(9, 6) ++#define RR_TXMO_FIQ GENMASK(5, 2) ++#define RR_TXA 0x5d ++#define RR_TXA_TRK GENMASK(19, 14) ++#define RR_TXRSV 0x5c ++#define RR_TXRSV_GAPK BIT(19) ++#define RR_BIAS 0x5e ++#define RR_BIAS_GAPK BIT(19) ++#define RR_BIASA 0x60 ++#define RR_BIASA_TXG GENMASK(15, 12) ++#define RR_BIASA_TXA GENMASK(19, 16) ++#define RR_BIASA_A GENMASK(2, 0) ++#define RR_BIASA2 0x63 ++#define RR_BIASA2_LB GENMASK(4, 2) ++#define RR_TXATANK 0x64 ++#define RR_TXATANK_LBSW GENMASK(16, 15) ++#define RR_TRXIQ 0x66 ++#define RR_RSV6 0x6d ++#define RR_TXPOW 0x7f ++#define RR_TXPOW_TXG BIT(1) ++#define RR_TXPOW_TXA BIT(8) ++#define RR_RXPOW 0x80 ++#define RR_RXPOW_IQK GENMASK(17, 16) ++#define RR_RXBB 0x83 ++#define RR_RXBB_C2G GENMASK(16, 10) ++#define RR_RXBB_C1G GENMASK(9, 8) ++#define RR_RXBB_ATTR GENMASK(7, 4) ++#define RR_RXBB_ATTC GENMASK(2, 0) ++#define RR_XGLNA2 0x85 ++#define RR_XGLNA2_SW GENMASK(1, 0) ++#define RR_RXA 0x8a ++#define RR_RXA_DPK GENMASK(9, 8) ++#define RR_RXA2 0x8c ++#define RR_RXA2_C2 GENMASK(9, 3) ++#define RR_RXA2_C1 GENMASK(12, 10) ++#define RR_RXIQGEN 0x8d ++#define RR_RXIQGEN_ATTL GENMASK(12, 8) ++#define RR_RXIQGEN_ATTH GENMASK(14, 13) ++#define RR_RXBB2 0x8f ++#define RR_EN_TIA_IDA GENMASK(11, 10) ++#define RR_RXBB2_DAC_EN BIT(13) ++#define RR_XALNA2 0x90 ++#define RR_XALNA2_SW GENMASK(1, 0) ++#define RR_DCK 0x92 ++#define RR_DCK_FINE BIT(1) ++#define RR_DCK_LV BIT(0) ++#define RR_DCK1 0x93 ++#define RR_DCK1_SEL BIT(3) ++#define RR_DCK2 0x94 ++#define RR_DCK2_CYCLE GENMASK(7, 2) ++#define RR_MIXER 0x9f ++#define RR_MIXER_GN GENMASK(4, 3) ++#define RR_XTALX2 0xb8 ++#define RR_MALSEL 0xbe ++#define RR_RCKD 0xde ++#define RR_RCKD_POW GENMASK(19, 13) ++#define RR_RCKD_BW BIT(2) ++#define RR_TXADBG 0xde ++#define RR_LUTDBG 0xdf ++#define RR_LUTDBG_LOK BIT(2) ++#define RR_LUTWE2 0xee ++#define RR_LUTWE 0xef ++#define RR_LUTWE_LOK BIT(2) ++#define RR_RFC 0xf0 ++#define RR_RFC_CKEN BIT(1) ++ ++#define R_UPD_P0 0x0000 ++#define R_RSTB_WATCH_DOG 0x000C ++#define B_P0_RSTB_WATCH_DOG BIT(0) ++#define B_P1_RSTB_WATCH_DOG BIT(1) ++#define B_UPD_P0_EN BIT(30) ++#define R_ANAPAR_PW15 0x030C ++#define B_ANAPAR_PW15 GENMASK(31, 24) ++#define B_ANAPAR_PW15_H GENMASK(27, 24) ++#define B_ANAPAR_PW15_H2 GENMASK(27, 26) ++#define R_ANAPAR 0x032C ++#define B_ANAPAR_15 GENMASK(31, 16) ++#define B_ANAPAR_ADCCLK BIT(30) ++#define B_ANAPAR_FLTRST BIT(22) ++#define B_ANAPAR_CRXBB GENMASK(18, 16) ++#define B_ANAPAR_14 GENMASK(15, 0) ++#define R_UPD_CLK_ADC 0x0700 ++#define B_UPD_CLK_ADC_ON BIT(24) ++#define B_UPD_CLK_ADC_VAL GENMASK(26, 25) ++#define R_RSTB_ASYNC 0x0704 ++#define B_RSTB_ASYNC_ALL BIT(1) ++#define R_PMAC_GNT 0x0980 ++#define B_PMAC_GNT_TXEN BIT(0) ++#define B_PMAC_GNT_RXEN BIT(16) ++#define B_PMAC_GNT_P1 GENMASK(20, 17) ++#define B_PMAC_GNT_P2 GENMASK(29, 26) ++#define R_PMAC_RX_CFG1 0x0988 ++#define B_PMAC_OPT1_MSK GENMASK(11, 0) ++#define R_PMAC_RXMOD 0x0994 ++#define B_PMAC_RXMOD_MSK GENMASK(7, 4) ++#define R_MAC_SEL 0x09A4 ++#define B_MAC_SEL_MOD GENMASK(4, 2) ++#define B_MAC_SEL_DPD_EN BIT(10) ++#define B_MAC_SEL_PWR_EN BIT(16) ++#define R_PMAC_TX_CTRL 0x09C0 ++#define B_PMAC_TXEN_DIS BIT(0) ++#define R_PMAC_TX_PRD 0x09C4 ++#define B_PMAC_TX_PRD_MSK GENMASK(31, 8) ++#define B_PMAC_CTX_EN BIT(0) ++#define B_PMAC_PTX_EN BIT(4) ++#define R_PMAC_TX_CNT 0x09C8 ++#define B_PMAC_TX_CNT_MSK GENMASK(31, 0) ++#define R_CCX 0x0C00 ++#define B_CCX_EDCCA_OPT_MSK GENMASK(6, 4) ++#define B_MEASUREMENT_TRIG_MSK BIT(2) ++#define B_CCX_TRIG_OPT_MSK BIT(1) ++#define B_CCX_EN_MSK BIT(0) ++#define R_IFS_COUNTER 0x0C28 ++#define B_IFS_CLM_PERIOD_MSK GENMASK(31, 16) ++#define B_IFS_CLM_COUNTER_UNIT_MSK GENMASK(15, 14) ++#define B_IFS_COUNTER_CLR_MSK BIT(13) ++#define B_IFS_COLLECT_EN BIT(12) ++#define R_IFS_T1 0x0C2C ++#define B_IFS_T1_TH_HIGH_MSK GENMASK(31, 16) ++#define B_IFS_T1_EN_MSK BIT(15) ++#define B_IFS_T1_TH_LOW_MSK GENMASK(14, 0) ++#define R_IFS_T2 0x0C30 ++#define B_IFS_T2_TH_HIGH_MSK GENMASK(31, 16) ++#define B_IFS_T2_EN_MSK BIT(15) ++#define B_IFS_T2_TH_LOW_MSK GENMASK(14, 0) ++#define R_IFS_T3 0x0C34 ++#define B_IFS_T3_TH_HIGH_MSK GENMASK(31, 16) ++#define B_IFS_T3_EN_MSK BIT(15) ++#define B_IFS_T3_TH_LOW_MSK GENMASK(14, 0) ++#define R_IFS_T4 0x0C38 ++#define B_IFS_T4_TH_HIGH_MSK GENMASK(31, 16) ++#define B_IFS_T4_EN_MSK BIT(15) ++#define B_IFS_T4_TH_LOW_MSK GENMASK(14, 0) ++#define R_PD_CTRL 0x0C3C ++#define B_PD_HIT_DIS BIT(9) ++#define R_IOQ_IQK_DPK 0x0C60 ++#define B_IOQ_IQK_DPK_EN BIT(1) ++#define R_P0_EN_SOUND_WO_NDP 0x0D7C ++#define B_P0_EN_SOUND_WO_NDP BIT(1) ++#define R_SPOOF_ASYNC_RST 0x0D84 ++#define B_SPOOF_ASYNC_RST BIT(15) ++#define R_NDP_BRK0 0xDA0 ++#define R_NDP_BRK1 0xDA4 ++#define B_NDP_RU_BRK BIT(0) ++#define R_BRK_ASYNC_RST_EN_1 0x0DC0 ++#define R_BRK_ASYNC_RST_EN_2 0x0DC4 ++#define R_BRK_ASYNC_RST_EN_3 0x0DC8 ++#define R_P0_RXCK 0x12A0 ++#define B_P0_RXCK_VAL GENMASK(18, 16) ++#define B_P0_RXCK_ON BIT(19) ++#define B_P0_RXCK_BW3 BIT(30) ++#define R_P0_NRBW 0x12B8 ++#define B_P0_NRBW_DBG BIT(30) ++#define R_S0_RXDC 0x12D4 ++#define B_S0_RXDC_I GENMASK(25, 16) ++#define B_S0_RXDC_Q GENMASK(31, 26) ++#define R_S0_RXDC2 0x12D8 ++#define B_S0_RXDC2_SEL GENMASK(9, 8) ++#define B_S0_RXDC2_AVG GENMASK(7, 6) ++#define B_S0_RXDC2_MEN GENMASK(5, 4) ++#define B_S0_RXDC2_Q2 GENMASK(3, 0) ++#define R_CFO_COMP_SEG0_L 0x1384 ++#define R_CFO_COMP_SEG0_H 0x1388 ++#define R_CFO_COMP_SEG0_CTRL 0x138C ++#define R_DBG32_D 0x1730 ++#define R_TX_COUNTER 0x1A40 ++#define R_IFS_CLM_TX_CNT 0x1ACC ++#define B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK GENMASK(31, 16) ++#define B_IFS_CLM_TX_CNT_MSK GENMASK(15, 0) ++#define R_IFS_CLM_CCA 0x1AD0 ++#define B_IFS_CLM_OFDMCCA_EXCLUDE_FA_MSK GENMASK(31, 16) ++#define B_IFS_CLM_CCKCCA_EXCLUDE_FA_MSK GENMASK(15, 0) ++#define R_IFS_CLM_FA 0x1AD4 ++#define B_IFS_CLM_OFDM_FA_MSK GENMASK(31, 16) ++#define B_IFS_CLM_CCK_FA_MSK GENMASK(15, 0) ++#define R_IFS_HIS 0x1AD8 ++#define B_IFS_T4_HIS_MSK GENMASK(31, 24) ++#define B_IFS_T3_HIS_MSK GENMASK(23, 16) ++#define B_IFS_T2_HIS_MSK GENMASK(15, 8) ++#define B_IFS_T1_HIS_MSK GENMASK(7, 0) ++#define R_IFS_AVG_L 0x1ADC ++#define B_IFS_T2_AVG_MSK GENMASK(31, 16) ++#define B_IFS_T1_AVG_MSK GENMASK(15, 0) ++#define R_IFS_AVG_H 0x1AE0 ++#define B_IFS_T4_AVG_MSK GENMASK(31, 16) ++#define B_IFS_T3_AVG_MSK GENMASK(15, 0) ++#define R_IFS_CCA_L 0x1AE4 ++#define B_IFS_T2_CCA_MSK GENMASK(31, 16) ++#define B_IFS_T1_CCA_MSK GENMASK(15, 0) ++#define R_IFS_CCA_H 0x1AE8 ++#define B_IFS_T4_CCA_MSK GENMASK(31, 16) ++#define B_IFS_T3_CCA_MSK GENMASK(15, 0) ++#define R_IFSCNT 0x1AEC ++#define B_IFSCNT_DONE_MSK BIT(16) ++#define B_IFSCNT_TOTAL_CNT_MSK GENMASK(15, 0) ++#define R_TXAGC_TP 0x1C04 ++#define B_TXAGC_TP GENMASK(2, 0) ++#define R_TSSI_THER 0x1C10 ++#define B_TSSI_THER GENMASK(29, 24) ++#define R_TXAGC_BB 0x1C60 ++#define B_TXAGC_BB_OFT GENMASK(31, 16) ++#define B_TXAGC_BB GENMASK(31, 24) ++#define R_S0_ADDCK 0x1E00 ++#define B_S0_ADDCK_I GENMASK(9, 0) ++#define B_S0_ADDCK_Q GENMASK(19, 10) ++#define R_ADC_FIFO 0x20fc ++#define B_ADC_FIFO_RST GENMASK(31, 24) ++#define R_TXFIR0 0x2300 ++#define B_TXFIR_C01 GENMASK(23, 0) ++#define R_TXFIR2 0x2304 ++#define B_TXFIR_C23 GENMASK(23, 0) ++#define R_TXFIR4 0x2308 ++#define B_TXFIR_C45 GENMASK(23, 0) ++#define R_TXFIR6 0x230c ++#define B_TXFIR_C67 GENMASK(23, 0) ++#define R_TXFIR8 0x2310 ++#define B_TXFIR_C89 GENMASK(23, 0) ++#define R_TXFIRA 0x2314 ++#define B_TXFIR_CAB GENMASK(23, 0) ++#define R_TXFIRC 0x2318 ++#define B_TXFIR_CCD GENMASK(23, 0) ++#define R_TXFIRE 0x231c ++#define B_TXFIR_CEF GENMASK(23, 0) ++#define R_RXCCA 0x2344 ++#define B_RXCCA_DIS BIT(31) ++#define R_RXSC 0x237C ++#define B_RXSC_EN BIT(0) ++#define R_RXSCOBC 0x23B0 ++#define B_RXSCOBC_TH GENMASK(18, 0) ++#define R_RXSCOCCK 0x23B4 ++#define B_RXSCOCCK_TH GENMASK(18, 0) ++#define R_P1_EN_SOUND_WO_NDP 0x2D7C ++#define B_P1_EN_SOUND_WO_NDP BIT(1) ++#define R_P1_DBGMOD 0x32B8 ++#define B_P1_DBGMOD_ON BIT(30) ++#define R_S1_RXDC 0x32D4 ++#define B_S1_RXDC_I GENMASK(25, 16) ++#define B_S1_RXDC_Q GENMASK(31, 26) ++#define R_S1_RXDC2 0x32D8 ++#define B_S1_RXDC2_EN GENMASK(5, 4) ++#define B_S1_RXDC2_SEL GENMASK(9, 8) ++#define B_S1_RXDC2_Q2 GENMASK(3, 0) ++#define R_TXAGC_BB_S1 0x3C60 ++#define B_TXAGC_BB_S1_OFT GENMASK(31, 16) ++#define B_TXAGC_BB_S1 GENMASK(31, 24) ++#define R_S1_ADDCK 0x3E00 ++#define B_S1_ADDCK_I GENMASK(9, 0) ++#define B_S1_ADDCK_Q GENMASK(19, 10) ++#define R_DCFO 0x4264 ++#define B_DCFO GENMASK(1, 0) ++#define R_SEG0CSI 0x42AC ++#define B_SEG0CSI_IDX GENMASK(10, 0) ++#define R_SEG0CSI_EN 0x42C4 ++#define B_SEG0CSI_EN BIT(23) ++#define R_BSS_CLR_MAP 0x43ac ++#define B_BSS_CLR_MAP_VLD0 BIT(28) ++#define B_BSS_CLR_MAP_TGT GENMASK(27, 22) ++#define B_BSS_CLR_MAP_STAID GENMASK(21, 11) ++#define R_CFO_TRK0 0x4404 ++#define R_CFO_TRK1 0x440C ++#define B_CFO_TRK_MSK GENMASK(14, 10) ++#define R_DCFO_COMP_S0 0x448C ++#define B_DCFO_COMP_S0_MSK GENMASK(11, 0) ++#define R_DCFO_WEIGHT 0x4490 ++#define B_DCFO_WEIGHT_MSK GENMASK(27, 24) ++#define R_DCFO_OPT 0x4494 ++#define B_DCFO_OPT_EN BIT(29) ++#define R_BANDEDGE 0x4498 ++#define B_BANDEDGE_EN BIT(30) ++#define R_TXPATH_SEL 0x458C ++#define B_TXPATH_SEL_MSK GENMASK(31, 28) ++#define R_TXPWR 0x4594 ++#define B_TXPWR_MSK GENMASK(30, 22) ++#define R_TXNSS_MAP 0x45B4 ++#define B_TXNSS_MAP_MSK GENMASK(20, 17) ++#define R_PATH0_IB_PKPW 0x4628 ++#define B_PATH0_IB_PKPW_MSK GENMASK(11, 6) ++#define R_PATH0_LNA_ERR1 0x462C ++#define B_PATH0_LNA_ERR_G1_A_MSK GENMASK(29, 24) ++#define B_PATH0_LNA_ERR_G0_G_MSK GENMASK(17, 12) ++#define B_PATH0_LNA_ERR_G0_A_MSK GENMASK(11, 6) ++#define R_PATH0_LNA_ERR2 0x4630 ++#define B_PATH0_LNA_ERR_G2_G_MSK GENMASK(23, 18) ++#define B_PATH0_LNA_ERR_G2_A_MSK GENMASK(17, 12) ++#define B_PATH0_LNA_ERR_G1_G_MSK GENMASK(5, 0) ++#define R_PATH0_LNA_ERR3 0x4634 ++#define B_PATH0_LNA_ERR_G4_G_MSK GENMASK(29, 24) ++#define B_PATH0_LNA_ERR_G4_A_MSK GENMASK(23, 18) ++#define B_PATH0_LNA_ERR_G3_G_MSK GENMASK(11, 6) ++#define B_PATH0_LNA_ERR_G3_A_MSK GENMASK(5, 0) ++#define R_PATH0_LNA_ERR4 0x4638 ++#define B_PATH0_LNA_ERR_G6_A_MSK GENMASK(29, 24) ++#define B_PATH0_LNA_ERR_G5_G_MSK GENMASK(17, 12) ++#define B_PATH0_LNA_ERR_G5_A_MSK GENMASK(11, 6) ++#define R_PATH0_LNA_ERR5 0x463C ++#define B_PATH0_LNA_ERR_G6_G_MSK GENMASK(5, 0) ++#define R_PATH0_TIA_ERR_G0 0x4640 ++#define B_PATH0_TIA_ERR_G0_G_MSK GENMASK(23, 18) ++#define B_PATH0_TIA_ERR_G0_A_MSK GENMASK(17, 12) ++#define R_PATH0_TIA_ERR_G1 0x4644 ++#define B_PATH0_TIA_ERR_G1_SEL GENMASK(31, 30) ++#define B_PATH0_TIA_ERR_G1_G_MSK GENMASK(11, 6) ++#define B_PATH0_TIA_ERR_G1_A_MSK GENMASK(5, 0) ++#define R_PATH0_IB_PBK 0x4650 ++#define B_PATH0_IB_PBK_MSK GENMASK(14, 10) ++#define R_PATH0_RXB_INIT 0x4658 ++#define B_PATH0_RXB_INIT_IDX_MSK GENMASK(9, 5) ++#define R_PATH0_LNA_INIT 0x4668 ++#define B_PATH0_LNA_INIT_IDX_MSK GENMASK(26, 24) ++#define R_PATH0_BTG 0x466C ++#define B_PATH0_BTG_SHEN GENMASK(18, 17) ++#define R_PATH0_TIA_INIT 0x4674 ++#define B_PATH0_TIA_INIT_IDX_MSK BIT(17) ++#define R_PATH0_P20_FOLLOW_BY_PAGCUGC 0x46A0 ++#define B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) ++#define R_PATH0_S20_FOLLOW_BY_PAGCUGC 0x46A4 ++#define B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) ++#define R_P0_NBIIDX 0x469C ++#define B_P0_NBIIDX_VAL GENMASK(11, 0) ++#define B_P0_NBIIDX_NOTCH_EN BIT(12) ++#define R_P1_MODE 0x4718 ++#define B_P1_MODE_SEL GENMASK(31, 30) ++#define R_PATH1_LNA_INIT 0x473C ++#define B_PATH1_LNA_INIT_IDX_MSK GENMASK(26, 24) ++#define R_PATH1_TIA_INIT 0x4748 ++#define B_PATH1_TIA_INIT_IDX_MSK BIT(17) ++#define R_PATH1_BTG 0x4740 ++#define B_PATH1_BTG_SHEN GENMASK(18, 17) ++#define R_PATH1_RXB_INIT 0x472C ++#define B_PATH1_RXB_INIT_IDX_MSK GENMASK(9, 5) ++#define R_PATH1_P20_FOLLOW_BY_PAGCUGC 0x4774 ++#define B_PATH1_P20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) ++#define R_PATH1_S20_FOLLOW_BY_PAGCUGC 0x4778 ++#define B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5) ++#define R_P1_NBIIDX 0x4770 ++#define B_P1_NBIIDX_VAL GENMASK(11, 0) ++#define B_P1_NBIIDX_NOTCH_EN BIT(12) ++#define R_SEG0R_PD 0x481C ++#define B_SEG0R_PD_SPATIAL_REUSE_EN_MSK BIT(29) ++#define B_SEG0R_PD_LOWER_BOUND_MSK GENMASK(10, 6) ++#define R_2P4G_BAND 0x4970 ++#define B_2P4G_BAND_SEL BIT(1) ++#define R_FC0_BW 0x4974 ++#define B_FC0_BW_INV GENMASK(6, 0) ++#define B_FC0_BW_SET GENMASK(31, 30) ++#define R_CHBW_MOD 0x4978 ++#define B_CHBW_MOD_PRICH GENMASK(11, 8) ++#define B_CHBW_MOD_SBW GENMASK(13, 12) ++#define R_CFO_COMP_SEG1_L 0x5384 ++#define R_CFO_COMP_SEG1_H 0x5388 ++#define R_CFO_COMP_SEG1_CTRL 0x538C ++#define B_CFO_COMP_VALID_BIT BIT(29) ++#define B_CFO_COMP_WEIGHT_MSK GENMASK(27, 24) ++#define B_CFO_COMP_VAL_MSK GENMASK(11, 0) ++#define R_DPD_OFT_EN 0x5800 ++#define B_DPD_OFT_EN BIT(28) ++#define R_DPD_OFT_ADDR 0x5804 ++#define B_DPD_OFT_ADDR GENMASK(31, 27) ++#define R_P0_TMETER 0x5810 ++#define B_P0_TMETER GENMASK(15, 10) ++#define B_P0_TMETER_DIS BIT(16) ++#define B_P0_TMETER_TRK BIT(24) ++#define R_P0_TSSI_TRK 0x5818 ++#define B_P0_TSSI_TRK_EN BIT(30) ++#define B_P0_TSSI_OFT_EN BIT(28) ++#define B_P0_TSSI_OFT GENMASK(7, 0) ++#define R_P0_TSSI_AVG 0x5820 ++#define B_P0_TSSI_AVG GENMASK(15, 12) ++#define R_P0_RFCTM 0x5864 ++#define B_P0_RFCTM_VAL GENMASK(25, 20) ++#define R_P0_RFCTM_RDY BIT(26) ++#define R_P0_TXDPD 0x58D4 ++#define B_P0_TXDPD GENMASK(31, 28) ++#define R_P0_TXPW_RSTB 0x58DC ++#define B_P0_TXPW_RSTB_MANON BIT(30) ++#define B_P0_TXPW_RSTB_TSSI BIT(31) ++#define R_P0_TSSI_MV_AVG 0x58E4 ++#define B_P0_TSSI_MV_AVG GENMASK(13, 11) ++#define R_TXGAIN_SCALE 0x58F0 ++#define B_TXGAIN_SCALE_EN BIT(19) ++#define B_TXGAIN_SCALE_OFT GENMASK(31, 24) ++#define R_P0_TSSI_BASE 0x5C00 ++#define R_S0_DACKI 0x5E00 ++#define B_S0_DACKI_AR GENMASK(31, 28) ++#define B_S0_DACKI_EN BIT(3) ++#define R_S0_DACKI2 0x5E30 ++#define B_S0_DACKI2_K GENMASK(21, 12) ++#define R_S0_DACKI7 0x5E44 ++#define B_S0_DACKI7_K GENMASK(15, 8) ++#define R_S0_DACKI8 0x5E48 ++#define B_S0_DACKI8_K GENMASK(15, 8) ++#define R_S0_DACKQ 0x5E50 ++#define B_S0_DACKQ_AR GENMASK(31, 28) ++#define B_S0_DACKQ_EN BIT(3) ++#define R_S0_DACKQ2 0x5E80 ++#define B_S0_DACKQ2_K GENMASK(21, 12) ++#define R_S0_DACKQ7 0x5E94 ++#define B_S0_DACKQ7_K GENMASK(15, 8) ++#define R_S0_DACKQ8 0x5E98 ++#define B_S0_DACKQ8_K GENMASK(15, 8) ++#define R_P1_TMETER 0x7810 ++#define B_P1_TMETER GENMASK(15, 10) ++#define B_P1_TMETER_DIS BIT(16) ++#define B_P1_TMETER_TRK BIT(24) ++#define R_P1_TSSI_TRK 0x7818 ++#define B_P1_TSSI_TRK_EN BIT(30) ++#define B_P1_TSSI_OFT_EN BIT(28) ++#define B_P1_TSSI_OFT GENMASK(7, 0) ++#define R_P1_TSSI_AVG 0x7820 ++#define B_P1_TSSI_AVG GENMASK(15, 12) ++#define R_P1_RFCTM 0x7864 ++#define R_P1_RFCTM_RDY BIT(26) ++#define B_P1_RFCTM_VAL GENMASK(25, 20) ++#define R_P1_TXPW_RSTB 0x78DC ++#define B_P1_TXPW_RSTB_MANON BIT(30) ++#define B_P1_TXPW_RSTB_TSSI BIT(31) ++#define R_P1_TSSI_MV_AVG 0x78E4 ++#define B_P1_TSSI_MV_AVG GENMASK(13, 11) ++#define R_TSSI_THOF 0x7C00 ++#define R_S1_DACKI 0x7E00 ++#define B_S1_DACKI_AR GENMASK(31, 28) ++#define B_S1_DACKI_EN BIT(3) ++#define R_S1_DACKI2 0x7E30 ++#define B_S1_DACKI2_K GENMASK(21, 12) ++#define R_S1_DACKI7 0x7E44 ++#define B_S1_DACKI_K GENMASK(15, 8) ++#define R_S1_DACKI8 0x7E48 ++#define B_S1_DACKI8_K GENMASK(15, 8) ++#define R_S1_DACKQ 0x7E50 ++#define B_S1_DACKQ_AR GENMASK(31, 28) ++#define B_S1_DACKQ_EN BIT(3) ++#define R_S1_DACKQ2 0x7E80 ++#define B_S1_DACKQ2_K GENMASK(21, 12) ++#define R_S1_DACKQ7 0x7E94 ++#define B_S1_DACKQ7_K GENMASK(15, 8) ++#define R_S1_DACKQ8 0x7E98 ++#define B_S1_DACKQ8_K GENMASK(15, 8) ++#define R_NCTL_CFG 0x8000 ++#define B_NCTL_CFG_SPAGE GENMASK(2, 1) ++#define R_NCTL_RPT 0x8008 ++#define B_NCTL_RPT_FLG BIT(26) ++#define R_NCTL_N1 0x8010 ++#define B_NCTL_N1_CIP GENMASK(7, 0) ++#define R_NCTL_N2 0x8014 ++#define R_IQK_COM 0x8018 ++#define R_IQK_DIF 0x801C ++#define B_IQK_DIF_TRX GENMASK(1, 0) ++#define R_IQK_DIF1 0x8020 ++#define B_IQK_DIF1_TXPI GENMASK(19, 0) ++#define R_IQK_DIF2 0x8024 ++#define B_IQK_DIF2_RXPI GENMASK(19, 0) ++#define R_IQK_DIF4 0x802C ++#define B_IQK_DIF4_TXT GENMASK(11, 0) ++#define B_IQK_DIF4_RXT GENMASK(27, 16) ++#define R_IQK_CFG 0x8034 ++#define B_IQK_CFG_SET GENMASK(5, 4) ++#define R_TPG_MOD 0x806C ++#define B_TPG_MOD_F GENMASK(2, 1) ++#define R_MDPK_SYNC 0x8070 ++#define B_MDPK_SYNC_SEL BIT(31) ++#define B_MDPK_SYNC_MAN GENMASK(31, 28) ++#define R_MDPK_RX_DCK 0x8074 ++#define R_NCTL_RW 0x8080 ++#define R_KIP_SYSCFG 0x8088 ++#define R_KIP_CLK 0x808C ++#define R_LDL_NORM 0x80A0 ++#define B_LDL_NORM_PN GENMASK(12, 8) ++#define B_LDL_NORM_OP GENMASK(1, 0) ++#define R_DPK_CTL 0x80B0 ++#define B_DPK_CTL_EN BIT(28) ++#define R_DPK_CFG 0x80B8 ++#define B_DPK_CFG_IDX GENMASK(14, 12) ++#define R_DPK_CFG2 0x80BC ++#define B_DPK_CFG2_ST BIT(14) ++#define R_DPK_CFG3 0x80C0 ++#define R_KPATH_CFG 0x80D0 ++#define R_KIP_RPT1 0x80D4 ++#define B_KIP_RPT1_SEL GENMASK(21, 16) ++#define R_SRAM_IQRX 0x80D8 ++#define R_GAPK 0x80E0 ++#define B_GAPK_ADR BIT(0) ++#define R_SRAM_IQRX2 0x80E8 ++#define R_DPK_TRK 0x80f0 ++#define B_DPK_TRK_DIS BIT(31) ++#define R_RPT_COM 0x80FC ++#define B_PRT_COM_SYNERR BIT(30) ++#define B_PRT_COM_DCI GENMASK(27, 16) ++#define B_PRT_COM_CORV GENMASK(15, 8) ++#define B_PRT_COM_DCQ GENMASK(11, 0) ++#define B_PRT_COM_GL GENMASK(7, 4) ++#define B_PRT_COM_CORI GENMASK(7, 0) ++#define R_COEF_SEL 0x8104 ++#define B_COEF_SEL_IQC BIT(0) ++#define B_COEF_SEL_MDPD BIT(8) ++#define R_CFIR_SYS 0x8120 ++#define R_IQK_RES 0x8124 ++#define B_IQK_RES_TXCFIR GENMASK(11, 8) ++#define B_IQK_RES_RXCFIR GENMASK(3, 0) ++#define R_TXIQC 0x8138 ++#define R_RXIQC 0x813c ++#define B_RXIQC_BYPASS BIT(0) ++#define B_RXIQC_BYPASS2 BIT(2) ++#define B_RXIQC_NEWP GENMASK(19, 8) ++#define B_RXIQC_NEWX GENMASK(31, 20) ++#define R_KIP 0x8140 ++#define B_KIP_DBCC BIT(0) ++#define B_KIP_RFGAIN BIT(8) ++#define R_RFGAIN 0x8144 ++#define B_RFGAIN_PAD GENMASK(4, 0) ++#define B_RFGAIN_TXBB GENMASK(12, 8) ++#define R_RFGAIN_BND 0x8148 ++#define B_RFGAIN_BND GENMASK(4, 0) ++#define R_CFIR_MAP 0x8150 ++#define R_CFIR_LUT 0x8154 ++#define B_CFIR_LUT_SEL BIT(8) ++#define B_CFIR_LUT_G3 BIT(3) ++#define B_CFIR_LUT_G2 BIT(2) ++#define B_CFIR_LUT_GP GENMASK(1, 0) ++#define R_DPD_V1 0x81a0 ++#define R_DPD_CH0 0x81AC ++#define R_DPD_BND 0x81B4 ++#define R_DPD_CH0A 0x81BC ++#define R_TXAGC_RFK 0x81C4 ++#define B_TXAGC_RFK_CH0 GENMASK(5, 0) ++#define R_DPD_COM 0x81C8 ++#define R_KIP_IQP 0x81CC ++#define B_KIP_IQP_IQSW GENMASK(5, 0) ++#define R_KIP_RPT 0x81D4 ++#define B_KIP_RPT_SEL GENMASK(21, 16) ++#define R_W_COEF 0x81D8 ++#define R_LOAD_COEF 0x81DC ++#define B_LOAD_COEF_MDPD BIT(16) ++#define B_LOAD_COEF_CFIR GENMASK(1, 0) ++#define B_LOAD_COEF_AUTO BIT(0) ++#define R_RPT_PER 0x81FC ++#define R_RXCFIR_P0C0 0x8D40 ++#define R_RXCFIR_P0C1 0x8D84 ++#define R_RXCFIR_P0C2 0x8DC8 ++#define R_RXCFIR_P0C3 0x8E0C ++#define R_TXCFIR_P0C0 0x8F50 ++#define R_TXCFIR_P0C1 0x8F84 ++#define R_TXCFIR_P0C2 0x8FB8 ++#define R_TXCFIR_P0C3 0x8FEC ++#define R_RXCFIR_P1C0 0x9140 ++#define R_RXCFIR_P1C1 0x9184 ++#define R_RXCFIR_P1C2 0x91C8 ++#define R_RXCFIR_P1C3 0x920C ++#define R_TXCFIR_P1C0 0x9350 ++#define R_TXCFIR_P1C1 0x9384 ++#define R_TXCFIR_P1C2 0x93B8 ++#define R_TXCFIR_P1C3 0x93EC ++#define R_IQKINF 0x9FE0 ++#define B_IQKINF_VER GENMASK(31, 24) ++#define B_IQKINF_FAIL_RXGRP GENMASK(23, 16) ++#define B_IQKINF_FAIL_TXGRP GENMASK(15, 8) ++#define B_IQKINF_FAIL GENMASK(3, 0) ++#define B_IQKINF_F_RX BIT(3) ++#define B_IQKINF_FTX BIT(2) ++#define B_IQKINF_FFIN BIT(1) ++#define B_IQKINF_FCOR BIT(0) ++#define R_IQKCH 0x9FE4 ++#define B_IQKCH_CH GENMASK(15, 8) ++#define B_IQKCH_BW GENMASK(7, 4) ++#define B_IQKCH_BAND GENMASK(3, 0) ++#define R_IQKINF2 0x9FE8 ++#define B_IQKINF2_FCNT GENMASK(23, 16) ++#define B_IQKINF2_KCNT GENMASK(15, 8) ++#define B_IQKINF2_NCTLV GENMAKS(7, 0) ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c +new file mode 100644 +index 000000000000..f00b94ecfff4 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/regd.c +@@ -0,0 +1,353 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "debug.h" ++#include "ps.h" ++ ++#define COUNTRY_REGD(_alpha2, _txpwr_regd_2g, _txpwr_regd_5g) \ ++ {.alpha2 = (_alpha2), \ ++ .txpwr_regd[RTW89_BAND_2G] = (_txpwr_regd_2g), \ ++ .txpwr_regd[RTW89_BAND_5G] = (_txpwr_regd_5g) \ ++ } ++ ++static const struct rtw89_regulatory rtw89_ww_regd = ++ COUNTRY_REGD("00", RTW89_WW, RTW89_WW); ++ ++static const struct rtw89_regulatory rtw89_regd_map[] = { ++ COUNTRY_REGD("AR", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("BO", RTW89_WW, RTW89_FCC), ++ COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("CL", RTW89_WW, RTW89_CHILE), ++ COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("CR", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("EC", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("SV", RTW89_WW, RTW89_FCC), ++ COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("HN", RTW89_WW, RTW89_FCC), ++ COUNTRY_REGD("MX", RTW89_FCC, RTW89_MEXICO), ++ COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("US", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("UY", RTW89_WW, RTW89_FCC), ++ COUNTRY_REGD("VE", RTW89_WW, RTW89_FCC), ++ COUNTRY_REGD("PR", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("DO", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("AT", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CY", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("DK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("EE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("FI", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("FR", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("DE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GR", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("HU", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IS", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IT", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LV", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LI", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LT", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LU", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MT", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MC", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NL", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("PL", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("PT", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SI", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ES", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GB", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AL", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("HR", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("EG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IQ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IL", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("JO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KW", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LB", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LS", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("OM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("QA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("RO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("RU", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("RS", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ME", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ZA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TR", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("UA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("YE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ZW", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BD", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("HK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI), ++ COUNTRY_REGD("KR", RTW89_KCC, RTW89_KCC), ++ COUNTRY_REGD("MY", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("PK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("PH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("TH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("VN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AU", RTW89_WW, RTW89_ACMA), ++ COUNTRY_REGD("NZ", RTW89_WW, RTW89_ACMA), ++ COUNTRY_REGD("PG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CA", RTW89_IC, RTW89_IC), ++ COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK), ++ COUNTRY_REGD("JM", RTW89_WW, RTW89_FCC), ++ COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("TT", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("TN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AF", RTW89_ETSI, RTW89_ETSI), ++ COUNTRY_REGD("DZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AS", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("AD", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AI", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AQ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("AM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("BY", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BZ", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("BJ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("BT", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BW", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BV", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("BN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BF", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("BI", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CV", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("CF", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TD", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CX", RTW89_WW, RTW89_ACMA), ++ COUNTRY_REGD("CC", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CD", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("CI", RTW89_ETSI, RTW89_ETSI), ++ COUNTRY_REGD("DJ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("GQ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ER", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ET", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("FK", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("FO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("FJ", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("GF", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("PF", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TF", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GI", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GL", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("GP", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("GG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GW", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GY", RTW89_FCC, RTW89_NCC), ++ COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("HM", RTW89_WW, RTW89_ACMA), ++ COUNTRY_REGD("VA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("JE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KI", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LA", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LR", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("LY", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MW", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MV", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ML", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MH", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("MQ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MR", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MU", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("YT", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("MD", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MN", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("MS", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NR", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NP", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NC", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("NU", RTW89_WW, RTW89_ACMA), ++ COUNTRY_REGD("NF", RTW89_WW, RTW89_ACMA), ++ COUNTRY_REGD("MP", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("PW", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("RE", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("RW", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("MF", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("SX", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("PM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("VC", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("WS", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("SM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ST", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("SC", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("SL", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SB", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("GS", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("SJ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("SZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TJ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TK", RTW89_WW, RTW89_ACMA), ++ COUNTRY_REGD("TO", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TC", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("TV", RTW89_ETSI, RTW89_NA), ++ COUNTRY_REGD("UG", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("VI", RTW89_FCC, RTW89_FCC), ++ COUNTRY_REGD("UZ", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("VU", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("WF", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("EH", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("ZM", RTW89_WW, RTW89_ETSI), ++ COUNTRY_REGD("IR", RTW89_WW, RTW89_ETSI), ++}; ++ ++static const struct rtw89_regulatory *rtw89_regd_find_reg_by_name(char *alpha2) ++{ ++ u32 i; ++ ++ for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) { ++ if (!memcmp(rtw89_regd_map[i].alpha2, alpha2, 2)) ++ return &rtw89_regd_map[i]; ++ } ++ ++ return &rtw89_ww_regd; ++} ++ ++static bool rtw89_regd_is_ww(const struct rtw89_regulatory *regd) ++{ ++ return regd == &rtw89_ww_regd; ++} ++ ++int rtw89_regd_init(struct rtw89_dev *rtwdev, ++ void (*reg_notifier)(struct wiphy *wiphy, ++ struct regulatory_request *request)) ++{ ++ const struct rtw89_regulatory *chip_regd; ++ struct wiphy *wiphy = rtwdev->hw->wiphy; ++ int ret; ++ ++ if (!wiphy) ++ return -EINVAL; ++ ++ chip_regd = rtw89_regd_find_reg_by_name(rtwdev->efuse.country_code); ++ if (!rtw89_regd_is_ww(chip_regd)) { ++ rtwdev->regd = chip_regd; ++ /* Ignore country ie if there is a country domain programmed in chip */ ++ wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; ++ wiphy->regulatory_flags |= REGULATORY_STRICT_REG; ++ ++ ret = regulatory_hint(rtwdev->hw->wiphy, rtwdev->regd->alpha2); ++ if (ret) ++ rtw89_warn(rtwdev, "failed to hint regulatory:%d\n", ret); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_REGD, ++ "efuse country code %c%c, mapping to 2g txregd %d, 5g txregd %d\n", ++ rtwdev->efuse.country_code[0], rtwdev->efuse.country_code[1], ++ rtwdev->regd->txpwr_regd[RTW89_BAND_2G], ++ rtwdev->regd->txpwr_regd[RTW89_BAND_5G]); ++ ++ return 0; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_REGD, ++ "worldwide roaming chip, follow the setting of stack(%c%c), mapping to 2g txregd %d, 5g txregd %d\n", ++ rtwdev->regd->alpha2[0], rtwdev->regd->alpha2[1], ++ rtwdev->regd->txpwr_regd[RTW89_BAND_2G], ++ rtwdev->regd->txpwr_regd[RTW89_BAND_5G]); ++ ++ return 0; ++} ++ ++static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev, ++ struct wiphy *wiphy, ++ struct regulatory_request *request) ++{ ++ rtwdev->regd = rtw89_regd_find_reg_by_name(request->alpha2); ++ /* This notification might be set from the system of distros, ++ * and it does not expect the regulatory will be modified by ++ * connecting to an AP (i.e. country ie). ++ */ ++ if (request->initiator == NL80211_REGDOM_SET_BY_USER && ++ !rtw89_regd_is_ww(rtwdev->regd)) ++ wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; ++ else ++ wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE; ++} ++ ++void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request) ++{ ++ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); ++ struct rtw89_dev *rtwdev = hw->priv; ++ ++ mutex_lock(&rtwdev->mutex); ++ rtw89_leave_ps_mode(rtwdev); ++ ++ if (wiphy->regd) { ++ rtw89_debug(rtwdev, RTW89_DBG_REGD, ++ "There is a country domain programmed in chip, ignore notifications\n"); ++ goto exit; ++ } ++ rtw89_regd_notifier_apply(rtwdev, wiphy, request); ++ rtw89_debug(rtwdev, RTW89_DBG_REGD, ++ "get alpha2 %c%c from initiator %d, mapping to 2g txregd %d, 5g txregd %d\n", ++ request->alpha2[0], request->alpha2[1], request->initiator, ++ rtwdev->regd->txpwr_regd[RTW89_BAND_2G], ++ rtwdev->regd->txpwr_regd[RTW89_BAND_5G]); ++ ++ rtw89_chip_set_txpwr(rtwdev); ++ ++exit: ++ mutex_unlock(&rtwdev->mutex); ++} +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +new file mode 100644 +index 000000000000..b1b87f0aadbb +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +@@ -0,0 +1,2036 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "coex.h" ++#include "mac.h" ++#include "phy.h" ++#include "reg.h" ++#include "rtw8852a.h" ++#include "rtw8852a_rfk.h" ++#include "rtw8852a_table.h" ++#include "txrx.h" ++ ++static const struct rtw89_hfc_ch_cfg rtw8852a_hfc_chcfg_pcie[] = { ++ {128, 1896, grp_0}, /* ACH 0 */ ++ {128, 1896, grp_0}, /* ACH 1 */ ++ {128, 1896, grp_0}, /* ACH 2 */ ++ {128, 1896, grp_0}, /* ACH 3 */ ++ {128, 1896, grp_1}, /* ACH 4 */ ++ {128, 1896, grp_1}, /* ACH 5 */ ++ {128, 1896, grp_1}, /* ACH 6 */ ++ {128, 1896, grp_1}, /* ACH 7 */ ++ {32, 1896, grp_0}, /* B0MGQ */ ++ {128, 1896, grp_0}, /* B0HIQ */ ++ {32, 1896, grp_1}, /* B1MGQ */ ++ {128, 1896, grp_1}, /* B1HIQ */ ++ {40, 0, 0} /* FWCMDQ */ ++}; ++ ++static const struct rtw89_hfc_pub_cfg rtw8852a_hfc_pubcfg_pcie = { ++ 1896, /* Group 0 */ ++ 1896, /* Group 1 */ ++ 3792, /* Public Max */ ++ 0 /* WP threshold */ ++}; ++ ++static const struct rtw89_hfc_param_ini rtw8852a_hfc_param_ini_pcie[] = { ++ [RTW89_QTA_SCC] = {rtw8852a_hfc_chcfg_pcie, &rtw8852a_hfc_pubcfg_pcie, ++ &rtw_hfc_preccfg_pcie, RTW89_HCIFC_POH}, ++ [RTW89_QTA_DLFW] = {NULL, NULL, &rtw_hfc_preccfg_pcie, RTW89_HCIFC_POH}, ++ [RTW89_QTA_INVALID] = {NULL}, ++}; ++ ++static const struct rtw89_dle_mem rtw8852a_dle_mem_pcie[] = { ++ [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &wde_size0, &ple_size0, &wde_qt0, ++ &wde_qt0, &ple_qt4, &ple_qt5}, ++ [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &wde_size4, &ple_size4, ++ &wde_qt4, &wde_qt4, &ple_qt13, &ple_qt13}, ++ [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, ++ NULL}, ++}; ++ ++static const struct rtw89_reg2_def rtw8852a_pmac_ht20_mcs7_tbl[] = { ++ {0x44AC, 0x00000000}, ++ {0x44B0, 0x00000000}, ++ {0x44B4, 0x00000000}, ++ {0x44B8, 0x00000000}, ++ {0x44BC, 0x00000000}, ++ {0x44C0, 0x00000000}, ++ {0x44C4, 0x00000000}, ++ {0x44C8, 0x00000000}, ++ {0x44CC, 0x00000000}, ++ {0x44D0, 0x00000000}, ++ {0x44D4, 0x00000000}, ++ {0x44D8, 0x00000000}, ++ {0x44DC, 0x00000000}, ++ {0x44E0, 0x00000000}, ++ {0x44E4, 0x00000000}, ++ {0x44E8, 0x00000000}, ++ {0x44EC, 0x00000000}, ++ {0x44F0, 0x00000000}, ++ {0x44F4, 0x00000000}, ++ {0x44F8, 0x00000000}, ++ {0x44FC, 0x00000000}, ++ {0x4500, 0x00000000}, ++ {0x4504, 0x00000000}, ++ {0x4508, 0x00000000}, ++ {0x450C, 0x00000000}, ++ {0x4510, 0x00000000}, ++ {0x4514, 0x00000000}, ++ {0x4518, 0x00000000}, ++ {0x451C, 0x00000000}, ++ {0x4520, 0x00000000}, ++ {0x4524, 0x00000000}, ++ {0x4528, 0x00000000}, ++ {0x452C, 0x00000000}, ++ {0x4530, 0x4E1F3E81}, ++ {0x4534, 0x00000000}, ++ {0x4538, 0x0000005A}, ++ {0x453C, 0x00000000}, ++ {0x4540, 0x00000000}, ++ {0x4544, 0x00000000}, ++ {0x4548, 0x00000000}, ++ {0x454C, 0x00000000}, ++ {0x4550, 0x00000000}, ++ {0x4554, 0x00000000}, ++ {0x4558, 0x00000000}, ++ {0x455C, 0x00000000}, ++ {0x4560, 0x4060001A}, ++ {0x4564, 0x40000000}, ++ {0x4568, 0x00000000}, ++ {0x456C, 0x00000000}, ++ {0x4570, 0x04000007}, ++ {0x4574, 0x0000DC87}, ++ {0x4578, 0x00000BAB}, ++ {0x457C, 0x03E00000}, ++ {0x4580, 0x00000048}, ++ {0x4584, 0x00000000}, ++ {0x4588, 0x000003E8}, ++ {0x458C, 0x30000000}, ++ {0x4590, 0x00000000}, ++ {0x4594, 0x10000000}, ++ {0x4598, 0x00000001}, ++ {0x459C, 0x00030000}, ++ {0x45A0, 0x01000000}, ++ {0x45A4, 0x03000200}, ++ {0x45A8, 0xC00001C0}, ++ {0x45AC, 0x78018000}, ++ {0x45B0, 0x80000000}, ++ {0x45B4, 0x01C80600}, ++ {0x45B8, 0x00000002}, ++ {0x4594, 0x10000000} ++}; ++ ++static const struct rtw89_reg3_def rtw8852a_btc_preagc_en_defs[] = { ++ {0x4624, GENMASK(20, 14), 0x40}, ++ {0x46f8, GENMASK(20, 14), 0x40}, ++ {0x4674, GENMASK(20, 19), 0x2}, ++ {0x4748, GENMASK(20, 19), 0x2}, ++ {0x4650, GENMASK(14, 10), 0x18}, ++ {0x4724, GENMASK(14, 10), 0x18}, ++ {0x4688, GENMASK(1, 0), 0x3}, ++ {0x475c, GENMASK(1, 0), 0x3}, ++}; ++ ++static DECLARE_PHY_REG3_TBL(rtw8852a_btc_preagc_en_defs); ++ ++static const struct rtw89_reg3_def rtw8852a_btc_preagc_dis_defs[] = { ++ {0x4624, GENMASK(20, 14), 0x1a}, ++ {0x46f8, GENMASK(20, 14), 0x1a}, ++ {0x4674, GENMASK(20, 19), 0x1}, ++ {0x4748, GENMASK(20, 19), 0x1}, ++ {0x4650, GENMASK(14, 10), 0x12}, ++ {0x4724, GENMASK(14, 10), 0x12}, ++ {0x4688, GENMASK(1, 0), 0x0}, ++ {0x475c, GENMASK(1, 0), 0x0}, ++}; ++ ++static DECLARE_PHY_REG3_TBL(rtw8852a_btc_preagc_dis_defs); ++ ++static const struct rtw89_pwr_cfg rtw8852a_pwron[] = { ++ {0x00C6, ++ PWR_CV_MSK_B, ++ PWR_INTF_MSK_PCIE, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(6), BIT(6)}, ++ {0x1086, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_SDIO, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), 0}, ++ {0x1086, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_SDIO, ++ PWR_BASE_MAC, ++ PWR_CMD_POLL, BIT(1), BIT(1)}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(4) | BIT(3), 0}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(7), 0}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(2), 0}, ++ {0x0006, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_POLL, BIT(1), BIT(1)}, ++ {0x0006, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_POLL, BIT(0), 0}, ++ {0x106D, ++ PWR_CV_MSK_B | PWR_CV_MSK_C, ++ PWR_INTF_MSK_USB, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(6), 0}, ++ {0x0088, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0088, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0088, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0088, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0088, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0083, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(6), 0}, ++ {0x0080, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(5), BIT(5)}, ++ {0x0024, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0), 0}, ++ {0x02A0, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x02A2, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(7) | BIT(6) | BIT(5), 0}, ++ {0x0071, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_PCIE, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(4), 0}, ++ {0x0010, ++ PWR_CV_MSK_A, ++ PWR_INTF_MSK_PCIE, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(2), BIT(2)}, ++ {0x02A0, ++ PWR_CV_MSK_A, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(7) | BIT(6), 0}, ++ {0xFFFF, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ 0, ++ PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw89_pwr_cfg rtw8852a_pwroff[] = { ++ {0x02F0, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, 0xFF, 0}, ++ {0x02F1, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, 0xFF, 0}, ++ {0x0006, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0002, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(1) | BIT(0), 0}, ++ {0x0082, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(1) | BIT(0), 0}, ++ {0x106D, ++ PWR_CV_MSK_B | PWR_CV_MSK_C, ++ PWR_INTF_MSK_USB, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(6), BIT(6)}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ PWR_BASE_MAC, ++ PWR_CMD_POLL, BIT(1), 0}, ++ {0x0091, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_PCIE, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_PCIE, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(2), BIT(2)}, ++ {0x0007, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_USB, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(4), 0}, ++ {0x0007, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_SDIO, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(6) | BIT(4), 0}, ++ {0x0005, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_SDIO, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(4) | BIT(3), BIT(3)}, ++ {0x0005, ++ PWR_CV_MSK_C | PWR_CV_MSK_D | PWR_CV_MSK_E | PWR_CV_MSK_F | ++ PWR_CV_MSK_G, ++ PWR_INTF_MSK_USB, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(4) | BIT(3), BIT(3)}, ++ {0x1086, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_SDIO, ++ PWR_BASE_MAC, ++ PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x1086, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_SDIO, ++ PWR_BASE_MAC, ++ PWR_CMD_POLL, BIT(1), 0}, ++ {0xFFFF, ++ PWR_CV_MSK_ALL, ++ PWR_INTF_MSK_ALL, ++ 0, ++ PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw89_pwr_cfg * const pwr_on_seq_8852a[] = { ++ rtw8852a_pwron, NULL ++}; ++ ++static const struct rtw89_pwr_cfg * const pwr_off_seq_8852a[] = { ++ rtw8852a_pwroff, NULL ++}; ++ ++static void rtw8852ae_efuse_parsing(struct rtw89_efuse *efuse, ++ struct rtw8852a_efuse *map) ++{ ++ ether_addr_copy(efuse->addr, map->e.mac_addr); ++ efuse->rfe_type = map->rfe_type; ++ efuse->xtal_cap = map->xtal_k; ++} ++ ++static void rtw8852a_efuse_parsing_tssi(struct rtw89_dev *rtwdev, ++ struct rtw8852a_efuse *map) ++{ ++ struct rtw89_tssi_info *tssi = &rtwdev->tssi; ++ struct rtw8852a_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi}; ++ u8 i, j; ++ ++ tssi->thermal[RF_PATH_A] = map->path_a_therm; ++ tssi->thermal[RF_PATH_B] = map->path_b_therm; ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi, ++ sizeof(ofst[i]->cck_tssi)); ++ ++ for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++) ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n", ++ i, j, tssi->tssi_cck[i][j]); ++ ++ memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi, ++ sizeof(ofst[i]->bw40_tssi)); ++ memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM, ++ ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g)); ++ ++ for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++) ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n", ++ i, j, tssi->tssi_mcs[i][j]); ++ } ++} ++ ++static int rtw8852a_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map) ++{ ++ struct rtw89_efuse *efuse = &rtwdev->efuse; ++ struct rtw8852a_efuse *map; ++ ++ map = (struct rtw8852a_efuse *)log_map; ++ ++ efuse->country_code[0] = map->country_code[0]; ++ efuse->country_code[1] = map->country_code[1]; ++ rtw8852a_efuse_parsing_tssi(rtwdev, map); ++ ++ switch (rtwdev->hci.type) { ++ case RTW89_HCI_TYPE_PCIE: ++ rtw8852ae_efuse_parsing(efuse, map); ++ break; ++ default: ++ return -ENOTSUPP; ++ } ++ ++ rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type); ++ ++ return 0; ++} ++ ++static void rtw8852a_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map) ++{ ++ struct rtw89_tssi_info *tssi = &rtwdev->tssi; ++ static const u32 tssi_trim_addr[RF_PATH_NUM_8852A] = {0x5D6, 0x5AB}; ++ u32 addr = rtwdev->chip->phycap_addr; ++ bool pg = false; ++ u32 ofst; ++ u8 i, j; ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) { ++ /* addrs are in decreasing order */ ++ ofst = tssi_trim_addr[i] - addr - j; ++ tssi->tssi_trim[i][j] = phycap_map[ofst]; ++ ++ if (phycap_map[ofst] != 0xff) ++ pg = true; ++ } ++ } ++ ++ if (!pg) { ++ memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim)); ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM] no PG, set all trim info to 0\n"); ++ } ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) ++ for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n", ++ i, j, tssi->tssi_trim[i][j], ++ tssi_trim_addr[i] - j); ++} ++ ++static void rtw8852a_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev, ++ u8 *phycap_map) ++{ ++ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; ++ static const u32 thm_trim_addr[RF_PATH_NUM_8852A] = {0x5DF, 0x5DC}; ++ u32 addr = rtwdev->chip->phycap_addr; ++ u8 i; ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n", ++ i, info->thermal_trim[i]); ++ ++ if (info->thermal_trim[i] != 0xff) ++ info->pg_thermal_trim = true; ++ } ++} ++ ++static void rtw8852a_thermal_trim(struct rtw89_dev *rtwdev) ++{ ++#define __thm_setting(raw) \ ++({ \ ++ u8 __v = (raw); \ ++ ((__v & 0x1) << 3) | ((__v & 0x1f) >> 1); \ ++}) ++ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; ++ u8 i, val; ++ ++ if (!info->pg_thermal_trim) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[THERMAL][TRIM] no PG, do nothing\n"); ++ ++ return; ++ } ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ val = __thm_setting(info->thermal_trim[i]); ++ rtw89_write_rf(rtwdev, i, RR_TM2, RR_TM2_OFF, val); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n", ++ i, val); ++ } ++#undef __thm_setting ++} ++ ++static void rtw8852a_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev, ++ u8 *phycap_map) ++{ ++ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; ++ static const u32 pabias_trim_addr[RF_PATH_NUM_8852A] = {0x5DE, 0x5DB}; ++ u32 addr = rtwdev->chip->phycap_addr; ++ u8 i; ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n", ++ i, info->pa_bias_trim[i]); ++ ++ if (info->pa_bias_trim[i] != 0xff) ++ info->pg_pa_bias_trim = true; ++ } ++} ++ ++static void rtw8852a_pa_bias_trim(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; ++ u8 pabias_2g, pabias_5g; ++ u8 i; ++ ++ if (!info->pg_pa_bias_trim) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[PA_BIAS][TRIM] no PG, do nothing\n"); ++ ++ return; ++ } ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]); ++ pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n", ++ i, pabias_2g, pabias_5g); ++ ++ rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG, pabias_2g); ++ rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA, pabias_5g); ++ } ++} ++ ++static int rtw8852a_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map) ++{ ++ rtw8852a_phycap_parsing_tssi(rtwdev, phycap_map); ++ rtw8852a_phycap_parsing_thermal_trim(rtwdev, phycap_map); ++ rtw8852a_phycap_parsing_pa_bias_trim(rtwdev, phycap_map); ++ ++ return 0; ++} ++ ++static void rtw8852a_power_trim(struct rtw89_dev *rtwdev) ++{ ++ rtw8852a_thermal_trim(rtwdev); ++ rtw8852a_pa_bias_trim(rtwdev); ++} ++ ++static void rtw8852a_set_channel_mac(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_params *param, ++ u8 mac_idx) ++{ ++ u32 rf_mod = rtw89_mac_reg_by_idx(R_AX_WMAC_RFMOD, mac_idx); ++ u32 sub_carr = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE, ++ mac_idx); ++ u32 chk_rate = rtw89_mac_reg_by_idx(R_AX_TXRATE_CHK, mac_idx); ++ u8 txsc20 = 0, txsc40 = 0; ++ ++ switch (param->bandwidth) { ++ case RTW89_CHANNEL_WIDTH_80: ++ txsc40 = rtw89_phy_get_txsc(rtwdev, param, ++ RTW89_CHANNEL_WIDTH_40); ++ fallthrough; ++ case RTW89_CHANNEL_WIDTH_40: ++ txsc20 = rtw89_phy_get_txsc(rtwdev, param, ++ RTW89_CHANNEL_WIDTH_20); ++ break; ++ default: ++ break; ++ } ++ ++ switch (param->bandwidth) { ++ case RTW89_CHANNEL_WIDTH_80: ++ rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(1)); ++ rtw89_write32(rtwdev, sub_carr, txsc20 | (txsc40 << 4)); ++ break; ++ case RTW89_CHANNEL_WIDTH_40: ++ rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, BIT(0)); ++ rtw89_write32(rtwdev, sub_carr, txsc20); ++ break; ++ case RTW89_CHANNEL_WIDTH_20: ++ rtw89_write8_clr(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK); ++ rtw89_write32(rtwdev, sub_carr, 0); ++ break; ++ default: ++ break; ++ } ++ ++ if (param->center_chan > 14) ++ rtw89_write8_set(rtwdev, chk_rate, ++ B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6); ++ else ++ rtw89_write8_clr(rtwdev, chk_rate, ++ B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6); ++} ++ ++static const u32 rtw8852a_sco_barker_threshold[14] = { ++ 0x1cfea, 0x1d0e1, 0x1d1d7, 0x1d2cd, 0x1d3c3, 0x1d4b9, 0x1d5b0, 0x1d6a6, ++ 0x1d79c, 0x1d892, 0x1d988, 0x1da7f, 0x1db75, 0x1ddc4 ++}; ++ ++static const u32 rtw8852a_sco_cck_threshold[14] = { ++ 0x27de3, 0x27f35, 0x28088, 0x281da, 0x2832d, 0x2847f, 0x285d2, 0x28724, ++ 0x28877, 0x289c9, 0x28b1c, 0x28c6e, 0x28dc1, 0x290ed ++}; ++ ++static int rtw8852a_ctrl_sco_cck(struct rtw89_dev *rtwdev, u8 central_ch, ++ u8 primary_ch, enum rtw89_bandwidth bw) ++{ ++ u8 ch_element; ++ ++ if (bw == RTW89_CHANNEL_WIDTH_20) { ++ ch_element = central_ch - 1; ++ } else if (bw == RTW89_CHANNEL_WIDTH_40) { ++ if (primary_ch == 1) ++ ch_element = central_ch - 1 + 2; ++ else ++ ch_element = central_ch - 1 - 2; ++ } else { ++ rtw89_warn(rtwdev, "Invalid BW:%d for CCK\n", bw); ++ return -EINVAL; ++ } ++ rtw89_phy_write32_mask(rtwdev, R_RXSCOBC, B_RXSCOBC_TH, ++ rtw8852a_sco_barker_threshold[ch_element]); ++ rtw89_phy_write32_mask(rtwdev, R_RXSCOCCK, B_RXSCOCCK_TH, ++ rtw8852a_sco_cck_threshold[ch_element]); ++ ++ return 0; ++} ++ ++static void rtw8852a_ch_setting(struct rtw89_dev *rtwdev, u8 central_ch, ++ u8 path) ++{ ++ u32 val; ++ ++ val = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); ++ if (val == INV_RF_DATA) { ++ rtw89_warn(rtwdev, "Invalid RF_0x18 for Path-%d\n", path); ++ return; ++ } ++ val &= ~0x303ff; ++ val |= central_ch; ++ if (central_ch > 14) ++ val |= (BIT(16) | BIT(8)); ++ rtw89_write_rf(rtwdev, path, RR_CFGCH, RFREG_MASK, val); ++} ++ ++static u8 rtw8852a_sco_mapping(u8 central_ch) ++{ ++ if (central_ch == 1) ++ return 109; ++ else if (central_ch >= 2 && central_ch <= 6) ++ return 108; ++ else if (central_ch >= 7 && central_ch <= 10) ++ return 107; ++ else if (central_ch >= 11 && central_ch <= 14) ++ return 106; ++ else if (central_ch == 36 || central_ch == 38) ++ return 51; ++ else if (central_ch >= 40 && central_ch <= 58) ++ return 50; ++ else if (central_ch >= 60 && central_ch <= 64) ++ return 49; ++ else if (central_ch == 100 || central_ch == 102) ++ return 48; ++ else if (central_ch >= 104 && central_ch <= 126) ++ return 47; ++ else if (central_ch >= 128 && central_ch <= 151) ++ return 46; ++ else if (central_ch >= 153 && central_ch <= 177) ++ return 45; ++ else ++ return 0; ++} ++ ++static void rtw8852a_ctrl_ch(struct rtw89_dev *rtwdev, u8 central_ch, ++ enum rtw89_phy_idx phy_idx) ++{ ++ u8 sco_comp; ++ bool is_2g = central_ch <= 14; ++ ++ if (phy_idx == RTW89_PHY_0) { ++ /* Path A */ ++ rtw8852a_ch_setting(rtwdev, central_ch, RF_PATH_A); ++ if (is_2g) ++ rtw89_phy_write32_idx(rtwdev, R_PATH0_TIA_ERR_G1, ++ B_PATH0_TIA_ERR_G1_SEL, 1, ++ phy_idx); ++ else ++ rtw89_phy_write32_idx(rtwdev, R_PATH0_TIA_ERR_G1, ++ B_PATH0_TIA_ERR_G1_SEL, 0, ++ phy_idx); ++ ++ /* Path B */ ++ if (!rtwdev->dbcc_en) { ++ rtw8852a_ch_setting(rtwdev, central_ch, RF_PATH_B); ++ if (is_2g) ++ rtw89_phy_write32_idx(rtwdev, R_P1_MODE, ++ B_P1_MODE_SEL, ++ 1, phy_idx); ++ else ++ rtw89_phy_write32_idx(rtwdev, R_P1_MODE, ++ B_P1_MODE_SEL, ++ 0, phy_idx); ++ } else { ++ if (is_2g) ++ rtw89_phy_write32_clr(rtwdev, R_2P4G_BAND, ++ B_2P4G_BAND_SEL); ++ else ++ rtw89_phy_write32_set(rtwdev, R_2P4G_BAND, ++ B_2P4G_BAND_SEL); ++ } ++ /* SCO compensate FC setting */ ++ sco_comp = rtw8852a_sco_mapping(central_ch); ++ rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, ++ sco_comp, phy_idx); ++ } else { ++ /* Path B */ ++ rtw8852a_ch_setting(rtwdev, central_ch, RF_PATH_B); ++ if (is_2g) ++ rtw89_phy_write32_idx(rtwdev, R_P1_MODE, ++ B_P1_MODE_SEL, ++ 1, phy_idx); ++ else ++ rtw89_phy_write32_idx(rtwdev, R_P1_MODE, ++ B_P1_MODE_SEL, ++ 1, phy_idx); ++ /* SCO compensate FC setting */ ++ sco_comp = rtw8852a_sco_mapping(central_ch); ++ rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, ++ sco_comp, phy_idx); ++ } ++ ++ /* Band edge */ ++ if (is_2g) ++ rtw89_phy_write32_idx(rtwdev, R_BANDEDGE, B_BANDEDGE_EN, 1, ++ phy_idx); ++ else ++ rtw89_phy_write32_idx(rtwdev, R_BANDEDGE, B_BANDEDGE_EN, 0, ++ phy_idx); ++ ++ /* CCK parameters */ ++ if (central_ch == 14) { ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, ++ 0x3b13ff); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, ++ 0x1c42de); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, ++ 0xfdb0ad); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, ++ 0xf60f6e); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, ++ 0xfd8f92); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, 0x2d011); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, 0x1c02c); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, ++ 0xfff00a); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR0, B_TXFIR_C01, ++ 0x3d23ff); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR2, B_TXFIR_C23, ++ 0x29b354); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR4, B_TXFIR_C45, 0xfc1c8); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR6, B_TXFIR_C67, ++ 0xfdb053); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIR8, B_TXFIR_C89, ++ 0xf86f9a); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIRA, B_TXFIR_CAB, ++ 0xfaef92); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIRC, B_TXFIR_CCD, ++ 0xfe5fcc); ++ rtw89_phy_write32_mask(rtwdev, R_TXFIRE, B_TXFIR_CEF, ++ 0xffdff5); ++ } ++} ++ ++static void rtw8852a_bw_setting(struct rtw89_dev *rtwdev, u8 bw, u8 path) ++{ ++ u32 val = 0; ++ u32 adc_sel[2] = {0x12d0, 0x32d0}; ++ u32 wbadc_sel[2] = {0x12ec, 0x32ec}; ++ ++ val = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); ++ if (val == INV_RF_DATA) { ++ rtw89_warn(rtwdev, "Invalid RF_0x18 for Path-%d\n", path); ++ return; ++ } ++ val &= ~(BIT(11) | BIT(10)); ++ switch (bw) { ++ case RTW89_CHANNEL_WIDTH_5: ++ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x1); ++ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x0); ++ val |= (BIT(11) | BIT(10)); ++ break; ++ case RTW89_CHANNEL_WIDTH_10: ++ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x2); ++ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x1); ++ val |= (BIT(11) | BIT(10)); ++ break; ++ case RTW89_CHANNEL_WIDTH_20: ++ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); ++ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); ++ val |= (BIT(11) | BIT(10)); ++ break; ++ case RTW89_CHANNEL_WIDTH_40: ++ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); ++ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); ++ val |= BIT(11); ++ break; ++ case RTW89_CHANNEL_WIDTH_80: ++ rtw89_phy_write32_mask(rtwdev, adc_sel[path], 0x6000, 0x0); ++ rtw89_phy_write32_mask(rtwdev, wbadc_sel[path], 0x30, 0x2); ++ val |= BIT(10); ++ break; ++ default: ++ rtw89_warn(rtwdev, "Fail to set ADC\n"); ++ } ++ ++ rtw89_write_rf(rtwdev, path, RR_CFGCH, RFREG_MASK, val); ++} ++ ++static void ++rtw8852a_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw, ++ enum rtw89_phy_idx phy_idx) ++{ ++ /* Switch bandwidth */ ++ switch (bw) { ++ case RTW89_CHANNEL_WIDTH_5: ++ rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x0, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x1, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, ++ 0x0, phy_idx); ++ break; ++ case RTW89_CHANNEL_WIDTH_10: ++ rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x0, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x2, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, ++ 0x0, phy_idx); ++ break; ++ case RTW89_CHANNEL_WIDTH_20: ++ rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x0, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, ++ 0x0, phy_idx); ++ break; ++ case RTW89_CHANNEL_WIDTH_40: ++ rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x1, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, ++ pri_ch, ++ phy_idx); ++ if (pri_ch == RTW89_SC_20_UPPER) ++ rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 1); ++ else ++ rtw89_phy_write32_mask(rtwdev, R_RXSC, B_RXSC_EN, 0); ++ break; ++ case RTW89_CHANNEL_WIDTH_80: ++ rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_SET, 0x2, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_SBW, 0x0, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_CHBW_MOD_PRICH, ++ pri_ch, ++ phy_idx); ++ break; ++ default: ++ rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw, ++ pri_ch); ++ } ++ ++ if (phy_idx == RTW89_PHY_0) { ++ rtw8852a_bw_setting(rtwdev, bw, RF_PATH_A); ++ if (!rtwdev->dbcc_en) ++ rtw8852a_bw_setting(rtwdev, bw, RF_PATH_B); ++ } else { ++ rtw8852a_bw_setting(rtwdev, bw, RF_PATH_B); ++ } ++} ++ ++static void rtw8852a_spur_elimination(struct rtw89_dev *rtwdev, u8 central_ch) ++{ ++ if (central_ch == 153) { ++ rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, B_P0_NBIIDX_VAL, ++ 0x210); ++ rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL, ++ 0x210); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x7c0); ++ rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, ++ B_P0_NBIIDX_NOTCH_EN, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, ++ B_P1_NBIIDX_NOTCH_EN, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, ++ 0x1); ++ } else if (central_ch == 151) { ++ rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, B_P0_NBIIDX_VAL, ++ 0x210); ++ rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL, ++ 0x210); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x40); ++ rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, ++ B_P0_NBIIDX_NOTCH_EN, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, ++ B_P1_NBIIDX_NOTCH_EN, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, ++ 0x1); ++ } else if (central_ch == 155) { ++ rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, B_P0_NBIIDX_VAL, ++ 0x2d0); ++ rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL, ++ 0x2d0); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x740); ++ rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, ++ B_P0_NBIIDX_NOTCH_EN, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, ++ B_P1_NBIIDX_NOTCH_EN, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, ++ 0x1); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_P0_NBIIDX, ++ B_P0_NBIIDX_NOTCH_EN, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, ++ B_P1_NBIIDX_NOTCH_EN, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_SEG0CSI_EN, B_SEG0CSI_EN, ++ 0x0); ++ } ++} ++ ++static void rtw8852a_bb_reset_all(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, ++ phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, ++ phy_idx); ++} ++ ++static void rtw8852a_bb_reset_en(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, bool en) ++{ ++ if (en) ++ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, ++ 1, ++ phy_idx); ++ else ++ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, ++ 0, ++ phy_idx); ++} ++ ++static void rtw8852a_bb_reset(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ rtw89_phy_write32_set(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON); ++ rtw89_phy_write32_set(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); ++ rtw89_phy_write32_set(rtwdev, R_P1_TXPW_RSTB, B_P1_TXPW_RSTB_MANON); ++ rtw89_phy_write32_set(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); ++ rtw8852a_bb_reset_all(rtwdev, phy_idx); ++ rtw89_phy_write32_clr(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON); ++ rtw89_phy_write32_clr(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); ++ rtw89_phy_write32_clr(rtwdev, R_P1_TXPW_RSTB, B_P1_TXPW_RSTB_MANON); ++ rtw89_phy_write32_clr(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); ++} ++ ++static void rtw8852a_bb_macid_ctrl_init(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ u32 addr; ++ ++ for (addr = R_AX_PWR_MACID_LMT_TABLE0; ++ addr <= R_AX_PWR_MACID_LMT_TABLE127; addr += 4) ++ rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, 0); ++} ++ ++static void rtw8852a_bb_sethw(struct rtw89_dev *rtwdev) ++{ ++ rtw89_phy_write32_clr(rtwdev, R_P0_EN_SOUND_WO_NDP, B_P0_EN_SOUND_WO_NDP); ++ rtw89_phy_write32_clr(rtwdev, R_P1_EN_SOUND_WO_NDP, B_P1_EN_SOUND_WO_NDP); ++ ++ if (rtwdev->hal.cv <= CHIP_CCV) { ++ rtw89_phy_write32_set(rtwdev, R_RSTB_WATCH_DOG, B_P0_RSTB_WATCH_DOG); ++ rtw89_phy_write32(rtwdev, R_BRK_ASYNC_RST_EN_1, 0x864FA000); ++ rtw89_phy_write32(rtwdev, R_BRK_ASYNC_RST_EN_2, 0x3F); ++ rtw89_phy_write32(rtwdev, R_BRK_ASYNC_RST_EN_3, 0x7FFF); ++ rtw89_phy_write32_set(rtwdev, R_SPOOF_ASYNC_RST, B_SPOOF_ASYNC_RST); ++ rtw89_phy_write32_set(rtwdev, R_P0_TXPW_RSTB, B_P0_TXPW_RSTB_MANON); ++ rtw89_phy_write32_set(rtwdev, R_P1_TXPW_RSTB, B_P1_TXPW_RSTB_MANON); ++ } ++ rtw89_phy_write32_mask(rtwdev, R_CFO_TRK0, B_CFO_TRK_MSK, 0x1f); ++ rtw89_phy_write32_mask(rtwdev, R_CFO_TRK1, B_CFO_TRK_MSK, 0x0c); ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0x0, RTW89_PHY_0); ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0x0, RTW89_PHY_1); ++ rtw89_phy_write32_clr(rtwdev, R_NDP_BRK0, B_NDP_RU_BRK); ++ rtw89_phy_write32_set(rtwdev, R_NDP_BRK1, B_NDP_RU_BRK); ++ ++ rtw8852a_bb_macid_ctrl_init(rtwdev, RTW89_PHY_0); ++} ++ ++static void rtw8852a_bbrst_for_rfk(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ rtw89_phy_write32_set(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); ++ rtw89_phy_write32_set(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); ++ rtw8852a_bb_reset_all(rtwdev, phy_idx); ++ rtw89_phy_write32_clr(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_TRK_EN); ++ rtw89_phy_write32_clr(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_TRK_EN); ++ udelay(1); ++} ++ ++static void rtw8852a_set_channel_bb(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_params *param, ++ enum rtw89_phy_idx phy_idx) ++{ ++ bool cck_en = param->center_chan > 14 ? false : true; ++ u8 pri_ch_idx = param->pri_ch_idx; ++ ++ if (param->center_chan <= 14) ++ rtw8852a_ctrl_sco_cck(rtwdev, param->center_chan, ++ param->primary_chan, param->bandwidth); ++ ++ rtw8852a_ctrl_ch(rtwdev, param->center_chan, phy_idx); ++ rtw8852a_ctrl_bw(rtwdev, pri_ch_idx, param->bandwidth, phy_idx); ++ if (cck_en) { ++ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 0); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_RXCCA, B_RXCCA_DIS, 1); ++ rtw8852a_bbrst_for_rfk(rtwdev, phy_idx); ++ } ++ rtw8852a_spur_elimination(rtwdev, param->center_chan); ++ rtw8852a_bb_reset_all(rtwdev, phy_idx); ++} ++ ++static void rtw8852a_set_channel(struct rtw89_dev *rtwdev, ++ struct rtw89_channel_params *params) ++{ ++ rtw8852a_set_channel_mac(rtwdev, params, RTW89_MAC_0); ++ rtw8852a_set_channel_bb(rtwdev, params, RTW89_PHY_0); ++} ++ ++static void rtw8852a_dfs_en(struct rtw89_dev *rtwdev, bool en) ++{ ++ if (en) ++ rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 1); ++ else ++ rtw89_phy_write32_mask(rtwdev, R_UPD_P0, B_UPD_P0_EN, 0); ++} ++ ++static void rtw8852a_tssi_cont_en(struct rtw89_dev *rtwdev, bool en, ++ enum rtw89_rf_path path) ++{ ++ static const u32 tssi_trk[2] = {0x5818, 0x7818}; ++ static const u32 ctrl_bbrst[2] = {0x58dc, 0x78dc}; ++ ++ if (en) { ++ rtw89_phy_write32_mask(rtwdev, ctrl_bbrst[path], BIT(30), 0x0); ++ rtw89_phy_write32_mask(rtwdev, tssi_trk[path], BIT(30), 0x0); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, ctrl_bbrst[path], BIT(30), 0x1); ++ rtw89_phy_write32_mask(rtwdev, tssi_trk[path], BIT(30), 0x1); ++ } ++} ++ ++static void rtw8852a_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, ++ u8 phy_idx) ++{ ++ if (!rtwdev->dbcc_en) { ++ rtw8852a_tssi_cont_en(rtwdev, en, RF_PATH_A); ++ rtw8852a_tssi_cont_en(rtwdev, en, RF_PATH_B); ++ } else { ++ if (phy_idx == RTW89_PHY_0) ++ rtw8852a_tssi_cont_en(rtwdev, en, RF_PATH_A); ++ else ++ rtw8852a_tssi_cont_en(rtwdev, en, RF_PATH_B); ++ } ++} ++ ++static void rtw8852a_adc_en(struct rtw89_dev *rtwdev, bool en) ++{ ++ if (en) ++ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, ++ 0x0); ++ else ++ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, ++ 0xf); ++} ++ ++static void rtw8852a_set_channel_help(struct rtw89_dev *rtwdev, bool enter, ++ struct rtw89_channel_help_params *p) ++{ ++ u8 phy_idx = RTW89_PHY_0; ++ ++ if (enter) { ++ rtw89_mac_stop_sch_tx(rtwdev, RTW89_MAC_0, &p->tx_en, RTW89_SCH_TX_SEL_ALL); ++ rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false); ++ rtw8852a_dfs_en(rtwdev, false); ++ rtw8852a_tssi_cont_en_phyidx(rtwdev, false, RTW89_PHY_0); ++ rtw8852a_adc_en(rtwdev, false); ++ fsleep(40); ++ rtw8852a_bb_reset_en(rtwdev, phy_idx, false); ++ } else { ++ rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); ++ rtw8852a_adc_en(rtwdev, true); ++ rtw8852a_dfs_en(rtwdev, true); ++ rtw8852a_tssi_cont_en_phyidx(rtwdev, true, RTW89_PHY_0); ++ rtw8852a_bb_reset_en(rtwdev, phy_idx, true); ++ rtw89_mac_resume_sch_tx(rtwdev, RTW89_MAC_0, p->tx_en); ++ } ++} ++ ++static void rtw8852a_fem_setup(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_efuse *efuse = &rtwdev->efuse; ++ ++ switch (efuse->rfe_type) { ++ case 11: ++ case 12: ++ case 17: ++ case 18: ++ case 51: ++ case 53: ++ rtwdev->fem.epa_2g = true; ++ rtwdev->fem.elna_2g = true; ++ fallthrough; ++ case 9: ++ case 10: ++ case 15: ++ case 16: ++ rtwdev->fem.epa_5g = true; ++ rtwdev->fem.elna_5g = true; ++ break; ++ default: ++ break; ++ } ++} ++ ++static void rtw8852a_rfk_init(struct rtw89_dev *rtwdev) ++{ ++ rtwdev->is_tssi_mode[RF_PATH_A] = false; ++ rtwdev->is_tssi_mode[RF_PATH_B] = false; ++ ++ rtw8852a_rck(rtwdev); ++ rtw8852a_dack(rtwdev); ++ rtw8852a_rx_dck(rtwdev, RTW89_PHY_0, true); ++} ++ ++static void rtw8852a_rfk_channel(struct rtw89_dev *rtwdev) ++{ ++ enum rtw89_phy_idx phy_idx = RTW89_PHY_0; ++ ++ rtw8852a_rx_dck(rtwdev, phy_idx, true); ++ rtw8852a_iqk(rtwdev, phy_idx); ++ rtw8852a_tssi(rtwdev, phy_idx); ++ rtw8852a_dpk(rtwdev, phy_idx); ++} ++ ++static void rtw8852a_rfk_band_changed(struct rtw89_dev *rtwdev) ++{ ++ rtw8852a_tssi_scan(rtwdev, RTW89_PHY_0); ++} ++ ++static void rtw8852a_rfk_scan(struct rtw89_dev *rtwdev, bool start) ++{ ++ rtw8852a_wifi_scan_notify(rtwdev, start, RTW89_PHY_0); ++} ++ ++static void rtw8852a_rfk_track(struct rtw89_dev *rtwdev) ++{ ++ rtw8852a_dpk_track(rtwdev); ++ rtw8852a_iqk_track(rtwdev); ++ rtw8852a_tssi_track(rtwdev); ++} ++ ++static u32 rtw8852a_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, s16 ref) ++{ ++ s8 ofst_int = 0; ++ u8 base_cw_0db = 0x27; ++ u16 tssi_16dbm_cw = 0x12c; ++ s16 pwr_s10_3 = 0; ++ s16 rf_pwr_cw = 0; ++ u16 bb_pwr_cw = 0; ++ u32 pwr_cw = 0; ++ u32 tssi_ofst_cw = 0; ++ ++ pwr_s10_3 = (ref << 1) + (s16)(ofst_int) + (s16)(base_cw_0db << 3); ++ bb_pwr_cw = FIELD_GET(GENMASK(2, 0), pwr_s10_3); ++ rf_pwr_cw = FIELD_GET(GENMASK(8, 3), pwr_s10_3); ++ rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63); ++ pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw; ++ ++ tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3)); ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, ++ "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n", ++ tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw); ++ ++ return (tssi_ofst_cw << 18) | (pwr_cw << 9) | (ref & GENMASK(8, 0)); ++} ++ ++static ++void rtw8852a_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, ++ s16 pw_ofst, enum rtw89_mac_idx mac_idx) ++{ ++ s32 val_1t = 0; ++ s32 val_2t = 0; ++ u32 reg; ++ ++ if (pw_ofst < -16 || pw_ofst > 15) { ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] Err pwr_offset=%d\n", ++ pw_ofst); ++ return; ++ } ++ reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_CTRL, mac_idx); ++ rtw89_write32_set(rtwdev, reg, B_AX_PWR_UL_TB_CTRL_EN); ++ val_1t = (s32)pw_ofst; ++ reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_1T, mac_idx); ++ rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, val_1t); ++ val_2t = max(val_1t - 3, -16); ++ reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_2T, mac_idx); ++ rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_MASK, val_2t); ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] Set TB pwr_offset=(%d, %d)\n", ++ val_1t, val_2t); ++} ++ ++static void rtw8852a_set_txpwr_ref(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ static const u32 addr[RF_PATH_NUM_8852A] = {0x5800, 0x7800}; ++ const u32 mask = 0x7FFFFFF; ++ const u8 ofst_ofdm = 0x4; ++ const u8 ofst_cck = 0x8; ++ s16 ref_ofdm = 0; ++ s16 ref_cck = 0; ++ u32 val; ++ u8 i; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr reference\n"); ++ ++ rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL, ++ GENMASK(27, 10), 0x0); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n"); ++ val = rtw8852a_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm); ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) ++ rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val, ++ phy_idx); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n"); ++ val = rtw8852a_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck); ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) ++ rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val, ++ phy_idx); ++} ++ ++static void rtw8852a_set_txpwr_byrate(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ u8 ch = rtwdev->hal.current_channel; ++ static const u8 rs[] = { ++ RTW89_RS_CCK, ++ RTW89_RS_OFDM, ++ RTW89_RS_MCS, ++ RTW89_RS_HEDCM, ++ }; ++ s8 tmp; ++ u8 i, j; ++ u32 val, shf, addr = R_AX_PWR_BY_RATE; ++ struct rtw89_rate_desc cur; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, ++ "[TXPWR] set txpwr byrate with ch=%d\n", ch); ++ ++ for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) { ++ for (i = 0; i < ARRAY_SIZE(rs); i++) { ++ if (cur.nss >= rtw89_rs_nss_max[rs[i]]) ++ continue; ++ ++ val = 0; ++ cur.rs = rs[i]; ++ ++ for (j = 0; j < rtw89_rs_idx_max[rs[i]]; j++) { ++ cur.idx = j; ++ shf = (j % 4) * 8; ++ tmp = rtw89_phy_read_txpwr_byrate(rtwdev, &cur); ++ val |= (tmp << shf); ++ ++ if ((j + 1) % 4) ++ continue; ++ ++ rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); ++ val = 0; ++ addr += 4; ++ } ++ } ++ } ++} ++ ++static void rtw8852a_set_txpwr_offset(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ struct rtw89_rate_desc desc = { ++ .nss = RTW89_NSS_1, ++ .rs = RTW89_RS_OFFSET, ++ }; ++ u32 val = 0; ++ s8 v; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n"); ++ ++ for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) { ++ v = rtw89_phy_read_txpwr_byrate(rtwdev, &desc); ++ val |= ((v & 0xf) << (4 * desc.idx)); ++ } ++ ++ rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_OFST_CTRL, ++ GENMASK(19, 0), val); ++} ++ ++static void rtw8852a_set_txpwr_limit(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++#define __MAC_TXPWR_LMT_PAGE_SIZE 40 ++ u8 ch = rtwdev->hal.current_channel; ++ u8 bw = rtwdev->hal.current_band_width; ++ struct rtw89_txpwr_limit lmt[NTX_NUM_8852A]; ++ u32 addr, val; ++ const s8 *ptr; ++ u8 i, j, k; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, ++ "[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw); ++ ++ for (i = 0; i < NTX_NUM_8852A; i++) { ++ rtw89_phy_fill_txpwr_limit(rtwdev, &lmt[i], i); ++ ++ for (j = 0; j < __MAC_TXPWR_LMT_PAGE_SIZE; j += 4) { ++ addr = R_AX_PWR_LMT + j + __MAC_TXPWR_LMT_PAGE_SIZE * i; ++ ptr = (s8 *)&lmt[i] + j; ++ val = 0; ++ ++ for (k = 0; k < 4; k++) ++ val |= (ptr[k] << (8 * k)); ++ ++ rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); ++ } ++ } ++#undef __MAC_TXPWR_LMT_PAGE_SIZE ++} ++ ++static void rtw8852a_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++#define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24 ++ u8 ch = rtwdev->hal.current_channel; ++ u8 bw = rtwdev->hal.current_band_width; ++ struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852A]; ++ u32 addr, val; ++ const s8 *ptr; ++ u8 i, j, k; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, ++ "[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw); ++ ++ for (i = 0; i < NTX_NUM_8852A; i++) { ++ rtw89_phy_fill_txpwr_limit_ru(rtwdev, &lmt_ru[i], i); ++ ++ for (j = 0; j < __MAC_TXPWR_LMT_RU_PAGE_SIZE; j += 4) { ++ addr = R_AX_PWR_RU_LMT + j + ++ __MAC_TXPWR_LMT_RU_PAGE_SIZE * i; ++ ptr = (s8 *)&lmt_ru[i] + j; ++ val = 0; ++ ++ for (k = 0; k < 4; k++) ++ val |= (ptr[k] << (8 * k)); ++ ++ rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); ++ } ++ } ++ ++#undef __MAC_TXPWR_LMT_RU_PAGE_SIZE ++} ++ ++static void rtw8852a_set_txpwr(struct rtw89_dev *rtwdev) ++{ ++ rtw8852a_set_txpwr_byrate(rtwdev, RTW89_PHY_0); ++ rtw8852a_set_txpwr_limit(rtwdev, RTW89_PHY_0); ++ rtw8852a_set_txpwr_limit_ru(rtwdev, RTW89_PHY_0); ++} ++ ++static void rtw8852a_set_txpwr_ctrl(struct rtw89_dev *rtwdev) ++{ ++ rtw8852a_set_txpwr_ref(rtwdev, RTW89_PHY_0); ++ rtw8852a_set_txpwr_offset(rtwdev, RTW89_PHY_0); ++} ++ ++static int ++rtw8852a_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) ++{ ++ int ret; ++ ++ ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL2, 0x07763333); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_COEXT_CTRL, 0x01ebf004); ++ if (ret) ++ return ret; ++ ++ ret = rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_AX_PWR_UL_CTRL0, 0x0002f8ff); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++void rtw8852a_bb_set_plcp_tx(struct rtw89_dev *rtwdev) ++{ ++ u8 i = 0; ++ u32 addr, val; ++ ++ for (i = 0; i < ARRAY_SIZE(rtw8852a_pmac_ht20_mcs7_tbl); i++) { ++ addr = rtw8852a_pmac_ht20_mcs7_tbl[i].addr; ++ val = rtw8852a_pmac_ht20_mcs7_tbl[i].data; ++ rtw89_phy_write32(rtwdev, addr, val); ++ } ++} ++ ++static void rtw8852a_stop_pmac_tx(struct rtw89_dev *rtwdev, ++ struct rtw8852a_bb_pmac_info *tx_info, ++ enum rtw89_phy_idx idx) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC Stop Tx"); ++ if (tx_info->mode == CONT_TX) ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_CTX_EN, 0, ++ idx); ++ else if (tx_info->mode == PKTS_TX) ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_PTX_EN, 0, ++ idx); ++} ++ ++static void rtw8852a_start_pmac_tx(struct rtw89_dev *rtwdev, ++ struct rtw8852a_bb_pmac_info *tx_info, ++ enum rtw89_phy_idx idx) ++{ ++ enum rtw8852a_pmac_mode mode = tx_info->mode; ++ u32 pkt_cnt = tx_info->tx_cnt; ++ u16 period = tx_info->period; ++ ++ if (mode == CONT_TX && !tx_info->is_cck) { ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_CTX_EN, 1, ++ idx); ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CTx Start"); ++ } else if (mode == PKTS_TX) { ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, B_PMAC_PTX_EN, 1, ++ idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_PRD, ++ B_PMAC_TX_PRD_MSK, period, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CNT, B_PMAC_TX_CNT_MSK, ++ pkt_cnt, idx); ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC PTx Start"); ++ } ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CTRL, B_PMAC_TXEN_DIS, 1, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_TX_CTRL, B_PMAC_TXEN_DIS, 0, idx); ++} ++ ++void rtw8852a_bb_set_pmac_tx(struct rtw89_dev *rtwdev, ++ struct rtw8852a_bb_pmac_info *tx_info, ++ enum rtw89_phy_idx idx) ++{ ++ if (!tx_info->en_pmac_tx) { ++ rtw8852a_stop_pmac_tx(rtwdev, tx_info, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0, idx); ++ if (rtwdev->hal.current_band_type == RTW89_BAND_2G) ++ rtw89_phy_write32_clr(rtwdev, R_RXCCA, B_RXCCA_DIS); ++ return; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC Tx Enable"); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_TXEN, 1, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_RXEN, 1, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_RX_CFG1, B_PMAC_OPT1_MSK, 0x3f, ++ idx); ++ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 0, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 1, idx); ++ rtw89_phy_write32_set(rtwdev, R_RXCCA, B_RXCCA_DIS); ++ rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, idx); ++ rtw8852a_start_pmac_tx(rtwdev, tx_info, idx); ++} ++ ++void rtw8852a_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable, ++ u16 tx_cnt, u16 period, u16 tx_time, ++ enum rtw89_phy_idx idx) ++{ ++ struct rtw8852a_bb_pmac_info tx_info = {0}; ++ ++ tx_info.en_pmac_tx = enable; ++ tx_info.is_cck = 0; ++ tx_info.mode = PKTS_TX; ++ tx_info.tx_cnt = tx_cnt; ++ tx_info.period = period; ++ tx_info.tx_time = tx_time; ++ rtw8852a_bb_set_pmac_tx(rtwdev, &tx_info, idx); ++} ++ ++void rtw8852a_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm, ++ enum rtw89_phy_idx idx) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CFG Tx PWR = %d", pwr_dbm); ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 1, idx); ++ rtw89_phy_write32_idx(rtwdev, R_TXPWR, B_TXPWR_MSK, pwr_dbm, idx); ++} ++ ++void rtw8852a_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path) ++{ ++ u32 rst_mask0 = 0; ++ u32 rst_mask1 = 0; ++ ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 7, RTW89_PHY_0); ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 7, RTW89_PHY_1); ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "PMAC CFG Tx Path = %d", tx_path); ++ if (!rtwdev->dbcc_en) { ++ if (tx_path == RF_PATH_A) { ++ rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, ++ B_TXPATH_SEL_MSK, 1); ++ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, ++ B_TXNSS_MAP_MSK, 0); ++ } else if (tx_path == RF_PATH_B) { ++ rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, ++ B_TXPATH_SEL_MSK, 2); ++ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, ++ B_TXNSS_MAP_MSK, 0); ++ } else if (tx_path == RF_PATH_AB) { ++ rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, ++ B_TXPATH_SEL_MSK, 3); ++ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, ++ B_TXNSS_MAP_MSK, 4); ++ } else { ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "Error Tx Path"); ++ } ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, ++ 1); ++ rtw89_phy_write32_idx(rtwdev, R_TXPATH_SEL, B_TXPATH_SEL_MSK, 2, ++ RTW89_PHY_1); ++ rtw89_phy_write32_mask(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, ++ 0); ++ rtw89_phy_write32_idx(rtwdev, R_TXNSS_MAP, B_TXNSS_MAP_MSK, 4, ++ RTW89_PHY_1); ++ } ++ rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI; ++ rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI; ++ if (tx_path == RF_PATH_A) { ++ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 1); ++ rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 3); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 1); ++ rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 3); ++ } ++} ++ ++void rtw8852a_bb_tx_mode_switch(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx idx, u8 mode) ++{ ++ if (mode != 0) ++ return; ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "Tx mode switch"); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_TXEN, 0, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_GNT, B_PMAC_GNT_RXEN, 0, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_RX_CFG1, B_PMAC_OPT1_MSK, 0, idx); ++ rtw89_phy_write32_idx(rtwdev, R_PMAC_RXMOD, B_PMAC_RXMOD_MSK, 0, idx); ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_DPD_EN, 0, idx); ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, idx); ++ rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_PWR_EN, 0, idx); ++} ++ ++static void rtw8852a_bb_ctrl_btc_preagc(struct rtw89_dev *rtwdev, bool bt_en) ++{ ++ rtw89_phy_write_reg3_tbl(rtwdev, bt_en ? &rtw8852a_btc_preagc_en_defs_tbl : ++ &rtw8852a_btc_preagc_dis_defs_tbl); ++} ++ ++static u8 rtw8852a_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) ++{ ++ if (rtwdev->is_tssi_mode[rf_path]) { ++ u32 addr = 0x1c10 + (rf_path << 13); ++ ++ return (u8)rtw89_phy_read32_mask(rtwdev, addr, 0x3F000000); ++ } ++ ++ rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); ++ rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0); ++ rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); ++ ++ fsleep(200); ++ ++ return (u8)rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL); ++} ++ ++static void rtw8852a_btc_set_rfe(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_module *module = &btc->mdinfo; ++ ++ module->rfe_type = rtwdev->efuse.rfe_type; ++ module->cv = rtwdev->hal.cv; ++ module->bt_solo = 0; ++ module->switch_type = BTC_SWITCH_INTERNAL; ++ ++ if (module->rfe_type > 0) ++ module->ant.num = (module->rfe_type % 2 ? 2 : 3); ++ else ++ module->ant.num = 2; ++ ++ module->ant.diversity = 0; ++ module->ant.isolation = 10; ++ ++ if (module->ant.num == 3) { ++ module->ant.type = BTC_ANT_DEDICATED; ++ module->bt_pos = BTC_BT_ALONE; ++ } else { ++ module->ant.type = BTC_ANT_SHARED; ++ module->bt_pos = BTC_BT_BTG; ++ } ++} ++ ++static ++void rtw8852a_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val) ++{ ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, 0xfffff, 0x20000); ++ rtw89_write_rf(rtwdev, path, RR_LUTWA, 0xfffff, group); ++ rtw89_write_rf(rtwdev, path, RR_LUTWD0, 0xfffff, val); ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, 0xfffff, 0x0); ++} ++ ++static void rtw8852a_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) ++{ ++ if (btg) { ++ rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG, B_PATH0_BTG_SHEN, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG, B_PATH1_BTG_SHEN, 0x3); ++ rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0x0); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_PATH0_BTG, B_PATH0_BTG_SHEN, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_PATH1_BTG, B_PATH1_BTG_SHEN, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P1, 0xf); ++ rtw89_phy_write32_mask(rtwdev, R_PMAC_GNT, B_PMAC_GNT_P2, 0x4); ++ } ++} ++ ++static void rtw8852a_btc_init_cfg(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_module *module = &btc->mdinfo; ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ const struct rtw89_mac_ax_coex coex_params = { ++ .pta_mode = RTW89_MAC_AX_COEX_RTK_MODE, ++ .direction = RTW89_MAC_AX_COEX_INNER, ++ }; ++ ++ /* PTA init */ ++ rtw89_mac_coex_init(rtwdev, &coex_params); ++ ++ /* set WL Tx response = Hi-Pri */ ++ chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true); ++ chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true); ++ ++ /* set rf gnt debug off */ ++ rtw89_write_rf(rtwdev, RF_PATH_A, RR_WLSEL, 0xfffff, 0x0); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_WLSEL, 0xfffff, 0x0); ++ ++ /* set WL Tx thru in TRX mask table if GNT_WL = 0 && BT_S1 = ss group */ ++ if (module->ant.type == BTC_ANT_SHARED) { ++ rtw8852a_set_trx_mask(rtwdev, ++ RF_PATH_A, BTC_BT_SS_GROUP, 0x5ff); ++ rtw8852a_set_trx_mask(rtwdev, ++ RF_PATH_B, BTC_BT_SS_GROUP, 0x5ff); ++ } else { /* set WL Tx stb if GNT_WL = 0 && BT_S1 = ss group for 3-ant */ ++ rtw8852a_set_trx_mask(rtwdev, ++ RF_PATH_A, BTC_BT_SS_GROUP, 0x5df); ++ rtw8852a_set_trx_mask(rtwdev, ++ RF_PATH_B, BTC_BT_SS_GROUP, 0x5df); ++ } ++ ++ /* set PTA break table */ ++ rtw89_write32(rtwdev, R_BTC_BREAK_TABLE, BTC_BREAK_PARAM); ++ ++ /* enable BT counter 0xda40[16,2] = 2b'11 */ ++ rtw89_write32_set(rtwdev, ++ R_AX_CSR_MODE, B_AX_BT_CNT_RST | B_AX_STATIS_BT_EN); ++ btc->cx.wl.status.map.init_ok = true; ++} ++ ++static ++void rtw8852a_btc_set_wl_pri(struct rtw89_dev *rtwdev, u8 map, bool state) ++{ ++ u32 bitmap = 0; ++ u32 reg = 0; ++ ++ switch (map) { ++ case BTC_PRI_MASK_TX_RESP: ++ reg = R_BTC_BT_COEX_MSK_TABLE; ++ bitmap = B_BTC_PRI_MASK_TX_RESP_V1; ++ break; ++ case BTC_PRI_MASK_BEACON: ++ reg = R_AX_WL_PRI_MSK; ++ bitmap = B_AX_PTA_WL_PRI_MASK_BCNQ; ++ break; ++ default: ++ return; ++ } ++ ++ if (state) ++ rtw89_write32_set(rtwdev, reg, bitmap); ++ else ++ rtw89_write32_clr(rtwdev, reg, bitmap); ++} ++ ++static inline u32 __btc_ctrl_val_all_time(u32 ctrl) ++{ ++ return FIELD_GET(GENMASK(15, 0), ctrl); ++} ++ ++static inline u32 __btc_ctrl_rst_all_time(u32 cur) ++{ ++ return cur & ~B_AX_FORCE_PWR_BY_RATE_EN; ++} ++ ++static inline u32 __btc_ctrl_gen_all_time(u32 cur, u32 val) ++{ ++ u32 hv = cur & ~B_AX_FORCE_PWR_BY_RATE_VALUE_MASK; ++ u32 lv = val & B_AX_FORCE_PWR_BY_RATE_VALUE_MASK; ++ ++ return hv | lv | B_AX_FORCE_PWR_BY_RATE_EN; ++} ++ ++static inline u32 __btc_ctrl_val_gnt_bt(u32 ctrl) ++{ ++ return FIELD_GET(GENMASK(31, 16), ctrl); ++} ++ ++static inline u32 __btc_ctrl_rst_gnt_bt(u32 cur) ++{ ++ return cur & ~B_AX_TXAGC_BT_EN; ++} ++ ++static inline u32 __btc_ctrl_gen_gnt_bt(u32 cur, u32 val) ++{ ++ u32 ov = cur & ~B_AX_TXAGC_BT_MASK; ++ u32 iv = FIELD_PREP(B_AX_TXAGC_BT_MASK, val); ++ ++ return ov | iv | B_AX_TXAGC_BT_EN; ++} ++ ++static void ++rtw8852a_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val) ++{ ++ const u32 __btc_cr_all_time = R_AX_PWR_RATE_CTRL; ++ const u32 __btc_cr_gnt_bt = R_AX_PWR_COEXT_CTRL; ++ ++#define __do_clr(_chk) ((_chk) == GENMASK(15, 0)) ++#define __handle(_case) \ ++ do { \ ++ const u32 _reg = __btc_cr_ ## _case; \ ++ u32 _val = __btc_ctrl_val_ ## _case(txpwr_val); \ ++ u32 _cur, _wrt; \ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, \ ++ "btc ctrl %s: 0x%x\n", #_case, _val); \ ++ rtw89_mac_txpwr_read32(rtwdev, RTW89_PHY_0, _reg, &_cur);\ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, \ ++ "btc ctrl ori 0x%x: 0x%x\n", _reg, _cur); \ ++ _wrt = __do_clr(_val) ? \ ++ __btc_ctrl_rst_ ## _case(_cur) : \ ++ __btc_ctrl_gen_ ## _case(_cur, _val); \ ++ rtw89_mac_txpwr_write32(rtwdev, RTW89_PHY_0, _reg, _wrt);\ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, \ ++ "btc ctrl set 0x%x: 0x%x\n", _reg, _wrt); \ ++ } while (0) ++ ++ __handle(all_time); ++ __handle(gnt_bt); ++ ++#undef __handle ++#undef __do_clr ++} ++ ++static ++s8 rtw8852a_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) ++{ ++ return clamp_t(s8, val, -100, 0) + 100; ++} ++ ++static struct rtw89_btc_rf_trx_para rtw89_btc_8852a_rf_ul[] = { ++ {255, 0, 0, 7}, /* 0 -> original */ ++ {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ ++ {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ ++ {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ ++ {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ ++ {255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ ++ {6, 1, 0, 7}, ++ {13, 1, 0, 7}, ++ {13, 1, 0, 7} ++}; ++ ++static struct rtw89_btc_rf_trx_para rtw89_btc_8852a_rf_dl[] = { ++ {255, 0, 0, 7}, /* 0 -> original */ ++ {255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */ ++ {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ ++ {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ ++ {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ ++ {255, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ ++ {255, 1, 0, 7}, ++ {255, 1, 0, 7}, ++ {255, 1, 0, 7} ++}; ++ ++static const ++u8 rtw89_btc_8852a_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {60, 50, 40, 30}; ++static const ++u8 rtw89_btc_8852a_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {40, 36, 31, 28}; ++ ++static struct rtw89_btc_fbtc_mreg rtw89_btc_8852a_mon_reg[] = { ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda24), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda28), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda2c), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda30), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda4c), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda10), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda20), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xda34), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xcef4), ++ RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x8424), ++ RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980), ++ RTW89_DEF_FBTC_MREG(REG_BT_MODEM, 4, 0x178), ++}; ++ ++static ++void rtw8852a_btc_bt_aci_imp(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ struct rtw89_btc_bt_link_info *b = &bt->link_info; ++ ++ /* fix LNA2 = level-5 for BT ACI issue at BTG */ ++ if (btc->dm.wl_btg_rx && b->profile_cnt.now != 0) ++ dm->trx_para_level = 1; ++} ++ ++static ++void rtw8852a_btc_update_bt_cnt(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_cx *cx = &btc->cx; ++ u32 val; ++ ++ val = rtw89_read32(rtwdev, R_AX_BT_STAST_HIGH); ++ cx->cnt_bt[BTC_BCNT_HIPRI_TX] = FIELD_GET(B_AX_STATIS_BT_HI_TX_MASK, val); ++ cx->cnt_bt[BTC_BCNT_HIPRI_RX] = FIELD_GET(B_AX_STATIS_BT_HI_RX_MASK, val); ++ ++ val = rtw89_read32(rtwdev, R_AX_BT_STAST_LOW); ++ cx->cnt_bt[BTC_BCNT_LOPRI_TX] = FIELD_GET(B_AX_STATIS_BT_LO_TX_1_MASK, val); ++ cx->cnt_bt[BTC_BCNT_LOPRI_RX] = FIELD_GET(B_AX_STATIS_BT_LO_RX_1_MASK, val); ++ ++ /* clock-gate off before reset counter*/ ++ rtw89_write32_set(rtwdev, R_AX_BTC_CFG, B_AX_DIS_BTC_CLK_G); ++ rtw89_write32_clr(rtwdev, R_AX_CSR_MODE, B_AX_BT_CNT_RST); ++ rtw89_write32_set(rtwdev, R_AX_CSR_MODE, B_AX_BT_CNT_RST); ++ rtw89_write32_clr(rtwdev, R_AX_BTC_CFG, B_AX_DIS_BTC_CLK_G); ++} ++ ++static ++void rtw8852a_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state) ++{ ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x1); ++ ++ /* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */ ++ if (state) ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, ++ RFREG_MASK, 0xa2d7c); ++ else ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, ++ RFREG_MASK, 0xa2020); ++ ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); ++} ++ ++static void rtw8852a_query_ppdu(struct rtw89_dev *rtwdev, ++ struct rtw89_rx_phy_ppdu *phy_ppdu, ++ struct ieee80211_rx_status *status) ++{ ++ u8 path; ++ s8 *rx_power = phy_ppdu->rssi; ++ ++ status->signal = max_t(s8, rx_power[RF_PATH_A], rx_power[RF_PATH_B]); ++ for (path = 0; path < rtwdev->chip->rf_path_num; path++) { ++ status->chains |= BIT(path); ++ status->chain_signal[path] = rx_power[path]; ++ } ++} ++ ++static const struct rtw89_chip_ops rtw8852a_chip_ops = { ++ .bb_reset = rtw8852a_bb_reset, ++ .bb_sethw = rtw8852a_bb_sethw, ++ .read_rf = rtw89_phy_read_rf, ++ .write_rf = rtw89_phy_write_rf, ++ .set_channel = rtw8852a_set_channel, ++ .set_channel_help = rtw8852a_set_channel_help, ++ .read_efuse = rtw8852a_read_efuse, ++ .read_phycap = rtw8852a_read_phycap, ++ .fem_setup = rtw8852a_fem_setup, ++ .rfk_init = rtw8852a_rfk_init, ++ .rfk_channel = rtw8852a_rfk_channel, ++ .rfk_band_changed = rtw8852a_rfk_band_changed, ++ .rfk_scan = rtw8852a_rfk_scan, ++ .rfk_track = rtw8852a_rfk_track, ++ .power_trim = rtw8852a_power_trim, ++ .set_txpwr = rtw8852a_set_txpwr, ++ .set_txpwr_ctrl = rtw8852a_set_txpwr_ctrl, ++ .init_txpwr_unit = rtw8852a_init_txpwr_unit, ++ .get_thermal = rtw8852a_get_thermal, ++ .ctrl_btg = rtw8852a_ctrl_btg, ++ .query_ppdu = rtw8852a_query_ppdu, ++ .bb_ctrl_btc_preagc = rtw8852a_bb_ctrl_btc_preagc, ++ .set_txpwr_ul_tb_offset = rtw8852a_set_txpwr_ul_tb_offset, ++ ++ .btc_set_rfe = rtw8852a_btc_set_rfe, ++ .btc_init_cfg = rtw8852a_btc_init_cfg, ++ .btc_set_wl_pri = rtw8852a_btc_set_wl_pri, ++ .btc_set_wl_txpwr_ctrl = rtw8852a_btc_set_wl_txpwr_ctrl, ++ .btc_get_bt_rssi = rtw8852a_btc_get_bt_rssi, ++ .btc_bt_aci_imp = rtw8852a_btc_bt_aci_imp, ++ .btc_update_bt_cnt = rtw8852a_btc_update_bt_cnt, ++ .btc_wl_s1_standby = rtw8852a_btc_wl_s1_standby, ++}; ++ ++const struct rtw89_chip_info rtw8852a_chip_info = { ++ .chip_id = RTL8852A, ++ .ops = &rtw8852a_chip_ops, ++ .fw_name = "rtw89/rtw8852a_fw.bin", ++ .fifo_size = 458752, ++ .max_amsdu_limit = 3500, ++ .dis_2g_40m_ul_ofdma = true, ++ .hfc_param_ini = rtw8852a_hfc_param_ini_pcie, ++ .dle_mem = rtw8852a_dle_mem_pcie, ++ .rf_base_addr = {0xc000, 0xd000}, ++ .pwr_on_seq = pwr_on_seq_8852a, ++ .pwr_off_seq = pwr_off_seq_8852a, ++ .bb_table = &rtw89_8852a_phy_bb_table, ++ .rf_table = {&rtw89_8852a_phy_radioa_table, ++ &rtw89_8852a_phy_radiob_table,}, ++ .nctl_table = &rtw89_8852a_phy_nctl_table, ++ .byr_table = &rtw89_8852a_byr_table, ++ .txpwr_lmt_2g = &rtw89_8852a_txpwr_lmt_2g, ++ .txpwr_lmt_5g = &rtw89_8852a_txpwr_lmt_5g, ++ .txpwr_lmt_ru_2g = &rtw89_8852a_txpwr_lmt_ru_2g, ++ .txpwr_lmt_ru_5g = &rtw89_8852a_txpwr_lmt_ru_5g, ++ .txpwr_factor_rf = 2, ++ .txpwr_factor_mac = 1, ++ .dig_table = &rtw89_8852a_phy_dig_table, ++ .rf_path_num = 2, ++ .tx_nss = 2, ++ .rx_nss = 2, ++ .acam_num = 128, ++ .bcam_num = 10, ++ .scam_num = 128, ++ .sec_ctrl_efuse_size = 4, ++ .physical_efuse_size = 1216, ++ .logical_efuse_size = 1536, ++ .limit_efuse_size = 1152, ++ .phycap_addr = 0x580, ++ .phycap_size = 128, ++ .para_ver = 0x05050764, ++ .wlcx_desired = 0x05050000, ++ .btcx_desired = 0x5, ++ .scbd = 0x1, ++ .mailbox = 0x1, ++ .afh_guard_ch = 6, ++ .wl_rssi_thres = rtw89_btc_8852a_wl_rssi_thres, ++ .bt_rssi_thres = rtw89_btc_8852a_bt_rssi_thres, ++ .rssi_tol = 2, ++ .mon_reg_num = ARRAY_SIZE(rtw89_btc_8852a_mon_reg), ++ .mon_reg = rtw89_btc_8852a_mon_reg, ++ .rf_para_ulink_num = ARRAY_SIZE(rtw89_btc_8852a_rf_ul), ++ .rf_para_ulink = rtw89_btc_8852a_rf_ul, ++ .rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8852a_rf_dl), ++ .rf_para_dlink = rtw89_btc_8852a_rf_dl, ++ .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) | ++ BIT(RTW89_PS_MODE_CLK_GATED) | ++ BIT(RTW89_PS_MODE_PWR_GATED), ++}; ++EXPORT_SYMBOL(rtw8852a_chip_info); ++ ++MODULE_FIRMWARE("rtw89/rtw8852a_fw.bin"); +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.h b/drivers/net/wireless/realtek/rtw89/rtw8852a.h +new file mode 100644 +index 000000000000..633384374de0 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.h +@@ -0,0 +1,109 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_8852A_H__ ++#define __RTW89_8852A_H__ ++ ++#include "core.h" ++ ++#define RF_PATH_NUM_8852A 2 ++#define NTX_NUM_8852A 2 ++ ++enum rtw8852a_pmac_mode { ++ NONE_TEST, ++ PKTS_TX, ++ PKTS_RX, ++ CONT_TX ++}; ++ ++struct rtw8852au_efuse { ++ u8 rsvd[0x38]; ++ u8 mac_addr[ETH_ALEN]; ++}; ++ ++struct rtw8852ae_efuse { ++ u8 mac_addr[ETH_ALEN]; ++}; ++ ++struct rtw8852a_tssi_offset { ++ u8 cck_tssi[TSSI_CCK_CH_GROUP_NUM]; ++ u8 bw40_tssi[TSSI_MCS_2G_CH_GROUP_NUM]; ++ u8 rsvd[7]; ++ u8 bw40_1s_tssi_5g[TSSI_MCS_5G_CH_GROUP_NUM]; ++} __packed; ++ ++struct rtw8852a_efuse { ++ u8 rsvd[0x210]; ++ struct rtw8852a_tssi_offset path_a_tssi; ++ u8 rsvd1[10]; ++ struct rtw8852a_tssi_offset path_b_tssi; ++ u8 rsvd2[94]; ++ u8 channel_plan; ++ u8 xtal_k; ++ u8 rsvd3; ++ u8 iqk_lck; ++ u8 rsvd4[5]; ++ u8 reg_setting:2; ++ u8 tx_diversity:1; ++ u8 rx_diversity:2; ++ u8 ac_mode:1; ++ u8 module_type:2; ++ u8 rsvd5; ++ u8 shared_ant:1; ++ u8 coex_type:3; ++ u8 ant_iso:1; ++ u8 radio_on_off:1; ++ u8 rsvd6:2; ++ u8 eeprom_version; ++ u8 customer_id; ++ u8 tx_bb_swing_2g; ++ u8 tx_bb_swing_5g; ++ u8 tx_cali_pwr_trk_mode; ++ u8 trx_path_selection; ++ u8 rfe_type; ++ u8 country_code[2]; ++ u8 rsvd7[3]; ++ u8 path_a_therm; ++ u8 path_b_therm; ++ u8 rsvd8[46]; ++ u8 path_a_cck_pwr_idx[6]; ++ u8 path_a_bw40_1tx_pwr_idx[5]; ++ u8 path_a_ofdm_1tx_pwr_idx_diff:4; ++ u8 path_a_bw20_1tx_pwr_idx_diff:4; ++ u8 path_a_bw20_2tx_pwr_idx_diff:4; ++ u8 path_a_bw40_2tx_pwr_idx_diff:4; ++ u8 path_a_cck_2tx_pwr_idx_diff:4; ++ u8 path_a_ofdm_2tx_pwr_idx_diff:4; ++ u8 rsvd9[0xf2]; ++ union { ++ struct rtw8852au_efuse u; ++ struct rtw8852ae_efuse e; ++ }; ++} __packed; ++ ++struct rtw8852a_bb_pmac_info { ++ u8 en_pmac_tx:1; ++ u8 is_cck:1; ++ u8 mode:3; ++ u8 rsvd:3; ++ u16 tx_cnt; ++ u16 period; ++ u16 tx_time; ++ u8 duty_cycle; ++}; ++ ++void rtw8852a_bb_set_plcp_tx(struct rtw89_dev *rtwdev); ++void rtw8852a_bb_set_pmac_tx(struct rtw89_dev *rtwdev, ++ struct rtw8852a_bb_pmac_info *tx_info, ++ enum rtw89_phy_idx idx); ++void rtw8852a_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable, ++ u16 tx_cnt, u16 period, u16 tx_time, ++ enum rtw89_phy_idx idx); ++void rtw8852a_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm, ++ enum rtw89_phy_idx idx); ++void rtw8852a_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path); ++void rtw8852a_bb_tx_mode_switch(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx idx, u8 mode); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c +new file mode 100644 +index 000000000000..c021e93eb07b +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c +@@ -0,0 +1,3911 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "coex.h" ++#include "debug.h" ++#include "mac.h" ++#include "phy.h" ++#include "reg.h" ++#include "rtw8852a.h" ++#include "rtw8852a_rfk.h" ++#include "rtw8852a_rfk_table.h" ++#include "rtw8852a_table.h" ++ ++static void ++_rfk_write_rf(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) ++{ ++ rtw89_write_rf(rtwdev, def->path, def->addr, def->mask, def->data); ++} ++ ++static void ++_rfk_write32_mask(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) ++{ ++ rtw89_phy_write32_mask(rtwdev, def->addr, def->mask, def->data); ++} ++ ++static void ++_rfk_write32_set(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) ++{ ++ rtw89_phy_write32_set(rtwdev, def->addr, def->mask); ++} ++ ++static void ++_rfk_write32_clr(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) ++{ ++ rtw89_phy_write32_clr(rtwdev, def->addr, def->mask); ++} ++ ++static void ++_rfk_delay(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) ++{ ++ udelay(def->data); ++} ++ ++static void ++(*_rfk_handler[])(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) = { ++ [RTW89_RFK_F_WRF] = _rfk_write_rf, ++ [RTW89_RFK_F_WM] = _rfk_write32_mask, ++ [RTW89_RFK_F_WS] = _rfk_write32_set, ++ [RTW89_RFK_F_WC] = _rfk_write32_clr, ++ [RTW89_RFK_F_DELAY] = _rfk_delay, ++}; ++ ++static_assert(ARRAY_SIZE(_rfk_handler) == RTW89_RFK_F_NUM); ++ ++static void ++rtw89_rfk_parser(struct rtw89_dev *rtwdev, const struct rtw89_rfk_tbl *tbl) ++{ ++ const struct rtw89_reg5_def *p = tbl->defs; ++ const struct rtw89_reg5_def *end = tbl->defs + tbl->size; ++ ++ for (; p < end; p++) ++ _rfk_handler[p->flag](rtwdev, p); ++} ++ ++#define rtw89_rfk_parser_by_cond(rtwdev, cond, tbl_t, tbl_f) \ ++ do { \ ++ typeof(rtwdev) _dev = (rtwdev); \ ++ if (cond) \ ++ rtw89_rfk_parser(_dev, (tbl_t)); \ ++ else \ ++ rtw89_rfk_parser(_dev, (tbl_f)); \ ++ } while (0) ++ ++static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x, PHY%d\n", ++ rtwdev->dbcc_en, phy_idx); ++ ++ if (!rtwdev->dbcc_en) ++ return RF_AB; ++ ++ if (phy_idx == RTW89_PHY_0) ++ return RF_A; ++ else ++ return RF_B; ++} ++ ++static const u32 rtw8852a_backup_bb_regs[] = {0x2344, 0x58f0, 0x78f0}; ++static const u32 rtw8852a_backup_rf_regs[] = {0xef, 0xde, 0x0, 0x1e, 0x2, 0x85, 0x90, 0x5}; ++#define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852a_backup_bb_regs) ++#define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8852a_backup_rf_regs) ++ ++static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[]) ++{ ++ u32 i; ++ ++ for (i = 0; i < BACKUP_BB_REGS_NR; i++) { ++ backup_bb_reg_val[i] = ++ rtw89_phy_read32_mask(rtwdev, rtw8852a_backup_bb_regs[i], ++ MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]backup bb reg : %x, value =%x\n", ++ rtw8852a_backup_bb_regs[i], backup_bb_reg_val[i]); ++ } ++} ++ ++static void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[], ++ u8 rf_path) ++{ ++ u32 i; ++ ++ for (i = 0; i < BACKUP_RF_REGS_NR; i++) { ++ backup_rf_reg_val[i] = ++ rtw89_read_rf(rtwdev, rf_path, ++ rtw8852a_backup_rf_regs[i], RFREG_MASK); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]backup rf S%d reg : %x, value =%x\n", rf_path, ++ rtw8852a_backup_rf_regs[i], backup_rf_reg_val[i]); ++ } ++} ++ ++static void _rfk_restore_bb_reg(struct rtw89_dev *rtwdev, ++ u32 backup_bb_reg_val[]) ++{ ++ u32 i; ++ ++ for (i = 0; i < BACKUP_BB_REGS_NR; i++) { ++ rtw89_phy_write32_mask(rtwdev, rtw8852a_backup_bb_regs[i], ++ MASKDWORD, backup_bb_reg_val[i]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]restore bb reg : %x, value =%x\n", ++ rtw8852a_backup_bb_regs[i], backup_bb_reg_val[i]); ++ } ++} ++ ++static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev, ++ u32 backup_rf_reg_val[], u8 rf_path) ++{ ++ u32 i; ++ ++ for (i = 0; i < BACKUP_RF_REGS_NR; i++) { ++ rtw89_write_rf(rtwdev, rf_path, rtw8852a_backup_rf_regs[i], ++ RFREG_MASK, backup_rf_reg_val[i]); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]restore rf S%d reg: %x, value =%x\n", rf_path, ++ rtw8852a_backup_rf_regs[i], backup_rf_reg_val[i]); ++ } ++} ++ ++static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) ++{ ++ u8 path; ++ u32 rf_mode; ++ int ret; ++ ++ for (path = 0; path < RF_PATH_MAX; path++) { ++ if (!(kpath & BIT(path))) ++ continue; ++ ++ ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, rf_mode != 2, ++ 2, 5000, false, rtwdev, path, 0x00, ++ RR_MOD_MASK); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", ++ path, ret); ++ } ++} ++ ++static void _dack_dump(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u8 i; ++ u8 t; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n", ++ dack->addck_d[0][0], dack->addck_d[0][1]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DACK]S1 ADC_DCK ic = 0x%x, qc = 0x%x\n", ++ dack->addck_d[1][0], dack->addck_d[1][1]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n", ++ dack->dadck_d[0][0], dack->dadck_d[0][1]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n", ++ dack->dadck_d[1][0], dack->dadck_d[1][1]); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n", ++ dack->biask_d[0][0], dack->biask_d[0][1]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DACK]S1 biask ic = 0x%x, qc = 0x%x\n", ++ dack->biask_d[1][0], dack->biask_d[1][1]); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n"); ++ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { ++ t = dack->msbk_d[0][0][i]; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n"); ++ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { ++ t = dack->msbk_d[0][1][i]; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n"); ++ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { ++ t = dack->msbk_d[1][0][i]; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n"); ++ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { ++ t = dack->msbk_d[1][1][i]; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); ++ } ++} ++ ++static void _afe_init(struct rtw89_dev *rtwdev) ++{ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_afe_init_defs_tbl); ++} ++ ++static void _addck_backup(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ ++ rtw89_phy_write32_clr(rtwdev, R_S0_RXDC2, B_S0_RXDC2_SEL); ++ dack->addck_d[0][0] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_ADDCK, ++ B_S0_ADDCK_Q); ++ dack->addck_d[0][1] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_ADDCK, ++ B_S0_ADDCK_I); ++ ++ rtw89_phy_write32_clr(rtwdev, R_S1_RXDC2, B_S1_RXDC2_SEL); ++ dack->addck_d[1][0] = (u16)rtw89_phy_read32_mask(rtwdev, R_S1_ADDCK, ++ B_S1_ADDCK_Q); ++ dack->addck_d[1][1] = (u16)rtw89_phy_read32_mask(rtwdev, R_S1_ADDCK, ++ B_S1_ADDCK_I); ++} ++ ++static void _addck_reload(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ ++ rtw89_phy_write32_mask(rtwdev, R_S0_RXDC, B_S0_RXDC_I, dack->addck_d[0][0]); ++ rtw89_phy_write32_mask(rtwdev, R_S0_RXDC2, B_S0_RXDC2_Q2, ++ (dack->addck_d[0][1] >> 6)); ++ rtw89_phy_write32_mask(rtwdev, R_S0_RXDC, B_S0_RXDC_Q, ++ (dack->addck_d[0][1] & 0x3f)); ++ rtw89_phy_write32_set(rtwdev, R_S0_RXDC2, B_S0_RXDC2_MEN); ++ rtw89_phy_write32_mask(rtwdev, R_S1_RXDC, B_S1_RXDC_I, dack->addck_d[1][0]); ++ rtw89_phy_write32_mask(rtwdev, R_S1_RXDC2, B_S1_RXDC2_Q2, ++ (dack->addck_d[1][1] >> 6)); ++ rtw89_phy_write32_mask(rtwdev, R_S1_RXDC, B_S1_RXDC_Q, ++ (dack->addck_d[1][1] & 0x3f)); ++ rtw89_phy_write32_set(rtwdev, R_S1_RXDC2, B_S1_RXDC2_EN); ++} ++ ++static void _dack_backup_s0(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u8 i; ++ ++ rtw89_phy_write32_set(rtwdev, R_S0_DACKI, B_S0_DACKI_EN); ++ rtw89_phy_write32_set(rtwdev, R_S0_DACKQ, B_S0_DACKQ_EN); ++ rtw89_phy_write32_set(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG); ++ ++ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { ++ rtw89_phy_write32_mask(rtwdev, R_S0_DACKI, B_S0_DACKI_AR, i); ++ dack->msbk_d[0][0][i] = ++ (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKI7, B_S0_DACKI7_K); ++ rtw89_phy_write32_mask(rtwdev, R_S0_DACKQ, B_S0_DACKQ_AR, i); ++ dack->msbk_d[0][1][i] = ++ (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKQ7, B_S0_DACKQ7_K); ++ } ++ dack->biask_d[0][0] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_DACKI2, ++ B_S0_DACKI2_K); ++ dack->biask_d[0][1] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_DACKQ2, ++ B_S0_DACKQ2_K); ++ dack->dadck_d[0][0] = (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKI8, ++ B_S0_DACKI8_K) - 8; ++ dack->dadck_d[0][1] = (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKQ8, ++ B_S0_DACKQ8_K) - 8; ++} ++ ++static void _dack_backup_s1(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u8 i; ++ ++ rtw89_phy_write32_set(rtwdev, R_S1_DACKI, B_S1_DACKI_EN); ++ rtw89_phy_write32_set(rtwdev, R_S1_DACKQ, B_S1_DACKQ_EN); ++ rtw89_phy_write32_set(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON); ++ ++ for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { ++ rtw89_phy_write32_mask(rtwdev, R_S1_DACKI, B_S1_DACKI_AR, i); ++ dack->msbk_d[1][0][i] = ++ (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKI7, B_S1_DACKI_K); ++ rtw89_phy_write32_mask(rtwdev, R_S1_DACKQ, B_S1_DACKQ_AR, i); ++ dack->msbk_d[1][1][i] = ++ (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKQ7, B_S1_DACKQ7_K); ++ } ++ dack->biask_d[1][0] = ++ (u16)rtw89_phy_read32_mask(rtwdev, R_S1_DACKI2, B_S1_DACKI2_K); ++ dack->biask_d[1][1] = ++ (u16)rtw89_phy_read32_mask(rtwdev, R_S1_DACKQ2, B_S1_DACKQ2_K); ++ dack->dadck_d[1][0] = ++ (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKI8, B_S1_DACKI8_K) - 8; ++ dack->dadck_d[1][1] = ++ (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKQ8, B_S1_DACKQ8_K) - 8; ++} ++ ++static void _dack_reload_by_path(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, u8 index) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u32 tmp = 0, tmp_offset, tmp_reg; ++ u8 i; ++ u32 idx_offset, path_offset; ++ ++ if (index == 0) ++ idx_offset = 0; ++ else ++ idx_offset = 0x50; ++ ++ if (path == RF_PATH_A) ++ path_offset = 0; ++ else ++ path_offset = 0x2000; ++ ++ tmp_offset = idx_offset + path_offset; ++ /* msbk_d: 15/14/13/12 */ ++ tmp = 0x0; ++ for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) ++ tmp |= dack->msbk_d[path][index][i + 12] << (i * 8); ++ tmp_reg = 0x5e14 + tmp_offset; ++ rtw89_phy_write32(rtwdev, tmp_reg, tmp); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, ++ rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); ++ /* msbk_d: 11/10/9/8 */ ++ tmp = 0x0; ++ for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) ++ tmp |= dack->msbk_d[path][index][i + 8] << (i * 8); ++ tmp_reg = 0x5e18 + tmp_offset; ++ rtw89_phy_write32(rtwdev, tmp_reg, tmp); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, ++ rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); ++ /* msbk_d: 7/6/5/4 */ ++ tmp = 0x0; ++ for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) ++ tmp |= dack->msbk_d[path][index][i + 4] << (i * 8); ++ tmp_reg = 0x5e1c + tmp_offset; ++ rtw89_phy_write32(rtwdev, tmp_reg, tmp); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, ++ rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); ++ /* msbk_d: 3/2/1/0 */ ++ tmp = 0x0; ++ for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) ++ tmp |= dack->msbk_d[path][index][i] << (i * 8); ++ tmp_reg = 0x5e20 + tmp_offset; ++ rtw89_phy_write32(rtwdev, tmp_reg, tmp); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, ++ rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); ++ /* dadak_d/biask_d */ ++ tmp = 0x0; ++ tmp = (dack->biask_d[path][index] << 22) | ++ (dack->dadck_d[path][index] << 14); ++ tmp_reg = 0x5e24 + tmp_offset; ++ rtw89_phy_write32(rtwdev, tmp_reg, tmp); ++} ++ ++static void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) ++{ ++ u8 i; ++ ++ for (i = 0; i < 2; i++) ++ _dack_reload_by_path(rtwdev, path, i); ++ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_rfk_dack_reload_defs_a_tbl, ++ &rtw8852a_rfk_dack_reload_defs_b_tbl); ++} ++ ++#define ADDC_T_AVG 100 ++static void _check_addc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) ++{ ++ s32 dc_re = 0, dc_im = 0; ++ u32 tmp; ++ u32 i; ++ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_rfk_check_addc_defs_a_tbl, ++ &rtw8852a_rfk_check_addc_defs_b_tbl); ++ ++ for (i = 0; i < ADDC_T_AVG; i++) { ++ tmp = rtw89_phy_read32_mask(rtwdev, R_DBG32_D, MASKDWORD); ++ dc_re += sign_extend32(FIELD_GET(0xfff000, tmp), 11); ++ dc_im += sign_extend32(FIELD_GET(0xfff, tmp), 11); ++ } ++ ++ dc_re /= ADDC_T_AVG; ++ dc_im /= ADDC_T_AVG; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DACK]S%d,dc_re = 0x%x,dc_im =0x%x\n", path, dc_re, dc_im); ++} ++ ++static void _addck(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u32 val; ++ int ret; ++ ++ /* S0 */ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_reset_defs_a_tbl); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]before S0 ADDCK\n"); ++ _check_addc(rtwdev, RF_PATH_A); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_trigger_defs_a_tbl); ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x1e00, BIT(0)); ++ if (ret) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADDCK timeout\n"); ++ dack->addck_timeout[0] = true; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 ADDCK\n"); ++ _check_addc(rtwdev, RF_PATH_A); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_restore_defs_a_tbl); ++ ++ /* S1 */ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_reset_defs_b_tbl); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]before S1 ADDCK\n"); ++ _check_addc(rtwdev, RF_PATH_B); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_trigger_defs_b_tbl); ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x3e00, BIT(0)); ++ if (ret) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADDCK timeout\n"); ++ dack->addck_timeout[1] = true; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 ADDCK\n"); ++ _check_addc(rtwdev, RF_PATH_B); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_restore_defs_b_tbl); ++} ++ ++static void _check_dadc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_rfk_check_dadc_defs_f_a_tbl, ++ &rtw8852a_rfk_check_dadc_defs_f_b_tbl); ++ ++ _check_addc(rtwdev, path); ++ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_rfk_check_dadc_defs_r_a_tbl, ++ &rtw8852a_rfk_check_dadc_defs_r_b_tbl); ++} ++ ++static void _dack_s0(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u32 val; ++ int ret; ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_f_a_tbl); ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x5e28, BIT(15)); ++ ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x5e78, BIT(15)); ++ if (ret) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK timeout\n"); ++ dack->msbk_timeout[0] = true; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_m_a_tbl); ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x5e48, BIT(17)); ++ ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x5e98, BIT(17)); ++ if (ret) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DADACK timeout\n"); ++ dack->dadck_timeout[0] = true; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_r_a_tbl); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 DADCK\n"); ++ _check_dadc(rtwdev, RF_PATH_A); ++ ++ _dack_backup_s0(rtwdev); ++ _dack_reload(rtwdev, RF_PATH_A); ++ ++ rtw89_phy_write32_clr(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG); ++} ++ ++static void _dack_s1(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u32 val; ++ int ret; ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_f_b_tbl); ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x7e28, BIT(15)); ++ ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x7e78, BIT(15)); ++ if (ret) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK timeout\n"); ++ dack->msbk_timeout[1] = true; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_m_b_tbl); ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x7e48, BIT(17)); ++ ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, ++ false, rtwdev, 0x7e98, BIT(17)); ++ if (ret) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DADCK timeout\n"); ++ dack->dadck_timeout[1] = true; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_r_b_tbl); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 DADCK\n"); ++ _check_dadc(rtwdev, RF_PATH_B); ++ ++ _dack_backup_s1(rtwdev); ++ _dack_reload(rtwdev, RF_PATH_B); ++ ++ rtw89_phy_write32_clr(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON); ++} ++ ++static void _dack(struct rtw89_dev *rtwdev) ++{ ++ _dack_s0(rtwdev); ++ _dack_s1(rtwdev); ++} ++ ++static void _dac_cal(struct rtw89_dev *rtwdev, bool force) ++{ ++ struct rtw89_dack_info *dack = &rtwdev->dack; ++ u32 rf0_0, rf1_0; ++ u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, RF_AB); ++ ++ dack->dack_done = false; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK b\n"); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK start!!!\n"); ++ rf0_0 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK); ++ rf1_0 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK); ++ _afe_init(rtwdev); ++ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x0); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x0); ++ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x30001); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x30001); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_START); ++ _addck(rtwdev); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_STOP); ++ _addck_backup(rtwdev); ++ _addck_reload(rtwdev); ++ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x40001); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x40001); ++ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RFREG_MASK, 0x0); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RFREG_MASK, 0x0); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_START); ++ _dack(rtwdev); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_STOP); ++ _dack_dump(rtwdev); ++ dack->dack_done = true; ++ rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, rf0_0); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, rf1_0); ++ rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x1); ++ rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x1); ++ dack->dack_cnt++; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); ++} ++ ++#define RTW8852A_NCTL_VER 0xd ++#define RTW8852A_IQK_VER 0x2a ++#define RTW8852A_IQK_SS 2 ++#define RTW8852A_IQK_THR_REK 8 ++#define RTW8852A_IQK_CFIR_GROUP_NR 4 ++ ++enum rtw8852a_iqk_type { ++ ID_TXAGC, ++ ID_FLOK_COARSE, ++ ID_FLOK_FINE, ++ ID_TXK, ++ ID_RXAGC, ++ ID_RXK, ++ ID_NBTXK, ++ ID_NBRXK, ++}; ++ ++static void _iqk_read_fft_dbcc0(struct rtw89_dev *rtwdev, u8 path) ++{ ++ u8 i = 0x0; ++ u32 fft[6] = {0x0}; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00160000); ++ fft[0] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00170000); ++ fft[1] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00180000); ++ fft[2] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00190000); ++ fft[3] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x001a0000); ++ fft[4] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x001b0000); ++ fft[5] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); ++ for (i = 0; i < 6; i++) ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x,fft[%x]= %x\n", ++ path, i, fft[i]); ++} ++ ++static void _iqk_read_xym_dbcc0(struct rtw89_dev *rtwdev, u8 path) ++{ ++ u8 i = 0x0; ++ u32 tmp = 0x0; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, B_NCTL_CFG_SPAGE, path); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF, B_IQK_DIF_TRX, 0x1); ++ ++ for (i = 0x0; i < 0x18; i++) { ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_N2, MASKDWORD, 0x000000c0 + i); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N2, MASKDWORD); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lx38 = %x\n", ++ path, BIT(path), tmp); ++ udelay(1); ++ } ++ rtw89_phy_write32_clr(rtwdev, R_IQK_DIF, B_IQK_DIF_TRX); ++ rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD, 0x40000000); ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_N2, MASKDWORD, 0x80010100); ++ udelay(1); ++} ++ ++static void _iqk_read_txcfir_dbcc0(struct rtw89_dev *rtwdev, u8 path, ++ u8 group) ++{ ++ static const u32 base_addrs[RTW8852A_IQK_SS][RTW8852A_IQK_CFIR_GROUP_NR] = { ++ {0x8f20, 0x8f54, 0x8f88, 0x8fbc}, ++ {0x9320, 0x9354, 0x9388, 0x93bc}, ++ }; ++ u8 idx = 0x0; ++ u32 tmp = 0x0; ++ u32 base_addr; ++ ++ if (path >= RTW8852A_IQK_SS) { ++ rtw89_warn(rtwdev, "cfir path %d out of range\n", path); ++ return; ++ } ++ if (group >= RTW8852A_IQK_CFIR_GROUP_NR) { ++ rtw89_warn(rtwdev, "cfir group %d out of range\n", group); ++ return; ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ rtw89_phy_write32_mask(rtwdev, R_W_COEF + (path << 8), MASKDWORD, 0x00000001); ++ ++ base_addr = base_addrs[path][group]; ++ ++ for (idx = 0; idx < 0x0d; idx++) { ++ tmp = rtw89_phy_read32_mask(rtwdev, base_addr + (idx << 2), MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK] %x = %x\n", ++ base_addr + (idx << 2), tmp); ++ } ++ ++ if (path == 0x0) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C0, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8f50 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C1, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8f84 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C2, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8fb8 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C3, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8fec = %x\n", tmp); ++ } else { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C0, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9350 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C1, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9384 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C2, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x93b8 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C3, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x93ec = %x\n", tmp); ++ } ++ rtw89_phy_write32_clr(rtwdev, R_W_COEF + (path << 8), MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, 0xc); ++ udelay(1); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lxfc = %x\n", path, ++ BIT(path), tmp); ++} ++ ++static void _iqk_read_rxcfir_dbcc0(struct rtw89_dev *rtwdev, u8 path, ++ u8 group) ++{ ++ static const u32 base_addrs[RTW8852A_IQK_SS][RTW8852A_IQK_CFIR_GROUP_NR] = { ++ {0x8d00, 0x8d44, 0x8d88, 0x8dcc}, ++ {0x9100, 0x9144, 0x9188, 0x91cc}, ++ }; ++ u8 idx = 0x0; ++ u32 tmp = 0x0; ++ u32 base_addr; ++ ++ if (path >= RTW8852A_IQK_SS) { ++ rtw89_warn(rtwdev, "cfir path %d out of range\n", path); ++ return; ++ } ++ if (group >= RTW8852A_IQK_CFIR_GROUP_NR) { ++ rtw89_warn(rtwdev, "cfir group %d out of range\n", group); ++ return; ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ rtw89_phy_write32_mask(rtwdev, R_W_COEF + (path << 8), MASKDWORD, 0x00000001); ++ ++ base_addr = base_addrs[path][group]; ++ for (idx = 0; idx < 0x10; idx++) { ++ tmp = rtw89_phy_read32_mask(rtwdev, base_addr + (idx << 2), MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]%x = %x\n", ++ base_addr + (idx << 2), tmp); ++ } ++ ++ if (path == 0x0) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C0, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8d40 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C1, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8d84 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C2, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8dc8 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C3, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8e0c = %x\n", tmp); ++ } else { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C0, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9140 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C1, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9184 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C2, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x91c8 = %x\n", tmp); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C3, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x920c = %x\n", tmp); ++ } ++ rtw89_phy_write32_clr(rtwdev, R_W_COEF + (path << 8), MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, 0xd); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lxfc = %x\n", path, ++ BIT(path), tmp); ++} ++ ++static void _iqk_sram(struct rtw89_dev *rtwdev, u8 path) ++{ ++ u32 tmp = 0x0; ++ u32 i = 0x0; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00020000); ++ rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX2, MASKDWORD, 0x00000080); ++ rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x009); ++ ++ for (i = 0; i <= 0x9f; i++) { ++ rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000 + i); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]0x%x\n", tmp); ++ } ++ ++ for (i = 0; i <= 0x9f; i++) { ++ rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000 + i); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]0x%x\n", tmp); ++ } ++ rtw89_phy_write32_clr(rtwdev, R_SRAM_IQRX2, MASKDWORD); ++ rtw89_phy_write32_clr(rtwdev, R_SRAM_IQRX, MASKDWORD); ++} ++ ++static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u32 tmp = 0x0; ++ ++ rtw89_phy_write32_set(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x3); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa041); ++ udelay(1); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H2, 0x3); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x0); ++ udelay(1); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H2, 0x0); ++ udelay(1); ++ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0303); ++ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0000); ++ ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RXK2); ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x1); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RXK2); ++ rtw89_write_rf(rtwdev, path, RR_WLSEL, RR_WLSEL_AG, 0x5); ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x1); ++ break; ++ default: ++ break; ++ } ++ tmp = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); ++ rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, tmp); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x1); ++ fsleep(128); ++} ++ ++static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path, u8 ktype) ++{ ++ u32 tmp; ++ u32 val; ++ int ret; ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, 1, 8200, ++ false, rtwdev, 0xbff8, MASKBYTE0); ++ if (ret) ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]IQK timeout!!!\n"); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ret=%d\n", path, ret); ++ tmp = rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]S%x, type= %x, 0x8008 = 0x%x\n", path, ktype, tmp); ++ ++ return false; ++} ++ ++static bool _iqk_one_shot(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path, u8 ktype) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ bool fail = false; ++ u32 iqk_cmd = 0x0; ++ u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy_idx, path); ++ u32 addr_rfc_ctl = 0x0; ++ ++ if (path == RF_PATH_A) ++ addr_rfc_ctl = 0x5864; ++ else ++ addr_rfc_ctl = 0x7864; ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); ++ switch (ktype) { ++ case ID_TXAGC: ++ iqk_cmd = 0x008 | (1 << (4 + path)) | (path << 1); ++ break; ++ case ID_FLOK_COARSE: ++ rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x009); ++ iqk_cmd = 0x108 | (1 << (4 + path)); ++ break; ++ case ID_FLOK_FINE: ++ rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x009); ++ iqk_cmd = 0x208 | (1 << (4 + path)); ++ break; ++ case ID_TXK: ++ rtw89_phy_write32_clr(rtwdev, addr_rfc_ctl, 0x20000000); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x025); ++ iqk_cmd = 0x008 | (1 << (path + 4)) | ++ (((0x8 + iqk_info->iqk_bw[path]) & 0xf) << 8); ++ break; ++ case ID_RXAGC: ++ iqk_cmd = 0x508 | (1 << (4 + path)) | (path << 1); ++ break; ++ case ID_RXK: ++ rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); ++ iqk_cmd = 0x008 | (1 << (path + 4)) | ++ (((0xb + iqk_info->iqk_bw[path]) & 0xf) << 8); ++ break; ++ case ID_NBTXK: ++ rtw89_phy_write32_clr(rtwdev, addr_rfc_ctl, 0x20000000); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x025); ++ iqk_cmd = 0x308 | (1 << (4 + path)); ++ break; ++ case ID_NBRXK: ++ rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); ++ iqk_cmd = 0x608 | (1 << (4 + path)); ++ break; ++ default: ++ return false; ++ } ++ ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, iqk_cmd + 1); ++ rtw89_phy_write32_set(rtwdev, R_DPK_CTL, B_DPK_CTL_EN); ++ udelay(1); ++ fail = _iqk_check_cal(rtwdev, path, ktype); ++ if (iqk_info->iqk_xym_en) ++ _iqk_read_xym_dbcc0(rtwdev, path); ++ if (iqk_info->iqk_fft_en) ++ _iqk_read_fft_dbcc0(rtwdev, path); ++ if (iqk_info->iqk_sram_en) ++ _iqk_sram(rtwdev, path); ++ if (iqk_info->iqk_cfir_en) { ++ if (ktype == ID_TXK) { ++ _iqk_read_txcfir_dbcc0(rtwdev, path, 0x0); ++ _iqk_read_txcfir_dbcc0(rtwdev, path, 0x1); ++ _iqk_read_txcfir_dbcc0(rtwdev, path, 0x2); ++ _iqk_read_txcfir_dbcc0(rtwdev, path, 0x3); ++ } else { ++ _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x0); ++ _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x1); ++ _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x2); ++ _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x3); ++ } ++ } ++ ++ rtw89_phy_write32_clr(rtwdev, addr_rfc_ctl, 0x20000000); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); ++ ++ return fail; ++} ++ ++static bool _rxk_group_sel(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ static const u32 rxgn_a[4] = {0x18C, 0x1A0, 0x28C, 0x2A0}; ++ static const u32 attc2_a[4] = {0x0, 0x0, 0x07, 0x30}; ++ static const u32 attc1_a[4] = {0x7, 0x5, 0x1, 0x1}; ++ static const u32 rxgn_g[4] = {0x1CC, 0x1E0, 0x2CC, 0x2E0}; ++ static const u32 attc2_g[4] = {0x0, 0x15, 0x3, 0x1a}; ++ static const u32 attc1_g[4] = {0x1, 0x0, 0x1, 0x0}; ++ u8 gp = 0x0; ++ bool fail = false; ++ u32 rf0 = 0x0; ++ ++ for (gp = 0; gp < 0x4; gp++) { ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, rxgn_g[gp]); ++ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G, attc2_g[gp]); ++ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G, attc1_g[gp]); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, rxgn_a[gp]); ++ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C2, attc2_a[gp]); ++ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C1, attc1_a[gp]); ++ break; ++ default: ++ break; ++ } ++ rtw89_phy_write32_set(rtwdev, R_IQK_CFG, B_IQK_CFG_SET); ++ rf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, ++ rf0 | iqk_info->syn1to2); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_COM, MASKDWORD, 0x40010100); ++ rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_RXCFIR); ++ rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); ++ rtw89_phy_write32_clr(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, gp); ++ rtw89_phy_write32_mask(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_EN, 0x1); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); ++ fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(16 + gp + path * 4), fail); ++ } ++ ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_WLSEL, RR_WLSEL_AG, 0x0); ++ break; ++ default: ++ break; ++ } ++ iqk_info->nb_rxcfir[path] = 0x40000000; ++ rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), ++ B_IQK_RES_RXCFIR, 0x5); ++ iqk_info->is_wb_rxiqk[path] = true; ++ return false; ++} ++ ++static bool _iqk_nbrxk(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u8 group = 0x0; ++ u32 rf0 = 0x0, tmp = 0x0; ++ u32 idxrxgain_a = 0x1a0; ++ u32 idxattc2_a = 0x00; ++ u32 idxattc1_a = 0x5; ++ u32 idxrxgain_g = 0x1E0; ++ u32 idxattc2_g = 0x15; ++ u32 idxattc1_g = 0x0; ++ bool fail = false; ++ ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, idxrxgain_g); ++ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G, idxattc2_g); ++ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G, idxattc1_g); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, idxrxgain_a); ++ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C2, idxattc2_a); ++ rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C1, idxattc1_a); ++ break; ++ default: ++ break; ++ } ++ rtw89_phy_write32_set(rtwdev, R_IQK_CFG, B_IQK_CFG_SET); ++ rf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, ++ rf0 | iqk_info->syn1to2); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_COM, MASKDWORD, 0x40010100); ++ rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_RXCFIR); ++ rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); ++ rtw89_phy_write32_clr(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), ++ B_CFIR_LUT_GP, group); ++ rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_EN); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); ++ fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); ++ ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_WLSEL, RR_WLSEL_AG, 0x0); ++ break; ++ default: ++ break; ++ } ++ if (!fail) { ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD); ++ iqk_info->nb_rxcfir[path] = tmp | 0x2; ++ } else { ++ iqk_info->nb_rxcfir[path] = 0x40000002; ++ } ++ return fail; ++} ++ ++static void _iqk_rxclk_setting(struct rtw89_dev *rtwdev, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ ++ if (iqk_info->iqk_bw[path] == RTW89_CHANNEL_WIDTH_80) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), ++ MASKDWORD, 0x4d000a08); ++ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), ++ B_P0_RXCK_VAL, 0x2); ++ rtw89_phy_write32_set(rtwdev, R_P0_RXCK + (path << 13), B_P0_RXCK_ON); ++ rtw89_phy_write32_set(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON); ++ rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL, 0x1); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), ++ MASKDWORD, 0x44000a08); ++ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), ++ B_P0_RXCK_VAL, 0x1); ++ rtw89_phy_write32_set(rtwdev, R_P0_RXCK + (path << 13), B_P0_RXCK_ON); ++ rtw89_phy_write32_set(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON); ++ rtw89_phy_write32_clr(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL); ++ } ++} ++ ++static bool _txk_group_sel(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ static const u32 a_txgain[4] = {0xE466, 0x646D, 0xE4E2, 0x64ED}; ++ static const u32 g_txgain[4] = {0x60e8, 0x60f0, 0x61e8, 0x61ED}; ++ static const u32 a_itqt[4] = {0x12, 0x12, 0x12, 0x1b}; ++ static const u32 g_itqt[4] = {0x09, 0x12, 0x12, 0x12}; ++ static const u32 g_attsmxr[4] = {0x0, 0x1, 0x1, 0x1}; ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ bool fail = false; ++ u8 gp = 0x0; ++ u32 tmp = 0x0; ++ ++ for (gp = 0x0; gp < 0x4; gp++) { ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), ++ B_RFGAIN_BND, 0x08); ++ rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, ++ g_txgain[gp]); ++ rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, ++ g_attsmxr[gp]); ++ rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, ++ g_attsmxr[gp]); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), ++ MASKDWORD, g_itqt[gp]); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), ++ B_RFGAIN_BND, 0x04); ++ rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, ++ a_txgain[gp]); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), ++ MASKDWORD, a_itqt[gp]); ++ break; ++ default: ++ break; ++ } ++ rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_TXCFIR); ++ rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); ++ rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), ++ B_CFIR_LUT_GP, gp); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); ++ fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK); ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(8 + gp + path * 4), fail); ++ } ++ ++ iqk_info->nb_txcfir[path] = 0x40000000; ++ rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), ++ B_IQK_RES_TXCFIR, 0x5); ++ iqk_info->is_wb_txiqk[path] = true; ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lx38 = 0x%x\n", path, ++ BIT(path), tmp); ++ return false; ++} ++ ++static bool _iqk_nbtxk(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u8 group = 0x2; ++ u32 a_mode_txgain = 0x64e2; ++ u32 g_mode_txgain = 0x61e8; ++ u32 attsmxr = 0x1; ++ u32 itqt = 0x12; ++ u32 tmp = 0x0; ++ bool fail = false; ++ ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), ++ B_RFGAIN_BND, 0x08); ++ rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, g_mode_txgain); ++ rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, attsmxr); ++ rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, attsmxr); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), ++ B_RFGAIN_BND, 0x04); ++ rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, a_mode_txgain); ++ break; ++ default: ++ break; ++ } ++ rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_TXCFIR); ++ rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); ++ rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, group); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, itqt); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); ++ fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); ++ if (!fail) { ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); ++ iqk_info->nb_txcfir[path] = tmp | 0x2; ++ } else { ++ iqk_info->nb_txcfir[path] = 0x40000002; ++ } ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lx38 = 0x%x\n", path, ++ BIT(path), tmp); ++ return fail; ++} ++ ++static void _lok_res_table(struct rtw89_dev *rtwdev, u8 path, u8 ibias) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ibias = %x\n", path, ibias); ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x2); ++ if (iqk_info->iqk_band[path] == RTW89_BAND_2G) ++ rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, 0x0); ++ else ++ rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, ibias); ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0); ++} ++ ++static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path) ++{ ++ bool is_fail = false; ++ u32 tmp = 0x0; ++ u32 core_i = 0x0; ++ u32 core_q = 0x0; ++ ++ tmp = rtw89_read_rf(rtwdev, path, RR_TXMO, RFREG_MASK); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK][FineLOK] S%x, 0x58 = 0x%x\n", ++ path, tmp); ++ core_i = FIELD_GET(RR_TXMO_COI, tmp); ++ core_q = FIELD_GET(RR_TXMO_COQ, tmp); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, i = 0x%x\n", path, core_i); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, q = 0x%x\n", path, core_q); ++ ++ if (core_i < 0x2 || core_i > 0x1d || core_q < 0x2 || core_q > 0x1d) ++ is_fail = true; ++ return is_fail; ++} ++ ++static bool _iqk_lok(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u32 rf0 = 0x0; ++ u8 itqt = 0x12; ++ bool fail = false; ++ bool tmp = false; ++ ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, 0xe5e0); ++ itqt = 0x09; ++ break; ++ case RTW89_BAND_5G: ++ rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, 0xe4e0); ++ itqt = 0x12; ++ break; ++ default: ++ break; ++ } ++ rtw89_phy_write32_set(rtwdev, R_IQK_CFG, B_IQK_CFG_SET); ++ rf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF1, B_IQK_DIF1_TXPI, ++ rf0 | iqk_info->syn1to2); ++ rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_TXCFIR); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, 0x0); ++ rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_EN); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, itqt); ++ tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_COARSE); ++ iqk_info->lok_cor_fail[0][path] = tmp; ++ fsleep(10); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, itqt); ++ tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_FINE); ++ iqk_info->lok_fin_fail[0][path] = tmp; ++ fail = _lok_finetune_check(rtwdev, path); ++ return fail; ++} ++ ++static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ ++ rtw89_phy_write32_set(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f); ++ udelay(1); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0001); ++ udelay(1); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0041); ++ udelay(1); ++ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0303); ++ rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0000); ++ switch (iqk_info->iqk_band[path]) { ++ case RTW89_BAND_2G: ++ rtw89_write_rf(rtwdev, path, RR_XALNA2, RR_XALNA2_SW, 0x00); ++ rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_POW, 0x3f); ++ rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT2, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EN, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_LOK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_MASK, 0x000); ++ rtw89_write_rf(rtwdev, path, RR_RSV2, RFREG_MASK, 0x80200); ++ rtw89_write_rf(rtwdev, path, RR_DTXLOK, RFREG_MASK, 0x80200); ++ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, ++ 0x403e0 | iqk_info->syn1to2); ++ udelay(1); ++ break; ++ case RTW89_BAND_5G: ++ rtw89_write_rf(rtwdev, path, RR_XGLNA2, RR_XGLNA2_SW, 0x00); ++ rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_POW, 0x3f); ++ rtw89_write_rf(rtwdev, path, RR_BIASA, RR_BIASA_A, 0x7); ++ rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EN, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_LOK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_MASK, 0x100); ++ rtw89_write_rf(rtwdev, path, RR_RSV2, RFREG_MASK, 0x80200); ++ rtw89_write_rf(rtwdev, path, RR_DTXLOK, RFREG_MASK, 0x80200); ++ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, ++ 0x403e0 | iqk_info->syn1to2); ++ udelay(1); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void _iqk_txclk_setting(struct rtw89_dev *rtwdev, u8 path) ++{ ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0xce000a08); ++} ++ ++static void _iqk_info_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, ++ u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u32 tmp = 0x0; ++ bool flag = 0x0; ++ ++ iqk_info->thermal[path] = ++ ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); ++ iqk_info->thermal_rek_en = false; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_thermal = %d\n", path, ++ iqk_info->thermal[path]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_COR_fail= %d\n", path, ++ iqk_info->lok_cor_fail[0][path]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_FIN_fail= %d\n", path, ++ iqk_info->lok_fin_fail[0][path]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_TXIQK_fail = %d\n", path, ++ iqk_info->iqk_tx_fail[0][path]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_RXIQK_fail= %d,\n", path, ++ iqk_info->iqk_rx_fail[0][path]); ++ flag = iqk_info->lok_cor_fail[0][path]; ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(0) << (path * 4), flag); ++ flag = iqk_info->lok_fin_fail[0][path]; ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(1) << (path * 4), flag); ++ flag = iqk_info->iqk_tx_fail[0][path]; ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(2) << (path * 4), flag); ++ flag = iqk_info->iqk_rx_fail[0][path]; ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(3) << (path * 4), flag); ++ ++ tmp = rtw89_phy_read32_mask(rtwdev, R_IQK_RES + (path << 8), MASKDWORD); ++ iqk_info->bp_iqkenable[path] = tmp; ++ tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); ++ iqk_info->bp_txkresult[path] = tmp; ++ tmp = rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD); ++ iqk_info->bp_rxkresult[path] = tmp; ++ ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_KCNT, ++ (u8)iqk_info->iqk_times); ++ ++ tmp = rtw89_phy_read32_mask(rtwdev, R_IQKINF, 0x0000000f << (path * 4)); ++ if (tmp != 0x0) ++ iqk_info->iqk_fail_cnt++; ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF2, 0x00ff0000 << (path * 4), ++ iqk_info->iqk_fail_cnt); ++} ++ ++static ++void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ bool lok_is_fail = false; ++ u8 ibias = 0x1; ++ u8 i = 0; ++ ++ _iqk_txclk_setting(rtwdev, path); ++ ++ for (i = 0; i < 3; i++) { ++ _lok_res_table(rtwdev, path, ibias++); ++ _iqk_txk_setting(rtwdev, path); ++ lok_is_fail = _iqk_lok(rtwdev, phy_idx, path); ++ if (!lok_is_fail) ++ break; ++ } ++ if (iqk_info->is_nbiqk) ++ iqk_info->iqk_tx_fail[0][path] = _iqk_nbtxk(rtwdev, phy_idx, path); ++ else ++ iqk_info->iqk_tx_fail[0][path] = _txk_group_sel(rtwdev, phy_idx, path); ++ ++ _iqk_rxclk_setting(rtwdev, path); ++ _iqk_rxk_setting(rtwdev, path); ++ if (iqk_info->is_nbiqk || rtwdev->dbcc_en || iqk_info->iqk_band[path] == RTW89_BAND_2G) ++ iqk_info->iqk_rx_fail[0][path] = _iqk_nbrxk(rtwdev, phy_idx, path); ++ else ++ iqk_info->iqk_rx_fail[0][path] = _rxk_group_sel(rtwdev, phy_idx, path); ++ ++ _iqk_info_iqk(rtwdev, phy_idx, path); ++} ++ ++static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ u32 reg_rf18 = 0x0, reg_35c = 0x0; ++ u8 idx = 0; ++ u8 get_empty_table = false; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) { ++ if (iqk_info->iqk_mcc_ch[idx][path] == 0) { ++ get_empty_table = true; ++ break; ++ } ++ } ++ if (!get_empty_table) { ++ idx = iqk_info->iqk_table_idx[path] + 1; ++ if (idx > RTW89_IQK_CHS_NR - 1) ++ idx = 0; ++ } ++ reg_rf18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]cfg ch = %d\n", reg_rf18); ++ reg_35c = rtw89_phy_read32_mask(rtwdev, 0x35c, 0x00000c00); ++ ++ iqk_info->iqk_band[path] = hal->current_band_type; ++ iqk_info->iqk_bw[path] = hal->current_band_width; ++ iqk_info->iqk_ch[path] = hal->current_channel; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]iqk_info->iqk_band[%x] = 0x%x\n", path, ++ iqk_info->iqk_band[path]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_info->iqk_bw[%x] = 0x%x\n", ++ path, iqk_info->iqk_bw[path]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_info->iqk_ch[%x] = 0x%x\n", ++ path, iqk_info->iqk_ch[path]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n", path, phy, ++ rtwdev->dbcc_en ? "on" : "off", ++ iqk_info->iqk_band[path] == 0 ? "2G" : ++ iqk_info->iqk_band[path] == 1 ? "5G" : "6G", ++ iqk_info->iqk_ch[path], ++ iqk_info->iqk_bw[path] == 0 ? "20M" : ++ iqk_info->iqk_bw[path] == 1 ? "40M" : "80M"); ++ if (reg_35c == 0x01) ++ iqk_info->syn1to2 = 0x1; ++ else ++ iqk_info->syn1to2 = 0x0; ++ ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_VER, RTW8852A_IQK_VER); ++ rtw89_phy_write32_mask(rtwdev, R_IQKCH, 0x000f << (path * 16), ++ (u8)iqk_info->iqk_band[path]); ++ rtw89_phy_write32_mask(rtwdev, R_IQKCH, 0x00f0 << (path * 16), ++ (u8)iqk_info->iqk_bw[path]); ++ rtw89_phy_write32_mask(rtwdev, R_IQKCH, 0xff00 << (path * 16), ++ (u8)iqk_info->iqk_ch[path]); ++ ++ rtw89_phy_write32_mask(rtwdev, R_IQKINF2, 0x000000ff, RTW8852A_NCTL_VER); ++} ++ ++static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, ++ u8 path) ++{ ++ _iqk_by_path(rtwdev, phy_idx, path); ++} ++ ++static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ ++ rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD, ++ iqk_info->nb_txcfir[path]); ++ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, ++ iqk_info->nb_rxcfir[path]); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_RPT, MASKDWORD); ++ rtw89_phy_write32_clr(rtwdev, R_MDPK_RX_DCK, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); ++ rtw89_phy_write32_clr(rtwdev, R_KPATH_CFG, MASKDWORD); ++ rtw89_phy_write32_clr(rtwdev, R_GAPK, B_GAPK_ADR); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0x10010000); ++ rtw89_phy_write32_clr(rtwdev, R_KIP + (path << 8), B_KIP_RFGAIN); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_MAP + (path << 8), MASKDWORD, 0xe4e4e4e4); ++ rtw89_phy_write32_clr(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); ++ rtw89_phy_write32_clr(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW); ++ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), MASKDWORD, 0x00000002); ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_POW, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); ++ rtw89_write_rf(rtwdev, path, RR_TXRSV, RR_TXRSV_GAPK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_BIAS, RR_BIAS_GAPK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); ++} ++ ++static void _iqk_afebb_restore(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ const struct rtw89_rfk_tbl *tbl; ++ ++ switch (_kpath(rtwdev, phy_idx)) { ++ case RF_A: ++ tbl = &rtw8852a_rfk_iqk_restore_defs_dbcc_path0_tbl; ++ break; ++ case RF_B: ++ tbl = &rtw8852a_rfk_iqk_restore_defs_dbcc_path1_tbl; ++ break; ++ default: ++ tbl = &rtw8852a_rfk_iqk_restore_defs_nondbcc_path01_tbl; ++ break; ++ } ++ ++ rtw89_rfk_parser(rtwdev, tbl); ++} ++ ++static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u8 idx = iqk_info->iqk_table_idx[path]; ++ ++ if (rtwdev->dbcc_en) { ++ rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), ++ B_COEF_SEL_IQC, path & 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), ++ B_CFIR_LUT_G2, path & 0x1); ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), ++ B_COEF_SEL_IQC, idx); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), ++ B_CFIR_LUT_G2, idx); ++ } ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_RW, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x81ff010a); ++ rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, MASKDWORD, 0x00200000); ++ rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, MASKDWORD, 0x80000000); ++ rtw89_phy_write32_clr(rtwdev, R_LOAD_COEF + (path << 8), MASKDWORD); ++} ++ ++static void _iqk_macbb_setting(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ const struct rtw89_rfk_tbl *tbl; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===> %s\n", __func__); ++ ++ switch (_kpath(rtwdev, phy_idx)) { ++ case RF_A: ++ tbl = &rtw8852a_rfk_iqk_set_defs_dbcc_path0_tbl; ++ break; ++ case RF_B: ++ tbl = &rtw8852a_rfk_iqk_set_defs_dbcc_path1_tbl; ++ break; ++ default: ++ tbl = &rtw8852a_rfk_iqk_set_defs_nondbcc_path01_tbl; ++ break; ++ } ++ ++ rtw89_rfk_parser(rtwdev, tbl); ++} ++ ++static void _iqk_dbcc(struct rtw89_dev *rtwdev, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u8 phy_idx = 0x0; ++ ++ iqk_info->iqk_times++; ++ ++ if (path == 0x0) ++ phy_idx = RTW89_PHY_0; ++ else ++ phy_idx = RTW89_PHY_1; ++ ++ _iqk_get_ch_info(rtwdev, phy_idx, path); ++ _iqk_macbb_setting(rtwdev, phy_idx, path); ++ _iqk_preset(rtwdev, path); ++ _iqk_start_iqk(rtwdev, phy_idx, path); ++ _iqk_restore(rtwdev, path); ++ _iqk_afebb_restore(rtwdev, phy_idx, path); ++} ++ ++static void _iqk_track(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_iqk_info *iqk = &rtwdev->iqk; ++ u8 path = 0x0; ++ u8 cur_ther; ++ ++ if (iqk->iqk_band[0] == RTW89_BAND_2G) ++ return; ++ if (iqk->iqk_bw[0] < RTW89_CHANNEL_WIDTH_80) ++ return; ++ ++ /* only check path 0 */ ++ for (path = 0; path < 1; path++) { ++ cur_ther = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); ++ ++ if (abs(cur_ther - iqk->thermal[path]) > RTW8852A_IQK_THR_REK) ++ iqk->thermal_rek_en = true; ++ else ++ iqk->thermal_rek_en = false; ++ } ++} ++ ++static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) ++{ ++ u32 rf_reg5, rck_val = 0; ++ u32 val; ++ int ret; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] ====== S%d RCK ======\n", path); ++ ++ rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); ++ ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF0x00 = 0x%x\n", ++ rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); ++ ++ /* RCK trigger */ ++ rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, 0x00240); ++ ++ ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 20, ++ false, rtwdev, path, 0x1c, BIT(3)); ++ if (ret) ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RCK timeout\n"); ++ ++ rck_val = rtw89_read_rf(rtwdev, path, RR_RCKC, RR_RCKC_CA); ++ rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, rck_val); ++ ++ /* RCK_ADC_OFFSET */ ++ rtw89_write_rf(rtwdev, path, RR_RCKO, RR_RCKO_OFF, 0x4); ++ ++ rtw89_write_rf(rtwdev, path, RR_RFC, RR_RFC_CKEN, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_RFC, RR_RFC_CKEN, 0x0); ++ ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[RCK] RF 0x1b / 0x1c / 0x1d = 0x%x / 0x%x / 0x%x\n", ++ rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK), ++ rtw89_read_rf(rtwdev, path, RR_RCKS, RFREG_MASK), ++ rtw89_read_rf(rtwdev, path, RR_RCKO, RFREG_MASK)); ++} ++ ++static void _iqk_init(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u8 ch, path; ++ ++ rtw89_phy_write32_clr(rtwdev, R_IQKINF, MASKDWORD); ++ if (iqk_info->is_iqk_init) ++ return; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); ++ iqk_info->is_iqk_init = true; ++ iqk_info->is_nbiqk = false; ++ iqk_info->iqk_fft_en = false; ++ iqk_info->iqk_sram_en = false; ++ iqk_info->iqk_cfir_en = false; ++ iqk_info->iqk_xym_en = false; ++ iqk_info->thermal_rek_en = false; ++ iqk_info->iqk_times = 0x0; ++ ++ for (ch = 0; ch < RTW89_IQK_CHS_NR; ch++) { ++ iqk_info->iqk_channel[ch] = 0x0; ++ for (path = 0; path < RTW8852A_IQK_SS; path++) { ++ iqk_info->lok_cor_fail[ch][path] = false; ++ iqk_info->lok_fin_fail[ch][path] = false; ++ iqk_info->iqk_tx_fail[ch][path] = false; ++ iqk_info->iqk_rx_fail[ch][path] = false; ++ iqk_info->iqk_mcc_ch[ch][path] = 0x0; ++ iqk_info->iqk_table_idx[path] = 0x0; ++ } ++ } ++} ++ ++static void _doiqk(struct rtw89_dev *rtwdev, bool force, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u32 backup_bb_val[BACKUP_BB_REGS_NR]; ++ u32 backup_rf_val[RTW8852A_IQK_SS][BACKUP_RF_REGS_NR]; ++ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]==========IQK strat!!!!!==========\n"); ++ iqk_info->iqk_times++; ++ iqk_info->kcount = 0; ++ iqk_info->version = RTW8852A_IQK_VER; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); ++ _iqk_get_ch_info(rtwdev, phy_idx, path); ++ _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]); ++ _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path); ++ _iqk_macbb_setting(rtwdev, phy_idx, path); ++ _iqk_preset(rtwdev, path); ++ _iqk_start_iqk(rtwdev, phy_idx, path); ++ _iqk_restore(rtwdev, path); ++ _iqk_afebb_restore(rtwdev, phy_idx, path); ++ _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]); ++ _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); ++} ++ ++static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force) ++{ ++ switch (_kpath(rtwdev, phy_idx)) { ++ case RF_A: ++ _doiqk(rtwdev, force, phy_idx, RF_PATH_A); ++ break; ++ case RF_B: ++ _doiqk(rtwdev, force, phy_idx, RF_PATH_B); ++ break; ++ case RF_AB: ++ _doiqk(rtwdev, force, phy_idx, RF_PATH_A); ++ _doiqk(rtwdev, force, phy_idx, RF_PATH_B); ++ break; ++ default: ++ break; ++ } ++} ++ ++#define RXDCK_VER_8852A 0xe ++ ++static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, bool is_afe) ++{ ++ u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy, path); ++ u32 ori_val; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[RX_DCK] ==== S%d RX DCK (by %s)====\n", ++ path, is_afe ? "AFE" : "RFC"); ++ ++ ori_val = rtw89_phy_read32_mask(rtwdev, R_P0_RXCK + (path << 13), MASKDWORD); ++ ++ if (is_afe) { ++ rtw89_phy_write32_set(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); ++ rtw89_phy_write32_set(rtwdev, R_P0_RXCK + (path << 13), B_P0_RXCK_ON); ++ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), ++ B_P0_RXCK_VAL, 0x3); ++ rtw89_phy_write32_set(rtwdev, R_S0_RXDC2 + (path << 13), B_S0_RXDC2_MEN); ++ rtw89_phy_write32_mask(rtwdev, R_S0_RXDC2 + (path << 13), ++ B_S0_RXDC2_AVG, 0x3); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0x3); ++ rtw89_phy_write32_clr(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK); ++ rtw89_phy_write32_clr(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST); ++ rtw89_phy_write32_set(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST); ++ rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_CRXBB, 0x1); ++ } ++ ++ rtw89_write_rf(rtwdev, path, RR_DCK2, RR_DCK2_CYCLE, 0x3f); ++ rtw89_write_rf(rtwdev, path, RR_DCK1, RR_DCK1_SEL, is_afe); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_ONESHOT_START); ++ ++ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1); ++ ++ fsleep(600); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_ONESHOT_STOP); ++ ++ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); ++ ++ if (is_afe) { ++ rtw89_phy_write32_clr(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); ++ rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), ++ MASKDWORD, ori_val); ++ } ++} ++ ++static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ bool is_afe) ++{ ++ u8 path, kpath, dck_tune; ++ u32 rf_reg5; ++ u32 addr; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, Cv: %d) ******\n", ++ RXDCK_VER_8852A, rtwdev->hal.cv); ++ ++ kpath = _kpath(rtwdev, phy); ++ ++ for (path = 0; path < 2; path++) { ++ if (!(kpath & BIT(path))) ++ continue; ++ ++ rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); ++ dck_tune = (u8)rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_FINE); ++ ++ if (rtwdev->is_tssi_mode[path]) { ++ addr = 0x5818 + (path << 13); ++ /* TSSI pause */ ++ rtw89_phy_write32_set(rtwdev, addr, BIT(30)); ++ } ++ ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); ++ _set_rx_dck(rtwdev, phy, path, is_afe); ++ rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, dck_tune); ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); ++ ++ if (rtwdev->is_tssi_mode[path]) { ++ addr = 0x5818 + (path << 13); ++ /* TSSI resume */ ++ rtw89_phy_write32_clr(rtwdev, addr, BIT(30)); ++ } ++ } ++} ++ ++#define RTW8852A_RF_REL_VERSION 34 ++#define RTW8852A_DPK_VER 0x10 ++#define RTW8852A_DPK_TH_AVG_NUM 4 ++#define RTW8852A_DPK_RF_PATH 2 ++#define RTW8852A_DPK_KIP_REG_NUM 2 ++ ++enum rtw8852a_dpk_id { ++ LBK_RXIQK = 0x06, ++ SYNC = 0x10, ++ MDPK_IDL = 0x11, ++ MDPK_MPA = 0x12, ++ GAIN_LOSS = 0x13, ++ GAIN_CAL = 0x14, ++}; ++ ++static void _rf_direct_cntrl(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, bool is_bybb) ++{ ++ if (is_bybb) ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); ++ else ++ rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); ++} ++ ++static void _dpk_onoff(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, bool off); ++ ++static void _dpk_bkup_kip(struct rtw89_dev *rtwdev, u32 *reg, ++ u32 reg_bkup[][RTW8852A_DPK_KIP_REG_NUM], ++ u8 path) ++{ ++ u8 i; ++ ++ for (i = 0; i < RTW8852A_DPK_KIP_REG_NUM; i++) { ++ reg_bkup[path][i] = rtw89_phy_read32_mask(rtwdev, ++ reg[i] + (path << 8), ++ MASKDWORD); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup 0x%x = %x\n", ++ reg[i] + (path << 8), reg_bkup[path][i]); ++ } ++} ++ ++static void _dpk_reload_kip(struct rtw89_dev *rtwdev, u32 *reg, ++ u32 reg_bkup[][RTW8852A_DPK_KIP_REG_NUM], u8 path) ++{ ++ u8 i; ++ ++ for (i = 0; i < RTW8852A_DPK_KIP_REG_NUM; i++) { ++ rtw89_phy_write32_mask(rtwdev, reg[i] + (path << 8), ++ MASKDWORD, reg_bkup[path][i]); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Reload 0x%x = %x\n", ++ reg[i] + (path << 8), reg_bkup[path][i]); ++ } ++} ++ ++static u8 _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, enum rtw8852a_dpk_id id) ++{ ++ u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy, path); ++ u16 dpk_cmd = 0x0; ++ u32 val; ++ int ret; ++ ++ dpk_cmd = (u16)((id << 8) | (0x19 + (path << 4))); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_ONESHOT_START); ++ ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, dpk_cmd); ++ rtw89_phy_write32_set(rtwdev, R_DPK_CTL, B_DPK_CTL_EN); ++ ++ ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, ++ 10, 20000, false, rtwdev, 0xbff8, MASKBYTE0); ++ ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_ONESHOT_STOP); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] one-shot for %s = 0x%x (ret=%d)\n", ++ id == 0x06 ? "LBK_RXIQK" : ++ id == 0x10 ? "SYNC" : ++ id == 0x11 ? "MDPK_IDL" : ++ id == 0x12 ? "MDPK_MPA" : ++ id == 0x13 ? "GAIN_LOSS" : "PWR_CAL", ++ dpk_cmd, ret); ++ ++ if (ret) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] one-shot over 20ms!!!!\n"); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static void _dpk_rx_dck(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_EN_TIA_IDA, 0x3); ++ _set_rx_dck(rtwdev, phy, path, false); ++} ++ ++static void _dpk_information(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ struct rtw89_hal *hal = &rtwdev->hal; ++ ++ u8 kidx = dpk->cur_idx[path]; ++ ++ dpk->bp[path][kidx].band = hal->current_band_type; ++ dpk->bp[path][kidx].ch = hal->current_channel; ++ dpk->bp[path][kidx].bw = hal->current_band_width; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", ++ path, dpk->cur_idx[path], phy, ++ rtwdev->is_tssi_mode[path] ? "on" : "off", ++ rtwdev->dbcc_en ? "on" : "off", ++ dpk->bp[path][kidx].band == 0 ? "2G" : ++ dpk->bp[path][kidx].band == 1 ? "5G" : "6G", ++ dpk->bp[path][kidx].ch, ++ dpk->bp[path][kidx].bw == 0 ? "20M" : ++ dpk->bp[path][kidx].bw == 1 ? "40M" : "80M"); ++} ++ ++static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, u8 kpath) ++{ ++ switch (kpath) { ++ case RF_A: ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sf_defs_a_tbl); ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL) == 0x0) ++ rtw89_phy_write32_set(rtwdev, R_RXCCA, B_RXCCA_DIS); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sr_defs_a_tbl); ++ break; ++ case RF_B: ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sf_defs_b_tbl); ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL) == 0x1) ++ rtw89_phy_write32_set(rtwdev, R_RXCCA, B_RXCCA_DIS); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sr_defs_b_tbl); ++ break; ++ case RF_AB: ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_s_defs_ab_tbl); ++ break; ++ default: ++ break; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Set BB/AFE for PHY%d (kpath=%d)\n", phy, kpath); ++} ++ ++static void _dpk_bb_afe_restore(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, u8 kpath) ++{ ++ switch (kpath) { ++ case RF_A: ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_r_defs_a_tbl); ++ break; ++ case RF_B: ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_r_defs_b_tbl); ++ break; ++ case RF_AB: ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_r_defs_ab_tbl); ++ break; ++ default: ++ break; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Restore BB/AFE for PHY%d (kpath=%d)\n", phy, kpath); ++} ++ ++static void _dpk_tssi_pause(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, bool is_pause) ++{ ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), ++ B_P0_TSSI_TRK_EN, is_pause); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI %s\n", path, ++ is_pause ? "pause" : "resume"); ++} ++ ++static void _dpk_kip_setting(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, u8 kidx) ++{ ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_CLK, MASKDWORD, 0x00093f3f); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x807f030a); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0xce000a08); ++ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG, B_DPK_CFG_IDX, 0x2); ++ rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, B_NCTL_CFG_SPAGE, path); /*subpage_id*/ ++ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0 + (path << 8) + (kidx << 2), ++ MASKDWORD, 0x003f2e2e); ++ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), ++ MASKDWORD, 0x005b5b5b); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] KIP setting for S%d[%d]!!\n", ++ path, kidx); ++} ++ ++static void _dpk_kip_restore(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path) ++{ ++ rtw89_phy_write32_clr(rtwdev, R_NCTL_RPT, MASKDWORD); ++ rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); ++ rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0x10010000); ++ rtw89_phy_write32_clr(rtwdev, R_KIP_CLK, MASKDWORD); ++ ++ if (rtwdev->hal.cv > CHIP_CBV) ++ rtw89_phy_write32_mask(rtwdev, R_DPD_COM + (path << 8), BIT(15), 0x1); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d restore KIP\n", path); ++} ++ ++static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ u8 cur_rxbb; ++ ++ cur_rxbb = (u8)rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_lbk_rxiqk_defs_f_tbl); ++ ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_RXPOW, RR_RXPOW_IQK, 0x2); ++ rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, ++ rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK)); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x1); ++ ++ fsleep(70); ++ ++ rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTL, 0x1f); ++ ++ if (cur_rxbb <= 0xa) ++ rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTH, 0x3); ++ else if (cur_rxbb <= 0x10 && cur_rxbb >= 0xb) ++ rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTH, 0x1); ++ else ++ rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTH, 0x0); ++ ++ rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); ++ ++ _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d LBK RXIQC = 0x%x\n", path, ++ rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD)); ++ ++ rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXPOW, RR_RXPOW_IQK, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); /*POW IQKPLL*/ ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_DPK); ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_lbk_rxiqk_defs_r_tbl); ++} ++ ++static void _dpk_get_thermal(struct rtw89_dev *rtwdev, u8 kidx, ++ enum rtw89_rf_path path) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ ++ dpk->bp[path][kidx].ther_dpk = ++ ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] thermal@DPK = 0x%x\n", ++ dpk->bp[path][kidx].ther_dpk); ++} ++ ++static u8 _dpk_set_tx_pwr(struct rtw89_dev *rtwdev, u8 gain, ++ enum rtw89_rf_path path) ++{ ++ u8 txagc_ori = 0x38; ++ ++ rtw89_write_rf(rtwdev, path, RR_MODOPT, RFREG_MASK, txagc_ori); ++ ++ return txagc_ori; ++} ++ ++static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain, ++ enum rtw89_rf_path path, u8 kidx) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ ++ if (dpk->bp[path][kidx].band == RTW89_BAND_2G) { ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DPK, 0x280b); ++ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTC, 0x0); ++ rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTR, 0x4); ++ rtw89_write_rf(rtwdev, path, RR_MIXER, RR_MIXER_GN, 0x0); ++ } else { ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DPK, 0x282e); ++ rtw89_write_rf(rtwdev, path, RR_BIASA2, RR_BIASA2_LB, 0x7); ++ rtw89_write_rf(rtwdev, path, RR_TXATANK, RR_TXATANK_LBSW, 0x3); ++ rtw89_write_rf(rtwdev, path, RR_RXA, RR_RXA_DPK, 0x3); ++ } ++ rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_BW, 0x1); ++ rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_TXBB, dpk->bp[path][kidx].bw + 1); ++ rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_RXBB, 0x0); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] RF 0x0/0x1/0x1a = 0x%x/ 0x%x/ 0x%x\n", ++ rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK), ++ rtw89_read_rf(rtwdev, path, RR_MODOPT, RFREG_MASK), ++ rtw89_read_rf(rtwdev, path, RR_BTC, RFREG_MASK)); ++} ++ ++static void _dpk_manual_txcfir(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, bool is_manual) ++{ ++ u8 tmp_pad, tmp_txbb; ++ ++ if (is_manual) { ++ rtw89_phy_write32_mask(rtwdev, R_KIP + (path << 8), B_KIP_RFGAIN, 0x1); ++ tmp_pad = (u8)rtw89_read_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_PAD); ++ rtw89_phy_write32_mask(rtwdev, R_RFGAIN + (path << 8), ++ B_RFGAIN_PAD, tmp_pad); ++ ++ tmp_txbb = (u8)rtw89_read_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_BB); ++ rtw89_phy_write32_mask(rtwdev, R_RFGAIN + (path << 8), ++ B_RFGAIN_TXBB, tmp_txbb); ++ ++ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), ++ B_LOAD_COEF_CFIR, 0x1); ++ rtw89_phy_write32_clr(rtwdev, R_LOAD_COEF + (path << 8), ++ B_LOAD_COEF_CFIR); ++ ++ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), BIT(1), 0x1); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] PAD_man / TXBB_man = 0x%x / 0x%x\n", tmp_pad, ++ tmp_txbb); ++ } else { ++ rtw89_phy_write32_clr(rtwdev, R_KIP + (path << 8), B_KIP_RFGAIN); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] disable manual switch TXCFIR\n"); ++ } ++} ++ ++static void _dpk_bypass_rxcfir(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, bool is_bypass) ++{ ++ if (is_bypass) { ++ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), ++ B_RXIQC_BYPASS2, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), ++ B_RXIQC_BYPASS, 0x1); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Bypass RXIQC (0x8%d3c = 0x%x)\n", 1 + path, ++ rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), ++ MASKDWORD)); ++ } else { ++ rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS2); ++ rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] restore 0x8%d3c = 0x%x\n", 1 + path, ++ rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), ++ MASKDWORD)); ++ } ++} ++ ++static ++void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ ++ if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) ++ rtw89_phy_write32_clr(rtwdev, R_TPG_MOD, B_TPG_MOD_F); ++ else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40) ++ rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x2); ++ else ++ rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x1); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] TPG_Select for %s\n", ++ dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" : ++ dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M"); ++} ++ ++static void _dpk_table_select(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, u8 kidx, u8 gain) ++{ ++ u8 val; ++ ++ val = 0x80 + kidx * 0x20 + gain * 0x10; ++ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0 + (path << 8), MASKBYTE3, val); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] table select for Kidx[%d], Gain[%d] (0x%x)\n", kidx, ++ gain, val); ++} ++ ++static bool _dpk_sync_check(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path) ++{ ++#define DPK_SYNC_TH_DC_I 200 ++#define DPK_SYNC_TH_DC_Q 200 ++#define DPK_SYNC_TH_CORR 170 ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ u16 dc_i, dc_q; ++ u8 corr_val, corr_idx; ++ ++ rtw89_phy_write32_clr(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL); ++ ++ corr_idx = (u8)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORI); ++ corr_val = (u8)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORV); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] S%d Corr_idx / Corr_val = %d / %d\n", path, corr_idx, ++ corr_val); ++ ++ dpk->corr_idx[path] = corr_idx; ++ dpk->corr_val[path] = corr_val; ++ ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x9); ++ ++ dc_i = (u16)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); ++ dc_q = (u16)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); ++ ++ dc_i = abs(sign_extend32(dc_i, 11)); ++ dc_q = abs(sign_extend32(dc_q, 11)); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d DC I/Q, = %d / %d\n", ++ path, dc_i, dc_q); ++ ++ dpk->dc_i[path] = dc_i; ++ dpk->dc_q[path] = dc_q; ++ ++ if (dc_i > DPK_SYNC_TH_DC_I || dc_q > DPK_SYNC_TH_DC_Q || ++ corr_val < DPK_SYNC_TH_CORR) ++ return true; ++ else ++ return false; ++} ++ ++static bool _dpk_sync(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, u8 kidx) ++{ ++ _dpk_tpg_sel(rtwdev, path, kidx); ++ _dpk_one_shot(rtwdev, phy, path, SYNC); ++ return _dpk_sync_check(rtwdev, path); /*1= fail*/ ++} ++ ++static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev) ++{ ++ u16 dgain = 0x0; ++ ++ rtw89_phy_write32_clr(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL); ++ ++ rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_SYNERR); ++ ++ dgain = (u16)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain = 0x%x (%d)\n", dgain, ++ dgain); ++ ++ return dgain; ++} ++ ++static s8 _dpk_dgain_mapping(struct rtw89_dev *rtwdev, u16 dgain) ++{ ++ s8 offset; ++ ++ if (dgain >= 0x783) ++ offset = 0x6; ++ else if (dgain <= 0x782 && dgain >= 0x551) ++ offset = 0x3; ++ else if (dgain <= 0x550 && dgain >= 0x3c4) ++ offset = 0x0; ++ else if (dgain <= 0x3c3 && dgain >= 0x2aa) ++ offset = -3; ++ else if (dgain <= 0x2a9 && dgain >= 0x1e3) ++ offset = -6; ++ else if (dgain <= 0x1e2 && dgain >= 0x156) ++ offset = -9; ++ else if (dgain <= 0x155) ++ offset = -12; ++ else ++ offset = 0x0; ++ ++ return offset; ++} ++ ++static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev) ++{ ++ rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6); ++ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1); ++ return rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL); ++} ++ ++static void _dpk_gainloss(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, enum rtw89_rf_path path, ++ u8 kidx) ++{ ++ _dpk_table_select(rtwdev, path, kidx, 1); ++ _dpk_one_shot(rtwdev, phy, path, GAIN_LOSS); ++} ++ ++#define DPK_TXAGC_LOWER 0x2e ++#define DPK_TXAGC_UPPER 0x3f ++#define DPK_TXAGC_INVAL 0xff ++ ++static u8 _dpk_set_offset(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, s8 gain_offset) ++{ ++ u8 txagc; ++ ++ txagc = (u8)rtw89_read_rf(rtwdev, path, RR_MODOPT, RFREG_MASK); ++ ++ if (txagc - gain_offset < DPK_TXAGC_LOWER) ++ txagc = DPK_TXAGC_LOWER; ++ else if (txagc - gain_offset > DPK_TXAGC_UPPER) ++ txagc = DPK_TXAGC_UPPER; ++ else ++ txagc = txagc - gain_offset; ++ ++ rtw89_write_rf(rtwdev, path, RR_MODOPT, RFREG_MASK, txagc); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] tmp_txagc (GL=%d) = 0x%x\n", ++ gain_offset, txagc); ++ return txagc; ++} ++ ++enum dpk_agc_step { ++ DPK_AGC_STEP_SYNC_DGAIN, ++ DPK_AGC_STEP_GAIN_ADJ, ++ DPK_AGC_STEP_GAIN_LOSS_IDX, ++ DPK_AGC_STEP_GL_GT_CRITERION, ++ DPK_AGC_STEP_GL_LT_CRITERION, ++ DPK_AGC_STEP_SET_TX_GAIN, ++}; ++ ++static u8 _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check) ++{ ++ u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0; ++ u8 i; ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_pas_read_defs_tbl); ++ ++ if (is_check) { ++ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x00); ++ val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); ++ val1_i = abs(sign_extend32(val1_i, 11)); ++ val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); ++ val1_q = abs(sign_extend32(val1_q, 11)); ++ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x1f); ++ val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); ++ val2_i = abs(sign_extend32(val2_i, 11)); ++ val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); ++ val2_q = abs(sign_extend32(val2_q, 11)); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n", ++ (val1_i * val1_i + val1_q * val1_q) / ++ (val2_i * val2_i + val2_q * val2_q)); ++ ++ } else { ++ for (i = 0; i < 32; i++) { ++ rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, i); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] PAS_Read[%02d]= 0x%08x\n", i, ++ rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); ++ } ++ } ++ if ((val1_i * val1_i + val1_q * val1_q) >= ++ ((val2_i * val2_i + val2_q * val2_q) * 8 / 5)) ++ return 1; ++ else ++ return 0; ++} ++ ++static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, u8 kidx, u8 init_txagc, ++ bool loss_only) ++{ ++#define DPK_AGC_ADJ_LMT 6 ++#define DPK_DGAIN_UPPER 1922 ++#define DPK_DGAIN_LOWER 342 ++#define DPK_RXBB_UPPER 0x1f ++#define DPK_RXBB_LOWER 0 ++#define DPK_GL_CRIT 7 ++ u8 tmp_txagc, tmp_rxbb = 0, tmp_gl_idx = 0; ++ u8 agc_cnt = 0; ++ bool limited_rxbb = false; ++ s8 offset = 0; ++ u16 dgain = 0; ++ u8 step = DPK_AGC_STEP_SYNC_DGAIN; ++ bool goout = false; ++ ++ tmp_txagc = init_txagc; ++ ++ do { ++ switch (step) { ++ case DPK_AGC_STEP_SYNC_DGAIN: ++ if (_dpk_sync(rtwdev, phy, path, kidx)) { ++ tmp_txagc = DPK_TXAGC_INVAL; ++ goout = true; ++ break; ++ } ++ ++ dgain = _dpk_dgain_read(rtwdev); ++ ++ if (loss_only || limited_rxbb) ++ step = DPK_AGC_STEP_GAIN_LOSS_IDX; ++ else ++ step = DPK_AGC_STEP_GAIN_ADJ; ++ break; ++ ++ case DPK_AGC_STEP_GAIN_ADJ: ++ tmp_rxbb = (u8)rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB); ++ offset = _dpk_dgain_mapping(rtwdev, dgain); ++ ++ if (tmp_rxbb + offset > DPK_RXBB_UPPER) { ++ tmp_rxbb = DPK_RXBB_UPPER; ++ limited_rxbb = true; ++ } else if (tmp_rxbb + offset < DPK_RXBB_LOWER) { ++ tmp_rxbb = DPK_RXBB_LOWER; ++ limited_rxbb = true; ++ } else { ++ tmp_rxbb = tmp_rxbb + offset; ++ } ++ ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB, tmp_rxbb); ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Adjust RXBB (%d) = 0x%x\n", offset, ++ tmp_rxbb); ++ if (offset != 0 || agc_cnt == 0) { ++ if (rtwdev->hal.current_band_width < RTW89_CHANNEL_WIDTH_80) ++ _dpk_bypass_rxcfir(rtwdev, path, true); ++ else ++ _dpk_lbk_rxiqk(rtwdev, phy, path); ++ } ++ if (dgain > DPK_DGAIN_UPPER || dgain < DPK_DGAIN_LOWER) ++ step = DPK_AGC_STEP_SYNC_DGAIN; ++ else ++ step = DPK_AGC_STEP_GAIN_LOSS_IDX; ++ ++ agc_cnt++; ++ break; ++ ++ case DPK_AGC_STEP_GAIN_LOSS_IDX: ++ _dpk_gainloss(rtwdev, phy, path, kidx); ++ tmp_gl_idx = _dpk_gainloss_read(rtwdev); ++ ++ if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true)) || ++ tmp_gl_idx > DPK_GL_CRIT) ++ step = DPK_AGC_STEP_GL_GT_CRITERION; ++ else if (tmp_gl_idx == 0) ++ step = DPK_AGC_STEP_GL_LT_CRITERION; ++ else ++ step = DPK_AGC_STEP_SET_TX_GAIN; ++ break; ++ ++ case DPK_AGC_STEP_GL_GT_CRITERION: ++ if (tmp_txagc == DPK_TXAGC_LOWER) { ++ goout = true; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Txagc@lower bound!!\n"); ++ } else { ++ tmp_txagc = _dpk_set_offset(rtwdev, path, 3); ++ } ++ step = DPK_AGC_STEP_GAIN_LOSS_IDX; ++ agc_cnt++; ++ break; ++ ++ case DPK_AGC_STEP_GL_LT_CRITERION: ++ if (tmp_txagc == DPK_TXAGC_UPPER) { ++ goout = true; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Txagc@upper bound!!\n"); ++ } else { ++ tmp_txagc = _dpk_set_offset(rtwdev, path, -2); ++ } ++ step = DPK_AGC_STEP_GAIN_LOSS_IDX; ++ agc_cnt++; ++ break; ++ ++ case DPK_AGC_STEP_SET_TX_GAIN: ++ tmp_txagc = _dpk_set_offset(rtwdev, path, tmp_gl_idx); ++ goout = true; ++ agc_cnt++; ++ break; ++ ++ default: ++ goout = true; ++ break; ++ } ++ } while (!goout && (agc_cnt < DPK_AGC_ADJ_LMT)); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Txagc / RXBB for DPK = 0x%x / 0x%x\n", tmp_txagc, ++ tmp_rxbb); ++ ++ return tmp_txagc; ++} ++ ++static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order) ++{ ++ switch (order) { ++ case 0: ++ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); ++ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x3); ++ rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN, 0x1); ++ break; ++ case 1: ++ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); ++ rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN); ++ rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN); ++ break; ++ case 2: ++ rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); ++ rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN); ++ rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN); ++ break; ++ default: ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Wrong MDPD order!!(0x%x)\n", order); ++ break; ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Set MDPD order to 0x%x for IDL\n", order); ++} ++ ++static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, u8 kidx, u8 gain) ++{ ++ _dpk_set_mdpd_para(rtwdev, 0x0); ++ _dpk_table_select(rtwdev, path, kidx, 1); ++ _dpk_one_shot(rtwdev, phy, path, MDPK_IDL); ++} ++ ++static void _dpk_fill_result(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, u8 kidx, u8 gain, ++ u8 txagc) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ ++ u16 pwsf = 0x78; ++ u8 gs = 0x5b; ++ ++ rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_MDPD, kidx); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Fill txagc/ pwsf/ gs = 0x%x/ 0x%x/ 0x%x\n", txagc, ++ pwsf, gs); ++ ++ dpk->bp[path][kidx].txagc_dpk = txagc; ++ rtw89_phy_write32_mask(rtwdev, R_TXAGC_RFK + (path << 8), ++ 0x3F << ((gain << 3) + (kidx << 4)), txagc); ++ ++ dpk->bp[path][kidx].pwsf = pwsf; ++ rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), ++ 0x1FF << (gain << 4), pwsf); ++ ++ rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x1); ++ rtw89_phy_write32_clr(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD); ++ ++ dpk->bp[path][kidx].gs = gs; ++ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), ++ MASKDWORD, 0x065b5b5b); ++ ++ rtw89_phy_write32_clr(rtwdev, R_DPD_V1 + (path << 8), MASKDWORD); ++ ++ rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_SEL); ++} ++ ++static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ bool is_reload = false; ++ u8 idx, cur_band, cur_ch; ++ ++ cur_band = rtwdev->hal.current_band_type; ++ cur_ch = rtwdev->hal.current_channel; ++ ++ for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) { ++ if (cur_band != dpk->bp[path][idx].band || ++ cur_ch != dpk->bp[path][idx].ch) ++ continue; ++ ++ rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), ++ B_COEF_SEL_MDPD, idx); ++ dpk->cur_idx[path] = idx; ++ is_reload = true; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] reload S%d[%d] success\n", path, idx); ++ } ++ ++ return is_reload; ++} ++ ++static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path, u8 gain) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ u8 txagc = 0, kidx = dpk->cur_idx[path]; ++ bool is_fail = false; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] ========= S%d[%d] DPK Start =========\n", path, ++ kidx); ++ ++ _rf_direct_cntrl(rtwdev, path, false); ++ txagc = _dpk_set_tx_pwr(rtwdev, gain, path); ++ _dpk_rf_setting(rtwdev, gain, path, kidx); ++ _dpk_rx_dck(rtwdev, phy, path); ++ ++ _dpk_kip_setting(rtwdev, path, kidx); ++ _dpk_manual_txcfir(rtwdev, path, true); ++ txagc = _dpk_agc(rtwdev, phy, path, kidx, txagc, false); ++ if (txagc == DPK_TXAGC_INVAL) ++ is_fail = true; ++ _dpk_get_thermal(rtwdev, kidx, path); ++ ++ _dpk_idl_mpa(rtwdev, phy, path, kidx, gain); ++ rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); ++ _dpk_fill_result(rtwdev, path, kidx, gain, txagc); ++ _dpk_manual_txcfir(rtwdev, path, false); ++ ++ if (!is_fail) ++ dpk->bp[path][kidx].path_ok = true; ++ else ++ dpk->bp[path][kidx].path_ok = false; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s\n", path, kidx, ++ is_fail ? "Check" : "Success"); ++ ++ return is_fail; ++} ++ ++static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force, ++ enum rtw89_phy_idx phy, u8 kpath) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ u32 backup_bb_val[BACKUP_BB_REGS_NR]; ++ u32 backup_rf_val[RTW8852A_DPK_RF_PATH][BACKUP_RF_REGS_NR]; ++ u32 kip_bkup[RTW8852A_DPK_RF_PATH][RTW8852A_DPK_KIP_REG_NUM] = {{0}}; ++ u32 kip_reg[] = {R_RXIQC, R_IQK_RES}; ++ u8 path; ++ bool is_fail = true, reloaded[RTW8852A_DPK_RF_PATH] = {false}; ++ ++ if (dpk->is_dpk_reload_en) { ++ for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { ++ if (!(kpath & BIT(path))) ++ continue; ++ ++ reloaded[path] = _dpk_reload_check(rtwdev, phy, path); ++ if (!reloaded[path] && dpk->bp[path][0].ch != 0) ++ dpk->cur_idx[path] = !dpk->cur_idx[path]; ++ else ++ _dpk_onoff(rtwdev, path, false); ++ } ++ } else { ++ for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) ++ dpk->cur_idx[path] = 0; ++ } ++ ++ if ((kpath == RF_A && reloaded[RF_PATH_A]) || ++ (kpath == RF_B && reloaded[RF_PATH_B]) || ++ (kpath == RF_AB && reloaded[RF_PATH_A] && reloaded[RF_PATH_B])) ++ return; ++ ++ _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]); ++ ++ for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { ++ if (!(kpath & BIT(path)) || reloaded[path]) ++ continue; ++ if (rtwdev->is_tssi_mode[path]) ++ _dpk_tssi_pause(rtwdev, path, true); ++ _dpk_bkup_kip(rtwdev, kip_reg, kip_bkup, path); ++ _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path); ++ _dpk_information(rtwdev, phy, path); ++ } ++ ++ _dpk_bb_afe_setting(rtwdev, phy, path, kpath); ++ ++ for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { ++ if (!(kpath & BIT(path)) || reloaded[path]) ++ continue; ++ ++ is_fail = _dpk_main(rtwdev, phy, path, 1); ++ _dpk_onoff(rtwdev, path, is_fail); ++ } ++ ++ _dpk_bb_afe_restore(rtwdev, phy, path, kpath); ++ _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]); ++ ++ for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { ++ if (!(kpath & BIT(path)) || reloaded[path]) ++ continue; ++ ++ _dpk_kip_restore(rtwdev, path); ++ _dpk_reload_kip(rtwdev, kip_reg, kip_bkup, path); ++ _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path); ++ if (rtwdev->is_tssi_mode[path]) ++ _dpk_tssi_pause(rtwdev, path, false); ++ } ++} ++ ++static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ struct rtw89_fem_info *fem = &rtwdev->fem; ++ ++ if (fem->epa_2g && rtwdev->hal.current_band_type == RTW89_BAND_2G) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Skip DPK due to 2G_ext_PA exist!!\n"); ++ return true; ++ } else if (fem->epa_5g && rtwdev->hal.current_band_type == RTW89_BAND_5G) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] Skip DPK due to 5G_ext_PA exist!!\n"); ++ return true; ++ } ++ ++ return false; ++} ++ ++static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ u8 path, kpath; ++ ++ kpath = _kpath(rtwdev, phy); ++ ++ for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { ++ if (kpath & BIT(path)) ++ _dpk_onoff(rtwdev, path, true); ++ } ++} ++ ++static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force) ++{ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[DPK] ****** DPK Start (Ver: 0x%x, Cv: %d, RF_para: %d) ******\n", ++ RTW8852A_DPK_VER, rtwdev->hal.cv, ++ RTW8852A_RF_REL_VERSION); ++ ++ if (_dpk_bypass_check(rtwdev, phy)) ++ _dpk_force_bypass(rtwdev, phy); ++ else ++ _dpk_cal_select(rtwdev, force, phy, _kpath(rtwdev, phy)); ++} ++ ++static void _dpk_onoff(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path path, bool off) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ u8 val, kidx = dpk->cur_idx[path]; ++ ++ val = dpk->is_dpk_enable && !off && dpk->bp[path][kidx].path_ok; ++ ++ rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), ++ MASKBYTE3, 0x6 | val); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path, ++ kidx, dpk->is_dpk_enable && !off ? "enable" : "disable"); ++} ++ ++static void _dpk_track(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_dpk_info *dpk = &rtwdev->dpk; ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 path, kidx; ++ u8 trk_idx = 0, txagc_rf = 0; ++ s8 txagc_bb = 0, txagc_bb_tp = 0, ini_diff = 0, txagc_ofst = 0; ++ u16 pwsf[2]; ++ u8 cur_ther; ++ s8 delta_ther[2] = {0}; ++ ++ for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { ++ kidx = dpk->cur_idx[path]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, ++ "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n", ++ path, kidx, dpk->bp[path][kidx].ch); ++ ++ cur_ther = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, ++ "[DPK_TRK] thermal now = %d\n", cur_ther); ++ ++ if (dpk->bp[path][kidx].ch != 0 && cur_ther != 0) ++ delta_ther[path] = dpk->bp[path][kidx].ther_dpk - cur_ther; ++ ++ if (dpk->bp[path][kidx].band == RTW89_BAND_2G) ++ delta_ther[path] = delta_ther[path] * 3 / 2; ++ else ++ delta_ther[path] = delta_ther[path] * 5 / 2; ++ ++ txagc_rf = (u8)rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), ++ RR_MODOPT_M_TXPWR); ++ ++ if (rtwdev->is_tssi_mode[path]) { ++ trk_idx = (u8)rtw89_read_rf(rtwdev, path, RR_TXA, RR_TXA_TRK); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, ++ "[DPK_TRK] txagc_RF / track_idx = 0x%x / %d\n", ++ txagc_rf, trk_idx); ++ ++ txagc_bb = ++ (s8)rtw89_phy_read32_mask(rtwdev, ++ R_TXAGC_BB + (path << 13), ++ MASKBYTE2); ++ txagc_bb_tp = ++ (u8)rtw89_phy_read32_mask(rtwdev, ++ R_TXAGC_TP + (path << 13), ++ B_TXAGC_TP); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, ++ "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n", ++ txagc_bb_tp, txagc_bb); ++ ++ txagc_ofst = ++ (s8)rtw89_phy_read32_mask(rtwdev, ++ R_TXAGC_BB + (path << 13), ++ MASKBYTE3); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, ++ "[DPK_TRK] txagc_offset / delta_ther = %d / %d\n", ++ txagc_ofst, delta_ther[path]); ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_DPD_COM + (path << 8), ++ BIT(15)) == 0x1) ++ txagc_ofst = 0; ++ ++ if (txagc_rf != 0 && cur_ther != 0) ++ ini_diff = txagc_ofst + delta_ther[path]; ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_P0_TXDPD + (path << 13), ++ B_P0_TXDPD) == 0x0) { ++ pwsf[0] = dpk->bp[path][kidx].pwsf + txagc_bb_tp - ++ txagc_bb + ini_diff + ++ tssi_info->extra_ofst[path]; ++ pwsf[1] = dpk->bp[path][kidx].pwsf + txagc_bb_tp - ++ txagc_bb + ini_diff + ++ tssi_info->extra_ofst[path]; ++ } else { ++ pwsf[0] = dpk->bp[path][kidx].pwsf + ini_diff + ++ tssi_info->extra_ofst[path]; ++ pwsf[1] = dpk->bp[path][kidx].pwsf + ini_diff + ++ tssi_info->extra_ofst[path]; ++ } ++ ++ } else { ++ pwsf[0] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff; ++ pwsf[1] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff; ++ } ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_DPK_TRK, B_DPK_TRK_DIS) == 0x0 && ++ txagc_rf != 0) { ++ rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, ++ "[DPK_TRK] New pwsf[0] / pwsf[1] = 0x%x / 0x%x\n", ++ pwsf[0], pwsf[1]); ++ ++ rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), ++ 0x000001FF, pwsf[0]); ++ rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), ++ 0x01FF0000, pwsf[1]); ++ } ++ } ++} ++ ++static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ enum rtw89_band band = rtwdev->hal.current_band_type; ++ ++ if (band == RTW89_BAND_2G) ++ rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXG, 0x1); ++ else ++ rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXA, 0x1); ++} ++ ++static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ enum rtw89_band band = rtwdev->hal.current_band_type; ++ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_sys_defs_tbl); ++ rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, ++ &rtw8852a_tssi_sys_defs_2g_tbl, ++ &rtw8852a_tssi_sys_defs_5g_tbl); ++} ++ ++static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ enum rtw89_band band = rtwdev->hal.current_band_type; ++ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_txpwr_ctrl_bb_defs_a_tbl, ++ &rtw8852a_tssi_txpwr_ctrl_bb_defs_b_tbl); ++ rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, ++ &rtw8852a_tssi_txpwr_ctrl_bb_defs_2g_tbl, ++ &rtw8852a_tssi_txpwr_ctrl_bb_defs_5g_tbl); ++} ++ ++static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_a_tbl, ++ &rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_b_tbl); ++} ++ ++static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_dck_defs_a_tbl, ++ &rtw8852a_tssi_dck_defs_b_tbl); ++} ++ ++static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++#define __get_val(ptr, idx) \ ++({ \ ++ s8 *__ptr = (ptr); \ ++ u8 __idx = (idx), __i, __v; \ ++ u32 __val = 0; \ ++ for (__i = 0; __i < 4; __i++) { \ ++ __v = (__ptr[__idx + __i]); \ ++ __val |= (__v << (8 * __i)); \ ++ } \ ++ __val; \ ++}) ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 ch = rtwdev->hal.current_channel; ++ u8 subband = rtwdev->hal.current_subband; ++ const u8 *thm_up_a = NULL; ++ const u8 *thm_down_a = NULL; ++ const u8 *thm_up_b = NULL; ++ const u8 *thm_down_b = NULL; ++ u8 thermal = 0xff; ++ s8 thm_ofst[64] = {0}; ++ u32 tmp = 0; ++ u8 i, j; ++ ++ switch (subband) { ++ case RTW89_CH_2G: ++ thm_up_a = rtw89_8852a_trk_cfg.delta_swingidx_2ga_p; ++ thm_down_a = rtw89_8852a_trk_cfg.delta_swingidx_2ga_n; ++ thm_up_b = rtw89_8852a_trk_cfg.delta_swingidx_2gb_p; ++ thm_down_b = rtw89_8852a_trk_cfg.delta_swingidx_2gb_n; ++ break; ++ case RTW89_CH_5G_BAND_1: ++ thm_up_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_p[0]; ++ thm_down_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_n[0]; ++ thm_up_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_p[0]; ++ thm_down_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_n[0]; ++ break; ++ case RTW89_CH_5G_BAND_3: ++ thm_up_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_p[1]; ++ thm_down_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_n[1]; ++ thm_up_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_p[1]; ++ thm_down_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_n[1]; ++ break; ++ case RTW89_CH_5G_BAND_4: ++ thm_up_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_p[2]; ++ thm_down_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_n[2]; ++ thm_up_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_p[2]; ++ thm_down_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_n[2]; ++ break; ++ } ++ ++ if (path == RF_PATH_A) { ++ thermal = tssi_info->thermal[RF_PATH_A]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] ch=%d thermal_pathA=0x%x\n", ch, thermal); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, 0x1); ++ ++ if (thermal == 0xff) { ++ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, 32); ++ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 32); ++ ++ for (i = 0; i < 64; i += 4) { ++ rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, 0x0); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] write 0x%x val=0x%08x\n", ++ 0x5c00 + i, 0x0); ++ } ++ ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, thermal); ++ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, ++ thermal); ++ ++ i = 0; ++ for (j = 0; j < 32; j++) ++ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? ++ -thm_down_a[i++] : ++ -thm_down_a[DELTA_SWINGIDX_SIZE - 1]; ++ ++ i = 1; ++ for (j = 63; j >= 32; j--) ++ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? ++ thm_up_a[i++] : ++ thm_up_a[DELTA_SWINGIDX_SIZE - 1]; ++ ++ for (i = 0; i < 64; i += 4) { ++ tmp = __get_val(thm_ofst, i); ++ rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, tmp); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] write 0x%x val=0x%08x\n", ++ 0x5c00 + i, tmp); ++ } ++ } ++ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x0); ++ ++ } else { ++ thermal = tssi_info->thermal[RF_PATH_B]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] ch=%d thermal_pathB=0x%x\n", ch, thermal); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_DIS, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_TRK, 0x1); ++ ++ if (thermal == 0xff) { ++ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, 32); ++ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, 32); ++ ++ for (i = 0; i < 64; i += 4) { ++ rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, 0x0); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] write 0x%x val=0x%08x\n", ++ 0x7c00 + i, 0x0); ++ } ++ ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, thermal); ++ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, ++ thermal); ++ ++ i = 0; ++ for (j = 0; j < 32; j++) ++ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? ++ -thm_down_b[i++] : ++ -thm_down_b[DELTA_SWINGIDX_SIZE - 1]; ++ ++ i = 1; ++ for (j = 63; j >= 32; j--) ++ thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? ++ thm_up_b[i++] : ++ thm_up_b[DELTA_SWINGIDX_SIZE - 1]; ++ ++ for (i = 0; i < 64; i += 4) { ++ tmp = __get_val(thm_ofst, i); ++ rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, tmp); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] write 0x%x val=0x%08x\n", ++ 0x7c00 + i, tmp); ++ } ++ } ++ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x1); ++ rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x0); ++ } ++#undef __get_val ++} ++ ++static void _tssi_set_dac_gain_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_dac_gain_tbl_defs_a_tbl, ++ &rtw8852a_tssi_dac_gain_tbl_defs_b_tbl); ++} ++ ++static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_slope_cal_org_defs_a_tbl, ++ &rtw8852a_tssi_slope_cal_org_defs_b_tbl); ++} ++ ++static void _tssi_set_rf_gap_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_rf_gap_tbl_defs_a_tbl, ++ &rtw8852a_tssi_rf_gap_tbl_defs_b_tbl); ++} ++ ++static void _tssi_set_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_slope_defs_a_tbl, ++ &rtw8852a_tssi_slope_defs_b_tbl); ++} ++ ++static void _tssi_set_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_track_defs_a_tbl, ++ &rtw8852a_tssi_track_defs_b_tbl); ++} ++ ++static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_txagc_ofst_mv_avg_defs_a_tbl, ++ &rtw8852a_tssi_txagc_ofst_mv_avg_defs_b_tbl); ++} ++ ++static void _tssi_pak(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ u8 subband = rtwdev->hal.current_subband; ++ ++ switch (subband) { ++ case RTW89_CH_2G: ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_pak_defs_a_2g_tbl, ++ &rtw8852a_tssi_pak_defs_b_2g_tbl); ++ break; ++ case RTW89_CH_5G_BAND_1: ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_pak_defs_a_5g_1_tbl, ++ &rtw8852a_tssi_pak_defs_b_5g_1_tbl); ++ break; ++ case RTW89_CH_5G_BAND_3: ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_pak_defs_a_5g_3_tbl, ++ &rtw8852a_tssi_pak_defs_b_5g_3_tbl); ++ break; ++ case RTW89_CH_5G_BAND_4: ++ rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, ++ &rtw8852a_tssi_pak_defs_a_5g_4_tbl, ++ &rtw8852a_tssi_pak_defs_b_5g_4_tbl); ++ break; ++ } ++} ++ ++static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 i; ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ _tssi_set_track(rtwdev, phy, i); ++ _tssi_set_txagc_offset_mv_avg(rtwdev, phy, i); ++ ++ rtw89_rfk_parser_by_cond(rtwdev, i == RF_PATH_A, ++ &rtw8852a_tssi_enable_defs_a_tbl, ++ &rtw8852a_tssi_enable_defs_b_tbl); ++ ++ tssi_info->base_thermal[i] = ++ ewma_thermal_read(&rtwdev->phystat.avg_thermal[i]); ++ rtwdev->is_tssi_mode[i] = true; ++ } ++} ++ ++static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_disable_defs_tbl); ++ ++ rtwdev->is_tssi_mode[RF_PATH_A] = false; ++ rtwdev->is_tssi_mode[RF_PATH_B] = false; ++} ++ ++static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch) ++{ ++ switch (ch) { ++ case 1 ... 2: ++ return 0; ++ case 3 ... 5: ++ return 1; ++ case 6 ... 8: ++ return 2; ++ case 9 ... 11: ++ return 3; ++ case 12 ... 13: ++ return 4; ++ case 14: ++ return 5; ++ } ++ ++ return 0; ++} ++ ++#define TSSI_EXTRA_GROUP_BIT (BIT(31)) ++#define TSSI_EXTRA_GROUP(idx) (TSSI_EXTRA_GROUP_BIT | (idx)) ++#define IS_TSSI_EXTRA_GROUP(group) ((group) & TSSI_EXTRA_GROUP_BIT) ++#define TSSI_EXTRA_GET_GROUP_IDX1(group) ((group) & ~TSSI_EXTRA_GROUP_BIT) ++#define TSSI_EXTRA_GET_GROUP_IDX2(group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1) ++ ++static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) ++{ ++ switch (ch) { ++ case 1 ... 2: ++ return 0; ++ case 3 ... 5: ++ return 1; ++ case 6 ... 8: ++ return 2; ++ case 9 ... 11: ++ return 3; ++ case 12 ... 14: ++ return 4; ++ case 36 ... 40: ++ return 5; ++ case 41 ... 43: ++ return TSSI_EXTRA_GROUP(5); ++ case 44 ... 48: ++ return 6; ++ case 49 ... 51: ++ return TSSI_EXTRA_GROUP(6); ++ case 52 ... 56: ++ return 7; ++ case 57 ... 59: ++ return TSSI_EXTRA_GROUP(7); ++ case 60 ... 64: ++ return 8; ++ case 100 ... 104: ++ return 9; ++ case 105 ... 107: ++ return TSSI_EXTRA_GROUP(9); ++ case 108 ... 112: ++ return 10; ++ case 113 ... 115: ++ return TSSI_EXTRA_GROUP(10); ++ case 116 ... 120: ++ return 11; ++ case 121 ... 123: ++ return TSSI_EXTRA_GROUP(11); ++ case 124 ... 128: ++ return 12; ++ case 129 ... 131: ++ return TSSI_EXTRA_GROUP(12); ++ case 132 ... 136: ++ return 13; ++ case 137 ... 139: ++ return TSSI_EXTRA_GROUP(13); ++ case 140 ... 144: ++ return 14; ++ case 149 ... 153: ++ return 15; ++ case 154 ... 156: ++ return TSSI_EXTRA_GROUP(15); ++ case 157 ... 161: ++ return 16; ++ case 162 ... 164: ++ return TSSI_EXTRA_GROUP(16); ++ case 165 ... 169: ++ return 17; ++ case 170 ... 172: ++ return TSSI_EXTRA_GROUP(17); ++ case 173 ... 177: ++ return 18; ++ } ++ ++ return 0; ++} ++ ++static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch) ++{ ++ switch (ch) { ++ case 1 ... 8: ++ return 0; ++ case 9 ... 14: ++ return 1; ++ case 36 ... 48: ++ return 2; ++ case 52 ... 64: ++ return 3; ++ case 100 ... 112: ++ return 4; ++ case 116 ... 128: ++ return 5; ++ case 132 ... 144: ++ return 6; ++ case 149 ... 177: ++ return 7; ++ } ++ ++ return 0; ++} ++ ++static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 ch = rtwdev->hal.current_channel; ++ u32 gidx, gidx_1st, gidx_2nd; ++ s8 de_1st = 0; ++ s8 de_2nd = 0; ++ s8 val; ++ ++ gidx = _tssi_get_ofdm_group(rtwdev, ch); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", ++ path, gidx); ++ ++ if (IS_TSSI_EXTRA_GROUP(gidx)) { ++ gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); ++ gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); ++ de_1st = tssi_info->tssi_mcs[path][gidx_1st]; ++ de_2nd = tssi_info->tssi_mcs[path][gidx_2nd]; ++ val = (de_1st + de_2nd) / 2; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", ++ path, val, de_1st, de_2nd); ++ } else { ++ val = tssi_info->tssi_mcs[path][gidx]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); ++ } ++ ++ return val; ++} ++ ++static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 ch = rtwdev->hal.current_channel; ++ u32 tgidx, tgidx_1st, tgidx_2nd; ++ s8 tde_1st = 0; ++ s8 tde_2nd = 0; ++ s8 val; ++ ++ tgidx = _tssi_get_trim_group(rtwdev, ch); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", ++ path, tgidx); ++ ++ if (IS_TSSI_EXTRA_GROUP(tgidx)) { ++ tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); ++ tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); ++ tde_1st = tssi_info->tssi_trim[path][tgidx_1st]; ++ tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd]; ++ val = (tde_1st + tde_2nd) / 2; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", ++ path, val, tde_1st, tde_2nd); ++ } else { ++ val = tssi_info->tssi_trim[path][tgidx]; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", ++ path, val); ++ } ++ ++ return val; ++} ++ ++static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy) ++{ ++#define __DE_MASK 0x003ff000 ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ static const u32 r_cck_long[RF_PATH_NUM_8852A] = {0x5858, 0x7858}; ++ static const u32 r_cck_short[RF_PATH_NUM_8852A] = {0x5860, 0x7860}; ++ static const u32 r_mcs_20m[RF_PATH_NUM_8852A] = {0x5838, 0x7838}; ++ static const u32 r_mcs_40m[RF_PATH_NUM_8852A] = {0x5840, 0x7840}; ++ static const u32 r_mcs_80m[RF_PATH_NUM_8852A] = {0x5848, 0x7848}; ++ static const u32 r_mcs_80m_80m[RF_PATH_NUM_8852A] = {0x5850, 0x7850}; ++ static const u32 r_mcs_5m[RF_PATH_NUM_8852A] = {0x5828, 0x7828}; ++ static const u32 r_mcs_10m[RF_PATH_NUM_8852A] = {0x5830, 0x7830}; ++ u8 ch = rtwdev->hal.current_channel; ++ u8 i, gidx; ++ s8 ofdm_de; ++ s8 trim_de; ++ s32 val; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n", ++ phy, ch); ++ ++ for (i = 0; i < RF_PATH_NUM_8852A; i++) { ++ gidx = _tssi_get_cck_group(rtwdev, ch); ++ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i); ++ val = tssi_info->tssi_cck[i][gidx] + trim_de; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n", ++ i, gidx, tssi_info->tssi_cck[i][gidx], trim_de); ++ ++ rtw89_phy_write32_mask(rtwdev, r_cck_long[i], __DE_MASK, val); ++ rtw89_phy_write32_mask(rtwdev, r_cck_short[i], __DE_MASK, val); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n", ++ r_cck_long[i], ++ rtw89_phy_read32_mask(rtwdev, r_cck_long[i], ++ __DE_MASK)); ++ ++ ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i); ++ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i); ++ val = ofdm_de + trim_de; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n", ++ i, ofdm_de, trim_de); ++ ++ rtw89_phy_write32_mask(rtwdev, r_mcs_20m[i], __DE_MASK, val); ++ rtw89_phy_write32_mask(rtwdev, r_mcs_40m[i], __DE_MASK, val); ++ rtw89_phy_write32_mask(rtwdev, r_mcs_80m[i], __DE_MASK, val); ++ rtw89_phy_write32_mask(rtwdev, r_mcs_80m_80m[i], __DE_MASK, val); ++ rtw89_phy_write32_mask(rtwdev, r_mcs_5m[i], __DE_MASK, val); ++ rtw89_phy_write32_mask(rtwdev, r_mcs_10m[i], __DE_MASK, val); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n", ++ r_mcs_20m[i], ++ rtw89_phy_read32_mask(rtwdev, r_mcs_20m[i], ++ __DE_MASK)); ++ } ++#undef __DE_MASK ++} ++ ++static void _tssi_track(struct rtw89_dev *rtwdev) ++{ ++ static const u32 tx_gain_scale_table[] = { ++ 0x400, 0x40e, 0x41d, 0x427, 0x43c, 0x44c, 0x45c, 0x46c, ++ 0x400, 0x39d, 0x3ab, 0x3b8, 0x3c6, 0x3d4, 0x3e2, 0x3f1 ++ }; ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 path; ++ u8 cur_ther; ++ s32 delta_ther = 0, gain_offset_int, gain_offset_float; ++ s8 gain_offset; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRK] %s:\n", ++ __func__); ++ ++ if (!rtwdev->is_tssi_mode[RF_PATH_A]) ++ return; ++ if (!rtwdev->is_tssi_mode[RF_PATH_B]) ++ return; ++ ++ for (path = RF_PATH_A; path < RF_PATH_NUM_8852A; path++) { ++ if (!tssi_info->tssi_tracking_check[path]) { ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRK] return!!!\n"); ++ continue; ++ } ++ ++ cur_ther = (u8)rtw89_phy_read32_mask(rtwdev, ++ R_TSSI_THER + (path << 13), ++ B_TSSI_THER); ++ ++ if (cur_ther == 0 || tssi_info->base_thermal[path] == 0) ++ continue; ++ ++ delta_ther = cur_ther - tssi_info->base_thermal[path]; ++ ++ gain_offset = (s8)delta_ther * 15 / 10; ++ ++ tssi_info->extra_ofst[path] = gain_offset; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI][TRK] base_thermal=%d gain_offset=0x%x path=%d\n", ++ tssi_info->base_thermal[path], gain_offset, path); ++ ++ gain_offset_int = gain_offset >> 3; ++ gain_offset_float = gain_offset & 7; ++ ++ if (gain_offset_int > 15) ++ gain_offset_int = 15; ++ else if (gain_offset_int < -16) ++ gain_offset_int = -16; ++ ++ rtw89_phy_write32_mask(rtwdev, R_DPD_OFT_EN + (path << 13), ++ B_DPD_OFT_EN, 0x1); ++ ++ rtw89_phy_write32_mask(rtwdev, R_TXGAIN_SCALE + (path << 13), ++ B_TXGAIN_SCALE_EN, 0x1); ++ ++ rtw89_phy_write32_mask(rtwdev, R_DPD_OFT_ADDR + (path << 13), ++ B_DPD_OFT_ADDR, gain_offset_int); ++ ++ rtw89_phy_write32_mask(rtwdev, R_TXGAIN_SCALE + (path << 13), ++ B_TXGAIN_SCALE_OFT, ++ tx_gain_scale_table[gain_offset_float]); ++ } ++} ++ ++static void _tssi_high_power(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 ch = rtwdev->hal.current_channel, ch_tmp; ++ u8 bw = rtwdev->hal.current_band_width; ++ u8 subband = rtwdev->hal.current_subband; ++ s8 power; ++ s32 xdbm; ++ ++ if (bw == RTW89_CHANNEL_WIDTH_40) ++ ch_tmp = ch - 2; ++ else if (bw == RTW89_CHANNEL_WIDTH_80) ++ ch_tmp = ch - 6; ++ else ++ ch_tmp = ch; ++ ++ power = rtw89_phy_read_txpwr_limit(rtwdev, bw, RTW89_1TX, ++ RTW89_RS_MCS, RTW89_NONBF, ch_tmp); ++ ++ xdbm = power * 100 / 4; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d xdbm=%d\n", ++ __func__, phy, xdbm); ++ ++ if (xdbm > 1800 && subband == RTW89_CH_2G) { ++ tssi_info->tssi_tracking_check[RF_PATH_A] = true; ++ tssi_info->tssi_tracking_check[RF_PATH_B] = true; ++ } else { ++ rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_tracking_defs_tbl); ++ tssi_info->extra_ofst[RF_PATH_A] = 0; ++ tssi_info->extra_ofst[RF_PATH_B] = 0; ++ tssi_info->tssi_tracking_check[RF_PATH_A] = false; ++ tssi_info->tssi_tracking_check[RF_PATH_B] = false; ++ } ++} ++ ++static void _tssi_hw_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ u8 path, s16 pwr_dbm, u8 enable) ++{ ++ rtw8852a_bb_set_plcp_tx(rtwdev); ++ rtw8852a_bb_cfg_tx_path(rtwdev, path); ++ rtw8852a_bb_set_power(rtwdev, pwr_dbm, phy); ++ rtw8852a_bb_set_pmac_pkt_tx(rtwdev, enable, 20, 5000, 0, phy); ++} ++ ++static void _tssi_pre_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ const struct rtw89_chip_info *mac_reg = rtwdev->chip; ++ u8 ch = rtwdev->hal.current_channel, ch_tmp; ++ u8 bw = rtwdev->hal.current_band_width; ++ u16 tx_en; ++ u8 phy_map = rtw89_btc_phymap(rtwdev, phy, 0); ++ s8 power; ++ s16 xdbm; ++ u32 i, tx_counter = 0; ++ ++ if (bw == RTW89_CHANNEL_WIDTH_40) ++ ch_tmp = ch - 2; ++ else if (bw == RTW89_CHANNEL_WIDTH_80) ++ ch_tmp = ch - 6; ++ else ++ ch_tmp = ch; ++ ++ power = rtw89_phy_read_txpwr_limit(rtwdev, RTW89_CHANNEL_WIDTH_20, RTW89_1TX, ++ RTW89_RS_OFDM, RTW89_NONBF, ch_tmp); ++ ++ xdbm = (power * 100) >> mac_reg->txpwr_factor_mac; ++ ++ if (xdbm > 1800) ++ xdbm = 68; ++ else ++ xdbm = power * 2; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] %s: phy=%d org_power=%d xdbm=%d\n", ++ __func__, phy, power, xdbm); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START); ++ rtw89_mac_stop_sch_tx(rtwdev, phy, &tx_en, RTW89_SCH_TX_SEL_ALL); ++ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy)); ++ tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); ++ ++ _tssi_hw_tx(rtwdev, phy, RF_PATH_AB, xdbm, true); ++ mdelay(15); ++ _tssi_hw_tx(rtwdev, phy, RF_PATH_AB, xdbm, false); ++ ++ tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD) - ++ tx_counter; ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, MASKHWORD) != 0xc000 && ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, MASKHWORD) != 0x0) { ++ for (i = 0; i < 6; i++) { ++ tssi_info->default_txagc_offset[RF_PATH_A] = ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, ++ MASKBYTE3); ++ ++ if (tssi_info->default_txagc_offset[RF_PATH_A] != 0x0) ++ break; ++ } ++ } ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, MASKHWORD) != 0xc000 && ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, MASKHWORD) != 0x0) { ++ for (i = 0; i < 6; i++) { ++ tssi_info->default_txagc_offset[RF_PATH_B] = ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, ++ MASKBYTE3); ++ ++ if (tssi_info->default_txagc_offset[RF_PATH_B] != 0x0) ++ break; ++ } ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] %s: tx counter=%d\n", ++ __func__, tx_counter); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, ++ "[TSSI] Backup R_TXAGC_BB=0x%x R_TXAGC_BB_S1=0x%x\n", ++ tssi_info->default_txagc_offset[RF_PATH_A], ++ tssi_info->default_txagc_offset[RF_PATH_B]); ++ ++ rtw8852a_bb_tx_mode_switch(rtwdev, phy, 0); ++ ++ rtw89_mac_resume_sch_tx(rtwdev, phy, tx_en); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP); ++} ++ ++void rtw8852a_rck(struct rtw89_dev *rtwdev) ++{ ++ u8 path; ++ ++ for (path = 0; path < 2; path++) ++ _rck(rtwdev, path); ++} ++ ++void rtw8852a_dack(struct rtw89_dev *rtwdev) ++{ ++ u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_START); ++ _dac_cal(rtwdev, false); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP); ++} ++ ++void rtw8852a_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) ++{ ++ u16 tx_en; ++ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START); ++ rtw89_mac_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); ++ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); ++ ++ _iqk_init(rtwdev); ++ if (rtwdev->dbcc_en) ++ _iqk_dbcc(rtwdev, phy_idx); ++ else ++ _iqk(rtwdev, phy_idx, false); ++ ++ rtw89_mac_resume_sch_tx(rtwdev, phy_idx, tx_en); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP); ++} ++ ++void rtw8852a_iqk_track(struct rtw89_dev *rtwdev) ++{ ++ _iqk_track(rtwdev); ++} ++ ++void rtw8852a_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, ++ bool is_afe) ++{ ++ u16 tx_en; ++ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START); ++ rtw89_mac_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); ++ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); ++ ++ _rx_dck(rtwdev, phy_idx, is_afe); ++ ++ rtw89_mac_resume_sch_tx(rtwdev, phy_idx, tx_en); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); ++} ++ ++void rtw8852a_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) ++{ ++ u16 tx_en; ++ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START); ++ rtw89_mac_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); ++ _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); ++ ++ rtwdev->dpk.is_dpk_enable = true; ++ rtwdev->dpk.is_dpk_reload_en = false; ++ _dpk(rtwdev, phy_idx, false); ++ ++ rtw89_mac_resume_sch_tx(rtwdev, phy_idx, tx_en); ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP); ++} ++ ++void rtw8852a_dpk_track(struct rtw89_dev *rtwdev) ++{ ++ _dpk_track(rtwdev); ++} ++ ++void rtw8852a_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ u8 i; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", ++ __func__, phy); ++ ++ _tssi_disable(rtwdev, phy); ++ ++ for (i = RF_PATH_A; i < RF_PATH_NUM_8852A; i++) { ++ _tssi_rf_setting(rtwdev, phy, i); ++ _tssi_set_sys(rtwdev, phy); ++ _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i); ++ _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i); ++ _tssi_set_dck(rtwdev, phy, i); ++ _tssi_set_tmeter_tbl(rtwdev, phy, i); ++ _tssi_set_dac_gain_tbl(rtwdev, phy, i); ++ _tssi_slope_cal_org(rtwdev, phy, i); ++ _tssi_set_rf_gap_tbl(rtwdev, phy, i); ++ _tssi_set_slope(rtwdev, phy, i); ++ _tssi_pak(rtwdev, phy, i); ++ } ++ ++ _tssi_enable(rtwdev, phy); ++ _tssi_set_efuse_to_de(rtwdev, phy); ++ _tssi_high_power(rtwdev, phy); ++ _tssi_pre_tx(rtwdev, phy); ++} ++ ++void rtw8852a_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ u8 i; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", ++ __func__, phy); ++ ++ if (!rtwdev->is_tssi_mode[RF_PATH_A]) ++ return; ++ if (!rtwdev->is_tssi_mode[RF_PATH_B]) ++ return; ++ ++ _tssi_disable(rtwdev, phy); ++ ++ for (i = RF_PATH_A; i < RF_PATH_NUM_8852A; i++) { ++ _tssi_rf_setting(rtwdev, phy, i); ++ _tssi_set_sys(rtwdev, phy); ++ _tssi_set_tmeter_tbl(rtwdev, phy, i); ++ _tssi_pak(rtwdev, phy, i); ++ } ++ ++ _tssi_enable(rtwdev, phy); ++ _tssi_set_efuse_to_de(rtwdev, phy); ++} ++ ++void rtw8852a_tssi_track(struct rtw89_dev *rtwdev) ++{ ++ _tssi_track(rtwdev); ++} ++ ++static ++void _rtw8852a_tssi_avg_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) ++ return; ++ ++ /* disable */ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_disable_defs_tbl); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_AVG, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_AVG, 0x0); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_AVG, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_AVG, 0x0); ++ ++ /* enable */ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_enable_defs_ab_tbl); ++} ++ ++static ++void _rtw8852a_tssi_set_avg(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) ++{ ++ if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) ++ return; ++ ++ /* disable */ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_disable_defs_tbl); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_AVG, 0x4); ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_AVG, 0x2); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_AVG, 0x4); ++ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_AVG, 0x2); ++ ++ /* enable */ ++ rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_enable_defs_ab_tbl); ++} ++ ++static void rtw8852a_tssi_set_avg(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, bool enable) ++{ ++ if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) ++ return; ++ ++ if (enable) { ++ /* SCAN_START */ ++ _rtw8852a_tssi_avg_scan(rtwdev, phy); ++ } else { ++ /* SCAN_END */ ++ _rtw8852a_tssi_set_avg(rtwdev, phy); ++ } ++} ++ ++static void rtw8852a_tssi_default_txagc(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, bool enable) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ u8 i; ++ ++ if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) ++ return; ++ ++ if (enable) { ++ if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, B_TXAGC_BB_OFT) != 0xc000 && ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, B_TXAGC_BB_OFT) != 0x0) { ++ for (i = 0; i < 6; i++) { ++ tssi_info->default_txagc_offset[RF_PATH_A] = ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, ++ B_TXAGC_BB); ++ if (tssi_info->default_txagc_offset[RF_PATH_A]) ++ break; ++ } ++ } ++ ++ if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, B_TXAGC_BB_S1_OFT) != 0xc000 && ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, B_TXAGC_BB_S1_OFT) != 0x0) { ++ for (i = 0; i < 6; i++) { ++ tssi_info->default_txagc_offset[RF_PATH_B] = ++ rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, ++ B_TXAGC_BB_S1); ++ if (tssi_info->default_txagc_offset[RF_PATH_B]) ++ break; ++ } ++ } ++ } else { ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, ++ tssi_info->default_txagc_offset[RF_PATH_A]); ++ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT, ++ tssi_info->default_txagc_offset[RF_PATH_B]); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); ++ ++ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x0); ++ rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x1); ++ } ++} ++ ++void rtw8852a_wifi_scan_notify(struct rtw89_dev *rtwdev, ++ bool scan_start, enum rtw89_phy_idx phy_idx) ++{ ++ if (scan_start) { ++ rtw8852a_tssi_default_txagc(rtwdev, phy_idx, true); ++ rtw8852a_tssi_set_avg(rtwdev, phy_idx, true); ++ } else { ++ rtw8852a_tssi_default_txagc(rtwdev, phy_idx, false); ++ rtw8852a_tssi_set_avg(rtwdev, phy_idx, false); ++ } ++} +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h +new file mode 100644 +index 000000000000..ea36553a76b7 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.h +@@ -0,0 +1,24 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_8852A_RFK_H__ ++#define __RTW89_8852A_RFK_H__ ++ ++#include "core.h" ++ ++void rtw8852a_rck(struct rtw89_dev *rtwdev); ++void rtw8852a_dack(struct rtw89_dev *rtwdev); ++void rtw8852a_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); ++void rtw8852a_iqk_track(struct rtw89_dev *rtwdev); ++void rtw8852a_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, ++ bool is_afe); ++void rtw8852a_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); ++void rtw8852a_dpk_track(struct rtw89_dev *rtwdev); ++void rtw8852a_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); ++void rtw8852a_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); ++void rtw8852a_tssi_track(struct rtw89_dev *rtwdev); ++void rtw8852a_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, ++ enum rtw89_phy_idx phy_idx); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.c +new file mode 100644 +index 000000000000..510570090502 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.c +@@ -0,0 +1,1607 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "rtw8852a_rfk_table.h" ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_sys_defs[] = { ++ DECL_RFK_WM(0x12a8, 0x00000001, 0x00000001), ++ DECL_RFK_WM(0x12a8, 0x0000000e, 0x00000002), ++ DECL_RFK_WM(0x32a8, 0x00000001, 0x00000001), ++ DECL_RFK_WM(0x32a8, 0x0000000e, 0x00000002), ++ DECL_RFK_WM(0x12bc, 0x000000f0, 0x00000005), ++ DECL_RFK_WM(0x12bc, 0x00000f00, 0x00000005), ++ DECL_RFK_WM(0x12bc, 0x000f0000, 0x00000005), ++ DECL_RFK_WM(0x12bc, 0x0000f000, 0x00000005), ++ DECL_RFK_WM(0x120c, 0x000000ff, 0x00000033), ++ DECL_RFK_WM(0x12c0, 0x0ff00000, 0x00000033), ++ DECL_RFK_WM(0x32bc, 0x000000f0, 0x00000005), ++ DECL_RFK_WM(0x32bc, 0x00000f00, 0x00000005), ++ DECL_RFK_WM(0x32bc, 0x000f0000, 0x00000005), ++ DECL_RFK_WM(0x32bc, 0x0000f000, 0x00000005), ++ DECL_RFK_WM(0x320c, 0x000000ff, 0x00000033), ++ DECL_RFK_WM(0x32c0, 0x0ff00000, 0x00000033), ++ DECL_RFK_WM(0x0300, 0xff000000, 0x00000019), ++ DECL_RFK_WM(0x0304, 0x000000ff, 0x00000019), ++ DECL_RFK_WM(0x0304, 0x0000ff00, 0x0000001d), ++ DECL_RFK_WM(0x0314, 0xffff0000, 0x00002044), ++ DECL_RFK_WM(0x0318, 0x0000ffff, 0x00002042), ++ DECL_RFK_WM(0x0318, 0xffff0000, 0x00002002), ++ DECL_RFK_WM(0x0020, 0x00006000, 0x00000003), ++ DECL_RFK_WM(0x0024, 0x00006000, 0x00000003), ++ DECL_RFK_WM(0x0704, 0xffff0000, 0x0000601e), ++ DECL_RFK_WM(0x2704, 0xffff0000, 0x0000601e), ++ DECL_RFK_WM(0x0700, 0xf0000000, 0x00000004), ++ DECL_RFK_WM(0x2700, 0xf0000000, 0x00000004), ++ DECL_RFK_WM(0x0650, 0x3c000000, 0x00000000), ++ DECL_RFK_WM(0x2650, 0x3c000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_sys_defs); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_sys_defs_2g[] = { ++ DECL_RFK_WM(0x120c, 0x000000ff, 0x00000033), ++ DECL_RFK_WM(0x12c0, 0x0ff00000, 0x00000033), ++ DECL_RFK_WM(0x32c0, 0x0ff00000, 0x00000033), ++ DECL_RFK_WM(0x320c, 0x000000ff, 0x00000033), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_sys_defs_2g); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_sys_defs_5g[] = { ++ DECL_RFK_WM(0x120c, 0x000000ff, 0x00000044), ++ DECL_RFK_WM(0x12c0, 0x0ff00000, 0x00000044), ++ DECL_RFK_WM(0x32c0, 0x0ff00000, 0x00000044), ++ DECL_RFK_WM(0x320c, 0x000000ff, 0x00000044), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_sys_defs_5g); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_defs_a[] = { ++ DECL_RFK_WM(0x5800, 0x000000ff, 0x0000007f), ++ DECL_RFK_WM(0x5800, 0x0000ff00, 0x00000080), ++ DECL_RFK_WM(0x5800, 0x003f0000, 0x0000003f), ++ DECL_RFK_WM(0x5800, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x5800, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x5800, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x5804, 0xf8000000, 0x00000000), ++ DECL_RFK_WM(0x580c, 0x0000007f, 0x00000040), ++ DECL_RFK_WM(0x580c, 0x00007f00, 0x00000040), ++ DECL_RFK_WM(0x580c, 0x00008000, 0x00000000), ++ DECL_RFK_WM(0x580c, 0x0fff0000, 0x00000000), ++ DECL_RFK_WM(0x5810, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x5810, 0x00000200, 0x00000000), ++ DECL_RFK_WM(0x5810, 0x0000fc00, 0x00000000), ++ DECL_RFK_WM(0x5810, 0x00010000, 0x00000001), ++ DECL_RFK_WM(0x5810, 0x00fe0000, 0x00000000), ++ DECL_RFK_WM(0x5810, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x5810, 0x06000000, 0x00000000), ++ DECL_RFK_WM(0x5810, 0x38000000, 0x00000003), ++ DECL_RFK_WM(0x5810, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x5810, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x00000c00, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x00001000, 0x00000001), ++ DECL_RFK_WM(0x5814, 0x00002000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x00004000, 0x00000001), ++ DECL_RFK_WM(0x5814, 0x00038000, 0x00000005), ++ DECL_RFK_WM(0x5814, 0x003c0000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x01c00000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x18000000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0xe0000000, 0x00000000), ++ DECL_RFK_WM(0x5818, 0x000000ff, 0x00000000), ++ DECL_RFK_WM(0x5818, 0x0001ff00, 0x00000018), ++ DECL_RFK_WM(0x5818, 0x03fe0000, 0x00000016), ++ DECL_RFK_WM(0x5818, 0xfc000000, 0x00000000), ++ DECL_RFK_WM(0x581c, 0x000003ff, 0x00000280), ++ DECL_RFK_WM(0x581c, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x581c, 0x00100000, 0x00000000), ++ DECL_RFK_WM(0x581c, 0x01e00000, 0x00000008), ++ DECL_RFK_WM(0x581c, 0x01e00000, 0x0000000e), ++ DECL_RFK_WM(0x581c, 0x1e000000, 0x00000008), ++ DECL_RFK_WM(0x581c, 0x1e000000, 0x0000000e), ++ DECL_RFK_WM(0x581c, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x5820, 0x00000fff, 0x00000080), ++ DECL_RFK_WM(0x5820, 0x0000f000, 0x0000000f), ++ DECL_RFK_WM(0x5820, 0x001f0000, 0x00000000), ++ DECL_RFK_WM(0x5820, 0xffe00000, 0x00000000), ++ DECL_RFK_WM(0x5824, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5824, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5828, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x582c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x582c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5830, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5834, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5834, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5838, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x583c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x583c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5840, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5844, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5844, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5848, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x584c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x584c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5850, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5854, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5854, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5858, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x585c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x585c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5860, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5828, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5828, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5830, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5830, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5838, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5838, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5840, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5840, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5848, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5848, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5850, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5850, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5858, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5858, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5860, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5860, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x5860, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x5864, 0x000003ff, 0x000001ff), ++ DECL_RFK_WM(0x5864, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x5864, 0x03f00000, 0x00000000), ++ DECL_RFK_WM(0x5864, 0x04000000, 0x00000000), ++ DECL_RFK_WM(0x5898, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x589c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x58a0, 0x000000ff, 0x000000fd), ++ DECL_RFK_WM(0x58a0, 0x0000ff00, 0x000000e5), ++ DECL_RFK_WM(0x58a0, 0x00ff0000, 0x000000cd), ++ DECL_RFK_WM(0x58a0, 0xff000000, 0x000000b5), ++ DECL_RFK_WM(0x58a4, 0x000000ff, 0x00000016), ++ DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x03fe0000, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x58b0, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x58b4, 0x0000001f, 0x00000000), ++ DECL_RFK_WM(0x58b4, 0x00000020, 0x00000000), ++ DECL_RFK_WM(0x58b4, 0x000001c0, 0x00000000), ++ DECL_RFK_WM(0x58b4, 0x00000200, 0x00000000), ++ DECL_RFK_WM(0x58b4, 0x0000f000, 0x00000002), ++ DECL_RFK_WM(0x58b4, 0x00ff0000, 0x00000000), ++ DECL_RFK_WM(0x58b4, 0x7f000000, 0x0000000a), ++ DECL_RFK_WM(0x58b8, 0x0000007f, 0x00000028), ++ DECL_RFK_WM(0x58b8, 0x00007f00, 0x00000076), ++ DECL_RFK_WM(0x58b8, 0x007f0000, 0x00000000), ++ DECL_RFK_WM(0x58b8, 0x7f000000, 0x00000000), ++ DECL_RFK_WM(0x58bc, 0x000000ff, 0x0000007f), ++ DECL_RFK_WM(0x58bc, 0x0000ff00, 0x00000080), ++ DECL_RFK_WM(0x58bc, 0x00030000, 0x00000003), ++ DECL_RFK_WM(0x58bc, 0x000c0000, 0x00000001), ++ DECL_RFK_WM(0x58bc, 0x00300000, 0x00000002), ++ DECL_RFK_WM(0x58bc, 0x00c00000, 0x00000002), ++ DECL_RFK_WM(0x58bc, 0x07000000, 0x00000007), ++ DECL_RFK_WM(0x58c0, 0x00fe0000, 0x0000003f), ++ DECL_RFK_WM(0x58c0, 0xff000000, 0x00000000), ++ DECL_RFK_WM(0x58c4, 0x0003ffff, 0x0003ffff), ++ DECL_RFK_WM(0x58c4, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x58c4, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x58c8, 0x00ffffff, 0x00000000), ++ DECL_RFK_WM(0x58c8, 0xf0000000, 0x00000000), ++ DECL_RFK_WM(0x58cc, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x58d0, 0x00001fff, 0x00000101), ++ DECL_RFK_WM(0x58d0, 0x0001e000, 0x00000004), ++ DECL_RFK_WM(0x58d0, 0x03fe0000, 0x00000100), ++ DECL_RFK_WM(0x58d0, 0x04000000, 0x00000000), ++ DECL_RFK_WM(0x58d4, 0x000000ff, 0x00000000), ++ DECL_RFK_WM(0x58d4, 0x0003fe00, 0x000000ff), ++ DECL_RFK_WM(0x58d4, 0x07fc0000, 0x00000100), ++ DECL_RFK_WM(0x58d8, 0x000001ff, 0x0000016c), ++ DECL_RFK_WM(0x58d8, 0x0003fe00, 0x0000005c), ++ DECL_RFK_WM(0x58d8, 0x000c0000, 0x00000002), ++ DECL_RFK_WM(0x58d8, 0xfff00000, 0x00000800), ++ DECL_RFK_WM(0x58dc, 0x000000ff, 0x0000007f), ++ DECL_RFK_WM(0x58dc, 0x0000ff00, 0x00000080), ++ DECL_RFK_WM(0x58dc, 0x00010000, 0x00000000), ++ DECL_RFK_WM(0x58dc, 0x3ff00000, 0x00000000), ++ DECL_RFK_WM(0x58dc, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x58f0, 0x000001ff, 0x000001ff), ++ DECL_RFK_WM(0x58f0, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_defs_b[] = { ++ DECL_RFK_WM(0x7800, 0x000000ff, 0x0000007f), ++ DECL_RFK_WM(0x7800, 0x0000ff00, 0x00000080), ++ DECL_RFK_WM(0x7800, 0x003f0000, 0x0000003f), ++ DECL_RFK_WM(0x7800, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x7800, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x7800, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x7804, 0xf8000000, 0x00000000), ++ DECL_RFK_WM(0x780c, 0x0000007f, 0x00000040), ++ DECL_RFK_WM(0x780c, 0x00007f00, 0x00000040), ++ DECL_RFK_WM(0x780c, 0x00008000, 0x00000000), ++ DECL_RFK_WM(0x780c, 0x0fff0000, 0x00000000), ++ DECL_RFK_WM(0x7810, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x7810, 0x00000200, 0x00000000), ++ DECL_RFK_WM(0x7810, 0x0000fc00, 0x00000000), ++ DECL_RFK_WM(0x7810, 0x00010000, 0x00000001), ++ DECL_RFK_WM(0x7810, 0x00fe0000, 0x00000000), ++ DECL_RFK_WM(0x7810, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x7810, 0x06000000, 0x00000000), ++ DECL_RFK_WM(0x7810, 0x38000000, 0x00000003), ++ DECL_RFK_WM(0x7810, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x7810, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x00000c00, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x00001000, 0x00000001), ++ DECL_RFK_WM(0x7814, 0x00002000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x00004000, 0x00000001), ++ DECL_RFK_WM(0x7814, 0x00038000, 0x00000005), ++ DECL_RFK_WM(0x7814, 0x003c0000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x01c00000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x18000000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0xe0000000, 0x00000000), ++ DECL_RFK_WM(0x7818, 0x000000ff, 0x00000000), ++ DECL_RFK_WM(0x7818, 0x0001ff00, 0x00000018), ++ DECL_RFK_WM(0x7818, 0x03fe0000, 0x00000016), ++ DECL_RFK_WM(0x7818, 0xfc000000, 0x00000000), ++ DECL_RFK_WM(0x781c, 0x000003ff, 0x00000280), ++ DECL_RFK_WM(0x781c, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x781c, 0x00100000, 0x00000000), ++ DECL_RFK_WM(0x781c, 0x01e00000, 0x00000008), ++ DECL_RFK_WM(0x781c, 0x01e00000, 0x0000000e), ++ DECL_RFK_WM(0x781c, 0x1e000000, 0x00000008), ++ DECL_RFK_WM(0x781c, 0x1e000000, 0x0000000e), ++ DECL_RFK_WM(0x781c, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x7820, 0x00000fff, 0x00000080), ++ DECL_RFK_WM(0x7820, 0x0000f000, 0x00000000), ++ DECL_RFK_WM(0x7820, 0x001f0000, 0x00000000), ++ DECL_RFK_WM(0x7820, 0xffe00000, 0x00000000), ++ DECL_RFK_WM(0x7824, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7824, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7828, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x782c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x782c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7830, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7834, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7834, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7838, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x783c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x783c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7840, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7844, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7844, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7848, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x784c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x784c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7850, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7854, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7854, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7858, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x785c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x785c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7860, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7828, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7828, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7830, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7830, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7838, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7838, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7840, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7840, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7848, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7848, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7850, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7850, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7858, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7858, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7860, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7860, 0x7fc00000, 0x00000000), ++ DECL_RFK_WM(0x7860, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x7864, 0x000003ff, 0x000001ff), ++ DECL_RFK_WM(0x7864, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x7864, 0x03f00000, 0x00000000), ++ DECL_RFK_WM(0x7864, 0x04000000, 0x00000000), ++ DECL_RFK_WM(0x7898, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x789c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x78a0, 0x000000ff, 0x000000fd), ++ DECL_RFK_WM(0x78a0, 0x0000ff00, 0x000000e5), ++ DECL_RFK_WM(0x78a0, 0x00ff0000, 0x000000cd), ++ DECL_RFK_WM(0x78a0, 0xff000000, 0x000000b5), ++ DECL_RFK_WM(0x78a4, 0x000000ff, 0x00000016), ++ DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x03fe0000, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x78b0, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x78b4, 0x0000001f, 0x00000000), ++ DECL_RFK_WM(0x78b4, 0x00000020, 0x00000000), ++ DECL_RFK_WM(0x78b4, 0x000001c0, 0x00000000), ++ DECL_RFK_WM(0x78b4, 0x00000200, 0x00000000), ++ DECL_RFK_WM(0x78b4, 0x0000f000, 0x00000002), ++ DECL_RFK_WM(0x78b4, 0x00ff0000, 0x00000000), ++ DECL_RFK_WM(0x78b4, 0x7f000000, 0x0000000a), ++ DECL_RFK_WM(0x78b8, 0x0000007f, 0x00000028), ++ DECL_RFK_WM(0x78b8, 0x00007f00, 0x00000076), ++ DECL_RFK_WM(0x78b8, 0x007f0000, 0x00000000), ++ DECL_RFK_WM(0x78b8, 0x7f000000, 0x00000000), ++ DECL_RFK_WM(0x78bc, 0x000000ff, 0x0000007f), ++ DECL_RFK_WM(0x78bc, 0x0000ff00, 0x00000080), ++ DECL_RFK_WM(0x78bc, 0x00030000, 0x00000003), ++ DECL_RFK_WM(0x78bc, 0x000c0000, 0x00000001), ++ DECL_RFK_WM(0x78bc, 0x00300000, 0x00000002), ++ DECL_RFK_WM(0x78bc, 0x00c00000, 0x00000002), ++ DECL_RFK_WM(0x78bc, 0x07000000, 0x00000007), ++ DECL_RFK_WM(0x78c0, 0x00fe0000, 0x0000003f), ++ DECL_RFK_WM(0x78c0, 0xff000000, 0x00000000), ++ DECL_RFK_WM(0x78c4, 0x0003ffff, 0x0003ffff), ++ DECL_RFK_WM(0x78c4, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x78c4, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x78c8, 0x00ffffff, 0x00000000), ++ DECL_RFK_WM(0x78c8, 0xf0000000, 0x00000000), ++ DECL_RFK_WM(0x78cc, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x78d0, 0x00001fff, 0x00000101), ++ DECL_RFK_WM(0x78d0, 0x0001e000, 0x00000004), ++ DECL_RFK_WM(0x78d0, 0x03fe0000, 0x00000100), ++ DECL_RFK_WM(0x78d0, 0x04000000, 0x00000000), ++ DECL_RFK_WM(0x78d4, 0x000000ff, 0x00000000), ++ DECL_RFK_WM(0x78d4, 0x0003fe00, 0x000000ff), ++ DECL_RFK_WM(0x78d4, 0x07fc0000, 0x00000100), ++ DECL_RFK_WM(0x78d8, 0x000001ff, 0x0000016c), ++ DECL_RFK_WM(0x78d8, 0x0003fe00, 0x0000005c), ++ DECL_RFK_WM(0x78d8, 0x000c0000, 0x00000002), ++ DECL_RFK_WM(0x78d8, 0xfff00000, 0x00000800), ++ DECL_RFK_WM(0x78dc, 0x000000ff, 0x0000007f), ++ DECL_RFK_WM(0x78dc, 0x0000ff00, 0x00000080), ++ DECL_RFK_WM(0x78dc, 0x00010000, 0x00000000), ++ DECL_RFK_WM(0x78dc, 0x3ff00000, 0x00000000), ++ DECL_RFK_WM(0x78dc, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x78f0, 0x000001ff, 0x000001ff), ++ DECL_RFK_WM(0x78f0, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_defs_2g[] = { ++ DECL_RFK_WM(0x58d8, 0x000001ff, 0x0000013c), ++ DECL_RFK_WM(0x78d8, 0x000001ff, 0x0000013c), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_defs_2g); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_defs_5g[] = { ++ DECL_RFK_WM(0x58d8, 0x000001ff, 0x0000016c), ++ DECL_RFK_WM(0x78d8, 0x000001ff, 0x0000016c), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_defs_5g); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_a[] = { ++ DECL_RFK_WM(0x58a0, 0xffffffff, 0x000000fc), ++ DECL_RFK_WM(0x58e4, 0x0000007f, 0x00000020), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_b[] = { ++ DECL_RFK_WM(0x78a0, 0xffffffff, 0x000000fc), ++ DECL_RFK_WM(0x78e4, 0x0000007f, 0x00000020), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_dck_defs_a[] = { ++ DECL_RFK_WM(0x580c, 0x0fff0000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x00001000, 0x00000001), ++ DECL_RFK_WM(0x5814, 0x00002000, 0x00000001), ++ DECL_RFK_WM(0x5814, 0x00004000, 0x00000001), ++ DECL_RFK_WM(0x5814, 0x00038000, 0x00000005), ++ DECL_RFK_WM(0x5814, 0x003c0000, 0x00000003), ++ DECL_RFK_WM(0x5814, 0x18000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_dck_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_dck_defs_b[] = { ++ DECL_RFK_WM(0x780c, 0x0fff0000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x00001000, 0x00000001), ++ DECL_RFK_WM(0x7814, 0x00002000, 0x00000001), ++ DECL_RFK_WM(0x7814, 0x00004000, 0x00000001), ++ DECL_RFK_WM(0x7814, 0x00038000, 0x00000005), ++ DECL_RFK_WM(0x7814, 0x003c0000, 0x00000003), ++ DECL_RFK_WM(0x7814, 0x18000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_dck_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_dac_gain_tbl_defs_a[] = { ++ DECL_RFK_WM(0x58b0, 0x00000fff, 0x00000000), ++ DECL_RFK_WM(0x58b0, 0x00000800, 0x00000001), ++ DECL_RFK_WM(0x5a00, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a04, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a08, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a0c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a10, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a14, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a18, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a1c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a20, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a24, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a28, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a2c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a30, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a34, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a38, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a3c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a40, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a44, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a48, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a4c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a50, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a54, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a58, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a5c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a60, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a64, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a68, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a6c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a70, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a74, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a78, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a7c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a80, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a84, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a88, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a8c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a90, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a94, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a98, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5a9c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5aa0, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5aa4, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5aa8, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5aac, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5ab0, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5ab4, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5ab8, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5abc, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x5ac0, 0xffffffff, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_dac_gain_tbl_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_dac_gain_tbl_defs_b[] = { ++ DECL_RFK_WM(0x78b0, 0x00000fff, 0x00000000), ++ DECL_RFK_WM(0x78b0, 0x00000800, 0x00000001), ++ DECL_RFK_WM(0x7a00, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a04, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a08, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a0c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a10, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a14, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a18, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a1c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a20, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a24, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a28, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a2c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a30, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a34, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a38, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a3c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a40, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a44, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a48, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a4c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a50, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a54, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a58, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a5c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a60, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a64, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a68, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a6c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a70, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a74, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a78, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a7c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a80, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a84, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a88, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a8c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a90, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a94, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a98, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7a9c, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7aa0, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7aa4, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7aa8, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7aac, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7ab0, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7ab4, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7ab8, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7abc, 0xffffffff, 0x00000000), ++ DECL_RFK_WM(0x7ac0, 0xffffffff, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_dac_gain_tbl_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_slope_cal_org_defs_a[] = { ++ DECL_RFK_WM(0x581c, 0x00100000, 0x00000000), ++ DECL_RFK_WM(0x58cc, 0x00001000, 0x00000001), ++ DECL_RFK_WM(0x58cc, 0x00000007, 0x00000000), ++ DECL_RFK_WM(0x58cc, 0x00000038, 0x00000001), ++ DECL_RFK_WM(0x58cc, 0x000001c0, 0x00000002), ++ DECL_RFK_WM(0x58cc, 0x00000e00, 0x00000003), ++ DECL_RFK_WM(0x5828, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x5898, 0x000000ff, 0x00000040), ++ DECL_RFK_WM(0x5830, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x5898, 0x0000ff00, 0x00000040), ++ DECL_RFK_WM(0x5838, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x5898, 0x00ff0000, 0x00000040), ++ DECL_RFK_WM(0x5840, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x5898, 0xff000000, 0x00000040), ++ DECL_RFK_WM(0x5848, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x589c, 0x000000ff, 0x00000040), ++ DECL_RFK_WM(0x5850, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x589c, 0x0000ff00, 0x00000040), ++ DECL_RFK_WM(0x5858, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x589c, 0x00ff0000, 0x00000040), ++ DECL_RFK_WM(0x5860, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x589c, 0xff000000, 0x00000040), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_slope_cal_org_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_slope_cal_org_defs_b[] = { ++ DECL_RFK_WM(0x781c, 0x00100000, 0x00000000), ++ DECL_RFK_WM(0x78cc, 0x00001000, 0x00000001), ++ DECL_RFK_WM(0x78cc, 0x00000007, 0x00000000), ++ DECL_RFK_WM(0x78cc, 0x00000038, 0x00000001), ++ DECL_RFK_WM(0x78cc, 0x000001c0, 0x00000002), ++ DECL_RFK_WM(0x78cc, 0x00000e00, 0x00000003), ++ DECL_RFK_WM(0x7828, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x7898, 0x000000ff, 0x00000040), ++ DECL_RFK_WM(0x7830, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x7898, 0x0000ff00, 0x00000040), ++ DECL_RFK_WM(0x7838, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x7898, 0x00ff0000, 0x00000040), ++ DECL_RFK_WM(0x7840, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x7898, 0xff000000, 0x00000040), ++ DECL_RFK_WM(0x7848, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x789c, 0x000000ff, 0x00000040), ++ DECL_RFK_WM(0x7850, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x789c, 0x0000ff00, 0x00000040), ++ DECL_RFK_WM(0x7878, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x789c, 0x00ff0000, 0x00000040), ++ DECL_RFK_WM(0x7860, 0x7fc00000, 0x00000040), ++ DECL_RFK_WM(0x789c, 0xff000000, 0x00000040), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_slope_cal_org_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_rf_gap_tbl_defs_a[] = { ++ DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x03fe0000, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x07fc0000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_rf_gap_tbl_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_rf_gap_tbl_defs_b[] = { ++ DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x03fe0000, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_rf_gap_tbl_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_slope_defs_a[] = { ++ DECL_RFK_WM(0x5820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x5818, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x00000800, 0x00000001), ++ DECL_RFK_WM(0x581c, 0x20000000, 0x00000001), ++ DECL_RFK_WM(0x5820, 0x0000f000, 0x00000001), ++ DECL_RFK_WM(0x581c, 0x000003ff, 0x00000280), ++ DECL_RFK_WM(0x581c, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x58b8, 0x007f0000, 0x00000000), ++ DECL_RFK_WM(0x58b8, 0x7f000000, 0x00000000), ++ DECL_RFK_WM(0x58b4, 0x7f000000, 0x0000000a), ++ DECL_RFK_WM(0x58b8, 0x0000007f, 0x00000028), ++ DECL_RFK_WM(0x58b8, 0x00007f00, 0x00000076), ++ DECL_RFK_WM(0x5810, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x20000000, 0x00000001), ++ DECL_RFK_WM(0x580c, 0x10000000, 0x00000001), ++ DECL_RFK_WM(0x580c, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x5838, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5858, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5834, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5834, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5838, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5854, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5854, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5858, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5824, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5824, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5828, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x582c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x582c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5830, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x583c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x583c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5840, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5844, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x5844, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5848, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x584c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x584c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5850, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x585c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x585c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x5860, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x5828, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5830, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5840, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5848, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5850, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x5860, 0x003ff000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_slope_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_slope_defs_b[] = { ++ DECL_RFK_WM(0x7820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x7818, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x00000800, 0x00000001), ++ DECL_RFK_WM(0x781c, 0x20000000, 0x00000001), ++ DECL_RFK_WM(0x7820, 0x0000f000, 0x00000001), ++ DECL_RFK_WM(0x781c, 0x000003ff, 0x00000280), ++ DECL_RFK_WM(0x781c, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x78b8, 0x007f0000, 0x00000000), ++ DECL_RFK_WM(0x78b8, 0x7f000000, 0x00000000), ++ DECL_RFK_WM(0x78b4, 0x7f000000, 0x0000000a), ++ DECL_RFK_WM(0x78b8, 0x0000007f, 0x00000028), ++ DECL_RFK_WM(0x78b8, 0x00007f00, 0x00000076), ++ DECL_RFK_WM(0x7810, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x20000000, 0x00000001), ++ DECL_RFK_WM(0x780c, 0x10000000, 0x00000001), ++ DECL_RFK_WM(0x780c, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x7838, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7858, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7834, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7834, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7838, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7854, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7854, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7858, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7824, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7824, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7828, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x782c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x782c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7830, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x783c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x783c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7840, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7844, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x7844, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7848, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x784c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x784c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7850, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x785c, 0x0003ffff, 0x000115f2), ++ DECL_RFK_WM(0x785c, 0x3ffc0000, 0x00000000), ++ DECL_RFK_WM(0x7860, 0x00000fff, 0x00000121), ++ DECL_RFK_WM(0x7828, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7830, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7840, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7848, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7850, 0x003ff000, 0x00000000), ++ DECL_RFK_WM(0x7860, 0x003ff000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_slope_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_track_defs_a[] = { ++ DECL_RFK_WM(0x5820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x5818, 0x18000000, 0x00000000), ++ DECL_RFK_WM(0x5814, 0x00000800, 0x00000000), ++ DECL_RFK_WM(0x581c, 0x20000000, 0x00000001), ++ DECL_RFK_WM(0x5864, 0x000003ff, 0x000001ff), ++ DECL_RFK_WM(0x5864, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x5820, 0x00000fff, 0x00000080), ++ DECL_RFK_WM(0x5814, 0x01000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_track_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_track_defs_b[] = { ++ DECL_RFK_WM(0x7820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x7818, 0x18000000, 0x00000000), ++ DECL_RFK_WM(0x7814, 0x00000800, 0x00000000), ++ DECL_RFK_WM(0x781c, 0x20000000, 0x00000001), ++ DECL_RFK_WM(0x7864, 0x000003ff, 0x000001ff), ++ DECL_RFK_WM(0x7864, 0x000ffc00, 0x00000200), ++ DECL_RFK_WM(0x7820, 0x00000fff, 0x00000080), ++ DECL_RFK_WM(0x7814, 0x01000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_track_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txagc_ofst_mv_avg_defs_a[] = { ++ DECL_RFK_WM(0x58e4, 0x00004000, 0x00000000), ++ DECL_RFK_WM(0x58e4, 0x00004000, 0x00000001), ++ DECL_RFK_WM(0x58e4, 0x00004000, 0x00000000), ++ DECL_RFK_WM(0x58e4, 0x00008000, 0x00000000), ++ DECL_RFK_WM(0x58e4, 0x000f0000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txagc_ofst_mv_avg_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_txagc_ofst_mv_avg_defs_b[] = { ++ DECL_RFK_WM(0x78e4, 0x00004000, 0x00000000), ++ DECL_RFK_WM(0x78e4, 0x00004000, 0x00000001), ++ DECL_RFK_WM(0x78e4, 0x00004000, 0x00000000), ++ DECL_RFK_WM(0x78e4, 0x00008000, 0x00000000), ++ DECL_RFK_WM(0x78e4, 0x000f0000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_txagc_ofst_mv_avg_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_a_2g[] = { ++ DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x03fe0000, 0x000001d0), ++ DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x0003fe00, 0x000001e8), ++ DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x000001ff, 0x0000000b), ++ DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x07fc0000, 0x00000088), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_a_2g); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_a_5g_1[] = { ++ DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x03fe0000, 0x000001d7), ++ DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x0003fe00, 0x000001fb), ++ DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000005), ++ DECL_RFK_WM(0x58ac, 0x07fc0000, 0x0000007c), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_a_5g_1); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_a_5g_3[] = { ++ DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x03fe0000, 0x000001d8), ++ DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x0003fe00, 0x000001fc), ++ DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000006), ++ DECL_RFK_WM(0x58ac, 0x07fc0000, 0x00000078), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_a_5g_3); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_a_5g_4[] = { ++ DECL_RFK_WM(0x5814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x58f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x58a4, 0x03fe0000, 0x000001e5), ++ DECL_RFK_WM(0x58a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58a8, 0x0003fe00, 0x0000000a), ++ DECL_RFK_WM(0x58a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x58ac, 0x0003fe00, 0x00000011), ++ DECL_RFK_WM(0x58ac, 0x07fc0000, 0x00000075), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_a_5g_4); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_b_2g[] = { ++ DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x03fe0000, 0x000001cc), ++ DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x0003fe00, 0x000001e2), ++ DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000005), ++ DECL_RFK_WM(0x78ac, 0x0003fe00, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000089), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_b_2g); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_b_5g_1[] = { ++ DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x03fe0000, 0x000001d5), ++ DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x0003fe00, 0x000001fc), ++ DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x0003fe00, 0x00000005), ++ DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000079), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_b_5g_1); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_b_5g_3[] = { ++ DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x03fe0000, 0x000001dc), ++ DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x0003fe00, 0x00000002), ++ DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x0003fe00, 0x0000000b), ++ DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000076), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_b_5g_3); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_pak_defs_b_5g_4[] = { ++ DECL_RFK_WM(0x7814, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f4, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000003ff, 0x00000000), ++ DECL_RFK_WM(0x78f8, 0x000ffc00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x0001ff00, 0x00000000), ++ DECL_RFK_WM(0x78a4, 0x03fe0000, 0x000001f0), ++ DECL_RFK_WM(0x78a8, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78a8, 0x0003fe00, 0x00000016), ++ DECL_RFK_WM(0x78a8, 0x07fc0000, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x000001ff, 0x00000000), ++ DECL_RFK_WM(0x78ac, 0x0003fe00, 0x0000001f), ++ DECL_RFK_WM(0x78ac, 0x07fc0000, 0x00000072), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_pak_defs_b_5g_4); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_enable_defs_a[] = { ++ DECL_RFK_WRF(0x0, 0x55, 0x00080, 0x00001), ++ DECL_RFK_WM(0x5818, 0x000000ff, 0x000000c0), ++ DECL_RFK_WM(0x5818, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x5818, 0x10000000, 0x00000001), ++ DECL_RFK_WM(0x5820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x5820, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x5818, 0x18000000, 0x00000003), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_enable_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_enable_defs_b[] = { ++ DECL_RFK_WRF(0x1, 0x55, 0x00080, 0x00001), ++ DECL_RFK_WM(0x7818, 0x000000ff, 0x000000c0), ++ DECL_RFK_WM(0x7818, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x7818, 0x10000000, 0x00000001), ++ DECL_RFK_WM(0x7820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x7820, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x7818, 0x18000000, 0x00000003), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_enable_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_disable_defs[] = { ++ DECL_RFK_WM(0x5820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x5818, 0x18000000, 0x00000001), ++ DECL_RFK_WM(0x7820, 0x80000000, 0x00000000), ++ DECL_RFK_WM(0x7818, 0x18000000, 0x00000001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_disable_defs); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_enable_defs_ab[] = { ++ DECL_RFK_WM(0x5820, 0x80000000, 0x0), ++ DECL_RFK_WM(0x5820, 0x80000000, 0x1), ++ DECL_RFK_WM(0x5818, 0x18000000, 0x3), ++ DECL_RFK_WM(0x7820, 0x80000000, 0x0), ++ DECL_RFK_WM(0x7820, 0x80000000, 0x1), ++ DECL_RFK_WM(0x7818, 0x18000000, 0x3), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_enable_defs_ab); ++ ++static const struct rtw89_reg5_def rtw8852a_tssi_tracking_defs[] = { ++ DECL_RFK_WM(0x5800, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x58f0, 0x00080000, 0x00000000), ++ DECL_RFK_WM(0x5804, 0xf8000000, 0x00000000), ++ DECL_RFK_WM(0x58f0, 0xfff00000, 0x00000400), ++ DECL_RFK_WM(0x7800, 0x10000000, 0x00000000), ++ DECL_RFK_WM(0x78f0, 0x00080000, 0x00000000), ++ DECL_RFK_WM(0x7804, 0xf8000000, 0x00000000), ++ DECL_RFK_WM(0x78f0, 0xfff00000, 0x00000400), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_tssi_tracking_defs); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_afe_init_defs[] = { ++ DECL_RFK_WC(0x12ec, 0x00008000), ++ DECL_RFK_WS(0x12ec, 0x00008000), ++ DECL_RFK_WC(0x5e00, 0x00000001), ++ DECL_RFK_WS(0x5e00, 0x00000001), ++ DECL_RFK_WC(0x32ec, 0x00008000), ++ DECL_RFK_WS(0x32ec, 0x00008000), ++ DECL_RFK_WC(0x7e00, 0x00000001), ++ DECL_RFK_WS(0x7e00, 0x00000001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_afe_init_defs); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_reload_defs_a[] = { ++ DECL_RFK_WS(0x5e00, 0x00000008), ++ DECL_RFK_WS(0x5e50, 0x00000008), ++ DECL_RFK_WS(0x5e10, 0x80000000), ++ DECL_RFK_WS(0x5e60, 0x80000000), ++ DECL_RFK_WC(0x5e00, 0x00000008), ++ DECL_RFK_WC(0x5e50, 0x00000008), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_reload_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_reload_defs_b[] = { ++ DECL_RFK_WS(0x7e00, 0x00000008), ++ DECL_RFK_WS(0x7e50, 0x00000008), ++ DECL_RFK_WS(0x7e10, 0x80000000), ++ DECL_RFK_WS(0x7e60, 0x80000000), ++ DECL_RFK_WC(0x7e00, 0x00000008), ++ DECL_RFK_WC(0x7e50, 0x00000008), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_reload_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_check_addc_defs_a[] = { ++ DECL_RFK_WC(0x20f4, 0x01000000), ++ DECL_RFK_WS(0x20f8, 0x80000000), ++ DECL_RFK_WM(0x20f0, 0x00ff0000, 0x00000001), ++ DECL_RFK_WM(0x20f0, 0x00000f00, 0x00000002), ++ DECL_RFK_WC(0x20f0, 0x0000000f), ++ DECL_RFK_WM(0x20f0, 0x000000c0, 0x00000002), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_check_addc_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_check_addc_defs_b[] = { ++ DECL_RFK_WC(0x20f4, 0x01000000), ++ DECL_RFK_WS(0x20f8, 0x80000000), ++ DECL_RFK_WM(0x20f0, 0x00ff0000, 0x00000001), ++ DECL_RFK_WM(0x20f0, 0x00000f00, 0x00000002), ++ DECL_RFK_WC(0x20f0, 0x0000000f), ++ DECL_RFK_WM(0x20f0, 0x000000c0, 0x00000003), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_check_addc_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_addck_reset_defs_a[] = { ++ DECL_RFK_WC(0x12d8, 0x00000030), ++ DECL_RFK_WC(0x32d8, 0x00000030), ++ DECL_RFK_WS(0x12b8, 0x40000000), ++ DECL_RFK_WC(0x032c, 0x40000000), ++ DECL_RFK_WC(0x032c, 0x00400000), ++ DECL_RFK_WS(0x032c, 0x00400000), ++ DECL_RFK_WS(0x030c, 0x0f000000), ++ DECL_RFK_WC(0x032c, 0x00010000), ++ DECL_RFK_WS(0x12dc, 0x00000002), ++ DECL_RFK_WM(0x030c, 0x0f000000, 0x00000003), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_addck_reset_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_addck_trigger_defs_a[] = { ++ DECL_RFK_WS(0x12d8, 0x000000c0), ++ DECL_RFK_WS(0x12d8, 0x00000800), ++ DECL_RFK_WC(0x12d8, 0x00000800), ++ DECL_RFK_DELAY(1), ++ DECL_RFK_WM(0x12d8, 0x00000300, 0x00000001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_addck_trigger_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_addck_restore_defs_a[] = { ++ DECL_RFK_WC(0x12dc, 0x00000002), ++ DECL_RFK_WS(0x032c, 0x00010000), ++ DECL_RFK_WM(0x030c, 0x0f000000, 0x0000000c), ++ DECL_RFK_WS(0x032c, 0x40000000), ++ DECL_RFK_WC(0x12b8, 0x40000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_addck_restore_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_addck_reset_defs_b[] = { ++ DECL_RFK_WS(0x32b8, 0x40000000), ++ DECL_RFK_WC(0x032c, 0x40000000), ++ DECL_RFK_WC(0x032c, 0x00400000), ++ DECL_RFK_WS(0x032c, 0x00400000), ++ DECL_RFK_WS(0x030c, 0x0f000000), ++ DECL_RFK_WC(0x032c, 0x00010000), ++ DECL_RFK_WS(0x32dc, 0x00000002), ++ DECL_RFK_WM(0x030c, 0x0f000000, 0x00000003), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_addck_reset_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_addck_trigger_defs_b[] = { ++ DECL_RFK_WS(0x32d8, 0x000000c0), ++ DECL_RFK_WS(0x32d8, 0x00000800), ++ DECL_RFK_WC(0x32d8, 0x00000800), ++ DECL_RFK_DELAY(1), ++ DECL_RFK_WM(0x32d8, 0x00000300, 0x00000001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_addck_trigger_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_addck_restore_defs_b[] = { ++ DECL_RFK_WC(0x32dc, 0x00000002), ++ DECL_RFK_WS(0x032c, 0x00010000), ++ DECL_RFK_WM(0x030c, 0x0f000000, 0x0000000c), ++ DECL_RFK_WS(0x032c, 0x40000000), ++ DECL_RFK_WC(0x32b8, 0x40000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_addck_restore_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_check_dadc_defs_f_a[] = { ++ DECL_RFK_WC(0x032c, 0x40000000), ++ DECL_RFK_WS(0x030c, 0x0f000000), ++ DECL_RFK_WM(0x030c, 0x0f000000, 0x00000003), ++ DECL_RFK_WC(0x032c, 0x00010000), ++ DECL_RFK_WS(0x12dc, 0x00000001), ++ DECL_RFK_WS(0x12e8, 0x00000004), ++ DECL_RFK_WRF(0x0, 0x8f, 0x02000, 0x00001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_check_dadc_defs_f_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_check_dadc_defs_f_b[] = { ++ DECL_RFK_WC(0x032c, 0x40000000), ++ DECL_RFK_WS(0x030c, 0x0f000000), ++ DECL_RFK_WM(0x030c, 0x0f000000, 0x00000003), ++ DECL_RFK_WC(0x032c, 0x00010000), ++ DECL_RFK_WS(0x32dc, 0x00000001), ++ DECL_RFK_WS(0x32e8, 0x00000004), ++ DECL_RFK_WRF(0x1, 0x8f, 0x02000, 0x00001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_check_dadc_defs_f_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_check_dadc_defs_r_a[] = { ++ DECL_RFK_WC(0x12dc, 0x00000001), ++ DECL_RFK_WC(0x12e8, 0x00000004), ++ DECL_RFK_WRF(0x0, 0x8f, 0x02000, 0x00000), ++ DECL_RFK_WM(0x032c, 0x00010000, 0x00000001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_check_dadc_defs_r_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_check_dadc_defs_r_b[] = { ++ DECL_RFK_WC(0x32dc, 0x00000001), ++ DECL_RFK_WC(0x32e8, 0x00000004), ++ DECL_RFK_WRF(0x1, 0x8f, 0x02000, 0x00000), ++ DECL_RFK_WM(0x032c, 0x00010000, 0x00000001), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_check_dadc_defs_r_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_f_a[] = { ++ DECL_RFK_WS(0x5e00, 0x00000008), ++ DECL_RFK_WC(0x5e10, 0x80000000), ++ DECL_RFK_WS(0x5e50, 0x00000008), ++ DECL_RFK_WC(0x5e60, 0x80000000), ++ DECL_RFK_WS(0x12a0, 0x00008000), ++ DECL_RFK_WM(0x12a0, 0x00007000, 0x00000003), ++ DECL_RFK_WS(0x12b8, 0x40000000), ++ DECL_RFK_WS(0x030c, 0x10000000), ++ DECL_RFK_WC(0x032c, 0x80000000), ++ DECL_RFK_WS(0x12e0, 0x00010000), ++ DECL_RFK_WS(0x12e4, 0x0c000000), ++ DECL_RFK_WM(0x5e00, 0x03ff0000, 0x00000030), ++ DECL_RFK_WM(0x5e50, 0x03ff0000, 0x00000030), ++ DECL_RFK_WC(0x5e00, 0x0c000000), ++ DECL_RFK_WC(0x5e50, 0x0c000000), ++ DECL_RFK_WC(0x5e0c, 0x00000008), ++ DECL_RFK_WC(0x5e5c, 0x00000008), ++ DECL_RFK_WS(0x5e0c, 0x00000001), ++ DECL_RFK_WS(0x5e5c, 0x00000001), ++ DECL_RFK_DELAY(1), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_f_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_m_a[] = { ++ DECL_RFK_WC(0x12e4, 0x0c000000), ++ DECL_RFK_WS(0x5e0c, 0x00000008), ++ DECL_RFK_WS(0x5e5c, 0x00000008), ++ DECL_RFK_DELAY(1), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_m_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_r_a[] = { ++ DECL_RFK_WC(0x5e0c, 0x00000001), ++ DECL_RFK_WC(0x5e5c, 0x00000001), ++ DECL_RFK_WC(0x12e0, 0x00010000), ++ DECL_RFK_WC(0x12a0, 0x00008000), ++ DECL_RFK_WS(0x12a0, 0x00007000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_r_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_f_b[] = { ++ DECL_RFK_WS(0x7e00, 0x00000008), ++ DECL_RFK_WC(0x7e10, 0x80000000), ++ DECL_RFK_WS(0x7e50, 0x00000008), ++ DECL_RFK_WC(0x7e60, 0x80000000), ++ DECL_RFK_WS(0x32a0, 0x00008000), ++ DECL_RFK_WM(0x32a0, 0x00007000, 0x00000003), ++ DECL_RFK_WS(0x32b8, 0x40000000), ++ DECL_RFK_WS(0x030c, 0x10000000), ++ DECL_RFK_WC(0x032c, 0x80000000), ++ DECL_RFK_WS(0x32e0, 0x00010000), ++ DECL_RFK_WS(0x32e4, 0x0c000000), ++ DECL_RFK_WM(0x7e00, 0x03ff0000, 0x00000030), ++ DECL_RFK_WM(0x7e50, 0x03ff0000, 0x00000030), ++ DECL_RFK_WC(0x7e00, 0x0c000000), ++ DECL_RFK_WC(0x7e50, 0x0c000000), ++ DECL_RFK_WC(0x7e0c, 0x00000008), ++ DECL_RFK_WC(0x7e5c, 0x00000008), ++ DECL_RFK_WS(0x7e0c, 0x00000001), ++ DECL_RFK_WS(0x7e5c, 0x00000001), ++ DECL_RFK_DELAY(1), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_f_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_m_b[] = { ++ DECL_RFK_WC(0x32e4, 0x0c000000), ++ DECL_RFK_WM(0x7e0c, 0x00000008, 0x00000001), ++ DECL_RFK_WM(0x7e5c, 0x00000008, 0x00000001), ++ DECL_RFK_DELAY(1), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_m_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dack_defs_r_b[] = { ++ DECL_RFK_WC(0x7e0c, 0x00000001), ++ DECL_RFK_WC(0x7e5c, 0x00000001), ++ DECL_RFK_WC(0x32e0, 0x00010000), ++ DECL_RFK_WC(0x32a0, 0x00008000), ++ DECL_RFK_WS(0x32a0, 0x00007000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dack_defs_r_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_sf_defs_a[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000101), ++ DECL_RFK_WS(0x12b8, 0x40000000), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000041), ++ DECL_RFK_WS(0x12b8, 0x10000000), ++ DECL_RFK_WS(0x58c8, 0x01000000), ++ DECL_RFK_WS(0x5864, 0xc0000000), ++ DECL_RFK_WS(0x2008, 0x01ffffff), ++ DECL_RFK_WS(0x0c1c, 0x00000004), ++ DECL_RFK_WS(0x0700, 0x08000000), ++ DECL_RFK_WS(0x0c70, 0x000003ff), ++ DECL_RFK_WS(0x0c60, 0x00000003), ++ DECL_RFK_WS(0x0c6c, 0x00000001), ++ DECL_RFK_WS(0x58ac, 0x08000000), ++ DECL_RFK_WS(0x0c3c, 0x00000200), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_sf_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_sr_defs_a[] = { ++ DECL_RFK_WS(0x4490, 0x80000000), ++ DECL_RFK_WS(0x12a0, 0x00007000), ++ DECL_RFK_WS(0x12a0, 0x00008000), ++ DECL_RFK_WM(0x12a0, 0x00070000, 0x00000003), ++ DECL_RFK_WS(0x12a0, 0x00080000), ++ DECL_RFK_WS(0x0700, 0x01000000), ++ DECL_RFK_WM(0x0700, 0x06000000, 0x00000002), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00001111), ++ DECL_RFK_WM(0x58f0, 0x00080000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_sr_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_sf_defs_b[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000202), ++ DECL_RFK_WS(0x32b8, 0x40000000), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000041), ++ DECL_RFK_WS(0x32b8, 0x10000000), ++ DECL_RFK_WS(0x78c8, 0x01000000), ++ DECL_RFK_WS(0x7864, 0xc0000000), ++ DECL_RFK_WS(0x2008, 0x01ffffff), ++ DECL_RFK_WS(0x2c1c, 0x00000004), ++ DECL_RFK_WS(0x2700, 0x08000000), ++ DECL_RFK_WS(0x0c70, 0x000003ff), ++ DECL_RFK_WS(0x0c60, 0x00000003), ++ DECL_RFK_WS(0x0c6c, 0x00000001), ++ DECL_RFK_WS(0x78ac, 0x08000000), ++ DECL_RFK_WS(0x2c3c, 0x00000200), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_sf_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_sr_defs_b[] = { ++ DECL_RFK_WS(0x6490, 0x80000000), ++ DECL_RFK_WS(0x32a0, 0x00007000), ++ DECL_RFK_WS(0x32a0, 0x00008000), ++ DECL_RFK_WM(0x32a0, 0x00070000, 0x00000003), ++ DECL_RFK_WS(0x32a0, 0x00080000), ++ DECL_RFK_WS(0x2700, 0x01000000), ++ DECL_RFK_WM(0x2700, 0x06000000, 0x00000002), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00002222), ++ DECL_RFK_WM(0x78f0, 0x00080000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_sr_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_s_defs_ab[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000303), ++ DECL_RFK_WS(0x12b8, 0x40000000), ++ DECL_RFK_WS(0x32b8, 0x40000000), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000041), ++ DECL_RFK_WS(0x12b8, 0x10000000), ++ DECL_RFK_WS(0x58c8, 0x01000000), ++ DECL_RFK_WS(0x78c8, 0x01000000), ++ DECL_RFK_WS(0x5864, 0xc0000000), ++ DECL_RFK_WS(0x7864, 0xc0000000), ++ DECL_RFK_WS(0x2008, 0x01ffffff), ++ DECL_RFK_WS(0x0c1c, 0x00000004), ++ DECL_RFK_WS(0x0700, 0x08000000), ++ DECL_RFK_WS(0x0c70, 0x000003ff), ++ DECL_RFK_WS(0x0c60, 0x00000003), ++ DECL_RFK_WS(0x0c6c, 0x00000001), ++ DECL_RFK_WS(0x58ac, 0x08000000), ++ DECL_RFK_WS(0x78ac, 0x08000000), ++ DECL_RFK_WS(0x0c3c, 0x00000200), ++ DECL_RFK_WS(0x2344, 0x80000000), ++ DECL_RFK_WS(0x4490, 0x80000000), ++ DECL_RFK_WS(0x12a0, 0x00007000), ++ DECL_RFK_WS(0x12a0, 0x00008000), ++ DECL_RFK_WM(0x12a0, 0x00070000, 0x00000003), ++ DECL_RFK_WS(0x12a0, 0x00080000), ++ DECL_RFK_WM(0x32a0, 0x00070000, 0x00000003), ++ DECL_RFK_WS(0x32a0, 0x00080000), ++ DECL_RFK_WS(0x0700, 0x01000000), ++ DECL_RFK_WM(0x0700, 0x06000000, 0x00000002), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00003333), ++ DECL_RFK_WM(0x58f0, 0x00080000, 0x00000000), ++ DECL_RFK_WM(0x78f0, 0x00080000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_s_defs_ab); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_r_defs_a[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000101), ++ DECL_RFK_WC(0x12b8, 0x40000000), ++ DECL_RFK_WC(0x5864, 0xc0000000), ++ DECL_RFK_WC(0x2008, 0x01ffffff), ++ DECL_RFK_WC(0x0c1c, 0x00000004), ++ DECL_RFK_WC(0x0700, 0x08000000), ++ DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), ++ DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), ++ DECL_RFK_WC(0x12a0, 0x000ff000), ++ DECL_RFK_WC(0x0700, 0x07000000), ++ DECL_RFK_WC(0x5864, 0x20000000), ++ DECL_RFK_WC(0x0c3c, 0x00000200), ++ DECL_RFK_WC(0x20fc, 0xffff0000), ++ DECL_RFK_WC(0x58c8, 0x01000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_r_defs_a); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_r_defs_b[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000202), ++ DECL_RFK_WC(0x32b8, 0x40000000), ++ DECL_RFK_WC(0x7864, 0xc0000000), ++ DECL_RFK_WC(0x2008, 0x01ffffff), ++ DECL_RFK_WC(0x2c1c, 0x00000004), ++ DECL_RFK_WC(0x2700, 0x08000000), ++ DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), ++ DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), ++ DECL_RFK_WC(0x32a0, 0x000ff000), ++ DECL_RFK_WC(0x2700, 0x07000000), ++ DECL_RFK_WC(0x7864, 0x20000000), ++ DECL_RFK_WC(0x2c3c, 0x00000200), ++ DECL_RFK_WC(0x20fc, 0xffff0000), ++ DECL_RFK_WC(0x78c8, 0x01000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_r_defs_b); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_bb_afe_r_defs_ab[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000303), ++ DECL_RFK_WC(0x12b8, 0x40000000), ++ DECL_RFK_WC(0x32b8, 0x40000000), ++ DECL_RFK_WC(0x5864, 0xc0000000), ++ DECL_RFK_WC(0x7864, 0xc0000000), ++ DECL_RFK_WC(0x2008, 0x01ffffff), ++ DECL_RFK_WC(0x0c1c, 0x00000004), ++ DECL_RFK_WC(0x0700, 0x08000000), ++ DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), ++ DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), ++ DECL_RFK_WC(0x12a0, 0x000ff000), ++ DECL_RFK_WC(0x32a0, 0x000ff000), ++ DECL_RFK_WC(0x0700, 0x07000000), ++ DECL_RFK_WC(0x5864, 0x20000000), ++ DECL_RFK_WC(0x7864, 0x20000000), ++ DECL_RFK_WC(0x0c3c, 0x00000200), ++ DECL_RFK_WC(0x20fc, 0xffff0000), ++ DECL_RFK_WC(0x58c8, 0x01000000), ++ DECL_RFK_WC(0x78c8, 0x01000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_bb_afe_r_defs_ab); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_lbk_rxiqk_defs_f[] = { ++ DECL_RFK_WM(0x030c, 0xff000000, 0x0000000f), ++ DECL_RFK_DELAY(1), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000003), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x0000a001), ++ DECL_RFK_DELAY(1), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x0000a041), ++ DECL_RFK_WS(0x8074, 0x80000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_lbk_rxiqk_defs_f); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_lbk_rxiqk_defs_r[] = { ++ DECL_RFK_WC(0x8074, 0x80000000), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x0000001f), ++ DECL_RFK_DELAY(1), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000001), ++ DECL_RFK_DELAY(1), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000041), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000303), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00003333), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_lbk_rxiqk_defs_r); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_dpk_pas_read_defs[] = { ++ DECL_RFK_WM(0x80d4, 0x00ff0000, 0x00000006), ++ DECL_RFK_WC(0x80bc, 0x00004000), ++ DECL_RFK_WM(0x80c0, 0x00ff0000, 0x00000008), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_dpk_pas_read_defs); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_iqk_set_defs_nondbcc_path01[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000303), ++ DECL_RFK_WM(0x5864, 0x18000000, 0x00000003), ++ DECL_RFK_WM(0x7864, 0x18000000, 0x00000003), ++ DECL_RFK_WM(0x12b8, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x32b8, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000001), ++ DECL_RFK_WM(0x12b8, 0x10000000, 0x00000001), ++ DECL_RFK_WM(0x58c8, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x78c8, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x5864, 0xc0000000, 0x00000003), ++ DECL_RFK_WM(0x7864, 0xc0000000, 0x00000003), ++ DECL_RFK_WM(0x2008, 0x01ffffff, 0x01ffffff), ++ DECL_RFK_WM(0x0c1c, 0x00000004, 0x00000001), ++ DECL_RFK_WM(0x0700, 0x08000000, 0x00000001), ++ DECL_RFK_WM(0x0c70, 0x000003ff, 0x000003ff), ++ DECL_RFK_WM(0x0c60, 0x00000003, 0x00000003), ++ DECL_RFK_WM(0x0c6c, 0x00000001, 0x00000001), ++ DECL_RFK_WM(0x58ac, 0x08000000, 0x00000001), ++ DECL_RFK_WM(0x78ac, 0x08000000, 0x00000001), ++ DECL_RFK_WM(0x0c3c, 0x00000200, 0x00000001), ++ DECL_RFK_WM(0x2344, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x4490, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x12a0, 0x00007000, 0x00000007), ++ DECL_RFK_WM(0x12a0, 0x00008000, 0x00000001), ++ DECL_RFK_WM(0x12a0, 0x00070000, 0x00000003), ++ DECL_RFK_WM(0x12a0, 0x00080000, 0x00000001), ++ DECL_RFK_WM(0x32a0, 0x00070000, 0x00000003), ++ DECL_RFK_WM(0x32a0, 0x00080000, 0x00000001), ++ DECL_RFK_WM(0x0700, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x0700, 0x06000000, 0x00000002), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00003333), ++ DECL_RFK_WM(0x58f0, 0x00080000, 0x00000000), ++ DECL_RFK_WM(0x78f0, 0x00080000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_iqk_set_defs_nondbcc_path01); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_iqk_set_defs_dbcc_path0[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000101), ++ DECL_RFK_WM(0x5864, 0x18000000, 0x00000003), ++ DECL_RFK_WM(0x7864, 0x18000000, 0x00000003), ++ DECL_RFK_WM(0x12b8, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000001), ++ DECL_RFK_WM(0x12b8, 0x10000000, 0x00000001), ++ DECL_RFK_WM(0x58c8, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x5864, 0xc0000000, 0x00000003), ++ DECL_RFK_WM(0x2008, 0x01ffffff, 0x01ffffff), ++ DECL_RFK_WM(0x0c1c, 0x00000004, 0x00000001), ++ DECL_RFK_WM(0x0700, 0x08000000, 0x00000001), ++ DECL_RFK_WM(0x0c70, 0x000003ff, 0x000003ff), ++ DECL_RFK_WM(0x0c60, 0x00000003, 0x00000003), ++ DECL_RFK_WM(0x0c6c, 0x00000001, 0x00000001), ++ DECL_RFK_WM(0x58ac, 0x08000000, 0x00000001), ++ DECL_RFK_WM(0x0c3c, 0x00000200, 0x00000001), ++ DECL_RFK_WM(0x2320, 0x00000001, 0x00000001), ++ DECL_RFK_WM(0x4490, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x12a0, 0x00007000, 0x00000007), ++ DECL_RFK_WM(0x12a0, 0x00008000, 0x00000001), ++ DECL_RFK_WM(0x12a0, 0x00070000, 0x00000003), ++ DECL_RFK_WM(0x12a0, 0x00080000, 0x00000001), ++ DECL_RFK_WM(0x0700, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x0700, 0x06000000, 0x00000002), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00001111), ++ DECL_RFK_WM(0x58f0, 0x00080000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_iqk_set_defs_dbcc_path0); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_iqk_set_defs_dbcc_path1[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000202), ++ DECL_RFK_WM(0x7864, 0x18000000, 0x00000003), ++ DECL_RFK_WM(0x32b8, 0x40000000, 0x00000001), ++ DECL_RFK_WM(0x030c, 0xff000000, 0x00000013), ++ DECL_RFK_WM(0x032c, 0xffff0000, 0x00000001), ++ DECL_RFK_WM(0x32b8, 0x10000000, 0x00000001), ++ DECL_RFK_WM(0x78c8, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x7864, 0xc0000000, 0x00000003), ++ DECL_RFK_WM(0x2008, 0x01ffffff, 0x01ffffff), ++ DECL_RFK_WM(0x2c1c, 0x00000004, 0x00000001), ++ DECL_RFK_WM(0x2700, 0x08000000, 0x00000001), ++ DECL_RFK_WM(0x0c70, 0x000003ff, 0x000003ff), ++ DECL_RFK_WM(0x0c60, 0x00000003, 0x00000003), ++ DECL_RFK_WM(0x0c6c, 0x00000001, 0x00000001), ++ DECL_RFK_WM(0x78ac, 0x08000000, 0x00000001), ++ DECL_RFK_WM(0x2c3c, 0x00000200, 0x00000001), ++ DECL_RFK_WM(0x6490, 0x80000000, 0x00000001), ++ DECL_RFK_WM(0x32a0, 0x00007000, 0x00000007), ++ DECL_RFK_WM(0x32a0, 0x00008000, 0x00000001), ++ DECL_RFK_WM(0x32a0, 0x00070000, 0x00000003), ++ DECL_RFK_WM(0x32a0, 0x00080000, 0x00000001), ++ DECL_RFK_WM(0x2700, 0x01000000, 0x00000001), ++ DECL_RFK_WM(0x2700, 0x06000000, 0x00000002), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00002222), ++ DECL_RFK_WM(0x78f0, 0x00080000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_iqk_set_defs_dbcc_path1); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_iqk_restore_defs_nondbcc_path01[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000303), ++ DECL_RFK_WM(0x12b8, 0x40000000, 0x00000000), ++ DECL_RFK_WM(0x32b8, 0x40000000, 0x00000000), ++ DECL_RFK_WM(0x5864, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x7864, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x2008, 0x01ffffff, 0x00000000), ++ DECL_RFK_WM(0x0c1c, 0x00000004, 0x00000000), ++ DECL_RFK_WM(0x0700, 0x08000000, 0x00000000), ++ DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), ++ DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), ++ DECL_RFK_WM(0x12a0, 0x000ff000, 0x00000000), ++ DECL_RFK_WM(0x32a0, 0x000ff000, 0x00000000), ++ DECL_RFK_WM(0x0700, 0x07000000, 0x00000000), ++ DECL_RFK_WM(0x5864, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x7864, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x0c3c, 0x00000200, 0x00000000), ++ DECL_RFK_WM(0x2320, 0x00000001, 0x00000000), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000000), ++ DECL_RFK_WM(0x58c8, 0x01000000, 0x00000000), ++ DECL_RFK_WM(0x78c8, 0x01000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_iqk_restore_defs_nondbcc_path01); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_iqk_restore_defs_dbcc_path0[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000101), ++ DECL_RFK_WM(0x12b8, 0x40000000, 0x00000000), ++ DECL_RFK_WM(0x5864, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x2008, 0x01ffffff, 0x00000000), ++ DECL_RFK_WM(0x0c1c, 0x00000004, 0x00000000), ++ DECL_RFK_WM(0x0700, 0x08000000, 0x00000000), ++ DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), ++ DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), ++ DECL_RFK_WM(0x12a0, 0x000ff000, 0x00000000), ++ DECL_RFK_WM(0x0700, 0x07000000, 0x00000000), ++ DECL_RFK_WM(0x5864, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x0c3c, 0x00000200, 0x00000000), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000000), ++ DECL_RFK_WM(0x58c8, 0x01000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_iqk_restore_defs_dbcc_path0); ++ ++static const struct rtw89_reg5_def rtw8852a_rfk_iqk_restore_defs_dbcc_path1[] = { ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000202), ++ DECL_RFK_WM(0x32b8, 0x40000000, 0x00000000), ++ DECL_RFK_WM(0x7864, 0xc0000000, 0x00000000), ++ DECL_RFK_WM(0x2008, 0x01ffffff, 0x00000000), ++ DECL_RFK_WM(0x2c1c, 0x00000004, 0x00000000), ++ DECL_RFK_WM(0x2700, 0x08000000, 0x00000000), ++ DECL_RFK_WM(0x0c70, 0x0000001f, 0x00000003), ++ DECL_RFK_WM(0x0c70, 0x000003e0, 0x00000003), ++ DECL_RFK_WM(0x32a0, 0x000ff000, 0x00000000), ++ DECL_RFK_WM(0x2700, 0x07000000, 0x00000000), ++ DECL_RFK_WM(0x7864, 0x20000000, 0x00000000), ++ DECL_RFK_WM(0x2c3c, 0x00000200, 0x00000000), ++ DECL_RFK_WM(0x20fc, 0xffff0000, 0x00000000), ++ DECL_RFK_WM(0x78c8, 0x01000000, 0x00000000), ++}; ++ ++DECLARE_RFK_TBL(rtw8852a_rfk_iqk_restore_defs_dbcc_path1); +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.h +new file mode 100644 +index 000000000000..4a4a45d778ff +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk_table.h +@@ -0,0 +1,133 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_8852A_RFK_TABLE_H__ ++#define __RTW89_8852A_RFK_TABLE_H__ ++ ++#include "core.h" ++ ++enum rtw89_rfk_flag { ++ RTW89_RFK_F_WRF = 0, ++ RTW89_RFK_F_WM = 1, ++ RTW89_RFK_F_WS = 2, ++ RTW89_RFK_F_WC = 3, ++ RTW89_RFK_F_DELAY = 4, ++ RTW89_RFK_F_NUM, ++}; ++ ++struct rtw89_rfk_tbl { ++ const struct rtw89_reg5_def *defs; ++ u32 size; ++}; ++ ++#define DECLARE_RFK_TBL(_name) \ ++const struct rtw89_rfk_tbl _name ## _tbl = { \ ++ .defs = _name, \ ++ .size = ARRAY_SIZE(_name), \ ++} ++ ++#define DECL_RFK_WRF(_path, _addr, _mask, _data) \ ++ {.flag = RTW89_RFK_F_WRF, \ ++ .path = _path, \ ++ .addr = _addr, \ ++ .mask = _mask, \ ++ .data = _data,} ++ ++#define DECL_RFK_WM(_addr, _mask, _data) \ ++ {.flag = RTW89_RFK_F_WM, \ ++ .addr = _addr, \ ++ .mask = _mask, \ ++ .data = _data,} ++ ++#define DECL_RFK_WS(_addr, _mask) \ ++ {.flag = RTW89_RFK_F_WS, \ ++ .addr = _addr, \ ++ .mask = _mask,} ++ ++#define DECL_RFK_WC(_addr, _mask) \ ++ {.flag = RTW89_RFK_F_WC, \ ++ .addr = _addr, \ ++ .mask = _mask,} ++ ++#define DECL_RFK_DELAY(_data) \ ++ {.flag = RTW89_RFK_F_DELAY, \ ++ .data = _data,} ++ ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_sys_defs_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_sys_defs_2g_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_sys_defs_5g_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_2g_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_defs_5g_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_dck_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_dck_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_dac_gain_tbl_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_dac_gain_tbl_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_cal_org_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_cal_org_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_rf_gap_tbl_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_rf_gap_tbl_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_slope_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_track_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_track_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txagc_ofst_mv_avg_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_txagc_ofst_mv_avg_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_2g_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_5g_1_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_5g_3_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_a_5g_4_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_2g_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_5g_1_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_5g_3_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_pak_defs_b_5g_4_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_enable_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_enable_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_enable_defs_ab_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_disable_defs_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_tssi_tracking_defs_tbl; ++ ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_afe_init_defs_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_reload_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_reload_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_addc_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_addc_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_reset_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_trigger_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_restore_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_reset_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_trigger_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_addck_restore_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_f_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_f_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_r_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_check_dadc_defs_r_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_f_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_m_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_r_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_f_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_m_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dack_defs_r_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sf_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sr_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sf_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_sr_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_s_defs_ab_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_r_defs_a_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_r_defs_b_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_bb_afe_r_defs_ab_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_lbk_rxiqk_defs_f_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_lbk_rxiqk_defs_r_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_dpk_pas_read_defs_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_set_defs_nondbcc_path01_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_set_defs_dbcc_path0_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_set_defs_dbcc_path1_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_restore_defs_nondbcc_path01_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_restore_defs_dbcc_path0_tbl; ++extern const struct rtw89_rfk_tbl rtw8852a_rfk_iqk_restore_defs_dbcc_path1_tbl; ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c +new file mode 100644 +index 000000000000..3a4fe7207420 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c +@@ -0,0 +1,48725 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "phy.h" ++#include "reg.h" ++#include "rtw8852a_table.h" ++ ++static const struct rtw89_reg2_def rtw89_8852a_phy_bb_regs[] = { ++ {0xF0FF0001, 0x00000000}, ++ {0xF03300FF, 0x00000001}, ++ {0xF03500FF, 0x00000002}, ++ {0xF03200FF, 0x00000003}, ++ {0xF03400FF, 0x00000004}, ++ {0xF03600FF, 0x00000005}, ++ {0x704, 0x601E0100}, ++ {0x714, 0x00000000}, ++ {0x718, 0x13332333}, ++ {0x714, 0x00010000}, ++ {0x720, 0x20000000}, ++ {0x980, 0x10002250}, ++ {0x994, 0x00000010}, ++ {0x644, 0x2314283C}, ++ {0x644, 0x3426283C}, ++ {0x994, 0x00000010}, ++ {0xC3C, 0x2840E1BF}, ++ {0xC40, 0x00000000}, ++ {0xC44, 0x00000007}, ++ {0xC48, 0x410E4000}, ++ {0xC54, 0x1001436E}, ++ {0xC58, 0x41000000}, ++ {0x730, 0x00000002}, ++ {0xC60, 0x017FFFF2}, ++ {0xC64, 0x0010A130}, ++ {0xC64, 0x0010A130}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0xC68, 0x10000068}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0xC68, 0x90000068}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0xC68, 0x90000068}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0xC68, 0x10000068}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0xC68, 0x90000068}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0xC68, 0x90000068}, ++ {0xA0000000, 0x00000000}, ++ {0xC68, 0x10000068}, ++ {0xB0000000, 0x00000000}, ++ {0xC64, 0x0010A130}, ++ {0xC54, 0x1EE1436E}, ++ {0xC6C, 0x00000020}, ++ {0x708, 0x00000000}, ++ {0xC6C, 0x00000020}, ++ {0x804, 0x0043F01D}, ++ {0x12D0, 0x00000000}, ++ {0x12EC, 0x888CA72B}, ++ {0x32D0, 0x00000000}, ++ {0x32EC, 0x888CA72B}, ++ {0xD40, 0xF64FA0F7}, ++ {0xD44, 0x0400063F}, ++ {0xD48, 0x0003FF7F}, ++ {0xD4C, 0x00000000}, ++ {0xD50, 0xF64FA0F7}, ++ {0xD54, 0x04100437}, ++ {0xD58, 0x0000FF7F}, ++ {0xD5C, 0x00000000}, ++ {0xD60, 0x00000000}, ++ {0xD64, 0x00000000}, ++ {0xD70, 0x0000001D}, ++ {0xD90, 0x000003FF}, ++ {0xD94, 0x00000000}, ++ {0xD98, 0x0000003F}, ++ {0xD9C, 0x00000000}, ++ {0xDA0, 0x000003FF}, ++ {0xDA4, 0x00000000}, ++ {0xDA8, 0x0000003F}, ++ {0xDAC, 0x00000000}, ++ {0xD00, 0x77777777}, ++ {0xD04, 0xBBBBBBBB}, ++ {0xD08, 0xBBBBBBBB}, ++ {0xD0C, 0x00000070}, ++ {0xD10, 0x20110900}, ++ {0xD10, 0x20110FFF}, ++ {0xD7C, 0x001D050C}, ++ {0xD84, 0x00006207}, ++ {0xD18, 0x50209900}, ++ {0xD80, 0x00804100}, ++ {0x714, 0x00010000}, ++ {0x704, 0x601E00FD}, ++ {0x710, 0xF3810000}, ++ {0x000, 0x0580801F}, ++ {0x000, 0x8580801F}, ++ {0x334, 0xFFFFFFFF}, ++ {0x33C, 0x55000000}, ++ {0x340, 0x00005555}, ++ {0x724, 0x00111200}, ++ {0x5868, 0xA9550000}, ++ {0x5870, 0x33221100}, ++ {0x5874, 0x77665544}, ++ {0x5878, 0xBBAA9988}, ++ {0x587C, 0xFFEEDDCC}, ++ {0x5880, 0x76543210}, ++ {0x5884, 0xFEDCBA98}, ++ {0x5888, 0x00000000}, ++ {0x588C, 0x00000000}, ++ {0x5894, 0x00000008}, ++ {0x7868, 0xA9550000}, ++ {0x7870, 0x33221100}, ++ {0x7874, 0x77665544}, ++ {0x7878, 0xBBAA9988}, ++ {0x787C, 0xFFEEDDCC}, ++ {0x7880, 0x76543210}, ++ {0x7884, 0xFEDCBA98}, ++ {0x7888, 0x00000000}, ++ {0x788C, 0x00000000}, ++ {0x7894, 0x00000008}, ++ {0x240C, 0x00000000}, ++ {0xC70, 0x00000400}, ++ {0x700, 0x00000030}, ++ {0x704, 0x601E00FF}, ++ {0x704, 0x601E00FD}, ++ {0x704, 0x601E00FF}, ++ {0x586C, 0x000000F0}, ++ {0x586C, 0x000000E0}, ++ {0x586C, 0x000000D0}, ++ {0x586C, 0x000000C0}, ++ {0x586C, 0x000000B0}, ++ {0x586C, 0x000000A0}, ++ {0x586C, 0x00000090}, ++ {0x586C, 0x00000080}, ++ {0x586C, 0x00000070}, ++ {0x586C, 0x00000060}, ++ {0x586C, 0x00000050}, ++ {0x586C, 0x00000040}, ++ {0x586C, 0x00000030}, ++ {0x586C, 0x00000020}, ++ {0x586C, 0x00000010}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x586C, 0x00000000}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x586C, 0x03E00000}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x586C, 0x03E00000}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x586C, 0x00000000}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x586C, 0x03E00000}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x586C, 0x03E00000}, ++ {0xA0000000, 0x00000000}, ++ {0x586C, 0x00000000}, ++ {0xB0000000, 0x00000000}, ++ {0x786C, 0x000000F0}, ++ {0x786C, 0x000000E0}, ++ {0x786C, 0x000000D0}, ++ {0x786C, 0x000000C0}, ++ {0x786C, 0x000000B0}, ++ {0x786C, 0x000000A0}, ++ {0x786C, 0x00000090}, ++ {0x786C, 0x00000080}, ++ {0x786C, 0x00000070}, ++ {0x786C, 0x00000060}, ++ {0x786C, 0x00000050}, ++ {0x786C, 0x00000040}, ++ {0x786C, 0x00000030}, ++ {0x786C, 0x00000020}, ++ {0x786C, 0x00000010}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x786C, 0x00000000}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x786C, 0x03E00000}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x786C, 0x03E00000}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x786C, 0x00000000}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x786C, 0x03E00000}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x786C, 0x03E00000}, ++ {0xA0000000, 0x00000000}, ++ {0x786C, 0x00000000}, ++ {0xB0000000, 0x00000000}, ++ {0x5864, 0x080801FF}, ++ {0x7864, 0x080801FF}, ++ {0xC60, 0x017FFFF3}, ++ {0xC6C, 0x00000021}, ++ {0x58AC, 0x08000000}, ++ {0x78AC, 0x08000000}, ++ {0x5864, 0x180801FF}, ++ {0x7864, 0x180801FF}, ++ {0xC60, 0x017FFFF3}, ++ {0xC60, 0x017FFFF3}, ++ {0x2C60, 0x013FFF0A}, ++ {0xC70, 0x00000600}, ++ {0xC70, 0x00000660}, ++ {0xC6C, 0x10001021}, ++ {0x58AC, 0x08000000}, ++ {0x78AC, 0x08000000}, ++ {0x5864, 0x100801FF}, ++ {0x7864, 0x100801FF}, ++ {0x5864, 0x180801FF}, ++ {0x7864, 0x180801FF}, ++ {0x704, 0x601C01FF}, ++ {0x58D4, 0x0401FE00}, ++ {0x78D4, 0x0401FE00}, ++ {0x58F0, 0x000401FF}, ++ {0x78F0, 0x000401FF}, ++ {0x58F0, 0x400401FF}, ++ {0x78F0, 0x400401FF}, ++ {0x12A8, 0x333378A5}, ++ {0x32A8, 0x333378A5}, ++ {0x2300, 0x02748790}, ++ {0x2304, 0x00558670}, ++ {0x2308, 0x002883F0}, ++ {0x230C, 0x00090120}, ++ {0x2310, 0x00000000}, ++ {0x2314, 0x06000000}, ++ {0x2318, 0x00000000}, ++ {0x231C, 0x00000000}, ++ {0x2320, 0x03020100}, ++ {0x2324, 0x07060504}, ++ {0x2328, 0x0B0A0908}, ++ {0x232C, 0x0F0E0D0C}, ++ {0x2330, 0x13121110}, ++ {0x2334, 0x17161514}, ++ {0x2338, 0x0C700022}, ++ {0x233C, 0x0A05298F}, ++ {0x2340, 0x0005298E}, ++ {0x2344, 0x0006318A}, ++ {0x2348, 0xB7E6318A}, ++ {0x234C, 0x80039CE7}, ++ {0x2350, 0x80039CE7}, ++ {0x2354, 0x0005298F}, ++ {0x2358, 0x0015296E}, ++ {0x235C, 0x0C07FC31}, ++ {0x2360, 0x0219A6AE}, ++ {0x2364, 0xE4F624C3}, ++ {0x2368, 0x53626F15}, ++ {0x236C, 0x48000000}, ++ {0x2370, 0x48000000}, ++ {0x2374, 0x074C0000}, ++ {0x2378, 0x202401B5}, ++ {0x237C, 0x00F7000E}, ++ {0x2380, 0x0F0A1111}, ++ {0x2384, 0x30D9000F}, ++ {0x2388, 0x0400EA02}, ++ {0x238C, 0x003CB061}, ++ {0x2390, 0x69C00000}, ++ {0x2394, 0x00000000}, ++ {0x2398, 0x000000F0}, ++ {0x239C, 0x0001FFFF}, ++ {0x23A0, 0x00C80064}, ++ {0x23A4, 0x0190012C}, ++ {0x23A8, 0x001917BE}, ++ {0x23AC, 0x0B308800}, ++ {0x23B0, 0x0001D5B0}, ++ {0x23B4, 0x000285D2}, ++ {0x23B8, 0x00000000}, ++ {0x23BC, 0x00000000}, ++ {0x23C0, 0x00000000}, ++ {0x23C4, 0x00000000}, ++ {0x23C8, 0x00000000}, ++ {0x23CC, 0x00000000}, ++ {0x23D0, 0x00000000}, ++ {0x23D4, 0x00000000}, ++ {0x23D8, 0x00000000}, ++ {0x23DC, 0x00000000}, ++ {0x23E0, 0x00000000}, ++ {0x23E4, 0x00000000}, ++ {0x23E8, 0x00000000}, ++ {0x23EC, 0x00000000}, ++ {0x23F0, 0x00000000}, ++ {0x23F4, 0x00000000}, ++ {0x23F8, 0x00000000}, ++ {0x23FC, 0x00000000}, ++ {0x804, 0x0043F01D}, ++ {0x300, 0xF30CE31C}, ++ {0x304, 0x13EF1F19}, ++ {0x308, 0x0C0CF3F3}, ++ {0x30C, 0x0C0C0C0C}, ++ {0x310, 0x80416000}, ++ {0x314, 0x0041E000}, ++ {0x318, 0x20022042}, ++ {0x31C, 0x20448001}, ++ {0x320, 0x00410040}, ++ {0x324, 0xE000E000}, ++ {0x328, 0xE000E000}, ++ {0x32C, 0xE000E000}, ++ {0x12BC, 0x10104041}, ++ {0x12C0, 0x14411111}, ++ {0x32BC, 0x10104041}, ++ {0x32C0, 0x14411111}, ++ {0x010, 0x0005FFFF}, ++ {0x604, 0x1E1E1E28}, ++ {0x650, 0x00200888}, ++ {0x620, 0x00141230}, ++ {0x35C, 0x000004C4}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5804, 0x04237040}, ++ {0x7804, 0x04237040}, ++ {0x5808, 0x04237040}, ++ {0x7808, 0x04237040}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5804, 0x04231040}, ++ {0x7804, 0x04231040}, ++ {0x5808, 0x04231040}, ++ {0x7808, 0x04231040}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5804, 0x04231040}, ++ {0x7804, 0x04231040}, ++ {0x5808, 0x04231040}, ++ {0x7808, 0x04231040}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5804, 0x04237040}, ++ {0x7804, 0x04237040}, ++ {0x5808, 0x04237040}, ++ {0x7808, 0x04237040}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5804, 0x04231040}, ++ {0x7804, 0x04231040}, ++ {0x5808, 0x04231040}, ++ {0x7808, 0x04231040}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5804, 0x04231040}, ++ {0x7804, 0x04231040}, ++ {0x5808, 0x04231040}, ++ {0x7808, 0x04231040}, ++ {0xA0000000, 0x00000000}, ++ {0x5804, 0x04237040}, ++ {0x7804, 0x04237040}, ++ {0x5808, 0x04237040}, ++ {0x7808, 0x04237040}, ++ {0xB0000000, 0x00000000}, ++ {0x12A0, 0x24903156}, ++ {0x32A0, 0x24903156}, ++ {0x640, 0x1414141E}, ++ {0x12B8, 0x30020000}, ++ {0x12AC, 0x02333121}, ++ {0x9A4, 0x0000001C}, ++ {0x624, 0x01010301}, ++ {0x628, 0x00010101}, ++ {0x5800, 0x03FF807F}, ++ {0x7800, 0x03FF807F}, ++ {0x4000, 0x00000000}, ++ {0x4004, 0xCA014000}, ++ {0x4008, 0xC751D4F0}, ++ {0x400C, 0x44511475}, ++ {0x4010, 0x00000000}, ++ {0x4014, 0x00000000}, ++ {0x4018, 0x4F4C084B}, ++ {0x401C, 0x084A4E52}, ++ {0x4020, 0x4D504E4B}, ++ {0x4024, 0x4F4C0849}, ++ {0x4028, 0x08484C50}, ++ {0x402C, 0x4C50504C}, ++ {0x4030, 0x5454084A}, ++ {0x4034, 0x084B5654}, ++ {0x4038, 0x6A6C605A}, ++ {0x403C, 0x4C4C084C}, ++ {0x4040, 0x084B4E4D}, ++ {0x4044, 0x4E4C4B4B}, ++ {0x4048, 0x4B4B084A}, ++ {0x404C, 0x084A4E4C}, ++ {0x4050, 0x514F4C4A}, ++ {0x4054, 0x524E084A}, ++ {0x4058, 0x084A5154}, ++ {0x405C, 0x53555554}, ++ {0x4060, 0x45450845}, ++ {0x4064, 0x08454144}, ++ {0x4068, 0x40434445}, ++ {0x406C, 0x44450845}, ++ {0x4070, 0x08444043}, ++ {0x4074, 0x42434444}, ++ {0x4078, 0x46450844}, ++ {0x407C, 0x08444843}, ++ {0x4080, 0x4B4E4A47}, ++ {0x4084, 0x4F4C084B}, ++ {0x4088, 0x084A4E52}, ++ {0x408C, 0x4D504E4B}, ++ {0x4090, 0x4F4C0849}, ++ {0x4094, 0x08484C50}, ++ {0x4098, 0x4C50504C}, ++ {0x409C, 0x5454084A}, ++ {0x40A0, 0x084B5654}, ++ {0x40A4, 0x6A6C605A}, ++ {0x40A8, 0x4C4C084C}, ++ {0x40AC, 0x084B4E4D}, ++ {0x40B0, 0x4E4C4B4B}, ++ {0x40B4, 0x4B4B084A}, ++ {0x40B8, 0x084A4E4C}, ++ {0x40BC, 0x514F4C4A}, ++ {0x40C0, 0x524E084A}, ++ {0x40C4, 0x084A5154}, ++ {0x40C8, 0x53555554}, ++ {0x40CC, 0x45450845}, ++ {0x40D0, 0x08454144}, ++ {0x40D4, 0x40434445}, ++ {0x40D8, 0x44450845}, ++ {0x40DC, 0x08444043}, ++ {0x40E0, 0x42434444}, ++ {0x40E4, 0x46450844}, ++ {0x40E8, 0x08444843}, ++ {0x40EC, 0x4B4E4A47}, ++ {0x40F0, 0x00000000}, ++ {0x40F4, 0x00000006}, ++ {0x40F8, 0x00000001}, ++ {0x40FC, 0x8C30C30C}, ++ {0x4100, 0x4C30C30C}, ++ {0x4104, 0x0C30C30C}, ++ {0x4108, 0x0C30C30C}, ++ {0x410C, 0x0C30C30C}, ++ {0x4110, 0x0C30C30C}, ++ {0x4114, 0x28A28A28}, ++ {0x4118, 0x28A28A28}, ++ {0x411C, 0x28A28A28}, ++ {0x4120, 0x28A28A28}, ++ {0x4124, 0x28A28A28}, ++ {0x4128, 0x28A28A28}, ++ {0x412C, 0x06666666}, ++ {0x4130, 0x33333333}, ++ {0x4134, 0x33333333}, ++ {0x4138, 0x33333333}, ++ {0x413C, 0x00000031}, ++ {0x4140, 0x5100600A}, ++ {0x4144, 0x18363113}, ++ {0x4148, 0x1D976DDC}, ++ {0x414C, 0x1C072DD7}, ++ {0x4150, 0x1127CDF4}, ++ {0x4154, 0x1E37BDF1}, ++ {0x4158, 0x1FB7F1D6}, ++ {0x415C, 0x1EA7DDF9}, ++ {0x4160, 0x1FE445DD}, ++ {0x4164, 0x1F97F1FE}, ++ {0x4168, 0x1FF781ED}, ++ {0x416C, 0x1FA7F5FE}, ++ {0x4170, 0x1E07B913}, ++ {0x4174, 0x1FD7FDFF}, ++ {0x4178, 0x1E17B9FA}, ++ {0x417C, 0x19A66914}, ++ {0x4180, 0x10F65598}, ++ {0x4184, 0x14A5A111}, ++ {0x4188, 0x1D3765DB}, ++ {0x418C, 0x17C685CA}, ++ {0x4190, 0x1107C5F3}, ++ {0x4194, 0x1B5785EB}, ++ {0x4198, 0x1F97ED8F}, ++ {0x419C, 0x1BC7A5F3}, ++ {0x41A0, 0x1FE43595}, ++ {0x41A4, 0x1EB7D9FC}, ++ {0x41A8, 0x1FE65DBE}, ++ {0x41AC, 0x1EC7D9FC}, ++ {0x41B0, 0x1976FCFF}, ++ {0x41B4, 0x1F77F5FF}, ++ {0x41B8, 0x1976FDEC}, ++ {0x41BC, 0x198664EF}, ++ {0x41C0, 0x11062D93}, ++ {0x41C4, 0x10C4E910}, ++ {0x41C8, 0x1CA759DB}, ++ {0x41CC, 0x1335A9B5}, ++ {0x41D0, 0x1097B9F3}, ++ {0x41D4, 0x17B72DE1}, ++ {0x41D8, 0x1F67ED42}, ++ {0x41DC, 0x18074DE9}, ++ {0x41E0, 0x1FD40547}, ++ {0x41E4, 0x1D57ADF9}, ++ {0x41E8, 0x1FE52182}, ++ {0x41EC, 0x1D67B1F9}, ++ {0x41F0, 0x14860CE1}, ++ {0x41F4, 0x1EC7E9FE}, ++ {0x41F8, 0x14860DD6}, ++ {0x41FC, 0x195664C7}, ++ {0x4200, 0x0005E58A}, ++ {0x4204, 0x00000000}, ++ {0x4208, 0x00000000}, ++ {0x420C, 0x7A000000}, ++ {0x4210, 0x0F9F3D7A}, ++ {0x4214, 0x0040817C}, ++ {0x4218, 0x00E10204}, ++ {0x421C, 0x227D94CD}, ++ {0x4220, 0x080238E3}, ++ {0x4224, 0x00000210}, ++ {0x4228, 0x04688000}, ++ {0x422C, 0x0060B002}, ++ {0x4230, 0x9A8249A8}, ++ {0x4234, 0x26A1469E}, ++ {0x4238, 0x2099A824}, ++ {0x423C, 0x2359461C}, ++ {0x4240, 0x1631A675}, ++ {0x4244, 0x2C6B1D63}, ++ {0x4248, 0x0000000E}, ++ {0x424C, 0x00000001}, ++ {0x4250, 0x00000001}, ++ {0x4254, 0x00000000}, ++ {0x4258, 0x00000000}, ++ {0x425C, 0x00000000}, ++ {0x4260, 0x0020000C}, ++ {0x4264, 0x00000000}, ++ {0x4268, 0x00000000}, ++ {0x426C, 0x0418317C}, ++ {0x4270, 0x00D6135C}, ++ {0x4274, 0x00000000}, ++ {0x4278, 0x00000000}, ++ {0x427C, 0x00000000}, ++ {0x4280, 0x00000000}, ++ {0x4284, 0x00000000}, ++ {0x4288, 0x00000000}, ++ {0x428C, 0x00000000}, ++ {0x4290, 0x00000000}, ++ {0x4294, 0x00000000}, ++ {0x4298, 0x84026000}, ++ {0x429C, 0x0051AC20}, ++ {0x42A0, 0x02024008}, ++ {0x42A4, 0x00000000}, ++ {0x42A8, 0x00000000}, ++ {0x42AC, 0x22CE803C}, ++ {0x42B0, 0x80000000}, ++ {0x42B4, 0x00E7D03D}, ++ {0x42B8, 0x3D67D67D}, ++ {0x42BC, 0x7D67D65B}, ++ {0x42C0, 0x2802AF59}, ++ {0x42C4, 0x00280280}, ++ {0x42C8, 0x00000000}, ++ {0x42CC, 0x00000000}, ++ {0x42D0, 0x00000003}, ++ {0x42D4, 0x00000001}, ++ {0x42D8, 0x61861800}, ++ {0x42DC, 0x830C30C3}, ++ {0x42E0, 0xC30C30C3}, ++ {0x42E4, 0x830C30C3}, ++ {0x42E8, 0x451450C3}, ++ {0x42EC, 0x05145145}, ++ {0x42F0, 0x05145145}, ++ {0x42F4, 0x05145145}, ++ {0x42F8, 0x0F0C3145}, ++ {0x42FC, 0x030C30CF}, ++ {0x4300, 0x030C30C3}, ++ {0x4304, 0x030CF3C3}, ++ {0x4308, 0x030C30C3}, ++ {0x430C, 0x0F3CF3C3}, ++ {0x4310, 0x0F3CF3CF}, ++ {0x4314, 0x0F3CF3CF}, ++ {0x4318, 0x0F3CF3CF}, ++ {0x431C, 0x0F3CF3CF}, ++ {0x4320, 0x030C10C3}, ++ {0x4324, 0x051430C3}, ++ {0x4328, 0x051490CB}, ++ {0x432C, 0x030CD151}, ++ {0x4330, 0x050C50C7}, ++ {0x4334, 0x051492CB}, ++ {0x4338, 0x05145145}, ++ {0x433C, 0x05145145}, ++ {0x4340, 0x05145145}, ++ {0x4344, 0x05145145}, ++ {0x4348, 0x090CD3CF}, ++ {0x434C, 0x071491C5}, ++ {0x4350, 0x073CF143}, ++ {0x4354, 0x071431C3}, ++ {0x4358, 0x0F3CF1C5}, ++ {0x435C, 0x0F3CF3CF}, ++ {0x4360, 0x0F3CF3CF}, ++ {0x4364, 0x0F3CF3CF}, ++ {0x4368, 0x0F3CF3CF}, ++ {0x436C, 0x090C91CF}, ++ {0x4370, 0x11243143}, ++ {0x4374, 0x9777A777}, ++ {0x4378, 0xBB7BAC95}, ++ {0x437C, 0xB667B889}, ++ {0x4380, 0x7B9B8899}, ++ {0x4384, 0x7A5567C8}, ++ {0x4388, 0x2278CCCC}, ++ {0x438C, 0x7C222222}, ++ {0x4390, 0x0000069B}, ++ {0x4394, 0x001CCCCC}, ++ {0x4398, 0x00000000}, ++ {0x439C, 0x00000008}, ++ {0x49A4, 0x00000000}, ++ {0x43A0, 0x00000000}, ++ {0x43A4, 0x00000000}, ++ {0x43A8, 0x00000000}, ++ {0x43AC, 0x10000800}, ++ {0x43B0, 0x00401802}, ++ {0x43B4, 0x00061004}, ++ {0x43B8, 0x000024D8}, ++ {0x43BC, 0x00000000}, ++ {0x43C0, 0x10000020}, ++ {0x43C4, 0x20000200}, ++ {0x43C8, 0x00000000}, ++ {0x43CC, 0x04000000}, ++ {0x43D0, 0x44000100}, ++ {0x43D4, 0x60804060}, ++ {0x43D8, 0x44204210}, ++ {0x43DC, 0x82108082}, ++ {0x43E0, 0x82108402}, ++ {0x43E4, 0xC8082108}, ++ {0x43E8, 0xC8202084}, ++ {0x43EC, 0x44208208}, ++ {0x43F0, 0x84108204}, ++ {0x43F4, 0xD0108104}, ++ {0x43F8, 0xF8210108}, ++ {0x43FC, 0x6431E930}, ++ {0x4400, 0x02109468}, ++ {0x4404, 0x10C61C22}, ++ {0x4408, 0x02109469}, ++ {0x440C, 0x10C61C22}, ++ {0x4410, 0x00041049}, ++ {0x4414, 0x00000000}, ++ {0x4418, 0x00000000}, ++ {0x441C, 0x6C000000}, ++ {0x4420, 0xB0200020}, ++ {0x4424, 0x00001FF0}, ++ {0x4428, 0x00000000}, ++ {0x442C, 0x00000000}, ++ {0x4430, 0x00000000}, ++ {0x4434, 0x00000000}, ++ {0x4438, 0x65F962F8}, ++ {0x443C, 0x280668A0}, ++ {0x4440, 0x64100820}, ++ {0x4444, 0x4A146304}, ++ {0x4448, 0x0C59008F}, ++ {0x444C, 0x6E30498A}, ++ {0x4450, 0x656E371B}, ++ {0x4454, 0x00000F52}, ++ {0x4458, 0x00000000}, ++ {0x445C, 0x4801442E}, ++ {0x4460, 0x0041A0B8}, ++ {0x4464, 0x00000000}, ++ {0x4468, 0x00000000}, ++ {0x446C, 0x00000000}, ++ {0x4470, 0x00000000}, ++ {0x4474, 0x00000000}, ++ {0x4478, 0x00000000}, ++ {0x447C, 0x00000000}, ++ {0x4480, 0x2A0A6040}, ++ {0x4484, 0x0A0A6829}, ++ {0x4488, 0x00000004}, ++ {0x448C, 0x00000000}, ++ {0x4490, 0x80000000}, ++ {0x4494, 0x10000000}, ++ {0x4498, 0xA0000000}, ++ {0x449C, 0x0000001E}, ++ {0x44A0, 0x02B29397}, ++ {0x44A4, 0x00000400}, ++ {0x44A8, 0x00000001}, ++ {0x44AC, 0x00000000}, ++ {0x44B0, 0x00000000}, ++ {0x44B4, 0x00000000}, ++ {0x44B8, 0x00000000}, ++ {0x44BC, 0x00000000}, ++ {0x44C0, 0x00000000}, ++ {0x44C4, 0x00000000}, ++ {0x44C8, 0x00000000}, ++ {0x44CC, 0x00000000}, ++ {0x44D0, 0x00000000}, ++ {0x44D4, 0x00000000}, ++ {0x44D8, 0x00000000}, ++ {0x44DC, 0x00000000}, ++ {0x44E0, 0x00000000}, ++ {0x44E4, 0x00000000}, ++ {0x44E8, 0x00000000}, ++ {0x44EC, 0x00000000}, ++ {0x44F0, 0x00000000}, ++ {0x44F4, 0x00000000}, ++ {0x44F8, 0x00000000}, ++ {0x44FC, 0x00000000}, ++ {0x4500, 0x00000000}, ++ {0x4504, 0x00000000}, ++ {0x4508, 0x00000000}, ++ {0x450C, 0x00000000}, ++ {0x4510, 0x00000000}, ++ {0x4514, 0x00000000}, ++ {0x4518, 0x00000000}, ++ {0x451C, 0x00000000}, ++ {0x4520, 0x00000000}, ++ {0x4524, 0x00000000}, ++ {0x4528, 0x00000000}, ++ {0x452C, 0x00000000}, ++ {0x4530, 0x4EA20631}, ++ {0x4534, 0x000005C8}, ++ {0x4538, 0x000000FF}, ++ {0x453C, 0x00000000}, ++ {0x4540, 0x00000000}, ++ {0x4544, 0x00000000}, ++ {0x4548, 0x00000000}, ++ {0x454C, 0x00000000}, ++ {0x4550, 0x00000000}, ++ {0x4554, 0x00000000}, ++ {0x4558, 0x00000000}, ++ {0x455C, 0x00000000}, ++ {0x4560, 0x4060001A}, ++ {0x4564, 0x40000000}, ++ {0x4568, 0x00000000}, ++ {0x456C, 0x20000000}, ++ {0x4570, 0x04800406}, ++ {0x4574, 0x00022270}, ++ {0x4578, 0x0002024B}, ++ {0x457C, 0x00200000}, ++ {0x4580, 0x00009B40}, ++ {0x4584, 0x00000000}, ++ {0x4588, 0x00000063}, ++ {0x458C, 0x30000000}, ++ {0x4590, 0x00000000}, ++ {0x4594, 0x05000000}, ++ {0x4598, 0x00000001}, ++ {0x459C, 0x0003FE00}, ++ {0x45A0, 0x00000000}, ++ {0x45A4, 0x00000000}, ++ {0x45A8, 0xC00001C0}, ++ {0x45AC, 0x78028000}, ++ {0x45B0, 0x80000048}, ++ {0x45B4, 0x01C90800}, ++ {0x45B8, 0x00000002}, ++ {0x45BC, 0x06748790}, ++ {0x45C0, 0x80000000}, ++ {0x45C4, 0x00000000}, ++ {0x45C8, 0x00000000}, ++ {0x45CC, 0x00558670}, ++ {0x45D0, 0x002883F0}, ++ {0x45D4, 0x00090120}, ++ {0x45D8, 0x00000000}, ++ {0x45DC, 0xA3A6D3C4}, ++ {0x49A8, 0xAB27B126}, ++ {0x49AC, 0x00006778}, ++ {0x49FC, 0x000001B5}, ++ {0x49B0, 0x11110F0A}, ++ {0x49B4, 0x00000007}, ++ {0x49B8, 0x0000000A}, ++ {0x49BC, 0x0058BC3F}, ++ {0x49C0, 0x00000003}, ++ {0x49C4, 0x000003D9}, ++ {0x49C8, 0x002B1CB0}, ++ {0x4A00, 0x00000000}, ++ {0x49CC, 0x00000001}, ++ {0x49D0, 0x00000010}, ++ {0x49D4, 0x00000001}, ++ {0x49D8, 0x85298FBF}, ++ {0x49DC, 0x18A5296E}, ++ {0x49E0, 0x18C6298C}, ++ {0x49E4, 0x0A739CA7}, ++ {0x49E8, 0x001A50E7}, ++ {0x49EC, 0x00000001}, ++ {0x49F0, 0x00005924}, ++ {0x49F4, 0x0003AAA6}, ++ {0x49F8, 0x0000C4C3}, ++ {0x45E0, 0x00000000}, ++ {0x45E4, 0x00000000}, ++ {0x45E8, 0x00E2E100}, ++ {0x45EC, 0xCB00B6B6}, ++ {0x45F0, 0x59100FCA}, ++ {0x45F4, 0x08882550}, ++ {0x45F8, 0x08CC2660}, ++ {0x45FC, 0x09102660}, ++ {0x4600, 0x00000154}, ++ {0x4604, 0x00000800}, ++ {0x4608, 0x31BF0400}, ++ {0x460C, 0x00E0C0A0}, ++ {0x4610, 0x30604020}, ++ {0x4614, 0x2F346D50}, ++ {0x4618, 0x2E36B6E2}, ++ {0x461C, 0x3E7EF86B}, ++ {0x4620, 0x001FC004}, ++ {0x4624, 0xA8068010}, ++ {0x4628, 0x4602CA80}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x462C, 0x76067E8C}, ++ {0x4630, 0x8EA350E8}, ++ {0x4634, 0xB3B8D8F5}, ++ {0x4638, 0x6FFF0C06}, ++ {0x463C, 0xB8FA4435}, ++ {0x4640, 0xB7C4FEF8}, ++ {0x4644, 0x2A72AD07}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x462C, 0x76078E8C}, ++ {0x4630, 0x8EDB50F6}, ++ {0x4634, 0xB5B8DD75}, ++ {0x4638, 0x6FFF4C06}, ++ {0x463C, 0xB8FA4434}, ++ {0x4640, 0xB7C4FEF8}, ++ {0x4644, 0x2A72AD07}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x462C, 0x76078E8C}, ++ {0x4630, 0x8EDB50F6}, ++ {0x4634, 0xB5B8DD75}, ++ {0x4638, 0x6FFF4C06}, ++ {0x463C, 0xB8FA4434}, ++ {0x4640, 0xB7C4FEF8}, ++ {0x4644, 0x2A72AD07}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x462C, 0x76067E8C}, ++ {0x4630, 0x8EA350E8}, ++ {0x4634, 0xB3B8D8F5}, ++ {0x4638, 0x6FFF0C06}, ++ {0x463C, 0xB8FA4435}, ++ {0x4640, 0xB7C4FEF8}, ++ {0x4644, 0x2A72AD07}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x462C, 0x76078E8C}, ++ {0x4630, 0x8EDB50F6}, ++ {0x4634, 0xB5B8DD75}, ++ {0x4638, 0x6FFF4C06}, ++ {0x463C, 0xB8FA4434}, ++ {0x4640, 0xB7C4FEF8}, ++ {0x4644, 0x2A72AD07}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x462C, 0x76078E8C}, ++ {0x4630, 0x8EDB50F6}, ++ {0x4634, 0xB5B8DD75}, ++ {0x4638, 0x6FFF4C06}, ++ {0x463C, 0xB8FA4434}, ++ {0x4640, 0xB7C4FEF8}, ++ {0x4644, 0x2A72AD07}, ++ {0xA0000000, 0x00000000}, ++ {0x462C, 0x76067E8C}, ++ {0x4630, 0x8EA350E8}, ++ {0x4634, 0xB3B8D8F5}, ++ {0x4638, 0x6FFF0C06}, ++ {0x463C, 0xB8FA4435}, ++ {0x4640, 0xB7C4FEF8}, ++ {0x4644, 0x2A72AD07}, ++ {0xB0000000, 0x00000000}, ++ {0x4648, 0x64204FB2}, ++ {0x464C, 0x4C823404}, ++ {0x4650, 0x9084C800}, ++ {0x4654, 0x9889314F}, ++ {0x4658, 0x5ECC3FF4}, ++ {0x465C, 0xFEECAECE}, ++ {0x4660, 0x47806638}, ++ {0x4664, 0x0F5AF843}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4668, 0x56452994}, ++ {0x466C, 0x54D89ADB}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4668, 0x55452994}, ++ {0x466C, 0x56D89ADB}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4668, 0x55452994}, ++ {0x466C, 0x56D89ADB}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4668, 0x56452994}, ++ {0x466C, 0x54D89ADB}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4668, 0x55452994}, ++ {0x466C, 0x56D89ADB}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4668, 0x55452994}, ++ {0x466C, 0x56D89ADB}, ++ {0xA0000000, 0x00000000}, ++ {0x4668, 0x56452994}, ++ {0x466C, 0x54D89ADB}, ++ {0xB0000000, 0x00000000}, ++ {0x4670, 0xE8DF38D8}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4674, 0x002ACC30}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4674, 0x0028CC30}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4674, 0x0028CC30}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4674, 0x002ACC30}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4674, 0x0028CC30}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4674, 0x0028CC30}, ++ {0xA0000000, 0x00000000}, ++ {0x4674, 0x002ACC30}, ++ {0xB0000000, 0x00000000}, ++ {0x4678, 0x00000000}, ++ {0x467C, 0x00000000}, ++ {0x4680, 0x00000219}, ++ {0x4684, 0x00000000}, ++ {0x4688, 0x00000000}, ++ {0x468C, 0x00000001}, ++ {0x4690, 0x00000001}, ++ {0x4694, 0x00000000}, ++ {0x4698, 0x00000000}, ++ {0x469C, 0x00000151}, ++ {0x46A0, 0x00000498}, ++ {0x46A4, 0x00000498}, ++ {0x46A8, 0x00000000}, ++ {0x46AC, 0x00000000}, ++ {0x46B0, 0x00001146}, ++ {0x46B4, 0x00000000}, ++ {0x46B8, 0x00000000}, ++ {0x46BC, 0x00E2E100}, ++ {0x46C0, 0xCB00B6B6}, ++ {0x46C4, 0x59100FCA}, ++ {0x46C8, 0x08882550}, ++ {0x46CC, 0x08CC2660}, ++ {0x46D0, 0x09102660}, ++ {0x46D4, 0x00000154}, ++ {0x46D8, 0x00000800}, ++ {0x46DC, 0x31BF0400}, ++ {0x46E0, 0x00E0C0A0}, ++ {0x46E4, 0x30604020}, ++ {0x46E8, 0x4F346D50}, ++ {0x46EC, 0x2E36B6E2}, ++ {0x46F0, 0x3E7EF86B}, ++ {0x46F4, 0x001FC004}, ++ {0x46F8, 0xA8068010}, ++ {0x46FC, 0x4602CA80}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4700, 0x7806FECC}, ++ {0x4704, 0x8EC360F1}, ++ {0x4708, 0xB4C4DA7A}, ++ {0x470C, 0x72FF2CC6}, ++ {0x4710, 0xB8FA4439}, ++ {0x4714, 0xB7C4FEF8}, ++ {0x4718, 0x2A72AD09}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4700, 0x78078ECC}, ++ {0x4704, 0x8EDB60F6}, ++ {0x4708, 0xB5C4DD7A}, ++ {0x470C, 0x72FF4CC6}, ++ {0x4710, 0xB8FA4434}, ++ {0x4714, 0xB7C4FEF8}, ++ {0x4718, 0x2A72AD09}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4700, 0x78078ECC}, ++ {0x4704, 0x8EDB60F6}, ++ {0x4708, 0xB5C4DD7A}, ++ {0x470C, 0x72FF4CC6}, ++ {0x4710, 0xB8FA4434}, ++ {0x4714, 0xB7C4FEF8}, ++ {0x4718, 0x2A72AD09}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4700, 0x7806FECC}, ++ {0x4704, 0x8EC360F1}, ++ {0x4708, 0xB4C4DA7A}, ++ {0x470C, 0x72FF2CC6}, ++ {0x4710, 0xB8FA4439}, ++ {0x4714, 0xB7C4FEF8}, ++ {0x4718, 0x2A72AD09}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4700, 0x78078ECC}, ++ {0x4704, 0x8EDB60F6}, ++ {0x4708, 0xB5C4DD7A}, ++ {0x470C, 0x72FF4CC6}, ++ {0x4710, 0xB8FA4434}, ++ {0x4714, 0xB7C4FEF8}, ++ {0x4718, 0x2A72AD09}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4700, 0x78078ECC}, ++ {0x4704, 0x8EDB60F6}, ++ {0x4708, 0xB5C4DD7A}, ++ {0x470C, 0x72FF4CC6}, ++ {0x4710, 0xB8FA4434}, ++ {0x4714, 0xB7C4FEF8}, ++ {0x4718, 0x2A72AD09}, ++ {0xA0000000, 0x00000000}, ++ {0x4700, 0x7806FECC}, ++ {0x4704, 0x8EC360F1}, ++ {0x4708, 0xB4C4DA7A}, ++ {0x470C, 0x72FF2CC6}, ++ {0x4710, 0xB8FA4439}, ++ {0x4714, 0xB7C4FEF8}, ++ {0x4718, 0x2A72AD09}, ++ {0xB0000000, 0x00000000}, ++ {0x471C, 0x64204FB2}, ++ {0x4720, 0x4C823404}, ++ {0x4724, 0x9084C800}, ++ {0x4728, 0x9889314F}, ++ {0x472C, 0x5ECC3FF4}, ++ {0x4730, 0xFEECAECE}, ++ {0x4734, 0x47806638}, ++ {0x4738, 0x0F4A7843}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x473C, 0x56452994}, ++ {0x4740, 0x54D89ADB}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x473C, 0x55452994}, ++ {0x4740, 0x56D89ADB}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x473C, 0x55452994}, ++ {0x4740, 0x56D89ADB}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x473C, 0x56452994}, ++ {0x4740, 0x54D89ADB}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x473C, 0x55452994}, ++ {0x4740, 0x56D89ADB}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x473C, 0x55452994}, ++ {0x4740, 0x56D89ADB}, ++ {0xA0000000, 0x00000000}, ++ {0x473C, 0x56452994}, ++ {0x4740, 0x54D89ADB}, ++ {0xB0000000, 0x00000000}, ++ {0x4744, 0xE8DF38D8}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4748, 0x002ACC30}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4748, 0x0028CC30}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4748, 0x0028CC30}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4748, 0x002ACC30}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4748, 0x0028CC30}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4748, 0x0028CC30}, ++ {0xA0000000, 0x00000000}, ++ {0x4748, 0x002ACC30}, ++ {0xB0000000, 0x00000000}, ++ {0x474C, 0x00000000}, ++ {0x4750, 0x00000000}, ++ {0x4754, 0x00000219}, ++ {0x4758, 0x00000000}, ++ {0x475C, 0x00000000}, ++ {0x4760, 0x00000001}, ++ {0x4764, 0x00000001}, ++ {0x4768, 0x00000000}, ++ {0x476C, 0x00000000}, ++ {0x4770, 0x00000151}, ++ {0x4774, 0x00000498}, ++ {0x4778, 0x00000498}, ++ {0x477C, 0x00000000}, ++ {0x4780, 0x00000000}, ++ {0x4784, 0x00001147}, ++ {0x4788, 0x00000000}, ++ {0x478C, 0xA32103FE}, ++ {0x4790, 0x320A7B28}, ++ {0x4794, 0xC6A7B14F}, ++ {0x4798, 0x000006D7}, ++ {0x479C, 0x009B902A}, ++ {0x47A0, 0x009B902A}, ++ {0x47A4, 0x98682C18}, ++ {0x47A8, 0x6308C4C1}, ++ {0x47AC, 0x6248C631}, ++ {0x47B0, 0x922A8253}, ++ {0x47B4, 0x00000005}, ++ {0x47B8, 0x00001759}, ++ {0x47BC, 0x4B802000}, ++ {0x47C0, 0x831408BE}, ++ {0x47C4, 0x9ABBCACB}, ++ {0x47C8, 0x56767578}, ++ {0x47CC, 0xBBCCBBB3}, ++ {0x47D0, 0x57889989}, ++ {0x47D4, 0x00000F45}, ++ {0x47D8, 0x27039CE9}, ++ {0x47DC, 0x31413432}, ++ {0x47E0, 0x26058342}, ++ {0x47E4, 0x00000006}, ++ {0x47E8, 0x00000005}, ++ {0x47EC, 0x00000005}, ++ {0x47F0, 0xC7013016}, ++ {0x47F4, 0x84413016}, ++ {0x47F8, 0x84413016}, ++ {0x47FC, 0x8C413016}, ++ {0x4800, 0x8C40B028}, ++ {0x4804, 0x3140B028}, ++ {0x4808, 0x2940B028}, ++ {0x480C, 0x8440B028}, ++ {0x4810, 0x2318C610}, ++ {0x4814, 0x45334753}, ++ {0x4818, 0x236A6A88}, ++ {0x481C, 0x576DF814}, ++ {0x4820, 0xA08877AC}, ++ {0x4824, 0x0000087A}, ++ {0x4828, 0xBCEB4A14}, ++ {0x482C, 0x000A3A4A}, ++ {0x4830, 0xBCEB4A14}, ++ {0x4834, 0x000A3A4A}, ++ {0x4838, 0xBCBDBD85}, ++ {0x483C, 0x0CABB99A}, ++ {0x4840, 0x38384242}, ++ {0x4844, 0x8086102E}, ++ {0x4848, 0xCA24C82A}, ++ {0x484C, 0x00008A62}, ++ {0x4850, 0x00000008}, ++ {0x4854, 0x009B902A}, ++ {0x4858, 0x009B902A}, ++ {0x485C, 0x98682C18}, ++ {0x4860, 0x6308C4C1}, ++ {0x4864, 0x6248C631}, ++ {0x4868, 0x922A8253}, ++ {0x486C, 0x00000005}, ++ {0x4870, 0x00001759}, ++ {0x4874, 0x4B802000}, ++ {0x4878, 0x831408BE}, ++ {0x487C, 0x9898A8BB}, ++ {0x4880, 0x54535368}, ++ {0x4884, 0x999999B3}, ++ {0x4888, 0x35555589}, ++ {0x488C, 0x00000745}, ++ {0x4890, 0x27039CE9}, ++ {0x4894, 0x31413432}, ++ {0x4898, 0x26058342}, ++ {0x489C, 0x00000006}, ++ {0x48A0, 0x00000005}, ++ {0x48A4, 0x00000005}, ++ {0x48A8, 0xC7013016}, ++ {0x48AC, 0x84413016}, ++ {0x48B0, 0x84413016}, ++ {0x48B4, 0x8C413016}, ++ {0x48B8, 0x8C40B028}, ++ {0x48BC, 0x3140B028}, ++ {0x48C0, 0x2940B028}, ++ {0x48C4, 0x8440B028}, ++ {0x48C8, 0x2318C610}, ++ {0x48CC, 0x45334753}, ++ {0x48D0, 0x236A6A88}, ++ {0x48D4, 0x576DF814}, ++ {0x48D8, 0xA08877AC}, ++ {0x48DC, 0x0000007A}, ++ {0x48E0, 0xBCEB4A14}, ++ {0x48E4, 0x000A3A4A}, ++ {0x48E8, 0xBCEB4A14}, ++ {0x48EC, 0x000A3A4A}, ++ {0x48F0, 0x9A8A8A85}, ++ {0x48F4, 0x0CA3B99A}, ++ {0x48F8, 0x38384242}, ++ {0x48FC, 0x8086102E}, ++ {0x4900, 0xCA24C82A}, ++ {0x4904, 0x00008A62}, ++ {0x4908, 0x00000008}, ++ {0x490C, 0x80040000}, ++ {0x4910, 0x80040000}, ++ {0x4914, 0xFE800000}, ++ {0x4918, 0x834C0000}, ++ {0x491C, 0x00000000}, ++ {0x4920, 0x00000000}, ++ {0x4924, 0x00000000}, ++ {0x4928, 0x00000000}, ++ {0x492C, 0x00000000}, ++ {0x4930, 0x00000000}, ++ {0x4934, 0x40000000}, ++ {0x4938, 0x00000000}, ++ {0x493C, 0x00000000}, ++ {0x4940, 0x00000000}, ++ {0x4944, 0x00000000}, ++ {0x4948, 0x04065800}, ++ {0x494C, 0x32004080}, ++ {0x4950, 0x0E1E3E05}, ++ {0x4954, 0x0A163068}, ++ {0x4958, 0x00206040}, ++ {0x495C, 0x02020202}, ++ {0x4960, 0x00A16020}, ++ {0x4964, 0x031F4284}, ++ {0x4968, 0x00A10285}, ++ {0x496C, 0x00000005}, ++ {0x4970, 0x00000000}, ++ {0x4974, 0x800CD62D}, ++ {0x4978, 0x00000103}, ++ {0x497C, 0x00000000}, ++ {0x4980, 0x00000000}, ++ {0x4984, 0x00000000}, ++ {0x4988, 0x00000000}, ++ {0x498C, 0x00000000}, ++ {0x4990, 0x00000000}, ++ {0x4994, 0x00000000}, ++ {0x4998, 0x00000000}, ++ {0x499C, 0x00000000}, ++ {0x49A0, 0x00000000}, ++ {0x2404, 0x00000001}, ++ {0xC7C, 0x0000BFE0}, ++ {0x020, 0x0000F381}, ++ {0x024, 0x0000F381}, ++ {0x028, 0x0000F381}, ++ {0x02C, 0x0000F381}, ++ {0xD78, 0x00000005}, ++ {0x12CC, 0x00000CC1}, ++ {0x12D0, 0x00000000}, ++ {0x12D4, 0x00000000}, ++ {0x12D8, 0x00000040}, ++ {0x12DC, 0x4486888C}, ++ {0x12E0, 0xC43A10E1}, ++ {0x12E4, 0x30D52C68}, ++ {0x12E8, 0x02024128}, ++ {0x12EC, 0x888C272B}, ++ {0x12EC, 0x888CA72B}, ++ {0x32CC, 0x00000CC1}, ++ {0x32D0, 0x00000000}, ++ {0x32D4, 0x00000000}, ++ {0x32D8, 0x00000040}, ++ {0x32DC, 0x4486888C}, ++ {0x32E0, 0xC43A10E1}, ++ {0x32E4, 0x30D52C68}, ++ {0x32E8, 0x02024128}, ++ {0x32EC, 0x888C272B}, ++ {0x32EC, 0x888CA72B}, ++ {0x12AC, 0x12333121}, ++ {0x32AC, 0x12333121}, ++ {0x738, 0x004100CC}, ++ {0x80ff0001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5820, 0x80001080}, ++ {0x7820, 0x80001080}, ++ {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5820, 0xC0001080}, ++ {0x7820, 0xC0001080}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5820, 0xC0001080}, ++ {0x7820, 0xC0001080}, ++ {0x903200ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5820, 0x80001080}, ++ {0x7820, 0x80001080}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5820, 0x80001080}, ++ {0x7820, 0x80001080}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x5820, 0x80001080}, ++ {0x7820, 0x80001080}, ++ {0xA0000000, 0x00000000}, ++ {0x5820, 0x80001080}, ++ {0x7820, 0x80001080}, ++ {0xB0000000, 0x00000000}, ++ {0x2000, 0x18BBBF84}, ++ {0x0F0, 0x00000002}, ++ {0x0F4, 0x00000016}, ++ {0x0F8, 0x20201013}, ++}; ++ ++static const struct rtw89_reg2_def rtw89_8852a_phy_radioa_regs[] = { ++ {0xF0010000, 0x00000000}, ++ {0xF0010001, 0x00000001}, ++ {0xF0020001, 0x00000002}, ++ {0xF0030001, 0x00000003}, ++ {0xF0250001, 0x00000004}, ++ {0xF0260001, 0x00000005}, ++ {0xF0320001, 0x00000006}, ++ {0xF0330001, 0x00000007}, ++ {0xF0340001, 0x00000008}, ++ {0xF0350001, 0x00000009}, ++ {0xF0360001, 0x0000000A}, ++ {0xF0010002, 0x0000000B}, ++ {0xF0020002, 0x0000000C}, ++ {0xF0030002, 0x0000000D}, ++ {0xF0250002, 0x0000000E}, ++ {0xF0260002, 0x0000000F}, ++ {0xF0320002, 0x00000010}, ++ {0xF0330002, 0x00000011}, ++ {0xF0340002, 0x00000012}, ++ {0xF0350002, 0x00000013}, ++ {0xF0360002, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000001}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x005, 0x00000001}, ++ {0xB0000000, 0x00000000}, ++ {0x000, 0x00030000}, ++ {0x018, 0x00011124}, ++ {0x000, 0x00033C00}, ++ {0x01A, 0x00040004}, ++ {0x0FE, 0x00000000}, ++ {0x055, 0x00080000}, ++ {0x056, 0x0008FFF0}, ++ {0x057, 0x0000C485}, ++ {0x058, 0x000A4164}, ++ {0x059, 0x00010000}, ++ {0x05A, 0x00060000}, ++ {0x05B, 0x0000A000}, ++ {0x05C, 0x00000000}, ++ {0x05D, 0x0001C013}, ++ {0x05E, 0x00000000}, ++ {0x05F, 0x00001FF0}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0xA0000000, 0x00000000}, ++ {0x060, 0x00011000}, ++ {0xB0000000, 0x00000000}, ++ {0x061, 0x0009F338}, ++ {0x062, 0x0009233A}, ++ {0x063, 0x000D6002}, ++ {0x064, 0x000A0CB0}, ++ {0x065, 0x00030EFE}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0xA0000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0xB0000000, 0x00000000}, ++ {0x068, 0x00000000}, ++ {0x069, 0x00030F0A}, ++ {0x06A, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000AD6A4}, ++ {0x052, 0x00091345}, ++ {0x053, 0x00080081}, ++ {0x054, 0x0009BC24}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0xA0000000, 0x00000000}, ++ {0x051, 0x000AD6A4}, ++ {0x052, 0x00091345}, ++ {0x053, 0x00080081}, ++ {0x054, 0x0009BC24}, ++ {0xB0000000, 0x00000000}, ++ {0x0D3, 0x00000143}, ++ {0x043, 0x00005000}, ++ {0x0DD, 0x000003A0}, ++ {0x0B0, 0x000E6700}, ++ {0x0AF, 0x0001F82E}, ++ {0x0B2, 0x000210A7}, ++ {0x0B1, 0x00065FFF}, ++ {0x0BB, 0x000F7A00}, ++ {0x0B3, 0x00013F7A}, ++ {0x0D4, 0x0000000E}, ++ {0x0B7, 0x00001E0C}, ++ {0x0A0, 0x0000004F}, ++ {0x0B4, 0x0007C03E}, ++ {0x0B5, 0x0007E301}, ++ {0x0B6, 0x00080800}, ++ {0x0CA, 0x00002000}, ++ {0x0DD, 0x000003A0}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x00080000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0xA0000000, 0x00000000}, ++ {0x0CC, 0x00080000}, ++ {0xB0000000, 0x00000000}, ++ {0x0A1, 0x0006F300}, ++ {0x0A2, 0x00080500}, ++ {0x0A3, 0x0008050B}, ++ {0x0A4, 0x0006DB12}, ++ {0x0A5, 0x00000000}, ++ {0x0A6, 0x00000000}, ++ {0x0A7, 0x00000000}, ++ {0x0A8, 0x00000000}, ++ {0x0A9, 0x00000000}, ++ {0x0AA, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x000B0000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0A5, 0x000B0000}, ++ {0xB0000000, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00008000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0ED, 0x00008000}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000000}, ++ {0x03E, 0x00008000}, ++ {0x03F, 0x000E1333}, ++ {0x033, 0x00000001}, ++ {0x03E, 0x00008000}, ++ {0x03F, 0x000E7333}, ++ {0x033, 0x00000002}, ++ {0x03E, 0x00008000}, ++ {0x03F, 0x000FA000}, ++ {0x033, 0x00000003}, ++ {0x03E, 0x00004000}, ++ {0x03F, 0x000FA400}, ++ {0x033, 0x00000004}, ++ {0x03E, 0x00004000}, ++ {0x03F, 0x000F5000}, ++ {0x033, 0x00000005}, ++ {0x03E, 0x00004001}, ++ {0x03F, 0x00029400}, ++ {0x033, 0x00000006}, ++ {0x03E, 0x0000AAA1}, ++ {0x03F, 0x00041999}, ++ {0x033, 0x00000007}, ++ {0x03E, 0x0000AAA1}, ++ {0x03F, 0x00034444}, ++ {0x033, 0x00000008}, ++ {0x03E, 0x0000AAA1}, ++ {0x03F, 0x0004D555}, ++ {0x033, 0x00000009}, ++ {0x03E, 0x00005551}, ++ {0x03F, 0x00046AAA}, ++ {0x033, 0x0000000A}, ++ {0x03E, 0x00005551}, ++ {0x03F, 0x00046AAA}, ++ {0x033, 0x0000000B}, ++ {0x03E, 0x00005551}, ++ {0x03F, 0x0008C555}, ++ {0x033, 0x0000000C}, ++ {0x03E, 0x0000CCC1}, ++ {0x03F, 0x00081EB8}, ++ {0x033, 0x0000000D}, ++ {0x03E, 0x0000CCC1}, ++ {0x03F, 0x00071EB8}, ++ {0x033, 0x0000000E}, ++ {0x03E, 0x0000CCC1}, ++ {0x03F, 0x00090000}, ++ {0x033, 0x0000000F}, ++ {0x03E, 0x00006661}, ++ {0x03F, 0x00088000}, ++ {0x033, 0x00000010}, ++ {0x03E, 0x00006661}, ++ {0x03F, 0x00088000}, ++ {0x033, 0x00000011}, ++ {0x03E, 0x00006661}, ++ {0x03F, 0x000DB999}, ++ {0x0ED, 0x00000000}, ++ {0x0ED, 0x00002000}, ++ {0x033, 0x00000002}, ++ {0x03D, 0x0004A883}, ++ {0x03E, 0x00000000}, ++ {0x03F, 0x00000001}, ++ {0x033, 0x00000006}, ++ {0x03D, 0x0004A883}, ++ {0x03E, 0x00000000}, ++ {0x03F, 0x00000001}, ++ {0x0ED, 0x00000000}, ++ {0x018, 0x00001001}, ++ {0x002, 0x0000000D}, ++ {0x0EE, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0xA0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0xB0000000, 0x00000000}, ++ {0x0EE, 0x00000000}, ++ {0x08F, 0x000D0F7A}, ++ {0x08C, 0x00084584}, ++ {0x0EF, 0x00004000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000500}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000500}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00008B00}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00008B00}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00001000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00000015}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00000017}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00008000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x000FECFC}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x000BECFC}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x0003E4FC}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x0001D0FC}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x0001C3FC}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x000103FC}, ++ {0x033, 0x00000006}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x000FECFC}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x000BECFC}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x0003E4FC}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0001D0FC}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x0001C3FC}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x000103FC}, ++ {0x033, 0x0000000E}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x0000000F}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000010}, ++ {0x03F, 0x000FECFC}, ++ {0x033, 0x00000011}, ++ {0x03F, 0x000BECFC}, ++ {0x033, 0x00000012}, ++ {0x03F, 0x0003E4FC}, ++ {0x033, 0x00000013}, ++ {0x03F, 0x0001D0FC}, ++ {0x033, 0x00000014}, ++ {0x03F, 0x0001C3FC}, ++ {0x033, 0x00000015}, ++ {0x03F, 0x000103FC}, ++ {0x033, 0x00000016}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000017}, ++ {0x03F, 0x0000007C}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000100}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00003317}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x00003317}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x00003317}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001A}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001B}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001C}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001D}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001E}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001F}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000020}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000021}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000022}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000023}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000024}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000025}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000026}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000027}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000028}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000029}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002A}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002B}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002C}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002D}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002E}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002F}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000030}, ++ {0x03F, 0x00003338}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000040}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000006}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x000004BA}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000010}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x00000430}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000430}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x03F, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000080}, ++ {0x033, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F358}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F358}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00023458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00023858}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x03E, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00023758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002E758}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000023}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000024}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000025}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000026}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000027}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002E658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00027758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C758}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000E}, ++ {0x03F, 0x0002F658}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EE, 0x00002000}, ++ {0x033, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000068}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000068}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000023}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000024}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000025}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000026}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000027}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000040}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000041}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000042}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000043}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000044}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000045}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000046}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000047}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000048}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000049}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000050}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000051}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000052}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000053}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000054}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000055}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000056}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000057}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000058}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000059}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000060}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000061}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000062}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000063}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000064}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000065}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000066}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000067}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000068}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000069}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000070}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000071}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000072}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000073}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000074}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000075}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000076}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000077}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000078}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000079}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000080}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000081}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000082}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000083}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000084}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000085}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000086}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000087}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x0EE, 0x00000000}, ++ {0x0EE, 0x00004000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00003BEF}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00003BE9}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x00003BE3}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x00003BDD}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x00003BD7}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x00003BD1}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00001BD9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000BD9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000859}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000859}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000819}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000819}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x03F, 0x000039EE}, ++ {0x033, 0x00000013}, ++ {0x03F, 0x000039E8}, ++ {0x033, 0x00000014}, ++ {0x03F, 0x000039E2}, ++ {0x033, 0x00000015}, ++ {0x03F, 0x000039DC}, ++ {0x033, 0x00000016}, ++ {0x03F, 0x000039D6}, ++ {0x033, 0x00000017}, ++ {0x03F, 0x000039D0}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x03F, 0x000019D2}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x03F, 0x000009D2}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x0000001E}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000023}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x00000024}, ++ {0x03F, 0x000039EE}, ++ {0x033, 0x00000025}, ++ {0x03F, 0x000039E8}, ++ {0x033, 0x00000026}, ++ {0x03F, 0x000039E2}, ++ {0x033, 0x00000027}, ++ {0x03F, 0x000039DC}, ++ {0x033, 0x00000028}, ++ {0x03F, 0x000039D6}, ++ {0x033, 0x00000029}, ++ {0x03F, 0x000039D0}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x03F, 0x000019D2}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x03F, 0x000009D2}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000030}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000035}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x00000036}, ++ {0x03F, 0x000039EE}, ++ {0x033, 0x00000037}, ++ {0x03F, 0x000039E8}, ++ {0x033, 0x00000038}, ++ {0x03F, 0x000039E2}, ++ {0x033, 0x00000039}, ++ {0x03F, 0x000039DC}, ++ {0x033, 0x0000003A}, ++ {0x03F, 0x000039D6}, ++ {0x033, 0x0000003B}, ++ {0x03F, 0x000039D0}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x03F, 0x000019D2}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x03F, 0x000009D2}, ++ {0x033, 0x00000040}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000041}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000042}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000043}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000044}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000045}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000046}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000047}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x00000048}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000049}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000050}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000051}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000052}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000053}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000054}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000055}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000056}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000057}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000058}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000059}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x0000005A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000060}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000061}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000062}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000063}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000064}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000065}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000066}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000067}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000068}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000069}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006A}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x0000006B}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x0000006C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000070}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000071}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000072}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000073}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000074}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000075}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000076}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000077}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000078}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000079}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007A}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x0000007B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007C}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x0000007D}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x0000007E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000080}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000081}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000082}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000083}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000084}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000085}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000086}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000087}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000088}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000089}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x0000008A}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x0000008B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000008C}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x0000008D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000008E}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x0000008F}, ++ {0x03F, 0x00000807}, ++ {0x0EE, 0x00000000}, ++ {0x0EF, 0x00080000}, ++ {0x033, 0x00000007}, ++ {0x03E, 0x00000001}, ++ {0x03F, 0x00020F3C}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00080000}, ++ {0x033, 0x0000000C}, ++ {0x03E, 0x00000001}, ++ {0x03F, 0x000305BC}, ++ {0x0EF, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000001}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0EC, 0x00000001}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x03C, 0x00000020}, ++ {0x03D, 0x00000078}, ++ {0x03E, 0x00080000}, ++ {0x03F, 0x00001999}, ++ {0x0EC, 0x00000000}, ++ {0x02F, 0x0002260D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000001}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0DE, 0x00000001}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000002}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00000002}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00000002}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000400}, ++ {0x033, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000023}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000024}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000025}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000026}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000027}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000200}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000006}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000E}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000F}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000010}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000011}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000012}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000013}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000014}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000015}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000016}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000017}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000018}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000019}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001A}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001B}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001C}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001D}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001E}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001F}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000020}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000021}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000022}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000023}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000024}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000025}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000026}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000027}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0xA0000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0xB0000000, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0xA0000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0xB0000000, 0x00000000}, ++ {0x06D, 0x00000C31}, ++ {0x0EF, 0x00020000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x000005FF}, ++ {0x0EF, 0x00000000}, ++ {0x005, 0x00000001}, ++ {0x0EF, 0x00080000}, ++ {0x033, 0x00000001}, ++ {0x03E, 0x00000001}, ++ {0x03F, 0x00022020}, ++ {0x0EF, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0xA0000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0xB0000000, 0x00000000}, ++ {0x002, 0x00000000}, ++ {0x067, 0x00000052}, ++ ++}; ++ ++static const struct rtw89_reg2_def rtw89_8852a_phy_radiob_regs[] = { ++ {0xF0010000, 0x00000000}, ++ {0xF0010001, 0x00000001}, ++ {0xF0020001, 0x00000002}, ++ {0xF0030001, 0x00000003}, ++ {0xF0250001, 0x00000004}, ++ {0xF0260001, 0x00000005}, ++ {0xF0320001, 0x00000006}, ++ {0xF0330001, 0x00000007}, ++ {0xF0340001, 0x00000008}, ++ {0xF0350001, 0x00000009}, ++ {0xF0360001, 0x0000000A}, ++ {0xF0010002, 0x0000000B}, ++ {0xF0020002, 0x0000000C}, ++ {0xF0030002, 0x0000000D}, ++ {0xF0250002, 0x0000000E}, ++ {0xF0260002, 0x0000000F}, ++ {0xF0320002, 0x00000010}, ++ {0xF0330002, 0x00000011}, ++ {0xF0340002, 0x00000012}, ++ {0xF0350002, 0x00000013}, ++ {0xF0360002, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000001}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x005, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x005, 0x00000001}, ++ {0xB0000000, 0x00000000}, ++ {0x000, 0x00030000}, ++ {0x018, 0x00011124}, ++ {0x000, 0x00033C00}, ++ {0x01A, 0x00040004}, ++ {0x0FE, 0x00000000}, ++ {0x055, 0x00080000}, ++ {0x056, 0x0008FFF0}, ++ {0x057, 0x0000C485}, ++ {0x058, 0x000A4164}, ++ {0x059, 0x00010000}, ++ {0x05A, 0x00060000}, ++ {0x05B, 0x0000A000}, ++ {0x05C, 0x00000000}, ++ {0x05D, 0x0001C013}, ++ {0x05E, 0x00000000}, ++ {0x05F, 0x00001FF0}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x060, 0x00011008}, ++ {0xA0000000, 0x00000000}, ++ {0x060, 0x00011000}, ++ {0xB0000000, 0x00000000}, ++ {0x061, 0x0009F338}, ++ {0x062, 0x0009233A}, ++ {0x063, 0x000D6002}, ++ {0x064, 0x000A0CB0}, ++ {0x065, 0x00030EFE}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x066, 0x00020000}, ++ {0xA0000000, 0x00000000}, ++ {0x066, 0x00010000}, ++ {0xB0000000, 0x00000000}, ++ {0x068, 0x00000000}, ++ {0x069, 0x00030F0A}, ++ {0x06A, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000AD6A4}, ++ {0x052, 0x00091345}, ++ {0x053, 0x00080081}, ++ {0x054, 0x0007BC24}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x051, 0x000BD267}, ++ {0x052, 0x00091345}, ++ {0x053, 0x000B0081}, ++ {0x054, 0x0007BCA4}, ++ {0xA0000000, 0x00000000}, ++ {0x051, 0x000AD6A4}, ++ {0x052, 0x00091345}, ++ {0x053, 0x00080081}, ++ {0x054, 0x0007BC24}, ++ {0xB0000000, 0x00000000}, ++ {0x0D3, 0x00000143}, ++ {0x043, 0x00005000}, ++ {0x0DD, 0x000003A0}, ++ {0x0B0, 0x000E6700}, ++ {0x0AF, 0x0001F82E}, ++ {0x0B2, 0x000210A7}, ++ {0x0B1, 0x00065FFF}, ++ {0x0BB, 0x000F7A00}, ++ {0x0B3, 0x00013F7A}, ++ {0x0D4, 0x0000000E}, ++ {0x0B7, 0x00001E0C}, ++ {0x0A0, 0x0000004F}, ++ {0x0B4, 0x0007C03E}, ++ {0x0B5, 0x0007E301}, ++ {0x0B6, 0x00080800}, ++ {0x0CA, 0x00002000}, ++ {0x0DD, 0x000003A0}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x00080000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0CC, 0x000E0000}, ++ {0xA0000000, 0x00000000}, ++ {0x0CC, 0x00080000}, ++ {0xB0000000, 0x00000000}, ++ {0x0A1, 0x0006F300}, ++ {0x0A2, 0x00080500}, ++ {0x0A3, 0x0008050B}, ++ {0x0A4, 0x0006DB12}, ++ {0x0A5, 0x00000000}, ++ {0x0A6, 0x00000000}, ++ {0x0A7, 0x00000000}, ++ {0x0A8, 0x00000000}, ++ {0x0A9, 0x00000000}, ++ {0x0AA, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x000B0000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0A5, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0A5, 0x000B0000}, ++ {0xB0000000, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00008000}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0ED, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0ED, 0x00008000}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000000}, ++ {0x03E, 0x00008000}, ++ {0x03F, 0x000E1333}, ++ {0x033, 0x00000001}, ++ {0x03E, 0x00008000}, ++ {0x03F, 0x000E7333}, ++ {0x033, 0x00000002}, ++ {0x03E, 0x00008000}, ++ {0x03F, 0x000FA000}, ++ {0x033, 0x00000003}, ++ {0x03E, 0x00004000}, ++ {0x03F, 0x000FA400}, ++ {0x033, 0x00000004}, ++ {0x03E, 0x00004000}, ++ {0x03F, 0x000F5000}, ++ {0x033, 0x00000005}, ++ {0x03E, 0x00004001}, ++ {0x03F, 0x00029400}, ++ {0x033, 0x00000006}, ++ {0x03E, 0x0000AAA1}, ++ {0x03F, 0x00041999}, ++ {0x033, 0x00000007}, ++ {0x03E, 0x0000AAA1}, ++ {0x03F, 0x00034444}, ++ {0x033, 0x00000008}, ++ {0x03E, 0x0000AAA1}, ++ {0x03F, 0x0004D555}, ++ {0x033, 0x00000009}, ++ {0x03E, 0x00005551}, ++ {0x03F, 0x00046AAA}, ++ {0x033, 0x0000000A}, ++ {0x03E, 0x00005551}, ++ {0x03F, 0x00046AAA}, ++ {0x033, 0x0000000B}, ++ {0x03E, 0x00005551}, ++ {0x03F, 0x0008C555}, ++ {0x033, 0x0000000C}, ++ {0x03E, 0x0000CCC1}, ++ {0x03F, 0x00081EB8}, ++ {0x033, 0x0000000D}, ++ {0x03E, 0x0000CCC1}, ++ {0x03F, 0x00071EB8}, ++ {0x033, 0x0000000E}, ++ {0x03E, 0x0000CCC1}, ++ {0x03F, 0x00090000}, ++ {0x033, 0x0000000F}, ++ {0x03E, 0x00006661}, ++ {0x03F, 0x00088000}, ++ {0x033, 0x00000010}, ++ {0x03E, 0x00006661}, ++ {0x03F, 0x00088000}, ++ {0x033, 0x00000011}, ++ {0x03E, 0x00006661}, ++ {0x03F, 0x000DB999}, ++ {0x0ED, 0x00000000}, ++ {0x0ED, 0x00002000}, ++ {0x033, 0x00000002}, ++ {0x03D, 0x0004A883}, ++ {0x03E, 0x00000000}, ++ {0x03F, 0x00000001}, ++ {0x033, 0x00000006}, ++ {0x03D, 0x0004A883}, ++ {0x03E, 0x00000000}, ++ {0x03F, 0x00000001}, ++ {0x0ED, 0x00000000}, ++ {0x018, 0x00001001}, ++ {0x002, 0x0000000D}, ++ {0x0EE, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000A}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000011}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000018}, ++ {0xA0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0000000B}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000012}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000019}, ++ {0xB0000000, 0x00000000}, ++ {0x0EE, 0x00000000}, ++ {0x08F, 0x000D0F7A}, ++ {0x08C, 0x00084584}, ++ {0x0EF, 0x00004000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004700}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000700}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000500}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000B0600}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00094600}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000500}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4500}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000400}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00008B00}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00038B00}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000D4400}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00008B00}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00014B00}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000B00}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004A00}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00001A00}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00004900}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00002900}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00001000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00000015}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00000017}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x00000015}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x00000017}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00008000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x000FECFC}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x000BECFC}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x0003E4FC}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x0001D0FC}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x0001C3FC}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x000103FC}, ++ {0x033, 0x00000006}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x000FECFC}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x000BECFC}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x0003E4FC}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x0001D0FC}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x0001C3FC}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x000103FC}, ++ {0x033, 0x0000000E}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x0000000F}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000010}, ++ {0x03F, 0x000FECFC}, ++ {0x033, 0x00000011}, ++ {0x03F, 0x000BECFC}, ++ {0x033, 0x00000012}, ++ {0x03F, 0x0003E4FC}, ++ {0x033, 0x00000013}, ++ {0x03F, 0x0001D0FC}, ++ {0x033, 0x00000014}, ++ {0x03F, 0x0001C3FC}, ++ {0x033, 0x00000015}, ++ {0x03F, 0x000103FC}, ++ {0x033, 0x00000016}, ++ {0x03F, 0x0000007C}, ++ {0x033, 0x00000017}, ++ {0x03F, 0x0000007C}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000100}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00003317}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x00003317}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x00003317}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003336}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003338}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003337}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00003356}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001A}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001B}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001C}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001D}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001E}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000001F}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000020}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000021}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000022}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000023}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000024}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000025}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000026}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000027}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000028}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000029}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002A}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002B}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002C}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002D}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002E}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x0000002F}, ++ {0x03F, 0x00003338}, ++ {0x033, 0x00000030}, ++ {0x03F, 0x00003338}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000040}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000006}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x000004BA}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x000004BA}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000010}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000730}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000430}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x00000CB0}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x00000870}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x00000430}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x00000430}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x03F, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000080}, ++ {0x033, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F258}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F258}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00036458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0003C458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026658}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00026458}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00028558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C358}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0002C558}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000023}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000024}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000025}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000026}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000027}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F358}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002F358}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F258}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023758}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00023558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00025558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x00024558}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000C}, ++ {0x03F, 0x0002C558}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xA0000000, 0x00000000}, ++ {0x03E, 0x0000000B}, ++ {0x03F, 0x0006F458}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EE, 0x00002000}, ++ {0x033, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000166}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000163}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000068}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000068}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F5}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F2}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A5}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A2}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000053}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000023}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000024}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000025}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000026}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000027}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000070}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000067}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000064}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000061}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000058}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E5}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000055}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000E2}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000052}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000DF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000065}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000062}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000040}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000049}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000041}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000046}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000042}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000043}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000059}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000043}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000040}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000056}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000044}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000045}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000046}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000047}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000048}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000049}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000050}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000051}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000052}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000053}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000054}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000055}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000056}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000057}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000058}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000059}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000060}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000061}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000062}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000063}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000064}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000065}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000066}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000067}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000068}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000069}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000070}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000071}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000072}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000073}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000074}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000075}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000076}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000077}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000078}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000078}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000075}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000079}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000072}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F6}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001EA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001F0}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001E4}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001ED}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AC}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001AA}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000E0}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000080}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001A4}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000081}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000006C}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000082}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000069}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000083}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000066}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000084}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000063}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000085}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004E}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000057}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000060}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000086}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000004B}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000054}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005D}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000087}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000048}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000051}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000005A}, ++ {0xB0000000, 0x00000000}, ++ {0x0EE, 0x00000000}, ++ {0x0EE, 0x00004000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00003BEF}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00003BE9}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x00003BE3}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x00003BDD}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x00003BD7}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x00003BD1}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00003BCB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00001BD9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BD1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00001BD3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00001BCD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000BD9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BD1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000BD3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000BCD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000859}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000857}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000859}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000851}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000819}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000084D}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000817}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000819}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000811}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x03F, 0x000039EE}, ++ {0x033, 0x00000013}, ++ {0x03F, 0x000039E8}, ++ {0x033, 0x00000014}, ++ {0x03F, 0x000039E2}, ++ {0x033, 0x00000015}, ++ {0x03F, 0x000039DC}, ++ {0x033, 0x00000016}, ++ {0x03F, 0x000039D6}, ++ {0x033, 0x00000017}, ++ {0x03F, 0x000039D0}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x03F, 0x000019D2}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x03F, 0x000009D2}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x0000001E}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000023}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x00000024}, ++ {0x03F, 0x000039EE}, ++ {0x033, 0x00000025}, ++ {0x03F, 0x000039E8}, ++ {0x033, 0x00000026}, ++ {0x03F, 0x000039E2}, ++ {0x033, 0x00000027}, ++ {0x03F, 0x000039DC}, ++ {0x033, 0x00000028}, ++ {0x03F, 0x000039D6}, ++ {0x033, 0x00000029}, ++ {0x03F, 0x000039D0}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x03F, 0x000019D2}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x03F, 0x000009D2}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000030}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000035}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x00000036}, ++ {0x03F, 0x000039EE}, ++ {0x033, 0x00000037}, ++ {0x03F, 0x000039E8}, ++ {0x033, 0x00000038}, ++ {0x03F, 0x000039E2}, ++ {0x033, 0x00000039}, ++ {0x03F, 0x000039DC}, ++ {0x033, 0x0000003A}, ++ {0x03F, 0x000039D6}, ++ {0x033, 0x0000003B}, ++ {0x03F, 0x000039D0}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x03F, 0x000019D2}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D8}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x03F, 0x000009D2}, ++ {0x033, 0x00000040}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CC}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000008D9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000041}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000042}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000043}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000044}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000045}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000046}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000047}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x00000048}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000049}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000004F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000050}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000051}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000052}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000053}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000054}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000055}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000056}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000057}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000058}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x00000059}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x0000005A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000005F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000060}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000061}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000062}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000063}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000064}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000065}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000066}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000067}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000068}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x00000069}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006A}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x0000006B}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x0000006C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000006F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000070}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000071}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000072}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000073}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000074}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000075}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000076}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000077}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x00000078}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x00000079}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007A}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x0000007B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007C}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x0000007D}, ++ {0x03F, 0x00000807}, ++ {0x033, 0x0000007E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EE}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039EF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000007F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E8}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E9}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000080}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039E3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000081}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039DD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000082}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D6}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D7}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000083}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D0}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039D1}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000084}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CA}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000039CB}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000085}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000086}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CC}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000019CD}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000087}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D2}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000009D3}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000088}, ++ {0x03F, 0x000009CD}, ++ {0x033, 0x00000089}, ++ {0x03F, 0x000008D3}, ++ {0x033, 0x0000008A}, ++ {0x03F, 0x000008CD}, ++ {0x033, 0x0000008B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000008C7}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000853}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000008C}, ++ {0x03F, 0x0000084D}, ++ {0x033, 0x0000008D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000847}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x00000813}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000008E}, ++ {0x03F, 0x0000080D}, ++ {0x033, 0x0000008F}, ++ {0x03F, 0x00000807}, ++ {0x0EE, 0x00000000}, ++ {0x0EF, 0x00080000}, ++ {0x033, 0x00000007}, ++ {0x03E, 0x00000001}, ++ {0x03F, 0x00020F3C}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00080000}, ++ {0x033, 0x0000000C}, ++ {0x03E, 0x00000001}, ++ {0x03F, 0x000305BC}, ++ {0x0EF, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000001}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0EC, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0EC, 0x00000001}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x03C, 0x00000020}, ++ {0x03D, 0x00000078}, ++ {0x03E, 0x00080000}, ++ {0x03F, 0x00001999}, ++ {0x0EC, 0x00000000}, ++ {0x02F, 0x0002260D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000001}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x0DE, 0x00000000}, ++ {0xA0000000, 0x00000000}, ++ {0x0DE, 0x00000001}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000002}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x00000002}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x00000002}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000400}, ++ {0x033, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000001}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000002}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000003}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000004}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000005}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000006}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000007}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000008}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000009}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000000F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000010}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000011}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000012}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000013}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000014}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000015}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000016}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000017}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000018}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000019}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000001F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000020}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000021}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000022}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000023}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000024}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000025}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000026}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000027}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000017F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000013F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FB}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FA}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x0EF, 0x00000200}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000001}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000002}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000003}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000004}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000005}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000006}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000007}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000008}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000009}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000A}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000B}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000C}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000D}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000E}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000000F}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000010}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000011}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000012}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000013}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000014}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000015}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000016}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000017}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000018}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000019}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001A}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001B}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001C}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001D}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001E}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x0000001F}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000020}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000021}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000022}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000023}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000024}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000025}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000026}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000027}, ++ {0x03F, 0x000001FF}, ++ {0x033, 0x00000028}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000029}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x000001FF}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x000000FF}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000002F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000030}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000031}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000032}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000033}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000034}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000035}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000036}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000037}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000038}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x00000039}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003A}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003B}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003C}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003D}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003E}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x033, 0x0000003F}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003B}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xA0000000, 0x00000000}, ++ {0x03F, 0x0000003F}, ++ {0xB0000000, 0x00000000}, ++ {0x0EF, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06E, 0x00067A7C}, ++ {0xA0000000, 0x00000000}, ++ {0x06E, 0x00077A7C}, ++ {0xB0000000, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x06F, 0x00067A7C}, ++ {0xA0000000, 0x00000000}, ++ {0x06F, 0x00077A7C}, ++ {0xB0000000, 0x00000000}, ++ {0x06D, 0x00000C31}, ++ {0x0EF, 0x00020000}, ++ {0x033, 0x00000000}, ++ {0x03F, 0x000005FF}, ++ {0x0EF, 0x00000000}, ++ {0x0A0, 0x00000043}, ++ {0x005, 0x00000001}, ++ {0x0EF, 0x00080000}, ++ {0x033, 0x00000001}, ++ {0x03E, 0x00000001}, ++ {0x03F, 0x00022020}, ++ {0x0EF, 0x00000000}, ++ {0x80010000, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90010001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90020001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90030001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90250001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90260001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90320001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90330001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90340001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90350001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90360001, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90010002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90020002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90030002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90250002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90260002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0x90320002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90330002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90340002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90350002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0x90360002, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x087, 0x0000042F}, ++ {0xA0000000, 0x00000000}, ++ {0x087, 0x00000427}, ++ {0xB0000000, 0x00000000}, ++ {0x002, 0x00000000}, ++ {0x067, 0x00000052}, ++ ++}; ++ ++static const struct rtw89_reg2_def rtw89_8852a_phy_nctl_regs[] = { ++ {0x8000, 0x00000008}, ++ {0x8008, 0x00000000}, ++ {0x8004, 0xf0862966}, ++ {0x800c, 0x78000000}, ++ {0x8010, 0x88015000}, ++ {0x8014, 0x80010100}, ++ {0x8018, 0x10010100}, ++ {0x801c, 0xa210bc00}, ++ {0x8020, 0x000403e0}, ++ {0x8024, 0x00072160}, ++ {0x8028, 0x00180e00}, ++ {0x8030, 0x400000c0}, ++ {0x8034, 0x56000800}, ++ {0x8038, 0x00000009}, ++ {0x803c, 0x00000008}, ++ {0x8040, 0x00000046}, ++ {0x8044, 0x0010001f}, ++ {0x8048, 0xf0000003}, ++ {0x804c, 0x62ac6162}, ++ {0x8050, 0xf2acf162}, ++ {0x8054, 0x62ac6162}, ++ {0x8058, 0xf2acf162}, ++ {0x805c, 0x150c0b02}, ++ {0x8060, 0x150c0b02}, ++ {0x8064, 0x2aa00047}, ++ {0x8074, 0x80000000}, ++ {0x807c, 0x000000ee}, ++ {0x8088, 0x80000000}, ++ {0x8098, 0x0000ff00}, ++ {0x809c, 0x0000001f}, ++ {0x80a0, 0x00010300}, ++ {0x80b0, 0x00000000}, ++ {0x80d0, 0x00000000}, ++ {0x8114, 0x00000000}, ++ {0x8120, 0x10010000}, ++ {0x8124, 0x00000000}, ++ {0x812c, 0x0000c000}, ++ {0x8138, 0x40000002}, ++ {0x813c, 0x40000002}, ++ {0x8140, 0x00000000}, ++ {0x8144, 0x0b040b03}, ++ {0x8148, 0x0b040b04}, ++ {0x814c, 0x0b040b03}, ++ {0x8150, 0x00000000}, ++ {0x8158, 0xffffffff}, ++ {0x815c, 0xffffffff}, ++ {0x8160, 0xffffffff}, ++ {0x8164, 0xffffffff}, ++ {0x8168, 0xffffffff}, ++ {0x816c, 0x1fffffff}, ++ {0x81ac, 0x003f1a00}, ++ {0x81b0, 0x003f1a00}, ++ {0x81bc, 0x005b5b5b}, ++ {0x81c0, 0x005b5b5b}, ++ {0x81b4, 0x00600060}, ++ {0x81b8, 0x00600060}, ++ {0x81cc, 0x00000000}, ++ {0x81dc, 0x00000002}, ++ {0x8214, 0x00000000}, ++ {0x8220, 0x10010000}, ++ {0x8224, 0x00000000}, ++ {0x822c, 0x0000d000}, ++ {0x8238, 0x40000002}, ++ {0x823c, 0x40000002}, ++ {0x8240, 0x00000000}, ++ {0x8244, 0x0b040b03}, ++ {0x8248, 0x0b040b03}, ++ {0x824c, 0x0b030b03}, ++ {0x8250, 0x00000000}, ++ {0x8258, 0xffffffff}, ++ {0x825c, 0xffffffff}, ++ {0x8260, 0xffffffff}, ++ {0x8264, 0xffffffff}, ++ {0x8268, 0xffffffff}, ++ {0x826c, 0x1fffffff}, ++ {0x82ac, 0x003f1a00}, ++ {0x82b0, 0x003f1a00}, ++ {0x82bc, 0x005b5b5b}, ++ {0x82c0, 0x005b5b5b}, ++ {0x82b4, 0x00600060}, ++ {0x82b8, 0x00600060}, ++ {0x82cc, 0x00000000}, ++ {0x82dc, 0x00000002}, ++ {0x81d8, 0x00000001}, ++ {0x82d8, 0x00000001}, ++ {0x8d00, 0x00000000}, ++ {0x8d04, 0x00000000}, ++ {0x8d08, 0x00000000}, ++ {0x8d0c, 0x00000000}, ++ {0x8d10, 0x00000000}, ++ {0x8d14, 0x00000000}, ++ {0x8d18, 0x00000000}, ++ {0x8d1c, 0x00000000}, ++ {0x8d20, 0x00000000}, ++ {0x8d24, 0x00000000}, ++ {0x8d28, 0x00000000}, ++ {0x8d2c, 0x00000000}, ++ {0x8d30, 0x00000000}, ++ {0x8d34, 0x00000000}, ++ {0x8d38, 0x00000000}, ++ {0x8d3c, 0x00000000}, ++ {0x8d40, 0x00000000}, ++ {0x8d44, 0x00000000}, ++ {0x8d48, 0x00000000}, ++ {0x8d4c, 0x00000000}, ++ {0x8d50, 0x00000000}, ++ {0x8d54, 0x00000000}, ++ {0x8d58, 0x00000000}, ++ {0x8d5c, 0x00000000}, ++ {0x8d60, 0x00000000}, ++ {0x8d64, 0x00000000}, ++ {0x8d68, 0x00000000}, ++ {0x8d6c, 0x00000000}, ++ {0x8d70, 0x00000000}, ++ {0x8d74, 0x00000000}, ++ {0x8d78, 0x00000000}, ++ {0x8d7c, 0x00000000}, ++ {0x8d80, 0x00000000}, ++ {0x8d84, 0x00000000}, ++ {0x8d88, 0x00000000}, ++ {0x8d8c, 0x00000000}, ++ {0x8d90, 0x00000000}, ++ {0x8d94, 0x00000000}, ++ {0x8d98, 0x00000000}, ++ {0x8d9c, 0x00000000}, ++ {0x8da0, 0x00000000}, ++ {0x8da4, 0x00000000}, ++ {0x8da8, 0x00000000}, ++ {0x8dac, 0x00000000}, ++ {0x8db0, 0x00000000}, ++ {0x8db4, 0x00000000}, ++ {0x8db8, 0x00000000}, ++ {0x8dbc, 0x00000000}, ++ {0x8dc0, 0x00000000}, ++ {0x8dc4, 0x00000000}, ++ {0x8dc8, 0x00000000}, ++ {0x8dcc, 0x00000000}, ++ {0x8dd0, 0x00000000}, ++ {0x8dd4, 0x00000000}, ++ {0x8dd8, 0x00000000}, ++ {0x8ddc, 0x00000000}, ++ {0x8de0, 0x00000000}, ++ {0x8de4, 0x00000000}, ++ {0x8de8, 0x00000000}, ++ {0x8dec, 0x00000000}, ++ {0x8df0, 0x00000000}, ++ {0x8df4, 0x00000000}, ++ {0x8df8, 0x00000000}, ++ {0x8dfc, 0x00000000}, ++ {0x8e00, 0x00000000}, ++ {0x8e04, 0x00000000}, ++ {0x8e08, 0x00000000}, ++ {0x8e0c, 0x00000000}, ++ {0x8e10, 0x00000000}, ++ {0x8e14, 0x00000000}, ++ {0x8e18, 0x00000000}, ++ {0x8e1c, 0x00000000}, ++ {0x8e20, 0x00000000}, ++ {0x8e24, 0x00000000}, ++ {0x8e28, 0x00000000}, ++ {0x8e2c, 0x00000000}, ++ {0x8e30, 0x00000000}, ++ {0x8e34, 0x00000000}, ++ {0x8e38, 0x00000000}, ++ {0x8e3c, 0x00000000}, ++ {0x8e40, 0x00000000}, ++ {0x8e44, 0x00000000}, ++ {0x8e48, 0x00000000}, ++ {0x8e4c, 0x00000000}, ++ {0x8e50, 0x00000000}, ++ {0x8e54, 0x00000000}, ++ {0x8e58, 0x00000000}, ++ {0x8e5c, 0x00000000}, ++ {0x8e60, 0x00000000}, ++ {0x8e64, 0x00000000}, ++ {0x8e68, 0x00000000}, ++ {0x8e6c, 0x00000000}, ++ {0x8e70, 0x00000000}, ++ {0x8e74, 0x00000000}, ++ {0x8e78, 0x00000000}, ++ {0x8e7c, 0x00000000}, ++ {0x8e80, 0x00000000}, ++ {0x8e84, 0x00000000}, ++ {0x8e88, 0x00000000}, ++ {0x8e8c, 0x00000000}, ++ {0x8e90, 0x00000000}, ++ {0x8e94, 0x00000000}, ++ {0x8e98, 0x00000000}, ++ {0x8e9c, 0x00000000}, ++ {0x8ea0, 0x00000000}, ++ {0x8ea4, 0x00000000}, ++ {0x8ea8, 0x00000000}, ++ {0x8eac, 0x00000000}, ++ {0x8eb0, 0x00000000}, ++ {0x8eb4, 0x00000000}, ++ {0x8eb8, 0x00000000}, ++ {0x8ebc, 0x00000000}, ++ {0x8ec0, 0x00000000}, ++ {0x8ec4, 0x00000000}, ++ {0x8ec8, 0x00000000}, ++ {0x8ecc, 0x00000000}, ++ {0x8ed0, 0x00000000}, ++ {0x8ed4, 0x00000000}, ++ {0x8ed8, 0x00000000}, ++ {0x8edc, 0x00000000}, ++ {0x8ee0, 0x00000000}, ++ {0x8ee4, 0x00000000}, ++ {0x8ee8, 0x00000000}, ++ {0x8eec, 0x00000000}, ++ {0x8ef0, 0x00000000}, ++ {0x8ef4, 0x00000000}, ++ {0x8ef8, 0x00000000}, ++ {0x8efc, 0x00000000}, ++ {0x8f00, 0x00000000}, ++ {0x8f04, 0x00000000}, ++ {0x8f08, 0x00000000}, ++ {0x8f0c, 0x00000000}, ++ {0x8f10, 0x00000000}, ++ {0x8f14, 0x00000000}, ++ {0x8f18, 0x00000000}, ++ {0x8f1c, 0x00000000}, ++ {0x8f20, 0x00000000}, ++ {0x8f24, 0x00000000}, ++ {0x8f28, 0x00000000}, ++ {0x8f2c, 0x00000000}, ++ {0x8f30, 0x00000000}, ++ {0x8f34, 0x00000000}, ++ {0x8f38, 0x00000000}, ++ {0x8f3c, 0x00000000}, ++ {0x8f40, 0x00000000}, ++ {0x8f44, 0x00000000}, ++ {0x8f48, 0x00000000}, ++ {0x8f4c, 0x00000000}, ++ {0x8f50, 0x00000000}, ++ {0x8f54, 0x00000000}, ++ {0x8f58, 0x00000000}, ++ {0x8f5c, 0x00000000}, ++ {0x8f60, 0x00000000}, ++ {0x8f64, 0x00000000}, ++ {0x8f68, 0x00000000}, ++ {0x8f6c, 0x00000000}, ++ {0x8f70, 0x00000000}, ++ {0x8f74, 0x00000000}, ++ {0x8f78, 0x00000000}, ++ {0x8f7c, 0x00000000}, ++ {0x8f80, 0x00000000}, ++ {0x8f84, 0x00000000}, ++ {0x8f88, 0x00000000}, ++ {0x8f8c, 0x00000000}, ++ {0x8f90, 0x00000000}, ++ {0x8f94, 0x00000000}, ++ {0x8f98, 0x00000000}, ++ {0x8f9c, 0x00000000}, ++ {0x8fa0, 0x00000000}, ++ {0x8fa4, 0x00000000}, ++ {0x8fa8, 0x00000000}, ++ {0x8fac, 0x00000000}, ++ {0x8fb0, 0x00000000}, ++ {0x8fb4, 0x00000000}, ++ {0x8fb8, 0x00000000}, ++ {0x8fbc, 0x00000000}, ++ {0x8fc0, 0x00000000}, ++ {0x8fc4, 0x00000000}, ++ {0x8fc8, 0x00000000}, ++ {0x8fcc, 0x00000000}, ++ {0x8fd0, 0x00000000}, ++ {0x8fd4, 0x00000000}, ++ {0x8fd8, 0x00000000}, ++ {0x8fdc, 0x00000000}, ++ {0x8fe0, 0x00000000}, ++ {0x8fe4, 0x00000000}, ++ {0x8fe8, 0x00000000}, ++ {0x8fec, 0x00000000}, ++ {0x8ff0, 0x00000000}, ++ {0x8ff4, 0x00000000}, ++ {0x8ff8, 0x00000000}, ++ {0x8ffc, 0x00000000}, ++ {0x9000, 0x00000000}, ++ {0x9004, 0x00000000}, ++ {0x9008, 0x00000000}, ++ {0x900c, 0x00000000}, ++ {0x9010, 0x00000000}, ++ {0x9014, 0x00000000}, ++ {0x9018, 0x00000000}, ++ {0x901c, 0x00000000}, ++ {0x9020, 0x00000000}, ++ {0x9024, 0x00000000}, ++ {0x9028, 0x00000000}, ++ {0x902c, 0x00000000}, ++ {0x9030, 0x00000000}, ++ {0x9034, 0x00000000}, ++ {0x9038, 0x00000000}, ++ {0x903c, 0x00000000}, ++ {0x9040, 0x00000000}, ++ {0x9044, 0x00000000}, ++ {0x9048, 0x00000000}, ++ {0x904c, 0x00000000}, ++ {0x9050, 0x00000000}, ++ {0x9054, 0x00000000}, ++ {0x9058, 0x00000000}, ++ {0x905c, 0x00000000}, ++ {0x9060, 0x00000000}, ++ {0x9064, 0x00000000}, ++ {0x9068, 0x00000000}, ++ {0x906c, 0x00000000}, ++ {0x9070, 0x00000000}, ++ {0x9074, 0x00000000}, ++ {0x9078, 0x00000000}, ++ {0x907c, 0x00000000}, ++ {0x9080, 0x00000000}, ++ {0x9084, 0x00000000}, ++ {0x9088, 0x00000000}, ++ {0x908c, 0x00000000}, ++ {0x9090, 0x00000000}, ++ {0x9094, 0x00000000}, ++ {0x9098, 0x00000000}, ++ {0x909c, 0x00000000}, ++ {0x90a0, 0x00000000}, ++ {0x90a4, 0x00000000}, ++ {0x90a8, 0x00000000}, ++ {0x90ac, 0x00000000}, ++ {0x90b0, 0x00000000}, ++ {0x90b4, 0x00000000}, ++ {0x90b8, 0x00000000}, ++ {0x90bc, 0x00000000}, ++ {0x9100, 0x00000000}, ++ {0x9104, 0x00000000}, ++ {0x9108, 0x00000000}, ++ {0x910c, 0x00000000}, ++ {0x9110, 0x00000000}, ++ {0x9114, 0x00000000}, ++ {0x9118, 0x00000000}, ++ {0x911c, 0x00000000}, ++ {0x9120, 0x00000000}, ++ {0x9124, 0x00000000}, ++ {0x9128, 0x00000000}, ++ {0x912c, 0x00000000}, ++ {0x9130, 0x00000000}, ++ {0x9134, 0x00000000}, ++ {0x9138, 0x00000000}, ++ {0x913c, 0x00000000}, ++ {0x9140, 0x00000000}, ++ {0x9144, 0x00000000}, ++ {0x9148, 0x00000000}, ++ {0x914c, 0x00000000}, ++ {0x9150, 0x00000000}, ++ {0x9154, 0x00000000}, ++ {0x9158, 0x00000000}, ++ {0x915c, 0x00000000}, ++ {0x9160, 0x00000000}, ++ {0x9164, 0x00000000}, ++ {0x9168, 0x00000000}, ++ {0x916c, 0x00000000}, ++ {0x9170, 0x00000000}, ++ {0x9174, 0x00000000}, ++ {0x9178, 0x00000000}, ++ {0x917c, 0x00000000}, ++ {0x9180, 0x00000000}, ++ {0x9184, 0x00000000}, ++ {0x9188, 0x00000000}, ++ {0x918c, 0x00000000}, ++ {0x9190, 0x00000000}, ++ {0x9194, 0x00000000}, ++ {0x9198, 0x00000000}, ++ {0x919c, 0x00000000}, ++ {0x91a0, 0x00000000}, ++ {0x91a4, 0x00000000}, ++ {0x91a8, 0x00000000}, ++ {0x91ac, 0x00000000}, ++ {0x91b0, 0x00000000}, ++ {0x91b4, 0x00000000}, ++ {0x91b8, 0x00000000}, ++ {0x91bc, 0x00000000}, ++ {0x91c0, 0x00000000}, ++ {0x91c4, 0x00000000}, ++ {0x91c8, 0x00000000}, ++ {0x91cc, 0x00000000}, ++ {0x91d0, 0x00000000}, ++ {0x91d4, 0x00000000}, ++ {0x91d8, 0x00000000}, ++ {0x91dc, 0x00000000}, ++ {0x91e0, 0x00000000}, ++ {0x91e4, 0x00000000}, ++ {0x91e8, 0x00000000}, ++ {0x91ec, 0x00000000}, ++ {0x91f0, 0x00000000}, ++ {0x91f4, 0x00000000}, ++ {0x91f8, 0x00000000}, ++ {0x91fc, 0x00000000}, ++ {0x9200, 0x00000000}, ++ {0x9204, 0x00000000}, ++ {0x9208, 0x00000000}, ++ {0x920c, 0x00000000}, ++ {0x9210, 0x00000000}, ++ {0x9214, 0x00000000}, ++ {0x9218, 0x00000000}, ++ {0x921c, 0x00000000}, ++ {0x9220, 0x00000000}, ++ {0x9224, 0x00000000}, ++ {0x9228, 0x00000000}, ++ {0x922c, 0x00000000}, ++ {0x9230, 0x00000000}, ++ {0x9234, 0x00000000}, ++ {0x9238, 0x00000000}, ++ {0x923c, 0x00000000}, ++ {0x9240, 0x00000000}, ++ {0x9244, 0x00000000}, ++ {0x9248, 0x00000000}, ++ {0x924c, 0x00000000}, ++ {0x9250, 0x00000000}, ++ {0x9254, 0x00000000}, ++ {0x9258, 0x00000000}, ++ {0x925c, 0x00000000}, ++ {0x9260, 0x00000000}, ++ {0x9264, 0x00000000}, ++ {0x9268, 0x00000000}, ++ {0x926c, 0x00000000}, ++ {0x9270, 0x00000000}, ++ {0x9274, 0x00000000}, ++ {0x9278, 0x00000000}, ++ {0x927c, 0x00000000}, ++ {0x9280, 0x00000000}, ++ {0x9284, 0x00000000}, ++ {0x9288, 0x00000000}, ++ {0x928c, 0x00000000}, ++ {0x9290, 0x00000000}, ++ {0x9294, 0x00000000}, ++ {0x9298, 0x00000000}, ++ {0x929c, 0x00000000}, ++ {0x92a0, 0x00000000}, ++ {0x92a4, 0x00000000}, ++ {0x92a8, 0x00000000}, ++ {0x92ac, 0x00000000}, ++ {0x92b0, 0x00000000}, ++ {0x92b4, 0x00000000}, ++ {0x92b8, 0x00000000}, ++ {0x92bc, 0x00000000}, ++ {0x92c0, 0x00000000}, ++ {0x92c4, 0x00000000}, ++ {0x92c8, 0x00000000}, ++ {0x92cc, 0x00000000}, ++ {0x92d0, 0x00000000}, ++ {0x92d4, 0x00000000}, ++ {0x92d8, 0x00000000}, ++ {0x92dc, 0x00000000}, ++ {0x92e0, 0x00000000}, ++ {0x92e4, 0x00000000}, ++ {0x92e8, 0x00000000}, ++ {0x92ec, 0x00000000}, ++ {0x92f0, 0x00000000}, ++ {0x92f4, 0x00000000}, ++ {0x92f8, 0x00000000}, ++ {0x92fc, 0x00000000}, ++ {0x9300, 0x00000000}, ++ {0x9304, 0x00000000}, ++ {0x9308, 0x00000000}, ++ {0x930c, 0x00000000}, ++ {0x9310, 0x00000000}, ++ {0x9314, 0x00000000}, ++ {0x9318, 0x00000000}, ++ {0x931c, 0x00000000}, ++ {0x9320, 0x00000000}, ++ {0x9324, 0x00000000}, ++ {0x9328, 0x00000000}, ++ {0x932c, 0x00000000}, ++ {0x9330, 0x00000000}, ++ {0x9334, 0x00000000}, ++ {0x9338, 0x00000000}, ++ {0x933c, 0x00000000}, ++ {0x9340, 0x00000000}, ++ {0x9344, 0x00000000}, ++ {0x9348, 0x00000000}, ++ {0x934c, 0x00000000}, ++ {0x9350, 0x00000000}, ++ {0x9354, 0x00000000}, ++ {0x9358, 0x00000000}, ++ {0x935c, 0x00000000}, ++ {0x9360, 0x00000000}, ++ {0x9364, 0x00000000}, ++ {0x9368, 0x00000000}, ++ {0x936c, 0x00000000}, ++ {0x9370, 0x00000000}, ++ {0x9374, 0x00000000}, ++ {0x9378, 0x00000000}, ++ {0x937c, 0x00000000}, ++ {0x9380, 0x00000000}, ++ {0x9384, 0x00000000}, ++ {0x9388, 0x00000000}, ++ {0x938c, 0x00000000}, ++ {0x9390, 0x00000000}, ++ {0x9394, 0x00000000}, ++ {0x9398, 0x00000000}, ++ {0x939c, 0x00000000}, ++ {0x93a0, 0x00000000}, ++ {0x93a4, 0x00000000}, ++ {0x93a8, 0x00000000}, ++ {0x93ac, 0x00000000}, ++ {0x93b0, 0x00000000}, ++ {0x93b4, 0x00000000}, ++ {0x93b8, 0x00000000}, ++ {0x93bc, 0x00000000}, ++ {0x93c0, 0x00000000}, ++ {0x93c4, 0x00000000}, ++ {0x93c8, 0x00000000}, ++ {0x93cc, 0x00000000}, ++ {0x93d0, 0x00000000}, ++ {0x93d4, 0x00000000}, ++ {0x93d8, 0x00000000}, ++ {0x93dc, 0x00000000}, ++ {0x93e0, 0x00000000}, ++ {0x93e4, 0x00000000}, ++ {0x93e8, 0x00000000}, ++ {0x93ec, 0x00000000}, ++ {0x93f0, 0x00000000}, ++ {0x93f4, 0x00000000}, ++ {0x93f8, 0x00000000}, ++ {0x93fc, 0x00000000}, ++ {0x9400, 0x00000000}, ++ {0x9404, 0x00000000}, ++ {0x9408, 0x00000000}, ++ {0x940c, 0x00000000}, ++ {0x9410, 0x00000000}, ++ {0x9414, 0x00000000}, ++ {0x9418, 0x00000000}, ++ {0x941c, 0x00000000}, ++ {0x9420, 0x00000000}, ++ {0x9424, 0x00000000}, ++ {0x9428, 0x00000000}, ++ {0x942c, 0x00000000}, ++ {0x9430, 0x00000000}, ++ {0x9434, 0x00000000}, ++ {0x9438, 0x00000000}, ++ {0x943c, 0x00000000}, ++ {0x9440, 0x00000000}, ++ {0x9444, 0x00000000}, ++ {0x9448, 0x00000000}, ++ {0x944c, 0x00000000}, ++ {0x9450, 0x00000000}, ++ {0x9454, 0x00000000}, ++ {0x9458, 0x00000000}, ++ {0x945c, 0x00000000}, ++ {0x9460, 0x00000000}, ++ {0x9464, 0x00000000}, ++ {0x9468, 0x00000000}, ++ {0x946c, 0x00000000}, ++ {0x9470, 0x00000000}, ++ {0x9474, 0x00000000}, ++ {0x9478, 0x00000000}, ++ {0x947c, 0x00000000}, ++ {0x9480, 0x00000000}, ++ {0x9484, 0x00000000}, ++ {0x9488, 0x00000000}, ++ {0x948c, 0x00000000}, ++ {0x9490, 0x00000000}, ++ {0x9494, 0x00000000}, ++ {0x9498, 0x00000000}, ++ {0x949c, 0x00000000}, ++ {0x94a0, 0x00000000}, ++ {0x94a4, 0x00000000}, ++ {0x94a8, 0x00000000}, ++ {0x94ac, 0x00000000}, ++ {0x94b0, 0x00000000}, ++ {0x94b4, 0x00000000}, ++ {0x94b8, 0x00000000}, ++ {0x94bc, 0x00000000}, ++ {0x81d8, 0x00000000}, ++ {0x82d8, 0x00000000}, ++ {0x9f04, 0x2b251f19}, ++ {0x9f08, 0x433d3731}, ++ {0x9f0c, 0x5b554f49}, ++ {0x9f10, 0x736d6761}, ++ {0x9f14, 0x7f7f7f79}, ++ {0x9f18, 0x120f7f7f}, ++ {0x9f1c, 0x1e1b1815}, ++ {0x9f20, 0x2a272421}, ++ {0x9f24, 0x3633302d}, ++ {0x9f28, 0x3f3f3c39}, ++ {0x9f2c, 0x3f3f3f3f}, ++ {0x8088, 0x00000110}, ++ {0x8000, 0x00000008}, ++ {0x8080, 0x00000005}, ++ {0x8500, 0x00060009}, ++ {0x8504, 0x000418b0}, ++ {0x8508, 0x00089c00}, ++ {0x850c, 0x43000004}, ++ {0x8510, 0x4b044a00}, ++ {0x8514, 0x40098603}, ++ {0x8518, 0x4b05e01f}, ++ {0x851c, 0x400b8703}, ++ {0x8520, 0x4b00e01f}, ++ {0x8524, 0x43800004}, ++ {0x8528, 0x4c000007}, ++ {0x852c, 0x43000004}, ++ {0x8530, 0x57007430}, ++ {0x8534, 0x73000006}, ++ {0x8538, 0x50550004}, ++ {0x853c, 0xb4163000}, ++ {0x8540, 0xe37ea510}, ++ {0x8544, 0xf117f017}, ++ {0x8548, 0xf317f217}, ++ {0x854c, 0xf517f417}, ++ {0x8550, 0xf717f617}, ++ {0x8554, 0xf917f817}, ++ {0x8558, 0xfb17fa17}, ++ {0x855c, 0xfd17fc17}, ++ {0x8560, 0xf117f017}, ++ {0x8564, 0xf317f217}, ++ {0x8568, 0xa503f417}, ++ {0x856c, 0xf116f016}, ++ {0x8570, 0x304e0001}, ++ {0x8574, 0x30873053}, ++ {0x8578, 0x30ab30a8}, ++ {0x857c, 0x30b330ae}, ++ {0x8580, 0x30ba30b6}, ++ {0x8584, 0x30d430c7}, ++ {0x8588, 0x310d3100}, ++ {0x858c, 0x31ed3112}, ++ {0x8590, 0x320a31f1}, ++ {0x8594, 0x3243320b}, ++ {0x8598, 0x31e631b1}, ++ {0x859c, 0x5b00e283}, ++ {0x85a0, 0xe2d15500}, ++ {0x85a4, 0xe2830001}, ++ {0x85a8, 0x5b10e2e3}, ++ {0x85ac, 0x20987410}, ++ {0x85b0, 0xe3750200}, ++ {0x85b4, 0x00002080}, ++ {0x85b8, 0x23f0e375}, ++ {0x85bc, 0xe3750001}, ++ {0x85c0, 0x000023f0}, ++ {0x85c4, 0x5507e375}, ++ {0x85c8, 0xe2d5e2d5}, ++ {0x85cc, 0x20887410}, ++ {0x85d0, 0xe3750200}, ++ {0x85d4, 0x000123f0}, ++ {0x85d8, 0x23f0e375}, ++ {0x85dc, 0xe3750000}, ++ {0x85e0, 0xe2d55517}, ++ {0x85e4, 0x4e004f02}, ++ {0x85e8, 0x52015302}, ++ {0x85ec, 0x7508e2d9}, ++ {0x85f0, 0x74207900}, ++ {0x85f4, 0x57005710}, ++ {0x85f8, 0x75fbe375}, ++ {0x85fc, 0x23f07410}, ++ {0x8600, 0xe3750001}, ++ {0x8604, 0x000023f0}, ++ {0x8608, 0x7430e375}, ++ {0x860c, 0x5b100001}, ++ {0x8610, 0x20907410}, ++ {0x8614, 0xe3750000}, ++ {0x8618, 0x000123f0}, ++ {0x861c, 0x23f0e375}, ++ {0x8620, 0xe3750000}, ++ {0x8624, 0xe2d55507}, ++ {0x8628, 0x7410e2d5}, ++ {0x862c, 0x02002098}, ++ {0x8630, 0x23f0e375}, ++ {0x8634, 0xe3750001}, ++ {0x8638, 0x000023f0}, ++ {0x863c, 0x5517e375}, ++ {0x8640, 0x4f02e2d5}, ++ {0x8644, 0x53024e00}, ++ {0x8648, 0xe2d95201}, ++ {0x864c, 0x30787509}, ++ {0x8650, 0xe2e3e283}, ++ {0x8654, 0xe27b0001}, ++ {0x8658, 0x0001e2e3}, ++ {0x865c, 0x5b30e28f}, ++ {0x8660, 0xe2d15500}, ++ {0x8664, 0xe28f0001}, ++ {0x8668, 0x0001e312}, ++ {0x866c, 0x4380e287}, ++ {0x8670, 0x0001e312}, ++ {0x8674, 0x30e2e283}, ++ {0x8678, 0xe3600023}, ++ {0x867c, 0x54ed0002}, ++ {0x8680, 0x00230baa}, ++ {0x8684, 0x0002e360}, ++ {0x8688, 0xe27be330}, ++ {0x868c, 0xe2830001}, ++ {0x8690, 0x002230dd}, ++ {0x8694, 0x0002e360}, ++ {0x8698, 0x0baa54ec}, ++ {0x869c, 0xe3600022}, ++ {0x86a0, 0xe3300002}, ++ {0x86a4, 0x0001e27b}, ++ {0x86a8, 0x0baae283}, ++ {0x86ac, 0x6d0f6c67}, ++ {0x86b0, 0xe360e2e3}, ++ {0x86b4, 0xe2e36c8b}, ++ {0x86b8, 0x0bace360}, ++ {0x86bc, 0x6d0f6cb3}, ++ {0x86c0, 0xe360e2e3}, ++ {0x86c4, 0x6cdb0bad}, ++ {0x86c8, 0xe2e36d0f}, ++ {0x86cc, 0x6cf7e360}, ++ {0x86d0, 0xe2e36d0f}, ++ {0x86d4, 0x6c09e360}, ++ {0x86d8, 0xe2e36d00}, ++ {0x86dc, 0x6c25e360}, ++ {0x86e0, 0xe360e2e3}, ++ {0x86e4, 0x6c4df8ca}, ++ {0x86e8, 0xe360e2e3}, ++ {0x86ec, 0x6c75f9d3}, ++ {0x86f0, 0xe360e2e3}, ++ {0x86f4, 0xe2e36c99}, ++ {0x86f8, 0xe330e360}, ++ {0x86fc, 0x0001e27b}, ++ {0x8700, 0x314de28f}, ++ {0x8704, 0xe3650022}, ++ {0x8708, 0x54ec0002}, ++ {0x870c, 0x00220baa}, ++ {0x8710, 0x0002e365}, ++ {0x8714, 0xe287e330}, ++ {0x8718, 0xe28f0001}, ++ {0x871c, 0xe3303139}, ++ {0x8720, 0x0001e287}, ++ {0x8724, 0x0ba6e28f}, ++ {0x8728, 0x21e07410}, ++ {0x872c, 0x21e80009}, ++ {0x8730, 0x6e670009}, ++ {0x8734, 0xe32b6f0f}, ++ {0x8738, 0xe365e312}, ++ {0x873c, 0x21e07410}, ++ {0x8740, 0x21e8000a}, ++ {0x8744, 0x6e77000a}, ++ {0x8748, 0xe312e32b}, ++ {0x874c, 0x7410e365}, ++ {0x8750, 0x000b21e0}, ++ {0x8754, 0x000b21e8}, ++ {0x8758, 0xe32b6e8b}, ++ {0x875c, 0xe365e312}, ++ {0x8760, 0x21e07410}, ++ {0x8764, 0x21e8000c}, ++ {0x8768, 0x6e9f000c}, ++ {0x876c, 0xe312e32b}, ++ {0x8770, 0x0baae365}, ++ {0x8774, 0x21e07410}, ++ {0x8778, 0x21e8000d}, ++ {0x877c, 0x6eb3000d}, ++ {0x8780, 0xe32b6f0f}, ++ {0x8784, 0xe365e312}, ++ {0x8788, 0x21e07410}, ++ {0x878c, 0x21e8000e}, ++ {0x8790, 0x6ec7000e}, ++ {0x8794, 0xe312e32b}, ++ {0x8798, 0x0bace365}, ++ {0x879c, 0x21e07410}, ++ {0x87a0, 0x21e8000f}, ++ {0x87a4, 0x6edb000f}, ++ {0x87a8, 0xe32b6f0f}, ++ {0x87ac, 0xe365e312}, ++ {0x87b0, 0x21e07410}, ++ {0x87b4, 0x21e80010}, ++ {0x87b8, 0x6eef0010}, ++ {0x87bc, 0xe312e32b}, ++ {0x87c0, 0xe365e365}, ++ {0x87c4, 0x21e07410}, ++ {0x87c8, 0x21e80013}, ++ {0x87cc, 0x6e110013}, ++ {0x87d0, 0xe32b6f00}, ++ {0x87d4, 0xe365e312}, ++ {0x87d8, 0x7410e365}, ++ {0x87dc, 0x001421e0}, ++ {0x87e0, 0x001421e8}, ++ {0x87e4, 0xe32b6e25}, ++ {0x87e8, 0xe365e312}, ++ {0x87ec, 0x7410fb8c}, ++ {0x87f0, 0x001521e0}, ++ {0x87f4, 0x001521e8}, ++ {0x87f8, 0xe32b6e39}, ++ {0x87fc, 0xe365e312}, ++ {0x8800, 0x21e07410}, ++ {0x8804, 0x21e80016}, ++ {0x8808, 0x6e4d0016}, ++ {0x880c, 0xe312e32b}, ++ {0x8810, 0xfc86e365}, ++ {0x8814, 0x21e07410}, ++ {0x8818, 0x21e80017}, ++ {0x881c, 0x6e610017}, ++ {0x8820, 0xe312e32b}, ++ {0x8824, 0x7410e365}, ++ {0x8828, 0x001821e0}, ++ {0x882c, 0x001821e8}, ++ {0x8830, 0xe32b6e75}, ++ {0x8834, 0xe365e312}, ++ {0x8838, 0x21e07410}, ++ {0x883c, 0x21e80019}, ++ {0x8840, 0x6e890019}, ++ {0x8844, 0xe312e32b}, ++ {0x8848, 0x7410e365}, ++ {0x884c, 0x001a21e0}, ++ {0x8850, 0x001a21e8}, ++ {0x8854, 0xe32b6e99}, ++ {0x8858, 0xe365e312}, ++ {0x885c, 0xe287e330}, ++ {0x8860, 0x00040001}, ++ {0x8864, 0x0007775c}, ++ {0x8868, 0x62006220}, ++ {0x886c, 0x55010004}, ++ {0x8870, 0xe2d15b00}, ++ {0x8874, 0x66055b40}, ++ {0x8878, 0x62000007}, ++ {0x887c, 0xe3506300}, ++ {0x8880, 0xe2d10004}, ++ {0x8884, 0x0a010900}, ++ {0x8888, 0x0d000b40}, ++ {0x888c, 0x00320e01}, ++ {0x8890, 0x95060004}, ++ {0x8894, 0x00074380}, ++ {0x8898, 0x00044d01}, ++ {0x889c, 0x00074300}, ++ {0x88a0, 0x05a30562}, ++ {0x88a4, 0xe3509617}, ++ {0x88a8, 0xe2d10004}, ++ {0x88ac, 0x06a20007}, ++ {0x88b0, 0xe35007a3}, ++ {0x88b4, 0xe2d10004}, ++ {0x88b8, 0x0002e340}, ++ {0x88bc, 0x4380e348}, ++ {0x88c0, 0x4d000007}, ++ {0x88c4, 0x43000004}, ++ {0x88c8, 0x00017900}, ++ {0x88cc, 0x775e0004}, ++ {0x88d0, 0x000731b3}, ++ {0x88d4, 0x07a306a2}, ++ {0x88d8, 0xe29331dd}, ++ {0x88dc, 0x73000005}, ++ {0x88e0, 0xe2930001}, ++ {0x88e4, 0x5d000006}, ++ {0x88e8, 0x42f70004}, ++ {0x88ec, 0x6c000005}, ++ {0x88f0, 0x42000004}, ++ {0x88f4, 0x0004e2ab}, ++ {0x88f8, 0x00074380}, ++ {0x88fc, 0x4a004e00}, ++ {0x8900, 0x00064c00}, ++ {0x8904, 0x60007f00}, ++ {0x8908, 0x00046f00}, ++ {0x890c, 0x00054300}, ++ {0x8910, 0x00017300}, ++ {0x8914, 0xe2930001}, ++ {0x8918, 0x5d010006}, ++ {0x891c, 0x61006002}, ++ {0x8920, 0x00055601}, ++ {0x8924, 0xe2ab7710}, ++ {0x8928, 0x73000005}, ++ {0x892c, 0x43800004}, ++ {0x8930, 0x5e010007}, ++ {0x8934, 0x4d205e00}, ++ {0x8938, 0x4a084e20}, ++ {0x893c, 0x4c3f4960}, ++ {0x8940, 0x00064301}, ++ {0x8944, 0x63807f01}, ++ {0x8948, 0x00046010}, ++ {0x894c, 0x00064300}, ++ {0x8950, 0x00077402}, ++ {0x8954, 0x40004001}, ++ {0x8958, 0x0006ab00}, ++ {0x895c, 0x00077404}, ++ {0x8960, 0x40004001}, ++ {0x8964, 0x0004ab00}, ++ {0x8968, 0x00074380}, ++ {0x896c, 0x4e004d00}, ++ {0x8970, 0x4c004a00}, ++ {0x8974, 0x00064300}, ++ {0x8978, 0x63007f00}, ++ {0x897c, 0x6f006000}, ++ {0x8980, 0x43000004}, ++ {0x8984, 0x00040001}, ++ {0x8988, 0x42bf4380}, ++ {0x898c, 0x48400007}, ++ {0x8990, 0x42ef0004}, ++ {0x8994, 0x4d100007}, ++ {0x8998, 0x42000004}, ++ {0x899c, 0x5f800006}, ++ {0x89a0, 0x5a010007}, ++ {0x89a4, 0x00044a08}, ++ {0x89a8, 0x00054300}, ++ {0x89ac, 0x73807381}, ++ {0x89b0, 0x003f9300}, ++ {0x89b4, 0x00000000}, ++ {0x89b8, 0x00000000}, ++ {0x89bc, 0x00020000}, ++ {0x89c0, 0x5f800006}, ++ {0x89c4, 0x99005f00}, ++ {0x89c8, 0x43800004}, ++ {0x89cc, 0x00074280}, ++ {0x89d0, 0x00044800}, ++ {0x89d4, 0x000742ef}, ++ {0x89d8, 0x00044d00}, ++ {0x89dc, 0x00064200}, ++ {0x89e0, 0x60005f00}, ++ {0x89e4, 0x5a000007}, ++ {0x89e8, 0x48004a00}, ++ {0x89ec, 0x43000004}, ++ {0x89f0, 0x73000005}, ++ {0x89f4, 0x43800001}, ++ {0x89f8, 0x78006505}, ++ {0x89fc, 0x7a007900}, ++ {0x8a00, 0x43007b00}, ++ {0x8a04, 0x43800001}, ++ {0x8a08, 0x43006500}, ++ {0x8a0c, 0x43800001}, ++ {0x8a10, 0x7c006405}, ++ {0x8a14, 0x7e007d00}, ++ {0x8a18, 0x43007f00}, ++ {0x8a1c, 0x43800001}, ++ {0x8a20, 0x43006400}, ++ {0x8a24, 0x00060001}, ++ {0x8a28, 0x55025601}, ++ {0x8a2c, 0x00055400}, ++ {0x8a30, 0x7e127f00}, ++ {0x8a34, 0x76007710}, ++ {0x8a38, 0x74007500}, ++ {0x8a3c, 0x42700004}, ++ {0x8a40, 0x73810005}, ++ {0x8a44, 0x00047380}, ++ {0x8a48, 0x93004200}, ++ {0x8a4c, 0x77000005}, ++ {0x8a50, 0x56000006}, ++ {0x8a54, 0x00060001}, ++ {0x8a58, 0x5f005f80}, ++ {0x8a5c, 0x00059900}, ++ {0x8a60, 0x00067300}, ++ {0x8a64, 0x63006380}, ++ {0x8a68, 0x00019800}, ++ {0x8a6c, 0x7b484380}, ++ {0x8a70, 0x79007a90}, ++ {0x8a74, 0x43007802}, ++ {0x8a78, 0x32cd5503}, ++ {0x8a7c, 0x7b384380}, ++ {0x8a80, 0x79007a80}, ++ {0x8a84, 0x43007802}, ++ {0x8a88, 0x32cd5513}, ++ {0x8a8c, 0x7b404380}, ++ {0x8a90, 0x79007a00}, ++ {0x8a94, 0x43007802}, ++ {0x8a98, 0x74315523}, ++ {0x8a9c, 0x8e007430}, ++ {0x8aa0, 0x74010001}, ++ {0x8aa4, 0x8e007400}, ++ {0x8aa8, 0x74310001}, ++ {0x8aac, 0x8e007430}, ++ {0x8ab0, 0x57020001}, ++ {0x8ab4, 0x97005700}, ++ {0x8ab8, 0x42ef0001}, ++ {0x8abc, 0x56005610}, ++ {0x8ac0, 0x8c004200}, ++ {0x8ac4, 0x4f780001}, ++ {0x8ac8, 0x53884e00}, ++ {0x8acc, 0x5b205201}, ++ {0x8ad0, 0x5480e2f2}, ++ {0x8ad4, 0x54815400}, ++ {0x8ad8, 0x54825400}, ++ {0x8adc, 0xe2fd5400}, ++ {0x8ae0, 0x3012bf1d}, ++ {0x8ae4, 0xe2bee2b6}, ++ {0x8ae8, 0xe2d9e2c6}, ++ {0x8aec, 0x5523e359}, ++ {0x8af0, 0x5525e2cd}, ++ {0x8af4, 0xe359e2d9}, ++ {0x8af8, 0x54bf0001}, ++ {0x8afc, 0x54a354c0}, ++ {0x8b00, 0x54a454c1}, ++ {0x8b04, 0xbf074c18}, ++ {0x8b08, 0x54a454c2}, ++ {0x8b0c, 0x54c1bf04}, ++ {0x8b10, 0xbf0154a3}, ++ {0x8b14, 0x54dfe36a}, ++ {0x8b18, 0x54bf0001}, ++ {0x8b1c, 0x050a54e5}, ++ {0x8b20, 0x000154df}, ++ {0x8b24, 0x43807b80}, ++ {0x8b28, 0x7e007f40}, ++ {0x8b2c, 0x7c027d00}, ++ {0x8b30, 0x5b404300}, ++ {0x8b34, 0x5c015501}, ++ {0x8b38, 0x5480e2dd}, ++ {0x8b3c, 0x54815400}, ++ {0x8b40, 0x54825400}, ++ {0x8b44, 0x7b005400}, ++ {0x8b48, 0xbfe8e2fd}, ++ {0x8b4c, 0x56103012}, ++ {0x8b50, 0x8c005600}, ++ {0x8b54, 0xe36d0001}, ++ {0x8b58, 0xe36de36d}, ++ {0x8b5c, 0x0001e36d}, ++ {0x8b60, 0x57005704}, ++ {0x8b64, 0x57089700}, ++ {0x8b68, 0x97005700}, ++ {0x8b6c, 0x57805781}, ++ {0x8b70, 0x43809700}, ++ {0x8b74, 0x5c010007}, ++ {0x8b78, 0x00045c00}, ++ {0x8b7c, 0x00014300}, ++ {0x8b80, 0x0007427f}, ++ {0x8b84, 0x62006280}, ++ {0x8b88, 0x00049200}, ++ {0x8b8c, 0x00014200}, ++ {0x8b90, 0x0007427f}, ++ {0x8b94, 0x63146394}, ++ {0x8b98, 0x00049100}, ++ {0x8b9c, 0x00014200}, ++ {0x8ba0, 0x79010004}, ++ {0x8ba4, 0xe3757420}, ++ {0x8ba8, 0x57005710}, ++ {0x8bac, 0xe375e375}, ++ {0x8bb0, 0x549f0001}, ++ {0x8bb4, 0x5c015400}, ++ {0x8bb8, 0x540054df}, ++ {0x8bbc, 0x00015c02}, ++ {0x8bc0, 0x07145c01}, ++ {0x8bc4, 0x5c025400}, ++ {0x8bc8, 0x5c020001}, ++ {0x8bcc, 0x54000714}, ++ {0x8bd0, 0x00015c01}, ++ {0x8bd4, 0x4c184c98}, ++ {0x8bd8, 0x003f0001}, ++ {0x8bdc, 0x00000000}, ++ {0x8be0, 0x00000000}, ++ {0x8be4, 0x00020000}, ++ {0x8be8, 0x00000001}, ++ {0x8bec, 0x00000000}, ++ {0x8bf0, 0x00000000}, ++ {0x8bf4, 0x00000000}, ++ {0x8bf8, 0x00010000}, ++ {0x8bfc, 0x5c020004}, ++ {0x8c00, 0x66076204}, ++ {0x8c04, 0x743070c0}, ++ {0x8c08, 0x0c010901}, ++ {0x8c0c, 0x00010ba6}, ++ {0x8080, 0x00000004}, ++ {0x8080, 0x00000000}, ++ {0x8088, 0x00000000}, ++}; ++ ++static const struct rtw89_txpwr_byrate_cfg rtw89_8852a_txpwr_byrate[] = { ++ { 0, 0, 0, 0, 4, 0x50505050, }, ++ { 0, 0, 1, 0, 4, 0x50505050, }, ++ { 0, 0, 1, 4, 4, 0x484c5050, }, ++ { 0, 0, 2, 0, 4, 0x50505050, }, ++ { 0, 0, 2, 4, 4, 0x44484c50, }, ++ { 0, 0, 2, 8, 4, 0x34383c40, }, ++ { 0, 0, 3, 0, 4, 0x50505050, }, ++ { 0, 1, 2, 0, 4, 0x50505050, }, ++ { 0, 1, 2, 4, 4, 0x44484c50, }, ++ { 0, 1, 2, 8, 4, 0x34383c40, }, ++ { 0, 1, 3, 0, 4, 0x50505050, }, ++ { 0, 0, 4, 1, 4, 0x00000000, }, ++ { 0, 0, 4, 0, 1, 0x00000000, }, ++ { 1, 0, 1, 0, 4, 0x50505050, }, ++ { 1, 0, 1, 4, 4, 0x484c5050, }, ++ { 1, 0, 2, 0, 4, 0x50505050, }, ++ { 1, 0, 2, 4, 4, 0x44484c50, }, ++ { 1, 0, 2, 8, 4, 0x34383c40, }, ++ { 1, 0, 3, 0, 4, 0x50505050, }, ++ { 1, 1, 2, 0, 4, 0x50505050, }, ++ { 1, 1, 2, 4, 4, 0x44484c50, }, ++ { 1, 1, 2, 8, 4, 0x34383c40, }, ++ { 1, 1, 3, 0, 4, 0x50505050, }, ++ { 1, 0, 4, 0, 4, 0x00000000, }, ++}; ++ ++static const u8 _txpwr_track_delta_swingidx_5gb_n[][DELTA_SWINGIDX_SIZE] = { ++ {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, ++ 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11}, ++ {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, ++ 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8}, ++ {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, ++ 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, ++}; ++ ++static const u8 _txpwr_track_delta_swingidx_5gb_p[][DELTA_SWINGIDX_SIZE] = { ++ {0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, ++ 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11}, ++ {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, ++ 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8}, ++ {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, ++ 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, ++}; ++ ++static const u8 _txpwr_track_delta_swingidx_5ga_n[][DELTA_SWINGIDX_SIZE] = { ++ {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, ++ 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11}, ++ {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, ++ 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8}, ++ {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, ++ 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, ++}; ++ ++static const u8 _txpwr_track_delta_swingidx_5ga_p[][DELTA_SWINGIDX_SIZE] = { ++ {0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, ++ 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11}, ++ {0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, ++ 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8}, ++ {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, ++ 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9}, ++}; ++ ++static const u8 _txpwr_track_delta_swingidx_2gb_n[] = { ++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, ++ 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7}; ++ ++static const u8 _txpwr_track_delta_swingidx_2gb_p[] = { ++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3}; ++ ++static const u8 _txpwr_track_delta_swingidx_2ga_n[] = { ++ 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, ++ 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5}; ++ ++static const u8 _txpwr_track_delta_swingidx_2ga_p[] = { ++ 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, ++ 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}; ++ ++static const u8 _txpwr_track_delta_swingidx_2g_cck_b_n[] = { ++ 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, ++ 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7}; ++ ++static const u8 _txpwr_track_delta_swingidx_2g_cck_b_p[] = { ++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3}; ++ ++static const u8 _txpwr_track_delta_swingidx_2g_cck_a_n[] = { ++ 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, ++ 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5}; ++ ++static const u8 _txpwr_track_delta_swingidx_2g_cck_a_p[] = { ++ 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, ++ 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10}; ++ ++const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] ++ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] ++ [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { ++ [0][0][0][0][0][0] = 56, ++ [0][0][0][0][0][1] = 56, ++ [0][0][0][0][0][2] = 56, ++ [0][0][0][0][0][3] = 56, ++ [0][0][0][0][0][4] = 56, ++ [0][0][0][0][0][5] = 56, ++ [0][0][0][0][0][6] = 56, ++ [0][0][0][0][0][7] = 56, ++ [0][0][0][0][0][8] = 56, ++ [0][0][0][0][0][9] = 56, ++ [0][0][0][0][0][10] = 56, ++ [0][0][0][0][0][11] = 56, ++ [0][0][0][0][0][12] = 48, ++ [0][0][0][0][0][13] = 76, ++ [0][1][0][0][0][0] = 44, ++ [0][1][0][0][0][1] = 44, ++ [0][1][0][0][0][2] = 44, ++ [0][1][0][0][0][3] = 44, ++ [0][1][0][0][0][4] = 44, ++ [0][1][0][0][0][5] = 44, ++ [0][1][0][0][0][6] = 44, ++ [0][1][0][0][0][7] = 44, ++ [0][1][0][0][0][8] = 44, ++ [0][1][0][0][0][9] = 44, ++ [0][1][0][0][0][10] = 44, ++ [0][1][0][0][0][11] = 44, ++ [0][1][0][0][0][12] = 38, ++ [0][1][0][0][0][13] = 64, ++ [1][0][0][0][0][0] = 0, ++ [1][0][0][0][0][1] = 0, ++ [1][0][0][0][0][2] = 58, ++ [1][0][0][0][0][3] = 58, ++ [1][0][0][0][0][4] = 58, ++ [1][0][0][0][0][5] = 58, ++ [1][0][0][0][0][6] = 46, ++ [1][0][0][0][0][7] = 46, ++ [1][0][0][0][0][8] = 46, ++ [1][0][0][0][0][9] = 32, ++ [1][0][0][0][0][10] = 32, ++ [1][0][0][0][0][11] = 0, ++ [1][0][0][0][0][12] = 0, ++ [1][0][0][0][0][13] = 0, ++ [1][1][0][0][0][0] = 0, ++ [1][1][0][0][0][1] = 0, ++ [1][1][0][0][0][2] = 46, ++ [1][1][0][0][0][3] = 46, ++ [1][1][0][0][0][4] = 46, ++ [1][1][0][0][0][5] = 46, ++ [1][1][0][0][0][6] = 46, ++ [1][1][0][0][0][7] = 46, ++ [1][1][0][0][0][8] = 46, ++ [1][1][0][0][0][9] = 24, ++ [1][1][0][0][0][10] = 24, ++ [1][1][0][0][0][11] = 0, ++ [1][1][0][0][0][12] = 0, ++ [1][1][0][0][0][13] = 0, ++ [0][0][1][0][0][0] = 58, ++ [0][0][1][0][0][1] = 58, ++ [0][0][1][0][0][2] = 58, ++ [0][0][1][0][0][3] = 58, ++ [0][0][1][0][0][4] = 58, ++ [0][0][1][0][0][5] = 58, ++ [0][0][1][0][0][6] = 58, ++ [0][0][1][0][0][7] = 58, ++ [0][0][1][0][0][8] = 58, ++ [0][0][1][0][0][9] = 58, ++ [0][0][1][0][0][10] = 58, ++ [0][0][1][0][0][11] = 56, ++ [0][0][1][0][0][12] = 52, ++ [0][0][1][0][0][13] = 0, ++ [0][1][1][0][0][0] = 46, ++ [0][1][1][0][0][1] = 46, ++ [0][1][1][0][0][2] = 46, ++ [0][1][1][0][0][3] = 46, ++ [0][1][1][0][0][4] = 46, ++ [0][1][1][0][0][5] = 46, ++ [0][1][1][0][0][6] = 46, ++ [0][1][1][0][0][7] = 46, ++ [0][1][1][0][0][8] = 46, ++ [0][1][1][0][0][9] = 46, ++ [0][1][1][0][0][10] = 46, ++ [0][1][1][0][0][11] = 42, ++ [0][1][1][0][0][12] = 40, ++ [0][1][1][0][0][13] = 0, ++ [0][0][2][0][0][0] = 58, ++ [0][0][2][0][0][1] = 58, ++ [0][0][2][0][0][2] = 58, ++ [0][0][2][0][0][3] = 58, ++ [0][0][2][0][0][4] = 58, ++ [0][0][2][0][0][5] = 58, ++ [0][0][2][0][0][6] = 58, ++ [0][0][2][0][0][7] = 58, ++ [0][0][2][0][0][8] = 58, ++ [0][0][2][0][0][9] = 58, ++ [0][0][2][0][0][10] = 58, ++ [0][0][2][0][0][11] = 54, ++ [0][0][2][0][0][12] = 50, ++ [0][0][2][0][0][13] = 0, ++ [0][1][2][0][0][0] = 46, ++ [0][1][2][0][0][1] = 46, ++ [0][1][2][0][0][2] = 46, ++ [0][1][2][0][0][3] = 46, ++ [0][1][2][0][0][4] = 46, ++ [0][1][2][0][0][5] = 46, ++ [0][1][2][0][0][6] = 46, ++ [0][1][2][0][0][7] = 46, ++ [0][1][2][0][0][8] = 46, ++ [0][1][2][0][0][9] = 46, ++ [0][1][2][0][0][10] = 46, ++ [0][1][2][0][0][11] = 42, ++ [0][1][2][0][0][12] = 40, ++ [0][1][2][0][0][13] = 0, ++ [0][1][2][1][0][0] = 34, ++ [0][1][2][1][0][1] = 34, ++ [0][1][2][1][0][2] = 34, ++ [0][1][2][1][0][3] = 34, ++ [0][1][2][1][0][4] = 34, ++ [0][1][2][1][0][5] = 34, ++ [0][1][2][1][0][6] = 34, ++ [0][1][2][1][0][7] = 34, ++ [0][1][2][1][0][8] = 34, ++ [0][1][2][1][0][9] = 34, ++ [0][1][2][1][0][10] = 34, ++ [0][1][2][1][0][11] = 34, ++ [0][1][2][1][0][12] = 34, ++ [0][1][2][1][0][13] = 0, ++ [1][0][2][0][0][0] = 0, ++ [1][0][2][0][0][1] = 0, ++ [1][0][2][0][0][2] = 56, ++ [1][0][2][0][0][3] = 56, ++ [1][0][2][0][0][4] = 58, ++ [1][0][2][0][0][5] = 58, ++ [1][0][2][0][0][6] = 54, ++ [1][0][2][0][0][7] = 50, ++ [1][0][2][0][0][8] = 50, ++ [1][0][2][0][0][9] = 42, ++ [1][0][2][0][0][10] = 40, ++ [1][0][2][0][0][11] = 0, ++ [1][0][2][0][0][12] = 0, ++ [1][0][2][0][0][13] = 0, ++ [1][1][2][0][0][0] = 0, ++ [1][1][2][0][0][1] = 0, ++ [1][1][2][0][0][2] = 46, ++ [1][1][2][0][0][3] = 46, ++ [1][1][2][0][0][4] = 46, ++ [1][1][2][0][0][5] = 46, ++ [1][1][2][0][0][6] = 46, ++ [1][1][2][0][0][7] = 46, ++ [1][1][2][0][0][8] = 46, ++ [1][1][2][0][0][9] = 38, ++ [1][1][2][0][0][10] = 36, ++ [1][1][2][0][0][11] = 0, ++ [1][1][2][0][0][12] = 0, ++ [1][1][2][0][0][13] = 0, ++ [1][1][2][1][0][0] = 0, ++ [1][1][2][1][0][1] = 0, ++ [1][1][2][1][0][2] = 34, ++ [1][1][2][1][0][3] = 34, ++ [1][1][2][1][0][4] = 34, ++ [1][1][2][1][0][5] = 34, ++ [1][1][2][1][0][6] = 34, ++ [1][1][2][1][0][7] = 34, ++ [1][1][2][1][0][8] = 34, ++ [1][1][2][1][0][9] = 34, ++ [1][1][2][1][0][10] = 34, ++ [1][1][2][1][0][11] = 0, ++ [1][1][2][1][0][12] = 0, ++ [1][1][2][1][0][13] = 0, ++ [0][0][0][0][2][0] = 76, ++ [0][0][0][0][1][0] = 56, ++ [0][0][0][0][3][0] = 68, ++ [0][0][0][0][5][0] = 76, ++ [0][0][0][0][6][0] = 56, ++ [0][0][0][0][9][0] = 56, ++ [0][0][0][0][8][0] = 60, ++ [0][0][0][0][11][0] = 56, ++ [0][0][0][0][2][1] = 76, ++ [0][0][0][0][1][1] = 56, ++ [0][0][0][0][3][1] = 68, ++ [0][0][0][0][5][1] = 76, ++ [0][0][0][0][6][1] = 56, ++ [0][0][0][0][9][1] = 56, ++ [0][0][0][0][8][1] = 60, ++ [0][0][0][0][11][1] = 56, ++ [0][0][0][0][2][2] = 76, ++ [0][0][0][0][1][2] = 56, ++ [0][0][0][0][3][2] = 68, ++ [0][0][0][0][5][2] = 76, ++ [0][0][0][0][6][2] = 56, ++ [0][0][0][0][9][2] = 56, ++ [0][0][0][0][8][2] = 60, ++ [0][0][0][0][11][2] = 56, ++ [0][0][0][0][2][3] = 76, ++ [0][0][0][0][1][3] = 56, ++ [0][0][0][0][3][3] = 68, ++ [0][0][0][0][5][3] = 76, ++ [0][0][0][0][6][3] = 56, ++ [0][0][0][0][9][3] = 56, ++ [0][0][0][0][8][3] = 60, ++ [0][0][0][0][11][3] = 56, ++ [0][0][0][0][2][4] = 76, ++ [0][0][0][0][1][4] = 56, ++ [0][0][0][0][3][4] = 68, ++ [0][0][0][0][5][4] = 76, ++ [0][0][0][0][6][4] = 56, ++ [0][0][0][0][9][4] = 56, ++ [0][0][0][0][8][4] = 60, ++ [0][0][0][0][11][4] = 56, ++ [0][0][0][0][2][5] = 76, ++ [0][0][0][0][1][5] = 56, ++ [0][0][0][0][3][5] = 68, ++ [0][0][0][0][5][5] = 76, ++ [0][0][0][0][6][5] = 56, ++ [0][0][0][0][9][5] = 56, ++ [0][0][0][0][8][5] = 60, ++ [0][0][0][0][11][5] = 56, ++ [0][0][0][0][2][6] = 76, ++ [0][0][0][0][1][6] = 56, ++ [0][0][0][0][3][6] = 68, ++ [0][0][0][0][5][6] = 76, ++ [0][0][0][0][6][6] = 56, ++ [0][0][0][0][9][6] = 56, ++ [0][0][0][0][8][6] = 60, ++ [0][0][0][0][11][6] = 56, ++ [0][0][0][0][2][7] = 76, ++ [0][0][0][0][1][7] = 56, ++ [0][0][0][0][3][7] = 68, ++ [0][0][0][0][5][7] = 76, ++ [0][0][0][0][6][7] = 56, ++ [0][0][0][0][9][7] = 56, ++ [0][0][0][0][8][7] = 60, ++ [0][0][0][0][11][7] = 56, ++ [0][0][0][0][2][8] = 76, ++ [0][0][0][0][1][8] = 56, ++ [0][0][0][0][3][8] = 68, ++ [0][0][0][0][5][8] = 76, ++ [0][0][0][0][6][8] = 56, ++ [0][0][0][0][9][8] = 56, ++ [0][0][0][0][8][8] = 60, ++ [0][0][0][0][11][8] = 56, ++ [0][0][0][0][2][9] = 76, ++ [0][0][0][0][1][9] = 56, ++ [0][0][0][0][3][9] = 68, ++ [0][0][0][0][5][9] = 76, ++ [0][0][0][0][6][9] = 56, ++ [0][0][0][0][9][9] = 56, ++ [0][0][0][0][8][9] = 60, ++ [0][0][0][0][11][9] = 56, ++ [0][0][0][0][2][10] = 76, ++ [0][0][0][0][1][10] = 56, ++ [0][0][0][0][3][10] = 68, ++ [0][0][0][0][5][10] = 76, ++ [0][0][0][0][6][10] = 56, ++ [0][0][0][0][9][10] = 56, ++ [0][0][0][0][8][10] = 60, ++ [0][0][0][0][11][10] = 56, ++ [0][0][0][0][2][11] = 68, ++ [0][0][0][0][1][11] = 56, ++ [0][0][0][0][3][11] = 68, ++ [0][0][0][0][5][11] = 68, ++ [0][0][0][0][6][11] = 56, ++ [0][0][0][0][9][11] = 56, ++ [0][0][0][0][8][11] = 60, ++ [0][0][0][0][11][11] = 56, ++ [0][0][0][0][2][12] = 48, ++ [0][0][0][0][1][12] = 56, ++ [0][0][0][0][3][12] = 68, ++ [0][0][0][0][5][12] = 48, ++ [0][0][0][0][6][12] = 56, ++ [0][0][0][0][9][12] = 56, ++ [0][0][0][0][8][12] = 60, ++ [0][0][0][0][11][12] = 56, ++ [0][0][0][0][2][13] = 127, ++ [0][0][0][0][1][13] = 127, ++ [0][0][0][0][3][13] = 76, ++ [0][0][0][0][5][13] = 127, ++ [0][0][0][0][6][13] = 127, ++ [0][0][0][0][9][13] = 127, ++ [0][0][0][0][8][13] = 127, ++ [0][0][0][0][11][13] = 127, ++ [0][1][0][0][2][0] = 74, ++ [0][1][0][0][1][0] = 44, ++ [0][1][0][0][3][0] = 56, ++ [0][1][0][0][5][0] = 74, ++ [0][1][0][0][6][0] = 44, ++ [0][1][0][0][9][0] = 44, ++ [0][1][0][0][8][0] = 48, ++ [0][1][0][0][11][0] = 44, ++ [0][1][0][0][2][1] = 76, ++ [0][1][0][0][1][1] = 44, ++ [0][1][0][0][3][1] = 56, ++ [0][1][0][0][5][1] = 76, ++ [0][1][0][0][6][1] = 44, ++ [0][1][0][0][9][1] = 44, ++ [0][1][0][0][8][1] = 48, ++ [0][1][0][0][11][1] = 44, ++ [0][1][0][0][2][2] = 76, ++ [0][1][0][0][1][2] = 44, ++ [0][1][0][0][3][2] = 56, ++ [0][1][0][0][5][2] = 76, ++ [0][1][0][0][6][2] = 44, ++ [0][1][0][0][9][2] = 44, ++ [0][1][0][0][8][2] = 48, ++ [0][1][0][0][11][2] = 44, ++ [0][1][0][0][2][3] = 76, ++ [0][1][0][0][1][3] = 44, ++ [0][1][0][0][3][3] = 56, ++ [0][1][0][0][5][3] = 76, ++ [0][1][0][0][6][3] = 44, ++ [0][1][0][0][9][3] = 44, ++ [0][1][0][0][8][3] = 48, ++ [0][1][0][0][11][3] = 44, ++ [0][1][0][0][2][4] = 76, ++ [0][1][0][0][1][4] = 44, ++ [0][1][0][0][3][4] = 56, ++ [0][1][0][0][5][4] = 76, ++ [0][1][0][0][6][4] = 44, ++ [0][1][0][0][9][4] = 44, ++ [0][1][0][0][8][4] = 48, ++ [0][1][0][0][11][4] = 44, ++ [0][1][0][0][2][5] = 76, ++ [0][1][0][0][1][5] = 44, ++ [0][1][0][0][3][5] = 56, ++ [0][1][0][0][5][5] = 76, ++ [0][1][0][0][6][5] = 44, ++ [0][1][0][0][9][5] = 44, ++ [0][1][0][0][8][5] = 48, ++ [0][1][0][0][11][5] = 44, ++ [0][1][0][0][2][6] = 76, ++ [0][1][0][0][1][6] = 44, ++ [0][1][0][0][3][6] = 56, ++ [0][1][0][0][5][6] = 76, ++ [0][1][0][0][6][6] = 44, ++ [0][1][0][0][9][6] = 44, ++ [0][1][0][0][8][6] = 48, ++ [0][1][0][0][11][6] = 44, ++ [0][1][0][0][2][7] = 76, ++ [0][1][0][0][1][7] = 44, ++ [0][1][0][0][3][7] = 56, ++ [0][1][0][0][5][7] = 76, ++ [0][1][0][0][6][7] = 44, ++ [0][1][0][0][9][7] = 44, ++ [0][1][0][0][8][7] = 48, ++ [0][1][0][0][11][7] = 44, ++ [0][1][0][0][2][8] = 76, ++ [0][1][0][0][1][8] = 44, ++ [0][1][0][0][3][8] = 56, ++ [0][1][0][0][5][8] = 76, ++ [0][1][0][0][6][8] = 44, ++ [0][1][0][0][9][8] = 44, ++ [0][1][0][0][8][8] = 48, ++ [0][1][0][0][11][8] = 44, ++ [0][1][0][0][2][9] = 76, ++ [0][1][0][0][1][9] = 44, ++ [0][1][0][0][3][9] = 56, ++ [0][1][0][0][5][9] = 76, ++ [0][1][0][0][6][9] = 44, ++ [0][1][0][0][9][9] = 44, ++ [0][1][0][0][8][9] = 48, ++ [0][1][0][0][11][9] = 44, ++ [0][1][0][0][2][10] = 62, ++ [0][1][0][0][1][10] = 44, ++ [0][1][0][0][3][10] = 56, ++ [0][1][0][0][5][10] = 62, ++ [0][1][0][0][6][10] = 44, ++ [0][1][0][0][9][10] = 44, ++ [0][1][0][0][8][10] = 48, ++ [0][1][0][0][11][10] = 44, ++ [0][1][0][0][2][11] = 52, ++ [0][1][0][0][1][11] = 44, ++ [0][1][0][0][3][11] = 56, ++ [0][1][0][0][5][11] = 52, ++ [0][1][0][0][6][11] = 44, ++ [0][1][0][0][9][11] = 44, ++ [0][1][0][0][8][11] = 48, ++ [0][1][0][0][11][11] = 44, ++ [0][1][0][0][2][12] = 38, ++ [0][1][0][0][1][12] = 44, ++ [0][1][0][0][3][12] = 56, ++ [0][1][0][0][5][12] = 38, ++ [0][1][0][0][6][12] = 44, ++ [0][1][0][0][9][12] = 44, ++ [0][1][0][0][8][12] = 48, ++ [0][1][0][0][11][12] = 44, ++ [0][1][0][0][2][13] = 127, ++ [0][1][0][0][1][13] = 127, ++ [0][1][0][0][3][13] = 64, ++ [0][1][0][0][5][13] = 127, ++ [0][1][0][0][6][13] = 127, ++ [0][1][0][0][9][13] = 127, ++ [0][1][0][0][8][13] = 127, ++ [0][1][0][0][11][13] = 127, ++ [1][0][0][0][2][0] = 127, ++ [1][0][0][0][1][0] = 127, ++ [1][0][0][0][3][0] = 127, ++ [1][0][0][0][5][0] = 127, ++ [1][0][0][0][6][0] = 127, ++ [1][0][0][0][9][0] = 127, ++ [1][0][0][0][8][0] = 127, ++ [1][0][0][0][11][0] = 127, ++ [1][0][0][0][2][1] = 127, ++ [1][0][0][0][1][1] = 127, ++ [1][0][0][0][3][1] = 127, ++ [1][0][0][0][5][1] = 127, ++ [1][0][0][0][6][1] = 127, ++ [1][0][0][0][9][1] = 127, ++ [1][0][0][0][8][1] = 127, ++ [1][0][0][0][11][1] = 127, ++ [1][0][0][0][2][2] = 60, ++ [1][0][0][0][1][2] = 58, ++ [1][0][0][0][3][2] = 68, ++ [1][0][0][0][5][2] = 60, ++ [1][0][0][0][6][2] = 58, ++ [1][0][0][0][9][2] = 58, ++ [1][0][0][0][8][2] = 60, ++ [1][0][0][0][11][2] = 58, ++ [1][0][0][0][2][3] = 60, ++ [1][0][0][0][1][3] = 58, ++ [1][0][0][0][3][3] = 68, ++ [1][0][0][0][5][3] = 60, ++ [1][0][0][0][6][3] = 58, ++ [1][0][0][0][9][3] = 58, ++ [1][0][0][0][8][3] = 60, ++ [1][0][0][0][11][3] = 58, ++ [1][0][0][0][2][4] = 60, ++ [1][0][0][0][1][4] = 58, ++ [1][0][0][0][3][4] = 68, ++ [1][0][0][0][5][4] = 60, ++ [1][0][0][0][6][4] = 58, ++ [1][0][0][0][9][4] = 58, ++ [1][0][0][0][8][4] = 60, ++ [1][0][0][0][11][4] = 58, ++ [1][0][0][0][2][5] = 60, ++ [1][0][0][0][1][5] = 58, ++ [1][0][0][0][3][5] = 68, ++ [1][0][0][0][5][5] = 60, ++ [1][0][0][0][6][5] = 58, ++ [1][0][0][0][9][5] = 58, ++ [1][0][0][0][8][5] = 60, ++ [1][0][0][0][11][5] = 58, ++ [1][0][0][0][2][6] = 46, ++ [1][0][0][0][1][6] = 58, ++ [1][0][0][0][3][6] = 68, ++ [1][0][0][0][5][6] = 46, ++ [1][0][0][0][6][6] = 58, ++ [1][0][0][0][9][6] = 58, ++ [1][0][0][0][8][6] = 60, ++ [1][0][0][0][11][6] = 58, ++ [1][0][0][0][2][7] = 46, ++ [1][0][0][0][1][7] = 58, ++ [1][0][0][0][3][7] = 68, ++ [1][0][0][0][5][7] = 46, ++ [1][0][0][0][6][7] = 58, ++ [1][0][0][0][9][7] = 58, ++ [1][0][0][0][8][7] = 60, ++ [1][0][0][0][11][7] = 58, ++ [1][0][0][0][2][8] = 46, ++ [1][0][0][0][1][8] = 58, ++ [1][0][0][0][3][8] = 68, ++ [1][0][0][0][5][8] = 46, ++ [1][0][0][0][6][8] = 58, ++ [1][0][0][0][9][8] = 58, ++ [1][0][0][0][8][8] = 60, ++ [1][0][0][0][11][8] = 58, ++ [1][0][0][0][2][9] = 32, ++ [1][0][0][0][1][9] = 58, ++ [1][0][0][0][3][9] = 68, ++ [1][0][0][0][5][9] = 32, ++ [1][0][0][0][6][9] = 58, ++ [1][0][0][0][9][9] = 58, ++ [1][0][0][0][8][9] = 60, ++ [1][0][0][0][11][9] = 58, ++ [1][0][0][0][2][10] = 32, ++ [1][0][0][0][1][10] = 58, ++ [1][0][0][0][3][10] = 68, ++ [1][0][0][0][5][10] = 32, ++ [1][0][0][0][6][10] = 58, ++ [1][0][0][0][9][10] = 58, ++ [1][0][0][0][8][10] = 60, ++ [1][0][0][0][11][10] = 58, ++ [1][0][0][0][2][11] = 127, ++ [1][0][0][0][1][11] = 127, ++ [1][0][0][0][3][11] = 127, ++ [1][0][0][0][5][11] = 127, ++ [1][0][0][0][6][11] = 127, ++ [1][0][0][0][9][11] = 127, ++ [1][0][0][0][8][11] = 127, ++ [1][0][0][0][11][11] = 127, ++ [1][0][0][0][2][12] = 127, ++ [1][0][0][0][1][12] = 127, ++ [1][0][0][0][3][12] = 127, ++ [1][0][0][0][5][12] = 127, ++ [1][0][0][0][6][12] = 127, ++ [1][0][0][0][9][12] = 127, ++ [1][0][0][0][8][12] = 127, ++ [1][0][0][0][11][12] = 127, ++ [1][0][0][0][2][13] = 127, ++ [1][0][0][0][1][13] = 127, ++ [1][0][0][0][3][13] = 127, ++ [1][0][0][0][5][13] = 127, ++ [1][0][0][0][6][13] = 127, ++ [1][0][0][0][9][13] = 127, ++ [1][0][0][0][8][13] = 127, ++ [1][0][0][0][11][13] = 127, ++ [1][1][0][0][2][0] = 127, ++ [1][1][0][0][1][0] = 127, ++ [1][1][0][0][3][0] = 127, ++ [1][1][0][0][5][0] = 127, ++ [1][1][0][0][6][0] = 127, ++ [1][1][0][0][9][0] = 127, ++ [1][1][0][0][8][0] = 127, ++ [1][1][0][0][11][0] = 127, ++ [1][1][0][0][2][1] = 127, ++ [1][1][0][0][1][1] = 127, ++ [1][1][0][0][3][1] = 127, ++ [1][1][0][0][5][1] = 127, ++ [1][1][0][0][6][1] = 127, ++ [1][1][0][0][9][1] = 127, ++ [1][1][0][0][8][1] = 127, ++ [1][1][0][0][11][1] = 127, ++ [1][1][0][0][2][2] = 48, ++ [1][1][0][0][1][2] = 46, ++ [1][1][0][0][3][2] = 56, ++ [1][1][0][0][5][2] = 48, ++ [1][1][0][0][6][2] = 46, ++ [1][1][0][0][9][2] = 46, ++ [1][1][0][0][8][2] = 48, ++ [1][1][0][0][11][2] = 46, ++ [1][1][0][0][2][3] = 48, ++ [1][1][0][0][1][3] = 46, ++ [1][1][0][0][3][3] = 56, ++ [1][1][0][0][5][3] = 48, ++ [1][1][0][0][6][3] = 46, ++ [1][1][0][0][9][3] = 46, ++ [1][1][0][0][8][3] = 48, ++ [1][1][0][0][11][3] = 46, ++ [1][1][0][0][2][4] = 48, ++ [1][1][0][0][1][4] = 46, ++ [1][1][0][0][3][4] = 56, ++ [1][1][0][0][5][4] = 48, ++ [1][1][0][0][6][4] = 46, ++ [1][1][0][0][9][4] = 46, ++ [1][1][0][0][8][4] = 48, ++ [1][1][0][0][11][4] = 46, ++ [1][1][0][0][2][5] = 58, ++ [1][1][0][0][1][5] = 46, ++ [1][1][0][0][3][5] = 56, ++ [1][1][0][0][5][5] = 58, ++ [1][1][0][0][6][5] = 46, ++ [1][1][0][0][9][5] = 46, ++ [1][1][0][0][8][5] = 48, ++ [1][1][0][0][11][5] = 46, ++ [1][1][0][0][2][6] = 46, ++ [1][1][0][0][1][6] = 46, ++ [1][1][0][0][3][6] = 56, ++ [1][1][0][0][5][6] = 46, ++ [1][1][0][0][6][6] = 46, ++ [1][1][0][0][9][6] = 46, ++ [1][1][0][0][8][6] = 48, ++ [1][1][0][0][11][6] = 46, ++ [1][1][0][0][2][7] = 46, ++ [1][1][0][0][1][7] = 46, ++ [1][1][0][0][3][7] = 56, ++ [1][1][0][0][5][7] = 46, ++ [1][1][0][0][6][7] = 46, ++ [1][1][0][0][9][7] = 46, ++ [1][1][0][0][8][7] = 48, ++ [1][1][0][0][11][7] = 46, ++ [1][1][0][0][2][8] = 46, ++ [1][1][0][0][1][8] = 46, ++ [1][1][0][0][3][8] = 56, ++ [1][1][0][0][5][8] = 46, ++ [1][1][0][0][6][8] = 46, ++ [1][1][0][0][9][8] = 46, ++ [1][1][0][0][8][8] = 48, ++ [1][1][0][0][11][8] = 46, ++ [1][1][0][0][2][9] = 24, ++ [1][1][0][0][1][9] = 46, ++ [1][1][0][0][3][9] = 56, ++ [1][1][0][0][5][9] = 24, ++ [1][1][0][0][6][9] = 46, ++ [1][1][0][0][9][9] = 46, ++ [1][1][0][0][8][9] = 48, ++ [1][1][0][0][11][9] = 46, ++ [1][1][0][0][2][10] = 24, ++ [1][1][0][0][1][10] = 46, ++ [1][1][0][0][3][10] = 56, ++ [1][1][0][0][5][10] = 24, ++ [1][1][0][0][6][10] = 46, ++ [1][1][0][0][9][10] = 46, ++ [1][1][0][0][8][10] = 48, ++ [1][1][0][0][11][10] = 46, ++ [1][1][0][0][2][11] = 127, ++ [1][1][0][0][1][11] = 127, ++ [1][1][0][0][3][11] = 127, ++ [1][1][0][0][5][11] = 127, ++ [1][1][0][0][6][11] = 127, ++ [1][1][0][0][9][11] = 127, ++ [1][1][0][0][8][11] = 127, ++ [1][1][0][0][11][11] = 127, ++ [1][1][0][0][2][12] = 127, ++ [1][1][0][0][1][12] = 127, ++ [1][1][0][0][3][12] = 127, ++ [1][1][0][0][5][12] = 127, ++ [1][1][0][0][6][12] = 127, ++ [1][1][0][0][9][12] = 127, ++ [1][1][0][0][8][12] = 127, ++ [1][1][0][0][11][12] = 127, ++ [1][1][0][0][2][13] = 127, ++ [1][1][0][0][1][13] = 127, ++ [1][1][0][0][3][13] = 127, ++ [1][1][0][0][5][13] = 127, ++ [1][1][0][0][6][13] = 127, ++ [1][1][0][0][9][13] = 127, ++ [1][1][0][0][8][13] = 127, ++ [1][1][0][0][11][13] = 127, ++ [0][0][1][0][2][0] = 66, ++ [0][0][1][0][1][0] = 58, ++ [0][0][1][0][3][0] = 76, ++ [0][0][1][0][5][0] = 66, ++ [0][0][1][0][6][0] = 58, ++ [0][0][1][0][9][0] = 58, ++ [0][0][1][0][8][0] = 60, ++ [0][0][1][0][11][0] = 58, ++ [0][0][1][0][2][1] = 66, ++ [0][0][1][0][1][1] = 58, ++ [0][0][1][0][3][1] = 76, ++ [0][0][1][0][5][1] = 66, ++ [0][0][1][0][6][1] = 58, ++ [0][0][1][0][9][1] = 58, ++ [0][0][1][0][8][1] = 60, ++ [0][0][1][0][11][1] = 58, ++ [0][0][1][0][2][2] = 70, ++ [0][0][1][0][1][2] = 58, ++ [0][0][1][0][3][2] = 76, ++ [0][0][1][0][5][2] = 70, ++ [0][0][1][0][6][2] = 58, ++ [0][0][1][0][9][2] = 58, ++ [0][0][1][0][8][2] = 60, ++ [0][0][1][0][11][2] = 58, ++ [0][0][1][0][2][3] = 74, ++ [0][0][1][0][1][3] = 58, ++ [0][0][1][0][3][3] = 76, ++ [0][0][1][0][5][3] = 74, ++ [0][0][1][0][6][3] = 58, ++ [0][0][1][0][9][3] = 58, ++ [0][0][1][0][8][3] = 60, ++ [0][0][1][0][11][3] = 58, ++ [0][0][1][0][2][4] = 78, ++ [0][0][1][0][1][4] = 58, ++ [0][0][1][0][3][4] = 76, ++ [0][0][1][0][5][4] = 78, ++ [0][0][1][0][6][4] = 58, ++ [0][0][1][0][9][4] = 58, ++ [0][0][1][0][8][4] = 60, ++ [0][0][1][0][11][4] = 58, ++ [0][0][1][0][2][5] = 78, ++ [0][0][1][0][1][5] = 58, ++ [0][0][1][0][3][5] = 76, ++ [0][0][1][0][5][5] = 78, ++ [0][0][1][0][6][5] = 58, ++ [0][0][1][0][9][5] = 58, ++ [0][0][1][0][8][5] = 60, ++ [0][0][1][0][11][5] = 58, ++ [0][0][1][0][2][6] = 78, ++ [0][0][1][0][1][6] = 58, ++ [0][0][1][0][3][6] = 76, ++ [0][0][1][0][5][6] = 78, ++ [0][0][1][0][6][6] = 58, ++ [0][0][1][0][9][6] = 58, ++ [0][0][1][0][8][6] = 60, ++ [0][0][1][0][11][6] = 58, ++ [0][0][1][0][2][7] = 74, ++ [0][0][1][0][1][7] = 58, ++ [0][0][1][0][3][7] = 76, ++ [0][0][1][0][5][7] = 74, ++ [0][0][1][0][6][7] = 58, ++ [0][0][1][0][9][7] = 58, ++ [0][0][1][0][8][7] = 60, ++ [0][0][1][0][11][7] = 58, ++ [0][0][1][0][2][8] = 70, ++ [0][0][1][0][1][8] = 58, ++ [0][0][1][0][3][8] = 76, ++ [0][0][1][0][5][8] = 70, ++ [0][0][1][0][6][8] = 58, ++ [0][0][1][0][9][8] = 58, ++ [0][0][1][0][8][8] = 60, ++ [0][0][1][0][11][8] = 58, ++ [0][0][1][0][2][9] = 66, ++ [0][0][1][0][1][9] = 58, ++ [0][0][1][0][3][9] = 76, ++ [0][0][1][0][5][9] = 66, ++ [0][0][1][0][6][9] = 58, ++ [0][0][1][0][9][9] = 58, ++ [0][0][1][0][8][9] = 60, ++ [0][0][1][0][11][9] = 58, ++ [0][0][1][0][2][10] = 66, ++ [0][0][1][0][1][10] = 58, ++ [0][0][1][0][3][10] = 76, ++ [0][0][1][0][5][10] = 66, ++ [0][0][1][0][6][10] = 58, ++ [0][0][1][0][9][10] = 58, ++ [0][0][1][0][8][10] = 60, ++ [0][0][1][0][11][10] = 58, ++ [0][0][1][0][2][11] = 56, ++ [0][0][1][0][1][11] = 58, ++ [0][0][1][0][3][11] = 76, ++ [0][0][1][0][5][11] = 56, ++ [0][0][1][0][6][11] = 58, ++ [0][0][1][0][9][11] = 58, ++ [0][0][1][0][8][11] = 60, ++ [0][0][1][0][11][11] = 58, ++ [0][0][1][0][2][12] = 52, ++ [0][0][1][0][1][12] = 58, ++ [0][0][1][0][3][12] = 76, ++ [0][0][1][0][5][12] = 52, ++ [0][0][1][0][6][12] = 58, ++ [0][0][1][0][9][12] = 58, ++ [0][0][1][0][8][12] = 60, ++ [0][0][1][0][11][12] = 58, ++ [0][0][1][0][2][13] = 127, ++ [0][0][1][0][1][13] = 127, ++ [0][0][1][0][3][13] = 127, ++ [0][0][1][0][5][13] = 127, ++ [0][0][1][0][6][13] = 127, ++ [0][0][1][0][9][13] = 127, ++ [0][0][1][0][8][13] = 127, ++ [0][0][1][0][11][13] = 127, ++ [0][1][1][0][2][0] = 62, ++ [0][1][1][0][1][0] = 46, ++ [0][1][1][0][3][0] = 64, ++ [0][1][1][0][5][0] = 62, ++ [0][1][1][0][6][0] = 46, ++ [0][1][1][0][9][0] = 46, ++ [0][1][1][0][8][0] = 48, ++ [0][1][1][0][11][0] = 46, ++ [0][1][1][0][2][1] = 62, ++ [0][1][1][0][1][1] = 46, ++ [0][1][1][0][3][1] = 64, ++ [0][1][1][0][5][1] = 62, ++ [0][1][1][0][6][1] = 46, ++ [0][1][1][0][9][1] = 46, ++ [0][1][1][0][8][1] = 48, ++ [0][1][1][0][11][1] = 46, ++ [0][1][1][0][2][2] = 66, ++ [0][1][1][0][1][2] = 46, ++ [0][1][1][0][3][2] = 64, ++ [0][1][1][0][5][2] = 66, ++ [0][1][1][0][6][2] = 46, ++ [0][1][1][0][9][2] = 46, ++ [0][1][1][0][8][2] = 48, ++ [0][1][1][0][11][2] = 46, ++ [0][1][1][0][2][3] = 70, ++ [0][1][1][0][1][3] = 46, ++ [0][1][1][0][3][3] = 64, ++ [0][1][1][0][5][3] = 70, ++ [0][1][1][0][6][3] = 46, ++ [0][1][1][0][9][3] = 46, ++ [0][1][1][0][8][3] = 48, ++ [0][1][1][0][11][3] = 46, ++ [0][1][1][0][2][4] = 78, ++ [0][1][1][0][1][4] = 46, ++ [0][1][1][0][3][4] = 64, ++ [0][1][1][0][5][4] = 78, ++ [0][1][1][0][6][4] = 46, ++ [0][1][1][0][9][4] = 46, ++ [0][1][1][0][8][4] = 48, ++ [0][1][1][0][11][4] = 46, ++ [0][1][1][0][2][5] = 78, ++ [0][1][1][0][1][5] = 46, ++ [0][1][1][0][3][5] = 64, ++ [0][1][1][0][5][5] = 78, ++ [0][1][1][0][6][5] = 46, ++ [0][1][1][0][9][5] = 46, ++ [0][1][1][0][8][5] = 48, ++ [0][1][1][0][11][5] = 46, ++ [0][1][1][0][2][6] = 78, ++ [0][1][1][0][1][6] = 46, ++ [0][1][1][0][3][6] = 64, ++ [0][1][1][0][5][6] = 78, ++ [0][1][1][0][6][6] = 46, ++ [0][1][1][0][9][6] = 46, ++ [0][1][1][0][8][6] = 48, ++ [0][1][1][0][11][6] = 46, ++ [0][1][1][0][2][7] = 70, ++ [0][1][1][0][1][7] = 46, ++ [0][1][1][0][3][7] = 64, ++ [0][1][1][0][5][7] = 70, ++ [0][1][1][0][6][7] = 46, ++ [0][1][1][0][9][7] = 46, ++ [0][1][1][0][8][7] = 48, ++ [0][1][1][0][11][7] = 46, ++ [0][1][1][0][2][8] = 66, ++ [0][1][1][0][1][8] = 46, ++ [0][1][1][0][3][8] = 64, ++ [0][1][1][0][5][8] = 66, ++ [0][1][1][0][6][8] = 46, ++ [0][1][1][0][9][8] = 46, ++ [0][1][1][0][8][8] = 48, ++ [0][1][1][0][11][8] = 46, ++ [0][1][1][0][2][9] = 62, ++ [0][1][1][0][1][9] = 46, ++ [0][1][1][0][3][9] = 64, ++ [0][1][1][0][5][9] = 62, ++ [0][1][1][0][6][9] = 46, ++ [0][1][1][0][9][9] = 46, ++ [0][1][1][0][8][9] = 48, ++ [0][1][1][0][11][9] = 46, ++ [0][1][1][0][2][10] = 62, ++ [0][1][1][0][1][10] = 46, ++ [0][1][1][0][3][10] = 64, ++ [0][1][1][0][5][10] = 62, ++ [0][1][1][0][6][10] = 46, ++ [0][1][1][0][9][10] = 46, ++ [0][1][1][0][8][10] = 48, ++ [0][1][1][0][11][10] = 46, ++ [0][1][1][0][2][11] = 42, ++ [0][1][1][0][1][11] = 46, ++ [0][1][1][0][3][11] = 64, ++ [0][1][1][0][5][11] = 42, ++ [0][1][1][0][6][11] = 46, ++ [0][1][1][0][9][11] = 46, ++ [0][1][1][0][8][11] = 48, ++ [0][1][1][0][11][11] = 46, ++ [0][1][1][0][2][12] = 40, ++ [0][1][1][0][1][12] = 46, ++ [0][1][1][0][3][12] = 64, ++ [0][1][1][0][5][12] = 40, ++ [0][1][1][0][6][12] = 46, ++ [0][1][1][0][9][12] = 46, ++ [0][1][1][0][8][12] = 48, ++ [0][1][1][0][11][12] = 46, ++ [0][1][1][0][2][13] = 127, ++ [0][1][1][0][1][13] = 127, ++ [0][1][1][0][3][13] = 127, ++ [0][1][1][0][5][13] = 127, ++ [0][1][1][0][6][13] = 127, ++ [0][1][1][0][9][13] = 127, ++ [0][1][1][0][8][13] = 127, ++ [0][1][1][0][11][13] = 127, ++ [0][0][2][0][2][0] = 66, ++ [0][0][2][0][1][0] = 58, ++ [0][0][2][0][3][0] = 76, ++ [0][0][2][0][5][0] = 66, ++ [0][0][2][0][6][0] = 58, ++ [0][0][2][0][9][0] = 58, ++ [0][0][2][0][8][0] = 60, ++ [0][0][2][0][11][0] = 58, ++ [0][0][2][0][2][1] = 66, ++ [0][0][2][0][1][1] = 58, ++ [0][0][2][0][3][1] = 76, ++ [0][0][2][0][5][1] = 66, ++ [0][0][2][0][6][1] = 58, ++ [0][0][2][0][9][1] = 58, ++ [0][0][2][0][8][1] = 60, ++ [0][0][2][0][11][1] = 58, ++ [0][0][2][0][2][2] = 70, ++ [0][0][2][0][1][2] = 58, ++ [0][0][2][0][3][2] = 76, ++ [0][0][2][0][5][2] = 70, ++ [0][0][2][0][6][2] = 58, ++ [0][0][2][0][9][2] = 58, ++ [0][0][2][0][8][2] = 60, ++ [0][0][2][0][11][2] = 58, ++ [0][0][2][0][2][3] = 74, ++ [0][0][2][0][1][3] = 58, ++ [0][0][2][0][3][3] = 76, ++ [0][0][2][0][5][3] = 74, ++ [0][0][2][0][6][3] = 58, ++ [0][0][2][0][9][3] = 58, ++ [0][0][2][0][8][3] = 60, ++ [0][0][2][0][11][3] = 58, ++ [0][0][2][0][2][4] = 76, ++ [0][0][2][0][1][4] = 58, ++ [0][0][2][0][3][4] = 76, ++ [0][0][2][0][5][4] = 76, ++ [0][0][2][0][6][4] = 58, ++ [0][0][2][0][9][4] = 58, ++ [0][0][2][0][8][4] = 60, ++ [0][0][2][0][11][4] = 58, ++ [0][0][2][0][2][5] = 76, ++ [0][0][2][0][1][5] = 58, ++ [0][0][2][0][3][5] = 76, ++ [0][0][2][0][5][5] = 76, ++ [0][0][2][0][6][5] = 58, ++ [0][0][2][0][9][5] = 58, ++ [0][0][2][0][8][5] = 60, ++ [0][0][2][0][11][5] = 58, ++ [0][0][2][0][2][6] = 76, ++ [0][0][2][0][1][6] = 58, ++ [0][0][2][0][3][6] = 76, ++ [0][0][2][0][5][6] = 76, ++ [0][0][2][0][6][6] = 58, ++ [0][0][2][0][9][6] = 58, ++ [0][0][2][0][8][6] = 60, ++ [0][0][2][0][11][6] = 58, ++ [0][0][2][0][2][7] = 74, ++ [0][0][2][0][1][7] = 58, ++ [0][0][2][0][3][7] = 76, ++ [0][0][2][0][5][7] = 74, ++ [0][0][2][0][6][7] = 58, ++ [0][0][2][0][9][7] = 58, ++ [0][0][2][0][8][7] = 60, ++ [0][0][2][0][11][7] = 58, ++ [0][0][2][0][2][8] = 70, ++ [0][0][2][0][1][8] = 58, ++ [0][0][2][0][3][8] = 76, ++ [0][0][2][0][5][8] = 70, ++ [0][0][2][0][6][8] = 58, ++ [0][0][2][0][9][8] = 58, ++ [0][0][2][0][8][8] = 60, ++ [0][0][2][0][11][8] = 58, ++ [0][0][2][0][2][9] = 66, ++ [0][0][2][0][1][9] = 58, ++ [0][0][2][0][3][9] = 76, ++ [0][0][2][0][5][9] = 66, ++ [0][0][2][0][6][9] = 58, ++ [0][0][2][0][9][9] = 58, ++ [0][0][2][0][8][9] = 60, ++ [0][0][2][0][11][9] = 58, ++ [0][0][2][0][2][10] = 66, ++ [0][0][2][0][1][10] = 58, ++ [0][0][2][0][3][10] = 76, ++ [0][0][2][0][5][10] = 66, ++ [0][0][2][0][6][10] = 58, ++ [0][0][2][0][9][10] = 58, ++ [0][0][2][0][8][10] = 60, ++ [0][0][2][0][11][10] = 58, ++ [0][0][2][0][2][11] = 54, ++ [0][0][2][0][1][11] = 58, ++ [0][0][2][0][3][11] = 76, ++ [0][0][2][0][5][11] = 54, ++ [0][0][2][0][6][11] = 58, ++ [0][0][2][0][9][11] = 58, ++ [0][0][2][0][8][11] = 60, ++ [0][0][2][0][11][11] = 58, ++ [0][0][2][0][2][12] = 50, ++ [0][0][2][0][1][12] = 58, ++ [0][0][2][0][3][12] = 76, ++ [0][0][2][0][5][12] = 50, ++ [0][0][2][0][6][12] = 58, ++ [0][0][2][0][9][12] = 58, ++ [0][0][2][0][8][12] = 60, ++ [0][0][2][0][11][12] = 58, ++ [0][0][2][0][2][13] = 127, ++ [0][0][2][0][1][13] = 127, ++ [0][0][2][0][3][13] = 127, ++ [0][0][2][0][5][13] = 127, ++ [0][0][2][0][6][13] = 127, ++ [0][0][2][0][9][13] = 127, ++ [0][0][2][0][8][13] = 127, ++ [0][0][2][0][11][13] = 127, ++ [0][1][2][0][2][0] = 62, ++ [0][1][2][0][1][0] = 46, ++ [0][1][2][0][3][0] = 64, ++ [0][1][2][0][5][0] = 62, ++ [0][1][2][0][6][0] = 46, ++ [0][1][2][0][9][0] = 46, ++ [0][1][2][0][8][0] = 48, ++ [0][1][2][0][11][0] = 46, ++ [0][1][2][0][2][1] = 62, ++ [0][1][2][0][1][1] = 46, ++ [0][1][2][0][3][1] = 64, ++ [0][1][2][0][5][1] = 62, ++ [0][1][2][0][6][1] = 46, ++ [0][1][2][0][9][1] = 46, ++ [0][1][2][0][8][1] = 48, ++ [0][1][2][0][11][1] = 46, ++ [0][1][2][0][2][2] = 66, ++ [0][1][2][0][1][2] = 46, ++ [0][1][2][0][3][2] = 64, ++ [0][1][2][0][5][2] = 66, ++ [0][1][2][0][6][2] = 46, ++ [0][1][2][0][9][2] = 46, ++ [0][1][2][0][8][2] = 48, ++ [0][1][2][0][11][2] = 46, ++ [0][1][2][0][2][3] = 70, ++ [0][1][2][0][1][3] = 46, ++ [0][1][2][0][3][3] = 64, ++ [0][1][2][0][5][3] = 70, ++ [0][1][2][0][6][3] = 46, ++ [0][1][2][0][9][3] = 46, ++ [0][1][2][0][8][3] = 48, ++ [0][1][2][0][11][3] = 46, ++ [0][1][2][0][2][4] = 76, ++ [0][1][2][0][1][4] = 46, ++ [0][1][2][0][3][4] = 64, ++ [0][1][2][0][5][4] = 76, ++ [0][1][2][0][6][4] = 46, ++ [0][1][2][0][9][4] = 46, ++ [0][1][2][0][8][4] = 48, ++ [0][1][2][0][11][4] = 46, ++ [0][1][2][0][2][5] = 76, ++ [0][1][2][0][1][5] = 46, ++ [0][1][2][0][3][5] = 64, ++ [0][1][2][0][5][5] = 76, ++ [0][1][2][0][6][5] = 46, ++ [0][1][2][0][9][5] = 46, ++ [0][1][2][0][8][5] = 48, ++ [0][1][2][0][11][5] = 46, ++ [0][1][2][0][2][6] = 76, ++ [0][1][2][0][1][6] = 46, ++ [0][1][2][0][3][6] = 64, ++ [0][1][2][0][5][6] = 76, ++ [0][1][2][0][6][6] = 46, ++ [0][1][2][0][9][6] = 46, ++ [0][1][2][0][8][6] = 48, ++ [0][1][2][0][11][6] = 46, ++ [0][1][2][0][2][7] = 68, ++ [0][1][2][0][1][7] = 46, ++ [0][1][2][0][3][7] = 64, ++ [0][1][2][0][5][7] = 68, ++ [0][1][2][0][6][7] = 46, ++ [0][1][2][0][9][7] = 46, ++ [0][1][2][0][8][7] = 48, ++ [0][1][2][0][11][7] = 46, ++ [0][1][2][0][2][8] = 64, ++ [0][1][2][0][1][8] = 46, ++ [0][1][2][0][3][8] = 64, ++ [0][1][2][0][5][8] = 64, ++ [0][1][2][0][6][8] = 46, ++ [0][1][2][0][9][8] = 46, ++ [0][1][2][0][8][8] = 48, ++ [0][1][2][0][11][8] = 46, ++ [0][1][2][0][2][9] = 60, ++ [0][1][2][0][1][9] = 46, ++ [0][1][2][0][3][9] = 64, ++ [0][1][2][0][5][9] = 60, ++ [0][1][2][0][6][9] = 46, ++ [0][1][2][0][9][9] = 46, ++ [0][1][2][0][8][9] = 48, ++ [0][1][2][0][11][9] = 46, ++ [0][1][2][0][2][10] = 60, ++ [0][1][2][0][1][10] = 46, ++ [0][1][2][0][3][10] = 64, ++ [0][1][2][0][5][10] = 60, ++ [0][1][2][0][6][10] = 46, ++ [0][1][2][0][9][10] = 46, ++ [0][1][2][0][8][10] = 48, ++ [0][1][2][0][11][10] = 46, ++ [0][1][2][0][2][11] = 42, ++ [0][1][2][0][1][11] = 46, ++ [0][1][2][0][3][11] = 64, ++ [0][1][2][0][5][11] = 42, ++ [0][1][2][0][6][11] = 46, ++ [0][1][2][0][9][11] = 46, ++ [0][1][2][0][8][11] = 48, ++ [0][1][2][0][11][11] = 46, ++ [0][1][2][0][2][12] = 40, ++ [0][1][2][0][1][12] = 46, ++ [0][1][2][0][3][12] = 64, ++ [0][1][2][0][5][12] = 40, ++ [0][1][2][0][6][12] = 46, ++ [0][1][2][0][9][12] = 46, ++ [0][1][2][0][8][12] = 48, ++ [0][1][2][0][11][12] = 46, ++ [0][1][2][0][2][13] = 127, ++ [0][1][2][0][1][13] = 127, ++ [0][1][2][0][3][13] = 127, ++ [0][1][2][0][5][13] = 127, ++ [0][1][2][0][6][13] = 127, ++ [0][1][2][0][9][13] = 127, ++ [0][1][2][0][8][13] = 127, ++ [0][1][2][0][11][13] = 127, ++ [0][1][2][1][2][0] = 62, ++ [0][1][2][1][1][0] = 34, ++ [0][1][2][1][3][0] = 64, ++ [0][1][2][1][5][0] = 62, ++ [0][1][2][1][6][0] = 34, ++ [0][1][2][1][9][0] = 34, ++ [0][1][2][1][8][0] = 36, ++ [0][1][2][1][11][0] = 34, ++ [0][1][2][1][2][1] = 62, ++ [0][1][2][1][1][1] = 34, ++ [0][1][2][1][3][1] = 64, ++ [0][1][2][1][5][1] = 62, ++ [0][1][2][1][6][1] = 34, ++ [0][1][2][1][9][1] = 34, ++ [0][1][2][1][8][1] = 36, ++ [0][1][2][1][11][1] = 34, ++ [0][1][2][1][2][2] = 66, ++ [0][1][2][1][1][2] = 34, ++ [0][1][2][1][3][2] = 64, ++ [0][1][2][1][5][2] = 66, ++ [0][1][2][1][6][2] = 34, ++ [0][1][2][1][9][2] = 34, ++ [0][1][2][1][8][2] = 36, ++ [0][1][2][1][11][2] = 34, ++ [0][1][2][1][2][3] = 70, ++ [0][1][2][1][1][3] = 34, ++ [0][1][2][1][3][3] = 64, ++ [0][1][2][1][5][3] = 70, ++ [0][1][2][1][6][3] = 34, ++ [0][1][2][1][9][3] = 34, ++ [0][1][2][1][8][3] = 36, ++ [0][1][2][1][11][3] = 34, ++ [0][1][2][1][2][4] = 76, ++ [0][1][2][1][1][4] = 34, ++ [0][1][2][1][3][4] = 64, ++ [0][1][2][1][5][4] = 76, ++ [0][1][2][1][6][4] = 34, ++ [0][1][2][1][9][4] = 34, ++ [0][1][2][1][8][4] = 36, ++ [0][1][2][1][11][4] = 34, ++ [0][1][2][1][2][5] = 76, ++ [0][1][2][1][1][5] = 34, ++ [0][1][2][1][3][5] = 64, ++ [0][1][2][1][5][5] = 76, ++ [0][1][2][1][6][5] = 34, ++ [0][1][2][1][9][5] = 34, ++ [0][1][2][1][8][5] = 36, ++ [0][1][2][1][11][5] = 34, ++ [0][1][2][1][2][6] = 76, ++ [0][1][2][1][1][6] = 34, ++ [0][1][2][1][3][6] = 64, ++ [0][1][2][1][5][6] = 76, ++ [0][1][2][1][6][6] = 34, ++ [0][1][2][1][9][6] = 34, ++ [0][1][2][1][8][6] = 36, ++ [0][1][2][1][11][6] = 34, ++ [0][1][2][1][2][7] = 68, ++ [0][1][2][1][1][7] = 34, ++ [0][1][2][1][3][7] = 64, ++ [0][1][2][1][5][7] = 68, ++ [0][1][2][1][6][7] = 34, ++ [0][1][2][1][9][7] = 34, ++ [0][1][2][1][8][7] = 36, ++ [0][1][2][1][11][7] = 34, ++ [0][1][2][1][2][8] = 64, ++ [0][1][2][1][1][8] = 34, ++ [0][1][2][1][3][8] = 64, ++ [0][1][2][1][5][8] = 64, ++ [0][1][2][1][6][8] = 34, ++ [0][1][2][1][9][8] = 34, ++ [0][1][2][1][8][8] = 36, ++ [0][1][2][1][11][8] = 34, ++ [0][1][2][1][2][9] = 60, ++ [0][1][2][1][1][9] = 34, ++ [0][1][2][1][3][9] = 64, ++ [0][1][2][1][5][9] = 60, ++ [0][1][2][1][6][9] = 34, ++ [0][1][2][1][9][9] = 34, ++ [0][1][2][1][8][9] = 36, ++ [0][1][2][1][11][9] = 34, ++ [0][1][2][1][2][10] = 60, ++ [0][1][2][1][1][10] = 34, ++ [0][1][2][1][3][10] = 64, ++ [0][1][2][1][5][10] = 60, ++ [0][1][2][1][6][10] = 34, ++ [0][1][2][1][9][10] = 34, ++ [0][1][2][1][8][10] = 36, ++ [0][1][2][1][11][10] = 34, ++ [0][1][2][1][2][11] = 42, ++ [0][1][2][1][1][11] = 34, ++ [0][1][2][1][3][11] = 64, ++ [0][1][2][1][5][11] = 42, ++ [0][1][2][1][6][11] = 34, ++ [0][1][2][1][9][11] = 34, ++ [0][1][2][1][8][11] = 36, ++ [0][1][2][1][11][11] = 34, ++ [0][1][2][1][2][12] = 40, ++ [0][1][2][1][1][12] = 34, ++ [0][1][2][1][3][12] = 64, ++ [0][1][2][1][5][12] = 40, ++ [0][1][2][1][6][12] = 34, ++ [0][1][2][1][9][12] = 34, ++ [0][1][2][1][8][12] = 36, ++ [0][1][2][1][11][12] = 34, ++ [0][1][2][1][2][13] = 127, ++ [0][1][2][1][1][13] = 127, ++ [0][1][2][1][3][13] = 127, ++ [0][1][2][1][5][13] = 127, ++ [0][1][2][1][6][13] = 127, ++ [0][1][2][1][9][13] = 127, ++ [0][1][2][1][8][13] = 127, ++ [0][1][2][1][11][13] = 127, ++ [1][0][2][0][2][0] = 127, ++ [1][0][2][0][1][0] = 127, ++ [1][0][2][0][3][0] = 127, ++ [1][0][2][0][5][0] = 127, ++ [1][0][2][0][6][0] = 127, ++ [1][0][2][0][9][0] = 127, ++ [1][0][2][0][8][0] = 127, ++ [1][0][2][0][11][0] = 127, ++ [1][0][2][0][2][1] = 127, ++ [1][0][2][0][1][1] = 127, ++ [1][0][2][0][3][1] = 127, ++ [1][0][2][0][5][1] = 127, ++ [1][0][2][0][6][1] = 127, ++ [1][0][2][0][9][1] = 127, ++ [1][0][2][0][8][1] = 127, ++ [1][0][2][0][11][1] = 127, ++ [1][0][2][0][2][2] = 56, ++ [1][0][2][0][1][2] = 58, ++ [1][0][2][0][3][2] = 76, ++ [1][0][2][0][5][2] = 56, ++ [1][0][2][0][6][2] = 58, ++ [1][0][2][0][9][2] = 58, ++ [1][0][2][0][8][2] = 60, ++ [1][0][2][0][11][2] = 58, ++ [1][0][2][0][2][3] = 56, ++ [1][0][2][0][1][3] = 58, ++ [1][0][2][0][3][3] = 76, ++ [1][0][2][0][5][3] = 56, ++ [1][0][2][0][6][3] = 58, ++ [1][0][2][0][9][3] = 58, ++ [1][0][2][0][8][3] = 60, ++ [1][0][2][0][11][3] = 58, ++ [1][0][2][0][2][4] = 60, ++ [1][0][2][0][1][4] = 58, ++ [1][0][2][0][3][4] = 76, ++ [1][0][2][0][5][4] = 60, ++ [1][0][2][0][6][4] = 58, ++ [1][0][2][0][9][4] = 58, ++ [1][0][2][0][8][4] = 60, ++ [1][0][2][0][11][4] = 58, ++ [1][0][2][0][2][5] = 64, ++ [1][0][2][0][1][5] = 58, ++ [1][0][2][0][3][5] = 76, ++ [1][0][2][0][5][5] = 64, ++ [1][0][2][0][6][5] = 58, ++ [1][0][2][0][9][5] = 58, ++ [1][0][2][0][8][5] = 60, ++ [1][0][2][0][11][5] = 58, ++ [1][0][2][0][2][6] = 54, ++ [1][0][2][0][1][6] = 58, ++ [1][0][2][0][3][6] = 76, ++ [1][0][2][0][5][6] = 54, ++ [1][0][2][0][6][6] = 58, ++ [1][0][2][0][9][6] = 58, ++ [1][0][2][0][8][6] = 60, ++ [1][0][2][0][11][6] = 58, ++ [1][0][2][0][2][7] = 50, ++ [1][0][2][0][1][7] = 58, ++ [1][0][2][0][3][7] = 76, ++ [1][0][2][0][5][7] = 50, ++ [1][0][2][0][6][7] = 58, ++ [1][0][2][0][9][7] = 58, ++ [1][0][2][0][8][7] = 60, ++ [1][0][2][0][11][7] = 58, ++ [1][0][2][0][2][8] = 50, ++ [1][0][2][0][1][8] = 58, ++ [1][0][2][0][3][8] = 76, ++ [1][0][2][0][5][8] = 50, ++ [1][0][2][0][6][8] = 58, ++ [1][0][2][0][9][8] = 58, ++ [1][0][2][0][8][8] = 60, ++ [1][0][2][0][11][8] = 58, ++ [1][0][2][0][2][9] = 42, ++ [1][0][2][0][1][9] = 58, ++ [1][0][2][0][3][9] = 76, ++ [1][0][2][0][5][9] = 42, ++ [1][0][2][0][6][9] = 58, ++ [1][0][2][0][9][9] = 58, ++ [1][0][2][0][8][9] = 60, ++ [1][0][2][0][11][9] = 58, ++ [1][0][2][0][2][10] = 40, ++ [1][0][2][0][1][10] = 58, ++ [1][0][2][0][3][10] = 76, ++ [1][0][2][0][5][10] = 40, ++ [1][0][2][0][6][10] = 58, ++ [1][0][2][0][9][10] = 58, ++ [1][0][2][0][8][10] = 60, ++ [1][0][2][0][11][10] = 58, ++ [1][0][2][0][2][11] = 127, ++ [1][0][2][0][1][11] = 127, ++ [1][0][2][0][3][11] = 127, ++ [1][0][2][0][5][11] = 127, ++ [1][0][2][0][6][11] = 127, ++ [1][0][2][0][9][11] = 127, ++ [1][0][2][0][8][11] = 127, ++ [1][0][2][0][11][11] = 127, ++ [1][0][2][0][2][12] = 127, ++ [1][0][2][0][1][12] = 127, ++ [1][0][2][0][3][12] = 127, ++ [1][0][2][0][5][12] = 127, ++ [1][0][2][0][6][12] = 127, ++ [1][0][2][0][9][12] = 127, ++ [1][0][2][0][8][12] = 127, ++ [1][0][2][0][11][12] = 127, ++ [1][0][2][0][2][13] = 127, ++ [1][0][2][0][1][13] = 127, ++ [1][0][2][0][3][13] = 127, ++ [1][0][2][0][5][13] = 127, ++ [1][0][2][0][6][13] = 127, ++ [1][0][2][0][9][13] = 127, ++ [1][0][2][0][8][13] = 127, ++ [1][0][2][0][11][13] = 127, ++ [1][1][2][0][2][0] = 127, ++ [1][1][2][0][1][0] = 127, ++ [1][1][2][0][3][0] = 127, ++ [1][1][2][0][5][0] = 127, ++ [1][1][2][0][6][0] = 127, ++ [1][1][2][0][9][0] = 127, ++ [1][1][2][0][8][0] = 127, ++ [1][1][2][0][11][0] = 127, ++ [1][1][2][0][2][1] = 127, ++ [1][1][2][0][1][1] = 127, ++ [1][1][2][0][3][1] = 127, ++ [1][1][2][0][5][1] = 127, ++ [1][1][2][0][6][1] = 127, ++ [1][1][2][0][9][1] = 127, ++ [1][1][2][0][8][1] = 127, ++ [1][1][2][0][11][1] = 127, ++ [1][1][2][0][2][2] = 52, ++ [1][1][2][0][1][2] = 46, ++ [1][1][2][0][3][2] = 64, ++ [1][1][2][0][5][2] = 52, ++ [1][1][2][0][6][2] = 46, ++ [1][1][2][0][9][2] = 46, ++ [1][1][2][0][8][2] = 48, ++ [1][1][2][0][11][2] = 46, ++ [1][1][2][0][2][3] = 52, ++ [1][1][2][0][1][3] = 46, ++ [1][1][2][0][3][3] = 64, ++ [1][1][2][0][5][3] = 52, ++ [1][1][2][0][6][3] = 46, ++ [1][1][2][0][9][3] = 46, ++ [1][1][2][0][8][3] = 48, ++ [1][1][2][0][11][3] = 46, ++ [1][1][2][0][2][4] = 56, ++ [1][1][2][0][1][4] = 46, ++ [1][1][2][0][3][4] = 64, ++ [1][1][2][0][5][4] = 56, ++ [1][1][2][0][6][4] = 46, ++ [1][1][2][0][9][4] = 46, ++ [1][1][2][0][8][4] = 48, ++ [1][1][2][0][11][4] = 46, ++ [1][1][2][0][2][5] = 60, ++ [1][1][2][0][1][5] = 46, ++ [1][1][2][0][3][5] = 64, ++ [1][1][2][0][5][5] = 60, ++ [1][1][2][0][6][5] = 46, ++ [1][1][2][0][9][5] = 46, ++ [1][1][2][0][8][5] = 48, ++ [1][1][2][0][11][5] = 46, ++ [1][1][2][0][2][6] = 54, ++ [1][1][2][0][1][6] = 46, ++ [1][1][2][0][3][6] = 64, ++ [1][1][2][0][5][6] = 52, ++ [1][1][2][0][6][6] = 46, ++ [1][1][2][0][9][6] = 46, ++ [1][1][2][0][8][6] = 48, ++ [1][1][2][0][11][6] = 46, ++ [1][1][2][0][2][7] = 50, ++ [1][1][2][0][1][7] = 46, ++ [1][1][2][0][3][7] = 64, ++ [1][1][2][0][5][7] = 48, ++ [1][1][2][0][6][7] = 46, ++ [1][1][2][0][9][7] = 46, ++ [1][1][2][0][8][7] = 48, ++ [1][1][2][0][11][7] = 46, ++ [1][1][2][0][2][8] = 50, ++ [1][1][2][0][1][8] = 46, ++ [1][1][2][0][3][8] = 64, ++ [1][1][2][0][5][8] = 48, ++ [1][1][2][0][6][8] = 46, ++ [1][1][2][0][9][8] = 46, ++ [1][1][2][0][8][8] = 48, ++ [1][1][2][0][11][8] = 46, ++ [1][1][2][0][2][9] = 38, ++ [1][1][2][0][1][9] = 46, ++ [1][1][2][0][3][9] = 64, ++ [1][1][2][0][5][9] = 38, ++ [1][1][2][0][6][9] = 46, ++ [1][1][2][0][9][9] = 46, ++ [1][1][2][0][8][9] = 48, ++ [1][1][2][0][11][9] = 46, ++ [1][1][2][0][2][10] = 36, ++ [1][1][2][0][1][10] = 46, ++ [1][1][2][0][3][10] = 64, ++ [1][1][2][0][5][10] = 36, ++ [1][1][2][0][6][10] = 46, ++ [1][1][2][0][9][10] = 46, ++ [1][1][2][0][8][10] = 48, ++ [1][1][2][0][11][10] = 46, ++ [1][1][2][0][2][11] = 127, ++ [1][1][2][0][1][11] = 127, ++ [1][1][2][0][3][11] = 127, ++ [1][1][2][0][5][11] = 127, ++ [1][1][2][0][6][11] = 127, ++ [1][1][2][0][9][11] = 127, ++ [1][1][2][0][8][11] = 127, ++ [1][1][2][0][11][11] = 127, ++ [1][1][2][0][2][12] = 127, ++ [1][1][2][0][1][12] = 127, ++ [1][1][2][0][3][12] = 127, ++ [1][1][2][0][5][12] = 127, ++ [1][1][2][0][6][12] = 127, ++ [1][1][2][0][9][12] = 127, ++ [1][1][2][0][8][12] = 127, ++ [1][1][2][0][11][12] = 127, ++ [1][1][2][0][2][13] = 127, ++ [1][1][2][0][1][13] = 127, ++ [1][1][2][0][3][13] = 127, ++ [1][1][2][0][5][13] = 127, ++ [1][1][2][0][6][13] = 127, ++ [1][1][2][0][9][13] = 127, ++ [1][1][2][0][8][13] = 127, ++ [1][1][2][0][11][13] = 127, ++ [1][1][2][1][2][0] = 127, ++ [1][1][2][1][1][0] = 127, ++ [1][1][2][1][3][0] = 127, ++ [1][1][2][1][5][0] = 127, ++ [1][1][2][1][6][0] = 127, ++ [1][1][2][1][9][0] = 127, ++ [1][1][2][1][8][0] = 127, ++ [1][1][2][1][11][0] = 127, ++ [1][1][2][1][2][1] = 127, ++ [1][1][2][1][1][1] = 127, ++ [1][1][2][1][3][1] = 127, ++ [1][1][2][1][5][1] = 127, ++ [1][1][2][1][6][1] = 127, ++ [1][1][2][1][9][1] = 127, ++ [1][1][2][1][8][1] = 127, ++ [1][1][2][1][11][1] = 127, ++ [1][1][2][1][2][2] = 52, ++ [1][1][2][1][1][2] = 34, ++ [1][1][2][1][3][2] = 64, ++ [1][1][2][1][5][2] = 52, ++ [1][1][2][1][6][2] = 34, ++ [1][1][2][1][9][2] = 34, ++ [1][1][2][1][8][2] = 36, ++ [1][1][2][1][11][2] = 34, ++ [1][1][2][1][2][3] = 52, ++ [1][1][2][1][1][3] = 34, ++ [1][1][2][1][3][3] = 64, ++ [1][1][2][1][5][3] = 52, ++ [1][1][2][1][6][3] = 34, ++ [1][1][2][1][9][3] = 34, ++ [1][1][2][1][8][3] = 36, ++ [1][1][2][1][11][3] = 34, ++ [1][1][2][1][2][4] = 56, ++ [1][1][2][1][1][4] = 34, ++ [1][1][2][1][3][4] = 64, ++ [1][1][2][1][5][4] = 56, ++ [1][1][2][1][6][4] = 34, ++ [1][1][2][1][9][4] = 34, ++ [1][1][2][1][8][4] = 36, ++ [1][1][2][1][11][4] = 34, ++ [1][1][2][1][2][5] = 60, ++ [1][1][2][1][1][5] = 34, ++ [1][1][2][1][3][5] = 64, ++ [1][1][2][1][5][5] = 60, ++ [1][1][2][1][6][5] = 34, ++ [1][1][2][1][9][5] = 34, ++ [1][1][2][1][8][5] = 36, ++ [1][1][2][1][11][5] = 34, ++ [1][1][2][1][2][6] = 54, ++ [1][1][2][1][1][6] = 34, ++ [1][1][2][1][3][6] = 64, ++ [1][1][2][1][5][6] = 52, ++ [1][1][2][1][6][6] = 34, ++ [1][1][2][1][9][6] = 34, ++ [1][1][2][1][8][6] = 36, ++ [1][1][2][1][11][6] = 34, ++ [1][1][2][1][2][7] = 50, ++ [1][1][2][1][1][7] = 34, ++ [1][1][2][1][3][7] = 64, ++ [1][1][2][1][5][7] = 48, ++ [1][1][2][1][6][7] = 34, ++ [1][1][2][1][9][7] = 34, ++ [1][1][2][1][8][7] = 36, ++ [1][1][2][1][11][7] = 34, ++ [1][1][2][1][2][8] = 50, ++ [1][1][2][1][1][8] = 34, ++ [1][1][2][1][3][8] = 64, ++ [1][1][2][1][5][8] = 48, ++ [1][1][2][1][6][8] = 34, ++ [1][1][2][1][9][8] = 34, ++ [1][1][2][1][8][8] = 36, ++ [1][1][2][1][11][8] = 34, ++ [1][1][2][1][2][9] = 38, ++ [1][1][2][1][1][9] = 34, ++ [1][1][2][1][3][9] = 64, ++ [1][1][2][1][5][9] = 38, ++ [1][1][2][1][6][9] = 34, ++ [1][1][2][1][9][9] = 34, ++ [1][1][2][1][8][9] = 36, ++ [1][1][2][1][11][9] = 34, ++ [1][1][2][1][2][10] = 36, ++ [1][1][2][1][1][10] = 34, ++ [1][1][2][1][3][10] = 64, ++ [1][1][2][1][5][10] = 36, ++ [1][1][2][1][6][10] = 34, ++ [1][1][2][1][9][10] = 34, ++ [1][1][2][1][8][10] = 36, ++ [1][1][2][1][11][10] = 34, ++ [1][1][2][1][2][11] = 127, ++ [1][1][2][1][1][11] = 127, ++ [1][1][2][1][3][11] = 127, ++ [1][1][2][1][5][11] = 127, ++ [1][1][2][1][6][11] = 127, ++ [1][1][2][1][9][11] = 127, ++ [1][1][2][1][8][11] = 127, ++ [1][1][2][1][11][11] = 127, ++ [1][1][2][1][2][12] = 127, ++ [1][1][2][1][1][12] = 127, ++ [1][1][2][1][3][12] = 127, ++ [1][1][2][1][5][12] = 127, ++ [1][1][2][1][6][12] = 127, ++ [1][1][2][1][9][12] = 127, ++ [1][1][2][1][8][12] = 127, ++ [1][1][2][1][11][12] = 127, ++ [1][1][2][1][2][13] = 127, ++ [1][1][2][1][1][13] = 127, ++ [1][1][2][1][3][13] = 127, ++ [1][1][2][1][5][13] = 127, ++ [1][1][2][1][6][13] = 127, ++ [1][1][2][1][9][13] = 127, ++ [1][1][2][1][8][13] = 127, ++ [1][1][2][1][11][13] = 127, ++}; ++ ++const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] ++ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] ++ [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { ++ [0][0][1][0][0][0] = 30, ++ [0][0][1][0][0][2] = 30, ++ [0][0][1][0][0][4] = 30, ++ [0][0][1][0][0][6] = 30, ++ [0][0][1][0][0][8] = 52, ++ [0][0][1][0][0][10] = 52, ++ [0][0][1][0][0][12] = 52, ++ [0][0][1][0][0][14] = 52, ++ [0][0][1][0][0][15] = 52, ++ [0][0][1][0][0][17] = 52, ++ [0][0][1][0][0][19] = 52, ++ [0][0][1][0][0][21] = 52, ++ [0][0][1][0][0][23] = 52, ++ [0][0][1][0][0][25] = 52, ++ [0][0][1][0][0][27] = 52, ++ [0][0][1][0][0][29] = 52, ++ [0][0][1][0][0][31] = 52, ++ [0][0][1][0][0][33] = 52, ++ [0][0][1][0][0][35] = 52, ++ [0][0][1][0][0][37] = 54, ++ [0][0][1][0][0][38] = 28, ++ [0][0][1][0][0][40] = 28, ++ [0][0][1][0][0][42] = 28, ++ [0][0][1][0][0][44] = 28, ++ [0][0][1][0][0][46] = 28, ++ [0][1][1][0][0][0] = 18, ++ [0][1][1][0][0][2] = 18, ++ [0][1][1][0][0][4] = 18, ++ [0][1][1][0][0][6] = 18, ++ [0][1][1][0][0][8] = 40, ++ [0][1][1][0][0][10] = 40, ++ [0][1][1][0][0][12] = 40, ++ [0][1][1][0][0][14] = 40, ++ [0][1][1][0][0][15] = 40, ++ [0][1][1][0][0][17] = 40, ++ [0][1][1][0][0][19] = 40, ++ [0][1][1][0][0][21] = 40, ++ [0][1][1][0][0][23] = 40, ++ [0][1][1][0][0][25] = 40, ++ [0][1][1][0][0][27] = 40, ++ [0][1][1][0][0][29] = 40, ++ [0][1][1][0][0][31] = 40, ++ [0][1][1][0][0][33] = 40, ++ [0][1][1][0][0][35] = 40, ++ [0][1][1][0][0][37] = 42, ++ [0][1][1][0][0][38] = 16, ++ [0][1][1][0][0][40] = 16, ++ [0][1][1][0][0][42] = 16, ++ [0][1][1][0][0][44] = 16, ++ [0][1][1][0][0][46] = 16, ++ [0][0][2][0][0][0] = 30, ++ [0][0][2][0][0][2] = 30, ++ [0][0][2][0][0][4] = 30, ++ [0][0][2][0][0][6] = 30, ++ [0][0][2][0][0][8] = 52, ++ [0][0][2][0][0][10] = 52, ++ [0][0][2][0][0][12] = 52, ++ [0][0][2][0][0][14] = 52, ++ [0][0][2][0][0][15] = 52, ++ [0][0][2][0][0][17] = 52, ++ [0][0][2][0][0][19] = 52, ++ [0][0][2][0][0][21] = 52, ++ [0][0][2][0][0][23] = 52, ++ [0][0][2][0][0][25] = 52, ++ [0][0][2][0][0][27] = 52, ++ [0][0][2][0][0][29] = 52, ++ [0][0][2][0][0][31] = 52, ++ [0][0][2][0][0][33] = 52, ++ [0][0][2][0][0][35] = 52, ++ [0][0][2][0][0][37] = 54, ++ [0][0][2][0][0][38] = 28, ++ [0][0][2][0][0][40] = 28, ++ [0][0][2][0][0][42] = 28, ++ [0][0][2][0][0][44] = 28, ++ [0][0][2][0][0][46] = 28, ++ [0][1][2][0][0][0] = 18, ++ [0][1][2][0][0][2] = 18, ++ [0][1][2][0][0][4] = 18, ++ [0][1][2][0][0][6] = 18, ++ [0][1][2][0][0][8] = 40, ++ [0][1][2][0][0][10] = 40, ++ [0][1][2][0][0][12] = 40, ++ [0][1][2][0][0][14] = 40, ++ [0][1][2][0][0][15] = 40, ++ [0][1][2][0][0][17] = 40, ++ [0][1][2][0][0][19] = 40, ++ [0][1][2][0][0][21] = 40, ++ [0][1][2][0][0][23] = 40, ++ [0][1][2][0][0][25] = 40, ++ [0][1][2][0][0][27] = 40, ++ [0][1][2][0][0][29] = 40, ++ [0][1][2][0][0][31] = 40, ++ [0][1][2][0][0][33] = 40, ++ [0][1][2][0][0][35] = 40, ++ [0][1][2][0][0][37] = 42, ++ [0][1][2][0][0][38] = 16, ++ [0][1][2][0][0][40] = 16, ++ [0][1][2][0][0][42] = 16, ++ [0][1][2][0][0][44] = 16, ++ [0][1][2][0][0][46] = 16, ++ [0][1][2][1][0][0] = 6, ++ [0][1][2][1][0][2] = 6, ++ [0][1][2][1][0][4] = 6, ++ [0][1][2][1][0][6] = 6, ++ [0][1][2][1][0][8] = 28, ++ [0][1][2][1][0][10] = 28, ++ [0][1][2][1][0][12] = 28, ++ [0][1][2][1][0][14] = 28, ++ [0][1][2][1][0][15] = 28, ++ [0][1][2][1][0][17] = 28, ++ [0][1][2][1][0][19] = 28, ++ [0][1][2][1][0][21] = 28, ++ [0][1][2][1][0][23] = 28, ++ [0][1][2][1][0][25] = 28, ++ [0][1][2][1][0][27] = 28, ++ [0][1][2][1][0][29] = 28, ++ [0][1][2][1][0][31] = 28, ++ [0][1][2][1][0][33] = 28, ++ [0][1][2][1][0][35] = 28, ++ [0][1][2][1][0][37] = 30, ++ [0][1][2][1][0][38] = 4, ++ [0][1][2][1][0][40] = 4, ++ [0][1][2][1][0][42] = 4, ++ [0][1][2][1][0][44] = 4, ++ [0][1][2][1][0][46] = 4, ++ [1][0][2][0][0][1] = 30, ++ [1][0][2][0][0][5] = 30, ++ [1][0][2][0][0][9] = 52, ++ [1][0][2][0][0][13] = 52, ++ [1][0][2][0][0][16] = 52, ++ [1][0][2][0][0][20] = 52, ++ [1][0][2][0][0][24] = 52, ++ [1][0][2][0][0][28] = 52, ++ [1][0][2][0][0][32] = 52, ++ [1][0][2][0][0][36] = 54, ++ [1][0][2][0][0][39] = 28, ++ [1][0][2][0][0][43] = 28, ++ [1][1][2][0][0][1] = 18, ++ [1][1][2][0][0][5] = 18, ++ [1][1][2][0][0][9] = 40, ++ [1][1][2][0][0][13] = 40, ++ [1][1][2][0][0][16] = 40, ++ [1][1][2][0][0][20] = 40, ++ [1][1][2][0][0][24] = 40, ++ [1][1][2][0][0][28] = 40, ++ [1][1][2][0][0][32] = 40, ++ [1][1][2][0][0][36] = 42, ++ [1][1][2][0][0][39] = 16, ++ [1][1][2][0][0][43] = 16, ++ [1][1][2][1][0][1] = 6, ++ [1][1][2][1][0][5] = 6, ++ [1][1][2][1][0][9] = 28, ++ [1][1][2][1][0][13] = 28, ++ [1][1][2][1][0][16] = 28, ++ [1][1][2][1][0][20] = 28, ++ [1][1][2][1][0][24] = 28, ++ [1][1][2][1][0][28] = 28, ++ [1][1][2][1][0][32] = 28, ++ [1][1][2][1][0][36] = 30, ++ [1][1][2][1][0][39] = 4, ++ [1][1][2][1][0][43] = 4, ++ [2][0][2][0][0][3] = 30, ++ [2][0][2][0][0][11] = 52, ++ [2][0][2][0][0][18] = 52, ++ [2][0][2][0][0][26] = 52, ++ [2][0][2][0][0][34] = 54, ++ [2][0][2][0][0][41] = 28, ++ [2][1][2][0][0][3] = 18, ++ [2][1][2][0][0][11] = 40, ++ [2][1][2][0][0][18] = 40, ++ [2][1][2][0][0][26] = 40, ++ [2][1][2][0][0][34] = 42, ++ [2][1][2][0][0][41] = 16, ++ [2][1][2][1][0][3] = 6, ++ [2][1][2][1][0][11] = 28, ++ [2][1][2][1][0][18] = 28, ++ [2][1][2][1][0][26] = 28, ++ [2][1][2][1][0][34] = 30, ++ [2][1][2][1][0][41] = 4, ++ [0][0][1][0][2][0] = 76, ++ [0][0][1][0][1][0] = 58, ++ [0][0][1][0][3][0] = 62, ++ [0][0][1][0][5][0] = 62, ++ [0][0][1][0][6][0] = 58, ++ [0][0][1][0][9][0] = 58, ++ [0][0][1][0][8][0] = 30, ++ [0][0][1][0][11][0] = 52, ++ [0][0][1][0][2][2] = 76, ++ [0][0][1][0][1][2] = 58, ++ [0][0][1][0][3][2] = 62, ++ [0][0][1][0][5][2] = 62, ++ [0][0][1][0][6][2] = 58, ++ [0][0][1][0][9][2] = 58, ++ [0][0][1][0][8][2] = 30, ++ [0][0][1][0][11][2] = 52, ++ [0][0][1][0][2][4] = 76, ++ [0][0][1][0][1][4] = 58, ++ [0][0][1][0][3][4] = 62, ++ [0][0][1][0][5][4] = 62, ++ [0][0][1][0][6][4] = 58, ++ [0][0][1][0][9][4] = 58, ++ [0][0][1][0][8][4] = 30, ++ [0][0][1][0][11][4] = 52, ++ [0][0][1][0][2][6] = 76, ++ [0][0][1][0][1][6] = 58, ++ [0][0][1][0][3][6] = 62, ++ [0][0][1][0][5][6] = 62, ++ [0][0][1][0][6][6] = 54, ++ [0][0][1][0][9][6] = 58, ++ [0][0][1][0][8][6] = 30, ++ [0][0][1][0][11][6] = 52, ++ [0][0][1][0][2][8] = 76, ++ [0][0][1][0][1][8] = 58, ++ [0][0][1][0][3][8] = 62, ++ [0][0][1][0][5][8] = 64, ++ [0][0][1][0][6][8] = 58, ++ [0][0][1][0][9][8] = 58, ++ [0][0][1][0][8][8] = 54, ++ [0][0][1][0][11][8] = 52, ++ [0][0][1][0][2][10] = 76, ++ [0][0][1][0][1][10] = 58, ++ [0][0][1][0][3][10] = 62, ++ [0][0][1][0][5][10] = 64, ++ [0][0][1][0][6][10] = 58, ++ [0][0][1][0][9][10] = 58, ++ [0][0][1][0][8][10] = 54, ++ [0][0][1][0][11][10] = 52, ++ [0][0][1][0][2][12] = 76, ++ [0][0][1][0][1][12] = 58, ++ [0][0][1][0][3][12] = 62, ++ [0][0][1][0][5][12] = 64, ++ [0][0][1][0][6][12] = 58, ++ [0][0][1][0][9][12] = 58, ++ [0][0][1][0][8][12] = 54, ++ [0][0][1][0][11][12] = 52, ++ [0][0][1][0][2][14] = 76, ++ [0][0][1][0][1][14] = 58, ++ [0][0][1][0][3][14] = 62, ++ [0][0][1][0][5][14] = 64, ++ [0][0][1][0][6][14] = 58, ++ [0][0][1][0][9][14] = 58, ++ [0][0][1][0][8][14] = 54, ++ [0][0][1][0][11][14] = 52, ++ [0][0][1][0][2][15] = 76, ++ [0][0][1][0][1][15] = 58, ++ [0][0][1][0][3][15] = 76, ++ [0][0][1][0][5][15] = 76, ++ [0][0][1][0][6][15] = 58, ++ [0][0][1][0][9][15] = 58, ++ [0][0][1][0][8][15] = 54, ++ [0][0][1][0][11][15] = 52, ++ [0][0][1][0][2][17] = 76, ++ [0][0][1][0][1][17] = 58, ++ [0][0][1][0][3][17] = 76, ++ [0][0][1][0][5][17] = 76, ++ [0][0][1][0][6][17] = 58, ++ [0][0][1][0][9][17] = 58, ++ [0][0][1][0][8][17] = 54, ++ [0][0][1][0][11][17] = 52, ++ [0][0][1][0][2][19] = 76, ++ [0][0][1][0][1][19] = 58, ++ [0][0][1][0][3][19] = 76, ++ [0][0][1][0][5][19] = 76, ++ [0][0][1][0][6][19] = 58, ++ [0][0][1][0][9][19] = 58, ++ [0][0][1][0][8][19] = 54, ++ [0][0][1][0][11][19] = 52, ++ [0][0][1][0][2][21] = 76, ++ [0][0][1][0][1][21] = 58, ++ [0][0][1][0][3][21] = 76, ++ [0][0][1][0][5][21] = 76, ++ [0][0][1][0][6][21] = 58, ++ [0][0][1][0][9][21] = 58, ++ [0][0][1][0][8][21] = 54, ++ [0][0][1][0][11][21] = 52, ++ [0][0][1][0][2][23] = 76, ++ [0][0][1][0][1][23] = 58, ++ [0][0][1][0][3][23] = 76, ++ [0][0][1][0][5][23] = 76, ++ [0][0][1][0][6][23] = 58, ++ [0][0][1][0][9][23] = 58, ++ [0][0][1][0][8][23] = 54, ++ [0][0][1][0][11][23] = 52, ++ [0][0][1][0][2][25] = 76, ++ [0][0][1][0][1][25] = 58, ++ [0][0][1][0][3][25] = 76, ++ [0][0][1][0][5][25] = 127, ++ [0][0][1][0][6][25] = 58, ++ [0][0][1][0][9][25] = 127, ++ [0][0][1][0][8][25] = 54, ++ [0][0][1][0][11][25] = 52, ++ [0][0][1][0][2][27] = 76, ++ [0][0][1][0][1][27] = 58, ++ [0][0][1][0][3][27] = 76, ++ [0][0][1][0][5][27] = 127, ++ [0][0][1][0][6][27] = 58, ++ [0][0][1][0][9][27] = 127, ++ [0][0][1][0][8][27] = 54, ++ [0][0][1][0][11][27] = 52, ++ [0][0][1][0][2][29] = 76, ++ [0][0][1][0][1][29] = 58, ++ [0][0][1][0][3][29] = 76, ++ [0][0][1][0][5][29] = 127, ++ [0][0][1][0][6][29] = 58, ++ [0][0][1][0][9][29] = 127, ++ [0][0][1][0][8][29] = 54, ++ [0][0][1][0][11][29] = 52, ++ [0][0][1][0][2][31] = 76, ++ [0][0][1][0][1][31] = 58, ++ [0][0][1][0][3][31] = 76, ++ [0][0][1][0][5][31] = 76, ++ [0][0][1][0][6][31] = 58, ++ [0][0][1][0][9][31] = 58, ++ [0][0][1][0][8][31] = 54, ++ [0][0][1][0][11][31] = 52, ++ [0][0][1][0][2][33] = 76, ++ [0][0][1][0][1][33] = 58, ++ [0][0][1][0][3][33] = 76, ++ [0][0][1][0][5][33] = 76, ++ [0][0][1][0][6][33] = 58, ++ [0][0][1][0][9][33] = 58, ++ [0][0][1][0][8][33] = 54, ++ [0][0][1][0][11][33] = 52, ++ [0][0][1][0][2][35] = 74, ++ [0][0][1][0][1][35] = 58, ++ [0][0][1][0][3][35] = 76, ++ [0][0][1][0][5][35] = 74, ++ [0][0][1][0][6][35] = 58, ++ [0][0][1][0][9][35] = 58, ++ [0][0][1][0][8][35] = 54, ++ [0][0][1][0][11][35] = 52, ++ [0][0][1][0][2][37] = 76, ++ [0][0][1][0][1][37] = 127, ++ [0][0][1][0][3][37] = 76, ++ [0][0][1][0][5][37] = 76, ++ [0][0][1][0][6][37] = 58, ++ [0][0][1][0][9][37] = 76, ++ [0][0][1][0][8][37] = 54, ++ [0][0][1][0][11][37] = 127, ++ [0][0][1][0][2][38] = 76, ++ [0][0][1][0][1][38] = 28, ++ [0][0][1][0][3][38] = 127, ++ [0][0][1][0][5][38] = 76, ++ [0][0][1][0][6][38] = 28, ++ [0][0][1][0][9][38] = 76, ++ [0][0][1][0][8][38] = 54, ++ [0][0][1][0][11][38] = 52, ++ [0][0][1][0][2][40] = 76, ++ [0][0][1][0][1][40] = 28, ++ [0][0][1][0][3][40] = 127, ++ [0][0][1][0][5][40] = 76, ++ [0][0][1][0][6][40] = 28, ++ [0][0][1][0][9][40] = 76, ++ [0][0][1][0][8][40] = 54, ++ [0][0][1][0][11][40] = 52, ++ [0][0][1][0][2][42] = 76, ++ [0][0][1][0][1][42] = 28, ++ [0][0][1][0][3][42] = 127, ++ [0][0][1][0][5][42] = 76, ++ [0][0][1][0][6][42] = 28, ++ [0][0][1][0][9][42] = 76, ++ [0][0][1][0][8][42] = 54, ++ [0][0][1][0][11][42] = 52, ++ [0][0][1][0][2][44] = 76, ++ [0][0][1][0][1][44] = 28, ++ [0][0][1][0][3][44] = 127, ++ [0][0][1][0][5][44] = 76, ++ [0][0][1][0][6][44] = 28, ++ [0][0][1][0][9][44] = 76, ++ [0][0][1][0][8][44] = 54, ++ [0][0][1][0][11][44] = 52, ++ [0][0][1][0][2][46] = 76, ++ [0][0][1][0][1][46] = 28, ++ [0][0][1][0][3][46] = 127, ++ [0][0][1][0][5][46] = 76, ++ [0][0][1][0][6][46] = 28, ++ [0][0][1][0][9][46] = 76, ++ [0][0][1][0][8][46] = 54, ++ [0][0][1][0][11][46] = 52, ++ [0][1][1][0][2][0] = 68, ++ [0][1][1][0][1][0] = 46, ++ [0][1][1][0][3][0] = 50, ++ [0][1][1][0][5][0] = 40, ++ [0][1][1][0][6][0] = 46, ++ [0][1][1][0][9][0] = 46, ++ [0][1][1][0][8][0] = 18, ++ [0][1][1][0][11][0] = 40, ++ [0][1][1][0][2][2] = 68, ++ [0][1][1][0][1][2] = 46, ++ [0][1][1][0][3][2] = 50, ++ [0][1][1][0][5][2] = 40, ++ [0][1][1][0][6][2] = 46, ++ [0][1][1][0][9][2] = 46, ++ [0][1][1][0][8][2] = 18, ++ [0][1][1][0][11][2] = 40, ++ [0][1][1][0][2][4] = 68, ++ [0][1][1][0][1][4] = 46, ++ [0][1][1][0][3][4] = 50, ++ [0][1][1][0][5][4] = 40, ++ [0][1][1][0][6][4] = 46, ++ [0][1][1][0][9][4] = 46, ++ [0][1][1][0][8][4] = 18, ++ [0][1][1][0][11][4] = 40, ++ [0][1][1][0][2][6] = 68, ++ [0][1][1][0][1][6] = 46, ++ [0][1][1][0][3][6] = 50, ++ [0][1][1][0][5][6] = 40, ++ [0][1][1][0][6][6] = 36, ++ [0][1][1][0][9][6] = 46, ++ [0][1][1][0][8][6] = 18, ++ [0][1][1][0][11][6] = 40, ++ [0][1][1][0][2][8] = 68, ++ [0][1][1][0][1][8] = 46, ++ [0][1][1][0][3][8] = 50, ++ [0][1][1][0][5][8] = 52, ++ [0][1][1][0][6][8] = 46, ++ [0][1][1][0][9][8] = 46, ++ [0][1][1][0][8][8] = 42, ++ [0][1][1][0][11][8] = 40, ++ [0][1][1][0][2][10] = 68, ++ [0][1][1][0][1][10] = 46, ++ [0][1][1][0][3][10] = 50, ++ [0][1][1][0][5][10] = 52, ++ [0][1][1][0][6][10] = 46, ++ [0][1][1][0][9][10] = 46, ++ [0][1][1][0][8][10] = 42, ++ [0][1][1][0][11][10] = 40, ++ [0][1][1][0][2][12] = 68, ++ [0][1][1][0][1][12] = 46, ++ [0][1][1][0][3][12] = 50, ++ [0][1][1][0][5][12] = 52, ++ [0][1][1][0][6][12] = 46, ++ [0][1][1][0][9][12] = 46, ++ [0][1][1][0][8][12] = 42, ++ [0][1][1][0][11][12] = 40, ++ [0][1][1][0][2][14] = 68, ++ [0][1][1][0][1][14] = 46, ++ [0][1][1][0][3][14] = 50, ++ [0][1][1][0][5][14] = 52, ++ [0][1][1][0][6][14] = 46, ++ [0][1][1][0][9][14] = 46, ++ [0][1][1][0][8][14] = 42, ++ [0][1][1][0][11][14] = 40, ++ [0][1][1][0][2][15] = 68, ++ [0][1][1][0][1][15] = 46, ++ [0][1][1][0][3][15] = 70, ++ [0][1][1][0][5][15] = 68, ++ [0][1][1][0][6][15] = 46, ++ [0][1][1][0][9][15] = 46, ++ [0][1][1][0][8][15] = 42, ++ [0][1][1][0][11][15] = 40, ++ [0][1][1][0][2][17] = 68, ++ [0][1][1][0][1][17] = 46, ++ [0][1][1][0][3][17] = 70, ++ [0][1][1][0][5][17] = 68, ++ [0][1][1][0][6][17] = 46, ++ [0][1][1][0][9][17] = 46, ++ [0][1][1][0][8][17] = 42, ++ [0][1][1][0][11][17] = 40, ++ [0][1][1][0][2][19] = 68, ++ [0][1][1][0][1][19] = 46, ++ [0][1][1][0][3][19] = 70, ++ [0][1][1][0][5][19] = 68, ++ [0][1][1][0][6][19] = 46, ++ [0][1][1][0][9][19] = 46, ++ [0][1][1][0][8][19] = 42, ++ [0][1][1][0][11][19] = 40, ++ [0][1][1][0][2][21] = 68, ++ [0][1][1][0][1][21] = 46, ++ [0][1][1][0][3][21] = 70, ++ [0][1][1][0][5][21] = 68, ++ [0][1][1][0][6][21] = 46, ++ [0][1][1][0][9][21] = 46, ++ [0][1][1][0][8][21] = 42, ++ [0][1][1][0][11][21] = 40, ++ [0][1][1][0][2][23] = 68, ++ [0][1][1][0][1][23] = 46, ++ [0][1][1][0][3][23] = 70, ++ [0][1][1][0][5][23] = 68, ++ [0][1][1][0][6][23] = 46, ++ [0][1][1][0][9][23] = 46, ++ [0][1][1][0][8][23] = 42, ++ [0][1][1][0][11][23] = 40, ++ [0][1][1][0][2][25] = 68, ++ [0][1][1][0][1][25] = 46, ++ [0][1][1][0][3][25] = 70, ++ [0][1][1][0][5][25] = 127, ++ [0][1][1][0][6][25] = 46, ++ [0][1][1][0][9][25] = 127, ++ [0][1][1][0][8][25] = 42, ++ [0][1][1][0][11][25] = 40, ++ [0][1][1][0][2][27] = 68, ++ [0][1][1][0][1][27] = 46, ++ [0][1][1][0][3][27] = 70, ++ [0][1][1][0][5][27] = 127, ++ [0][1][1][0][6][27] = 46, ++ [0][1][1][0][9][27] = 127, ++ [0][1][1][0][8][27] = 42, ++ [0][1][1][0][11][27] = 40, ++ [0][1][1][0][2][29] = 68, ++ [0][1][1][0][1][29] = 46, ++ [0][1][1][0][3][29] = 70, ++ [0][1][1][0][5][29] = 127, ++ [0][1][1][0][6][29] = 46, ++ [0][1][1][0][9][29] = 127, ++ [0][1][1][0][8][29] = 42, ++ [0][1][1][0][11][29] = 40, ++ [0][1][1][0][2][31] = 68, ++ [0][1][1][0][1][31] = 46, ++ [0][1][1][0][3][31] = 70, ++ [0][1][1][0][5][31] = 68, ++ [0][1][1][0][6][31] = 46, ++ [0][1][1][0][9][31] = 46, ++ [0][1][1][0][8][31] = 42, ++ [0][1][1][0][11][31] = 40, ++ [0][1][1][0][2][33] = 68, ++ [0][1][1][0][1][33] = 46, ++ [0][1][1][0][3][33] = 70, ++ [0][1][1][0][5][33] = 68, ++ [0][1][1][0][6][33] = 46, ++ [0][1][1][0][9][33] = 46, ++ [0][1][1][0][8][33] = 42, ++ [0][1][1][0][11][33] = 40, ++ [0][1][1][0][2][35] = 66, ++ [0][1][1][0][1][35] = 46, ++ [0][1][1][0][3][35] = 70, ++ [0][1][1][0][5][35] = 66, ++ [0][1][1][0][6][35] = 46, ++ [0][1][1][0][9][35] = 46, ++ [0][1][1][0][8][35] = 42, ++ [0][1][1][0][11][35] = 40, ++ [0][1][1][0][2][37] = 68, ++ [0][1][1][0][1][37] = 127, ++ [0][1][1][0][3][37] = 70, ++ [0][1][1][0][5][37] = 68, ++ [0][1][1][0][6][37] = 46, ++ [0][1][1][0][9][37] = 68, ++ [0][1][1][0][8][37] = 42, ++ [0][1][1][0][11][37] = 127, ++ [0][1][1][0][2][38] = 76, ++ [0][1][1][0][1][38] = 16, ++ [0][1][1][0][3][38] = 127, ++ [0][1][1][0][5][38] = 76, ++ [0][1][1][0][6][38] = 16, ++ [0][1][1][0][9][38] = 76, ++ [0][1][1][0][8][38] = 42, ++ [0][1][1][0][11][38] = 40, ++ [0][1][1][0][2][40] = 76, ++ [0][1][1][0][1][40] = 16, ++ [0][1][1][0][3][40] = 127, ++ [0][1][1][0][5][40] = 76, ++ [0][1][1][0][6][40] = 16, ++ [0][1][1][0][9][40] = 76, ++ [0][1][1][0][8][40] = 42, ++ [0][1][1][0][11][40] = 40, ++ [0][1][1][0][2][42] = 76, ++ [0][1][1][0][1][42] = 16, ++ [0][1][1][0][3][42] = 127, ++ [0][1][1][0][5][42] = 76, ++ [0][1][1][0][6][42] = 16, ++ [0][1][1][0][9][42] = 76, ++ [0][1][1][0][8][42] = 42, ++ [0][1][1][0][11][42] = 40, ++ [0][1][1][0][2][44] = 76, ++ [0][1][1][0][1][44] = 16, ++ [0][1][1][0][3][44] = 127, ++ [0][1][1][0][5][44] = 76, ++ [0][1][1][0][6][44] = 16, ++ [0][1][1][0][9][44] = 76, ++ [0][1][1][0][8][44] = 42, ++ [0][1][1][0][11][44] = 40, ++ [0][1][1][0][2][46] = 76, ++ [0][1][1][0][1][46] = 16, ++ [0][1][1][0][3][46] = 127, ++ [0][1][1][0][5][46] = 76, ++ [0][1][1][0][6][46] = 16, ++ [0][1][1][0][9][46] = 76, ++ [0][1][1][0][8][46] = 42, ++ [0][1][1][0][11][46] = 40, ++ [0][0][2][0][2][0] = 76, ++ [0][0][2][0][1][0] = 58, ++ [0][0][2][0][3][0] = 62, ++ [0][0][2][0][5][0] = 62, ++ [0][0][2][0][6][0] = 58, ++ [0][0][2][0][9][0] = 58, ++ [0][0][2][0][8][0] = 30, ++ [0][0][2][0][11][0] = 52, ++ [0][0][2][0][2][2] = 76, ++ [0][0][2][0][1][2] = 58, ++ [0][0][2][0][3][2] = 62, ++ [0][0][2][0][5][2] = 62, ++ [0][0][2][0][6][2] = 58, ++ [0][0][2][0][9][2] = 58, ++ [0][0][2][0][8][2] = 30, ++ [0][0][2][0][11][2] = 52, ++ [0][0][2][0][2][4] = 76, ++ [0][0][2][0][1][4] = 58, ++ [0][0][2][0][3][4] = 62, ++ [0][0][2][0][5][4] = 62, ++ [0][0][2][0][6][4] = 58, ++ [0][0][2][0][9][4] = 58, ++ [0][0][2][0][8][4] = 30, ++ [0][0][2][0][11][4] = 52, ++ [0][0][2][0][2][6] = 76, ++ [0][0][2][0][1][6] = 58, ++ [0][0][2][0][3][6] = 62, ++ [0][0][2][0][5][6] = 62, ++ [0][0][2][0][6][6] = 54, ++ [0][0][2][0][9][6] = 58, ++ [0][0][2][0][8][6] = 30, ++ [0][0][2][0][11][6] = 52, ++ [0][0][2][0][2][8] = 76, ++ [0][0][2][0][1][8] = 58, ++ [0][0][2][0][3][8] = 62, ++ [0][0][2][0][5][8] = 64, ++ [0][0][2][0][6][8] = 58, ++ [0][0][2][0][9][8] = 58, ++ [0][0][2][0][8][8] = 54, ++ [0][0][2][0][11][8] = 52, ++ [0][0][2][0][2][10] = 76, ++ [0][0][2][0][1][10] = 58, ++ [0][0][2][0][3][10] = 62, ++ [0][0][2][0][5][10] = 64, ++ [0][0][2][0][6][10] = 58, ++ [0][0][2][0][9][10] = 58, ++ [0][0][2][0][8][10] = 54, ++ [0][0][2][0][11][10] = 52, ++ [0][0][2][0][2][12] = 76, ++ [0][0][2][0][1][12] = 58, ++ [0][0][2][0][3][12] = 62, ++ [0][0][2][0][5][12] = 64, ++ [0][0][2][0][6][12] = 58, ++ [0][0][2][0][9][12] = 58, ++ [0][0][2][0][8][12] = 54, ++ [0][0][2][0][11][12] = 52, ++ [0][0][2][0][2][14] = 76, ++ [0][0][2][0][1][14] = 58, ++ [0][0][2][0][3][14] = 62, ++ [0][0][2][0][5][14] = 64, ++ [0][0][2][0][6][14] = 58, ++ [0][0][2][0][9][14] = 58, ++ [0][0][2][0][8][14] = 54, ++ [0][0][2][0][11][14] = 52, ++ [0][0][2][0][2][15] = 74, ++ [0][0][2][0][1][15] = 58, ++ [0][0][2][0][3][15] = 76, ++ [0][0][2][0][5][15] = 74, ++ [0][0][2][0][6][15] = 58, ++ [0][0][2][0][9][15] = 58, ++ [0][0][2][0][8][15] = 54, ++ [0][0][2][0][11][15] = 52, ++ [0][0][2][0][2][17] = 76, ++ [0][0][2][0][1][17] = 58, ++ [0][0][2][0][3][17] = 76, ++ [0][0][2][0][5][17] = 76, ++ [0][0][2][0][6][17] = 58, ++ [0][0][2][0][9][17] = 58, ++ [0][0][2][0][8][17] = 54, ++ [0][0][2][0][11][17] = 52, ++ [0][0][2][0][2][19] = 76, ++ [0][0][2][0][1][19] = 58, ++ [0][0][2][0][3][19] = 76, ++ [0][0][2][0][5][19] = 76, ++ [0][0][2][0][6][19] = 58, ++ [0][0][2][0][9][19] = 58, ++ [0][0][2][0][8][19] = 54, ++ [0][0][2][0][11][19] = 52, ++ [0][0][2][0][2][21] = 76, ++ [0][0][2][0][1][21] = 58, ++ [0][0][2][0][3][21] = 76, ++ [0][0][2][0][5][21] = 76, ++ [0][0][2][0][6][21] = 58, ++ [0][0][2][0][9][21] = 58, ++ [0][0][2][0][8][21] = 54, ++ [0][0][2][0][11][21] = 52, ++ [0][0][2][0][2][23] = 76, ++ [0][0][2][0][1][23] = 58, ++ [0][0][2][0][3][23] = 76, ++ [0][0][2][0][5][23] = 76, ++ [0][0][2][0][6][23] = 58, ++ [0][0][2][0][9][23] = 58, ++ [0][0][2][0][8][23] = 54, ++ [0][0][2][0][11][23] = 52, ++ [0][0][2][0][2][25] = 76, ++ [0][0][2][0][1][25] = 58, ++ [0][0][2][0][3][25] = 76, ++ [0][0][2][0][5][25] = 127, ++ [0][0][2][0][6][25] = 58, ++ [0][0][2][0][9][25] = 127, ++ [0][0][2][0][8][25] = 54, ++ [0][0][2][0][11][25] = 52, ++ [0][0][2][0][2][27] = 76, ++ [0][0][2][0][1][27] = 58, ++ [0][0][2][0][3][27] = 76, ++ [0][0][2][0][5][27] = 127, ++ [0][0][2][0][6][27] = 58, ++ [0][0][2][0][9][27] = 127, ++ [0][0][2][0][8][27] = 54, ++ [0][0][2][0][11][27] = 52, ++ [0][0][2][0][2][29] = 76, ++ [0][0][2][0][1][29] = 58, ++ [0][0][2][0][3][29] = 76, ++ [0][0][2][0][5][29] = 127, ++ [0][0][2][0][6][29] = 58, ++ [0][0][2][0][9][29] = 127, ++ [0][0][2][0][8][29] = 54, ++ [0][0][2][0][11][29] = 52, ++ [0][0][2][0][2][31] = 76, ++ [0][0][2][0][1][31] = 58, ++ [0][0][2][0][3][31] = 76, ++ [0][0][2][0][5][31] = 76, ++ [0][0][2][0][6][31] = 58, ++ [0][0][2][0][9][31] = 58, ++ [0][0][2][0][8][31] = 54, ++ [0][0][2][0][11][31] = 52, ++ [0][0][2][0][2][33] = 76, ++ [0][0][2][0][1][33] = 58, ++ [0][0][2][0][3][33] = 76, ++ [0][0][2][0][5][33] = 76, ++ [0][0][2][0][6][33] = 58, ++ [0][0][2][0][9][33] = 58, ++ [0][0][2][0][8][33] = 54, ++ [0][0][2][0][11][33] = 52, ++ [0][0][2][0][2][35] = 70, ++ [0][0][2][0][1][35] = 58, ++ [0][0][2][0][3][35] = 76, ++ [0][0][2][0][5][35] = 70, ++ [0][0][2][0][6][35] = 58, ++ [0][0][2][0][9][35] = 58, ++ [0][0][2][0][8][35] = 54, ++ [0][0][2][0][11][35] = 52, ++ [0][0][2][0][2][37] = 76, ++ [0][0][2][0][1][37] = 127, ++ [0][0][2][0][3][37] = 76, ++ [0][0][2][0][5][37] = 76, ++ [0][0][2][0][6][37] = 58, ++ [0][0][2][0][9][37] = 76, ++ [0][0][2][0][8][37] = 54, ++ [0][0][2][0][11][37] = 127, ++ [0][0][2][0][2][38] = 76, ++ [0][0][2][0][1][38] = 28, ++ [0][0][2][0][3][38] = 127, ++ [0][0][2][0][5][38] = 76, ++ [0][0][2][0][6][38] = 28, ++ [0][0][2][0][9][38] = 76, ++ [0][0][2][0][8][38] = 54, ++ [0][0][2][0][11][38] = 52, ++ [0][0][2][0][2][40] = 76, ++ [0][0][2][0][1][40] = 28, ++ [0][0][2][0][3][40] = 127, ++ [0][0][2][0][5][40] = 76, ++ [0][0][2][0][6][40] = 28, ++ [0][0][2][0][9][40] = 76, ++ [0][0][2][0][8][40] = 54, ++ [0][0][2][0][11][40] = 52, ++ [0][0][2][0][2][42] = 76, ++ [0][0][2][0][1][42] = 28, ++ [0][0][2][0][3][42] = 127, ++ [0][0][2][0][5][42] = 76, ++ [0][0][2][0][6][42] = 28, ++ [0][0][2][0][9][42] = 76, ++ [0][0][2][0][8][42] = 54, ++ [0][0][2][0][11][42] = 52, ++ [0][0][2][0][2][44] = 76, ++ [0][0][2][0][1][44] = 28, ++ [0][0][2][0][3][44] = 127, ++ [0][0][2][0][5][44] = 76, ++ [0][0][2][0][6][44] = 28, ++ [0][0][2][0][9][44] = 76, ++ [0][0][2][0][8][44] = 54, ++ [0][0][2][0][11][44] = 52, ++ [0][0][2][0][2][46] = 76, ++ [0][0][2][0][1][46] = 28, ++ [0][0][2][0][3][46] = 127, ++ [0][0][2][0][5][46] = 76, ++ [0][0][2][0][6][46] = 28, ++ [0][0][2][0][9][46] = 76, ++ [0][0][2][0][8][46] = 54, ++ [0][0][2][0][11][46] = 52, ++ [0][1][2][0][2][0] = 68, ++ [0][1][2][0][1][0] = 46, ++ [0][1][2][0][3][0] = 50, ++ [0][1][2][0][5][0] = 40, ++ [0][1][2][0][6][0] = 46, ++ [0][1][2][0][9][0] = 46, ++ [0][1][2][0][8][0] = 18, ++ [0][1][2][0][11][0] = 40, ++ [0][1][2][0][2][2] = 68, ++ [0][1][2][0][1][2] = 46, ++ [0][1][2][0][3][2] = 50, ++ [0][1][2][0][5][2] = 40, ++ [0][1][2][0][6][2] = 46, ++ [0][1][2][0][9][2] = 46, ++ [0][1][2][0][8][2] = 18, ++ [0][1][2][0][11][2] = 40, ++ [0][1][2][0][2][4] = 68, ++ [0][1][2][0][1][4] = 46, ++ [0][1][2][0][3][4] = 50, ++ [0][1][2][0][5][4] = 40, ++ [0][1][2][0][6][4] = 46, ++ [0][1][2][0][9][4] = 46, ++ [0][1][2][0][8][4] = 18, ++ [0][1][2][0][11][4] = 40, ++ [0][1][2][0][2][6] = 68, ++ [0][1][2][0][1][6] = 46, ++ [0][1][2][0][3][6] = 50, ++ [0][1][2][0][5][6] = 40, ++ [0][1][2][0][6][6] = 36, ++ [0][1][2][0][9][6] = 46, ++ [0][1][2][0][8][6] = 18, ++ [0][1][2][0][11][6] = 40, ++ [0][1][2][0][2][8] = 68, ++ [0][1][2][0][1][8] = 46, ++ [0][1][2][0][3][8] = 50, ++ [0][1][2][0][5][8] = 52, ++ [0][1][2][0][6][8] = 46, ++ [0][1][2][0][9][8] = 46, ++ [0][1][2][0][8][8] = 42, ++ [0][1][2][0][11][8] = 40, ++ [0][1][2][0][2][10] = 68, ++ [0][1][2][0][1][10] = 46, ++ [0][1][2][0][3][10] = 50, ++ [0][1][2][0][5][10] = 52, ++ [0][1][2][0][6][10] = 46, ++ [0][1][2][0][9][10] = 46, ++ [0][1][2][0][8][10] = 42, ++ [0][1][2][0][11][10] = 40, ++ [0][1][2][0][2][12] = 68, ++ [0][1][2][0][1][12] = 46, ++ [0][1][2][0][3][12] = 50, ++ [0][1][2][0][5][12] = 52, ++ [0][1][2][0][6][12] = 46, ++ [0][1][2][0][9][12] = 46, ++ [0][1][2][0][8][12] = 42, ++ [0][1][2][0][11][12] = 40, ++ [0][1][2][0][2][14] = 68, ++ [0][1][2][0][1][14] = 46, ++ [0][1][2][0][3][14] = 50, ++ [0][1][2][0][5][14] = 52, ++ [0][1][2][0][6][14] = 46, ++ [0][1][2][0][9][14] = 46, ++ [0][1][2][0][8][14] = 42, ++ [0][1][2][0][11][14] = 40, ++ [0][1][2][0][2][15] = 68, ++ [0][1][2][0][1][15] = 46, ++ [0][1][2][0][3][15] = 70, ++ [0][1][2][0][5][15] = 68, ++ [0][1][2][0][6][15] = 46, ++ [0][1][2][0][9][15] = 46, ++ [0][1][2][0][8][15] = 42, ++ [0][1][2][0][11][15] = 40, ++ [0][1][2][0][2][17] = 68, ++ [0][1][2][0][1][17] = 46, ++ [0][1][2][0][3][17] = 70, ++ [0][1][2][0][5][17] = 68, ++ [0][1][2][0][6][17] = 46, ++ [0][1][2][0][9][17] = 46, ++ [0][1][2][0][8][17] = 42, ++ [0][1][2][0][11][17] = 40, ++ [0][1][2][0][2][19] = 68, ++ [0][1][2][0][1][19] = 46, ++ [0][1][2][0][3][19] = 70, ++ [0][1][2][0][5][19] = 68, ++ [0][1][2][0][6][19] = 46, ++ [0][1][2][0][9][19] = 46, ++ [0][1][2][0][8][19] = 42, ++ [0][1][2][0][11][19] = 40, ++ [0][1][2][0][2][21] = 68, ++ [0][1][2][0][1][21] = 46, ++ [0][1][2][0][3][21] = 70, ++ [0][1][2][0][5][21] = 68, ++ [0][1][2][0][6][21] = 46, ++ [0][1][2][0][9][21] = 46, ++ [0][1][2][0][8][21] = 42, ++ [0][1][2][0][11][21] = 40, ++ [0][1][2][0][2][23] = 68, ++ [0][1][2][0][1][23] = 46, ++ [0][1][2][0][3][23] = 70, ++ [0][1][2][0][5][23] = 68, ++ [0][1][2][0][6][23] = 46, ++ [0][1][2][0][9][23] = 46, ++ [0][1][2][0][8][23] = 42, ++ [0][1][2][0][11][23] = 40, ++ [0][1][2][0][2][25] = 68, ++ [0][1][2][0][1][25] = 46, ++ [0][1][2][0][3][25] = 70, ++ [0][1][2][0][5][25] = 127, ++ [0][1][2][0][6][25] = 46, ++ [0][1][2][0][9][25] = 127, ++ [0][1][2][0][8][25] = 42, ++ [0][1][2][0][11][25] = 40, ++ [0][1][2][0][2][27] = 68, ++ [0][1][2][0][1][27] = 46, ++ [0][1][2][0][3][27] = 70, ++ [0][1][2][0][5][27] = 127, ++ [0][1][2][0][6][27] = 46, ++ [0][1][2][0][9][27] = 127, ++ [0][1][2][0][8][27] = 42, ++ [0][1][2][0][11][27] = 40, ++ [0][1][2][0][2][29] = 68, ++ [0][1][2][0][1][29] = 46, ++ [0][1][2][0][3][29] = 70, ++ [0][1][2][0][5][29] = 127, ++ [0][1][2][0][6][29] = 46, ++ [0][1][2][0][9][29] = 127, ++ [0][1][2][0][8][29] = 42, ++ [0][1][2][0][11][29] = 40, ++ [0][1][2][0][2][31] = 68, ++ [0][1][2][0][1][31] = 46, ++ [0][1][2][0][3][31] = 70, ++ [0][1][2][0][5][31] = 68, ++ [0][1][2][0][6][31] = 46, ++ [0][1][2][0][9][31] = 46, ++ [0][1][2][0][8][31] = 42, ++ [0][1][2][0][11][31] = 40, ++ [0][1][2][0][2][33] = 68, ++ [0][1][2][0][1][33] = 46, ++ [0][1][2][0][3][33] = 70, ++ [0][1][2][0][5][33] = 68, ++ [0][1][2][0][6][33] = 46, ++ [0][1][2][0][9][33] = 46, ++ [0][1][2][0][8][33] = 42, ++ [0][1][2][0][11][33] = 40, ++ [0][1][2][0][2][35] = 64, ++ [0][1][2][0][1][35] = 46, ++ [0][1][2][0][3][35] = 70, ++ [0][1][2][0][5][35] = 64, ++ [0][1][2][0][6][35] = 46, ++ [0][1][2][0][9][35] = 46, ++ [0][1][2][0][8][35] = 42, ++ [0][1][2][0][11][35] = 40, ++ [0][1][2][0][2][37] = 68, ++ [0][1][2][0][1][37] = 127, ++ [0][1][2][0][3][37] = 70, ++ [0][1][2][0][5][37] = 68, ++ [0][1][2][0][6][37] = 46, ++ [0][1][2][0][9][37] = 68, ++ [0][1][2][0][8][37] = 42, ++ [0][1][2][0][11][37] = 127, ++ [0][1][2][0][2][38] = 76, ++ [0][1][2][0][1][38] = 16, ++ [0][1][2][0][3][38] = 127, ++ [0][1][2][0][5][38] = 76, ++ [0][1][2][0][6][38] = 16, ++ [0][1][2][0][9][38] = 76, ++ [0][1][2][0][8][38] = 42, ++ [0][1][2][0][11][38] = 40, ++ [0][1][2][0][2][40] = 76, ++ [0][1][2][0][1][40] = 16, ++ [0][1][2][0][3][40] = 127, ++ [0][1][2][0][5][40] = 76, ++ [0][1][2][0][6][40] = 16, ++ [0][1][2][0][9][40] = 76, ++ [0][1][2][0][8][40] = 42, ++ [0][1][2][0][11][40] = 40, ++ [0][1][2][0][2][42] = 76, ++ [0][1][2][0][1][42] = 16, ++ [0][1][2][0][3][42] = 127, ++ [0][1][2][0][5][42] = 76, ++ [0][1][2][0][6][42] = 16, ++ [0][1][2][0][9][42] = 76, ++ [0][1][2][0][8][42] = 42, ++ [0][1][2][0][11][42] = 40, ++ [0][1][2][0][2][44] = 76, ++ [0][1][2][0][1][44] = 16, ++ [0][1][2][0][3][44] = 127, ++ [0][1][2][0][5][44] = 76, ++ [0][1][2][0][6][44] = 16, ++ [0][1][2][0][9][44] = 76, ++ [0][1][2][0][8][44] = 42, ++ [0][1][2][0][11][44] = 40, ++ [0][1][2][0][2][46] = 76, ++ [0][1][2][0][1][46] = 16, ++ [0][1][2][0][3][46] = 127, ++ [0][1][2][0][5][46] = 76, ++ [0][1][2][0][6][46] = 16, ++ [0][1][2][0][9][46] = 76, ++ [0][1][2][0][8][46] = 42, ++ [0][1][2][0][11][46] = 40, ++ [0][1][2][1][2][0] = 68, ++ [0][1][2][1][1][0] = 34, ++ [0][1][2][1][3][0] = 50, ++ [0][1][2][1][5][0] = 38, ++ [0][1][2][1][6][0] = 34, ++ [0][1][2][1][9][0] = 34, ++ [0][1][2][1][8][0] = 6, ++ [0][1][2][1][11][0] = 28, ++ [0][1][2][1][2][2] = 68, ++ [0][1][2][1][1][2] = 34, ++ [0][1][2][1][3][2] = 50, ++ [0][1][2][1][5][2] = 38, ++ [0][1][2][1][6][2] = 34, ++ [0][1][2][1][9][2] = 34, ++ [0][1][2][1][8][2] = 6, ++ [0][1][2][1][11][2] = 28, ++ [0][1][2][1][2][4] = 68, ++ [0][1][2][1][1][4] = 34, ++ [0][1][2][1][3][4] = 50, ++ [0][1][2][1][5][4] = 38, ++ [0][1][2][1][6][4] = 34, ++ [0][1][2][1][9][4] = 34, ++ [0][1][2][1][8][4] = 6, ++ [0][1][2][1][11][4] = 28, ++ [0][1][2][1][2][6] = 68, ++ [0][1][2][1][1][6] = 34, ++ [0][1][2][1][3][6] = 50, ++ [0][1][2][1][5][6] = 38, ++ [0][1][2][1][6][6] = 34, ++ [0][1][2][1][9][6] = 34, ++ [0][1][2][1][8][6] = 6, ++ [0][1][2][1][11][6] = 28, ++ [0][1][2][1][2][8] = 68, ++ [0][1][2][1][1][8] = 34, ++ [0][1][2][1][3][8] = 50, ++ [0][1][2][1][5][8] = 38, ++ [0][1][2][1][6][8] = 34, ++ [0][1][2][1][9][8] = 34, ++ [0][1][2][1][8][8] = 30, ++ [0][1][2][1][11][8] = 28, ++ [0][1][2][1][2][10] = 68, ++ [0][1][2][1][1][10] = 34, ++ [0][1][2][1][3][10] = 50, ++ [0][1][2][1][5][10] = 38, ++ [0][1][2][1][6][10] = 34, ++ [0][1][2][1][9][10] = 34, ++ [0][1][2][1][8][10] = 30, ++ [0][1][2][1][11][10] = 28, ++ [0][1][2][1][2][12] = 68, ++ [0][1][2][1][1][12] = 34, ++ [0][1][2][1][3][12] = 50, ++ [0][1][2][1][5][12] = 38, ++ [0][1][2][1][6][12] = 34, ++ [0][1][2][1][9][12] = 34, ++ [0][1][2][1][8][12] = 30, ++ [0][1][2][1][11][12] = 28, ++ [0][1][2][1][2][14] = 68, ++ [0][1][2][1][1][14] = 34, ++ [0][1][2][1][3][14] = 50, ++ [0][1][2][1][5][14] = 38, ++ [0][1][2][1][6][14] = 34, ++ [0][1][2][1][9][14] = 34, ++ [0][1][2][1][8][14] = 30, ++ [0][1][2][1][11][14] = 28, ++ [0][1][2][1][2][15] = 68, ++ [0][1][2][1][1][15] = 34, ++ [0][1][2][1][3][15] = 70, ++ [0][1][2][1][5][15] = 62, ++ [0][1][2][1][6][15] = 34, ++ [0][1][2][1][9][15] = 34, ++ [0][1][2][1][8][15] = 30, ++ [0][1][2][1][11][15] = 28, ++ [0][1][2][1][2][17] = 68, ++ [0][1][2][1][1][17] = 34, ++ [0][1][2][1][3][17] = 70, ++ [0][1][2][1][5][17] = 62, ++ [0][1][2][1][6][17] = 34, ++ [0][1][2][1][9][17] = 34, ++ [0][1][2][1][8][17] = 30, ++ [0][1][2][1][11][17] = 28, ++ [0][1][2][1][2][19] = 68, ++ [0][1][2][1][1][19] = 34, ++ [0][1][2][1][3][19] = 70, ++ [0][1][2][1][5][19] = 62, ++ [0][1][2][1][6][19] = 34, ++ [0][1][2][1][9][19] = 34, ++ [0][1][2][1][8][19] = 30, ++ [0][1][2][1][11][19] = 28, ++ [0][1][2][1][2][21] = 68, ++ [0][1][2][1][1][21] = 34, ++ [0][1][2][1][3][21] = 70, ++ [0][1][2][1][5][21] = 62, ++ [0][1][2][1][6][21] = 34, ++ [0][1][2][1][9][21] = 34, ++ [0][1][2][1][8][21] = 30, ++ [0][1][2][1][11][21] = 28, ++ [0][1][2][1][2][23] = 68, ++ [0][1][2][1][1][23] = 34, ++ [0][1][2][1][3][23] = 70, ++ [0][1][2][1][5][23] = 62, ++ [0][1][2][1][6][23] = 34, ++ [0][1][2][1][9][23] = 34, ++ [0][1][2][1][8][23] = 30, ++ [0][1][2][1][11][23] = 28, ++ [0][1][2][1][2][25] = 68, ++ [0][1][2][1][1][25] = 34, ++ [0][1][2][1][3][25] = 70, ++ [0][1][2][1][5][25] = 127, ++ [0][1][2][1][6][25] = 34, ++ [0][1][2][1][9][25] = 127, ++ [0][1][2][1][8][25] = 30, ++ [0][1][2][1][11][25] = 28, ++ [0][1][2][1][2][27] = 68, ++ [0][1][2][1][1][27] = 34, ++ [0][1][2][1][3][27] = 70, ++ [0][1][2][1][5][27] = 127, ++ [0][1][2][1][6][27] = 34, ++ [0][1][2][1][9][27] = 127, ++ [0][1][2][1][8][27] = 30, ++ [0][1][2][1][11][27] = 28, ++ [0][1][2][1][2][29] = 68, ++ [0][1][2][1][1][29] = 34, ++ [0][1][2][1][3][29] = 70, ++ [0][1][2][1][5][29] = 127, ++ [0][1][2][1][6][29] = 34, ++ [0][1][2][1][9][29] = 127, ++ [0][1][2][1][8][29] = 30, ++ [0][1][2][1][11][29] = 28, ++ [0][1][2][1][2][31] = 68, ++ [0][1][2][1][1][31] = 34, ++ [0][1][2][1][3][31] = 70, ++ [0][1][2][1][5][31] = 62, ++ [0][1][2][1][6][31] = 34, ++ [0][1][2][1][9][31] = 34, ++ [0][1][2][1][8][31] = 30, ++ [0][1][2][1][11][31] = 28, ++ [0][1][2][1][2][33] = 68, ++ [0][1][2][1][1][33] = 34, ++ [0][1][2][1][3][33] = 70, ++ [0][1][2][1][5][33] = 62, ++ [0][1][2][1][6][33] = 34, ++ [0][1][2][1][9][33] = 34, ++ [0][1][2][1][8][33] = 30, ++ [0][1][2][1][11][33] = 28, ++ [0][1][2][1][2][35] = 64, ++ [0][1][2][1][1][35] = 34, ++ [0][1][2][1][3][35] = 70, ++ [0][1][2][1][5][35] = 62, ++ [0][1][2][1][6][35] = 34, ++ [0][1][2][1][9][35] = 34, ++ [0][1][2][1][8][35] = 30, ++ [0][1][2][1][11][35] = 28, ++ [0][1][2][1][2][37] = 68, ++ [0][1][2][1][1][37] = 127, ++ [0][1][2][1][3][37] = 70, ++ [0][1][2][1][5][37] = 62, ++ [0][1][2][1][6][37] = 34, ++ [0][1][2][1][9][37] = 68, ++ [0][1][2][1][8][37] = 30, ++ [0][1][2][1][11][37] = 127, ++ [0][1][2][1][2][38] = 76, ++ [0][1][2][1][1][38] = 4, ++ [0][1][2][1][3][38] = 127, ++ [0][1][2][1][5][38] = 76, ++ [0][1][2][1][6][38] = 4, ++ [0][1][2][1][9][38] = 76, ++ [0][1][2][1][8][38] = 30, ++ [0][1][2][1][11][38] = 28, ++ [0][1][2][1][2][40] = 76, ++ [0][1][2][1][1][40] = 4, ++ [0][1][2][1][3][40] = 127, ++ [0][1][2][1][5][40] = 76, ++ [0][1][2][1][6][40] = 4, ++ [0][1][2][1][9][40] = 76, ++ [0][1][2][1][8][40] = 30, ++ [0][1][2][1][11][40] = 28, ++ [0][1][2][1][2][42] = 76, ++ [0][1][2][1][1][42] = 4, ++ [0][1][2][1][3][42] = 127, ++ [0][1][2][1][5][42] = 76, ++ [0][1][2][1][6][42] = 4, ++ [0][1][2][1][9][42] = 76, ++ [0][1][2][1][8][42] = 30, ++ [0][1][2][1][11][42] = 28, ++ [0][1][2][1][2][44] = 76, ++ [0][1][2][1][1][44] = 4, ++ [0][1][2][1][3][44] = 127, ++ [0][1][2][1][5][44] = 76, ++ [0][1][2][1][6][44] = 4, ++ [0][1][2][1][9][44] = 76, ++ [0][1][2][1][8][44] = 30, ++ [0][1][2][1][11][44] = 28, ++ [0][1][2][1][2][46] = 76, ++ [0][1][2][1][1][46] = 4, ++ [0][1][2][1][3][46] = 127, ++ [0][1][2][1][5][46] = 76, ++ [0][1][2][1][6][46] = 4, ++ [0][1][2][1][9][46] = 76, ++ [0][1][2][1][8][46] = 30, ++ [0][1][2][1][11][46] = 28, ++ [1][0][2][0][2][1] = 68, ++ [1][0][2][0][1][1] = 64, ++ [1][0][2][0][3][1] = 62, ++ [1][0][2][0][5][1] = 64, ++ [1][0][2][0][6][1] = 64, ++ [1][0][2][0][9][1] = 64, ++ [1][0][2][0][8][1] = 30, ++ [1][0][2][0][11][1] = 52, ++ [1][0][2][0][2][5] = 72, ++ [1][0][2][0][1][5] = 64, ++ [1][0][2][0][3][5] = 62, ++ [1][0][2][0][5][5] = 64, ++ [1][0][2][0][6][5] = 60, ++ [1][0][2][0][9][5] = 64, ++ [1][0][2][0][8][5] = 30, ++ [1][0][2][0][11][5] = 52, ++ [1][0][2][0][2][9] = 72, ++ [1][0][2][0][1][9] = 64, ++ [1][0][2][0][3][9] = 62, ++ [1][0][2][0][5][9] = 64, ++ [1][0][2][0][6][9] = 64, ++ [1][0][2][0][9][9] = 64, ++ [1][0][2][0][8][9] = 54, ++ [1][0][2][0][11][9] = 52, ++ [1][0][2][0][2][13] = 66, ++ [1][0][2][0][1][13] = 64, ++ [1][0][2][0][3][13] = 62, ++ [1][0][2][0][5][13] = 64, ++ [1][0][2][0][6][13] = 64, ++ [1][0][2][0][9][13] = 64, ++ [1][0][2][0][8][13] = 54, ++ [1][0][2][0][11][13] = 52, ++ [1][0][2][0][2][16] = 62, ++ [1][0][2][0][1][16] = 64, ++ [1][0][2][0][3][16] = 72, ++ [1][0][2][0][5][16] = 62, ++ [1][0][2][0][6][16] = 64, ++ [1][0][2][0][9][16] = 64, ++ [1][0][2][0][8][16] = 54, ++ [1][0][2][0][11][16] = 52, ++ [1][0][2][0][2][20] = 72, ++ [1][0][2][0][1][20] = 64, ++ [1][0][2][0][3][20] = 72, ++ [1][0][2][0][5][20] = 72, ++ [1][0][2][0][6][20] = 64, ++ [1][0][2][0][9][20] = 64, ++ [1][0][2][0][8][20] = 54, ++ [1][0][2][0][11][20] = 52, ++ [1][0][2][0][2][24] = 72, ++ [1][0][2][0][1][24] = 64, ++ [1][0][2][0][3][24] = 72, ++ [1][0][2][0][5][24] = 127, ++ [1][0][2][0][6][24] = 64, ++ [1][0][2][0][9][24] = 127, ++ [1][0][2][0][8][24] = 54, ++ [1][0][2][0][11][24] = 52, ++ [1][0][2][0][2][28] = 72, ++ [1][0][2][0][1][28] = 64, ++ [1][0][2][0][3][28] = 72, ++ [1][0][2][0][5][28] = 127, ++ [1][0][2][0][6][28] = 64, ++ [1][0][2][0][9][28] = 127, ++ [1][0][2][0][8][28] = 54, ++ [1][0][2][0][11][28] = 52, ++ [1][0][2][0][2][32] = 72, ++ [1][0][2][0][1][32] = 64, ++ [1][0][2][0][3][32] = 72, ++ [1][0][2][0][5][32] = 72, ++ [1][0][2][0][6][32] = 64, ++ [1][0][2][0][9][32] = 64, ++ [1][0][2][0][8][32] = 54, ++ [1][0][2][0][11][32] = 52, ++ [1][0][2][0][2][36] = 72, ++ [1][0][2][0][1][36] = 127, ++ [1][0][2][0][3][36] = 72, ++ [1][0][2][0][5][36] = 72, ++ [1][0][2][0][6][36] = 64, ++ [1][0][2][0][9][36] = 72, ++ [1][0][2][0][8][36] = 54, ++ [1][0][2][0][11][36] = 127, ++ [1][0][2][0][2][39] = 72, ++ [1][0][2][0][1][39] = 28, ++ [1][0][2][0][3][39] = 127, ++ [1][0][2][0][5][39] = 72, ++ [1][0][2][0][6][39] = 28, ++ [1][0][2][0][9][39] = 72, ++ [1][0][2][0][8][39] = 54, ++ [1][0][2][0][11][39] = 52, ++ [1][0][2][0][2][43] = 72, ++ [1][0][2][0][1][43] = 28, ++ [1][0][2][0][3][43] = 127, ++ [1][0][2][0][5][43] = 72, ++ [1][0][2][0][6][43] = 28, ++ [1][0][2][0][9][43] = 72, ++ [1][0][2][0][8][43] = 54, ++ [1][0][2][0][11][43] = 52, ++ [1][1][2][0][2][1] = 58, ++ [1][1][2][0][1][1] = 52, ++ [1][1][2][0][3][1] = 50, ++ [1][1][2][0][5][1] = 52, ++ [1][1][2][0][6][1] = 52, ++ [1][1][2][0][9][1] = 52, ++ [1][1][2][0][8][1] = 18, ++ [1][1][2][0][11][1] = 40, ++ [1][1][2][0][2][5] = 72, ++ [1][1][2][0][1][5] = 52, ++ [1][1][2][0][3][5] = 50, ++ [1][1][2][0][5][5] = 52, ++ [1][1][2][0][6][5] = 46, ++ [1][1][2][0][9][5] = 52, ++ [1][1][2][0][8][5] = 18, ++ [1][1][2][0][11][5] = 40, ++ [1][1][2][0][2][9] = 72, ++ [1][1][2][0][1][9] = 52, ++ [1][1][2][0][3][9] = 50, ++ [1][1][2][0][5][9] = 52, ++ [1][1][2][0][6][9] = 52, ++ [1][1][2][0][9][9] = 52, ++ [1][1][2][0][8][9] = 42, ++ [1][1][2][0][11][9] = 40, ++ [1][1][2][0][2][13] = 58, ++ [1][1][2][0][1][13] = 52, ++ [1][1][2][0][3][13] = 50, ++ [1][1][2][0][5][13] = 52, ++ [1][1][2][0][6][13] = 52, ++ [1][1][2][0][9][13] = 52, ++ [1][1][2][0][8][13] = 42, ++ [1][1][2][0][11][13] = 40, ++ [1][1][2][0][2][16] = 56, ++ [1][1][2][0][1][16] = 52, ++ [1][1][2][0][3][16] = 72, ++ [1][1][2][0][5][16] = 56, ++ [1][1][2][0][6][16] = 52, ++ [1][1][2][0][9][16] = 52, ++ [1][1][2][0][8][16] = 42, ++ [1][1][2][0][11][16] = 40, ++ [1][1][2][0][2][20] = 72, ++ [1][1][2][0][1][20] = 52, ++ [1][1][2][0][3][20] = 72, ++ [1][1][2][0][5][20] = 72, ++ [1][1][2][0][6][20] = 52, ++ [1][1][2][0][9][20] = 52, ++ [1][1][2][0][8][20] = 42, ++ [1][1][2][0][11][20] = 40, ++ [1][1][2][0][2][24] = 72, ++ [1][1][2][0][1][24] = 52, ++ [1][1][2][0][3][24] = 72, ++ [1][1][2][0][5][24] = 127, ++ [1][1][2][0][6][24] = 52, ++ [1][1][2][0][9][24] = 127, ++ [1][1][2][0][8][24] = 42, ++ [1][1][2][0][11][24] = 40, ++ [1][1][2][0][2][28] = 72, ++ [1][1][2][0][1][28] = 52, ++ [1][1][2][0][3][28] = 72, ++ [1][1][2][0][5][28] = 127, ++ [1][1][2][0][6][28] = 52, ++ [1][1][2][0][9][28] = 127, ++ [1][1][2][0][8][28] = 42, ++ [1][1][2][0][11][28] = 40, ++ [1][1][2][0][2][32] = 68, ++ [1][1][2][0][1][32] = 52, ++ [1][1][2][0][3][32] = 72, ++ [1][1][2][0][5][32] = 68, ++ [1][1][2][0][6][32] = 52, ++ [1][1][2][0][9][32] = 52, ++ [1][1][2][0][8][32] = 42, ++ [1][1][2][0][11][32] = 40, ++ [1][1][2][0][2][36] = 72, ++ [1][1][2][0][1][36] = 127, ++ [1][1][2][0][3][36] = 72, ++ [1][1][2][0][5][36] = 72, ++ [1][1][2][0][6][36] = 52, ++ [1][1][2][0][9][36] = 72, ++ [1][1][2][0][8][36] = 42, ++ [1][1][2][0][11][36] = 127, ++ [1][1][2][0][2][39] = 72, ++ [1][1][2][0][1][39] = 16, ++ [1][1][2][0][3][39] = 127, ++ [1][1][2][0][5][39] = 72, ++ [1][1][2][0][6][39] = 16, ++ [1][1][2][0][9][39] = 72, ++ [1][1][2][0][8][39] = 42, ++ [1][1][2][0][11][39] = 40, ++ [1][1][2][0][2][43] = 72, ++ [1][1][2][0][1][43] = 16, ++ [1][1][2][0][3][43] = 127, ++ [1][1][2][0][5][43] = 72, ++ [1][1][2][0][6][43] = 16, ++ [1][1][2][0][9][43] = 72, ++ [1][1][2][0][8][43] = 42, ++ [1][1][2][0][11][43] = 40, ++ [1][1][2][1][2][1] = 58, ++ [1][1][2][1][1][1] = 40, ++ [1][1][2][1][3][1] = 50, ++ [1][1][2][1][5][1] = 40, ++ [1][1][2][1][6][1] = 40, ++ [1][1][2][1][9][1] = 40, ++ [1][1][2][1][8][1] = 6, ++ [1][1][2][1][11][1] = 28, ++ [1][1][2][1][2][5] = 68, ++ [1][1][2][1][1][5] = 40, ++ [1][1][2][1][3][5] = 50, ++ [1][1][2][1][5][5] = 40, ++ [1][1][2][1][6][5] = 40, ++ [1][1][2][1][9][5] = 40, ++ [1][1][2][1][8][5] = 6, ++ [1][1][2][1][11][5] = 28, ++ [1][1][2][1][2][9] = 68, ++ [1][1][2][1][1][9] = 40, ++ [1][1][2][1][3][9] = 50, ++ [1][1][2][1][5][9] = 40, ++ [1][1][2][1][6][9] = 40, ++ [1][1][2][1][9][9] = 40, ++ [1][1][2][1][8][9] = 30, ++ [1][1][2][1][11][9] = 28, ++ [1][1][2][1][2][13] = 58, ++ [1][1][2][1][1][13] = 40, ++ [1][1][2][1][3][13] = 50, ++ [1][1][2][1][5][13] = 40, ++ [1][1][2][1][6][13] = 40, ++ [1][1][2][1][9][13] = 40, ++ [1][1][2][1][8][13] = 30, ++ [1][1][2][1][11][13] = 28, ++ [1][1][2][1][2][16] = 56, ++ [1][1][2][1][1][16] = 40, ++ [1][1][2][1][3][16] = 72, ++ [1][1][2][1][5][16] = 56, ++ [1][1][2][1][6][16] = 40, ++ [1][1][2][1][9][16] = 40, ++ [1][1][2][1][8][16] = 30, ++ [1][1][2][1][11][16] = 28, ++ [1][1][2][1][2][20] = 68, ++ [1][1][2][1][1][20] = 40, ++ [1][1][2][1][3][20] = 72, ++ [1][1][2][1][5][20] = 68, ++ [1][1][2][1][6][20] = 40, ++ [1][1][2][1][9][20] = 40, ++ [1][1][2][1][8][20] = 30, ++ [1][1][2][1][11][20] = 28, ++ [1][1][2][1][2][24] = 68, ++ [1][1][2][1][1][24] = 40, ++ [1][1][2][1][3][24] = 72, ++ [1][1][2][1][5][24] = 127, ++ [1][1][2][1][6][24] = 40, ++ [1][1][2][1][9][24] = 127, ++ [1][1][2][1][8][24] = 30, ++ [1][1][2][1][11][24] = 28, ++ [1][1][2][1][2][28] = 68, ++ [1][1][2][1][1][28] = 40, ++ [1][1][2][1][3][28] = 72, ++ [1][1][2][1][5][28] = 127, ++ [1][1][2][1][6][28] = 40, ++ [1][1][2][1][9][28] = 127, ++ [1][1][2][1][8][28] = 30, ++ [1][1][2][1][11][28] = 28, ++ [1][1][2][1][2][32] = 68, ++ [1][1][2][1][1][32] = 40, ++ [1][1][2][1][3][32] = 72, ++ [1][1][2][1][5][32] = 68, ++ [1][1][2][1][6][32] = 40, ++ [1][1][2][1][9][32] = 40, ++ [1][1][2][1][8][32] = 30, ++ [1][1][2][1][11][32] = 28, ++ [1][1][2][1][2][36] = 68, ++ [1][1][2][1][1][36] = 127, ++ [1][1][2][1][3][36] = 72, ++ [1][1][2][1][5][36] = 68, ++ [1][1][2][1][6][36] = 40, ++ [1][1][2][1][9][36] = 68, ++ [1][1][2][1][8][36] = 30, ++ [1][1][2][1][11][36] = 127, ++ [1][1][2][1][2][39] = 72, ++ [1][1][2][1][1][39] = 4, ++ [1][1][2][1][3][39] = 127, ++ [1][1][2][1][5][39] = 72, ++ [1][1][2][1][6][39] = 4, ++ [1][1][2][1][9][39] = 72, ++ [1][1][2][1][8][39] = 30, ++ [1][1][2][1][11][39] = 28, ++ [1][1][2][1][2][43] = 72, ++ [1][1][2][1][1][43] = 4, ++ [1][1][2][1][3][43] = 127, ++ [1][1][2][1][5][43] = 72, ++ [1][1][2][1][6][43] = 4, ++ [1][1][2][1][9][43] = 72, ++ [1][1][2][1][8][43] = 30, ++ [1][1][2][1][11][43] = 28, ++ [2][0][2][0][2][3] = 64, ++ [2][0][2][0][1][3] = 64, ++ [2][0][2][0][3][3] = 64, ++ [2][0][2][0][5][3] = 62, ++ [2][0][2][0][6][3] = 64, ++ [2][0][2][0][9][3] = 64, ++ [2][0][2][0][8][3] = 30, ++ [2][0][2][0][11][3] = 52, ++ [2][0][2][0][2][11] = 64, ++ [2][0][2][0][1][11] = 64, ++ [2][0][2][0][3][11] = 64, ++ [2][0][2][0][5][11] = 62, ++ [2][0][2][0][6][11] = 64, ++ [2][0][2][0][9][11] = 64, ++ [2][0][2][0][8][11] = 54, ++ [2][0][2][0][11][11] = 52, ++ [2][0][2][0][2][18] = 62, ++ [2][0][2][0][1][18] = 64, ++ [2][0][2][0][3][18] = 72, ++ [2][0][2][0][5][18] = 66, ++ [2][0][2][0][6][18] = 64, ++ [2][0][2][0][9][18] = 64, ++ [2][0][2][0][8][18] = 54, ++ [2][0][2][0][11][18] = 52, ++ [2][0][2][0][2][26] = 72, ++ [2][0][2][0][1][26] = 64, ++ [2][0][2][0][3][26] = 72, ++ [2][0][2][0][5][26] = 127, ++ [2][0][2][0][6][26] = 64, ++ [2][0][2][0][9][26] = 127, ++ [2][0][2][0][8][26] = 54, ++ [2][0][2][0][11][26] = 52, ++ [2][0][2][0][2][34] = 72, ++ [2][0][2][0][1][34] = 127, ++ [2][0][2][0][3][34] = 72, ++ [2][0][2][0][5][34] = 72, ++ [2][0][2][0][6][34] = 64, ++ [2][0][2][0][9][34] = 72, ++ [2][0][2][0][8][34] = 54, ++ [2][0][2][0][11][34] = 127, ++ [2][0][2][0][2][41] = 72, ++ [2][0][2][0][1][41] = 28, ++ [2][0][2][0][3][41] = 127, ++ [2][0][2][0][5][41] = 72, ++ [2][0][2][0][6][41] = 28, ++ [2][0][2][0][9][41] = 72, ++ [2][0][2][0][8][41] = 54, ++ [2][0][2][0][11][41] = 52, ++ [2][1][2][0][2][3] = 56, ++ [2][1][2][0][1][3] = 52, ++ [2][1][2][0][3][3] = 52, ++ [2][1][2][0][5][3] = 52, ++ [2][1][2][0][6][3] = 52, ++ [2][1][2][0][9][3] = 52, ++ [2][1][2][0][8][3] = 18, ++ [2][1][2][0][11][3] = 40, ++ [2][1][2][0][2][11] = 56, ++ [2][1][2][0][1][11] = 52, ++ [2][1][2][0][3][11] = 52, ++ [2][1][2][0][5][11] = 52, ++ [2][1][2][0][6][11] = 52, ++ [2][1][2][0][9][11] = 52, ++ [2][1][2][0][8][11] = 42, ++ [2][1][2][0][11][11] = 40, ++ [2][1][2][0][2][18] = 56, ++ [2][1][2][0][1][18] = 52, ++ [2][1][2][0][3][18] = 72, ++ [2][1][2][0][5][18] = 56, ++ [2][1][2][0][6][18] = 52, ++ [2][1][2][0][9][18] = 52, ++ [2][1][2][0][8][18] = 42, ++ [2][1][2][0][11][18] = 40, ++ [2][1][2][0][2][26] = 72, ++ [2][1][2][0][1][26] = 52, ++ [2][1][2][0][3][26] = 72, ++ [2][1][2][0][5][26] = 127, ++ [2][1][2][0][6][26] = 52, ++ [2][1][2][0][9][26] = 127, ++ [2][1][2][0][8][26] = 42, ++ [2][1][2][0][11][26] = 40, ++ [2][1][2][0][2][34] = 72, ++ [2][1][2][0][1][34] = 127, ++ [2][1][2][0][3][34] = 72, ++ [2][1][2][0][5][34] = 72, ++ [2][1][2][0][6][34] = 52, ++ [2][1][2][0][9][34] = 72, ++ [2][1][2][0][8][34] = 42, ++ [2][1][2][0][11][34] = 127, ++ [2][1][2][0][2][41] = 72, ++ [2][1][2][0][1][41] = 16, ++ [2][1][2][0][3][41] = 127, ++ [2][1][2][0][5][41] = 72, ++ [2][1][2][0][6][41] = 16, ++ [2][1][2][0][9][41] = 72, ++ [2][1][2][0][8][41] = 42, ++ [2][1][2][0][11][41] = 40, ++ [2][1][2][1][2][3] = 56, ++ [2][1][2][1][1][3] = 40, ++ [2][1][2][1][3][3] = 52, ++ [2][1][2][1][5][3] = 40, ++ [2][1][2][1][6][3] = 40, ++ [2][1][2][1][9][3] = 40, ++ [2][1][2][1][8][3] = 6, ++ [2][1][2][1][11][3] = 28, ++ [2][1][2][1][2][11] = 56, ++ [2][1][2][1][1][11] = 40, ++ [2][1][2][1][3][11] = 52, ++ [2][1][2][1][5][11] = 40, ++ [2][1][2][1][6][11] = 40, ++ [2][1][2][1][9][11] = 40, ++ [2][1][2][1][8][11] = 30, ++ [2][1][2][1][11][11] = 28, ++ [2][1][2][1][2][18] = 56, ++ [2][1][2][1][1][18] = 40, ++ [2][1][2][1][3][18] = 72, ++ [2][1][2][1][5][18] = 56, ++ [2][1][2][1][6][18] = 40, ++ [2][1][2][1][9][18] = 40, ++ [2][1][2][1][8][18] = 30, ++ [2][1][2][1][11][18] = 28, ++ [2][1][2][1][2][26] = 68, ++ [2][1][2][1][1][26] = 40, ++ [2][1][2][1][3][26] = 72, ++ [2][1][2][1][5][26] = 127, ++ [2][1][2][1][6][26] = 40, ++ [2][1][2][1][9][26] = 127, ++ [2][1][2][1][8][26] = 30, ++ [2][1][2][1][11][26] = 28, ++ [2][1][2][1][2][34] = 68, ++ [2][1][2][1][1][34] = 127, ++ [2][1][2][1][3][34] = 72, ++ [2][1][2][1][5][34] = 68, ++ [2][1][2][1][6][34] = 40, ++ [2][1][2][1][9][34] = 68, ++ [2][1][2][1][8][34] = 30, ++ [2][1][2][1][11][34] = 127, ++ [2][1][2][1][2][41] = 72, ++ [2][1][2][1][1][41] = 4, ++ [2][1][2][1][3][41] = 127, ++ [2][1][2][1][5][41] = 72, ++ [2][1][2][1][6][41] = 4, ++ [2][1][2][1][9][41] = 72, ++ [2][1][2][1][8][41] = 30, ++ [2][1][2][1][11][41] = 28, ++}; ++ ++const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] ++ [RTW89_REGD_NUM][RTW89_2G_CH_NUM] = { ++ [0][0][0][0] = 32, ++ [0][0][0][1] = 32, ++ [0][0][0][2] = 32, ++ [0][0][0][3] = 32, ++ [0][0][0][4] = 32, ++ [0][0][0][5] = 32, ++ [0][0][0][6] = 32, ++ [0][0][0][7] = 32, ++ [0][0][0][8] = 32, ++ [0][0][0][9] = 32, ++ [0][0][0][10] = 32, ++ [0][0][0][11] = 32, ++ [0][0][0][12] = 32, ++ [0][0][0][13] = 0, ++ [0][1][0][0] = 20, ++ [0][1][0][1] = 20, ++ [0][1][0][2] = 20, ++ [0][1][0][3] = 20, ++ [0][1][0][4] = 20, ++ [0][1][0][5] = 20, ++ [0][1][0][6] = 20, ++ [0][1][0][7] = 20, ++ [0][1][0][8] = 20, ++ [0][1][0][9] = 20, ++ [0][1][0][10] = 20, ++ [0][1][0][11] = 20, ++ [0][1][0][12] = 20, ++ [0][1][0][13] = 0, ++ [1][0][0][0] = 42, ++ [1][0][0][1] = 42, ++ [1][0][0][2] = 42, ++ [1][0][0][3] = 42, ++ [1][0][0][4] = 42, ++ [1][0][0][5] = 42, ++ [1][0][0][6] = 42, ++ [1][0][0][7] = 42, ++ [1][0][0][8] = 42, ++ [1][0][0][9] = 42, ++ [1][0][0][10] = 42, ++ [1][0][0][11] = 42, ++ [1][0][0][12] = 36, ++ [1][0][0][13] = 0, ++ [1][1][0][0] = 30, ++ [1][1][0][1] = 30, ++ [1][1][0][2] = 30, ++ [1][1][0][3] = 30, ++ [1][1][0][4] = 30, ++ [1][1][0][5] = 30, ++ [1][1][0][6] = 30, ++ [1][1][0][7] = 30, ++ [1][1][0][8] = 30, ++ [1][1][0][9] = 30, ++ [1][1][0][10] = 30, ++ [1][1][0][11] = 30, ++ [1][1][0][12] = 30, ++ [1][1][0][13] = 0, ++ [2][0][0][0] = 52, ++ [2][0][0][1] = 52, ++ [2][0][0][2] = 52, ++ [2][0][0][3] = 52, ++ [2][0][0][4] = 52, ++ [2][0][0][5] = 52, ++ [2][0][0][6] = 52, ++ [2][0][0][7] = 52, ++ [2][0][0][8] = 52, ++ [2][0][0][9] = 52, ++ [2][0][0][10] = 52, ++ [2][0][0][11] = 52, ++ [2][0][0][12] = 40, ++ [2][0][0][13] = 0, ++ [2][1][0][0] = 40, ++ [2][1][0][1] = 40, ++ [2][1][0][2] = 40, ++ [2][1][0][3] = 40, ++ [2][1][0][4] = 40, ++ [2][1][0][5] = 40, ++ [2][1][0][6] = 40, ++ [2][1][0][7] = 40, ++ [2][1][0][8] = 40, ++ [2][1][0][9] = 40, ++ [2][1][0][10] = 40, ++ [2][1][0][11] = 40, ++ [2][1][0][12] = 26, ++ [2][1][0][13] = 0, ++ [0][0][2][0] = 70, ++ [0][0][1][0] = 32, ++ [0][0][3][0] = 40, ++ [0][0][5][0] = 70, ++ [0][0][6][0] = 32, ++ [0][0][9][0] = 32, ++ [0][0][8][0] = 60, ++ [0][0][11][0] = 32, ++ [0][0][2][1] = 70, ++ [0][0][1][1] = 32, ++ [0][0][3][1] = 40, ++ [0][0][5][1] = 70, ++ [0][0][6][1] = 32, ++ [0][0][9][1] = 32, ++ [0][0][8][1] = 60, ++ [0][0][11][1] = 32, ++ [0][0][2][2] = 74, ++ [0][0][1][2] = 32, ++ [0][0][3][2] = 40, ++ [0][0][5][2] = 74, ++ [0][0][6][2] = 32, ++ [0][0][9][2] = 32, ++ [0][0][8][2] = 60, ++ [0][0][11][2] = 32, ++ [0][0][2][3] = 78, ++ [0][0][1][3] = 32, ++ [0][0][3][3] = 40, ++ [0][0][5][3] = 78, ++ [0][0][6][3] = 32, ++ [0][0][9][3] = 32, ++ [0][0][8][3] = 60, ++ [0][0][11][3] = 32, ++ [0][0][2][4] = 78, ++ [0][0][1][4] = 32, ++ [0][0][3][4] = 40, ++ [0][0][5][4] = 78, ++ [0][0][6][4] = 32, ++ [0][0][9][4] = 32, ++ [0][0][8][4] = 60, ++ [0][0][11][4] = 32, ++ [0][0][2][5] = 78, ++ [0][0][1][5] = 32, ++ [0][0][3][5] = 40, ++ [0][0][5][5] = 78, ++ [0][0][6][5] = 32, ++ [0][0][9][5] = 32, ++ [0][0][8][5] = 60, ++ [0][0][11][5] = 32, ++ [0][0][2][6] = 78, ++ [0][0][1][6] = 32, ++ [0][0][3][6] = 40, ++ [0][0][5][6] = 78, ++ [0][0][6][6] = 32, ++ [0][0][9][6] = 32, ++ [0][0][8][6] = 60, ++ [0][0][11][6] = 32, ++ [0][0][2][7] = 78, ++ [0][0][1][7] = 32, ++ [0][0][3][7] = 40, ++ [0][0][5][7] = 78, ++ [0][0][6][7] = 32, ++ [0][0][9][7] = 32, ++ [0][0][8][7] = 60, ++ [0][0][11][7] = 32, ++ [0][0][2][8] = 74, ++ [0][0][1][8] = 32, ++ [0][0][3][8] = 40, ++ [0][0][5][8] = 74, ++ [0][0][6][8] = 32, ++ [0][0][9][8] = 32, ++ [0][0][8][8] = 60, ++ [0][0][11][8] = 32, ++ [0][0][2][9] = 70, ++ [0][0][1][9] = 32, ++ [0][0][3][9] = 40, ++ [0][0][5][9] = 70, ++ [0][0][6][9] = 32, ++ [0][0][9][9] = 32, ++ [0][0][8][9] = 60, ++ [0][0][11][9] = 32, ++ [0][0][2][10] = 70, ++ [0][0][1][10] = 32, ++ [0][0][3][10] = 40, ++ [0][0][5][10] = 70, ++ [0][0][6][10] = 32, ++ [0][0][9][10] = 32, ++ [0][0][8][10] = 60, ++ [0][0][11][10] = 32, ++ [0][0][2][11] = 58, ++ [0][0][1][11] = 32, ++ [0][0][3][11] = 40, ++ [0][0][5][11] = 58, ++ [0][0][6][11] = 32, ++ [0][0][9][11] = 32, ++ [0][0][8][11] = 60, ++ [0][0][11][11] = 32, ++ [0][0][2][12] = 34, ++ [0][0][1][12] = 32, ++ [0][0][3][12] = 40, ++ [0][0][5][12] = 34, ++ [0][0][6][12] = 32, ++ [0][0][9][12] = 32, ++ [0][0][8][12] = 60, ++ [0][0][11][12] = 32, ++ [0][0][2][13] = 127, ++ [0][0][1][13] = 127, ++ [0][0][3][13] = 127, ++ [0][0][5][13] = 127, ++ [0][0][6][13] = 127, ++ [0][0][9][13] = 127, ++ [0][0][8][13] = 127, ++ [0][0][11][13] = 127, ++ [0][1][2][0] = 64, ++ [0][1][1][0] = 20, ++ [0][1][3][0] = 28, ++ [0][1][5][0] = 64, ++ [0][1][6][0] = 20, ++ [0][1][9][0] = 20, ++ [0][1][8][0] = 48, ++ [0][1][11][0] = 20, ++ [0][1][2][1] = 64, ++ [0][1][1][1] = 20, ++ [0][1][3][1] = 28, ++ [0][1][5][1] = 64, ++ [0][1][6][1] = 20, ++ [0][1][9][1] = 20, ++ [0][1][8][1] = 48, ++ [0][1][11][1] = 20, ++ [0][1][2][2] = 68, ++ [0][1][1][2] = 20, ++ [0][1][3][2] = 28, ++ [0][1][5][2] = 68, ++ [0][1][6][2] = 20, ++ [0][1][9][2] = 20, ++ [0][1][8][2] = 48, ++ [0][1][11][2] = 20, ++ [0][1][2][3] = 72, ++ [0][1][1][3] = 20, ++ [0][1][3][3] = 28, ++ [0][1][5][3] = 72, ++ [0][1][6][3] = 20, ++ [0][1][9][3] = 20, ++ [0][1][8][3] = 48, ++ [0][1][11][3] = 20, ++ [0][1][2][4] = 76, ++ [0][1][1][4] = 20, ++ [0][1][3][4] = 28, ++ [0][1][5][4] = 76, ++ [0][1][6][4] = 20, ++ [0][1][9][4] = 20, ++ [0][1][8][4] = 48, ++ [0][1][11][4] = 20, ++ [0][1][2][5] = 78, ++ [0][1][1][5] = 20, ++ [0][1][3][5] = 28, ++ [0][1][5][5] = 78, ++ [0][1][6][5] = 20, ++ [0][1][9][5] = 20, ++ [0][1][8][5] = 48, ++ [0][1][11][5] = 20, ++ [0][1][2][6] = 76, ++ [0][1][1][6] = 20, ++ [0][1][3][6] = 28, ++ [0][1][5][6] = 76, ++ [0][1][6][6] = 20, ++ [0][1][9][6] = 20, ++ [0][1][8][6] = 48, ++ [0][1][11][6] = 20, ++ [0][1][2][7] = 72, ++ [0][1][1][7] = 20, ++ [0][1][3][7] = 28, ++ [0][1][5][7] = 72, ++ [0][1][6][7] = 20, ++ [0][1][9][7] = 20, ++ [0][1][8][7] = 48, ++ [0][1][11][7] = 20, ++ [0][1][2][8] = 68, ++ [0][1][1][8] = 20, ++ [0][1][3][8] = 28, ++ [0][1][5][8] = 68, ++ [0][1][6][8] = 20, ++ [0][1][9][8] = 20, ++ [0][1][8][8] = 48, ++ [0][1][11][8] = 20, ++ [0][1][2][9] = 64, ++ [0][1][1][9] = 20, ++ [0][1][3][9] = 28, ++ [0][1][5][9] = 64, ++ [0][1][6][9] = 20, ++ [0][1][9][9] = 20, ++ [0][1][8][9] = 48, ++ [0][1][11][9] = 20, ++ [0][1][2][10] = 64, ++ [0][1][1][10] = 20, ++ [0][1][3][10] = 28, ++ [0][1][5][10] = 64, ++ [0][1][6][10] = 20, ++ [0][1][9][10] = 20, ++ [0][1][8][10] = 48, ++ [0][1][11][10] = 20, ++ [0][1][2][11] = 54, ++ [0][1][1][11] = 20, ++ [0][1][3][11] = 28, ++ [0][1][5][11] = 54, ++ [0][1][6][11] = 20, ++ [0][1][9][11] = 20, ++ [0][1][8][11] = 48, ++ [0][1][11][11] = 20, ++ [0][1][2][12] = 32, ++ [0][1][1][12] = 20, ++ [0][1][3][12] = 28, ++ [0][1][5][12] = 32, ++ [0][1][6][12] = 20, ++ [0][1][9][12] = 20, ++ [0][1][8][12] = 48, ++ [0][1][11][12] = 20, ++ [0][1][2][13] = 127, ++ [0][1][1][13] = 127, ++ [0][1][3][13] = 127, ++ [0][1][5][13] = 127, ++ [0][1][6][13] = 127, ++ [0][1][9][13] = 127, ++ [0][1][8][13] = 127, ++ [0][1][11][13] = 127, ++ [1][0][2][0] = 72, ++ [1][0][1][0] = 42, ++ [1][0][3][0] = 50, ++ [1][0][5][0] = 72, ++ [1][0][6][0] = 42, ++ [1][0][9][0] = 42, ++ [1][0][8][0] = 60, ++ [1][0][11][0] = 42, ++ [1][0][2][1] = 72, ++ [1][0][1][1] = 42, ++ [1][0][3][1] = 50, ++ [1][0][5][1] = 72, ++ [1][0][6][1] = 42, ++ [1][0][9][1] = 42, ++ [1][0][8][1] = 60, ++ [1][0][11][1] = 42, ++ [1][0][2][2] = 76, ++ [1][0][1][2] = 42, ++ [1][0][3][2] = 50, ++ [1][0][5][2] = 76, ++ [1][0][6][2] = 42, ++ [1][0][9][2] = 42, ++ [1][0][8][2] = 60, ++ [1][0][11][2] = 42, ++ [1][0][2][3] = 78, ++ [1][0][1][3] = 42, ++ [1][0][3][3] = 50, ++ [1][0][5][3] = 78, ++ [1][0][6][3] = 42, ++ [1][0][9][3] = 42, ++ [1][0][8][3] = 60, ++ [1][0][11][3] = 42, ++ [1][0][2][4] = 78, ++ [1][0][1][4] = 42, ++ [1][0][3][4] = 50, ++ [1][0][5][4] = 78, ++ [1][0][6][4] = 42, ++ [1][0][9][4] = 42, ++ [1][0][8][4] = 60, ++ [1][0][11][4] = 42, ++ [1][0][2][5] = 78, ++ [1][0][1][5] = 42, ++ [1][0][3][5] = 50, ++ [1][0][5][5] = 78, ++ [1][0][6][5] = 42, ++ [1][0][9][5] = 42, ++ [1][0][8][5] = 60, ++ [1][0][11][5] = 42, ++ [1][0][2][6] = 78, ++ [1][0][1][6] = 42, ++ [1][0][3][6] = 50, ++ [1][0][5][6] = 78, ++ [1][0][6][6] = 42, ++ [1][0][9][6] = 42, ++ [1][0][8][6] = 60, ++ [1][0][11][6] = 42, ++ [1][0][2][7] = 78, ++ [1][0][1][7] = 42, ++ [1][0][3][7] = 50, ++ [1][0][5][7] = 78, ++ [1][0][6][7] = 42, ++ [1][0][9][7] = 42, ++ [1][0][8][7] = 60, ++ [1][0][11][7] = 42, ++ [1][0][2][8] = 78, ++ [1][0][1][8] = 42, ++ [1][0][3][8] = 50, ++ [1][0][5][8] = 78, ++ [1][0][6][8] = 42, ++ [1][0][9][8] = 42, ++ [1][0][8][8] = 60, ++ [1][0][11][8] = 42, ++ [1][0][2][9] = 74, ++ [1][0][1][9] = 42, ++ [1][0][3][9] = 50, ++ [1][0][5][9] = 74, ++ [1][0][6][9] = 42, ++ [1][0][9][9] = 42, ++ [1][0][8][9] = 60, ++ [1][0][11][9] = 42, ++ [1][0][2][10] = 74, ++ [1][0][1][10] = 42, ++ [1][0][3][10] = 50, ++ [1][0][5][10] = 74, ++ [1][0][6][10] = 42, ++ [1][0][9][10] = 42, ++ [1][0][8][10] = 60, ++ [1][0][11][10] = 42, ++ [1][0][2][11] = 64, ++ [1][0][1][11] = 42, ++ [1][0][3][11] = 50, ++ [1][0][5][11] = 64, ++ [1][0][6][11] = 42, ++ [1][0][9][11] = 42, ++ [1][0][8][11] = 60, ++ [1][0][11][11] = 42, ++ [1][0][2][12] = 36, ++ [1][0][1][12] = 42, ++ [1][0][3][12] = 50, ++ [1][0][5][12] = 36, ++ [1][0][6][12] = 42, ++ [1][0][9][12] = 42, ++ [1][0][8][12] = 60, ++ [1][0][11][12] = 42, ++ [1][0][2][13] = 127, ++ [1][0][1][13] = 127, ++ [1][0][3][13] = 127, ++ [1][0][5][13] = 127, ++ [1][0][6][13] = 127, ++ [1][0][9][13] = 127, ++ [1][0][8][13] = 127, ++ [1][0][11][13] = 127, ++ [1][1][2][0] = 66, ++ [1][1][1][0] = 30, ++ [1][1][3][0] = 38, ++ [1][1][5][0] = 66, ++ [1][1][6][0] = 30, ++ [1][1][9][0] = 30, ++ [1][1][8][0] = 48, ++ [1][1][11][0] = 30, ++ [1][1][2][1] = 66, ++ [1][1][1][1] = 30, ++ [1][1][3][1] = 38, ++ [1][1][5][1] = 66, ++ [1][1][6][1] = 30, ++ [1][1][9][1] = 30, ++ [1][1][8][1] = 48, ++ [1][1][11][1] = 30, ++ [1][1][2][2] = 70, ++ [1][1][1][2] = 30, ++ [1][1][3][2] = 38, ++ [1][1][5][2] = 70, ++ [1][1][6][2] = 30, ++ [1][1][9][2] = 30, ++ [1][1][8][2] = 48, ++ [1][1][11][2] = 30, ++ [1][1][2][3] = 74, ++ [1][1][1][3] = 30, ++ [1][1][3][3] = 38, ++ [1][1][5][3] = 74, ++ [1][1][6][3] = 30, ++ [1][1][9][3] = 30, ++ [1][1][8][3] = 48, ++ [1][1][11][3] = 30, ++ [1][1][2][4] = 78, ++ [1][1][1][4] = 30, ++ [1][1][3][4] = 38, ++ [1][1][5][4] = 78, ++ [1][1][6][4] = 30, ++ [1][1][9][4] = 30, ++ [1][1][8][4] = 48, ++ [1][1][11][4] = 30, ++ [1][1][2][5] = 78, ++ [1][1][1][5] = 30, ++ [1][1][3][5] = 38, ++ [1][1][5][5] = 78, ++ [1][1][6][5] = 30, ++ [1][1][9][5] = 30, ++ [1][1][8][5] = 48, ++ [1][1][11][5] = 30, ++ [1][1][2][6] = 78, ++ [1][1][1][6] = 30, ++ [1][1][3][6] = 38, ++ [1][1][5][6] = 78, ++ [1][1][6][6] = 30, ++ [1][1][9][6] = 30, ++ [1][1][8][6] = 48, ++ [1][1][11][6] = 30, ++ [1][1][2][7] = 74, ++ [1][1][1][7] = 30, ++ [1][1][3][7] = 38, ++ [1][1][5][7] = 74, ++ [1][1][6][7] = 30, ++ [1][1][9][7] = 30, ++ [1][1][8][7] = 48, ++ [1][1][11][7] = 30, ++ [1][1][2][8] = 70, ++ [1][1][1][8] = 30, ++ [1][1][3][8] = 38, ++ [1][1][5][8] = 70, ++ [1][1][6][8] = 30, ++ [1][1][9][8] = 30, ++ [1][1][8][8] = 48, ++ [1][1][11][8] = 30, ++ [1][1][2][9] = 66, ++ [1][1][1][9] = 30, ++ [1][1][3][9] = 38, ++ [1][1][5][9] = 66, ++ [1][1][6][9] = 30, ++ [1][1][9][9] = 30, ++ [1][1][8][9] = 48, ++ [1][1][11][9] = 30, ++ [1][1][2][10] = 66, ++ [1][1][1][10] = 30, ++ [1][1][3][10] = 38, ++ [1][1][5][10] = 66, ++ [1][1][6][10] = 30, ++ [1][1][9][10] = 30, ++ [1][1][8][10] = 48, ++ [1][1][11][10] = 30, ++ [1][1][2][11] = 60, ++ [1][1][1][11] = 30, ++ [1][1][3][11] = 38, ++ [1][1][5][11] = 60, ++ [1][1][6][11] = 30, ++ [1][1][9][11] = 30, ++ [1][1][8][11] = 48, ++ [1][1][11][11] = 30, ++ [1][1][2][12] = 32, ++ [1][1][1][12] = 30, ++ [1][1][3][12] = 38, ++ [1][1][5][12] = 32, ++ [1][1][6][12] = 30, ++ [1][1][9][12] = 30, ++ [1][1][8][12] = 48, ++ [1][1][11][12] = 30, ++ [1][1][2][13] = 127, ++ [1][1][1][13] = 127, ++ [1][1][3][13] = 127, ++ [1][1][5][13] = 127, ++ [1][1][6][13] = 127, ++ [1][1][9][13] = 127, ++ [1][1][8][13] = 127, ++ [1][1][11][13] = 127, ++ [2][0][2][0] = 76, ++ [2][0][1][0] = 52, ++ [2][0][3][0] = 64, ++ [2][0][5][0] = 76, ++ [2][0][6][0] = 52, ++ [2][0][9][0] = 52, ++ [2][0][8][0] = 60, ++ [2][0][11][0] = 52, ++ [2][0][2][1] = 76, ++ [2][0][1][1] = 52, ++ [2][0][3][1] = 64, ++ [2][0][5][1] = 76, ++ [2][0][6][1] = 52, ++ [2][0][9][1] = 52, ++ [2][0][8][1] = 60, ++ [2][0][11][1] = 52, ++ [2][0][2][2] = 78, ++ [2][0][1][2] = 52, ++ [2][0][3][2] = 64, ++ [2][0][5][2] = 78, ++ [2][0][6][2] = 52, ++ [2][0][9][2] = 52, ++ [2][0][8][2] = 60, ++ [2][0][11][2] = 52, ++ [2][0][2][3] = 78, ++ [2][0][1][3] = 52, ++ [2][0][3][3] = 64, ++ [2][0][5][3] = 78, ++ [2][0][6][3] = 52, ++ [2][0][9][3] = 52, ++ [2][0][8][3] = 60, ++ [2][0][11][3] = 52, ++ [2][0][2][4] = 78, ++ [2][0][1][4] = 52, ++ [2][0][3][4] = 64, ++ [2][0][5][4] = 78, ++ [2][0][6][4] = 52, ++ [2][0][9][4] = 52, ++ [2][0][8][4] = 60, ++ [2][0][11][4] = 52, ++ [2][0][2][5] = 78, ++ [2][0][1][5] = 52, ++ [2][0][3][5] = 64, ++ [2][0][5][5] = 78, ++ [2][0][6][5] = 52, ++ [2][0][9][5] = 52, ++ [2][0][8][5] = 60, ++ [2][0][11][5] = 52, ++ [2][0][2][6] = 78, ++ [2][0][1][6] = 52, ++ [2][0][3][6] = 64, ++ [2][0][5][6] = 78, ++ [2][0][6][6] = 52, ++ [2][0][9][6] = 52, ++ [2][0][8][6] = 60, ++ [2][0][11][6] = 52, ++ [2][0][2][7] = 78, ++ [2][0][1][7] = 52, ++ [2][0][3][7] = 64, ++ [2][0][5][7] = 78, ++ [2][0][6][7] = 52, ++ [2][0][9][7] = 52, ++ [2][0][8][7] = 60, ++ [2][0][11][7] = 52, ++ [2][0][2][8] = 78, ++ [2][0][1][8] = 52, ++ [2][0][3][8] = 64, ++ [2][0][5][8] = 78, ++ [2][0][6][8] = 52, ++ [2][0][9][8] = 52, ++ [2][0][8][8] = 60, ++ [2][0][11][8] = 52, ++ [2][0][2][9] = 76, ++ [2][0][1][9] = 52, ++ [2][0][3][9] = 64, ++ [2][0][5][9] = 76, ++ [2][0][6][9] = 52, ++ [2][0][9][9] = 52, ++ [2][0][8][9] = 60, ++ [2][0][11][9] = 52, ++ [2][0][2][10] = 76, ++ [2][0][1][10] = 52, ++ [2][0][3][10] = 64, ++ [2][0][5][10] = 76, ++ [2][0][6][10] = 52, ++ [2][0][9][10] = 52, ++ [2][0][8][10] = 60, ++ [2][0][11][10] = 52, ++ [2][0][2][11] = 68, ++ [2][0][1][11] = 52, ++ [2][0][3][11] = 64, ++ [2][0][5][11] = 68, ++ [2][0][6][11] = 52, ++ [2][0][9][11] = 52, ++ [2][0][8][11] = 60, ++ [2][0][11][11] = 52, ++ [2][0][2][12] = 40, ++ [2][0][1][12] = 52, ++ [2][0][3][12] = 64, ++ [2][0][5][12] = 40, ++ [2][0][6][12] = 52, ++ [2][0][9][12] = 52, ++ [2][0][8][12] = 60, ++ [2][0][11][12] = 52, ++ [2][0][2][13] = 127, ++ [2][0][1][13] = 127, ++ [2][0][3][13] = 127, ++ [2][0][5][13] = 127, ++ [2][0][6][13] = 127, ++ [2][0][9][13] = 127, ++ [2][0][8][13] = 127, ++ [2][0][11][13] = 127, ++ [2][1][2][0] = 68, ++ [2][1][1][0] = 40, ++ [2][1][3][0] = 52, ++ [2][1][5][0] = 68, ++ [2][1][6][0] = 40, ++ [2][1][9][0] = 40, ++ [2][1][8][0] = 48, ++ [2][1][11][0] = 40, ++ [2][1][2][1] = 68, ++ [2][1][1][1] = 40, ++ [2][1][3][1] = 52, ++ [2][1][5][1] = 68, ++ [2][1][6][1] = 40, ++ [2][1][9][1] = 40, ++ [2][1][8][1] = 48, ++ [2][1][11][1] = 40, ++ [2][1][2][2] = 72, ++ [2][1][1][2] = 40, ++ [2][1][3][2] = 52, ++ [2][1][5][2] = 72, ++ [2][1][6][2] = 40, ++ [2][1][9][2] = 40, ++ [2][1][8][2] = 48, ++ [2][1][11][2] = 40, ++ [2][1][2][3] = 76, ++ [2][1][1][3] = 40, ++ [2][1][3][3] = 52, ++ [2][1][5][3] = 76, ++ [2][1][6][3] = 40, ++ [2][1][9][3] = 40, ++ [2][1][8][3] = 48, ++ [2][1][11][3] = 40, ++ [2][1][2][4] = 78, ++ [2][1][1][4] = 40, ++ [2][1][3][4] = 52, ++ [2][1][5][4] = 78, ++ [2][1][6][4] = 40, ++ [2][1][9][4] = 40, ++ [2][1][8][4] = 48, ++ [2][1][11][4] = 40, ++ [2][1][2][5] = 78, ++ [2][1][1][5] = 40, ++ [2][1][3][5] = 52, ++ [2][1][5][5] = 78, ++ [2][1][6][5] = 40, ++ [2][1][9][5] = 40, ++ [2][1][8][5] = 48, ++ [2][1][11][5] = 40, ++ [2][1][2][6] = 78, ++ [2][1][1][6] = 40, ++ [2][1][3][6] = 52, ++ [2][1][5][6] = 78, ++ [2][1][6][6] = 40, ++ [2][1][9][6] = 40, ++ [2][1][8][6] = 48, ++ [2][1][11][6] = 40, ++ [2][1][2][7] = 78, ++ [2][1][1][7] = 40, ++ [2][1][3][7] = 52, ++ [2][1][5][7] = 78, ++ [2][1][6][7] = 40, ++ [2][1][9][7] = 40, ++ [2][1][8][7] = 48, ++ [2][1][11][7] = 40, ++ [2][1][2][8] = 74, ++ [2][1][1][8] = 40, ++ [2][1][3][8] = 52, ++ [2][1][5][8] = 74, ++ [2][1][6][8] = 40, ++ [2][1][9][8] = 40, ++ [2][1][8][8] = 48, ++ [2][1][11][8] = 40, ++ [2][1][2][9] = 70, ++ [2][1][1][9] = 40, ++ [2][1][3][9] = 52, ++ [2][1][5][9] = 70, ++ [2][1][6][9] = 40, ++ [2][1][9][9] = 40, ++ [2][1][8][9] = 48, ++ [2][1][11][9] = 40, ++ [2][1][2][10] = 70, ++ [2][1][1][10] = 40, ++ [2][1][3][10] = 52, ++ [2][1][5][10] = 70, ++ [2][1][6][10] = 40, ++ [2][1][9][10] = 40, ++ [2][1][8][10] = 48, ++ [2][1][11][10] = 40, ++ [2][1][2][11] = 48, ++ [2][1][1][11] = 40, ++ [2][1][3][11] = 52, ++ [2][1][5][11] = 48, ++ [2][1][6][11] = 40, ++ [2][1][9][11] = 40, ++ [2][1][8][11] = 48, ++ [2][1][11][11] = 40, ++ [2][1][2][12] = 26, ++ [2][1][1][12] = 40, ++ [2][1][3][12] = 52, ++ [2][1][5][12] = 26, ++ [2][1][6][12] = 40, ++ [2][1][9][12] = 40, ++ [2][1][8][12] = 48, ++ [2][1][11][12] = 40, ++ [2][1][2][13] = 127, ++ [2][1][1][13] = 127, ++ [2][1][3][13] = 127, ++ [2][1][5][13] = 127, ++ [2][1][6][13] = 127, ++ [2][1][9][13] = 127, ++ [2][1][8][13] = 127, ++ [2][1][11][13] = 127, ++}; ++ ++const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] ++ [RTW89_REGD_NUM][RTW89_5G_CH_NUM] = { ++ [0][0][0][0] = 22, ++ [0][0][0][2] = 22, ++ [0][0][0][4] = 22, ++ [0][0][0][6] = 22, ++ [0][0][0][8] = 24, ++ [0][0][0][10] = 24, ++ [0][0][0][12] = 24, ++ [0][0][0][14] = 24, ++ [0][0][0][15] = 24, ++ [0][0][0][17] = 24, ++ [0][0][0][19] = 24, ++ [0][0][0][21] = 24, ++ [0][0][0][23] = 24, ++ [0][0][0][25] = 24, ++ [0][0][0][27] = 24, ++ [0][0][0][29] = 24, ++ [0][0][0][31] = 24, ++ [0][0][0][33] = 24, ++ [0][0][0][35] = 24, ++ [0][0][0][37] = 24, ++ [0][0][0][38] = 28, ++ [0][0][0][40] = 28, ++ [0][0][0][42] = 28, ++ [0][0][0][44] = 28, ++ [0][0][0][46] = 28, ++ [0][1][0][0] = 8, ++ [0][1][0][2] = 8, ++ [0][1][0][4] = 8, ++ [0][1][0][6] = 8, ++ [0][1][0][8] = 12, ++ [0][1][0][10] = 12, ++ [0][1][0][12] = 12, ++ [0][1][0][14] = 12, ++ [0][1][0][15] = 12, ++ [0][1][0][17] = 12, ++ [0][1][0][19] = 12, ++ [0][1][0][21] = 12, ++ [0][1][0][23] = 12, ++ [0][1][0][25] = 12, ++ [0][1][0][27] = 12, ++ [0][1][0][29] = 12, ++ [0][1][0][31] = 12, ++ [0][1][0][33] = 12, ++ [0][1][0][35] = 12, ++ [0][1][0][37] = 12, ++ [0][1][0][38] = 16, ++ [0][1][0][40] = 16, ++ [0][1][0][42] = 16, ++ [0][1][0][44] = 16, ++ [0][1][0][46] = 16, ++ [1][0][0][0] = 30, ++ [1][0][0][2] = 30, ++ [1][0][0][4] = 30, ++ [1][0][0][6] = 30, ++ [1][0][0][8] = 36, ++ [1][0][0][10] = 36, ++ [1][0][0][12] = 36, ++ [1][0][0][14] = 36, ++ [1][0][0][15] = 36, ++ [1][0][0][17] = 36, ++ [1][0][0][19] = 36, ++ [1][0][0][21] = 36, ++ [1][0][0][23] = 36, ++ [1][0][0][25] = 36, ++ [1][0][0][27] = 36, ++ [1][0][0][29] = 36, ++ [1][0][0][31] = 36, ++ [1][0][0][33] = 36, ++ [1][0][0][35] = 36, ++ [1][0][0][37] = 36, ++ [1][0][0][38] = 28, ++ [1][0][0][40] = 28, ++ [1][0][0][42] = 28, ++ [1][0][0][44] = 28, ++ [1][0][0][46] = 28, ++ [1][1][0][0] = 18, ++ [1][1][0][2] = 18, ++ [1][1][0][4] = 18, ++ [1][1][0][6] = 18, ++ [1][1][0][8] = 22, ++ [1][1][0][10] = 22, ++ [1][1][0][12] = 22, ++ [1][1][0][14] = 22, ++ [1][1][0][15] = 22, ++ [1][1][0][17] = 22, ++ [1][1][0][19] = 22, ++ [1][1][0][21] = 22, ++ [1][1][0][23] = 22, ++ [1][1][0][25] = 22, ++ [1][1][0][27] = 22, ++ [1][1][0][29] = 22, ++ [1][1][0][31] = 22, ++ [1][1][0][33] = 22, ++ [1][1][0][35] = 22, ++ [1][1][0][37] = 22, ++ [1][1][0][38] = 16, ++ [1][1][0][40] = 16, ++ [1][1][0][42] = 16, ++ [1][1][0][44] = 16, ++ [1][1][0][46] = 16, ++ [2][0][0][0] = 30, ++ [2][0][0][2] = 30, ++ [2][0][0][4] = 30, ++ [2][0][0][6] = 30, ++ [2][0][0][8] = 46, ++ [2][0][0][10] = 46, ++ [2][0][0][12] = 46, ++ [2][0][0][14] = 46, ++ [2][0][0][15] = 46, ++ [2][0][0][17] = 46, ++ [2][0][0][19] = 46, ++ [2][0][0][21] = 46, ++ [2][0][0][23] = 46, ++ [2][0][0][25] = 46, ++ [2][0][0][27] = 46, ++ [2][0][0][29] = 46, ++ [2][0][0][31] = 46, ++ [2][0][0][33] = 46, ++ [2][0][0][35] = 46, ++ [2][0][0][37] = 46, ++ [2][0][0][38] = 28, ++ [2][0][0][40] = 28, ++ [2][0][0][42] = 28, ++ [2][0][0][44] = 28, ++ [2][0][0][46] = 28, ++ [2][1][0][0] = 18, ++ [2][1][0][2] = 18, ++ [2][1][0][4] = 18, ++ [2][1][0][6] = 18, ++ [2][1][0][8] = 32, ++ [2][1][0][10] = 32, ++ [2][1][0][12] = 32, ++ [2][1][0][14] = 32, ++ [2][1][0][15] = 32, ++ [2][1][0][17] = 32, ++ [2][1][0][19] = 32, ++ [2][1][0][21] = 32, ++ [2][1][0][23] = 32, ++ [2][1][0][25] = 32, ++ [2][1][0][27] = 32, ++ [2][1][0][29] = 32, ++ [2][1][0][31] = 32, ++ [2][1][0][33] = 32, ++ [2][1][0][35] = 32, ++ [2][1][0][37] = 32, ++ [2][1][0][38] = 16, ++ [2][1][0][40] = 16, ++ [2][1][0][42] = 16, ++ [2][1][0][44] = 16, ++ [2][1][0][46] = 16, ++ [0][0][2][0] = 48, ++ [0][0][1][0] = 24, ++ [0][0][3][0] = 26, ++ [0][0][5][0] = 22, ++ [0][0][6][0] = 24, ++ [0][0][9][0] = 24, ++ [0][0][8][0] = 30, ++ [0][0][11][0] = 24, ++ [0][0][2][2] = 48, ++ [0][0][1][2] = 24, ++ [0][0][3][2] = 26, ++ [0][0][5][2] = 22, ++ [0][0][6][2] = 24, ++ [0][0][9][2] = 24, ++ [0][0][8][2] = 30, ++ [0][0][11][2] = 24, ++ [0][0][2][4] = 48, ++ [0][0][1][4] = 24, ++ [0][0][3][4] = 26, ++ [0][0][5][4] = 22, ++ [0][0][6][4] = 24, ++ [0][0][9][4] = 24, ++ [0][0][8][4] = 30, ++ [0][0][11][4] = 24, ++ [0][0][2][6] = 48, ++ [0][0][1][6] = 24, ++ [0][0][3][6] = 26, ++ [0][0][5][6] = 22, ++ [0][0][6][6] = 24, ++ [0][0][9][6] = 24, ++ [0][0][8][6] = 30, ++ [0][0][11][6] = 24, ++ [0][0][2][8] = 48, ++ [0][0][1][8] = 24, ++ [0][0][3][8] = 26, ++ [0][0][5][8] = 48, ++ [0][0][6][8] = 24, ++ [0][0][9][8] = 24, ++ [0][0][8][8] = 54, ++ [0][0][11][8] = 24, ++ [0][0][2][10] = 48, ++ [0][0][1][10] = 24, ++ [0][0][3][10] = 26, ++ [0][0][5][10] = 48, ++ [0][0][6][10] = 24, ++ [0][0][9][10] = 24, ++ [0][0][8][10] = 54, ++ [0][0][11][10] = 24, ++ [0][0][2][12] = 48, ++ [0][0][1][12] = 24, ++ [0][0][3][12] = 26, ++ [0][0][5][12] = 48, ++ [0][0][6][12] = 24, ++ [0][0][9][12] = 24, ++ [0][0][8][12] = 54, ++ [0][0][11][12] = 24, ++ [0][0][2][14] = 48, ++ [0][0][1][14] = 24, ++ [0][0][3][14] = 26, ++ [0][0][5][14] = 48, ++ [0][0][6][14] = 24, ++ [0][0][9][14] = 24, ++ [0][0][8][14] = 54, ++ [0][0][11][14] = 24, ++ [0][0][2][15] = 48, ++ [0][0][1][15] = 24, ++ [0][0][3][15] = 44, ++ [0][0][5][15] = 48, ++ [0][0][6][15] = 24, ++ [0][0][9][15] = 24, ++ [0][0][8][15] = 54, ++ [0][0][11][15] = 24, ++ [0][0][2][17] = 48, ++ [0][0][1][17] = 24, ++ [0][0][3][17] = 44, ++ [0][0][5][17] = 48, ++ [0][0][6][17] = 24, ++ [0][0][9][17] = 24, ++ [0][0][8][17] = 54, ++ [0][0][11][17] = 24, ++ [0][0][2][19] = 48, ++ [0][0][1][19] = 24, ++ [0][0][3][19] = 44, ++ [0][0][5][19] = 48, ++ [0][0][6][19] = 24, ++ [0][0][9][19] = 24, ++ [0][0][8][19] = 54, ++ [0][0][11][19] = 24, ++ [0][0][2][21] = 48, ++ [0][0][1][21] = 24, ++ [0][0][3][21] = 44, ++ [0][0][5][21] = 48, ++ [0][0][6][21] = 24, ++ [0][0][9][21] = 24, ++ [0][0][8][21] = 54, ++ [0][0][11][21] = 24, ++ [0][0][2][23] = 48, ++ [0][0][1][23] = 24, ++ [0][0][3][23] = 44, ++ [0][0][5][23] = 48, ++ [0][0][6][23] = 24, ++ [0][0][9][23] = 24, ++ [0][0][8][23] = 54, ++ [0][0][11][23] = 24, ++ [0][0][2][25] = 48, ++ [0][0][1][25] = 24, ++ [0][0][3][25] = 44, ++ [0][0][5][25] = 127, ++ [0][0][6][25] = 24, ++ [0][0][9][25] = 127, ++ [0][0][8][25] = 54, ++ [0][0][11][25] = 24, ++ [0][0][2][27] = 48, ++ [0][0][1][27] = 24, ++ [0][0][3][27] = 44, ++ [0][0][5][27] = 127, ++ [0][0][6][27] = 24, ++ [0][0][9][27] = 127, ++ [0][0][8][27] = 54, ++ [0][0][11][27] = 24, ++ [0][0][2][29] = 48, ++ [0][0][1][29] = 24, ++ [0][0][3][29] = 44, ++ [0][0][5][29] = 127, ++ [0][0][6][29] = 24, ++ [0][0][9][29] = 127, ++ [0][0][8][29] = 54, ++ [0][0][11][29] = 24, ++ [0][0][2][31] = 48, ++ [0][0][1][31] = 24, ++ [0][0][3][31] = 44, ++ [0][0][5][31] = 48, ++ [0][0][6][31] = 24, ++ [0][0][9][31] = 24, ++ [0][0][8][31] = 54, ++ [0][0][11][31] = 24, ++ [0][0][2][33] = 48, ++ [0][0][1][33] = 24, ++ [0][0][3][33] = 44, ++ [0][0][5][33] = 48, ++ [0][0][6][33] = 24, ++ [0][0][9][33] = 24, ++ [0][0][8][33] = 54, ++ [0][0][11][33] = 24, ++ [0][0][2][35] = 48, ++ [0][0][1][35] = 24, ++ [0][0][3][35] = 44, ++ [0][0][5][35] = 48, ++ [0][0][6][35] = 24, ++ [0][0][9][35] = 24, ++ [0][0][8][35] = 54, ++ [0][0][11][35] = 24, ++ [0][0][2][37] = 48, ++ [0][0][1][37] = 127, ++ [0][0][3][37] = 44, ++ [0][0][5][37] = 48, ++ [0][0][6][37] = 24, ++ [0][0][9][37] = 48, ++ [0][0][8][37] = 54, ++ [0][0][11][37] = 127, ++ [0][0][2][38] = 76, ++ [0][0][1][38] = 28, ++ [0][0][3][38] = 127, ++ [0][0][5][38] = 76, ++ [0][0][6][38] = 28, ++ [0][0][9][38] = 76, ++ [0][0][8][38] = 54, ++ [0][0][11][38] = 28, ++ [0][0][2][40] = 76, ++ [0][0][1][40] = 28, ++ [0][0][3][40] = 127, ++ [0][0][5][40] = 76, ++ [0][0][6][40] = 28, ++ [0][0][9][40] = 76, ++ [0][0][8][40] = 54, ++ [0][0][11][40] = 28, ++ [0][0][2][42] = 76, ++ [0][0][1][42] = 28, ++ [0][0][3][42] = 127, ++ [0][0][5][42] = 76, ++ [0][0][6][42] = 28, ++ [0][0][9][42] = 76, ++ [0][0][8][42] = 54, ++ [0][0][11][42] = 28, ++ [0][0][2][44] = 76, ++ [0][0][1][44] = 28, ++ [0][0][3][44] = 127, ++ [0][0][5][44] = 76, ++ [0][0][6][44] = 28, ++ [0][0][9][44] = 76, ++ [0][0][8][44] = 54, ++ [0][0][11][44] = 28, ++ [0][0][2][46] = 76, ++ [0][0][1][46] = 28, ++ [0][0][3][46] = 127, ++ [0][0][5][46] = 76, ++ [0][0][6][46] = 28, ++ [0][0][9][46] = 76, ++ [0][0][8][46] = 54, ++ [0][0][11][46] = 28, ++ [0][1][2][0] = 36, ++ [0][1][1][0] = 12, ++ [0][1][3][0] = 14, ++ [0][1][5][0] = 8, ++ [0][1][6][0] = 12, ++ [0][1][9][0] = 12, ++ [0][1][8][0] = 18, ++ [0][1][11][0] = 12, ++ [0][1][2][2] = 36, ++ [0][1][1][2] = 12, ++ [0][1][3][2] = 14, ++ [0][1][5][2] = 8, ++ [0][1][6][2] = 12, ++ [0][1][9][2] = 12, ++ [0][1][8][2] = 18, ++ [0][1][11][2] = 12, ++ [0][1][2][4] = 36, ++ [0][1][1][4] = 12, ++ [0][1][3][4] = 14, ++ [0][1][5][4] = 8, ++ [0][1][6][4] = 12, ++ [0][1][9][4] = 12, ++ [0][1][8][4] = 18, ++ [0][1][11][4] = 12, ++ [0][1][2][6] = 36, ++ [0][1][1][6] = 12, ++ [0][1][3][6] = 14, ++ [0][1][5][6] = 8, ++ [0][1][6][6] = 12, ++ [0][1][9][6] = 12, ++ [0][1][8][6] = 18, ++ [0][1][11][6] = 12, ++ [0][1][2][8] = 36, ++ [0][1][1][8] = 12, ++ [0][1][3][8] = 14, ++ [0][1][5][8] = 36, ++ [0][1][6][8] = 12, ++ [0][1][9][8] = 12, ++ [0][1][8][8] = 42, ++ [0][1][11][8] = 12, ++ [0][1][2][10] = 36, ++ [0][1][1][10] = 12, ++ [0][1][3][10] = 14, ++ [0][1][5][10] = 36, ++ [0][1][6][10] = 12, ++ [0][1][9][10] = 12, ++ [0][1][8][10] = 42, ++ [0][1][11][10] = 12, ++ [0][1][2][12] = 36, ++ [0][1][1][12] = 12, ++ [0][1][3][12] = 14, ++ [0][1][5][12] = 36, ++ [0][1][6][12] = 12, ++ [0][1][9][12] = 12, ++ [0][1][8][12] = 42, ++ [0][1][11][12] = 12, ++ [0][1][2][14] = 36, ++ [0][1][1][14] = 12, ++ [0][1][3][14] = 14, ++ [0][1][5][14] = 36, ++ [0][1][6][14] = 12, ++ [0][1][9][14] = 12, ++ [0][1][8][14] = 42, ++ [0][1][11][14] = 12, ++ [0][1][2][15] = 36, ++ [0][1][1][15] = 12, ++ [0][1][3][15] = 32, ++ [0][1][5][15] = 36, ++ [0][1][6][15] = 12, ++ [0][1][9][15] = 12, ++ [0][1][8][15] = 42, ++ [0][1][11][15] = 12, ++ [0][1][2][17] = 36, ++ [0][1][1][17] = 12, ++ [0][1][3][17] = 32, ++ [0][1][5][17] = 36, ++ [0][1][6][17] = 12, ++ [0][1][9][17] = 12, ++ [0][1][8][17] = 42, ++ [0][1][11][17] = 12, ++ [0][1][2][19] = 36, ++ [0][1][1][19] = 12, ++ [0][1][3][19] = 32, ++ [0][1][5][19] = 36, ++ [0][1][6][19] = 12, ++ [0][1][9][19] = 12, ++ [0][1][8][19] = 42, ++ [0][1][11][19] = 12, ++ [0][1][2][21] = 36, ++ [0][1][1][21] = 12, ++ [0][1][3][21] = 32, ++ [0][1][5][21] = 36, ++ [0][1][6][21] = 12, ++ [0][1][9][21] = 12, ++ [0][1][8][21] = 42, ++ [0][1][11][21] = 12, ++ [0][1][2][23] = 36, ++ [0][1][1][23] = 12, ++ [0][1][3][23] = 32, ++ [0][1][5][23] = 36, ++ [0][1][6][23] = 12, ++ [0][1][9][23] = 12, ++ [0][1][8][23] = 42, ++ [0][1][11][23] = 12, ++ [0][1][2][25] = 36, ++ [0][1][1][25] = 12, ++ [0][1][3][25] = 32, ++ [0][1][5][25] = 127, ++ [0][1][6][25] = 12, ++ [0][1][9][25] = 127, ++ [0][1][8][25] = 42, ++ [0][1][11][25] = 12, ++ [0][1][2][27] = 36, ++ [0][1][1][27] = 12, ++ [0][1][3][27] = 32, ++ [0][1][5][27] = 127, ++ [0][1][6][27] = 12, ++ [0][1][9][27] = 127, ++ [0][1][8][27] = 42, ++ [0][1][11][27] = 12, ++ [0][1][2][29] = 36, ++ [0][1][1][29] = 12, ++ [0][1][3][29] = 32, ++ [0][1][5][29] = 127, ++ [0][1][6][29] = 12, ++ [0][1][9][29] = 127, ++ [0][1][8][29] = 42, ++ [0][1][11][29] = 12, ++ [0][1][2][31] = 36, ++ [0][1][1][31] = 12, ++ [0][1][3][31] = 32, ++ [0][1][5][31] = 36, ++ [0][1][6][31] = 12, ++ [0][1][9][31] = 12, ++ [0][1][8][31] = 42, ++ [0][1][11][31] = 12, ++ [0][1][2][33] = 36, ++ [0][1][1][33] = 12, ++ [0][1][3][33] = 32, ++ [0][1][5][33] = 36, ++ [0][1][6][33] = 12, ++ [0][1][9][33] = 12, ++ [0][1][8][33] = 42, ++ [0][1][11][33] = 12, ++ [0][1][2][35] = 36, ++ [0][1][1][35] = 12, ++ [0][1][3][35] = 32, ++ [0][1][5][35] = 36, ++ [0][1][6][35] = 12, ++ [0][1][9][35] = 12, ++ [0][1][8][35] = 42, ++ [0][1][11][35] = 12, ++ [0][1][2][37] = 36, ++ [0][1][1][37] = 127, ++ [0][1][3][37] = 32, ++ [0][1][5][37] = 36, ++ [0][1][6][37] = 12, ++ [0][1][9][37] = 36, ++ [0][1][8][37] = 42, ++ [0][1][11][37] = 127, ++ [0][1][2][38] = 72, ++ [0][1][1][38] = 16, ++ [0][1][3][38] = 127, ++ [0][1][5][38] = 72, ++ [0][1][6][38] = 16, ++ [0][1][9][38] = 76, ++ [0][1][8][38] = 42, ++ [0][1][11][38] = 16, ++ [0][1][2][40] = 76, ++ [0][1][1][40] = 16, ++ [0][1][3][40] = 127, ++ [0][1][5][40] = 76, ++ [0][1][6][40] = 16, ++ [0][1][9][40] = 76, ++ [0][1][8][40] = 42, ++ [0][1][11][40] = 16, ++ [0][1][2][42] = 76, ++ [0][1][1][42] = 16, ++ [0][1][3][42] = 127, ++ [0][1][5][42] = 76, ++ [0][1][6][42] = 16, ++ [0][1][9][42] = 76, ++ [0][1][8][42] = 42, ++ [0][1][11][42] = 16, ++ [0][1][2][44] = 76, ++ [0][1][1][44] = 16, ++ [0][1][3][44] = 127, ++ [0][1][5][44] = 76, ++ [0][1][6][44] = 16, ++ [0][1][9][44] = 76, ++ [0][1][8][44] = 42, ++ [0][1][11][44] = 16, ++ [0][1][2][46] = 76, ++ [0][1][1][46] = 16, ++ [0][1][3][46] = 127, ++ [0][1][5][46] = 76, ++ [0][1][6][46] = 16, ++ [0][1][9][46] = 76, ++ [0][1][8][46] = 42, ++ [0][1][11][46] = 16, ++ [1][0][2][0] = 62, ++ [1][0][1][0] = 36, ++ [1][0][3][0] = 36, ++ [1][0][5][0] = 34, ++ [1][0][6][0] = 36, ++ [1][0][9][0] = 36, ++ [1][0][8][0] = 30, ++ [1][0][11][0] = 36, ++ [1][0][2][2] = 62, ++ [1][0][1][2] = 36, ++ [1][0][3][2] = 36, ++ [1][0][5][2] = 34, ++ [1][0][6][2] = 36, ++ [1][0][9][2] = 36, ++ [1][0][8][2] = 30, ++ [1][0][11][2] = 36, ++ [1][0][2][4] = 62, ++ [1][0][1][4] = 36, ++ [1][0][3][4] = 36, ++ [1][0][5][4] = 34, ++ [1][0][6][4] = 36, ++ [1][0][9][4] = 36, ++ [1][0][8][4] = 30, ++ [1][0][11][4] = 36, ++ [1][0][2][6] = 62, ++ [1][0][1][6] = 36, ++ [1][0][3][6] = 36, ++ [1][0][5][6] = 34, ++ [1][0][6][6] = 36, ++ [1][0][9][6] = 36, ++ [1][0][8][6] = 30, ++ [1][0][11][6] = 36, ++ [1][0][2][8] = 62, ++ [1][0][1][8] = 36, ++ [1][0][3][8] = 36, ++ [1][0][5][8] = 62, ++ [1][0][6][8] = 36, ++ [1][0][9][8] = 36, ++ [1][0][8][8] = 54, ++ [1][0][11][8] = 36, ++ [1][0][2][10] = 62, ++ [1][0][1][10] = 36, ++ [1][0][3][10] = 36, ++ [1][0][5][10] = 62, ++ [1][0][6][10] = 36, ++ [1][0][9][10] = 36, ++ [1][0][8][10] = 54, ++ [1][0][11][10] = 36, ++ [1][0][2][12] = 62, ++ [1][0][1][12] = 36, ++ [1][0][3][12] = 36, ++ [1][0][5][12] = 62, ++ [1][0][6][12] = 36, ++ [1][0][9][12] = 36, ++ [1][0][8][12] = 54, ++ [1][0][11][12] = 36, ++ [1][0][2][14] = 62, ++ [1][0][1][14] = 36, ++ [1][0][3][14] = 36, ++ [1][0][5][14] = 62, ++ [1][0][6][14] = 36, ++ [1][0][9][14] = 36, ++ [1][0][8][14] = 54, ++ [1][0][11][14] = 36, ++ [1][0][2][15] = 62, ++ [1][0][1][15] = 36, ++ [1][0][3][15] = 58, ++ [1][0][5][15] = 62, ++ [1][0][6][15] = 36, ++ [1][0][9][15] = 36, ++ [1][0][8][15] = 54, ++ [1][0][11][15] = 36, ++ [1][0][2][17] = 62, ++ [1][0][1][17] = 36, ++ [1][0][3][17] = 58, ++ [1][0][5][17] = 62, ++ [1][0][6][17] = 36, ++ [1][0][9][17] = 36, ++ [1][0][8][17] = 54, ++ [1][0][11][17] = 36, ++ [1][0][2][19] = 62, ++ [1][0][1][19] = 36, ++ [1][0][3][19] = 58, ++ [1][0][5][19] = 62, ++ [1][0][6][19] = 36, ++ [1][0][9][19] = 36, ++ [1][0][8][19] = 54, ++ [1][0][11][19] = 36, ++ [1][0][2][21] = 62, ++ [1][0][1][21] = 36, ++ [1][0][3][21] = 58, ++ [1][0][5][21] = 62, ++ [1][0][6][21] = 36, ++ [1][0][9][21] = 36, ++ [1][0][8][21] = 54, ++ [1][0][11][21] = 36, ++ [1][0][2][23] = 62, ++ [1][0][1][23] = 36, ++ [1][0][3][23] = 58, ++ [1][0][5][23] = 62, ++ [1][0][6][23] = 36, ++ [1][0][9][23] = 36, ++ [1][0][8][23] = 54, ++ [1][0][11][23] = 36, ++ [1][0][2][25] = 62, ++ [1][0][1][25] = 36, ++ [1][0][3][25] = 58, ++ [1][0][5][25] = 127, ++ [1][0][6][25] = 36, ++ [1][0][9][25] = 127, ++ [1][0][8][25] = 54, ++ [1][0][11][25] = 36, ++ [1][0][2][27] = 62, ++ [1][0][1][27] = 36, ++ [1][0][3][27] = 58, ++ [1][0][5][27] = 127, ++ [1][0][6][27] = 36, ++ [1][0][9][27] = 127, ++ [1][0][8][27] = 54, ++ [1][0][11][27] = 36, ++ [1][0][2][29] = 62, ++ [1][0][1][29] = 36, ++ [1][0][3][29] = 58, ++ [1][0][5][29] = 127, ++ [1][0][6][29] = 36, ++ [1][0][9][29] = 127, ++ [1][0][8][29] = 54, ++ [1][0][11][29] = 36, ++ [1][0][2][31] = 62, ++ [1][0][1][31] = 36, ++ [1][0][3][31] = 58, ++ [1][0][5][31] = 62, ++ [1][0][6][31] = 36, ++ [1][0][9][31] = 36, ++ [1][0][8][31] = 54, ++ [1][0][11][31] = 36, ++ [1][0][2][33] = 62, ++ [1][0][1][33] = 36, ++ [1][0][3][33] = 58, ++ [1][0][5][33] = 62, ++ [1][0][6][33] = 36, ++ [1][0][9][33] = 36, ++ [1][0][8][33] = 54, ++ [1][0][11][33] = 36, ++ [1][0][2][35] = 62, ++ [1][0][1][35] = 36, ++ [1][0][3][35] = 58, ++ [1][0][5][35] = 62, ++ [1][0][6][35] = 36, ++ [1][0][9][35] = 36, ++ [1][0][8][35] = 54, ++ [1][0][11][35] = 36, ++ [1][0][2][37] = 56, ++ [1][0][1][37] = 62, ++ [1][0][3][37] = 127, ++ [1][0][5][37] = 58, ++ [1][0][6][37] = 62, ++ [1][0][9][37] = 36, ++ [1][0][8][37] = 62, ++ [1][0][11][37] = 54, ++ [1][0][2][38] = 76, ++ [1][0][1][38] = 28, ++ [1][0][3][38] = 127, ++ [1][0][5][38] = 76, ++ [1][0][6][38] = 28, ++ [1][0][9][38] = 76, ++ [1][0][8][38] = 54, ++ [1][0][11][38] = 28, ++ [1][0][2][40] = 76, ++ [1][0][1][40] = 28, ++ [1][0][3][40] = 127, ++ [1][0][5][40] = 76, ++ [1][0][6][40] = 28, ++ [1][0][9][40] = 76, ++ [1][0][8][40] = 54, ++ [1][0][11][40] = 28, ++ [1][0][2][42] = 76, ++ [1][0][1][42] = 28, ++ [1][0][3][42] = 127, ++ [1][0][5][42] = 76, ++ [1][0][6][42] = 28, ++ [1][0][9][42] = 76, ++ [1][0][8][42] = 54, ++ [1][0][11][42] = 28, ++ [1][0][2][44] = 76, ++ [1][0][1][44] = 28, ++ [1][0][3][44] = 127, ++ [1][0][5][44] = 76, ++ [1][0][6][44] = 28, ++ [1][0][9][44] = 76, ++ [1][0][8][44] = 54, ++ [1][0][11][44] = 28, ++ [1][0][2][46] = 76, ++ [1][0][1][46] = 28, ++ [1][0][3][46] = 127, ++ [1][0][5][46] = 76, ++ [1][0][6][46] = 28, ++ [1][0][9][46] = 76, ++ [1][0][8][46] = 54, ++ [1][0][11][46] = 28, ++ [1][1][2][0] = 46, ++ [1][1][1][0] = 22, ++ [1][1][3][0] = 24, ++ [1][1][5][0] = 18, ++ [1][1][6][0] = 22, ++ [1][1][9][0] = 22, ++ [1][1][8][0] = 18, ++ [1][1][11][0] = 22, ++ [1][1][2][2] = 46, ++ [1][1][1][2] = 22, ++ [1][1][3][2] = 24, ++ [1][1][5][2] = 18, ++ [1][1][6][2] = 22, ++ [1][1][9][2] = 22, ++ [1][1][8][2] = 18, ++ [1][1][11][2] = 22, ++ [1][1][2][4] = 46, ++ [1][1][1][4] = 22, ++ [1][1][3][4] = 24, ++ [1][1][5][4] = 18, ++ [1][1][6][4] = 22, ++ [1][1][9][4] = 22, ++ [1][1][8][4] = 18, ++ [1][1][11][4] = 22, ++ [1][1][2][6] = 46, ++ [1][1][1][6] = 22, ++ [1][1][3][6] = 24, ++ [1][1][5][6] = 18, ++ [1][1][6][6] = 22, ++ [1][1][9][6] = 22, ++ [1][1][8][6] = 18, ++ [1][1][11][6] = 22, ++ [1][1][2][8] = 46, ++ [1][1][1][8] = 22, ++ [1][1][3][8] = 24, ++ [1][1][5][8] = 46, ++ [1][1][6][8] = 22, ++ [1][1][9][8] = 22, ++ [1][1][8][8] = 42, ++ [1][1][11][8] = 22, ++ [1][1][2][10] = 46, ++ [1][1][1][10] = 22, ++ [1][1][3][10] = 24, ++ [1][1][5][10] = 46, ++ [1][1][6][10] = 22, ++ [1][1][9][10] = 22, ++ [1][1][8][10] = 42, ++ [1][1][11][10] = 22, ++ [1][1][2][12] = 46, ++ [1][1][1][12] = 22, ++ [1][1][3][12] = 24, ++ [1][1][5][12] = 46, ++ [1][1][6][12] = 22, ++ [1][1][9][12] = 22, ++ [1][1][8][12] = 42, ++ [1][1][11][12] = 22, ++ [1][1][2][14] = 46, ++ [1][1][1][14] = 22, ++ [1][1][3][14] = 24, ++ [1][1][5][14] = 46, ++ [1][1][6][14] = 22, ++ [1][1][9][14] = 22, ++ [1][1][8][14] = 42, ++ [1][1][11][14] = 22, ++ [1][1][2][15] = 46, ++ [1][1][1][15] = 22, ++ [1][1][3][15] = 46, ++ [1][1][5][15] = 46, ++ [1][1][6][15] = 22, ++ [1][1][9][15] = 22, ++ [1][1][8][15] = 42, ++ [1][1][11][15] = 22, ++ [1][1][2][17] = 46, ++ [1][1][1][17] = 22, ++ [1][1][3][17] = 46, ++ [1][1][5][17] = 46, ++ [1][1][6][17] = 22, ++ [1][1][9][17] = 22, ++ [1][1][8][17] = 42, ++ [1][1][11][17] = 22, ++ [1][1][2][19] = 46, ++ [1][1][1][19] = 22, ++ [1][1][3][19] = 46, ++ [1][1][5][19] = 46, ++ [1][1][6][19] = 22, ++ [1][1][9][19] = 22, ++ [1][1][8][19] = 42, ++ [1][1][11][19] = 22, ++ [1][1][2][21] = 46, ++ [1][1][1][21] = 22, ++ [1][1][3][21] = 46, ++ [1][1][5][21] = 46, ++ [1][1][6][21] = 22, ++ [1][1][9][21] = 22, ++ [1][1][8][21] = 42, ++ [1][1][11][21] = 22, ++ [1][1][2][23] = 46, ++ [1][1][1][23] = 22, ++ [1][1][3][23] = 46, ++ [1][1][5][23] = 46, ++ [1][1][6][23] = 22, ++ [1][1][9][23] = 22, ++ [1][1][8][23] = 42, ++ [1][1][11][23] = 22, ++ [1][1][2][25] = 46, ++ [1][1][1][25] = 22, ++ [1][1][3][25] = 46, ++ [1][1][5][25] = 127, ++ [1][1][6][25] = 22, ++ [1][1][9][25] = 127, ++ [1][1][8][25] = 42, ++ [1][1][11][25] = 22, ++ [1][1][2][27] = 46, ++ [1][1][1][27] = 22, ++ [1][1][3][27] = 46, ++ [1][1][5][27] = 127, ++ [1][1][6][27] = 22, ++ [1][1][9][27] = 127, ++ [1][1][8][27] = 42, ++ [1][1][11][27] = 22, ++ [1][1][2][29] = 46, ++ [1][1][1][29] = 22, ++ [1][1][3][29] = 46, ++ [1][1][5][29] = 127, ++ [1][1][6][29] = 22, ++ [1][1][9][29] = 127, ++ [1][1][8][29] = 42, ++ [1][1][11][29] = 22, ++ [1][1][2][31] = 46, ++ [1][1][1][31] = 22, ++ [1][1][3][31] = 46, ++ [1][1][5][31] = 46, ++ [1][1][6][31] = 22, ++ [1][1][9][31] = 22, ++ [1][1][8][31] = 42, ++ [1][1][11][31] = 22, ++ [1][1][2][33] = 46, ++ [1][1][1][33] = 22, ++ [1][1][3][33] = 46, ++ [1][1][5][33] = 46, ++ [1][1][6][33] = 22, ++ [1][1][9][33] = 22, ++ [1][1][8][33] = 42, ++ [1][1][11][33] = 22, ++ [1][1][2][35] = 46, ++ [1][1][1][35] = 22, ++ [1][1][3][35] = 46, ++ [1][1][5][35] = 46, ++ [1][1][6][35] = 22, ++ [1][1][9][35] = 22, ++ [1][1][8][35] = 42, ++ [1][1][11][35] = 22, ++ [1][1][2][37] = 46, ++ [1][1][1][37] = 127, ++ [1][1][3][37] = 46, ++ [1][1][5][37] = 46, ++ [1][1][6][37] = 22, ++ [1][1][9][37] = 50, ++ [1][1][8][37] = 42, ++ [1][1][11][37] = 127, ++ [1][1][2][38] = 74, ++ [1][1][1][38] = 16, ++ [1][1][3][38] = 127, ++ [1][1][5][38] = 74, ++ [1][1][6][38] = 16, ++ [1][1][9][38] = 76, ++ [1][1][8][38] = 42, ++ [1][1][11][38] = 16, ++ [1][1][2][40] = 76, ++ [1][1][1][40] = 16, ++ [1][1][3][40] = 127, ++ [1][1][5][40] = 76, ++ [1][1][6][40] = 16, ++ [1][1][9][40] = 76, ++ [1][1][8][40] = 42, ++ [1][1][11][40] = 16, ++ [1][1][2][42] = 76, ++ [1][1][1][42] = 16, ++ [1][1][3][42] = 127, ++ [1][1][5][42] = 76, ++ [1][1][6][42] = 16, ++ [1][1][9][42] = 76, ++ [1][1][8][42] = 42, ++ [1][1][11][42] = 16, ++ [1][1][2][44] = 76, ++ [1][1][1][44] = 16, ++ [1][1][3][44] = 127, ++ [1][1][5][44] = 76, ++ [1][1][6][44] = 16, ++ [1][1][9][44] = 76, ++ [1][1][8][44] = 42, ++ [1][1][11][44] = 16, ++ [1][1][2][46] = 76, ++ [1][1][1][46] = 16, ++ [1][1][3][46] = 127, ++ [1][1][5][46] = 76, ++ [1][1][6][46] = 16, ++ [1][1][9][46] = 76, ++ [1][1][8][46] = 42, ++ [1][1][11][46] = 16, ++ [2][0][2][0] = 74, ++ [2][0][1][0] = 46, ++ [2][0][3][0] = 50, ++ [2][0][5][0] = 46, ++ [2][0][6][0] = 46, ++ [2][0][9][0] = 46, ++ [2][0][8][0] = 30, ++ [2][0][11][0] = 46, ++ [2][0][2][2] = 74, ++ [2][0][1][2] = 46, ++ [2][0][3][2] = 50, ++ [2][0][5][2] = 46, ++ [2][0][6][2] = 46, ++ [2][0][9][2] = 46, ++ [2][0][8][2] = 30, ++ [2][0][11][2] = 46, ++ [2][0][2][4] = 74, ++ [2][0][1][4] = 46, ++ [2][0][3][4] = 50, ++ [2][0][5][4] = 46, ++ [2][0][6][4] = 46, ++ [2][0][9][4] = 46, ++ [2][0][8][4] = 30, ++ [2][0][11][4] = 46, ++ [2][0][2][6] = 74, ++ [2][0][1][6] = 46, ++ [2][0][3][6] = 50, ++ [2][0][5][6] = 46, ++ [2][0][6][6] = 46, ++ [2][0][9][6] = 46, ++ [2][0][8][6] = 30, ++ [2][0][11][6] = 46, ++ [2][0][2][8] = 74, ++ [2][0][1][8] = 46, ++ [2][0][3][8] = 50, ++ [2][0][5][8] = 66, ++ [2][0][6][8] = 46, ++ [2][0][9][8] = 46, ++ [2][0][8][8] = 54, ++ [2][0][11][8] = 46, ++ [2][0][2][10] = 74, ++ [2][0][1][10] = 46, ++ [2][0][3][10] = 50, ++ [2][0][5][10] = 66, ++ [2][0][6][10] = 46, ++ [2][0][9][10] = 46, ++ [2][0][8][10] = 54, ++ [2][0][11][10] = 46, ++ [2][0][2][12] = 74, ++ [2][0][1][12] = 46, ++ [2][0][3][12] = 50, ++ [2][0][5][12] = 66, ++ [2][0][6][12] = 46, ++ [2][0][9][12] = 46, ++ [2][0][8][12] = 54, ++ [2][0][11][12] = 46, ++ [2][0][2][14] = 74, ++ [2][0][1][14] = 46, ++ [2][0][3][14] = 50, ++ [2][0][5][14] = 66, ++ [2][0][6][14] = 46, ++ [2][0][9][14] = 46, ++ [2][0][8][14] = 54, ++ [2][0][11][14] = 46, ++ [2][0][2][15] = 74, ++ [2][0][1][15] = 46, ++ [2][0][3][15] = 70, ++ [2][0][5][15] = 74, ++ [2][0][6][15] = 46, ++ [2][0][9][15] = 46, ++ [2][0][8][15] = 54, ++ [2][0][11][15] = 46, ++ [2][0][2][17] = 74, ++ [2][0][1][17] = 46, ++ [2][0][3][17] = 70, ++ [2][0][5][17] = 74, ++ [2][0][6][17] = 46, ++ [2][0][9][17] = 46, ++ [2][0][8][17] = 54, ++ [2][0][11][17] = 46, ++ [2][0][2][19] = 74, ++ [2][0][1][19] = 46, ++ [2][0][3][19] = 70, ++ [2][0][5][19] = 74, ++ [2][0][6][19] = 46, ++ [2][0][9][19] = 46, ++ [2][0][8][19] = 54, ++ [2][0][11][19] = 46, ++ [2][0][2][21] = 74, ++ [2][0][1][21] = 46, ++ [2][0][3][21] = 70, ++ [2][0][5][21] = 74, ++ [2][0][6][21] = 46, ++ [2][0][9][21] = 46, ++ [2][0][8][21] = 54, ++ [2][0][11][21] = 46, ++ [2][0][2][23] = 74, ++ [2][0][1][23] = 46, ++ [2][0][3][23] = 70, ++ [2][0][5][23] = 74, ++ [2][0][6][23] = 46, ++ [2][0][9][23] = 46, ++ [2][0][8][23] = 54, ++ [2][0][11][23] = 46, ++ [2][0][2][25] = 74, ++ [2][0][1][25] = 46, ++ [2][0][3][25] = 70, ++ [2][0][5][25] = 127, ++ [2][0][6][25] = 46, ++ [2][0][9][25] = 127, ++ [2][0][8][25] = 54, ++ [2][0][11][25] = 46, ++ [2][0][2][27] = 74, ++ [2][0][1][27] = 46, ++ [2][0][3][27] = 70, ++ [2][0][5][27] = 127, ++ [2][0][6][27] = 46, ++ [2][0][9][27] = 127, ++ [2][0][8][27] = 54, ++ [2][0][11][27] = 46, ++ [2][0][2][29] = 74, ++ [2][0][1][29] = 46, ++ [2][0][3][29] = 70, ++ [2][0][5][29] = 127, ++ [2][0][6][29] = 46, ++ [2][0][9][29] = 127, ++ [2][0][8][29] = 54, ++ [2][0][11][29] = 46, ++ [2][0][2][31] = 74, ++ [2][0][1][31] = 46, ++ [2][0][3][31] = 70, ++ [2][0][5][31] = 74, ++ [2][0][6][31] = 46, ++ [2][0][9][31] = 46, ++ [2][0][8][31] = 54, ++ [2][0][11][31] = 46, ++ [2][0][2][33] = 74, ++ [2][0][1][33] = 46, ++ [2][0][3][33] = 70, ++ [2][0][5][33] = 74, ++ [2][0][6][33] = 46, ++ [2][0][9][33] = 46, ++ [2][0][8][33] = 54, ++ [2][0][11][33] = 46, ++ [2][0][2][35] = 74, ++ [2][0][1][35] = 46, ++ [2][0][3][35] = 70, ++ [2][0][5][35] = 74, ++ [2][0][6][35] = 46, ++ [2][0][9][35] = 46, ++ [2][0][8][35] = 54, ++ [2][0][11][35] = 46, ++ [2][0][2][37] = 74, ++ [2][0][1][37] = 127, ++ [2][0][3][37] = 70, ++ [2][0][5][37] = 74, ++ [2][0][6][37] = 46, ++ [2][0][9][37] = 74, ++ [2][0][8][37] = 54, ++ [2][0][11][37] = 127, ++ [2][0][2][38] = 76, ++ [2][0][1][38] = 28, ++ [2][0][3][38] = 127, ++ [2][0][5][38] = 76, ++ [2][0][6][38] = 28, ++ [2][0][9][38] = 76, ++ [2][0][8][38] = 54, ++ [2][0][11][38] = 28, ++ [2][0][2][40] = 76, ++ [2][0][1][40] = 28, ++ [2][0][3][40] = 127, ++ [2][0][5][40] = 76, ++ [2][0][6][40] = 28, ++ [2][0][9][40] = 76, ++ [2][0][8][40] = 54, ++ [2][0][11][40] = 28, ++ [2][0][2][42] = 76, ++ [2][0][1][42] = 28, ++ [2][0][3][42] = 127, ++ [2][0][5][42] = 76, ++ [2][0][6][42] = 28, ++ [2][0][9][42] = 76, ++ [2][0][8][42] = 54, ++ [2][0][11][42] = 28, ++ [2][0][2][44] = 76, ++ [2][0][1][44] = 28, ++ [2][0][3][44] = 127, ++ [2][0][5][44] = 76, ++ [2][0][6][44] = 28, ++ [2][0][9][44] = 76, ++ [2][0][8][44] = 54, ++ [2][0][11][44] = 28, ++ [2][0][2][46] = 76, ++ [2][0][1][46] = 28, ++ [2][0][3][46] = 127, ++ [2][0][5][46] = 76, ++ [2][0][6][46] = 28, ++ [2][0][9][46] = 76, ++ [2][0][8][46] = 54, ++ [2][0][11][46] = 28, ++ [2][1][2][0] = 58, ++ [2][1][1][0] = 32, ++ [2][1][3][0] = 38, ++ [2][1][5][0] = 30, ++ [2][1][6][0] = 32, ++ [2][1][9][0] = 32, ++ [2][1][8][0] = 18, ++ [2][1][11][0] = 32, ++ [2][1][2][2] = 58, ++ [2][1][1][2] = 32, ++ [2][1][3][2] = 38, ++ [2][1][5][2] = 30, ++ [2][1][6][2] = 32, ++ [2][1][9][2] = 32, ++ [2][1][8][2] = 18, ++ [2][1][11][2] = 32, ++ [2][1][2][4] = 58, ++ [2][1][1][4] = 32, ++ [2][1][3][4] = 38, ++ [2][1][5][4] = 30, ++ [2][1][6][4] = 32, ++ [2][1][9][4] = 32, ++ [2][1][8][4] = 18, ++ [2][1][11][4] = 32, ++ [2][1][2][6] = 58, ++ [2][1][1][6] = 32, ++ [2][1][3][6] = 38, ++ [2][1][5][6] = 30, ++ [2][1][6][6] = 32, ++ [2][1][9][6] = 32, ++ [2][1][8][6] = 18, ++ [2][1][11][6] = 32, ++ [2][1][2][8] = 58, ++ [2][1][1][8] = 32, ++ [2][1][3][8] = 38, ++ [2][1][5][8] = 52, ++ [2][1][6][8] = 32, ++ [2][1][9][8] = 32, ++ [2][1][8][8] = 42, ++ [2][1][11][8] = 32, ++ [2][1][2][10] = 58, ++ [2][1][1][10] = 32, ++ [2][1][3][10] = 38, ++ [2][1][5][10] = 52, ++ [2][1][6][10] = 32, ++ [2][1][9][10] = 32, ++ [2][1][8][10] = 42, ++ [2][1][11][10] = 32, ++ [2][1][2][12] = 58, ++ [2][1][1][12] = 32, ++ [2][1][3][12] = 38, ++ [2][1][5][12] = 52, ++ [2][1][6][12] = 32, ++ [2][1][9][12] = 32, ++ [2][1][8][12] = 42, ++ [2][1][11][12] = 32, ++ [2][1][2][14] = 58, ++ [2][1][1][14] = 32, ++ [2][1][3][14] = 38, ++ [2][1][5][14] = 52, ++ [2][1][6][14] = 32, ++ [2][1][9][14] = 32, ++ [2][1][8][14] = 42, ++ [2][1][11][14] = 32, ++ [2][1][2][15] = 58, ++ [2][1][1][15] = 32, ++ [2][1][3][15] = 58, ++ [2][1][5][15] = 58, ++ [2][1][6][15] = 32, ++ [2][1][9][15] = 32, ++ [2][1][8][15] = 42, ++ [2][1][11][15] = 32, ++ [2][1][2][17] = 58, ++ [2][1][1][17] = 32, ++ [2][1][3][17] = 58, ++ [2][1][5][17] = 58, ++ [2][1][6][17] = 32, ++ [2][1][9][17] = 32, ++ [2][1][8][17] = 42, ++ [2][1][11][17] = 32, ++ [2][1][2][19] = 58, ++ [2][1][1][19] = 32, ++ [2][1][3][19] = 58, ++ [2][1][5][19] = 58, ++ [2][1][6][19] = 32, ++ [2][1][9][19] = 32, ++ [2][1][8][19] = 42, ++ [2][1][11][19] = 32, ++ [2][1][2][21] = 58, ++ [2][1][1][21] = 32, ++ [2][1][3][21] = 58, ++ [2][1][5][21] = 58, ++ [2][1][6][21] = 32, ++ [2][1][9][21] = 32, ++ [2][1][8][21] = 42, ++ [2][1][11][21] = 32, ++ [2][1][2][23] = 58, ++ [2][1][1][23] = 32, ++ [2][1][3][23] = 58, ++ [2][1][5][23] = 58, ++ [2][1][6][23] = 32, ++ [2][1][9][23] = 32, ++ [2][1][8][23] = 42, ++ [2][1][11][23] = 32, ++ [2][1][2][25] = 58, ++ [2][1][1][25] = 32, ++ [2][1][3][25] = 58, ++ [2][1][5][25] = 127, ++ [2][1][6][25] = 32, ++ [2][1][9][25] = 127, ++ [2][1][8][25] = 42, ++ [2][1][11][25] = 32, ++ [2][1][2][27] = 58, ++ [2][1][1][27] = 32, ++ [2][1][3][27] = 58, ++ [2][1][5][27] = 127, ++ [2][1][6][27] = 32, ++ [2][1][9][27] = 127, ++ [2][1][8][27] = 42, ++ [2][1][11][27] = 32, ++ [2][1][2][29] = 58, ++ [2][1][1][29] = 32, ++ [2][1][3][29] = 58, ++ [2][1][5][29] = 127, ++ [2][1][6][29] = 32, ++ [2][1][9][29] = 127, ++ [2][1][8][29] = 42, ++ [2][1][11][29] = 32, ++ [2][1][2][31] = 58, ++ [2][1][1][31] = 32, ++ [2][1][3][31] = 58, ++ [2][1][5][31] = 58, ++ [2][1][6][31] = 32, ++ [2][1][9][31] = 32, ++ [2][1][8][31] = 42, ++ [2][1][11][31] = 32, ++ [2][1][2][33] = 58, ++ [2][1][1][33] = 32, ++ [2][1][3][33] = 58, ++ [2][1][5][33] = 58, ++ [2][1][6][33] = 32, ++ [2][1][9][33] = 32, ++ [2][1][8][33] = 42, ++ [2][1][11][33] = 32, ++ [2][1][2][35] = 58, ++ [2][1][1][35] = 32, ++ [2][1][3][35] = 58, ++ [2][1][5][35] = 58, ++ [2][1][6][35] = 32, ++ [2][1][9][35] = 32, ++ [2][1][8][35] = 42, ++ [2][1][11][35] = 32, ++ [2][1][2][37] = 58, ++ [2][1][1][37] = 127, ++ [2][1][3][37] = 58, ++ [2][1][5][37] = 58, ++ [2][1][6][37] = 32, ++ [2][1][9][37] = 62, ++ [2][1][8][37] = 42, ++ [2][1][11][37] = 127, ++ [2][1][2][38] = 76, ++ [2][1][1][38] = 16, ++ [2][1][3][38] = 127, ++ [2][1][5][38] = 76, ++ [2][1][6][38] = 16, ++ [2][1][9][38] = 76, ++ [2][1][8][38] = 42, ++ [2][1][11][38] = 16, ++ [2][1][2][40] = 76, ++ [2][1][1][40] = 16, ++ [2][1][3][40] = 127, ++ [2][1][5][40] = 76, ++ [2][1][6][40] = 16, ++ [2][1][9][40] = 76, ++ [2][1][8][40] = 42, ++ [2][1][11][40] = 16, ++ [2][1][2][42] = 76, ++ [2][1][1][42] = 16, ++ [2][1][3][42] = 127, ++ [2][1][5][42] = 76, ++ [2][1][6][42] = 16, ++ [2][1][9][42] = 76, ++ [2][1][8][42] = 42, ++ [2][1][11][42] = 16, ++ [2][1][2][44] = 76, ++ [2][1][1][44] = 16, ++ [2][1][3][44] = 127, ++ [2][1][5][44] = 76, ++ [2][1][6][44] = 16, ++ [2][1][9][44] = 76, ++ [2][1][8][44] = 42, ++ [2][1][11][44] = 16, ++ [2][1][2][46] = 76, ++ [2][1][1][46] = 16, ++ [2][1][3][46] = 127, ++ [2][1][5][46] = 76, ++ [2][1][6][46] = 16, ++ [2][1][9][46] = 76, ++ [2][1][8][46] = 42, ++ [2][1][11][46] = 16, ++}; ++ ++#define DECLARE_DIG_TABLE(name) \ ++static const struct rtw89_phy_dig_gain_cfg name##_table = { \ ++ .table = name, \ ++ .size = ARRAY_SIZE(name) \ ++} ++ ++static const struct rtw89_reg_def rtw89_8852a_lna_gain_g[] = { ++ {R_PATH0_LNA_ERR1, B_PATH0_LNA_ERR_G0_G_MSK}, ++ {R_PATH0_LNA_ERR2, B_PATH0_LNA_ERR_G1_G_MSK}, ++ {R_PATH0_LNA_ERR2, B_PATH0_LNA_ERR_G2_G_MSK}, ++ {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G3_G_MSK}, ++ {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G4_G_MSK}, ++ {R_PATH0_LNA_ERR4, B_PATH0_LNA_ERR_G5_G_MSK}, ++ {R_PATH0_LNA_ERR5, B_PATH0_LNA_ERR_G6_G_MSK}, ++}; ++ ++DECLARE_DIG_TABLE(rtw89_8852a_lna_gain_g); ++ ++static const struct rtw89_reg_def rtw89_8852a_tia_gain_g[] = { ++ {R_PATH0_TIA_ERR_G0, B_PATH0_TIA_ERR_G0_G_MSK}, ++ {R_PATH0_TIA_ERR_G1, B_PATH0_TIA_ERR_G1_G_MSK}, ++}; ++ ++DECLARE_DIG_TABLE(rtw89_8852a_tia_gain_g); ++ ++static const struct rtw89_reg_def rtw89_8852a_lna_gain_a[] = { ++ {R_PATH0_LNA_ERR1, B_PATH0_LNA_ERR_G0_A_MSK}, ++ {R_PATH0_LNA_ERR1, B_PATH0_LNA_ERR_G1_A_MSK}, ++ {R_PATH0_LNA_ERR2, B_PATH0_LNA_ERR_G2_A_MSK}, ++ {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G3_A_MSK}, ++ {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G4_A_MSK}, ++ {R_PATH0_LNA_ERR4, B_PATH0_LNA_ERR_G5_A_MSK}, ++ {R_PATH0_LNA_ERR4, B_PATH0_LNA_ERR_G6_A_MSK}, ++}; ++ ++DECLARE_DIG_TABLE(rtw89_8852a_lna_gain_a); ++ ++static const struct rtw89_reg_def rtw89_8852a_tia_gain_a[] = { ++ {R_PATH0_TIA_ERR_G0, B_PATH0_TIA_ERR_G0_A_MSK}, ++ {R_PATH0_TIA_ERR_G1, B_PATH0_TIA_ERR_G1_A_MSK}, ++}; ++ ++DECLARE_DIG_TABLE(rtw89_8852a_tia_gain_a); ++ ++const struct rtw89_phy_table rtw89_8852a_phy_bb_table = { ++ .regs = rtw89_8852a_phy_bb_regs, ++ .n_regs = ARRAY_SIZE(rtw89_8852a_phy_bb_regs), ++ .rf_path = 0, /* don't care */ ++}; ++ ++const struct rtw89_phy_table rtw89_8852a_phy_radioa_table = { ++ .regs = rtw89_8852a_phy_radioa_regs, ++ .n_regs = ARRAY_SIZE(rtw89_8852a_phy_radioa_regs), ++ .rf_path = RF_PATH_A, ++}; ++ ++const struct rtw89_phy_table rtw89_8852a_phy_radiob_table = { ++ .regs = rtw89_8852a_phy_radiob_regs, ++ .n_regs = ARRAY_SIZE(rtw89_8852a_phy_radiob_regs), ++ .rf_path = RF_PATH_B, ++}; ++ ++const struct rtw89_phy_table rtw89_8852a_phy_nctl_table = { ++ .regs = rtw89_8852a_phy_nctl_regs, ++ .n_regs = ARRAY_SIZE(rtw89_8852a_phy_nctl_regs), ++ .rf_path = 0, /* don't care */ ++}; ++ ++const struct rtw89_txpwr_table rtw89_8852a_byr_table = { ++ .data = rtw89_8852a_txpwr_byrate, ++ .size = ARRAY_SIZE(rtw89_8852a_txpwr_byrate), ++ .load = rtw89_phy_load_txpwr_byrate, ++}; ++ ++const struct rtw89_txpwr_track_cfg rtw89_8852a_trk_cfg = { ++ .delta_swingidx_5gb_n = _txpwr_track_delta_swingidx_5gb_n, ++ .delta_swingidx_5gb_p = _txpwr_track_delta_swingidx_5gb_p, ++ .delta_swingidx_5ga_n = _txpwr_track_delta_swingidx_5ga_n, ++ .delta_swingidx_5ga_p = _txpwr_track_delta_swingidx_5ga_p, ++ .delta_swingidx_2gb_n = _txpwr_track_delta_swingidx_2gb_n, ++ .delta_swingidx_2gb_p = _txpwr_track_delta_swingidx_2gb_p, ++ .delta_swingidx_2ga_n = _txpwr_track_delta_swingidx_2ga_n, ++ .delta_swingidx_2ga_p = _txpwr_track_delta_swingidx_2ga_p, ++ .delta_swingidx_2g_cck_b_n = _txpwr_track_delta_swingidx_2g_cck_b_n, ++ .delta_swingidx_2g_cck_b_p = _txpwr_track_delta_swingidx_2g_cck_b_p, ++ .delta_swingidx_2g_cck_a_n = _txpwr_track_delta_swingidx_2g_cck_a_n, ++ .delta_swingidx_2g_cck_a_p = _txpwr_track_delta_swingidx_2g_cck_a_p, ++}; ++ ++const struct rtw89_phy_dig_gain_table rtw89_8852a_phy_dig_table = { ++ .cfg_lna_g = &rtw89_8852a_lna_gain_g_table, ++ .cfg_tia_g = &rtw89_8852a_tia_gain_g_table, ++ .cfg_lna_a = &rtw89_8852a_lna_gain_a_table, ++ .cfg_tia_a = &rtw89_8852a_tia_gain_a_table ++}; +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.h +new file mode 100644 +index 000000000000..913796506286 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.h +@@ -0,0 +1,28 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_8852A_TABLE_H__ ++#define __RTW89_8852A_TABLE_H__ ++ ++#include "core.h" ++ ++extern const struct rtw89_phy_table rtw89_8852a_phy_bb_table; ++extern const struct rtw89_phy_table rtw89_8852a_phy_radioa_table; ++extern const struct rtw89_phy_table rtw89_8852a_phy_radiob_table; ++extern const struct rtw89_phy_table rtw89_8852a_phy_nctl_table; ++extern const struct rtw89_txpwr_table rtw89_8852a_byr_table; ++extern const struct rtw89_phy_dig_gain_table rtw89_8852a_phy_dig_table; ++extern const struct rtw89_txpwr_track_cfg rtw89_8852a_trk_cfg; ++extern const s8 rtw89_8852a_txpwr_lmt_2g[RTW89_2G_BW_NUM][RTW89_NTX_NUM] ++ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] ++ [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; ++extern const s8 rtw89_8852a_txpwr_lmt_5g[RTW89_5G_BW_NUM][RTW89_NTX_NUM] ++ [RTW89_RS_LMT_NUM][RTW89_BF_NUM] ++ [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; ++extern const s8 rtw89_8852a_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] ++ [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; ++extern const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] ++ [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/sar.c b/drivers/net/wireless/realtek/rtw89/sar.c +new file mode 100644 +index 000000000000..097c87899cea +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/sar.c +@@ -0,0 +1,190 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "debug.h" ++#include "sar.h" ++ ++static int rtw89_query_sar_config_common(struct rtw89_dev *rtwdev, s32 *cfg) ++{ ++ struct rtw89_sar_cfg_common *rtwsar = &rtwdev->sar.cfg_common; ++ enum rtw89_subband subband = rtwdev->hal.current_subband; ++ ++ if (!rtwsar->set[subband]) ++ return -ENODATA; ++ ++ *cfg = rtwsar->cfg[subband]; ++ return 0; ++} ++ ++static const ++struct rtw89_sar_handler rtw89_sar_handlers[RTW89_SAR_SOURCE_NR] = { ++ [RTW89_SAR_SOURCE_COMMON] = { ++ .descr_sar_source = "RTW89_SAR_SOURCE_COMMON", ++ .txpwr_factor_sar = 2, ++ .query_sar_config = rtw89_query_sar_config_common, ++ }, ++}; ++ ++#define rtw89_sar_set_src(_dev, _src, _cfg_name, _cfg_data) \ ++ do { \ ++ typeof(_src) _s = (_src); \ ++ typeof(_dev) _d = (_dev); \ ++ BUILD_BUG_ON(!rtw89_sar_handlers[_s].descr_sar_source); \ ++ BUILD_BUG_ON(!rtw89_sar_handlers[_s].query_sar_config); \ ++ lockdep_assert_held(&_d->mutex); \ ++ _d->sar._cfg_name = *(_cfg_data); \ ++ _d->sar.src = _s; \ ++ } while (0) ++ ++static s8 rtw89_txpwr_sar_to_mac(struct rtw89_dev *rtwdev, u8 fct, s32 cfg) ++{ ++ const u8 fct_mac = rtwdev->chip->txpwr_factor_mac; ++ s32 cfg_mac; ++ ++ cfg_mac = fct > fct_mac ? ++ cfg >> (fct - fct_mac) : cfg << (fct_mac - fct); ++ ++ return (s8)clamp_t(s32, cfg_mac, ++ RTW89_SAR_TXPWR_MAC_MIN, ++ RTW89_SAR_TXPWR_MAC_MAX); ++} ++ ++s8 rtw89_query_sar(struct rtw89_dev *rtwdev) ++{ ++ const enum rtw89_sar_sources src = rtwdev->sar.src; ++ /* its members are protected by rtw89_sar_set_src() */ ++ const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src]; ++ int ret; ++ s32 cfg; ++ u8 fct; ++ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ if (src == RTW89_SAR_SOURCE_NONE) ++ return RTW89_SAR_TXPWR_MAC_MAX; ++ ++ ret = sar_hdl->query_sar_config(rtwdev, &cfg); ++ if (ret) ++ return RTW89_SAR_TXPWR_MAC_MAX; ++ ++ fct = sar_hdl->txpwr_factor_sar; ++ ++ return rtw89_txpwr_sar_to_mac(rtwdev, fct, cfg); ++} ++ ++void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev) ++{ ++ const enum rtw89_sar_sources src = rtwdev->sar.src; ++ /* its members are protected by rtw89_sar_set_src() */ ++ const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src]; ++ const u8 fct_mac = rtwdev->chip->txpwr_factor_mac; ++ int ret; ++ s32 cfg; ++ u8 fct; ++ ++ lockdep_assert_held(&rtwdev->mutex); ++ ++ if (src == RTW89_SAR_SOURCE_NONE) { ++ seq_puts(m, "no SAR is applied\n"); ++ return; ++ } ++ ++ seq_printf(m, "source: %d (%s)\n", src, sar_hdl->descr_sar_source); ++ ++ ret = sar_hdl->query_sar_config(rtwdev, &cfg); ++ if (ret) { ++ seq_printf(m, "config: return code: %d\n", ret); ++ seq_printf(m, "assign: max setting: %d (unit: 1/%lu dBm)\n", ++ RTW89_SAR_TXPWR_MAC_MAX, BIT(fct_mac)); ++ return; ++ } ++ ++ fct = sar_hdl->txpwr_factor_sar; ++ ++ seq_printf(m, "config: %d (unit: 1/%lu dBm)\n", cfg, BIT(fct)); ++} ++ ++static int rtw89_apply_sar_common(struct rtw89_dev *rtwdev, ++ const struct rtw89_sar_cfg_common *sar) ++{ ++ enum rtw89_sar_sources src; ++ int ret = 0; ++ ++ mutex_lock(&rtwdev->mutex); ++ ++ src = rtwdev->sar.src; ++ if (src != RTW89_SAR_SOURCE_NONE && src != RTW89_SAR_SOURCE_COMMON) { ++ rtw89_warn(rtwdev, "SAR source: %d is in use", src); ++ ret = -EBUSY; ++ goto exit; ++ } ++ ++ rtw89_sar_set_src(rtwdev, RTW89_SAR_SOURCE_COMMON, cfg_common, sar); ++ rtw89_chip_set_txpwr(rtwdev); ++ ++exit: ++ mutex_unlock(&rtwdev->mutex); ++ return ret; ++} ++ ++static const u8 rtw89_common_sar_subband_map[] = { ++ RTW89_CH_2G, ++ RTW89_CH_5G_BAND_1, ++ RTW89_CH_5G_BAND_3, ++ RTW89_CH_5G_BAND_4, ++}; ++ ++static const struct cfg80211_sar_freq_ranges rtw89_common_sar_freq_ranges[] = { ++ { .start_freq = 2412, .end_freq = 2484, }, ++ { .start_freq = 5180, .end_freq = 5320, }, ++ { .start_freq = 5500, .end_freq = 5720, }, ++ { .start_freq = 5745, .end_freq = 5825, }, ++}; ++ ++static_assert(ARRAY_SIZE(rtw89_common_sar_subband_map) == ++ ARRAY_SIZE(rtw89_common_sar_freq_ranges)); ++ ++const struct cfg80211_sar_capa rtw89_sar_capa = { ++ .type = NL80211_SAR_TYPE_POWER, ++ .num_freq_ranges = ARRAY_SIZE(rtw89_common_sar_freq_ranges), ++ .freq_ranges = rtw89_common_sar_freq_ranges, ++}; ++ ++int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw, ++ const struct cfg80211_sar_specs *sar) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ struct rtw89_sar_cfg_common sar_common = {0}; ++ u8 fct; ++ u32 freq_start; ++ u32 freq_end; ++ u32 band; ++ s32 power; ++ u32 i, idx; ++ ++ if (sar->type != NL80211_SAR_TYPE_POWER) ++ return -EINVAL; ++ ++ fct = rtw89_sar_handlers[RTW89_SAR_SOURCE_COMMON].txpwr_factor_sar; ++ ++ for (i = 0; i < sar->num_sub_specs; i++) { ++ idx = sar->sub_specs[i].freq_range_index; ++ if (idx >= ARRAY_SIZE(rtw89_common_sar_freq_ranges)) ++ return -EINVAL; ++ ++ freq_start = rtw89_common_sar_freq_ranges[idx].start_freq; ++ freq_end = rtw89_common_sar_freq_ranges[idx].end_freq; ++ band = rtw89_common_sar_subband_map[idx]; ++ power = sar->sub_specs[i].power; ++ ++ rtw89_info(rtwdev, "On freq %u to %u, ", freq_start, freq_end); ++ rtw89_info(rtwdev, "set SAR power limit %d (unit: 1/%lu dBm)\n", ++ power, BIT(fct)); ++ ++ sar_common.set[band] = true; ++ sar_common.cfg[band] = power; ++ } ++ ++ return rtw89_apply_sar_common(rtwdev, &sar_common); ++} +diff --git a/drivers/net/wireless/realtek/rtw89/sar.h b/drivers/net/wireless/realtek/rtw89/sar.h +new file mode 100644 +index 000000000000..7b5484c84eb1 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/sar.h +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_SAR_H__ ++#define __RTW89_SAR_H__ ++ ++#include "core.h" ++ ++#define RTW89_SAR_TXPWR_MAC_MAX S8_MAX ++#define RTW89_SAR_TXPWR_MAC_MIN S8_MIN ++ ++struct rtw89_sar_handler { ++ const char *descr_sar_source; ++ u8 txpwr_factor_sar; ++ int (*query_sar_config)(struct rtw89_dev *rtwdev, s32 *cfg); ++}; ++ ++extern const struct cfg80211_sar_capa rtw89_sar_capa; ++ ++s8 rtw89_query_sar(struct rtw89_dev *rtwdev); ++void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev); ++int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw, ++ const struct cfg80211_sar_specs *sar); ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c +new file mode 100644 +index 000000000000..837cdc366a61 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/ser.c +@@ -0,0 +1,491 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#include "cam.h" ++#include "debug.h" ++#include "mac.h" ++#include "ps.h" ++#include "ser.h" ++#include "util.h" ++ ++#define SER_RECFG_TIMEOUT 1000 ++ ++enum ser_evt { ++ SER_EV_NONE, ++ SER_EV_STATE_IN, ++ SER_EV_STATE_OUT, ++ SER_EV_L1_RESET, /* M1 */ ++ SER_EV_DO_RECOVERY, /* M3 */ ++ SER_EV_MAC_RESET_DONE, /* M5 */ ++ SER_EV_L2_RESET, ++ SER_EV_L2_RECFG_DONE, ++ SER_EV_L2_RECFG_TIMEOUT, ++ SER_EV_M3_TIMEOUT, ++ SER_EV_FW_M5_TIMEOUT, ++ SER_EV_L0_RESET, ++ SER_EV_MAXX ++}; ++ ++enum ser_state { ++ SER_IDLE_ST, ++ SER_RESET_TRX_ST, ++ SER_DO_HCI_ST, ++ SER_L2_RESET_ST, ++ SER_ST_MAX_ST ++}; ++ ++struct ser_msg { ++ struct list_head list; ++ u8 event; ++}; ++ ++struct state_ent { ++ u8 state; ++ char *name; ++ void (*st_func)(struct rtw89_ser *ser, u8 event); ++}; ++ ++struct event_ent { ++ u8 event; ++ char *name; ++}; ++ ++static char *ser_ev_name(struct rtw89_ser *ser, u8 event) ++{ ++ if (event < SER_EV_MAXX) ++ return ser->ev_tbl[event].name; ++ ++ return "err_ev_name"; ++} ++ ++static char *ser_st_name(struct rtw89_ser *ser) ++{ ++ if (ser->state < SER_ST_MAX_ST) ++ return ser->st_tbl[ser->state].name; ++ ++ return "err_st_name"; ++} ++ ++static void ser_state_run(struct rtw89_ser *ser, u8 evt) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s receive %s\n", ++ ser_st_name(ser), ser_ev_name(ser, evt)); ++ ++ rtw89_leave_lps(rtwdev); ++ ser->st_tbl[ser->state].st_func(ser, evt); ++} ++ ++static void ser_state_goto(struct rtw89_ser *ser, u8 new_state) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ if (ser->state == new_state || new_state >= SER_ST_MAX_ST) ++ return; ++ ser_state_run(ser, SER_EV_STATE_OUT); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s goto -> %s\n", ++ ser_st_name(ser), ser->st_tbl[new_state].name); ++ ++ ser->state = new_state; ++ ser_state_run(ser, SER_EV_STATE_IN); ++} ++ ++static struct ser_msg *__rtw89_ser_dequeue_msg(struct rtw89_ser *ser) ++{ ++ struct ser_msg *msg; ++ ++ spin_lock_irq(&ser->msg_q_lock); ++ msg = list_first_entry_or_null(&ser->msg_q, struct ser_msg, list); ++ if (msg) ++ list_del(&msg->list); ++ spin_unlock_irq(&ser->msg_q_lock); ++ ++ return msg; ++} ++ ++static void rtw89_ser_hdl_work(struct work_struct *work) ++{ ++ struct ser_msg *msg; ++ struct rtw89_ser *ser = container_of(work, struct rtw89_ser, ++ ser_hdl_work); ++ ++ while ((msg = __rtw89_ser_dequeue_msg(ser))) { ++ ser_state_run(ser, msg->event); ++ kfree(msg); ++ } ++} ++ ++static int ser_send_msg(struct rtw89_ser *ser, u8 event) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ struct ser_msg *msg = NULL; ++ ++ if (test_bit(RTW89_SER_DRV_STOP_RUN, ser->flags)) ++ return -EIO; ++ ++ msg = kmalloc(sizeof(*msg), GFP_ATOMIC); ++ if (!msg) ++ return -ENOMEM; ++ ++ msg->event = event; ++ ++ spin_lock_irq(&ser->msg_q_lock); ++ list_add(&msg->list, &ser->msg_q); ++ spin_unlock_irq(&ser->msg_q_lock); ++ ++ ieee80211_queue_work(rtwdev->hw, &ser->ser_hdl_work); ++ return 0; ++} ++ ++static void rtw89_ser_alarm_work(struct work_struct *work) ++{ ++ struct rtw89_ser *ser = container_of(work, struct rtw89_ser, ++ ser_alarm_work.work); ++ ++ ser_send_msg(ser, ser->alarm_event); ++ ser->alarm_event = SER_EV_NONE; ++} ++ ++static void ser_set_alarm(struct rtw89_ser *ser, u32 ms, u8 event) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ if (test_bit(RTW89_SER_DRV_STOP_RUN, ser->flags)) ++ return; ++ ++ ser->alarm_event = event; ++ ieee80211_queue_delayed_work(rtwdev->hw, &ser->ser_alarm_work, ++ msecs_to_jiffies(ms)); ++} ++ ++static void ser_del_alarm(struct rtw89_ser *ser) ++{ ++ cancel_delayed_work(&ser->ser_alarm_work); ++ ser->alarm_event = SER_EV_NONE; ++} ++ ++/* driver function */ ++static void drv_stop_tx(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ ieee80211_stop_queues(rtwdev->hw); ++ set_bit(RTW89_SER_DRV_STOP_TX, ser->flags); ++} ++ ++static void drv_stop_rx(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ clear_bit(RTW89_FLAG_RUNNING, rtwdev->flags); ++ set_bit(RTW89_SER_DRV_STOP_RX, ser->flags); ++} ++ ++static void drv_trx_reset(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ rtw89_hci_reset(rtwdev); ++} ++ ++static void drv_resume_tx(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ if (!test_bit(RTW89_SER_DRV_STOP_TX, ser->flags)) ++ return; ++ ++ ieee80211_wake_queues(rtwdev->hw); ++ clear_bit(RTW89_SER_DRV_STOP_TX, ser->flags); ++} ++ ++static void drv_resume_rx(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ if (!test_bit(RTW89_SER_DRV_STOP_RX, ser->flags)) ++ return; ++ ++ set_bit(RTW89_FLAG_RUNNING, rtwdev->flags); ++ clear_bit(RTW89_SER_DRV_STOP_RX, ser->flags); ++} ++ ++static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port); ++ rtwvif->net_type = RTW89_NET_TYPE_NO_LINK; ++ rtwvif->trigger = false; ++} ++ ++static void ser_reset_mac_binding(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_vif *rtwvif; ++ ++ rtw89_cam_reset_keys(rtwdev); ++ rtw89_core_release_all_bits_map(rtwdev->mac_id_map, RTW89_MAX_MAC_ID_NUM); ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ ser_reset_vif(rtwdev, rtwvif); ++} ++ ++/* hal function */ ++static int hal_enable_dma(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ int ret; ++ ++ if (!test_bit(RTW89_SER_HAL_STOP_DMA, ser->flags)) ++ return 0; ++ ++ if (!rtwdev->hci.ops->mac_lv1_rcvy) ++ return -EIO; ++ ++ ret = rtwdev->hci.ops->mac_lv1_rcvy(rtwdev, RTW89_LV1_RCVY_STEP_2); ++ if (!ret) ++ clear_bit(RTW89_SER_HAL_STOP_DMA, ser->flags); ++ ++ return ret; ++} ++ ++static int hal_stop_dma(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ int ret; ++ ++ if (!rtwdev->hci.ops->mac_lv1_rcvy) ++ return -EIO; ++ ++ ret = rtwdev->hci.ops->mac_lv1_rcvy(rtwdev, RTW89_LV1_RCVY_STEP_1); ++ if (!ret) ++ set_bit(RTW89_SER_HAL_STOP_DMA, ser->flags); ++ ++ return ret; ++} ++ ++static void hal_send_m2_event(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_DISABLE_EN); ++} ++ ++static void hal_send_m4_event(struct rtw89_ser *ser) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_RCVY_EN); ++} ++ ++/* state handler */ ++static void ser_idle_st_hdl(struct rtw89_ser *ser, u8 evt) ++{ ++ switch (evt) { ++ case SER_EV_STATE_IN: ++ break; ++ case SER_EV_L1_RESET: ++ ser_state_goto(ser, SER_RESET_TRX_ST); ++ break; ++ case SER_EV_L2_RESET: ++ ser_state_goto(ser, SER_L2_RESET_ST); ++ break; ++ case SER_EV_STATE_OUT: ++ default: ++ break; ++ } ++} ++ ++static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt) ++{ ++ switch (evt) { ++ case SER_EV_STATE_IN: ++ drv_stop_tx(ser); ++ ++ if (hal_stop_dma(ser)) { ++ ser_state_goto(ser, SER_L2_RESET_ST); ++ break; ++ } ++ ++ drv_stop_rx(ser); ++ drv_trx_reset(ser); ++ ++ /* wait m3 */ ++ hal_send_m2_event(ser); ++ ++ /* set alarm to prevent FW response timeout */ ++ ser_set_alarm(ser, 1000, SER_EV_M3_TIMEOUT); ++ break; ++ ++ case SER_EV_DO_RECOVERY: ++ ser_state_goto(ser, SER_DO_HCI_ST); ++ break; ++ ++ case SER_EV_M3_TIMEOUT: ++ ser_state_goto(ser, SER_L2_RESET_ST); ++ break; ++ ++ case SER_EV_STATE_OUT: ++ ser_del_alarm(ser); ++ hal_enable_dma(ser); ++ drv_resume_rx(ser); ++ drv_resume_tx(ser); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++static void ser_do_hci_st_hdl(struct rtw89_ser *ser, u8 evt) ++{ ++ switch (evt) { ++ case SER_EV_STATE_IN: ++ /* wait m5 */ ++ hal_send_m4_event(ser); ++ ++ /* prevent FW response timeout */ ++ ser_set_alarm(ser, 1000, SER_EV_FW_M5_TIMEOUT); ++ break; ++ ++ case SER_EV_FW_M5_TIMEOUT: ++ ser_state_goto(ser, SER_L2_RESET_ST); ++ break; ++ ++ case SER_EV_MAC_RESET_DONE: ++ ser_state_goto(ser, SER_IDLE_ST); ++ break; ++ ++ case SER_EV_STATE_OUT: ++ ser_del_alarm(ser); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++static void ser_l2_reset_st_hdl(struct rtw89_ser *ser, u8 evt) ++{ ++ struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); ++ ++ switch (evt) { ++ case SER_EV_STATE_IN: ++ mutex_lock(&rtwdev->mutex); ++ ser_reset_mac_binding(rtwdev); ++ rtw89_core_stop(rtwdev); ++ mutex_unlock(&rtwdev->mutex); ++ ++ ieee80211_restart_hw(rtwdev->hw); ++ ser_set_alarm(ser, SER_RECFG_TIMEOUT, SER_EV_L2_RECFG_TIMEOUT); ++ break; ++ ++ case SER_EV_L2_RECFG_TIMEOUT: ++ rtw89_info(rtwdev, "Err: ser L2 re-config timeout\n"); ++ fallthrough; ++ case SER_EV_L2_RECFG_DONE: ++ ser_state_goto(ser, SER_IDLE_ST); ++ break; ++ ++ case SER_EV_STATE_OUT: ++ ser_del_alarm(ser); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++static struct event_ent ser_ev_tbl[] = { ++ {SER_EV_NONE, "SER_EV_NONE"}, ++ {SER_EV_STATE_IN, "SER_EV_STATE_IN"}, ++ {SER_EV_STATE_OUT, "SER_EV_STATE_OUT"}, ++ {SER_EV_L1_RESET, "SER_EV_L1_RESET"}, ++ {SER_EV_DO_RECOVERY, "SER_EV_DO_RECOVERY m3"}, ++ {SER_EV_MAC_RESET_DONE, "SER_EV_MAC_RESET_DONE m5"}, ++ {SER_EV_L2_RESET, "SER_EV_L2_RESET"}, ++ {SER_EV_L2_RECFG_DONE, "SER_EV_L2_RECFG_DONE"}, ++ {SER_EV_L2_RECFG_TIMEOUT, "SER_EV_L2_RECFG_TIMEOUT"}, ++ {SER_EV_M3_TIMEOUT, "SER_EV_M3_TIMEOUT"}, ++ {SER_EV_FW_M5_TIMEOUT, "SER_EV_FW_M5_TIMEOUT"}, ++ {SER_EV_L0_RESET, "SER_EV_L0_RESET"}, ++ {SER_EV_MAXX, "SER_EV_MAX"} ++}; ++ ++static struct state_ent ser_st_tbl[] = { ++ {SER_IDLE_ST, "SER_IDLE_ST", ser_idle_st_hdl}, ++ {SER_RESET_TRX_ST, "SER_RESET_TRX_ST", ser_reset_trx_st_hdl}, ++ {SER_DO_HCI_ST, "SER_DO_HCI_ST", ser_do_hci_st_hdl}, ++ {SER_L2_RESET_ST, "SER_L2_RESET_ST", ser_l2_reset_st_hdl} ++}; ++ ++int rtw89_ser_init(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_ser *ser = &rtwdev->ser; ++ ++ memset(ser, 0, sizeof(*ser)); ++ INIT_LIST_HEAD(&ser->msg_q); ++ ser->state = SER_IDLE_ST; ++ ser->st_tbl = ser_st_tbl; ++ ser->ev_tbl = ser_ev_tbl; ++ ++ bitmap_zero(ser->flags, RTW89_NUM_OF_SER_FLAGS); ++ spin_lock_init(&ser->msg_q_lock); ++ INIT_WORK(&ser->ser_hdl_work, rtw89_ser_hdl_work); ++ INIT_DELAYED_WORK(&ser->ser_alarm_work, rtw89_ser_alarm_work); ++ return 0; ++} ++ ++int rtw89_ser_deinit(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_ser *ser = (struct rtw89_ser *)&rtwdev->ser; ++ ++ set_bit(RTW89_SER_DRV_STOP_RUN, ser->flags); ++ cancel_delayed_work_sync(&ser->ser_alarm_work); ++ cancel_work_sync(&ser->ser_hdl_work); ++ clear_bit(RTW89_SER_DRV_STOP_RUN, ser->flags); ++ return 0; ++} ++ ++void rtw89_ser_recfg_done(struct rtw89_dev *rtwdev) ++{ ++ ser_send_msg(&rtwdev->ser, SER_EV_L2_RECFG_DONE); ++} ++ ++int rtw89_ser_notify(struct rtw89_dev *rtwdev, u32 err) ++{ ++ u8 event = SER_EV_NONE; ++ ++ rtw89_info(rtwdev, "ser event = 0x%04x\n", err); ++ ++ switch (err) { ++ case MAC_AX_ERR_L1_ERR_DMAC: ++ case MAC_AX_ERR_L0_PROMOTE_TO_L1: ++ event = SER_EV_L1_RESET; /* M1 */ ++ break; ++ case MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE: ++ event = SER_EV_DO_RECOVERY; /* M3 */ ++ break; ++ case MAC_AX_ERR_L1_RESET_RECOVERY_DONE: ++ event = SER_EV_MAC_RESET_DONE; /* M5 */ ++ break; ++ case MAC_AX_ERR_L0_ERR_CMAC0: ++ case MAC_AX_ERR_L0_ERR_CMAC1: ++ case MAC_AX_ERR_L0_RESET_DONE: ++ event = SER_EV_L0_RESET; ++ break; ++ default: ++ if (err == MAC_AX_ERR_L1_PROMOTE_TO_L2 || ++ (err >= MAC_AX_ERR_L2_ERR_AH_DMA && ++ err <= MAC_AX_GET_ERR_MAX)) ++ event = SER_EV_L2_RESET; ++ break; ++ } ++ ++ if (event == SER_EV_NONE) ++ return -EINVAL; ++ ++ ser_send_msg(&rtwdev->ser, event); ++ return 0; ++} ++EXPORT_SYMBOL(rtw89_ser_notify); +diff --git a/drivers/net/wireless/realtek/rtw89/ser.h b/drivers/net/wireless/realtek/rtw89/ser.h +new file mode 100644 +index 000000000000..6b8e62019942 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/ser.h +@@ -0,0 +1,15 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++ * Copyright(c) 2019-2020 Realtek Corporation ++ */ ++#ifndef __SER_H__ ++#define __SER_H__ ++ ++#include "core.h" ++ ++int rtw89_ser_init(struct rtw89_dev *rtwdev); ++int rtw89_ser_deinit(struct rtw89_dev *rtwdev); ++int rtw89_ser_notify(struct rtw89_dev *rtwdev, u32 err); ++void rtw89_ser_recfg_done(struct rtw89_dev *rtwdev); ++ ++#endif /* __SER_H__*/ ++ +diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h +new file mode 100644 +index 000000000000..f1e0fe36107d +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/txrx.h +@@ -0,0 +1,358 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2020 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_TXRX_H__ ++#define __RTW89_TXRX_H__ ++ ++#include "debug.h" ++ ++#define DATA_RATE_MODE_CTRL_MASK GENMASK(8, 7) ++#define DATA_RATE_NOT_HT_IDX_MASK GENMASK(3, 0) ++#define DATA_RATE_MODE_NON_HT 0x0 ++#define DATA_RATE_HT_IDX_MASK GENMASK(4, 0) ++#define DATA_RATE_MODE_HT 0x1 ++#define DATA_RATE_VHT_HE_NSS_MASK GENMASK(6, 4) ++#define DATA_RATE_VHT_HE_IDX_MASK GENMASK(3, 0) ++#define DATA_RATE_MODE_VHT 0x2 ++#define DATA_RATE_MODE_HE 0x3 ++#define GET_DATA_RATE_MODE(r) FIELD_GET(DATA_RATE_MODE_CTRL_MASK, r) ++#define GET_DATA_RATE_NOT_HT_IDX(r) FIELD_GET(DATA_RATE_NOT_HT_IDX_MASK, r) ++#define GET_DATA_RATE_HT_IDX(r) FIELD_GET(DATA_RATE_HT_IDX_MASK, r) ++#define GET_DATA_RATE_VHT_HE_IDX(r) FIELD_GET(DATA_RATE_VHT_HE_IDX_MASK, r) ++#define GET_DATA_RATE_NSS(r) FIELD_GET(DATA_RATE_VHT_HE_NSS_MASK, r) ++ ++/* TX WD BODY DWORD 0 */ ++#define RTW89_TXWD_BODY0_WP_OFFSET GENMASK(31, 24) ++#define RTW89_TXWD_BODY0_MORE_DATA BIT(23) ++#define RTW89_TXWD_BODY0_WD_INFO_EN BIT(22) ++#define RTW89_TXWD_BODY0_FW_DL BIT(20) ++#define RTW89_TXWD_BODY0_CHANNEL_DMA GENMASK(19, 16) ++#define RTW89_TXWD_BODY0_HDR_LLC_LEN GENMASK(15, 11) ++#define RTW89_TXWD_BODY0_WD_PAGE BIT(7) ++#define RTW89_TXWD_BODY0_HW_AMSDU BIT(5) ++ ++/* TX WD BODY DWORD 1 */ ++#define RTW89_TXWD_BODY1_PAYLOAD_ID GENMASK(31, 16) ++ ++/* TX WD BODY DWORD 2 */ ++#define RTW89_TXWD_BODY2_MACID GENMASK(30, 24) ++#define RTW89_TXWD_BODY2_TID_INDICATE BIT(23) ++#define RTW89_TXWD_BODY2_QSEL GENMASK(22, 17) ++#define RTW89_TXWD_BODY2_TXPKT_SIZE GENMASK(13, 0) ++ ++/* TX WD BODY DWORD 3 */ ++#define RTW89_TXWD_BODY3_BK BIT(13) ++#define RTW89_TXWD_BODY3_AGG_EN BIT(12) ++#define RTW89_TXWD_BODY3_SW_SEQ GENMASK(11, 0) ++ ++/* TX WD BODY DWORD 4 */ ++ ++/* TX WD BODY DWORD 5 */ ++ ++/* TX WD INFO DWORD 0 */ ++#define RTW89_TXWD_INFO0_USE_RATE BIT(30) ++#define RTW89_TXWD_INFO0_DATA_BW GENMASK(29, 28) ++#define RTW89_TXWD_INFO0_GI_LTF GENMASK(27, 25) ++#define RTW89_TXWD_INFO0_DATA_RATE GENMASK(24, 16) ++#define RTW89_TXWD_INFO0_DISDATAFB BIT(10) ++ ++/* TX WD INFO DWORD 1 */ ++#define RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE GENMASK(24, 16) ++#define RTW89_TXWD_INFO1_A_CTRL_BSR BIT(14) ++#define RTW89_TXWD_INFO1_MAX_AGGNUM GENMASK(7, 0) ++ ++/* TX WD INFO DWORD 2 */ ++#define RTW89_TXWD_INFO2_AMPDU_DENSITY GENMASK(20, 18) ++#define RTW89_TXWD_INFO2_SEC_TYPE GENMASK(12, 9) ++#define RTW89_TXWD_INFO2_SEC_HW_ENC BIT(8) ++#define RTW89_TXWD_INFO2_SEC_CAM_IDX GENMASK(7, 0) ++ ++/* TX WD INFO DWORD 3 */ ++ ++/* TX WD INFO DWORD 4 */ ++#define RTW89_TXWD_INFO4_RTS_EN BIT(27) ++#define RTW89_TXWD_INFO4_HW_RTS_EN BIT(31) ++ ++/* TX WD INFO DWORD 5 */ ++ ++/* RX DESC helpers */ ++/* Short Descriptor */ ++#define RTW89_GET_RXWD_LONG_RXD(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, BIT(31)) ++#define RTW89_GET_RXWD_DRV_INFO_SIZE(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, GENMASK(30, 28)) ++#define RTW89_GET_RXWD_RPKT_TYPE(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, GENMASK(27, 24)) ++#define RTW89_GET_RXWD_MAC_INFO_VALID(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, BIT(23)) ++#define RTW89_GET_RXWD_BB_SEL(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, BIT(22)) ++#define RTW89_GET_RXWD_HD_IV_LEN(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, GENMASK(21, 16)) ++#define RTW89_GET_RXWD_SHIFT(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, GENMASK(15, 14)) ++#define RTW89_GET_RXWD_PKT_SIZE(rxdesc) \ ++ le32_get_bits((rxdesc)->dword0, GENMASK(13, 0)) ++#define RTW89_GET_RXWD_BW(rxdesc) \ ++ le32_get_bits((rxdesc)->dword1, GENMASK(31, 30)) ++#define RTW89_GET_RXWD_GI_LTF(rxdesc) \ ++ le32_get_bits((rxdesc)->dword1, GENMASK(27, 25)) ++#define RTW89_GET_RXWD_DATA_RATE(rxdesc) \ ++ le32_get_bits((rxdesc)->dword1, GENMASK(24, 16)) ++#define RTW89_GET_RXWD_USER_ID(rxdesc) \ ++ le32_get_bits((rxdesc)->dword1, GENMASK(15, 8)) ++#define RTW89_GET_RXWD_SR_EN(rxdesc) \ ++ le32_get_bits((rxdesc)->dword1, BIT(7)) ++#define RTW89_GET_RXWD_PPDU_CNT(rxdesc) \ ++ le32_get_bits((rxdesc)->dword1, GENMASK(6, 4)) ++#define RTW89_GET_RXWD_PPDU_TYPE(rxdesc) \ ++ le32_get_bits((rxdesc)->dword1, GENMASK(3, 0)) ++#define RTW89_GET_RXWD_FREE_RUN_CNT(rxdesc) \ ++ le32_get_bits((rxdesc)->dword2, GENMASK(31, 0)) ++#define RTW89_GET_RXWD_ICV_ERR(rxdesc) \ ++ le32_get_bits((rxdesc)->dword3, BIT(10)) ++#define RTW89_GET_RXWD_CRC32_ERR(rxdesc) \ ++ le32_get_bits((rxdesc)->dword3, BIT(9)) ++#define RTW89_GET_RXWD_HW_DEC(rxdesc) \ ++ le32_get_bits((rxdesc)->dword3, BIT(2)) ++#define RTW89_GET_RXWD_SW_DEC(rxdesc) \ ++ le32_get_bits((rxdesc)->dword3, BIT(1)) ++#define RTW89_GET_RXWD_A1_MATCH(rxdesc) \ ++ le32_get_bits((rxdesc)->dword3, BIT(0)) ++ ++/* Long Descriptor */ ++#define RTW89_GET_RXWD_FRAG(rxdesc) \ ++ le32_get_bits((rxdesc)->dword4, GENMASK(31, 28)) ++#define RTW89_GET_RXWD_SEQ(rxdesc) \ ++ le32_get_bits((rxdesc)->dword4, GENMASK(27, 16)) ++#define RTW89_GET_RXWD_TYPE(rxdesc) \ ++ le32_get_bits((rxdesc)->dword4, GENMASK(1, 0)) ++#define RTW89_GET_RXWD_ADDR_CAM_VLD(rxdesc) \ ++ le32_get_bits((rxdesc)->dword5, BIT(28)) ++#define RTW89_GET_RXWD_RX_PL_ID(rxdesc) \ ++ le32_get_bits((rxdesc)->dword5, GENMASK(27, 24)) ++#define RTW89_GET_RXWD_MAC_ID(rxdesc) \ ++ le32_get_bits((rxdesc)->dword5, GENMASK(23, 16)) ++#define RTW89_GET_RXWD_ADDR_CAM_ID(rxdesc) \ ++ le32_get_bits((rxdesc)->dword5, GENMASK(15, 8)) ++#define RTW89_GET_RXWD_SEC_CAM_ID(rxdesc) \ ++ le32_get_bits((rxdesc)->dword5, GENMASK(7, 0)) ++ ++#define RTW89_GET_RXINFO_USR_NUM(rpt) \ ++ le32_get_bits(*((__le32 *)rpt), GENMASK(3, 0)) ++#define RTW89_GET_RXINFO_FW_DEFINE(rpt) \ ++ le32_get_bits(*((__le32 *)rpt), GENMASK(15, 8)) ++#define RTW89_GET_RXINFO_LSIG_LEN(rpt) \ ++ le32_get_bits(*((__le32 *)rpt), GENMASK(27, 16)) ++#define RTW89_GET_RXINFO_IS_TO_SELF(rpt) \ ++ le32_get_bits(*((__le32 *)rpt), BIT(28)) ++#define RTW89_GET_RXINFO_RX_CNT_VLD(rpt) \ ++ le32_get_bits(*((__le32 *)rpt), BIT(29)) ++#define RTW89_GET_RXINFO_LONG_RXD(rpt) \ ++ le32_get_bits(*((__le32 *)rpt), GENMASK(31, 30)) ++#define RTW89_GET_RXINFO_SERVICE(rpt) \ ++ le32_get_bits(*((__le32 *)(rpt) + 1), GENMASK(15, 0)) ++#define RTW89_GET_RXINFO_PLCP_LEN(rpt) \ ++ le32_get_bits(*((__le32 *)(rpt) + 1), GENMASK(23, 16)) ++#define RTW89_GET_RXINFO_MAC_ID_VALID(rpt, usr) \ ++ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(0)) ++#define RTW89_GET_RXINFO_DATA(rpt, usr) \ ++ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(1)) ++#define RTW89_GET_RXINFO_CTRL(rpt, usr) \ ++ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(2)) ++#define RTW89_GET_RXINFO_MGMT(rpt, usr) \ ++ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(3)) ++#define RTW89_GET_RXINFO_BCM(rpt, usr) \ ++ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), BIT(4)) ++#define RTW89_GET_RXINFO_MACID(rpt, usr) \ ++ le32_get_bits(*((__le32 *)(rpt) + (usr) + 2), GENMASK(15, 8)) ++ ++#define RTW89_GET_PHY_STS_RSSI_A(sts) \ ++ le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(7, 0)) ++#define RTW89_GET_PHY_STS_RSSI_B(sts) \ ++ le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(15, 8)) ++#define RTW89_GET_PHY_STS_RSSI_C(sts) \ ++ le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(23, 16)) ++#define RTW89_GET_PHY_STS_RSSI_D(sts) \ ++ le32_get_bits(*((__le32 *)(sts) + 1), GENMASK(31, 24)) ++#define RTW89_GET_PHY_STS_LEN(sts) \ ++ le32_get_bits(*((__le32 *)sts), GENMASK(15, 8)) ++#define RTW89_GET_PHY_STS_RSSI_AVG(sts) \ ++ le32_get_bits(*((__le32 *)sts), GENMASK(31, 24)) ++#define RTW89_GET_PHY_STS_IE_TYPE(ie) \ ++ le32_get_bits(*((__le32 *)ie), GENMASK(4, 0)) ++#define RTW89_GET_PHY_STS_IE_LEN(ie) \ ++ le32_get_bits(*((__le32 *)ie), GENMASK(11, 5)) ++#define RTW89_GET_PHY_STS_IE0_CFO(ie) \ ++ le32_get_bits(*((__le32 *)(ie) + 1), GENMASK(31, 20)) ++ ++enum rtw89_tx_channel { ++ RTW89_TXCH_ACH0 = 0, ++ RTW89_TXCH_ACH1 = 1, ++ RTW89_TXCH_ACH2 = 2, ++ RTW89_TXCH_ACH3 = 3, ++ RTW89_TXCH_ACH4 = 4, ++ RTW89_TXCH_ACH5 = 5, ++ RTW89_TXCH_ACH6 = 6, ++ RTW89_TXCH_ACH7 = 7, ++ RTW89_TXCH_CH8 = 8, /* MGMT Band 0 */ ++ RTW89_TXCH_CH9 = 9, /* HI Band 0 */ ++ RTW89_TXCH_CH10 = 10, /* MGMT Band 1 */ ++ RTW89_TXCH_CH11 = 11, /* HI Band 1 */ ++ RTW89_TXCH_CH12 = 12, /* FW CMD */ ++ ++ /* keep last */ ++ RTW89_TXCH_NUM, ++ RTW89_TXCH_MAX = RTW89_TXCH_NUM - 1 ++}; ++ ++enum rtw89_rx_channel { ++ RTW89_RXCH_RXQ = 0, ++ RTW89_RXCH_RPQ = 1, ++ ++ /* keep last */ ++ RTW89_RXCH_NUM, ++ RTW89_RXCH_MAX = RTW89_RXCH_NUM - 1 ++}; ++ ++enum rtw89_tx_qsel { ++ RTW89_TX_QSEL_BE_0 = 0x00, ++ RTW89_TX_QSEL_BK_0 = 0x01, ++ RTW89_TX_QSEL_VI_0 = 0x02, ++ RTW89_TX_QSEL_VO_0 = 0x03, ++ RTW89_TX_QSEL_BE_1 = 0x04, ++ RTW89_TX_QSEL_BK_1 = 0x05, ++ RTW89_TX_QSEL_VI_1 = 0x06, ++ RTW89_TX_QSEL_VO_1 = 0x07, ++ RTW89_TX_QSEL_BE_2 = 0x08, ++ RTW89_TX_QSEL_BK_2 = 0x09, ++ RTW89_TX_QSEL_VI_2 = 0x0a, ++ RTW89_TX_QSEL_VO_2 = 0x0b, ++ RTW89_TX_QSEL_BE_3 = 0x0c, ++ RTW89_TX_QSEL_BK_3 = 0x0d, ++ RTW89_TX_QSEL_VI_3 = 0x0e, ++ RTW89_TX_QSEL_VO_3 = 0x0f, ++ RTW89_TX_QSEL_B0_BCN = 0x10, ++ RTW89_TX_QSEL_B0_HI = 0x11, ++ RTW89_TX_QSEL_B0_MGMT = 0x12, ++ RTW89_TX_QSEL_B0_NOPS = 0x13, ++ RTW89_TX_QSEL_B0_MGMT_FAST = 0x14, ++ /* reserved */ ++ /* reserved */ ++ /* reserved */ ++ RTW89_TX_QSEL_B1_BCN = 0x18, ++ RTW89_TX_QSEL_B1_HI = 0x19, ++ RTW89_TX_QSEL_B1_MGMT = 0x1a, ++ RTW89_TX_QSEL_B1_NOPS = 0x1b, ++ RTW89_TX_QSEL_B1_MGMT_FAST = 0x1c, ++ /* reserved */ ++ /* reserved */ ++ /* reserved */ ++}; ++ ++enum rtw89_phy_status_ie_type { ++ RTW89_PHYSTS_IE00_CMN_CCK = 0, ++ RTW89_PHYSTS_IE01_CMN_OFDM = 1, ++ RTW89_PHYSTS_IE02_CMN_EXT_AX = 2, ++ RTW89_PHYSTS_IE03_CMN_EXT_SEG_1 = 3, ++ RTW89_PHYSTS_IE04_CMN_EXT_PATH_A = 4, ++ RTW89_PHYSTS_IE05_CMN_EXT_PATH_B = 5, ++ RTW89_PHYSTS_IE06_CMN_EXT_PATH_C = 6, ++ RTW89_PHYSTS_IE07_CMN_EXT_PATH_D = 7, ++ RTW89_PHYSTS_IE08_FTR_CH = 8, ++ RTW89_PHYSTS_IE09_FTR_PLCP_0 = 9, ++ RTW89_PHYSTS_IE10_FTR_PLCP_EXT = 10, ++ RTW89_PHYSTS_IE11_FTR_PLCP_HISTOGRAM = 11, ++ RTW89_PHYSTS_IE12_MU_EIGEN_INFO = 12, ++ RTW89_PHYSTS_IE13_DL_MU_DEF = 13, ++ RTW89_PHYSTS_IE14_TB_UL_CQI = 14, ++ RTW89_PHYSTS_IE15_TB_UL_DEF = 15, ++ RTW89_PHYSTS_IE16_RSVD16 = 16, ++ RTW89_PHYSTS_IE17_TB_UL_CTRL = 17, ++ RTW89_PHYSTS_IE18_DBG_OFDM_FD_CMN = 18, ++ RTW89_PHYSTS_IE19_DBG_OFDM_TD_CMN = 19, ++ RTW89_PHYSTS_IE20_DBG_OFDM_FD_USER_SEG_0 = 20, ++ RTW89_PHYSTS_IE21_DBG_OFDM_FD_USER_SEG_1 = 21, ++ RTW89_PHYSTS_IE22_DBG_OFDM_FD_USER_AGC = 22, ++ RTW89_PHYSTS_IE23_RSVD23 = 23, ++ RTW89_PHYSTS_IE24_DBG_OFDM_TD_PATH_A = 24, ++ RTW89_PHYSTS_IE25_DBG_OFDM_TD_PATH_B = 25, ++ RTW89_PHYSTS_IE26_DBG_OFDM_TD_PATH_C = 26, ++ RTW89_PHYSTS_IE27_DBG_OFDM_TD_PATH_D = 27, ++ RTW89_PHYSTS_IE28_DBG_CCK_PATH_A = 28, ++ RTW89_PHYSTS_IE29_DBG_CCK_PATH_B = 29, ++ RTW89_PHYSTS_IE30_DBG_CCK_PATH_C = 30, ++ RTW89_PHYSTS_IE31_DBG_CCK_PATH_D = 31, ++ ++ /* keep last */ ++ RTW89_PHYSTS_IE_NUM, ++ RTW89_PHYSTS_IE_MAX = RTW89_PHYSTS_IE_NUM - 1 ++}; ++ ++static inline u8 rtw89_core_get_qsel(struct rtw89_dev *rtwdev, u8 tid) ++{ ++ switch (tid) { ++ default: ++ rtw89_warn(rtwdev, "Should use tag 1d: %d\n", tid); ++ fallthrough; ++ case 0: ++ case 3: ++ return RTW89_TX_QSEL_BE_0; ++ case 1: ++ case 2: ++ return RTW89_TX_QSEL_BK_0; ++ case 4: ++ case 5: ++ return RTW89_TX_QSEL_VI_0; ++ case 6: ++ case 7: ++ return RTW89_TX_QSEL_VO_0; ++ } ++} ++ ++static inline u8 rtw89_core_get_ch_dma(struct rtw89_dev *rtwdev, u8 qsel) ++{ ++ switch (qsel) { ++ default: ++ rtw89_warn(rtwdev, "Cannot map qsel to dma: %d\n", qsel); ++ fallthrough; ++ case RTW89_TX_QSEL_BE_0: ++ return RTW89_TXCH_ACH0; ++ case RTW89_TX_QSEL_BK_0: ++ return RTW89_TXCH_ACH1; ++ case RTW89_TX_QSEL_VI_0: ++ return RTW89_TXCH_ACH2; ++ case RTW89_TX_QSEL_VO_0: ++ return RTW89_TXCH_ACH3; ++ case RTW89_TX_QSEL_B0_MGMT: ++ return RTW89_TXCH_CH8; ++ case RTW89_TX_QSEL_B0_HI: ++ return RTW89_TXCH_CH9; ++ case RTW89_TX_QSEL_B1_MGMT: ++ return RTW89_TXCH_CH10; ++ case RTW89_TX_QSEL_B1_HI: ++ return RTW89_TXCH_CH11; ++ } ++} ++ ++static inline u8 rtw89_core_get_tid_indicate(struct rtw89_dev *rtwdev, u8 tid) ++{ ++ switch (tid) { ++ case 3: ++ case 2: ++ case 5: ++ case 7: ++ return 1; ++ default: ++ rtw89_warn(rtwdev, "Should use tag 1d: %d\n", tid); ++ fallthrough; ++ case 0: ++ case 1: ++ case 4: ++ case 6: ++ return 0; ++ } ++} ++ ++#endif +diff --git a/drivers/net/wireless/realtek/rtw89/util.h b/drivers/net/wireless/realtek/rtw89/util.h +new file mode 100644 +index 000000000000..229e81009de6 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/util.h +@@ -0,0 +1,17 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++ * Copyright(c) 2019-2020 Realtek Corporation ++ */ ++#ifndef __RTW89_UTIL_H__ ++#define __RTW89_UTIL_H__ ++ ++#include "core.h" ++ ++#define rtw89_iterate_vifs_bh(rtwdev, iterator, data) \ ++ ieee80211_iterate_active_interfaces_atomic((rtwdev)->hw, \ ++ IEEE80211_IFACE_ITER_NORMAL, iterator, data) ++ ++/* call this function with rtwdev->mutex is held */ ++#define rtw89_for_each_rtwvif(rtwdev, rtwvif) \ ++ list_for_each_entry(rtwvif, &(rtwdev)->rtwvifs_list, list) ++ ++#endif +-- +2.34.0 + diff --git a/kernel/tools/cpupowertools/files/patches/mageia/staging-add-r8188eu.patch b/kernel/tools/cpupowertools/files/patches/mageia/staging-add-r8188eu.patch new file mode 100644 index 00000000..d1c75633 --- /dev/null +++ b/kernel/tools/cpupowertools/files/patches/mageia/staging-add-r8188eu.patch @@ -0,0 +1,81013 @@ +diff --git a/drivers/staging/r8188eu/Kconfig b/drivers/staging/r8188eu/Kconfig +new file mode 100644 +index 000000000000..dc1719d3f2e4 +--- /dev/null ++++ b/drivers/staging/r8188eu/Kconfig +@@ -0,0 +1,26 @@ ++# SPDX-License-Identifier: GPL-2.0 ++config R8188EU ++ tristate "Realtek RTL8188EU Wireless LAN NIC driver" ++ depends on WLAN && USB && CFG80211 ++ depends on m ++ select WIRELESS_EXT ++ select WEXT_PRIV ++ select LIB80211 ++ select LIB80211_CRYPT_WEP ++ select LIB80211_CRYPT_CCMP ++ help ++ This option adds support for the Realtek RTL8188EU chipset, used in USB ++ devices such as the ASUS USB-N10 Nano. This newer driver is based on GitHub ++ sources for version v4.1.4_6773.20130222, and contains modifications for ++ newer kernel features. If built as a module, it will be called r8188eu. ++ ++if R8188EU ++ ++config 88EU_AP_MODE ++ bool "Realtek RTL8188EU AP mode" ++ help ++ This option enables Access Point mode. Unless you know that your system ++ will never be used as an AP, or the target system has limited memory, ++ "Y" should be selected. ++ ++endif +diff --git a/drivers/staging/r8188eu/Makefile b/drivers/staging/r8188eu/Makefile +new file mode 100644 +index 000000000000..aebaf29990fd +--- /dev/null ++++ b/drivers/staging/r8188eu/Makefile +@@ -0,0 +1,105 @@ ++SHELL := /bin/bash ++EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS) ++EXTRA_CFLAGS += -O1 ++ ++ccflags-y += -D__CHECK_ENDIAN__ ++ ++CONFIG_BT_COEXIST = n ++CONFIG_WOWLAN = n ++ ++OUTSRC_FILES := \ ++ hal/HalHWImg8188E_MAC.o \ ++ hal/HalHWImg8188E_BB.o \ ++ hal/HalHWImg8188E_RF.o \ ++ hal/HalPhyRf_8188e.o \ ++ hal/HalPwrSeqCmd.o \ ++ hal/Hal8188EPwrSeq.o \ ++ hal/Hal8188ERateAdaptive.o\ ++ hal/hal_intf.o \ ++ hal/hal_com.o \ ++ hal/odm.o \ ++ hal/odm_debug.o \ ++ hal/odm_interface.o \ ++ hal/odm_HWConfig.o \ ++ hal/odm_RegConfig8188E.o\ ++ hal/odm_RTL8188E.o \ ++ hal/rtl8188e_cmd.o \ ++ hal/rtl8188e_dm.o \ ++ hal/rtl8188e_hal_init.o \ ++ hal/rtl8188e_mp.o \ ++ hal/rtl8188e_phycfg.o \ ++ hal/rtl8188e_rf6052.o \ ++ hal/rtl8188e_rxdesc.o \ ++ hal/rtl8188e_sreset.o \ ++ hal/rtl8188e_xmit.o \ ++ hal/rtl8188eu_led.o \ ++ hal/rtl8188eu_recv.o \ ++ hal/rtl8188eu_xmit.o \ ++ hal/usb_halinit.o \ ++ hal/usb_ops_linux.o ++ ++RTL871X = rtl8188e ++ ++HCI_NAME = usb ++ ++_OS_INTFS_FILES := \ ++ os_dep/ioctl_linux.o \ ++ os_dep/mlme_linux.o \ ++ os_dep/os_intfs.o \ ++ os_dep/osdep_service.o \ ++ os_dep/recv_linux.o \ ++ os_dep/usb_intf.o \ ++ os_dep/usb_ops_linux.o \ ++ os_dep/xmit_linux.o ++ ++_HAL_INTFS_FILES += $(OUTSRC_FILES) ++ ++ifeq ($(CONFIG_BT_COEXIST), y) ++EXTRA_CFLAGS += -DCONFIG_BT_COEXIST ++endif ++ ++ifeq ($(CONFIG_WOWLAN), y) ++EXTRA_CFLAGS += -DCONFIG_WOWLAN ++endif ++ ++SUBARCH := $(shell uname -m | sed -e "s/i.86/i386/; s/ppc.*/powerpc/; s/armv.l/arm/; s/aarch64/arm64/;") ++ ++ARCH ?= $(SUBARCH) ++CROSS_COMPILE ?= ++KVER ?= $(if $(KERNELRELEASE),$(KERNELRELEASE),$(shell uname -r)) ++KSRC ?= $(if $(KERNEL_SRC),$(KERNEL_SRC),/lib/modules/$(KVER)/build) ++MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless ++INSTALL_PREFIX := ++ ++rtk_core := \ ++ core/rtw_ap.o \ ++ core/rtw_br_ext.o \ ++ core/rtw_cmd.o \ ++ core/rtw_debug.o \ ++ core/rtw_efuse.o \ ++ core/rtw_ieee80211.o \ ++ core/rtw_io.o \ ++ core/rtw_ioctl_set.o \ ++ core/rtw_iol.o \ ++ core/rtw_led.o \ ++ core/rtw_mlme.o \ ++ core/rtw_mlme_ext.o \ ++ core/rtw_mp.o \ ++ core/rtw_mp_ioctl.o \ ++ core/rtw_pwrctrl.o \ ++ core/rtw_p2p.o \ ++ core/rtw_recv.o \ ++ core/rtw_rf.o \ ++ core/rtw_security.o \ ++ core/rtw_sreset.o \ ++ core/rtw_sta_mgt.o \ ++ core/rtw_wlan_util.o \ ++ core/rtw_xmit.o ++ ++r8188eu-y += $(rtk_core) ++ ++r8188eu-y += $(_HAL_INTFS_FILES) ++ ++r8188eu-y += $(_OS_INTFS_FILES) ++ ++obj-$(CONFIG_R8188EU) := r8188eu.o +diff --git a/drivers/staging/r8188eu/TODO b/drivers/staging/r8188eu/TODO +new file mode 100644 +index 000000000000..ab9d5d145b3b +--- /dev/null ++++ b/drivers/staging/r8188eu/TODO +@@ -0,0 +1,16 @@ ++To-do list: ++ ++* Correct the coding style according to Linux guidelines; please read the document ++ at https://www.kernel.org/doc/html/latest/process/coding-style.html. ++* Remove unnecessary debugging/printing macros; for those that are still needed ++ use the proper kernel API (pr_debug(), dev_dbg(), netdev_dbg()). ++* Remove dead code such as unusued functions, variables, fields, etc.. ++* Use in-kernel API and remove unnecessary wrappers where possible. ++* Fix bugs due to code that sleeps in atomic context. ++* Remove the HAL layer and migrate its functionality into the relevant parts of ++ the driver. ++* Switch to use LIB80211. ++* Switch to use MAC80211. ++* Switch to use CFG80211. ++* Improve the error handling of various functions, particularly those that use ++ existing kernel APIs. +diff --git a/drivers/staging/r8188eu/core/rtw_ap.c b/drivers/staging/r8188eu/core/rtw_ap.c +new file mode 100644 +index 000000000000..1c07ad28b242 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_ap.c +@@ -0,0 +1,1850 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_AP_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wifi.h" ++#include "../include/ieee80211.h" ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++void init_mlme_ap_info(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; ++ ++ spin_lock_init(&pmlmepriv->bcn_update_lock); ++ ++ /* for ACL */ ++ _rtw_init_queue(&pacl_list->acl_node_q); ++ ++ start_ap_mode(padapter); ++} ++ ++void free_mlme_ap_info(struct adapter *padapter) ++{ ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ pmlmepriv->update_bcn = false; ++ pmlmeext->bstart_bss = false; ++ ++ rtw_sta_flush(padapter); ++ ++ pmlmeinfo->state = _HW_STATE_NOLINK_; ++ ++ /* free_assoc_sta_resources */ ++ rtw_free_all_stainfo(padapter); ++ ++ /* free bc/mc sta_info */ ++ psta = rtw_get_bcmc_stainfo(padapter); ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(padapter, psta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++} ++ ++static void update_BCNTIM(struct adapter *padapter) ++{ ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network; ++ unsigned char *pie = pnetwork_mlmeext->IEs; ++ ++ /* update TIM IE */ ++ if (true) { ++ u8 *p, *dst_ie, *premainder_ie = NULL; ++ u8 *pbackup_remainder_ie = NULL; ++ __le16 tim_bitmap_le; ++ uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen; ++ ++ tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap); ++ ++ p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen, pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_); ++ if (p && tim_ielen > 0) { ++ tim_ielen += 2; ++ premainder_ie = p + tim_ielen; ++ tim_ie_offset = (int)(p - pie); ++ remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen; ++ /* append TIM IE from dst_ie offset */ ++ dst_ie = p; ++ } else { ++ tim_ielen = 0; ++ ++ /* calculate head_len */ ++ offset = _FIXED_IE_LENGTH_; ++ offset += pnetwork_mlmeext->Ssid.SsidLength + 2; ++ ++ /* get supported rates len */ ++ p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_)); ++ if (p) ++ offset += tmp_len + 2; ++ ++ /* DS Parameter Set IE, len = 3 */ ++ offset += 3; ++ ++ premainder_ie = pie + offset; ++ ++ remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen; ++ ++ /* append TIM IE from offset */ ++ dst_ie = pie + offset; ++ } ++ ++ if (remainder_ielen > 0) { ++ pbackup_remainder_ie = kmalloc(remainder_ielen, GFP_ATOMIC); ++ if (pbackup_remainder_ie && premainder_ie) ++ memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); ++ } ++ *dst_ie++ = _TIM_IE_; ++ ++ if ((pstapriv->tim_bitmap & 0xff00) && (pstapriv->tim_bitmap & 0x00fc)) ++ tim_ielen = 5; ++ else ++ tim_ielen = 4; ++ ++ *dst_ie++ = tim_ielen; ++ ++ *dst_ie++ = 0;/* DTIM count */ ++ *dst_ie++ = 1;/* DTIM period */ ++ ++ if (pstapriv->tim_bitmap & BIT(0))/* for bc/mc frames */ ++ *dst_ie++ = BIT(0);/* bitmap ctrl */ ++ else ++ *dst_ie++ = 0; ++ ++ if (tim_ielen == 4) { ++ *dst_ie++ = *(u8 *)&tim_bitmap_le; ++ } else if (tim_ielen == 5) { ++ memcpy(dst_ie, &tim_bitmap_le, 2); ++ dst_ie += 2; ++ } ++ ++ /* copy remainder IE */ ++ if (pbackup_remainder_ie) { ++ memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen); ++ ++ kfree(pbackup_remainder_ie); ++ } ++ offset = (uint)(dst_ie - pie); ++ pnetwork_mlmeext->IELength = offset + remainder_ielen; ++ } ++ ++ set_tx_beacon_cmd(padapter); ++} ++ ++static u8 chk_sta_is_alive(struct sta_info *psta) ++{ ++ u8 ret = false; ++ ++ if ((psta->sta_stats.last_rx_data_pkts + psta->sta_stats.last_rx_ctrl_pkts) == ++ (psta->sta_stats.rx_data_pkts + psta->sta_stats.rx_ctrl_pkts)) ++ ; ++ else ++ ret = true; ++ ++ sta_update_last_rx_pkts(psta); ++ ++ return ret; ++} ++ ++void expire_timeout_chk(struct adapter *padapter) ++{ ++ struct list_head *phead, *plist; ++ u8 updated = 0; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 chk_alive_num = 0; ++ char chk_alive_list[NUM_STA]; ++ int i; ++ ++ spin_lock_bh(&pstapriv->auth_list_lock); ++ ++ phead = &pstapriv->auth_list; ++ plist = phead->next; ++ ++ /* check auth_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, auth_list); ++ plist = plist->next; ++ ++ if (psta->expire_to > 0) { ++ psta->expire_to--; ++ if (psta->expire_to == 0) { ++ list_del_init(&psta->auth_list); ++ pstapriv->auth_list_cnt--; ++ ++ DBG_88E("auth expire %6ph\n", ++ psta->hwaddr); ++ ++ spin_unlock_bh(&pstapriv->auth_list_lock); ++ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(padapter, psta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++ spin_lock_bh(&pstapriv->auth_list_lock); ++ } ++ } ++ ++ } ++ spin_unlock_bh(&pstapriv->auth_list_lock); ++ ++ psta = NULL; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ ++ phead = &pstapriv->asoc_list; ++ plist = phead->next; ++ ++ /* check asoc_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, asoc_list); ++ plist = plist->next; ++ ++ if (chk_sta_is_alive(psta) || !psta->expire_to) { ++ psta->expire_to = pstapriv->expire_to; ++ psta->keep_alive_trycnt = 0; ++ psta->under_exist_checking = 0; ++ } else { ++ psta->expire_to--; ++ } ++ ++ if (psta->expire_to <= 0) { ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ if (padapter->registrypriv.wifi_spec == 1) { ++ psta->expire_to = pstapriv->expire_to; ++ continue; ++ } ++ ++ if (psta->state & WIFI_SLEEP_STATE) { ++ if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) { ++ /* to check if alive by another methods if station is at ps mode. */ ++ psta->expire_to = pstapriv->expire_to; ++ psta->state |= WIFI_STA_ALIVE_CHK_STATE; ++ ++ /* to update bcn with tim_bitmap for this station */ ++ pstapriv->tim_bitmap |= BIT(psta->aid); ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++ ++ if (!pmlmeext->active_keep_alive_check) ++ continue; ++ } ++ } ++ if (pmlmeext->active_keep_alive_check) { ++ int stainfo_offset; ++ ++ stainfo_offset = rtw_stainfo_offset(pstapriv, psta); ++ if (stainfo_offset_valid(stainfo_offset)) ++ chk_alive_list[chk_alive_num++] = stainfo_offset; ++ continue; ++ } ++ ++ list_del_init(&psta->asoc_list); ++ pstapriv->asoc_list_cnt--; ++ ++ DBG_88E("asoc expire %pM, state = 0x%x\n", (psta->hwaddr), psta->state); ++ updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING); ++ } else { ++ /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */ ++ if (psta->sleepq_len > (NR_XMITFRAME / pstapriv->asoc_list_cnt) && ++ padapter->xmitpriv.free_xmitframe_cnt < (NR_XMITFRAME / pstapriv->asoc_list_cnt / 2)) { ++ DBG_88E("%s sta:%pM, sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n", __func__, ++ (psta->hwaddr), psta->sleepq_len, ++ padapter->xmitpriv.free_xmitframe_cnt, ++ pstapriv->asoc_list_cnt); ++ wakeup_sta_to_xmit(padapter, psta); ++ } ++ } ++ } ++ ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ if (chk_alive_num) { ++ u8 backup_oper_channel = 0; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ /* switch to correct channel of current network before issue keep-alive frames */ ++ if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) { ++ backup_oper_channel = rtw_get_oper_ch(padapter); ++ SelectChannel(padapter, pmlmeext->cur_channel); ++ } ++ ++ /* issue null data to check sta alive*/ ++ for (i = 0; i < chk_alive_num; i++) { ++ int ret = _FAIL; ++ ++ psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]); ++ ++ if (psta->state & WIFI_SLEEP_STATE) ++ ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50); ++ else ++ ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50); ++ ++ psta->keep_alive_trycnt++; ++ if (ret == _SUCCESS) { ++ DBG_88E("asoc check, sta(%pM) is alive\n", (psta->hwaddr)); ++ psta->expire_to = pstapriv->expire_to; ++ psta->keep_alive_trycnt = 0; ++ continue; ++ } else if (psta->keep_alive_trycnt <= 3) { ++ DBG_88E("ack check for asoc expire, keep_alive_trycnt =%d\n", psta->keep_alive_trycnt); ++ psta->expire_to = 1; ++ continue; ++ } ++ ++ psta->keep_alive_trycnt = 0; ++ ++ DBG_88E("asoc expire %pM, state = 0x%x\n", (psta->hwaddr), psta->state); ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ list_del_init(&psta->asoc_list); ++ pstapriv->asoc_list_cnt--; ++ updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING); ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ } ++ ++ if (backup_oper_channel > 0) /* back to the original operation channel */ ++ SelectChannel(padapter, backup_oper_channel); ++ } ++ ++ associated_clients_update(padapter, updated); ++} ++ ++void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level) ++{ ++ int i; ++ u8 rf_type; ++ u32 init_rate = 0; ++ unsigned char sta_band = 0, raid, shortGIrate = false; ++ unsigned char limit; ++ unsigned int tx_ra_bitmap = 0; ++ struct ht_priv *psta_ht = NULL; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; ++ ++ if (psta) ++ psta_ht = &psta->htpriv; ++ else ++ return; ++ ++ if (!(psta->state & _FW_LINKED)) ++ return; ++ ++ /* b/g mode ra_bitmap */ ++ for (i = 0; i < sizeof(psta->bssrateset); i++) { ++ if (psta->bssrateset[i]) ++ tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f); ++ } ++ /* n mode ra_bitmap */ ++ if (psta_ht->ht_option) { ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ if (rf_type == RF_2T2R) ++ limit = 16;/* 2R */ ++ else ++ limit = 8;/* 1R */ ++ ++ for (i = 0; i < limit; i++) { ++ if (psta_ht->ht_cap.mcs.rx_mask[i / 8] & BIT(i % 8)) ++ tx_ra_bitmap |= BIT(i + 12); ++ } ++ ++ /* max short GI rate */ ++ shortGIrate = psta_ht->sgi; ++ } ++ ++ if (pcur_network->Configuration.DSConfig > 14) { ++ sta_band |= WIRELESS_INVALID; ++ } else { ++ if (tx_ra_bitmap & 0xffff000) ++ sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B; ++ else if (tx_ra_bitmap & 0xff0) ++ sta_band |= WIRELESS_11G | WIRELESS_11B; ++ else ++ sta_band |= WIRELESS_11B; ++ } ++ ++ psta->wireless_mode = sta_band; ++ ++ raid = networktype_to_raid(sta_band); ++ init_rate = get_highest_rate_idx(tx_ra_bitmap & 0x0fffffff) & 0x3f; ++ ++ if (psta->aid < NUM_STA) { ++ u8 arg = 0; ++ ++ arg = psta->mac_id & 0x1f; ++ ++ arg |= BIT(7);/* support entry 2~31 */ ++ ++ if (shortGIrate) ++ arg |= BIT(5); ++ ++ tx_ra_bitmap |= ((raid << 28) & 0xf0000000); ++ ++ DBG_88E("%s => mac_id:%d , raid:%d , bitmap = 0x%x, arg = 0x%x\n", ++ __func__, psta->mac_id, raid, tx_ra_bitmap, arg); ++ ++ /* bitmap[0:27] = tx_rate_bitmap */ ++ /* bitmap[28:31]= Rate Adaptive id */ ++ /* arg[0:4] = macid */ ++ /* arg[5] = Short GI */ ++ rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, rssi_level); ++ ++ if (shortGIrate) ++ init_rate |= BIT(6); ++ ++ /* set ra_id, init_rate */ ++ psta->raid = raid; ++ psta->init_rate = init_rate; ++ ++ } else { ++ DBG_88E("station aid %d exceed the max number\n", psta->aid); ++ } ++} ++ ++void update_bmc_sta(struct adapter *padapter) ++{ ++ u32 init_rate = 0; ++ unsigned char network_type, raid; ++ int i, supportRateNum = 0; ++ unsigned int tx_ra_bitmap = 0; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; ++ struct sta_info *psta = rtw_get_bcmc_stainfo(padapter); ++ ++ if (psta) { ++ psta->aid = 0;/* default set to 0 */ ++ psta->mac_id = psta->aid + 1; ++ ++ psta->qos_option = 0; ++ psta->htpriv.ht_option = false; ++ ++ psta->ieee8021x_blocked = 0; ++ ++ memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats)); ++ ++ /* prepare for add_RATid */ ++ supportRateNum = rtw_get_rateset_len((u8 *)&pcur_network->SupportedRates); ++ network_type = rtw_check_network_type((u8 *)&pcur_network->SupportedRates, supportRateNum, 1); ++ ++ memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum); ++ psta->bssratelen = supportRateNum; ++ ++ /* b/g mode ra_bitmap */ ++ for (i = 0; i < supportRateNum; i++) { ++ if (psta->bssrateset[i]) ++ tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f); ++ } ++ ++ if (pcur_network->Configuration.DSConfig > 14) { ++ network_type = WIRELESS_INVALID; ++ } else { ++ /* force to b mode */ ++ network_type = WIRELESS_11B; ++ tx_ra_bitmap = 0xf; ++ } ++ ++ raid = networktype_to_raid(network_type); ++ init_rate = get_highest_rate_idx(tx_ra_bitmap & 0x0fffffff) & 0x3f; ++ ++ /* ap mode */ ++ rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true); ++ ++ { ++ u8 arg = 0; ++ ++ arg = psta->mac_id & 0x1f; ++ arg |= BIT(7); ++ tx_ra_bitmap |= ((raid << 28) & 0xf0000000); ++ DBG_88E("update_bmc_sta, mask = 0x%x, arg = 0x%x\n", tx_ra_bitmap, arg); ++ ++ /* bitmap[0:27] = tx_rate_bitmap */ ++ /* bitmap[28:31]= Rate Adaptive id */ ++ /* arg[0:4] = macid */ ++ /* arg[5] = Short GI */ ++ rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, 0); ++ } ++ /* set ra_id, init_rate */ ++ psta->raid = raid; ++ psta->init_rate = init_rate; ++ ++ rtw_sta_media_status_rpt(padapter, psta, 1); ++ ++ spin_lock_bh(&psta->lock); ++ psta->state = _FW_LINKED; ++ spin_unlock_bh(&psta->lock); ++ ++ } else { ++ DBG_88E("add_RATid_bmc_sta error!\n"); ++ } ++} ++ ++/* notes: */ ++/* AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode */ ++/* MAC_ID = AID+1 for sta in ap/adhoc mode */ ++/* MAC_ID = 1 for bc/mc for sta/ap/adhoc */ ++/* MAC_ID = 0 for bssid for sta/ap/adhoc */ ++/* CAM_ID = 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */ ++ ++void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv; ++ struct ht_priv *phtpriv_sta = &psta->htpriv; ++ u16 sta_cap_info; ++ u16 ap_cap_info; ++ ++ psta->mac_id = psta->aid + 1; ++ DBG_88E("%s\n", __func__); ++ ++ /* ap mode */ ++ rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true); ++ ++ if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ++ psta->ieee8021x_blocked = true; ++ else ++ psta->ieee8021x_blocked = false; ++ ++ /* update sta's cap */ ++ ++ /* ERP */ ++ VCS_update(padapter, psta); ++ /* HT related cap */ ++ if (phtpriv_sta->ht_option) { ++ /* check if sta supports rx ampdu */ ++ phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable; ++ sta_cap_info = le16_to_cpu(phtpriv_sta->ht_cap.cap_info); ++ ap_cap_info = le16_to_cpu(phtpriv_ap->ht_cap.cap_info); ++ ++ /* check if sta support s Short GI */ ++ if ((sta_cap_info & ap_cap_info) & ++ (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ++ phtpriv_sta->sgi = true; ++ ++ /* bwmode */ ++ if ((sta_cap_info & ap_cap_info) & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { ++ phtpriv_sta->bwmode = pmlmeext->cur_bwmode; ++ phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset; ++ } ++ psta->qos_option = true; ++ } else { ++ phtpriv_sta->ampdu_enable = false; ++ phtpriv_sta->sgi = false; ++ phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20; ++ phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ } ++ ++ /* Rx AMPDU */ ++ send_delba(padapter, 0, psta->hwaddr);/* recipient */ ++ ++ /* TX AMPDU */ ++ send_delba(padapter, 1, psta->hwaddr);/* originator */ ++ phtpriv_sta->agg_enable_bitmap = 0x0;/* reset */ ++ phtpriv_sta->candidate_tid_bitmap = 0x0;/* reset */ ++ ++ /* todo: init other variables */ ++ ++ memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats)); ++ ++ spin_lock_bh(&psta->lock); ++ psta->state |= _FW_LINKED; ++ spin_unlock_bh(&psta->lock); ++} ++ ++static void update_hw_ht_param(struct adapter *padapter) ++{ ++ unsigned char max_AMPDU_len; ++ unsigned char min_MPDU_spacing; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ DBG_88E("%s\n", __func__); ++ ++ /* handle A-MPDU parameter field */ ++ /* ++ AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k ++ AMPDU_para [4:2]:Min MPDU Start Spacing ++ */ ++ max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03; ++ ++ min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing)); ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len)); ++ ++ /* */ ++ /* Config SM Power Save setting */ ++ /* */ ++ pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & 0x0C) >> 2; ++ if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) ++ DBG_88E("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__); ++} ++ ++static void start_bss_network(struct adapter *padapter, u8 *pbuf) ++{ ++ u8 *p; ++ u8 val8, cur_channel, cur_bwmode, cur_ch_offset; ++ u16 bcn_interval; ++ u32 acparm; ++ int ie_len; ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network; ++ struct HT_info_element *pht_info = NULL; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod; ++ cur_channel = pnetwork->Configuration.DSConfig; ++ cur_bwmode = HT_CHANNEL_WIDTH_20; ++ cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ ++ /* check if there is wps ie, */ ++ /* if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd, */ ++ /* and at first time the security ie (RSN/WPA IE) will not include in beacon. */ ++ if (!rtw_get_wps_ie(pnetwork->IEs + _FIXED_IE_LENGTH_, pnetwork->IELength - _FIXED_IE_LENGTH_, NULL, NULL)) ++ pmlmeext->bstart_bss = true; ++ ++ /* todo: update wmm, ht cap */ ++ if (pmlmepriv->qospriv.qos_option) ++ pmlmeinfo->WMM_enable = true; ++ if (pmlmepriv->htpriv.ht_option) { ++ pmlmeinfo->WMM_enable = true; ++ pmlmeinfo->HT_enable = true; ++ ++ update_hw_ht_param(padapter); ++ } ++ ++ if (pmlmepriv->cur_network.join_res != true) { /* setting only at first time */ ++ /* WEP Key will be set before this function, do not clear CAM. */ ++ if ((psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) && ++ (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)) ++ flush_all_cam_entry(padapter); /* clear CAM */ ++ } ++ ++ /* set MSR to AP_Mode */ ++ Set_MSR(padapter, _HW_STATE_AP_); ++ ++ /* Set BSSID REG */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress); ++ ++ /* Set EDCA param reg */ ++ acparm = 0x002F3217; /* VO */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm)); ++ acparm = 0x005E4317; /* VI */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm)); ++ acparm = 0x005ea42b; ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm)); ++ acparm = 0x0000A444; /* BK */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm)); ++ ++ /* Set Security */ ++ val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf; ++ rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); ++ ++ /* Beacon Control related register */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval)); ++ ++ UpdateBrateTbl(padapter, pnetwork->SupportedRates); ++ rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates); ++ ++ if (!pmlmepriv->cur_network.join_res) { /* setting only at first time */ ++ /* turn on all dynamic functions */ ++ Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); ++ } ++ /* set channel, bwmode */ ++ p = rtw_get_ie((pnetwork->IEs + sizeof(struct ndis_802_11_fixed_ie)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - sizeof(struct ndis_802_11_fixed_ie))); ++ if (p && ie_len) { ++ pht_info = (struct HT_info_element *)(p + 2); ++ ++ if ((pregpriv->cbw40_enable) && (pht_info->infos[0] & BIT(2))) { ++ /* switch to the 40M Hz mode */ ++ cur_bwmode = HT_CHANNEL_WIDTH_40; ++ switch (pht_info->infos[0] & 0x3) { ++ case 1: ++ cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; ++ break; ++ case 3: ++ cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; ++ break; ++ default: ++ cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ break; ++ } ++ } ++ } ++ /* TODO: need to judge the phy parameters on concurrent mode for single phy */ ++ set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode); ++ ++ DBG_88E("CH =%d, BW =%d, offset =%d\n", cur_channel, cur_bwmode, cur_ch_offset); ++ ++ /* */ ++ pmlmeext->cur_channel = cur_channel; ++ pmlmeext->cur_bwmode = cur_bwmode; ++ pmlmeext->cur_ch_offset = cur_ch_offset; ++ pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type; ++ ++ /* update cur_wireless_mode */ ++ update_wireless_mode(padapter); ++ ++ /* udpate capability after cur_wireless_mode updated */ ++ update_capinfo(padapter, rtw_get_capability((struct wlan_bssid_ex *)pnetwork)); ++ ++ /* let pnetwork_mlmeext == pnetwork_mlme. */ ++ memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length); ++ ++#ifdef CONFIG_88EU_P2P ++ memcpy(pwdinfo->p2p_group_ssid, pnetwork->Ssid.Ssid, pnetwork->Ssid.SsidLength); ++ pwdinfo->p2p_group_ssid_len = pnetwork->Ssid.SsidLength; ++#endif /* CONFIG_88EU_P2P */ ++ ++ if (pmlmeext->bstart_bss) { ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++ ++ /* issue beacon frame */ ++ if (send_beacon(padapter) == _FAIL) ++ DBG_88E("issue_beacon, fail!\n"); ++ } ++ ++ /* update bc/mc sta_info */ ++ update_bmc_sta(padapter); ++} ++ ++int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) ++{ ++ int ret = _SUCCESS; ++ u8 *p; ++ u8 *pHT_caps_ie = NULL; ++ u8 *pHT_info_ie = NULL; ++ struct sta_info *psta = NULL; ++ u16 cap, ht_cap = false; ++ uint ie_len = 0; ++ int group_cipher, pairwise_cipher; ++ u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX]; ++ int supportRateNum = 0; ++ u8 OUI1[] = {0x00, 0x50, 0xf2, 0x01}; ++ u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pbss_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; ++ u8 *ie = pbss_network->IEs; ++ ++ /* SSID */ ++ /* Supported rates */ ++ /* DS Params */ ++ /* WLAN_EID_COUNTRY */ ++ /* ERP Information element */ ++ /* Extended supported rates */ ++ /* WPA/WPA2 */ ++ /* Wi-Fi Wireless Multimedia Extensions */ ++ /* ht_capab, ht_oper */ ++ /* WPS IE */ ++ ++ DBG_88E("%s, len =%d\n", __func__, len); ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) ++ return _FAIL; ++ ++ if (len > MAX_IE_SZ) ++ return _FAIL; ++ ++ pbss_network->IELength = len; ++ ++ memset(ie, 0, MAX_IE_SZ); ++ ++ memcpy(ie, pbuf, pbss_network->IELength); ++ ++ if (pbss_network->InfrastructureMode != Ndis802_11APMode) ++ return _FAIL; ++ ++ pbss_network->Rssi = 0; ++ ++ memcpy(pbss_network->MacAddress, myid(&padapter->eeprompriv), ETH_ALEN); ++ ++ /* beacon interval */ ++ p = rtw_get_beacon_interval_from_ie(ie);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */ ++ pbss_network->Configuration.BeaconPeriod = get_unaligned_le16(p); ++ ++ /* capability */ ++ cap = get_unaligned_le16(ie); ++ ++ /* SSID */ ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); ++ if (p && ie_len > 0) { ++ memset(&pbss_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); ++ memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len); ++ pbss_network->Ssid.SsidLength = ie_len; ++ } ++ ++ /* channel */ ++ channel = 0; ++ pbss_network->Configuration.Length = 0; ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); ++ if (p && ie_len > 0) ++ channel = *(p + 2); ++ ++ pbss_network->Configuration.DSConfig = channel; ++ ++ memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX); ++ /* get supported rates */ ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); ++ if (p) { ++ memcpy(supportRate, p + 2, ie_len); ++ supportRateNum = ie_len; ++ } ++ ++ /* get ext_supported rates */ ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_); ++ if (p) { ++ memcpy(supportRate + supportRateNum, p + 2, ie_len); ++ supportRateNum += ie_len; ++ } ++ ++ network_type = rtw_check_network_type(supportRate, supportRateNum, channel); ++ ++ rtw_set_supported_rate(pbss_network->SupportedRates, network_type); ++ ++ /* parsing ERP_IE */ ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); ++ if (p && ie_len > 0) ++ ERP_IE_handler(padapter, (struct ndis_802_11_var_ie *)p); ++ ++ /* update privacy/security */ ++ if (cap & BIT(4)) ++ pbss_network->Privacy = 1; ++ else ++ pbss_network->Privacy = 0; ++ ++ psecuritypriv->wpa_psk = 0; ++ ++ /* wpa2 */ ++ group_cipher = 0; ++ pairwise_cipher = 0; ++ psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_; ++ psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_; ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); ++ if (p && ie_len > 0) { ++ if (rtw_parse_wpa2_ie(p, ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { ++ psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; ++ ++ psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */ ++ psecuritypriv->wpa_psk |= BIT(1); ++ ++ psecuritypriv->wpa2_group_cipher = group_cipher; ++ psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher; ++ } ++ } ++ /* wpa */ ++ ie_len = 0; ++ group_cipher = 0; ++ pairwise_cipher = 0; ++ psecuritypriv->wpa_group_cipher = _NO_PRIVACY_; ++ psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_; ++ for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) { ++ p = rtw_get_ie(p, _SSN_IE_1_, &ie_len, ++ (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))); ++ if ((p) && (!memcmp(p + 2, OUI1, 4))) { ++ if (rtw_parse_wpa_ie(p, ie_len + 2, &group_cipher, ++ &pairwise_cipher, NULL) == _SUCCESS) { ++ psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; ++ ++ psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */ ++ ++ psecuritypriv->wpa_psk |= BIT(0); ++ ++ psecuritypriv->wpa_group_cipher = group_cipher; ++ psecuritypriv->wpa_pairwise_cipher = pairwise_cipher; ++ } ++ break; ++ } ++ if (!p || ie_len == 0) ++ break; ++ } ++ ++ /* wmm */ ++ ie_len = 0; ++ pmlmepriv->qospriv.qos_option = 0; ++ if (pregistrypriv->wmm_enable) { ++ for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) { ++ p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, ++ (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))); ++ if ((p) && !memcmp(p + 2, WMM_PARA_IE, 6)) { ++ pmlmepriv->qospriv.qos_option = 1; ++ ++ *(p + 8) |= BIT(7);/* QoS Info, support U-APSD */ ++ ++ /* disable all ACM bits since the WMM admission control is not supported */ ++ *(p + 10) &= ~BIT(4); /* BE */ ++ *(p + 14) &= ~BIT(4); /* BK */ ++ *(p + 18) &= ~BIT(4); /* VI */ ++ *(p + 22) &= ~BIT(4); /* VO */ ++ break; ++ } ++ ++ if (!p || ie_len == 0) ++ break; ++ } ++ } ++ /* parsing HT_CAP_IE */ ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, ++ (pbss_network->IELength - _BEACON_IE_OFFSET_)); ++ if (p && ie_len > 0) { ++ u8 rf_type; ++ struct ieee80211_ht_cap *pht_cap = (struct ieee80211_ht_cap *)(p + 2); ++ ++ pHT_caps_ie = p; ++ ht_cap = true; ++ network_type |= WIRELESS_11_24N; ++ ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ ++ if ((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) || ++ (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP)) ++ pht_cap->ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY & (0x07 << 2)); ++ else ++ pht_cap->ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00); ++ ++ /* set Max Rx AMPDU size to 64K */ ++ pht_cap->ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_FACTOR & 0x03); ++ ++ if (rf_type == RF_1T1R) { ++ pht_cap->mcs.rx_mask[0] = 0xff; ++ pht_cap->mcs.rx_mask[1] = 0x0; ++ } ++ memcpy(&pmlmepriv->htpriv.ht_cap, p + 2, ie_len); ++ } ++ ++ /* parsing HT_INFO_IE */ ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, ++ (pbss_network->IELength - _BEACON_IE_OFFSET_)); ++ if (p && ie_len > 0) ++ pHT_info_ie = p; ++ switch (network_type) { ++ case WIRELESS_11B: ++ pbss_network->NetworkTypeInUse = Ndis802_11DS; ++ break; ++ case WIRELESS_11G: ++ case WIRELESS_11BG: ++ case WIRELESS_11G_24N: ++ case WIRELESS_11BG_24N: ++ pbss_network->NetworkTypeInUse = Ndis802_11OFDM24; ++ break; ++ default: ++ pbss_network->NetworkTypeInUse = Ndis802_11OFDM24; ++ break; ++ } ++ ++ pmlmepriv->cur_network.network_type = network_type; ++ ++ pmlmepriv->htpriv.ht_option = false; ++ ++ if ((psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) || ++ (psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) { ++ /* todo: */ ++ /* ht_cap = false; */ ++ } ++ ++ /* ht_cap */ ++ if (pregistrypriv->ht_enable && ht_cap) { ++ pmlmepriv->htpriv.ht_option = true; ++ pmlmepriv->qospriv.qos_option = 1; ++ ++ if (pregistrypriv->ampdu_enable == 1) ++ pmlmepriv->htpriv.ampdu_enable = true; ++ HT_caps_handler(padapter, (struct ndis_802_11_var_ie *)pHT_caps_ie); ++ ++ HT_info_handler(padapter, (struct ndis_802_11_var_ie *)pHT_info_ie); ++ } ++ ++ pbss_network->Length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pbss_network); ++ ++ /* issue beacon to start bss network */ ++ start_bss_network(padapter, (u8 *)pbss_network); ++ ++ /* alloc sta_info for ap itself */ ++ psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress); ++ if (!psta) { ++ psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress); ++ if (!psta) ++ return _FAIL; ++ } ++ ++ /* fix bug of flush_cam_entry at STOP AP mode */ ++ psta->state |= WIFI_AP_STATE; ++ rtw_indicate_connect(padapter); ++ pmlmepriv->cur_network.join_res = true;/* for check if already set beacon */ ++ return ret; ++} ++ ++void rtw_set_macaddr_acl(struct adapter *padapter, int mode) ++{ ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; ++ ++ DBG_88E("%s, mode =%d\n", __func__, mode); ++ ++ pacl_list->mode = mode; ++} ++ ++int rtw_acl_add_sta(struct adapter *padapter, u8 *addr) ++{ ++ struct list_head *plist, *phead; ++ u8 added = false; ++ int i, ret = 0; ++ struct rtw_wlan_acl_node *paclnode; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; ++ struct __queue *pacl_node_q = &pacl_list->acl_node_q; ++ ++ DBG_88E("%s(acl_num =%d) =%pM\n", __func__, pacl_list->num, (addr)); ++ ++ if ((NUM_ACL - 1) < pacl_list->num) ++ return -1; ++ ++ spin_lock_bh(&pacl_node_q->lock); ++ ++ phead = get_list_head(pacl_node_q); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ paclnode = container_of(plist, struct rtw_wlan_acl_node, list); ++ plist = plist->next; ++ ++ if (!memcmp(paclnode->addr, addr, ETH_ALEN)) { ++ if (paclnode->valid) { ++ added = true; ++ DBG_88E("%s, sta has been added\n", __func__); ++ break; ++ } ++ } ++ } ++ ++ spin_unlock_bh(&pacl_node_q->lock); ++ ++ if (added) ++ return ret; ++ ++ spin_lock_bh(&pacl_node_q->lock); ++ ++ for (i = 0; i < NUM_ACL; i++) { ++ paclnode = &pacl_list->aclnode[i]; ++ ++ if (!paclnode->valid) { ++ INIT_LIST_HEAD(&paclnode->list); ++ ++ memcpy(paclnode->addr, addr, ETH_ALEN); ++ ++ paclnode->valid = true; ++ ++ list_add_tail(&paclnode->list, get_list_head(pacl_node_q)); ++ ++ pacl_list->num++; ++ ++ break; ++ } ++ } ++ ++ DBG_88E("%s, acl_num =%d\n", __func__, pacl_list->num); ++ ++ spin_unlock_bh(&pacl_node_q->lock); ++ ++ return ret; ++} ++ ++int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr) ++{ ++ struct list_head *plist, *phead; ++ int ret = 0; ++ struct rtw_wlan_acl_node *paclnode; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; ++ struct __queue *pacl_node_q = &pacl_list->acl_node_q; ++ ++ DBG_88E("%s(acl_num =%d) =%pM\n", __func__, pacl_list->num, (addr)); ++ ++ spin_lock_bh(&pacl_node_q->lock); ++ ++ phead = get_list_head(pacl_node_q); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ paclnode = container_of(plist, struct rtw_wlan_acl_node, list); ++ plist = plist->next; ++ ++ if (!memcmp(paclnode->addr, addr, ETH_ALEN)) { ++ if (paclnode->valid) { ++ paclnode->valid = false; ++ ++ list_del_init(&paclnode->list); ++ ++ pacl_list->num--; ++ } ++ } ++ } ++ ++ spin_unlock_bh(&pacl_node_q->lock); ++ ++ DBG_88E("%s, acl_num =%d\n", __func__, pacl_list->num); ++ return ret; ++} ++ ++static void update_bcn_fixed_ie(struct adapter *padapter) ++{ ++ DBG_88E("%s\n", __func__); ++} ++ ++static void update_bcn_erpinfo_ie(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; ++ unsigned char *p, *ie = pnetwork->IEs; ++ u32 len = 0; ++ ++ DBG_88E("%s, ERP_enable =%d\n", __func__, pmlmeinfo->ERP_enable); ++ ++ if (!pmlmeinfo->ERP_enable) ++ return; ++ ++ /* parsing ERP_IE */ ++ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len, ++ (pnetwork->IELength - _BEACON_IE_OFFSET_)); ++ if (p && len > 0) { ++ struct ndis_802_11_var_ie *pIE = (struct ndis_802_11_var_ie *)p; ++ ++ if (pmlmepriv->num_sta_non_erp == 1) ++ pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT | RTW_ERP_INFO_USE_PROTECTION; ++ else ++ pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT | RTW_ERP_INFO_USE_PROTECTION); ++ ++ if (pmlmepriv->num_sta_no_short_preamble > 0) ++ pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE; ++ else ++ pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE); ++ ++ ERP_IE_handler(padapter, pIE); ++ } ++} ++ ++static void update_bcn_htcap_ie(struct adapter *padapter) ++{ ++ DBG_88E("%s\n", __func__); ++} ++ ++static void update_bcn_htinfo_ie(struct adapter *padapter) ++{ ++ DBG_88E("%s\n", __func__); ++} ++ ++static void update_bcn_rsn_ie(struct adapter *padapter) ++{ ++ DBG_88E("%s\n", __func__); ++} ++ ++static void update_bcn_wpa_ie(struct adapter *padapter) ++{ ++ DBG_88E("%s\n", __func__); ++} ++ ++static void update_bcn_wmm_ie(struct adapter *padapter) ++{ ++ DBG_88E("%s\n", __func__); ++} ++ ++static void update_bcn_wps_ie(struct adapter *padapter) ++{ ++ u8 *pwps_ie = NULL, *pwps_ie_src; ++ u8 *premainder_ie, *pbackup_remainder_ie = NULL; ++ uint wps_ielen = 0, wps_offset, remainder_ielen; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; ++ unsigned char *ie = pnetwork->IEs; ++ u32 ielen = pnetwork->IELength; ++ ++ DBG_88E("%s\n", __func__); ++ ++ pwps_ie = rtw_get_wps_ie(ie + _FIXED_IE_LENGTH_, ielen - _FIXED_IE_LENGTH_, NULL, &wps_ielen); ++ ++ if (!pwps_ie || wps_ielen == 0) ++ return; ++ ++ wps_offset = (uint)(pwps_ie - ie); ++ ++ premainder_ie = pwps_ie + wps_ielen; ++ ++ remainder_ielen = ielen - wps_offset - wps_ielen; ++ ++ if (remainder_ielen > 0) { ++ pbackup_remainder_ie = kmalloc(remainder_ielen, GFP_ATOMIC); ++ if (pbackup_remainder_ie) ++ memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); ++ } ++ ++ pwps_ie_src = pmlmepriv->wps_beacon_ie; ++ if (!pwps_ie_src) ++ goto exit; ++ ++ wps_ielen = (uint)pwps_ie_src[1];/* to get ie data len */ ++ if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) { ++ memcpy(pwps_ie, pwps_ie_src, wps_ielen + 2); ++ pwps_ie += (wps_ielen + 2); ++ ++ if (pbackup_remainder_ie) ++ memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen); ++ ++ /* update IELength */ ++ pnetwork->IELength = wps_offset + (wps_ielen + 2) + remainder_ielen; ++ } ++ ++exit: ++ kfree(pbackup_remainder_ie); ++} ++ ++static void update_bcn_p2p_ie(struct adapter *padapter) ++{ ++} ++ ++static void update_bcn_vendor_spec_ie(struct adapter *padapter, u8 *oui) ++{ ++ DBG_88E("%s\n", __func__); ++ ++ if (!memcmp(RTW_WPA_OUI, oui, 4)) ++ update_bcn_wpa_ie(padapter); ++ else if (!memcmp(WMM_OUI, oui, 4)) ++ update_bcn_wmm_ie(padapter); ++ else if (!memcmp(WPS_OUI, oui, 4)) ++ update_bcn_wps_ie(padapter); ++ else if (!memcmp(P2P_OUI, oui, 4)) ++ update_bcn_p2p_ie(padapter); ++ else ++ DBG_88E("unknown OUI type!\n"); ++} ++ ++void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx) ++{ ++ struct mlme_priv *pmlmepriv; ++ struct mlme_ext_priv *pmlmeext; ++ ++ if (!padapter) ++ return; ++ ++ pmlmepriv = &padapter->mlmepriv; ++ pmlmeext = &padapter->mlmeextpriv; ++ ++ if (!pmlmeext->bstart_bss) ++ return; ++ ++ spin_lock_bh(&pmlmepriv->bcn_update_lock); ++ ++ switch (ie_id) { ++ case 0xFF: ++ update_bcn_fixed_ie(padapter);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */ ++ break; ++ case _TIM_IE_: ++ update_BCNTIM(padapter); ++ break; ++ case _ERPINFO_IE_: ++ update_bcn_erpinfo_ie(padapter); ++ break; ++ case _HT_CAPABILITY_IE_: ++ update_bcn_htcap_ie(padapter); ++ break; ++ case _RSN_IE_2_: ++ update_bcn_rsn_ie(padapter); ++ break; ++ case _HT_ADD_INFO_IE_: ++ update_bcn_htinfo_ie(padapter); ++ break; ++ case _VENDOR_SPECIFIC_IE_: ++ update_bcn_vendor_spec_ie(padapter, oui); ++ break; ++ default: ++ break; ++ } ++ ++ pmlmepriv->update_bcn = true; ++ ++ spin_unlock_bh(&pmlmepriv->bcn_update_lock); ++ ++ if (tx) ++ set_tx_beacon_cmd(padapter); ++} ++ ++/* ++op_mode ++Set to 0 (HT pure) under the followign conditions ++ - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or ++ - all STAs in the BSS are 20 MHz HT in 20 MHz BSS ++Set to 1 (HT non-member protection) if there may be non-HT STAs ++ in both the primary and the secondary channel ++Set to 2 if only HT STAs are associated in BSS, ++ however and at least one 20 MHz HT STA is associated ++Set to 3 (HT mixed mode) when one or more non-HT STAs are associated ++ (currently non-GF HT station is considered as non-HT STA also) ++*/ ++static int rtw_ht_operation_update(struct adapter *padapter) ++{ ++ u16 cur_op_mode, new_op_mode; ++ int op_mode_changes = 0; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv; ++ ++ if (pmlmepriv->htpriv.ht_option) ++ return 0; ++ ++ DBG_88E("%s current operation mode = 0x%X\n", ++ __func__, pmlmepriv->ht_op_mode); ++ ++ if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) && ++ pmlmepriv->num_sta_ht_no_gf) { ++ pmlmepriv->ht_op_mode |= ++ HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT; ++ op_mode_changes++; ++ } else if ((pmlmepriv->ht_op_mode & ++ HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) && ++ pmlmepriv->num_sta_ht_no_gf == 0) { ++ pmlmepriv->ht_op_mode &= ++ ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT; ++ op_mode_changes++; ++ } ++ ++ if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) && ++ (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) { ++ pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT; ++ op_mode_changes++; ++ } else if ((pmlmepriv->ht_op_mode & ++ HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) && ++ (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) { ++ pmlmepriv->ht_op_mode &= ++ ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT; ++ op_mode_changes++; ++ } ++ ++ /* Note: currently we switch to the MIXED op mode if HT non-greenfield ++ * station is associated. Probably it's a theoretical case, since ++ * it looks like all known HT STAs support greenfield. ++ */ ++ new_op_mode = 0; ++ if (pmlmepriv->num_sta_no_ht || ++ (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)) ++ new_op_mode = OP_MODE_MIXED; ++ else if ((le16_to_cpu(phtpriv_ap->ht_cap.cap_info) & ++ IEEE80211_HT_CAP_SUP_WIDTH_20_40) && ++ pmlmepriv->num_sta_ht_20mhz) ++ new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED; ++ else if (pmlmepriv->olbc_ht) ++ new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS; ++ else ++ new_op_mode = OP_MODE_PURE; ++ ++ cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK; ++ if (cur_op_mode != new_op_mode) { ++ pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK; ++ pmlmepriv->ht_op_mode |= new_op_mode; ++ op_mode_changes++; ++ } ++ ++ DBG_88E("%s new operation mode = 0x%X changes =%d\n", ++ __func__, pmlmepriv->ht_op_mode, op_mode_changes); ++ ++ return op_mode_changes; ++} ++ ++void associated_clients_update(struct adapter *padapter, u8 updated) ++{ ++ /* update associcated stations cap. */ ++ if (updated) { ++ struct list_head *phead, *plist; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ ++ phead = &pstapriv->asoc_list; ++ plist = phead->next; ++ ++ /* check asoc_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, asoc_list); ++ ++ plist = plist->next; ++ ++ VCS_update(padapter, psta); ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ } ++} ++ ++/* called > TSR LEVEL for USB or SDIO Interface*/ ++void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta) ++{ ++ u8 beacon_updated = false; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) { ++ if (!psta->no_short_preamble_set) { ++ psta->no_short_preamble_set = 1; ++ ++ pmlmepriv->num_sta_no_short_preamble++; ++ ++ if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && ++ (pmlmepriv->num_sta_no_short_preamble == 1)) { ++ beacon_updated = true; ++ update_beacon(padapter, 0xFF, NULL, true); ++ } ++ } ++ } else { ++ if (psta->no_short_preamble_set) { ++ psta->no_short_preamble_set = 0; ++ ++ pmlmepriv->num_sta_no_short_preamble--; ++ ++ if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && ++ (pmlmepriv->num_sta_no_short_preamble == 0)) { ++ beacon_updated = true; ++ update_beacon(padapter, 0xFF, NULL, true); ++ } ++ } ++ } ++ ++ if (psta->flags & WLAN_STA_NONERP) { ++ if (!psta->nonerp_set) { ++ psta->nonerp_set = 1; ++ ++ pmlmepriv->num_sta_non_erp++; ++ ++ if (pmlmepriv->num_sta_non_erp == 1) { ++ beacon_updated = true; ++ update_beacon(padapter, _ERPINFO_IE_, NULL, true); ++ } ++ } ++ } else { ++ if (psta->nonerp_set) { ++ psta->nonerp_set = 0; ++ ++ pmlmepriv->num_sta_non_erp--; ++ ++ if (pmlmepriv->num_sta_non_erp == 0) { ++ beacon_updated = true; ++ update_beacon(padapter, _ERPINFO_IE_, NULL, true); ++ } ++ } ++ } ++ ++ if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT)) { ++ if (!psta->no_short_slot_time_set) { ++ psta->no_short_slot_time_set = 1; ++ ++ pmlmepriv->num_sta_no_short_slot_time++; ++ ++ if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && ++ (pmlmepriv->num_sta_no_short_slot_time == 1)) { ++ beacon_updated = true; ++ update_beacon(padapter, 0xFF, NULL, true); ++ } ++ } ++ } else { ++ if (psta->no_short_slot_time_set) { ++ psta->no_short_slot_time_set = 0; ++ ++ pmlmepriv->num_sta_no_short_slot_time--; ++ ++ if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && ++ (pmlmepriv->num_sta_no_short_slot_time == 0)) { ++ beacon_updated = true; ++ update_beacon(padapter, 0xFF, NULL, true); ++ } ++ } ++ } ++ ++ if (psta->flags & WLAN_STA_HT) { ++ u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info); ++ ++ DBG_88E("HT: STA %pM HT Capabilities Info: 0x%04x\n", ++ (psta->hwaddr), ht_capab); ++ ++ if (psta->no_ht_set) { ++ psta->no_ht_set = 0; ++ pmlmepriv->num_sta_no_ht--; ++ } ++ ++ if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) { ++ if (!psta->no_ht_gf_set) { ++ psta->no_ht_gf_set = 1; ++ pmlmepriv->num_sta_ht_no_gf++; ++ } ++ DBG_88E("%s STA %pM - no greenfield, num of non-gf stations %d\n", ++ __func__, (psta->hwaddr), ++ pmlmepriv->num_sta_ht_no_gf); ++ } ++ ++ if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH_20_40) == 0) { ++ if (!psta->ht_20mhz_set) { ++ psta->ht_20mhz_set = 1; ++ pmlmepriv->num_sta_ht_20mhz++; ++ } ++ DBG_88E("%s STA %pM - 20 MHz HT, num of 20MHz HT STAs %d\n", ++ __func__, (psta->hwaddr), ++ pmlmepriv->num_sta_ht_20mhz); ++ } ++ } else { ++ if (!psta->no_ht_set) { ++ psta->no_ht_set = 1; ++ pmlmepriv->num_sta_no_ht++; ++ } ++ if (pmlmepriv->htpriv.ht_option) { ++ DBG_88E("%s STA %pM - no HT, num of non-HT stations %d\n", ++ __func__, (psta->hwaddr), ++ pmlmepriv->num_sta_no_ht); ++ } ++ } ++ ++ if (rtw_ht_operation_update(padapter) > 0) { ++ update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, false); ++ update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, true); ++ } ++ ++ /* update associcated stations cap. */ ++ associated_clients_update(padapter, beacon_updated); ++ ++ DBG_88E("%s, updated =%d\n", __func__, beacon_updated); ++} ++ ++u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta) ++{ ++ u8 beacon_updated = false; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ if (!psta) ++ return beacon_updated; ++ ++ if (psta->no_short_preamble_set) { ++ psta->no_short_preamble_set = 0; ++ pmlmepriv->num_sta_no_short_preamble--; ++ if (pmlmeext->cur_wireless_mode > WIRELESS_11B && ++ pmlmepriv->num_sta_no_short_preamble == 0) { ++ beacon_updated = true; ++ update_beacon(padapter, 0xFF, NULL, true); ++ } ++ } ++ ++ if (psta->nonerp_set) { ++ psta->nonerp_set = 0; ++ pmlmepriv->num_sta_non_erp--; ++ if (pmlmepriv->num_sta_non_erp == 0) { ++ beacon_updated = true; ++ update_beacon(padapter, _ERPINFO_IE_, NULL, true); ++ } ++ } ++ ++ if (psta->no_short_slot_time_set) { ++ psta->no_short_slot_time_set = 0; ++ pmlmepriv->num_sta_no_short_slot_time--; ++ if (pmlmeext->cur_wireless_mode > WIRELESS_11B && ++ pmlmepriv->num_sta_no_short_slot_time == 0) { ++ beacon_updated = true; ++ update_beacon(padapter, 0xFF, NULL, true); ++ } ++ } ++ ++ if (psta->no_ht_gf_set) { ++ psta->no_ht_gf_set = 0; ++ pmlmepriv->num_sta_ht_no_gf--; ++ } ++ ++ if (psta->no_ht_set) { ++ psta->no_ht_set = 0; ++ pmlmepriv->num_sta_no_ht--; ++ } ++ ++ if (psta->ht_20mhz_set) { ++ psta->ht_20mhz_set = 0; ++ pmlmepriv->num_sta_ht_20mhz--; ++ } ++ ++ if (rtw_ht_operation_update(padapter) > 0) { ++ update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, false); ++ update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, true); ++ } ++ ++ /* update associcated stations cap. */ ++ ++ DBG_88E("%s, updated =%d\n", __func__, beacon_updated); ++ ++ return beacon_updated; ++} ++ ++u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta, ++ bool active, u16 reason) ++{ ++ u8 beacon_updated = false; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ if (!psta) ++ return beacon_updated; ++ ++ /* tear down Rx AMPDU */ ++ send_delba(padapter, 0, psta->hwaddr);/* recipient */ ++ ++ /* tear down TX AMPDU */ ++ send_delba(padapter, 1, psta->hwaddr);/* originator */ ++ psta->htpriv.agg_enable_bitmap = 0x0;/* reset */ ++ psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */ ++ ++ if (active) ++ issue_deauth(padapter, psta->hwaddr, reason); ++ ++ /* clear cam entry / key */ ++ rtw_clearstakey_cmd(padapter, (u8 *)psta, (u8)(psta->mac_id + 3), true); ++ ++ spin_lock_bh(&psta->lock); ++ psta->state &= ~_FW_LINKED; ++ spin_unlock_bh(&psta->lock); ++ ++ rtw_indicate_sta_disassoc_event(padapter, psta); ++ ++ report_del_sta_event(padapter, psta->hwaddr, reason); ++ ++ beacon_updated = bss_cap_update_on_sta_leave(padapter, psta); ++ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(padapter, psta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++ return beacon_updated; ++} ++ ++int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset) ++{ ++ struct list_head *phead, *plist; ++ int ret = 0; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ ++ if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) ++ return ret; ++ ++ DBG_88E(FUNC_NDEV_FMT" with ch:%u, offset:%u\n", ++ FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset); ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ phead = &pstapriv->asoc_list; ++ plist = phead->next; ++ ++ /* for each sta in asoc_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, asoc_list); ++ plist = plist->next; ++ ++ issue_action_spct_ch_switch(padapter, psta->hwaddr, new_ch, ch_offset); ++ psta->expire_to = ((pstapriv->expire_to * 2) > 5) ? 5 : (pstapriv->expire_to * 2); ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset); ++ ++ return ret; ++} ++ ++int rtw_sta_flush(struct adapter *padapter) ++{ ++ struct list_head *phead, *plist; ++ int ret = 0; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ ++ DBG_88E(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); ++ ++ if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) ++ return ret; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ phead = &pstapriv->asoc_list; ++ plist = phead->next; ++ ++ /* free sta asoc_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, asoc_list); ++ ++ plist = plist->next; ++ ++ list_del_init(&psta->asoc_list); ++ pstapriv->asoc_list_cnt--; ++ ++ ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING); ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING); ++ ++ associated_clients_update(padapter, true); ++ ++ return ret; ++} ++ ++/* called > TSR LEVEL for USB or SDIO Interface*/ ++void sta_info_update(struct adapter *padapter, struct sta_info *psta) ++{ ++ int flags = psta->flags; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ /* update wmm cap. */ ++ if (WLAN_STA_WME & flags) ++ psta->qos_option = 1; ++ else ++ psta->qos_option = 0; ++ ++ if (pmlmepriv->qospriv.qos_option == 0) ++ psta->qos_option = 0; ++ ++ /* update 802.11n ht cap. */ ++ if (WLAN_STA_HT & flags) { ++ psta->htpriv.ht_option = true; ++ psta->qos_option = 1; ++ } else { ++ psta->htpriv.ht_option = false; ++ } ++ ++ if (!pmlmepriv->htpriv.ht_option) ++ psta->htpriv.ht_option = false; ++ ++ update_sta_info_apmode(padapter, psta); ++} ++ ++/* called >= TSR LEVEL for USB or SDIO Interface*/ ++void ap_sta_info_defer_update(struct adapter *padapter, struct sta_info *psta) ++{ ++ if (psta->state & _FW_LINKED) { ++ /* add ratid */ ++ add_RATid(padapter, psta, 0);/* DM_RATR_STA_INIT */ ++ } ++} ++ ++void start_ap_mode(struct adapter *padapter) ++{ ++ int i; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; ++ ++ pmlmepriv->update_bcn = false; ++ ++ pmlmeext->bstart_bss = false; ++ ++ pmlmepriv->num_sta_non_erp = 0; ++ ++ pmlmepriv->num_sta_no_short_slot_time = 0; ++ ++ pmlmepriv->num_sta_no_short_preamble = 0; ++ ++ pmlmepriv->num_sta_ht_no_gf = 0; ++ pmlmepriv->num_sta_no_ht = 0; ++ pmlmepriv->num_sta_ht_20mhz = 0; ++ ++ pmlmepriv->olbc = false; ++ ++ pmlmepriv->olbc_ht = false; ++ ++ pmlmepriv->ht_op_mode = 0; ++ ++ for (i = 0; i < NUM_STA; i++) ++ pstapriv->sta_aid[i] = NULL; ++ ++ pmlmepriv->wps_beacon_ie = NULL; ++ pmlmepriv->wps_probe_resp_ie = NULL; ++ pmlmepriv->wps_assoc_resp_ie = NULL; ++ ++ pmlmepriv->p2p_beacon_ie = NULL; ++ pmlmepriv->p2p_probe_resp_ie = NULL; ++ ++ /* for ACL */ ++ INIT_LIST_HEAD(&pacl_list->acl_node_q.queue); ++ pacl_list->num = 0; ++ pacl_list->mode = 0; ++ for (i = 0; i < NUM_ACL; i++) { ++ INIT_LIST_HEAD(&pacl_list->aclnode[i].list); ++ pacl_list->aclnode[i].valid = false; ++ } ++} ++ ++void stop_ap_mode(struct adapter *padapter) ++{ ++ struct list_head *phead, *plist; ++ struct rtw_wlan_acl_node *paclnode; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; ++ struct __queue *pacl_node_q = &pacl_list->acl_node_q; ++ ++ pmlmepriv->update_bcn = false; ++ pmlmeext->bstart_bss = false; ++ ++ /* reset and init security priv , this can refine with rtw_reset_securitypriv */ ++ memset((unsigned char *)&padapter->securitypriv, 0, sizeof(struct security_priv)); ++ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled; ++ ++ /* for ACL */ ++ spin_lock_bh(&pacl_node_q->lock); ++ phead = get_list_head(pacl_node_q); ++ plist = phead->next; ++ while (phead != plist) { ++ paclnode = container_of(plist, struct rtw_wlan_acl_node, list); ++ plist = plist->next; ++ ++ if (paclnode->valid) { ++ paclnode->valid = false; ++ ++ list_del_init(&paclnode->list); ++ ++ pacl_list->num--; ++ } ++ } ++ spin_unlock_bh(&pacl_node_q->lock); ++ ++ DBG_88E("%s, free acl_node_queue, num =%d\n", __func__, pacl_list->num); ++ ++ rtw_sta_flush(padapter); ++ ++ /* free_assoc_sta_resources */ ++ rtw_free_all_stainfo(padapter); ++ ++ psta = rtw_get_bcmc_stainfo(padapter); ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(padapter, psta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++ rtw_init_bcmc_stainfo(padapter); ++ ++ rtw_free_mlme_priv_ie_data(pmlmepriv); ++} ++ ++#endif /* CONFIG_88EU_AP_MODE */ +diff --git a/drivers/staging/r8188eu/core/rtw_br_ext.c b/drivers/staging/r8188eu/core/rtw_br_ext.c +new file mode 100644 +index 000000000000..62a672243696 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_br_ext.c +@@ -0,0 +1,717 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. i*/ ++ ++#define _RTW_BR_EXT_C_ ++ ++#include "../include/linux/if_arp.h" ++#include "../include/net/ip.h" ++#include "../include/linux/atalk.h" ++#include "../include/linux/udp.h" ++#include "../include/linux/if_pppox.h" ++ ++#include "../include/drv_types.h" ++#include "../include/rtw_br_ext.h" ++#include "../include/usb_osintf.h" ++#include "../include/recv_osdep.h" ++ ++#ifndef csum_ipv6_magic ++#include "../include/net/ip6_checksum.h" ++#endif ++ ++#include "../include/linux/ipv6.h" ++#include "../include/linux/icmpv6.h" ++#include "../include/net/ndisc.h" ++#include "../include/net/checksum.h" ++ ++#define NAT25_IPV4 01 ++#define NAT25_IPV6 02 ++#define NAT25_IPX 03 ++#define NAT25_APPLE 04 ++#define NAT25_PPPOE 05 ++ ++#define RTL_RELAY_TAG_LEN (ETH_ALEN) ++#define TAG_HDR_LEN 4 ++ ++#define MAGIC_CODE 0x8186 ++#define MAGIC_CODE_LEN 2 ++#define WAIT_TIME_PPPOE 5 /* waiting time for pppoe server in sec */ ++ ++/*----------------------------------------------------------------- ++ How database records network address: ++ 0 1 2 3 4 5 6 7 8 9 10 ++ |----|----|----|----|----|----|----|----|----|----|----| ++ IPv4 |type| | IP addr | ++ IPX |type| Net addr | Node addr | ++ IPX |type| Net addr |Sckt addr| ++ Apple |type| Network |node| ++ PPPoE |type| SID | AC MAC | ++-----------------------------------------------------------------*/ ++ ++/* Find a tag in pppoe frame and return the pointer */ ++static unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, unsigned short type) ++{ ++ unsigned char *cur_ptr, *start_ptr; ++ unsigned short tagLen, tagType; ++ ++ start_ptr = cur_ptr = (unsigned char *)ph->tag; ++ while ((cur_ptr - start_ptr) < ntohs(ph->length)) { ++ /* prevent un-alignment access */ ++ tagType = (unsigned short)((cur_ptr[0] << 8) + cur_ptr[1]); ++ tagLen = (unsigned short)((cur_ptr[2] << 8) + cur_ptr[3]); ++ if (tagType == type) ++ return cur_ptr; ++ cur_ptr = cur_ptr + TAG_HDR_LEN + tagLen; ++ } ++ return NULL; ++} ++ ++static int __nat25_add_pppoe_tag(struct sk_buff *skb, struct pppoe_tag *tag) ++{ ++ struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN); ++ int data_len; ++ ++ data_len = tag->tag_len + TAG_HDR_LEN; ++ if (skb_tailroom(skb) < data_len) { ++ _DEBUG_ERR("skb_tailroom() failed in add SID tag!\n"); ++ return -1; ++ } ++ ++ skb_put(skb, data_len); ++ /* have a room for new tag */ ++ memmove(((unsigned char *)ph->tag + data_len), (unsigned char *)ph->tag, ntohs(ph->length)); ++ ph->length = htons(ntohs(ph->length) + data_len); ++ memcpy((unsigned char *)ph->tag, tag, data_len); ++ return data_len; ++} ++ ++static int skb_pull_and_merge(struct sk_buff *skb, unsigned char *src, int len) ++{ ++ int tail_len; ++ unsigned long end, tail; ++ ++ if ((src+len) > skb_tail_pointer(skb) || skb->len < len) ++ return -1; ++ ++ tail = (unsigned long)skb_tail_pointer(skb); ++ end = (unsigned long)src+len; ++ if (tail < end) ++ return -1; ++ ++ tail_len = (int)(tail-end); ++ if (tail_len > 0) ++ memmove(src, src+len, tail_len); ++ ++ skb_trim(skb, skb->len-len); ++ return 0; ++} ++ ++static unsigned long __nat25_timeout(struct adapter *priv) ++{ ++ unsigned long timeout; ++ ++ timeout = jiffies - NAT25_AGEING_TIME*HZ; ++ ++ return timeout; ++} ++ ++static int __nat25_has_expired(struct adapter *priv, ++ struct nat25_network_db_entry *fdb) ++{ ++ if (time_before_eq(fdb->ageing_timer, __nat25_timeout(priv))) ++ return 1; ++ ++ return 0; ++} ++ ++static void __nat25_generate_ipv4_network_addr(unsigned char *networkAddr, ++ unsigned int *ipAddr) ++{ ++ memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); ++ ++ networkAddr[0] = NAT25_IPV4; ++ memcpy(networkAddr+7, (unsigned char *)ipAddr, 4); ++} ++ ++static void __nat25_generate_pppoe_network_addr(unsigned char *networkAddr, ++ unsigned char *ac_mac, __be16 *sid) ++{ ++ memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); ++ ++ networkAddr[0] = NAT25_PPPOE; ++ memcpy(networkAddr+1, (unsigned char *)sid, 2); ++ memcpy(networkAddr+3, (unsigned char *)ac_mac, 6); ++} ++ ++static void __nat25_generate_ipv6_network_addr(unsigned char *networkAddr, ++ unsigned int *ipAddr) ++{ ++ memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); ++ ++ networkAddr[0] = NAT25_IPV6; ++ memcpy(networkAddr+1, (unsigned char *)ipAddr, 16); ++} ++ ++static unsigned char *scan_tlv(unsigned char *data, int len, unsigned char tag, unsigned char len8b) ++{ ++ while (len > 0) { ++ if (*data == tag && *(data+1) == len8b && len >= len8b*8) ++ return data+2; ++ ++ len -= (*(data+1))*8; ++ data += (*(data+1))*8; ++ } ++ return NULL; ++} ++ ++static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char *replace_mac) ++{ ++ struct icmp6hdr *icmphdr = (struct icmp6hdr *)data; ++ unsigned char *mac; ++ ++ if (icmphdr->icmp6_type == NDISC_ROUTER_SOLICITATION) { ++ if (len >= 8) { ++ mac = scan_tlv(&data[8], len-8, 1, 1); ++ if (mac) { ++ _DEBUG_INFO("Router Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], ++ replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); ++ memcpy(mac, replace_mac, 6); ++ return 1; ++ } ++ } ++ } else if (icmphdr->icmp6_type == NDISC_ROUTER_ADVERTISEMENT) { ++ if (len >= 16) { ++ mac = scan_tlv(&data[16], len-16, 1, 1); ++ if (mac) { ++ _DEBUG_INFO("Router Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], ++ replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); ++ memcpy(mac, replace_mac, 6); ++ return 1; ++ } ++ } ++ } else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) { ++ if (len >= 24) { ++ mac = scan_tlv(&data[24], len-24, 1, 1); ++ if (mac) { ++ _DEBUG_INFO("Neighbor Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], ++ replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); ++ memcpy(mac, replace_mac, 6); ++ return 1; ++ } ++ } ++ } else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) { ++ if (len >= 24) { ++ mac = scan_tlv(&data[24], len-24, 2, 1); ++ if (mac) { ++ _DEBUG_INFO("Neighbor Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], ++ replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); ++ memcpy(mac, replace_mac, 6); ++ return 1; ++ } ++ } ++ } else if (icmphdr->icmp6_type == NDISC_REDIRECT) { ++ if (len >= 40) { ++ mac = scan_tlv(&data[40], len-40, 2, 1); ++ if (mac) { ++ _DEBUG_INFO("Redirect, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], ++ replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); ++ memcpy(mac, replace_mac, 6); ++ return 1; ++ } ++ } ++ } ++ return 0; ++} ++ ++static int __nat25_network_hash(unsigned char *networkAddr) ++{ ++ if (networkAddr[0] == NAT25_IPV4) { ++ unsigned long x; ++ ++ x = networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; ++ ++ return x & (NAT25_HASH_SIZE - 1); ++ } else if (networkAddr[0] == NAT25_IPX) { ++ unsigned long x; ++ ++ x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ ++ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; ++ ++ return x & (NAT25_HASH_SIZE - 1); ++ } else if (networkAddr[0] == NAT25_APPLE) { ++ unsigned long x; ++ ++ x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3]; ++ ++ return x & (NAT25_HASH_SIZE - 1); ++ } else if (networkAddr[0] == NAT25_PPPOE) { ++ unsigned long x; ++ ++ x = networkAddr[0] ^ networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8]; ++ ++ return x & (NAT25_HASH_SIZE - 1); ++ } else if (networkAddr[0] == NAT25_IPV6) { ++ unsigned long x; ++ ++ x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ ++ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10] ^ ++ networkAddr[11] ^ networkAddr[12] ^ networkAddr[13] ^ networkAddr[14] ^ networkAddr[15] ^ ++ networkAddr[16]; ++ ++ return x & (NAT25_HASH_SIZE - 1); ++ } else { ++ unsigned long x = 0; ++ int i; ++ ++ for (i = 0; i < MAX_NETWORK_ADDR_LEN; i++) ++ x ^= networkAddr[i]; ++ ++ return x & (NAT25_HASH_SIZE - 1); ++ } ++} ++ ++static void __network_hash_link(struct adapter *priv, ++ struct nat25_network_db_entry *ent, int hash) ++{ ++ /* Caller must spin_lock already! */ ++ ent->next_hash = priv->nethash[hash]; ++ if (ent->next_hash) ++ ent->next_hash->pprev_hash = &ent->next_hash; ++ priv->nethash[hash] = ent; ++ ent->pprev_hash = &priv->nethash[hash]; ++} ++ ++static void __network_hash_unlink(struct nat25_network_db_entry *ent) ++{ ++ /* Caller must spin_lock already! */ ++ *ent->pprev_hash = ent->next_hash; ++ if (ent->next_hash) ++ ent->next_hash->pprev_hash = ent->pprev_hash; ++ ent->next_hash = NULL; ++ ent->pprev_hash = NULL; ++} ++ ++static void __nat25_db_network_insert(struct adapter *priv, ++ unsigned char *macAddr, unsigned char *networkAddr) ++{ ++ struct nat25_network_db_entry *db; ++ int hash; ++ ++ spin_lock_bh(&priv->br_ext_lock); ++ hash = __nat25_network_hash(networkAddr); ++ db = priv->nethash[hash]; ++ while (db) { ++ if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) { ++ memcpy(db->macAddr, macAddr, ETH_ALEN); ++ db->ageing_timer = jiffies; ++ spin_unlock_bh(&priv->br_ext_lock); ++ return; ++ } ++ db = db->next_hash; ++ } ++ db = kmalloc(sizeof(*db), GFP_ATOMIC); ++ if (!db) { ++ spin_unlock_bh(&priv->br_ext_lock); ++ return; ++ } ++ memcpy(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN); ++ memcpy(db->macAddr, macAddr, ETH_ALEN); ++ atomic_set(&db->use_count, 1); ++ db->ageing_timer = jiffies; ++ ++ __network_hash_link(priv, db, hash); ++ ++ spin_unlock_bh(&priv->br_ext_lock); ++} ++ ++static void __nat25_db_print(struct adapter *priv) ++{ ++} ++ ++/* ++ * NAT2.5 interface ++ */ ++ ++void nat25_db_cleanup(struct adapter *priv) ++{ ++ int i; ++ ++ spin_lock_bh(&priv->br_ext_lock); ++ ++ for (i = 0; i < NAT25_HASH_SIZE; i++) { ++ struct nat25_network_db_entry *f; ++ f = priv->nethash[i]; ++ while (f) { ++ struct nat25_network_db_entry *g; ++ ++ g = f->next_hash; ++ if (priv->scdb_entry == f) { ++ memset(priv->scdb_mac, 0, ETH_ALEN); ++ memset(priv->scdb_ip, 0, 4); ++ priv->scdb_entry = NULL; ++ } ++ __network_hash_unlink(f); ++ kfree(f); ++ f = g; ++ } ++ } ++ spin_unlock_bh(&priv->br_ext_lock); ++} ++ ++void nat25_db_expire(struct adapter *priv) ++{ ++ int i; ++ ++ spin_lock_bh(&priv->br_ext_lock); ++ ++ for (i = 0; i < NAT25_HASH_SIZE; i++) { ++ struct nat25_network_db_entry *f; ++ f = priv->nethash[i]; ++ ++ while (f) { ++ struct nat25_network_db_entry *g; ++ g = f->next_hash; ++ ++ if (__nat25_has_expired(priv, f)) { ++ if (atomic_dec_and_test(&f->use_count)) { ++ if (priv->scdb_entry == f) { ++ memset(priv->scdb_mac, 0, ETH_ALEN); ++ memset(priv->scdb_ip, 0, 4); ++ priv->scdb_entry = NULL; ++ } ++ __network_hash_unlink(f); ++ kfree(f); ++ } ++ } ++ f = g; ++ } ++ } ++ spin_unlock_bh(&priv->br_ext_lock); ++} ++ ++int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method) ++{ ++ unsigned short protocol; ++ unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; ++ unsigned int tmp; ++ ++ if (!skb) ++ return -1; ++ ++ if ((method <= NAT25_MIN) || (method >= NAT25_MAX)) ++ return -1; ++ ++ protocol = be16_to_cpu(*((__be16 *)(skb->data + 2 * ETH_ALEN))); ++ ++ /*---------------------------------------------------*/ ++ /* Handle IP frame */ ++ /*---------------------------------------------------*/ ++ if (protocol == ETH_P_IP) { ++ struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN); ++ ++ if (((unsigned char *)(iph) + (iph->ihl<<2)) >= (skb->data + ETH_HLEN + skb->len)) { ++ DEBUG_WARN("NAT25: malformed IP packet !\n"); ++ return -1; ++ } ++ ++ switch (method) { ++ case NAT25_CHECK: ++ return -1; ++ case NAT25_INSERT: ++ /* some multicast with source IP is all zero, maybe other case is illegal */ ++ /* in class A, B, C, host address is all zero or all one is illegal */ ++ if (iph->saddr == 0) ++ return 0; ++ tmp = be32_to_cpu(iph->saddr); ++ DEBUG_INFO("NAT25: Insert IP, SA =%08x, DA =%08x\n", tmp, iph->daddr); ++ __nat25_generate_ipv4_network_addr(networkAddr, &tmp); ++ /* record source IP address and , source mac address into db */ ++ __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); ++ ++ __nat25_db_print(priv); ++ return 0; ++ default: ++ return -1; ++ } ++ } else if (protocol == ETH_P_ARP) { ++ /*---------------------------------------------------*/ ++ /* Handle ARP frame */ ++ /*---------------------------------------------------*/ ++ struct arphdr *arp = (struct arphdr *)(skb->data + ETH_HLEN); ++ unsigned char *arp_ptr = (unsigned char *)(arp + 1); ++ unsigned int *sender; ++ ++ if (arp->ar_pro != __constant_htons(ETH_P_IP)) { ++ DEBUG_WARN("NAT25: arp protocol unknown (%4x)!\n", be16_to_cpu(arp->ar_pro)); ++ return -1; ++ } ++ ++ switch (method) { ++ case NAT25_CHECK: ++ return 0; /* skb_copy for all ARP frame */ ++ case NAT25_INSERT: ++ DEBUG_INFO("NAT25: Insert ARP, MAC =%02x%02x%02x%02x%02x%02x\n", arp_ptr[0], ++ arp_ptr[1], arp_ptr[2], arp_ptr[3], arp_ptr[4], arp_ptr[5]); ++ ++ /* change to ARP sender mac address to wlan STA address */ ++ memcpy(arp_ptr, GET_MY_HWADDR(priv), ETH_ALEN); ++ arp_ptr += arp->ar_hln; ++ sender = (unsigned int *)arp_ptr; ++ __nat25_generate_ipv4_network_addr(networkAddr, sender); ++ __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); ++ __nat25_db_print(priv); ++ return 0; ++ default: ++ return -1; ++ } ++ } else if ((protocol == ETH_P_PPP_DISC) || ++ (protocol == ETH_P_PPP_SES)) { ++ /*---------------------------------------------------*/ ++ /* Handle PPPoE frame */ ++ /*---------------------------------------------------*/ ++ struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN); ++ unsigned short *pMagic; ++ ++ switch (method) { ++ case NAT25_CHECK: ++ if (ph->sid == 0) ++ return 0; ++ return 1; ++ case NAT25_INSERT: ++ if (ph->sid == 0) { /* Discovery phase according to tag */ ++ if (ph->code == PADI_CODE || ph->code == PADR_CODE) { ++ if (priv->ethBrExtInfo.addPPPoETag) { ++ struct pppoe_tag *tag, *pOldTag; ++ unsigned char tag_buf[40]; ++ int old_tag_len = 0; ++ ++ tag = (struct pppoe_tag *)tag_buf; ++ pOldTag = (struct pppoe_tag *)__nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID)); ++ if (pOldTag) { /* if SID existed, copy old value and delete it */ ++ old_tag_len = ntohs(pOldTag->tag_len); ++ if (old_tag_len+TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN > sizeof(tag_buf)) { ++ DEBUG_ERR("SID tag length too long!\n"); ++ return -1; ++ } ++ ++ memcpy(tag->tag_data+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN, ++ pOldTag->tag_data, old_tag_len); ++ ++ if (skb_pull_and_merge(skb, (unsigned char *)pOldTag, TAG_HDR_LEN+old_tag_len) < 0) { ++ DEBUG_ERR("call skb_pull_and_merge() failed in PADI/R packet!\n"); ++ return -1; ++ } ++ ph->length = htons(ntohs(ph->length)-TAG_HDR_LEN-old_tag_len); ++ } ++ ++ tag->tag_type = PTT_RELAY_SID; ++ tag->tag_len = htons(MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN+old_tag_len); ++ ++ /* insert the magic_code+client mac in relay tag */ ++ pMagic = (unsigned short *)tag->tag_data; ++ *pMagic = htons(MAGIC_CODE); ++ memcpy(tag->tag_data+MAGIC_CODE_LEN, skb->data+ETH_ALEN, ETH_ALEN); ++ ++ /* Add relay tag */ ++ if (__nat25_add_pppoe_tag(skb, tag) < 0) ++ return -1; ++ ++ DEBUG_INFO("NAT25: Insert PPPoE, forward %s packet\n", ++ (ph->code == PADI_CODE ? "PADI" : "PADR")); ++ } else { /* not add relay tag */ ++ if (priv->pppoe_connection_in_progress && ++ memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) { ++ DEBUG_ERR("Discard PPPoE packet due to another PPPoE connection is in progress!\n"); ++ return -2; ++ } ++ ++ if (priv->pppoe_connection_in_progress == 0) ++ memcpy(priv->pppoe_addr, skb->data+ETH_ALEN, ETH_ALEN); ++ ++ priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE; ++ } ++ } else { ++ return -1; ++ } ++ } else { /* session phase */ ++ DEBUG_INFO("NAT25: Insert PPPoE, insert session packet to %s\n", skb->dev->name); ++ ++ __nat25_generate_pppoe_network_addr(networkAddr, skb->data, &ph->sid); ++ ++ __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); ++ ++ __nat25_db_print(priv); ++ ++ if (!priv->ethBrExtInfo.addPPPoETag && ++ priv->pppoe_connection_in_progress && ++ !memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) ++ priv->pppoe_connection_in_progress = 0; ++ } ++ return 0; ++ default: ++ return -1; ++ } ++ } else if (protocol == 0x888e) { ++ /*---------------------------------------------------*/ ++ /* Handle EAP frame */ ++ /*---------------------------------------------------*/ ++ switch (method) { ++ case NAT25_CHECK: ++ return -1; ++ case NAT25_INSERT: ++ return 0; ++ default: ++ return -1; ++ } ++ } else if ((protocol == 0xe2ae) || (protocol == 0xe2af)) { ++ /*---------------------------------------------------*/ ++ /* Handle C-Media proprietary frame */ ++ /*---------------------------------------------------*/ ++ switch (method) { ++ case NAT25_CHECK: ++ return -1; ++ case NAT25_INSERT: ++ return 0; ++ default: ++ return -1; ++ } ++ } else if (protocol == ETH_P_IPV6) { ++ /*------------------------------------------------*/ ++ /* Handle IPV6 frame */ ++ /*------------------------------------------------*/ ++ struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN); ++ ++ if (sizeof(*iph) >= (skb->len - ETH_HLEN)) { ++ DEBUG_WARN("NAT25: malformed IPv6 packet !\n"); ++ return -1; ++ } ++ ++ switch (method) { ++ case NAT25_CHECK: ++ if (skb->data[0] & 1) ++ return 0; ++ return -1; ++ case NAT25_INSERT: ++ DEBUG_INFO("NAT25: Insert IP, SA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x," ++ " DA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n", ++ iph->saddr.s6_addr16[0], iph->saddr.s6_addr16[1], iph->saddr.s6_addr16[2], iph->saddr.s6_addr16[3], ++ iph->saddr.s6_addr16[4], iph->saddr.s6_addr16[5], iph->saddr.s6_addr16[6], iph->saddr.s6_addr16[7], ++ iph->daddr.s6_addr16[0], iph->daddr.s6_addr16[1], iph->daddr.s6_addr16[2], iph->daddr.s6_addr16[3], ++ iph->daddr.s6_addr16[4], iph->daddr.s6_addr16[5], iph->daddr.s6_addr16[6], iph->daddr.s6_addr16[7]); ++ ++ if (memcmp(&iph->saddr, "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16)) { ++ __nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->saddr); ++ __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); ++ __nat25_db_print(priv); ++ ++ if (iph->nexthdr == IPPROTO_ICMPV6 && ++ skb->len > (ETH_HLEN + sizeof(*iph) + 4)) { ++ if (update_nd_link_layer_addr(skb->data + ETH_HLEN + sizeof(*iph), ++ skb->len - ETH_HLEN - sizeof(*iph), GET_MY_HWADDR(priv))) { ++ struct icmp6hdr *hdr = (struct icmp6hdr *)(skb->data + ETH_HLEN + sizeof(*iph)); ++ hdr->icmp6_cksum = 0; ++ hdr->icmp6_cksum = csum_ipv6_magic(&iph->saddr, &iph->daddr, ++ iph->payload_len, ++ IPPROTO_ICMPV6, ++ csum_partial((__u8 *)hdr, iph->payload_len, 0)); ++ } ++ } ++ } ++ return 0; ++ default: ++ return -1; ++ } ++ } ++ return -1; ++} ++ ++#define SERVER_PORT 67 ++#define CLIENT_PORT 68 ++#define DHCP_MAGIC 0x63825363 ++#define BROADCAST_FLAG 0x8000 ++ ++struct dhcpMessage { ++ u_int8_t op; ++ u_int8_t htype; ++ u_int8_t hlen; ++ u_int8_t hops; ++ u_int32_t xid; ++ __be16 secs; ++ __be16 flags; ++ __be32 ciaddr; ++ __be32 yiaddr; ++ __be32 siaddr; ++ __be32 giaddr; ++ u_int8_t chaddr[16]; ++ u_int8_t sname[64]; ++ u_int8_t file[128]; ++ __be32 cookie; ++ u_int8_t options[308]; /* 312 - cookie */ ++}; ++ ++void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb) ++{ ++ if (!skb) ++ return; ++ ++ if (!priv->ethBrExtInfo.dhcp_bcst_disable) { ++ __be16 protocol = *((__be16 *)(skb->data + 2 * ETH_ALEN)); ++ ++ if (protocol == __constant_htons(ETH_P_IP)) { /* IP */ ++ struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN); ++ ++ if (iph->protocol == IPPROTO_UDP) { /* UDP */ ++ struct udphdr *udph = (struct udphdr *)((size_t)iph + (iph->ihl << 2)); ++ ++ if ((udph->source == __constant_htons(CLIENT_PORT)) && ++ (udph->dest == __constant_htons(SERVER_PORT))) { /* DHCP request */ ++ struct dhcpMessage *dhcph = ++ (struct dhcpMessage *)((size_t)udph + sizeof(struct udphdr)); ++ u32 cookie = be32_to_cpu((__be32)dhcph->cookie); ++ ++ if (cookie == DHCP_MAGIC) { /* match magic word */ ++ if (!(dhcph->flags & htons(BROADCAST_FLAG))) { ++ /* if not broadcast */ ++ register int sum = 0; ++ ++ DEBUG_INFO("DHCP: change flag of DHCP request to broadcast.\n"); ++ /* or BROADCAST flag */ ++ dhcph->flags |= htons(BROADCAST_FLAG); ++ /* recalculate checksum */ ++ sum = ~(udph->check) & 0xffff; ++ sum += be16_to_cpu(dhcph->flags); ++ while (sum >> 16) ++ sum = (sum & 0xffff) + (sum >> 16); ++ udph->check = ~sum; ++ } ++ } ++ } ++ } ++ } ++ } ++} ++ ++void *scdb_findEntry(struct adapter *priv, unsigned char *macAddr, ++ unsigned char *ipAddr) ++{ ++ unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; ++ struct nat25_network_db_entry *db; ++ int hash; ++ ++ __nat25_generate_ipv4_network_addr(networkAddr, (unsigned int *)ipAddr); ++ hash = __nat25_network_hash(networkAddr); ++ db = priv->nethash[hash]; ++ while (db) { ++ if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) { ++ return (void *)db; ++ } ++ ++ db = db->next_hash; ++ } ++ ++ return NULL; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_cmd.c b/drivers/staging/r8188eu/core/rtw_cmd.c +new file mode 100644 +index 000000000000..ce73ac7cf973 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_cmd.c +@@ -0,0 +1,2128 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_CMD_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/mlme_osdep.h" ++#include "../include/rtw_br_ext.h" ++#include "../include/rtw_mlme_ext.h" ++ ++/* ++Caller and the rtw_cmd_thread can protect cmd_q by spin_lock. ++No irqsave is necessary. ++*/ ++ ++static int _rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) ++{ ++ int res = _SUCCESS; ++ ++ sema_init(&pcmdpriv->cmd_queue_sema, 0); ++ /* sema_init(&(pcmdpriv->cmd_done_sema), 0); */ ++ sema_init(&pcmdpriv->terminate_cmdthread_sema, 0); ++ ++ _rtw_init_queue(&pcmdpriv->cmd_queue); ++ ++ /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ ++ ++ pcmdpriv->cmd_seq = 1; ++ ++ pcmdpriv->cmd_allocated_buf = kzalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ, ++ GFP_KERNEL); ++ ++ if (!pcmdpriv->cmd_allocated_buf) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ - ((size_t)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ - 1)); ++ ++ pcmdpriv->rsp_allocated_buf = kzalloc(MAX_RSPSZ + 4, GFP_KERNEL); ++ ++ if (!pcmdpriv->rsp_allocated_buf) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - ((size_t)(pcmdpriv->rsp_allocated_buf) & 3); ++ ++ pcmdpriv->cmd_issued_cnt = 0; ++ pcmdpriv->cmd_done_cnt = 0; ++ pcmdpriv->rsp_cnt = 0; ++exit: ++ ++ return res; ++} ++ ++static void c2h_wk_callback(struct work_struct *work); ++ ++static int _rtw_init_evt_priv(struct evt_priv *pevtpriv) ++{ ++ int res = _SUCCESS; ++ ++ /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ ++ atomic_set(&pevtpriv->event_seq, 0); ++ pevtpriv->evt_done_cnt = 0; ++ ++ _init_workitem(&pevtpriv->c2h_wk, c2h_wk_callback, NULL); ++ pevtpriv->c2h_wk_alive = false; ++ pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN + 1); ++ ++ return res; ++} ++ ++void rtw_free_evt_priv(struct evt_priv *pevtpriv) ++{ ++ _cancel_workitem_sync(&pevtpriv->c2h_wk); ++ while (pevtpriv->c2h_wk_alive) ++ msleep(10); ++ ++ while (!rtw_cbuf_empty(pevtpriv->c2h_queue)) { ++ void *c2h = rtw_cbuf_pop(pevtpriv->c2h_queue); ++ if (c2h && c2h != (void *)pevtpriv) ++ kfree(c2h); ++ } ++} ++ ++static void _rtw_free_cmd_priv(struct cmd_priv *pcmdpriv) ++{ ++ if (pcmdpriv) { ++ kfree(pcmdpriv->cmd_allocated_buf); ++ kfree(pcmdpriv->rsp_allocated_buf); ++ } ++} ++ ++/* ++Calling Context: ++ ++rtw_enqueue_cmd can only be called between kernel thread, ++since only spin_lock is used. ++ ++ISR/Call-Back functions can't call this sub-function. ++ ++*/ ++ ++static int _rtw_enqueue_cmd(struct __queue *queue, struct cmd_obj *obj) ++{ ++ unsigned long flags; ++ ++ if (!obj) ++ goto exit; ++ ++ spin_lock_irqsave(&queue->lock, flags); ++ ++ list_add_tail(&obj->list, &queue->queue); ++ ++ spin_unlock_irqrestore(&queue->lock, flags); ++ ++exit: ++ ++ return _SUCCESS; ++} ++ ++static struct cmd_obj *_rtw_dequeue_cmd(struct __queue *queue) ++{ ++ struct cmd_obj *obj; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&queue->lock, flags); ++ if (list_empty(&queue->queue)) { ++ obj = NULL; ++ } else { ++ obj = container_of((&queue->queue)->next, struct cmd_obj, list); ++ rtw_list_delete(&obj->list); ++ } ++ ++ spin_unlock_irqrestore(&queue->lock, flags); ++ ++ return obj; ++} ++ ++u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) ++{ ++ u32 res; ++ ++ res = _rtw_init_cmd_priv(pcmdpriv); ++ ++ return res; ++} ++ ++u32 rtw_init_evt_priv(struct evt_priv *pevtpriv) ++{ ++ int res; ++ ++ res = _rtw_init_evt_priv(pevtpriv); ++ ++ return res; ++} ++ ++void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv) ++{ ++ _rtw_free_cmd_priv(pcmdpriv); ++} ++ ++static int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) ++{ ++ u8 bAllow = false; /* set to true to allow enqueuing cmd when hw_init_completed is false */ ++ ++ /* To decide allow or not */ ++ if ((pcmdpriv->padapter->pwrctrlpriv.bHWPwrPindetect) && ++ (!pcmdpriv->padapter->registrypriv.usbss_enable)) { ++ if (cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)cmd_obj->parmbuf; ++ if (pdrvextra_cmd_parm->ec_id == POWER_SAVING_CTRL_WK_CID) ++ bAllow = true; ++ } ++ } ++ ++ if (cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan)) ++ bAllow = true; ++ ++ if ((!pcmdpriv->padapter->hw_init_completed && !bAllow) || ++ !pcmdpriv->cmdthd_running) /* com_thread not running */ ++ return _FAIL; ++ return _SUCCESS; ++} ++ ++u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) ++{ ++ int res = _FAIL; ++ struct adapter *padapter = pcmdpriv->padapter; ++ ++ if (!cmd_obj) ++ goto exit; ++ ++ cmd_obj->padapter = padapter; ++ ++ res = rtw_cmd_filter(pcmdpriv, cmd_obj); ++ if (_FAIL == res) { ++ rtw_free_cmd_obj(cmd_obj); ++ goto exit; ++ } ++ ++ res = _rtw_enqueue_cmd(&pcmdpriv->cmd_queue, cmd_obj); ++ ++ if (res == _SUCCESS) ++ up(&pcmdpriv->cmd_queue_sema); ++ ++exit: ++ ++ return res; ++} ++ ++struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv) ++{ ++ struct cmd_obj *cmd_obj; ++ ++ cmd_obj = _rtw_dequeue_cmd(&pcmdpriv->cmd_queue); ++ ++ return cmd_obj; ++} ++ ++void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv) ++{ ++ ++ pcmdpriv->cmd_done_cnt++; ++ /* up(&(pcmdpriv->cmd_done_sema)); */ ++ ++} ++ ++void rtw_free_cmd_obj(struct cmd_obj *pcmd) ++{ ++ ++ if ((pcmd->cmdcode != _JoinBss_CMD_) && (pcmd->cmdcode != _CreateBss_CMD_)) { ++ /* free parmbuf in cmd_obj */ ++ kfree(pcmd->parmbuf); ++ } ++ ++ if (pcmd->rsp) { ++ if (pcmd->rspsz != 0) { ++ /* free rsp in cmd_obj */ ++ kfree(pcmd->rsp); ++ } ++ } ++ ++ /* free cmd_obj */ ++ kfree(pcmd); ++ ++} ++ ++int rtw_cmd_thread(void *context) ++{ ++ u8 ret; ++ struct cmd_obj *pcmd; ++ u8 *pcmdbuf; ++ u8 (*cmd_hdl)(struct adapter *padapter, u8 *pbuf); ++ void (*pcmd_callback)(struct adapter *dev, struct cmd_obj *pcmd); ++ struct adapter *padapter = (struct adapter *)context; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ thread_enter("RTW_CMD_THREAD"); ++ ++ pcmdbuf = pcmdpriv->cmd_buf; ++ ++ pcmdpriv->cmdthd_running = true; ++ up(&pcmdpriv->terminate_cmdthread_sema); ++ ++ while (1) { ++ if (_rtw_down_sema(&pcmdpriv->cmd_queue_sema) == _FAIL) ++ break; ++ ++ if (padapter->bDriverStopped || ++ padapter->bSurpriseRemoved) { ++ DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n", ++ __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__); ++ break; ++ } ++_next: ++ if (padapter->bDriverStopped || ++ padapter->bSurpriseRemoved) { ++ DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n", ++ __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__); ++ break; ++ } ++ ++ pcmd = rtw_dequeue_cmd(pcmdpriv); ++ if (!pcmd) ++ continue; ++ ++ if (_FAIL == rtw_cmd_filter(pcmdpriv, pcmd)) { ++ pcmd->res = H2C_DROPPED; ++ goto post_process; ++ } ++ ++ pcmdpriv->cmd_issued_cnt++; ++ ++ pcmd->cmdsz = _RND4((pcmd->cmdsz));/* _RND4 */ ++ ++ memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz); ++ ++ if (pcmd->cmdcode < ARRAY_SIZE(wlancmds)) { ++ cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns; ++ ++ if (cmd_hdl) { ++ ret = cmd_hdl(pcmd->padapter, pcmdbuf); ++ pcmd->res = ret; ++ } ++ ++ pcmdpriv->cmd_seq++; ++ } else { ++ pcmd->res = H2C_PARAMETERS_ERROR; ++ } ++ ++ cmd_hdl = NULL; ++ ++post_process: ++ ++ /* call callback function for post-processed */ ++ if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) { ++ pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback; ++ if (!pcmd_callback) ++ rtw_free_cmd_obj(pcmd); ++ else ++ /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!= NULL) */ ++ pcmd_callback(pcmd->padapter, pcmd);/* need conider that free cmd_obj in rtw_cmd_callback */ ++ } else { ++ rtw_free_cmd_obj(pcmd); ++ } ++ ++ flush_signals_thread(); ++ ++ goto _next; ++ } ++ pcmdpriv->cmdthd_running = false; ++ ++ /* free all cmd_obj resources */ ++ do { ++ pcmd = rtw_dequeue_cmd(pcmdpriv); ++ if (!pcmd) ++ break; ++ ++ /* DBG_88E("%s: leaving... drop cmdcode:%u\n", __func__, pcmd->cmdcode); */ ++ ++ rtw_free_cmd_obj(pcmd); ++ } while (1); ++ ++ up(&pcmdpriv->terminate_cmdthread_sema); ++ ++ thread_exit(); ++} ++ ++u8 rtw_setstandby_cmd(struct adapter *padapter, uint action) ++{ ++ struct cmd_obj *ph2c; ++ struct usb_suspend_parm *psetusbsuspend; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ u8 ret = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ psetusbsuspend = kzalloc(sizeof(struct usb_suspend_parm), GFP_ATOMIC); ++ if (!psetusbsuspend) { ++ kfree(ph2c); ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ psetusbsuspend->action = action; ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psetusbsuspend, GEN_CMD_CODE(_SetUsbSuspend)); ++ ++ ret = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return ret; ++} ++ ++/* ++rtw_sitesurvey_cmd(~) ++ ### NOTE:#### (!!!!) ++ MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock ++*/ ++u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, int ssid_num, ++ struct rtw_ieee80211_channel *ch, int ch_num) ++{ ++ u8 res = _FAIL; ++ struct cmd_obj *ph2c; ++ struct sitesurvey_parm *psurveyPara; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1); ++ } ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ p2p_ps_wk_cmd(padapter, P2P_PS_SCAN, 1); ++ } ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) ++ return _FAIL; ++ ++ psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC); ++ if (!psurveyPara) { ++ kfree(ph2c); ++ return _FAIL; ++ } ++ ++ rtw_free_network_queue(padapter, false); ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey)); ++ ++ /* psurveyPara->bsslimit = 48; */ ++ psurveyPara->scan_mode = pmlmepriv->scan_mode; ++ ++ /* prepare ssid list */ ++ if (ssid) { ++ int i; ++ for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) { ++ if (ssid[i].SsidLength) { ++ memcpy(&psurveyPara->ssid[i], &ssid[i], sizeof(struct ndis_802_11_ssid)); ++ psurveyPara->ssid_num++; ++ } ++ } ++ } ++ ++ /* prepare channel list */ ++ if (ch) { ++ int i; ++ for (i = 0; i < ch_num && i < RTW_CHANNEL_SCAN_AMOUNT; i++) { ++ if (ch[i].hw_value && !(ch[i].flags & RTW_IEEE80211_CHAN_DISABLED)) { ++ memcpy(&psurveyPara->ch[i], &ch[i], sizeof(struct rtw_ieee80211_channel)); ++ psurveyPara->ch_num++; ++ } ++ } ++ } ++ ++ set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++ if (res == _SUCCESS) { ++ pmlmepriv->scan_start_time = jiffies; ++ ++ _set_timer(&pmlmepriv->scan_to_timer, SCANNING_TIMEOUT); ++ ++ rtw_led_control(padapter, LED_CTL_SITE_SURVEY); ++ ++ pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */ ++ } else { ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); ++ } ++ ++ return res; ++} ++ ++u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset) ++{ ++ struct cmd_obj *ph2c; ++ struct setdatarate_parm *pbsetdataratepara; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pbsetdataratepara = kzalloc(sizeof(struct setdatarate_parm), GFP_ATOMIC); ++ if (!pbsetdataratepara) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate)); ++ pbsetdataratepara->mac_id = 5; ++ memcpy(pbsetdataratepara->datarates, rateset, NumRates); ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_setbasicrate_cmd(struct adapter *padapter, u8 *rateset) ++{ ++ struct cmd_obj *ph2c; ++ struct setbasicrate_parm *pssetbasicratepara; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ pssetbasicratepara = kzalloc(sizeof(struct setbasicrate_parm), GFP_ATOMIC); ++ ++ if (!pssetbasicratepara) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pssetbasicratepara, _SetBasicRate_CMD_); ++ ++ memcpy(pssetbasicratepara->basicrates, rateset, NumRates); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++/* ++unsigned char rtw_setphy_cmd(unsigned char *adapter) ++ ++1. be called only after rtw_update_registrypriv_dev_network(~) or mp testing program ++2. for AdHoc/Ap mode or mp mode? ++ ++*/ ++u8 rtw_setphy_cmd(struct adapter *padapter, u8 modem, u8 ch) ++{ ++ struct cmd_obj *ph2c; ++ struct setphy_parm *psetphypara; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ psetphypara = kzalloc(sizeof(struct setphy_parm), GFP_ATOMIC); ++ ++ if (!psetphypara) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psetphypara, _SetPhy_CMD_); ++ ++ psetphypara->modem = modem; ++ psetphypara->rfchannel = ch; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_setbbreg_cmd(struct adapter *padapter, u8 offset, u8 val) ++{ ++ struct cmd_obj *ph2c; ++ struct writeBB_parm *pwritebbparm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ pwritebbparm = kzalloc(sizeof(struct writeBB_parm), GFP_ATOMIC); ++ ++ if (!pwritebbparm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pwritebbparm, GEN_CMD_CODE(_SetBBReg)); ++ ++ pwritebbparm->offset = offset; ++ pwritebbparm->value = val; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_getbbreg_cmd(struct adapter *padapter, u8 offset, u8 *pval) ++{ ++ struct cmd_obj *ph2c; ++ struct readBB_parm *prdbbparm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ prdbbparm = kzalloc(sizeof(struct readBB_parm), GFP_ATOMIC); ++ ++ if (!prdbbparm) { ++ kfree(ph2c); ++ return _FAIL; ++ } ++ ++ INIT_LIST_HEAD(&ph2c->list); ++ ph2c->cmdcode = GEN_CMD_CODE(_GetBBReg); ++ ph2c->parmbuf = (unsigned char *)prdbbparm; ++ ph2c->cmdsz = sizeof(struct readBB_parm); ++ ph2c->rsp = pval; ++ ph2c->rspsz = sizeof(struct readBB_rsp); ++ ++ prdbbparm->offset = offset; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_setrfreg_cmd(struct adapter *padapter, u8 offset, u32 val) ++{ ++ struct cmd_obj *ph2c; ++ struct writeRF_parm *pwriterfparm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ pwriterfparm = kzalloc(sizeof(struct writeRF_parm), GFP_ATOMIC); ++ ++ if (!pwriterfparm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg)); ++ ++ pwriterfparm->offset = offset; ++ pwriterfparm->value = val; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_getrfreg_cmd(struct adapter *padapter, u8 offset, u8 *pval) ++{ ++ struct cmd_obj *ph2c; ++ struct readRF_parm *prdrfparm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ prdrfparm = kzalloc(sizeof(struct readRF_parm), GFP_ATOMIC); ++ if (!prdrfparm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ INIT_LIST_HEAD(&ph2c->list); ++ ph2c->cmdcode = GEN_CMD_CODE(_GetRFReg); ++ ph2c->parmbuf = (unsigned char *)prdrfparm; ++ ph2c->cmdsz = sizeof(struct readRF_parm); ++ ph2c->rsp = pval; ++ ph2c->rspsz = sizeof(struct readRF_rsp); ++ ++ prdrfparm->offset = offset; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++} ++ ++void rtw_getbbrfreg_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ ++ ++ kfree(pcmd->parmbuf); ++ kfree(pcmd); ++ ++ if (padapter->registrypriv.mp_mode == 1) ++ padapter->mppriv.workparam.bcompleted = true; ++ ++} ++ ++void rtw_readtssi_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ ++ ++ kfree(pcmd->parmbuf); ++ kfree(pcmd); ++ ++ if (padapter->registrypriv.mp_mode == 1) ++ padapter->mppriv.workparam.bcompleted = true; ++ ++} ++ ++u8 rtw_createbss_cmd(struct adapter *padapter) ++{ ++ struct cmd_obj *pcmd; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct wlan_bssid_ex *pdev_network = &padapter->registrypriv.dev_network; ++ u8 res = _SUCCESS; ++ ++ rtw_led_control(padapter, LED_CTL_START_TO_LINK); ++ ++ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmd) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ INIT_LIST_HEAD(&pcmd->list); ++ pcmd->cmdcode = _CreateBss_CMD_; ++ pcmd->parmbuf = (unsigned char *)pdev_network; ++ pcmd->cmdsz = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network); ++ pcmd->rsp = NULL; ++ pcmd->rspsz = 0; ++ pdev_network->Length = pcmd->cmdsz; ++ res = rtw_enqueue_cmd(pcmdpriv, pcmd); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_createbss_cmd_ex(struct adapter *padapter, unsigned char *pbss, unsigned int sz) ++{ ++ struct cmd_obj *pcmd; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmd) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ INIT_LIST_HEAD(&pcmd->list); ++ pcmd->cmdcode = GEN_CMD_CODE(_CreateBss); ++ pcmd->parmbuf = pbss; ++ pcmd->cmdsz = sz; ++ pcmd->rsp = NULL; ++ pcmd->rspsz = 0; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, pcmd); ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) ++{ ++ u8 res = _SUCCESS; ++ uint t_len = 0; ++ struct wlan_bssid_ex *psecnetwork; ++ struct cmd_obj *pcmd; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct qos_priv *pqospriv = &pmlmepriv->qospriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ enum ndis_802_11_network_infra ndis_network_mode = pnetwork->network.InfrastructureMode; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ rtw_led_control(padapter, LED_CTL_START_TO_LINK); ++ ++ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmd) { ++ res = _FAIL; ++ goto exit; ++ } ++ /* for IEs is fix buf size */ ++ t_len = sizeof(struct wlan_bssid_ex); ++ ++ /* for hidden ap to set fw_state here */ ++ if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE)) { ++ switch (ndis_network_mode) { ++ case Ndis802_11IBSS: ++ set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); ++ break; ++ case Ndis802_11Infrastructure: ++ set_fwstate(pmlmepriv, WIFI_STATION_STATE); ++ break; ++ case Ndis802_11APMode: ++ case Ndis802_11AutoUnknown: ++ case Ndis802_11InfrastructureMax: ++ break; ++ } ++ } ++ ++ psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss; ++ if (!psecnetwork) { ++ kfree(pcmd); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ memset(psecnetwork, 0, t_len); ++ ++ memcpy(psecnetwork, &pnetwork->network, get_wlan_bssid_ex_sz(&pnetwork->network)); ++ ++ psecuritypriv->authenticator_ie[0] = (unsigned char)psecnetwork->IELength; ++ ++ if (psecnetwork->IELength - 12 < 255) { ++ memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], psecnetwork->IELength - 12); ++ } else { ++ memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], 255); ++ } ++ ++ psecnetwork->IELength = 0; ++ /* Added by Albert 2009/02/18 */ ++ /* If the the driver wants to use the bssid to create the connection. */ ++ /* If not, we have to copy the connecting AP's MAC address to it so that */ ++ /* the driver just has the bssid information for PMKIDList searching. */ ++ ++ if (!pmlmepriv->assoc_by_bssid) ++ memcpy(&pmlmepriv->assoc_bssid[0], &pnetwork->network.MacAddress[0], ETH_ALEN); ++ ++ psecnetwork->IELength = rtw_restruct_sec_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength); ++ ++ pqospriv->qos_option = 0; ++ ++ if (pregistrypriv->wmm_enable) { ++ u32 tmp_len; ++ ++ tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength, psecnetwork->IELength); ++ ++ if (psecnetwork->IELength != tmp_len) { ++ psecnetwork->IELength = tmp_len; ++ pqospriv->qos_option = 1; /* There is WMM IE in this corresp. beacon */ ++ } else { ++ pqospriv->qos_option = 0;/* There is no WMM IE in this corresp. beacon */ ++ } ++ } ++ ++ phtpriv->ht_option = false; ++ if (pregistrypriv->ht_enable) { ++ /* Added by Albert 2010/06/23 */ ++ /* For the WEP mode, we will use the bg mode to do the connection to avoid some IOT issue. */ ++ /* Especially for Realtek 8192u SoftAP. */ ++ if ((padapter->securitypriv.dot11PrivacyAlgrthm != _WEP40_) && ++ (padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_) && ++ (padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_)) { ++ /* rtw_restructure_ht_ie */ ++ rtw_restructure_ht_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], ++ pnetwork->network.IELength, &psecnetwork->IELength); ++ } ++ } ++ ++ pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.IEs, pnetwork->network.IELength); ++ ++ if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_TENDA) ++ padapter->pwrctrlpriv.smart_ps = 0; ++ else ++ padapter->pwrctrlpriv.smart_ps = padapter->registrypriv.smart_ps; ++ ++ DBG_88E("%s: smart_ps =%d\n", __func__, padapter->pwrctrlpriv.smart_ps); ++ ++ pcmd->cmdsz = get_wlan_bssid_ex_sz(psecnetwork);/* get cmdsz before endian conversion */ ++ ++ INIT_LIST_HEAD(&pcmd->list); ++ pcmd->cmdcode = _JoinBss_CMD_;/* GEN_CMD_CODE(_JoinBss) */ ++ pcmd->parmbuf = (unsigned char *)psecnetwork; ++ pcmd->rsp = NULL; ++ pcmd->rspsz = 0; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, pcmd); ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueue) /* for sta_mode */ ++{ ++ struct cmd_obj *cmdobj = NULL; ++ struct disconnect_parm *param = NULL; ++ struct cmd_priv *cmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ /* prepare cmd parameter */ ++ param = kzalloc(sizeof(*param), GFP_ATOMIC); ++ if (!param) { ++ res = _FAIL; ++ goto exit; ++ } ++ param->deauth_timeout_ms = deauth_timeout_ms; ++ ++ if (enqueue) { ++ /* need enqueue, prepare cmd_obj and enqueue */ ++ cmdobj = kzalloc(sizeof(*cmdobj), GFP_ATOMIC); ++ if (!cmdobj) { ++ res = _FAIL; ++ kfree(param); ++ goto exit; ++ } ++ init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_); ++ res = rtw_enqueue_cmd(cmdpriv, cmdobj); ++ } else { ++ /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ ++ if (H2C_SUCCESS != disconnect_hdl(padapter, (u8 *)param)) ++ res = _FAIL; ++ kfree(param); ++ } ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_setopmode_cmd(struct adapter *padapter, enum ndis_802_11_network_infra networktype) ++{ ++ struct cmd_obj *ph2c; ++ struct setopmode_parm *psetop; ++ ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!ph2c) { ++ res = false; ++ goto exit; ++ } ++ psetop = kzalloc(sizeof(struct setopmode_parm), GFP_KERNEL); ++ ++ if (!psetop) { ++ kfree(ph2c); ++ res = false; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_); ++ psetop->mode = (u8)networktype; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key) ++{ ++ struct cmd_obj *ph2c; ++ struct set_stakey_parm *psetstakey_para; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct set_stakey_rsp *psetstakey_rsp = NULL; ++ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct sta_info *sta = (struct sta_info *)psta; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL); ++ if (!psetstakey_para) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), GFP_KERNEL); ++ if (!psetstakey_rsp) { ++ kfree(ph2c); ++ kfree(psetstakey_para); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); ++ ph2c->rsp = (u8 *)psetstakey_rsp; ++ ph2c->rspsz = sizeof(struct set_stakey_rsp); ++ ++ memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN); ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) ++ psetstakey_para->algorithm = (unsigned char)psecuritypriv->dot11PrivacyAlgrthm; ++ else ++ GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, false); ++ ++ if (unicast_key) ++ memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16); ++ else ++ memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16); ++ ++ /* jeff: set this because at least sw key is ready */ ++ padapter->securitypriv.busetkipkey = true; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry, u8 enqueue) ++{ ++ struct cmd_obj *ph2c; ++ struct set_stakey_parm *psetstakey_para; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct set_stakey_rsp *psetstakey_rsp = NULL; ++ struct sta_info *sta = (struct sta_info *)psta; ++ u8 res = _SUCCESS; ++ ++ if (!enqueue) { ++ clear_cam_entry(padapter, entry); ++ } else { ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), ++ GFP_ATOMIC); ++ if (!psetstakey_para) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), ++ GFP_ATOMIC); ++ if (!psetstakey_rsp) { ++ kfree(ph2c); ++ kfree(psetstakey_para); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); ++ ph2c->rsp = (u8 *)psetstakey_rsp; ++ ph2c->rspsz = sizeof(struct set_stakey_rsp); ++ ++ memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN); ++ ++ psetstakey_para->algorithm = _NO_PRIVACY_; ++ ++ psetstakey_para->id = entry; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ } ++exit: ++ ++ return res; ++} ++ ++u8 rtw_setrttbl_cmd(struct adapter *padapter, struct setratable_parm *prate_table) ++{ ++ struct cmd_obj *ph2c; ++ struct setratable_parm *psetrttblparm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ psetrttblparm = kzalloc(sizeof(struct setratable_parm), GFP_KERNEL); ++ ++ if (!psetrttblparm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable)); ++ ++ memcpy(psetrttblparm, prate_table, sizeof(struct setratable_parm)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_getrttbl_cmd(struct adapter *padapter, struct getratable_rsp *pval) ++{ ++ struct cmd_obj *ph2c; ++ struct getratable_parm *pgetrttblparm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ pgetrttblparm = kzalloc(sizeof(struct getratable_parm), GFP_KERNEL); ++ ++ if (!pgetrttblparm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++/* init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable)); */ ++ ++ INIT_LIST_HEAD(&ph2c->list); ++ ph2c->cmdcode = GEN_CMD_CODE(_GetRaTable); ++ ph2c->parmbuf = (unsigned char *)pgetrttblparm; ++ ph2c->cmdsz = sizeof(struct getratable_parm); ++ ph2c->rsp = (u8 *)pval; ++ ph2c->rspsz = sizeof(struct getratable_rsp); ++ ++ pgetrttblparm->rsvd = 0x0; ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_setassocsta_cmd(struct adapter *padapter, u8 *mac_addr) ++{ ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct cmd_obj *ph2c; ++ struct set_assocsta_parm *psetassocsta_para; ++ struct set_stakey_rsp *psetassocsta_rsp = NULL; ++ ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ psetassocsta_para = kzalloc(sizeof(struct set_assocsta_parm), GFP_ATOMIC); ++ if (!psetassocsta_para) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ psetassocsta_rsp = kzalloc(sizeof(struct set_assocsta_rsp), GFP_ATOMIC); ++ if (!psetassocsta_rsp) { ++ kfree(ph2c); ++ kfree(psetassocsta_para); ++ return _FAIL; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_); ++ ph2c->rsp = (u8 *)psetassocsta_rsp; ++ ph2c->rspsz = sizeof(struct set_assocsta_rsp); ++ ++ memcpy(psetassocsta_para->addr, mac_addr, ETH_ALEN); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++ } ++ ++u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr) ++{ ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct cmd_obj *ph2c; ++ struct addBaReq_parm *paddbareq_parm; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_ATOMIC); ++ if (!paddbareq_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ paddbareq_parm->tid = tid; ++ memcpy(paddbareq_parm->addr, addr, ETH_ALEN); ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq)); ++ ++ /* DBG_88E("rtw_addbareq_cmd, tid =%d\n", tid); */ ++ ++ /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = DYNAMIC_CHK_WK_CID; ++ pdrvextra_cmd_parm->type_size = 0; ++ pdrvextra_cmd_parm->pbuf = (u8 *)padapter; ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++u8 rtw_set_ch_cmd(struct adapter *padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue) ++{ ++ struct cmd_obj *pcmdobj; ++ struct set_ch_parm *set_ch_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ u8 res = _SUCCESS; ++ ++ DBG_88E(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n", ++ FUNC_NDEV_ARG(padapter->pnetdev), ch, bw, ch_offset); ++ ++ /* check input parameter */ ++ ++ /* prepare cmd parameter */ ++ set_ch_parm = kzalloc(sizeof(*set_ch_parm), GFP_ATOMIC); ++ if (!set_ch_parm) { ++ res = _FAIL; ++ goto exit; ++ } ++ set_ch_parm->ch = ch; ++ set_ch_parm->bw = bw; ++ set_ch_parm->ch_offset = ch_offset; ++ ++ if (enqueue) { ++ /* need enqueue, prepare cmd_obj and enqueue */ ++ pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmdobj) { ++ kfree(set_ch_parm); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm, GEN_CMD_CODE(_SetChannel)); ++ res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); ++ } else { ++ /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ ++ if (H2C_SUCCESS != set_ch_hdl(padapter, (u8 *)set_ch_parm)) ++ res = _FAIL; ++ ++ kfree(set_ch_parm); ++ } ++ ++ /* do something based on res... */ ++ ++exit: ++ ++ DBG_88E(FUNC_NDEV_FMT" res:%u\n", FUNC_NDEV_ARG(padapter->pnetdev), res); ++ ++ return res; ++} ++ ++u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue) ++{ ++ struct cmd_obj *pcmdobj; ++ struct SetChannelPlan_param *setChannelPlan_param; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ u8 res = _SUCCESS; ++ ++ /* check input parameter */ ++ if (!rtw_is_channel_plan_valid(chplan)) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ /* prepare cmd parameter */ ++ setChannelPlan_param = kzalloc(sizeof(struct SetChannelPlan_param), ++ GFP_KERNEL); ++ if (!setChannelPlan_param) { ++ res = _FAIL; ++ goto exit; ++ } ++ setChannelPlan_param->channel_plan = chplan; ++ ++ if (enqueue) { ++ /* need enqueue, prepare cmd_obj and enqueue */ ++ pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!pcmdobj) { ++ kfree(setChannelPlan_param); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelPlan_param, GEN_CMD_CODE(_SetChannelPlan)); ++ res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); ++ } else { ++ /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ ++ if (H2C_SUCCESS != set_chplan_hdl(padapter, (unsigned char *)setChannelPlan_param)) ++ res = _FAIL; ++ ++ kfree(setChannelPlan_param); ++ } ++ ++ /* do something based on res... */ ++ if (res == _SUCCESS) ++ padapter->mlmepriv.ChannelPlan = chplan; ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_led_blink_cmd(struct adapter *padapter, struct LED_871x *pLed) ++{ ++ struct cmd_obj *pcmdobj; ++ struct LedBlink_param *ledBlink_param; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ u8 res = _SUCCESS; ++ ++ pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmdobj) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ ledBlink_param = kzalloc(sizeof(struct LedBlink_param), GFP_ATOMIC); ++ if (!ledBlink_param) { ++ kfree(pcmdobj); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ ledBlink_param->pLed = pLed; ++ ++ init_h2fwcmd_w_parm_no_rsp(pcmdobj, ledBlink_param, GEN_CMD_CODE(_LedBlink)); ++ res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_set_csa_cmd(struct adapter *padapter, u8 new_ch_no) ++{ ++ struct cmd_obj *pcmdobj; ++ struct SetChannelSwitch_param *setChannelSwitch_param; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ u8 res = _SUCCESS; ++ ++ pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmdobj) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ setChannelSwitch_param = kzalloc(sizeof(struct SetChannelSwitch_param), ++ GFP_ATOMIC); ++ if (!setChannelSwitch_param) { ++ kfree(pcmdobj); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ setChannelSwitch_param->new_ch_no = new_ch_no; ++ ++ init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelSwitch_param, GEN_CMD_CODE(_SetChannelSwitch)); ++ res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); ++ ++exit: ++ ++ return res; ++} ++ ++u8 rtw_tdls_cmd(struct adapter *padapter, u8 *addr, u8 option) ++{ ++ return _SUCCESS; ++} ++ ++static void traffic_status_watchdog(struct adapter *padapter) ++{ ++ u8 bEnterPS; ++ u8 bBusyTraffic = false, bTxBusyTraffic = false, bRxBusyTraffic = false; ++ u8 bHigherBusyTraffic = false, bHigherBusyRxTraffic = false, bHigherBusyTxTraffic = false; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ /* */ ++ /* Determine if our traffic is busy now */ ++ /* */ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 100 || ++ pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 100) { ++ bBusyTraffic = true; ++ ++ if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) ++ bRxBusyTraffic = true; ++ else ++ bTxBusyTraffic = true; ++ } ++ ++ /* Higher Tx/Rx data. */ ++ if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 || ++ pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000) { ++ bHigherBusyTraffic = true; ++ ++ if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) ++ bHigherBusyRxTraffic = true; ++ else ++ bHigherBusyTxTraffic = true; ++ } ++ ++ /* check traffic for powersaving. */ ++ if (((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8) || ++ (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2)) ++ bEnterPS = false; ++ else ++ bEnterPS = true; ++ ++ /* LeisurePS only work in infra mode. */ ++ if (bEnterPS) ++ LPS_Enter(padapter); ++ else ++ LPS_Leave(padapter); ++ } else { ++ LPS_Leave(padapter); ++ } ++ ++ pmlmepriv->LinkDetectInfo.NumRxOkInPeriod = 0; ++ pmlmepriv->LinkDetectInfo.NumTxOkInPeriod = 0; ++ pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod = 0; ++ pmlmepriv->LinkDetectInfo.bBusyTraffic = bBusyTraffic; ++ pmlmepriv->LinkDetectInfo.bTxBusyTraffic = bTxBusyTraffic; ++ pmlmepriv->LinkDetectInfo.bRxBusyTraffic = bRxBusyTraffic; ++ pmlmepriv->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic; ++ pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic; ++ pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic; ++} ++ ++static void dynamic_chk_wk_hdl(struct adapter *padapter, u8 *pbuf, int sz) ++{ ++ struct mlme_priv *pmlmepriv; ++ ++ padapter = (struct adapter *)pbuf; ++ pmlmepriv = &padapter->mlmepriv; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ expire_timeout_chk(padapter); ++#endif ++ ++ rtw_hal_sreset_xmit_status_check(padapter); ++ ++ linked_status_chk(padapter); ++ traffic_status_watchdog(padapter); ++ ++ rtw_hal_dm_watchdog(padapter); ++} ++ ++static void lps_ctrl_wk_hdl(struct adapter *padapter, u8 lps_ctrl_type) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 mstatus; ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) ++ return; ++ ++ switch (lps_ctrl_type) { ++ case LPS_CTRL_SCAN: ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ /* connect */ ++ LPS_Leave(padapter); ++ } ++ break; ++ case LPS_CTRL_JOINBSS: ++ LPS_Leave(padapter); ++ break; ++ case LPS_CTRL_CONNECT: ++ mstatus = 1;/* connect */ ++ /* Reset LPS Setting */ ++ padapter->pwrctrlpriv.LpsIdleCount = 0; ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); ++ break; ++ case LPS_CTRL_DISCONNECT: ++ mstatus = 0;/* disconnect */ ++ LPS_Leave(padapter); ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); ++ break; ++ case LPS_CTRL_SPECIAL_PACKET: ++ /* DBG_88E("LPS_CTRL_SPECIAL_PACKET\n"); */ ++ pwrpriv->DelayLPSLastTimeStamp = jiffies; ++ LPS_Leave(padapter); ++ break; ++ case LPS_CTRL_LEAVE: ++ LPS_Leave(padapter); ++ break; ++ default: ++ break; ++ } ++ ++} ++ ++u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ /* struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; */ ++ u8 res = _SUCCESS; ++ ++ /* if (!pwrctrlpriv->bLeisurePs) */ ++ /* return res; */ ++ ++ if (enqueue) { ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), ++ GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = LPS_CTRL_WK_CID; ++ pdrvextra_cmd_parm->type_size = lps_ctrl_type; ++ pdrvextra_cmd_parm->pbuf = NULL; ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ } else { ++ lps_ctrl_wk_hdl(padapter, lps_ctrl_type); ++ } ++ ++exit: ++ ++ return res; ++} ++ ++static void rpt_timer_setting_wk_hdl(struct adapter *padapter, u16 min_time) ++{ ++ rtw_hal_set_hwreg(padapter, HW_VAR_RPT_TIMER_SETTING, (u8 *)(&min_time)); ++} ++ ++u8 rtw_rpt_timer_cfg_cmd(struct adapter *padapter, u16 min_time) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), ++ GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = RTP_TIMER_CFG_WK_CID; ++ pdrvextra_cmd_parm->type_size = min_time; ++ pdrvextra_cmd_parm->pbuf = NULL; ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ ++ return res; ++} ++ ++static void antenna_select_wk_hdl(struct adapter *padapter, u8 antenna) ++{ ++ rtw_hal_set_hwreg(padapter, HW_VAR_ANTENNA_DIVERSITY_SELECT, (u8 *)(&antenna)); ++} ++ ++u8 rtw_antenna_select_cmd(struct adapter *padapter, u8 antenna, u8 enqueue) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 support_ant_div; ++ u8 res = _SUCCESS; ++ ++ rtw_hal_get_def_var(padapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &support_ant_div); ++ if (!support_ant_div) ++ return res; ++ ++ if (enqueue) { ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), ++ GFP_KERNEL); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = ANT_SELECT_WK_CID; ++ pdrvextra_cmd_parm->type_size = antenna; ++ pdrvextra_cmd_parm->pbuf = NULL; ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ } else { ++ antenna_select_wk_hdl(padapter, antenna); ++ } ++exit: ++ ++ return res; ++} ++ ++static void power_saving_wk_hdl(struct adapter *padapter, u8 *pbuf, int sz) ++{ ++ rtw_ps_processor(padapter); ++} ++ ++#ifdef CONFIG_88EU_P2P ++u8 p2p_protocol_wk_cmd(struct adapter *padapter, int intCmdType) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return res; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = P2P_PROTO_WK_CID; ++ pdrvextra_cmd_parm->type_size = intCmdType; /* As the command tppe. */ ++ pdrvextra_cmd_parm->pbuf = NULL; /* Must be NULL here */ ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++} ++#endif /* CONFIG_88EU_P2P */ ++ ++u8 rtw_ps_cmd(struct adapter *padapter) ++{ ++ struct cmd_obj *ppscmd; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ u8 res = _SUCCESS; ++ ++ ppscmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ppscmd) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ppscmd); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID; ++ pdrvextra_cmd_parm->pbuf = NULL; ++ init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ppscmd); ++ ++exit: ++ ++ return res; ++} ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++static void rtw_chk_hi_queue_hdl(struct adapter *padapter) ++{ ++ int cnt = 0; ++ struct sta_info *psta_bmc; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ psta_bmc = rtw_get_bcmc_stainfo(padapter); ++ if (!psta_bmc) ++ return; ++ ++ if (psta_bmc->sleepq_len == 0) { ++ u8 val = 0; ++ ++ /* while ((rtw_read32(padapter, 0x414)&0x00ffff00)!= 0) */ ++ /* while ((rtw_read32(padapter, 0x414)&0x0000ff00)!= 0) */ ++ ++ rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &val); ++ ++ while (!val) { ++ msleep(100); ++ ++ cnt++; ++ ++ if (cnt > 10) ++ break; ++ ++ rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &val); ++ } ++ ++ if (cnt <= 10) { ++ pstapriv->tim_bitmap &= ~BIT(0); ++ pstapriv->sta_dz_bitmap &= ~BIT(0); ++ ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++ } else { /* re check again */ ++ rtw_chk_hi_queue_cmd(padapter); ++ } ++ } ++} ++ ++u8 rtw_chk_hi_queue_cmd(struct adapter *padapter) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = CHECK_HIQ_WK_CID; ++ pdrvextra_cmd_parm->type_size = 0; ++ pdrvextra_cmd_parm->pbuf = NULL; ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++exit: ++ return res; ++} ++#endif ++ ++u8 rtw_c2h_wk_cmd(struct adapter *padapter, u8 *c2h_evt) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = C2H_WK_CID; ++ pdrvextra_cmd_parm->type_size = c2h_evt ? 16 : 0; ++ pdrvextra_cmd_parm->pbuf = c2h_evt; ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++} ++ ++static s32 c2h_evt_hdl(struct adapter *adapter, struct c2h_evt_hdr *c2h_evt, c2h_id_filter filter) ++{ ++ s32 ret = _FAIL; ++ u8 buf[16]; ++ ++ if (!c2h_evt) { ++ /* No c2h event in cmd_obj, read c2h event before handling*/ ++ if (c2h_evt_read(adapter, buf) == _SUCCESS) { ++ c2h_evt = (struct c2h_evt_hdr *)buf; ++ ++ if (filter && !filter(c2h_evt->id)) ++ goto exit; ++ ++ ret = rtw_hal_c2h_handler(adapter, c2h_evt); ++ } ++ } else { ++ if (filter && !filter(c2h_evt->id)) ++ goto exit; ++ ++ ret = rtw_hal_c2h_handler(adapter, c2h_evt); ++ } ++exit: ++ return ret; ++} ++ ++static void c2h_wk_callback(struct work_struct *work) ++{ ++ struct evt_priv *evtpriv = container_of(work, struct evt_priv, c2h_wk); ++ struct adapter *adapter = container_of(evtpriv, struct adapter, evtpriv); ++ struct c2h_evt_hdr *c2h_evt; ++ c2h_id_filter ccx_id_filter = rtw_hal_c2h_id_filter_ccx(adapter); ++ ++ evtpriv->c2h_wk_alive = true; ++ ++ while (!rtw_cbuf_empty(evtpriv->c2h_queue)) { ++ if ((c2h_evt = (struct c2h_evt_hdr *)rtw_cbuf_pop(evtpriv->c2h_queue)) != NULL) { ++ /* This C2H event is read, clear it */ ++ c2h_evt_clear(adapter); ++ } else { ++ c2h_evt = kmalloc(16, GFP_KERNEL); ++ if (c2h_evt) { ++ /* This C2H event is not read, read & clear now */ ++ if (c2h_evt_read(adapter, (u8 *)c2h_evt) != _SUCCESS) { ++ kfree(c2h_evt); ++ continue; ++ } ++ } else { ++ return; ++ } ++ } ++ ++ /* Special pointer to trigger c2h_evt_clear only */ ++ if ((void *)c2h_evt == (void *)evtpriv) ++ continue; ++ ++ if (!c2h_evt_exist(c2h_evt)) { ++ kfree(c2h_evt); ++ continue; ++ } ++ ++ if (ccx_id_filter(c2h_evt->id)) { ++ /* Handle CCX report here */ ++ rtw_hal_c2h_handler(adapter, c2h_evt); ++ kfree(c2h_evt); ++ } else { ++#ifdef CONFIG_88EU_P2P ++ /* Enqueue into cmd_thread for others */ ++ rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt); ++#endif ++ } ++ } ++ ++ evtpriv->c2h_wk_alive = false; ++} ++ ++u8 rtw_drvextra_cmd_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ struct drvextra_cmd_parm *pdrvextra_cmd; ++ ++ if (!pbuf) ++ return H2C_PARAMETERS_ERROR; ++ ++ pdrvextra_cmd = (struct drvextra_cmd_parm *)pbuf; ++ ++ switch (pdrvextra_cmd->ec_id) { ++ case DYNAMIC_CHK_WK_CID: ++ dynamic_chk_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size); ++ break; ++ case POWER_SAVING_CTRL_WK_CID: ++ power_saving_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size); ++ break; ++ case LPS_CTRL_WK_CID: ++ lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type_size); ++ break; ++ case RTP_TIMER_CFG_WK_CID: ++ rpt_timer_setting_wk_hdl(padapter, pdrvextra_cmd->type_size); ++ break; ++ case ANT_SELECT_WK_CID: ++ antenna_select_wk_hdl(padapter, pdrvextra_cmd->type_size); ++ break; ++#ifdef CONFIG_88EU_P2P ++ case P2P_PS_WK_CID: ++ p2p_ps_wk_hdl(padapter, pdrvextra_cmd->type_size); ++ break; ++ case P2P_PROTO_WK_CID: ++ /* Commented by Albert 2011/07/01 */ ++ /* I used the type_size as the type command */ ++ p2p_protocol_wk_hdl(padapter, pdrvextra_cmd->type_size); ++ break; ++#endif ++#ifdef CONFIG_88EU_AP_MODE ++ case CHECK_HIQ_WK_CID: ++ rtw_chk_hi_queue_hdl(padapter); ++ break; ++#endif /* CONFIG_88EU_AP_MODE */ ++ case C2H_WK_CID: ++ c2h_evt_hdl(padapter, (struct c2h_evt_hdr *)pdrvextra_cmd->pbuf, NULL); ++ break; ++ default: ++ break; ++ } ++ ++ if (pdrvextra_cmd->pbuf && pdrvextra_cmd->type_size > 0) ++ kfree(pdrvextra_cmd->pbuf); ++ ++ return H2C_SUCCESS; ++} ++ ++void rtw_survey_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if (pcmd->res == H2C_DROPPED) { ++ /* TODO: cancel timer and do timeout handler directly... */ ++ /* need to make timeout handlerOS independent */ ++ _set_timer(&pmlmepriv->scan_to_timer, 1); ++ } else if (pcmd->res != H2C_SUCCESS) { ++ _set_timer(&pmlmepriv->scan_to_timer, 1); ++ } ++ ++ /* free cmd */ ++ rtw_free_cmd_obj(pcmd); ++ ++} ++void rtw_disassoc_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if (pcmd->res != H2C_SUCCESS) { ++ spin_lock_bh(&pmlmepriv->lock); ++ set_fwstate(pmlmepriv, _FW_LINKED); ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++ return; ++ } else /* clear bridge database */ ++ nat25_db_cleanup(padapter); ++ ++ /* free cmd */ ++ rtw_free_cmd_obj(pcmd); ++} ++ ++void rtw_joinbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if (pcmd->res == H2C_DROPPED) { ++ /* TODO: cancel timer and do timeout handler directly... */ ++ /* need to make timeout handlerOS independent */ ++ _set_timer(&pmlmepriv->assoc_timer, 1); ++ } else if (pcmd->res != H2C_SUCCESS) { ++ _set_timer(&pmlmepriv->assoc_timer, 1); ++ } ++ ++ rtw_free_cmd_obj(pcmd); ++} ++ ++void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ u8 timer_cancelled; ++ struct sta_info *psta = NULL; ++ struct wlan_network *pwlan = NULL; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf; ++ struct wlan_network *tgt_network = &pmlmepriv->cur_network; ++ ++ if (pcmd->res != H2C_SUCCESS) ++ _set_timer(&pmlmepriv->assoc_timer, 1); ++ ++ _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled); ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ psta = rtw_get_stainfo(&padapter->stapriv, pnetwork->MacAddress); ++ if (!psta) { ++ psta = rtw_alloc_stainfo(&padapter->stapriv, pnetwork->MacAddress); ++ if (!psta) ++ goto createbss_cmd_fail; ++ } ++ ++ rtw_indicate_connect(padapter); ++ } else { ++ ++ pwlan = _rtw_alloc_network(pmlmepriv); ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ if (!pwlan) { ++ pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue); ++ if (!pwlan) { ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ goto createbss_cmd_fail; ++ } ++ pwlan->last_scanned = jiffies; ++ } else { ++ list_add_tail(&pwlan->list, &pmlmepriv->scanned_queue.queue); ++ } ++ ++ pnetwork->Length = get_wlan_bssid_ex_sz(pnetwork); ++ memcpy(&pwlan->network, pnetwork, pnetwork->Length); ++ ++ memcpy(&tgt_network->network, pnetwork, (get_wlan_bssid_ex_sz(pnetwork))); ++ ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ /* we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) */ ++ } ++ ++createbss_cmd_fail: ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++ rtw_free_cmd_obj(pcmd); ++ ++} ++ ++void rtw_setstaKey_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct set_stakey_rsp *psetstakey_rsp = (struct set_stakey_rsp *)(pcmd->rsp); ++ struct sta_info *psta = rtw_get_stainfo(pstapriv, psetstakey_rsp->addr); ++ ++ if (!psta) ++ goto exit; ++exit: ++ rtw_free_cmd_obj(pcmd); ++ ++} ++ ++void rtw_setassocsta_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) ++{ ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct set_assocsta_parm *passocsta_parm = (struct set_assocsta_parm *)(pcmd->parmbuf); ++ struct set_assocsta_rsp *passocsta_rsp = (struct set_assocsta_rsp *)(pcmd->rsp); ++ struct sta_info *psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr); ++ ++ if (!psta) ++ goto exit; ++ ++ psta->aid = passocsta_rsp->cam_id; ++ psta->mac_id = passocsta_rsp->cam_id; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (check_fwstate(pmlmepriv, WIFI_MP_STATE) && check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ ++ set_fwstate(pmlmepriv, _FW_LINKED); ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++exit: ++ rtw_free_cmd_obj(pcmd); ++ ++} +diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c +new file mode 100644 +index 000000000000..2ee64cef73f7 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_debug.c +@@ -0,0 +1,904 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_DEBUG_C_ ++ ++#include "../include/rtw_debug.h" ++#include "../include/drv_types.h" ++ ++int proc_get_drv_version(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "%s\n", DRIVERVERSION); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_write_reg(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ *eof = 1; ++ return 0; ++} ++ ++int proc_set_write_reg(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ char tmp[32]; ++ u32 addr, val, len; ++ ++ if (count < 3) { ++ DBG_88E("argument size is less than 3\n"); ++ return -EFAULT; ++ } ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ int num = sscanf(tmp, "%x %x %x", &addr, &val, &len); ++ ++ if (num != 3) { ++ DBG_88E("invalid write_reg parameter!\n"); ++ return count; ++ } ++ switch (len) { ++ case 1: ++ rtw_write8(padapter, addr, (u8)val); ++ break; ++ case 2: ++ rtw_write16(padapter, addr, (u16)val); ++ break; ++ case 4: ++ rtw_write32(padapter, addr, val); ++ break; ++ default: ++ DBG_88E("error write length =%d", len); ++ break; ++ } ++ } ++ return count; ++} ++ ++static u32 proc_get_read_addr = 0xeeeeeeee; ++static u32 proc_get_read_len = 0x4; ++ ++int proc_get_read_reg(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ int len = 0; ++ ++ if (proc_get_read_addr == 0xeeeeeeee) { ++ *eof = 1; ++ return len; ++ } ++ ++ switch (proc_get_read_len) { ++ case 1: ++ len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n", proc_get_read_addr, rtw_read8(padapter, proc_get_read_addr)); ++ break; ++ case 2: ++ len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr)); ++ break; ++ case 4: ++ len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr)); ++ break; ++ default: ++ len += snprintf(page + len, count - len, "error read length=%d\n", proc_get_read_len); ++ break; ++ } ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_set_read_reg(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ char tmp[16]; ++ u32 addr, len; ++ ++ if (count < 2) { ++ DBG_88E("argument size is less than 2\n"); ++ return -EFAULT; ++ } ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ int num = sscanf(tmp, "%x %x", &addr, &len); ++ ++ if (num != 2) { ++ DBG_88E("invalid read_reg parameter!\n"); ++ return count; ++ } ++ ++ proc_get_read_addr = addr; ++ ++ proc_get_read_len = len; ++ } ++ ++ return count; ++} ++ ++int proc_get_fwstate(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "fwstate=0x%x\n", get_fwstate(pmlmepriv)); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_sec_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", ++ psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, ++ psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_mlmext_state(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "pmlmeinfo->state=0x%x\n", pmlmeinfo->state); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_qos_option(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "qos_option=%d\n", pmlmepriv->qospriv.qos_option); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_ht_option(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ int len = 0; ++ len += snprintf(page + len, count - len, "ht_option=%d\n", pmlmepriv->htpriv.ht_option); ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_rf_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "cur_ch=%d, cur_bw=%d, cur_ch_offet=%d\n", ++ pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_ap_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct sta_info *psta; ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wlan_network *cur_network = &pmlmepriv->cur_network; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ int len = 0; ++ ++ psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress); ++ if (psta) { ++ int i; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ ++ len += snprintf(page + len, count - len, "SSID=%s\n", cur_network->network.Ssid.Ssid); ++ len += snprintf(page + len, count - len, "sta's macaddr:%pM\n", psta->hwaddr); ++ len += snprintf(page + len, count - len, "cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); ++ len += snprintf(page + len, count - len, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self); ++ len += snprintf(page + len, count - len, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); ++ len += snprintf(page + len, count - len, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); ++ len += snprintf(page + len, count - len, "bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi); ++ len += snprintf(page + len, count - len, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable); ++ len += snprintf(page + len, count - len, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); ++ ++ for (i = 0; i < 16; i++) { ++ preorder_ctrl = &psta->recvreorder_ctrl[i]; ++ if (preorder_ctrl->enable) ++ len += snprintf(page + len, count - len, "tid=%d, indicate_seq=%d\n", i, preorder_ctrl->indicate_seq); ++ } ++ } else { ++ len += snprintf(page + len, count - len, "can't get sta's macaddr, cur_network's macaddr: %pM\n", cur_network->network.MacAddress); ++ } ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_adapter_state(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "bSurpriseRemoved=%d, bDriverStopped=%d\n", ++ padapter->bSurpriseRemoved, padapter->bDriverStopped); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_trx_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d, free_ext_xmitbuf_cnt=%d, free_recvframe_cnt=%d\n", ++ pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmit_extbuf_cnt, precvpriv->free_recvframe_cnt); ++ len += snprintf(page + len, count - len, "rx_urb_pending_cn=%d\n", precvpriv->rx_pending_cnt); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_mac_reg_dump1(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1; ++ ++ len += snprintf(page + len, count - len, "\n======= MAC REG =======\n"); ++ ++ for (i = 0x0; i < 0x300; i += 4) { ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_mac_reg_dump2(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1; ++ ++ len += snprintf(page + len, count - len, "\n======= MAC REG =======\n"); ++ memset(page, 0, count); ++ for (i = 0x300; i < 0x600; i += 4) { ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_mac_reg_dump3(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1; ++ ++ len += snprintf(page + len, count - len, "\n======= MAC REG =======\n"); ++ ++ for (i = 0x600; i < 0x800; i += 4) { ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_bb_reg_dump1(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1; ++ ++ len += snprintf(page + len, count - len, "\n======= BB REG =======\n"); ++ for (i = 0x800; i < 0xB00; i += 4) { ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_bb_reg_dump2(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1; ++ ++ len += snprintf(page + len, count - len, "\n======= BB REG =======\n"); ++ for (i = 0xB00; i < 0xE00; i += 4) { ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_bb_reg_dump3(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1; ++ ++ len += snprintf(page + len, count - len, "\n======= BB REG =======\n"); ++ for (i = 0xE00; i < 0x1000; i += 4) { ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_rf_reg_dump1(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1, path; ++ u32 value; ++ ++ len += snprintf(page + len, count - len, "\n======= RF REG =======\n"); ++ path = 1; ++ len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path); ++ for (i = 0; i < 0xC0; i++) { ++ value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x ", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", value); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_rf_reg_dump2(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1, path; ++ u32 value; ++ ++ len += snprintf(page + len, count - len, "\n======= RF REG =======\n"); ++ path = 1; ++ len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path); ++ for (i = 0xC0; i < 0x100; i++) { ++ value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x ", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", value); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_rf_reg_dump3(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1, path; ++ u32 value; ++ ++ len += snprintf(page + len, count - len, "\n======= RF REG =======\n"); ++ path = 2; ++ len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path); ++ for (i = 0; i < 0xC0; i++) { ++ value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x ", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", value); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_rf_reg_dump4(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ int i, j = 1, path; ++ u32 value; ++ ++ len += snprintf(page + len, count - len, "\n======= RF REG =======\n"); ++ path = 2; ++ len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path); ++ for (i = 0xC0; i < 0x100; i++) { ++ value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); ++ if (j % 4 == 1) ++ len += snprintf(page + len, count - len, "0x%02x ", i); ++ len += snprintf(page + len, count - len, " 0x%08x ", value); ++ if ((j++) % 4 == 0) ++ len += snprintf(page + len, count - len, "\n"); ++ } ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_rx_signal(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int len = 0; ++ ++ len = snprintf(page + len, count, ++ "rssi:%d\n" ++ "rxpwdb:%d\n" ++ "signal_strength:%u\n" ++ "signal_qual:%u\n" ++ "noise:%u\n", ++ padapter->recvpriv.rssi, ++ padapter->recvpriv.rxpwdb, ++ padapter->recvpriv.signal_strength, ++ padapter->recvpriv.signal_qual, ++ padapter->recvpriv.noise ++ ); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_set_rx_signal(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ char tmp[32]; ++ u32 is_signal_dbg; ++ s32 signal_strength; ++ ++ if (count < 1) ++ return -EFAULT; ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ int num = sscanf(tmp, "%u %u", &is_signal_dbg, &signal_strength); ++ is_signal_dbg = is_signal_dbg == 0 ? 0 : 1; ++ if (is_signal_dbg && num != 2) ++ return count; ++ ++ signal_strength = signal_strength > 100 ? 100 : signal_strength; ++ signal_strength = signal_strength < 0 ? 0 : signal_strength; ++ ++ padapter->recvpriv.is_signal_dbg = is_signal_dbg; ++ padapter->recvpriv.signal_strength_dbg = signal_strength; ++ ++ if (is_signal_dbg) ++ DBG_88E("set %s %u\n", "DBG_SIGNAL_STRENGTH", signal_strength); ++ else ++ DBG_88E("set %s\n", "HW_SIGNAL_STRENGTH"); ++ } ++ return count; ++} ++ ++int proc_get_ht_enable(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ int len = 0; ++ ++ if (pregpriv) ++ len += snprintf(page + len, count - len, ++ "%d\n", ++ pregpriv->ht_enable ++ ); ++ *eof = 1; ++ return len; ++} ++ ++int proc_set_ht_enable(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ char tmp[32]; ++ s32 mode = 0; ++ ++ if (count < 1) ++ return -EFAULT; ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ if (pregpriv) { ++ pregpriv->ht_enable = mode; ++ pr_info("ht_enable=%d\n", pregpriv->ht_enable); ++ } ++ } ++ ++ return count; ++} ++ ++int proc_get_cbw40_enable(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ ++ int len = 0; ++ ++ if (pregpriv) ++ len += snprintf(page + len, count - len, ++ "%d\n", ++ pregpriv->cbw40_enable ++ ); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_set_cbw40_enable(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ char tmp[32]; ++ s32 mode = 0; ++ ++ if (count < 1) ++ return -EFAULT; ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ if (pregpriv) { ++ pregpriv->cbw40_enable = mode; ++ pr_info("cbw40_enable=%d\n", mode); ++ } ++ } ++ return count; ++} ++ ++int proc_get_ampdu_enable(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ ++ int len = 0; ++ ++ if (pregpriv) ++ len += snprintf(page + len, count - len, ++ "%d\n", ++ pregpriv->ampdu_enable ++ ); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_set_ampdu_enable(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ char tmp[32]; ++ s32 mode = 0; ++ ++ if (count < 1) ++ return -EFAULT; ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ if (pregpriv) { ++ pregpriv->ampdu_enable = mode; ++ pr_info("ampdu_enable=%d\n", mode); ++ } ++ } ++ return count; ++} ++ ++int proc_get_two_path_rssi(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ int len = 0; ++ ++ if (padapter) ++ len += snprintf(page + len, count - len, ++ "%d %d\n", ++ padapter->recvpriv.RxRssi[0], ++ padapter->recvpriv.RxRssi[1] ++ ); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_get_rx_stbc(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ ++ int len = 0; ++ ++ if (pregpriv) ++ len += snprintf(page + len, count - len, ++ "%d\n", ++ pregpriv->rx_stbc ++ ); ++ ++ *eof = 1; ++ return len; ++} ++ ++int proc_set_rx_stbc(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ char tmp[32]; ++ u32 mode = 0; ++ ++ if (count < 1) ++ return -EFAULT; ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ if (pregpriv) { ++ pregpriv->rx_stbc = mode; ++ printk("rx_stbc=%d\n", mode); ++ } ++ } ++ return count; ++} ++ ++int proc_get_rssi_disp(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ *eof = 1; ++ return 0; ++} ++ ++int proc_set_rssi_disp(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ struct net_device *dev = (struct net_device *)data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ char tmp[32]; ++ u32 enable = 0; ++ ++ if (count < 1) { ++ DBG_88E("argument size is less than 1\n"); ++ return -EFAULT; ++ } ++ ++ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { ++ int num = sscanf(tmp, "%x", &enable); ++ ++ if (num != 1) { ++ DBG_88E("invalid set_rssi_disp parameter!\n"); ++ return count; ++ } ++ ++ if (enable) { ++ DBG_88E("Turn On Rx RSSI Display Function\n"); ++ padapter->bRxRSSIDisplay = enable; ++ } else { ++ DBG_88E("Turn Off Rx RSSI Display Function\n"); ++ padapter->bRxRSSIDisplay = 0; ++ } ++ } ++ return count; ++} ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++int proc_get_all_sta_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct sta_info *psta; ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ int i, j; ++ struct list_head *plist, *phead; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ int len = 0; ++ ++ len += snprintf(page + len, count - len, "sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap); ++ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ ++ for (i = 0; i < NUM_STA; i++) { ++ phead = &pstapriv->sta_hash[i]; ++ plist = phead->next; ++ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, hash_list); ++ ++ plist = plist->next; ++ ++ len += snprintf(page + len, count - len, "sta's macaddr: %pM\n", psta->hwaddr); ++ len += snprintf(page + len, count - len, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self); ++ len += snprintf(page + len, count - len, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); ++ len += snprintf(page + len, count - len, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); ++ len += snprintf(page + len, count - len, "bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi); ++ len += snprintf(page + len, count - len, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable); ++ len += snprintf(page + len, count - len, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); ++ len += snprintf(page + len, count - len, "sleepq_len=%d\n", psta->sleepq_len); ++ len += snprintf(page + len, count - len, "capability=0x%x\n", psta->capability); ++ len += snprintf(page + len, count - len, "flags=0x%x\n", psta->flags); ++ len += snprintf(page + len, count - len, "wpa_psk=0x%x\n", psta->wpa_psk); ++ len += snprintf(page + len, count - len, "wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher); ++ len += snprintf(page + len, count - len, "wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher); ++ len += snprintf(page + len, count - len, "qos_info=0x%x\n", psta->qos_info); ++ len += snprintf(page + len, count - len, "dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy); ++ ++ for (j = 0; j < 16; j++) { ++ preorder_ctrl = &psta->recvreorder_ctrl[j]; ++ if (preorder_ctrl->enable) ++ len += snprintf(page + len, count - len, "tid=%d, indicate_seq=%d\n", j, preorder_ctrl->indicate_seq); ++ } ++ } ++ } ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++ *eof = 1; ++ return len; ++} ++#endif ++ ++int proc_get_best_channel(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *dev = data; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ int len = 0; ++ u32 i, best_channel_24G = 1, index_24G = 0; ++ ++ for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) { ++ if (pmlmeext->channel_set[i].ChannelNum == 1) ++ index_24G = i; ++ } ++ ++ for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) { ++ /* 2.4G */ ++ if (pmlmeext->channel_set[i].ChannelNum == 6) { ++ if (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_24G].rx_count) { ++ index_24G = i; ++ best_channel_24G = pmlmeext->channel_set[i].ChannelNum; ++ } ++ } ++ ++ /* debug */ ++ len += snprintf(page + len, count - len, "The rx cnt of channel %3d = %d\n", ++ pmlmeext->channel_set[i].ChannelNum, pmlmeext->channel_set[i].rx_count); ++ } ++ ++ len += snprintf(page + len, count - len, "best_channel_24G = %d\n", best_channel_24G); ++ ++ *eof = 1; ++ return len; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c +new file mode 100644 +index 000000000000..c1c70648f5bc +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_efuse.c +@@ -0,0 +1,848 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_EFUSE_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtw_efuse.h" ++ ++/*------------------------Define local variable------------------------------*/ ++u8 fakeEfuseBank; ++u32 fakeEfuseUsedBytes; ++u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE] = {0}; ++u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN] = {0}; ++u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN] = {0}; ++ ++u32 BTEfuseUsedBytes; ++u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; ++u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0}; ++u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0}; ++ ++u32 fakeBTEfuseUsedBytes; ++u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; ++u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0}; ++u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0}; ++/*------------------------Define local variable------------------------------*/ ++ ++/* */ ++#define REG_EFUSE_CTRL 0x0030 ++#define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */ ++/* */ ++static bool Efuse_Read1ByteFromFakeContent(struct adapter *pAdapter, ++ u16 Offset, ++ u8 *Value) ++{ ++ if (Offset >= EFUSE_MAX_HW_SIZE) ++ return false; ++ if (fakeEfuseBank == 0) ++ *Value = fakeEfuseContent[Offset]; ++ else ++ *Value = fakeBTEfuseContent[fakeEfuseBank - 1][Offset]; ++ return true; ++} ++ ++static bool ++Efuse_Write1ByteToFakeContent( ++ struct adapter *pAdapter, ++ u16 Offset, ++ u8 Value) ++{ ++ if (Offset >= EFUSE_MAX_HW_SIZE) ++ return false; ++ if (fakeEfuseBank == 0) { ++ fakeEfuseContent[Offset] = Value; ++ } else { ++ fakeBTEfuseContent[fakeEfuseBank - 1][Offset] = Value; ++ } ++ return true; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: Efuse_PowerSwitch ++ * ++ * Overview: When we want to enable write operation, we should change to ++ * pwr on state. When we stop write, we should switch to 500k mode ++ * and disable LDO 2.5V. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/17/2008 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++void ++Efuse_PowerSwitch( ++ struct adapter *pAdapter, ++ u8 write, ++ u8 PwrState) ++{ ++ pAdapter->HalFunc.EfusePowerSwitch(pAdapter, write, PwrState); ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: efuse_GetCurrentSize ++ * ++ * Overview: Get current efuse size!!! ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/16/2008 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++u16 ++Efuse_GetCurrentSize( ++ struct adapter *pAdapter, ++ u8 efuseType, ++ bool pseudo) ++{ ++ u16 ret = 0; ++ ++ ret = pAdapter->HalFunc.EfuseGetCurrentSize(pAdapter, efuseType, pseudo); ++ ++ return ret; ++} ++ ++/* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */ ++u8 ++Efuse_CalculateWordCnts(u8 word_en) ++{ ++ u8 word_cnts = 0; ++ if (!(word_en & BIT(0))) ++ word_cnts++; /* 0 : write enable */ ++ if (!(word_en & BIT(1))) ++ word_cnts++; ++ if (!(word_en & BIT(2))) ++ word_cnts++; ++ if (!(word_en & BIT(3))) ++ word_cnts++; ++ return word_cnts; ++} ++ ++/* */ ++/* Description: */ ++/* Execute E-Fuse read byte operation. */ ++/* Referred from SD1 Richard. */ ++/* */ ++/* Assumption: */ ++/* 1. Boot from E-Fuse and successfully auto-load. */ ++/* 2. PASSIVE_LEVEL (USB interface) */ ++/* */ ++/* Created by Roger, 2008.10.21. */ ++/* */ ++void ++ReadEFuseByte( ++ struct adapter *Adapter, ++ u16 _offset, ++ u8 *pbuf, ++ bool pseudo) ++{ ++ u32 value32; ++ u8 readbyte; ++ u16 retry; ++ ++ if (pseudo) { ++ Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf); ++ return; ++ } ++ ++ /* Write Address */ ++ rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff)); ++ readbyte = rtw_read8(Adapter, EFUSE_CTRL + 2); ++ rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc)); ++ ++ /* Write bit 32 0 */ ++ readbyte = rtw_read8(Adapter, EFUSE_CTRL + 3); ++ rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f)); ++ ++ /* Check bit 32 read-ready */ ++ retry = 0; ++ value32 = rtw_read32(Adapter, EFUSE_CTRL); ++ while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) { ++ value32 = rtw_read32(Adapter, EFUSE_CTRL); ++ retry++; ++ } ++ ++ /* 20100205 Joseph: Add delay suggested by SD1 Victor. */ ++ /* This fix the problem that Efuse read error in high temperature condition. */ ++ /* Designer says that there shall be some delay after ready bit is set, or the */ ++ /* result will always stay on last data we read. */ ++ udelay(50); ++ value32 = rtw_read32(Adapter, EFUSE_CTRL); ++ ++ *pbuf = (u8)(value32 & 0xff); ++} ++ ++/* */ ++/* Description: */ ++/* 1. Execute E-Fuse read byte operation according as map offset and */ ++/* save to E-Fuse table. */ ++/* 2. Referred from SD1 Richard. */ ++/* */ ++/* Assumption: */ ++/* 1. Boot from E-Fuse and successfully auto-load. */ ++/* 2. PASSIVE_LEVEL (USB interface) */ ++/* */ ++/* Created by Roger, 2008.10.21. */ ++/* */ ++/* 2008/12/12 MH 1. Reorganize code flow and reserve bytes. and add description. */ ++/* 2. Add efuse utilization collect. */ ++/* 2008/12/22 MH Read Efuse must check if we write section 1 data again!!! Sec1 */ ++/* write addr must be after sec5. */ ++/* */ ++ ++static void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo) ++{ ++ Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo); ++} ++ ++void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool pseudo ++ ) ++{ ++ pAdapter->HalFunc.EFUSEGetEfuseDefinition(pAdapter, efuseType, type, pOut, pseudo); ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: EFUSE_Read1Byte ++ * ++ * Overview: Copy from WMAC fot EFUSE read 1 byte. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 09/23/2008 MHC Copy from WMAC. ++ * ++ *---------------------------------------------------------------------------*/ ++u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address) ++{ ++ u8 data; ++ u8 Bytetemp = {0x00}; ++ u8 temp = {0x00}; ++ u32 k = 0; ++ u16 contentLen = 0; ++ ++ EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, false); ++ ++ if (Address < contentLen) { /* E-fuse 512Byte */ ++ /* Write E-fuse Register address bit0~7 */ ++ temp = Address & 0xFF; ++ rtw_write8(Adapter, EFUSE_CTRL + 1, temp); ++ Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 2); ++ /* Write E-fuse Register address bit8~9 */ ++ temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC); ++ rtw_write8(Adapter, EFUSE_CTRL + 2, temp); ++ ++ /* Write 0x30[31]= 0 */ ++ Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3); ++ temp = Bytetemp & 0x7F; ++ rtw_write8(Adapter, EFUSE_CTRL + 3, temp); ++ ++ /* Wait Write-ready (0x30[31]= 1) */ ++ Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3); ++ while (!(Bytetemp & 0x80)) { ++ Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3); ++ k++; ++ if (k == 1000) { ++ k = 0; ++ break; ++ } ++ } ++ data = rtw_read8(Adapter, EFUSE_CTRL); ++ return data; ++ } else { ++ return 0xFF; ++ } ++ ++} /* EFUSE_Read1Byte */ ++ ++/* 11/16/2008 MH Read one byte from real Efuse. */ ++u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data, bool pseudo) ++{ ++ u8 tmpidx = 0; ++ u8 result; ++ ++ if (pseudo) { ++ result = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data); ++ return result; ++ } ++ /* -----------------e-fuse reg ctrl --------------------------------- */ ++ /* address */ ++ rtw_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff)); ++ rtw_write8(pAdapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) | ++ (rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC)); ++ ++ rtw_write8(pAdapter, EFUSE_CTRL + 3, 0x72);/* read cmd */ ++ ++ while (!(0x80 & rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100)) ++ tmpidx++; ++ if (tmpidx < 100) { ++ *data = rtw_read8(pAdapter, EFUSE_CTRL); ++ result = true; ++ } else { ++ *data = 0xff; ++ result = false; ++ } ++ return result; ++} ++ ++/* 11/16/2008 MH Write one byte to reald Efuse. */ ++u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data, bool pseudo) ++{ ++ u8 tmpidx = 0; ++ u8 result; ++ ++ if (pseudo) { ++ result = Efuse_Write1ByteToFakeContent(pAdapter, addr, data); ++ return result; ++ } ++ ++ /* -----------------e-fuse reg ctrl --------------------------------- */ ++ /* address */ ++ rtw_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff)); ++ rtw_write8(pAdapter, EFUSE_CTRL + 2, ++ (rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC) | ++ (u8)((addr >> 8) & 0x03)); ++ rtw_write8(pAdapter, EFUSE_CTRL, data);/* data */ ++ ++ rtw_write8(pAdapter, EFUSE_CTRL + 3, 0xF2);/* write cmd */ ++ ++ while ((0x80 & rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100)) ++ tmpidx++; ++ ++ if (tmpidx < 100) ++ result = true; ++ else ++ result = false; ++ ++ return result; ++} ++ ++int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool pseudo) ++{ ++ int ret = 0; ++ ++ ret = pAdapter->HalFunc.Efuse_PgPacketRead(pAdapter, offset, data, pseudo); ++ ++ return ret; ++} ++ ++int Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool pseudo) ++{ ++ int ret; ++ ++ ret = pAdapter->HalFunc.Efuse_PgPacketWrite(pAdapter, offset, word_en, data, pseudo); ++ ++ return ret; ++} ++ ++static int Efuse_PgPacketWrite_BT(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool pseudo) ++{ ++ int ret; ++ ++ ret = pAdapter->HalFunc.Efuse_PgPacketWrite_BT(pAdapter, offset, word_en, data, pseudo); ++ ++ return ret; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: efuse_WordEnableDataRead ++ * ++ * Overview: Read allowed word in current efuse section data. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/16/2008 MHC Create Version 0. ++ * 11/21/2008 MHC Fix Write bug when we only enable late word. ++ * ++ *---------------------------------------------------------------------------*/ ++void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata) ++{ ++ if (!(word_en & BIT(0))) { ++ targetdata[0] = sourdata[0]; ++ targetdata[1] = sourdata[1]; ++ } ++ if (!(word_en & BIT(1))) { ++ targetdata[2] = sourdata[2]; ++ targetdata[3] = sourdata[3]; ++ } ++ if (!(word_en & BIT(2))) { ++ targetdata[4] = sourdata[4]; ++ targetdata[5] = sourdata[5]; ++ } ++ if (!(word_en & BIT(3))) { ++ targetdata[6] = sourdata[6]; ++ targetdata[7] = sourdata[7]; ++ } ++} ++ ++u8 Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool pseudo) ++{ ++ u8 ret = 0; ++ ++ ret = pAdapter->HalFunc.Efuse_WordEnableDataWrite(pAdapter, efuse_addr, word_en, data, pseudo); ++ ++ return ret; ++} ++ ++static u8 efuse_read8(struct adapter *padapter, u16 address, u8 *value) ++{ ++ return efuse_OneByteRead(padapter, address, value, false); ++} ++ ++static u8 efuse_write8(struct adapter *padapter, u16 address, u8 *value) ++{ ++ return efuse_OneByteWrite(padapter, address, *value, false); ++} ++ ++/* ++ * read/wirte raw efuse data ++ */ ++u8 rtw_efuse_access(struct adapter *padapter, u8 write, u16 start_addr, u16 cnts, u8 *data) ++{ ++ int i = 0; ++ u16 real_content_len = 0, max_available_size = 0; ++ u8 res = _FAIL; ++ u8 (*rw8)(struct adapter *, u16, u8*); ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&real_content_len, false); ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ ++ if (start_addr > real_content_len) ++ return _FAIL; ++ ++ if (write) { ++ if ((start_addr + cnts) > max_available_size) ++ return _FAIL; ++ rw8 = &efuse_write8; ++ } else { ++ rw8 = &efuse_read8; ++ } ++ ++ Efuse_PowerSwitch(padapter, write, true); ++ ++ /* e-fuse one byte read / write */ ++ for (i = 0; i < cnts; i++) { ++ if (start_addr >= real_content_len) { ++ res = _FAIL; ++ break; ++ } ++ ++ res = rw8(padapter, start_addr++, data++); ++ if (_FAIL == res) ++ break; ++ } ++ ++ Efuse_PowerSwitch(padapter, write, false); ++ ++ return res; ++} ++/* */ ++u16 efuse_GetMaxSize(struct adapter *padapter) ++{ ++ u16 max_size; ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_size, false); ++ return max_size; ++} ++/* */ ++u8 efuse_GetCurrentSize(struct adapter *padapter, u16 *size) ++{ ++ Efuse_PowerSwitch(padapter, false, true); ++ *size = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, false); ++ Efuse_PowerSwitch(padapter, false, false); ++ ++ return _SUCCESS; ++} ++/* */ ++u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data) ++{ ++ u16 mapLen = 0; ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false); ++ ++ if ((addr + cnts) > mapLen) ++ return _FAIL; ++ ++ Efuse_PowerSwitch(padapter, false, true); ++ ++ efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false); ++ ++ Efuse_PowerSwitch(padapter, false, false); ++ ++ return _SUCCESS; ++} ++ ++u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data) ++{ ++ u16 mapLen = 0; ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false); ++ ++ if ((addr + cnts) > mapLen) ++ return _FAIL; ++ ++ Efuse_PowerSwitch(padapter, false, true); ++ ++ efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false); ++ ++ Efuse_PowerSwitch(padapter, false, false); ++ ++ return _SUCCESS; ++} ++/* */ ++u8 rtw_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data) ++{ ++ u8 offset, word_en; ++ u8 *map; ++ u8 newdata[PGPKT_DATA_SIZE + 1]; ++ s32 i, idx; ++ u8 ret = _SUCCESS; ++ u16 mapLen = 0; ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false); ++ ++ if ((addr + cnts) > mapLen) ++ return _FAIL; ++ ++ map = kzalloc(mapLen, GFP_KERNEL); ++ if (!map) ++ return _FAIL; ++ ++ ret = rtw_efuse_map_read(padapter, 0, mapLen, map); ++ if (ret == _FAIL) ++ goto exit; ++ ++ Efuse_PowerSwitch(padapter, true, true); ++ ++ offset = (addr >> 3); ++ word_en = 0xF; ++ memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1); ++ i = addr & 0x7; /* index of one package */ ++ idx = 0; /* data index */ ++ ++ if (i & 0x1) { ++ /* odd start */ ++ if (data[idx] != map[addr + idx]) { ++ word_en &= ~BIT(i >> 1); ++ newdata[i - 1] = map[addr + idx - 1]; ++ newdata[i] = data[idx]; ++ } ++ i++; ++ idx++; ++ } ++ do { ++ for (; i < PGPKT_DATA_SIZE; i += 2) { ++ if (cnts == idx) ++ break; ++ if ((cnts - idx) == 1) { ++ if (data[idx] != map[addr + idx]) { ++ word_en &= ~BIT(i >> 1); ++ newdata[i] = data[idx]; ++ newdata[i + 1] = map[addr + idx + 1]; ++ } ++ idx++; ++ break; ++ } else { ++ if ((data[idx] != map[addr + idx]) || ++ (data[idx + 1] != map[addr + idx + 1])) { ++ word_en &= ~BIT(i >> 1); ++ newdata[i] = data[idx]; ++ newdata[i + 1] = data[idx + 1]; ++ } ++ idx += 2; ++ } ++ if (idx == cnts) ++ break; ++ } ++ ++ if (word_en != 0xF) { ++ ret = Efuse_PgPacketWrite(padapter, offset, word_en, newdata, false); ++ DBG_88E("offset=%x\n", offset); ++ DBG_88E("word_en=%x\n", word_en); ++ ++ for (i = 0; i < PGPKT_DATA_SIZE; i++) ++ DBG_88E("data=%x \t", newdata[i]); ++ if (ret == _FAIL) ++ break; ++ } ++ ++ if (idx == cnts) ++ break; ++ ++ offset++; ++ i = 0; ++ word_en = 0xF; ++ memset(newdata, 0xFF, PGPKT_DATA_SIZE); ++ } while (1); ++ ++ Efuse_PowerSwitch(padapter, true, false); ++exit: ++ kfree(map); ++ return ret; ++} ++ ++/* */ ++u8 rtw_BT_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data) ++{ ++ u8 offset, word_en; ++ u8 *map; ++ u8 newdata[PGPKT_DATA_SIZE + 1]; ++ s32 i, idx; ++ u8 ret = _SUCCESS; ++ u16 mapLen = 0; ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false); ++ ++ if ((addr + cnts) > mapLen) ++ return _FAIL; ++ ++ map = kzalloc(mapLen, GFP_KERNEL); ++ if (!map) ++ return _FAIL; ++ ++ ret = rtw_BT_efuse_map_read(padapter, 0, mapLen, map); ++ if (ret == _FAIL) ++ goto exit; ++ ++ Efuse_PowerSwitch(padapter, true, true); ++ ++ offset = (addr >> 3); ++ word_en = 0xF; ++ memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1); ++ i = addr & 0x7; /* index of one package */ ++ idx = 0; /* data index */ ++ ++ if (i & 0x1) { ++ /* odd start */ ++ if (data[idx] != map[addr + idx]) { ++ word_en &= ~BIT(i >> 1); ++ newdata[i - 1] = map[addr + idx - 1]; ++ newdata[i] = data[idx]; ++ } ++ i++; ++ idx++; ++ } ++ do { ++ for (; i < PGPKT_DATA_SIZE; i += 2) { ++ if (cnts == idx) ++ break; ++ if ((cnts - idx) == 1) { ++ if (data[idx] != map[addr + idx]) { ++ word_en &= ~BIT(i >> 1); ++ newdata[i] = data[idx]; ++ newdata[i + 1] = map[addr + idx + 1]; ++ } ++ idx++; ++ break; ++ } else { ++ if ((data[idx] != map[addr + idx]) || ++ (data[idx + 1] != map[addr + idx + 1])) { ++ word_en &= ~BIT(i >> 1); ++ newdata[i] = data[idx]; ++ newdata[i + 1] = data[idx + 1]; ++ } ++ idx += 2; ++ } ++ if (idx == cnts) ++ break; ++ } ++ ++ if (word_en != 0xF) { ++ DBG_88E("%s: offset=%#X\n", __func__, offset); ++ DBG_88E("%s: word_en=%#X\n", __func__, word_en); ++ DBG_88E("%s: data=", __func__); ++ for (i = 0; i < PGPKT_DATA_SIZE; i++) ++ DBG_88E("0x%02X ", newdata[i]); ++ DBG_88E("\n"); ++ ++ ret = Efuse_PgPacketWrite_BT(padapter, offset, word_en, newdata, false); ++ if (ret == _FAIL) ++ break; ++ } ++ ++ if (idx == cnts) ++ break; ++ ++ offset++; ++ i = 0; ++ word_en = 0xF; ++ memset(newdata, 0xFF, PGPKT_DATA_SIZE); ++ } while (1); ++ ++ Efuse_PowerSwitch(padapter, true, false); ++ ++exit: ++ ++ kfree(map); ++ ++ return ret; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: efuse_ShadowRead1Byte ++ * efuse_ShadowRead2Byte ++ * efuse_ShadowRead4Byte ++ * ++ * Overview: Read from efuse init map by one/two/four bytes !!!!! ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/12/2008 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++static void ++efuse_ShadowRead1Byte( ++ struct adapter *pAdapter, ++ u16 Offset, ++ u8 *Value) ++{ ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); ++ ++ *Value = pEEPROM->efuse_eeprom_data[Offset]; ++ ++} /* EFUSE_ShadowRead1Byte */ ++ ++/* Read Two Bytes */ ++static void ++efuse_ShadowRead2Byte( ++ struct adapter *pAdapter, ++ u16 Offset, ++ u16 *Value) ++{ ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); ++ ++ *Value = pEEPROM->efuse_eeprom_data[Offset]; ++ *Value |= pEEPROM->efuse_eeprom_data[Offset + 1] << 8; ++ ++} /* EFUSE_ShadowRead2Byte */ ++ ++/* Read Four Bytes */ ++static void ++efuse_ShadowRead4Byte( ++ struct adapter *pAdapter, ++ u16 Offset, ++ u32 *Value) ++{ ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); ++ ++ *Value = pEEPROM->efuse_eeprom_data[Offset]; ++ *Value |= pEEPROM->efuse_eeprom_data[Offset + 1] << 8; ++ *Value |= pEEPROM->efuse_eeprom_data[Offset + 2] << 16; ++ *Value |= pEEPROM->efuse_eeprom_data[Offset + 3] << 24; ++ ++} /* efuse_ShadowRead4Byte */ ++ ++/*----------------------------------------------------------------------------- ++ * Function: Efuse_ReadAllMap ++ * ++ * Overview: Read All Efuse content ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/11/2008 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo) ++{ ++ u16 mapLen = 0; ++ ++ Efuse_PowerSwitch(pAdapter, false, true); ++ ++ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo); ++ ++ efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo); ++ ++ Efuse_PowerSwitch(pAdapter, false, false); ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: EFUSE_ShadowMapUpdate ++ * ++ * Overview: Transfer current EFUSE content to shadow init and modify map. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/13/2008 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++void EFUSE_ShadowMapUpdate( ++ struct adapter *pAdapter, ++ u8 efuseType, ++ bool pseudo) ++{ ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); ++ u16 mapLen = 0; ++ ++ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo); ++ ++ if (pEEPROM->bautoload_fail_flag) ++ memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen); ++ else ++ Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo); ++} /* EFUSE_ShadowMapUpdate */ ++ ++/*----------------------------------------------------------------------------- ++ * Function: EFUSE_ShadowRead ++ * ++ * Overview: Read from efuse init map !!!!! ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/12/2008 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++void EFUSE_ShadowRead(struct adapter *pAdapter, u8 Type, u16 Offset, u32 *Value) ++{ ++ if (Type == 1) ++ efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value); ++ else if (Type == 2) ++ efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value); ++ else if (Type == 4) ++ efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value); ++ ++} /* EFUSE_ShadowRead */ +diff --git a/drivers/staging/r8188eu/core/rtw_ieee80211.c b/drivers/staging/r8188eu/core/rtw_ieee80211.c +new file mode 100644 +index 000000000000..b3a74198596a +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_ieee80211.c +@@ -0,0 +1,1539 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _IEEE80211_C ++ ++#include "../include/drv_types.h" ++#include "../include/ieee80211.h" ++#include "../include/wifi.h" ++#include "../include/osdep_service.h" ++#include "../include/wlan_bssdef.h" ++#include "../include/usb_osintf.h" ++ ++u8 RTW_WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 }; ++u16 RTW_WPA_VERSION = 1; ++u8 WPA_AUTH_KEY_MGMT_NONE[] = { 0x00, 0x50, 0xf2, 0 }; ++u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x50, 0xf2, 1 }; ++u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x50, 0xf2, 2 }; ++u8 WPA_CIPHER_SUITE_NONE[] = { 0x00, 0x50, 0xf2, 0 }; ++u8 WPA_CIPHER_SUITE_WEP40[] = { 0x00, 0x50, 0xf2, 1 }; ++u8 WPA_CIPHER_SUITE_TKIP[] = { 0x00, 0x50, 0xf2, 2 }; ++u8 WPA_CIPHER_SUITE_WRAP[] = { 0x00, 0x50, 0xf2, 3 }; ++u8 WPA_CIPHER_SUITE_CCMP[] = { 0x00, 0x50, 0xf2, 4 }; ++u8 WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 }; ++ ++u16 RSN_VERSION_BSD = 1; ++u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x0f, 0xac, 1 }; ++u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x0f, 0xac, 2 }; ++u8 RSN_CIPHER_SUITE_NONE[] = { 0x00, 0x0f, 0xac, 0 }; ++u8 RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 }; ++u8 RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 }; ++u8 RSN_CIPHER_SUITE_WRAP[] = { 0x00, 0x0f, 0xac, 3 }; ++u8 RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 }; ++u8 RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 }; ++/* */ ++/* for adhoc-master to generate ie and provide supported-rate to fw */ ++/* */ ++ ++static u8 WIFI_CCKRATES[] = { ++ (IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK), ++ (IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK), ++ (IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK), ++ (IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK) ++ }; ++ ++static u8 WIFI_OFDMRATES[] = { ++ (IEEE80211_OFDM_RATE_6MB), ++ (IEEE80211_OFDM_RATE_9MB), ++ (IEEE80211_OFDM_RATE_12MB), ++ (IEEE80211_OFDM_RATE_18MB), ++ (IEEE80211_OFDM_RATE_24MB), ++ IEEE80211_OFDM_RATE_36MB, ++ IEEE80211_OFDM_RATE_48MB, ++ IEEE80211_OFDM_RATE_54MB ++ }; ++ ++int rtw_get_bit_value_from_ieee_value(u8 val) ++{ ++ unsigned char dot11_rate_table[] = { ++ 2, 4, 11, 22, 12, 18, 24, 36, 48, ++ 72, 96, 108, 0}; /* last element must be zero!! */ ++ ++ int i = 0; ++ while (dot11_rate_table[i] != 0) { ++ if (dot11_rate_table[i] == val) ++ return BIT(i); ++ i++; ++ } ++ return 0; ++} ++ ++uint rtw_is_cckrates_included(u8 *rate) ++{ ++ u32 i = 0; ++ ++ while (rate[i] != 0) { ++ if ((((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) || ++ (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22)) ++ return true; ++ i++; ++ } ++ return false; ++} ++ ++uint rtw_is_cckratesonly_included(u8 *rate) ++{ ++ u32 i = 0; ++ ++ while (rate[i] != 0) { ++ if ((((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && ++ (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22)) ++ return false; ++ i++; ++ } ++ ++ return true; ++} ++ ++int rtw_check_network_type(unsigned char *rate, int ratelen, int channel) ++{ ++ if (channel > 14) { ++ return WIRELESS_INVALID; ++ } else { /* could be pure B, pure G, or B/G */ ++ if (rtw_is_cckratesonly_included(rate)) ++ return WIRELESS_11B; ++ else if (rtw_is_cckrates_included(rate)) ++ return WIRELESS_11BG; ++ else ++ return WIRELESS_11G; ++ } ++} ++ ++u8 *rtw_set_fixed_ie(unsigned char *pbuf, unsigned int len, unsigned char *source, ++ unsigned int *frlen) ++{ ++ memcpy((void *)pbuf, (void *)source, len); ++ *frlen = *frlen + len; ++ return pbuf + len; ++} ++ ++/* rtw_set_ie will update frame length */ ++u8 *rtw_set_ie ++( ++ u8 *pbuf, ++ int index, ++ uint len, ++ u8 *source, ++ uint *frlen /* frame length */ ++) ++{ ++ ++ *pbuf = (u8)index; ++ ++ *(pbuf + 1) = (u8)len; ++ ++ if (len > 0) ++ memcpy((void *)(pbuf + 2), (void *)source, len); ++ ++ *frlen = *frlen + (len + 2); ++ ++ return pbuf + len + 2; ++} ++ ++inline u8 *rtw_set_ie_ch_switch(u8 *buf, u32 *buf_len, u8 ch_switch_mode, ++ u8 new_ch, u8 ch_switch_cnt) ++{ ++ u8 ie_data[3]; ++ ++ ie_data[0] = ch_switch_mode; ++ ie_data[1] = new_ch; ++ ie_data[2] = ch_switch_cnt; ++ return rtw_set_ie(buf, WLAN_EID_CHANNEL_SWITCH, 3, ie_data, buf_len); ++} ++ ++inline u8 secondary_ch_offset_to_hal_ch_offset(u8 ch_offset) ++{ ++ if (ch_offset == SCN) ++ return HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ else if (ch_offset == SCA) ++ return HAL_PRIME_CHNL_OFFSET_UPPER; ++ else if (ch_offset == SCB) ++ return HAL_PRIME_CHNL_OFFSET_LOWER; ++ ++ return HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++} ++ ++inline u8 hal_ch_offset_to_secondary_ch_offset(u8 ch_offset) ++{ ++ if (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ++ return SCN; ++ else if (ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) ++ return SCB; ++ else if (ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER) ++ return SCA; ++ ++ return SCN; ++} ++ ++inline u8 *rtw_set_ie_secondary_ch_offset(u8 *buf, u32 *buf_len, u8 secondary_ch_offset) ++{ ++ return rtw_set_ie(buf, WLAN_EID_SECONDARY_CHANNEL_OFFSET, 1, &secondary_ch_offset, buf_len); ++} ++ ++inline u8 *rtw_set_ie_mesh_ch_switch_parm(u8 *buf, u32 *buf_len, u8 ttl, ++ u8 flags, u16 reason, u16 precedence) ++{ ++ u8 ie_data[6]; ++ ++ ie_data[0] = ttl; ++ ie_data[1] = flags; ++ *(u16 *)(ie_data + 2) = cpu_to_le16(reason); ++ *(u16 *)(ie_data + 4) = cpu_to_le16(precedence); ++ ++ return rtw_set_ie(buf, 0x118, 6, ie_data, buf_len); ++} ++ ++/*---------------------------------------------------------------------------- ++index: the information element id index, limit is the limit for search ++-----------------------------------------------------------------------------*/ ++u8 *rtw_get_ie(u8 *pbuf, int index, int *len, int limit) ++{ ++ int tmp, i; ++ u8 *p; ++ ++ if (limit < 1) { ++ ++ return NULL; ++ } ++ ++ p = pbuf; ++ i = 0; ++ *len = 0; ++ while (1) { ++ if (*p == index) { ++ *len = *(p + 1); ++ return p; ++ } else { ++ tmp = *(p + 1); ++ p += (tmp + 2); ++ i += (tmp + 2); ++ } ++ if (i >= limit) ++ break; ++ } ++ ++ return NULL; ++} ++ ++/** ++ * rtw_get_ie_ex - Search specific IE from a series of IEs ++ * @in_ie: Address of IEs to search ++ * @in_len: Length limit from in_ie ++ * @eid: Element ID to match ++ * @oui: OUI to match ++ * @oui_len: OUI length ++ * @ie: If not NULL and the specific IE is found, the IE will be copied to the buf starting from the specific IE ++ * @ielen: If not NULL and the specific IE is found, will set to the length of the entire IE ++ * ++ * Returns: The address of the specific IE found, or NULL ++ */ ++u8 *rtw_get_ie_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, u8 oui_len, u8 *ie, uint *ielen) ++{ ++ uint cnt; ++ u8 *target_ie = NULL; ++ ++ if (ielen) ++ *ielen = 0; ++ ++ if (!in_ie || in_len <= 0) ++ return target_ie; ++ ++ cnt = 0; ++ ++ while (cnt < in_len) { ++ if (eid == in_ie[cnt] && (!oui || !memcmp(&in_ie[cnt + 2], oui, oui_len))) { ++ target_ie = &in_ie[cnt]; ++ ++ if (ie) ++ memcpy(ie, &in_ie[cnt], in_ie[cnt + 1] + 2); ++ ++ if (ielen) ++ *ielen = in_ie[cnt + 1] + 2; ++ ++ break; ++ } else { ++ cnt += in_ie[cnt + 1] + 2; /* goto next */ ++ } ++ } ++ return target_ie; ++} ++ ++/** ++ * rtw_ies_remove_ie - Find matching IEs and remove ++ * @ies: Address of IEs to search ++ * @ies_len: Pointer of length of ies, will update to new length ++ * @offset: The offset to start scarch ++ * @eid: Element ID to match ++ * @oui: OUI to match ++ * @oui_len: OUI length ++ * ++ * Returns: _SUCCESS: ies is updated, _FAIL: not updated ++ */ ++int rtw_ies_remove_ie(u8 *ies, uint *ies_len, uint offset, u8 eid, u8 *oui, u8 oui_len) ++{ ++ int ret = _FAIL; ++ u8 *target_ie; ++ u32 target_ielen; ++ u8 *start; ++ uint search_len; ++ ++ if (!ies || !ies_len || *ies_len <= offset) ++ goto exit; ++ ++ start = ies + offset; ++ search_len = *ies_len - offset; ++ ++ while (1) { ++ target_ie = rtw_get_ie_ex(start, search_len, eid, oui, oui_len, NULL, &target_ielen); ++ if (target_ie && target_ielen) { ++ u8 buf[MAX_IE_SZ] = {0}; ++ u8 *remain_ies = target_ie + target_ielen; ++ uint remain_len = search_len - (remain_ies - start); ++ ++ memcpy(buf, remain_ies, remain_len); ++ memcpy(target_ie, buf, remain_len); ++ *ies_len = *ies_len - target_ielen; ++ ret = _SUCCESS; ++ ++ start = target_ie; ++ search_len = remain_len; ++ } else { ++ break; ++ } ++ } ++exit: ++ return ret; ++} ++ ++void rtw_set_supported_rate(u8 *SupportedRates, uint mode) ++{ ++ ++ memset(SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX); ++ ++ switch (mode) { ++ case WIRELESS_11B: ++ memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN); ++ break; ++ case WIRELESS_11G: ++ memcpy(SupportedRates, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN); ++ break; ++ case WIRELESS_11BG: ++ case WIRELESS_11G_24N: ++ case WIRELESS_11_24N: ++ case WIRELESS_11BG_24N: ++ memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN); ++ memcpy(SupportedRates + IEEE80211_CCK_RATE_LEN, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN); ++ break; ++ } ++ ++} ++ ++uint rtw_get_rateset_len(u8 *rateset) ++{ ++ uint i = 0; ++ ++ while (1) { ++ if ((rateset[i]) == 0) ++ break; ++ if (i > 12) ++ break; ++ i++; ++ } ++ ++ return i; ++} ++ ++int rtw_generate_ie(struct registry_priv *pregistrypriv) ++{ ++ u8 wireless_mode; ++ int sz = 0, rateLen; ++ struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; ++ u8 *ie = pdev_network->IEs; ++ ++ /* timestamp will be inserted by hardware */ ++ sz += 8; ++ ie += sz; ++ ++ /* beacon interval : 2bytes */ ++ *(__le16 *)ie = cpu_to_le16((u16)pdev_network->Configuration.BeaconPeriod);/* BCN_INTERVAL; */ ++ sz += 2; ++ ie += 2; ++ ++ /* capability info */ ++ *(u16 *)ie = 0; ++ ++ *(__le16 *)ie |= cpu_to_le16(cap_IBSS); ++ ++ if (pregistrypriv->preamble == PREAMBLE_SHORT) ++ *(__le16 *)ie |= cpu_to_le16(cap_ShortPremble); ++ ++ if (pdev_network->Privacy) ++ *(__le16 *)ie |= cpu_to_le16(cap_Privacy); ++ ++ sz += 2; ++ ie += 2; ++ ++ /* SSID */ ++ ie = rtw_set_ie(ie, _SSID_IE_, pdev_network->Ssid.SsidLength, pdev_network->Ssid.Ssid, &sz); ++ ++ /* supported rates */ ++ wireless_mode = pregistrypriv->wireless_mode; ++ ++ rtw_set_supported_rate(pdev_network->SupportedRates, wireless_mode); ++ ++ rateLen = rtw_get_rateset_len(pdev_network->SupportedRates); ++ ++ if (rateLen > 8) { ++ ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, pdev_network->SupportedRates, &sz); ++ /* ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz); */ ++ } else { ++ ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, pdev_network->SupportedRates, &sz); ++ } ++ ++ /* DS parameter set */ ++ ie = rtw_set_ie(ie, _DSSET_IE_, 1, (u8 *)&pdev_network->Configuration.DSConfig, &sz); ++ ++ /* IBSS Parameter Set */ ++ ++ ie = rtw_set_ie(ie, _IBSS_PARA_IE_, 2, (u8 *)&pdev_network->Configuration.ATIMWindow, &sz); ++ ++ if (rateLen > 8) ++ ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz); ++ ++ return sz; ++} ++ ++unsigned char *rtw_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit) ++{ ++ int len; ++ u16 val16; ++ __le16 le_tmp; ++ unsigned char wpa_oui_type[] = {0x00, 0x50, 0xf2, 0x01}; ++ u8 *pbuf = pie; ++ int limit_new = limit; ++ ++ while (1) { ++ pbuf = rtw_get_ie(pbuf, _WPA_IE_ID_, &len, limit_new); ++ ++ if (pbuf) { ++ /* check if oui matches... */ ++ if (memcmp((pbuf + 2), wpa_oui_type, sizeof(wpa_oui_type))) ++ goto check_next_ie; ++ ++ /* check version... */ ++ memcpy((u8 *)&le_tmp, (pbuf + 6), sizeof(val16)); ++ ++ val16 = le16_to_cpu(le_tmp); ++ if (val16 != 0x0001) ++ goto check_next_ie; ++ *wpa_ie_len = *(pbuf + 1); ++ return pbuf; ++ } else { ++ *wpa_ie_len = 0; ++ return NULL; ++ } ++ ++check_next_ie: ++ limit_new = limit - (pbuf - pie) - 2 - len; ++ if (limit_new <= 0) ++ break; ++ pbuf += (2 + len); ++ } ++ *wpa_ie_len = 0; ++ return NULL; ++} ++ ++unsigned char *rtw_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit) ++{ ++ ++ return rtw_get_ie(pie, _WPA2_IE_ID_, rsn_ie_len, limit); ++} ++ ++int rtw_get_wpa_cipher_suite(u8 *s) ++{ ++ if (!memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN)) ++ return WPA_CIPHER_NONE; ++ if (!memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN)) ++ return WPA_CIPHER_WEP40; ++ if (!memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN)) ++ return WPA_CIPHER_TKIP; ++ if (!memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN)) ++ return WPA_CIPHER_CCMP; ++ if (!memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN)) ++ return WPA_CIPHER_WEP104; ++ ++ return 0; ++} ++ ++int rtw_get_wpa2_cipher_suite(u8 *s) ++{ ++ if (!memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN)) ++ return WPA_CIPHER_NONE; ++ if (!memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN)) ++ return WPA_CIPHER_WEP40; ++ if (!memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN)) ++ return WPA_CIPHER_TKIP; ++ if (!memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN)) ++ return WPA_CIPHER_CCMP; ++ if (!memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN)) ++ return WPA_CIPHER_WEP104; ++ ++ return 0; ++} ++ ++int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x) ++{ ++ int i, ret = _SUCCESS; ++ int left, count; ++ u8 *pos; ++ u8 SUITE_1X[4] = {0x00, 0x50, 0xf2, 1}; ++ ++ if (wpa_ie_len <= 0) { ++ /* No WPA IE - fail silently */ ++ return _FAIL; ++ } ++ ++ if ((*wpa_ie != _WPA_IE_ID_) || (*(wpa_ie + 1) != (u8)(wpa_ie_len - 2)) || ++ (memcmp(wpa_ie + 2, RTW_WPA_OUI_TYPE, WPA_SELECTOR_LEN))) ++ return _FAIL; ++ ++ pos = wpa_ie; ++ ++ pos += 8; ++ left = wpa_ie_len - 8; ++ ++ /* group_cipher */ ++ if (left >= WPA_SELECTOR_LEN) { ++ *group_cipher = rtw_get_wpa_cipher_suite(pos); ++ pos += WPA_SELECTOR_LEN; ++ left -= WPA_SELECTOR_LEN; ++ } else if (left > 0) { ++ return _FAIL; ++ } ++ ++ /* pairwise_cipher */ ++ if (left >= 2) { ++ count = get_unaligned_le16(pos); ++ pos += 2; ++ left -= 2; ++ ++ if (count == 0 || left < count * WPA_SELECTOR_LEN) ++ return _FAIL; ++ ++ for (i = 0; i < count; i++) { ++ *pairwise_cipher |= rtw_get_wpa_cipher_suite(pos); ++ ++ pos += WPA_SELECTOR_LEN; ++ left -= WPA_SELECTOR_LEN; ++ } ++ } else if (left == 1) { ++ return _FAIL; ++ } ++ ++ if (is_8021x) { ++ if (left >= 6) { ++ pos += 2; ++ if (!memcmp(pos, SUITE_1X, 4)) ++ *is_8021x = 1; ++ } ++ } ++ ++ return ret; ++} ++ ++int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x) ++{ ++ int i, ret = _SUCCESS; ++ int left, count; ++ u8 *pos; ++ u8 SUITE_1X[4] = {0x00, 0x0f, 0xac, 0x01}; ++ ++ if (rsn_ie_len <= 0) { ++ /* No RSN IE - fail silently */ ++ return _FAIL; ++ } ++ ++ if ((*rsn_ie != _WPA2_IE_ID_) || (*(rsn_ie + 1) != (u8)(rsn_ie_len - 2))) ++ return _FAIL; ++ ++ pos = rsn_ie; ++ pos += 4; ++ left = rsn_ie_len - 4; ++ ++ /* group_cipher */ ++ if (left >= RSN_SELECTOR_LEN) { ++ *group_cipher = rtw_get_wpa2_cipher_suite(pos); ++ ++ pos += RSN_SELECTOR_LEN; ++ left -= RSN_SELECTOR_LEN; ++ ++ } else if (left > 0) { ++ return _FAIL; ++ } ++ ++ /* pairwise_cipher */ ++ if (left >= 2) { ++ count = get_unaligned_le16(pos); ++ pos += 2; ++ left -= 2; ++ ++ if (count == 0 || left < count * RSN_SELECTOR_LEN) ++ return _FAIL; ++ ++ for (i = 0; i < count; i++) { ++ *pairwise_cipher |= rtw_get_wpa2_cipher_suite(pos); ++ ++ pos += RSN_SELECTOR_LEN; ++ left -= RSN_SELECTOR_LEN; ++ } ++ ++ } else if (left == 1) { ++ return _FAIL; ++ } ++ ++ if (is_8021x) { ++ if (left >= 6) { ++ pos += 2; ++ if (!memcmp(pos, SUITE_1X, 4)) ++ *is_8021x = 1; ++ } ++ } ++ return ret; ++} ++ ++int rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie, u16 *wpa_len) ++{ ++ u8 authmode; ++ u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01}; ++ uint cnt; ++ ++ /* Search required WPA or WPA2 IE and copy to sec_ie[] */ ++ ++ cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_); ++ ++ while (cnt < in_len) { ++ authmode = in_ie[cnt]; ++ ++ if ((authmode == _WPA_IE_ID_) && (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) { ++ if (wpa_ie) ++ memcpy(wpa_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); ++ ++ *wpa_len = in_ie[cnt + 1] + 2; ++ cnt += in_ie[cnt + 1] + 2; /* get next */ ++ } else { ++ if (authmode == _WPA2_IE_ID_) { ++ if (rsn_ie) ++ memcpy(rsn_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); ++ ++ *rsn_len = in_ie[cnt + 1] + 2; ++ cnt += in_ie[cnt + 1] + 2; /* get next */ ++ } else { ++ cnt += in_ie[cnt + 1] + 2; /* get next */ ++ } ++ } ++ } ++ ++ return *rsn_len + *wpa_len; ++} ++ ++u8 rtw_is_wps_ie(u8 *ie_ptr, uint *wps_ielen) ++{ ++ u8 match = false; ++ u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; ++ ++ if (!ie_ptr) ++ return match; ++ ++ eid = ie_ptr[0]; ++ ++ if ((eid == _WPA_IE_ID_) && (!memcmp(&ie_ptr[2], wps_oui, 4))) { ++ *wps_ielen = ie_ptr[1] + 2; ++ match = true; ++ } ++ return match; ++} ++ ++/** ++ * rtw_get_wps_ie - Search WPS IE from a series of IEs ++ * @in_ie: Address of IEs to search ++ * @in_len: Length limit from in_ie ++ * @wps_ie: If not NULL and WPS IE is found, WPS IE will be copied to the buf starting from wps_ie ++ * @wps_ielen: If not NULL and WPS IE is found, will set to the length of the entire WPS IE ++ * ++ * Returns: The address of the WPS IE found, or NULL ++ */ ++u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen) ++{ ++ uint cnt; ++ u8 *wpsie_ptr = NULL; ++ u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; ++ ++ if (wps_ielen) ++ *wps_ielen = 0; ++ ++ if (!in_ie || in_len <= 0) ++ return wpsie_ptr; ++ ++ cnt = 0; ++ ++ while (cnt < in_len) { ++ eid = in_ie[cnt]; ++ ++ if ((eid == _WPA_IE_ID_) && (!memcmp(&in_ie[cnt + 2], wps_oui, 4))) { ++ wpsie_ptr = &in_ie[cnt]; ++ ++ if (wps_ie) ++ memcpy(wps_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); ++ ++ if (wps_ielen) ++ *wps_ielen = in_ie[cnt + 1] + 2; ++ ++ cnt += in_ie[cnt + 1] + 2; ++ ++ break; ++ } else { ++ cnt += in_ie[cnt + 1] + 2; /* goto next */ ++ } ++ } ++ return wpsie_ptr; ++} ++ ++/** ++ * rtw_get_wps_attr - Search a specific WPS attribute from a given WPS IE ++ * @wps_ie: Address of WPS IE to search ++ * @wps_ielen: Length limit from wps_ie ++ * @target_attr_id: The attribute ID of WPS attribute to search ++ * @buf_attr: If not NULL and the WPS attribute is found, WPS attribute will be copied to the buf starting from buf_attr ++ * @len_attr: If not NULL and the WPS attribute is found, will set to the length of the entire WPS attribute ++ * ++ * Returns: the address of the specific WPS attribute found, or NULL ++ */ ++u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_attr, u32 *len_attr) ++{ ++ u8 *attr_ptr = NULL; ++ u8 *target_attr_ptr = NULL; ++ u8 wps_oui[4] = {0x00, 0x50, 0xF2, 0x04}; ++ ++ if (len_attr) ++ *len_attr = 0; ++ ++ if ((wps_ie[0] != _VENDOR_SPECIFIC_IE_) || ++ (memcmp(wps_ie + 2, wps_oui, 4))) ++ return attr_ptr; ++ ++ /* 6 = 1(Element ID) + 1(Length) + 4(WPS OUI) */ ++ attr_ptr = wps_ie + 6; /* goto first attr */ ++ ++ while (attr_ptr - wps_ie < wps_ielen) { ++ /* 4 = 2(Attribute ID) + 2(Length) */ ++ u16 attr_id = RTW_GET_BE16(attr_ptr); ++ u16 attr_data_len = RTW_GET_BE16(attr_ptr + 2); ++ u16 attr_len = attr_data_len + 4; ++ ++ if (attr_id == target_attr_id) { ++ target_attr_ptr = attr_ptr; ++ if (buf_attr) ++ memcpy(buf_attr, attr_ptr, attr_len); ++ if (len_attr) ++ *len_attr = attr_len; ++ break; ++ } else { ++ attr_ptr += attr_len; /* goto next */ ++ } ++ } ++ return target_attr_ptr; ++} ++ ++/** ++ * rtw_get_wps_attr_content - Search a specific WPS attribute content from a given WPS IE ++ * @wps_ie: Address of WPS IE to search ++ * @wps_ielen: Length limit from wps_ie ++ * @target_attr_id: The attribute ID of WPS attribute to search ++ * @buf_content: If not NULL and the WPS attribute is found, WPS attribute content will be copied to the buf starting from buf_content ++ * @len_content: If not NULL and the WPS attribute is found, will set to the length of the WPS attribute content ++ * ++ * Returns: the address of the specific WPS attribute content found, or NULL ++ */ ++u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_content, uint *len_content) ++{ ++ u8 *attr_ptr; ++ u32 attr_len; ++ ++ if (len_content) ++ *len_content = 0; ++ ++ attr_ptr = rtw_get_wps_attr(wps_ie, wps_ielen, target_attr_id, NULL, &attr_len); ++ ++ if (attr_ptr && attr_len) { ++ if (buf_content) ++ memcpy(buf_content, attr_ptr + 4, attr_len - 4); ++ ++ if (len_content) ++ *len_content = attr_len - 4; ++ ++ return attr_ptr + 4; ++ } ++ ++ return NULL; ++} ++ ++static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, ++ struct rtw_ieee802_11_elems *elems, ++ int show_errors) ++{ ++ unsigned int oui; ++ ++ /* first 3 bytes in vendor specific information element are the IEEE ++ * OUI of the vendor. The following byte is used a vendor specific ++ * sub-type. */ ++ if (elen < 4) { ++ if (show_errors) { ++ DBG_88E("short vendor specific information element ignored (len=%lu)\n", ++ (unsigned long)elen); ++ } ++ return -1; ++ } ++ ++ oui = RTW_GET_BE24(pos); ++ switch (oui) { ++ case OUI_MICROSOFT: ++ /* Microsoft/Wi-Fi information elements are further typed and ++ * subtyped */ ++ switch (pos[3]) { ++ case 1: ++ /* Microsoft OUI (00:50:F2) with OUI Type 1: ++ * real WPA information element */ ++ elems->wpa_ie = pos; ++ elems->wpa_ie_len = elen; ++ break; ++ case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */ ++ if (elen < 5) { ++ DBG_88E("short WME information element ignored (len=%lu)\n", ++ (unsigned long)elen); ++ return -1; ++ } ++ switch (pos[4]) { ++ case WME_OUI_SUBTYPE_INFORMATION_ELEMENT: ++ case WME_OUI_SUBTYPE_PARAMETER_ELEMENT: ++ elems->wme = pos; ++ elems->wme_len = elen; ++ break; ++ case WME_OUI_SUBTYPE_TSPEC_ELEMENT: ++ elems->wme_tspec = pos; ++ elems->wme_tspec_len = elen; ++ break; ++ default: ++ DBG_88E("unknown WME information element ignored (subtype=%d len=%lu)\n", ++ pos[4], (unsigned long)elen); ++ return -1; ++ } ++ break; ++ case 4: ++ /* Wi-Fi Protected Setup (WPS) IE */ ++ elems->wps_ie = pos; ++ elems->wps_ie_len = elen; ++ break; ++ default: ++ DBG_88E("Unknown Microsoft information element ignored (type=%d len=%lu)\n", ++ pos[3], (unsigned long)elen); ++ return -1; ++ } ++ break; ++ ++ case OUI_BROADCOM: ++ switch (pos[3]) { ++ case VENDOR_HT_CAPAB_OUI_TYPE: ++ elems->vendor_ht_cap = pos; ++ elems->vendor_ht_cap_len = elen; ++ break; ++ default: ++ DBG_88E("Unknown Broadcom information element ignored (type=%d len=%lu)\n", ++ pos[3], (unsigned long)elen); ++ return -1; ++ } ++ break; ++ default: ++ DBG_88E("unknown vendor specific information element ignored (vendor OUI %02x:%02x:%02x len=%lu)\n", ++ pos[0], pos[1], pos[2], (unsigned long)elen); ++ return -1; ++ } ++ return 0; ++} ++ ++/** ++ * ieee802_11_parse_elems - Parse information elements in management frames ++ * @start: Pointer to the start of IEs ++ * @len: Length of IE buffer in octets ++ * @elems: Data structure for parsed elements ++ * @show_errors: Whether to show parsing errors in debug log ++ * Returns: Parsing result ++ */ ++enum parse_res rtw_ieee802_11_parse_elems(u8 *start, uint len, ++ struct rtw_ieee802_11_elems *elems, ++ int show_errors) ++{ ++ uint left = len; ++ u8 *pos = start; ++ int unknown = 0; ++ ++ memset(elems, 0, sizeof(*elems)); ++ ++ while (left >= 2) { ++ u8 id, elen; ++ ++ id = *pos++; ++ elen = *pos++; ++ left -= 2; ++ ++ if (elen > left) { ++ if (show_errors) { ++ DBG_88E("IEEE 802.11 element parse failed (id=%d elen=%d left=%lu)\n", ++ id, elen, (unsigned long)left); ++ } ++ return ParseFailed; ++ } ++ ++ switch (id) { ++ case WLAN_EID_SSID: ++ elems->ssid = pos; ++ elems->ssid_len = elen; ++ break; ++ case WLAN_EID_SUPP_RATES: ++ elems->supp_rates = pos; ++ elems->supp_rates_len = elen; ++ break; ++ case WLAN_EID_FH_PARAMS: ++ elems->fh_params = pos; ++ elems->fh_params_len = elen; ++ break; ++ case WLAN_EID_DS_PARAMS: ++ elems->ds_params = pos; ++ elems->ds_params_len = elen; ++ break; ++ case WLAN_EID_CF_PARAMS: ++ elems->cf_params = pos; ++ elems->cf_params_len = elen; ++ break; ++ case WLAN_EID_TIM: ++ elems->tim = pos; ++ elems->tim_len = elen; ++ break; ++ case WLAN_EID_IBSS_PARAMS: ++ elems->ibss_params = pos; ++ elems->ibss_params_len = elen; ++ break; ++ case WLAN_EID_CHALLENGE: ++ elems->challenge = pos; ++ elems->challenge_len = elen; ++ break; ++ case WLAN_EID_ERP_INFO: ++ elems->erp_info = pos; ++ elems->erp_info_len = elen; ++ break; ++ case WLAN_EID_EXT_SUPP_RATES: ++ elems->ext_supp_rates = pos; ++ elems->ext_supp_rates_len = elen; ++ break; ++ case WLAN_EID_VENDOR_SPECIFIC: ++ if (rtw_ieee802_11_parse_vendor_specific(pos, elen, elems, show_errors)) ++ unknown++; ++ break; ++ case WLAN_EID_RSN: ++ elems->rsn_ie = pos; ++ elems->rsn_ie_len = elen; ++ break; ++ case WLAN_EID_PWR_CAPABILITY: ++ elems->power_cap = pos; ++ elems->power_cap_len = elen; ++ break; ++ case WLAN_EID_SUPPORTED_CHANNELS: ++ elems->supp_channels = pos; ++ elems->supp_channels_len = elen; ++ break; ++ case WLAN_EID_MOBILITY_DOMAIN: ++ elems->mdie = pos; ++ elems->mdie_len = elen; ++ break; ++ case WLAN_EID_FAST_BSS_TRANSITION: ++ elems->ftie = pos; ++ elems->ftie_len = elen; ++ break; ++ case WLAN_EID_TIMEOUT_INTERVAL: ++ elems->timeout_int = pos; ++ elems->timeout_int_len = elen; ++ break; ++ case WLAN_EID_HT_CAP: ++ elems->ht_capabilities = pos; ++ elems->ht_capabilities_len = elen; ++ break; ++ case WLAN_EID_HT_OPERATION: ++ elems->ht_operation = pos; ++ elems->ht_operation_len = elen; ++ break; ++ default: ++ unknown++; ++ if (!show_errors) ++ break; ++ DBG_88E("IEEE 802.11 element parse ignored unknown element (id=%d elen=%d)\n", ++ id, elen); ++ break; ++ } ++ left -= elen; ++ pos += elen; ++ } ++ if (left) ++ return ParseFailed; ++ return unknown ? ParseUnknown : ParseOK; ++} ++ ++u8 key_char2num(u8 ch) ++{ ++ if ((ch >= '0') && (ch <= '9')) ++ return ch - '0'; ++ else if ((ch >= 'a') && (ch <= 'f')) ++ return ch - 'a' + 10; ++ else if ((ch >= 'A') && (ch <= 'F')) ++ return ch - 'A' + 10; ++ else ++ return 0xff; ++} ++ ++u8 str_2char2num(u8 hch, u8 lch) ++{ ++ return (key_char2num(hch) * 10) + key_char2num(lch); ++} ++ ++u8 key_2char2num(u8 hch, u8 lch) ++{ ++ return (key_char2num(hch) << 4) | key_char2num(lch); ++} ++ ++void rtw_macaddr_cfg(u8 *mac_addr) ++{ ++ u8 mac[ETH_ALEN]; ++ if (!mac_addr) ++ return; ++ ++ if (rtw_initmac) { /* Users specify the mac address */ ++ int jj, kk; ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ mac[jj] = key_2char2num(rtw_initmac[kk], rtw_initmac[kk + 1]); ++ memcpy(mac_addr, mac, ETH_ALEN); ++ } else { /* Use the mac address stored in the Efuse */ ++ memcpy(mac, mac_addr, ETH_ALEN); ++ } ++ ++ if (((mac[0] == 0xff) && (mac[1] == 0xff) && (mac[2] == 0xff) && ++ (mac[3] == 0xff) && (mac[4] == 0xff) && (mac[5] == 0xff)) || ++ ((mac[0] == 0x0) && (mac[1] == 0x0) && (mac[2] == 0x0) && ++ (mac[3] == 0x0) && (mac[4] == 0x0) && (mac[5] == 0x0))) { ++ mac[0] = 0x00; ++ mac[1] = 0xe0; ++ mac[2] = 0x4c; ++ mac[3] = 0x87; ++ mac[4] = 0x00; ++ mac[5] = 0x00; ++ /* use default mac addresss */ ++ memcpy(mac_addr, mac, ETH_ALEN); ++ DBG_88E("MAC Address from efuse error, assign default one !!!\n"); ++ } ++ ++ DBG_88E("rtw_macaddr_cfg MAC Address = %pM\n", (mac_addr)); ++} ++ ++void dump_ies(u8 *buf, u32 buf_len) ++{ ++ u8 *pos = (u8 *)buf; ++ u8 id, len; ++ ++ while (pos - buf <= buf_len) { ++ id = *pos; ++ len = *(pos + 1); ++ ++ DBG_88E("%s ID:%u, LEN:%u\n", __func__, id, len); ++ #ifdef CONFIG_88EU_P2P ++ dump_p2p_ie(pos, len); ++ #endif ++ dump_wps_ie(pos, len); ++ ++ pos += (2 + len); ++ } ++} ++ ++void dump_wps_ie(u8 *ie, u32 ie_len) ++{ ++ u8 *pos = (u8 *)ie; ++ u16 id; ++ u16 len; ++ u8 *wps_ie; ++ uint wps_ielen; ++ ++ wps_ie = rtw_get_wps_ie(ie, ie_len, NULL, &wps_ielen); ++ if (wps_ie != ie || wps_ielen == 0) ++ return; ++ ++ pos += 6; ++ while (pos - ie < ie_len) { ++ id = RTW_GET_BE16(pos); ++ len = RTW_GET_BE16(pos + 2); ++ DBG_88E("%s ID:0x%04x, LEN:%u\n", __func__, id, len); ++ pos += (4 + len); ++ } ++} ++ ++#ifdef CONFIG_88EU_P2P ++void dump_p2p_ie(u8 *ie, u32 ie_len) ++{ ++ u8 *pos = (u8 *)ie; ++ u8 id; ++ u16 len; ++ u8 *p2p_ie; ++ uint p2p_ielen; ++ ++ p2p_ie = rtw_get_p2p_ie(ie, ie_len, NULL, &p2p_ielen); ++ if (p2p_ie != ie || p2p_ielen == 0) ++ return; ++ ++ pos += 6; ++ while (pos - ie < ie_len) { ++ id = *pos; ++ len = get_unaligned_le16(pos + 1); ++ DBG_88E("%s ID:%u, LEN:%u\n", __func__, id, len); ++ pos += (3 + len); ++ } ++} ++ ++/** ++ * rtw_get_p2p_ie - Search P2P IE from a series of IEs ++ * @in_ie: Address of IEs to search ++ * @in_len: Length limit from in_ie ++ * @p2p_ie: If not NULL and P2P IE is found, P2P IE will be copied to the buf starting from p2p_ie ++ * @p2p_ielen: If not NULL and P2P IE is found, will set to the length of the entire P2P IE ++ * ++ * Returns: The address of the P2P IE found, or NULL ++ */ ++u8 *rtw_get_p2p_ie(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen) ++{ ++ uint cnt = 0; ++ u8 *p2p_ie_ptr; ++ u8 eid, p2p_oui[4] = {0x50, 0x6F, 0x9A, 0x09}; ++ ++ if (p2p_ielen) ++ *p2p_ielen = 0; ++ ++ while (cnt < in_len) { ++ eid = in_ie[cnt]; ++ if ((in_len < 0) || (cnt > MAX_IE_SZ)) { ++ dump_stack(); ++ return NULL; ++ } ++ if ((eid == _VENDOR_SPECIFIC_IE_) && !memcmp(&in_ie[cnt + 2], p2p_oui, 4)) { ++ p2p_ie_ptr = in_ie + cnt; ++ ++ if (p2p_ie) ++ memcpy(p2p_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); ++ if (p2p_ielen) ++ *p2p_ielen = in_ie[cnt + 1] + 2; ++ return p2p_ie_ptr; ++ } else { ++ cnt += in_ie[cnt + 1] + 2; /* goto next */ ++ } ++ } ++ return NULL; ++} ++ ++/** ++ * rtw_get_p2p_attr - Search a specific P2P attribute from a given P2P IE ++ * @p2p_ie: Address of P2P IE to search ++ * @p2p_ielen: Length limit from p2p_ie ++ * @target_attr_id: The attribute ID of P2P attribute to search ++ * @buf_attr: If not NULL and the P2P attribute is found, P2P attribute will be copied to the buf starting from buf_attr ++ * @len_attr: If not NULL and the P2P attribute is found, will set to the length of the entire P2P attribute ++ * ++ * Returns: the address of the specific WPS attribute found, or NULL ++ */ ++u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id, u8 *buf_attr, u32 *len_attr) ++{ ++ u8 *attr_ptr = NULL; ++ u8 *target_attr_ptr = NULL; ++ u8 p2p_oui[4] = {0x50, 0x6F, 0x9A, 0x09}; ++ ++ if (len_attr) ++ *len_attr = 0; ++ ++ if (!p2p_ie || (p2p_ie[0] != _VENDOR_SPECIFIC_IE_) || ++ memcmp(p2p_ie + 2, p2p_oui, 4)) ++ return attr_ptr; ++ ++ /* 6 = 1(Element ID) + 1(Length) + 3 (OUI) + 1(OUI Type) */ ++ attr_ptr = p2p_ie + 6; /* goto first attr */ ++ ++ while (attr_ptr - p2p_ie < p2p_ielen) { ++ /* 3 = 1(Attribute ID) + 2(Length) */ ++ u8 attr_id = *attr_ptr; ++ u16 attr_data_len = get_unaligned_le16(attr_ptr + 1); ++ u16 attr_len = attr_data_len + 3; ++ ++ if (attr_id == target_attr_id) { ++ target_attr_ptr = attr_ptr; ++ ++ if (buf_attr) ++ memcpy(buf_attr, attr_ptr, attr_len); ++ if (len_attr) ++ *len_attr = attr_len; ++ break; ++ } else { ++ attr_ptr += attr_len; /* goto next */ ++ } ++ } ++ return target_attr_ptr; ++} ++ ++/** ++ * rtw_get_p2p_attr_content - Search a specific P2P attribute content from a given P2P IE ++ * @p2p_ie: Address of P2P IE to search ++ * @p2p_ielen: Length limit from p2p_ie ++ * @target_attr_id: The attribute ID of P2P attribute to search ++ * @buf_content: If not NULL and the P2P attribute is found, P2P attribute content will be copied to the buf starting from buf_content ++ * @len_content: If not NULL and the P2P attribute is found, will set to the length of the P2P attribute content ++ * ++ * Returns: the address of the specific P2P attribute content found, or NULL ++ */ ++u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id, u8 *buf_content, uint *len_content) ++{ ++ u8 *attr_ptr; ++ u32 attr_len; ++ ++ if (len_content) ++ *len_content = 0; ++ ++ attr_ptr = rtw_get_p2p_attr(p2p_ie, p2p_ielen, target_attr_id, NULL, &attr_len); ++ ++ if (attr_ptr && attr_len) { ++ if (buf_content) ++ memcpy(buf_content, attr_ptr + 3, attr_len - 3); ++ ++ if (len_content) ++ *len_content = attr_len - 3; ++ ++ return attr_ptr + 3; ++ } ++ ++ return NULL; ++} ++ ++u32 rtw_set_p2p_attr_content(u8 *pbuf, u8 attr_id, u16 attr_len, u8 *pdata_attr) ++{ ++ u32 a_len; ++ ++ *pbuf = attr_id; ++ ++ /* u16*)(pbuf + 1) = cpu_to_le16(attr_len); */ ++ RTW_PUT_LE16(pbuf + 1, attr_len); ++ ++ if (pdata_attr) ++ memcpy(pbuf + 3, pdata_attr, attr_len); ++ ++ a_len = attr_len + 3; ++ ++ return a_len; ++} ++ ++static uint rtw_p2p_attr_remove(u8 *ie, uint ielen_ori, u8 attr_id) ++{ ++ u8 *target_attr; ++ u32 target_attr_len; ++ uint ielen = ielen_ori; ++ ++ while (1) { ++ target_attr = rtw_get_p2p_attr(ie, ielen, attr_id, NULL, &target_attr_len); ++ if (target_attr && target_attr_len) { ++ u8 *next_attr = target_attr + target_attr_len; ++ uint remain_len = ielen - (next_attr - ie); ++ ++ memset(target_attr, 0, target_attr_len); ++ memcpy(target_attr, next_attr, remain_len); ++ memset(target_attr + remain_len, 0, target_attr_len); ++ *(ie + 1) -= target_attr_len; ++ ielen -= target_attr_len; ++ } else { ++ break; ++ } ++ } ++ return ielen; ++} ++ ++void rtw_wlan_bssid_ex_remove_p2p_attr(struct wlan_bssid_ex *bss_ex, u8 attr_id) ++{ ++ u8 *p2p_ie; ++ uint p2p_ielen, p2p_ielen_ori; ++ ++ p2p_ie = rtw_get_p2p_ie(bss_ex->IEs + _FIXED_IE_LENGTH_, bss_ex->IELength - _FIXED_IE_LENGTH_, NULL, &p2p_ielen_ori); ++ if (p2p_ie) { ++ p2p_ielen = rtw_p2p_attr_remove(p2p_ie, p2p_ielen_ori, attr_id); ++ if (p2p_ielen != p2p_ielen_ori) { ++ u8 *next_ie_ori = p2p_ie + p2p_ielen_ori; ++ u8 *next_ie = p2p_ie + p2p_ielen; ++ uint remain_len = bss_ex->IELength - (next_ie_ori - bss_ex->IEs); ++ ++ memcpy(next_ie, next_ie_ori, remain_len); ++ memset(next_ie + remain_len, 0, p2p_ielen_ori - p2p_ielen); ++ bss_ex->IELength -= p2p_ielen_ori - p2p_ielen; ++ } ++ } ++} ++ ++#endif /* CONFIG_88EU_P2P */ ++ ++/* Baron adds to avoid FreeBSD warning */ ++int ieee80211_is_empty_essid(const char *essid, int essid_len) ++{ ++ /* Single white space is for Linksys APs */ ++ if (essid_len == 1 && essid[0] == ' ') ++ return 1; ++ ++ /* Otherwise, if the entire essid is 0, we assume it is hidden */ ++ while (essid_len) { ++ essid_len--; ++ if (essid[essid_len] != '\0') ++ return 0; ++ } ++ ++ return 1; ++} ++ ++int ieee80211_get_hdrlen(u16 fc) ++{ ++ int hdrlen = 24; ++ ++ switch (WLAN_FC_GET_TYPE(fc)) { ++ case RTW_IEEE80211_FTYPE_DATA: ++ if (fc & RTW_IEEE80211_STYPE_QOS_DATA) ++ hdrlen += 2; ++ if ((fc & RTW_IEEE80211_FCTL_FROMDS) && (fc & RTW_IEEE80211_FCTL_TODS)) ++ hdrlen += 6; /* Addr4 */ ++ break; ++ case RTW_IEEE80211_FTYPE_CTL: ++ switch (WLAN_FC_GET_STYPE(fc)) { ++ case RTW_IEEE80211_STYPE_CTS: ++ case RTW_IEEE80211_STYPE_ACK: ++ hdrlen = 10; ++ break; ++ default: ++ hdrlen = 16; ++ break; ++ } ++ break; ++ } ++ ++ return hdrlen; ++} ++ ++static int rtw_get_cipher_info(struct wlan_network *pnetwork) ++{ ++ u32 wpa_ielen; ++ unsigned char *pbuf; ++ int group_cipher = 0, pairwise_cipher = 0, is8021x = 0; ++ int ret = _FAIL; ++ pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12); ++ ++ if (pbuf && (wpa_ielen > 0)) { ++ if (_SUCCESS == rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x)) { ++ pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher; ++ pnetwork->BcnInfo.group_cipher = group_cipher; ++ pnetwork->BcnInfo.is_8021x = is8021x; ++ ret = _SUCCESS; ++ } ++ } else { ++ pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12); ++ ++ if (pbuf && (wpa_ielen > 0)) { ++ if (_SUCCESS == rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x)) { ++ pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher; ++ pnetwork->BcnInfo.group_cipher = group_cipher; ++ pnetwork->BcnInfo.is_8021x = is8021x; ++ ret = _SUCCESS; ++ } ++ } ++ } ++ ++ return ret; ++} ++ ++void rtw_get_bcn_info(struct wlan_network *pnetwork) ++{ ++ unsigned short cap = 0; ++ u8 bencrypt = 0; ++ __le16 le_tmp; ++ u16 wpa_len = 0, rsn_len = 0; ++ struct HT_info_element *pht_info = NULL; ++ struct ieee80211_ht_cap *pht_cap = NULL; ++ unsigned int len; ++ unsigned char *p; ++ ++ memcpy(&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2); ++ cap = le16_to_cpu(le_tmp); ++ if (cap & WLAN_CAPABILITY_PRIVACY) { ++ bencrypt = 1; ++ pnetwork->network.Privacy = 1; ++ } else { ++ pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_OPENSYS; ++ } ++ rtw_get_sec_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &rsn_len, NULL, &wpa_len); ++ ++ if (rsn_len > 0) { ++ pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA2; ++ } else if (wpa_len > 0) { ++ pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA; ++ } else { ++ if (bencrypt) ++ pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WEP; ++ } ++ rtw_get_cipher_info(pnetwork); ++ ++ /* get bwmode and ch_offset */ ++ /* parsing HT_CAP_IE */ ++ p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_); ++ if (p && len > 0) { ++ pht_cap = (struct ieee80211_ht_cap *)(p + 2); ++ pnetwork->BcnInfo.ht_cap_info = le16_to_cpu(pht_cap->cap_info); ++ } else { ++ pnetwork->BcnInfo.ht_cap_info = 0; ++ } ++ /* parsing HT_INFO_IE */ ++ p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_); ++ if (p && len > 0) { ++ pht_info = (struct HT_info_element *)(p + 2); ++ pnetwork->BcnInfo.ht_info_infos_0 = pht_info->infos[0]; ++ } else { ++ pnetwork->BcnInfo.ht_info_infos_0 = 0; ++ } ++} ++ ++/* show MCS rate, unit: 100Kbps */ ++u16 rtw_mcs_rate(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40, unsigned char *MCS_rate) ++{ ++ u16 max_rate = 0; ++ ++ if (rf_type == RF_1T1R) { ++ if (MCS_rate[0] & BIT(7)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1500 : 1350) : ((short_GI_20) ? 722 : 650); ++ else if (MCS_rate[0] & BIT(6)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1350 : 1215) : ((short_GI_20) ? 650 : 585); ++ else if (MCS_rate[0] & BIT(5)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1200 : 1080) : ((short_GI_20) ? 578 : 520); ++ else if (MCS_rate[0] & BIT(4)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 900 : 810) : ((short_GI_20) ? 433 : 390); ++ else if (MCS_rate[0] & BIT(3)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 600 : 540) : ((short_GI_20) ? 289 : 260); ++ else if (MCS_rate[0] & BIT(2)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 450 : 405) : ((short_GI_20) ? 217 : 195); ++ else if (MCS_rate[0] & BIT(1)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 300 : 270) : ((short_GI_20) ? 144 : 130); ++ else if (MCS_rate[0] & BIT(0)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 150 : 135) : ((short_GI_20) ? 72 : 65); ++ } else { ++ if (MCS_rate[1]) { ++ if (MCS_rate[1] & BIT(7)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 3000 : 2700) : ((short_GI_20) ? 1444 : 1300); ++ else if (MCS_rate[1] & BIT(6)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 2700 : 2430) : ((short_GI_20) ? 1300 : 1170); ++ else if (MCS_rate[1] & BIT(5)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 2400 : 2160) : ((short_GI_20) ? 1156 : 1040); ++ else if (MCS_rate[1] & BIT(4)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1800 : 1620) : ((short_GI_20) ? 867 : 780); ++ else if (MCS_rate[1] & BIT(3)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1200 : 1080) : ((short_GI_20) ? 578 : 520); ++ else if (MCS_rate[1] & BIT(2)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 900 : 810) : ((short_GI_20) ? 433 : 390); ++ else if (MCS_rate[1] & BIT(1)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 600 : 540) : ((short_GI_20) ? 289 : 260); ++ else if (MCS_rate[1] & BIT(0)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 300 : 270) : ((short_GI_20) ? 144 : 130); ++ } else { ++ if (MCS_rate[0] & BIT(7)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1500 : 1350) : ((short_GI_20) ? 722 : 650); ++ else if (MCS_rate[0] & BIT(6)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1350 : 1215) : ((short_GI_20) ? 650 : 585); ++ else if (MCS_rate[0] & BIT(5)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 1200 : 1080) : ((short_GI_20) ? 578 : 520); ++ else if (MCS_rate[0] & BIT(4)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 900 : 810) : ((short_GI_20) ? 433 : 390); ++ else if (MCS_rate[0] & BIT(3)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 600 : 540) : ((short_GI_20) ? 289 : 260); ++ else if (MCS_rate[0] & BIT(2)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 450 : 405) : ((short_GI_20) ? 217 : 195); ++ else if (MCS_rate[0] & BIT(1)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 300 : 270) : ((short_GI_20) ? 144 : 130); ++ else if (MCS_rate[0] & BIT(0)) ++ max_rate = (bw_40MHz) ? ((short_GI_40) ? 150 : 135) : ((short_GI_20) ? 72 : 65); ++ } ++ } ++ return max_rate; ++} ++ ++int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category, u8 *action) ++{ ++ const u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr); ++ u16 fc; ++ u8 c, a = 0; ++ ++ fc = le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)frame)->frame_ctl); ++ ++ if ((fc & (RTW_IEEE80211_FCTL_FTYPE | RTW_IEEE80211_FCTL_STYPE)) != ++ (RTW_IEEE80211_FTYPE_MGMT | RTW_IEEE80211_STYPE_ACTION)) ++ return false; ++ ++ c = frame_body[0]; ++ ++ switch (c) { ++ case RTW_WLAN_CATEGORY_P2P: /* vendor-specific */ ++ break; ++ default: ++ a = frame_body[1]; ++ } ++ ++ if (category) ++ *category = c; ++ if (action) ++ *action = a; ++ ++ return true; ++} ++ ++static const char *_action_public_str[] = { ++ "ACT_PUB_BSSCOEXIST", ++ "ACT_PUB_DSE_ENABLE", ++ "ACT_PUB_DSE_DEENABLE", ++ "ACT_PUB_DSE_REG_LOCATION", ++ "ACT_PUB_EXT_CHL_SWITCH", ++ "ACT_PUB_DSE_MSR_REQ", ++ "ACT_PUB_DSE_MSR_RPRT", ++ "ACT_PUB_MP", ++ "ACT_PUB_DSE_PWR_CONSTRAINT", ++ "ACT_PUB_VENDOR", ++ "ACT_PUB_GAS_INITIAL_REQ", ++ "ACT_PUB_GAS_INITIAL_RSP", ++ "ACT_PUB_GAS_COMEBACK_REQ", ++ "ACT_PUB_GAS_COMEBACK_RSP", ++ "ACT_PUB_TDLS_DISCOVERY_RSP", ++ "ACT_PUB_LOCATION_TRACK", ++ "ACT_PUB_RSVD", ++}; ++ ++const char *action_public_str(u8 action) ++{ ++ action = (action >= ACT_PUBLIC_MAX) ? ACT_PUBLIC_MAX : action; ++ return _action_public_str[action]; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c +new file mode 100644 +index 000000000000..cde0205816b1 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_io.c +@@ -0,0 +1,299 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++/* ++ ++The purpose of rtw_io.c ++ ++a. provides the API ++ ++b. provides the protocol engine ++ ++c. provides the software interface between caller and the hardware interface ++ ++Compiler Flag Option: ++ ++USB: ++ a. USE_ASYNC_IRP: Both sync/async operations are provided. ++ ++Only sync read/rtw_write_mem operations are provided. ++ ++jackson@realtek.com.tw ++ ++*/ ++ ++#define _RTW_IO_C_ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtw_io.h" ++#include "../include/osdep_intf.h" ++#include "../include/usb_ops.h" ++ ++#define rtw_le16_to_cpu(val) le16_to_cpu(val) ++#define rtw_le32_to_cpu(val) le32_to_cpu(val) ++#define rtw_cpu_to_le16(val) cpu_to_le16(val) ++#define rtw_cpu_to_le32(val) cpu_to_le32(val) ++ ++u8 _rtw_read8(struct adapter *adapter, u32 addr) ++{ ++ u8 r_val; ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr); ++ ++ ++ _read8 = pintfhdl->io_ops._read8; ++ r_val = _read8(pintfhdl, addr); ++ ++ return r_val; ++} ++ ++u16 _rtw_read16(struct adapter *adapter, u32 addr) ++{ ++ u16 r_val; ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr); ++ ++ _read16 = pintfhdl->io_ops._read16; ++ ++ r_val = _read16(pintfhdl, addr); ++ ++ return r_val; ++} ++ ++u32 _rtw_read32(struct adapter *adapter, u32 addr) ++{ ++ u32 r_val; ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr); ++ ++ _read32 = pintfhdl->io_ops._read32; ++ ++ r_val = _read32(pintfhdl, addr); ++ ++ return r_val; ++} ++ ++int _rtw_write8(struct adapter *adapter, u32 addr, u8 val) ++{ ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); ++ int ret; ++ ++ _write8 = pintfhdl->io_ops._write8; ++ ++ ret = _write8(pintfhdl, addr, val); ++ ++ ++ return RTW_STATUS_CODE(ret); ++} ++ ++int _rtw_write16(struct adapter *adapter, u32 addr, u16 val) ++{ ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val); ++ int ret; ++ ++ _write16 = pintfhdl->io_ops._write16; ++ ++ ret = _write16(pintfhdl, addr, val); ++ ++ ++ return RTW_STATUS_CODE(ret); ++} ++int _rtw_write32(struct adapter *adapter, u32 addr, u32 val) ++{ ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val); ++ int ret; ++ ++ _write32 = pintfhdl->io_ops._write32; ++ ++ ret = _write32(pintfhdl, addr, val); ++ ++ ++ return RTW_STATUS_CODE(ret); ++} ++ ++int _rtw_writeN(struct adapter *adapter, u32 addr, u32 length, u8 *pdata) ++{ ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = (struct intf_hdl *)(&pio_priv->intf); ++ int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata); ++ int ret; ++ ++ _writeN = pintfhdl->io_ops._writeN; ++ ++ ret = _writeN(pintfhdl, addr, length, pdata); ++ ++ ++ return RTW_STATUS_CODE(ret); ++} ++int _rtw_write8_async(struct adapter *adapter, u32 addr, u8 val) ++{ ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val); ++ int ret; ++ ++ _write8_async = pintfhdl->io_ops._write8_async; ++ ++ ret = _write8_async(pintfhdl, addr, val); ++ ++ ++ return RTW_STATUS_CODE(ret); ++} ++ ++int _rtw_write16_async(struct adapter *adapter, u32 addr, u16 val) ++{ ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val); ++ int ret; ++ ++ _write16_async = pintfhdl->io_ops._write16_async; ++ ret = _write16_async(pintfhdl, addr, val); ++ ++ return RTW_STATUS_CODE(ret); ++} ++ ++int _rtw_write32_async(struct adapter *adapter, u32 addr, u32 val) ++{ ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val); ++ int ret; ++ ++ _write32_async = pintfhdl->io_ops._write32_async; ++ ret = _write32_async(pintfhdl, addr, val); ++ ++ return RTW_STATUS_CODE(ret); ++} ++ ++void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) ++{ ++ void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ ++ ++ if (adapter->bDriverStopped || adapter->bSurpriseRemoved) ++ return; ++ _read_mem = pintfhdl->io_ops._read_mem; ++ _read_mem(pintfhdl, addr, cnt, pmem); ++ ++} ++ ++void _rtw_write_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) ++{ ++ void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ ++ ++ ++ _write_mem = pintfhdl->io_ops._write_mem; ++ ++ _write_mem(pintfhdl, addr, cnt, pmem); ++ ++ ++} ++ ++void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) ++{ ++ u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ ++ ++ ++ if (adapter->bDriverStopped || adapter->bSurpriseRemoved) ++ return; ++ ++ _read_port = pintfhdl->io_ops._read_port; ++ ++ _read_port(pintfhdl, addr, cnt, pmem); ++ ++ ++} ++ ++void _rtw_read_port_cancel(struct adapter *adapter) ++{ ++ void (*_read_port_cancel)(struct intf_hdl *pintfhdl); ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ ++ _read_port_cancel = pintfhdl->io_ops._read_port_cancel; ++ ++ if (_read_port_cancel) ++ _read_port_cancel(pintfhdl); ++} ++ ++u32 _rtw_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) ++{ ++ u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ u32 ret = _SUCCESS; ++ ++ ++ ++ _write_port = pintfhdl->io_ops._write_port; ++ ++ ret = _write_port(pintfhdl, addr, cnt, pmem); ++ ++ ++ ++ return ret; ++} ++ ++u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms) ++{ ++ int ret = _SUCCESS; ++ struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem; ++ struct submit_ctx sctx; ++ ++ rtw_sctx_init(&sctx, timeout_ms); ++ pxmitbuf->sctx = &sctx; ++ ++ ret = _rtw_write_port(adapter, addr, cnt, pmem); ++ ++ if (ret == _SUCCESS) ++ ret = rtw_sctx_wait(&sctx); ++ ++ return ret; ++} ++ ++void _rtw_write_port_cancel(struct adapter *adapter) ++{ ++ void (*_write_port_cancel)(struct intf_hdl *pintfhdl); ++ struct io_priv *pio_priv = &adapter->iopriv; ++ struct intf_hdl *pintfhdl = &pio_priv->intf; ++ ++ _write_port_cancel = pintfhdl->io_ops._write_port_cancel; ++ ++ if (_write_port_cancel) ++ _write_port_cancel(pintfhdl); ++} ++ ++int rtw_init_io_priv(struct adapter *padapter, void (*set_intf_ops)(struct _io_ops *pops)) ++{ ++ struct io_priv *piopriv = &padapter->iopriv; ++ struct intf_hdl *pintf = &piopriv->intf; ++ ++ if (!set_intf_ops) ++ return _FAIL; ++ ++ piopriv->padapter = padapter; ++ pintf->padapter = padapter; ++ pintf->pintf_dev = adapter_to_dvobj(padapter); ++ ++ set_intf_ops(&pintf->io_ops); ++ ++ return _SUCCESS; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_ioctl_set.c b/drivers/staging/r8188eu/core/rtw_ioctl_set.c +new file mode 100644 +index 000000000000..c187de78b4ac +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_ioctl_set.c +@@ -0,0 +1,891 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_IOCTL_SET_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtw_ioctl_set.h" ++#include "../include/hal_intf.h" ++ ++#include "../include/usb_osintf.h" ++#include "../include/usb_ops.h" ++ ++extern void indicate_wx_scan_complete_event(struct adapter *padapter); ++ ++u8 rtw_validate_ssid(struct ndis_802_11_ssid *ssid) ++{ ++ u8 i; ++ u8 ret = true; ++ ++ if (ssid->SsidLength > 32) { ++ ret = false; ++ goto exit; ++ } ++ ++ for (i = 0; i < ssid->SsidLength; i++) { ++ /* wifi, printable ascii code must be supported */ ++ if (!((ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e))) { ++ ret = false; ++ break; ++ } ++ } ++ ++exit: ++ ++ return ret; ++} ++ ++u8 rtw_do_join(struct adapter *padapter) ++{ ++ struct list_head *plist, *phead; ++ u8 *pibss = NULL; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ u8 ret = _SUCCESS; ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ pmlmepriv->cur_network.join_res = -2; ++ ++ set_fwstate(pmlmepriv, _FW_UNDER_LINKING); ++ ++ pmlmepriv->pscanned = plist; ++ ++ pmlmepriv->to_join = true; ++ ++ if (list_empty(&queue->queue)) { ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ ++ /* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */ ++ /* we try to issue sitesurvey firstly */ ++ ++ if (!pmlmepriv->LinkDetectInfo.bBusyTraffic || ++ pmlmepriv->to_roaming > 0) { ++ /* submit site_survey_cmd */ ++ ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0); ++ if (_SUCCESS != ret) ++ pmlmepriv->to_join = false; ++ } else { ++ pmlmepriv->to_join = false; ++ ret = _FAIL; ++ } ++ ++ goto exit; ++ } else { ++ int select_ret; ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv); ++ if (select_ret == _SUCCESS) { ++ pmlmepriv->to_join = false; ++ _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); ++ } else { ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { ++ /* submit createbss_cmd to change to a ADHOC_MASTER */ ++ ++ /* pmlmepriv->lock has been acquired by caller... */ ++ struct wlan_bssid_ex *pdev_network = &padapter->registrypriv.dev_network; ++ ++ pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; ++ ++ pibss = padapter->registrypriv.dev_network.MacAddress; ++ ++ memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); ++ memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); ++ ++ rtw_update_registrypriv_dev_network(padapter); ++ ++ rtw_generate_random_ibss(pibss); ++ ++ if (rtw_createbss_cmd(padapter) != _SUCCESS) { ++ ret = false; ++ goto exit; ++ } ++ pmlmepriv->to_join = false; ++ } else { ++ /* can't associate ; reset under-linking */ ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ ++ /* when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue */ ++ /* we try to issue sitesurvey firstly */ ++ if (!pmlmepriv->LinkDetectInfo.bBusyTraffic || ++ pmlmepriv->to_roaming > 0) { ++ ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0); ++ if (_SUCCESS != ret) ++ pmlmepriv->to_join = false; ++ } else { ++ ret = _FAIL; ++ pmlmepriv->to_join = false; ++ } ++ } ++ } ++ } ++ ++exit: ++ ++ return ret; ++} ++ ++u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid) ++{ ++ u8 status = _SUCCESS; ++ u32 cur_time = 0; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ DBG_88E_LEVEL(_drv_info_, "set bssid:%pM\n", bssid); ++ ++ if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 && ++ bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) || ++ (bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF && ++ bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) { ++ status = _FAIL; ++ goto exit; ++ } ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ DBG_88E("Set BSSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv)); ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) ++ goto handle_tkip_countermeasure; ++ else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) ++ goto release_mlme_lock; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) { ++ if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN)) { ++ if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) ++ goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */ ++ } else { ++ rtw_disassoc_cmd(padapter, 0, true); ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ rtw_indicate_disconnect(padapter); ++ ++ rtw_free_assoc_resources(padapter, 1); ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); ++ set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); ++ } ++ } ++ } ++ ++handle_tkip_countermeasure: ++ /* should we add something here...? */ ++ ++ if (padapter->securitypriv.btkip_countermeasure) { ++ cur_time = jiffies; ++ ++ if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) { ++ padapter->securitypriv.btkip_countermeasure = false; ++ padapter->securitypriv.btkip_countermeasure_time = 0; ++ } else { ++ status = _FAIL; ++ goto release_mlme_lock; ++ } ++ } ++ ++ memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN); ++ pmlmepriv->assoc_by_bssid = true; ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) ++ pmlmepriv->to_join = true; ++ else ++ status = rtw_do_join(padapter); ++ ++release_mlme_lock: ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++exit: ++ return status; ++} ++ ++u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) ++{ ++ u8 status = _SUCCESS; ++ u32 cur_time = 0; ++ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_network *pnetwork = &pmlmepriv->cur_network; ++ ++ DBG_88E_LEVEL(_drv_info_, "set ssid [%s] fw_state=0x%08x\n", ++ ssid->Ssid, get_fwstate(pmlmepriv)); ++ ++ if (!padapter->hw_init_completed) { ++ status = _FAIL; ++ goto exit; ++ } ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ DBG_88E("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv)); ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { ++ goto handle_tkip_countermeasure; ++ } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { ++ goto release_mlme_lock; ++ } ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) { ++ if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && ++ (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength))) { ++ if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ if (!rtw_is_same_ibss(padapter, pnetwork)) { ++ /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */ ++ rtw_disassoc_cmd(padapter, 0, true); ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ rtw_indicate_disconnect(padapter); ++ ++ rtw_free_assoc_resources(padapter, 1); ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); ++ set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); ++ } ++ } else { ++ goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */ ++ } ++ } else { ++ rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1); ++ } ++ } else { ++ rtw_disassoc_cmd(padapter, 0, true); ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ rtw_indicate_disconnect(padapter); ++ ++ rtw_free_assoc_resources(padapter, 1); ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); ++ set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); ++ } ++ } ++ } ++ ++handle_tkip_countermeasure: ++ ++ if (padapter->securitypriv.btkip_countermeasure) { ++ cur_time = jiffies; ++ ++ if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) { ++ padapter->securitypriv.btkip_countermeasure = false; ++ padapter->securitypriv.btkip_countermeasure_time = 0; ++ } else { ++ status = _FAIL; ++ goto release_mlme_lock; ++ } ++ } ++ ++ memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid)); ++ pmlmepriv->assoc_by_bssid = false; ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { ++ pmlmepriv->to_join = true; ++ } else { ++ status = rtw_do_join(padapter); ++ } ++ ++release_mlme_lock: ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++exit: ++ return status; ++} ++ ++u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter, ++ enum ndis_802_11_network_infra networktype) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_network *cur_network = &pmlmepriv->cur_network; ++ enum ndis_802_11_network_infra *pold_state = &cur_network->network.InfrastructureMode; ++ ++ if (*pold_state != networktype) { ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ /* DBG_88E("change mode, old_mode =%d, new_mode =%d, fw_state = 0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); */ ++ ++ if (*pold_state == Ndis802_11APMode) { ++ /* change to other mode from Ndis802_11APMode */ ++ cur_network->join_res = -1; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ stop_ap_mode(padapter); ++#endif ++ } ++ ++ if ((check_fwstate(pmlmepriv, _FW_LINKED)) || ++ (*pold_state == Ndis802_11IBSS)) ++ rtw_disassoc_cmd(padapter, 0, true); ++ ++ if ((check_fwstate(pmlmepriv, _FW_LINKED)) || ++ (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) ++ rtw_free_assoc_resources(padapter, 1); ++ ++ if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) { ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ rtw_indicate_disconnect(padapter); /* will clr Linked_state; before this function, we must have chked whether issue dis-assoc_cmd or not */ ++ } ++ ++ *pold_state = networktype; ++ ++ _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE); ++ ++ switch (networktype) { ++ case Ndis802_11IBSS: ++ set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); ++ break; ++ case Ndis802_11Infrastructure: ++ set_fwstate(pmlmepriv, WIFI_STATION_STATE); ++ break; ++ case Ndis802_11APMode: ++ set_fwstate(pmlmepriv, WIFI_AP_STATE); ++#ifdef CONFIG_88EU_AP_MODE ++ start_ap_mode(padapter); ++#endif ++ break; ++ case Ndis802_11AutoUnknown: ++ case Ndis802_11InfrastructureMax: ++ break; ++ } ++ spin_unlock_bh(&pmlmepriv->lock); ++ } ++ ++ return true; ++} ++ ++u8 rtw_set_802_11_disassociate(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ rtw_disassoc_cmd(padapter, 0, true); ++ rtw_indicate_disconnect(padapter); ++ rtw_free_assoc_resources(padapter, 1); ++ rtw_pwr_wakeup(padapter); ++ } ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++ return true; ++} ++ ++u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_ssid *pssid, int ssid_max_num) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 res = true; ++ ++ if (!padapter) { ++ res = false; ++ goto exit; ++ } ++ if (!padapter->hw_init_completed) { ++ res = false; ++ goto exit; ++ } ++ ++ if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) || ++ (pmlmepriv->LinkDetectInfo.bBusyTraffic)) { ++ /* Scan or linking is in progress, do nothing. */ ++ res = true; ++ } else { ++ if (rtw_is_scan_deny(padapter)) { ++ DBG_88E(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter)); ++ indicate_wx_scan_complete_event(padapter); ++ return _SUCCESS; ++ } ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, NULL, 0); ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ } ++exit: ++ ++ return res; ++} ++ ++u8 rtw_set_802_11_authentication_mode(struct adapter *padapter, enum ndis_802_11_auth_mode authmode) ++{ ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ int res; ++ u8 ret; ++ ++ psecuritypriv->ndisauthtype = authmode; ++ ++ if (psecuritypriv->ndisauthtype > 3) ++ psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; ++ ++ res = rtw_set_auth(padapter, psecuritypriv); ++ ++ if (res == _SUCCESS) ++ ret = true; ++ else ++ ret = false; ++ ++ return ret; ++} ++ ++u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep) ++{ ++ int keyid, res; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ u8 ret = _SUCCESS; ++ ++ keyid = wep->KeyIndex & 0x3fffffff; ++ ++ if (keyid >= 4) { ++ ret = false; ++ goto exit; ++ } ++ ++ switch (wep->KeyLength) { ++ case 5: ++ psecuritypriv->dot11PrivacyAlgrthm = _WEP40_; ++ break; ++ case 13: ++ psecuritypriv->dot11PrivacyAlgrthm = _WEP104_; ++ break; ++ default: ++ psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ break; ++ } ++ ++ memcpy(&psecuritypriv->dot11DefKey[keyid].skey[0], &wep->KeyMaterial, wep->KeyLength); ++ ++ psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength; ++ ++ psecuritypriv->dot11PrivacyKeyIndex = keyid; ++ ++ res = rtw_set_key(padapter, psecuritypriv, keyid, 1); ++ ++ if (res == _FAIL) ++ ret = false; ++exit: ++ ++ return ret; ++} ++ ++u8 rtw_set_802_11_remove_wep(struct adapter *padapter, u32 keyindex) ++{ ++ u8 ret = _SUCCESS; ++ ++ if (keyindex >= 0x80000000 || !padapter) { ++ ret = false; ++ goto exit; ++ } else { ++ int res; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ if (keyindex < 4) { ++ memset(&psecuritypriv->dot11DefKey[keyindex], 0, 16); ++ res = rtw_set_key(padapter, psecuritypriv, keyindex, 0); ++ psecuritypriv->dot11DefKeylen[keyindex] = 0; ++ if (res == _FAIL) ++ ret = _FAIL; ++ } else { ++ ret = _FAIL; ++ } ++ } ++exit: ++ ++ return ret; ++} ++ ++u8 rtw_set_802_11_add_key(struct adapter *padapter, struct ndis_802_11_key *key) ++{ ++ uint encryptionalgo; ++ u8 *pbssid; ++ struct sta_info *stainfo; ++ u8 bgroup = false; ++ u8 bgrouptkey = false;/* can be removed later */ ++ u8 ret = _SUCCESS; ++ ++ if (((key->KeyIndex & 0x80000000) == 0) && ((key->KeyIndex & 0x40000000) > 0)) { ++ /* It is invalid to clear bit 31 and set bit 30. If the miniport driver encounters this combination, */ ++ /* it must fail the request and return NDIS_STATUS_INVALID_DATA. */ ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ if (key->KeyIndex & 0x40000000) { ++ /* Pairwise key */ ++ ++ pbssid = get_bssid(&padapter->mlmepriv); ++ stainfo = rtw_get_stainfo(&padapter->stapriv, pbssid); ++ ++ if (stainfo && padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ++ encryptionalgo = stainfo->dot118021XPrivacy; ++ else ++ encryptionalgo = padapter->securitypriv.dot11PrivacyAlgrthm; ++ ++ if (key->KeyIndex & 0x000000FF) { ++ /* The key index is specified in the lower 8 bits by values of zero to 255. */ ++ /* The key index should be set to zero for a Pairwise key, and the driver should fail with */ ++ /* NDIS_STATUS_INVALID_DATA if the lower 8 bits is not zero */ ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* check BSSID */ ++ if (is_broadcast_ether_addr(key->BSSID)) { ++ ret = false; ++ goto exit; ++ } ++ ++ /* Check key length for TKIP. */ ++ if ((encryptionalgo == _TKIP_) && (key->KeyLength != 32)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* Check key length for AES. */ ++ if ((encryptionalgo == _AES_) && (key->KeyLength != 16)) { ++ /* For our supplicant, EAPPkt9x.vxd, cannot differentiate TKIP and AES case. */ ++ if (key->KeyLength == 32) { ++ key->KeyLength = 16; ++ } else { ++ ret = _FAIL; ++ goto exit; ++ } ++ } ++ ++ /* Check key length for WEP. For NDTEST, 2005.01.27, by rcnjko. */ ++ if ((encryptionalgo == _WEP40_ || encryptionalgo == _WEP104_) && ++ (key->KeyLength != 5 && key->KeyLength != 13)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ bgroup = false; ++ } else { ++ /* Group key - KeyIndex(BIT(30) == 0) */ ++ /* when add wep key through add key and didn't assigned encryption type before */ ++ if ((padapter->securitypriv.ndisauthtype <= 3) && ++ (padapter->securitypriv.dot118021XGrpPrivacy == 0)) { ++ switch (key->KeyLength) { ++ case 5: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; ++ break; ++ case 13: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; ++ break; ++ default: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ break; ++ } ++ ++ encryptionalgo = padapter->securitypriv.dot11PrivacyAlgrthm; ++ } else { ++ encryptionalgo = padapter->securitypriv.dot118021XGrpPrivacy; ++ } ++ ++ if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE) && !is_broadcast_ether_addr(key->BSSID)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* Check key length for TKIP */ ++ if ((encryptionalgo == _TKIP_) && (key->KeyLength != 32)) { ++ ret = _FAIL; ++ goto exit; ++ } else if (encryptionalgo == _AES_ && (key->KeyLength != 16 && key->KeyLength != 32)) { ++ /* Check key length for AES */ ++ /* For NDTEST, we allow keylen = 32 in this case. 2005.01.27, by rcnjko. */ ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* Change the key length for EAPPkt9x.vxd. Added by Annie, 2005-11-03. */ ++ if ((encryptionalgo == _AES_) && (key->KeyLength == 32)) ++ key->KeyLength = 16; ++ ++ if (key->KeyIndex & 0x8000000) {/* error ??? 0x8000_0000 */ ++ bgrouptkey = true; ++ } ++ ++ if ((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)) && ++ (check_fwstate(&padapter->mlmepriv, _FW_LINKED))) ++ bgrouptkey = true; ++ bgroup = true; ++ } ++ ++ /* If WEP encryption algorithm, just call rtw_set_802_11_add_wep(). */ ++ if ((padapter->securitypriv.dot11AuthAlgrthm != dot11AuthAlgrthm_8021X) && ++ (encryptionalgo == _WEP40_ || encryptionalgo == _WEP104_)) { ++ u32 keyindex; ++ u32 len = FIELD_OFFSET(struct ndis_802_11_key, KeyMaterial) + key->KeyLength; ++ struct ndis_802_11_wep *wep = &padapter->securitypriv.ndiswep; ++ ++ wep->Length = len; ++ keyindex = key->KeyIndex & 0x7fffffff; ++ wep->KeyIndex = keyindex; ++ wep->KeyLength = key->KeyLength; ++ ++ memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength); ++ memcpy(&padapter->securitypriv.dot11DefKey[keyindex].skey[0], key->KeyMaterial, key->KeyLength); ++ ++ padapter->securitypriv.dot11DefKeylen[keyindex] = key->KeyLength; ++ padapter->securitypriv.dot11PrivacyKeyIndex = keyindex; ++ ++ ret = rtw_set_802_11_add_wep(padapter, wep); ++ goto exit; ++ } ++ if (key->KeyIndex & 0x20000000) { ++ /* SetRSC */ ++ if (bgroup) { ++ unsigned long long keysrc = key->KeyRSC & 0x00FFFFFFFFFFFFULL; ++ memcpy(&padapter->securitypriv.dot11Grprxpn, &keysrc, 8); ++ } else { ++ unsigned long long keysrc = key->KeyRSC & 0x00FFFFFFFFFFFFULL; ++ memcpy(&padapter->securitypriv.dot11Grptxpn, &keysrc, 8); ++ } ++ } ++ ++ /* Indicate this key idx is used for TX */ ++ /* Save the key in KeyMaterial */ ++ if (bgroup) { /* Group transmit key */ ++ int res; ++ ++ if (bgrouptkey) ++ padapter->securitypriv.dot118021XGrpKeyid = (u8)key->KeyIndex; ++ if ((key->KeyIndex & 0x3) == 0) { ++ ret = _FAIL; ++ goto exit; ++ } ++ memset(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], 0, 16); ++ memset(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16); ++ memset(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16); ++ ++ if ((key->KeyIndex & 0x10000000)) { ++ memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); ++ memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); ++ } else { ++ memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); ++ memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); ++ } ++ ++ /* set group key by index */ ++ memcpy(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial, key->KeyLength); ++ ++ key->KeyIndex = key->KeyIndex & 0x03; ++ ++ padapter->securitypriv.binstallGrpkey = true; ++ ++ padapter->securitypriv.bcheck_grpkey = false; ++ ++ res = rtw_set_key(padapter, &padapter->securitypriv, key->KeyIndex, 1); ++ ++ if (res == _FAIL) ++ ret = _FAIL; ++ ++ goto exit; ++ ++ } else { /* Pairwise Key */ ++ u8 res; ++ ++ pbssid = get_bssid(&padapter->mlmepriv); ++ stainfo = rtw_get_stainfo(&padapter->stapriv, pbssid); ++ ++ if (stainfo) { ++ memset(&stainfo->dot118021x_UncstKey, 0, 16);/* clear keybuffer */ ++ ++ memcpy(&stainfo->dot118021x_UncstKey, key->KeyMaterial, 16); ++ ++ if (encryptionalgo == _TKIP_) { ++ padapter->securitypriv.busetkipkey = false; ++ ++ /* _set_timer(&padapter->securitypriv.tkip_timer, 50); */ ++ ++ /* if TKIP, save the Receive/Transmit MIC key in KeyMaterial[128-255] */ ++ if ((key->KeyIndex & 0x10000000)) { ++ memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 16, 8); ++ memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 24, 8); ++ ++ } else { ++ memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 24, 8); ++ memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 16, 8); ++ } ++ } ++ ++ /* Set key to CAM through H2C command */ ++ if (bgrouptkey) /* never go to here */ ++ res = rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, false); ++ else ++ res = rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, true); ++ if (!res) ++ ret = _FAIL; ++ } ++ } ++exit: ++ ++ return ret; ++} ++ ++u8 rtw_set_802_11_remove_key(struct adapter *padapter, struct ndis_802_11_remove_key *key) ++{ ++ u8 *pbssid; ++ struct sta_info *stainfo; ++ u8 bgroup = (key->KeyIndex & 0x4000000) > 0 ? false : true; ++ u8 keyIndex = (u8)key->KeyIndex & 0x03; ++ u8 ret = _SUCCESS; ++ ++ if ((key->KeyIndex & 0xbffffffc) > 0) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ if (bgroup) { ++ /* clear group key by index */ ++ ++ memset(&padapter->securitypriv.dot118021XGrpKey[keyIndex], 0, 16); ++ ++ /* \todo Send a H2C Command to Firmware for removing this Key in CAM Entry. */ ++ } else { ++ pbssid = get_bssid(&padapter->mlmepriv); ++ stainfo = rtw_get_stainfo(&padapter->stapriv, pbssid); ++ if (stainfo) { ++ /* clear key by BSSID */ ++ memset(&stainfo->dot118021x_UncstKey, 0, 16); ++ ++ /* \todo Send a H2C Command to Firmware for disable this Key in CAM Entry. */ ++ } else { ++ ret = _FAIL; ++ goto exit; ++ } ++ } ++exit: ++ ++ return ret; ++} ++ ++/* ++* rtw_get_cur_max_rate - ++* @adapter: pointer to struct adapter structure ++* ++* Return 0 or 100Kbps ++*/ ++u16 rtw_get_cur_max_rate(struct adapter *adapter) ++{ ++ int i = 0; ++ u8 *p; ++ u16 rate = 0, max_rate = 0; ++ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct registry_priv *pregistrypriv = &adapter->registrypriv; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; ++ struct ieee80211_ht_cap *pht_capie; ++ u8 rf_type = 0; ++ u8 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0; ++ u16 mcs_rate = 0; ++ u32 ht_ielen = 0; ++ ++ if (adapter->registrypriv.mp_mode == 1) { ++ if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) ++ return 0; ++ } ++ ++ if ((!check_fwstate(pmlmepriv, _FW_LINKED)) && ++ (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) ++ return 0; ++ ++ if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N)) { ++ p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength - 12); ++ if (p && ht_ielen > 0) { ++ pht_capie = (struct ieee80211_ht_cap *)(p + 2); ++ ++ memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2); ++ ++ /* cur_bwmod is updated by beacon, pmlmeinfo is updated by association response */ ++ bw_40MHz = (pmlmeext->cur_bwmode && (HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH & pmlmeinfo->HT_info.infos[0])) ? 1 : 0; ++ ++ short_GI_20 = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; ++ short_GI_40 = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; ++ ++ rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ max_rate = rtw_mcs_rate( ++ rf_type, ++ bw_40MHz & (pregistrypriv->cbw40_enable), ++ short_GI_20, ++ short_GI_40, ++ pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate ++ ); ++ } ++ } else { ++ while ((pcur_bss->SupportedRates[i] != 0) && (pcur_bss->SupportedRates[i] != 0xFF)) { ++ rate = pcur_bss->SupportedRates[i] & 0x7F; ++ if (rate > max_rate) ++ max_rate = rate; ++ i++; ++ } ++ ++ max_rate *= 5; ++ } ++ ++ return max_rate; ++} ++ ++/* ++* rtw_set_scan_mode - ++* @adapter: pointer to struct adapter structure ++* @scan_mode: ++* ++* Return _SUCCESS or _FAIL ++*/ ++int rtw_set_scan_mode(struct adapter *adapter, enum rt_scan_type scan_mode) ++{ ++ if (scan_mode != SCAN_ACTIVE && scan_mode != SCAN_PASSIVE) ++ return _FAIL; ++ ++ adapter->mlmepriv.scan_mode = scan_mode; ++ ++ return _SUCCESS; ++} ++ ++/* ++* rtw_set_channel_plan - ++* @adapter: pointer to struct adapter structure ++* @channel_plan: ++* ++* Return _SUCCESS or _FAIL ++*/ ++int rtw_set_channel_plan(struct adapter *adapter, u8 channel_plan) ++{ ++ /* handle by cmd_thread to sync with scan operation */ ++ return rtw_set_chplan_cmd(adapter, channel_plan, 1); ++} ++ ++/* ++* rtw_set_country - ++* @adapter: pointer to struct adapter structure ++* @country_code: string of country code ++* ++* Return _SUCCESS or _FAIL ++*/ ++int rtw_set_country(struct adapter *adapter, const char *country_code) ++{ ++ int channel_plan = RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G; ++ ++ DBG_88E("%s country_code:%s\n", __func__, country_code); ++ ++ /* TODO: should have a table to match country code and RT_CHANNEL_DOMAIN */ ++ /* TODO: should consider 2-character and 3-character country code */ ++ if (0 == strcmp(country_code, "US")) ++ channel_plan = RT_CHANNEL_DOMAIN_FCC; ++ else if (0 == strcmp(country_code, "EU")) ++ channel_plan = RT_CHANNEL_DOMAIN_ETSI; ++ else if (0 == strcmp(country_code, "JP")) ++ channel_plan = RT_CHANNEL_DOMAIN_MKK; ++ else if (0 == strcmp(country_code, "CN")) ++ channel_plan = RT_CHANNEL_DOMAIN_CHINA; ++ else ++ DBG_88E("%s unknown country_code:%s\n", __func__, country_code); ++ ++ return rtw_set_channel_plan(adapter, channel_plan); ++} +diff --git a/drivers/staging/r8188eu/core/rtw_iol.c b/drivers/staging/r8188eu/core/rtw_iol.c +new file mode 100644 +index 000000000000..5c1b19679cad +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_iol.c +@@ -0,0 +1,192 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/rtw_iol.h" ++ ++struct xmit_frame *rtw_IOL_accquire_xmit_frame(struct adapter *adapter) ++{ ++ struct xmit_frame *xmit_frame; ++ struct xmit_buf *xmitbuf; ++ struct pkt_attrib *pattrib; ++ struct xmit_priv *pxmitpriv = &adapter->xmitpriv; ++ ++ xmit_frame = rtw_alloc_xmitframe(pxmitpriv); ++ if (!xmit_frame) { ++ DBG_88E("%s rtw_alloc_xmitframe return null\n", __func__); ++ goto exit; ++ } ++ ++ xmitbuf = rtw_alloc_xmitbuf(pxmitpriv); ++ if (!xmitbuf) { ++ DBG_88E("%s rtw_alloc_xmitbuf return null\n", __func__); ++ rtw_free_xmitframe(pxmitpriv, xmit_frame); ++ xmit_frame = NULL; ++ goto exit; ++ } ++ ++ xmit_frame->frame_tag = MGNT_FRAMETAG; ++ xmit_frame->pxmitbuf = xmitbuf; ++ xmit_frame->buf_addr = xmitbuf->pbuf; ++ xmitbuf->priv_data = xmit_frame; ++ ++ pattrib = &xmit_frame->attrib; ++ update_mgntframe_attrib(adapter, pattrib); ++ pattrib->qsel = 0x10;/* Beacon */ ++ pattrib->subtype = WIFI_BEACON; ++ pattrib->pktlen = 0; ++ pattrib->last_txcmdsz = 0; ++exit: ++ return xmit_frame; ++} ++ ++int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len) ++{ ++ struct pkt_attrib *pattrib = &xmit_frame->attrib; ++ u16 buf_offset; ++ u32 ori_len; ++ ++ buf_offset = TXDESC_OFFSET; ++ ori_len = buf_offset + pattrib->pktlen; ++ ++ /* check if the io_buf can accommodate new cmds */ ++ if (ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) { ++ DBG_88E("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n", ++ __func__, ori_len + cmd_len + 8, MAX_XMITBUF_SZ); ++ return _FAIL; ++ } ++ ++ memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len); ++ pattrib->pktlen += cmd_len; ++ pattrib->last_txcmdsz += cmd_len; ++ ++ return _SUCCESS; ++} ++ ++bool rtw_IOL_applied(struct adapter *adapter) ++{ ++ if (1 == adapter->registrypriv.fw_iol) ++ return true; ++ ++ if ((2 == adapter->registrypriv.fw_iol) && (!adapter_to_dvobj(adapter)->ishighspeed)) ++ return true; ++ return false; ++} ++ ++int rtw_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt) ++{ ++ return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms, bndy_cnt); ++} ++ ++int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary) ++{ ++ return _SUCCESS; ++} ++ ++int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask) ++{ ++ struct ioreg_cfg cmd = {8, IOREG_CMD_WB_REG, 0x0, 0x0, 0x0}; ++ ++ cmd.address = cpu_to_le16(addr); ++ cmd.data = cpu_to_le32(value); ++ ++ if (mask != 0xFF) { ++ cmd.length = 12; ++ cmd.mask = cpu_to_le32(mask); ++ } ++ return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length); ++} ++ ++int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask) ++{ ++ struct ioreg_cfg cmd = {8, IOREG_CMD_WW_REG, 0x0, 0x0, 0x0}; ++ ++ cmd.address = cpu_to_le16(addr); ++ cmd.data = cpu_to_le32(value); ++ ++ if (mask != 0xFFFF) { ++ cmd.length = 12; ++ cmd.mask = cpu_to_le32(mask); ++ } ++ return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length); ++} ++ ++int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask) ++{ ++ struct ioreg_cfg cmd = {8, IOREG_CMD_WD_REG, 0x0, 0x0, 0x0}; ++ ++ cmd.address = cpu_to_le16(addr); ++ cmd.data = cpu_to_le32(value); ++ ++ if (mask != 0xFFFFFFFF) { ++ cmd.length = 12; ++ cmd.mask = cpu_to_le32(mask); ++ } ++ return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length); ++} ++ ++int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask) ++{ ++ struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0}; ++ ++ cmd.address = cpu_to_le16((rf_path << 8) | ((addr) & 0xFF)); ++ cmd.data = cpu_to_le32(value); ++ ++ if (mask != 0x000FFFFF) { ++ cmd.length = 12; ++ cmd.mask = cpu_to_le32(mask); ++ } ++ return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length); ++} ++ ++int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us) ++{ ++ struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0}; ++ cmd.address = cpu_to_le16(us); ++ ++ return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4); ++} ++ ++int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms) ++{ ++ struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0}; ++ ++ cmd.address = cpu_to_le16(ms); ++ return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4); ++} ++ ++int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame) ++{ ++ struct ioreg_cfg cmd = {4, IOREG_CMD_END, cpu_to_le16(0xFFFF), cpu_to_le32(0xFF), 0x0}; ++ ++ return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4); ++} ++ ++u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame) ++{ ++ u8 is_cmd_bndy = false; ++ if (((pxmit_frame->attrib.pktlen + 32) % 256) + 8 >= 256) { ++ rtw_IOL_append_END_cmd(pxmit_frame); ++ pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen + 32) / 256) + 1) * 256); ++ ++ pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen; ++ is_cmd_bndy = true; ++ } ++ return is_cmd_bndy; ++} ++ ++void rtw_IOL_cmd_buf_dump(struct adapter *Adapter, int buf_len, u8 *pbuf) ++{ ++ int i; ++ int j = 1; ++ ++ pr_info("###### %s ######\n", __func__); ++ for (i = 0; i < buf_len; i++) { ++ printk("%02x-", *(pbuf + i)); ++ ++ if (j % 32 == 0) ++ printk("\n"); ++ j++; ++ } ++ printk("\n"); ++ pr_info("=============ioreg_cmd len=%d===============\n", buf_len); ++} +diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c +new file mode 100644 +index 000000000000..b33e34cce12e +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_led.c +@@ -0,0 +1,1612 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#include "../include/drv_types.h" ++#include "../include/rtw_led.h" ++ ++/* */ ++/* Description: */ ++/* Callback function of LED BlinkTimer, */ ++/* it just schedules to corresponding BlinkWorkItem/led_blink_hdl */ ++/* */ ++void BlinkTimerCallback(struct timer_list *t) ++{ ++ struct LED_871x *pLed = from_timer(pLed, t, BlinkTimer); ++ struct adapter *padapter = pLed->padapter; ++ ++ if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped)) ++ return; ++ ++ _set_workitem(&pLed->BlinkWorkItem); ++} ++ ++/* */ ++/* Description: */ ++/* Callback function of LED BlinkWorkItem. */ ++/* We dispatch acture LED blink action according to LedStrategy. */ ++/* */ ++void BlinkWorkItemCallback(struct work_struct *work) ++{ ++ struct LED_871x *pLed = container_of(work, struct LED_871x, BlinkWorkItem); ++ BlinkHandler(pLed); ++} ++ ++/* */ ++/* Description: */ ++/* Reset status of LED_871x object. */ ++/* */ ++void ResetLedStatus(struct LED_871x *pLed) ++{ ++ pLed->CurrLedState = RTW_LED_OFF; /* Current LED state. */ ++ pLed->bLedOn = false; /* true if LED is ON, false if LED is OFF. */ ++ ++ pLed->bLedBlinkInProgress = false; /* true if it is blinking, false o.w.. */ ++ pLed->bLedWPSBlinkInProgress = false; ++ ++ pLed->BlinkTimes = 0; /* Number of times to toggle led state for blinking. */ ++ pLed->BlinkingLedState = LED_UNKNOWN; /* Next state for blinking, either RTW_LED_ON or RTW_LED_OFF are. */ ++ ++ pLed->bLedNoLinkBlinkInProgress = false; ++ pLed->bLedLinkBlinkInProgress = false; ++ pLed->bLedStartToLinkBlinkInProgress = false; ++ pLed->bLedScanBlinkInProgress = false; ++} ++ ++/*Description: */ ++/* Initialize an LED_871x object. */ ++void InitLed871x(struct adapter *padapter, struct LED_871x *pLed, enum LED_PIN_871x LedPin) ++{ ++ pLed->padapter = padapter; ++ pLed->LedPin = LedPin; ++ ++ ResetLedStatus(pLed); ++ ++ timer_setup(&pLed->BlinkTimer, BlinkTimerCallback, 0); ++ _init_workitem(&pLed->BlinkWorkItem, BlinkWorkItemCallback, pLed); ++} ++ ++/* */ ++/* Description: */ ++/* DeInitialize an LED_871x object. */ ++/* */ ++void DeInitLed871x(struct LED_871x *pLed) ++{ ++ _cancel_workitem_sync(&pLed->BlinkWorkItem); ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ ResetLedStatus(pLed); ++} ++ ++/* */ ++/* Description: */ ++/* Implementation of LED blinking behavior. */ ++/* It toggle off LED and schedule corresponding timer if necessary. */ ++/* */ ++ ++static void SwLedBlink(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 bStopBlinking = false; ++ ++ /* Change LED according to BlinkingLedState specified. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ SwLedOn(padapter, pLed); ++ else ++ SwLedOff(padapter, pLed); ++ ++ /* Determine if we shall change LED state again. */ ++ pLed->BlinkTimes--; ++ switch (pLed->CurrLedState) { ++ case LED_BLINK_NORMAL: ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ break; ++ case LED_BLINK_StartToBlink: ++ if (check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE)) ++ bStopBlinking = true; ++ if (check_fwstate(pmlmepriv, _FW_LINKED) && ++ (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) ++ bStopBlinking = true; ++ else if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ break; ++ case LED_BLINK_WPS: ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ break; ++ default: ++ bStopBlinking = true; ++ break; ++ } ++ ++ if (bStopBlinking) { ++ if (check_fwstate(pmlmepriv, _FW_LINKED) && !pLed->bLedOn) { ++ SwLedOn(padapter, pLed); ++ } else if (check_fwstate(pmlmepriv, _FW_LINKED) && pLed->bLedOn) { ++ SwLedOff(padapter, pLed); ++ } ++ pLed->BlinkTimes = 0; ++ pLed->bLedBlinkInProgress = false; ++ } else { ++ /* Assign LED state to toggle. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ ++ /* Schedule a timer to toggle LED state. */ ++ switch (pLed->CurrLedState) { ++ case LED_BLINK_NORMAL: ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ break; ++ case LED_BLINK_SLOWLY: ++ case LED_BLINK_StartToBlink: ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SLOWLY_INTERVAL); ++ break; ++ case LED_BLINK_WPS: ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_LONG_INTERVAL); ++ break; ++ default: ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SLOWLY_INTERVAL); ++ break; ++ } ++ } ++} ++ ++static void SwLedBlink1(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 bStopBlinking = false; ++ ++ /* Change LED according to BlinkingLedState specified. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ SwLedOn(padapter, pLed); ++ else ++ SwLedOff(padapter, pLed); ++ ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ ResetLedStatus(pLed); ++ return; ++ } ++ ++ switch (pLed->CurrLedState) { ++ case LED_BLINK_SLOWLY: ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ break; ++ case LED_BLINK_NORMAL: ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA); ++ break; ++ case LED_BLINK_SCAN: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ if (bStopBlinking) { ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->bLedLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_NORMAL; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA); ++ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ } ++ pLed->bLedScanBlinkInProgress = false; ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_BLINK_TXRX: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ if (bStopBlinking) { ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->bLedLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_NORMAL; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA); ++ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ } ++ pLed->BlinkTimes = 0; ++ pLed->bLedBlinkInProgress = false; ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_BLINK_WPS: ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ break; ++ case LED_BLINK_WPS_STOP: /* WPS success */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ bStopBlinking = false; ++ else ++ bStopBlinking = true; ++ ++ if (bStopBlinking) { ++ pLed->bLedLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_NORMAL; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA); ++ ++ pLed->bLedWPSBlinkInProgress = false; ++ } else { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++static void SwLedBlink2(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 bStopBlinking = false; ++ ++ /* Change LED according to BlinkingLedState specified. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ SwLedOn(padapter, pLed); ++ else ++ SwLedOff(padapter, pLed); ++ ++ switch (pLed->CurrLedState) { ++ case LED_BLINK_SCAN: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ SwLedOn(padapter, pLed); ++ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ SwLedOff(padapter, pLed); ++ } ++ pLed->bLedScanBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ case LED_BLINK_TXRX: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ SwLedOn(padapter, pLed); ++ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ SwLedOff(padapter, pLed); ++ } ++ pLed->bLedBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++static void SwLedBlink3(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 bStopBlinking = false; ++ ++ /* Change LED according to BlinkingLedState specified. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) { ++ SwLedOn(padapter, pLed); ++ } else { ++ if (pLed->CurrLedState != LED_BLINK_WPS_STOP) ++ SwLedOff(padapter, pLed); ++ } ++ ++ switch (pLed->CurrLedState) { ++ case LED_BLINK_SCAN: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ if (!pLed->bLedOn) ++ SwLedOn(padapter, pLed); ++ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ if (pLed->bLedOn) ++ SwLedOff(padapter, pLed); ++ } ++ pLed->bLedScanBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ case LED_BLINK_TXRX: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ if (!pLed->bLedOn) ++ SwLedOn(padapter, pLed); ++ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ ++ if (pLed->bLedOn) ++ SwLedOff(padapter, pLed); ++ } ++ pLed->bLedBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ case LED_BLINK_WPS: ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ break; ++ case LED_BLINK_WPS_STOP: /* WPS success */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); ++ bStopBlinking = false; ++ } else { ++ bStopBlinking = true; ++ } ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ SwLedOn(padapter, pLed); ++ } ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++static void SwLedBlink4(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct LED_871x *pLed1 = &ledpriv->SwLed1; ++ u8 bStopBlinking = false; ++ ++ /* Change LED according to BlinkingLedState specified. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ SwLedOn(padapter, pLed); ++ else ++ SwLedOff(padapter, pLed); ++ ++ if (!pLed1->bLedWPSBlinkInProgress && pLed1->BlinkingLedState == LED_UNKNOWN) { ++ pLed1->BlinkingLedState = RTW_LED_OFF; ++ pLed1->CurrLedState = RTW_LED_OFF; ++ SwLedOff(padapter, pLed1); ++ } ++ ++ switch (pLed->CurrLedState) { ++ case LED_BLINK_SLOWLY: ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ break; ++ case LED_BLINK_StartToBlink: ++ if (pLed->bLedOn) { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SLOWLY_INTERVAL); ++ } else { ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ } ++ break; ++ case LED_BLINK_SCAN: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = false; ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ SwLedOff(padapter, pLed); ++ } else { ++ pLed->bLedNoLinkBlinkInProgress = false; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ } ++ pLed->bLedScanBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ case LED_BLINK_TXRX: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ SwLedOff(padapter, pLed); ++ } else { ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ } ++ pLed->bLedBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ case LED_BLINK_WPS: ++ if (pLed->bLedOn) { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SLOWLY_INTERVAL); ++ } else { ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ } ++ break; ++ case LED_BLINK_WPS_STOP: /* WPS authentication fail */ ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ break; ++ case LED_BLINK_WPS_STOP_OVERLAP: /* WPS session overlap */ ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) { ++ if (pLed->bLedOn) ++ pLed->BlinkTimes = 1; ++ else ++ bStopBlinking = true; ++ } ++ ++ if (bStopBlinking) { ++ pLed->BlinkTimes = 10; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++static void SwLedBlink5(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ u8 bStopBlinking = false; ++ ++ /* Change LED according to BlinkingLedState specified. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ SwLedOn(padapter, pLed); ++ else ++ SwLedOff(padapter, pLed); ++ ++ switch (pLed->CurrLedState) { ++ case LED_BLINK_SCAN: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ if (pLed->bLedOn) ++ SwLedOff(padapter, pLed); ++ } else { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ if (!pLed->bLedOn) ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ ++ pLed->bLedScanBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ case LED_BLINK_TXRX: ++ pLed->BlinkTimes--; ++ if (pLed->BlinkTimes == 0) ++ bStopBlinking = true; ++ ++ if (bStopBlinking) { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ if (pLed->bLedOn) ++ SwLedOff(padapter, pLed); ++ } else { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ if (!pLed->bLedOn) ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ ++ pLed->bLedBlinkInProgress = false; ++ } else { ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) { ++ SwLedOff(padapter, pLed); ++ } else { ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ } ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++static void SwLedBlink6(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ ++ /* Change LED according to BlinkingLedState specified. */ ++ if (pLed->BlinkingLedState == RTW_LED_ON) ++ SwLedOn(padapter, pLed); ++ else ++ SwLedOff(padapter, pLed); ++} ++ ++ /* ALPHA, added by chiyoko, 20090106 */ ++static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAction) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct LED_871x *pLed = &ledpriv->SwLed0; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ switch (LedAction) { ++ case LED_CTL_POWER_ON: ++ case LED_CTL_START_TO_LINK: ++ case LED_CTL_NO_LINK: ++ if (!pLed->bLedNoLinkBlinkInProgress) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ if (pLed->bLedLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_LINK: ++ if (!pLed->bLedLinkBlinkInProgress) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ pLed->bLedLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_NORMAL; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_LINK_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_SITE_SURVEY: ++ if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED))) { ++ ; ++ } else if (!pLed->bLedScanBlinkInProgress) { ++ if (IS_LED_WPS_BLINKING(pLed)) ++ return; ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ pLed->bLedScanBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SCAN; ++ pLed->BlinkTimes = 24; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_TX: ++ case LED_CTL_RX: ++ if (!pLed->bLedBlinkInProgress) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedLinkBlinkInProgress = false; ++ } ++ pLed->bLedBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_TXRX; ++ pLed->BlinkTimes = 2; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_START_WPS: /* wait until xinpin finish */ ++ case LED_CTL_START_WPS_BOTTON: ++ if (!pLed->bLedWPSBlinkInProgress) { ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ pLed->bLedWPSBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_WPS; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_STOP_WPS: ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ if (pLed->bLedWPSBlinkInProgress) ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ else ++ pLed->bLedWPSBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_WPS_STOP; ++ if (pLed->bLedOn) { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); ++ } else { ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ break; ++ case LED_CTL_STOP_WPS_FAIL: ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ break; ++ case LED_CTL_POWER_OFF: ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ SwLedOff(padapter, pLed); ++ break; ++ default: ++ break; ++ } ++} ++ ++ /* Arcadyan/Sitecom , added by chiyoko, 20090216 */ ++static void SwLedControlMode2(struct adapter *padapter, enum LED_CTL_MODE LedAction) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct LED_871x *pLed = &ledpriv->SwLed0; ++ ++ switch (LedAction) { ++ case LED_CTL_SITE_SURVEY: ++ if (pmlmepriv->LinkDetectInfo.bBusyTraffic) { ++ } else if (!pLed->bLedScanBlinkInProgress) { ++ if (IS_LED_WPS_BLINKING(pLed)) ++ return; ++ ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ pLed->bLedScanBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SCAN; ++ pLed->BlinkTimes = 24; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_TX: ++ case LED_CTL_RX: ++ if ((!pLed->bLedBlinkInProgress) && (check_fwstate(pmlmepriv, _FW_LINKED))) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ pLed->bLedBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_TXRX; ++ pLed->BlinkTimes = 2; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_LINK: ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ _set_timer(&pLed->BlinkTimer, 0); ++ break; ++ case LED_CTL_START_WPS: /* wait until xinpin finish */ ++ case LED_CTL_START_WPS_BOTTON: ++ if (!pLed->bLedWPSBlinkInProgress) { ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ pLed->bLedWPSBlinkInProgress = true; ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ break; ++ case LED_CTL_STOP_WPS: ++ pLed->bLedWPSBlinkInProgress = false; ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else { ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ break; ++ case LED_CTL_STOP_WPS_FAIL: ++ pLed->bLedWPSBlinkInProgress = false; ++ if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { ++ SwLedOff(padapter, pLed); ++ } else { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ break; ++ case LED_CTL_START_TO_LINK: ++ case LED_CTL_NO_LINK: ++ if (!IS_LED_BLINKING(pLed)) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ break; ++ case LED_CTL_POWER_OFF: ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ ++ _set_timer(&pLed->BlinkTimer, 0); ++ break; ++ default: ++ break; ++ } ++} ++ ++ /* COREGA, added by chiyoko, 20090316 */ ++ static void SwLedControlMode3(struct adapter *padapter, enum LED_CTL_MODE LedAction) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct LED_871x *pLed = &ledpriv->SwLed0; ++ ++ switch (LedAction) { ++ case LED_CTL_SITE_SURVEY: ++ if (pmlmepriv->LinkDetectInfo.bBusyTraffic) { ++ } else if (!pLed->bLedScanBlinkInProgress) { ++ if (IS_LED_WPS_BLINKING(pLed)) ++ return; ++ ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ pLed->bLedScanBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SCAN; ++ pLed->BlinkTimes = 24; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_TX: ++ case LED_CTL_RX: ++ if ((!pLed->bLedBlinkInProgress) && (check_fwstate(pmlmepriv, _FW_LINKED))) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ pLed->bLedBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_TXRX; ++ pLed->BlinkTimes = 2; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_LINK: ++ if (IS_LED_WPS_BLINKING(pLed)) ++ return; ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ ++ _set_timer(&pLed->BlinkTimer, 0); ++ break; ++ case LED_CTL_START_WPS: /* wait until xinpin finish */ ++ case LED_CTL_START_WPS_BOTTON: ++ if (!pLed->bLedWPSBlinkInProgress) { ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ pLed->bLedWPSBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_WPS; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_STOP_WPS: ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } else { ++ pLed->bLedWPSBlinkInProgress = true; ++ } ++ ++ pLed->CurrLedState = LED_BLINK_WPS_STOP; ++ if (pLed->bLedOn) { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); ++ } else { ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ break; ++ case LED_CTL_STOP_WPS_FAIL: ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, 0); ++ break; ++ case LED_CTL_START_TO_LINK: ++ case LED_CTL_NO_LINK: ++ if (!IS_LED_BLINKING(pLed)) { ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ break; ++ case LED_CTL_POWER_OFF: ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ ++ _set_timer(&pLed->BlinkTimer, 0); ++ break; ++ default: ++ break; ++ } ++} ++ ++ /* Edimax-Belkin, added by chiyoko, 20090413 */ ++static void SwLedControlMode4(struct adapter *padapter, enum LED_CTL_MODE LedAction) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct LED_871x *pLed = &ledpriv->SwLed0; ++ struct LED_871x *pLed1 = &ledpriv->SwLed1; ++ ++ switch (LedAction) { ++ case LED_CTL_START_TO_LINK: ++ if (pLed1->bLedWPSBlinkInProgress) { ++ pLed1->bLedWPSBlinkInProgress = false; ++ _cancel_timer_ex(&pLed1->BlinkTimer); ++ ++ pLed1->BlinkingLedState = RTW_LED_OFF; ++ pLed1->CurrLedState = RTW_LED_OFF; ++ ++ if (pLed1->bLedOn) ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ ++ if (!pLed->bLedStartToLinkBlinkInProgress) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ ++ pLed->bLedStartToLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_StartToBlink; ++ if (pLed->bLedOn) { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SLOWLY_INTERVAL); ++ } else { ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ } ++ } ++ break; ++ case LED_CTL_LINK: ++ case LED_CTL_NO_LINK: ++ /* LED1 settings */ ++ if (LedAction == LED_CTL_LINK) { ++ if (pLed1->bLedWPSBlinkInProgress) { ++ pLed1->bLedWPSBlinkInProgress = false; ++ _cancel_timer_ex(&pLed1->BlinkTimer); ++ ++ pLed1->BlinkingLedState = RTW_LED_OFF; ++ pLed1->CurrLedState = RTW_LED_OFF; ++ ++ if (pLed1->bLedOn) ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ } ++ ++ if (!pLed->bLedNoLinkBlinkInProgress) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_SITE_SURVEY: ++ if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED))) { ++ } else if (!pLed->bLedScanBlinkInProgress) { ++ if (IS_LED_WPS_BLINKING(pLed)) ++ return; ++ ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ pLed->bLedScanBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SCAN; ++ pLed->BlinkTimes = 24; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_TX: ++ case LED_CTL_RX: ++ if (!pLed->bLedBlinkInProgress) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) ++ return; ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ pLed->bLedBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_TXRX; ++ pLed->BlinkTimes = 2; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_START_WPS: /* wait until xinpin finish */ ++ case LED_CTL_START_WPS_BOTTON: ++ if (pLed1->bLedWPSBlinkInProgress) { ++ pLed1->bLedWPSBlinkInProgress = false; ++ _cancel_timer_ex(&pLed1->BlinkTimer); ++ ++ pLed1->BlinkingLedState = RTW_LED_OFF; ++ pLed1->CurrLedState = RTW_LED_OFF; ++ ++ if (pLed1->bLedOn) ++ _set_timer(&pLed->BlinkTimer, 0); ++ } ++ ++ if (!pLed->bLedWPSBlinkInProgress) { ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ pLed->bLedWPSBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_WPS; ++ if (pLed->bLedOn) { ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SLOWLY_INTERVAL); ++ } else { ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ } ++ } ++ break; ++ case LED_CTL_STOP_WPS: /* WPS connect success */ ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ ++ break; ++ case LED_CTL_STOP_WPS_FAIL: /* WPS authentication fail */ ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ ++ /* LED1 settings */ ++ if (pLed1->bLedWPSBlinkInProgress) ++ _cancel_timer_ex(&pLed1->BlinkTimer); ++ else ++ pLed1->bLedWPSBlinkInProgress = true; ++ pLed1->CurrLedState = LED_BLINK_WPS_STOP; ++ if (pLed1->bLedOn) ++ pLed1->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed1->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ break; ++ case LED_CTL_STOP_WPS_FAIL_OVERLAP: /* WPS session overlap */ ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ pLed->bLedNoLinkBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SLOWLY; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NO_LINK_INTERVAL_ALPHA); ++ ++ /* LED1 settings */ ++ if (pLed1->bLedWPSBlinkInProgress) ++ _cancel_timer_ex(&pLed1->BlinkTimer); ++ else ++ pLed1->bLedWPSBlinkInProgress = true; ++ pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP; ++ pLed1->BlinkTimes = 10; ++ if (pLed1->bLedOn) ++ pLed1->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed1->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_NORMAL_INTERVAL); ++ break; ++ case LED_CTL_POWER_OFF: ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ ++ if (pLed->bLedNoLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedNoLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedLinkBlinkInProgress = false; ++ } ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ if (pLed->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedWPSBlinkInProgress = false; ++ } ++ if (pLed->bLedScanBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedScanBlinkInProgress = false; ++ } ++ if (pLed->bLedStartToLinkBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedStartToLinkBlinkInProgress = false; ++ } ++ if (pLed1->bLedWPSBlinkInProgress) { ++ _cancel_timer_ex(&pLed1->BlinkTimer); ++ pLed1->bLedWPSBlinkInProgress = false; ++ } ++ pLed1->BlinkingLedState = LED_UNKNOWN; ++ SwLedOff(padapter, pLed); ++ SwLedOff(padapter, pLed1); ++ break; ++ default: ++ break; ++ } ++} ++ ++ /* Sercomm-Belkin, added by chiyoko, 20090415 */ ++static void ++SwLedControlMode5( ++ struct adapter *padapter, ++ enum LED_CTL_MODE LedAction ++) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct LED_871x *pLed = &ledpriv->SwLed0; ++ ++ switch (LedAction) { ++ case LED_CTL_POWER_ON: ++ case LED_CTL_NO_LINK: ++ case LED_CTL_LINK: /* solid blue */ ++ pLed->CurrLedState = RTW_LED_ON; ++ pLed->BlinkingLedState = RTW_LED_ON; ++ ++ _set_timer(&pLed->BlinkTimer, 0); ++ break; ++ case LED_CTL_SITE_SURVEY: ++ if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED))) { ++ } else if (!pLed->bLedScanBlinkInProgress) { ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ pLed->bLedScanBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_SCAN; ++ pLed->BlinkTimes = 24; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_SCAN_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_TX: ++ case LED_CTL_RX: ++ if (!pLed->bLedBlinkInProgress) { ++ if (pLed->CurrLedState == LED_BLINK_SCAN) ++ return; ++ pLed->bLedBlinkInProgress = true; ++ pLed->CurrLedState = LED_BLINK_TXRX; ++ pLed->BlinkTimes = 2; ++ if (pLed->bLedOn) ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ else ++ pLed->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed->BlinkTimer, LED_BLINK_FASTER_INTERVAL_ALPHA); ++ } ++ break; ++ case LED_CTL_POWER_OFF: ++ pLed->CurrLedState = RTW_LED_OFF; ++ pLed->BlinkingLedState = RTW_LED_OFF; ++ ++ if (pLed->bLedBlinkInProgress) { ++ _cancel_timer_ex(&pLed->BlinkTimer); ++ pLed->bLedBlinkInProgress = false; ++ } ++ SwLedOff(padapter, pLed); ++ break; ++ default: ++ break; ++ } ++} ++ ++ /* WNC-Corega, added by chiyoko, 20090902 */ ++static void ++SwLedControlMode6( ++ struct adapter *padapter, ++ enum LED_CTL_MODE LedAction ++) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct LED_871x *pLed0 = &ledpriv->SwLed0; ++ ++ switch (LedAction) { ++ case LED_CTL_POWER_ON: ++ case LED_CTL_LINK: ++ case LED_CTL_NO_LINK: ++ _cancel_timer_ex(&pLed0->BlinkTimer); ++ pLed0->CurrLedState = RTW_LED_ON; ++ pLed0->BlinkingLedState = RTW_LED_ON; ++ _set_timer(&pLed0->BlinkTimer, 0); ++ break; ++ case LED_CTL_POWER_OFF: ++ SwLedOff(padapter, pLed0); ++ break; ++ default: ++ break; ++ } ++} ++ ++/* */ ++/* Description: */ ++/* Handler function of LED Blinking. */ ++/* We dispatch acture LED blink action according to LedStrategy. */ ++/* */ ++void BlinkHandler(struct LED_871x *pLed) ++{ ++ struct adapter *padapter = pLed->padapter; ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ ++ if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped)) ++ return; ++ ++ switch (ledpriv->LedStrategy) { ++ case SW_LED_MODE0: ++ SwLedBlink(pLed); ++ break; ++ case SW_LED_MODE1: ++ SwLedBlink1(pLed); ++ break; ++ case SW_LED_MODE2: ++ SwLedBlink2(pLed); ++ break; ++ case SW_LED_MODE3: ++ SwLedBlink3(pLed); ++ break; ++ case SW_LED_MODE4: ++ SwLedBlink4(pLed); ++ break; ++ case SW_LED_MODE5: ++ SwLedBlink5(pLed); ++ break; ++ case SW_LED_MODE6: ++ SwLedBlink6(pLed); ++ break; ++ default: ++ break; ++ } ++} ++ ++void LedControl8188eu(struct adapter *padapter, enum LED_CTL_MODE LedAction) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ struct registry_priv *registry_par; ++ ++ if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped) || ++ (!padapter->hw_init_completed)) ++ return; ++ ++ if (!ledpriv->bRegUseLed) ++ return; ++ ++ registry_par = &padapter->registrypriv; ++ if (!registry_par->led_enable) ++ return; ++ ++ if ((padapter->pwrctrlpriv.rf_pwrstate != rf_on && ++ padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) && ++ (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX || ++ LedAction == LED_CTL_SITE_SURVEY || ++ LedAction == LED_CTL_LINK || ++ LedAction == LED_CTL_NO_LINK || ++ LedAction == LED_CTL_POWER_ON)) ++ return; ++ ++ switch (ledpriv->LedStrategy) { ++ case SW_LED_MODE0: ++ break; ++ case SW_LED_MODE1: ++ SwLedControlMode1(padapter, LedAction); ++ break; ++ case SW_LED_MODE2: ++ SwLedControlMode2(padapter, LedAction); ++ break; ++ case SW_LED_MODE3: ++ SwLedControlMode3(padapter, LedAction); ++ break; ++ case SW_LED_MODE4: ++ SwLedControlMode4(padapter, LedAction); ++ break; ++ case SW_LED_MODE5: ++ SwLedControlMode5(padapter, LedAction); ++ break; ++ case SW_LED_MODE6: ++ SwLedControlMode6(padapter, LedAction); ++ break; ++ default: ++ break; ++ } ++} +diff --git a/drivers/staging/r8188eu/core/rtw_mlme.c b/drivers/staging/r8188eu/core/rtw_mlme.c +new file mode 100644 +index 000000000000..1115ff5d865a +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_mlme.c +@@ -0,0 +1,2199 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_MLME_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/xmit_osdep.h" ++#include "../include/hal_intf.h" ++#include "../include/mlme_osdep.h" ++#include "../include/sta_info.h" ++#include "../include/wifi.h" ++#include "../include/wlan_bssdef.h" ++#include "../include/rtw_ioctl_set.h" ++#include "../include/usb_osintf.h" ++ ++extern unsigned char MCS_rate_2R[16]; ++extern unsigned char MCS_rate_1R[16]; ++ ++void rtw_set_roaming(struct adapter *adapter, u8 to_roaming) ++{ ++ if (to_roaming == 0) ++ adapter->mlmepriv.to_join = false; ++ adapter->mlmepriv.to_roaming = to_roaming; ++} ++ ++u8 rtw_to_roaming(struct adapter *adapter) ++{ ++ return adapter->mlmepriv.to_roaming; ++} ++ ++int _rtw_init_mlme_priv(struct adapter *padapter) ++{ ++ int i; ++ u8 *pbuf; ++ struct wlan_network *pnetwork; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ int res = _SUCCESS; ++ ++ /* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */ ++ ++ pmlmepriv->nic_hdl = (u8 *)padapter; ++ ++ pmlmepriv->pscanned = NULL; ++ pmlmepriv->fw_state = 0; ++ pmlmepriv->cur_network.network.InfrastructureMode = Ndis802_11AutoUnknown; ++ pmlmepriv->scan_mode = SCAN_ACTIVE;/* 1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff) */ ++ ++ spin_lock_init(&pmlmepriv->lock); ++ _rtw_init_queue(&pmlmepriv->free_bss_pool); ++ _rtw_init_queue(&pmlmepriv->scanned_queue); ++ ++ set_scanned_network_val(pmlmepriv, 0); ++ ++ memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid)); ++ ++ pbuf = vzalloc(MAX_BSS_CNT * (sizeof(struct wlan_network))); ++ ++ if (!pbuf) { ++ res = _FAIL; ++ goto exit; ++ } ++ pmlmepriv->free_bss_buf = pbuf; ++ ++ pnetwork = (struct wlan_network *)pbuf; ++ ++ for (i = 0; i < MAX_BSS_CNT; i++) { ++ INIT_LIST_HEAD(&pnetwork->list); ++ ++ list_add_tail(&pnetwork->list, &pmlmepriv->free_bss_pool.queue); ++ ++ pnetwork++; ++ } ++ ++ /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ ++ ++ rtw_clear_scan_deny(padapter); ++ ++ rtw_init_mlme_timer(padapter); ++ ++exit: ++ ++ return res; ++} ++ ++static void rtw_mfree_mlme_priv_lock(struct mlme_priv *pmlmepriv) ++{ ++} ++ ++#if defined(CONFIG_88EU_AP_MODE) ++static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen) ++{ ++ kfree(*ppie); ++ *plen = 0; ++ *ppie = NULL; ++} ++ ++void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv) ++{ ++ kfree(pmlmepriv->assoc_req); ++ kfree(pmlmepriv->assoc_rsp); ++ rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len); ++ rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len); ++ rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len); ++ rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len); ++ ++ rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len); ++ rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len); ++ rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len); ++ rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len); ++ rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len); ++} ++#else ++void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv) ++{ ++} ++#endif ++ ++void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) ++{ ++ ++ rtw_free_mlme_priv_ie_data(pmlmepriv); ++ ++ if (pmlmepriv) { ++ rtw_mfree_mlme_priv_lock(pmlmepriv); ++ ++ vfree(pmlmepriv->free_bss_buf); ++ } ++ ++} ++ ++int _rtw_enqueue_network(struct __queue *queue, struct wlan_network *pnetwork) ++{ ++ ++ if (!pnetwork) ++ goto exit; ++ ++ spin_lock_bh(&queue->lock); ++ ++ list_add_tail(&pnetwork->list, &queue->queue); ++ ++ spin_unlock_bh(&queue->lock); ++ ++exit: ++ ++ return _SUCCESS; ++} ++ ++struct wlan_network *_rtw_dequeue_network(struct __queue *queue) ++{ ++ struct wlan_network *pnetwork; ++ ++ spin_lock_bh(&queue->lock); ++ ++ if (list_empty(&queue->queue)) { ++ pnetwork = NULL; ++ } else { ++ pnetwork = container_of((&queue->queue)->next, struct wlan_network, list); ++ ++ list_del_init(&pnetwork->list); ++ } ++ ++ spin_unlock_bh(&queue->lock); ++ ++ return pnetwork; ++} ++ ++struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv)/* _queue *free_queue) */ ++{ ++ struct wlan_network *pnetwork; ++ struct __queue *free_queue = &pmlmepriv->free_bss_pool; ++ struct list_head *plist = NULL; ++ ++ spin_lock_bh(&free_queue->lock); ++ ++ if (list_empty(&free_queue->queue)) { ++ pnetwork = NULL; ++ goto exit; ++ } ++ plist = (&free_queue->queue)->next; ++ ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ list_del_init(&pnetwork->list); ++ ++ pnetwork->network_type = 0; ++ pnetwork->fixed = false; ++ pnetwork->last_scanned = jiffies; ++ pnetwork->aid = 0; ++ pnetwork->join_res = 0; ++ ++ pmlmepriv->num_of_scanned++; ++ ++exit: ++ spin_unlock_bh(&free_queue->lock); ++ ++ return pnetwork; ++} ++ ++void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 isfreeall) ++{ ++ u32 curr_time, delta_time; ++ u32 lifetime = SCANQUEUE_LIFETIME; ++ struct __queue *free_queue = &pmlmepriv->free_bss_pool; ++ ++ if (!pnetwork) ++ return; ++ ++ if (pnetwork->fixed) ++ return; ++ curr_time = jiffies; ++ if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) || ++ (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))) ++ lifetime = 1; ++ if (!isfreeall) { ++ delta_time = (curr_time - pnetwork->last_scanned) / HZ; ++ if (delta_time < lifetime)/* unit:sec */ ++ return; ++ } ++ spin_lock_bh(&free_queue->lock); ++ list_del_init(&pnetwork->list); ++ list_add_tail(&pnetwork->list, &free_queue->queue); ++ pmlmepriv->num_of_scanned--; ++ spin_unlock_bh(&free_queue->lock); ++} ++ ++void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork) ++{ ++ struct __queue *free_queue = &pmlmepriv->free_bss_pool; ++ ++ if (!pnetwork) ++ return; ++ if (pnetwork->fixed) ++ return; ++ list_del_init(&pnetwork->list); ++ list_add_tail(&pnetwork->list, get_list_head(free_queue)); ++ pmlmepriv->num_of_scanned--; ++} ++ ++/* ++ return the wlan_network with the matching addr ++ ++ Shall be calle under atomic context... to avoid possible racing condition... ++*/ ++struct wlan_network *_rtw_find_network(struct __queue *scanned_queue, u8 *addr) ++{ ++ struct list_head *phead, *plist; ++ struct wlan_network *pnetwork = NULL; ++ u8 zero_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; ++ ++ if (!memcmp(zero_addr, addr, ETH_ALEN)) { ++ pnetwork = NULL; ++ goto exit; ++ } ++ phead = get_list_head(scanned_queue); ++ plist = phead->next; ++ ++ while (plist != phead) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN)) ++ break; ++ plist = plist->next; ++ } ++ if (plist == phead) ++ pnetwork = NULL; ++exit: ++ ++ return pnetwork; ++} ++ ++void _rtw_free_network_queue(struct adapter *padapter, u8 isfreeall) ++{ ++ struct list_head *phead, *plist; ++ struct wlan_network *pnetwork; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct __queue *scanned_queue = &pmlmepriv->scanned_queue; ++ ++ spin_lock_bh(&scanned_queue->lock); ++ ++ phead = get_list_head(scanned_queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ plist = plist->next; ++ ++ _rtw_free_network(pmlmepriv, pnetwork, isfreeall); ++ } ++ spin_unlock_bh(&scanned_queue->lock); ++ ++} ++ ++int rtw_if_up(struct adapter *padapter) ++{ ++ int res; ++ ++ if (padapter->bDriverStopped || padapter->bSurpriseRemoved || ++ !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) ++ res = false; ++ else ++ res = true; ++ ++ return res; ++} ++ ++void rtw_generate_random_ibss(u8 *pibss) ++{ ++ u32 curtime = jiffies; ++ ++ pibss[0] = 0x02; /* in ad-hoc mode bit1 must set to 1 */ ++ pibss[1] = 0x11; ++ pibss[2] = 0x87; ++ pibss[3] = (u8)(curtime & 0xff);/* p[0]; */ ++ pibss[4] = (u8)((curtime >> 8) & 0xff);/* p[1]; */ ++ pibss[5] = (u8)((curtime >> 16) & 0xff);/* p[2]; */ ++} ++ ++u8 *rtw_get_capability_from_ie(u8 *ie) ++{ ++ return ie + 8 + 2; ++} ++ ++u16 rtw_get_capability(struct wlan_bssid_ex *bss) ++{ ++ __le16 val; ++ ++ memcpy((u8 *)&val, rtw_get_capability_from_ie(bss->IEs), 2); ++ ++ return le16_to_cpu(val); ++} ++ ++u8 *rtw_get_timestampe_from_ie(u8 *ie) ++{ ++ return ie + 0; ++} ++ ++u8 *rtw_get_beacon_interval_from_ie(u8 *ie) ++{ ++ return ie + 8; ++} ++ ++int rtw_init_mlme_priv(struct adapter *padapter)/* struct mlme_priv *pmlmepriv) */ ++{ ++ int res; ++ ++ res = _rtw_init_mlme_priv(padapter);/* (pmlmepriv); */ ++ ++ return res; ++} ++ ++void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) ++{ ++ _rtw_free_mlme_priv(pmlmepriv); ++} ++ ++static struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv) ++{ ++ struct wlan_network *pnetwork; ++ ++ pnetwork = _rtw_alloc_network(pmlmepriv); ++ ++ return pnetwork; ++} ++ ++static void rtw_free_network_nolock(struct mlme_priv *pmlmepriv, ++ struct wlan_network *pnetwork) ++{ ++ ++ _rtw_free_network_nolock(pmlmepriv, pnetwork); ++ ++} ++ ++void rtw_free_network_queue(struct adapter *dev, u8 isfreeall) ++{ ++ ++ _rtw_free_network_queue(dev, isfreeall); ++ ++} ++ ++/* ++ return the wlan_network with the matching addr ++ ++ Shall be calle under atomic context... to avoid possible racing condition... ++*/ ++struct wlan_network *rtw_find_network(struct __queue *scanned_queue, u8 *addr) ++{ ++ struct wlan_network *pnetwork = _rtw_find_network(scanned_queue, addr); ++ ++ return pnetwork; ++} ++ ++int rtw_is_same_ibss(struct adapter *adapter, struct wlan_network *pnetwork) ++{ ++ int ret = true; ++ struct security_priv *psecuritypriv = &adapter->securitypriv; ++ ++ if ((psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_) && ++ (pnetwork->network.Privacy == 0)) ++ ret = false; ++ else if ((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_) && ++ (pnetwork->network.Privacy == 1)) ++ ret = false; ++ else ++ ret = true; ++ return ret; ++} ++ ++static int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b) ++{ ++ return (a->Ssid.SsidLength == b->Ssid.SsidLength) && ++ !memcmp(a->Ssid.Ssid, b->Ssid.Ssid, a->Ssid.SsidLength); ++} ++ ++int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst) ++{ ++ u16 s_cap, d_cap; ++ __le16 le_scap, le_dcap; ++ ++ memcpy((u8 *)&le_scap, rtw_get_capability_from_ie(src->IEs), 2); ++ memcpy((u8 *)&le_dcap, rtw_get_capability_from_ie(dst->IEs), 2); ++ ++ s_cap = le16_to_cpu(le_scap); ++ d_cap = le16_to_cpu(le_dcap); ++ ++ return ((src->Ssid.SsidLength == dst->Ssid.SsidLength) && ++ ((!memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN))) && ++ ((!memcmp(src->Ssid.Ssid, dst->Ssid.Ssid, src->Ssid.SsidLength))) && ++ ((s_cap & WLAN_CAPABILITY_IBSS) == ++ (d_cap & WLAN_CAPABILITY_IBSS)) && ++ ((s_cap & WLAN_CAPABILITY_BSS) == ++ (d_cap & WLAN_CAPABILITY_BSS))); ++} ++ ++struct wlan_network *rtw_get_oldest_wlan_network(struct __queue *scanned_queue) ++{ ++ struct list_head *plist, *phead; ++ struct wlan_network *pwlan = NULL; ++ struct wlan_network *oldest = NULL; ++ ++ phead = get_list_head(scanned_queue); ++ ++ plist = phead->next; ++ ++ while (1) { ++ if (phead == plist) ++ break; ++ ++ pwlan = container_of(plist, struct wlan_network, list); ++ ++ if (!pwlan->fixed) { ++ if (!oldest || time_after(oldest->last_scanned, pwlan->last_scanned)) ++ oldest = pwlan; ++ } ++ ++ plist = plist->next; ++ } ++ ++ return oldest; ++} ++ ++void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, ++ struct adapter *padapter, bool update_ie) ++{ ++ long rssi_ori = dst->Rssi; ++ u8 sq_smp = src->PhyInfo.SignalQuality; ++ u8 ss_final; ++ u8 sq_final; ++ long rssi_final; ++ ++ rtw_hal_antdiv_rssi_compared(padapter, dst, src); /* this will update src.Rssi, need consider again */ ++ ++ /* The rule below is 1/5 for sample value, 4/5 for history value */ ++ if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&padapter->mlmepriv.cur_network.network, src)) { ++ /* Take the recvpriv's value for the connected AP*/ ++ ss_final = padapter->recvpriv.signal_strength; ++ sq_final = padapter->recvpriv.signal_qual; ++ /* the rssi value here is undecorated, and will be used for antenna diversity */ ++ if (sq_smp != 101) /* from the right channel */ ++ rssi_final = dst->Rssi; //(src->Rssi+dst->Rssi*4)/5; ++ else ++ rssi_final = rssi_ori; ++ } else { ++// if (sq_smp != 101) { /* from the right channel */ ++ ss_final = (u32)dst->PhyInfo.SignalStrength; //((u32)(src->PhyInfo.SignalStrength)+(u32)(dst->PhyInfo.SignalStrength)*4)/5; ++ sq_final = (u32)dst->PhyInfo.SignalQuality; //((u32)(src->PhyInfo.SignalQuality)+(u32)(dst->PhyInfo.SignalQuality)*4)/5; ++ rssi_final = dst->Rssi; //(src->Rssi+dst->Rssi*4)/5; ++// } else { ++// /* bss info not receiving from the right channel, use the original RX signal infos */ ++// ss_final = dst->PhyInfo.SignalStrength; ++// sq_final = dst->PhyInfo.SignalQuality; ++// rssi_final = dst->Rssi; ++// } ++ } ++ if (update_ie) { ++ dst->Reserved[0] = src->Reserved[0]; ++ dst->Reserved[1] = src->Reserved[1]; ++ memcpy((u8 *)dst, (u8 *)src, get_wlan_bssid_ex_sz(src)); ++ } ++ dst->PhyInfo.SignalStrength = ss_final; ++ dst->PhyInfo.SignalQuality = sq_final; ++ dst->Rssi = rssi_final; ++ ++} ++ ++static void update_current_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork) ++{ ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED) && ++ is_same_network(&pmlmepriv->cur_network.network, pnetwork)) { ++ update_network(&pmlmepriv->cur_network.network, pnetwork, adapter, true); ++ rtw_update_protection(adapter, (pmlmepriv->cur_network.network.IEs) + sizeof(struct ndis_802_11_fixed_ie), ++ pmlmepriv->cur_network.network.IELength); ++ } ++ ++} ++ ++/* ++Caller must hold pmlmepriv->lock first. ++*/ ++void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *target) ++{ ++ struct list_head *plist, *phead; ++ u32 bssid_ex_sz; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ struct wlan_network *oldest = NULL; ++ ++ spin_lock_bh(&queue->lock); ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ if (is_same_network(&pnetwork->network, target)) ++ break; ++ if ((oldest == ((struct wlan_network *)0)) || ++ time_after(oldest->last_scanned, pnetwork->last_scanned)) ++ oldest = pnetwork; ++ plist = plist->next; ++ } ++ /* If we didn't find a match, then get a new network slot to initialize ++ * with this beacon's information */ ++ if (phead == plist) { ++ if (list_empty(&pmlmepriv->free_bss_pool.queue)) { ++ /* If there are no more slots, expire the oldest */ ++ pnetwork = oldest; ++ ++ rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &target->PhyInfo.Optimum_antenna); ++ memcpy(&pnetwork->network, target, get_wlan_bssid_ex_sz(target)); ++ /* variable initialize */ ++ pnetwork->fixed = false; ++ pnetwork->last_scanned = jiffies; ++ ++ pnetwork->network_type = 0; ++ pnetwork->aid = 0; ++ pnetwork->join_res = 0; ++ ++ /* bss info not receiving from the right channel */ ++ if (pnetwork->network.PhyInfo.SignalQuality == 101) ++ pnetwork->network.PhyInfo.SignalQuality = 0; ++ } else { ++ /* Otherwise just pull from the free list */ ++ ++ pnetwork = rtw_alloc_network(pmlmepriv); /* will update scan_time */ ++ ++ if (!pnetwork) ++ goto exit; ++ ++ bssid_ex_sz = get_wlan_bssid_ex_sz(target); ++ target->Length = bssid_ex_sz; ++ rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &target->PhyInfo.Optimum_antenna); ++ memcpy(&pnetwork->network, target, bssid_ex_sz); ++ ++ pnetwork->last_scanned = jiffies; ++ ++ /* bss info not receiving from the right channel */ ++ if (pnetwork->network.PhyInfo.SignalQuality == 101) ++ pnetwork->network.PhyInfo.SignalQuality = 0; ++ list_add_tail(&pnetwork->list, &queue->queue); ++ } ++ } else { ++ /* we have an entry and we are going to update it. But this entry may ++ * be already expired. In this case we do the same as we found a new ++ * net and call the new_net handler ++ */ ++ bool update_ie = true; ++ ++ pnetwork->last_scanned = jiffies; ++ ++ /* target.Reserved[0]== 1, means that scanned network is a bcn frame. */ ++ /* probe resp(3) > beacon(1) > probe req(2) */ ++ if ((target->Reserved[0] != 2) && ++ (target->Reserved[0] >= pnetwork->network.Reserved[0])) ++ update_ie = true; ++ else ++ update_ie = false; ++ update_network(&pnetwork->network, target, adapter, update_ie); ++ } ++ ++exit: ++ spin_unlock_bh(&queue->lock); ++ ++} ++ ++static void rtw_add_network(struct adapter *adapter, ++ struct wlan_bssid_ex *pnetwork) ++{ ++ ++#if defined(CONFIG_88EU_P2P) ++ rtw_wlan_bssid_ex_remove_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO); ++#endif ++ update_current_network(adapter, pnetwork); ++ rtw_update_scanned_network(adapter, pnetwork); ++ ++} ++ ++/* select the desired network based on the capability of the (i)bss. */ ++/* check items: (1) security */ ++/* (2) network_type */ ++/* (3) WMM */ ++/* (4) HT */ ++/* (5) others */ ++static int rtw_is_desired_network(struct adapter *adapter, struct wlan_network *pnetwork) ++{ ++ struct security_priv *psecuritypriv = &adapter->securitypriv; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ u32 desired_encmode; ++ u32 privacy; ++ ++ /* u8 wps_ie[512]; */ ++ uint wps_ielen; ++ ++ int bselected = true; ++ ++ desired_encmode = psecuritypriv->ndisencryptstatus; ++ privacy = pnetwork->network.Privacy; ++ ++ if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) { ++ if (rtw_get_wps_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, pnetwork->network.IELength - _FIXED_IE_LENGTH_, NULL, &wps_ielen)) ++ return true; ++ else ++ return false; ++ } ++ if (adapter->registrypriv.wifi_spec == 1) { /* for correct flow of 8021X to do.... */ ++ u8 *p = NULL; ++ uint ie_len = 0; ++ ++ if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0)) ++ bselected = false; ++ if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) { ++ p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, ++ _RSN_IE_2_, &ie_len, ++ (pnetwork->network.IELength - ++ _BEACON_IE_OFFSET_)); ++ if (p && ie_len > 0) ++ bselected = true; ++ else ++ bselected = false; ++ } ++ } ++ ++ if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0)) { ++ DBG_88E("desired_encmode: %d, privacy: %d\n", desired_encmode, privacy); ++ bselected = false; ++ } ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { ++ if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode) ++ bselected = false; ++ } ++ ++ return bselected; ++} ++ ++void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf) ++{ ++ u32 len; ++ struct wlan_bssid_ex *pnetwork; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ ++ pnetwork = (struct wlan_bssid_ex *)pbuf; ++ ++ len = get_wlan_bssid_ex_sz(pnetwork); ++ if (len > (sizeof(struct wlan_bssid_ex))) ++ return; ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ /* update IBSS_network 's timestamp */ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, pnetwork->MacAddress, ETH_ALEN)) { ++ struct wlan_network *ibss_wlan = NULL; ++ ++ memcpy(pmlmepriv->cur_network.network.IEs, pnetwork->IEs, 8); ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ibss_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->MacAddress); ++ if (ibss_wlan) { ++ memcpy(ibss_wlan->network.IEs, pnetwork->IEs, 8); ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ goto exit; ++ } ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ } ++ } ++ ++ /* lock pmlmepriv->lock when you accessing network_q */ ++ if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { ++ if (pnetwork->Ssid.Ssid[0] == 0) ++ pnetwork->Ssid.SsidLength = 0; ++ rtw_add_network(adapter, pnetwork); ++ } ++ ++exit: ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) ++{ ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ u8 timer_cancelled = 0; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (pmlmepriv->wps_probe_req_ie) { ++ pmlmepriv->wps_probe_req_ie_len = 0; ++ kfree(pmlmepriv->wps_probe_req_ie); ++ pmlmepriv->wps_probe_req_ie = NULL; ++ } ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { ++ timer_cancelled = 1; ++ ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); ++ } ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++ if (timer_cancelled) ++ _cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled); ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ rtw_set_signal_stat_timer(&adapter->recvpriv); ++ ++ if (pmlmepriv->to_join) { ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { ++ if (!check_fwstate(pmlmepriv, _FW_LINKED)) { ++ set_fwstate(pmlmepriv, _FW_UNDER_LINKING); ++ ++ if (rtw_select_and_join_from_scanned_queue(pmlmepriv) == _SUCCESS) { ++ _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); ++ } else { ++ struct wlan_bssid_ex *pdev_network = &adapter->registrypriv.dev_network; ++ u8 *pibss = adapter->registrypriv.dev_network.MacAddress; ++ ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); ++ ++ memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); ++ memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); ++ ++ rtw_update_registrypriv_dev_network(adapter); ++ rtw_generate_random_ibss(pibss); ++ ++ pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; ++ ++ rtw_createbss_cmd(adapter); ++ pmlmepriv->to_join = false; ++ } ++ } ++ } else { ++ int s_ret; ++ set_fwstate(pmlmepriv, _FW_UNDER_LINKING); ++ pmlmepriv->to_join = false; ++ s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv); ++ if (_SUCCESS == s_ret) { ++ _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); ++ } else if (s_ret == 2) { /* there is no need to wait for join */ ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ rtw_indicate_connect(adapter); ++ } else { ++ DBG_88E("try_to_join, but select scanning queue fail, to_roaming:%d\n", ++ pmlmepriv->to_roaming); ++ if (rtw_to_roaming(adapter) != 0) { ++ if (--pmlmepriv->to_roaming == 0 || ++ _SUCCESS != rtw_sitesurvey_cmd(adapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)) { ++ rtw_set_roaming(adapter, 0); ++ rtw_free_assoc_resources(adapter, 1); ++ rtw_indicate_disconnect(adapter); ++ } else { ++ pmlmepriv->to_join = true; ++ } ++ } else { ++ rtw_indicate_disconnect(adapter); ++ } ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ } ++ } ++ } ++ ++ indicate_wx_scan_complete_event(adapter); ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ p2p_ps_wk_cmd(adapter, P2P_PS_SCAN_DONE, 0); ++ ++ rtw_os_xmit_schedule(adapter); ++} ++ ++void rtw_dummy_event_callback(struct adapter *adapter, u8 *pbuf) ++{ ++} ++ ++void rtw_fwdbg_event_callback(struct adapter *adapter, u8 *pbuf) ++{ ++} ++ ++static void free_scanqueue(struct mlme_priv *pmlmepriv) ++{ ++ struct __queue *free_queue = &pmlmepriv->free_bss_pool; ++ struct __queue *scan_queue = &pmlmepriv->scanned_queue; ++ struct list_head *plist, *phead, *ptemp; ++ ++ spin_lock_bh(&scan_queue->lock); ++ spin_lock_bh(&free_queue->lock); ++ ++ phead = get_list_head(scan_queue); ++ plist = phead->next; ++ ++ while (plist != phead) { ++ ptemp = plist->next; ++ list_del_init(plist); ++ list_add_tail(plist, &free_queue->queue); ++ plist = ptemp; ++ pmlmepriv->num_of_scanned--; ++ } ++ ++ spin_unlock_bh(&free_queue->lock); ++ spin_unlock_bh(&scan_queue->lock); ++} ++ ++/* ++*rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock ++*/ ++void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue) ++{ ++ struct wlan_network *pwlan = NULL; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct sta_priv *pstapriv = &adapter->stapriv; ++ struct wlan_network *tgt_network = &pmlmepriv->cur_network; ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) { ++ struct sta_info *psta; ++ ++ psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.MacAddress); ++ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(adapter, psta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ } ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) { ++ struct sta_info *psta; ++ ++ rtw_free_all_stainfo(adapter); ++ ++ psta = rtw_get_bcmc_stainfo(adapter); ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(adapter, psta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++ rtw_init_bcmc_stainfo(adapter); ++ } ++ ++ if (lock_scanned_queue) ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress); ++ if (pwlan) ++ pwlan->fixed = false; ++ ++ if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) && (adapter->stapriv.asoc_sta_count == 1))) ++ rtw_free_network_nolock(pmlmepriv, pwlan); ++ ++ if (lock_scanned_queue) ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ pmlmepriv->key_mask = 0; ++ ++} ++ ++/* ++*rtw_indicate_connect: the caller has to lock pmlmepriv->lock ++*/ ++void rtw_indicate_connect(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ pmlmepriv->to_join = false; ++ ++ if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { ++ set_fwstate(pmlmepriv, _FW_LINKED); ++ ++ rtw_led_control(padapter, LED_CTL_LINK); ++ ++ rtw_os_indicate_connect(padapter); ++ } ++ ++ pmlmepriv->to_roaming = 0; ++ ++ rtw_set_scan_deny(padapter, 3000); ++} ++ ++/* ++*rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock ++*/ ++void rtw_indicate_disconnect(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING | WIFI_UNDER_WPS); ++ ++ if (pmlmepriv->to_roaming > 0) ++ _clr_fwstate_(pmlmepriv, _FW_LINKED); ++ ++ if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) || ++ (pmlmepriv->to_roaming <= 0)) { ++ rtw_os_indicate_disconnect(padapter); ++ ++ _clr_fwstate_(pmlmepriv, _FW_LINKED); ++ rtw_led_control(padapter, LED_CTL_NO_LINK); ++ rtw_clear_scan_deny(padapter); ++ } ++ p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1); ++ ++ rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1); ++ ++} ++ ++inline void rtw_indicate_scan_done(struct adapter *padapter, bool aborted) ++{ ++ rtw_os_indicate_scan_done(padapter, aborted); ++} ++ ++void rtw_scan_abort(struct adapter *adapter) ++{ ++ u32 start; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; ++ ++ start = jiffies; ++ pmlmeext->scan_abort = true; ++ while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) && ++ rtw_get_passing_time_ms(start) <= 200) { ++ if (adapter->bDriverStopped || adapter->bSurpriseRemoved) ++ break; ++ DBG_88E(FUNC_NDEV_FMT"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev)); ++ msleep(20); ++ } ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { ++ if (!adapter->bDriverStopped && !adapter->bSurpriseRemoved) ++ DBG_88E(FUNC_NDEV_FMT"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter->pnetdev)); ++ rtw_indicate_scan_done(adapter, true); ++ } ++ pmlmeext->scan_abort = false; ++} ++ ++static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, struct wlan_network *pnetwork) ++{ ++ int i; ++ struct sta_info *bmc_sta, *psta = NULL; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ psta = rtw_get_stainfo(pstapriv, pnetwork->network.MacAddress); ++ if (!psta) ++ psta = rtw_alloc_stainfo(pstapriv, pnetwork->network.MacAddress); ++ ++ if (psta) { /* update ptarget_sta */ ++ DBG_88E("%s\n", __func__); ++ psta->aid = pnetwork->join_res; ++ psta->mac_id = 0; ++ /* sta mode */ ++ rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true); ++ /* security related */ ++ if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { ++ padapter->securitypriv.binstallGrpkey = false; ++ padapter->securitypriv.busetkipkey = false; ++ padapter->securitypriv.bgrpkey_handshake = false; ++ psta->ieee8021x_blocked = true; ++ psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; ++ memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype)); ++ memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype)); ++ memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype)); ++ memset((u8 *)&psta->dot11txpn, 0, sizeof(union pn48)); ++ memset((u8 *)&psta->dot11rxpn, 0, sizeof(union pn48)); ++ } ++ /* Commented by Albert 2012/07/21 */ ++ /* When doing the WPS, the wps_ie_len won't equal to 0 */ ++ /* And the Wi-Fi driver shouldn't allow the data packet to be tramsmitted. */ ++ if (padapter->securitypriv.wps_ie_len != 0) { ++ psta->ieee8021x_blocked = true; ++ padapter->securitypriv.wps_ie_len = 0; ++ } ++ /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */ ++ /* if A-MPDU Rx is enabled, resetting rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */ ++ /* todo: check if AP can send A-MPDU packets */ ++ for (i = 0; i < 16; i++) { ++ /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */ ++ preorder_ctrl = &psta->recvreorder_ctrl[i]; ++ preorder_ctrl->enable = false; ++ preorder_ctrl->indicate_seq = 0xffff; ++ preorder_ctrl->wend_b = 0xffff; ++ preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */ ++ } ++ bmc_sta = rtw_get_bcmc_stainfo(padapter); ++ if (bmc_sta) { ++ for (i = 0; i < 16; i++) { ++ /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */ ++ preorder_ctrl = &bmc_sta->recvreorder_ctrl[i]; ++ preorder_ctrl->enable = false; ++ preorder_ctrl->indicate_seq = 0xffff; ++ preorder_ctrl->wend_b = 0xffff; ++ preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */ ++ } ++ } ++ /* misc. */ ++ update_sta_info(padapter, psta); ++ } ++ return psta; ++} ++ ++/* pnetwork: returns from rtw_joinbss_event_callback */ ++/* ptarget_wlan: found from scanned_queue */ ++static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network *pnetwork) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_network *cur_network = &pmlmepriv->cur_network; ++ ++ DBG_88E("%s\n", __func__); ++ ++ /* why not use ptarget_wlan?? */ ++ memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.Length); ++ /* some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */ ++ cur_network->network.IELength = ptarget_wlan->network.IELength; ++ memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0], MAX_IE_SZ); ++ ++ cur_network->aid = pnetwork->join_res; ++ ++ rtw_set_signal_stat_timer(&padapter->recvpriv); ++ padapter->recvpriv.signal_strength = ptarget_wlan->network.PhyInfo.SignalStrength; ++ padapter->recvpriv.signal_qual = ptarget_wlan->network.PhyInfo.SignalQuality; ++ /* the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) */ ++ padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.PhyInfo.SignalStrength); ++ rtw_set_signal_stat_timer(&padapter->recvpriv); ++ ++ /* update fw_state will clr _FW_UNDER_LINKING here indirectly */ ++ switch (pnetwork->network.InfrastructureMode) { ++ case Ndis802_11Infrastructure: ++ if (pmlmepriv->fw_state & WIFI_UNDER_WPS) ++ pmlmepriv->fw_state = WIFI_STATION_STATE | WIFI_UNDER_WPS; ++ else ++ pmlmepriv->fw_state = WIFI_STATION_STATE; ++ break; ++ case Ndis802_11IBSS: ++ pmlmepriv->fw_state = WIFI_ADHOC_STATE; ++ break; ++ default: ++ pmlmepriv->fw_state = WIFI_NULL_STATE; ++ break; ++ } ++ ++ rtw_update_protection(padapter, (cur_network->network.IEs) + ++ sizeof(struct ndis_802_11_fixed_ie), ++ (cur_network->network.IELength)); ++ rtw_update_ht_cap(padapter, cur_network->network.IEs, cur_network->network.IELength); ++} ++ ++/* Notes: the function could be > passive_level (the same context as Rx tasklet) */ ++/* pnetwork: returns from rtw_joinbss_event_callback */ ++/* ptarget_wlan: found from scanned_queue */ ++/* if join_res > 0, for (fw_state == WIFI_STATION_STATE), we check if "ptarget_sta" & "ptarget_wlan" exist. */ ++/* if join_res > 0, for (fw_state == WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. */ ++/* if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan != NULL). */ ++ ++void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) ++{ ++ u8 timer_cancelled; ++ struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL; ++ struct sta_priv *pstapriv = &adapter->stapriv; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct wlan_network *pnetwork = (struct wlan_network *)pbuf; ++ struct wlan_network *cur_network = &pmlmepriv->cur_network; ++ struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL; ++ unsigned int the_same_macaddr = false; ++ ++ rtw_get_encrypt_decrypt_from_registrypriv(adapter); ++ ++ the_same_macaddr = !memcmp(pnetwork->network.MacAddress, cur_network->network.MacAddress, ETH_ALEN); ++ ++ pnetwork->network.Length = get_wlan_bssid_ex_sz(&pnetwork->network); ++ if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex)) ++ return; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (pnetwork->join_res > 0) { ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { ++ /* s1. find ptarget_wlan */ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ if (the_same_macaddr) { ++ ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); ++ } else { ++ pcur_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); ++ if (pcur_wlan) ++ pcur_wlan->fixed = false; ++ ++ pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress); ++ if (pcur_sta) { ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(adapter, pcur_sta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ } ++ ++ ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress); ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ if (ptarget_wlan) ++ ptarget_wlan->fixed = true; ++ } ++ } ++ } else { ++ ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress); ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ if (ptarget_wlan) ++ ptarget_wlan->fixed = true; ++ } ++ } ++ ++ /* s2. update cur_network */ ++ if (ptarget_wlan) { ++ rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork); ++ } else { ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ goto ignore_joinbss_callback; ++ } ++ ++ /* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork); ++ if (!ptarget_sta) { ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ goto ignore_joinbss_callback; ++ } ++ } ++ ++ /* s4. indicate connect */ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ pmlmepriv->cur_network_scanned = ptarget_wlan; ++ rtw_indicate_connect(adapter); ++ } ++ ++ /* s5. Cancle assoc_timer */ ++ _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled); ++ } else { ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ goto ignore_joinbss_callback; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ } else if (pnetwork->join_res == -4) { ++ rtw_reset_securitypriv(adapter); ++ _set_timer(&pmlmepriv->assoc_timer, 1); ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ } else { /* if join_res < 0 (join fails), then try again */ ++ _set_timer(&pmlmepriv->assoc_timer, 1); ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ } ++ ++ignore_joinbss_callback: ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++void rtw_joinbss_event_callback(struct adapter *adapter, u8 *pbuf) ++{ ++ struct wlan_network *pnetwork = (struct wlan_network *)pbuf; ++ ++ mlmeext_joinbss_event_callback(adapter, pnetwork->join_res); ++ ++ rtw_os_xmit_schedule(adapter); ++ ++} ++ ++static u8 search_max_mac_id(struct adapter *padapter) ++{ ++ u8 mac_id; ++#if defined(CONFIG_88EU_AP_MODE) ++ u8 aid; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++#endif ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++#if defined(CONFIG_88EU_AP_MODE) ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ for (aid = (pstapriv->max_num_sta); aid > 0; aid--) { ++ if (pstapriv->sta_aid[aid - 1]) ++ break; ++ } ++ mac_id = aid + 1; ++ } else ++#endif ++ {/* adhoc id = 31~2 */ ++ for (mac_id = (NUM_STA - 1); mac_id >= IBSS_START_MAC_ID; mac_id--) { ++ if (pmlmeinfo->FW_sta_info[mac_id].status == 1) ++ break; ++ } ++ } ++ return mac_id; ++} ++ ++/* FOR AP , AD-HOC mode */ ++void rtw_sta_media_status_rpt(struct adapter *adapter, struct sta_info *psta, ++ u32 mstatus) ++{ ++ u16 media_status_rpt; ++ u8 macid; ++ ++ if (!psta) ++ return; ++ ++ macid = search_max_mac_id(adapter); ++ rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, (u8 *)&macid); ++ /* MACID|OPMODE:1 connect */ ++ media_status_rpt = (u16)((psta->mac_id << 8) | mstatus); ++ rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, ++ (u8 *)&media_status_rpt); ++} ++ ++void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf) ++{ ++ struct sta_info *psta; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf; ++ struct wlan_network *cur_network = &pmlmepriv->cur_network; ++ struct wlan_network *ptarget_wlan = NULL; ++ ++ if (!rtw_access_ctrl(adapter, pstassoc->macaddr)) ++ return; ++ ++#if defined(CONFIG_88EU_AP_MODE) ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr); ++ if (psta) ++ rtw_indicate_sta_assoc_event(adapter, psta); ++ return; ++ } ++#endif ++ /* for AD-HOC mode */ ++ psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr); ++ if (psta) ++ /* the sta have been in sta_info_queue => do nothing */ ++ return; /* between drv has received this event before and fw have not yet to set key to CAM_ENTRY) */ ++ psta = rtw_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr); ++ if (!psta) ++ return; ++ /* to do: init sta_info variable */ ++ psta->qos_option = 0; ++ psta->mac_id = (uint)pstassoc->cam_id; ++ DBG_88E("%s\n", __func__); ++ /* for ad-hoc mode */ ++ rtw_hal_set_odm_var(adapter, HAL_ODM_STA_INFO, psta, true); ++ rtw_sta_media_status_rpt(adapter, psta, 1); ++ if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ++ psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm; ++ psta->ieee8021x_blocked = false; ++ spin_lock_bh(&pmlmepriv->lock); ++ if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) || ++ (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))) { ++ if (adapter->stapriv.asoc_sta_count == 2) { ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); ++ pmlmepriv->cur_network_scanned = ptarget_wlan; ++ if (ptarget_wlan) ++ ptarget_wlan->fixed = true; ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ /* a sta + bc/mc_stainfo (not Ibss_stainfo) */ ++ rtw_indicate_connect(adapter); ++ } ++ } ++ spin_unlock_bh(&pmlmepriv->lock); ++ mlmeext_sta_add_event_callback(adapter, psta); ++} ++ ++void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf) ++{ ++ int mac_id = -1; ++ struct sta_info *psta; ++ struct wlan_network *pwlan = NULL; ++ struct wlan_bssid_ex *pdev_network = NULL; ++ u8 *pibss = NULL; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct stadel_event *pstadel = (struct stadel_event *)pbuf; ++ struct sta_priv *pstapriv = &adapter->stapriv; ++ struct wlan_network *tgt_network = &pmlmepriv->cur_network; ++ ++ psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr); ++ if (psta) ++ mac_id = psta->mac_id; ++ else ++ mac_id = pstadel->mac_id; ++ ++ DBG_88E("%s(mac_id=%d)=%pM\n", __func__, mac_id, pstadel->macaddr); ++ ++ if (mac_id >= 0) { ++ u16 media_status; ++ media_status = (mac_id << 8) | 0; /* MACID|OPMODE:0 means disconnect */ ++ /* for STA, AP, ADHOC mode, report disconnect stauts to FW */ ++ rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status); ++ } ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ return; ++ ++ mlmeext_sta_del_event_callback(adapter); ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ if (adapter->registrypriv.wifi_spec == 1) ++ rtw_set_roaming(adapter, 0); /* don't roam */ ++ else if (rtw_to_roaming(adapter) > 0) ++ pmlmepriv->to_roaming--; /* this stadel_event is caused by roaming, decrease to_roaming */ ++ else if (rtw_to_roaming(adapter) == 0) ++ rtw_set_roaming(adapter, ++ adapter->registrypriv.max_roaming_times); ++ ++ if (*((unsigned short *)(pstadel->rsvd)) != WLAN_REASON_EXPIRATION_CHK) ++ rtw_set_roaming(adapter, 0); /* don't roam */ ++ ++ rtw_free_uc_swdec_pending_queue(adapter); ++ ++ rtw_free_assoc_resources(adapter, 1); ++ rtw_indicate_disconnect(adapter); ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ /* remove the network entry in scanned_queue */ ++ pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress); ++ if (pwlan) { ++ pwlan->fixed = false; ++ rtw_free_network_nolock(pmlmepriv, pwlan); ++ } ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ _rtw_roaming(adapter, tgt_network); ++ } ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ rtw_free_stainfo(adapter, psta); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++ if (adapter->stapriv.asoc_sta_count == 1) { /* a sta + bc/mc_stainfo (not Ibss_stainfo) */ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ /* free old ibss network */ ++ pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress); ++ if (pwlan) { ++ pwlan->fixed = false; ++ rtw_free_network_nolock(pmlmepriv, pwlan); ++ } ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ /* re-create ibss */ ++ pdev_network = &adapter->registrypriv.dev_network; ++ pibss = adapter->registrypriv.dev_network.MacAddress; ++ ++ memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network)); ++ ++ memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); ++ memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); ++ ++ rtw_update_registrypriv_dev_network(adapter); ++ ++ rtw_generate_random_ibss(pibss); ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { ++ set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE); ++ _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE); ++ } ++ ++ rtw_createbss_cmd(adapter); ++ } ++ } ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++} ++ ++/* ++* _rtw_join_timeout_handler - Timeout/faliure handler for CMD JoinBss ++* @adapter: pointer to struct adapter structure ++*/ ++void _rtw_join_timeout_handler (struct adapter *adapter) ++{ ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ int do_join_r; ++ ++ DBG_88E("%s, fw_state=%x\n", __func__, get_fwstate(pmlmepriv)); ++ ++ if (adapter->bDriverStopped || adapter->bSurpriseRemoved) ++ return; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (rtw_to_roaming(adapter) > 0) { /* join timeout caused by roaming */ ++ while (1) { ++ pmlmepriv->to_roaming--; ++ if (rtw_to_roaming(adapter) != 0) { /* try another */ ++ DBG_88E("%s try another roaming\n", __func__); ++ do_join_r = rtw_do_join(adapter); ++ if (_SUCCESS != do_join_r) { ++ DBG_88E("%s roaming do_join return %d\n", __func__, do_join_r); ++ continue; ++ } ++ break; ++ } else { ++ DBG_88E("%s We've try roaming but fail\n", __func__); ++ rtw_indicate_disconnect(adapter); ++ break; ++ } ++ } ++ } else { ++ rtw_indicate_disconnect(adapter); ++ free_scanqueue(pmlmepriv);/* */ ++ } ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++} ++ ++/* ++* rtw_scan_timeout_handler - Timeout/Faliure handler for CMD SiteSurvey ++* @adapter: pointer to struct adapter structure ++*/ ++void rtw_scan_timeout_handler (struct adapter *adapter) ++{ ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ ++ DBG_88E(FUNC_ADPT_FMT" fw_state=%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv)); ++ spin_lock_bh(&pmlmepriv->lock); ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); ++ spin_unlock_bh(&pmlmepriv->lock); ++ rtw_indicate_scan_done(adapter, true); ++} ++ ++static void rtw_auto_scan_handler(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ /* auto site survey per 60sec */ ++ if (pmlmepriv->scan_interval > 0) { ++ pmlmepriv->scan_interval--; ++ if (pmlmepriv->scan_interval == 0) { ++ DBG_88E("%s\n", __func__); ++ rtw_set_802_11_bssid_list_scan(padapter, NULL, 0); ++ pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */ ++ } ++ } ++} ++ ++void rtw_dynamic_check_timer_handlder(struct adapter *adapter) ++{ ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct registry_priv *pregistrypriv = &adapter->registrypriv; ++ ++ if (!adapter) ++ return; ++ if (!adapter->hw_init_completed) ++ return; ++ if ((adapter->bDriverStopped) || (adapter->bSurpriseRemoved)) ++ return; ++ if (adapter->net_closed) ++ return; ++ rtw_dynamic_chk_wk_cmd(adapter); ++ ++ if (pregistrypriv->wifi_spec == 1) { ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &adapter->wdinfo; ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++#endif ++ { ++ /* auto site survey */ ++ rtw_auto_scan_handler(adapter); ++ } ++ } ++ ++ rcu_read_lock(); ++ ++ if (rcu_dereference(adapter->pnetdev->rx_handler_data) && ++ check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE)) { ++ /* expire NAT2.5 entry */ ++ nat25_db_expire(adapter); ++ ++ if (adapter->pppoe_connection_in_progress > 0) { ++ adapter->pppoe_connection_in_progress--; ++ } ++ ++ /* due to rtw_dynamic_check_timer_handlder() is called every 2 seconds */ ++ if (adapter->pppoe_connection_in_progress > 0) { ++ adapter->pppoe_connection_in_progress--; ++ } ++ } ++ ++ rcu_read_unlock(); ++} ++ ++#define RTW_SCAN_RESULT_EXPIRE 2000 ++ ++/* ++* Select a new join candidate from the original @param candidate and @param competitor ++* @return true: candidate is updated ++* @return false: candidate is not updated ++*/ ++static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv ++ , struct wlan_network **candidate, struct wlan_network *competitor) ++{ ++ int updated = false; ++ struct adapter *adapter = container_of(pmlmepriv, struct adapter, mlmepriv); ++ ++ /* check bssid, if needed */ ++ if (pmlmepriv->assoc_by_bssid) { ++ if (memcmp(competitor->network.MacAddress, pmlmepriv->assoc_bssid, ETH_ALEN)) ++ goto exit; ++ } ++ ++ /* check ssid, if needed */ ++ if (pmlmepriv->assoc_ssid.SsidLength) { ++ if (competitor->network.Ssid.SsidLength != pmlmepriv->assoc_ssid.SsidLength || ++ memcmp(competitor->network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength)) ++ goto exit; ++ } ++ ++ if (!rtw_is_desired_network(adapter, competitor)) ++ goto exit; ++ ++ if (rtw_to_roaming(adapter) > 0) { ++ if (rtw_get_passing_time_ms((u32)competitor->last_scanned) >= RTW_SCAN_RESULT_EXPIRE || ++ !is_same_ess(&competitor->network, &pmlmepriv->cur_network.network)) ++ goto exit; ++ } ++ ++ if (!*candidate || (*candidate)->network.Rssi < competitor->network.Rssi) { ++ *candidate = competitor; ++ updated = true; ++ } ++ if (updated) { ++ DBG_88E("[by_bssid:%u][assoc_ssid:%s]new candidate: %s(%pM rssi:%d\n", ++ pmlmepriv->assoc_by_bssid, ++ pmlmepriv->assoc_ssid.Ssid, ++ (*candidate)->network.Ssid.Ssid, ++ (*candidate)->network.MacAddress, ++ (int)(*candidate)->network.Rssi); ++ DBG_88E("[to_roaming:%u]\n", rtw_to_roaming(adapter)); ++ } ++ ++exit: ++ return updated; ++} ++ ++/* ++Calling context: ++The caller of the sub-routine will be in critical section... ++The caller must hold the following spinlock ++pmlmepriv->lock ++*/ ++ ++int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv) ++{ ++ int ret; ++ struct list_head *phead; ++ struct adapter *adapter; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ struct wlan_network *candidate = NULL; ++ u8 supp_ant_div = false; ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ phead = get_list_head(queue); ++ adapter = (struct adapter *)pmlmepriv->nic_hdl; ++ pmlmepriv->pscanned = phead->next; ++ while (phead != pmlmepriv->pscanned) { ++ pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list); ++ if (!pnetwork) { ++ ret = _FAIL; ++ goto exit; ++ } ++ pmlmepriv->pscanned = pmlmepriv->pscanned->next; ++ rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork); ++ } ++ if (!candidate) { ++ DBG_88E("%s: return _FAIL(candidate==NULL)\n", __func__); ++ ret = _FAIL; ++ goto exit; ++ } else { ++ DBG_88E("%s: candidate: %s(%pM ch:%u)\n", __func__, ++ candidate->network.Ssid.Ssid, candidate->network.MacAddress, ++ candidate->network.Configuration.DSConfig); ++ } ++ ++ /* check for situation of _FW_LINKED */ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ DBG_88E("%s: _FW_LINKED while ask_for_joinbss!!!\n", __func__); ++ ++ rtw_disassoc_cmd(adapter, 0, true); ++ rtw_indicate_disconnect(adapter); ++ rtw_free_assoc_resources(adapter, 0); ++ } ++ ++ rtw_hal_get_def_var(adapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(supp_ant_div)); ++ if (supp_ant_div) { ++ u8 cur_ant; ++ rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(cur_ant)); ++ DBG_88E("#### Opt_Ant_(%s), cur_Ant(%s)\n", ++ (2 == candidate->network.PhyInfo.Optimum_antenna) ? "A" : "B", ++ (2 == cur_ant) ? "A" : "B" ++ ); ++ } ++ ++ ret = rtw_joinbss_cmd(adapter, candidate); ++ ++exit: ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ return ret; ++} ++ ++int rtw_set_auth(struct adapter *adapter, struct security_priv *psecuritypriv) ++{ ++ struct cmd_obj *pcmd; ++ struct setauth_parm *psetauthparm; ++ struct cmd_priv *pcmdpriv = &adapter->cmdpriv; ++ int res = _SUCCESS; ++ ++ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!pcmd) { ++ res = _FAIL; /* try again */ ++ goto exit; ++ } ++ ++ psetauthparm = kzalloc(sizeof(struct setauth_parm), GFP_KERNEL); ++ if (!psetauthparm) { ++ kfree(pcmd); ++ res = _FAIL; ++ goto exit; ++ } ++ memset(psetauthparm, 0, sizeof(struct setauth_parm)); ++ psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm; ++ pcmd->cmdcode = _SetAuth_CMD_; ++ pcmd->parmbuf = (unsigned char *)psetauthparm; ++ pcmd->cmdsz = (sizeof(struct setauth_parm)); ++ pcmd->rsp = NULL; ++ pcmd->rspsz = 0; ++ INIT_LIST_HEAD(&pcmd->list); ++ res = rtw_enqueue_cmd(pcmdpriv, pcmd); ++exit: ++ ++ return res; ++} ++ ++int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, int keyid, u8 set_tx) ++{ ++ u8 keylen; ++ struct cmd_obj *pcmd; ++ struct setkey_parm *psetkeyparm; ++ struct cmd_priv *pcmdpriv = &adapter->cmdpriv; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ int res = _SUCCESS; ++ ++ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!pcmd) { ++ res = _FAIL; /* try again */ ++ goto exit; ++ } ++ psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL); ++ if (!psetkeyparm) { ++ kfree(pcmd); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ memset(psetkeyparm, 0, sizeof(struct setkey_parm)); ++ ++ if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ++ psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy; ++ else ++ psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm; ++ psetkeyparm->keyid = (u8)keyid;/* 0~3 */ ++ psetkeyparm->set_tx = set_tx; ++ pmlmepriv->key_mask |= BIT(psetkeyparm->keyid); ++ DBG_88E("==> rtw_set_key algorithm(%x), keyid(%x), key_mask(%x)\n", ++ psetkeyparm->algorithm, psetkeyparm->keyid, pmlmepriv->key_mask); ++ ++ switch (psetkeyparm->algorithm) { ++ case _WEP40_: ++ keylen = 5; ++ memcpy(&psetkeyparm->key[0], &psecuritypriv->dot11DefKey[keyid].skey[0], keylen); ++ break; ++ case _WEP104_: ++ keylen = 13; ++ memcpy(&psetkeyparm->key[0], &psecuritypriv->dot11DefKey[keyid].skey[0], keylen); ++ break; ++ case _TKIP_: ++ keylen = 16; ++ memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen); ++ psetkeyparm->grpkey = 1; ++ break; ++ case _AES_: ++ keylen = 16; ++ memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen); ++ psetkeyparm->grpkey = 1; ++ break; ++ default: ++ res = _FAIL; ++ goto exit; ++ } ++ pcmd->cmdcode = _SetKey_CMD_; ++ pcmd->parmbuf = (u8 *)psetkeyparm; ++ pcmd->cmdsz = (sizeof(struct setkey_parm)); ++ pcmd->rsp = NULL; ++ pcmd->rspsz = 0; ++ INIT_LIST_HEAD(&pcmd->list); ++ res = rtw_enqueue_cmd(pcmdpriv, pcmd); ++exit: ++ return res; ++} ++ ++/* adjust IEs for rtw_joinbss_cmd in WMM */ ++int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len) ++{ ++ unsigned int ielength = 0; ++ unsigned int i, j; ++ ++ i = 12; /* after the fixed IE */ ++ while (i < in_len) { ++ ielength = initial_out_len; ++ ++ if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 && in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 && in_ie[i + 5] == 0x02 && i + 5 < in_len) { ++ /* WMM element ID and OUI */ ++ /* Append WMM IE to the last index of out_ie */ ++ ++ for (j = i; j < i + 9; j++) { ++ out_ie[ielength] = in_ie[j]; ++ ielength++; ++ } ++ out_ie[initial_out_len + 1] = 0x07; ++ out_ie[initial_out_len + 6] = 0x00; ++ out_ie[initial_out_len + 8] = 0x00; ++ break; ++ } ++ i += (in_ie[i + 1] + 2); /* to the next IE element */ ++ } ++ return ielength; ++} ++ ++/* */ ++/* Ported from 8185: IsInPreAuthKeyList(). (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.) */ ++/* Added by Annie, 2006-05-07. */ ++/* */ ++/* Search by BSSID, */ ++/* Return Value: */ ++/* -1 :if there is no pre-auth key in the table */ ++/* >= 0 :if there is pre-auth key, and return the entry id */ ++/* */ ++/* */ ++ ++static int SecIsInPMKIDList(struct adapter *Adapter, u8 *bssid) ++{ ++ struct security_priv *psecuritypriv = &Adapter->securitypriv; ++ int i = 0; ++ ++ do { ++ if ((psecuritypriv->PMKIDList[i].bUsed) && ++ (!memcmp(psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN))) { ++ break; ++ } else { ++ i++; ++ /* continue; */ ++ } ++ ++ } while (i < NUM_PMKID_CACHE); ++ ++ if (i == NUM_PMKID_CACHE) { ++ i = -1;/* Could not find. */ ++ } else { ++ /* There is one Pre-Authentication Key for the specific BSSID. */ ++ } ++ return i; ++} ++ ++/* */ ++/* Check the RSN IE length */ ++/* If the RSN IE length <= 20, the RSN IE didn't include the PMKID information */ ++/* 0-11th element in the array are the fixed IE */ ++/* 12th element in the array is the IE */ ++/* 13th element in the array is the IE length */ ++/* */ ++ ++static int rtw_append_pmkid(struct adapter *Adapter, int iEntry, u8 *ie, uint ie_len) ++{ ++ struct security_priv *psecuritypriv = &Adapter->securitypriv; ++ ++ if (ie[13] <= 20) { ++ /* The RSN IE didn't include the PMK ID, append the PMK information */ ++ ie[ie_len] = 1; ++ ie_len++; ++ ie[ie_len] = 0; /* PMKID count = 0x0100 */ ++ ie_len++; ++ memcpy(&ie[ie_len], &psecuritypriv->PMKIDList[iEntry].PMKID, 16); ++ ++ ie_len += 16; ++ ie[13] += 18;/* PMKID length = 2+16 */ ++ } ++ return ie_len; ++} ++ ++int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len) ++{ ++ u8 authmode = 0; ++ uint ielength; ++ int iEntry; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ struct security_priv *psecuritypriv = &adapter->securitypriv; ++ uint ndisauthmode = psecuritypriv->ndisauthtype; ++ ++ /* copy fixed ie only */ ++ memcpy(out_ie, in_ie, 12); ++ ielength = 12; ++ if ((ndisauthmode == Ndis802_11AuthModeWPA) || ++ (ndisauthmode == Ndis802_11AuthModeWPAPSK)) ++ authmode = _WPA_IE_ID_; ++ if ((ndisauthmode == Ndis802_11AuthModeWPA2) || ++ (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) ++ authmode = _WPA2_IE_ID_; ++ ++ if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) { ++ memcpy(out_ie + ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len); ++ ++ ielength += psecuritypriv->wps_ie_len; ++ } else if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) { ++ /* copy RSN or SSN */ ++ memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1] + 2); ++ ielength += psecuritypriv->supplicant_ie[1] + 2; ++ rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie); ++ } ++ ++ iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid); ++ if (iEntry < 0) { ++ return ielength; ++ } else { ++ if (authmode == _WPA2_IE_ID_) ++ ielength = rtw_append_pmkid(adapter, iEntry, out_ie, ielength); ++ } ++ ++ return ielength; ++} ++ ++void rtw_init_registrypriv_dev_network(struct adapter *adapter) ++{ ++ struct registry_priv *pregistrypriv = &adapter->registrypriv; ++ struct eeprom_priv *peepriv = &adapter->eeprompriv; ++ struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; ++ u8 *myhwaddr = myid(peepriv); ++ ++ memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN); ++ ++ memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, sizeof(struct ndis_802_11_ssid)); ++ ++ pdev_network->Configuration.Length = sizeof(struct ndis_802_11_config); ++ pdev_network->Configuration.BeaconPeriod = 100; ++ pdev_network->Configuration.FHConfig.Length = 0; ++ pdev_network->Configuration.FHConfig.HopPattern = 0; ++ pdev_network->Configuration.FHConfig.HopSet = 0; ++ pdev_network->Configuration.FHConfig.DwellTime = 0; ++ ++} ++ ++void rtw_update_registrypriv_dev_network(struct adapter *adapter) ++{ ++ int sz = 0; ++ struct registry_priv *pregistrypriv = &adapter->registrypriv; ++ struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; ++ struct security_priv *psecuritypriv = &adapter->securitypriv; ++ struct wlan_network *cur_network = &adapter->mlmepriv.cur_network; ++ ++ pdev_network->Privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0); /* adhoc no 802.1x */ ++ ++ pdev_network->Rssi = 0; ++ ++ switch (pregistrypriv->wireless_mode) { ++ case WIRELESS_11B: ++ pdev_network->NetworkTypeInUse = (Ndis802_11DS); ++ break; ++ case WIRELESS_11G: ++ case WIRELESS_11BG: ++ case WIRELESS_11_24N: ++ case WIRELESS_11G_24N: ++ case WIRELESS_11BG_24N: ++ pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24); ++ break; ++ default: ++ /* TODO */ ++ break; ++ } ++ ++ pdev_network->Configuration.DSConfig = (pregistrypriv->channel); ++ ++ if (cur_network->network.InfrastructureMode == Ndis802_11IBSS) ++ pdev_network->Configuration.ATIMWindow = (0); ++ ++ pdev_network->InfrastructureMode = (cur_network->network.InfrastructureMode); ++ ++ /* 1. Supported rates */ ++ /* 2. IE */ ++ ++ sz = rtw_generate_ie(pregistrypriv); ++ pdev_network->IELength = sz; ++ pdev_network->Length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network); ++ ++ /* notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd(); */ ++ /* pdev_network->IELength = cpu_to_le32(sz); */ ++ ++} ++ ++void rtw_get_encrypt_decrypt_from_registrypriv(struct adapter *adapter) ++{ ++ ++} ++ ++/* the function is at passive_level */ ++void rtw_joinbss_reset(struct adapter *padapter) ++{ ++ u8 threshold; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ ++ /* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */ ++ pmlmepriv->num_FortyMHzIntolerant = 0; ++ ++ pmlmepriv->num_sta_no_ht = 0; ++ ++ phtpriv->ampdu_enable = false;/* reset to disabled */ ++ ++ /* TH = 1 => means that invalidate usb rx aggregation */ ++ /* TH = 0 => means that validate usb rx aggregation, use init value. */ ++ if (phtpriv->ht_option) { ++ if (padapter->registrypriv.wifi_spec == 1) ++ threshold = 1; ++ else ++ threshold = 0; ++ rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); ++ } else { ++ threshold = 1; ++ rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); ++ } ++} ++ ++/* the function is >= passive_level */ ++unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len) ++{ ++ u32 ielen, out_len; ++ enum ht_cap_ampdu_factor max_rx_ampdu_factor; ++ unsigned char *p; ++ struct ieee80211_ht_cap ht_capie; ++ unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct qos_priv *pqospriv = &pmlmepriv->qospriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ u32 rx_packet_offset, max_recvbuf_sz; ++ ++ phtpriv->ht_option = false; ++ ++ p = rtw_get_ie(in_ie + 12, _HT_CAPABILITY_IE_, &ielen, in_len - 12); ++ ++ if (p && ielen > 0) { ++ if (pqospriv->qos_option == 0) { ++ out_len = *pout_len; ++ rtw_set_ie(out_ie + out_len, _VENDOR_SPECIFIC_IE_, ++ _WMM_IE_Length_, WMM_IE, pout_len); ++ ++ pqospriv->qos_option = 1; ++ } ++ ++ out_len = *pout_len; ++ ++ memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap)); ++ ++ ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 | ++ IEEE80211_HT_CAP_SGI_20 | ++ IEEE80211_HT_CAP_SGI_40 | ++ IEEE80211_HT_CAP_TX_STBC | ++ IEEE80211_HT_CAP_DSSSCCK40); ++ ++ rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset); ++ rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz); ++ ++ /* ++ AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k ++ AMPDU_para [4:2]:Min MPDU Start Spacing ++ */ ++ ++ rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); ++ ht_capie.ampdu_params_info = (max_rx_ampdu_factor & 0x03); ++ ++ if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) ++ ht_capie.ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY & (0x07 << 2)); ++ else ++ ht_capie.ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00); ++ ++ rtw_set_ie(out_ie + out_len, _HT_CAPABILITY_IE_, ++ sizeof(struct ieee80211_ht_cap), (unsigned char *)&ht_capie, pout_len); ++ ++ phtpriv->ht_option = true; ++ ++ p = rtw_get_ie(in_ie + 12, _HT_ADD_INFO_IE_, &ielen, in_len - 12); ++ if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) { ++ out_len = *pout_len; ++ rtw_set_ie(out_ie + out_len, _HT_ADD_INFO_IE_, ielen, p + 2, pout_len); ++ } ++ } ++ return phtpriv->ht_option; ++} ++ ++/* the function is > passive_level (in critical_section) */ ++void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len) ++{ ++ u8 *p, max_ampdu_sz; ++ int len; ++ struct ieee80211_ht_cap *pht_capie; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (!phtpriv->ht_option) ++ return; ++ ++ if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable)) ++ return; ++ ++ DBG_88E("+rtw_update_ht_cap()\n"); ++ ++ /* maybe needs check if ap supports rx ampdu. */ ++ if ((!phtpriv->ampdu_enable) && (pregistrypriv->ampdu_enable == 1)) { ++ if (pregistrypriv->wifi_spec == 1) ++ phtpriv->ampdu_enable = false; ++ else ++ phtpriv->ampdu_enable = true; ++ } else if (pregistrypriv->ampdu_enable == 2) { ++ phtpriv->ampdu_enable = true; ++ } ++ ++ /* check Max Rx A-MPDU Size */ ++ len = 0; ++ p = rtw_get_ie(pie + sizeof(struct ndis_802_11_fixed_ie), _HT_CAPABILITY_IE_, &len, ie_len - sizeof(struct ndis_802_11_fixed_ie)); ++ if (p && len > 0) { ++ pht_capie = (struct ieee80211_ht_cap *)(p + 2); ++ max_ampdu_sz = (pht_capie->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_FACTOR); ++ max_ampdu_sz = 1 << (max_ampdu_sz + 3); /* max_ampdu_sz (kbytes); */ ++ phtpriv->rx_ampdu_maxlen = max_ampdu_sz; ++ } ++ len = 0; ++ p = rtw_get_ie(pie + sizeof(struct ndis_802_11_fixed_ie), _HT_ADD_INFO_IE_, &len, ie_len - sizeof(struct ndis_802_11_fixed_ie)); ++ ++ /* update cur_bwmode & cur_ch_offset */ ++ if ((pregistrypriv->cbw40_enable) && ++ (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & BIT(1)) && ++ (pmlmeinfo->HT_info.infos[0] & BIT(2))) { ++ int i; ++ u8 rf_type; ++ ++ padapter->HalFunc.GetHwRegHandler(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ ++ /* update the MCS rates */ ++ for (i = 0; i < 16; i++) { ++ if ((rf_type == RF_1T1R) || (rf_type == RF_1T2R)) ++ pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; ++ else ++ pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i]; ++ } ++ /* switch to the 40M Hz mode according to the AP */ ++ pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40; ++ switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) { ++ case HT_EXTCHNL_OFFSET_UPPER: ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; ++ break; ++ case HT_EXTCHNL_OFFSET_LOWER: ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; ++ break; ++ default: ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ break; ++ } ++ } ++ ++ /* Config SM Power Save setting */ ++ pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & 0x0C) >> 2; ++ if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) ++ DBG_88E("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__); ++ ++ /* Config current HT Protection mode. */ ++ pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3; ++} ++ ++void rtw_issue_addbareq_cmd(struct adapter *padapter, struct xmit_frame *pxmitframe) ++{ ++ u8 issued; ++ int priority; ++ struct sta_info *psta = NULL; ++ struct ht_priv *phtpriv; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ ++ if (is_multicast_ether_addr(pattrib->ra) || ++ padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod < 100) ++ return; ++ ++ priority = pattrib->priority; ++ ++ if (pattrib->psta) ++ psta = pattrib->psta; ++ else ++ psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); ++ ++ if (!psta) ++ return; ++ ++ phtpriv = &psta->htpriv; ++ ++ if ((phtpriv->ht_option) && (phtpriv->ampdu_enable)) { ++ issued = (phtpriv->agg_enable_bitmap >> priority) & 0x1; ++ issued |= (phtpriv->candidate_tid_bitmap >> priority) & 0x1; ++ ++ if (0 == issued) { ++ DBG_88E("rtw_issue_addbareq_cmd, p=%d\n", priority); ++ psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority); ++ rtw_addbareq_cmd(padapter, (u8)priority, pattrib->ra); ++ } ++ } ++} ++ ++void rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ _rtw_roaming(padapter, tgt_network); ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++void _rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ int do_join_r; ++ ++ struct wlan_network *pnetwork; ++ ++ if (tgt_network) ++ pnetwork = tgt_network; ++ else ++ pnetwork = &pmlmepriv->cur_network; ++ ++ if (0 < rtw_to_roaming(padapter)) { ++ DBG_88E("roaming from %s(%pM length:%d\n", ++ pnetwork->network.Ssid.Ssid, pnetwork->network.MacAddress, ++ pnetwork->network.Ssid.SsidLength); ++ memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.Ssid, sizeof(struct ndis_802_11_ssid)); ++ ++ pmlmepriv->assoc_by_bssid = false; ++ ++ while (1) { ++ do_join_r = rtw_do_join(padapter); ++ if (_SUCCESS == do_join_r) { ++ break; ++ } else { ++ DBG_88E("roaming do_join return %d\n", do_join_r); ++ pmlmepriv->to_roaming--; ++ ++ if (0 < pmlmepriv->to_roaming) { ++ continue; ++ } else { ++ DBG_88E("%s(%d) -to roaming fail, indicate_disconnect\n", __func__, __LINE__); ++ rtw_indicate_disconnect(padapter); ++ break; ++ } ++ } ++ } ++ } ++} +diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c +new file mode 100644 +index 000000000000..5a472a4954b0 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c +@@ -0,0 +1,8327 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_MLME_EXT_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wifi.h" ++#include "../include/rtw_mlme_ext.h" ++#include "../include/wlan_bssdef.h" ++#include "../include/mlme_osdep.h" ++#include "../include/recv_osdep.h" ++ ++static struct mlme_handler mlme_sta_tbl[] = { ++ {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq}, ++ {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp}, ++ {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq}, ++ {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp}, ++ {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq}, ++ {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp}, ++ ++ /*---------------------------------------------------------- ++ below 2 are reserved ++ -----------------------------------------------------------*/ ++ {0, "DoReserved", &DoReserved}, ++ {0, "DoReserved", &DoReserved}, ++ {WIFI_BEACON, "OnBeacon", &OnBeacon}, ++ {WIFI_ATIM, "OnATIM", &OnAtim}, ++ {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc}, ++ {WIFI_AUTH, "OnAuth", &OnAuthClient}, ++ {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth}, ++ {WIFI_ACTION, "OnAction", &OnAction}, ++}; ++ ++static struct action_handler OnAction_tbl[] = { ++ {RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct}, ++ {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos}, ++ {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls}, ++ {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back}, ++ {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public}, ++ {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved}, ++ {RTW_WLAN_CATEGORY_FT, "ACTION_FT", &DoReserved}, ++ {RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht}, ++ {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved}, ++ {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm}, ++ {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p}, ++}; ++ ++static u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; ++ ++/************************************************** ++OUI definitions for the vendor specific IE ++***************************************************/ ++unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01}; ++unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02}; ++unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04}; ++unsigned char P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09}; ++unsigned char WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A}; ++ ++unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; ++unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; ++ ++unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02}; ++unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02}; ++ ++extern unsigned char REALTEK_96B_IE[]; ++ ++/******************************************************** ++MCS rate definitions ++*********************************************************/ ++unsigned char MCS_rate_2R[16] = {0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; ++unsigned char MCS_rate_1R[16] = {0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; ++ ++/******************************************************** ++ChannelPlan definitions ++*********************************************************/ ++static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = { ++ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */ ++ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */ ++ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */ ++ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */ ++ {{10, 11, 12, 13}, 4}, /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */ ++ {{}, 0}, /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */ ++}; ++ ++static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = { ++ /* 0x00 ~ 0x1F , Old Define ===== */ ++ {0x02}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */ ++ {0x02}, /* 0x01, RT_CHANNEL_DOMAIN_IC */ ++ {0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */ ++ {0x01}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */ ++ {0x01}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */ ++ {0x03}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */ ++ {0x03}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */ ++ {0x01}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */ ++ {0x03}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */ ++ {0x03}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */ ++ {0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */ ++ {0x02}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */ ++ {0x01}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */ ++ {0x02}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */ ++ {0x02}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */ ++ {0x02}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */ ++ {0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */ ++ {0x02}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */ ++ {0x01}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */ ++ {0x02}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */ ++ {0x00}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */ ++ {0x00}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */ ++ {0x03}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */ ++ {0x05}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */ ++ {0x02}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */ ++ {0x00}, /* 0x1A, */ ++ {0x00}, /* 0x1B, */ ++ {0x00}, /* 0x1C, */ ++ {0x00}, /* 0x1D, */ ++ {0x00}, /* 0x1E, */ ++ /* 0x20 ~ 0x7F , New Define ===== */ ++ {0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */ ++ {0x01}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */ ++ {0x02}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */ ++ {0x03}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */ ++ {0x04}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */ ++ {0x02}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */ ++ {0x00}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */ ++ {0x03}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */ ++ {0x00}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */ ++ {0x00}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */ ++ {0x00}, /* 0x2A, */ ++ {0x00}, /* 0x2B, */ ++ {0x00}, /* 0x2C, */ ++ {0x00}, /* 0x2D, */ ++ {0x00}, /* 0x2E, */ ++ {0x00}, /* 0x2F, */ ++ {0x00}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */ ++ {0x00}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */ ++ {0x00}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */ ++ {0x00}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */ ++ {0x02}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */ ++ {0x00}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */ ++ {0x00}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */ ++ {0x03}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */ ++ {0x03}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */ ++ {0x02}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */ ++ {0x00}, /* 0x3A, */ ++ {0x00}, /* 0x3B, */ ++ {0x00}, /* 0x3C, */ ++ {0x00}, /* 0x3D, */ ++ {0x00}, /* 0x3E, */ ++ {0x00}, /* 0x3F, */ ++ {0x02}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */ ++ {0x03}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */ ++}; ++ ++static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03}; /* use the conbination for max channel numbers */ ++ ++/* ++ * Search the @param channel_num in given @param channel_set ++ * @ch_set: the given channel set ++ * @ch: the given channel number ++ * ++ * return the index of channel_num in channel_set, -1 if not found ++ */ ++int rtw_ch_set_search_ch(struct rt_channel_info *ch_set, const u32 ch) ++{ ++ int i; ++ for (i = 0; ch_set[i].ChannelNum != 0; i++) { ++ if (ch == ch_set[i].ChannelNum) ++ break; ++ } ++ ++ if (i >= ch_set[i].ChannelNum) ++ return -1; ++ return i; ++} ++ ++/**************************************************************************** ++ ++Following are the initialization functions for WiFi MLME ++ ++*****************************************************************************/ ++ ++int init_hw_mlme_ext(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); ++ return _SUCCESS; ++} ++ ++static void init_mlme_ext_priv_value(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ unsigned char mixed_datarate[NumRates] = { ++ _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, ++ _9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_, ++ _48M_RATE_, _54M_RATE_, 0xff ++ }; ++ unsigned char mixed_basicrate[NumRates] = { ++ _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, ++ _12M_RATE_, _24M_RATE_, 0xff, ++ }; ++ ++ atomic_set(&pmlmeext->event_seq, 0); ++ pmlmeext->mgnt_seq = 0;/* reset to zero when disconnect at client mode */ ++ ++ pmlmeext->cur_channel = padapter->registrypriv.channel; ++ pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ pmlmeext->retry = 0; ++ ++ pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode; ++ ++ memcpy(pmlmeext->datarate, mixed_datarate, NumRates); ++ memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates); ++ ++ pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB; ++ ++ pmlmeext->sitesurvey_res.state = SCAN_DISABLE; ++ pmlmeext->sitesurvey_res.channel_idx = 0; ++ pmlmeext->sitesurvey_res.bss_cnt = 0; ++ pmlmeext->scan_abort = false; ++ ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ pmlmeinfo->reauth_count = 0; ++ pmlmeinfo->reassoc_count = 0; ++ pmlmeinfo->link_count = 0; ++ pmlmeinfo->auth_seq = 0; ++ pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open; ++ pmlmeinfo->key_index = 0; ++ pmlmeinfo->iv = 0; ++ ++ pmlmeinfo->enc_algo = _NO_PRIVACY_; ++ pmlmeinfo->authModeToggle = 0; ++ ++ memset(pmlmeinfo->chg_txt, 0, 128); ++ ++ pmlmeinfo->slotTime = SHORT_SLOT_TIME; ++ pmlmeinfo->preamble_mode = PREAMBLE_AUTO; ++ ++ pmlmeinfo->dialogToken = 0; ++ ++ pmlmeext->action_public_rxseq = 0xffff; ++ pmlmeext->action_public_dialog_token = 0xff; ++} ++ ++static int has_channel(struct rt_channel_info *channel_set, ++ u8 chanset_size, ++ u8 chan) { ++ int i; ++ ++ for (i = 0; i < chanset_size; i++) { ++ if (channel_set[i].ChannelNum == chan) ++ return 1; ++ } ++ return 0; ++} ++ ++static void init_channel_list(struct adapter *padapter, struct rt_channel_info *channel_set, ++ u8 chanset_size, ++ struct p2p_channels *channel_list) { ++ struct p2p_oper_class_map op_class[] = { ++ { IEEE80211G, 81, 1, 13, 1, BW20 }, ++ { IEEE80211G, 82, 14, 14, 1, BW20 }, ++ { -1, 0, 0, 0, 0, BW20 } ++ }; ++ ++ int cla, op; ++ ++ cla = 0; ++ ++ for (op = 0; op_class[op].op_class; op++) { ++ u8 ch; ++ struct p2p_oper_class_map *o = &op_class[op]; ++ struct p2p_reg_class *reg = NULL; ++ ++ for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) { ++ if (!has_channel(channel_set, chanset_size, ch)) { ++ continue; ++ } ++ ++ if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc)) ++ continue; ++ ++ if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) && ++ ((BW40MINUS == o->bw) || (BW40PLUS == o->bw))) ++ continue; ++ ++ if (!reg) { ++ reg = &channel_list->reg_class[cla]; ++ cla++; ++ reg->reg_class = o->op_class; ++ reg->channels = 0; ++ } ++ reg->channel[reg->channels] = ch; ++ reg->channels++; ++ } ++ } ++ channel_list->reg_classes = cla; ++} ++ ++static u8 init_channel_set(struct adapter *padapter, u8 ChannelPlan, struct rt_channel_info *channel_set) ++{ ++ u8 index, chanset_size = 0; ++ u8 b2_4GBand = false; ++ u8 Index2G = 0; ++ ++ memset(channel_set, 0, sizeof(struct rt_channel_info) * MAX_CHANNEL_NUM); ++ ++ if (ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) { ++ DBG_88E("ChannelPlan ID %x error !!!!!\n", ChannelPlan); ++ return chanset_size; ++ } ++ ++ if (padapter->registrypriv.wireless_mode & WIRELESS_11G) { ++ b2_4GBand = true; ++ if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan) ++ Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G; ++ else ++ Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G; ++ } ++ ++ if (b2_4GBand) { ++ for (index = 0; index < RTW_ChannelPlan2G[Index2G].Len; index++) { ++ channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index]; ++ ++ if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) ||/* Channel 1~11 is active, and 12~14 is passive */ ++ (RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G == ChannelPlan)) { ++ if (channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11) ++ channel_set[chanset_size].ScanType = SCAN_ACTIVE; ++ else if ((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14)) ++ channel_set[chanset_size].ScanType = SCAN_PASSIVE; ++ } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan || ++ RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) {/* channel 12~13, passive scan */ ++ if (channel_set[chanset_size].ChannelNum <= 11) ++ channel_set[chanset_size].ScanType = SCAN_ACTIVE; ++ else ++ channel_set[chanset_size].ScanType = SCAN_PASSIVE; ++ } else { ++ channel_set[chanset_size].ScanType = SCAN_ACTIVE; ++ } ++ ++ chanset_size++; ++ } ++ } ++ return chanset_size; ++} ++ ++int init_mlme_ext_priv(struct adapter *padapter) ++{ ++ int res = _SUCCESS; ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ pmlmeext->padapter = padapter; ++ ++ init_mlme_ext_priv_value(padapter); ++ pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq; ++ ++ init_mlme_ext_timer(padapter); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ init_mlme_ap_info(padapter); ++#endif ++ ++ pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan, pmlmeext->channel_set); ++ init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list); ++ ++ pmlmeext->chan_scan_time = SURVEY_TO; ++ pmlmeext->mlmeext_init = true; ++ ++ pmlmeext->active_keep_alive_check = true; ++ ++ return res; ++} ++ ++void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext) ++{ ++ struct adapter *padapter = pmlmeext->padapter; ++ ++ if (!padapter) ++ return; ++ ++ if (padapter->bDriverStopped) { ++ _cancel_timer_ex(&pmlmeext->survey_timer); ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ /* _cancel_timer_ex(&pmlmeext->ADDBA_timer); */ ++ } ++} ++ ++static void _mgt_dispatcher(struct adapter *padapter, struct mlme_handler *ptable, struct recv_frame *precv_frame) ++{ ++ u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ u8 *pframe = precv_frame->rx_data; ++ ++ if (ptable->func) { ++ /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ ++ if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) && ++ memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) ++ return; ++ ptable->func(padapter, precv_frame); ++ } ++} ++ ++void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ int index; ++ struct mlme_handler *ptable; ++#ifdef CONFIG_88EU_AP_MODE ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++#endif /* CONFIG_88EU_AP_MODE */ ++ u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ u8 *pframe = precv_frame->rx_data; ++ struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe)); ++ ++ if (GetFrameType(pframe) != WIFI_MGT_TYPE) ++ return; ++ ++ /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ ++ if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) && ++ memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) ++ return; ++ ++ ptable = mlme_sta_tbl; ++ ++ index = GetFrameSubType(pframe) >> 4; ++ ++ if (index > 13) ++ return; ++ ptable += index; ++ ++ if (psta) { ++ if (GetRetry(pframe)) { ++ if (precv_frame->attrib.seq_num == psta->RxMgmtFrameSeqNum) { ++ /* drop the duplicate management frame */ ++ DBG_88E("Drop duplicate management frame with seq_num=%d.\n", precv_frame->attrib.seq_num); ++ return; ++ } ++ } ++ psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num; ++ } ++ ++#ifdef CONFIG_88EU_AP_MODE ++ switch (GetFrameSubType(pframe)) { ++ case WIFI_AUTH: ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ ptable->func = &OnAuth; ++ else ++ ptable->func = &OnAuthClient; ++ fallthrough; ++ case WIFI_ASSOCREQ: ++ case WIFI_REASSOCREQ: ++ _mgt_dispatcher(padapter, ptable, precv_frame); ++ break; ++ case WIFI_PROBEREQ: ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ _mgt_dispatcher(padapter, ptable, precv_frame); ++ else ++ _mgt_dispatcher(padapter, ptable, precv_frame); ++ break; ++ case WIFI_BEACON: ++ _mgt_dispatcher(padapter, ptable, precv_frame); ++ break; ++ case WIFI_ACTION: ++ _mgt_dispatcher(padapter, ptable, precv_frame); ++ break; ++ default: ++ _mgt_dispatcher(padapter, ptable, precv_frame); ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ rtw_hostapd_mlme_rx(padapter, precv_frame); ++ break; ++ } ++#else ++ _mgt_dispatcher(padapter, ptable, precv_frame); ++#endif ++} ++ ++#ifdef CONFIG_88EU_P2P ++static u32 p2p_listen_state_process(struct adapter *padapter, unsigned char *da) ++{ ++ bool response = true; ++ ++ /* do nothing if the device name is empty */ ++ if (!padapter->wdinfo.device_name_len) ++ response = false; ++ ++ if (response) ++ issue_probersp_p2p(padapter, da); ++ ++ return _SUCCESS; ++} ++#endif /* CONFIG_88EU_P2P */ ++ ++/**************************************************************************** ++ ++Following are the callback functions for each subtype of the management frames ++ ++*****************************************************************************/ ++ ++unsigned int OnProbeReq(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ unsigned int ielen; ++ unsigned char *p; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur = &pmlmeinfo->network; ++ u8 *pframe = precv_frame->rx_data; ++ uint len = precv_frame->len; ++ u8 is_valid_p2p_probereq = false; ++ ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 wifi_test_chk_rate = 1; ++ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && ++ !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) && ++ !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && ++ !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) && ++ !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)) { ++ /* mcs_rate = 0 -> CCK 1M rate */ ++ /* mcs_rate = 1 -> CCK 2M rate */ ++ /* mcs_rate = 2 -> CCK 5.5M rate */ ++ /* mcs_rate = 3 -> CCK 11M rate */ ++ /* In the P2P mode, the driver should not support the CCK rate */ ++ ++ /* Commented by Kurt 2012/10/16 */ ++ /* IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client */ ++ if (wifi_test_chk_rate == 1) { ++ is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len); ++ if (is_valid_p2p_probereq) { ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) { ++ /* FIXME */ ++ report_survey_event(padapter, precv_frame); ++ p2p_listen_state_process(padapter, get_sa(pframe)); ++ ++ return _SUCCESS; ++ } ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) ++ goto _continue; ++ } ++ } ++ } ++ ++_continue: ++#endif /* CONFIG_88EU_P2P */ ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) ++ return _SUCCESS; ++ ++ if (!check_fwstate(pmlmepriv, _FW_LINKED) && ++ !check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) ++ return _SUCCESS; ++ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen, ++ len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); ++ ++ /* check (wildcard) SSID */ ++ if (p) { ++ if (is_valid_p2p_probereq) ++ goto _issue_probersp; ++ ++ if ((ielen != 0 && memcmp((void *)(p + 2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength)) || ++ (ielen == 0 && pmlmeinfo->hidden_ssid_mode)) ++ return _SUCCESS; ++ ++_issue_probersp: ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED) && ++ (pmlmepriv->cur_network.join_res || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) ++ issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq); ++ } ++ return _SUCCESS; ++} ++ ++unsigned int OnProbeRsp(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 *pframe = precv_frame->rx_data; ++#endif ++ ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) { ++ if (pwdinfo->tx_prov_disc_info.benable) { ++ if (!memcmp(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN)) { ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) { ++ pwdinfo->tx_prov_disc_info.benable = false; ++ issue_p2p_provision_request(padapter, ++ pwdinfo->tx_prov_disc_info.ssid.Ssid, ++ pwdinfo->tx_prov_disc_info.ssid.SsidLength, ++ pwdinfo->tx_prov_disc_info.peerDevAddr); ++ } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ pwdinfo->tx_prov_disc_info.benable = false; ++ issue_p2p_provision_request(padapter, NULL, 0, ++ pwdinfo->tx_prov_disc_info.peerDevAddr); ++ } ++ } ++ } ++ return _SUCCESS; ++ } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) { ++ if (pwdinfo->nego_req_info.benable) { ++ DBG_88E("[%s] P2P State is GONEGO ING!\n", __func__); ++ if (!memcmp(pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN)) { ++ pwdinfo->nego_req_info.benable = false; ++ issue_p2p_GO_request(padapter, pwdinfo->nego_req_info.peerDevAddr); ++ } ++ } ++ } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) { ++ if (pwdinfo->invitereq_info.benable) { ++ DBG_88E("[%s] P2P_STATE_TX_INVITE_REQ!\n", __func__); ++ if (!memcmp(pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN)) { ++ pwdinfo->invitereq_info.benable = false; ++ issue_p2p_invitation_request(padapter, pwdinfo->invitereq_info.peer_macaddr); ++ } ++ } ++ } ++#endif ++ ++ if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { ++ report_survey_event(padapter, precv_frame); ++ return _SUCCESS; ++ } ++ ++ return _SUCCESS; ++} ++ ++unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ int cam_idx; ++ struct sta_info *psta; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 *pframe = precv_frame->rx_data; ++ uint len = precv_frame->len; ++ struct wlan_bssid_ex *pbss; ++ int ret = _SUCCESS; ++ ++ if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { ++ report_survey_event(padapter, precv_frame); ++ return _SUCCESS; ++ } ++ ++ if (!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) { ++ if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) { ++ /* we should update current network before auth, or some IE is wrong */ ++ pbss = kmalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC); ++ if (pbss) { ++ if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) { ++ update_network(&pmlmepriv->cur_network.network, pbss, padapter, true); ++ rtw_get_bcn_info(&pmlmepriv->cur_network); ++ } ++ kfree(pbss); ++ } ++ ++ /* check the vendor of the assoc AP */ ++ pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe + sizeof(struct rtw_ieee80211_hdr_3addr), len - sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ /* update TSF Value */ ++ update_TSF(pmlmeext, pframe, len); ++ ++ /* start auth */ ++ start_clnt_auth(padapter); ++ ++ return _SUCCESS; ++ } ++ ++ if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) { ++ psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); ++ if (psta) { ++ ret = rtw_check_bcn_info(padapter, pframe, len); ++ if (!ret) { ++ DBG_88E_LEVEL(_drv_info_, "ap has changed, disconnect now\n "); ++ receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0); ++ return _SUCCESS; ++ } ++ /* update WMM, ERP in the beacon */ ++ /* todo: the timer is used instead of the number of the beacon received */ ++ if ((sta_rx_pkts(psta) & 0xf) == 0) ++ update_beacon_info(padapter, pframe, len, psta); ++ process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)); ++ } ++ } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { ++ psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); ++ if (psta) { ++ /* update WMM, ERP in the beacon */ ++ /* todo: the timer is used instead of the number of the beacon received */ ++ if ((sta_rx_pkts(psta) & 0xf) == 0) ++ update_beacon_info(padapter, pframe, len, psta); ++ } else { ++ /* allocate a new CAM entry for IBSS station */ ++ cam_idx = allocate_fw_sta_entry(padapter); ++ if (cam_idx == NUM_STA) ++ goto _END_ONBEACON_; ++ ++ /* get supported rate */ ++ if (update_sta_support_rate(padapter, (pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_), (len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_), cam_idx) == _FAIL) { ++ pmlmeinfo->FW_sta_info[cam_idx].status = 0; ++ goto _END_ONBEACON_; ++ } ++ ++ /* update TSF Value */ ++ update_TSF(pmlmeext, pframe, len); ++ ++ /* report sta add event */ ++ report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx); ++ } ++ } ++ } ++ ++_END_ONBEACON_: ++ ++ return _SUCCESS; ++} ++ ++unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++#ifdef CONFIG_88EU_AP_MODE ++ unsigned int auth_mode, ie_len; ++ u16 seq; ++ unsigned char *sa, *p; ++ u16 algorithm; ++ int status; ++ static struct sta_info stat; ++ struct sta_info *pstat = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 *pframe = precv_frame->rx_data; ++ uint len = precv_frame->len; ++ ++ if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) ++ return _FAIL; ++ ++ DBG_88E("+OnAuth\n"); ++ ++ sa = GetAddr2Ptr(pframe); ++ ++ auth_mode = psecuritypriv->dot11AuthAlgrthm; ++ seq = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + 2)); ++ algorithm = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN)); ++ ++ DBG_88E("auth alg=%x, seq=%X\n", algorithm, seq); ++ ++ if (auth_mode == 2 && psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ && ++ psecuritypriv->dot11PrivacyAlgrthm != _WEP104_) ++ auth_mode = 0; ++ ++ if ((algorithm > 0 && auth_mode == 0) || /* rx a shared-key auth but shared not enabled */ ++ (algorithm == 0 && auth_mode == 1)) { /* rx a open-system auth but shared-key is enabled */ ++ DBG_88E("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n", ++ algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]); ++ ++ status = _STATS_NO_SUPP_ALG_; ++ ++ goto auth_fail; ++ } ++ ++ if (!rtw_access_ctrl(padapter, sa)) { ++ status = _STATS_UNABLE_HANDLE_STA_; ++ goto auth_fail; ++ } ++ ++ pstat = rtw_get_stainfo(pstapriv, sa); ++ if (!pstat) { ++ /* allocate a new one */ ++ DBG_88E("going to alloc stainfo for sa=%pM\n", sa); ++ pstat = rtw_alloc_stainfo(pstapriv, sa); ++ if (!pstat) { ++ DBG_88E(" Exceed the upper limit of supported clients...\n"); ++ status = _STATS_UNABLE_HANDLE_STA_; ++ goto auth_fail; ++ } ++ ++ pstat->state = WIFI_FW_AUTH_NULL; ++ pstat->auth_seq = 0; ++ } else { ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ if (!list_empty(&pstat->asoc_list)) { ++ list_del_init(&pstat->asoc_list); ++ pstapriv->asoc_list_cnt--; ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ if (seq == 1) { ++ /* TODO: STA re_auth and auth timeout */ ++ } ++ } ++ ++ spin_lock_bh(&pstapriv->auth_list_lock); ++ if (list_empty(&pstat->auth_list)) { ++ list_add_tail(&pstat->auth_list, &pstapriv->auth_list); ++ pstapriv->auth_list_cnt++; ++ } ++ spin_unlock_bh(&pstapriv->auth_list_lock); ++ ++ if (pstat->auth_seq == 0) ++ pstat->expire_to = pstapriv->auth_to; ++ ++ if ((pstat->auth_seq + 1) != seq) { ++ DBG_88E("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n", ++ seq, pstat->auth_seq + 1); ++ status = _STATS_OUT_OF_AUTH_SEQ_; ++ goto auth_fail; ++ } ++ ++ if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2)) { ++ if (seq == 1) { ++ pstat->state &= ~WIFI_FW_AUTH_NULL; ++ pstat->state |= WIFI_FW_AUTH_SUCCESS; ++ pstat->expire_to = pstapriv->assoc_to; ++ pstat->authalg = algorithm; ++ } else { ++ DBG_88E("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n", ++ seq, pstat->auth_seq + 1); ++ status = _STATS_OUT_OF_AUTH_SEQ_; ++ goto auth_fail; ++ } ++ } else { /* shared system or auto authentication */ ++ if (seq == 1) { ++ /* prepare for the challenging txt... */ ++ ++ pstat->state &= ~WIFI_FW_AUTH_NULL; ++ pstat->state |= WIFI_FW_AUTH_STATE; ++ pstat->authalg = algorithm; ++ pstat->auth_seq = 2; ++ } else if (seq == 3) { ++ /* checking for challenging txt... */ ++ DBG_88E("checking for challenging txt...\n"); ++ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&ie_len, ++ len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4); ++ ++ if (!p || ie_len <= 0) { ++ DBG_88E("auth rejected because challenge failure!(1)\n"); ++ status = _STATS_CHALLENGE_FAIL_; ++ goto auth_fail; ++ } ++ ++ if (!memcmp((void *)(p + 2), pstat->chg_txt, 128)) { ++ pstat->state &= (~WIFI_FW_AUTH_STATE); ++ pstat->state |= WIFI_FW_AUTH_SUCCESS; ++ /* challenging txt is correct... */ ++ pstat->expire_to = pstapriv->assoc_to; ++ } else { ++ DBG_88E("auth rejected because challenge failure!\n"); ++ status = _STATS_CHALLENGE_FAIL_; ++ goto auth_fail; ++ } ++ } else { ++ DBG_88E("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n", ++ seq, pstat->auth_seq + 1); ++ status = _STATS_OUT_OF_AUTH_SEQ_; ++ goto auth_fail; ++ } ++ } ++ ++ /* Now, we are going to issue_auth... */ ++ pstat->auth_seq = seq + 1; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_)); ++#endif ++ ++ if (pstat->state & WIFI_FW_AUTH_SUCCESS) ++ pstat->auth_seq = 0; ++ ++ return _SUCCESS; ++ ++auth_fail: ++ ++ if (pstat) ++ rtw_free_stainfo(padapter, pstat); ++ ++ pstat = &stat; ++ memset((char *)pstat, '\0', sizeof(stat)); ++ pstat->auth_seq = 2; ++ memcpy(pstat->hwaddr, sa, 6); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ issue_auth(padapter, pstat, (unsigned short)status); ++#endif ++ ++#endif ++ return _FAIL; ++} ++ ++unsigned int OnAuthClient(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ unsigned int seq, len, status, offset; ++ unsigned char *p; ++ unsigned int go2asoc = 0; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 *pframe = precv_frame->rx_data; ++ uint pkt_len = precv_frame->len; ++ ++ DBG_88E("%s\n", __func__); ++ ++ /* check A1 matches or not */ ++ if (memcmp(myid(&padapter->eeprompriv), get_da(pframe), ETH_ALEN)) ++ return _SUCCESS; ++ ++ if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE)) ++ return _SUCCESS; ++ ++ offset = (GetPrivacy(pframe)) ? 4 : 0; ++ ++ seq = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + offset + 2)); ++ status = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + offset + 4)); ++ ++ if (status != 0) { ++ DBG_88E("clnt auth fail, status: %d\n", status); ++ if (status == 13) { /* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */ ++ if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ++ pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open; ++ else ++ pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; ++ } ++ ++ set_link_timer(pmlmeext, 1); ++ goto authclnt_fail; ++ } ++ ++ if (seq == 2) { ++ if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) { ++ /* legendary shared system */ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len, ++ pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_); ++ ++ if (!p) ++ goto authclnt_fail; ++ ++ memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len); ++ pmlmeinfo->auth_seq = 3; ++ issue_auth(padapter, NULL, 0); ++ set_link_timer(pmlmeext, REAUTH_TO); ++ ++ return _SUCCESS; ++ } else { ++ /* open system */ ++ go2asoc = 1; ++ } ++ } else if (seq == 4) { ++ if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ++ go2asoc = 1; ++ else ++ goto authclnt_fail; ++ } else { ++ /* this is also illegal */ ++ goto authclnt_fail; ++ } ++ ++ if (go2asoc) { ++ DBG_88E_LEVEL(_drv_info_, "auth success, start assoc\n"); ++ start_clnt_assoc(padapter); ++ return _SUCCESS; ++ } ++authclnt_fail: ++ return _FAIL; ++} ++ ++unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++#ifdef CONFIG_88EU_AP_MODE ++ u16 capab_info; ++ struct rtw_ieee802_11_elems elems; ++ struct sta_info *pstat; ++ unsigned char reassoc, *p, *pos, *wpa_ie; ++ unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; ++ int i, ie_len, wpa_ie_len, left; ++ unsigned char supportRate[16]; ++ int supportRateNum; ++ unsigned short status = _STATS_SUCCESSFUL_; ++ unsigned short frame_type, ie_offset = 0; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur = &pmlmeinfo->network; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 *pframe = precv_frame->rx_data; ++ uint pkt_len = precv_frame->len; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 p2p_status_code = P2P_STATUS_SUCCESS; ++ u8 *p2pie; ++ u32 p2pielen = 0; ++#endif /* CONFIG_88EU_P2P */ ++ ++ if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) ++ return _FAIL; ++ ++ frame_type = GetFrameSubType(pframe); ++ if (frame_type == WIFI_ASSOCREQ) { ++ reassoc = 0; ++ ie_offset = _ASOCREQ_IE_OFFSET_; ++ } else { /* WIFI_REASSOCREQ */ ++ reassoc = 1; ++ ie_offset = _REASOCREQ_IE_OFFSET_; ++ } ++ ++ if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) { ++ DBG_88E("handle_assoc(reassoc=%d) - too short payload (len=%lu)" ++ "\n", reassoc, (unsigned long)pkt_len); ++ return _FAIL; ++ } ++ ++ pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); ++ if (pstat == (struct sta_info *)NULL) { ++ status = _RSON_CLS2_; ++ goto asoc_class2_error; ++ } ++ ++ capab_info = get_unaligned_le16(pframe + WLAN_HDR_A3_LEN); ++ ++ left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset); ++ pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset); ++ ++ DBG_88E("%s\n", __func__); ++ ++ /* check if this stat has been successfully authenticated/assocated */ ++ if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) { ++ if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) { ++ status = _RSON_CLS2_; ++ goto asoc_class2_error; ++ } else { ++ pstat->state &= (~WIFI_FW_ASSOC_SUCCESS); ++ pstat->state |= WIFI_FW_ASSOC_STATE; ++ } ++ } else { ++ pstat->state &= (~WIFI_FW_AUTH_SUCCESS); ++ pstat->state |= WIFI_FW_ASSOC_STATE; ++ } ++ pstat->capability = capab_info; ++ /* now parse all ieee802_11 ie to point to elems */ ++ if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed || ++ !elems.ssid) { ++ DBG_88E("STA %pM sent invalid association request\n", ++ pstat->hwaddr); ++ status = _STATS_FAILURE_; ++ goto OnAssocReqFail; ++ } ++ ++ /* now we should check all the fields... */ ++ /* checking SSID */ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len, ++ pkt_len - WLAN_HDR_A3_LEN - ie_offset); ++ if (!p) ++ status = _STATS_FAILURE_; ++ ++ if (ie_len == 0) { /* broadcast ssid, however it is not allowed in assocreq */ ++ status = _STATS_FAILURE_; ++ } else { ++ /* check if ssid match */ ++ if (memcmp((void *)(p + 2), cur->Ssid.Ssid, cur->Ssid.SsidLength)) ++ status = _STATS_FAILURE_; ++ ++ if (ie_len != cur->Ssid.SsidLength) ++ status = _STATS_FAILURE_; ++ } ++ ++ if (_STATS_SUCCESSFUL_ != status) ++ goto OnAssocReqFail; ++ ++ /* check if the supported rate is ok */ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset); ++ if (!p) { ++ DBG_88E("Rx a sta assoc-req which supported rate is empty!\n"); ++ /* use our own rate set as statoin used */ ++ /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */ ++ /* supportRateNum = AP_BSSRATE_LEN; */ ++ ++ status = _STATS_FAILURE_; ++ goto OnAssocReqFail; ++ } else { ++ memcpy(supportRate, p + 2, ie_len); ++ supportRateNum = ie_len; ++ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_, &ie_len, ++ pkt_len - WLAN_HDR_A3_LEN - ie_offset); ++ if (p) { ++ if (supportRateNum <= sizeof(supportRate)) { ++ memcpy(supportRate + supportRateNum, p + 2, ie_len); ++ supportRateNum += ie_len; ++ } ++ } ++ } ++ ++ /* todo: mask supportRate between AP & STA -> move to update raid */ ++ /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */ ++ ++ /* update station supportRate */ ++ pstat->bssratelen = supportRateNum; ++ memcpy(pstat->bssrateset, supportRate, supportRateNum); ++ UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen); ++ ++ /* check RSN/WPA/WPS */ ++ pstat->dot8021xalg = 0; ++ pstat->wpa_psk = 0; ++ pstat->wpa_group_cipher = 0; ++ pstat->wpa2_group_cipher = 0; ++ pstat->wpa_pairwise_cipher = 0; ++ pstat->wpa2_pairwise_cipher = 0; ++ memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie)); ++ if ((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) { ++ int group_cipher = 0, pairwise_cipher = 0; ++ ++ wpa_ie = elems.rsn_ie; ++ wpa_ie_len = elems.rsn_ie_len; ++ ++ if (rtw_parse_wpa2_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { ++ pstat->dot8021xalg = 1;/* psk, todo:802.1x */ ++ pstat->wpa_psk |= BIT(1); ++ ++ pstat->wpa2_group_cipher = group_cipher & psecuritypriv->wpa2_group_cipher; ++ pstat->wpa2_pairwise_cipher = pairwise_cipher & psecuritypriv->wpa2_pairwise_cipher; ++ ++ if (!pstat->wpa2_group_cipher) ++ status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; ++ ++ if (!pstat->wpa2_pairwise_cipher) ++ status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; ++ } else { ++ status = WLAN_STATUS_INVALID_IE; ++ } ++ } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) { ++ int group_cipher = 0, pairwise_cipher = 0; ++ ++ wpa_ie = elems.wpa_ie; ++ wpa_ie_len = elems.wpa_ie_len; ++ ++ if (rtw_parse_wpa_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { ++ pstat->dot8021xalg = 1;/* psk, todo:802.1x */ ++ pstat->wpa_psk |= BIT(0); ++ ++ pstat->wpa_group_cipher = group_cipher & psecuritypriv->wpa_group_cipher; ++ pstat->wpa_pairwise_cipher = pairwise_cipher & psecuritypriv->wpa_pairwise_cipher; ++ ++ if (!pstat->wpa_group_cipher) ++ status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; ++ ++ if (!pstat->wpa_pairwise_cipher) ++ status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; ++ } else { ++ status = WLAN_STATUS_INVALID_IE; ++ } ++ } else { ++ wpa_ie = NULL; ++ wpa_ie_len = 0; ++ } ++ ++ if (_STATS_SUCCESSFUL_ != status) ++ goto OnAssocReqFail; ++ ++ pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); ++ if (!wpa_ie) { ++ if (elems.wps_ie) { ++ DBG_88E("STA included WPS IE in " ++ "(Re)Association Request - assume WPS is " ++ "used\n"); ++ pstat->flags |= WLAN_STA_WPS; ++ /* wpabuf_free(sta->wps_ie); */ ++ /* sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4, */ ++ /* elems.wps_ie_len - 4); */ ++ } else { ++ DBG_88E("STA did not include WPA/RSN IE " ++ "in (Re)Association Request - possible WPS " ++ "use\n"); ++ pstat->flags |= WLAN_STA_MAYBE_WPS; ++ } ++ ++ /* AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */ ++ /* that the selected registrar of AP is _FLASE */ ++ if ((psecuritypriv->wpa_psk > 0) && (pstat->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) { ++ if (pmlmepriv->wps_beacon_ie) { ++ u8 selected_registrar = 0; ++ ++ rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR, &selected_registrar, NULL); ++ ++ if (!selected_registrar) { ++ DBG_88E("selected_registrar is false , or AP is not ready to do WPS\n"); ++ ++ status = _STATS_UNABLE_HANDLE_STA_; ++ ++ goto OnAssocReqFail; ++ } ++ } ++ } ++ } else { ++ int copy_len; ++ ++ if (psecuritypriv->wpa_psk == 0) { ++ DBG_88E("STA %pM: WPA/RSN IE in association " ++ "request, but AP don't support WPA/RSN\n", pstat->hwaddr); ++ ++ status = WLAN_STATUS_INVALID_IE; ++ ++ goto OnAssocReqFail; ++ } ++ ++ if (elems.wps_ie) { ++ DBG_88E("STA included WPS IE in " ++ "(Re)Association Request - WPS is " ++ "used\n"); ++ pstat->flags |= WLAN_STA_WPS; ++ copy_len = 0; ++ } else { ++ copy_len = ((wpa_ie_len + 2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)) : (wpa_ie_len + 2); ++ } ++ if (copy_len > 0) ++ memcpy(pstat->wpa_ie, wpa_ie - 2, copy_len); ++ } ++ /* check if there is WMM IE & support WWM-PS */ ++ pstat->flags &= ~WLAN_STA_WME; ++ pstat->qos_option = 0; ++ pstat->qos_info = 0; ++ pstat->has_legacy_ac = true; ++ pstat->uapsd_vo = 0; ++ pstat->uapsd_vi = 0; ++ pstat->uapsd_be = 0; ++ pstat->uapsd_bk = 0; ++ if (pmlmepriv->qospriv.qos_option) { ++ p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0; ++ for (;;) { ++ p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset); ++ if (p) { ++ if (!memcmp(p + 2, WMM_IE, 6)) { ++ pstat->flags |= WLAN_STA_WME; ++ ++ pstat->qos_option = 1; ++ pstat->qos_info = *(p + 8); ++ ++ pstat->max_sp_len = (pstat->qos_info >> 5) & 0x3; ++ ++ if ((pstat->qos_info & 0xf) != 0xf) ++ pstat->has_legacy_ac = true; ++ else ++ pstat->has_legacy_ac = false; ++ ++ if (pstat->qos_info & 0xf) { ++ if (pstat->qos_info & BIT(0)) ++ pstat->uapsd_vo = BIT(0) | BIT(1); ++ else ++ pstat->uapsd_vo = 0; ++ ++ if (pstat->qos_info & BIT(1)) ++ pstat->uapsd_vi = BIT(0) | BIT(1); ++ else ++ pstat->uapsd_vi = 0; ++ ++ if (pstat->qos_info & BIT(2)) ++ pstat->uapsd_bk = BIT(0) | BIT(1); ++ else ++ pstat->uapsd_bk = 0; ++ ++ if (pstat->qos_info & BIT(3)) ++ pstat->uapsd_be = BIT(0) | BIT(1); ++ else ++ pstat->uapsd_be = 0; ++ } ++ break; ++ } ++ } else { ++ break; ++ } ++ p = p + ie_len + 2; ++ } ++ } ++ ++ /* save HT capabilities in the sta object */ ++ memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap)); ++ if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct ieee80211_ht_cap)) { ++ pstat->flags |= WLAN_STA_HT; ++ ++ pstat->flags |= WLAN_STA_WME; ++ ++ memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct ieee80211_ht_cap)); ++ } else { ++ pstat->flags &= ~WLAN_STA_HT; ++ } ++ if ((!pmlmepriv->htpriv.ht_option) && (pstat->flags & WLAN_STA_HT)) { ++ status = _STATS_FAILURE_; ++ goto OnAssocReqFail; ++ } ++ ++ if ((pstat->flags & WLAN_STA_HT) && ++ ((pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) || ++ (pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP))) { ++ DBG_88E("HT: %pM tried to " ++ "use TKIP with HT association\n", pstat->hwaddr); ++ ++ /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */ ++ /* goto OnAssocReqFail; */ ++ } ++ ++ pstat->flags |= WLAN_STA_NONERP; ++ for (i = 0; i < pstat->bssratelen; i++) { ++ if ((pstat->bssrateset[i] & 0x7f) > 22) { ++ pstat->flags &= ~WLAN_STA_NONERP; ++ break; ++ } ++ } ++ ++ if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) ++ pstat->flags |= WLAN_STA_SHORT_PREAMBLE; ++ else ++ pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE; ++ ++ if (status != _STATS_SUCCESSFUL_) ++ goto OnAssocReqFail; ++ ++#ifdef CONFIG_88EU_P2P ++ pstat->is_p2p_device = false; ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, NULL, &p2pielen); ++ if (p2pie) { ++ pstat->is_p2p_device = true; ++ p2p_status_code = (u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat); ++ if (p2p_status_code > 0) { ++ pstat->p2p_status_code = p2p_status_code; ++ status = _STATS_CAP_FAIL_; ++ goto OnAssocReqFail; ++ } ++ } ++ } ++ pstat->p2p_status_code = p2p_status_code; ++#endif /* CONFIG_88EU_P2P */ ++ ++ /* TODO: identify_proprietary_vendor_ie(); */ ++ /* Realtek proprietary IE */ ++ /* identify if this is Broadcom sta */ ++ /* identify if this is ralink sta */ ++ /* Customer proprietary IE */ ++ ++ /* get a unique AID */ ++ if (pstat->aid > 0) { ++ DBG_88E(" old AID %d\n", pstat->aid); ++ } else { ++ for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) ++ if (!pstapriv->sta_aid[pstat->aid - 1]) ++ break; ++ ++ /* if (pstat->aid > NUM_STA) { */ ++ if (pstat->aid > pstapriv->max_num_sta) { ++ pstat->aid = 0; ++ ++ DBG_88E(" no room for more AIDs\n"); ++ ++ status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; ++ ++ goto OnAssocReqFail; ++ } else { ++ pstapriv->sta_aid[pstat->aid - 1] = pstat; ++ DBG_88E("allocate new AID=(%d)\n", pstat->aid); ++ } ++ } ++ ++ pstat->state &= (~WIFI_FW_ASSOC_STATE); ++ pstat->state |= WIFI_FW_ASSOC_SUCCESS; ++ ++ spin_lock_bh(&pstapriv->auth_list_lock); ++ if (!list_empty(&pstat->auth_list)) { ++ list_del_init(&pstat->auth_list); ++ pstapriv->auth_list_cnt--; ++ } ++ spin_unlock_bh(&pstapriv->auth_list_lock); ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ if (list_empty(&pstat->asoc_list)) { ++ pstat->expire_to = pstapriv->expire_to; ++ list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list); ++ pstapriv->asoc_list_cnt++; ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ /* now the station is qualified to join our BSS... */ ++ if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_ == status)) { ++#ifdef CONFIG_88EU_AP_MODE ++ /* 1 bss_cap_update & sta_info_update */ ++ bss_cap_update_on_sta_join(padapter, pstat); ++ sta_info_update(padapter, pstat); ++ ++ /* issue assoc rsp before notify station join event. */ ++ if (frame_type == WIFI_ASSOCREQ) ++ issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); ++ else ++ issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); ++ ++ /* 2 - report to upper layer */ ++ DBG_88E("indicate_sta_join_event to upper layer - hostapd\n"); ++ rtw_indicate_sta_assoc_event(padapter, pstat); ++ ++ /* 3-(1) report sta add event */ ++ report_add_sta_event(padapter, pstat->hwaddr, pstat->aid); ++#endif ++ } ++ ++ return _SUCCESS; ++ ++asoc_class2_error: ++ ++#ifdef CONFIG_88EU_AP_MODE ++ issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status); ++#endif ++ ++ return _FAIL; ++ ++OnAssocReqFail: ++ ++#ifdef CONFIG_88EU_AP_MODE ++ pstat->aid = 0; ++ if (frame_type == WIFI_ASSOCREQ) ++ issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); ++ else ++ issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); ++#endif ++ ++#endif /* CONFIG_88EU_AP_MODE */ ++ ++ return _FAIL; ++} ++ ++unsigned int OnAssocRsp(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ uint i; ++ int res; ++ unsigned short status; ++ struct ndis_802_11_var_ie *pIE; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ /* struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); */ ++ u8 *pframe = precv_frame->rx_data; ++ uint pkt_len = precv_frame->len; ++ ++ DBG_88E("%s\n", __func__); ++ ++ /* check A1 matches or not */ ++ if (memcmp(myid(&padapter->eeprompriv), get_da(pframe), ETH_ALEN)) ++ return _SUCCESS; ++ ++ if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE))) ++ return _SUCCESS; ++ ++ if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) ++ return _SUCCESS; ++ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ ++ /* status */ ++ status = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 2)); ++ if (status > 0) { ++ DBG_88E("assoc reject, status code: %d\n", status); ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ res = -4; ++ goto report_assoc_result; ++ } ++ ++ /* get capabilities */ ++ pmlmeinfo->capability = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); ++ ++ /* set slot time */ ++ pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10)) ? 9 : 20; ++ ++ /* AID */ ++ pmlmeinfo->aid = (int)(le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 4)) & 0x3fff); ++ res = pmlmeinfo->aid; ++ ++ /* following are moved to join event callback function */ ++ /* to handle HT, WMM, rate adaptive, update MAC reg */ ++ /* for not to handle the synchronous IO in the tasklet */ ++ for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) { ++ pIE = (struct ndis_802_11_var_ie *)(pframe + i); ++ ++ switch (pIE->ElementID) { ++ case _VENDOR_SPECIFIC_IE_: ++ if (!memcmp(pIE->data, WMM_PARA_OUI, 6)) /* WMM */ ++ WMM_param_handler(padapter, pIE); ++ break; ++ case _HT_CAPABILITY_IE_: /* HT caps */ ++ HT_caps_handler(padapter, pIE); ++ break; ++ case _HT_EXTRA_INFO_IE_: /* HT info */ ++ HT_info_handler(padapter, pIE); ++ break; ++ case _ERPINFO_IE_: ++ ERP_IE_handler(padapter, pIE); ++ break; ++ default: ++ break; ++ } ++ ++ i += (pIE->Length + 2); ++ } ++ ++ pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE); ++ pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; ++ ++ /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */ ++ UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates); ++ ++report_assoc_result: ++ if (res > 0) ++ rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len); ++ else ++ kfree(pmlmepriv->assoc_rsp); ++ ++ report_join_res(padapter, res); ++ ++ return _SUCCESS; ++} ++ ++unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ unsigned short reason; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 *pframe = precv_frame->rx_data; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ /* check A3 */ ++ if (!(!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) ++ return _SUCCESS; ++ ++#ifdef CONFIG_88EU_P2P ++ if (pwdinfo->rx_invitereq_info.scan_op_ch_only) { ++ _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey); ++ _set_timer(&pwdinfo->reset_ch_sitesurvey, 10); ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); ++ ++ DBG_88E("%s Reason code(%d)\n", __func__, reason); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ struct sta_info *psta; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ DBG_88E_LEVEL(_drv_always_, "ap recv deauth reason code(%d) sta:%pM\n", ++ reason, GetAddr2Ptr(pframe)); ++ ++ psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); ++ if (psta) { ++ u8 updated = 0; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ if (!list_empty(&psta->asoc_list)) { ++ list_del_init(&psta->asoc_list); ++ pstapriv->asoc_list_cnt--; ++ updated = ap_free_sta(padapter, psta, false, reason); ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ associated_clients_update(padapter, updated); ++ } ++ ++ return _SUCCESS; ++ } else ++#endif ++ { ++ int ignore_received_deauth = 0; ++ ++ /* Before sending the auth frame to start the STA/GC mode connection with AP/GO, ++ * we will send the deauth first. ++ * However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth. ++ * Added the following code to avoid this case. ++ */ ++ if ((pmlmeinfo->state & WIFI_FW_AUTH_STATE) || ++ (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)) { ++ if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA) { ++ ignore_received_deauth = 1; ++ } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) { ++ // TODO: 802.11r ++ ignore_received_deauth = 1; ++ } ++ } ++ ++ DBG_88E_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM, ignore = %d\n", ++ reason, GetAddr3Ptr(pframe), ignore_received_deauth); ++ ++ if (!ignore_received_deauth) ++ receive_disconnect(padapter, GetAddr3Ptr(pframe), reason); ++ } ++ pmlmepriv->LinkDetectInfo.bBusyTraffic = false; ++ return _SUCCESS; ++} ++ ++unsigned int OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ u16 reason; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 *pframe = precv_frame->rx_data; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ /* check A3 */ ++ if (!(!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) ++ return _SUCCESS; ++ ++#ifdef CONFIG_88EU_P2P ++ if (pwdinfo->rx_invitereq_info.scan_op_ch_only) { ++ _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey); ++ _set_timer(&pwdinfo->reset_ch_sitesurvey, 10); ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); ++ ++ DBG_88E("%s Reason code(%d)\n", __func__, reason); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ struct sta_info *psta; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ DBG_88E_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n", ++ reason, GetAddr2Ptr(pframe)); ++ ++ psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); ++ if (psta) { ++ u8 updated = 0; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ if (!list_empty(&psta->asoc_list)) { ++ list_del_init(&psta->asoc_list); ++ pstapriv->asoc_list_cnt--; ++ updated = ap_free_sta(padapter, psta, false, reason); ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ associated_clients_update(padapter, updated); ++ } ++ ++ return _SUCCESS; ++ } else ++#endif ++ { ++ DBG_88E_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n", ++ reason, GetAddr3Ptr(pframe)); ++ ++ receive_disconnect(padapter, GetAddr3Ptr(pframe), reason); ++ } ++ pmlmepriv->LinkDetectInfo.bBusyTraffic = false; ++ return _SUCCESS; ++} ++ ++unsigned int OnAtim(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ DBG_88E("%s\n", __func__); ++ return _SUCCESS; ++} ++ ++unsigned int on_action_spct(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ unsigned int ret = _FAIL; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 *pframe = precv_frame->rx_data; ++ u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ u8 category; ++ u8 action; ++ ++ DBG_88E(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); ++ ++ psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); ++ ++ if (!psta) ++ goto exit; ++ ++ category = frame_body[0]; ++ if (category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT) ++ goto exit; ++ ++ action = frame_body[1]; ++ switch (action) { ++ case RTW_WLAN_ACTION_SPCT_MSR_REQ: ++ case RTW_WLAN_ACTION_SPCT_MSR_RPRT: ++ case RTW_WLAN_ACTION_SPCT_TPC_REQ: ++ case RTW_WLAN_ACTION_SPCT_TPC_RPRT: ++ break; ++ case RTW_WLAN_ACTION_SPCT_CHL_SWITCH: ++ break; ++ default: ++ break; ++ } ++ ++exit: ++ return ret; ++} ++ ++unsigned int OnAction_qos(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ return _SUCCESS; ++} ++ ++unsigned int OnAction_dls(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ return _SUCCESS; ++} ++ ++unsigned int OnAction_back(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ u8 *addr; ++ struct sta_info *psta = NULL; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ unsigned char *frame_body; ++ unsigned char category, action; ++ unsigned short tid, status, reason_code = 0; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 *pframe = precv_frame->rx_data; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ /* check RA matches or not */ ++ if (memcmp(myid(&padapter->eeprompriv), GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */ ++ return _SUCCESS; ++ ++ DBG_88E("%s\n", __func__); ++ ++ if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) ++ if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) ++ return _SUCCESS; ++ ++ addr = GetAddr2Ptr(pframe); ++ psta = rtw_get_stainfo(pstapriv, addr); ++ ++ if (!psta) ++ return _SUCCESS; ++ ++ frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ category = frame_body[0]; ++ if (category == RTW_WLAN_CATEGORY_BACK) { /* representing Block Ack */ ++ if (!pmlmeinfo->HT_enable) ++ return _SUCCESS; ++ action = frame_body[1]; ++ DBG_88E("%s, action=%d\n", __func__, action); ++ switch (action) { ++ case RTW_WLAN_ACTION_ADDBA_REQ: /* ADDBA request */ ++ memcpy(&pmlmeinfo->ADDBA_req, &frame_body[2], sizeof(struct ADDBA_request)); ++ process_addba_req(padapter, (u8 *)&pmlmeinfo->ADDBA_req, addr); ++ ++ if (pmlmeinfo->bAcceptAddbaReq) ++ issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 0); ++ else ++ issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 37);/* reject ADDBA Req */ ++ break; ++ case RTW_WLAN_ACTION_ADDBA_RESP: /* ADDBA response */ ++ status = get_unaligned_le16(&frame_body[3]); ++ tid = ((frame_body[5] >> 2) & 0x7); ++ if (status == 0) { /* successful */ ++ DBG_88E("agg_enable for TID=%d\n", tid); ++ psta->htpriv.agg_enable_bitmap |= 1 << tid; ++ psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); ++ } else { ++ psta->htpriv.agg_enable_bitmap &= ~BIT(tid); ++ } ++ break; ++ case RTW_WLAN_ACTION_DELBA: /* DELBA */ ++ if ((frame_body[3] & BIT(3)) == 0) { ++ psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf)); ++ psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf)); ++ reason_code = get_unaligned_le16(&frame_body[4]); ++ } else if ((frame_body[3] & BIT(3)) == BIT(3)) { ++ tid = (frame_body[3] >> 4) & 0x0F; ++ preorder_ctrl = &psta->recvreorder_ctrl[tid]; ++ preorder_ctrl->enable = false; ++ preorder_ctrl->indicate_seq = 0xffff; ++ } ++ DBG_88E("%s(): DELBA: %x(%x)\n", __func__, pmlmeinfo->agg_enable_bitmap, reason_code); ++ /* todo: how to notify the host while receiving DELETE BA */ ++ break; ++ default: ++ break; ++ } ++ } ++ return _SUCCESS; ++} ++ ++#ifdef CONFIG_88EU_P2P ++ ++static int get_reg_classes_full_count(struct p2p_channels *channel_list) ++{ ++ int cnt = 0; ++ int i; ++ ++ for (i = 0; i < channel_list->reg_classes; i++) { ++ cnt += channel_list->reg_class[i].channels; ++ } ++ ++ return cnt; ++} ++ ++void issue_p2p_GO_request(struct adapter *padapter, u8 *raddr) ++{ ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_GO_NEGO_REQ; ++ u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 }; ++ u8 wpsielen = 0, p2pielen = 0; ++ u16 len_channellist_attr = 0; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ DBG_88E("[%s] In\n", __func__); ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pwdinfo->negotiation_dialog_token = 1; /* Initialize the dialog value */ ++ pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &pattrib->pktlen); ++ ++ /* WPS Section */ ++ wpsielen = 0; ++ /* WPS OUI */ ++ *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI); ++ wpsielen += 4; ++ ++ /* WPS version */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */ ++ ++ /* Device Password ID */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002); ++ wpsielen += 2; ++ ++ /* Value: */ ++ ++ if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN) ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC); ++ else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN) ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC); ++ else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC) ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC); ++ ++ wpsielen += 2; ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen); ++ ++ /* P2P IE Section. */ ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20110306 */ ++ /* According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes */ ++ /* 1. P2P Capability */ ++ /* 2. Group Owner Intent */ ++ /* 3. Configuration Timeout */ ++ /* 4. Listen Channel */ ++ /* 5. Extended Listen Timing */ ++ /* 6. Intended P2P Interface Address */ ++ /* 7. Channel List */ ++ /* 8. P2P Device Info */ ++ /* 9. Operating Channel */ ++ ++ /* P2P Capability */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CAPABILITY; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT; ++ ++ /* Group Capability Bitmap, 1 byte */ ++ if (pwdinfo->persistent_supported) ++ p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP; ++ else ++ p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN; ++ ++ /* Group Owner Intent */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GO_INTENT; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Todo the tie breaker bit. */ ++ p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0)); ++ ++ /* Configuration Timeout */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */ ++ ++ /* Listen Channel */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; /* Copy from SD7 */ ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->listen_channel; /* listening channel number */ ++ ++ /* Extended Listen Timing ATTR */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Availability Period */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF); ++ p2pielen += 2; ++ ++ /* Availability Interval */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF); ++ p2pielen += 2; ++ ++ /* Intended P2P Interface Address */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Channel List */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CH_LIST; ++ ++ /* Length: */ ++ /* Country String(3) */ ++ /* + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */ ++ /* + number of channels in all classes */ ++ len_channellist_attr = 3 ++ + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes) ++ + get_reg_classes_full_count(&pmlmeext->channel_list); ++ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Channel Entry List */ ++ ++ { ++ int i, j; ++ for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) { ++ /* Operating Class */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class; ++ ++ /* Number of Channels */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels; ++ ++ /* Channel List */ ++ for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) { ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i]; ++ } ++ } ++ } ++ ++ /* Device Info */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO; ++ ++ /* Length: */ ++ /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */ ++ /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address */ ++ memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Config Method */ ++ /* This field should be big endian. Noted by P2P specification. */ ++ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm); ++ ++ p2pielen += 2; ++ ++ /* Primary Device Type */ ++ /* Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); ++ p2pielen += 2; ++ ++ /* OUI */ ++ *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI); ++ p2pielen += 4; ++ ++ /* Sub Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); ++ p2pielen += 2; ++ ++ /* Number of Secondary Device Types */ ++ p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */ ++ ++ /* Device Name */ ++ /* Type: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); ++ p2pielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ p2pielen += pwdinfo->device_name_len; ++ ++ /* Operating Channel */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */ ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static void issue_p2p_GO_response(struct adapter *padapter, u8 *raddr, u8 *frame_body, uint len, u8 result) ++{ ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_GO_NEGO_RESP; ++ u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 }; ++ u8 p2pielen = 0; ++ uint wpsielen = 0; ++ u16 wps_devicepassword_id = 0x0000; ++ __be16 be_tmp; ++ uint wps_devicepassword_id_len = 0; ++ u16 len_channellist_attr = 0; ++ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ DBG_88E("[%s] In, result=%d\n", __func__, result); ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pwdinfo->negotiation_dialog_token = frame_body[7]; /* The Dialog Token of provisioning discovery request frame. */ ++ pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &pattrib->pktlen); ++ ++ /* Commented by Albert 20110328 */ ++ /* Try to get the device password ID from the WPS IE of group negotiation request frame */ ++ /* WiFi Direct test plan 5.1.15 */ ++ rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen); ++ rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8 *)&be_tmp, &wps_devicepassword_id_len); ++ wps_devicepassword_id = be16_to_cpu(be_tmp); ++ ++ memset(wpsie, 0x00, 255); ++ wpsielen = 0; ++ ++ /* WPS Section */ ++ wpsielen = 0; ++ /* WPS OUI */ ++ *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI); ++ wpsielen += 4; ++ ++ /* WPS version */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */ ++ ++ /* Device Password ID */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002); ++ wpsielen += 2; ++ ++ /* Value: */ ++ if (wps_devicepassword_id == WPS_DPID_USER_SPEC) ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC); ++ else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC) ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC); ++ else ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC); ++ wpsielen += 2; ++ ++ /* Commented by Kurt 20120113 */ ++ /* If some device wants to do p2p handshake without sending prov_disc_req */ ++ /* We have to get peer_req_cm from here. */ ++ if (!memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) { ++ if (wps_devicepassword_id == WPS_DPID_USER_SPEC) ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3); ++ else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC) ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3); ++ else ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3); ++ } ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen); ++ ++ /* P2P IE Section. */ ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20100908 */ ++ /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */ ++ /* 1. Status */ ++ /* 2. P2P Capability */ ++ /* 3. Group Owner Intent */ ++ /* 4. Configuration Timeout */ ++ /* 5. Operating Channel */ ++ /* 6. Intended P2P Interface Address */ ++ /* 7. Channel List */ ++ /* 8. Device Info */ ++ /* 9. Group ID (Only GO) */ ++ ++ /* ToDo: */ ++ ++ /* P2P Status */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_STATUS; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001); ++ p2pielen += 2; ++ ++ /* Value: */ ++ p2pie[p2pielen++] = result; ++ ++ /* P2P Capability */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CAPABILITY; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) { ++ /* Commented by Albert 2011/03/08 */ ++ /* According to the P2P specification */ ++ /* if the sending device will be client, the P2P Capability should be reserved of group negotiation response frame */ ++ p2pie[p2pielen++] = 0; ++ } else { ++ /* Be group owner or meet the error case */ ++ p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT; ++ } ++ ++ /* Group Capability Bitmap, 1 byte */ ++ if (pwdinfo->persistent_supported) { ++ p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP; ++ } else { ++ p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN; ++ } ++ ++ /* Group Owner Intent */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GO_INTENT; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001); ++ p2pielen += 2; ++ ++ /* Value: */ ++ if (pwdinfo->peer_intent & 0x01) { ++ /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */ ++ p2pie[p2pielen++] = (pwdinfo->intent << 1); ++ } else { ++ /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */ ++ p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0)); ++ } ++ ++ /* Configuration Timeout */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */ ++ ++ /* Operating Channel */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */ ++ ++ /* Intended P2P Interface Address */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Channel List */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CH_LIST; ++ ++ /* Country String(3) */ ++ /* + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */ ++ /* + number of channels in all classes */ ++ len_channellist_attr = 3 ++ + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes ++ + get_reg_classes_full_count(&pmlmeext->channel_list); ++ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr); ++ ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Channel Entry List */ ++ ++ { ++ int i, j; ++ for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) { ++ /* Operating Class */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class; ++ ++ /* Number of Channels */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels; ++ ++ /* Channel List */ ++ for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) { ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i]; ++ } ++ } ++ } ++ ++ /* Device Info */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO; ++ ++ /* Length: */ ++ /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */ ++ /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address */ ++ memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Config Method */ ++ /* This field should be big endian. Noted by P2P specification. */ ++ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm); ++ ++ p2pielen += 2; ++ ++ /* Primary Device Type */ ++ /* Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); ++ p2pielen += 2; ++ ++ /* OUI */ ++ *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI); ++ p2pielen += 4; ++ ++ /* Sub Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); ++ p2pielen += 2; ++ ++ /* Number of Secondary Device Types */ ++ p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */ ++ ++ /* Device Name */ ++ /* Type: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); ++ p2pielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ p2pielen += pwdinfo->device_name_len; ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ /* Group ID Attribute */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GROUP_ID; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* p2P Device Address */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* SSID */ ++ memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen); ++ p2pielen += pwdinfo->nego_ssidlen; ++ } ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static void issue_p2p_GO_confirm(struct adapter *padapter, u8 *raddr, u8 result) ++{ ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_GO_NEGO_CONF; ++ u8 p2pie[255] = { 0x00 }; ++ u8 p2pielen = 0; ++ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ DBG_88E("[%s] In\n", __func__); ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &pattrib->pktlen); ++ ++ /* P2P IE Section. */ ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20110306 */ ++ /* According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes */ ++ /* 1. Status */ ++ /* 2. P2P Capability */ ++ /* 3. Operating Channel */ ++ /* 4. Channel List */ ++ /* 5. Group ID (if this WiFi is GO) */ ++ ++ /* P2P Status */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_STATUS; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001); ++ p2pielen += 2; ++ ++ /* Value: */ ++ p2pie[p2pielen++] = result; ++ ++ /* P2P Capability */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CAPABILITY; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT; ++ ++ /* Group Capability Bitmap, 1 byte */ ++ if (pwdinfo->persistent_supported) ++ p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP; ++ else ++ p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN; ++ ++ /* Operating Channel */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) { ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; ++ p2pie[p2pielen++] = pwdinfo->peer_operating_ch; ++ } else { ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->operating_channel; /* Use the listen channel as the operating channel */ ++ } ++ ++ /* Channel List */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CH_LIST; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(pwdinfo->channel_list_attr_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len); ++ p2pielen += pwdinfo->channel_list_attr_len; ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ /* Group ID Attribute */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GROUP_ID; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* p2P Device Address */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* SSID */ ++ memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen); ++ p2pielen += pwdinfo->nego_ssidlen; ++ } ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen); ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++void issue_p2p_invitation_request(struct adapter *padapter, u8 *raddr) ++{ ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_INVIT_REQ; ++ u8 p2pie[255] = { 0x00 }; ++ u8 p2pielen = 0; ++ u8 dialogToken = 3; ++ u16 len_channellist_attr = 0; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, raddr, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen); ++ ++ /* P2P IE Section. */ ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20101011 */ ++ /* According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes */ ++ /* 1. Configuration Timeout */ ++ /* 2. Invitation Flags */ ++ /* 3. Operating Channel (Only GO) */ ++ /* 4. P2P Group BSSID (Should be included if I am the GO) */ ++ /* 5. Channel List */ ++ /* 6. P2P Group ID */ ++ /* 7. P2P Device Info */ ++ ++ /* Configuration Timeout */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */ ++ ++ /* Invitation Flags */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_INVITATION_FLAGS; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001); ++ p2pielen += 2; ++ ++ /* Value: */ ++ p2pie[p2pielen++] = P2P_INVITATION_FLAGS_PERSISTENT; ++ ++ /* Operating Channel */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->invitereq_info.operating_ch; /* operating channel number */ ++ ++ if (!memcmp(myid(&padapter->eeprompriv), pwdinfo->invitereq_info.go_bssid, ETH_ALEN)) { ++ /* P2P Group BSSID */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address for GO */ ++ memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ } ++ ++ /* Channel List */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CH_LIST; ++ ++ /* Length: */ ++ /* Country String(3) */ ++ /* + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */ ++ /* + number of channels in all classes */ ++ len_channellist_attr = 3 ++ + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes ++ + get_reg_classes_full_count(&pmlmeext->channel_list); ++ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr); ++ ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Channel Entry List */ ++ { ++ int i, j; ++ for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) { ++ /* Operating Class */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class; ++ ++ /* Number of Channels */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels; ++ ++ /* Channel List */ ++ for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) { ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i]; ++ } ++ } ++ } ++ ++ /* P2P Group ID */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GROUP_ID; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(6 + pwdinfo->invitereq_info.ssidlen); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address for GO */ ++ memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* SSID */ ++ memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen); ++ p2pielen += pwdinfo->invitereq_info.ssidlen; ++ ++ /* Device Info */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO; ++ ++ /* Length: */ ++ /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */ ++ /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address */ ++ memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Config Method */ ++ /* This field should be big endian. Noted by P2P specification. */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY); ++ p2pielen += 2; ++ ++ /* Primary Device Type */ ++ /* Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); ++ p2pielen += 2; ++ ++ /* OUI */ ++ *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI); ++ p2pielen += 4; ++ ++ /* Sub Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); ++ p2pielen += 2; ++ ++ /* Number of Secondary Device Types */ ++ p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */ ++ ++ /* Device Name */ ++ /* Type: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); ++ p2pielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ p2pielen += pwdinfo->device_name_len; ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++void issue_p2p_invitation_response(struct adapter *padapter, u8 *raddr, u8 dialogToken, u8 status_code) ++{ ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_INVIT_RESP; ++ u8 p2pie[255] = { 0x00 }; ++ u8 p2pielen = 0; ++ u16 len_channellist_attr = 0; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, raddr, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen); ++ ++ /* P2P IE Section. */ ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20101005 */ ++ /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */ ++ /* 1. Status */ ++ /* 2. Configuration Timeout */ ++ /* 3. Operating Channel (Only GO) */ ++ /* 4. P2P Group BSSID (Only GO) */ ++ /* 5. Channel List */ ++ ++ /* P2P Status */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_STATUS; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. */ ++ /* Sent the event receiving the P2P Invitation Req frame to DMP UI. */ ++ /* DMP had to compare the MAC address to find out the profile. */ ++ /* So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. */ ++ /* If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req */ ++ /* to NB to rebuild the persistent group. */ ++ p2pie[p2pielen++] = status_code; ++ ++ /* Configuration Timeout */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */ ++ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */ ++ ++ if (status_code == P2P_STATUS_SUCCESS) { ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */ ++ /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */ ++ /* First one is operating channel attribute. */ ++ /* Second one is P2P Group BSSID attribute. */ ++ ++ /* Operating Channel */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; /* Copy from SD7 */ ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */ ++ ++ /* P2P Group BSSID */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address for GO */ ++ memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ } ++ ++ /* Channel List */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CH_LIST; ++ ++ /* Length: */ ++ /* Country String(3) */ ++ /* + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */ ++ /* + number of channels in all classes */ ++ len_channellist_attr = 3 ++ + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes ++ + get_reg_classes_full_count(&pmlmeext->channel_list); ++ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Channel Entry List */ ++ { ++ int i, j; ++ for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) { ++ /* Operating Class */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class; ++ ++ /* Number of Channels */ ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels; ++ ++ /* Channel List */ ++ for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) { ++ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i]; ++ } ++ } ++ } ++ } ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++void issue_p2p_provision_request(struct adapter *padapter, u8 *pssid, u8 ussidlen, u8 *pdev_raddr) ++{ ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ u8 dialogToken = 1; ++ u8 oui_subtype = P2P_PROVISION_DISC_REQ; ++ u8 wpsie[100] = { 0x00 }; ++ u8 wpsielen = 0; ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u32 p2pielen = 0; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ DBG_88E("[%s] In\n", __func__); ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen); ++ ++ p2pielen = build_prov_disc_request_p2p_ie(pwdinfo, pframe, pssid, ussidlen, pdev_raddr); ++ ++ pframe += p2pielen; ++ pattrib->pktlen += p2pielen; ++ ++ wpsielen = 0; ++ /* WPS OUI */ ++ *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI); ++ wpsielen += 4; ++ ++ /* WPS version */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */ ++ ++ /* Config Method */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002); ++ wpsielen += 2; ++ ++ /* Value: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request); ++ wpsielen += 2; ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static u8 is_matched_in_profilelist(u8 *peermacaddr, struct profile_info *profileinfo) ++{ ++ u8 i, match_result = 0; ++ ++ DBG_88E("[%s] peermac=%.2X %.2X %.2X %.2X %.2X %.2X\n", __func__, ++ peermacaddr[0], peermacaddr[1], peermacaddr[2], peermacaddr[3], peermacaddr[4], peermacaddr[5]); ++ ++ for (i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++) { ++ DBG_88E("[%s] profileinfo_mac=%.2X %.2X %.2X %.2X %.2X %.2X\n", __func__, ++ profileinfo->peermac[0], profileinfo->peermac[1], profileinfo->peermac[2], ++ profileinfo->peermac[3], profileinfo->peermac[4], profileinfo->peermac[5]); ++ if (!memcmp(peermacaddr, profileinfo->peermac, ETH_ALEN)) { ++ match_result = 1; ++ DBG_88E("[%s] Match!\n", __func__); ++ break; ++ } ++ } ++ return match_result; ++} ++ ++void issue_probersp_p2p(struct adapter *padapter, unsigned char *da) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ unsigned char *mac; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ u16 beacon_interval = 100; ++ u16 capInfo = 0; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 wpsie[255] = { 0x00 }; ++ u32 wpsielen = 0, p2pielen = 0; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ mac = myid(&padapter->eeprompriv); ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, mac, ETH_ALEN); ++ ++ /* Use the device address for BSSID field. */ ++ memcpy(pwlanhdr->addr3, mac, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(fctrl, WIFI_PROBERSP); ++ ++ pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = pattrib->hdrlen; ++ pframe += pattrib->hdrlen; ++ ++ /* timestamp will be inserted by hardware */ ++ pframe += 8; ++ pattrib->pktlen += 8; ++ ++ /* beacon interval: 2 bytes */ ++ memcpy(pframe, (unsigned char *)&beacon_interval, 2); ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* capability info: 2 bytes */ ++ /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */ ++ capInfo |= cap_ShortPremble; ++ capInfo |= cap_ShortSlot; ++ ++ memcpy(pframe, (unsigned char *)&capInfo, 2); ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* SSID */ ++ pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen); ++ ++ /* supported rates... */ ++ /* Use the OFDM rate in the P2P probe response frame. (6(B), 9(B), 12, 18, 24, 36, 48, 54) */ ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen); ++ ++ /* DS parameter set */ ++ pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen); ++ ++ /* Todo: WPS IE */ ++ /* Noted by Albert 20100907 */ ++ /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */ ++ ++ wpsielen = 0; ++ /* WPS OUI */ ++ *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI); ++ wpsielen += 4; ++ ++ /* WPS version */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */ ++ ++ /* WiFi Simple Config State */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */ ++ ++ /* Response Type */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X; ++ ++ /* UUID-E */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010); ++ wpsielen += 2; ++ ++ /* Value: */ ++ memcpy(wpsie + wpsielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ wpsielen += 0x10; ++ ++ /* Manufacturer */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007); ++ wpsielen += 2; ++ ++ /* Value: */ ++ memcpy(wpsie + wpsielen, "Realtek", 7); ++ wpsielen += 7; ++ ++ /* Model Name */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006); ++ wpsielen += 2; ++ ++ /* Value: */ ++ memcpy(wpsie + wpsielen, "8188EU", 6); ++ wpsielen += 6; ++ ++ /* Model Number */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = 0x31; /* character 1 */ ++ ++ /* Serial Number */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN); ++ wpsielen += 2; ++ ++ /* Value: */ ++ memcpy(wpsie + wpsielen, "123456", ETH_ALEN); ++ wpsielen += ETH_ALEN; ++ ++ /* Primary Device Type */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008); ++ wpsielen += 2; ++ ++ /* Value: */ ++ /* Category ID */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); ++ wpsielen += 2; ++ ++ /* OUI */ ++ *(__be32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI); ++ wpsielen += 4; ++ ++ /* Sub Category ID */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); ++ wpsielen += 2; ++ ++ /* Device Name */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len); ++ wpsielen += 2; ++ ++ /* Value: */ ++ if (pwdinfo->device_name_len) { ++ memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ wpsielen += pwdinfo->device_name_len; ++ } ++ ++ /* Config Method */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002); ++ wpsielen += 2; ++ ++ /* Value: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm); ++ wpsielen += 2; ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen); ++ ++ p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe); ++ pframe += p2pielen; ++ pattrib->pktlen += p2pielen; ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static int _issue_probereq_p2p(struct adapter *padapter, u8 *da, int wait_ack) ++{ ++ int ret = _FAIL; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ unsigned char *mac; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 }; ++ u16 wpsielen = 0, p2pielen = 0; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ goto exit; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ mac = myid(&padapter->eeprompriv); ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ if (da) { ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, da, ETH_ALEN); ++ } else { ++ if ((pwdinfo->p2p_info.scan_op_ch_only) || (pwdinfo->rx_invitereq_info.scan_op_ch_only)) { ++ /* This two flags will be set when this is only the P2P client mode. */ ++ memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN); ++ } else { ++ /* broadcast probe request frame */ ++ memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN); ++ } ++ } ++ memcpy(pwlanhdr->addr2, mac, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_PROBEREQ); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) ++ pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &pattrib->pktlen); ++ else ++ pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen); ++ ++ /* Use the OFDM rate in the P2P probe request frame. (6(B), 9(B), 12(B), 24(B), 36, 48, 54) */ ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen); ++ ++ /* WPS IE */ ++ /* Noted by Albert 20110221 */ ++ /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */ ++ ++ wpsielen = 0; ++ /* WPS OUI */ ++ *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI); ++ wpsielen += 4; ++ ++ /* WPS version */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001); ++ wpsielen += 2; ++ ++ /* Value: */ ++ wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */ ++ ++ if (!pmlmepriv->wps_probe_req_ie) { ++ /* UUID-E */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010); ++ wpsielen += 2; ++ ++ /* Value: */ ++ memcpy(wpsie + wpsielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ wpsielen += 0x10; ++ ++ /* Config Method */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002); ++ wpsielen += 2; ++ ++ /* Value: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm); ++ wpsielen += 2; ++ } ++ ++ /* Device Name */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len); ++ wpsielen += 2; ++ ++ /* Value: */ ++ memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ wpsielen += pwdinfo->device_name_len; ++ ++ /* Primary Device Type */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008); ++ wpsielen += 2; ++ ++ /* Value: */ ++ /* Category ID */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_RTK_WIDI); ++ wpsielen += 2; ++ ++ /* OUI */ ++ *(__be32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI); ++ wpsielen += 4; ++ ++ /* Sub Category ID */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_RTK_DMP); ++ wpsielen += 2; ++ ++ /* Device Password ID */ ++ /* Type: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID); ++ wpsielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002); ++ wpsielen += 2; ++ ++ /* Value: */ ++ *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC); /* Registrar-specified */ ++ wpsielen += 2; ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen); ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20110221 */ ++ /* According to the P2P Specification, the probe request frame should contain 5 P2P attributes */ ++ /* 1. P2P Capability */ ++ /* 2. P2P Device ID if this probe request wants to find the specific P2P device */ ++ /* 3. Listen Channel */ ++ /* 4. Extended Listen Timing */ ++ /* 5. Operating Channel if this WiFi is working as the group owner now */ ++ ++ /* P2P Capability */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CAPABILITY; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT; ++ ++ /* Group Capability Bitmap, 1 byte */ ++ if (pwdinfo->persistent_supported) ++ p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; ++ else ++ p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT; ++ ++ /* Listen Channel */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; /* Copy from SD7 */ ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->listen_channel; /* listen channel */ ++ ++ /* Extended Listen Timing */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Availability Period */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF); ++ p2pielen += 2; ++ ++ /* Availability Interval */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF); ++ p2pielen += 2; ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ /* Operating Channel (if this WiFi is working as the group owner now) */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Country String */ ++ p2pie[p2pielen++] = 'X'; ++ p2pie[p2pielen++] = 'X'; ++ ++ /* The third byte should be set to 0x04. */ ++ /* Described in the "Operating Channel Attribute" section. */ ++ p2pie[p2pielen++] = 0x04; ++ ++ /* Operating Class */ ++ p2pie[p2pielen++] = 0x51; /* Copy from SD7 */ ++ ++ /* Channel Number */ ++ p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */ ++ } ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen); ++ ++ if (pmlmepriv->wps_probe_req_ie) { ++ /* WPS IE */ ++ memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len); ++ pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len; ++ pframe += pmlmepriv->wps_probe_req_ie_len; ++ } ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ if (wait_ack) { ++ ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); ++ } else { ++ dump_mgntframe(padapter, pmgntframe); ++ ret = _SUCCESS; ++ } ++ ++exit: ++ return ret; ++} ++ ++inline void issue_probereq_p2p(struct adapter *adapter, u8 *da) ++{ ++ _issue_probereq_p2p(adapter, da, false); ++} ++ ++int issue_probereq_p2p_ex(struct adapter *adapter, u8 *da, int try_cnt, int wait_ms) ++{ ++ int ret; ++ int i = 0; ++ u32 start = jiffies; ++ ++ do { ++ ret = _issue_probereq_p2p(adapter, da, wait_ms > 0); ++ ++ i++; ++ ++ if (adapter->bDriverStopped || adapter->bSurpriseRemoved) ++ break; ++ ++ if (i < try_cnt && wait_ms > 0 && ret == _FAIL) ++ msleep(wait_ms); ++ } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); ++ ++ if (ret != _FAIL) { ++ ret = _SUCCESS; ++ goto exit; ++ } ++ ++ if (try_cnt && wait_ms) { ++ if (da) ++ DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(adapter), da, rtw_get_oper_ch(adapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ else ++ DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ } ++exit: ++ return ret; ++} ++ ++#endif /* CONFIG_88EU_P2P */ ++ ++static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token) ++{ ++ struct adapter *adapter = recv_frame->adapter; ++ struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; ++ u8 *frame = recv_frame->rx_data; ++ u16 seq_ctrl = ((recv_frame->attrib.seq_num & 0xffff) << 4) | ++ (recv_frame->attrib.frag_num & 0xf); ++ ++ if (GetRetry(frame)) { ++ if (token >= 0) { ++ if ((seq_ctrl == mlmeext->action_public_rxseq) && (token == mlmeext->action_public_dialog_token)) { ++ DBG_88E(FUNC_ADPT_FMT" seq_ctrl = 0x%x, rxseq = 0x%x, token:%d\n", ++ FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token); ++ return _FAIL; ++ } ++ } else { ++ if (seq_ctrl == mlmeext->action_public_rxseq) { ++ DBG_88E(FUNC_ADPT_FMT" seq_ctrl = 0x%x, rxseq = 0x%x\n", ++ FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq); ++ return _FAIL; ++ } ++ } ++ } ++ ++ mlmeext->action_public_rxseq = seq_ctrl; ++ ++ if (token >= 0) ++ mlmeext->action_public_dialog_token = token; ++ ++ return _SUCCESS; ++} ++ ++static unsigned int on_action_public_p2p(struct recv_frame *precv_frame) ++{ ++ u8 *pframe = precv_frame->rx_data; ++ u8 *frame_body; ++ u8 dialogToken = 0; ++#ifdef CONFIG_88EU_P2P ++ struct adapter *padapter = precv_frame->adapter; ++ uint len = precv_frame->len; ++ u8 *p2p_ie; ++ u32 p2p_ielen; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 result = P2P_STATUS_SUCCESS; ++ u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++#endif /* CONFIG_88EU_P2P */ ++ ++ frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ dialogToken = frame_body[7]; ++ ++ if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL) ++ return _FAIL; ++ ++#ifdef CONFIG_88EU_P2P ++ _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey); ++ /* Do nothing if the driver doesn't enable the P2P function. */ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) ++ return _SUCCESS; ++ ++ len -= sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ switch (frame_body[6]) { /* OUI Subtype */ ++ case P2P_GO_NEGO_REQ: ++ DBG_88E("[%s] Got GO Nego Req Frame\n", __func__); ++ memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info)); ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ)) ++ rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) { ++ /* Commented by Albert 20110526 */ ++ /* In this case, this means the previous nego fail doesn't be reset yet. */ ++ _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); ++ /* Restore the previous p2p state */ ++ rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); ++ DBG_88E("[%s] Restore the previous p2p state to %d\n", __func__, rtw_p2p_state(pwdinfo)); ++ } ++ ++ /* Commented by Kurt 20110902 */ ++ /* Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) ++ rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); ++ ++ /* Commented by Kurt 20120113 */ ++ /* Get peer_dev_addr here if peer doesn't issue prov_disc frame. */ ++ if (!memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN)) ++ memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN); ++ ++ result = process_p2p_group_negotation_req(pwdinfo, frame_body, len); ++ issue_p2p_GO_response(padapter, GetAddr2Ptr(pframe), frame_body, len, result); ++ ++ /* Commented by Albert 20110718 */ ++ /* No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. */ ++ _set_timer(&pwdinfo->restore_p2p_state_timer, 5000); ++ break; ++ case P2P_GO_NEGO_RESP: ++ DBG_88E("[%s] Got GO Nego Resp Frame\n", __func__); ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) { ++ /* Commented by Albert 20110425 */ ++ /* The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. */ ++ _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); ++ pwdinfo->nego_req_info.benable = false; ++ result = process_p2p_group_negotation_resp(pwdinfo, frame_body, len); ++ issue_p2p_GO_confirm(pwdinfo->padapter, GetAddr2Ptr(pframe), result); ++ if (P2P_STATUS_SUCCESS == result) { ++ if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) { ++ pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch; ++ pwdinfo->p2p_info.scan_op_ch_only = 1; ++ _set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH); ++ } ++ } ++ /* Reset the dialog token for group negotiation frames. */ ++ pwdinfo->negotiation_dialog_token = 1; ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) ++ _set_timer(&pwdinfo->restore_p2p_state_timer, 5000); ++ } else { ++ DBG_88E("[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __func__); ++ } ++ break; ++ case P2P_GO_NEGO_CONF: ++ DBG_88E("[%s] Got GO Nego Confirm Frame\n", __func__); ++ result = process_p2p_group_negotation_confirm(pwdinfo, frame_body, len); ++ if (P2P_STATUS_SUCCESS == result) { ++ if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) { ++ pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch; ++ pwdinfo->p2p_info.scan_op_ch_only = 1; ++ _set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH); ++ } ++ } ++ break; ++ case P2P_INVIT_REQ: ++ /* Added by Albert 2010/10/05 */ ++ /* Received the P2P Invite Request frame. */ ++ ++ DBG_88E("[%s] Got invite request frame!\n", __func__); ++ p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen); ++ if (p2p_ie) { ++ /* Parse the necessary information from the P2P Invitation Request frame. */ ++ /* For example: The MAC address of sending this P2P Invitation Request frame. */ ++ u32 attr_contentlen = 0; ++ u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; ++ struct group_id_info group_id; ++ u8 invitation_flag = 0; ++ ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen); ++ if (attr_contentlen) { ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen); ++ /* Commented by Albert 20120510 */ ++ /* Copy to the pwdinfo->p2p_peer_interface_addr. */ ++ /* So that the WFD UI (or Sigma) can get the peer interface address by using the following command. */ ++ /* #> iwpriv wlan0 p2p_get peer_ifa */ ++ /* After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. */ ++ ++ if (attr_contentlen) { ++ DBG_88E("[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __func__, ++ pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], ++ pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3], ++ pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]); ++ } ++ ++ if (invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT) { ++ /* Re-invoke the persistent group. */ ++ ++ memset(&group_id, 0x00, sizeof(struct group_id_info)); ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *)&group_id, &attr_contentlen); ++ if (attr_contentlen) { ++ if (!memcmp(group_id.go_device_addr, myid(&padapter->eeprompriv), ETH_ALEN)) { ++ /* The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. */ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ status_code = P2P_STATUS_SUCCESS; ++ } else { ++ /* The p2p device sending this p2p invitation request wants to be the persistent GO. */ ++ if (is_matched_in_profilelist(pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[0])) { ++ u8 operatingch_info[5] = { 0x00 }; ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) { ++ if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4])) { ++ /* The operating channel is acceptable for this device. */ ++ pwdinfo->rx_invitereq_info.operation_ch[0] = operatingch_info[4]; ++ pwdinfo->rx_invitereq_info.scan_op_ch_only = 1; ++ _set_timer(&pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ status_code = P2P_STATUS_SUCCESS; ++ } else { ++ /* The operating channel isn't supported by this device. */ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ status_code = P2P_STATUS_FAIL_NO_COMMON_CH; ++ _set_timer(&pwdinfo->restore_p2p_state_timer, 3000); ++ } ++ } else { ++ /* Commented by Albert 20121130 */ ++ /* Intel will use the different P2P IE to store the operating channel information */ ++ /* Workaround for Intel WiDi 3.5 */ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ status_code = P2P_STATUS_SUCCESS; ++ } ++ } else { ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH); ++ status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP; ++ } ++ } ++ } else { ++ DBG_88E("[%s] P2P Group ID Attribute NOT FOUND!\n", __func__); ++ status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; ++ } ++ } else { ++ /* Received the invitation to join a P2P group. */ ++ ++ memset(&group_id, 0x00, sizeof(struct group_id_info)); ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *)&group_id, &attr_contentlen); ++ if (attr_contentlen) { ++ if (!memcmp(group_id.go_device_addr, myid(&padapter->eeprompriv), ETH_ALEN)) { ++ /* In this case, the GO can't be myself. */ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH); ++ status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; ++ } else { ++ /* The p2p device sending this p2p invitation request wants to join an existing P2P group */ ++ /* Commented by Albert 2012/06/28 */ ++ /* In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. */ ++ /* The peer device address should be the destination address for the provisioning discovery request. */ ++ /* Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. */ ++ /* The peer interface address should be the address for WPS mac address */ ++ memcpy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr, ETH_ALEN); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN); ++ status_code = P2P_STATUS_SUCCESS; ++ } ++ } else { ++ DBG_88E("[%s] P2P Group ID Attribute NOT FOUND!\n", __func__); ++ status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; ++ } ++ } ++ } else { ++ DBG_88E("[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __func__); ++ status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; ++ } ++ ++ DBG_88E("[%s] status_code = %d\n", __func__, status_code); ++ ++ pwdinfo->inviteresp_info.token = frame_body[7]; ++ issue_p2p_invitation_response(padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code); ++ } ++ break; ++ case P2P_INVIT_RESP: { ++ u8 attr_content = 0x00; ++ u32 attr_contentlen = 0; ++ ++ DBG_88E("[%s] Got invite response frame!\n", __func__); ++ _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); ++ p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen); ++ if (p2p_ie) { ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen); ++ ++ if (attr_contentlen == 1) { ++ DBG_88E("[%s] Status = %d\n", __func__, attr_content); ++ pwdinfo->invitereq_info.benable = false; ++ ++ if (attr_content == P2P_STATUS_SUCCESS) { ++ if (!memcmp(pwdinfo->invitereq_info.go_bssid, myid(&padapter->eeprompriv), ETH_ALEN)) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ } else { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ } ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_OK); ++ } else { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL); ++ } ++ } else { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL); ++ } ++ } else { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL); ++ } ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL)) ++ _set_timer(&pwdinfo->restore_p2p_state_timer, 5000); ++ break; ++ } ++ case P2P_DEVDISC_REQ: ++ process_p2p_devdisc_req(pwdinfo, pframe, len); ++ break; ++ case P2P_DEVDISC_RESP: ++ process_p2p_devdisc_resp(pwdinfo, pframe, len); ++ break; ++ case P2P_PROVISION_DISC_REQ: ++ DBG_88E("[%s] Got Provisioning Discovery Request Frame\n", __func__); ++ process_p2p_provdisc_req(pwdinfo, pframe, len); ++ memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN); ++ ++ /* 20110902 Kurt */ ++ /* Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ)) ++ rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); ++ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ); ++ _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT); ++ break; ++ case P2P_PROVISION_DISC_RESP: ++ /* Commented by Albert 20110707 */ ++ /* Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? */ ++ DBG_88E("[%s] Got Provisioning Discovery Response Frame\n", __func__); ++ /* Commented by Albert 20110426 */ ++ /* The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. */ ++ _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP); ++ process_p2p_provdisc_resp(pwdinfo, pframe); ++ _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT); ++ break; ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ return _SUCCESS; ++} ++ ++static unsigned int on_action_public_vendor(struct recv_frame *precv_frame) ++{ ++ unsigned int ret = _FAIL; ++ u8 *pframe = precv_frame->rx_data; ++ u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ if (!memcmp(frame_body + 2, P2P_OUI, 4)) { ++ ret = on_action_public_p2p(precv_frame); ++ } ++ ++ return ret; ++} ++ ++static unsigned int on_action_public_default(struct recv_frame *precv_frame, u8 action) ++{ ++ unsigned int ret = _FAIL; ++ u8 *pframe = precv_frame->rx_data; ++ u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); ++ u8 token; ++ ++ token = frame_body[2]; ++ ++ if (rtw_action_public_decache(precv_frame, token) == _FAIL) ++ goto exit; ++ ++ ret = _SUCCESS; ++ ++exit: ++ return ret; ++} ++ ++unsigned int on_action_public(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ unsigned int ret = _FAIL; ++ u8 *pframe = precv_frame->rx_data; ++ u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); ++ u8 category, action; ++ ++ /* check RA matches or not */ ++ if (memcmp(myid(&padapter->eeprompriv), GetAddr1Ptr(pframe), ETH_ALEN)) ++ goto exit; ++ ++ category = frame_body[0]; ++ if (category != RTW_WLAN_CATEGORY_PUBLIC) ++ goto exit; ++ ++ action = frame_body[1]; ++ switch (action) { ++ case ACT_PUBLIC_VENDOR: ++ ret = on_action_public_vendor(precv_frame); ++ break; ++ default: ++ ret = on_action_public_default(precv_frame, action); ++ break; ++ } ++ ++exit: ++ return ret; ++} ++ ++unsigned int OnAction_ht(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ return _SUCCESS; ++} ++ ++unsigned int OnAction_wmm(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ return _SUCCESS; ++} ++ ++unsigned int OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++#ifdef CONFIG_88EU_P2P ++ u8 *frame_body; ++ u8 category, OUI_Subtype; ++ u8 *pframe = precv_frame->rx_data; ++ uint len = precv_frame->len; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("%s\n", __func__); ++ ++ /* check RA matches or not */ ++ if (memcmp(myid(&padapter->eeprompriv), GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */ ++ return _SUCCESS; ++ ++ frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ category = frame_body[0]; ++ if (category != RTW_WLAN_CATEGORY_P2P) ++ return _SUCCESS; ++ ++ if (be32_to_cpu(*((__be32 *)(frame_body + 1))) != P2POUI) ++ return _SUCCESS; ++ ++ len -= sizeof(struct rtw_ieee80211_hdr_3addr); ++ OUI_Subtype = frame_body[5]; ++ ++ switch (OUI_Subtype) { ++ case P2P_NOTICE_OF_ABSENCE: ++ break; ++ case P2P_PRESENCE_REQUEST: ++ process_p2p_presence_req(pwdinfo, pframe, len); ++ break; ++ case P2P_PRESENCE_RESPONSE: ++ break; ++ case P2P_GO_DISC_REQUEST: ++ break; ++ default: ++ break; ++ } ++#endif /* CONFIG_88EU_P2P */ ++ return _SUCCESS; ++} ++ ++unsigned int OnAction(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ int i; ++ unsigned char category; ++ struct action_handler *ptable; ++ unsigned char *frame_body; ++ u8 *pframe = precv_frame->rx_data; ++ ++ frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ category = frame_body[0]; ++ ++ for (i = 0; i < sizeof(OnAction_tbl) / sizeof(struct action_handler); i++) { ++ ptable = &OnAction_tbl[i]; ++ if (category == ptable->num) ++ ptable->func(padapter, precv_frame); ++ } ++ return _SUCCESS; ++} ++ ++unsigned int DoReserved(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ return _SUCCESS; ++} ++ ++struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv) ++{ ++ struct xmit_frame *pmgntframe; ++ struct xmit_buf *pxmitbuf; ++ ++ pmgntframe = rtw_alloc_xmitframe(pxmitpriv); ++ if (!pmgntframe) { ++ DBG_88E("%s, alloc xmitframe fail\n", __func__); ++ return NULL; ++ } ++ ++ pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv); ++ if (!pxmitbuf) { ++ DBG_88E("%s, alloc xmitbuf fail\n", __func__); ++ rtw_free_xmitframe(pxmitpriv, pmgntframe); ++ return NULL; ++ } ++ pmgntframe->frame_tag = MGNT_FRAMETAG; ++ pmgntframe->pxmitbuf = pxmitbuf; ++ pmgntframe->buf_addr = pxmitbuf->pbuf; ++ pxmitbuf->priv_data = pmgntframe; ++ return pmgntframe; ++} ++ ++/**************************************************************************** ++ ++Following are some TX fuctions for WiFi MLME ++ ++*****************************************************************************/ ++ ++void update_mgnt_tx_rate(struct adapter *padapter, u8 rate) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ pmlmeext->tx_rate = rate; ++ DBG_88E("%s(): rate = %x\n", __func__, rate); ++} ++ ++void update_mgntframe_attrib(struct adapter *padapter, struct pkt_attrib *pattrib) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib)); ++ ++ pattrib->hdrlen = 24; ++ pattrib->nr_frags = 1; ++ pattrib->priority = 7; ++ pattrib->mac_id = 0; ++ pattrib->qsel = 0x12; ++ ++ pattrib->pktlen = 0; ++ ++ if (pmlmeext->cur_wireless_mode & WIRELESS_11B) ++ pattrib->raid = 6;/* b mode */ ++ else ++ pattrib->raid = 5;/* a/g mode */ ++ ++ pattrib->encrypt = _NO_PRIVACY_; ++ pattrib->bswenc = false; ++ ++ pattrib->qos_en = false; ++ pattrib->ht_en = false; ++ pattrib->bwmode = HT_CHANNEL_WIDTH_20; ++ pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ pattrib->sgi = false; ++ ++ pattrib->seqnum = pmlmeext->mgnt_seq; ++ ++ pattrib->retry_ctrl = true; ++} ++ ++void dump_mgntframe(struct adapter *padapter, struct xmit_frame *pmgntframe) ++{ ++ if (padapter->bSurpriseRemoved || padapter->bDriverStopped) ++ return; ++ ++ rtw_hal_mgnt_xmit(padapter, pmgntframe); ++} ++ ++s32 dump_mgntframe_and_wait(struct adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms) ++{ ++ s32 ret = _FAIL; ++ struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf; ++ struct submit_ctx sctx; ++ ++ if (padapter->bSurpriseRemoved || padapter->bDriverStopped) ++ return ret; ++ ++ rtw_sctx_init(&sctx, timeout_ms); ++ pxmitbuf->sctx = &sctx; ++ ++ ret = rtw_hal_mgnt_xmit(padapter, pmgntframe); ++ ++ if (ret == _SUCCESS) ++ ret = rtw_sctx_wait(&sctx); ++ ++ return ret; ++} ++ ++s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmgntframe) ++{ ++ s32 ret = _FAIL; ++ u32 timeout_ms = 500;/* 500ms */ ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ if (padapter->bSurpriseRemoved || padapter->bDriverStopped) ++ return -1; ++ ++ _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL); ++ pxmitpriv->ack_tx = true; ++ ++ pmgntframe->ack_report = 1; ++ if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) { ++ ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms); ++ } ++ ++ pxmitpriv->ack_tx = false; ++ _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL); ++ ++ return ret; ++} ++ ++static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode) ++{ ++ u8 *ssid_ie; ++ int ssid_len_ori; ++ int len_diff = 0; ++ ++ ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len); ++ ++ if (ssid_ie && ssid_len_ori > 0) { ++ switch (hidden_ssid_mode) { ++ case 1: { ++ u8 *next_ie = ssid_ie + 2 + ssid_len_ori; ++ u32 remain_len = 0; ++ ++ remain_len = ies_len - (next_ie - ies); ++ ++ ssid_ie[1] = 0; ++ memcpy(ssid_ie + 2, next_ie, remain_len); ++ len_diff -= ssid_len_ori; ++ ++ break; ++ } ++ case 2: ++ memset(&ssid_ie[2], 0, ssid_len_ori); ++ break; ++ default: ++ break; ++ } ++ } ++ ++ return len_diff; ++} ++ ++void issue_beacon(struct adapter *padapter, int timeout_ms) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ unsigned int rate_len; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) { ++ DBG_88E("%s, alloc mgnt frame fail\n", __func__); ++ return; ++ } ++#if defined(CONFIG_88EU_AP_MODE) ++ spin_lock_bh(&pmlmepriv->bcn_update_lock); ++#endif /* if defined (CONFIG_88EU_AP_MODE) */ ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ pattrib->qsel = 0x10; ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); ++ /* pmlmeext->mgnt_seq++; */ ++ SetFrameSubType(pframe, WIFI_BEACON); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { ++#ifdef CONFIG_88EU_P2P ++ /* for P2P : Primary Device Type & Device Name */ ++ u32 wpsielen = 0, insert_len = 0; ++ u8 *wpsie = NULL; ++ wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen); ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) { ++ uint wps_offset, remainder_ielen; ++ u8 *premainder_ie, *pframe_wscie; ++ ++ wps_offset = (uint)(wpsie - cur_network->IEs); ++ premainder_ie = wpsie + wpsielen; ++ remainder_ielen = cur_network->IELength - wps_offset - wpsielen; ++ pframe_wscie = pframe + wps_offset; ++ memcpy(pframe, cur_network->IEs, wps_offset + wpsielen); ++ pframe += (wps_offset + wpsielen); ++ pattrib->pktlen += (wps_offset + wpsielen); ++ ++ /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */ ++ /* Primary Device Type */ ++ /* Type: */ ++ *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE); ++ insert_len += 2; ++ ++ /* Length: */ ++ *(__be16 *)(pframe + insert_len) = cpu_to_be16(0x0008); ++ insert_len += 2; ++ ++ /* Value: */ ++ /* Category ID */ ++ *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); ++ insert_len += 2; ++ ++ /* OUI */ ++ *(__be32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI); ++ insert_len += 4; ++ ++ /* Sub Category ID */ ++ *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); ++ insert_len += 2; ++ ++ /* Device Name */ ++ /* Type: */ ++ *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); ++ insert_len += 2; ++ ++ /* Length: */ ++ *(__be16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len); ++ insert_len += 2; ++ ++ /* Value: */ ++ memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len); ++ insert_len += pwdinfo->device_name_len; ++ ++ /* update wsc ie length */ ++ *(pframe_wscie + 1) = (wpsielen - 2) + insert_len; ++ ++ /* pframe move to end */ ++ pframe += insert_len; ++ pattrib->pktlen += insert_len; ++ ++ /* copy remainder_ie to pframe */ ++ memcpy(pframe, premainder_ie, remainder_ielen); ++ pframe += remainder_ielen; ++ pattrib->pktlen += remainder_ielen; ++ } else ++#endif /* CONFIG_88EU_P2P */ ++ { ++ int len_diff; ++ memcpy(pframe, cur_network->IEs, cur_network->IELength); ++ len_diff = update_hidden_ssid( ++ pframe + _BEACON_IE_OFFSET_ ++ , cur_network->IELength - _BEACON_IE_OFFSET_ ++ , pmlmeinfo->hidden_ssid_mode ++ ); ++ pframe += (cur_network->IELength + len_diff); ++ pattrib->pktlen += (cur_network->IELength + len_diff); ++ } ++ ++ { ++ u8 *wps_ie; ++ uint wps_ielen; ++ u8 sr = 0; ++ wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, ++ pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen); ++ if (wps_ie && wps_ielen > 0) ++ rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL); ++ if (sr != 0) ++ set_fwstate(pmlmepriv, WIFI_UNDER_WPS); ++ else ++ _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS); ++ } ++ ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ u32 len; ++ len = build_beacon_p2p_ie(pwdinfo, pframe); ++ ++ pframe += len; ++ pattrib->pktlen += len; ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ goto _issue_bcn; ++ } ++ ++ /* below for ad-hoc mode */ ++ ++ /* timestamp will be inserted by hardware */ ++ pframe += 8; ++ pattrib->pktlen += 8; ++ ++ /* beacon interval: 2 bytes */ ++ ++ memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); ++ ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* capability info: 2 bytes */ ++ ++ memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); ++ ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* SSID */ ++ pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen); ++ ++ /* supported rates... */ ++ rate_len = rtw_get_rateset_len(cur_network->SupportedRates); ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen); ++ ++ /* DS parameter set */ ++ pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&cur_network->Configuration.DSConfig, &pattrib->pktlen); ++ ++ { ++ u8 erpinfo = 0; ++ u32 ATIMWindow; ++ /* IBSS Parameter Set... */ ++ ATIMWindow = 0; ++ pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen); ++ ++ /* ERP IE */ ++ pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen); ++ } ++ ++ /* EXTERNDED SUPPORTED RATE */ ++ if (rate_len > 8) ++ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen); ++ /* todo:HT for adhoc */ ++_issue_bcn: ++ ++#if defined(CONFIG_88EU_AP_MODE) ++ pmlmepriv->update_bcn = false; ++ ++ spin_unlock_bh(&pmlmepriv->bcn_update_lock); ++#endif /* if defined (CONFIG_88EU_AP_MODE) */ ++ ++ if ((pattrib->pktlen + TXDESC_SIZE) > 512) { ++ DBG_88E("beacon frame too large\n"); ++ return; ++ } ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ /* DBG_88E("issue bcn_sz=%d\n", pattrib->last_txcmdsz); */ ++ if (timeout_ms > 0) ++ dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms); ++ else ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ unsigned char *mac, *bssid; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++#if defined(CONFIG_88EU_AP_MODE) ++ u8 *pwps_ie; ++ uint wps_ielen; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++#endif /* if defined (CONFIG_88EU_AP_MODE) */ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ unsigned int rate_len; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) { ++ DBG_88E("%s, alloc mgnt frame fail\n", __func__); ++ return; ++ } ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ mac = myid(&padapter->eeprompriv); ++ bssid = cur_network->MacAddress; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, mac, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, bssid, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(fctrl, WIFI_PROBERSP); ++ ++ pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = pattrib->hdrlen; ++ pframe += pattrib->hdrlen; ++ ++ if (cur_network->IELength > MAX_IE_SZ) ++ return; ++ ++#if defined(CONFIG_88EU_AP_MODE) ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { ++ pwps_ie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wps_ielen); ++ ++ /* inerset & update wps_probe_resp_ie */ ++ if (pmlmepriv->wps_probe_resp_ie && pwps_ie && wps_ielen > 0) { ++ uint wps_offset, remainder_ielen; ++ u8 *premainder_ie; ++ ++ wps_offset = (uint)(pwps_ie - cur_network->IEs); ++ ++ premainder_ie = pwps_ie + wps_ielen; ++ ++ remainder_ielen = cur_network->IELength - wps_offset - wps_ielen; ++ ++ memcpy(pframe, cur_network->IEs, wps_offset); ++ pframe += wps_offset; ++ pattrib->pktlen += wps_offset; ++ ++ wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];/* to get ie data len */ ++ if ((wps_offset + wps_ielen + 2) <= MAX_IE_SZ) { ++ memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen + 2); ++ pframe += wps_ielen + 2; ++ pattrib->pktlen += wps_ielen + 2; ++ } ++ ++ if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) { ++ memcpy(pframe, premainder_ie, remainder_ielen); ++ pframe += remainder_ielen; ++ pattrib->pktlen += remainder_ielen; ++ } ++ } else { ++ memcpy(pframe, cur_network->IEs, cur_network->IELength); ++ pframe += cur_network->IELength; ++ pattrib->pktlen += cur_network->IELength; ++ } ++ } else ++#endif ++ { ++ /* timestamp will be inserted by hardware */ ++ pframe += 8; ++ pattrib->pktlen += 8; ++ ++ /* beacon interval: 2 bytes */ ++ ++ memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); ++ ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* capability info: 2 bytes */ ++ ++ memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); ++ ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* below for ad-hoc mode */ ++ ++ /* SSID */ ++ pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen); ++ ++ /* supported rates... */ ++ rate_len = rtw_get_rateset_len(cur_network->SupportedRates); ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen); ++ ++ /* DS parameter set */ ++ pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&cur_network->Configuration.DSConfig, &pattrib->pktlen); ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { ++ u8 erpinfo = 0; ++ u32 ATIMWindow; ++ /* IBSS Parameter Set... */ ++ /* ATIMWindow = cur->Configuration.ATIMWindow; */ ++ ATIMWindow = 0; ++ pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen); ++ ++ /* ERP IE */ ++ pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen); ++ } ++ ++ /* EXTERNDED SUPPORTED RATE */ ++ if (rate_len > 8) ++ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen); ++ /* todo:HT for adhoc */ ++ } ++ ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && is_valid_p2p_probereq) { ++ u32 len; ++ len = build_probe_resp_p2p_ie(pwdinfo, pframe); ++ ++ pframe += len; ++ pattrib->pktlen += len; ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static int _issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, int wait_ack) ++{ ++ int ret = _FAIL; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ unsigned char *mac; ++ unsigned char bssrate[NumRates]; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ int bssrate_len = 0; ++ u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ goto exit; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ mac = myid(&padapter->eeprompriv); ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ if (da) { ++ /* unicast probe request frame */ ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, da, ETH_ALEN); ++ } else { ++ /* broadcast probe request frame */ ++ memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN); ++ } ++ ++ memcpy(pwlanhdr->addr2, mac, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_PROBEREQ); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ if (pssid) ++ pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &pattrib->pktlen); ++ else ++ pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pattrib->pktlen); ++ ++ get_rate_set(padapter, bssrate, &bssrate_len); ++ ++ if (bssrate_len > 8) { ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &pattrib->pktlen); ++ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, bssrate_len - 8, bssrate + 8, &pattrib->pktlen); ++ } else { ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &pattrib->pktlen); ++ } ++ ++ /* add wps_ie for wps2.0 */ ++ if (pmlmepriv->wps_probe_req_ie_len > 0 && pmlmepriv->wps_probe_req_ie) { ++ memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len); ++ pframe += pmlmepriv->wps_probe_req_ie_len; ++ pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len; ++ } ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ if (wait_ack) { ++ ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); ++ } else { ++ dump_mgntframe(padapter, pmgntframe); ++ ret = _SUCCESS; ++ } ++ ++exit: ++ return ret; ++} ++ ++inline void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da) ++{ ++ _issue_probereq(padapter, pssid, da, false); ++} ++ ++int issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, ++ int try_cnt, int wait_ms) ++{ ++ int ret; ++ int i = 0; ++ u32 start = jiffies; ++ ++ do { ++ ret = _issue_probereq(padapter, pssid, da, wait_ms > 0); ++ ++ i++; ++ ++ if (padapter->bDriverStopped || padapter->bSurpriseRemoved) ++ break; ++ ++ if (i < try_cnt && wait_ms > 0 && ret == _FAIL) ++ msleep(wait_ms); ++ ++ } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); ++ ++ if (ret != _FAIL) { ++ ret = _SUCCESS; ++ goto exit; ++ } ++ ++ if (try_cnt && wait_ms) { ++ if (da) ++ DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ else ++ DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ } ++exit: ++ return ret; ++} ++ ++/* if psta == NULL, indiate we are station(client) now... */ ++void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short status) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ unsigned int val32; ++ u16 val16; ++#ifdef CONFIG_88EU_AP_MODE ++ __le16 le_val16; ++#endif ++ int use_shared_key = 0; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_AUTH); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ if (psta) {/* for AP mode */ ++#ifdef CONFIG_88EU_AP_MODE ++ ++ memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN); ++ ++ /* setting auth algo number */ ++ val16 = (u16)psta->authalg; ++ ++ if (status != _STATS_SUCCESSFUL_) ++ val16 = 0; ++ ++ if (val16) { ++ le_val16 = cpu_to_le16(val16); ++ use_shared_key = 1; ++ } else { ++ le_val16 = 0; ++ } ++ ++ pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_val16, &pattrib->pktlen); ++ ++ /* setting auth seq number */ ++ val16 = (u16)psta->auth_seq; ++ le_val16 = cpu_to_le16(val16); ++ pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_val16, &pattrib->pktlen); ++ ++ /* setting status code... */ ++ val16 = status; ++ le_val16 = cpu_to_le16(val16); ++ pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_val16, &pattrib->pktlen); ++ ++ /* added challenging text... */ ++ if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) ++ pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &pattrib->pktlen); ++#endif ++ } else { ++ __le32 le_tmp32; ++ __le16 le_tmp16; ++ memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ /* setting auth algo number */ ++ val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0;/* 0:OPEN System, 1:Shared key */ ++ if (val16) ++ use_shared_key = 1; ++ ++ /* setting IV for auth seq #3 */ ++ if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) { ++ val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30)); ++ le_tmp32 = cpu_to_le32(val32); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&le_tmp32, &pattrib->pktlen); ++ ++ pattrib->iv_len = 4; ++ } ++ ++ le_tmp16 = cpu_to_le16(val16); ++ pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_tmp16, &pattrib->pktlen); ++ ++ /* setting auth seq number */ ++ val16 = pmlmeinfo->auth_seq; ++ le_tmp16 = cpu_to_le16(val16); ++ pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_tmp16, &pattrib->pktlen); ++ ++ /* setting status code... */ ++ le_tmp16 = cpu_to_le16(status); ++ pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_tmp16, &pattrib->pktlen); ++ ++ /* then checking to see if sending challenging text... */ ++ if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) { ++ pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &pattrib->pktlen); ++ ++ SetPrivacy(fctrl); ++ ++ pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pattrib->encrypt = _WEP40_; ++ ++ pattrib->icv_len = 4; ++ ++ pattrib->pktlen += pattrib->icv_len; ++ } ++ } ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ rtw_wep_encrypt(padapter, (u8 *)pmgntframe); ++ DBG_88E("%s\n", __func__); ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type) ++{ ++#ifdef CONFIG_88EU_AP_MODE ++ struct xmit_frame *pmgntframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ struct pkt_attrib *pattrib; ++ unsigned char *pbuf, *pframe; ++ unsigned short val; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; ++ u8 *ie = pnetwork->IEs; ++ __le16 lestatus, leval; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ DBG_88E("%s\n", __func__); ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN); ++ memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP)) ++ SetFrameSubType(pwlanhdr, pkt_type); ++ else ++ return; ++ ++ pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen += pattrib->hdrlen; ++ pframe += pattrib->hdrlen; ++ ++ /* capability */ ++ val = *(unsigned short *)rtw_get_capability_from_ie(ie); ++ ++ pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_, (unsigned char *)&val, &pattrib->pktlen); ++ ++ lestatus = cpu_to_le16(status); ++ pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&lestatus, &pattrib->pktlen); ++ ++ leval = cpu_to_le16(pstat->aid | BIT(14) | BIT(15)); ++ pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_, (unsigned char *)&leval, &pattrib->pktlen); ++ ++ if (pstat->bssratelen <= 8) { ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &pattrib->pktlen); ++ } else { ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &pattrib->pktlen); ++ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, pstat->bssratelen - 8, pstat->bssrateset + 8, &pattrib->pktlen); ++ } ++ ++ if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) { ++ uint ie_len = 0; ++ ++ /* FILL HT CAP INFO IE */ ++ pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); ++ if (pbuf && ie_len > 0) { ++ memcpy(pframe, pbuf, ie_len + 2); ++ pframe += (ie_len + 2); ++ pattrib->pktlen += (ie_len + 2); ++ } ++ ++ /* FILL HT ADD INFO IE */ ++ pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); ++ if (pbuf && ie_len > 0) { ++ memcpy(pframe, pbuf, ie_len + 2); ++ pframe += (ie_len + 2); ++ pattrib->pktlen += (ie_len + 2); ++ } ++ } ++ ++ /* FILL WMM IE */ ++ if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) { ++ uint ie_len = 0; ++ unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; ++ ++ for (pbuf = ie + _BEACON_IE_OFFSET_;; pbuf += (ie_len + 2)) { ++ pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))); ++ if (pbuf && !memcmp(pbuf + 2, WMM_PARA_IE, 6)) { ++ memcpy(pframe, pbuf, ie_len + 2); ++ pframe += (ie_len + 2); ++ pattrib->pktlen += (ie_len + 2); ++ break; ++ } ++ ++ if (!pbuf || ie_len == 0) ++ break; ++ } ++ } ++ ++ if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &pattrib->pktlen); ++ ++ /* add WPS IE ie for wps 2.0 */ ++ if (pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len > 0) { ++ memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len); ++ ++ pframe += pmlmepriv->wps_assoc_resp_ie_len; ++ pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len; ++ } ++ ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device)) { ++ u32 len; ++ ++ len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code); ++ ++ pframe += len; ++ pattrib->pktlen += len; ++ } ++#endif /* CONFIG_88EU_P2P */ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ dump_mgntframe(padapter, pmgntframe); ++#endif ++} ++ ++void issue_assocreq(struct adapter *padapter) ++{ ++ int ret = _FAIL; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe, *p; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ __le16 le_tmp; ++ unsigned int i, j, ie_len, index = 0; ++ unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates]; ++ struct ndis_802_11_var_ie *pIE; ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ int bssrate_len = 0, sta_bssrate_len = 0; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 p2pie[255] = { 0x00 }; ++ u16 p2pielen = 0; ++#endif /* CONFIG_88EU_P2P */ ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ goto exit; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ASSOCREQ); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ /* caps */ ++ ++ memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); ++ ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* listen interval */ ++ /* todo: listen interval for power saving */ ++ le_tmp = cpu_to_le16(3); ++ memcpy(pframe, (unsigned char *)&le_tmp, 2); ++ pframe += 2; ++ pattrib->pktlen += 2; ++ ++ /* SSID */ ++ pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &pattrib->pktlen); ++ ++ /* supported rate & extended supported rate */ ++ ++ /* Check if the AP's supported rates are also supported by STA. */ ++ get_rate_set(padapter, sta_bssrate, &sta_bssrate_len); ++ ++ if (pmlmeext->cur_channel == 14)/* for JAPAN, channel 14 can only uses B Mode(CCK) */ ++ sta_bssrate_len = 4; ++ ++ for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { ++ if (pmlmeinfo->network.SupportedRates[i] == 0) ++ break; ++ DBG_88E("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]); ++ } ++ ++ for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { ++ if (pmlmeinfo->network.SupportedRates[i] == 0) ++ break; ++ ++ /* Check if the AP's supported rates are also supported by STA. */ ++ for (j = 0; j < sta_bssrate_len; j++) { ++ /* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */ ++ if ((pmlmeinfo->network.SupportedRates[i] | IEEE80211_BASIC_RATE_MASK) ++ == (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) ++ break; ++ } ++ ++ if (j == sta_bssrate_len) { ++ /* the rate is not supported by STA */ ++ DBG_88E("%s(): the rate[%d]=%02X is not supported by STA!\n", __func__, i, pmlmeinfo->network.SupportedRates[i]); ++ } else { ++ /* the rate is supported by STA */ ++ bssrate[index++] = pmlmeinfo->network.SupportedRates[i]; ++ } ++ } ++ ++ bssrate_len = index; ++ DBG_88E("bssrate_len=%d\n", bssrate_len); ++ ++ if (bssrate_len == 0) { ++ rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); ++ rtw_free_xmitframe(pxmitpriv, pmgntframe); ++ goto exit; /* don't connect to AP if no joint supported rate */ ++ } ++ ++ if (bssrate_len > 8) { ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &pattrib->pktlen); ++ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, bssrate_len - 8, bssrate + 8, &pattrib->pktlen); ++ } else { ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &pattrib->pktlen); ++ } ++ ++ /* RSN */ ++ p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(struct ndis_802_11_fixed_ie)), _RSN_IE_2_, &ie_len, (pmlmeinfo->network.IELength - sizeof(struct ndis_802_11_fixed_ie))); ++ if (p) ++ pframe = rtw_set_ie(pframe, _RSN_IE_2_, ie_len, p + 2, &pattrib->pktlen); ++ ++ /* HT caps */ ++ if (padapter->mlmepriv.htpriv.ht_option) { ++ p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(struct ndis_802_11_fixed_ie)), _HT_CAPABILITY_IE_, &ie_len, (pmlmeinfo->network.IELength - sizeof(struct ndis_802_11_fixed_ie))); ++ if (p && !is_ap_in_tkip(padapter)) { ++ memcpy(&pmlmeinfo->HT_caps, p + 2, sizeof(struct HT_caps_element)); ++ ++ /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */ ++ if (pregpriv->cbw40_enable == 0) ++ pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= cpu_to_le16(~(BIT(6) | BIT(1))); ++ else ++ pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(BIT(1)); ++ ++ /* todo: disable SM power save mode */ ++ pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x000c); ++ ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ switch (rf_type) { ++ case RF_1T1R: ++ if (pregpriv->rx_stbc) ++ pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);/* RX STBC One spatial stream */ ++ memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16); ++ break; ++ case RF_2T2R: ++ case RF_1T2R: ++ default: ++ if ((pregpriv->rx_stbc == 0x3) ||/* enable for 2.4/5 GHz */ ++ ((pmlmeext->cur_wireless_mode & WIRELESS_11_24N) && (pregpriv->rx_stbc == 0x1)) || /* enable for 2.4GHz */ ++ (pregpriv->wifi_spec == 1)) { ++ DBG_88E("declare supporting RX STBC\n"); ++ pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);/* RX STBC two spatial stream */ ++ } ++ memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16); ++ break; ++ } ++ pframe = rtw_set_ie(pframe, _HT_CAPABILITY_IE_, ie_len, (u8 *)(&pmlmeinfo->HT_caps), &pattrib->pktlen); ++ } ++ } ++ ++ /* vendor specific IE, such as WPA, WMM, WPS */ ++ for (i = sizeof(struct ndis_802_11_fixed_ie); i < pmlmeinfo->network.IELength;) { ++ pIE = (struct ndis_802_11_var_ie *)(pmlmeinfo->network.IEs + i); ++ ++ switch (pIE->ElementID) { ++ case _VENDOR_SPECIFIC_IE_: ++ if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) || ++ (!memcmp(pIE->data, WMM_OUI, 4)) || ++ (!memcmp(pIE->data, WPS_OUI, 4))) { ++ if (!padapter->registrypriv.wifi_spec) { ++ /* Commented by Kurt 20110629 */ ++ /* In some older APs, WPS handshake */ ++ /* would be fail if we append vender extensions informations to AP */ ++ if (!memcmp(pIE->data, WPS_OUI, 4)) ++ pIE->Length = 14; ++ } ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, pIE->Length, pIE->data, &pattrib->pktlen); ++ } ++ break; ++ default: ++ break; ++ } ++ i += (pIE->Length + 2); ++ } ++ ++ if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &pattrib->pktlen); ++ ++#ifdef CONFIG_88EU_P2P ++ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) { ++ /* Should add the P2P IE in the association request frame. */ ++ /* P2P OUI */ ++ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20101109 */ ++ /* According to the P2P Specification, the association request frame should contain 3 P2P attributes */ ++ /* 1. P2P Capability */ ++ /* 2. Extended Listen Timing */ ++ /* 3. Device Info */ ++ /* Commented by Albert 20110516 */ ++ /* 4. P2P Interface */ ++ ++ /* P2P Capability */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CAPABILITY; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT; ++ ++ /* Group Capability Bitmap, 1 byte */ ++ if (pwdinfo->persistent_supported) ++ p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; ++ else ++ p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT; ++ ++ /* Extended Listen Timing */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Availability Period */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF); ++ p2pielen += 2; ++ ++ /* Availability Interval */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF); ++ p2pielen += 2; ++ ++ /* Device Info */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO; ++ ++ /* Length: */ ++ /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */ ++ /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address */ ++ memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Config Method */ ++ /* This field should be big endian. Noted by P2P specification. */ ++ if ((pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN) || ++ (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN)) ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY); ++ else ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_PBC); ++ ++ p2pielen += 2; ++ ++ /* Primary Device Type */ ++ /* Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); ++ p2pielen += 2; ++ ++ /* OUI */ ++ *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI); ++ p2pielen += 4; ++ ++ /* Sub Category ID */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); ++ p2pielen += 2; ++ ++ /* Number of Secondary Device Types */ ++ p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */ ++ ++ /* Device Name */ ++ /* Type: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); ++ p2pielen += 2; ++ ++ /* Length: */ ++ *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ p2pielen += pwdinfo->device_name_len; ++ ++ /* P2P Interface */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_INTERFACE; ++ ++ /* Length: */ ++ *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x000D); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); /* P2P Device Address */ ++ p2pielen += ETH_ALEN; ++ ++ p2pie[p2pielen++] = 1; /* P2P Interface Address Count */ ++ ++ memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); /* P2P Interface Address List */ ++ p2pielen += ETH_ALEN; ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen); ++ } ++ ++#endif /* CONFIG_88EU_P2P */ ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ dump_mgntframe(padapter, pmgntframe); ++ ++ ret = _SUCCESS; ++ ++exit: ++ if (ret == _SUCCESS) ++ rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen); ++ else ++ kfree(pmlmepriv->assoc_req); ++} ++ ++/* when wait_ack is ture, this function shoule be called at process context */ ++static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack) ++{ ++ int ret = _FAIL; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv; ++ struct mlme_ext_priv *pmlmeext; ++ struct mlme_ext_info *pmlmeinfo; ++ ++ if (!padapter) ++ goto exit; ++ ++ pxmitpriv = &padapter->xmitpriv; ++ pmlmeext = &padapter->mlmeextpriv; ++ pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ goto exit; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ pattrib->retry_ctrl = false; ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) ++ SetFrDs(fctrl); ++ else if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) ++ SetToDs(fctrl); ++ ++ if (power_mode) ++ SetPwrMgt(fctrl); ++ ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_DATA_NULL); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ if (wait_ack) { ++ ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); ++ } else { ++ dump_mgntframe(padapter, pmgntframe); ++ ret = _SUCCESS; ++ } ++ ++exit: ++ return ret; ++} ++ ++/* when wait_ms > 0 , this function shoule be called at process context */ ++/* da == NULL for station mode */ ++int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms) ++{ ++ int ret; ++ int i = 0; ++ u32 start = jiffies; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ /* da == NULL, assum it's null data for sta to ap*/ ++ if (!da) ++ da = get_my_bssid(&pmlmeinfo->network); ++ ++ do { ++ ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0); ++ ++ i++; ++ ++ if (padapter->bDriverStopped || padapter->bSurpriseRemoved) ++ break; ++ ++ if (i < try_cnt && wait_ms > 0 && ret == _FAIL) ++ msleep(wait_ms); ++ } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); ++ ++ if (ret != _FAIL) { ++ ret = _SUCCESS; ++ goto exit; ++ } ++ ++ if (try_cnt && wait_ms) { ++ if (da) ++ DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ else ++ DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ } ++exit: ++ return ret; ++} ++ ++/* when wait_ack is ture, this function shoule be called at process context */ ++static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int wait_ack) ++{ ++ int ret = _FAIL; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ unsigned short *qc; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ DBG_88E("%s\n", __func__); ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ goto exit; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ pattrib->hdrlen += 2; ++ pattrib->qos_en = true; ++ pattrib->eosp = 1; ++ pattrib->ack_policy = 0; ++ pattrib->mdata = 0; ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) ++ SetFrDs(fctrl); ++ else if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) ++ SetToDs(fctrl); ++ ++ if (pattrib->mdata) ++ SetMData(fctrl); ++ ++ qc = (unsigned short *)(pframe + pattrib->hdrlen - 2); ++ ++ SetPriority(qc, tid); ++ ++ SetEOSP(qc, pattrib->eosp); ++ ++ SetAckpolicy(qc, pattrib->ack_policy); ++ ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_QOS_DATA_NULL); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ if (wait_ack) { ++ ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); ++ } else { ++ dump_mgntframe(padapter, pmgntframe); ++ ret = _SUCCESS; ++ } ++ ++exit: ++ return ret; ++} ++ ++/* when wait_ms > 0 , this function shoule be called at process context */ ++/* da == NULL for station mode */ ++int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms) ++{ ++ int ret; ++ int i = 0; ++ u32 start = jiffies; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ /* da == NULL, assum it's null data for sta to ap*/ ++ if (!da) ++ da = get_my_bssid(&pmlmeinfo->network); ++ ++ do { ++ ret = _issue_qos_nulldata(padapter, da, tid, wait_ms > 0); ++ ++ i++; ++ ++ if (padapter->bDriverStopped || padapter->bSurpriseRemoved) ++ break; ++ ++ if (i < try_cnt && wait_ms > 0 && ret == _FAIL) ++ msleep(wait_ms); ++ } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); ++ ++ if (ret != _FAIL) { ++ ret = _SUCCESS; ++ goto exit; ++ } ++ ++ if (try_cnt && wait_ms) { ++ if (da) ++ DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ else ++ DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ } ++exit: ++ return ret; ++} ++ ++static int _issue_deauth(struct adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ int ret = _FAIL; ++ __le16 le_tmp; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++#ifdef CONFIG_88EU_P2P ++ if (!(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) && (pwdinfo->rx_invitereq_info.scan_op_ch_only)) { ++ _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey); ++ _set_timer(&pwdinfo->reset_ch_sitesurvey, 10); ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ goto exit; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ pattrib->retry_ctrl = false; ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_DEAUTH); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ le_tmp = cpu_to_le16(reason); ++ pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_, (unsigned char *)&le_tmp, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ if (wait_ack) { ++ ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); ++ } else { ++ dump_mgntframe(padapter, pmgntframe); ++ ret = _SUCCESS; ++ } ++ ++exit: ++ return ret; ++} ++ ++int issue_deauth(struct adapter *padapter, unsigned char *da, unsigned short reason) ++{ ++ DBG_88E("%s to %pM\n", __func__, da); ++ return _issue_deauth(padapter, da, reason, false); ++} ++ ++int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason, int try_cnt, ++ int wait_ms) ++{ ++ int ret; ++ int i = 0; ++ u32 start = jiffies; ++ ++ do { ++ ret = _issue_deauth(padapter, da, reason, wait_ms > 0); ++ ++ i++; ++ ++ if (padapter->bDriverStopped || padapter->bSurpriseRemoved) ++ break; ++ ++ if (i < try_cnt && wait_ms > 0 && ret == _FAIL) ++ msleep(wait_ms); ++ } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); ++ ++ if (ret != _FAIL) { ++ ret = _SUCCESS; ++ goto exit; ++ } ++ ++ if (try_cnt && wait_ms) { ++ if (da) ++ DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ else ++ DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", ++ FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), ++ ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start)); ++ } ++exit: ++ return ret; ++} ++ ++void issue_action_spct_ch_switch(struct adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ DBG_88E(FUNC_NDEV_FMT" ra =%pM, ch:%u, offset:%u\n", ++ FUNC_NDEV_ARG(padapter->pnetdev), ra, new_ch, ch_offset); ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */ ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); /* TA */ ++ memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */ ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ /* category, action */ ++ { ++ u8 category, action; ++ category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT; ++ action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH; ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ } ++ ++ pframe = rtw_set_ie_ch_switch(pframe, &pattrib->pktlen, 0, new_ch, 0); ++ pframe = rtw_set_ie_secondary_ch_offset(pframe, &pattrib->pktlen, ++ hal_ch_offset_to_secondary_ch_offset(ch_offset)); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status) ++{ ++ u8 category = RTW_WLAN_CATEGORY_BACK; ++ u16 start_seq; ++ u16 BA_para_set; ++ u16 reason_code; ++ u16 BA_timeout_value; ++ __le16 le_tmp; ++ u16 BA_starting_seqctrl = 0; ++ enum ht_cap_ampdu_factor max_rx_ampdu_factor; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ u8 *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct sta_info *psta; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ ++ DBG_88E("%s, category=%d, action=%d, status=%d\n", __func__, category, action, status); ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ /* memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */ ++ memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &(action), &pattrib->pktlen); ++ ++ if (category == 3) { ++ switch (action) { ++ case 0: /* ADDBA req */ ++ do { ++ pmlmeinfo->dialogToken++; ++ } while (pmlmeinfo->dialogToken == 0); ++ pframe = rtw_set_fixed_ie(pframe, 1, &pmlmeinfo->dialogToken, &pattrib->pktlen); ++ ++ BA_para_set = (0x1002 | ((status & 0xf) << 2)); /* immediate ack & 64 buffer size */ ++ le_tmp = cpu_to_le16(BA_para_set); ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen); ++ ++ BA_timeout_value = 5000;/* 5ms */ ++ le_tmp = cpu_to_le16(BA_timeout_value); ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen); ++ ++ psta = rtw_get_stainfo(pstapriv, raddr); ++ if (psta) { ++ start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07] & 0xfff) + 1; ++ ++ DBG_88E("BA_starting_seqctrl=%d for TID=%d\n", start_seq, status & 0x07); ++ ++ psta->BA_starting_seqctrl[status & 0x07] = start_seq; ++ ++ BA_starting_seqctrl = start_seq << 4; ++ } ++ le_tmp = cpu_to_le16(BA_starting_seqctrl); ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen); ++ break; ++ case 1: /* ADDBA rsp */ ++ pframe = rtw_set_fixed_ie(pframe, 1, &pmlmeinfo->ADDBA_req.dialog_token, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&status, &pattrib->pktlen); ++ BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f; ++ rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); ++ switch (max_rx_ampdu_factor) { ++ case MAX_AMPDU_FACTOR_64K: ++ BA_para_set |= 0x1000; /* 64 buffer size */ ++ break; ++ case MAX_AMPDU_FACTOR_32K: ++ BA_para_set |= 0x0800; /* 32 buffer size */ ++ break; ++ case MAX_AMPDU_FACTOR_16K: ++ BA_para_set |= 0x0400; /* 16 buffer size */ ++ break; ++ case MAX_AMPDU_FACTOR_8K: ++ BA_para_set |= 0x0200; /* 8 buffer size */ ++ break; ++ default: ++ BA_para_set |= 0x1000; /* 64 buffer size */ ++ break; ++ } ++ ++ if (pregpriv->ampdu_amsdu == 0)/* disabled */ ++ BA_para_set = BA_para_set & ~BIT(0); ++ else if (pregpriv->ampdu_amsdu == 1)/* enabled */ ++ BA_para_set = BA_para_set | BIT(0); ++ le_tmp = cpu_to_le16(BA_para_set); ++ ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeinfo->ADDBA_req.BA_timeout_value, &pattrib->pktlen); ++ break; ++ case 2:/* DELBA */ ++ BA_para_set = (status & 0x1F) << 3; ++ le_tmp = cpu_to_le16(BA_para_set); ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen); ++ ++ reason_code = 37;/* Requested from peer STA as it does not want to use the mechanism */ ++ le_tmp = cpu_to_le16(reason_code); ++ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen); ++ break; ++ default: ++ break; ++ } ++ } ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static void issue_action_BSSCoexistPacket(struct adapter *padapter) ++{ ++ struct list_head *plist, *phead; ++ unsigned char category, action; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct wlan_network *pnetwork = NULL; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ u8 InfoContent[16] = {0}; ++ u8 ICS[8][15]; ++ if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0)) ++ return; ++ ++ if (pmlmeinfo->bwmode_updated) ++ return; ++ ++ DBG_88E("%s\n", __func__); ++ ++ category = RTW_WLAN_CATEGORY_PUBLIC; ++ action = ACT_PUBLIC_BSSCOEXIST; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ ++ /* */ ++ if (pmlmepriv->num_FortyMHzIntolerant > 0) { ++ u8 iedata = 0; ++ ++ iedata |= BIT(2);/* 20 MHz BSS Width Request */ ++ ++ pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &pattrib->pktlen); ++ } ++ ++ /* */ ++ memset(ICS, 0, sizeof(ICS)); ++ if (pmlmepriv->num_sta_no_ht > 0) { ++ int i; ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ int len; ++ u8 *p; ++ struct wlan_bssid_ex *pbss_network; ++ ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ plist = plist->next; ++ ++ pbss_network = (struct wlan_bssid_ex *)&pnetwork->network; ++ ++ p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_); ++ if (!p || len == 0) { /* non-HT */ ++ if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14)) ++ continue; ++ ++ ICS[0][pbss_network->Configuration.DSConfig] = 1; ++ ++ if (ICS[0][0] == 0) ++ ICS[0][0] = 1; ++ } ++ } ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ for (i = 0; i < 8; i++) { ++ if (ICS[i][0] == 1) { ++ int j, k = 0; ++ ++ InfoContent[k] = i; ++ /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */ ++ k++; ++ ++ for (j = 1; j <= 14; j++) { ++ if (ICS[i][j] == 1) { ++ if (k < 16) { ++ InfoContent[k] = j; /* channel number */ ++ /* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */ ++ k++; ++ } ++ } ++ } ++ ++ pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &pattrib->pktlen); ++ } ++ } ++ } ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr) ++{ ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct sta_info *psta = NULL; ++ /* struct recv_reorder_ctrl *preorder_ctrl; */ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u16 tid; ++ ++ if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) ++ if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) ++ return _SUCCESS; ++ ++ psta = rtw_get_stainfo(pstapriv, addr); ++ if (!psta) ++ return _SUCCESS; ++ ++ if (initiator == 0) { /* recipient */ ++ for (tid = 0; tid < MAXTID; tid++) { ++ if (psta->recvreorder_ctrl[tid].enable) { ++ DBG_88E("rx agg disable tid(%d)\n", tid); ++ issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator) & 0x1F)); ++ psta->recvreorder_ctrl[tid].enable = false; ++ psta->recvreorder_ctrl[tid].indicate_seq = 0xffff; ++ } ++ } ++ } else if (initiator == 1) { /* originator */ ++ for (tid = 0; tid < MAXTID; tid++) { ++ if (psta->htpriv.agg_enable_bitmap & BIT(tid)) { ++ DBG_88E("tx agg disable tid(%d)\n", tid); ++ issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator) & 0x1F)); ++ psta->htpriv.agg_enable_bitmap &= ~BIT(tid); ++ psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); ++ } ++ } ++ } ++ ++ return _SUCCESS; ++} ++ ++unsigned int send_beacon(struct adapter *padapter) ++{ ++ u8 bxmitok = false; ++ int issue = 0; ++ int poll = 0; ++ ++ u32 start = jiffies; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL); ++ do { ++ issue_beacon(padapter, 100); ++ issue++; ++ do { ++ yield(); ++ rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok)); ++ poll++; ++ } while ((poll % 10) != 0 && !bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); ++ } while (!bxmitok && issue < 100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); ++ ++ if (padapter->bSurpriseRemoved || padapter->bDriverStopped) ++ return _FAIL; ++ if (!bxmitok) { ++ DBG_88E("%s fail! %u ms\n", __func__, rtw_get_passing_time_ms(start)); ++ return _FAIL; ++ } else { ++ u32 passing_time = rtw_get_passing_time_ms(start); ++ ++ if (passing_time > 100 || issue > 3) ++ DBG_88E("%s success, issue:%d, poll:%d, %u ms\n", __func__, issue, poll, rtw_get_passing_time_ms(start)); ++ return _SUCCESS; ++ } ++} ++ ++/**************************************************************************** ++ ++Following are some utitity fuctions for WiFi MLME ++ ++*****************************************************************************/ ++ ++void site_survey(struct adapter *padapter) ++{ ++ unsigned char survey_channel = 0, val8; ++ enum rt_scan_type ScanType = SCAN_PASSIVE; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u32 initialgain = 0; ++ ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ if ((pwdinfo->rx_invitereq_info.scan_op_ch_only) || (pwdinfo->p2p_info.scan_op_ch_only)) { ++ if (pwdinfo->rx_invitereq_info.scan_op_ch_only) { ++ survey_channel = pwdinfo->rx_invitereq_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx]; ++ } else { ++ survey_channel = pwdinfo->p2p_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx]; ++ } ++ ScanType = SCAN_ACTIVE; ++ } else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) { ++ /* Commented by Albert 2011/06/03 */ ++ /* The driver is in the find phase, it should go through the social channel. */ ++ int ch_set_idx; ++ survey_channel = pwdinfo->social_chan[pmlmeext->sitesurvey_res.channel_idx]; ++ ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, survey_channel); ++ if (ch_set_idx >= 0) ++ ScanType = pmlmeext->channel_set[ch_set_idx].ScanType; ++ else ++ ScanType = SCAN_ACTIVE; ++ } else ++#endif /* CONFIG_88EU_P2P */ ++ { ++ struct rtw_ieee80211_channel *ch; ++ if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) { ++ ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx]; ++ survey_channel = ch->hw_value; ++ ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE; ++ } ++ } ++ ++ if (survey_channel != 0) { ++ /* PAUSE 4-AC Queue when site_survey */ ++ /* rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */ ++ /* val8 |= 0x0f; */ ++ /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */ ++ if (pmlmeext->sitesurvey_res.channel_idx == 0) ++ set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ else ++ SelectChannel(padapter, survey_channel); ++ ++ if (ScanType == SCAN_ACTIVE) { /* obey the channel plan setting... */ ++ #ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || ++ rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) { ++ issue_probereq_p2p(padapter, NULL); ++ issue_probereq_p2p(padapter, NULL); ++ issue_probereq_p2p(padapter, NULL); ++ } else ++ #endif /* CONFIG_88EU_P2P */ ++ { ++ int i; ++ for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { ++ if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) { ++ /* todo: to issue two probe req??? */ ++ issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL); ++ /* msleep(SURVEY_TO>>1); */ ++ issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL); ++ } ++ } ++ ++ if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) { ++ /* todo: to issue two probe req??? */ ++ issue_probereq(padapter, NULL, NULL); ++ /* msleep(SURVEY_TO>>1); */ ++ issue_probereq(padapter, NULL, NULL); ++ } ++ } ++ } ++ ++ set_survey_timer(pmlmeext, pmlmeext->chan_scan_time); ++ } else { ++ /* channel number is 0 or this channel is not valid. */ ++ ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) { ++ if ((pwdinfo->rx_invitereq_info.scan_op_ch_only) || (pwdinfo->p2p_info.scan_op_ch_only)) { ++ /* Set the find_phase_state_exchange_cnt to P2P_FINDPHASE_EX_CNT. */ ++ /* This will let the following flow to run the scanning end. */ ++ rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX); ++ } ++ } ++ ++ if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) { ++ /* Set the P2P State to the listen state of find phase and set the current channel to the listen channel */ ++ set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN); ++ pmlmeext->sitesurvey_res.state = SCAN_DISABLE; ++ ++ initialgain = 0xff; /* restore RX GAIN */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); ++ /* turn on dynamic functions */ ++ Restore_DM_Func_Flag(padapter); ++ /* Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, true); */ ++ ++ _set_timer(&pwdinfo->find_phase_timer, (u32)((u32)(pwdinfo->listen_dwell) * 100)); ++ } else ++#endif /* CONFIG_88EU_P2P */ ++ { ++ /* 20100721:Interrupt scan operation here. */ ++ /* For SW antenna diversity before link, it needs to switch to another antenna and scan again. */ ++ /* It compares the scan result and select beter one to do connection. */ ++ if (rtw_hal_antdiv_before_linked(padapter)) { ++ pmlmeext->sitesurvey_res.bss_cnt = 0; ++ pmlmeext->sitesurvey_res.channel_idx = -1; ++ pmlmeext->chan_scan_time = SURVEY_TO / 2; ++ set_survey_timer(pmlmeext, pmlmeext->chan_scan_time); ++ return; ++ } ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) ++ rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); ++ rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE); ++#endif /* CONFIG_88EU_P2P */ ++ ++ pmlmeext->sitesurvey_res.state = SCAN_COMPLETE; ++ ++ /* switch back to the original channel */ ++ ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) ++ set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ else ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); ++#endif /* CONFIG_88EU_P2P */ ++ ++ /* flush 4-AC Queue after site_survey */ ++ /* val8 = 0; */ ++ /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */ ++ ++ /* config MSR */ ++ Set_MSR(padapter, (pmlmeinfo->state & 0x3)); ++ ++ initialgain = 0xff; /* restore RX GAIN */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); ++ /* turn on dynamic functions */ ++ Restore_DM_Func_Flag(padapter); ++ /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); */ ++ ++ if (is_client_associated_to_ap(padapter)) ++ issue_nulldata(padapter, NULL, 0, 3, 500); ++ ++ val8 = 0; /* survey done */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); ++ ++ report_surveydone_event(padapter); ++ ++ pmlmeext->chan_scan_time = SURVEY_TO; ++ pmlmeext->sitesurvey_res.state = SCAN_DISABLE; ++ ++ issue_action_BSSCoexistPacket(padapter); ++ issue_action_BSSCoexistPacket(padapter); ++ issue_action_BSSCoexistPacket(padapter); ++ } ++ } ++} ++ ++/* collect bss info from Beacon and Probe request/response frames. */ ++u8 collect_bss_info(struct adapter *padapter, struct recv_frame *precv_frame, struct wlan_bssid_ex *bssid) ++{ ++ int i; ++ u32 len; ++ u8 *p; ++ u16 val16, subtype; ++ u8 *pframe = precv_frame->rx_data; ++ u32 packet_len = precv_frame->len; ++ u8 ie_offset; ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ __le32 le32_tmp; ++ ++ len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ if (len > MAX_IE_SZ) ++ return _FAIL; ++ ++ memset(bssid, 0, sizeof(struct wlan_bssid_ex)); ++ ++ subtype = GetFrameSubType(pframe); ++ ++ if (subtype == WIFI_BEACON) { ++ bssid->Reserved[0] = 1; ++ ie_offset = _BEACON_IE_OFFSET_; ++ } else { ++ /* FIXME : more type */ ++ if (subtype == WIFI_PROBEREQ) { ++ ie_offset = _PROBEREQ_IE_OFFSET_; ++ bssid->Reserved[0] = 2; ++ } else if (subtype == WIFI_PROBERSP) { ++ ie_offset = _PROBERSP_IE_OFFSET_; ++ bssid->Reserved[0] = 3; ++ } else { ++ bssid->Reserved[0] = 0; ++ ie_offset = _FIXED_IE_LENGTH_; ++ } ++ } ++ ++ bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len; ++ ++ /* below is to copy the information element */ ++ bssid->IELength = len; ++ memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength); ++ ++ /* get the signal strength */ ++ bssid->Rssi = precv_frame->attrib.phy_info.recvpower; /* in dBM.raw data */ ++ bssid->PhyInfo.SignalQuality = precv_frame->attrib.phy_info.SignalQuality;/* in percentage */ ++ bssid->PhyInfo.SignalStrength = precv_frame->attrib.phy_info.SignalStrength;/* in percentage */ ++ rtw_hal_get_def_var(padapter, HAL_DEF_CURRENT_ANTENNA, &bssid->PhyInfo.Optimum_antenna); ++ ++ /* checking SSID */ ++ p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset); ++ if (!p) { ++ DBG_88E("marc: cannot find SSID for survey event\n"); ++ return _FAIL; ++ } ++ ++ if (*(p + 1)) { ++ if (len > NDIS_802_11_LENGTH_SSID) { ++ DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len); ++ return _FAIL; ++ } ++ memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1)); ++ bssid->Ssid.SsidLength = *(p + 1); ++ } else { ++ bssid->Ssid.SsidLength = 0; ++ } ++ ++ memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX); ++ ++ /* checking rate info... */ ++ i = 0; ++ p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset); ++ if (p) { ++ if (len > NDIS_802_11_LENGTH_RATES_EX) { ++ DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len); ++ return _FAIL; ++ } ++ memcpy(bssid->SupportedRates, (p + 2), len); ++ i = len; ++ } ++ ++ p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset); ++ if (p) { ++ if (len > (NDIS_802_11_LENGTH_RATES_EX - i)) { ++ DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len); ++ return _FAIL; ++ } ++ memcpy(bssid->SupportedRates + i, (p + 2), len); ++ } ++ ++ /* todo: */ ++ bssid->NetworkTypeInUse = Ndis802_11OFDM24; ++ ++ if (bssid->IELength < 12) ++ return _FAIL; ++ ++ /* Checking for DSConfig */ ++ p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset); ++ ++ bssid->Configuration.DSConfig = 0; ++ bssid->Configuration.Length = 0; ++ ++ if (p) { ++ bssid->Configuration.DSConfig = *(p + 2); ++ } else {/* In 5G, some ap do not have DSSET IE */ ++ /* checking HT info for channel */ ++ p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset); ++ if (p) { ++ struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2); ++ bssid->Configuration.DSConfig = HT_info->primary_channel; ++ } else { /* use current channel */ ++ bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter); ++ } ++ } ++ ++ memcpy(&le32_tmp, rtw_get_beacon_interval_from_ie(bssid->IEs), 2); ++ bssid->Configuration.BeaconPeriod = le32_to_cpu(le32_tmp); ++ ++ val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid); ++ ++ if (val16 & BIT(0)) { ++ bssid->InfrastructureMode = Ndis802_11Infrastructure; ++ memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN); ++ } else { ++ bssid->InfrastructureMode = Ndis802_11IBSS; ++ memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN); ++ } ++ ++ if (val16 & BIT(4)) ++ bssid->Privacy = 1; ++ else ++ bssid->Privacy = 0; ++ ++ bssid->Configuration.ATIMWindow = 0; ++ ++ /* 20/40 BSS Coexistence check */ ++ if ((pregistrypriv->wifi_spec == 1) && (!pmlmeinfo->bwmode_updated)) { ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset); ++ if (p && len > 0) { ++ struct HT_caps_element *pHT_caps; ++ pHT_caps = (struct HT_caps_element *)(p + 2); ++ ++ if (le16_to_cpu(pHT_caps->u.HT_cap_element.HT_caps_info) & BIT(14)) ++ pmlmepriv->num_FortyMHzIntolerant++; ++ } else { ++ pmlmepriv->num_sta_no_ht++; ++ } ++ } ++ ++ /* mark bss info receiving from nearby channel as SignalQuality 101 */ ++ if (bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter)) ++ bssid->PhyInfo.SignalQuality = 101; ++ return _SUCCESS; ++} ++ ++void start_create_ibss(struct adapter *padapter) ++{ ++ unsigned short caps; ++ u8 val8; ++ u8 join_type; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); ++ pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; ++ pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork); ++ ++ /* update wireless mode */ ++ update_wireless_mode(padapter); ++ ++ /* udpate capability */ ++ caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); ++ update_capinfo(padapter, caps); ++ if (caps & cap_IBSS) {/* adhoc master */ ++ val8 = 0xcf; ++ rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); ++ ++ /* switch channel */ ++ /* SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */ ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ ++ beacon_timing_control(padapter); ++ ++ /* set msr to WIFI_FW_ADHOC_STATE */ ++ pmlmeinfo->state = WIFI_FW_ADHOC_STATE; ++ Set_MSR(padapter, (pmlmeinfo->state & 0x3)); ++ ++ /* issue beacon */ ++ if (send_beacon(padapter) == _FAIL) { ++ report_join_res(padapter, -1); ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ } else { ++ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress); ++ join_type = 0; ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); ++ ++ report_join_res(padapter, 1); ++ pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; ++ rtw_indicate_connect(padapter); ++ } ++ } else { ++ DBG_88E("start_create_ibss, invalid cap:%x\n", caps); ++ return; ++ } ++ /* update bc/mc sta_info */ ++ update_bmc_sta(padapter); ++} ++ ++void start_clnt_join(struct adapter *padapter) ++{ ++ unsigned short caps; ++ u8 val8; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); ++ int beacon_timeout; ++ ++ pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; ++ pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork); ++ ++ /* update wireless mode */ ++ update_wireless_mode(padapter); ++ ++ /* udpate capability */ ++ caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); ++ update_capinfo(padapter, caps); ++ if (caps & cap_ESS) { ++ Set_MSR(padapter, WIFI_FW_STATION_STATE); ++ ++ val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); ++ ++ /* switch channel */ ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); ++ ++ /* here wait for receiving the beacon to start auth */ ++ /* and enable a timer */ ++ beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval); ++ set_link_timer(pmlmeext, beacon_timeout); ++ _set_timer(&padapter->mlmepriv.assoc_timer, ++ (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO * REASSOC_LIMIT) + beacon_timeout); ++ ++ pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE; ++ } else if (caps & cap_IBSS) { /* adhoc client */ ++ Set_MSR(padapter, WIFI_FW_ADHOC_STATE); ++ ++ val8 = 0xcf; ++ rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); ++ ++ /* switch channel */ ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); ++ ++ beacon_timing_control(padapter); ++ ++ pmlmeinfo->state = WIFI_FW_ADHOC_STATE; ++ ++ report_join_res(padapter, 1); ++ } else { ++ return; ++ } ++} ++ ++void start_clnt_auth(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ ++ pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL); ++ pmlmeinfo->state |= WIFI_FW_AUTH_STATE; ++ ++ pmlmeinfo->auth_seq = 1; ++ pmlmeinfo->reauth_count = 0; ++ pmlmeinfo->reassoc_count = 0; ++ pmlmeinfo->link_count = 0; ++ pmlmeext->retry = 0; ++ ++ /* Because of AP's not receiving deauth before */ ++ /* AP may: 1)not response auth or 2)deauth us after link is complete */ ++ /* issue deauth before issuing auth to deal with the situation */ ++ /* Commented by Albert 2012/07/21 */ ++ /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */ ++ issue_deauth(padapter, (&pmlmeinfo->network)->MacAddress, WLAN_REASON_DEAUTH_LEAVING); ++ ++ DBG_88E_LEVEL(_drv_info_, "start auth\n"); ++ issue_auth(padapter, NULL, 0); ++ ++ set_link_timer(pmlmeext, REAUTH_TO); ++} ++ ++void start_clnt_assoc(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ ++ pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE)); ++ pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE); ++ ++ issue_assocreq(padapter); ++ ++ set_link_timer(pmlmeext, REASSOC_TO); ++} ++ ++unsigned int receive_disconnect(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ /* check A3 */ ++ if (!(!memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) ++ return _SUCCESS; ++ ++ DBG_88E("%s\n", __func__); ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) { ++ if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ report_del_sta_event(padapter, MacAddr, reason); ++ } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) { ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ report_join_res(padapter, -2); ++ } ++ } ++ return _SUCCESS; ++} ++ ++static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid) ++{ ++ struct registry_priv *pregistrypriv; ++ struct mlme_ext_priv *pmlmeext; ++ struct rt_channel_info *chplan_new; ++ u8 channel; ++ u8 i; ++ ++ pregistrypriv = &padapter->registrypriv; ++ pmlmeext = &padapter->mlmeextpriv; ++ ++ /* Adjust channel plan by AP Country IE */ ++ if (pregistrypriv->enable80211d && ++ (!pmlmeext->update_channel_plan_by_ap_done)) { ++ u8 *ie, *p; ++ u32 len; ++ struct rt_channel_plan chplan_ap; ++ struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM]; ++ u8 country[4]; ++ u8 fcn; /* first channel number */ ++ u8 noc; /* number of channel */ ++ u8 j, k; ++ ++ ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); ++ if (!ie) ++ return; ++ if (len < 6) ++ return; ++ ie += 2; ++ p = ie; ++ ie += len; ++ ++ memset(country, 0, 4); ++ memcpy(country, p, 3); ++ p += 3; ++ ++ i = 0; ++ while ((ie - p) >= 3) { ++ fcn = *(p++); ++ noc = *(p++); ++ p++; ++ ++ for (j = 0; j < noc; j++) { ++ channel = fcn + j; ++ chplan_ap.Channel[i++] = channel; ++ } ++ } ++ chplan_ap.Len = i; ++ ++ memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta)); ++ ++ memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set)); ++ chplan_new = pmlmeext->channel_set; ++ ++ i = 0; ++ j = 0; ++ k = 0; ++ if (pregistrypriv->wireless_mode & WIRELESS_11G) { ++ do { ++ if ((i == MAX_CHANNEL_NUM) || ++ (chplan_sta[i].ChannelNum == 0)) ++ break; ++ ++ if (j == chplan_ap.Len) ++ break; ++ ++ if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) { ++ chplan_new[k].ChannelNum = chplan_ap.Channel[j]; ++ chplan_new[k].ScanType = SCAN_ACTIVE; ++ i++; ++ j++; ++ k++; ++ } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) { ++ chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; ++ chplan_new[k].ScanType = SCAN_PASSIVE; ++ i++; ++ k++; ++ } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) { ++ chplan_new[k].ChannelNum = chplan_ap.Channel[j]; ++ chplan_new[k].ScanType = SCAN_ACTIVE; ++ j++; ++ k++; ++ } ++ } while (1); ++ ++ /* change AP not support channel to Passive scan */ ++ while ((i < MAX_CHANNEL_NUM) && ++ (chplan_sta[i].ChannelNum != 0) && ++ (chplan_sta[i].ChannelNum <= 14)) { ++ chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; ++ chplan_new[k].ScanType = SCAN_PASSIVE; ++ i++; ++ k++; ++ } ++ ++ /* add channel AP supported */ ++ while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) { ++ chplan_new[k].ChannelNum = chplan_ap.Channel[j]; ++ chplan_new[k].ScanType = SCAN_ACTIVE; ++ j++; ++ k++; ++ } ++ } else { ++ /* keep original STA 2.4G channel plan */ ++ while ((i < MAX_CHANNEL_NUM) && ++ (chplan_sta[i].ChannelNum != 0) && ++ (chplan_sta[i].ChannelNum <= 14)) { ++ chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; ++ chplan_new[k].ScanType = chplan_sta[i].ScanType; ++ i++; ++ k++; ++ } ++ ++ /* skip AP 2.4G channel plan */ ++ while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) ++ j++; ++ } ++ ++ /* keep original STA 5G channel plan */ ++ while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) { ++ chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; ++ chplan_new[k].ScanType = chplan_sta[i].ScanType; ++ i++; ++ k++; ++ } ++ ++ pmlmeext->update_channel_plan_by_ap_done = 1; ++ } ++ ++ /* If channel is used by AP, set channel scan type to active */ ++ channel = bssid->Configuration.DSConfig; ++ chplan_new = pmlmeext->channel_set; ++ i = 0; ++ while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) { ++ if (chplan_new[i].ChannelNum == channel) { ++ if (chplan_new[i].ScanType == SCAN_PASSIVE) ++ chplan_new[i].ScanType = SCAN_ACTIVE; ++ break; ++ } ++ i++; ++ } ++} ++ ++/**************************************************************************** ++ ++Following are the functions to report events ++ ++*****************************************************************************/ ++ ++void report_survey_event(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ struct cmd_obj *pcmd_obj; ++ u8 *pevtcmd; ++ u32 cmdsz; ++ struct survey_event *psurvey_evt; ++ struct C2HEvent_Header *pc2h_evt_hdr; ++ struct mlme_ext_priv *pmlmeext; ++ struct cmd_priv *pcmdpriv; ++ /* u8 *pframe = precv_frame->rx_data; */ ++ /* uint len = precv_frame->len; */ ++ ++ if (!padapter) ++ return; ++ ++ pmlmeext = &padapter->mlmeextpriv; ++ pcmdpriv = &padapter->cmdpriv; ++ ++ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmd_obj) ++ return; ++ ++ cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header)); ++ pevtcmd = kzalloc(cmdsz, GFP_ATOMIC); ++ if (!pevtcmd) { ++ kfree(pcmd_obj); ++ return; ++ } ++ ++ INIT_LIST_HEAD(&pcmd_obj->list); ++ ++ pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); ++ pcmd_obj->cmdsz = cmdsz; ++ pcmd_obj->parmbuf = pevtcmd; ++ ++ pcmd_obj->rsp = NULL; ++ pcmd_obj->rspsz = 0; ++ ++ pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); ++ pc2h_evt_hdr->len = sizeof(struct survey_event); ++ pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey); ++ pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); ++ ++ psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); ++ ++ if (collect_bss_info(padapter, precv_frame, (struct wlan_bssid_ex *)&psurvey_evt->bss) == _FAIL) { ++ kfree(pcmd_obj); ++ kfree(pevtcmd); ++ return; ++ } ++ ++ process_80211d(padapter, &psurvey_evt->bss); ++ ++ rtw_enqueue_cmd(pcmdpriv, pcmd_obj); ++ ++ pmlmeext->sitesurvey_res.bss_cnt++; ++} ++ ++void report_surveydone_event(struct adapter *padapter) ++{ ++ struct cmd_obj *pcmd_obj; ++ u8 *pevtcmd; ++ u32 cmdsz; ++ struct surveydone_event *psurveydone_evt; ++ struct C2HEvent_Header *pc2h_evt_hdr; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!pcmd_obj) ++ return; ++ ++ cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header)); ++ pevtcmd = kzalloc(cmdsz, GFP_KERNEL); ++ if (!pevtcmd) { ++ kfree(pcmd_obj); ++ return; ++ } ++ ++ INIT_LIST_HEAD(&pcmd_obj->list); ++ ++ pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); ++ pcmd_obj->cmdsz = cmdsz; ++ pcmd_obj->parmbuf = pevtcmd; ++ ++ pcmd_obj->rsp = NULL; ++ pcmd_obj->rspsz = 0; ++ ++ pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); ++ pc2h_evt_hdr->len = sizeof(struct surveydone_event); ++ pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone); ++ pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); ++ ++ psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); ++ psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt; ++ ++ DBG_88E("survey done event(%x)\n", psurveydone_evt->bss_cnt); ++ ++ rtw_enqueue_cmd(pcmdpriv, pcmd_obj); ++} ++ ++void report_join_res(struct adapter *padapter, int res) ++{ ++ struct cmd_obj *pcmd_obj; ++ u8 *pevtcmd; ++ u32 cmdsz; ++ struct joinbss_event *pjoinbss_evt; ++ struct C2HEvent_Header *pc2h_evt_hdr; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!pcmd_obj) ++ return; ++ ++ cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header)); ++ pevtcmd = kzalloc(cmdsz, GFP_ATOMIC); ++ if (!pevtcmd) { ++ kfree(pcmd_obj); ++ return; ++ } ++ ++ INIT_LIST_HEAD(&pcmd_obj->list); ++ ++ pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); ++ pcmd_obj->cmdsz = cmdsz; ++ pcmd_obj->parmbuf = pevtcmd; ++ ++ pcmd_obj->rsp = NULL; ++ pcmd_obj->rspsz = 0; ++ ++ pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); ++ pc2h_evt_hdr->len = sizeof(struct joinbss_event); ++ pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss); ++ pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); ++ ++ pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); ++ memcpy((unsigned char *)(&pjoinbss_evt->network.network), &pmlmeinfo->network, sizeof(struct wlan_bssid_ex)); ++ pjoinbss_evt->network.join_res = res; ++ pjoinbss_evt->network.aid = res; ++ ++ DBG_88E("report_join_res(%d)\n", res); ++ ++ rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network); ++ ++ rtw_enqueue_cmd(pcmdpriv, pcmd_obj); ++} ++ ++void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason) ++{ ++ struct cmd_obj *pcmd_obj; ++ u8 *pevtcmd; ++ u32 cmdsz; ++ struct sta_info *psta; ++ int mac_id; ++ struct stadel_event *pdel_sta_evt; ++ struct C2HEvent_Header *pc2h_evt_hdr; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!pcmd_obj) ++ return; ++ ++ cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header)); ++ pevtcmd = kzalloc(cmdsz, GFP_KERNEL); ++ if (!pevtcmd) { ++ kfree(pcmd_obj); ++ return; ++ } ++ ++ INIT_LIST_HEAD(&pcmd_obj->list); ++ ++ pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); ++ pcmd_obj->cmdsz = cmdsz; ++ pcmd_obj->parmbuf = pevtcmd; ++ ++ pcmd_obj->rsp = NULL; ++ pcmd_obj->rspsz = 0; ++ ++ pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); ++ pc2h_evt_hdr->len = sizeof(struct stadel_event); ++ pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA); ++ pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); ++ ++ pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); ++ memcpy((unsigned char *)(&pdel_sta_evt->macaddr), MacAddr, ETH_ALEN); ++ memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2); ++ ++ psta = rtw_get_stainfo(&padapter->stapriv, MacAddr); ++ if (psta) ++ mac_id = (int)psta->mac_id; ++ else ++ mac_id = (-1); ++ ++ pdel_sta_evt->mac_id = mac_id; ++ ++ DBG_88E("report_del_sta_event: delete STA, mac_id =%d\n", mac_id); ++ ++ rtw_enqueue_cmd(pcmdpriv, pcmd_obj); ++} ++ ++void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int cam_idx) ++{ ++ struct cmd_obj *pcmd_obj; ++ u8 *pevtcmd; ++ u32 cmdsz; ++ struct stassoc_event *padd_sta_evt; ++ struct C2HEvent_Header *pc2h_evt_hdr; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ ++ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ++ if (!pcmd_obj) ++ return; ++ ++ cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header)); ++ pevtcmd = kzalloc(cmdsz, GFP_KERNEL); ++ if (!pevtcmd) { ++ kfree(pcmd_obj); ++ return; ++ } ++ ++ INIT_LIST_HEAD(&pcmd_obj->list); ++ ++ pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); ++ pcmd_obj->cmdsz = cmdsz; ++ pcmd_obj->parmbuf = pevtcmd; ++ ++ pcmd_obj->rsp = NULL; ++ pcmd_obj->rspsz = 0; ++ ++ pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); ++ pc2h_evt_hdr->len = sizeof(struct stassoc_event); ++ pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA); ++ pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); ++ ++ padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); ++ memcpy((unsigned char *)(&padd_sta_evt->macaddr), MacAddr, ETH_ALEN); ++ padd_sta_evt->cam_id = cam_idx; ++ ++ DBG_88E("report_add_sta_event: add STA\n"); ++ ++ rtw_enqueue_cmd(pcmdpriv, pcmd_obj); ++} ++ ++/**************************************************************************** ++ ++Following are the event callback functions ++ ++*****************************************************************************/ ++ ++/* for sta/adhoc mode */ ++void update_sta_info(struct adapter *padapter, struct sta_info *psta) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ /* ERP */ ++ VCS_update(padapter, psta); ++ ++ /* HT */ ++ if (pmlmepriv->htpriv.ht_option) { ++ psta->htpriv.ht_option = true; ++ ++ psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable; ++ ++ if (support_short_GI(padapter, &pmlmeinfo->HT_caps)) ++ psta->htpriv.sgi = true; ++ ++ psta->qos_option = true; ++ } else { ++ psta->htpriv.ht_option = false; ++ ++ psta->htpriv.ampdu_enable = false; ++ ++ psta->htpriv.sgi = false; ++ psta->qos_option = false; ++ } ++ psta->htpriv.bwmode = pmlmeext->cur_bwmode; ++ psta->htpriv.ch_offset = pmlmeext->cur_ch_offset; ++ ++ psta->htpriv.agg_enable_bitmap = 0x0;/* reset */ ++ psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */ ++ ++ /* QoS */ ++ if (pmlmepriv->qospriv.qos_option) ++ psta->qos_option = true; ++ ++ psta->state = _FW_LINKED; ++} ++ ++void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res) ++{ ++ struct sta_info *psta, *psta_bmc; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 join_type; ++ u16 media_status; ++ ++ if (join_res < 0) { ++ join_type = 1; ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); ++ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); ++ ++ /* restore to initial setting. */ ++ update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); ++ ++ goto exit_mlmeext_joinbss_event_callback; ++ } ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { ++ /* for bc/mc */ ++ psta_bmc = rtw_get_bcmc_stainfo(padapter); ++ if (psta_bmc) { ++ pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc; ++ update_bmc_sta_support_rate(padapter, psta_bmc->mac_id); ++ Update_RA_Entry(padapter, psta_bmc->mac_id); ++ } ++ } ++ ++ /* turn on dynamic functions */ ++ Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); ++ ++ /* update IOT-releated issue */ ++ update_IOT_info(padapter); ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates); ++ ++ /* BCN interval */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval)); ++ ++ /* udpate capability */ ++ update_capinfo(padapter, pmlmeinfo->capability); ++ ++ /* WMM, Update EDCA param */ ++ WMMOnAssocRsp(padapter); ++ ++ /* HT */ ++ HTOnAssocRsp(padapter); ++ ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); ++ ++ psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress); ++ if (psta) { /* only for infra. mode */ ++ pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta; ++ ++ psta->wireless_mode = pmlmeext->cur_wireless_mode; ++ ++ /* set per sta rate after updating HT cap. */ ++ set_sta_rate(padapter, psta); ++ rtw_hal_set_hwreg(padapter, HW_VAR_TX_RPT_MAX_MACID, (u8 *)&psta->mac_id); ++ media_status = (psta->mac_id << 8) | 1; /* MACID|OPMODE: 1 means connect */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status); ++ } ++ ++ join_type = 2; ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) { ++ /* correcting TSF */ ++ correct_TSF(padapter, pmlmeext); ++ } ++ rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0); ++ ++exit_mlmeext_joinbss_event_callback: ++ ++ DBG_88E("=>%s\n", __func__); ++} ++ ++void mlmeext_sta_add_event_callback(struct adapter *padapter, struct sta_info *psta) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 join_type; ++ ++ DBG_88E("%s\n", __func__); ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { ++ if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {/* adhoc master or sta_count>1 */ ++ /* nothing to do */ ++ } else { /* adhoc client */ ++ /* correcting TSF */ ++ correct_TSF(padapter, pmlmeext); ++ ++ /* start beacon */ ++ if (send_beacon(padapter) == _FAIL) { ++ pmlmeinfo->FW_sta_info[psta->mac_id].status = 0; ++ pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE; ++ return; ++ } ++ pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; ++ } ++ ++ join_type = 2; ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); ++ } ++ ++ pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta; ++ ++ /* rate radaptive */ ++ Update_RA_Entry(padapter, psta->mac_id); ++ ++ /* update adhoc sta_info */ ++ update_sta_info(padapter, psta); ++} ++ ++void mlmeext_sta_del_event_callback(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter)) { ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL); ++ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); ++ ++ /* restore to initial setting. */ ++ update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); ++ ++ /* switch to the 20M Hz mode after disconnect */ ++ pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ ++ /* SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */ ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); ++ ++ flush_all_cam_entry(padapter); ++ ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ ++ /* set MSR to no link state -> infra. mode */ ++ Set_MSR(padapter, _HW_STATE_STATION_); ++ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ } ++} ++ ++/**************************************************************************** ++ ++Following are the functions for the timer handlers ++ ++*****************************************************************************/ ++void _linked_rx_signal_strehgth_display(struct adapter *padapter); ++void _linked_rx_signal_strehgth_display(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 mac_id; ++ int UndecoratedSmoothedPWDB; ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) ++ mac_id = 0; ++ else if ((pmlmeinfo->state & 0x03) == _HW_STATE_AP_) ++ mac_id = 2; ++ ++ rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, &mac_id); ++ ++ rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB); ++ DBG_88E("UndecoratedSmoothedPWDB:%d\n", UndecoratedSmoothedPWDB); ++} ++ ++static u8 chk_ap_is_alive(struct adapter *padapter, struct sta_info *psta) ++{ ++ u8 ret = false; ++ ++ if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)) && ++ sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) && ++ sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)) ++ ret = false; ++ else ++ ret = true; ++ ++ sta_update_last_rx_pkts(psta); ++ ++ return ret; ++} ++ ++void linked_status_chk(struct adapter *padapter) ++{ ++ u32 i; ++ struct sta_info *psta; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ if (padapter->bRxRSSIDisplay) ++ _linked_rx_signal_strehgth_display(padapter); ++ ++ rtw_hal_sreset_linked_status_check(padapter); ++ ++ if (is_client_associated_to_ap(padapter)) { ++ /* linked infrastructure client mode */ ++ ++ int tx_chk = _SUCCESS, rx_chk = _SUCCESS; ++ int rx_chk_limit; ++ ++ rx_chk_limit = 4; ++ psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress); ++ if (psta) { ++ bool is_p2p_enable = false; ++ #ifdef CONFIG_88EU_P2P ++ is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE); ++ #endif ++ ++ if (!chk_ap_is_alive(padapter, psta)) ++ rx_chk = _FAIL; ++ ++ if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts) ++ tx_chk = _FAIL; ++ ++ if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) { ++ u8 backup_oper_channel = 0; ++ ++ /* switch to correct channel of current network before issue keep-alive frames */ ++ if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) { ++ backup_oper_channel = rtw_get_oper_ch(padapter); ++ SelectChannel(padapter, pmlmeext->cur_channel); ++ } ++ ++ if (rx_chk != _SUCCESS) ++ issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1); ++ ++ if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) { ++ tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1); ++ /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */ ++ if (tx_chk == _SUCCESS && !is_p2p_enable) ++ rx_chk = _SUCCESS; ++ } ++ ++ /* back to the original operation channel */ ++ if (backup_oper_channel > 0) ++ SelectChannel(padapter, backup_oper_channel); ++ } else { ++ if (rx_chk != _SUCCESS) { ++ if (pmlmeext->retry == 0) { ++ issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress); ++ issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress); ++ issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress); ++ } ++ } ++ ++ if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) { ++ tx_chk = issue_nulldata(padapter, NULL, 0, 1, 0); ++ } ++ } ++ ++ if (rx_chk == _FAIL) { ++ pmlmeext->retry++; ++ if (pmlmeext->retry > rx_chk_limit) { ++ DBG_88E_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n", ++ FUNC_ADPT_ARG(padapter)); ++ receive_disconnect(padapter, pmlmeinfo->network.MacAddress, ++ WLAN_REASON_EXPIRATION_CHK); ++ return; ++ } ++ } else { ++ pmlmeext->retry = 0; ++ } ++ ++ if (tx_chk == _FAIL) { ++ pmlmeinfo->link_count &= 0xf; ++ } else { ++ pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts; ++ pmlmeinfo->link_count = 0; ++ } ++ } /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */ ++ } else if (is_client_associated_to_ibss(padapter)) { ++ /* linked IBSS mode */ ++ /* for each assoc list entry to check the rx pkt counter */ ++ for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) { ++ if (pmlmeinfo->FW_sta_info[i].status == 1) { ++ psta = pmlmeinfo->FW_sta_info[i].psta; ++ ++ if (NULL == psta) ++ continue; ++ if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta)) { ++ if (pmlmeinfo->FW_sta_info[i].retry < 3) { ++ pmlmeinfo->FW_sta_info[i].retry++; ++ } else { ++ pmlmeinfo->FW_sta_info[i].retry = 0; ++ pmlmeinfo->FW_sta_info[i].status = 0; ++ report_del_sta_event(padapter, psta->hwaddr ++ , 65535/* indicate disconnect caused by no rx */ ++ ); ++ } ++ } else { ++ pmlmeinfo->FW_sta_info[i].retry = 0; ++ pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta); ++ } ++ } ++ } ++ } ++} ++ ++void survey_timer_hdl(struct adapter *padapter) ++{ ++ struct cmd_obj *ph2c; ++ struct sitesurvey_parm *psurveyPara; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif ++ ++ /* issue rtw_sitesurvey_cmd */ ++ if (pmlmeext->sitesurvey_res.state > SCAN_START) { ++ if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) ++ pmlmeext->sitesurvey_res.channel_idx++; ++ ++ if (pmlmeext->scan_abort) { ++ #ifdef CONFIG_88EU_P2P ++ if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) { ++ rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX); ++ pmlmeext->sitesurvey_res.channel_idx = 3; ++ DBG_88E("%s idx:%d, cnt:%u\n", __func__ ++ , pmlmeext->sitesurvey_res.channel_idx ++ , pwdinfo->find_phase_state_exchange_cnt ++ ); ++ } else ++ #endif ++ { ++ pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num; ++ DBG_88E("%s idx:%d\n", __func__ ++ , pmlmeext->sitesurvey_res.channel_idx ++ ); ++ } ++ ++ pmlmeext->scan_abort = false;/* reset */ ++ } ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) ++ goto exit_survey_timer_hdl; ++ ++ psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC); ++ if (!psurveyPara) { ++ kfree(ph2c); ++ goto exit_survey_timer_hdl; ++ } ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey)); ++ rtw_enqueue_cmd(pcmdpriv, ph2c); ++ } ++ ++exit_survey_timer_hdl: ++ return; ++} ++ ++void link_timer_hdl(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) { ++ DBG_88E("link_timer_hdl:no beacon while connecting\n"); ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ report_join_res(padapter, -3); ++ } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) { ++ /* re-auth timer */ ++ if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) { ++ pmlmeinfo->state = 0; ++ report_join_res(padapter, -1); ++ return; ++ } ++ ++ DBG_88E("link_timer_hdl: auth timeout and try again\n"); ++ pmlmeinfo->auth_seq = 1; ++ issue_auth(padapter, NULL, 0); ++ set_link_timer(pmlmeext, REAUTH_TO); ++ } else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) { ++ /* re-assoc timer */ ++ if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) { ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ report_join_res(padapter, -2); ++ return; ++ } ++ ++ DBG_88E("link_timer_hdl: assoc timeout and try again\n"); ++ issue_assocreq(padapter); ++ set_link_timer(pmlmeext, REASSOC_TO); ++ } ++} ++ ++void addba_timer_hdl(struct sta_info *psta) ++{ ++ struct ht_priv *phtpriv; ++ ++ if (!psta) ++ return; ++ ++ phtpriv = &psta->htpriv; ++ ++ if ((phtpriv->ht_option) && (phtpriv->ampdu_enable)) { ++ if (phtpriv->candidate_tid_bitmap) ++ phtpriv->candidate_tid_bitmap = 0x0; ++ } ++} ++ ++u8 NULL_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ return H2C_SUCCESS; ++} ++ ++u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ u8 type; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf; ++ ++ if (psetop->mode == Ndis802_11APMode) { ++ pmlmeinfo->state = WIFI_FW_AP_STATE; ++ type = _HW_STATE_AP_; ++ } else if (psetop->mode == Ndis802_11Infrastructure) { ++ pmlmeinfo->state &= ~(BIT(0) | BIT(1));/* clear state */ ++ pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */ ++ type = _HW_STATE_STATION_; ++ } else if (psetop->mode == Ndis802_11IBSS) { ++ type = _HW_STATE_ADHOC_; ++ } else { ++ type = _HW_STATE_NOLINK_; ++ } ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type)); ++ /* Set_NETYPE0_MSR(padapter, type); */ ++ ++ return H2C_SUCCESS; ++} ++ ++u8 createbss_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); ++ struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf; ++ /* u32 initialgain; */ ++ ++ if (pparm->network.InfrastructureMode == Ndis802_11APMode) { ++#ifdef CONFIG_88EU_AP_MODE ++ ++ if (pmlmeinfo->state == WIFI_FW_AP_STATE) { ++ /* todo: */ ++ return H2C_SUCCESS; ++ } ++#endif ++ } ++ ++ /* below is for ad-hoc master */ ++ if (pparm->network.InfrastructureMode == Ndis802_11IBSS) { ++ rtw_joinbss_reset(padapter); ++ ++ pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ pmlmeinfo->ERP_enable = 0; ++ pmlmeinfo->WMM_enable = 0; ++ pmlmeinfo->HT_enable = 0; ++ pmlmeinfo->HT_caps_enable = 0; ++ pmlmeinfo->HT_info_enable = 0; ++ pmlmeinfo->agg_enable_bitmap = 0; ++ pmlmeinfo->candidate_tid_bitmap = 0; ++ ++ /* disable dynamic functions, such as high power, DIG */ ++ Save_DM_Func_Flag(padapter); ++ Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); ++ ++ /* config the initial gain under linking, need to write the BB registers */ ++ /* initialgain = 0x1E; */ ++ /* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */ ++ ++ /* cancel link timer */ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ ++ /* clear CAM */ ++ flush_all_cam_entry(padapter); ++ ++ memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength)); ++ pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength; ++ ++ if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */ ++ return H2C_PARAMETERS_ERROR; ++ ++ memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength); ++ ++ start_create_ibss(padapter); ++ } ++ ++ return H2C_SUCCESS; ++} ++ ++u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ u8 join_type; ++ struct ndis_802_11_var_ie *pIE; ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); ++ struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf; ++ u32 i; ++ ++ /* check already connecting to AP or not */ ++ if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { ++ if (pmlmeinfo->state & WIFI_FW_STATION_STATE) ++ issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 5, 100); ++ ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ ++ /* clear CAM */ ++ flush_all_cam_entry(padapter); ++ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ ++ /* set MSR to nolink -> infra. mode */ ++ Set_MSR(padapter, _HW_STATE_STATION_); ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL); ++ } ++ ++ rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, false); ++ ++ rtw_joinbss_reset(padapter); ++ ++ pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ pmlmeinfo->ERP_enable = 0; ++ pmlmeinfo->WMM_enable = 0; ++ pmlmeinfo->HT_enable = 0; ++ pmlmeinfo->HT_caps_enable = 0; ++ pmlmeinfo->HT_info_enable = 0; ++ pmlmeinfo->agg_enable_bitmap = 0; ++ pmlmeinfo->candidate_tid_bitmap = 0; ++ pmlmeinfo->bwmode_updated = false; ++ ++ memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength)); ++ pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength; ++ ++ if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */ ++ return H2C_PARAMETERS_ERROR; ++ ++ memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength); ++ ++ /* Check AP vendor to move rtw_joinbss_cmd() */ ++ ++ for (i = sizeof(struct ndis_802_11_fixed_ie); i < pnetwork->IELength;) { ++ pIE = (struct ndis_802_11_var_ie *)(pnetwork->IEs + i); ++ ++ switch (pIE->ElementID) { ++ case _VENDOR_SPECIFIC_IE_:/* Get WMM IE. */ ++ if (!memcmp(pIE->data, WMM_OUI, 4)) ++ pmlmeinfo->WMM_enable = 1; ++ break; ++ case _HT_CAPABILITY_IE_: /* Get HT Cap IE. */ ++ pmlmeinfo->HT_caps_enable = 1; ++ break; ++ case _HT_EXTRA_INFO_IE_: /* Get HT Info IE. */ ++ pmlmeinfo->HT_info_enable = 1; ++ ++ /* spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz */ ++ { ++ struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data); ++ ++ if ((pregpriv->cbw40_enable) && (pht_info->infos[0] & BIT(2))) { ++ /* switch to the 40M Hz mode according to the AP */ ++ pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40; ++ switch (pht_info->infos[0] & 0x3) { ++ case 1: ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; ++ break; ++ case 3: ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; ++ break; ++ default: ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ break; ++ } ++ ++ DBG_88E("set ch/bw before connected\n"); ++ } ++ } ++ break; ++ default: ++ break; ++ } ++ ++ i += (pIE->Length + 2); ++ } ++ /* disable dynamic functions, such as high power, DIG */ ++ ++ /* config the initial gain under linking, need to write the BB registers */ ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress); ++ join_type = 0; ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); ++ ++ /* cancel link timer */ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ ++ start_clnt_join(padapter); ++ ++ return H2C_SUCCESS; ++} ++ ++u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ struct disconnect_parm *param = (struct disconnect_parm *)pbuf; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network); ++ u8 val8; ++ ++ if (is_client_associated_to_ap(padapter)) ++ issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms / 100, 100); ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL); ++ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); ++ ++ /* restore to initial setting. */ ++ update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); ++ ++ if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) { ++ /* Stop BCN */ ++ val8 = 0; ++ rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8)); ++ } ++ ++ /* set MSR to no link state -> infra. mode */ ++ Set_MSR(padapter, _HW_STATE_STATION_); ++ ++ pmlmeinfo->state = WIFI_FW_NULL_STATE; ++ ++ /* switch to the 20M Hz mode after disconnect */ ++ pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; ++ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ ++ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); ++ ++ flush_all_cam_entry(padapter); ++ ++ _cancel_timer_ex(&pmlmeext->link_timer); ++ ++ rtw_free_uc_swdec_pending_queue(padapter); ++ ++ return H2C_SUCCESS; ++} ++ ++static int rtw_scan_ch_decision(struct adapter *padapter, struct rtw_ieee80211_channel *out, ++ u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num) ++{ ++ int i, j; ++ int set_idx; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ /* clear out first */ ++ memset(out, 0, sizeof(struct rtw_ieee80211_channel) * out_num); ++ ++ /* acquire channels from in */ ++ j = 0; ++ for (i = 0; i < in_num; i++) { ++ set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value); ++ if (in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED) && ++ set_idx >= 0) { ++ memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel)); ++ ++ if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE) ++ out[j].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN; ++ ++ j++; ++ } ++ if (j >= out_num) ++ break; ++ } ++ ++ /* if out is empty, use channel_set as default */ ++ if (j == 0) { ++ for (i = 0; i < pmlmeext->max_chan_nums; i++) { ++ out[i].hw_value = pmlmeext->channel_set[i].ChannelNum; ++ ++ if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE) ++ out[i].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN; ++ ++ j++; ++ } ++ } ++ ++ return j; ++} ++ ++u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf; ++ u8 bdelayscan = false; ++ u8 val8; ++ u32 initialgain; ++ u32 i; ++ ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif ++ ++ if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) { ++ /* for first time sitesurvey_cmd */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, NULL); ++ ++ pmlmeext->sitesurvey_res.state = SCAN_START; ++ pmlmeext->sitesurvey_res.bss_cnt = 0; ++ pmlmeext->sitesurvey_res.channel_idx = 0; ++ ++ for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { ++ if (pparm->ssid[i].SsidLength) { ++ memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE); ++ pmlmeext->sitesurvey_res.ssid[i].SsidLength = pparm->ssid[i].SsidLength; ++ } else { ++ pmlmeext->sitesurvey_res.ssid[i].SsidLength = 0; ++ } ++ } ++ ++ pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter ++ , pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT ++ , pparm->ch, pparm->ch_num ++ ); ++ ++ pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode; ++ ++ /* issue null data if associating to the AP */ ++ if (is_client_associated_to_ap(padapter)) { ++ pmlmeext->sitesurvey_res.state = SCAN_TXNULL; ++ ++ issue_nulldata(padapter, NULL, 1, 3, 500); ++ ++ bdelayscan = true; ++ } ++ if (bdelayscan) { ++ /* delay 50ms to protect nulldata(1). */ ++ set_survey_timer(pmlmeext, 50); ++ return H2C_SUCCESS; ++ } ++ } ++ ++ if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) { ++ /* disable dynamic functions, such as high power, DIG */ ++ Save_DM_Func_Flag(padapter); ++ Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); ++ ++ /* config the initial gain under scanning, need to write the BB registers */ ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ initialgain = 0x1E; ++ else ++ initialgain = 0x28; ++#else /* CONFIG_88EU_P2P */ ++ initialgain = 0x1E; ++#endif /* CONFIG_88EU_P2P */ ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); ++ ++ /* set MSR to no link state */ ++ Set_MSR(padapter, _HW_STATE_NOLINK_); ++ ++ val8 = 1; /* under site survey */ ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); ++ ++ pmlmeext->sitesurvey_res.state = SCAN_PROCESS; ++ } ++ ++ site_survey(padapter); ++ ++ return H2C_SUCCESS; ++} ++ ++u8 setauth_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ struct setauth_parm *pparm = (struct setauth_parm *)pbuf; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pparm->mode < 4) ++ pmlmeinfo->auth_algo = pparm->mode; ++ return H2C_SUCCESS; ++} ++ ++u8 setkey_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ unsigned short ctrl; ++ struct setkey_parm *pparm = (struct setkey_parm *)pbuf; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; ++ ++ /* main tx key for wep. */ ++ if (pparm->set_tx) ++ pmlmeinfo->key_index = pparm->keyid; ++ ++ /* write cam */ ++ ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid; ++ ++ DBG_88E_LEVEL(_drv_info_, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) " ++ "keyid:%d\n", pparm->algorithm, pparm->keyid); ++ write_cam(padapter, pparm->keyid, ctrl, null_sta, pparm->key); ++ ++ return H2C_SUCCESS; ++} ++ ++u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ u16 ctrl = 0; ++ u8 cam_id;/* cam_entry */ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf; ++ ++ /* cam_entry: */ ++ /* 0~3 for default key */ ++ ++ /* for concurrent mode (ap+sta): */ ++ /* default key is disable, using sw encrypt/decrypt */ ++ /* cam_entry = 4 for sta mode (macid = 0) */ ++ /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */ ++ ++ /* for concurrent mode (sta+sta): */ ++ /* default key is disable, using sw encrypt/decrypt */ ++ /* cam_entry = 4 mapping to macid = 0 */ ++ /* cam_entry = 5 mapping to macid = 2 */ ++ ++ cam_id = 4; ++ ++ DBG_88E_LEVEL(_drv_info_, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n", ++ pparm->algorithm, cam_id); ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { ++ struct sta_info *psta; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ if (pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */ { ++ clear_cam_entry(padapter, pparm->id); ++ return H2C_SUCCESS_RSP; ++ } ++ ++ psta = rtw_get_stainfo(pstapriv, pparm->addr); ++ if (psta) { ++ ctrl = (BIT(15) | ((pparm->algorithm) << 2)); ++ ++ DBG_88E("r871x_set_stakey_hdl(): enc_algorithm=%d\n", pparm->algorithm); ++ ++ if ((psta->mac_id < 1) || (psta->mac_id > (NUM_STA - 4))) { ++ DBG_88E("r871x_set_stakey_hdl():set_stakey failed, mac_id(aid)=%d\n", psta->mac_id); ++ return H2C_REJECTED; ++ } ++ ++ cam_id = (psta->mac_id + 3);/* 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */ ++ ++ DBG_88E("Write CAM, mac_addr =%x:%x:%x:%x:%x:%x, cam_entry=%d\n", pparm->addr[0], ++ pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4], ++ pparm->addr[5], cam_id); ++ ++ write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key); ++ ++ return H2C_SUCCESS_RSP; ++ } else { ++ DBG_88E("r871x_set_stakey_hdl(): sta has been free\n"); ++ return H2C_REJECTED; ++ } ++ } ++ ++ /* below for sta mode */ ++ ++ if (pparm->algorithm == _NO_PRIVACY_) { /* clear cam entry */ ++ clear_cam_entry(padapter, pparm->id); ++ return H2C_SUCCESS; ++ } ++ ctrl = BIT(15) | ((pparm->algorithm) << 2); ++ write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key); ++ pmlmeinfo->enc_algo = pparm->algorithm; ++ return H2C_SUCCESS; ++} ++ ++u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr); ++ ++ if (!psta) ++ return H2C_SUCCESS; ++ ++ if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) || ++ ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) { ++ issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid); ++ _set_timer(&psta->addba_retry_timer, ADDBA_TO); ++ } else { ++ psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid); ++ } ++ return H2C_SUCCESS; ++} ++ ++u8 set_tx_beacon_cmd(struct adapter *padapter) ++{ ++ struct cmd_obj *ph2c; ++ struct Tx_Beacon_param *ptxBeacon_parm; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u8 res = _SUCCESS; ++ int len_diff = 0; ++ ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ ptxBeacon_parm = kzalloc(sizeof(struct Tx_Beacon_param), GFP_ATOMIC); ++ if (!ptxBeacon_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ memcpy(&ptxBeacon_parm->network, &pmlmeinfo->network, sizeof(struct wlan_bssid_ex)); ++ ++ len_diff = update_hidden_ssid(ptxBeacon_parm->network.IEs + _BEACON_IE_OFFSET_, ++ ptxBeacon_parm->network.IELength - _BEACON_IE_OFFSET_, ++ pmlmeinfo->hidden_ssid_mode); ++ ptxBeacon_parm->network.IELength += len_diff; ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ ++exit: ++ ++ return res; ++} ++ ++u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ u8 evt_code; ++ u16 evt_sz; ++ uint *peventbuf; ++ void (*event_callback)(struct adapter *dev, u8 *pbuf); ++ struct evt_priv *pevt_priv = &padapter->evtpriv; ++ ++ peventbuf = (uint *)pbuf; ++ evt_sz = (u16)(*peventbuf & 0xffff); ++ evt_code = (u8)((*peventbuf >> 16) & 0xff); ++ ++ /* checking if event code is valid */ ++ if (evt_code >= MAX_C2HEVT) ++ goto _abort_event_; ++ ++ /* checking if event size match the event parm size */ ++ if ((wlanevents[evt_code].parmsize != 0) && ++ (wlanevents[evt_code].parmsize != evt_sz)) ++ goto _abort_event_; ++ ++ atomic_inc(&pevt_priv->event_seq); ++ ++ peventbuf += 2; ++ ++ if (peventbuf) { ++ event_callback = wlanevents[evt_code].event_callback; ++ event_callback(padapter, (u8 *)peventbuf); ++ ++ pevt_priv->evt_done_cnt++; ++ } ++ ++_abort_event_: ++ return H2C_SUCCESS; ++} ++ ++u8 h2c_msg_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ if (!pbuf) ++ return H2C_PARAMETERS_ERROR; ++ ++ return H2C_SUCCESS; ++} ++ ++u8 tx_beacon_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ if (send_beacon(padapter) == _FAIL) { ++ DBG_88E("issue_beacon, fail!\n"); ++ return H2C_PARAMETERS_ERROR; ++ } ++#ifdef CONFIG_88EU_AP_MODE ++ else { /* tx bc/mc frames after update TIM */ ++ struct sta_info *psta_bmc; ++ struct list_head *xmitframe_plist, *xmitframe_phead; ++ struct xmit_frame *pxmitframe = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ /* for BC/MC Frames */ ++ psta_bmc = rtw_get_bcmc_stainfo(padapter); ++ if (!psta_bmc) ++ return H2C_SUCCESS; ++ ++ if ((pstapriv->tim_bitmap & BIT(0)) && (psta_bmc->sleepq_len > 0)) { ++ msleep(10);/* 10ms, ATIM(HIQ) Windows */ ++ spin_lock_bh(&psta_bmc->sleep_q.lock); ++ ++ xmitframe_phead = get_list_head(&psta_bmc->sleep_q); ++ xmitframe_plist = xmitframe_phead->next; ++ ++ while (xmitframe_phead != xmitframe_plist) { ++ pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); ++ ++ xmitframe_plist = xmitframe_plist->next; ++ ++ list_del_init(&pxmitframe->list); ++ ++ psta_bmc->sleepq_len--; ++ if (psta_bmc->sleepq_len > 0) ++ pxmitframe->attrib.mdata = 1; ++ else ++ pxmitframe->attrib.mdata = 0; ++ ++ pxmitframe->attrib.triggered = 1; ++ ++ pxmitframe->attrib.qsel = 0x11;/* HIQ */ ++ ++ spin_unlock_bh(&psta_bmc->sleep_q.lock); ++ if (rtw_hal_xmit(padapter, pxmitframe)) ++ rtw_os_xmit_complete(padapter, pxmitframe); ++ spin_lock_bh(&psta_bmc->sleep_q.lock); ++ } ++ spin_unlock_bh(&psta_bmc->sleep_q.lock); ++ } ++ } ++#endif ++ return H2C_SUCCESS; ++} ++ ++u8 set_ch_hdl(struct adapter *padapter, u8 *pbuf) ++{ ++ struct set_ch_parm *set_ch_parm; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ if (!pbuf) ++ return H2C_PARAMETERS_ERROR; ++ ++ set_ch_parm = (struct set_ch_parm *)pbuf; ++ ++ DBG_88E(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n", ++ FUNC_NDEV_ARG(padapter->pnetdev), ++ set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset); ++ ++ pmlmeext->cur_channel = set_ch_parm->ch; ++ pmlmeext->cur_ch_offset = set_ch_parm->ch_offset; ++ pmlmeext->cur_bwmode = set_ch_parm->bw; ++ ++ set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw); ++ ++ return H2C_SUCCESS; ++} ++ ++u8 set_chplan_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ struct SetChannelPlan_param *setChannelPlan_param; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ if (!pbuf) ++ return H2C_PARAMETERS_ERROR; ++ ++ setChannelPlan_param = (struct SetChannelPlan_param *)pbuf; ++ ++ pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set); ++ init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list); ++ ++ return H2C_SUCCESS; ++} ++ ++u8 led_blink_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ if (!pbuf) ++ return H2C_PARAMETERS_ERROR; ++ return H2C_SUCCESS; ++} ++ ++u8 set_csa_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ return H2C_REJECTED; ++} ++ ++/* TDLS_WRCR : write RCR DATA BIT */ ++/* TDLS_SD_PTI : issue peer traffic indication */ ++/* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */ ++/* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */ ++/* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */ ++/* TDLS_OFF_CH : first time set channel to off channel */ ++/* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */ ++/* TDLS_P_OFF_CH : periodically go to off channel */ ++/* TDLS_P_BASE_CH : periodically go back to base channel */ ++/* TDLS_RS_RCR : restore RCR */ ++/* TDLS_CKALV_PH1 : check alive timer phase1 */ ++/* TDLS_CKALV_PH2 : check alive timer phase2 */ ++/* TDLS_FREE_STA : free tdls sta */ ++u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf) ++{ ++ return H2C_REJECTED; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c +new file mode 100644 +index 000000000000..dabdd0406f30 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_mp.c +@@ -0,0 +1,935 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_MP_C_ ++ ++#include "../include/drv_types.h" ++#include "../include/odm_precomp.h" ++#include "../include/rtl8188e_hal.h" ++ ++u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask) ++{ ++ return rtw_hal_read_bbreg(padapter, addr, bitmask); ++} ++ ++void write_bbreg(struct adapter *padapter, u32 addr, u32 bitmask, u32 val) ++{ ++ rtw_hal_write_bbreg(padapter, addr, bitmask, val); ++} ++ ++u32 _read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask) ++{ ++ return rtw_hal_read_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bitmask); ++} ++ ++void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val) ++{ ++ rtw_hal_write_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bitmask, val); ++} ++ ++u32 read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr) ++{ ++ return _read_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bRFRegOffsetMask); ++} ++ ++void write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 val) ++{ ++ _write_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bRFRegOffsetMask, val); ++} ++ ++static void _init_mp_priv_(struct mp_priv *pmp_priv) ++{ ++ struct wlan_bssid_ex *pnetwork; ++ ++ memset(pmp_priv, 0, sizeof(struct mp_priv)); ++ ++ pmp_priv->mode = MP_OFF; ++ ++ pmp_priv->channel = 1; ++ pmp_priv->bandwidth = HT_CHANNEL_WIDTH_20; ++ pmp_priv->prime_channel_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ pmp_priv->rateidx = MPT_RATE_1M; ++ pmp_priv->txpoweridx = 0x2A; ++ ++ pmp_priv->antenna_tx = ANTENNA_A; ++ pmp_priv->antenna_rx = ANTENNA_AB; ++ ++ pmp_priv->check_mp_pkt = 0; ++ ++ pmp_priv->tx_pktcount = 0; ++ ++ pmp_priv->rx_pktcount = 0; ++ pmp_priv->rx_crcerrpktcount = 0; ++ ++ pmp_priv->network_macaddr[0] = 0x00; ++ pmp_priv->network_macaddr[1] = 0xE0; ++ pmp_priv->network_macaddr[2] = 0x4C; ++ pmp_priv->network_macaddr[3] = 0x87; ++ pmp_priv->network_macaddr[4] = 0x66; ++ pmp_priv->network_macaddr[5] = 0x55; ++ ++ pnetwork = &pmp_priv->mp_network.network; ++ memcpy(pnetwork->MacAddress, pmp_priv->network_macaddr, ETH_ALEN); ++ ++ pnetwork->Ssid.SsidLength = 8; ++ memcpy(pnetwork->Ssid.Ssid, "mp_871x", pnetwork->Ssid.SsidLength); ++} ++ ++static void mp_init_xmit_attrib(struct mp_tx *pmptx, struct adapter *padapter) ++{ ++ struct pkt_attrib *pattrib; ++ struct tx_desc *desc; ++ ++ /* init xmitframe attribute */ ++ pattrib = &pmptx->attrib; ++ memset(pattrib, 0, sizeof(struct pkt_attrib)); ++ desc = &pmptx->desc; ++ memset(desc, 0, TXDESC_SIZE); ++ ++ pattrib->ether_type = 0x8712; ++ memset(pattrib->dst, 0xFF, ETH_ALEN); ++ pattrib->ack_policy = 0; ++ pattrib->hdrlen = WLAN_HDR_A3_LEN; ++ pattrib->subtype = WIFI_DATA; ++ pattrib->priority = 0; ++ pattrib->qsel = pattrib->priority; ++ pattrib->nr_frags = 1; ++ pattrib->encrypt = 0; ++ pattrib->bswenc = false; ++ pattrib->qos_en = false; ++} ++ ++s32 init_mp_priv(struct adapter *padapter) ++{ ++ struct mp_priv *pmppriv = &padapter->mppriv; ++ ++ _init_mp_priv_(pmppriv); ++ pmppriv->papdater = padapter; ++ ++ pmppriv->tx.stop = 1; ++ mp_init_xmit_attrib(&pmppriv->tx, padapter); ++ ++ switch (padapter->registrypriv.rf_config) { ++ case RF_1T1R: ++ pmppriv->antenna_tx = ANTENNA_A; ++ pmppriv->antenna_rx = ANTENNA_A; ++ break; ++ case RF_1T2R: ++ default: ++ pmppriv->antenna_tx = ANTENNA_A; ++ pmppriv->antenna_rx = ANTENNA_AB; ++ break; ++ case RF_2T2R: ++ case RF_2T2R_GREEN: ++ pmppriv->antenna_tx = ANTENNA_AB; ++ pmppriv->antenna_rx = ANTENNA_AB; ++ break; ++ case RF_2T4R: ++ pmppriv->antenna_tx = ANTENNA_AB; ++ pmppriv->antenna_rx = ANTENNA_ABCD; ++ break; ++ } ++ ++ return _SUCCESS; ++} ++ ++void free_mp_priv(struct mp_priv *pmp_priv) ++{ ++ kfree(pmp_priv->pallocated_mp_xmitframe_buf); ++ pmp_priv->pallocated_mp_xmitframe_buf = NULL; ++ pmp_priv->pmp_xmtframe_buf = NULL; ++} ++ ++#define PHY_IQCalibrate(a, b) PHY_IQCalibrate_8188E(a, b) ++#define PHY_LCCalibrate(a) PHY_LCCalibrate_8188E(a) ++#define PHY_SetRFPathSwitch(a, b) PHY_SetRFPathSwitch_8188E(a, b) ++ ++s32 MPT_InitializeAdapter(struct adapter *pAdapter, u8 Channel) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ s32 rtStatus = _SUCCESS; ++ struct mpt_context *pMptCtx = &pAdapter->mppriv.MptCtx; ++ struct mlme_priv *pmlmepriv = &pAdapter->mlmepriv; ++ ++ /* HW Initialization for 8190 MPT. */ ++ /* SW Initialization for 8190 MP. */ ++ pMptCtx->bMptDrvUnload = false; ++ pMptCtx->bMassProdTest = false; ++ pMptCtx->bMptIndexEven = true; /* default gain index is -6.0db */ ++ pMptCtx->h2cReqNum = 0x0; ++ /* Init mpt event. */ ++ /* init for BT MP */ ++ ++ pMptCtx->bMptWorkItemInProgress = false; ++ pMptCtx->CurrMptAct = NULL; ++ /* */ ++ ++ /* Don't accept any packets */ ++ rtw_write32(pAdapter, REG_RCR, 0); ++ ++ PHY_IQCalibrate(pAdapter, false); ++ dm_CheckTXPowerTracking(&pHalData->odmpriv); /* trigger thermal meter */ ++ PHY_LCCalibrate(pAdapter); ++ ++ pMptCtx->backup0xc50 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0); ++ pMptCtx->backup0xc58 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_XBAGCCore1, bMaskByte0); ++ pMptCtx->backup0xc30 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_RxDetector1, bMaskByte0); ++ pMptCtx->backup0x52_RF_A = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0); ++ pMptCtx->backup0x52_RF_B = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0); ++ ++ /* set ant to wifi side in mp mode */ ++ rtw_write16(pAdapter, 0x870, 0x300); ++ rtw_write16(pAdapter, 0x860, 0x110); ++ ++ if (pAdapter->registrypriv.mp_mode == 1) ++ pmlmepriv->fw_state = WIFI_MP_STATE; ++ ++ return rtStatus; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: MPT_DeInitAdapter() ++ * ++ * Overview: Extra DeInitialization for Mass Production Test. ++ * ++ * Input: struct adapter * pAdapter ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 05/08/2007 MHC Create Version 0. ++ * 05/18/2007 MHC Add normal driver MPHalt code. ++ * ++ *---------------------------------------------------------------------------*/ ++void MPT_DeInitAdapter(struct adapter *pAdapter) ++{ ++ struct mpt_context *pMptCtx = &pAdapter->mppriv.MptCtx; ++ ++ pMptCtx->bMptDrvUnload = true; ++} ++ ++static u8 mpt_ProStartTest(struct adapter *padapter) ++{ ++ struct mpt_context *pMptCtx = &padapter->mppriv.MptCtx; ++ ++ pMptCtx->bMassProdTest = true; ++ pMptCtx->bStartContTx = false; ++ pMptCtx->bCckContTx = false; ++ pMptCtx->bOfdmContTx = false; ++ pMptCtx->bSingleCarrier = false; ++ pMptCtx->bCarrierSuppression = false; ++ pMptCtx->bSingleTone = false; ++ ++ return _SUCCESS; ++} ++ ++/* ++ * General use ++ */ ++s32 SetPowerTracking(struct adapter *padapter, u8 enable) ++{ ++ Hal_SetPowerTracking(padapter, enable); ++ return 0; ++} ++ ++void GetPowerTracking(struct adapter *padapter, u8 *enable) ++{ ++ Hal_GetPowerTracking(padapter, enable); ++} ++ ++static void disable_dm(struct adapter *padapter) ++{ ++ u8 v8; ++ ++ /* 3 1. disable firmware dynamic mechanism */ ++ /* disable Power Training, Rate Adaptive */ ++ v8 = rtw_read8(padapter, REG_BCN_CTRL); ++ v8 &= ~EN_BCN_FUNCTION; ++ rtw_write8(padapter, REG_BCN_CTRL, v8); ++ ++ /* 3 2. disable driver dynamic mechanism */ ++ /* disable Dynamic Initial Gain */ ++ /* disable High Power */ ++ /* disable Power Tracking */ ++ Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); ++ ++ /* enable APK, LCK and IQK but disable power tracking */ ++ Switch_DM_Func(padapter, DYNAMIC_RF_CALIBRATION, true); ++} ++ ++/* This function initializes the DUT to the MP test mode */ ++s32 mp_start_test(struct adapter *padapter) ++{ ++ struct wlan_bssid_ex bssid; ++ struct sta_info *psta; ++ u32 length; ++ u8 val8; ++ s32 res = _SUCCESS; ++ struct mp_priv *pmppriv = &padapter->mppriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_network *tgt_network = &pmlmepriv->cur_network; ++ ++ padapter->registrypriv.mp_mode = 1; ++ pmppriv->bSetTxPower = 0; /* for manually set tx power */ ++ ++ /* 3 disable dynamic mechanism */ ++ disable_dm(padapter); ++ ++ /* 3 0. update mp_priv */ ++ ++ if (padapter->registrypriv.rf_config == RF_819X_MAX_TYPE) { ++ switch (GET_RF_TYPE(padapter)) { ++ case RF_1T1R: ++ pmppriv->antenna_tx = ANTENNA_A; ++ pmppriv->antenna_rx = ANTENNA_A; ++ break; ++ case RF_1T2R: ++ default: ++ pmppriv->antenna_tx = ANTENNA_A; ++ pmppriv->antenna_rx = ANTENNA_AB; ++ break; ++ case RF_2T2R: ++ case RF_2T2R_GREEN: ++ pmppriv->antenna_tx = ANTENNA_AB; ++ pmppriv->antenna_rx = ANTENNA_AB; ++ break; ++ case RF_2T4R: ++ pmppriv->antenna_tx = ANTENNA_AB; ++ pmppriv->antenna_rx = ANTENNA_ABCD; ++ break; ++ } ++ } ++ ++ mpt_ProStartTest(padapter); ++ ++ /* 3 1. initialize a new struct wlan_bssid_ex */ ++/* memset(&bssid, 0, sizeof(struct wlan_bssid_ex)); */ ++ memcpy(bssid.MacAddress, pmppriv->network_macaddr, ETH_ALEN); ++ bssid.Ssid.SsidLength = strlen("mp_pseudo_adhoc"); ++ memcpy(bssid.Ssid.Ssid, (u8 *)"mp_pseudo_adhoc", bssid.Ssid.SsidLength); ++ bssid.InfrastructureMode = Ndis802_11IBSS; ++ bssid.NetworkTypeInUse = Ndis802_11DS; ++ bssid.IELength = 0; ++ ++ length = get_wlan_bssid_ex_sz(&bssid); ++ if (length % 4) ++ bssid.Length = ((length >> 2) + 1) << 2; /* round up to multiple of 4 bytes. */ ++ else ++ bssid.Length = length; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) ++ goto end_of_mp_start_test; ++ ++ /* init mp_start_test status */ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ rtw_disassoc_cmd(padapter, 500, true); ++ rtw_indicate_disconnect(padapter); ++ rtw_free_assoc_resources(padapter, 1); ++ } ++ pmppriv->prev_fw_state = get_fwstate(pmlmepriv); ++ if (padapter->registrypriv.mp_mode == 1) ++ pmlmepriv->fw_state = WIFI_MP_STATE; ++ set_fwstate(pmlmepriv, _FW_UNDER_LINKING); ++ ++ /* 3 2. create a new psta for mp driver */ ++ /* clear psta in the cur_network, if any */ ++ psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress); ++ if (psta) ++ rtw_free_stainfo(padapter, psta); ++ ++ psta = rtw_alloc_stainfo(&padapter->stapriv, bssid.MacAddress); ++ if (!psta) { ++ pmlmepriv->fw_state = pmppriv->prev_fw_state; ++ res = _FAIL; ++ goto end_of_mp_start_test; ++ } ++ ++ /* 3 3. join psudo AdHoc */ ++ tgt_network->join_res = 1; ++ tgt_network->aid = 1; ++ psta->aid = 1; ++ memcpy(&tgt_network->network, &bssid, length); ++ ++ rtw_indicate_connect(padapter); ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); ++ ++end_of_mp_start_test: ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++ if (res == _SUCCESS) { ++ /* set MSR to WIFI_FW_ADHOC_STATE */ ++ val8 = rtw_read8(padapter, MSR) & 0xFC; /* 0x0102 */ ++ val8 |= WIFI_FW_ADHOC_STATE; ++ rtw_write8(padapter, MSR, val8); /* Link in ad hoc network */ ++ } ++ return res; ++} ++/* */ ++/* This function change the DUT from the MP test mode into normal mode */ ++void mp_stop_test(struct adapter *padapter) ++{ ++ struct mp_priv *pmppriv = &padapter->mppriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_network *tgt_network = &pmlmepriv->cur_network; ++ struct sta_info *psta; ++ ++ if (pmppriv->mode == MP_ON) { ++ pmppriv->bSetTxPower = 0; ++ spin_lock_bh(&pmlmepriv->lock); ++ if (!check_fwstate(pmlmepriv, WIFI_MP_STATE)) ++ goto end_of_mp_stop_test; ++ ++ /* 3 1. disconnect psudo AdHoc */ ++ rtw_indicate_disconnect(padapter); ++ ++ /* 3 2. clear psta used in mp test mode. */ ++ psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress); ++ if (psta) ++ rtw_free_stainfo(padapter, psta); ++ ++ /* 3 3. return to normal state (default:station mode) */ ++ pmlmepriv->fw_state = pmppriv->prev_fw_state; /* WIFI_STATION_STATE; */ ++ ++ /* flush the cur_network */ ++ memset(tgt_network, 0, sizeof(struct wlan_network)); ++ ++ _clr_fwstate_(pmlmepriv, WIFI_MP_STATE); ++ ++end_of_mp_stop_test: ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ } ++} ++ ++/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/ ++/* ++ * SetChannel ++ * Description ++ * Use H2C command to change channel, ++ * not only modify rf register, but also other setting need to be done. ++ */ ++void SetChannel(struct adapter *pAdapter) ++{ ++ Hal_SetChannel(pAdapter); ++} ++ ++/* ++ * Notice ++ * Switch bandwitdth may change center frequency(channel) ++ */ ++void SetBandwidth(struct adapter *pAdapter) ++{ ++ Hal_SetBandwidth(pAdapter); ++} ++ ++void SetAntenna(struct adapter *pAdapter) ++{ ++ Hal_SetAntenna(pAdapter); ++} ++ ++void SetAntennaPathPower(struct adapter *pAdapter) ++{ ++ Hal_SetAntennaPathPower(pAdapter); ++} ++ ++void SetTxPower(struct adapter *pAdapter) ++{ ++ Hal_SetTxPower(pAdapter); ++ } ++ ++void SetDataRate(struct adapter *pAdapter) ++{ ++ Hal_SetDataRate(pAdapter); ++} ++ ++void MP_PHY_SetRFPathSwitch(struct adapter *pAdapter, bool bMain) ++{ ++ PHY_SetRFPathSwitch(pAdapter, bMain); ++} ++ ++s32 SetThermalMeter(struct adapter *pAdapter, u8 target_ther) ++{ ++ return Hal_SetThermalMeter(pAdapter, target_ther); ++} ++ ++void GetThermalMeter(struct adapter *pAdapter, u8 *value) ++{ ++ Hal_GetThermalMeter(pAdapter, value); ++} ++ ++void SetSingleCarrierTx(struct adapter *pAdapter, u8 bStart) ++{ ++ PhySetTxPowerLevel(pAdapter); ++ Hal_SetSingleCarrierTx(pAdapter, bStart); ++} ++ ++void SetSingleToneTx(struct adapter *pAdapter, u8 bStart) ++{ ++ PhySetTxPowerLevel(pAdapter); ++ Hal_SetSingleToneTx(pAdapter, bStart); ++} ++ ++void SetCarrierSuppressionTx(struct adapter *pAdapter, u8 bStart) ++{ ++ PhySetTxPowerLevel(pAdapter); ++ Hal_SetCarrierSuppressionTx(pAdapter, bStart); ++} ++ ++void SetContinuousTx(struct adapter *pAdapter, u8 bStart) ++{ ++ PhySetTxPowerLevel(pAdapter); ++ Hal_SetContinuousTx(pAdapter, bStart); ++} ++ ++void PhySetTxPowerLevel(struct adapter *pAdapter) ++{ ++ struct mp_priv *pmp_priv = &pAdapter->mppriv; ++ ++ if (pmp_priv->bSetTxPower == 0) /* for NO manually set power index */ ++ PHY_SetTxPowerLevel8188E(pAdapter, pmp_priv->channel); ++} ++ ++/* */ ++static void dump_mpframe(struct adapter *padapter, struct xmit_frame *pmpframe) ++{ ++ rtw_hal_mgnt_xmit(padapter, pmpframe); ++} ++ ++static struct xmit_frame *alloc_mp_xmitframe(struct xmit_priv *pxmitpriv) ++{ ++ struct xmit_frame *pmpframe; ++ struct xmit_buf *pxmitbuf; ++ ++ pmpframe = rtw_alloc_xmitframe(pxmitpriv); ++ if (!pmpframe) ++ return NULL; ++ ++ pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); ++ if (!pxmitbuf) { ++ rtw_free_xmitframe(pxmitpriv, pmpframe); ++ return NULL; ++ } ++ ++ pmpframe->frame_tag = MP_FRAMETAG; ++ ++ pmpframe->pxmitbuf = pxmitbuf; ++ ++ pmpframe->buf_addr = pxmitbuf->pbuf; ++ ++ pxmitbuf->priv_data = pmpframe; ++ ++ return pmpframe; ++} ++ ++static int mp_xmit_packet_thread(void *context) ++{ ++ struct xmit_frame *pxmitframe; ++ struct mp_tx *pmptx; ++ struct mp_priv *pmp_priv; ++ struct xmit_priv *pxmitpriv; ++ struct adapter *padapter; ++ ++ pmp_priv = (struct mp_priv *)context; ++ pmptx = &pmp_priv->tx; ++ padapter = pmp_priv->papdater; ++ pxmitpriv = &padapter->xmitpriv; ++ ++ thread_enter("RTW_MP_THREAD"); ++ ++ /* DBG_88E("%s:pkTx Start\n", __func__); */ ++ while (1) { ++ pxmitframe = alloc_mp_xmitframe(pxmitpriv); ++ if (!pxmitframe) { ++ if (pmptx->stop || ++ padapter->bSurpriseRemoved || ++ padapter->bDriverStopped) { ++ goto exit; ++ } else { ++ msleep(1); ++ continue; ++ } ++ } ++ ++ memcpy((u8 *)(pxmitframe->buf_addr + TXDESC_OFFSET), pmptx->buf, pmptx->write_size); ++ memcpy(&pxmitframe->attrib, &pmptx->attrib, sizeof(struct pkt_attrib)); ++ ++ dump_mpframe(padapter, pxmitframe); ++ ++ pmptx->sended++; ++ pmp_priv->tx_pktcount++; ++ ++ if (pmptx->stop || ++ padapter->bSurpriseRemoved || ++ padapter->bDriverStopped) ++ goto exit; ++ if ((pmptx->count != 0) && ++ (pmptx->count == pmptx->sended)) ++ goto exit; ++ ++ flush_signals_thread(); ++ } ++ ++exit: ++ kfree(pmptx->pallocated_buf); ++ pmptx->pallocated_buf = NULL; ++ pmptx->stop = 1; ++ ++ thread_exit(); ++} ++ ++void fill_txdesc_for_mp(struct adapter *padapter, struct tx_desc *ptxdesc) ++{ ++ struct mp_priv *pmp_priv = &padapter->mppriv; ++ memcpy(ptxdesc, &pmp_priv->tx.desc, TXDESC_SIZE); ++} ++ ++void SetPacketTx(struct adapter *padapter) ++{ ++ u8 *ptr, *pkt_start, *pkt_end; ++ u32 pkt_size; ++ struct tx_desc *desc; ++ struct rtw_ieee80211_hdr *hdr; ++ u8 payload; ++ bool bmcast; ++ struct pkt_attrib *pattrib; ++ struct mp_priv *pmp_priv; ++ ++ pmp_priv = &padapter->mppriv; ++ if (pmp_priv->tx.stop) ++ return; ++ pmp_priv->tx.sended = 0; ++ pmp_priv->tx.stop = 0; ++ pmp_priv->tx_pktcount = 0; ++ ++ /* 3 1. update_attrib() */ ++ pattrib = &pmp_priv->tx.attrib; ++ memcpy(pattrib->src, padapter->eeprompriv.mac_addr, ETH_ALEN); ++ memcpy(pattrib->ta, pattrib->src, ETH_ALEN); ++ memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); ++ bmcast = is_multicast_ether_addr(pattrib->ra); ++ if (bmcast) { ++ pattrib->mac_id = 1; ++ pattrib->psta = rtw_get_bcmc_stainfo(padapter); ++ } else { ++ pattrib->mac_id = 0; ++ pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv)); ++ } ++ ++ pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen; ++ ++ /* 3 2. allocate xmit buffer */ ++ pkt_size = pattrib->last_txcmdsz; ++ ++ kfree(pmp_priv->tx.pallocated_buf); ++ pmp_priv->tx.write_size = pkt_size; ++ pmp_priv->tx.buf_size = pkt_size + XMITBUF_ALIGN_SZ; ++ pmp_priv->tx.pallocated_buf = kzalloc(pmp_priv->tx.buf_size, GFP_KERNEL); ++ if (!pmp_priv->tx.pallocated_buf) { ++ DBG_88E("%s: malloc(%d) fail!!\n", __func__, pmp_priv->tx.buf_size); ++ return; ++ } ++ pmp_priv->tx.buf = (u8 *)N_BYTE_ALIGMENT((size_t)(pmp_priv->tx.pallocated_buf), XMITBUF_ALIGN_SZ); ++ ptr = pmp_priv->tx.buf; ++ ++ desc = &pmp_priv->tx.desc; ++ memset(desc, 0, TXDESC_SIZE); ++ pkt_start = ptr; ++ pkt_end = pkt_start + pkt_size; ++ ++ /* 3 3. init TX descriptor */ ++ /* offset 0 */ ++ desc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); ++ desc->txdw0 |= cpu_to_le32(pkt_size & 0x0000FFFF); /* packet size */ ++ desc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00FF0000); /* 32 bytes for TX Desc */ ++ if (bmcast) ++ desc->txdw0 |= cpu_to_le32(BMC); /* broadcast packet */ ++ ++ desc->txdw1 |= cpu_to_le32((0x01 << 26) & 0xff000000); ++ /* offset 4 */ ++ desc->txdw1 |= cpu_to_le32((pattrib->mac_id) & 0x3F); /* CAM_ID(MAC_ID) */ ++ desc->txdw1 |= cpu_to_le32((pattrib->qsel << QSEL_SHT) & 0x00001F00); /* Queue Select, TID */ ++ ++ desc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000F0000); /* Rate Adaptive ID */ ++ /* offset 8 */ ++ /* offset 12 */ ++ ++ desc->txdw3 |= cpu_to_le32((pattrib->seqnum << 16) & 0x0fff0000); ++ ++ /* offset 16 */ ++ desc->txdw4 |= cpu_to_le32(HW_SSN); ++ desc->txdw4 |= cpu_to_le32(USERATE); ++ desc->txdw4 |= cpu_to_le32(DISDATAFB); ++ ++ if (pmp_priv->preamble) { ++ if (pmp_priv->rateidx <= MPT_RATE_54M) ++ desc->txdw4 |= cpu_to_le32(DATA_SHORT); /* CCK Short Preamble */ ++ } ++ if (pmp_priv->bandwidth == HT_CHANNEL_WIDTH_40) ++ desc->txdw4 |= cpu_to_le32(DATA_BW); ++ ++ /* offset 20 */ ++ desc->txdw5 |= cpu_to_le32(pmp_priv->rateidx & 0x0000001F); ++ ++ if (pmp_priv->preamble) { ++ if (pmp_priv->rateidx > MPT_RATE_54M) ++ desc->txdw5 |= cpu_to_le32(SGI); /* MCS Short Guard Interval */ ++ } ++ desc->txdw5 |= cpu_to_le32(RTY_LMT_EN); /* retry limit enable */ ++ desc->txdw5 |= cpu_to_le32(0x00180000); /* DATA/RTS Rate Fallback Limit */ ++ ++ /* 3 4. make wlan header, make_wlanhdr() */ ++ hdr = (struct rtw_ieee80211_hdr *)pkt_start; ++ SetFrameSubType(&hdr->frame_ctl, pattrib->subtype); ++ memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); /* DA */ ++ memcpy(hdr->addr2, pattrib->src, ETH_ALEN); /* SA */ ++ memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); /* RA, BSSID */ ++ ++ /* 3 5. make payload */ ++ ptr = pkt_start + pattrib->hdrlen; ++ ++ switch (pmp_priv->tx.payload) { ++ case 0: ++ payload = 0x00; ++ break; ++ case 1: ++ payload = 0x5a; ++ break; ++ case 2: ++ payload = 0xa5; ++ break; ++ case 3: ++ payload = 0xff; ++ break; ++ default: ++ payload = 0x00; ++ break; ++ } ++ ++ memset(ptr, payload, pkt_end - ptr); ++ ++ /* 3 6. start thread */ ++ pmp_priv->tx.PktTxThread = kthread_run(mp_xmit_packet_thread, pmp_priv, "RTW_MP_THREAD"); ++ if (IS_ERR(pmp_priv->tx.PktTxThread)) ++ DBG_88E("Create PktTx Thread Fail !!!!!\n"); ++} ++ ++void SetPacketRx(struct adapter *pAdapter, u8 bStartRx) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ ++ if (bStartRx) { ++ /* Accept CRC error and destination address */ ++ pHalData->ReceiveConfig = AAP | APM | AM | AB | APP_ICV | ++ AMF | ADF | APP_FCS | HTC_LOC_CTRL | ++ APP_MIC | APP_PHYSTS; ++ ++ pHalData->ReceiveConfig |= (RCR_ACRC32 | RCR_AAP); ++ ++ rtw_write32(pAdapter, REG_RCR, pHalData->ReceiveConfig); ++ ++ /* Accept all data frames */ ++ rtw_write16(pAdapter, REG_RXFLTMAP2, 0xFFFF); ++ } else { ++ rtw_write32(pAdapter, REG_RCR, 0); ++ } ++} ++ ++void ResetPhyRxPktCount(struct adapter *pAdapter) ++{ ++ u32 i, phyrx_set = 0; ++ ++ for (i = 0; i <= 0xF; i++) { ++ phyrx_set = 0; ++ phyrx_set |= _RXERR_RPT_SEL(i); /* select */ ++ phyrx_set |= RXERR_RPT_RST; /* set counter to zero */ ++ rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set); ++ } ++} ++ ++static u32 GetPhyRxPktCounts(struct adapter *pAdapter, u32 selbit) ++{ ++ /* selection */ ++ u32 phyrx_set = 0, count = 0; ++ ++ phyrx_set = _RXERR_RPT_SEL(selbit & 0xF); ++ rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set); ++ ++ /* Read packet count */ ++ count = rtw_read32(pAdapter, REG_RXERR_RPT) & RXERR_COUNTER_MASK; ++ ++ return count; ++} ++ ++u32 GetPhyRxPktReceived(struct adapter *pAdapter) ++{ ++ u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0; ++ ++ OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_OK); ++ CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_OK); ++ HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_OK); ++ ++ return OFDM_cnt + CCK_cnt + HT_cnt; ++} ++ ++u32 GetPhyRxPktCRC32Error(struct adapter *pAdapter) ++{ ++ u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0; ++ ++ OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_FAIL); ++ CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_FAIL); ++ HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_FAIL); ++ ++ return OFDM_cnt + CCK_cnt + HT_cnt; ++} ++ ++/* reg 0x808[9:0]: FFT data x */ ++/* reg 0x808[22]: 0 --> 1 to get 1 FFT data y */ ++/* reg 0x8B4[15:0]: FFT data y report */ ++static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point) ++{ ++ int psd_val; ++ ++ psd_val = rtw_read32(pAdapter, 0x808); ++ psd_val &= 0xFFBFFC00; ++ psd_val |= point; ++ ++ rtw_write32(pAdapter, 0x808, psd_val); ++ mdelay(1); ++ psd_val |= 0x00400000; ++ ++ rtw_write32(pAdapter, 0x808, psd_val); ++ mdelay(1); ++ psd_val = rtw_read32(pAdapter, 0x8B4); ++ ++ psd_val &= 0x0000FFFF; ++ ++ return psd_val; ++} ++ ++/* ++ *pts start_point_min stop_point_max ++ * 128 64 64 + 128 = 192 ++ * 256 128 128 + 256 = 384 ++ * 512 256 256 + 512 = 768 ++ * 1024 512 512 + 1024 = 1536 ++ */ ++u32 mp_query_psd(struct adapter *pAdapter, u8 *data) ++{ ++ u32 i, psd_pts = 0, psd_start = 0, psd_stop = 0; ++ u32 psd_data = 0; ++ ++ if (!netif_running(pAdapter->pnetdev)) ++ return 0; ++ ++ if (!check_fwstate(&pAdapter->mlmepriv, WIFI_MP_STATE)) ++ return 0; ++ ++ if (strlen(data) == 0) { /* default value */ ++ psd_pts = 128; ++ psd_start = 64; ++ psd_stop = 128; ++ } else { ++ sscanf(data, "pts =%d, start =%d, stop =%d", &psd_pts, &psd_start, &psd_stop); ++ } ++ ++ memset(data, '\0', sizeof(*data)); ++ ++ i = psd_start; ++ while (i < psd_stop) { ++ if (i >= psd_pts) { ++ psd_data = rtw_GetPSDData(pAdapter, i - psd_pts); ++ } else { ++ psd_data = rtw_GetPSDData(pAdapter, i); ++ } ++ sprintf(data + strlen(data), "%x ", psd_data); ++ i++; ++ } ++ ++ msleep(100); ++ return strlen(data) + 1; ++} ++ ++void _rtw_mp_xmit_priv(struct xmit_priv *pxmitpriv) ++{ ++ int i, res; ++ struct adapter *padapter = pxmitpriv->adapter; ++ struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; ++ u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; ++ u32 num_xmit_extbuf = NR_XMIT_EXTBUFF; ++ ++ if (padapter->registrypriv.mp_mode == 0) { ++ max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; ++ num_xmit_extbuf = NR_XMIT_EXTBUFF; ++ } else { ++ max_xmit_extbuf_size = 6000; ++ num_xmit_extbuf = 8; ++ } ++ ++ pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; ++ for (i = 0; i < num_xmit_extbuf; i++) { ++ rtw_os_xmit_resource_free(padapter, pxmitbuf, (max_xmit_extbuf_size + XMITBUF_ALIGN_SZ)); ++ ++ pxmitbuf++; ++ } ++ ++ vfree(pxmitpriv->pallocated_xmit_extbuf); ++ ++ if (padapter->registrypriv.mp_mode == 0) { ++ max_xmit_extbuf_size = 6000; ++ num_xmit_extbuf = 8; ++ } else { ++ max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; ++ num_xmit_extbuf = NR_XMIT_EXTBUFF; ++ } ++ ++ /* Init xmit extension buff */ ++ _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue); ++ ++ pxmitpriv->pallocated_xmit_extbuf = vzalloc(num_xmit_extbuf * sizeof(struct xmit_buf) + 4); ++ ++ if (!pxmitpriv->pallocated_xmit_extbuf) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_xmit_extbuf), 4); ++ ++ pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; ++ ++ for (i = 0; i < num_xmit_extbuf; i++) { ++ INIT_LIST_HEAD(&pxmitbuf->list); ++ ++ pxmitbuf->priv_data = NULL; ++ pxmitbuf->padapter = padapter; ++ pxmitbuf->ext_tag = true; ++ ++ res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ); ++ if (res == _FAIL) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmit_extbuf_queue.queue); ++ pxmitbuf++; ++ } ++ ++ pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf; ++ ++exit: ++ ; ++} ++ ++void Hal_ProSetCrystalCap(struct adapter *pAdapter, u32 CrystalCapVal) ++{ ++ CrystalCapVal = CrystalCapVal & 0x3F; ++ ++ // write 0x24[16:11] = 0x24[22:17] = CrystalCap ++ PHY_SetBBReg(pAdapter, REG_AFE_XTAL_CTRL, 0x7FF800, ++ (CrystalCapVal | (CrystalCapVal << 6))); ++} +diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c +new file mode 100644 +index 000000000000..c85f8e467337 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c +@@ -0,0 +1,1170 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_MP_IOCTL_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/mlme_osdep.h" ++#include "../include/rtw_mp_ioctl.h" ++ ++/* rtl8188eu_oid_rtl_seg_81_85 section start **************** */ ++int rtl8188eu_oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->information_buf_len < sizeof(u8)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ if (poid_par_priv->type_of_oid == SET_OID) { ++ Adapter->registrypriv.wireless_mode = *(u8 *)poid_par_priv->information_buf; ++ } else if (poid_par_priv->type_of_oid == QUERY_OID) { ++ *(u8 *)poid_par_priv->information_buf = Adapter->registrypriv.wireless_mode; ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ } else { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ } ++ ++ return status; ++} ++/* rtl8188eu_oid_rtl_seg_81_87_80 section start **************** */ ++int rtl8188eu_oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct bb_reg_param *pbbreg; ++ u16 offset; ++ u32 value; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf); ++ ++ offset = (u16)(pbbreg->offset) & 0xFFF; /* 0ffset :0x800~0xfff */ ++ if (offset < BB_REG_BASE_ADDR) ++ offset |= BB_REG_BASE_ADDR; ++ ++ value = pbbreg->value; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ write_bbreg(Adapter, offset, 0xFFFFFFFF, value); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct bb_reg_param *pbbreg; ++ u16 offset; ++ u32 value; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf); ++ ++ offset = (u16)(pbbreg->offset) & 0xFFF; /* 0ffset :0x800~0xfff */ ++ if (offset < BB_REG_BASE_ADDR) ++ offset |= BB_REG_BASE_ADDR; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ value = read_bbreg(Adapter, offset, 0xFFFFFFFF); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ pbbreg->value = value; ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct rf_reg_param *pbbreg; ++ u8 path; ++ u8 offset; ++ u32 value; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf); ++ ++ if (pbbreg->path >= RF_PATH_MAX) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ if (pbbreg->offset > 0xFF) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ if (pbbreg->value > 0xFFFFF) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ path = (u8)pbbreg->path; ++ offset = (u8)pbbreg->offset; ++ value = pbbreg->value; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ write_rfreg(Adapter, path, offset, value); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct rf_reg_param *pbbreg; ++ u8 path; ++ u8 offset; ++ u32 value; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ int status = NDIS_STATUS_SUCCESS; ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf); ++ ++ if (pbbreg->path >= RF_PATH_MAX) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ if (pbbreg->offset > 0xFF) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ path = (u8)pbbreg->path; ++ offset = (u8)pbbreg->offset; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ value = read_rfreg(Adapter, path, offset); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ pbbreg->value = value; ++ ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ ++ return status; ++} ++/* rtl8188eu_oid_rtl_seg_81_87_00 section end**************** */ ++/* */ ++ ++/* rtl8188eu_oid_rtl_seg_81_80_00 section start **************** */ ++/* */ ++int rtl8188eu_oid_rt_pro_set_data_rate_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 ratevalue;/* 4 */ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len != sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ ratevalue = *((u32 *)poid_par_priv->information_buf);/* 4 */ ++ if (ratevalue >= MPT_RATE_LAST) ++ return NDIS_STATUS_INVALID_DATA; ++ ++ Adapter->mppriv.rateidx = ratevalue; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetDataRate(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 mode; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (Adapter->registrypriv.mp_mode == 0) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ++ /* IQCalibrateBcut(Adapter); */ ++ ++ mode = *((u32 *)poid_par_priv->information_buf); ++ Adapter->mppriv.mode = mode;/* 1 for loopback */ ++ ++ if (mp_start_test(Adapter) == _FAIL) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ goto exit; ++ } ++ ++exit: ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ mp_stop_test(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 Channel; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->information_buf_len != sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ if (poid_par_priv->type_of_oid == QUERY_OID) { ++ *((u32 *)poid_par_priv->information_buf) = Adapter->mppriv.channel; ++ return NDIS_STATUS_SUCCESS; ++ } ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ Channel = *((u32 *)poid_par_priv->information_buf); ++ if (Channel > 14) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ Adapter->mppriv.channel = Channel; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetChannel(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u16 bandwidth; ++ u16 channel_offset; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *padapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ bandwidth = *((u32 *)poid_par_priv->information_buf);/* 4 */ ++ channel_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ ++ if (bandwidth != HT_CHANNEL_WIDTH_40) ++ bandwidth = HT_CHANNEL_WIDTH_20; ++ padapter->mppriv.bandwidth = (u8)bandwidth; ++ padapter->mppriv.prime_channel_offset = (u8)channel_offset; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetBandwidth(padapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 antenna; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->information_buf_len != sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ if (poid_par_priv->type_of_oid == SET_OID) { ++ antenna = *(u32 *)poid_par_priv->information_buf; ++ ++ Adapter->mppriv.antenna_tx = (u16)((antenna & 0xFFFF0000) >> 16); ++ Adapter->mppriv.antenna_rx = (u16)(antenna & 0x0000FFFF); ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetAntenna(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ } else { ++ antenna = (Adapter->mppriv.antenna_tx << 16) | Adapter->mppriv.antenna_rx; ++ *(u32 *)poid_par_priv->information_buf = antenna; ++ } ++ ++ return status; ++} ++ ++int rtl8188eu_oid_rt_pro_set_tx_power_control_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 tx_pwr_idx; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len != sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ tx_pwr_idx = *((u32 *)poid_par_priv->information_buf); ++ if (tx_pwr_idx > MAX_TX_PWR_INDEX_N_MODE) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ Adapter->mppriv.txpoweridx = (u8)tx_pwr_idx; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetTxPower(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++ ++/* */ ++/* rtl8188eu_oid_rtl_seg_81_80_20 section start **************** */ ++/* */ ++int rtl8188eu_oid_rt_pro_query_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ return status; ++ } ++ ++ if (poid_par_priv->information_buf_len == sizeof(u32)) { ++ *(u32 *)poid_par_priv->information_buf = Adapter->mppriv.tx_pktcount; ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ } else { ++ status = NDIS_STATUS_INVALID_LENGTH; ++ } ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_query_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ return status; ++ } ++ if (poid_par_priv->information_buf_len == sizeof(u32)) { ++ *(u32 *)poid_par_priv->information_buf = Adapter->mppriv.rx_pktcount; ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ } else { ++ status = NDIS_STATUS_INVALID_LENGTH; ++ } ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_query_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ return status; ++ } ++ if (poid_par_priv->information_buf_len == sizeof(u32)) { ++ *(u32 *)poid_par_priv->information_buf = Adapter->mppriv.rx_crcerrpktcount; ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ } else { ++ status = NDIS_STATUS_INVALID_LENGTH; ++ } ++ ++ return status; ++} ++/* */ ++ ++int rtl8188eu_oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ return status; ++ } ++ ++ Adapter->mppriv.tx_pktcount = 0; ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ return status; ++ } ++ ++ if (poid_par_priv->information_buf_len == sizeof(u32)) { ++ Adapter->mppriv.rx_pktcount = 0; ++ Adapter->mppriv.rx_crcerrpktcount = 0; ++ } else { ++ status = NDIS_STATUS_INVALID_LENGTH; ++ } ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ return status; ++ } ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ResetPhyRxPktCount(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len != sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ *(u32 *)poid_par_priv->information_buf = GetPhyRxPktReceived(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len != sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ *(u32 *)poid_par_priv->information_buf = GetPhyRxPktCRC32Error(Adapter); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ ++ return status; ++} ++/* rtl8188eu_oid_rtl_seg_81_80_20 section end **************** */ ++int rtl8188eu_oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 bStartTest; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ bStartTest = *((u32 *)poid_par_priv->information_buf); ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetContinuousTx(Adapter, (u8)bStartTest); ++ if (bStartTest) { ++ struct mp_priv *pmp_priv = &Adapter->mppriv; ++ if (pmp_priv->tx.stop == 0) { ++ pmp_priv->tx.stop = 1; ++ DBG_88E("%s: pkt tx is running...\n", __func__); ++ msleep(5); ++ } ++ pmp_priv->tx.stop = 0; ++ pmp_priv->tx.count = 1; ++ SetPacketTx(Adapter); ++ } ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++ ++int rtl8188eu_oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 bStartTest; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ bStartTest = *((u32 *)poid_par_priv->information_buf); ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetSingleCarrierTx(Adapter, (u8)bStartTest); ++ if (bStartTest) { ++ struct mp_priv *pmp_priv = &Adapter->mppriv; ++ if (pmp_priv->tx.stop == 0) { ++ pmp_priv->tx.stop = 1; ++ DBG_88E("%s: pkt tx is running...\n", __func__); ++ msleep(5); ++ } ++ pmp_priv->tx.stop = 0; ++ pmp_priv->tx.count = 1; ++ SetPacketTx(Adapter); ++ } ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++ ++int rtl8188eu_oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 bStartTest; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ bStartTest = *((u32 *)poid_par_priv->information_buf); ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetCarrierSuppressionTx(Adapter, (u8)bStartTest); ++ if (bStartTest) { ++ struct mp_priv *pmp_priv = &Adapter->mppriv; ++ if (pmp_priv->tx.stop == 0) { ++ pmp_priv->tx.stop = 1; ++ DBG_88E("%s: pkt tx is running...\n", __func__); ++ msleep(5); ++ } ++ pmp_priv->tx.stop = 0; ++ pmp_priv->tx.count = 1; ++ SetPacketTx(Adapter); ++ } ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++ ++int rtl8188eu_oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u32 bStartTest; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ bStartTest = *((u32 *)poid_par_priv->information_buf); ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ SetSingleToneTx(Adapter, (u8)bStartTest); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++ ++int rtl8188eu_oid_rt_pro_set_modulation_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++int rtl8188eu_oid_rt_pro_trigger_gpio_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ int status = NDIS_STATUS_SUCCESS; ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ rtw_hal_set_hwreg(Adapter, HW_VAR_TRIGGER_GPIO_0, NULL); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* rtl8188eu_oid_rtl_seg_81_80_00 section end **************** */ ++/* */ ++int rtl8188eu_oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct mp_rw_reg *RegRWStruct; ++ u32 offset, width; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf; ++ offset = RegRWStruct->offset; ++ width = RegRWStruct->width; ++ ++ if (offset > 0xFFF) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ++ switch (width) { ++ case 1: ++ RegRWStruct->value = rtw_read8(Adapter, offset); ++ break; ++ case 2: ++ RegRWStruct->value = rtw_read16(Adapter, offset); ++ break; ++ default: ++ width = 4; ++ RegRWStruct->value = rtw_read32(Adapter, offset); ++ break; ++ } ++ ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ *poid_par_priv->bytes_rw = width; ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct mp_rw_reg *RegRWStruct; ++ u32 offset, value; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *padapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf; ++ offset = RegRWStruct->offset; ++ value = RegRWStruct->value; ++ ++ if (offset > 0xFFF) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ++ switch (RegRWStruct->width) { ++ case 1: ++ if (value > 0xFF) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ break; ++ } ++ rtw_write8(padapter, offset, (u8)value); ++ break; ++ case 2: ++ if (value > 0xFFFF) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ break; ++ } ++ rtw_write16(padapter, offset, (u16)value); ++ break; ++ case 4: ++ rtw_write32(padapter, offset, value); ++ break; ++ default: ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ break; ++ } ++ ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_burst_read_register_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_burst_write_register_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++/* */ ++int rtl8188eu_oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++/* */ ++int rtl8188eu_oid_rt_pro_write16_eeprom_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_wr_attrib_mem_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_cfg_debug_message_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_set_data_rate_ex_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ int status = NDIS_STATUS_SUCCESS; ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ++ if (rtw_setdatarate_cmd(Adapter, poid_par_priv->information_buf) != _SUCCESS) ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ u8 thermal = 0; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ GetThermalMeter(Adapter, &thermal); ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ *(u32 *)poid_par_priv->information_buf = (u32)thermal; ++ *poid_par_priv->bytes_rw = sizeof(u32); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_read_tssi_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_set_power_tracking_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->information_buf_len < sizeof(u8)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ if (poid_par_priv->type_of_oid == SET_OID) { ++ u8 enable; ++ ++ enable = *(u8 *)poid_par_priv->information_buf; ++ ++ SetPowerTracking(Adapter, enable); ++ } else { ++ GetPowerTracking(Adapter, (u8 *)poid_par_priv->information_buf); ++ } ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_set_basic_rate_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_qry_pwrstate_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_set_pwrstate_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_h2c_set_rate_table_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_h2c_get_rate_table_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++/* rtl8188eu_oid_rtl_seg_87_12_00 section start **************** */ ++int rtl8188eu_oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++int rtl8188eu_oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++int rtl8188eu_oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++int rtl8188eu_oid_rt_pro_query_dr_variable_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++int rtl8188eu_oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return NDIS_STATUS_SUCCESS; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct efuse_access_struct *pefuse; ++ u8 *data; ++ u16 addr = 0, cnts = 0, max_available_size = 0; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(struct efuse_access_struct)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ pefuse = (struct efuse_access_struct *)poid_par_priv->information_buf; ++ addr = pefuse->start_addr; ++ cnts = pefuse->cnts; ++ data = pefuse->data; ++ ++ EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ ++ if ((addr + cnts) > max_available_size) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ if (rtw_efuse_access(Adapter, false, addr, cnts, data) == _FAIL) ++ status = NDIS_STATUS_FAILURE; ++ else ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct efuse_access_struct *pefuse; ++ u8 *data; ++ u16 addr = 0, cnts = 0, max_available_size = 0; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ pefuse = (struct efuse_access_struct *)poid_par_priv->information_buf; ++ addr = pefuse->start_addr; ++ cnts = pefuse->cnts; ++ data = pefuse->data; ++ ++ EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ ++ if ((addr + cnts) > max_available_size) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ if (rtw_efuse_access(Adapter, true, addr, cnts, data) == _FAIL) ++ status = NDIS_STATUS_FAILURE; ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct pgpkt *ppgpkt; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ *poid_par_priv->bytes_rw = 0; ++ ++ if (poid_par_priv->information_buf_len < sizeof(struct pgpkt *)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ ppgpkt = (struct pgpkt *)poid_par_priv->information_buf; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ++ if (poid_par_priv->type_of_oid == QUERY_OID) { ++ Efuse_PowerSwitch(Adapter, false, true); ++ if (Efuse_PgPacketRead(Adapter, ppgpkt->offset, ppgpkt->data, false)) ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ else ++ status = NDIS_STATUS_FAILURE; ++ Efuse_PowerSwitch(Adapter, false, false); ++ } else { ++ Efuse_PowerSwitch(Adapter, true, true); ++ if (Efuse_PgPacketWrite(Adapter, ppgpkt->offset, ppgpkt->word_en, ppgpkt->data, false)) ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ else ++ status = NDIS_STATUS_FAILURE; ++ Efuse_PowerSwitch(Adapter, true, false); ++ } ++ ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_get_efuse_current_size_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u16 size; ++ u8 ret; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ret = efuse_GetCurrentSize(Adapter, &size); ++ _irqlevel_changed_(&oldirql, RAISE); ++ if (ret == _SUCCESS) { ++ *(u32 *)poid_par_priv->information_buf = size; ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ } else { ++ status = NDIS_STATUS_FAILURE; ++ } ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ ++ if (poid_par_priv->type_of_oid != QUERY_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(u32)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ *(u32 *)poid_par_priv->information_buf = efuse_GetMaxSize(Adapter); ++ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status; ++ ++ if (poid_par_priv->type_of_oid == QUERY_OID) ++ status = rtl8188eu_oid_rt_pro_read_efuse_hdl(poid_par_priv); ++ else ++ status = rtl8188eu_oid_rt_pro_write_efuse_hdl(poid_par_priv); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ u8 *data; ++ int status = NDIS_STATUS_SUCCESS; ++ struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context); ++ u16 maplen = 0; ++ ++ EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&maplen, false); ++ ++ *poid_par_priv->bytes_rw = 0; ++ ++ if (poid_par_priv->information_buf_len < maplen) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ data = (u8 *)poid_par_priv->information_buf; ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ++ if (poid_par_priv->type_of_oid == QUERY_OID) { ++ if (rtw_efuse_map_read(Adapter, 0, maplen, data) == _SUCCESS) ++ *poid_par_priv->bytes_rw = maplen; ++ else ++ status = NDIS_STATUS_FAILURE; ++ } else { ++ /* SET_OID */ ++ if (rtw_efuse_map_write(Adapter, 0, maplen, data) == _SUCCESS) ++ *poid_par_priv->bytes_rw = maplen; ++ else ++ status = NDIS_STATUS_FAILURE; ++ } ++ ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++ ++int rtl8188eu_oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ return status; ++} ++ ++int rtl8188eu_oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ ++ if (poid_par_priv->type_of_oid != SET_OID) ++ return NDIS_STATUS_NOT_ACCEPTED; ++ ++ if (poid_par_priv->information_buf_len < sizeof(u8)) ++ return NDIS_STATUS_INVALID_LENGTH; ++ ++ return status; ++} ++ ++int rtl8188eu_oid_rt_pro_set_tx_agc_offset_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++int rtl8188eu_oid_rt_pro_set_pkt_test_mode_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} ++ ++int rtl8188eu_mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ struct mp_xmit_parm *pparm; ++ struct adapter *padapter; ++ struct mp_priv *pmp_priv; ++ struct pkt_attrib *pattrib; ++ ++ pparm = (struct mp_xmit_parm *)poid_par_priv->information_buf; ++ padapter = (struct adapter *)poid_par_priv->adapter_context; ++ pmp_priv = &padapter->mppriv; ++ ++ if (poid_par_priv->type_of_oid == QUERY_OID) { ++ pparm->enable = !pmp_priv->tx.stop; ++ pparm->count = pmp_priv->tx.sended; ++ } else { ++ if (pparm->enable == 0) { ++ pmp_priv->tx.stop = 1; ++ } else if (pmp_priv->tx.stop == 1) { ++ pmp_priv->tx.stop = 0; ++ pmp_priv->tx.count = pparm->count; ++ pmp_priv->tx.payload = pparm->payload_type; ++ pattrib = &pmp_priv->tx.attrib; ++ pattrib->pktlen = pparm->length; ++ memcpy(pattrib->dst, pparm->da, ETH_ALEN); ++ SetPacketTx(padapter); ++ } else { ++ return NDIS_STATUS_FAILURE; ++ } ++ } ++ ++ return NDIS_STATUS_SUCCESS; ++} ++ ++/* */ ++int rtl8188eu_oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ int status = NDIS_STATUS_SUCCESS; ++ ++ if (poid_par_priv->type_of_oid != SET_OID) { ++ status = NDIS_STATUS_NOT_ACCEPTED; ++ return status; ++ } ++ ++ _irqlevel_changed_(&oldirql, LOWER); ++ ++ /* CALL the power_down function */ ++ _irqlevel_changed_(&oldirql, RAISE); ++ ++ return status; ++} ++/* */ ++int rtl8188eu_oid_rt_get_power_mode_hdl(struct oid_par_priv *poid_par_priv) ++{ ++ return 0; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_p2p.c b/drivers/staging/r8188eu/core/rtw_p2p.c +new file mode 100644 +index 000000000000..e2b6cf2386e0 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_p2p.c +@@ -0,0 +1,1997 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_P2P_C_ ++ ++#include "../include/drv_types.h" ++#include "../include/rtw_p2p.h" ++#include "../include/wifi.h" ++ ++#ifdef CONFIG_88EU_P2P ++ ++static int rtw_p2p_is_channel_list_ok(u8 desired_ch, u8 *ch_list, u8 ch_cnt) ++{ ++ int found = 0, i = 0; ++ ++ for (i = 0; i < ch_cnt; i++) { ++ if (ch_list[i] == desired_ch) { ++ found = 1; ++ break; ++ } ++ } ++ return found; ++} ++ ++static u32 go_add_group_info_attr(struct wifidirect_info *pwdinfo, u8 *pbuf) ++{ ++ struct list_head *phead, *plist; ++ u32 len = 0; ++ u16 attr_len = 0; ++ u8 tmplen, *pdata_attr, *pstart, *pcur; ++ struct sta_info *psta = NULL; ++ struct adapter *padapter = pwdinfo->padapter; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ DBG_88E("%s\n", __func__); ++ ++ pdata_attr = kzalloc(MAX_P2P_IE_LEN, GFP_KERNEL); ++ ++ pstart = pdata_attr; ++ pcur = pdata_attr; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ phead = &pstapriv->asoc_list; ++ plist = phead->next; ++ ++ /* look up sta asoc_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, asoc_list); ++ ++ plist = plist->next; ++ ++ if (psta->is_p2p_device) { ++ tmplen = 0; ++ ++ pcur++; ++ ++ /* P2P device address */ ++ memcpy(pcur, psta->dev_addr, ETH_ALEN); ++ pcur += ETH_ALEN; ++ ++ /* P2P interface address */ ++ memcpy(pcur, psta->hwaddr, ETH_ALEN); ++ pcur += ETH_ALEN; ++ ++ *pcur = psta->dev_cap; ++ pcur++; ++ ++ /* u16*)(pcur) = cpu_to_be16(psta->config_methods); */ ++ RTW_PUT_BE16(pcur, psta->config_methods); ++ pcur += 2; ++ ++ memcpy(pcur, psta->primary_dev_type, 8); ++ pcur += 8; ++ ++ *pcur = psta->num_of_secdev_type; ++ pcur++; ++ ++ memcpy(pcur, psta->secdev_types_list, psta->num_of_secdev_type * 8); ++ pcur += psta->num_of_secdev_type * 8; ++ ++ if (psta->dev_name_len > 0) { ++ /* u16*)(pcur) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */ ++ RTW_PUT_BE16(pcur, WPS_ATTR_DEVICE_NAME); ++ pcur += 2; ++ ++ /* u16*)(pcur) = cpu_to_be16(psta->dev_name_len); */ ++ RTW_PUT_BE16(pcur, psta->dev_name_len); ++ pcur += 2; ++ ++ memcpy(pcur, psta->dev_name, psta->dev_name_len); ++ pcur += psta->dev_name_len; ++ } ++ ++ tmplen = (u8)(pcur - pstart); ++ ++ *pstart = (tmplen - 1); ++ ++ attr_len += tmplen; ++ ++ /* pstart += tmplen; */ ++ pstart = pcur; ++ } ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ ++ if (attr_len > 0) ++ len = rtw_set_p2p_attr_content(pbuf, P2P_ATTR_GROUP_INFO, attr_len, pdata_attr); ++ ++ kfree(pdata_attr); ++ return len; ++} ++ ++static void issue_group_disc_req(struct wifidirect_info *pwdinfo, u8 *da) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct adapter *padapter = pwdinfo->padapter; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ unsigned char category = RTW_WLAN_CATEGORY_P2P;/* P2P action frame */ ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_GO_DISC_REQUEST; ++ u8 dialogToken = 0; ++ ++ DBG_88E("[%s]\n", __func__); ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ /* Build P2P action frame header */ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen); ++ ++ /* there is no IE in this P2P action frame */ ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct adapter *padapter = pwdinfo->padapter; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_DEVDISC_RESP; ++ u8 p2pie[8] = { 0x00 }; ++ u32 p2pielen = 0; ++ ++ DBG_88E("[%s]\n", __func__); ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, pwdinfo->device_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, pwdinfo->device_addr, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ /* Build P2P public action frame header */ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen); ++ ++ /* Build P2P IE */ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* P2P_ATTR_STATUS */ ++ p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status); ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8 *raddr, u8 *frame_body, u16 config_method) ++{ ++ struct adapter *padapter = pwdinfo->padapter; ++ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; ++ u8 action = P2P_PUB_ACTION_ACTION; ++ u8 dialogToken = frame_body[7]; /* The Dialog Token of provisioning discovery request frame. */ ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_PROVISION_DISC_RESP; ++ u8 wpsie[100] = { 0x00 }; ++ u8 wpsielen = 0; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen); ++ ++ wpsielen = 0; ++ /* WPS OUI */ ++ RTW_PUT_BE32(wpsie, WPSOUI); ++ wpsielen += 4; ++ ++ /* Config Method */ ++ /* Type: */ ++ RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD); ++ wpsielen += 2; ++ ++ /* Length: */ ++ RTW_PUT_BE16(wpsie + wpsielen, 0x0002); ++ wpsielen += 2; ++ ++ /* Value: */ ++ RTW_PUT_BE16(wpsie + wpsielen, config_method); ++ wpsielen += 2; ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken) ++{ ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ unsigned char *pframe; ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ struct adapter *padapter = pwdinfo->padapter; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ unsigned char category = RTW_WLAN_CATEGORY_P2P;/* P2P action frame */ ++ __be32 p2poui = cpu_to_be32(P2POUI); ++ u8 oui_subtype = P2P_PRESENCE_RESPONSE; ++ u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 }; ++ u8 noa_attr_content[32] = { 0x00 }; ++ u32 p2pielen = 0; ++ ++ DBG_88E("[%s]\n", __func__); ++ ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ return; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(padapter, pattrib); ++ ++ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); ++ ++ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, da, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); ++ pmlmeext->mgnt_seq++; ++ SetFrameSubType(pframe, WIFI_ACTION); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ /* Build P2P action frame header */ ++ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen); ++ pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen); ++ ++ /* Add P2P IE header */ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Add Status attribute in P2P IE */ ++ p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status); ++ ++ /* Add NoA attribute in P2P IE */ ++ noa_attr_content[0] = 0x1;/* index */ ++ noa_attr_content[1] = 0x0;/* CTWindow and OppPS Parameters */ ++ ++ /* todo: Notice of Absence Descriptor(s) */ ++ ++ p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_NOA, 2, noa_attr_content); ++ ++ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &pattrib->pktlen); ++ ++ pattrib->last_txcmdsz = pattrib->pktlen; ++ ++ dump_mgntframe(padapter, pmgntframe); ++} ++ ++u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) ++{ ++ u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 }; ++ u16 capability = 0; ++ u32 len = 0, p2pielen = 0; ++ __le16 le_tmp; ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* According to the P2P Specification, the beacon frame should contain 3 P2P attributes */ ++ /* 1. P2P Capability */ ++ /* 2. P2P Device ID */ ++ /* 3. Notice of Absence (NOA) */ ++ ++ /* P2P Capability ATTR */ ++ /* Type: */ ++ /* Length: */ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ /* Be able to participate in additional P2P Groups and */ ++ /* support the P2P Invitation Procedure */ ++ /* Group Capability Bitmap, 1 byte */ ++ capability = P2P_DEVCAP_INVITATION_PROC | P2P_DEVCAP_CLIENT_DISCOVERABILITY; ++ capability |= ((P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS) << 8); ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) ++ capability |= (P2P_GRPCAP_GROUP_FORMATION << 8); ++ ++ le_tmp = cpu_to_le16(capability); ++ p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_CAPABILITY, 2, (u8 *)&le_tmp); ++ ++ /* P2P Device ID ATTR */ ++ p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_DEVICE_ID, ETH_ALEN, pwdinfo->device_addr); ++ ++ /* Notice of Absence ATTR */ ++ /* Type: */ ++ /* Length: */ ++ /* Value: */ ++ ++ pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len); ++ return len; ++} ++ ++u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) ++{ ++ u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 }; ++ u32 len = 0, p2pielen = 0; ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20100907 */ ++ /* According to the P2P Specification, the probe response frame should contain 5 P2P attributes */ ++ /* 1. P2P Capability */ ++ /* 2. Extended Listen Timing */ ++ /* 3. Notice of Absence (NOA) (Only GO needs this) */ ++ /* 4. Device Info */ ++ /* 5. Group Info (Only GO need this) */ ++ ++ /* P2P Capability ATTR */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CAPABILITY; ++ ++ /* Length: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002); */ ++ RTW_PUT_LE16(p2pie + p2pielen, 0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT; ++ ++ /* Group Capability Bitmap, 1 byte */ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ p2pie[p2pielen] = (P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS); ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) ++ p2pie[p2pielen] |= P2P_GRPCAP_GROUP_FORMATION; ++ ++ p2pielen++; ++ } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) { ++ /* Group Capability Bitmap, 1 byte */ ++ if (pwdinfo->persistent_supported) ++ p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; ++ else ++ p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT; ++ } ++ ++ /* Extended Listen Timing ATTR */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING; ++ ++ /* Length: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0004); */ ++ RTW_PUT_LE16(p2pie + p2pielen, 0x0004); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Availability Period */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF); */ ++ RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF); ++ p2pielen += 2; ++ ++ /* Availability Interval */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF); */ ++ RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF); ++ p2pielen += 2; ++ ++ /* Notice of Absence ATTR */ ++ /* Type: */ ++ /* Length: */ ++ /* Value: */ ++ ++ /* Device Info ATTR */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO; ++ ++ /* Length: */ ++ /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */ ++ /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); */ ++ RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Config Method */ ++ /* This field should be big endian. Noted by P2P specification. */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm); */ ++ RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->supported_wps_cm); ++ p2pielen += 2; ++ ++ /* Primary Device Type */ ++ /* Category ID */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA); ++ p2pielen += 2; ++ ++ /* OUI */ ++ /* u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI); */ ++ RTW_PUT_BE32(p2pie + p2pielen, WPSOUI); ++ p2pielen += 4; ++ ++ /* Sub Category ID */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER); ++ p2pielen += 2; ++ ++ /* Number of Secondary Device Types */ ++ p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */ ++ ++ /* Device Name */ ++ /* Type: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME); ++ p2pielen += 2; ++ ++ /* Length: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); */ ++ RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ p2pielen += pwdinfo->device_name_len; ++ ++ /* Group Info ATTR */ ++ /* Type: */ ++ /* Length: */ ++ /* Value: */ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) ++ p2pielen += go_add_group_info_attr(pwdinfo, p2pie + p2pielen); ++ ++ pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len); ++ ++ return len; ++} ++ ++u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 *pssid, u8 ussidlen, u8 *pdev_raddr) ++{ ++ u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 }; ++ u32 len = 0, p2pielen = 0; ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* Commented by Albert 20110301 */ ++ /* According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes */ ++ /* 1. P2P Capability */ ++ /* 2. Device Info */ ++ /* 3. Group ID (When joining an operating P2P Group) */ ++ ++ /* P2P Capability ATTR */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_CAPABILITY; ++ ++ /* Length: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002); */ ++ RTW_PUT_LE16(p2pie + p2pielen, 0x0002); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* Device Capability Bitmap, 1 byte */ ++ p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT; ++ ++ /* Group Capability Bitmap, 1 byte */ ++ if (pwdinfo->persistent_supported) ++ p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; ++ else ++ p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT; ++ ++ /* Device Info ATTR */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO; ++ ++ /* Length: */ ++ /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */ ++ /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); */ ++ RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ /* P2P Device Address */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ /* Config Method */ ++ /* This field should be big endian. Noted by P2P specification. */ ++ if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC) { ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_PBC); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_PBC); ++ } else { ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_DISPLAY); ++ } ++ ++ p2pielen += 2; ++ ++ /* Primary Device Type */ ++ /* Category ID */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA); ++ p2pielen += 2; ++ ++ /* OUI */ ++ /* u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI); */ ++ RTW_PUT_BE32(p2pie + p2pielen, WPSOUI); ++ p2pielen += 4; ++ ++ /* Sub Category ID */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER); ++ p2pielen += 2; ++ ++ /* Number of Secondary Device Types */ ++ p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */ ++ ++ /* Device Name */ ++ /* Type: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */ ++ RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME); ++ p2pielen += 2; ++ ++ /* Length: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); */ ++ RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len); ++ p2pielen += pwdinfo->device_name_len; ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) { ++ /* Added by Albert 2011/05/19 */ ++ /* In this case, the pdev_raddr is the device address of the group owner. */ ++ ++ /* P2P Group ID ATTR */ ++ /* Type: */ ++ p2pie[p2pielen++] = P2P_ATTR_GROUP_ID; ++ ++ /* Length: */ ++ /* u16*) (p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + ussidlen); */ ++ RTW_PUT_LE16(p2pie + p2pielen, ETH_ALEN + ussidlen); ++ p2pielen += 2; ++ ++ /* Value: */ ++ memcpy(p2pie + p2pielen, pdev_raddr, ETH_ALEN); ++ p2pielen += ETH_ALEN; ++ ++ memcpy(p2pie + p2pielen, pssid, ussidlen); ++ p2pielen += ussidlen; ++ } ++ ++ pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len); ++ ++ return len; ++} ++ ++u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 status_code) ++{ ++ u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 }; ++ u32 len = 0, p2pielen = 0; ++ ++ /* P2P OUI */ ++ p2pielen = 0; ++ p2pie[p2pielen++] = 0x50; ++ p2pie[p2pielen++] = 0x6F; ++ p2pie[p2pielen++] = 0x9A; ++ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */ ++ ++ /* According to the P2P Specification, the Association response frame should contain 2 P2P attributes */ ++ /* 1. Status */ ++ /* 2. Extended Listen Timing (optional) */ ++ ++ /* Status ATTR */ ++ p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status_code); ++ ++ /* Extended Listen Timing ATTR */ ++ /* Type: */ ++ /* Length: */ ++ /* Value: */ ++ ++ pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len); ++ ++ return len; ++} ++ ++u32 build_deauth_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) ++{ ++ u32 len = 0; ++ ++ return len; ++} ++ ++u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ u8 *p; ++ u32 ret = false; ++ u8 *p2pie; ++ u32 p2pielen = 0; ++ int ssid_len = 0, rate_cnt = 0; ++ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SUPPORTEDRATES_IE_, (int *)&rate_cnt, ++ len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); ++ ++ if (rate_cnt <= 4) { ++ int i, g_rate = 0; ++ ++ for (i = 0; i < rate_cnt; i++) { ++ if (((*(p + 2 + i) & 0xff) != 0x02) && ++ ((*(p + 2 + i) & 0xff) != 0x04) && ++ ((*(p + 2 + i) & 0xff) != 0x0B) && ++ ((*(p + 2 + i) & 0xff) != 0x16)) ++ g_rate = 1; ++ } ++ ++ if (g_rate == 0) { ++ /* There is no OFDM rate included in SupportedRates IE of this probe request frame */ ++ /* The driver should response this probe request. */ ++ return ret; ++ } ++ } else { ++ /* rate_cnt > 4 means the SupportRates IE contains the OFDM rate because the count of CCK rates are 4. */ ++ /* We should proceed the following check for this probe request. */ ++ } ++ ++ /* Added comments by Albert 20100906 */ ++ /* There are several items we should check here. */ ++ /* 1. This probe request frame must contain the P2P IE. (Done) */ ++ /* 2. This probe request frame must contain the wildcard SSID. (Done) */ ++ /* 3. Wildcard BSSID. (Todo) */ ++ /* 4. Destination Address. (Done in mgt_dispatcher function) */ ++ /* 5. Requested Device Type in WSC IE. (Todo) */ ++ /* 6. Device ID attribute in P2P IE. (Todo) */ ++ ++ p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ssid_len, ++ len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); ++ ++ ssid_len &= 0xff; /* Just last 1 byte is valid for ssid len of the probe request */ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_, NULL, &p2pielen); ++ if (p2pie) { ++ if (p && !memcmp((void *)(p + 2), (void *)pwdinfo->p2p_wildcard_ssid, 7)) { ++ /* todo: */ ++ /* Check Requested Device Type attributes in WSC IE. */ ++ /* Check Device ID attribute in P2P IE */ ++ ++ ret = true; ++ } else if (p && ssid_len == 0) { ++ ret = true; ++ } ++ } else { ++ /* non -p2p device */ ++ } ++ } ++ ++ return ret; ++} ++ ++u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len, struct sta_info *psta) ++{ ++ u8 status_code = P2P_STATUS_SUCCESS; ++ u8 *pbuf, *pattr_content = NULL; ++ u32 attr_contentlen = 0; ++ u16 cap_attr = 0; ++ unsigned short frame_type, ie_offset = 0; ++ u8 *ies; ++ u32 ies_len; ++ u8 *p2p_ie; ++ u32 p2p_ielen = 0; ++ __be16 be_tmp; ++ __le16 le_tmp; ++ ++ if (!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) ++ return P2P_STATUS_FAIL_REQUEST_UNABLE; ++ ++ frame_type = GetFrameSubType(pframe); ++ if (frame_type == WIFI_ASSOCREQ) ++ ie_offset = _ASOCREQ_IE_OFFSET_; ++ else /* WIFI_REASSOCREQ */ ++ ie_offset = _REASOCREQ_IE_OFFSET_; ++ ++ ies = pframe + WLAN_HDR_A3_LEN + ie_offset; ++ ies_len = len - WLAN_HDR_A3_LEN - ie_offset; ++ ++ p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen); ++ ++ if (!p2p_ie) { ++ DBG_88E("[%s] P2P IE not Found!!\n", __func__); ++ status_code = P2P_STATUS_FAIL_INVALID_PARAM; ++ } else { ++ DBG_88E("[%s] P2P IE Found!!\n", __func__); ++ } ++ ++ while (p2p_ie) { ++ /* Check P2P Capability ATTR */ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&le_tmp, (uint *)&attr_contentlen)) { ++ DBG_88E("[%s] Got P2P Capability Attr!!\n", __func__); ++ cap_attr = le16_to_cpu(le_tmp); ++ psta->dev_cap = cap_attr & 0xff; ++ } ++ ++ /* Check Extended Listen Timing ATTR */ ++ ++ /* Check P2P Device Info ATTR */ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, NULL, (uint *)&attr_contentlen)) { ++ DBG_88E("[%s] Got P2P DEVICE INFO Attr!!\n", __func__); ++ pattr_content = kzalloc(attr_contentlen, GFP_KERNEL); ++ pbuf = pattr_content; ++ if (pattr_content) { ++ u8 num_of_secdev_type; ++ u16 dev_name_len; ++ ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, pattr_content, (uint *)&attr_contentlen); ++ ++ memcpy(psta->dev_addr, pattr_content, ETH_ALEN);/* P2P Device Address */ ++ ++ pattr_content += ETH_ALEN; ++ ++ memcpy(&be_tmp, pattr_content, 2);/* Config Methods */ ++ psta->config_methods = be16_to_cpu(be_tmp); ++ ++ pattr_content += 2; ++ ++ memcpy(psta->primary_dev_type, pattr_content, 8); ++ ++ pattr_content += 8; ++ ++ num_of_secdev_type = *pattr_content; ++ pattr_content += 1; ++ ++ if (num_of_secdev_type == 0) { ++ psta->num_of_secdev_type = 0; ++ } else { ++ u32 len; ++ ++ psta->num_of_secdev_type = num_of_secdev_type; ++ ++ len = (sizeof(psta->secdev_types_list) < (num_of_secdev_type * 8)) ? ++ (sizeof(psta->secdev_types_list)) : (num_of_secdev_type * 8); ++ ++ memcpy(psta->secdev_types_list, pattr_content, len); ++ ++ pattr_content += (num_of_secdev_type * 8); ++ } ++ ++ psta->dev_name_len = 0; ++ if (WPS_ATTR_DEVICE_NAME == be16_to_cpu(*(__be16 *)pattr_content)) { ++ dev_name_len = be16_to_cpu(*(__be16 *)(pattr_content + 2)); ++ ++ psta->dev_name_len = (sizeof(psta->dev_name) < dev_name_len) ? sizeof(psta->dev_name) : dev_name_len; ++ ++ memcpy(psta->dev_name, pattr_content + 4, psta->dev_name_len); ++ } ++ kfree(pbuf); ++ } ++ } ++ ++ /* Get the next P2P IE */ ++ p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen); ++ } ++ ++ return status_code; ++} ++ ++u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ u8 *frame_body; ++ u8 status, dialogToken; ++ struct sta_info *psta = NULL; ++ struct adapter *padapter = pwdinfo->padapter; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 *p2p_ie; ++ u32 p2p_ielen = 0; ++ ++ frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ dialogToken = frame_body[7]; ++ status = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP; ++ ++ p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen); ++ if (p2p_ie) { ++ u8 groupid[38] = { 0x00 }; ++ u8 dev_addr[ETH_ALEN] = { 0x00 }; ++ u32 attr_contentlen = 0; ++ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) { ++ if (!memcmp(pwdinfo->device_addr, groupid, ETH_ALEN) && ++ !memcmp(pwdinfo->p2p_group_ssid, groupid + ETH_ALEN, pwdinfo->p2p_group_ssid_len)) { ++ attr_contentlen = 0; ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_ID, dev_addr, &attr_contentlen)) { ++ struct list_head *phead, *plist; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ phead = &pstapriv->asoc_list; ++ plist = phead->next; ++ ++ /* look up sta asoc_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, asoc_list); ++ ++ plist = plist->next; ++ ++ if (psta->is_p2p_device && (psta->dev_cap & P2P_DEVCAP_CLIENT_DISCOVERABILITY) && ++ !memcmp(psta->dev_addr, dev_addr, ETH_ALEN)) { ++ /* issue GO Discoverability Request */ ++ issue_group_disc_req(pwdinfo, psta->hwaddr); ++ status = P2P_STATUS_SUCCESS; ++ break; ++ } else { ++ status = P2P_STATUS_FAIL_INFO_UNAVAILABLE; ++ } ++ } ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ } else { ++ status = P2P_STATUS_FAIL_INVALID_PARAM; ++ } ++ } else { ++ status = P2P_STATUS_FAIL_INVALID_PARAM; ++ } ++ } ++ } ++ ++ /* issue Device Discoverability Response */ ++ issue_p2p_devdisc_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken); ++ ++ return (status == P2P_STATUS_SUCCESS) ? true : false; ++} ++ ++u32 process_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ return true; ++} ++ ++u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ u8 *frame_body; ++ u8 *wpsie; ++ uint wps_ielen = 0, attr_contentlen = 0; ++ u16 uconfig_method = 0; ++ __be16 be_tmp; ++ ++ frame_body = (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ wpsie = rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen); ++ if (wpsie) { ++ if (rtw_get_wps_attr_content(wpsie, wps_ielen, WPS_ATTR_CONF_METHOD, (u8 *)&be_tmp, &attr_contentlen)) { ++ uconfig_method = be16_to_cpu(be_tmp); ++ switch (uconfig_method) { ++ case WPS_CM_DISPLYA: ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3); ++ break; ++ case WPS_CM_LABEL: ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "lab", 3); ++ break; ++ case WPS_CM_PUSH_BUTTON: ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3); ++ break; ++ case WPS_CM_KEYPAD: ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3); ++ break; ++ } ++ issue_p2p_provision_resp(pwdinfo, GetAddr2Ptr(pframe), frame_body, uconfig_method); ++ } ++ } ++ DBG_88E("[%s] config method = %s\n", __func__, pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req); ++ return true; ++} ++ ++u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe) ++{ ++ return true; ++} ++ ++static u8 rtw_p2p_get_peer_ch_list(struct wifidirect_info *pwdinfo, u8 *ch_content, u8 ch_cnt, u8 *peer_ch_list) ++{ ++ u8 i = 0, j = 0; ++ u8 temp = 0; ++ u8 ch_no = 0; ++ ch_content += 3; ++ ch_cnt -= 3; ++ ++ while (ch_cnt > 0) { ++ ch_content += 1; ++ ch_cnt -= 1; ++ temp = *ch_content; ++ for (i = 0 ; i < temp ; i++, j++) ++ peer_ch_list[j] = *(ch_content + 1 + i); ++ ch_content += (temp + 1); ++ ch_cnt -= (temp + 1); ++ ch_no += temp; ++ } ++ ++ return ch_no; ++} ++ ++static u8 rtw_p2p_ch_inclusion(struct mlme_ext_priv *pmlmeext, u8 *peer_ch_list, u8 peer_ch_num, u8 *ch_list_inclusioned) ++{ ++ int i = 0, j = 0, temp = 0; ++ u8 ch_no = 0; ++ ++ for (i = 0; i < peer_ch_num; i++) { ++ for (j = temp; j < pmlmeext->max_chan_nums; j++) { ++ if (*(peer_ch_list + i) == pmlmeext->channel_set[j].ChannelNum) { ++ ch_list_inclusioned[ch_no++] = *(peer_ch_list + i); ++ temp = j; ++ break; ++ } ++ } ++ } ++ ++ return ch_no; ++} ++ ++u8 process_p2p_group_negotation_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ struct adapter *padapter = pwdinfo->padapter; ++ u8 result = P2P_STATUS_SUCCESS; ++ u32 p2p_ielen = 0, wps_ielen = 0; ++ u8 *ies; ++ u32 ies_len; ++ u8 *p2p_ie; ++ u8 *wpsie; ++ u16 wps_devicepassword_id = 0x0000; ++ uint wps_devicepassword_id_len = 0; ++ __be16 be_tmp; ++ ++ wpsie = rtw_get_wps_ie(pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen); ++ if (wpsie) { ++ /* Commented by Kurt 20120113 */ ++ /* If some device wants to do p2p handshake without sending prov_disc_req */ ++ /* We have to get peer_req_cm from here. */ ++ if (!memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) { ++ rtw_get_wps_attr_content(wpsie, wps_ielen, WPS_ATTR_DEVICE_PWID, (u8 *)&be_tmp, &wps_devicepassword_id_len); ++ wps_devicepassword_id = be16_to_cpu(be_tmp); ++ ++ if (wps_devicepassword_id == WPS_DPID_USER_SPEC) ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3); ++ else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC) ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3); ++ else ++ memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3); ++ } ++ } else { ++ DBG_88E("[%s] WPS IE not Found!!\n", __func__); ++ result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ return result; ++ } ++ ++ if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO) { ++ result = P2P_STATUS_FAIL_INFO_UNAVAILABLE; ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INFOR_NOREADY); ++ return result; ++ } ++ ++ ies = pframe + _PUBLIC_ACTION_IE_OFFSET_; ++ ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; ++ ++ p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen); ++ ++ if (!p2p_ie) { ++ DBG_88E("[%s] P2P IE not Found!!\n", __func__); ++ result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ } ++ ++ while (p2p_ie) { ++ u8 attr_content = 0x00; ++ u32 attr_contentlen = 0; ++ u8 ch_content[50] = { 0x00 }; ++ uint ch_cnt = 0; ++ u8 peer_ch_list[50] = { 0x00 }; ++ u8 peer_ch_num = 0; ++ u8 ch_list_inclusioned[50] = { 0x00 }; ++ u8 ch_num_inclusioned = 0; ++ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING); ++ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, &attr_content, &attr_contentlen)) { ++ DBG_88E("[%s] GO Intent = %d, tie = %d\n", __func__, attr_content >> 1, attr_content & 0x01); ++ pwdinfo->peer_intent = attr_content; /* include both intent and tie breaker values. */ ++ ++ if (pwdinfo->intent == (pwdinfo->peer_intent >> 1)) { ++ /* Try to match the tie breaker value */ ++ if (pwdinfo->intent == P2P_MAX_INTENT) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ result = P2P_STATUS_FAIL_BOTH_GOINTENT_15; ++ } else { ++ if (attr_content & 0x01) ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ else ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ } ++ } else if (pwdinfo->intent > (pwdinfo->peer_intent >> 1)) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ } else { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ } ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ /* Store the group id information. */ ++ memcpy(pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN); ++ memcpy(pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen); ++ } ++ } ++ ++ attr_contentlen = 0; ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen)) { ++ if (attr_contentlen != ETH_ALEN) ++ memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN); ++ } ++ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, ch_content, &ch_cnt)) { ++ peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, ch_content, ch_cnt, peer_ch_list); ++ ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned); ++ ++ if (ch_num_inclusioned == 0) { ++ DBG_88E("[%s] No common channel in channel list!\n", __func__); ++ result = P2P_STATUS_FAIL_NO_COMMON_CH; ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ break; ++ } ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ if (!rtw_p2p_is_channel_list_ok(pwdinfo->operating_channel, ++ ch_list_inclusioned, ch_num_inclusioned)) { ++ u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0; ++ attr_contentlen = 0; ++ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) ++ peer_operating_ch = operatingch_info[4]; ++ ++ if (rtw_p2p_is_channel_list_ok(peer_operating_ch, ++ ch_list_inclusioned, ch_num_inclusioned)) { ++ /** ++ * Change our operating channel as peer's for compatibility. ++ */ ++ pwdinfo->operating_channel = peer_operating_ch; ++ DBG_88E("[%s] Change op ch to %02x as peer's\n", __func__, pwdinfo->operating_channel); ++ } else { ++ /* Take first channel of ch_list_inclusioned as operating channel */ ++ pwdinfo->operating_channel = ch_list_inclusioned[0]; ++ DBG_88E("[%s] Change op ch to %02x\n", __func__, pwdinfo->operating_channel); ++ } ++ } ++ } ++ } ++ ++ /* Get the next P2P IE */ ++ p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen); ++ } ++ return result; ++} ++ ++u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ struct adapter *padapter = pwdinfo->padapter; ++ u8 result = P2P_STATUS_SUCCESS; ++ u32 p2p_ielen, wps_ielen; ++ u8 *ies; ++ u32 ies_len; ++ u8 *p2p_ie; ++ ++ ies = pframe + _PUBLIC_ACTION_IE_OFFSET_; ++ ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; ++ ++ /* Be able to know which one is the P2P GO and which one is P2P client. */ ++ ++ if (rtw_get_wps_ie(ies, ies_len, NULL, &wps_ielen)) { ++ } else { ++ DBG_88E("[%s] WPS IE not Found!!\n", __func__); ++ result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ } ++ ++ p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen); ++ if (!p2p_ie) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; ++ } else { ++ u8 attr_content = 0x00; ++ u32 attr_contentlen = 0; ++ u8 operatingch_info[5] = { 0x00 }; ++ u8 groupid[38]; ++ u8 peer_ch_list[50] = { 0x00 }; ++ u8 peer_ch_num = 0; ++ u8 ch_list_inclusioned[50] = { 0x00 }; ++ u8 ch_num_inclusioned = 0; ++ ++ while (p2p_ie) { /* Found the P2P IE. */ ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen); ++ if (attr_contentlen == 1) { ++ DBG_88E("[%s] Status = %d\n", __func__, attr_content); ++ if (attr_content == P2P_STATUS_SUCCESS) { ++ /* Do nothing. */ ++ } else { ++ if (P2P_STATUS_FAIL_INFO_UNAVAILABLE == attr_content) { ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INFOR_NOREADY); ++ } else { ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ } ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ result = attr_content; ++ break; ++ } ++ } ++ ++ /* Try to get the peer's interface address */ ++ attr_contentlen = 0; ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen)) { ++ if (attr_contentlen != ETH_ALEN) ++ memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN); ++ } ++ ++ /* Try to get the peer's intent and tie breaker value. */ ++ attr_content = 0x00; ++ attr_contentlen = 0; ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, &attr_content, &attr_contentlen)) { ++ DBG_88E("[%s] GO Intent = %d, tie = %d\n", __func__, attr_content >> 1, attr_content & 0x01); ++ pwdinfo->peer_intent = attr_content; /* include both intent and tie breaker values. */ ++ ++ if (pwdinfo->intent == (pwdinfo->peer_intent >> 1)) { ++ /* Try to match the tie breaker value */ ++ if (pwdinfo->intent == P2P_MAX_INTENT) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ result = P2P_STATUS_FAIL_BOTH_GOINTENT_15; ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ } else { ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ if (attr_content & 0x01) ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ else ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ } ++ } else if (pwdinfo->intent > (pwdinfo->peer_intent >> 1)) { ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ } else { ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ } ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ /* Store the group id information. */ ++ memcpy(pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN); ++ memcpy(pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen); ++ } ++ } ++ ++ /* Try to get the operation channel information */ ++ ++ attr_contentlen = 0; ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) { ++ DBG_88E("[%s] Peer's operating channel = %d\n", __func__, operatingch_info[4]); ++ pwdinfo->peer_operating_ch = operatingch_info[4]; ++ } ++ ++ /* Try to get the channel list information */ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, pwdinfo->channel_list_attr, &pwdinfo->channel_list_attr_len)) { ++ DBG_88E("[%s] channel list attribute found, len = %d\n", __func__, pwdinfo->channel_list_attr_len); ++ ++ peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len, peer_ch_list); ++ ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned); ++ ++ if (ch_num_inclusioned == 0) { ++ DBG_88E("[%s] No common channel in channel list!\n", __func__); ++ result = P2P_STATUS_FAIL_NO_COMMON_CH; ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ break; ++ } ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ if (!rtw_p2p_is_channel_list_ok(pwdinfo->operating_channel, ++ ch_list_inclusioned, ch_num_inclusioned)) { ++ u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0; ++ attr_contentlen = 0; ++ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) ++ peer_operating_ch = operatingch_info[4]; ++ ++ if (rtw_p2p_is_channel_list_ok(peer_operating_ch, ++ ch_list_inclusioned, ch_num_inclusioned)) { ++ /** ++ * Change our operating channel as peer's for compatibility. ++ */ ++ pwdinfo->operating_channel = peer_operating_ch; ++ DBG_88E("[%s] Change op ch to %02x as peer's\n", __func__, pwdinfo->operating_channel); ++ } else { ++ /* Take first channel of ch_list_inclusioned as operating channel */ ++ pwdinfo->operating_channel = ch_list_inclusioned[0]; ++ DBG_88E("[%s] Change op ch to %02x\n", __func__, pwdinfo->operating_channel); ++ } ++ } ++ } ++ } else { ++ DBG_88E("[%s] channel list attribute not found!\n", __func__); ++ } ++ ++ /* Try to get the group id information if peer is GO */ ++ attr_contentlen = 0; ++ memset(groupid, 0x00, 38); ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) { ++ memcpy(pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN); ++ memcpy(pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN); ++ } ++ ++ /* Get the next P2P IE */ ++ p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen); ++ } ++ } ++ return result; ++} ++ ++u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ u8 *ies; ++ u32 ies_len; ++ u8 *p2p_ie; ++ u32 p2p_ielen = 0; ++ u8 result = P2P_STATUS_SUCCESS; ++ ies = pframe + _PUBLIC_ACTION_IE_OFFSET_; ++ ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; ++ ++ p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen); ++ while (p2p_ie) { /* Found the P2P IE. */ ++ u8 attr_content = 0x00, operatingch_info[5] = { 0x00 }; ++ u8 groupid[38] = { 0x00 }; ++ u32 attr_contentlen = 0; ++ ++ pwdinfo->negotiation_dialog_token = 1; ++ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen); ++ if (attr_contentlen == 1) { ++ DBG_88E("[%s] Status = %d\n", __func__, attr_content); ++ result = attr_content; ++ ++ if (attr_content == P2P_STATUS_SUCCESS) { ++ u8 bcancelled = 0; ++ ++ _cancel_timer(&pwdinfo->restore_p2p_state_timer, &bcancelled); ++ ++ /* Commented by Albert 20100911 */ ++ /* Todo: Need to handle the case which both Intents are the same. */ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ if ((pwdinfo->intent) > (pwdinfo->peer_intent >> 1)) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ } else if ((pwdinfo->intent) < (pwdinfo->peer_intent >> 1)) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ } else { ++ /* Have to compare the Tie Breaker */ ++ if (pwdinfo->peer_intent & 0x01) ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ else ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ } ++ } else { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); ++ break; ++ } ++ } ++ ++ /* Try to get the group id information */ ++ attr_contentlen = 0; ++ memset(groupid, 0x00, 38); ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) { ++ DBG_88E("[%s] Ssid = %s, ssidlen = %zu\n", __func__, &groupid[ETH_ALEN], strlen(&groupid[ETH_ALEN])); ++ memcpy(pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN); ++ memcpy(pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN); ++ } ++ ++ attr_contentlen = 0; ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) { ++ DBG_88E("[%s] Peer's operating channel = %d\n", __func__, operatingch_info[4]); ++ pwdinfo->peer_operating_ch = operatingch_info[4]; ++ } ++ ++ /* Get the next P2P IE */ ++ p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen); ++ } ++ return result; ++} ++ ++u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) ++{ ++ u8 *frame_body; ++ u8 dialogToken = 0; ++ u8 status = P2P_STATUS_SUCCESS; ++ ++ frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); ++ ++ dialogToken = frame_body[6]; ++ ++ /* todo: check NoA attribute */ ++ ++ issue_p2p_presence_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken); ++ ++ return true; ++} ++ ++static void find_phase_handler(struct adapter *padapter) ++{ ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ndis_802_11_ssid ssid; ++ ++ memset((unsigned char *)&ssid, 0, sizeof(struct ndis_802_11_ssid)); ++ memcpy(ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN); ++ ssid.SsidLength = P2P_WILDCARD_SSID_LEN; ++ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH); ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ spin_unlock_bh(&pmlmepriv->lock); ++ ++} ++ ++void p2p_concurrent_handler(struct adapter *padapter); ++ ++static void restore_p2p_state_handler(struct adapter *padapter) ++{ ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) { ++ /* In the P2P client mode, the driver should not switch back to its listen channel */ ++ /* because this P2P client should stay at the operating channel of P2P GO. */ ++ set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ } ++ ++} ++ ++static void pre_tx_invitereq_handler(struct adapter *padapter) ++{ ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 val8 = 1; ++ ++ set_channel_bwmode(padapter, pwdinfo->invitereq_info.peer_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); ++ issue_probereq_p2p(padapter, NULL); ++ _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); ++ ++} ++ ++static void pre_tx_provdisc_handler(struct adapter *padapter) ++{ ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 val8 = 1; ++ ++ set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); ++ issue_probereq_p2p(padapter, NULL); ++ _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); ++ ++} ++ ++static void pre_tx_negoreq_handler(struct adapter *padapter) ++{ ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 val8 = 1; ++ ++ set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); ++ issue_probereq_p2p(padapter, NULL); ++ _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); ++ ++} ++ ++void p2p_protocol_wk_hdl(struct adapter *padapter, int intCmdType) ++{ ++ ++ switch (intCmdType) { ++ case P2P_FIND_PHASE_WK: ++ find_phase_handler(padapter); ++ break; ++ case P2P_RESTORE_STATE_WK: ++ restore_p2p_state_handler(padapter); ++ break; ++ case P2P_PRE_TX_PROVDISC_PROCESS_WK: ++ pre_tx_provdisc_handler(padapter); ++ break; ++ case P2P_PRE_TX_INVITEREQ_PROCESS_WK: ++ pre_tx_invitereq_handler(padapter); ++ break; ++ case P2P_PRE_TX_NEGOREQ_PROCESS_WK: ++ pre_tx_negoreq_handler(padapter); ++ break; ++ } ++ ++} ++ ++void process_p2p_ps_ie(struct adapter *padapter, u8 *IEs, u32 IELength) ++{ ++ u8 *ies; ++ u32 ies_len; ++ u8 *p2p_ie; ++ u32 p2p_ielen = 0; ++ u8 noa_attr[MAX_P2P_IE_LEN] = { 0x00 };/* NoA length should be n*(13) + 2 */ ++ u32 attr_contentlen = 0; ++ ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 find_p2p = false, find_p2p_ps = false; ++ u8 noa_offset, noa_num, noa_index; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return; ++ if (IELength <= _BEACON_IE_OFFSET_) ++ return; ++ ++ ies = IEs + _BEACON_IE_OFFSET_; ++ ies_len = IELength - _BEACON_IE_OFFSET_; ++ ++ p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen); ++ ++ while (p2p_ie) { ++ find_p2p = true; ++ /* Get Notice of Absence IE. */ ++ if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_NOA, noa_attr, &attr_contentlen)) { ++ find_p2p_ps = true; ++ noa_index = noa_attr[0]; ++ ++ if ((pwdinfo->p2p_ps_mode == P2P_PS_NONE) || ++ (noa_index != pwdinfo->noa_index)) { /* if index change, driver should reconfigure related setting. */ ++ pwdinfo->noa_index = noa_index; ++ pwdinfo->opp_ps = noa_attr[1] >> 7; ++ pwdinfo->ctwindow = noa_attr[1] & 0x7F; ++ ++ noa_offset = 2; ++ noa_num = 0; ++ /* NoA length should be n*(13) + 2 */ ++ if (attr_contentlen > 2) { ++ while (noa_offset < attr_contentlen) { ++ /* memcpy(&wifidirect_info->noa_count[noa_num], &noa_attr[noa_offset], 1); */ ++ pwdinfo->noa_count[noa_num] = noa_attr[noa_offset]; ++ noa_offset += 1; ++ ++ memcpy(&pwdinfo->noa_duration[noa_num], &noa_attr[noa_offset], 4); ++ noa_offset += 4; ++ ++ memcpy(&pwdinfo->noa_interval[noa_num], &noa_attr[noa_offset], 4); ++ noa_offset += 4; ++ ++ memcpy(&pwdinfo->noa_start_time[noa_num], &noa_attr[noa_offset], 4); ++ noa_offset += 4; ++ ++ noa_num++; ++ } ++ } ++ pwdinfo->noa_num = noa_num; ++ ++ if (pwdinfo->opp_ps == 1) { ++ pwdinfo->p2p_ps_mode = P2P_PS_CTWINDOW; ++ /* driver should wait LPS for entering CTWindow */ ++ if (padapter->pwrctrlpriv.bFwCurrentInPSMode) ++ p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1); ++ } else if (pwdinfo->noa_num > 0) { ++ pwdinfo->p2p_ps_mode = P2P_PS_NOA; ++ p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1); ++ } else if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) { ++ p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1); ++ } ++ } ++ ++ break; /* find target, just break. */ ++ } ++ ++ /* Get the next P2P IE */ ++ p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen); ++ } ++ ++ if (find_p2p) { ++ if ((pwdinfo->p2p_ps_mode > P2P_PS_NONE) && !find_p2p_ps) ++ p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1); ++ } ++ ++} ++ ++void p2p_ps_wk_hdl(struct adapter *padapter, u8 p2p_ps_state) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ /* Pre action for p2p state */ ++ switch (p2p_ps_state) { ++ case P2P_PS_DISABLE: ++ pwdinfo->p2p_ps_state = p2p_ps_state; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); ++ ++ pwdinfo->noa_index = 0; ++ pwdinfo->ctwindow = 0; ++ pwdinfo->opp_ps = 0; ++ pwdinfo->noa_num = 0; ++ pwdinfo->p2p_ps_mode = P2P_PS_NONE; ++ if (padapter->pwrctrlpriv.bFwCurrentInPSMode) { ++ if (pwrpriv->smart_ps == 0) { ++ pwrpriv->smart_ps = 2; ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&padapter->pwrctrlpriv.pwr_mode)); ++ } ++ } ++ break; ++ case P2P_PS_ENABLE: ++ if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) { ++ pwdinfo->p2p_ps_state = p2p_ps_state; ++ ++ if (pwdinfo->ctwindow > 0) { ++ if (pwrpriv->smart_ps != 0) { ++ pwrpriv->smart_ps = 0; ++ DBG_88E("%s(): Enter CTW, change SmartPS\n", __func__); ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&padapter->pwrctrlpriv.pwr_mode)); ++ } ++ } ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); ++ } ++ break; ++ case P2P_PS_SCAN: ++ case P2P_PS_SCAN_DONE: ++ case P2P_PS_ALLSTASLEEP: ++ if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) { ++ pwdinfo->p2p_ps_state = p2p_ps_state; ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); ++ } ++ break; ++ default: ++ break; ++ } ++ ++} ++ ++u8 p2p_ps_wk_cmd(struct adapter *padapter, u8 p2p_ps_state, u8 enqueue) ++{ ++ struct cmd_obj *ph2c; ++ struct drvextra_cmd_parm *pdrvextra_cmd_parm; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ struct cmd_priv *pcmdpriv = &padapter->cmdpriv; ++ u8 res = _SUCCESS; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return res; ++ ++ if (enqueue) { ++ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); ++ if (!ph2c) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC); ++ if (!pdrvextra_cmd_parm) { ++ kfree(ph2c); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pdrvextra_cmd_parm->ec_id = P2P_PS_WK_CID; ++ pdrvextra_cmd_parm->type_size = p2p_ps_state; ++ pdrvextra_cmd_parm->pbuf = NULL; ++ ++ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); ++ ++ res = rtw_enqueue_cmd(pcmdpriv, ph2c); ++ } else { ++ p2p_ps_wk_hdl(padapter, p2p_ps_state); ++ } ++ ++exit: ++ ++ return res; ++} ++ ++static void reset_ch_sitesurvey_timer_process(struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, pwrctrlpriv.pwr_state_check_timer); ++ struct wifidirect_info *pwdinfo = &adapter->wdinfo; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return; ++ ++ DBG_88E("[%s] In\n", __func__); ++ /* Reset the operation channel information */ ++ pwdinfo->rx_invitereq_info.operation_ch[0] = 0; ++ pwdinfo->rx_invitereq_info.scan_op_ch_only = 0; ++} ++ ++static void reset_ch_sitesurvey_timer_process2(struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, pwrctrlpriv.pwr_state_check_timer); ++ struct wifidirect_info *pwdinfo = &adapter->wdinfo; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return; ++ ++ DBG_88E("[%s] In\n", __func__); ++ /* Reset the operation channel information */ ++ pwdinfo->p2p_info.operation_ch[0] = 0; ++ pwdinfo->p2p_info.scan_op_ch_only = 0; ++} ++ ++static void restore_p2p_state_timer_process(struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, wdinfo.restore_p2p_state_timer); ++ struct wifidirect_info *pwdinfo = &adapter->wdinfo; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return; ++ ++ p2p_protocol_wk_cmd(adapter, P2P_RESTORE_STATE_WK); ++} ++ ++static void pre_tx_scan_timer_process(struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, wdinfo.pre_tx_scan_timer); ++ struct wifidirect_info *pwdinfo = &adapter->wdinfo; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return; ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) { ++ if (pwdinfo->tx_prov_disc_info.benable) { /* the provision discovery request frame is trigger to send or not */ ++ p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_PROVDISC_PROCESS_WK); ++ /* issue_probereq_p2p(adapter, NULL); */ ++ /* _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); */ ++ } ++ } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) { ++ if (pwdinfo->nego_req_info.benable) ++ p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_NEGOREQ_PROCESS_WK); ++ } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) { ++ if (pwdinfo->invitereq_info.benable) ++ p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_INVITEREQ_PROCESS_WK); ++ } else { ++ DBG_88E("[%s] p2p_state is %d, ignore!!\n", __func__, rtw_p2p_state(pwdinfo)); ++ } ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++static void find_phase_timer_process(struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, wdinfo.find_phase_timer); ++ struct wifidirect_info *pwdinfo = &adapter->wdinfo; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return; ++ ++ adapter->wdinfo.find_phase_state_exchange_cnt++; ++ ++ p2p_protocol_wk_cmd(adapter, P2P_FIND_PHASE_WK); ++} ++ ++void reset_global_wifidirect_info(struct adapter *padapter) ++{ ++ struct wifidirect_info *pwdinfo; ++ ++ pwdinfo = &padapter->wdinfo; ++ pwdinfo->persistent_supported = 0; ++ pwdinfo->session_available = true; ++ pwdinfo->wfd_tdls_enable = 0; ++ pwdinfo->wfd_tdls_weaksec = 0; ++} ++ ++void rtw_init_wifidirect_timers(struct adapter *padapter) ++{ ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ timer_setup(&pwdinfo->find_phase_timer, find_phase_timer_process, 0); ++ timer_setup(&pwdinfo->restore_p2p_state_timer, restore_p2p_state_timer_process, 0); ++ timer_setup(&pwdinfo->pre_tx_scan_timer, pre_tx_scan_timer_process, 0); ++ timer_setup(&pwdinfo->reset_ch_sitesurvey, reset_ch_sitesurvey_timer_process, 0); ++ timer_setup(&pwdinfo->reset_ch_sitesurvey2, reset_ch_sitesurvey_timer_process2, 0); ++} ++ ++void rtw_init_wifidirect_addrs(struct adapter *padapter, u8 *dev_addr, u8 *iface_addr) ++{ ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ /*init device&interface address */ ++ if (dev_addr) ++ memcpy(pwdinfo->device_addr, dev_addr, ETH_ALEN); ++ if (iface_addr) ++ memcpy(pwdinfo->interface_addr, iface_addr, ETH_ALEN); ++#endif ++} ++ ++void init_wifidirect_info(struct adapter *padapter, enum P2P_ROLE role) ++{ ++ struct wifidirect_info *pwdinfo; ++ ++ pwdinfo = &padapter->wdinfo; ++ pwdinfo->padapter = padapter; ++ ++ /* 1, 6, 11 are the social channel defined in the WiFi Direct specification. */ ++ pwdinfo->social_chan[0] = 1; ++ pwdinfo->social_chan[1] = 6; ++ pwdinfo->social_chan[2] = 11; ++ pwdinfo->social_chan[3] = 0; /* channel 0 for scanning ending in site survey function. */ ++ ++ /* Use the channel 11 as the listen channel */ ++ pwdinfo->listen_channel = 11; ++ ++ if (role == P2P_ROLE_DEVICE) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); ++ pwdinfo->intent = 1; ++ rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_LISTEN); ++ } else if (role == P2P_ROLE_CLIENT) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ pwdinfo->intent = 1; ++ rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ } else if (role == P2P_ROLE_GO) { ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ pwdinfo->intent = 15; ++ rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); ++ } ++ ++/* Use the OFDM rate in the P2P probe response frame. (6(B), 9(B), 12, 18, 24, 36, 48, 54) */ ++ pwdinfo->support_rate[0] = 0x8c; /* 6(B) */ ++ pwdinfo->support_rate[1] = 0x92; /* 9(B) */ ++ pwdinfo->support_rate[2] = 0x18; /* 12 */ ++ pwdinfo->support_rate[3] = 0x24; /* 18 */ ++ pwdinfo->support_rate[4] = 0x30; /* 24 */ ++ pwdinfo->support_rate[5] = 0x48; /* 36 */ ++ pwdinfo->support_rate[6] = 0x60; /* 48 */ ++ pwdinfo->support_rate[7] = 0x6c; /* 54 */ ++ ++ memcpy(pwdinfo->p2p_wildcard_ssid, "DIRECT-", 7); ++ ++ memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN); ++ pwdinfo->device_name_len = 0; ++ ++ memset(&pwdinfo->invitereq_info, 0x00, sizeof(struct tx_invite_req_info)); ++ pwdinfo->invitereq_info.token = 3; /* Token used for P2P invitation request frame. */ ++ ++ memset(&pwdinfo->inviteresp_info, 0x00, sizeof(struct tx_invite_resp_info)); ++ pwdinfo->inviteresp_info.token = 0; ++ ++ pwdinfo->profileindex = 0; ++ memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM); ++ ++ rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE); ++ ++ pwdinfo->listen_dwell = (u8)((jiffies % 3) + 1); ++ ++ memset(&pwdinfo->tx_prov_disc_info, 0x00, sizeof(struct tx_provdisc_req_info)); ++ pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_NONE; ++ ++ memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info)); ++ ++ pwdinfo->device_password_id_for_nego = WPS_DPID_PBC; ++ pwdinfo->negotiation_dialog_token = 1; ++ ++ memset(pwdinfo->nego_ssid, 0x00, WLAN_SSID_MAXLEN); ++ pwdinfo->nego_ssidlen = 0; ++ ++ pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO; ++ pwdinfo->supported_wps_cm = WPS_CONFIG_METHOD_DISPLAY | WPS_CONFIG_METHOD_PBC | WPS_CONFIG_METHOD_KEYPAD; ++ pwdinfo->channel_list_attr_len = 0; ++ memset(pwdinfo->channel_list_attr, 0x00, 100); ++ ++ memset(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, 0x00, 4); ++ memset(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, '0', 3); ++ memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info)); ++ pwdinfo->wfd_tdls_enable = 0; ++ memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN); ++ memset(pwdinfo->p2p_peer_device_addr, 0x00, ETH_ALEN); ++ ++ pwdinfo->rx_invitereq_info.operation_ch[0] = 0; ++ pwdinfo->rx_invitereq_info.operation_ch[1] = 0; /* Used to indicate the scan end in site survey function */ ++ pwdinfo->rx_invitereq_info.scan_op_ch_only = 0; ++ pwdinfo->p2p_info.operation_ch[0] = 0; ++ pwdinfo->p2p_info.operation_ch[1] = 0; /* Used to indicate the scan end in site survey function */ ++ pwdinfo->p2p_info.scan_op_ch_only = 0; ++} ++ ++int rtw_p2p_enable(struct adapter *padapter, enum P2P_ROLE role) ++{ ++ int ret = _SUCCESS; ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT || role == P2P_ROLE_GO) { ++ /* leave IPS/Autosuspend */ ++ if (_FAIL == rtw_pwr_wakeup(padapter)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* Added by Albert 2011/03/22 */ ++ /* In the P2P mode, the driver should not support the b mode. */ ++ /* So, the Tx packet shouldn't use the CCK rate */ ++ update_tx_basic_rate(padapter, (WIRELESS_11G | WIRELESS_11_24N)); ++ ++ /* Enable P2P function */ ++ init_wifidirect_info(padapter, role); ++ ++ rtw_hal_set_odm_var(padapter, HAL_ODM_P2P_STATE, NULL, true); ++ } else if (role == P2P_ROLE_DISABLE) { ++ if (_FAIL == rtw_pwr_wakeup(padapter)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* Disable P2P function */ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ++ _cancel_timer_ex(&pwdinfo->find_phase_timer); ++ _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); ++ _cancel_timer_ex(&pwdinfo->pre_tx_scan_timer); ++ _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey); ++ _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey2); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE); ++ rtw_p2p_set_role(pwdinfo, P2P_ROLE_DISABLE); ++ memset(&pwdinfo->rx_prov_disc_info, 0x00, sizeof(struct rx_provdisc_req_info)); ++ } ++ ++ rtw_hal_set_odm_var(padapter, HAL_ODM_P2P_STATE, NULL, false); ++ ++ /* Restore to initial setting. */ ++ update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); ++ } ++ ++exit: ++ return ret; ++} ++ ++#else ++u8 p2p_ps_wk_cmd(struct adapter *padapter, u8 p2p_ps_state, u8 enqueue) ++{ ++ return _FAIL; ++} ++ ++void process_p2p_ps_ie(struct adapter *padapter, u8 *IEs, u32 IELength) ++{ ++} ++ ++#endif /* CONFIG_88EU_P2P */ +diff --git a/drivers/staging/r8188eu/core/rtw_pwrctrl.c b/drivers/staging/r8188eu/core/rtw_pwrctrl.c +new file mode 100644 +index 000000000000..c3897b29121c +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_pwrctrl.c +@@ -0,0 +1,605 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_PWRCTRL_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/osdep_intf.h" ++#include "../include/linux/usb.h" ++ ++void ips_enter(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct xmit_priv *pxmit_priv = &padapter->xmitpriv; ++ ++ if (padapter->registrypriv.mp_mode == 1) ++ return; ++ ++ if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF || ++ pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) { ++ DBG_88E_LEVEL(_drv_info_, "There are some pkts to transmit\n"); ++ DBG_88E_LEVEL(_drv_info_, "free_xmitbuf_cnt: %d, free_xmit_extbuf_cnt: %d\n", ++ pxmit_priv->free_xmitbuf_cnt, pxmit_priv->free_xmit_extbuf_cnt); ++ return; ++ } ++ ++ _enter_pwrlock(&pwrpriv->lock); ++ ++ pwrpriv->bips_processing = true; ++ ++ /* syn ips_mode with request */ ++ pwrpriv->ips_mode = pwrpriv->ips_mode_req; ++ ++ pwrpriv->ips_enter_cnts++; ++ DBG_88E("==>ips_enter cnts:%d\n", pwrpriv->ips_enter_cnts); ++ if (rf_off == pwrpriv->change_rfpwrstate) { ++ pwrpriv->bpower_saving = true; ++ DBG_88E_LEVEL(_drv_info_, "nolinked power save enter\n"); ++ ++ if (pwrpriv->ips_mode == IPS_LEVEL_2) ++ pwrpriv->bkeepfwalive = true; ++ ++ rtw_ips_pwr_down(padapter); ++ pwrpriv->rf_pwrstate = rf_off; ++ } ++ pwrpriv->bips_processing = false; ++ ++ _exit_pwrlock(&pwrpriv->lock); ++} ++ ++int ips_leave(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ int result = _SUCCESS; ++ int keyid; ++ ++ _enter_pwrlock(&pwrpriv->lock); ++ ++ if ((pwrpriv->rf_pwrstate == rf_off) && (!pwrpriv->bips_processing)) { ++ pwrpriv->bips_processing = true; ++ pwrpriv->change_rfpwrstate = rf_on; ++ pwrpriv->ips_leave_cnts++; ++ DBG_88E("==>ips_leave cnts:%d\n", pwrpriv->ips_leave_cnts); ++ ++ result = rtw_ips_pwr_up(padapter); ++ if (result == _SUCCESS) { ++ pwrpriv->rf_pwrstate = rf_on; ++ } ++ DBG_88E_LEVEL(_drv_info_, "nolinked power save leave\n"); ++ ++ if ((_WEP40_ == psecuritypriv->dot11PrivacyAlgrthm) || (_WEP104_ == psecuritypriv->dot11PrivacyAlgrthm)) { ++ DBG_88E("==>%s, channel(%d), processing(%x)\n", __func__, padapter->mlmeextpriv.cur_channel, pwrpriv->bips_processing); ++ set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ for (keyid = 0; keyid < 4; keyid++) { ++ if (pmlmepriv->key_mask & BIT(keyid)) { ++ if (keyid == psecuritypriv->dot11PrivacyKeyIndex) ++ result = rtw_set_key(padapter, psecuritypriv, keyid, 1); ++ else ++ result = rtw_set_key(padapter, psecuritypriv, keyid, 0); ++ } ++ } ++ } ++ ++ DBG_88E("==> ips_leave.....LED(0x%08x)...\n", rtw_read32(padapter, 0x4c)); ++ pwrpriv->bips_processing = false; ++ ++ pwrpriv->bkeepfwalive = false; ++ pwrpriv->bpower_saving = false; ++ } ++ ++ _exit_pwrlock(&pwrpriv->lock); ++ ++ return result; ++} ++ ++static bool rtw_pwr_unassociated_idle(struct adapter *adapter) ++{ ++ struct adapter *buddy = adapter->pbuddy_adapter; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &adapter->wdinfo; ++#endif ++ ++ bool ret = false; ++ ++ if (adapter->pwrctrlpriv.ips_deny_time >= jiffies) ++ goto exit; ++ ++ if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_SITE_MONITOR) || ++ check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS) || ++ check_fwstate(pmlmepriv, WIFI_UNDER_WPS) || ++ check_fwstate(pmlmepriv, WIFI_AP_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) || ++#if defined(CONFIG_88EU_P2P) ++ !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++#else ++ 0) ++#endif ++ goto exit; ++ ++ /* consider buddy, if exist */ ++ if (buddy) { ++ struct mlme_priv *b_pmlmepriv = &buddy->mlmepriv; ++ #ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *b_pwdinfo = &buddy->wdinfo; ++ #endif ++ ++ if (check_fwstate(b_pmlmepriv, WIFI_ASOC_STATE | WIFI_SITE_MONITOR) || ++ check_fwstate(b_pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS) || ++ check_fwstate(b_pmlmepriv, WIFI_AP_STATE) || ++ check_fwstate(b_pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) || ++#if defined(CONFIG_88EU_P2P) ++ !rtw_p2p_chk_state(b_pwdinfo, P2P_STATE_NONE)) ++#else ++ 0) ++#endif ++ goto exit; ++ } ++ ret = true; ++ ++exit: ++ return ret; ++} ++ ++void rtw_ps_processor(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ enum rt_rf_power_state rfpwrstate; ++ ++ pwrpriv->ps_processing = true; ++ ++ if (pwrpriv->bips_processing) ++ goto exit; ++ ++ if (padapter->pwrctrlpriv.bHWPwrPindetect) { ++ rfpwrstate = RfOnOffDetect(padapter); ++ DBG_88E("@@@@- #2 %s==> rfstate:%s\n", __func__, (rfpwrstate == rf_on) ? "rf_on" : "rf_off"); ++ ++ if (rfpwrstate != pwrpriv->rf_pwrstate) { ++ if (rfpwrstate == rf_off) { ++ pwrpriv->change_rfpwrstate = rf_off; ++ pwrpriv->brfoffbyhw = true; ++ padapter->bCardDisableWOHSM = true; ++ rtw_hw_suspend(padapter); ++ } else { ++ pwrpriv->change_rfpwrstate = rf_on; ++ rtw_hw_resume(padapter); ++ } ++ DBG_88E("current rf_pwrstate(%s)\n", (pwrpriv->rf_pwrstate == rf_off) ? "rf_off" : "rf_on"); ++ } ++ pwrpriv->pwr_state_check_cnts++; ++ } ++ ++ if (pwrpriv->ips_mode_req == IPS_NONE) ++ goto exit; ++ ++ if (!rtw_pwr_unassociated_idle(padapter)) ++ goto exit; ++ ++ if ((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts % 4) == 0)) { ++ DBG_88E("==>%s .fw_state(%x)\n", __func__, get_fwstate(pmlmepriv)); ++ pwrpriv->change_rfpwrstate = rf_off; ++ ++ ips_enter(padapter); ++ } ++exit: ++ rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); ++ pwrpriv->ps_processing = false; ++} ++ ++static void pwr_state_check_handler(struct timer_list *t) ++{ ++ struct adapter *padapter = ++ from_timer(padapter, t, ++ pwrctrlpriv.pwr_state_check_timer); ++ rtw_ps_cmd(padapter); ++} ++ ++/* ++ * ++ * Parameters ++ * padapter ++ * pslv power state level, only could be PS_STATE_S0 ~ PS_STATE_S4 ++ * ++ */ ++void rtw_set_rpwm(struct adapter *padapter, u8 pslv) ++{ ++ u8 rpwm; ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ ++ pslv = PS_STATE(pslv); ++ ++ if (pwrpriv->btcoex_rfon) { ++ if (pslv < PS_STATE_S4) ++ pslv = PS_STATE_S3; ++ } ++ ++ if (pwrpriv->rpwm == pslv) ++ return; ++ ++ if ((padapter->bSurpriseRemoved) || ++ (!padapter->hw_init_completed)) { ++ pwrpriv->cpwm = PS_STATE_S4; ++ ++ return; ++ } ++ ++ if (padapter->bDriverStopped) { ++ if (pslv < PS_STATE_S2) ++ return; ++ } ++ ++ rpwm = pslv | pwrpriv->tog; ++ ++ pwrpriv->rpwm = pslv; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm)); ++ ++ pwrpriv->tog += 0x80; ++ pwrpriv->cpwm = pslv; ++ ++} ++ ++static u8 PS_RDY_CHECK(struct adapter *padapter) ++{ ++ u32 curr_time, delta_time; ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ curr_time = jiffies; ++ delta_time = curr_time - pwrpriv->DelayLPSLastTimeStamp; ++ ++ if (delta_time < LPS_DELAY_TIME) ++ return false; ++ ++ if (!check_fwstate(pmlmepriv, _FW_LINKED) || ++ check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) || ++ check_fwstate(pmlmepriv, WIFI_AP_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) ++ return false; ++ if (pwrpriv->bInSuspend) ++ return false; ++ if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && !padapter->securitypriv.binstallGrpkey) { ++ DBG_88E("Group handshake still in progress !!!\n"); ++ return false; ++ } ++ return true; ++} ++ ++void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ if (ps_mode > PM_Card_Disable) ++ return; ++ ++ if (pwrpriv->pwr_mode == ps_mode) { ++ if (PS_MODE_ACTIVE == ps_mode) ++ return; ++ ++ if ((pwrpriv->smart_ps == smart_ps) && ++ (pwrpriv->bcn_ant_mode == bcn_ant_mode)) ++ return; ++ } ++ ++ /* if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) */ ++ if (ps_mode == PS_MODE_ACTIVE) { ++#ifdef CONFIG_88EU_P2P ++ if (pwdinfo->opp_ps == 0) { ++ DBG_88E("rtw_set_ps_mode: Leave 802.11 power save\n"); ++ pwrpriv->pwr_mode = ps_mode; ++ rtw_set_rpwm(padapter, PS_STATE_S4); ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); ++ pwrpriv->bFwCurrentInPSMode = false; ++ } ++ } else { ++#endif /* CONFIG_88EU_P2P */ ++ if (PS_RDY_CHECK(padapter)) { ++ DBG_88E("%s: Enter 802.11 power save\n", __func__); ++ pwrpriv->bFwCurrentInPSMode = true; ++ pwrpriv->pwr_mode = ps_mode; ++ pwrpriv->smart_ps = smart_ps; ++ pwrpriv->bcn_ant_mode = bcn_ant_mode; ++ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); ++ ++#ifdef CONFIG_88EU_P2P ++ /* Set CTWindow after LPS */ ++ if (pwdinfo->opp_ps == 1) ++ p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 0); ++#endif /* CONFIG_88EU_P2P */ ++ ++ rtw_set_rpwm(padapter, PS_STATE_S2); ++ } ++ } ++ ++} ++ ++/* ++ * Return: ++ * 0: Leave OK ++ * -1: Timeout ++ * -2: Other error ++ */ ++s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms) ++{ ++ u32 start_time; ++ u8 bAwake = false; ++ s32 err = 0; ++ ++ start_time = jiffies; ++ while (1) { ++ rtw_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, &bAwake); ++ if (bAwake) ++ break; ++ ++ if (padapter->bSurpriseRemoved) { ++ err = -2; ++ DBG_88E("%s: device surprise removed!!\n", __func__); ++ break; ++ } ++ ++ if (rtw_get_passing_time_ms(start_time) > delay_ms) { ++ err = -1; ++ DBG_88E("%s: Wait for FW LPS leave more than %u ms!!!\n", __func__, delay_ms); ++ break; ++ } ++ rtw_usleep_os(100); ++ } ++ ++ return err; ++} ++ ++/* */ ++/* Description: */ ++/* Enter the leisure power save mode. */ ++/* */ ++void LPS_Enter(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ ++ if (!PS_RDY_CHECK(padapter)) ++ return; ++ ++ if (pwrpriv->bLeisurePs) { ++ /* Idle for a while if we connect to AP a while ago. */ ++ if (pwrpriv->LpsIdleCount >= 2) { /* 4 Sec */ ++ if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) { ++ pwrpriv->bpower_saving = true; ++ DBG_88E("%s smart_ps:%d\n", __func__, pwrpriv->smart_ps); ++ /* For Tenda W311R IOT issue */ ++ rtw_set_ps_mode(padapter, pwrpriv->power_mgnt, ++ pwrpriv->smart_ps, 0x40); ++ } ++ } else { ++ pwrpriv->LpsIdleCount++; ++ } ++ } ++ ++} ++ ++#define LPS_LEAVE_TIMEOUT_MS 100 ++ ++/* Description: */ ++/* Leave the leisure power save mode. */ ++void LPS_Leave(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ ++ if (pwrpriv->bLeisurePs) { ++ if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) { ++ rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0x40); ++ ++ if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) ++ LPS_RF_ON_check(padapter, LPS_LEAVE_TIMEOUT_MS); ++ } ++ } ++ ++ pwrpriv->bpower_saving = false; ++ ++} ++ ++/* */ ++/* Description: Leave all power save mode: LPS, FwLPS, IPS if needed. */ ++/* Move code to function by tynli. 2010.03.26. */ ++/* */ ++void LeaveAllPowerSaveMode(struct adapter *Adapter) ++{ ++ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; ++ u8 enqueue = 0; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { /* connect */ ++ p2p_ps_wk_cmd(Adapter, P2P_PS_DISABLE, enqueue); ++ ++ rtw_lps_ctrl_wk_cmd(Adapter, LPS_CTRL_LEAVE, enqueue); ++ } ++ ++} ++ ++void rtw_init_pwrctrl_priv(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; ++ ++ _init_pwrlock(&pwrctrlpriv->lock); ++ pwrctrlpriv->rf_pwrstate = rf_on; ++ pwrctrlpriv->ips_enter_cnts = 0; ++ pwrctrlpriv->ips_leave_cnts = 0; ++ pwrctrlpriv->bips_processing = false; ++ ++ pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode; ++ pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode; ++ ++ pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL; ++ pwrctrlpriv->pwr_state_check_cnts = 0; ++ pwrctrlpriv->bInternalAutoSuspend = false; ++ pwrctrlpriv->bInSuspend = false; ++ pwrctrlpriv->bkeepfwalive = false; ++ ++ pwrctrlpriv->LpsIdleCount = 0; ++ if (padapter->registrypriv.mp_mode == 1) ++ pwrctrlpriv->power_mgnt = PS_MODE_ACTIVE; ++ else ++ pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;/* PS_MODE_MIN; */ ++ pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? true : false; ++ ++ pwrctrlpriv->bFwCurrentInPSMode = false; ++ ++ pwrctrlpriv->rpwm = 0; ++ pwrctrlpriv->cpwm = PS_STATE_S4; ++ ++ pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE; ++ pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps; ++ pwrctrlpriv->bcn_ant_mode = 0; ++ ++ pwrctrlpriv->tog = 0x80; ++ ++ pwrctrlpriv->btcoex_rfon = false; ++ ++ timer_setup(&pwrctrlpriv->pwr_state_check_timer, pwr_state_check_handler, 0); ++} ++ ++void rtw_free_pwrctrl_priv(struct adapter *adapter) ++{ ++ struct pwrctrl_priv *pwrctrlpriv = &adapter->pwrctrlpriv; ++ ++ _free_pwrlock(&pwrctrlpriv->lock); ++ ++} ++ ++u8 rtw_interface_ps_func(struct adapter *padapter, enum hal_intf_ps_func efunc_id, u8 *val) ++{ ++ u8 bResult = true; ++ rtw_hal_intf_ps_func(padapter, efunc_id, val); ++ ++ return bResult; ++} ++ ++inline void rtw_set_ips_deny(struct adapter *padapter, u32 ms) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ms); ++} ++ ++/* ++* rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend ++* @adapter: pointer to struct adapter structure ++* @ips_deffer_ms: the ms wiil prevent from falling into IPS after wakeup ++* Return _SUCCESS or _FAIL ++*/ ++ ++int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *caller) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ int ret = _SUCCESS; ++ u32 start = jiffies; ++ ++ if (pwrpriv->ips_deny_time < jiffies + rtw_ms_to_systime(ips_deffer_ms)) ++ pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ips_deffer_ms); ++ ++ if (pwrpriv->ps_processing) { ++ DBG_88E("%s wait ps_processing...\n", __func__); ++ while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000) ++ msleep(10); ++ if (pwrpriv->ps_processing) ++ DBG_88E("%s wait ps_processing timeout\n", __func__); ++ else ++ DBG_88E("%s wait ps_processing done\n", __func__); ++ } ++ ++ /* System suspend is not allowed to wakeup */ ++ if ((!pwrpriv->bInternalAutoSuspend) && pwrpriv->bInSuspend) { ++ while (pwrpriv->bInSuspend && ++ (rtw_get_passing_time_ms(start) <= 3000 || ++ (rtw_get_passing_time_ms(start) <= 500))) ++ msleep(10); ++ if (pwrpriv->bInSuspend) ++ DBG_88E("%s wait bInSuspend timeout\n", __func__); ++ else ++ DBG_88E("%s wait bInSuspend done\n", __func__); ++ } ++ ++ /* block??? */ ++ if ((pwrpriv->bInternalAutoSuspend) && (padapter->net_closed)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* I think this should be check in IPS, LPS, autosuspend functions... */ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ ret = _SUCCESS; ++ goto exit; ++ } ++ if (rf_off == pwrpriv->rf_pwrstate) { ++ DBG_88E("%s call ips_leave....\n", __func__); ++ if (_FAIL == ips_leave(padapter)) { ++ DBG_88E("======> ips_leave fail.............\n"); ++ ret = _FAIL; ++ goto exit; ++ } ++ } ++ ++ /* TODO: the following checking need to be merged... */ ++ if (padapter->bDriverStopped || !padapter->bup || ++ !padapter->hw_init_completed) { ++ DBG_88E("%s: bDriverStopped=%d, bup=%d, hw_init_completed =%u\n" ++ , caller ++ , padapter->bDriverStopped ++ , padapter->bup ++ , padapter->hw_init_completed); ++ ret = false; ++ goto exit; ++ } ++ ++exit: ++ if (pwrpriv->ips_deny_time < jiffies + rtw_ms_to_systime(ips_deffer_ms)) ++ pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ips_deffer_ms); ++ return ret; ++} ++ ++int rtw_pm_set_lps(struct adapter *padapter, u8 mode) ++{ ++ int ret = 0; ++ struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; ++ ++ if (mode < PS_MODE_NUM) { ++ if (pwrctrlpriv->power_mgnt != mode) { ++ if (PS_MODE_ACTIVE == mode) ++ LeaveAllPowerSaveMode(padapter); ++ else ++ pwrctrlpriv->LpsIdleCount = 2; ++ pwrctrlpriv->power_mgnt = mode; ++ pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? true : false; ++ } ++ } else { ++ ret = -EINVAL; ++ } ++ ++ return ret; ++} ++ ++int rtw_pm_set_ips(struct adapter *padapter, u8 mode) ++{ ++ struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; ++ ++ if (mode == IPS_NORMAL || mode == IPS_LEVEL_2) { ++ rtw_ips_mode_req(pwrctrlpriv, mode); ++ DBG_88E("%s %s\n", __func__, mode == IPS_NORMAL ? "IPS_NORMAL" : "IPS_LEVEL_2"); ++ return 0; ++ } else if (mode == IPS_NONE) { ++ rtw_ips_mode_req(pwrctrlpriv, mode); ++ DBG_88E("%s %s\n", __func__, "IPS_NONE"); ++ if ((padapter->bSurpriseRemoved == 0) && (_FAIL == rtw_pwr_wakeup(padapter))) ++ return -EFAULT; ++ } else { ++ return -EINVAL; ++ } ++ return 0; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_recv.c b/drivers/staging/r8188eu/core/rtw_recv.c +new file mode 100644 +index 000000000000..e082edfbaad8 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_recv.c +@@ -0,0 +1,2058 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_RECV_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/mlme_osdep.h" ++#include "../include/usb_ops.h" ++#include "../include/wifi.h" ++ ++static u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37}; ++static u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3}; ++ ++/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ ++static u8 rtw_bridge_tunnel_header[] = { ++ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 ++}; ++ ++static u8 rtw_rfc1042_header[] = { ++ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 ++}; ++ ++void rtw_signal_stat_timer_hdl(struct timer_list *); ++ ++void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv) ++{ ++ ++ memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv)); ++ ++ spin_lock_init(&psta_recvpriv->lock); ++ ++ _rtw_init_queue(&psta_recvpriv->defrag_q); ++ ++} ++ ++int _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter) ++{ ++ int i; ++ ++ struct recv_frame *precvframe; ++ ++ int res = _SUCCESS; ++ ++ spin_lock_init(&precvpriv->lock); ++ ++ _rtw_init_queue(&precvpriv->free_recv_queue); ++ _rtw_init_queue(&precvpriv->recv_pending_queue); ++ _rtw_init_queue(&precvpriv->uc_swdec_pending_queue); ++ ++ precvpriv->adapter = padapter; ++ ++ precvpriv->free_recvframe_cnt = NR_RECVFRAME; ++ ++ rtw_os_recv_resource_init(precvpriv, padapter); ++ ++ precvpriv->pallocated_frame_buf = vzalloc(NR_RECVFRAME * sizeof(struct recv_frame) + RXFRAME_ALIGN_SZ); ++ ++ if (!precvpriv->pallocated_frame_buf) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ precvpriv->precv_frame_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ); ++ ++ precvframe = (struct recv_frame *)precvpriv->precv_frame_buf; ++ ++ for (i = 0; i < NR_RECVFRAME; i++) { ++ INIT_LIST_HEAD(&precvframe->list); ++ ++ list_add_tail(&precvframe->list, &precvpriv->free_recv_queue.queue); ++ ++ res = rtw_os_recv_resource_alloc(padapter, precvframe); ++ ++ precvframe->len = 0; ++ ++ precvframe->adapter = padapter; ++ precvframe++; ++ } ++ precvpriv->rx_pending_cnt = 1; ++ ++ sema_init(&precvpriv->allrxreturnevt, 0); ++ ++ res = rtw_hal_init_recv_priv(padapter); ++ ++ timer_setup(&precvpriv->signal_stat_timer, rtw_signal_stat_timer_hdl, 0); ++ precvpriv->signal_stat_sampling_interval = 1000; /* ms */ ++ ++ rtw_set_signal_stat_timer(precvpriv); ++exit: ++ ++ return res; ++} ++ ++void _rtw_free_recv_priv(struct recv_priv *precvpriv) ++{ ++ struct adapter *padapter = precvpriv->adapter; ++ ++ rtw_free_uc_swdec_pending_queue(padapter); ++ ++ rtw_os_recv_resource_free(precvpriv); ++ ++ vfree(precvpriv->pallocated_frame_buf); ++ ++ rtw_hal_free_recv_priv(padapter); ++} ++ ++struct recv_frame *_rtw_alloc_recvframe(struct __queue *pfree_recv_queue) ++{ ++ struct recv_frame *hdr; ++ struct list_head *plist, *phead; ++ struct adapter *padapter; ++ struct recv_priv *precvpriv; ++ ++ if (list_empty(&pfree_recv_queue->queue)) { ++ hdr = NULL; ++ } else { ++ phead = get_list_head(pfree_recv_queue); ++ ++ plist = phead->next; ++ ++ hdr = container_of(plist, struct recv_frame, list); ++ ++ list_del_init(&hdr->list); ++ padapter = hdr->adapter; ++ if (padapter) { ++ precvpriv = &padapter->recvpriv; ++ if (pfree_recv_queue == &precvpriv->free_recv_queue) ++ precvpriv->free_recvframe_cnt--; ++ } ++ } ++ ++ return (struct recv_frame *)hdr; ++} ++ ++struct recv_frame *rtw_alloc_recvframe(struct __queue *pfree_recv_queue) ++{ ++ struct recv_frame *precvframe; ++ ++ spin_lock_bh(&pfree_recv_queue->lock); ++ ++ precvframe = _rtw_alloc_recvframe(pfree_recv_queue); ++ ++ spin_unlock_bh(&pfree_recv_queue->lock); ++ ++ return precvframe; ++} ++ ++void rtw_init_recvframe(struct recv_frame *precvframe, struct recv_priv *precvpriv) ++{ ++ /* Perry: This can be removed */ ++ INIT_LIST_HEAD(&precvframe->list); ++ ++ precvframe->len = 0; ++} ++ ++int rtw_free_recvframe(struct recv_frame *precvframe, struct __queue *pfree_recv_queue) ++{ ++ struct adapter *padapter; ++ struct recv_priv *precvpriv; ++ ++ if (!precvframe) ++ return _FAIL; ++ padapter = precvframe->adapter; ++ precvpriv = &padapter->recvpriv; ++ if (precvframe->pkt) { ++ dev_kfree_skb_any(precvframe->pkt);/* free skb by driver */ ++ precvframe->pkt = NULL; ++ } ++ ++ spin_lock_bh(&pfree_recv_queue->lock); ++ ++ list_del_init(&precvframe->list); ++ ++ precvframe->len = 0; ++ ++ list_add_tail(&precvframe->list, get_list_head(pfree_recv_queue)); ++ ++ if (padapter) { ++ if (pfree_recv_queue == &precvpriv->free_recv_queue) ++ precvpriv->free_recvframe_cnt++; ++ } ++ ++ spin_unlock_bh(&pfree_recv_queue->lock); ++ ++ return _SUCCESS; ++} ++ ++int _rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue) ++{ ++ struct adapter *padapter = precvframe->adapter; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ ++ list_del_init(&precvframe->list); ++ list_add_tail(&precvframe->list, get_list_head(queue)); ++ ++ if (padapter) { ++ if (queue == &precvpriv->free_recv_queue) ++ precvpriv->free_recvframe_cnt++; ++ } ++ ++ return _SUCCESS; ++} ++ ++int rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue) ++{ ++ int ret; ++ ++ spin_lock_bh(&queue->lock); ++ ret = _rtw_enqueue_recvframe(precvframe, queue); ++ spin_unlock_bh(&queue->lock); ++ ++ return ret; ++} ++ ++/* ++caller : defrag ; recvframe_chk_defrag in recv_thread (passive) ++pframequeue: defrag_queue : will be accessed in recv_thread (passive) ++ ++using spinlock to protect ++ ++*/ ++ ++void rtw_free_recvframe_queue(struct __queue *pframequeue, struct __queue *pfree_recv_queue) ++{ ++ struct recv_frame *hdr; ++ struct list_head *plist, *phead; ++ ++ spin_lock(&pframequeue->lock); ++ ++ phead = get_list_head(pframequeue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ hdr = container_of(plist, struct recv_frame, list); ++ ++ plist = plist->next; ++ ++ rtw_free_recvframe((struct recv_frame *)hdr, pfree_recv_queue); ++ } ++ ++ spin_unlock(&pframequeue->lock); ++ ++} ++ ++u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter) ++{ ++ u32 cnt = 0; ++ struct recv_frame *pending_frame; ++ while ((pending_frame = rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) { ++ rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue); ++ DBG_88E("%s: dequeue uc_swdec_pending_queue\n", __func__); ++ cnt++; ++ } ++ ++ return cnt; ++} ++ ++int rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, struct __queue *queue) ++{ ++ spin_lock_bh(&queue->lock); ++ ++ list_del_init(&precvbuf->list); ++ list_add(&precvbuf->list, get_list_head(queue)); ++ ++ spin_unlock_bh(&queue->lock); ++ ++ return _SUCCESS; ++} ++ ++int rtw_enqueue_recvbuf(struct recv_buf *precvbuf, struct __queue *queue) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&queue->lock, flags); ++ ++ list_del_init(&precvbuf->list); ++ ++ list_add_tail(&precvbuf->list, get_list_head(queue)); ++ spin_unlock_irqrestore(&queue->lock, flags); ++ return _SUCCESS; ++} ++ ++struct recv_buf *rtw_dequeue_recvbuf(struct __queue *queue) ++{ ++ struct recv_buf *precvbuf; ++ struct list_head *plist, *phead; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&queue->lock, flags); ++ ++ if (list_empty(&queue->queue)) { ++ precvbuf = NULL; ++ } else { ++ phead = get_list_head(queue); ++ ++ plist = phead->next; ++ ++ precvbuf = container_of(plist, struct recv_buf, list); ++ ++ list_del_init(&precvbuf->list); ++ } ++ ++ spin_unlock_irqrestore(&queue->lock, flags); ++ ++ return precvbuf; ++} ++ ++static int recvframe_chkmic(struct adapter *adapter, struct recv_frame *precvframe) ++{ ++ int i, res = _SUCCESS; ++ u32 datalen; ++ u8 miccode[8]; ++ u8 bmic_err = false, brpt_micerror = true; ++ u8 *pframe, *payload, *pframemic; ++ u8 *mickey; ++ struct sta_info *stainfo; ++ struct rx_pkt_attrib *prxattrib = &precvframe->attrib; ++ struct security_priv *psecuritypriv = &adapter->securitypriv; ++ ++ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ stainfo = rtw_get_stainfo(&adapter->stapriv, &prxattrib->ta[0]); ++ ++ if (prxattrib->encrypt == _TKIP_) { ++ /* calculate mic code */ ++ if (stainfo) { ++ if (is_multicast_ether_addr(prxattrib->ra)) { ++ mickey = &psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0]; ++ ++ if (!psecuritypriv) { ++ res = _FAIL; ++ DBG_88E("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n"); ++ goto exit; ++ } ++ } else { ++ mickey = &stainfo->dot11tkiprxmickey.skey[0]; ++ } ++ ++ datalen = precvframe->len - prxattrib->hdrlen - prxattrib->iv_len - prxattrib->icv_len - 8;/* icv_len included the mic code */ ++ pframe = precvframe->rx_data; ++ payload = pframe + prxattrib->hdrlen + prxattrib->iv_len; ++ ++ rtw_seccalctkipmic(mickey, pframe, payload, datalen, &miccode[0], ++ (unsigned char)prxattrib->priority); /* care the length of the data */ ++ ++ pframemic = payload + datalen; ++ ++ bmic_err = false; ++ ++ for (i = 0; i < 8; i++) { ++ if (miccode[i] != *(pframemic + i)) ++ bmic_err = true; ++ } ++ ++ if (bmic_err) { ++ /* double check key_index for some timing issue , */ ++ /* cannot compare with psecuritypriv->dot118021XGrpKeyid also cause timing issue */ ++ if (is_multicast_ether_addr(prxattrib->ra) && prxattrib->key_index != pmlmeinfo->key_index) ++ brpt_micerror = false; ++ ++ if ((prxattrib->bdecrypted) && (brpt_micerror)) { ++ rtw_handle_tkip_mic_err(adapter, (u8)is_multicast_ether_addr(prxattrib->ra)); ++ DBG_88E(" mic error :prxattrib->bdecrypted=%d\n", prxattrib->bdecrypted); ++ } else { ++ DBG_88E(" mic error :prxattrib->bdecrypted=%d\n", prxattrib->bdecrypted); ++ } ++ res = _FAIL; ++ } else { ++ /* mic checked ok */ ++ if (!psecuritypriv->bcheck_grpkey && is_multicast_ether_addr(prxattrib->ra)) ++ psecuritypriv->bcheck_grpkey = true; ++ } ++ } ++ ++ recvframe_pull_tail(precvframe, 8); ++ } ++ ++exit: ++ ++ return res; ++} ++ ++/* decrypt and set the ivlen, icvlen of the recv_frame */ ++static struct recv_frame *decryptor(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ struct rx_pkt_attrib *prxattrib = &precv_frame->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct recv_frame *return_packet = precv_frame; ++ u32 res = _SUCCESS; ++ ++ if (prxattrib->encrypt > 0) { ++ u8 *iv = precv_frame->rx_data + prxattrib->hdrlen; ++ prxattrib->key_index = (((iv[3]) >> 6) & 0x3); ++ ++ if (prxattrib->key_index > WEP_KEYS) { ++ DBG_88E("prxattrib->key_index(%d)>WEP_KEYS\n", prxattrib->key_index); ++ ++ switch (prxattrib->encrypt) { ++ case _WEP40_: ++ case _WEP104_: ++ prxattrib->key_index = psecuritypriv->dot11PrivacyKeyIndex; ++ break; ++ case _TKIP_: ++ case _AES_: ++ default: ++ prxattrib->key_index = psecuritypriv->dot118021XGrpKeyid; ++ break; ++ } ++ } ++ } ++ ++ if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0) || (psecuritypriv->sw_decrypt))) { ++ psecuritypriv->hw_decrypted = false; ++ ++ switch (prxattrib->encrypt) { ++ case _WEP40_: ++ case _WEP104_: ++ rtw_wep_decrypt(padapter, (u8 *)precv_frame); ++ break; ++ case _TKIP_: ++ res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame); ++ break; ++ case _AES_: ++ res = rtw_aes_decrypt(padapter, (u8 *)precv_frame); ++ break; ++ default: ++ break; ++ } ++ } else if (prxattrib->bdecrypted == 1 && prxattrib->encrypt > 0 && ++ (psecuritypriv->busetkipkey == 1 || prxattrib->encrypt != _TKIP_)) ++ psecuritypriv->hw_decrypted = true; ++ ++ if (res == _FAIL) { ++ rtw_free_recvframe(return_packet, &padapter->recvpriv.free_recv_queue); ++ return_packet = NULL; ++ } else { ++ prxattrib->bdecrypted = true; ++ } ++ ++ return return_packet; ++} ++ ++/* set the security information in the recv_frame */ ++static struct recv_frame *portctrl(struct adapter *adapter, struct recv_frame *precv_frame) ++{ ++ u8 *psta_addr, *ptr; ++ uint auth_alg; ++ struct recv_frame *pfhdr; ++ struct sta_info *psta; ++ struct sta_priv *pstapriv; ++ struct recv_frame *prtnframe; ++ u16 ether_type = 0; ++ u16 eapol_type = 0x888e;/* for Funia BD's WPA issue */ ++ struct rx_pkt_attrib *pattrib; ++ __be16 be_tmp; ++ ++ pstapriv = &adapter->stapriv; ++ ++ auth_alg = adapter->securitypriv.dot11AuthAlgrthm; ++ ++ ptr = precv_frame->rx_data; ++ pfhdr = precv_frame; ++ pattrib = &pfhdr->attrib; ++ psta_addr = pattrib->ta; ++ ++ prtnframe = NULL; ++ ++ psta = rtw_get_stainfo(pstapriv, psta_addr); ++ ++ if (auth_alg == 2) { ++ if (psta && psta->ieee8021x_blocked) { ++ /* blocked */ ++ /* only accept EAPOL frame */ ++ prtnframe = precv_frame; ++ ++ /* get ether_type */ ++ ptr = ptr + pfhdr->attrib.hdrlen + pfhdr->attrib.iv_len + LLC_HEADER_SIZE; ++ memcpy(&be_tmp, ptr, 2); ++ ether_type = ntohs(be_tmp); ++ ++ if (ether_type == eapol_type) { ++ prtnframe = precv_frame; ++ } else { ++ /* free this frame */ ++ rtw_free_recvframe(precv_frame, &adapter->recvpriv.free_recv_queue); ++ prtnframe = NULL; ++ } ++ } else { ++ /* allowed */ ++ /* check decryption status, and decrypt the frame if needed */ ++ prtnframe = precv_frame; ++ } ++ } else { ++ prtnframe = precv_frame; ++ } ++ ++ return prtnframe; ++} ++ ++static int recv_decache(struct recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache) ++{ ++ int tid = precv_frame->attrib.priority; ++ ++ u16 seq_ctrl = ((precv_frame->attrib.seq_num & 0xffff) << 4) | ++ (precv_frame->attrib.frag_num & 0xf); ++ ++ if (tid > 15) ++ return _FAIL; ++ ++ if (1) {/* if (bretry) */ ++ if (seq_ctrl == prxcache->tid_rxseq[tid]) ++ return _FAIL; ++ } ++ ++ prxcache->tid_rxseq[tid] = seq_ctrl; ++ ++ return _SUCCESS; ++} ++ ++void process_pwrbit_data(struct adapter *padapter, struct recv_frame *precv_frame); ++void process_pwrbit_data(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++#ifdef CONFIG_88EU_AP_MODE ++ unsigned char pwrbit; ++ u8 *ptr = precv_frame->rx_data; ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct sta_info *psta = NULL; ++ ++ psta = rtw_get_stainfo(pstapriv, pattrib->src); ++ ++ pwrbit = GetPwrMgt(ptr); ++ ++ if (psta) { ++ if (pwrbit) { ++ if (!(psta->state & WIFI_SLEEP_STATE)) ++ stop_sta_xmit(padapter, psta); ++ } else { ++ if (psta->state & WIFI_SLEEP_STATE) ++ wakeup_sta_to_xmit(padapter, psta); ++ } ++ } ++ ++#endif ++} ++ ++static void process_wmmps_data(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++#ifdef CONFIG_88EU_AP_MODE ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct sta_info *psta = NULL; ++ ++ psta = rtw_get_stainfo(pstapriv, pattrib->src); ++ ++ if (!psta) ++ return; ++ ++ if (!psta->qos_option) ++ return; ++ ++ if (!(psta->qos_info & 0xf)) ++ return; ++ ++ if (psta->state & WIFI_SLEEP_STATE) { ++ u8 wmmps_ac = 0; ++ ++ switch (pattrib->priority) { ++ case 1: ++ case 2: ++ wmmps_ac = psta->uapsd_bk & BIT(1); ++ break; ++ case 4: ++ case 5: ++ wmmps_ac = psta->uapsd_vi & BIT(1); ++ break; ++ case 6: ++ case 7: ++ wmmps_ac = psta->uapsd_vo & BIT(1); ++ break; ++ case 0: ++ case 3: ++ default: ++ wmmps_ac = psta->uapsd_be & BIT(1); ++ break; ++ } ++ ++ if (wmmps_ac) { ++ if (psta->sleepq_ac_len > 0) { ++ /* process received triggered frame */ ++ xmit_delivery_enabled_frames(padapter, psta); ++ } else { ++ /* issue one qos null frame with More data bit = 0 and the EOSP bit set (= 1) */ ++ issue_qos_nulldata(padapter, psta->hwaddr, (u16)pattrib->priority, 0, 0); ++ } ++ } ++ } ++ ++#endif ++} ++ ++static void count_rx_stats(struct adapter *padapter, struct recv_frame *prframe, struct sta_info *sta) ++{ ++ int sz; ++ struct sta_info *psta = NULL; ++ struct stainfo_stats *pstats = NULL; ++ struct rx_pkt_attrib *pattrib = &prframe->attrib; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ ++ sz = get_recvframe_len(prframe); ++ precvpriv->rx_bytes += sz; ++ ++ padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++; ++ ++ if (!is_broadcast_ether_addr(pattrib->dst) && !is_multicast_ether_addr(pattrib->dst)) ++ padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++; ++ ++ if (sta) ++ psta = sta; ++ else ++ psta = prframe->psta; ++ ++ if (psta) { ++ pstats = &psta->sta_stats; ++ ++ pstats->rx_data_pkts++; ++ pstats->rx_bytes += sz; ++ } ++} ++ ++int sta2sta_data_frame( ++ struct adapter *adapter, ++ struct recv_frame *precv_frame, ++ struct sta_info **psta ++); ++ ++int sta2sta_data_frame(struct adapter *adapter, struct recv_frame *precv_frame, struct sta_info **psta) ++{ ++ u8 *ptr = precv_frame->rx_data; ++ int ret = _SUCCESS; ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ struct sta_priv *pstapriv = &adapter->stapriv; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ u8 *mybssid = get_bssid(pmlmepriv); ++ u8 *myhwaddr = myid(&adapter->eeprompriv); ++ u8 *sta_addr = NULL; ++ bool bmcast = is_multicast_ether_addr(pattrib->dst); ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ /* filter packets that SA is myself or multicast or broadcast */ ++ if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || ++ !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || ++ memcmp(pattrib->bssid, mybssid, ETH_ALEN)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ sta_addr = pattrib->src; ++ } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ /* For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */ ++ if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ sta_addr = pattrib->bssid; ++ } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ if (bmcast) { ++ /* For AP mode, if DA == MCAST, then BSSID should be also MCAST */ ++ if (!is_multicast_ether_addr(pattrib->bssid)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ } else { /* not mc-frame */ ++ /* For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID */ ++ if (memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ sta_addr = pattrib->src; ++ } ++ } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { ++ memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); ++ memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN); ++ memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); ++ memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); ++ memcpy(pattrib->ta, pattrib->src, ETH_ALEN); ++ ++ sta_addr = mybssid; ++ } else { ++ ret = _FAIL; ++ } ++ ++ if (bmcast) ++ *psta = rtw_get_bcmc_stainfo(adapter); ++ else ++ *psta = rtw_get_stainfo(pstapriv, sta_addr); /* get ap_info */ ++ ++ if (!*psta) { ++ if (adapter->registrypriv.mp_mode == 1) { ++ if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) ++ adapter->mppriv.rx_pktloss++; ++ } ++ ret = _FAIL; ++ goto exit; ++ } ++ ++exit: ++ ++ return ret; ++} ++ ++static int ap2sta_data_frame( ++ struct adapter *adapter, ++ struct recv_frame *precv_frame, ++ struct sta_info **psta) ++{ ++ u8 *ptr = precv_frame->rx_data; ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ int ret = _SUCCESS; ++ struct sta_priv *pstapriv = &adapter->stapriv; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ u8 *mybssid = get_bssid(pmlmepriv); ++ u8 *myhwaddr = myid(&adapter->eeprompriv); ++ bool bmcast = is_multicast_ether_addr(pattrib->dst); ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && ++ (check_fwstate(pmlmepriv, _FW_LINKED) || ++ check_fwstate(pmlmepriv, _FW_UNDER_LINKING))) { ++ /* filter packets that SA is myself or multicast or broadcast */ ++ if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* da should be for me */ ++ if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* check BSSID */ ++ if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || ++ !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || ++ (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) { ++ if (!bmcast) { ++ DBG_88E("issue_deauth to the nonassociated ap=%pM for the reason(7)\n", (pattrib->bssid)); ++ issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); ++ } ++ ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ if (bmcast) ++ *psta = rtw_get_bcmc_stainfo(adapter); ++ else ++ *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get ap_info */ ++ ++ if (!*psta) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { */ ++ /* */ ++ ++ if (GetFrameSubType(ptr) & BIT(6)) { ++ /* No data, will not indicate to upper layer, temporily count it here */ ++ count_rx_stats(adapter, precv_frame, *psta); ++ ret = RTW_RX_HANDLED; ++ goto exit; ++ } ++ } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) && ++ check_fwstate(pmlmepriv, _FW_LINKED)) { ++ memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); ++ memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN); ++ memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); ++ memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); ++ memcpy(pattrib->ta, pattrib->src, ETH_ALEN); ++ ++ /* */ ++ memcpy(pattrib->bssid, mybssid, ETH_ALEN); ++ ++ *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */ ++ if (!*psta) { ++ ret = _FAIL; ++ goto exit; ++ } ++ } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ /* Special case */ ++ ret = RTW_RX_HANDLED; ++ goto exit; ++ } else { ++ if (!memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && (!bmcast)) { ++ *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */ ++ if (!*psta) { ++ DBG_88E("issue_deauth to the ap =%pM for the reason(7)\n", (pattrib->bssid)); ++ ++ issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); ++ } ++ } ++ ++ ret = _FAIL; ++ } ++ ++exit: ++ ++ return ret; ++} ++ ++static int sta2ap_data_frame(struct adapter *adapter, ++ struct recv_frame *precv_frame, ++ struct sta_info **psta) ++{ ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ struct sta_priv *pstapriv = &adapter->stapriv; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ u8 *ptr = precv_frame->rx_data; ++ unsigned char *mybssid = get_bssid(pmlmepriv); ++ int ret = _SUCCESS; ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ /* For AP mode, RA = BSSID, TX = STA(SRC_ADDR), A3 = DST_ADDR */ ++ if (memcmp(pattrib->bssid, mybssid, ETH_ALEN)) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ *psta = rtw_get_stainfo(pstapriv, pattrib->src); ++ if (!*psta) { ++ DBG_88E("issue_deauth to sta=%pM for the reason(7)\n", (pattrib->src)); ++ ++ issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); ++ ++ ret = RTW_RX_HANDLED; ++ goto exit; ++ } ++ ++ process_pwrbit_data(adapter, precv_frame); ++ ++ if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { ++ process_wmmps_data(adapter, precv_frame); ++ } ++ ++ if (GetFrameSubType(ptr) & BIT(6)) { ++ /* No data, will not indicate to upper layer, temporily count it here */ ++ count_rx_stats(adapter, precv_frame, *psta); ++ ret = RTW_RX_HANDLED; ++ goto exit; ++ } ++ } else { ++ u8 *myhwaddr = myid(&adapter->eeprompriv); ++ if (memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) { ++ ret = RTW_RX_HANDLED; ++ goto exit; ++ } ++ DBG_88E("issue_deauth to sta=%pM for the reason(7)\n", (pattrib->src)); ++ issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); ++ ret = RTW_RX_HANDLED; ++ goto exit; ++ } ++ ++exit: ++ ++ return ret; ++} ++ ++static int validate_recv_ctrl_frame(struct adapter *padapter, ++ struct recv_frame *precv_frame) ++{ ++#ifdef CONFIG_88EU_AP_MODE ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 *pframe = precv_frame->rx_data; ++ /* uint len = precv_frame->len; */ ++ ++ if (GetFrameType(pframe) != WIFI_CTRL_TYPE) ++ return _FAIL; ++ ++ /* receive the frames that ra(a1) is my address */ ++ if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN)) ++ return _FAIL; ++ ++ /* only handle ps-poll */ ++ if (GetFrameSubType(pframe) == WIFI_PSPOLL) { ++ u16 aid; ++ u8 wmmps_ac = 0; ++ struct sta_info *psta = NULL; ++ ++ aid = GetAid(pframe); ++ psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); ++ ++ if (!psta || psta->aid != aid) ++ return _FAIL; ++ ++ /* for rx pkt statistics */ ++ psta->sta_stats.rx_ctrl_pkts++; ++ ++ switch (pattrib->priority) { ++ case 1: ++ case 2: ++ wmmps_ac = psta->uapsd_bk & BIT(0); ++ break; ++ case 4: ++ case 5: ++ wmmps_ac = psta->uapsd_vi & BIT(0); ++ break; ++ case 6: ++ case 7: ++ wmmps_ac = psta->uapsd_vo & BIT(0); ++ break; ++ case 0: ++ case 3: ++ default: ++ wmmps_ac = psta->uapsd_be & BIT(0); ++ break; ++ } ++ ++ if (wmmps_ac) ++ return _FAIL; ++ ++ if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { ++ DBG_88E("%s alive check-rx ps-poll\n", __func__); ++ psta->expire_to = pstapriv->expire_to; ++ psta->state ^= WIFI_STA_ALIVE_CHK_STATE; ++ } ++ ++ if ((psta->state & WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap & BIT(psta->aid))) { ++ struct list_head *xmitframe_plist, *xmitframe_phead; ++ struct xmit_frame *pxmitframe = NULL; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ spin_lock_bh(&pxmitpriv->lock); ++ ++ xmitframe_phead = get_list_head(&psta->sleep_q); ++ xmitframe_plist = xmitframe_phead->next; ++ ++ if (xmitframe_phead != xmitframe_plist) { ++ pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); ++ ++ xmitframe_plist = xmitframe_plist->next; ++ ++ list_del_init(&pxmitframe->list); ++ ++ psta->sleepq_len--; ++ ++ if (psta->sleepq_len > 0) ++ pxmitframe->attrib.mdata = 1; ++ else ++ pxmitframe->attrib.mdata = 0; ++ ++ pxmitframe->attrib.triggered = 1; ++ ++ rtw_hal_xmitframe_enqueue(padapter, pxmitframe); ++ ++ if (psta->sleepq_len == 0) { ++ pstapriv->tim_bitmap &= ~BIT(psta->aid); ++ ++ /* upate BCN for TIM IE */ ++ /* update_BCNTIM(padapter); */ ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++ } ++ } else { ++ if (pstapriv->tim_bitmap & BIT(psta->aid)) { ++ if (psta->sleepq_len == 0) { ++ DBG_88E("no buffered packets to xmit\n"); ++ ++ /* issue nulldata with More data bit = 0 to indicate we have no buffered packets */ ++ issue_nulldata(padapter, psta->hwaddr, 0, 0, 0); ++ } else { ++ DBG_88E("error!psta->sleepq_len=%d\n", psta->sleepq_len); ++ psta->sleepq_len = 0; ++ } ++ ++ pstapriv->tim_bitmap &= ~BIT(psta->aid); ++ ++ /* upate BCN for TIM IE */ ++ /* update_BCNTIM(padapter); */ ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++ } ++ } ++ spin_unlock_bh(&pxmitpriv->lock); ++ } ++ } ++ ++#endif ++ ++ return _FAIL; ++} ++ ++struct recv_frame *recvframe_chk_defrag(struct adapter *padapter, struct recv_frame *precv_frame); ++ ++static int validate_recv_mgnt_frame(struct adapter *padapter, ++ struct recv_frame *precv_frame) ++{ ++ struct sta_info *psta; ++ ++ precv_frame = recvframe_chk_defrag(padapter, precv_frame); ++ if (!precv_frame) ++ return _SUCCESS; ++ ++ /* for rx pkt statistics */ ++ psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(precv_frame->rx_data)); ++ if (psta) { ++ psta->sta_stats.rx_mgnt_pkts++; ++ if (GetFrameSubType(precv_frame->rx_data) == WIFI_BEACON) { ++ psta->sta_stats.rx_beacon_pkts++; ++ } else if (GetFrameSubType(precv_frame->rx_data) == WIFI_PROBEREQ) { ++ psta->sta_stats.rx_probereq_pkts++; ++ } else if (GetFrameSubType(precv_frame->rx_data) == WIFI_PROBERSP) { ++ if (!memcmp(padapter->eeprompriv.mac_addr, GetAddr1Ptr(precv_frame->rx_data), ETH_ALEN)) ++ psta->sta_stats.rx_probersp_pkts++; ++ else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->rx_data)) || ++ is_multicast_mac_addr(GetAddr1Ptr(precv_frame->rx_data))) ++ psta->sta_stats.rx_probersp_bm_pkts++; ++ else ++ psta->sta_stats.rx_probersp_uo_pkts++; ++ } ++ } ++ ++ mgt_dispatcher(padapter, precv_frame); ++ ++ return _SUCCESS; ++} ++ ++static int validate_recv_data_frame(struct adapter *adapter, ++ struct recv_frame *precv_frame) ++{ ++ u8 bretry; ++ u8 *psa, *pda, *pbssid; ++ struct sta_info *psta = NULL; ++ u8 *ptr = precv_frame->rx_data; ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ struct security_priv *psecuritypriv = &adapter->securitypriv; ++ int ret = _SUCCESS; ++ ++ bretry = GetRetry(ptr); ++ pda = get_da(ptr); ++ psa = get_sa(ptr); ++ pbssid = get_hdr_bssid(ptr); ++ ++ if (!pbssid) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ memcpy(pattrib->dst, pda, ETH_ALEN); ++ memcpy(pattrib->src, psa, ETH_ALEN); ++ ++ memcpy(pattrib->bssid, pbssid, ETH_ALEN); ++ ++ switch (pattrib->to_fr_ds) { ++ case 0: ++ memcpy(pattrib->ra, pda, ETH_ALEN); ++ memcpy(pattrib->ta, psa, ETH_ALEN); ++ ret = sta2sta_data_frame(adapter, precv_frame, &psta); ++ break; ++ case 1: ++ memcpy(pattrib->ra, pda, ETH_ALEN); ++ memcpy(pattrib->ta, pbssid, ETH_ALEN); ++ ret = ap2sta_data_frame(adapter, precv_frame, &psta); ++ break; ++ case 2: ++ memcpy(pattrib->ra, pbssid, ETH_ALEN); ++ memcpy(pattrib->ta, psa, ETH_ALEN); ++ ret = sta2ap_data_frame(adapter, precv_frame, &psta); ++ break; ++ case 3: ++ memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); ++ memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN); ++ ret = _FAIL; ++ break; ++ default: ++ ret = _FAIL; ++ break; ++ } ++ ++ if (ret == _FAIL) { ++ goto exit; ++ } else if (ret == RTW_RX_HANDLED) { ++ goto exit; ++ } ++ ++ if (!psta) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ /* psta->rssi = prxcmd->rssi; */ ++ /* psta->signal_quality = prxcmd->sq; */ ++ precv_frame->psta = psta; ++ ++ pattrib->amsdu = 0; ++ pattrib->ack_policy = 0; ++ /* parsing QC field */ ++ if (pattrib->qos == 1) { ++ pattrib->priority = GetPriority((ptr + 24)); ++ pattrib->ack_policy = GetAckpolicy((ptr + 24)); ++ pattrib->amsdu = GetAMsdu((ptr + 24)); ++ pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 32 : 26; ++ ++ if (pattrib->priority != 0 && pattrib->priority != 3) ++ adapter->recvpriv.bIsAnyNonBEPkts = true; ++ } else { ++ pattrib->priority = 0; ++ pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 30 : 24; ++ } ++ ++ if (pattrib->order)/* HT-CTRL 11n */ ++ pattrib->hdrlen += 4; ++ ++ precv_frame->preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority]; ++ ++ /* decache, drop duplicate recv packets */ ++ if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) == _FAIL) { ++ ret = _FAIL; ++ goto exit; ++ } ++ ++ if (pattrib->privacy) { ++ GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, is_multicast_ether_addr(pattrib->ra)); ++ ++ SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt); ++ } else { ++ pattrib->encrypt = 0; ++ pattrib->iv_len = 0; ++ pattrib->icv_len = 0; ++ } ++ ++exit: ++ ++ return ret; ++} ++ ++static int validate_recv_frame(struct adapter *adapter, struct recv_frame *precv_frame) ++{ ++ /* shall check frame subtype, to / from ds, da, bssid */ ++ ++ /* then call check if rx seq/frag. duplicated. */ ++ ++ u8 type; ++ u8 subtype; ++ int retval = _SUCCESS; ++ u8 bDumpRxPkt; ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ u8 *ptr = precv_frame->rx_data; ++ u8 ver = (unsigned char)(*ptr) & 0x3; ++ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; ++ ++ if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { ++ int ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, rtw_get_oper_ch(adapter)); ++ if (ch_set_idx >= 0) ++ pmlmeext->channel_set[ch_set_idx].rx_count++; ++ } ++ ++ /* add version chk */ ++ if (ver != 0) { ++ retval = _FAIL; ++ goto exit; ++ } ++ ++ type = GetFrameType(ptr); ++ subtype = GetFrameSubType(ptr); /* bit(7)~bit(2) */ ++ ++ pattrib->to_fr_ds = get_tofr_ds(ptr); ++ ++ pattrib->frag_num = GetFragNum(ptr); ++ pattrib->seq_num = GetSequence(ptr); ++ ++ pattrib->pw_save = GetPwrMgt(ptr); ++ pattrib->mfrag = GetMFrag(ptr); ++ pattrib->mdata = GetMData(ptr); ++ pattrib->privacy = GetPrivacy(ptr); ++ pattrib->order = GetOrder(ptr); ++ ++ /* Dump rx packets */ ++ rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt)); ++ if (bDumpRxPkt == 1) {/* dump all rx packets */ ++ int i; ++ DBG_88E("#############################\n"); ++ ++ for (i = 0; i < 64; i = i + 8) ++ DBG_88E("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr + i), ++ *(ptr + i + 1), *(ptr + i + 2), *(ptr + i + 3), *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7)); ++ DBG_88E("#############################\n"); ++ } else if (bDumpRxPkt == 2) { ++ if (type == WIFI_MGT_TYPE) { ++ int i; ++ DBG_88E("#############################\n"); ++ ++ for (i = 0; i < 64; i = i + 8) ++ DBG_88E("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr + i), ++ *(ptr + i + 1), *(ptr + i + 2), *(ptr + i + 3), *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7)); ++ DBG_88E("#############################\n"); ++ } ++ } else if (bDumpRxPkt == 3) { ++ if (type == WIFI_DATA_TYPE) { ++ int i; ++ DBG_88E("#############################\n"); ++ ++ for (i = 0; i < 64; i = i + 8) ++ DBG_88E("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr + i), ++ *(ptr + i + 1), *(ptr + i + 2), *(ptr + i + 3), *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7)); ++ DBG_88E("#############################\n"); ++ } ++ } ++ switch (type) { ++ case WIFI_MGT_TYPE: /* mgnt */ ++ validate_recv_mgnt_frame(adapter, precv_frame); ++ retval = _FAIL; /* only data frame return _SUCCESS */ ++ break; ++ case WIFI_CTRL_TYPE: /* ctrl */ ++ validate_recv_ctrl_frame(adapter, precv_frame); ++ retval = _FAIL; /* only data frame return _SUCCESS */ ++ break; ++ case WIFI_DATA_TYPE: /* data */ ++ rtw_led_control(adapter, LED_CTL_RX); ++ pattrib->qos = (subtype & BIT(7)) ? 1 : 0; ++ retval = validate_recv_data_frame(adapter, precv_frame); ++ if (retval == _FAIL) { ++ struct recv_priv *precvpriv = &adapter->recvpriv; ++ precvpriv->rx_drop++; ++ } ++ break; ++ default: ++ retval = _FAIL; ++ break; ++ } ++ ++exit: ++ ++ return retval; ++} ++ ++/* remove the wlanhdr and add the eth_hdr */ ++ ++static int wlanhdr_to_ethhdr(struct recv_frame *precvframe) ++{ ++ int rmv_len; ++ u16 eth_type, len; ++ __be16 be_tmp; ++ u8 bsnaphdr; ++ u8 *psnap_type; ++ struct ieee80211_snap_hdr *psnap; ++ ++ int ret = _SUCCESS; ++ struct adapter *adapter = precvframe->adapter; ++ struct mlme_priv *pmlmepriv = &adapter->mlmepriv; ++ ++ u8 *ptr = get_recvframe_data(precvframe); /* point to frame_ctrl field */ ++ struct rx_pkt_attrib *pattrib = &precvframe->attrib; ++ ++ if (pattrib->encrypt) ++ recvframe_pull_tail(precvframe, pattrib->icv_len); ++ ++ psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len); ++ psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE; ++ /* convert hdr + possible LLC headers into Ethernet header */ ++ if ((!memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) && ++ memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) && ++ memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2)) || ++ !memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) { ++ /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ ++ bsnaphdr = true; ++ } else { ++ /* Leave Ethernet header part of hdr and full payload */ ++ bsnaphdr = false; ++ } ++ ++ rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr ? SNAP_SIZE : 0); ++ len = precvframe->len - rmv_len; ++ ++ memcpy(&be_tmp, ptr + rmv_len, 2); ++ eth_type = ntohs(be_tmp); /* pattrib->ether_type */ ++ pattrib->eth_type = eth_type; ++ ++ if ((check_fwstate(pmlmepriv, WIFI_MP_STATE))) { ++ ptr += rmv_len; ++ *ptr = 0x87; ++ *(ptr + 1) = 0x12; ++ ++ eth_type = 0x8712; ++ /* append rx status for mp test packets */ ++ ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2) - 24); ++ memcpy(ptr, get_rxmem(precvframe), 24); ++ ptr += 24; ++ } else { ++ ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0))); ++ } ++ ++ memcpy(ptr, pattrib->dst, ETH_ALEN); ++ memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN); ++ ++ if (!bsnaphdr) { ++ be_tmp = htons(len); ++ memcpy(ptr + 12, &be_tmp, 2); ++ } ++ ++ return ret; ++} ++ ++/* perform defrag */ ++static struct recv_frame *recvframe_defrag(struct adapter *adapter, struct __queue *defrag_q) ++{ ++ struct list_head *plist, *phead; ++ u8 wlanhdr_offset; ++ u8 curfragnum; ++ struct recv_frame *pfhdr, *pnfhdr; ++ struct recv_frame *prframe, *pnextrframe; ++ struct __queue *pfree_recv_queue; ++ ++ curfragnum = 0; ++ pfree_recv_queue = &adapter->recvpriv.free_recv_queue; ++ ++ phead = get_list_head(defrag_q); ++ plist = phead->next; ++ pfhdr = container_of(plist, struct recv_frame, list); ++ prframe = (struct recv_frame *)pfhdr; ++ list_del_init(&prframe->list); ++ ++ if (curfragnum != pfhdr->attrib.frag_num) { ++ /* the first fragment number must be 0 */ ++ /* free the whole queue */ ++ rtw_free_recvframe(prframe, pfree_recv_queue); ++ rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); ++ ++ return NULL; ++ } ++ ++ curfragnum++; ++ ++ plist = get_list_head(defrag_q); ++ plist = phead->next; ++ pfhdr = container_of(plist, struct recv_frame, list); ++ prframe = (struct recv_frame *)pfhdr; ++ list_del_init(&prframe->list); ++ ++ plist = plist->next; ++ ++ while (phead != plist) { ++ pnfhdr = container_of(plist, struct recv_frame, list); ++ pnextrframe = (struct recv_frame *)pnfhdr; ++ ++ /* check the fragment sequence (2nd ~n fragment frame) */ ++ ++ if (curfragnum != pnfhdr->attrib.frag_num) { ++ /* the fragment number must be increasing (after decache) */ ++ /* release the defrag_q & prframe */ ++ rtw_free_recvframe(prframe, pfree_recv_queue); ++ rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); ++ return NULL; ++ } ++ ++ curfragnum++; ++ ++ /* copy the 2nd~n fragment frame's payload to the first fragment */ ++ /* get the 2nd~last fragment frame's payload */ ++ ++ wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len; ++ ++ recvframe_pull(pnextrframe, wlanhdr_offset); ++ ++ /* append to first fragment frame's tail (if privacy frame, pull the ICV) */ ++ recvframe_pull_tail(prframe, pfhdr->attrib.icv_len); ++ ++ /* memcpy */ ++ memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len); ++ ++ recvframe_put(prframe, pnfhdr->len); ++ ++ pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len; ++ plist = plist->next; ++ } ++ ++ /* free the defrag_q queue and return the prframe */ ++ rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); ++ ++ return prframe; ++} ++ ++/* check if need to defrag, if needed queue the frame to defrag_q */ ++struct recv_frame *recvframe_chk_defrag(struct adapter *padapter, struct recv_frame *precv_frame) ++{ ++ u8 ismfrag; ++ u8 fragnum; ++ u8 *psta_addr; ++ struct recv_frame *pfhdr; ++ struct sta_info *psta; ++ struct sta_priv *pstapriv; ++ struct list_head *phead; ++ struct recv_frame *prtnframe = NULL; ++ struct __queue *pfree_recv_queue, *pdefrag_q; ++ ++ pstapriv = &padapter->stapriv; ++ ++ pfhdr = precv_frame; ++ ++ pfree_recv_queue = &padapter->recvpriv.free_recv_queue; ++ ++ /* need to define struct of wlan header frame ctrl */ ++ ismfrag = pfhdr->attrib.mfrag; ++ fragnum = pfhdr->attrib.frag_num; ++ ++ psta_addr = pfhdr->attrib.ta; ++ psta = rtw_get_stainfo(pstapriv, psta_addr); ++ if (!psta) { ++ u8 type = GetFrameType(pfhdr->rx_data); ++ if (type != WIFI_DATA_TYPE) { ++ psta = rtw_get_bcmc_stainfo(padapter); ++ pdefrag_q = &psta->sta_recvpriv.defrag_q; ++ } else { ++ pdefrag_q = NULL; ++ } ++ } else { ++ pdefrag_q = &psta->sta_recvpriv.defrag_q; ++ } ++ ++ if ((ismfrag == 0) && (fragnum == 0)) ++ prtnframe = precv_frame;/* isn't a fragment frame */ ++ ++ if (ismfrag == 1) { ++ /* 0~(n-1) fragment frame */ ++ /* enqueue to defraf_g */ ++ if (pdefrag_q) { ++ if (fragnum == 0) { ++ /* the first fragment */ ++ if (!list_empty(&pdefrag_q->queue)) { ++ /* free current defrag_q */ ++ rtw_free_recvframe_queue(pdefrag_q, pfree_recv_queue); ++ } ++ } ++ ++ /* Then enqueue the 0~(n-1) fragment into the defrag_q */ ++ ++ phead = get_list_head(pdefrag_q); ++ list_add_tail(&pfhdr->list, phead); ++ ++ prtnframe = NULL; ++ } else { ++ /* can't find this ta's defrag_queue, so free this recv_frame */ ++ if (precv_frame && pfree_recv_queue) ++ rtw_free_recvframe(precv_frame, pfree_recv_queue); ++ prtnframe = NULL; ++ } ++ } ++ ++ if ((ismfrag == 0) && (fragnum != 0)) { ++ /* the last fragment frame */ ++ /* enqueue the last fragment */ ++ if (pdefrag_q) { ++ phead = get_list_head(pdefrag_q); ++ list_add_tail(&pfhdr->list, phead); ++ ++ /* call recvframe_defrag to defrag */ ++ precv_frame = recvframe_defrag(padapter, pdefrag_q); ++ prtnframe = precv_frame; ++ } else { ++ /* can't find this ta's defrag_queue, so free this recv_frame */ ++ if (precv_frame && pfree_recv_queue) ++ rtw_free_recvframe(precv_frame, pfree_recv_queue); ++ prtnframe = NULL; ++ } ++ } ++ ++ if (prtnframe && prtnframe->attrib.privacy) { ++ /* after defrag we must check tkip mic code */ ++ if (recvframe_chkmic(padapter, prtnframe) == _FAIL) { ++ if (precv_frame && pfree_recv_queue) ++ rtw_free_recvframe(prtnframe, pfree_recv_queue); ++ prtnframe = NULL; ++ } ++ } ++ ++ return prtnframe; ++} ++ ++static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe) ++{ ++ int a_len, padding_len; ++ u16 eth_type, nSubframe_Length; ++ u8 nr_subframes, i; ++ unsigned char *pdata; ++ struct rx_pkt_attrib *pattrib; ++ unsigned char *data_ptr; ++ struct sk_buff *sub_skb, *subframes[MAX_SUBFRAME_COUNT]; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue; ++ int ret = _SUCCESS; ++ nr_subframes = 0; ++ ++ pattrib = &prframe->attrib; ++ ++ recvframe_pull(prframe, prframe->attrib.hdrlen); ++ ++ if (prframe->attrib.iv_len > 0) ++ recvframe_pull(prframe, prframe->attrib.iv_len); ++ ++ a_len = prframe->len; ++ ++ pdata = prframe->rx_data; ++ ++ while (a_len > ETH_HLEN) { ++ /* Offset 12 denote 2 mac address */ ++ nSubframe_Length = RTW_GET_BE16(pdata + 12); ++ ++ if (a_len < ETH_HLEN + nSubframe_Length) { ++ DBG_88E("nRemain_Length is %d and nSubframe_Length is : %d\n", a_len, nSubframe_Length); ++ goto exit; ++ } ++ ++ /* move the data point to data content */ ++ pdata += ETH_HLEN; ++ a_len -= ETH_HLEN; ++ ++ /* Allocate new skb for releasing to upper layer */ ++ sub_skb = dev_alloc_skb(nSubframe_Length + 12); ++ if (sub_skb) { ++ skb_reserve(sub_skb, 12); ++ data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length); ++ memcpy(data_ptr, pdata, nSubframe_Length); ++ } else { ++ sub_skb = skb_clone(prframe->pkt, GFP_ATOMIC); ++ if (sub_skb) { ++ sub_skb->data = pdata; ++ sub_skb->len = nSubframe_Length; ++ skb_set_tail_pointer(sub_skb, nSubframe_Length); ++ } else { ++ DBG_88E("skb_clone() Fail!!! , nr_subframes=%d\n", nr_subframes); ++ break; ++ } ++ } ++ ++ subframes[nr_subframes++] = sub_skb; ++ ++ if (nr_subframes >= MAX_SUBFRAME_COUNT) { ++ DBG_88E("ParseSubframe(): Too many Subframes! Packets dropped!\n"); ++ break; ++ } ++ ++ pdata += nSubframe_Length; ++ a_len -= nSubframe_Length; ++ if (a_len != 0) { ++ padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & (4 - 1)); ++ if (padding_len == 4) { ++ padding_len = 0; ++ } ++ ++ if (a_len < padding_len) { ++ goto exit; ++ } ++ pdata += padding_len; ++ a_len -= padding_len; ++ } ++ } ++ ++ for (i = 0; i < nr_subframes; i++) { ++ sub_skb = subframes[i]; ++ /* convert hdr + possible LLC headers into Ethernet header */ ++ eth_type = RTW_GET_BE16(&sub_skb->data[6]); ++ if (sub_skb->len >= 8 && ++ ((!memcmp(sub_skb->data, rtw_rfc1042_header, SNAP_SIZE) && ++ eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || ++ !memcmp(sub_skb->data, rtw_bridge_tunnel_header, SNAP_SIZE))) { ++ /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ ++ skb_pull(sub_skb, SNAP_SIZE); ++ memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN); ++ memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN); ++ } else { ++ __be16 len; ++ /* Leave Ethernet header part of hdr and full payload */ ++ len = htons(sub_skb->len); ++ memcpy(skb_push(sub_skb, 2), &len, 2); ++ memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN); ++ memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN); ++ } ++ ++ /* Indicate the packets to upper layer */ ++ /* Insert NAT2.5 RX here! */ ++ sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev); ++ sub_skb->dev = padapter->pnetdev; ++ ++ sub_skb->ip_summed = CHECKSUM_NONE; ++ ++ netif_rx(sub_skb); ++ } ++ ++exit: ++ ++ prframe->len = 0; ++ rtw_free_recvframe(prframe, pfree_recv_queue);/* free this recv_frame */ ++ ++ return ret; ++} ++ ++static int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num) ++{ ++ u8 wsize = preorder_ctrl->wsize_b; ++ u16 wend = (preorder_ctrl->indicate_seq + wsize - 1) & 0xFFF;/* 4096; */ ++ ++ /* Rx Reorder initialize condition. */ ++ if (preorder_ctrl->indicate_seq == 0xFFFF) ++ preorder_ctrl->indicate_seq = seq_num; ++ ++ /* Drop out the packet which SeqNum is smaller than WinStart */ ++ if (SN_LESS(seq_num, preorder_ctrl->indicate_seq)) ++ return false; ++ ++ /* */ ++ /* Sliding window manipulation. Conditions includes: */ ++ /* 1. Incoming SeqNum is equal to WinStart =>Window shift 1 */ ++ /* 2. Incoming SeqNum is larger than the WinEnd => Window shift N */ ++ /* */ ++ if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) { ++ preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF; ++ } else if (SN_LESS(wend, seq_num)) { ++ if (seq_num >= (wsize - 1)) ++ preorder_ctrl->indicate_seq = seq_num + 1 - wsize; ++ else ++ preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1; ++ } ++ ++ return true; ++} ++ ++int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, struct recv_frame *prframe); ++int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, struct recv_frame *prframe) ++{ ++ struct rx_pkt_attrib *pattrib = &prframe->attrib; ++ struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; ++ struct list_head *phead, *plist; ++ struct recv_frame *hdr; ++ struct rx_pkt_attrib *pnextattrib; ++ ++ phead = get_list_head(ppending_recvframe_queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ hdr = container_of(plist, struct recv_frame, list); ++ pnextattrib = &hdr->attrib; ++ ++ if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num)) ++ plist = plist->next; ++ else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) ++ return false; ++ else ++ break; ++ } ++ ++ list_del_init(&prframe->list); ++ ++ list_add_tail(&prframe->list, plist); ++ return true; ++} ++ ++static int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced) ++{ ++ struct list_head *phead, *plist; ++ struct recv_frame *prframe; ++ struct rx_pkt_attrib *pattrib; ++ int bPktInBuf = false; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; ++ ++ phead = get_list_head(ppending_recvframe_queue); ++ plist = phead->next; ++ ++ /* Handling some condition for forced indicate case. */ ++ if (bforced) { ++ if (list_empty(phead)) ++ return true; ++ ++ prframe = container_of(plist, struct recv_frame, list); ++ pattrib = &prframe->attrib; ++ preorder_ctrl->indicate_seq = pattrib->seq_num; ++ } ++ ++ /* Prepare indication list and indication. */ ++ /* Check if there is any packet need indicate. */ ++ while (!list_empty(phead)) { ++ prframe = container_of(plist, struct recv_frame, list); ++ pattrib = &prframe->attrib; ++ ++ if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) { ++ plist = plist->next; ++ list_del_init(&prframe->list); ++ ++ if (SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num)) ++ preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF; ++ ++ /* Set this as a lock to make sure that only one thread is indicating packet. */ ++ ++ /* indicate this recv_frame */ ++ if (!pattrib->amsdu) { ++ if ((!padapter->bDriverStopped) && ++ (!padapter->bSurpriseRemoved)) ++ rtw_recv_indicatepkt(padapter, prframe);/* indicate this recv_frame */ ++ } else if (pattrib->amsdu == 1) { ++ if (amsdu_to_msdu(padapter, prframe) != _SUCCESS) ++ rtw_free_recvframe(prframe, &precvpriv->free_recv_queue); ++ } else { ++ /* error condition; */ ++ } ++ ++ /* Update local variables. */ ++ bPktInBuf = false; ++ } else { ++ bPktInBuf = true; ++ break; ++ } ++ } ++ return bPktInBuf; ++} ++ ++static int recv_indicatepkt_reorder(struct adapter *padapter, struct recv_frame *prframe) ++{ ++ int retval = _SUCCESS; ++ struct rx_pkt_attrib *pattrib = &prframe->attrib; ++ struct recv_reorder_ctrl *preorder_ctrl = prframe->preorder_ctrl; ++ struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; ++ ++ if (!pattrib->amsdu) { ++ /* s1. */ ++ wlanhdr_to_ethhdr(prframe); ++ ++ if (pattrib->qos != 1) { ++ if (!padapter->bDriverStopped && ++ !padapter->bSurpriseRemoved) { ++ rtw_recv_indicatepkt(padapter, prframe); ++ return _SUCCESS; ++ } ++ ++ return _FAIL; ++ } ++ ++ if (!preorder_ctrl->enable) { ++ /* indicate this recv_frame */ ++ preorder_ctrl->indicate_seq = pattrib->seq_num; ++ rtw_recv_indicatepkt(padapter, prframe); ++ ++ preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) % 4096; ++ return _SUCCESS; ++ } ++ } else if (pattrib->amsdu == 1) { /* temp filter -> means didn't support A-MSDUs in a A-MPDU */ ++ if (!preorder_ctrl->enable) { ++ preorder_ctrl->indicate_seq = pattrib->seq_num; ++ retval = amsdu_to_msdu(padapter, prframe); ++ ++ preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) % 4096; ++ return retval; ++ } ++ } ++ ++ spin_lock_bh(&ppending_recvframe_queue->lock); ++ ++ /* s2. check if winstart_b(indicate_seq) needs to been updated */ ++ if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) ++ goto _err_exit; ++ ++ /* s3. Insert all packet into Reorder Queue to maintain its ordering. */ ++ if (!enqueue_reorder_recvframe(preorder_ctrl, prframe)) ++ goto _err_exit; ++ ++ /* s4. */ ++ /* Indication process. */ ++ /* After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets */ ++ /* with the SeqNum smaller than latest WinStart and buffer other packets. */ ++ /* */ ++ /* For Rx Reorder condition: */ ++ /* 1. All packets with SeqNum smaller than WinStart => Indicate */ ++ /* 2. All packets with SeqNum larger than or equal to WinStart => Buffer it. */ ++ /* */ ++ ++ /* recv_indicatepkts_in_order(padapter, preorder_ctrl, true); */ ++ if (recv_indicatepkts_in_order(padapter, preorder_ctrl, false)) { ++ _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME); ++ spin_unlock_bh(&ppending_recvframe_queue->lock); ++ } else { ++ spin_unlock_bh(&ppending_recvframe_queue->lock); ++ _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer); ++ } ++ ++ return _SUCCESS; ++ ++_err_exit: ++ ++ spin_unlock_bh(&ppending_recvframe_queue->lock); ++ ++ return _FAIL; ++} ++ ++void rtw_reordering_ctrl_timeout_handler(void *pcontext) ++{ ++ struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)pcontext; ++ struct adapter *padapter = preorder_ctrl->padapter; ++ struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; ++ ++ if (padapter->bDriverStopped || padapter->bSurpriseRemoved) ++ return; ++ ++ spin_lock_bh(&ppending_recvframe_queue->lock); ++ ++ if (recv_indicatepkts_in_order(padapter, preorder_ctrl, true)) ++ _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME); ++ ++ spin_unlock_bh(&ppending_recvframe_queue->lock); ++} ++ ++static int process_recv_indicatepkts(struct adapter *padapter, struct recv_frame *prframe) ++{ ++ int retval = _SUCCESS; ++ /* struct recv_priv *precvpriv = &padapter->recvpriv; */ ++ /* struct rx_pkt_attrib *pattrib = &prframe->attrib; */ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ ++ if (phtpriv->ht_option) { /* B/G/N Mode */ ++ /* prframe->preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority]; */ ++ ++ if (recv_indicatepkt_reorder(padapter, prframe) != _SUCCESS) { ++ /* including perform A-MPDU Rx Ordering Buffer Control */ ++ if ((!padapter->bDriverStopped) && ++ (!padapter->bSurpriseRemoved)) { ++ retval = _FAIL; ++ return retval; ++ } ++ } ++ } else { /* B/G mode */ ++ retval = wlanhdr_to_ethhdr(prframe); ++ if (retval != _SUCCESS) ++ return retval; ++ ++ if ((!padapter->bDriverStopped) && ++ (!padapter->bSurpriseRemoved)) { ++ /* indicate this recv_frame */ ++ rtw_recv_indicatepkt(padapter, prframe); ++ } else { ++ retval = _FAIL; ++ return retval; ++ } ++ } ++ ++ return retval; ++} ++ ++static int recv_func_prehandle(struct adapter *padapter, struct recv_frame *rframe) ++{ ++ int ret = _SUCCESS; ++ struct rx_pkt_attrib *pattrib = &rframe->attrib; ++ struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if (padapter->registrypriv.mp_mode == 1) { ++ if (pattrib->crc_err == 1) ++ padapter->mppriv.rx_crcerrpktcount++; ++ else ++ padapter->mppriv.rx_pktcount++; ++ ++ if (!check_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE)) { ++ ret = _FAIL; ++ rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */ ++ goto exit; ++ } ++ } ++ ++ /* check the frame crtl field and decache */ ++ ret = validate_recv_frame(padapter, rframe); ++ if (ret != _SUCCESS) { ++ rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */ ++ goto exit; ++ } ++ ++exit: ++ return ret; ++} ++ ++static int recv_func_posthandle(struct adapter *padapter, struct recv_frame *prframe) ++{ ++ int ret = _SUCCESS; ++ struct recv_frame *orig_prframe = prframe; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; ++ ++ /* DATA FRAME */ ++ rtw_led_control(padapter, LED_CTL_RX); ++ ++ prframe = decryptor(padapter, prframe); ++ if (!prframe) { ++ ret = _FAIL; ++ goto _recv_data_drop; ++ } ++ ++ prframe = recvframe_chk_defrag(padapter, prframe); ++ if (!prframe) ++ goto _recv_data_drop; ++ ++ prframe = portctrl(padapter, prframe); ++ if (!prframe) { ++ ret = _FAIL; ++ goto _recv_data_drop; ++ } ++ ++ count_rx_stats(padapter, prframe, NULL); ++ ++ ret = process_recv_indicatepkts(padapter, prframe); ++ if (ret != _SUCCESS) { ++ rtw_free_recvframe(orig_prframe, pfree_recv_queue);/* free this recv_frame */ ++ goto _recv_data_drop; ++ } ++ return ret; ++ ++_recv_data_drop: ++ precvpriv->rx_drop++; ++ return ret; ++} ++ ++static int recv_func(struct adapter *padapter, struct recv_frame *rframe) ++{ ++ int ret; ++ struct rx_pkt_attrib *prxattrib = &rframe->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct mlme_priv *mlmepriv = &padapter->mlmepriv; ++ struct recv_priv *recvpriv = &padapter->recvpriv; ++ ++ /* check if need to handle uc_swdec_pending_queue*/ ++ if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && ++ psecuritypriv->busetkipkey) { ++ struct recv_frame *pending_frame; ++ int cnt = 0; ++ ++ pending_frame = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue); ++ while (pending_frame) { ++ cnt++; ++ recv_func_posthandle(padapter, pending_frame); ++ } ++ } ++ ++ ret = recv_func_prehandle(padapter, rframe); ++ ++ if (ret == _SUCCESS) { ++ /* check if need to enqueue into uc_swdec_pending_queue*/ ++ if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && ++ !is_multicast_ether_addr(prxattrib->ra) && prxattrib->encrypt > 0 && ++ (prxattrib->bdecrypted == 0 || psecuritypriv->sw_decrypt) && ++ psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK && ++ !psecuritypriv->busetkipkey) { ++ rtw_enqueue_recvframe(rframe, &padapter->recvpriv.uc_swdec_pending_queue); ++ DBG_88E("%s: no key, enqueue uc_swdec_pending_queue\n", __func__); ++ if (recvpriv->free_recvframe_cnt < NR_RECVFRAME / 4) { ++ /* to prevent from recvframe starvation, ++ * get recvframe from uc_swdec_pending_queue to ++ * free_recvframe_cnt */ ++ rframe = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue); ++ if (rframe) ++ goto do_posthandle; ++ } ++ goto exit; ++ } ++do_posthandle: ++ ret = recv_func_posthandle(padapter, rframe); ++ } ++ ++exit: ++ return ret; ++} ++ ++s32 rtw_recv_entry(struct recv_frame *precvframe) ++{ ++ struct adapter *padapter; ++ struct recv_priv *precvpriv; ++ s32 ret = _SUCCESS; ++ ++ padapter = precvframe->adapter; ++ ++ precvpriv = &padapter->recvpriv; ++ ++ ret = recv_func(padapter, precvframe); ++ if (ret == _FAIL) ++ goto _recv_entry_drop; ++ ++ precvpriv->rx_pkts++; ++ ++ return ret; ++ ++_recv_entry_drop: ++ ++ if (padapter->registrypriv.mp_mode == 1) ++ padapter->mppriv.rx_pktloss = precvpriv->rx_drop; ++ ++ return ret; ++} ++ ++void rtw_signal_stat_timer_hdl(struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, recvpriv.signal_stat_timer); ++ struct recv_priv *recvpriv = &adapter->recvpriv; ++ ++ u32 tmp_s, tmp_q; ++ u8 avg_signal_strength = 0; ++ u8 avg_signal_qual = 0; ++ u8 _alpha = 3; /* this value is based on converging_constant = 5000 and sampling_interval = 1000 */ ++ ++ if (adapter->recvpriv.is_signal_dbg) { ++ /* update the user specific value, signal_strength_dbg, to signal_strength, rssi */ ++ adapter->recvpriv.signal_strength = adapter->recvpriv.signal_strength_dbg; ++ adapter->recvpriv.rssi = (s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg); ++ } else { ++ if (recvpriv->signal_strength_data.update_req == 0) {/* update_req is clear, means we got rx */ ++ avg_signal_strength = recvpriv->signal_strength_data.avg_val; ++ /* after avg_vals are accquired, we can re-stat the signal values */ ++ recvpriv->signal_strength_data.update_req = 1; ++ } ++ ++ if (recvpriv->signal_qual_data.update_req == 0) {/* update_req is clear, means we got rx */ ++ avg_signal_qual = recvpriv->signal_qual_data.avg_val; ++ /* after avg_vals are accquired, we can re-stat the signal values */ ++ recvpriv->signal_qual_data.update_req = 1; ++ } ++ ++ /* update value of signal_strength, rssi, signal_qual */ ++ if (!check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY)) { ++ tmp_s = (avg_signal_strength + (_alpha - 1) * recvpriv->signal_strength); ++ if (tmp_s % _alpha) ++ tmp_s = tmp_s / _alpha + 1; ++ else ++ tmp_s = tmp_s / _alpha; ++ if (tmp_s > 100) ++ tmp_s = 100; ++ ++ tmp_q = (avg_signal_qual + (_alpha - 1) * recvpriv->signal_qual); ++ if (tmp_q % _alpha) ++ tmp_q = tmp_q / _alpha + 1; ++ else ++ tmp_q = tmp_q / _alpha; ++ if (tmp_q > 100) ++ tmp_q = 100; ++ ++ recvpriv->signal_strength = tmp_s; ++ recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s); ++ recvpriv->signal_qual = tmp_q; ++ } ++ } ++ rtw_set_signal_stat_timer(recvpriv); ++} +diff --git a/drivers/staging/r8188eu/core/rtw_rf.c b/drivers/staging/r8188eu/core/rtw_rf.c +new file mode 100644 +index 000000000000..321546c40446 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_rf.c +@@ -0,0 +1,72 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_RF_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/xmit_osdep.h" ++ ++struct ch_freq { ++ u32 channel; ++ u32 frequency; ++}; ++ ++static struct ch_freq ch_freq_map[] = { ++ {1, 2412}, {2, 2417}, {3, 2422}, {4, 2427}, {5, 2432}, ++ {6, 2437}, {7, 2442}, {8, 2447}, {9, 2452}, {10, 2457}, ++ {11, 2462}, {12, 2467}, {13, 2472}, {14, 2484}, ++ /* UNII */ ++ {36, 5180}, {40, 5200}, {44, 5220}, {48, 5240}, {52, 5260}, ++ {56, 5280}, {60, 5300}, {64, 5320}, {149, 5745}, {153, 5765}, ++ {157, 5785}, {161, 5805}, {165, 5825}, {167, 5835}, {169, 5845}, ++ {171, 5855}, {173, 5865}, ++ /* HiperLAN2 */ ++ {100, 5500}, {104, 5520}, {108, 5540}, {112, 5560}, {116, 5580}, ++ {120, 5600}, {124, 5620}, {128, 5640}, {132, 5660}, {136, 5680}, ++ {140, 5700}, ++ /* Japan MMAC */ ++ {34, 5170}, {38, 5190}, {42, 5210}, {46, 5230}, ++ /* Japan */ ++ {184, 4920}, {188, 4940}, {192, 4960}, {196, 4980}, ++ {208, 5040},/* Japan, means J08 */ ++ {212, 5060},/* Japan, means J12 */ ++ {216, 5080},/* Japan, means J16 */ ++}; ++ ++static int ch_freq_map_num = (sizeof(ch_freq_map) / sizeof(struct ch_freq)); ++ ++u32 rtw_ch2freq(u32 channel) ++{ ++ u8 i; ++ u32 freq = 0; ++ ++ for (i = 0; i < ch_freq_map_num; i++) { ++ if (channel == ch_freq_map[i].channel) { ++ freq = ch_freq_map[i].frequency; ++ break; ++ } ++ } ++ if (i == ch_freq_map_num) ++ freq = 2412; ++ ++ return freq; ++} ++ ++u32 rtw_freq2ch(u32 freq) ++{ ++ u8 i; ++ u32 ch = 0; ++ ++ for (i = 0; i < ch_freq_map_num; i++) { ++ if (freq == ch_freq_map[i].frequency) { ++ ch = ch_freq_map[i].channel; ++ break; ++ } ++ } ++ if (i == ch_freq_map_num) ++ ch = 1; ++ ++ return ch; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_security.c b/drivers/staging/r8188eu/core/rtw_security.c +new file mode 100644 +index 000000000000..5aa893ab46e9 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_security.c +@@ -0,0 +1,1656 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_SECURITY_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wifi.h" ++#include "../include/osdep_intf.h" ++ ++/* WEP related ===== */ ++ ++#define CRC32_POLY 0x04c11db7 ++ ++struct arc4context { ++ u32 x; ++ u32 y; ++ u8 state[256]; ++}; ++ ++static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len) ++{ ++ u32 t, u; ++ u32 keyindex; ++ u32 stateindex; ++ u8 *state; ++ u32 counter; ++ ++ state = parc4ctx->state; ++ parc4ctx->x = 0; ++ parc4ctx->y = 0; ++ for (counter = 0; counter < 256; counter++) ++ state[counter] = (u8)counter; ++ keyindex = 0; ++ stateindex = 0; ++ for (counter = 0; counter < 256; counter++) { ++ t = state[counter]; ++ stateindex = (stateindex + key[keyindex] + t) & 0xff; ++ u = state[stateindex]; ++ state[stateindex] = (u8)t; ++ state[counter] = (u8)u; ++ if (++keyindex >= key_len) ++ keyindex = 0; ++ } ++ ++} ++ ++static u32 arcfour_byte(struct arc4context *parc4ctx) ++{ ++ u32 x; ++ u32 y; ++ u32 sx, sy; ++ u8 *state; ++ ++ state = parc4ctx->state; ++ x = (parc4ctx->x + 1) & 0xff; ++ sx = state[x]; ++ y = (sx + parc4ctx->y) & 0xff; ++ sy = state[y]; ++ parc4ctx->x = x; ++ parc4ctx->y = y; ++ state[y] = (u8)sx; ++ state[x] = (u8)sy; ++ ++ return state[(sx + sy) & 0xff]; ++} ++ ++static void arcfour_encrypt(struct arc4context *parc4ctx, u8 *dest, u8 *src, u32 len) ++{ ++ u32 i; ++ ++ for (i = 0; i < len; i++) ++ dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx); ++ ++} ++ ++/* ++ Need to consider the fragment situation ++*/ ++void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe) ++{ /* exclude ICV */ ++ union { ++ __le32 f0; ++ u8 f1[4]; ++ } crc; ++ struct arc4context mycontext; ++ ++ int curfragnum, length; ++ u32 keylength; ++ ++ u8 *pframe, *payload, *iv; /* wepkey */ ++ u8 wepkey[16]; ++ u8 hw_hdr_offset = 0; ++ struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ if (!((struct xmit_frame *)pxmitframe)->buf_addr) ++ return; ++ ++ hw_hdr_offset = TXDESC_SIZE + ++ (((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ); ++ ++ pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset; ++ ++ /* start to encrypt each fragment */ ++ if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) { ++ keylength = psecuritypriv->dot11DefKeylen[psecuritypriv->dot11PrivacyKeyIndex]; ++ ++ for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { ++ iv = pframe + pattrib->hdrlen; ++ memcpy(&wepkey[0], iv, 3); ++ memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength); ++ payload = pframe + pattrib->iv_len + pattrib->hdrlen; ++ ++ if ((curfragnum + 1) == pattrib->nr_frags) { /* the last fragment */ ++ length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; ++ ++ crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length)); ++ ++ arcfour_init(&mycontext, wepkey, 3 + keylength); ++ arcfour_encrypt(&mycontext, payload, payload, length); ++ arcfour_encrypt(&mycontext, payload + length, crc.f1, 4); ++ } else { ++ length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; ++ crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length)); ++ arcfour_init(&mycontext, wepkey, 3 + keylength); ++ arcfour_encrypt(&mycontext, payload, payload, length); ++ arcfour_encrypt(&mycontext, payload + length, crc.f1, 4); ++ ++ pframe += pxmitpriv->frag_len; ++ pframe = (u8 *)RND4((size_t)(pframe)); ++ } ++ } ++ } ++ ++} ++ ++void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe) ++{ ++ /* exclude ICV */ ++ struct arc4context mycontext; ++ int length; ++ u32 keylength; ++ u8 *pframe, *payload, *iv, wepkey[16]; ++ u8 keyindex; ++ struct rx_pkt_attrib *prxattrib = &(((struct recv_frame *)precvframe)->attrib); ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ ++ pframe = (unsigned char *)((struct recv_frame *)precvframe)->rx_data; ++ ++ /* start to decrypt recvframe */ ++ if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) { ++ iv = pframe + prxattrib->hdrlen; ++ keyindex = prxattrib->key_index; ++ keylength = psecuritypriv->dot11DefKeylen[keyindex]; ++ memcpy(&wepkey[0], iv, 3); ++ memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength); ++ length = ((struct recv_frame *)precvframe)->len - prxattrib->hdrlen - prxattrib->iv_len; ++ ++ payload = pframe + prxattrib->iv_len + prxattrib->hdrlen; ++ ++ /* decrypt payload include icv */ ++ arcfour_init(&mycontext, wepkey, 3 + keylength); ++ arcfour_encrypt(&mycontext, payload, payload, length); ++ } ++} ++ ++/* 3 ===== TKIP related ===== */ ++ ++static u32 secmicgetuint32(u8 *p) ++/* Convert from Byte[] to Us3232 in a portable way */ ++{ ++ s32 i; ++ u32 res = 0; ++ ++ for (i = 0; i < 4; i++) ++ res |= ((u32)(*p++)) << (8 * i); ++ ++ return res; ++} ++ ++static void secmicputuint32(u8 *p, u32 val) ++/* Convert from Us3232 to Byte[] in a portable way */ ++{ ++ long i; ++ ++ for (i = 0; i < 4; i++) { ++ *p++ = (u8)(val & 0xff); ++ val >>= 8; ++ } ++ ++} ++ ++static void secmicclear(struct mic_data *pmicdata) ++{ ++/* Reset the state to the empty message. */ ++ ++ pmicdata->L = pmicdata->K0; ++ pmicdata->R = pmicdata->K1; ++ pmicdata->nBytesInM = 0; ++ pmicdata->M = 0; ++ ++} ++ ++void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key) ++{ ++ /* Set the key */ ++ ++ pmicdata->K0 = secmicgetuint32(key); ++ pmicdata->K1 = secmicgetuint32(key + 4); ++ /* and reset the message */ ++ secmicclear(pmicdata); ++ ++} ++ ++void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b) ++{ ++ ++ /* Append the byte to our word-sized buffer */ ++ pmicdata->M |= ((unsigned long)b) << (8 * pmicdata->nBytesInM); ++ pmicdata->nBytesInM++; ++ /* Process the word if it is full. */ ++ if (pmicdata->nBytesInM >= 4) { ++ pmicdata->L ^= pmicdata->M; ++ pmicdata->R ^= ROL32(pmicdata->L, 17); ++ pmicdata->L += pmicdata->R; ++ pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | ((pmicdata->L & 0x00ff00ff) << 8); ++ pmicdata->L += pmicdata->R; ++ pmicdata->R ^= ROL32(pmicdata->L, 3); ++ pmicdata->L += pmicdata->R; ++ pmicdata->R ^= ROR32(pmicdata->L, 2); ++ pmicdata->L += pmicdata->R; ++ /* Clear the buffer */ ++ pmicdata->M = 0; ++ pmicdata->nBytesInM = 0; ++ } ++ ++} ++ ++void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes) ++{ ++ ++ /* This is simple */ ++ while (nbytes > 0) { ++ rtw_secmicappendbyte(pmicdata, *src++); ++ nbytes--; ++ } ++ ++} ++ ++void rtw_secgetmic(struct mic_data *pmicdata, u8 *dst) ++{ ++ ++ /* Append the minimum padding */ ++ rtw_secmicappendbyte(pmicdata, 0x5a); ++ rtw_secmicappendbyte(pmicdata, 0); ++ rtw_secmicappendbyte(pmicdata, 0); ++ rtw_secmicappendbyte(pmicdata, 0); ++ rtw_secmicappendbyte(pmicdata, 0); ++ /* and then zeroes until the length is a multiple of 4 */ ++ while (pmicdata->nBytesInM != 0) ++ rtw_secmicappendbyte(pmicdata, 0); ++ /* The appendByte function has already computed the result. */ ++ secmicputuint32(dst, pmicdata->L); ++ secmicputuint32(dst + 4, pmicdata->R); ++ /* Reset to the empty message. */ ++ secmicclear(pmicdata); ++ ++} ++ ++void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, u8 pri) ++{ ++ struct mic_data micdata; ++ u8 priority[4] = {0x0, 0x0, 0x0, 0x0}; ++ ++ rtw_secmicsetkey(&micdata, key); ++ priority[0] = pri; ++ ++ /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */ ++ if (header[1] & 1) { /* ToDS == 1 */ ++ rtw_secmicappend(&micdata, &header[16], 6); /* DA */ ++ if (header[1] & 2) /* From Ds == 1 */ ++ rtw_secmicappend(&micdata, &header[24], 6); ++ else ++ rtw_secmicappend(&micdata, &header[10], 6); ++ } else { /* ToDS == 0 */ ++ rtw_secmicappend(&micdata, &header[4], 6); /* DA */ ++ if (header[1] & 2) /* From Ds == 1 */ ++ rtw_secmicappend(&micdata, &header[16], 6); ++ else ++ rtw_secmicappend(&micdata, &header[10], 6); ++ } ++ rtw_secmicappend(&micdata, &priority[0], 4); ++ ++ rtw_secmicappend(&micdata, data, data_len); ++ ++ rtw_secgetmic(&micdata, mic_code); ++ ++} ++ ++/* macros for extraction/creation of unsigned char/unsigned short values */ ++#define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15)) ++#define Lo8(v16) ((u8)((v16) & 0x00FF)) ++#define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF)) ++#define Lo16(v32) ((u16)((v32) & 0xFFFF)) ++#define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF)) ++#define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8)) ++ ++/* select the Nth 16-bit word of the temporal key unsigned char array TK[] */ ++#define TK16(N) Mk16(tk[2 * (N) + 1], tk[2 * (N)]) ++ ++/* S-box lookup: 16 bits --> 16 bits */ ++#define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)]) ++ ++/* fixed algorithm "parameters" */ ++#define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */ ++#define TA_SIZE 6 /* 48-bit transmitter address */ ++#define TK_SIZE 16 /* 128-bit temporal key */ ++#define P1K_SIZE 10 /* 80-bit Phase1 key */ ++#define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */ ++ ++/* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */ ++static const unsigned short Sbox1[2][256] = { /* Sbox for hash (can be in ROM) */ ++{ ++ 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, ++ 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, ++ 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, ++ 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, ++ 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, ++ 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, ++ 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, ++ 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, ++ 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, ++ 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, ++ 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, ++ 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, ++ 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, ++ 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, ++ 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, ++ 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, ++ 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, ++ 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, ++ 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, ++ 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, ++ 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, ++ 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, ++ 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, ++ 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, ++ 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, ++ 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, ++ 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, ++ 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, ++ 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, ++ 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, ++ 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, ++ 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, ++ }, ++ ++ { /* second half of table is unsigned char-reversed version of first! */ ++ 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491, ++ 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC, ++ 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB, ++ 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B, ++ 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83, ++ 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A, ++ 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F, ++ 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA, ++ 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B, ++ 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713, ++ 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6, ++ 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85, ++ 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411, ++ 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B, ++ 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1, ++ 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF, ++ 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E, ++ 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6, ++ 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B, ++ 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD, ++ 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8, ++ 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2, ++ 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049, ++ 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810, ++ 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197, ++ 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F, ++ 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C, ++ 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927, ++ 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733, ++ 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5, ++ 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0, ++ 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C, ++ } ++}; ++ ++ /* ++********************************************************************** ++* Routine: Phase 1 -- generate P1K, given TA, TK, IV32 ++* ++* Inputs: ++* tk[] = temporal key [128 bits] ++* ta[] = transmitter's MAC address [ 48 bits] ++* iv32 = upper 32 bits of IV [ 32 bits] ++* Output: ++* p1k[] = Phase 1 key [ 80 bits] ++* ++* Note: ++* This function only needs to be called every 2**16 packets, ++* although in theory it could be called every packet. ++* ++********************************************************************** ++*/ ++static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32) ++{ ++ int i; ++ ++ /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */ ++ p1k[0] = Lo16(iv32); ++ p1k[1] = Hi16(iv32); ++ p1k[2] = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */ ++ p1k[3] = Mk16(ta[3], ta[2]); ++ p1k[4] = Mk16(ta[5], ta[4]); ++ ++ /* Now compute an unbalanced Feistel cipher with 80-bit block */ ++ /* size on the 80-bit block P1K[], using the 128-bit key TK[] */ ++ for (i = 0; i < PHASE1_LOOP_CNT; i++) { /* Each add operation here is mod 2**16 */ ++ p1k[0] += _S_(p1k[4] ^ TK16((i & 1) + 0)); ++ p1k[1] += _S_(p1k[0] ^ TK16((i & 1) + 2)); ++ p1k[2] += _S_(p1k[1] ^ TK16((i & 1) + 4)); ++ p1k[3] += _S_(p1k[2] ^ TK16((i & 1) + 6)); ++ p1k[4] += _S_(p1k[3] ^ TK16((i & 1) + 0)); ++ p1k[4] += (unsigned short)i; /* avoid "slide attacks" */ ++ } ++ ++} ++ ++/* ++********************************************************************** ++* Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16 ++* ++* Inputs: ++* tk[] = Temporal key [128 bits] ++* p1k[] = Phase 1 output key [ 80 bits] ++* iv16 = low 16 bits of IV counter [ 16 bits] ++* Output: ++* rc4key[] = the key used to encrypt the packet [128 bits] ++* ++* Note: ++* The value {TA, IV32, IV16} for Phase1/Phase2 must be unique ++* across all packets using the same key TK value. Then, for a ++* given value of TK[], this TKIP48 construction guarantees that ++* the final RC4KEY value is unique across all packets. ++* ++* Suggested implementation optimization: if PPK[] is "overlaid" ++* appropriately on RC4KEY[], there is no need for the final ++* for loop below that copies the PPK[] result into RC4KEY[]. ++* ++********************************************************************** ++*/ ++static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16) ++{ ++ int i; ++ u16 PPK[6]; /* temporary key for mixing */ ++ ++ /* Note: all adds in the PPK[] equations below are mod 2**16 */ ++ for (i = 0; i < 5; i++) ++ PPK[i] = p1k[i]; /* first, copy P1K to PPK */ ++ PPK[5] = p1k[4] + iv16; /* next, add in IV16 */ ++ ++ /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */ ++ PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */ ++ PPK[1] += _S_(PPK[0] ^ TK16(1)); ++ PPK[2] += _S_(PPK[1] ^ TK16(2)); ++ PPK[3] += _S_(PPK[2] ^ TK16(3)); ++ PPK[4] += _S_(PPK[3] ^ TK16(4)); ++ PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */ ++ ++ /* Final sweep: bijective, "linear". Rotates kill LSB correlations */ ++ PPK[0] += RotR1(PPK[5] ^ TK16(6)); ++ PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */ ++ PPK[2] += RotR1(PPK[1]); ++ PPK[3] += RotR1(PPK[2]); ++ PPK[4] += RotR1(PPK[3]); ++ PPK[5] += RotR1(PPK[4]); ++ /* Note: At this point, for a given key TK[0..15], the 96-bit output */ ++ /* value PPK[0..5] is guaranteed to be unique, as a function */ ++ /* of the 96-bit "input" value {TA, IV32, IV16}. That is, P1K */ ++ /* is now a keyed permutation of {TA, IV32, IV16}. */ ++ ++ /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */ ++ rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV */ ++ rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */ ++ rc4key[2] = Lo8(iv16); ++ rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1); ++ ++ /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */ ++ for (i = 0; i < 6; i++) { ++ rc4key[4 + 2 * i] = Lo8(PPK[i]); ++ rc4key[5 + 2 * i] = Hi8(PPK[i]); ++ } ++ ++} ++ ++/* The hlen isn't include the IV */ ++u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe) ++{ /* exclude ICV */ ++ u16 pnl; ++ u32 pnh; ++ u8 rc4key[16]; ++ u8 ttkey[16]; ++ union { ++ __le32 f0; ++ u8 f1[4]; ++ } crc; ++ u8 hw_hdr_offset = 0; ++ struct arc4context mycontext; ++ int curfragnum, length; ++ ++ u8 *pframe, *payload, *iv, *prwskey; ++ union pn48 dot11txpn; ++ struct sta_info *stainfo; ++ struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ u32 res = _SUCCESS; ++ ++ if (!((struct xmit_frame *)pxmitframe)->buf_addr) ++ return _FAIL; ++ ++ hw_hdr_offset = TXDESC_SIZE + ++ (((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ); ++ pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset; ++ /* 4 start to encrypt each fragment */ ++ if (pattrib->encrypt == _TKIP_) { ++ if (pattrib->psta) ++ stainfo = pattrib->psta; ++ else ++ stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]); ++ ++ if (stainfo) { ++ if (is_multicast_ether_addr(pattrib->ra)) ++ prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; ++ else ++ prwskey = &stainfo->dot118021x_UncstKey.skey[0]; ++ ++ for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { ++ iv = pframe + pattrib->hdrlen; ++ payload = pframe + pattrib->iv_len + pattrib->hdrlen; ++ ++ GET_TKIP_PN(iv, dot11txpn); ++ ++ pnl = (u16)(dot11txpn.val); ++ pnh = (u32)(dot11txpn.val >> 16); ++ phase1((u16 *)&ttkey[0], prwskey, &pattrib->ta[0], pnh); ++ phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], pnl); ++ ++ if ((curfragnum + 1) == pattrib->nr_frags) { /* 4 the last fragment */ ++ length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; ++ crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length)); ++ ++ arcfour_init(&mycontext, rc4key, 16); ++ arcfour_encrypt(&mycontext, payload, payload, length); ++ arcfour_encrypt(&mycontext, payload + length, crc.f1, 4); ++ } else { ++ length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; ++ crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length)); ++ ++ arcfour_init(&mycontext, rc4key, 16); ++ arcfour_encrypt(&mycontext, payload, payload, length); ++ arcfour_encrypt(&mycontext, payload + length, crc.f1, 4); ++ ++ pframe += pxmitpriv->frag_len; ++ pframe = (u8 *)RND4((size_t)(pframe)); ++ } ++ } ++ } else { ++ res = _FAIL; ++ } ++ } ++ ++ return res; ++} ++ ++/* The hlen isn't include the IV */ ++u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe) ++{ /* exclude ICV */ ++ u16 pnl; ++ u32 pnh; ++ u8 rc4key[16]; ++ u8 ttkey[16]; ++ union { ++ __le32 f0; ++ u8 f1[4]; ++ } crc; ++ struct arc4context mycontext; ++ int length; ++ ++ u8 *pframe, *payload, *iv, *prwskey; ++ union pn48 dot11txpn; ++ struct sta_info *stainfo; ++ struct rx_pkt_attrib *prxattrib = &((struct recv_frame *)precvframe)->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ u32 res = _SUCCESS; ++ ++ pframe = (unsigned char *)((struct recv_frame *)precvframe)->rx_data; ++ ++ /* 4 start to decrypt recvframe */ ++ if (prxattrib->encrypt == _TKIP_) { ++ stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]); ++ if (stainfo) { ++ if (is_multicast_ether_addr(prxattrib->ra)) { ++ if (!psecuritypriv->binstallGrpkey) { ++ res = _FAIL; ++ DBG_88E("%s:rx bc/mc packets, but didn't install group key!!!!!!!!!!\n", __func__); ++ goto exit; ++ } ++ prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey; ++ } else { ++ prwskey = &stainfo->dot118021x_UncstKey.skey[0]; ++ } ++ ++ iv = pframe + prxattrib->hdrlen; ++ payload = pframe + prxattrib->iv_len + prxattrib->hdrlen; ++ length = ((struct recv_frame *)precvframe)->len - prxattrib->hdrlen - prxattrib->iv_len; ++ ++ GET_TKIP_PN(iv, dot11txpn); ++ ++ pnl = (u16)(dot11txpn.val); ++ pnh = (u32)(dot11txpn.val >> 16); ++ ++ phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], pnh); ++ phase2(&rc4key[0], prwskey, (unsigned short *)&ttkey[0], pnl); ++ ++ /* 4 decrypt payload include icv */ ++ ++ arcfour_init(&mycontext, rc4key, 16); ++ arcfour_encrypt(&mycontext, payload, payload, length); ++ ++ crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length)); ++ ++ if (crc.f1[3] != payload[length - 1] || ++ crc.f1[2] != payload[length - 2] || ++ crc.f1[1] != payload[length - 3] || ++ crc.f1[0] != payload[length - 4]) ++ res = _FAIL; ++ } else { ++ res = _FAIL; ++ } ++ } ++ ++exit: ++ return res; ++} ++ ++/* 3 ===== AES related ===== */ ++ ++#define MAX_MSG_SIZE 2048 ++/*****************************/ ++/******** SBOX Table *********/ ++/*****************************/ ++ ++static u8 sbox_table[256] = { ++ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, ++ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, ++ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, ++ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, ++ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, ++ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, ++ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, ++ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, ++ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, ++ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, ++ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, ++ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, ++ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, ++ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, ++ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, ++ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, ++ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, ++ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, ++ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, ++ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, ++ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, ++ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, ++ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, ++ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, ++ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, ++ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, ++ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, ++ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, ++ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, ++ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, ++ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, ++ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ++}; ++ ++/*****************************/ ++/**** Function Prototypes ****/ ++/*****************************/ ++ ++static void bitwise_xor(u8 *ina, u8 *inb, u8 *out); ++static void construct_mic_iv(u8 *mic_header1, int qc_exists, int a4_exists, u8 *mpdu, uint payload_length, u8 *pn_vector); ++static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu); ++static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int qc_exists); ++static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, u8 *mpdu, u8 *pn_vector, int c); ++static void xor_128(u8 *a, u8 *b, u8 *out); ++static void xor_32(u8 *a, u8 *b, u8 *out); ++static u8 sbox(u8 a); ++static void next_key(u8 *key, int round); ++static void byte_sub(u8 *in, u8 *out); ++static void shift_row(u8 *in, u8 *out); ++static void mix_column(u8 *in, u8 *out); ++static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext); ++ ++/****************************************/ ++/* aes128k128d() */ ++/* Performs a 128 bit AES encrypt with */ ++/* 128 bit data. */ ++/****************************************/ ++static void xor_128(u8 *a, u8 *b, u8 *out) ++{ ++ int i; ++ ++ for (i = 0; i < 16; i++) ++ out[i] = a[i] ^ b[i]; ++ ++} ++ ++static void xor_32(u8 *a, u8 *b, u8 *out) ++{ ++ int i; ++ ++ for (i = 0; i < 4; i++) ++ out[i] = a[i] ^ b[i]; ++ ++} ++ ++static u8 sbox(u8 a) ++{ ++ return sbox_table[(int)a]; ++} ++ ++static void next_key(u8 *key, int round) ++{ ++ u8 rcon; ++ u8 sbox_key[4]; ++ u8 rcon_table[12] = { ++ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, ++ 0x1b, 0x36, 0x36, 0x36 ++ }; ++ ++ sbox_key[0] = sbox(key[13]); ++ sbox_key[1] = sbox(key[14]); ++ sbox_key[2] = sbox(key[15]); ++ sbox_key[3] = sbox(key[12]); ++ ++ rcon = rcon_table[round]; ++ ++ xor_32(&key[0], sbox_key, &key[0]); ++ key[0] = key[0] ^ rcon; ++ ++ xor_32(&key[4], &key[0], &key[4]); ++ xor_32(&key[8], &key[4], &key[8]); ++ xor_32(&key[12], &key[8], &key[12]); ++ ++} ++ ++static void byte_sub(u8 *in, u8 *out) ++{ ++ int i; ++ ++ for (i = 0; i < 16; i++) ++ out[i] = sbox(in[i]); ++ ++} ++ ++static void shift_row(u8 *in, u8 *out) ++{ ++ ++ out[0] = in[0]; ++ out[1] = in[5]; ++ out[2] = in[10]; ++ out[3] = in[15]; ++ out[4] = in[4]; ++ out[5] = in[9]; ++ out[6] = in[14]; ++ out[7] = in[3]; ++ out[8] = in[8]; ++ out[9] = in[13]; ++ out[10] = in[2]; ++ out[11] = in[7]; ++ out[12] = in[12]; ++ out[13] = in[1]; ++ out[14] = in[6]; ++ out[15] = in[11]; ++ ++} ++ ++static void mix_column(u8 *in, u8 *out) ++{ ++ int i; ++ u8 add1b[4]; ++ u8 add1bf7[4]; ++ u8 rotl[4]; ++ u8 swap_halfs[4]; ++ u8 andf7[4]; ++ u8 rotr[4]; ++ u8 temp[4]; ++ u8 tempb[4]; ++ ++ for (i = 0 ; i < 4; i++) { ++ if ((in[i] & 0x80) == 0x80) ++ add1b[i] = 0x1b; ++ else ++ add1b[i] = 0x00; ++ } ++ ++ swap_halfs[0] = in[2]; /* Swap halves */ ++ swap_halfs[1] = in[3]; ++ swap_halfs[2] = in[0]; ++ swap_halfs[3] = in[1]; ++ ++ rotl[0] = in[3]; /* Rotate left 8 bits */ ++ rotl[1] = in[0]; ++ rotl[2] = in[1]; ++ rotl[3] = in[2]; ++ ++ andf7[0] = in[0] & 0x7f; ++ andf7[1] = in[1] & 0x7f; ++ andf7[2] = in[2] & 0x7f; ++ andf7[3] = in[3] & 0x7f; ++ ++ for (i = 3; i > 0; i--) { /* logical shift left 1 bit */ ++ andf7[i] = andf7[i] << 1; ++ if ((andf7[i - 1] & 0x80) == 0x80) ++ andf7[i] = (andf7[i] | 0x01); ++ } ++ andf7[0] = andf7[0] << 1; ++ andf7[0] = andf7[0] & 0xfe; ++ ++ xor_32(add1b, andf7, add1bf7); ++ ++ xor_32(in, add1bf7, rotr); ++ ++ temp[0] = rotr[0]; /* Rotate right 8 bits */ ++ rotr[0] = rotr[1]; ++ rotr[1] = rotr[2]; ++ rotr[2] = rotr[3]; ++ rotr[3] = temp[0]; ++ ++ xor_32(add1bf7, rotr, temp); ++ xor_32(swap_halfs, rotl, tempb); ++ xor_32(temp, tempb, out); ++ ++} ++ ++static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext) ++{ ++ int round; ++ int i; ++ u8 intermediatea[16]; ++ u8 intermediateb[16]; ++ u8 round_key[16]; ++ ++ for (i = 0; i < 16; i++) ++ round_key[i] = key[i]; ++ for (round = 0; round < 11; round++) { ++ if (round == 0) { ++ xor_128(round_key, data, ciphertext); ++ next_key(round_key, round); ++ } else if (round == 10) { ++ byte_sub(ciphertext, intermediatea); ++ shift_row(intermediatea, intermediateb); ++ xor_128(intermediateb, round_key, ciphertext); ++ } else { /* 1 - 9 */ ++ byte_sub(ciphertext, intermediatea); ++ shift_row(intermediatea, intermediateb); ++ mix_column(&intermediateb[0], &intermediatea[0]); ++ mix_column(&intermediateb[4], &intermediatea[4]); ++ mix_column(&intermediateb[8], &intermediatea[8]); ++ mix_column(&intermediateb[12], &intermediatea[12]); ++ xor_128(intermediatea, round_key, ciphertext); ++ next_key(round_key, round); ++ } ++ } ++ ++} ++ ++/************************************************/ ++/* construct_mic_iv() */ ++/* Builds the MIC IV from header fields and PN */ ++/************************************************/ ++static void construct_mic_iv(u8 *mic_iv, int qc_exists, int a4_exists, u8 *mpdu, ++ uint payload_length, u8 *pn_vector) ++{ ++ int i; ++ ++ mic_iv[0] = 0x59; ++ if (qc_exists && a4_exists) ++ mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */ ++ if (qc_exists && !a4_exists) ++ mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */ ++ if (!qc_exists) ++ mic_iv[1] = 0x00; ++ for (i = 2; i < 8; i++) ++ mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */ ++ for (i = 8; i < 14; i++) ++ mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */ ++ mic_iv[14] = (unsigned char)(payload_length / 256); ++ mic_iv[15] = (unsigned char)(payload_length % 256); ++ ++} ++ ++/************************************************/ ++/* construct_mic_header1() */ ++/* Builds the first MIC header block from */ ++/* header fields. */ ++/************************************************/ ++static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu) ++{ ++ ++ mic_header1[0] = (u8)((header_length - 2) / 256); ++ mic_header1[1] = (u8)((header_length - 2) % 256); ++ mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */ ++ mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */ ++ mic_header1[4] = mpdu[4]; /* A1 */ ++ mic_header1[5] = mpdu[5]; ++ mic_header1[6] = mpdu[6]; ++ mic_header1[7] = mpdu[7]; ++ mic_header1[8] = mpdu[8]; ++ mic_header1[9] = mpdu[9]; ++ mic_header1[10] = mpdu[10]; /* A2 */ ++ mic_header1[11] = mpdu[11]; ++ mic_header1[12] = mpdu[12]; ++ mic_header1[13] = mpdu[13]; ++ mic_header1[14] = mpdu[14]; ++ mic_header1[15] = mpdu[15]; ++ ++} ++ ++/************************************************/ ++/* construct_mic_header2() */ ++/* Builds the last MIC header block from */ ++/* header fields. */ ++/************************************************/ ++static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int qc_exists) ++{ ++ int i; ++ ++ for (i = 0; i < 16; i++) ++ mic_header2[i] = 0x00; ++ ++ mic_header2[0] = mpdu[16]; /* A3 */ ++ mic_header2[1] = mpdu[17]; ++ mic_header2[2] = mpdu[18]; ++ mic_header2[3] = mpdu[19]; ++ mic_header2[4] = mpdu[20]; ++ mic_header2[5] = mpdu[21]; ++ ++ mic_header2[6] = 0x00; ++ mic_header2[7] = 0x00; /* mpdu[23]; */ ++ ++ if (!qc_exists && a4_exists) { ++ for (i = 0; i < 6; i++) ++ mic_header2[8 + i] = mpdu[24 + i]; /* A4 */ ++ } ++ ++ if (qc_exists && !a4_exists) { ++ mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */ ++ mic_header2[9] = mpdu[25] & 0x00; ++ } ++ ++ if (qc_exists && a4_exists) { ++ for (i = 0; i < 6; i++) ++ mic_header2[8 + i] = mpdu[24 + i]; /* A4 */ ++ ++ mic_header2[14] = mpdu[30] & 0x0f; ++ mic_header2[15] = mpdu[31] & 0x00; ++ } ++ ++} ++ ++/************************************************/ ++/* construct_mic_header2() */ ++/* Builds the last MIC header block from */ ++/* header fields. */ ++/************************************************/ ++static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, u8 *mpdu, u8 *pn_vector, int c) ++{ ++ int i; ++ ++ for (i = 0; i < 16; i++) ++ ctr_preload[i] = 0x00; ++ i = 0; ++ ++ ctr_preload[0] = 0x01; /* flag */ ++ if (qc_exists && a4_exists) ++ ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */ ++ if (qc_exists && !a4_exists) ++ ctr_preload[1] = mpdu[24] & 0x0f; ++ ++ for (i = 2; i < 8; i++) ++ ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */ ++ for (i = 8; i < 14; i++) ++ ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */ ++ ctr_preload[14] = (unsigned char)(c / 256); /* Ctr */ ++ ctr_preload[15] = (unsigned char)(c % 256); ++ ++} ++ ++/************************************/ ++/* bitwise_xor() */ ++/* A 128 bit, bitwise exclusive or */ ++/************************************/ ++static void bitwise_xor(u8 *ina, u8 *inb, u8 *out) ++{ ++ int i; ++ ++ for (i = 0; i < 16; i++) ++ out[i] = ina[i] ^ inb[i]; ++ ++} ++ ++static int aes_cipher(u8 *key, uint hdrlen, u8 *pframe, uint plen) ++{ ++ uint qc_exists, a4_exists, i, j, payload_remainder, ++ num_blocks, payload_index; ++ ++ u8 pn_vector[6]; ++ u8 mic_iv[16]; ++ u8 mic_header1[16]; ++ u8 mic_header2[16]; ++ u8 ctr_preload[16]; ++ ++ /* Intermediate Buffers */ ++ u8 chain_buffer[16]; ++ u8 aes_out[16]; ++ u8 padded_buffer[16]; ++ u8 mic[8]; ++ uint frtype = GetFrameType(pframe); ++ uint frsubtype = GetFrameSubType(pframe); ++ ++ frsubtype = frsubtype >> 4; ++ ++ memset((void *)mic_iv, 0, 16); ++ memset((void *)mic_header1, 0, 16); ++ memset((void *)mic_header2, 0, 16); ++ memset((void *)ctr_preload, 0, 16); ++ memset((void *)chain_buffer, 0, 16); ++ memset((void *)aes_out, 0, 16); ++ memset((void *)padded_buffer, 0, 16); ++ ++ if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN)) ++ a4_exists = 0; ++ else ++ a4_exists = 1; ++ ++ if ((frtype == WIFI_DATA_CFACK) || (frtype == WIFI_DATA_CFPOLL) || (frtype == WIFI_DATA_CFACKPOLL)) { ++ qc_exists = 1; ++ if (hdrlen != WLAN_HDR_A3_QOS_LEN) ++ hdrlen += 2; ++ } else if ((frsubtype == 0x08) || (frsubtype == 0x09) || (frsubtype == 0x0a) || (frsubtype == 0x0b)) { ++ if (hdrlen != WLAN_HDR_A3_QOS_LEN) ++ hdrlen += 2; ++ qc_exists = 1; ++ } else { ++ qc_exists = 0; ++ } ++ ++ pn_vector[0] = pframe[hdrlen]; ++ pn_vector[1] = pframe[hdrlen + 1]; ++ pn_vector[2] = pframe[hdrlen + 4]; ++ pn_vector[3] = pframe[hdrlen + 5]; ++ pn_vector[4] = pframe[hdrlen + 6]; ++ pn_vector[5] = pframe[hdrlen + 7]; ++ ++ construct_mic_iv(mic_iv, qc_exists, a4_exists, pframe, plen, pn_vector); ++ ++ construct_mic_header1(mic_header1, hdrlen, pframe); ++ construct_mic_header2(mic_header2, pframe, a4_exists, qc_exists); ++ ++ payload_remainder = plen % 16; ++ num_blocks = plen / 16; ++ ++ /* Find start of payload */ ++ payload_index = (hdrlen + 8); ++ ++ /* Calculate MIC */ ++ aes128k128d(key, mic_iv, aes_out); ++ bitwise_xor(aes_out, mic_header1, chain_buffer); ++ aes128k128d(key, chain_buffer, aes_out); ++ bitwise_xor(aes_out, mic_header2, chain_buffer); ++ aes128k128d(key, chain_buffer, aes_out); ++ ++ for (i = 0; i < num_blocks; i++) { ++ bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);/* bitwise_xor(aes_out, &message[payload_index], chain_buffer); */ ++ ++ payload_index += 16; ++ aes128k128d(key, chain_buffer, aes_out); ++ } ++ ++ /* Add on the final payload block if it needs padding */ ++ if (payload_remainder > 0) { ++ for (j = 0; j < 16; j++) ++ padded_buffer[j] = 0x00; ++ for (j = 0; j < payload_remainder; j++) ++ padded_buffer[j] = pframe[payload_index++];/* padded_buffer[j] = message[payload_index++]; */ ++ bitwise_xor(aes_out, padded_buffer, chain_buffer); ++ aes128k128d(key, chain_buffer, aes_out); ++ } ++ ++ for (j = 0; j < 8; j++) ++ mic[j] = aes_out[j]; ++ ++ /* Insert MIC into payload */ ++ for (j = 0; j < 8; j++) ++ pframe[payload_index + j] = mic[j]; /* message[payload_index+j] = mic[j]; */ ++ ++ payload_index = hdrlen + 8; ++ for (i = 0; i < num_blocks; i++) { ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, i + 1); ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, &pframe[payload_index], chain_buffer); ++ for (j = 0; j < 16; j++) ++ pframe[payload_index++] = chain_buffer[j]; ++ } ++ ++ if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/ ++ /* encrypt it and copy the unpadded part back */ ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, num_blocks + 1); ++ ++ for (j = 0; j < 16; j++) ++ padded_buffer[j] = 0x00; ++ for (j = 0; j < payload_remainder; j++) ++ padded_buffer[j] = pframe[payload_index + j]; ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, padded_buffer, chain_buffer); ++ for (j = 0; j < payload_remainder; j++) ++ pframe[payload_index++] = chain_buffer[j]; ++ } ++ /* Encrypt the MIC */ ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, 0); ++ ++ for (j = 0; j < 16; j++) ++ padded_buffer[j] = 0x00; ++ for (j = 0; j < 8; j++) ++ padded_buffer[j] = pframe[j + hdrlen + 8 + plen]; ++ ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, padded_buffer, chain_buffer); ++ for (j = 0; j < 8; j++) ++ pframe[payload_index++] = chain_buffer[j]; ++ ++ return _SUCCESS; ++} ++ ++u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe) ++{ /* exclude ICV */ ++ ++ /*static*/ ++/* unsigned char message[MAX_MSG_SIZE]; */ ++ ++ /* Intermediate Buffers */ ++ int curfragnum, length; ++ u8 *pframe, *prwskey; /* *payload,*iv */ ++ u8 hw_hdr_offset = 0; ++ struct sta_info *stainfo; ++ struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++/* uint offset = 0; */ ++ u32 res = _SUCCESS; ++ ++ if (!((struct xmit_frame *)pxmitframe)->buf_addr) ++ return _FAIL; ++ ++ hw_hdr_offset = TXDESC_SIZE + ++ (((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ); ++ ++ pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset; ++ ++ /* 4 start to encrypt each fragment */ ++ if (pattrib->encrypt == _AES_) { ++ if (pattrib->psta) ++ stainfo = pattrib->psta; ++ else ++ stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]); ++ ++ if (stainfo) { ++ if (is_multicast_ether_addr(pattrib->ra)) ++ prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; ++ else ++ prwskey = &stainfo->dot118021x_UncstKey.skey[0]; ++ for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { ++ if ((curfragnum + 1) == pattrib->nr_frags) { /* 4 the last fragment */ ++ length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; ++ ++ aes_cipher(prwskey, pattrib->hdrlen, pframe, length); ++ } else { ++ length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; ++ ++ aes_cipher(prwskey, pattrib->hdrlen, pframe, length); ++ pframe += pxmitpriv->frag_len; ++ pframe = (u8 *)RND4((size_t)(pframe)); ++ } ++ } ++ } else { ++ res = _FAIL; ++ } ++ } ++ ++ return res; ++} ++ ++static int aes_decipher(u8 *key, uint hdrlen, ++ u8 *pframe, uint plen) ++{ ++ static u8 message[MAX_MSG_SIZE]; ++ uint qc_exists, a4_exists, i, j, payload_remainder, ++ num_blocks, payload_index; ++ int res = _SUCCESS; ++ u8 pn_vector[6]; ++ u8 mic_iv[16]; ++ u8 mic_header1[16]; ++ u8 mic_header2[16]; ++ u8 ctr_preload[16]; ++ ++ /* Intermediate Buffers */ ++ u8 chain_buffer[16]; ++ u8 aes_out[16]; ++ u8 padded_buffer[16]; ++ u8 mic[8]; ++ ++/* uint offset = 0; */ ++ uint frtype = GetFrameType(pframe); ++ uint frsubtype = GetFrameSubType(pframe); ++ ++ frsubtype = frsubtype >> 4; ++ ++ memset((void *)mic_iv, 0, 16); ++ memset((void *)mic_header1, 0, 16); ++ memset((void *)mic_header2, 0, 16); ++ memset((void *)ctr_preload, 0, 16); ++ memset((void *)chain_buffer, 0, 16); ++ memset((void *)aes_out, 0, 16); ++ memset((void *)padded_buffer, 0, 16); ++ ++ /* start to decrypt the payload */ ++ ++ num_blocks = (plen - 8) / 16; /* plen including llc, payload_length and mic) */ ++ ++ payload_remainder = (plen - 8) % 16; ++ ++ pn_vector[0] = pframe[hdrlen]; ++ pn_vector[1] = pframe[hdrlen + 1]; ++ pn_vector[2] = pframe[hdrlen + 4]; ++ pn_vector[3] = pframe[hdrlen + 5]; ++ pn_vector[4] = pframe[hdrlen + 6]; ++ pn_vector[5] = pframe[hdrlen + 7]; ++ ++ if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN)) ++ a4_exists = 0; ++ else ++ a4_exists = 1; ++ ++ if ((frtype == WIFI_DATA_CFACK) || (frtype == WIFI_DATA_CFPOLL) || ++ (frtype == WIFI_DATA_CFACKPOLL)) { ++ qc_exists = 1; ++ if (hdrlen != WLAN_HDR_A3_QOS_LEN) ++ hdrlen += 2; ++ } else if ((frsubtype == 0x08) || (frsubtype == 0x09) || ++ (frsubtype == 0x0a) || (frsubtype == 0x0b)) { ++ if (hdrlen != WLAN_HDR_A3_QOS_LEN) ++ hdrlen += 2; ++ qc_exists = 1; ++ } else { ++ qc_exists = 0; ++ } ++ ++ /* now, decrypt pframe with hdrlen offset and plen long */ ++ ++ payload_index = hdrlen + 8; /* 8 is for extiv */ ++ ++ for (i = 0; i < num_blocks; i++) { ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, i + 1); ++ ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, &pframe[payload_index], chain_buffer); ++ ++ for (j = 0; j < 16; j++) ++ pframe[payload_index++] = chain_buffer[j]; ++ } ++ ++ if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/ ++ /* encrypt it and copy the unpadded part back */ ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, num_blocks + 1); ++ ++ for (j = 0; j < 16; j++) ++ padded_buffer[j] = 0x00; ++ for (j = 0; j < payload_remainder; j++) ++ padded_buffer[j] = pframe[payload_index + j]; ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, padded_buffer, chain_buffer); ++ for (j = 0; j < payload_remainder; j++) ++ pframe[payload_index++] = chain_buffer[j]; ++ } ++ ++ /* start to calculate the mic */ ++ if ((hdrlen + plen + 8) <= MAX_MSG_SIZE) ++ memcpy(message, pframe, (hdrlen + plen + 8)); /* 8 is for ext iv len */ ++ ++ pn_vector[0] = pframe[hdrlen]; ++ pn_vector[1] = pframe[hdrlen + 1]; ++ pn_vector[2] = pframe[hdrlen + 4]; ++ pn_vector[3] = pframe[hdrlen + 5]; ++ pn_vector[4] = pframe[hdrlen + 6]; ++ pn_vector[5] = pframe[hdrlen + 7]; ++ construct_mic_iv(mic_iv, qc_exists, a4_exists, message, plen - 8, pn_vector); ++ ++ construct_mic_header1(mic_header1, hdrlen, message); ++ construct_mic_header2(mic_header2, message, a4_exists, qc_exists); ++ ++ payload_remainder = (plen - 8) % 16; ++ num_blocks = (plen - 8) / 16; ++ ++ /* Find start of payload */ ++ payload_index = (hdrlen + 8); ++ ++ /* Calculate MIC */ ++ aes128k128d(key, mic_iv, aes_out); ++ bitwise_xor(aes_out, mic_header1, chain_buffer); ++ aes128k128d(key, chain_buffer, aes_out); ++ bitwise_xor(aes_out, mic_header2, chain_buffer); ++ aes128k128d(key, chain_buffer, aes_out); ++ ++ for (i = 0; i < num_blocks; i++) { ++ bitwise_xor(aes_out, &message[payload_index], chain_buffer); ++ ++ payload_index += 16; ++ aes128k128d(key, chain_buffer, aes_out); ++ } ++ ++ /* Add on the final payload block if it needs padding */ ++ if (payload_remainder > 0) { ++ for (j = 0; j < 16; j++) ++ padded_buffer[j] = 0x00; ++ for (j = 0; j < payload_remainder; j++) ++ padded_buffer[j] = message[payload_index++]; ++ bitwise_xor(aes_out, padded_buffer, chain_buffer); ++ aes128k128d(key, chain_buffer, aes_out); ++ } ++ ++ for (j = 0 ; j < 8; j++) ++ mic[j] = aes_out[j]; ++ ++ /* Insert MIC into payload */ ++ for (j = 0; j < 8; j++) ++ message[payload_index + j] = mic[j]; ++ ++ payload_index = hdrlen + 8; ++ for (i = 0; i < num_blocks; i++) { ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, i + 1); ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, &message[payload_index], chain_buffer); ++ for (j = 0; j < 16; j++) ++ message[payload_index++] = chain_buffer[j]; ++ } ++ ++ if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/ ++ /* encrypt it and copy the unpadded part back */ ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, num_blocks + 1); ++ ++ for (j = 0; j < 16; j++) ++ padded_buffer[j] = 0x00; ++ for (j = 0; j < payload_remainder; j++) ++ padded_buffer[j] = message[payload_index + j]; ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, padded_buffer, chain_buffer); ++ for (j = 0; j < payload_remainder; j++) ++ message[payload_index++] = chain_buffer[j]; ++ } ++ ++ /* Encrypt the MIC */ ++ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, 0); ++ ++ for (j = 0; j < 16; j++) ++ padded_buffer[j] = 0x00; ++ for (j = 0; j < 8; j++) ++ padded_buffer[j] = message[j + hdrlen + 8 + plen - 8]; ++ ++ aes128k128d(key, ctr_preload, aes_out); ++ bitwise_xor(aes_out, padded_buffer, chain_buffer); ++ for (j = 0; j < 8; j++) ++ message[payload_index++] = chain_buffer[j]; ++ ++ /* compare the mic */ ++ for (i = 0; i < 8; i++) { ++ if (pframe[hdrlen + 8 + plen - 8 + i] != message[hdrlen + 8 + plen - 8 + i]) { ++ DBG_88E("aes_decipher:mic check error mic[%d]: pframe(%x)!=message(%x)\n", ++ i, pframe[hdrlen + 8 + plen - 8 + i], message[hdrlen + 8 + plen - 8 + i]); ++ res = _FAIL; ++ } ++ } ++ ++ return res; ++} ++ ++u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe) ++{ /* exclude ICV */ ++ /* Intermediate Buffers */ ++ int length; ++ u8 *pframe, *prwskey; /* *payload,*iv */ ++ struct sta_info *stainfo; ++ struct rx_pkt_attrib *prxattrib = &((struct recv_frame *)precvframe)->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ u32 res = _SUCCESS; ++ ++ pframe = (unsigned char *)((struct recv_frame *)precvframe)->rx_data; ++ /* 4 start to encrypt each fragment */ ++ if (prxattrib->encrypt == _AES_) { ++ stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]); ++ if (stainfo) { ++ if (is_multicast_ether_addr(prxattrib->ra)) { ++ /* in concurrent we should use sw descrypt in group key, so we remove this message */ ++ if (!psecuritypriv->binstallGrpkey) { ++ res = _FAIL; ++ DBG_88E("%s:rx bc/mc packets, but didn't install group key!!!!!!!!!!\n", __func__); ++ goto exit; ++ } ++ prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey; ++ if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) { ++ DBG_88E("not match packet_index=%d, install_index=%d\n", ++ prxattrib->key_index, psecuritypriv->dot118021XGrpKeyid); ++ res = _FAIL; ++ goto exit; ++ } ++ } else { ++ prwskey = &stainfo->dot118021x_UncstKey.skey[0]; ++ } ++ length = ((struct recv_frame *)precvframe)->len - prxattrib->hdrlen - prxattrib->iv_len; ++ res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length); ++ } else { ++ res = _FAIL; ++ } ++ } ++ ++exit: ++ return res; ++} ++ ++/* AES tables*/ ++const u32 Te0[256] = { ++ 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, ++ 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, ++ 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, ++ 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, ++ 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, ++ 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, ++ 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, ++ 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, ++ 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, ++ 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, ++ 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, ++ 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, ++ 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, ++ 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, ++ 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, ++ 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, ++ 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, ++ 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, ++ 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, ++ 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, ++ 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, ++ 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, ++ 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, ++ 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, ++ 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, ++ 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, ++ 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, ++ 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, ++ 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, ++ 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, ++ 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, ++ 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, ++ 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, ++ 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, ++ 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, ++ 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, ++ 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, ++ 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, ++ 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, ++ 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, ++ 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, ++ 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, ++ 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, ++ 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, ++ 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, ++ 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, ++ 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, ++ 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, ++ 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, ++ 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, ++ 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, ++ 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, ++ 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, ++ 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, ++ 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, ++ 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, ++ 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, ++ 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, ++ 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, ++ 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, ++ 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, ++ 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, ++ 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, ++ 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, ++}; ++ ++const u32 Td0[256] = { ++ 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, ++ 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, ++ 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, ++ 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, ++ 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, ++ 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, ++ 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, ++ 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, ++ 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, ++ 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, ++ 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, ++ 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, ++ 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, ++ 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, ++ 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, ++ 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, ++ 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, ++ 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, ++ 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, ++ 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, ++ 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, ++ 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, ++ 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, ++ 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, ++ 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, ++ 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, ++ 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, ++ 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, ++ 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, ++ 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, ++ 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, ++ 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, ++ 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, ++ 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, ++ 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, ++ 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, ++ 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, ++ 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, ++ 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, ++ 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, ++ 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, ++ 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, ++ 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, ++ 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, ++ 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, ++ 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, ++ 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, ++ 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, ++ 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, ++ 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, ++ 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, ++ 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, ++ 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, ++ 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, ++ 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, ++ 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, ++ 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, ++ 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, ++ 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, ++ 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, ++ 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, ++ 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, ++ 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, ++ 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, ++}; ++ ++const u8 Td4s[256] = { ++ 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, ++ 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, ++ 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, ++ 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, ++ 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, ++ 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, ++ 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, ++ 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, ++ 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, ++ 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, ++ 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, ++ 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, ++ 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, ++ 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, ++ 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, ++ 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, ++ 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, ++ 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, ++ 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, ++ 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, ++ 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, ++ 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, ++ 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, ++ 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, ++ 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, ++ 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, ++ 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, ++ 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, ++ 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, ++ 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, ++ 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, ++ 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, ++}; ++const u8 rcons[] = { ++ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 ++ /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ ++}; ++ ++/** ++ * Expand the cipher key into the encryption key schedule. ++ * ++ * @return the number of rounds for the given cipher key size. ++ */ ++#define ROUND(i, d, s) \ ++do { \ ++ d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \ ++ d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \ ++ d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \ ++ d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]; \ ++} while (0); ++ ++/** ++ * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC) ++ * @key: 128-bit key for the hash operation ++ * @data: Data buffer for which a MAC is determined ++ * @data_len: Length of data buffer in bytes ++ * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) ++ * Returns: 0 on success, -1 on failure ++ * ++ * This is a mode for using block cipher (AES in this case) for authentication. ++ * OMAC1 was standardized with the name CMAC by NIST in a Special Publication ++ * (SP) 800-38B. ++ */ ++void rtw_use_tkipkey_handler(void *FunctionContext) ++{ ++ struct adapter *padapter = (struct adapter *)FunctionContext; ++ ++ padapter->securitypriv.busetkipkey = true; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_sreset.c b/drivers/staging/r8188eu/core/rtw_sreset.c +new file mode 100644 +index 000000000000..c831033d20a9 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_sreset.c +@@ -0,0 +1,62 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#include "../include/rtw_sreset.h" ++ ++void sreset_init_value(struct adapter *padapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct sreset_priv *psrtpriv = &pHalData->srestpriv; ++ ++ _rtw_mutex_init(&psrtpriv->silentreset_mutex); ++ psrtpriv->silent_reset_inprogress = false; ++ psrtpriv->wifi_error_status = WIFI_STATUS_SUCCESS; ++ psrtpriv->last_tx_time = 0; ++ psrtpriv->last_tx_complete_time = 0; ++} ++void sreset_reset_value(struct adapter *padapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct sreset_priv *psrtpriv = &pHalData->srestpriv; ++ ++ psrtpriv->silent_reset_inprogress = false; ++ psrtpriv->wifi_error_status = WIFI_STATUS_SUCCESS; ++ psrtpriv->last_tx_time = 0; ++ psrtpriv->last_tx_complete_time = 0; ++} ++ ++u8 sreset_get_wifi_status(struct adapter *padapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct sreset_priv *psrtpriv = &pHalData->srestpriv; ++ ++ u8 status = WIFI_STATUS_SUCCESS; ++ u32 val32 = 0; ++ ++ if (psrtpriv->silent_reset_inprogress) ++ return status; ++ val32 = rtw_read32(padapter, REG_TXDMA_STATUS); ++ if (val32 == 0xeaeaeaea) { ++ psrtpriv->wifi_error_status = WIFI_IF_NOT_EXIST; ++ } else if (val32 != 0) { ++ DBG_88E("txdmastatu(%x)\n", val32); ++ psrtpriv->wifi_error_status = WIFI_MAC_TXDMA_ERROR; ++ } ++ ++ if (WIFI_STATUS_SUCCESS != psrtpriv->wifi_error_status) { ++ DBG_88E("==>%s error_status(0x%x)\n", __func__, psrtpriv->wifi_error_status); ++ status = (psrtpriv->wifi_error_status & (~(USB_READ_PORT_FAIL | USB_WRITE_PORT_FAIL))); ++ } ++ DBG_88E("==> %s wifi_status(0x%x)\n", __func__, status); ++ ++ /* status restore */ ++ psrtpriv->wifi_error_status = WIFI_STATUS_SUCCESS; ++ ++ return status; ++} ++ ++void sreset_set_wifi_error_status(struct adapter *padapter, u32 status) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ pHalData->srestpriv.wifi_error_status = status; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_sta_mgt.c b/drivers/staging/r8188eu/core/rtw_sta_mgt.c +new file mode 100644 +index 000000000000..f6dffed53a60 +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_sta_mgt.c +@@ -0,0 +1,508 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTW_STA_MGT_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/xmit_osdep.h" ++#include "../include/mlme_osdep.h" ++#include "../include/sta_info.h" ++ ++static void _rtw_init_stainfo(struct sta_info *psta) ++{ ++ ++ memset((u8 *)psta, 0, sizeof(struct sta_info)); ++ ++ spin_lock_init(&psta->lock); ++ INIT_LIST_HEAD(&psta->list); ++ INIT_LIST_HEAD(&psta->hash_list); ++ _rtw_init_queue(&psta->sleep_q); ++ psta->sleepq_len = 0; ++ ++ _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv); ++ _rtw_init_sta_recv_priv(&psta->sta_recvpriv); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++ INIT_LIST_HEAD(&psta->asoc_list); ++ ++ INIT_LIST_HEAD(&psta->auth_list); ++ ++ psta->expire_to = 0; ++ ++ psta->flags = 0; ++ ++ psta->capability = 0; ++ ++ psta->bpairwise_key_installed = false; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ psta->nonerp_set = 0; ++ psta->no_short_slot_time_set = 0; ++ psta->no_short_preamble_set = 0; ++ psta->no_ht_gf_set = 0; ++ psta->no_ht_set = 0; ++ psta->ht_20mhz_set = 0; ++#endif ++ ++ psta->under_exist_checking = 0; ++ ++ psta->keep_alive_trycnt = 0; ++ ++#endif /* CONFIG_88EU_AP_MODE */ ++ ++} ++ ++u32 _rtw_init_sta_priv(struct sta_priv *pstapriv) ++{ ++ struct sta_info *psta; ++ s32 i; ++ ++ pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * NUM_STA + 4); ++ ++ if (!pstapriv->pallocated_stainfo_buf) ++ return _FAIL; ++ ++ pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 - ++ ((size_t)(pstapriv->pallocated_stainfo_buf) & 3); ++ ++ _rtw_init_queue(&pstapriv->free_sta_queue); ++ ++ spin_lock_init(&pstapriv->sta_hash_lock); ++ ++ pstapriv->asoc_sta_count = 0; ++ _rtw_init_queue(&pstapriv->sleep_q); ++ _rtw_init_queue(&pstapriv->wakeup_q); ++ ++ psta = (struct sta_info *)(pstapriv->pstainfo_buf); ++ ++ for (i = 0; i < NUM_STA; i++) { ++ _rtw_init_stainfo(psta); ++ ++ INIT_LIST_HEAD(&pstapriv->sta_hash[i]); ++ ++ list_add_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue)); ++ ++ psta++; ++ } ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++ pstapriv->sta_dz_bitmap = 0; ++ pstapriv->tim_bitmap = 0; ++ ++ INIT_LIST_HEAD(&pstapriv->asoc_list); ++ INIT_LIST_HEAD(&pstapriv->auth_list); ++ spin_lock_init(&pstapriv->asoc_list_lock); ++ spin_lock_init(&pstapriv->auth_list_lock); ++ pstapriv->asoc_list_cnt = 0; ++ pstapriv->auth_list_cnt = 0; ++ ++ pstapriv->auth_to = 3; /* 3*2 = 6 sec */ ++ pstapriv->assoc_to = 3; ++ pstapriv->expire_to = 3; /* 3*2 = 6 sec */ ++ pstapriv->max_num_sta = NUM_STA; ++#endif ++ ++ return _SUCCESS; ++} ++ ++inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta) ++{ ++ int offset = (((u8 *)sta) - stapriv->pstainfo_buf) / sizeof(struct sta_info); ++ ++ if (!stainfo_offset_valid(offset)) ++ DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset); ++ ++ return offset; ++} ++ ++inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset) ++{ ++ if (!stainfo_offset_valid(offset)) ++ DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset); ++ ++ return (struct sta_info *)(stapriv->pstainfo_buf + offset * sizeof(struct sta_info)); ++} ++ ++u32 _rtw_free_sta_priv(struct sta_priv *pstapriv) ++{ ++ struct list_head *phead, *plist; ++ struct sta_info *psta = NULL; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ int index; ++ ++ if (pstapriv) { ++ /* delete all reordering_ctrl_timer */ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ for (index = 0; index < NUM_STA; index++) { ++ phead = &pstapriv->sta_hash[index]; ++ plist = phead->next; ++ ++ while (phead != plist) { ++ int i; ++ psta = container_of(plist, struct sta_info, hash_list); ++ plist = plist->next; ++ ++ for (i = 0; i < 16; i++) { ++ preorder_ctrl = &psta->recvreorder_ctrl[i]; ++ _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer); ++ } ++ } ++ } ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ /*===============================*/ ++ ++ if (pstapriv->pallocated_stainfo_buf) ++ vfree(pstapriv->pallocated_stainfo_buf); ++ } ++ ++ return _SUCCESS; ++} ++ ++struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) ++{ ++ s32 index; ++ struct list_head *phash_list; ++ struct sta_info *psta; ++ struct __queue *pfree_sta_queue; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ int i = 0; ++ u16 wRxSeqInitialValue = 0xffff; ++ ++ pfree_sta_queue = &pstapriv->free_sta_queue; ++ ++ spin_lock_bh(&pfree_sta_queue->lock); ++ ++ if (list_empty(&pfree_sta_queue->queue)) { ++ spin_unlock_bh(&pfree_sta_queue->lock); ++ psta = NULL; ++ } else { ++ psta = container_of((&pfree_sta_queue->queue)->next, struct sta_info, list); ++ list_del_init(&psta->list); ++ spin_unlock_bh(&pfree_sta_queue->lock); ++ _rtw_init_stainfo(psta); ++ memcpy(psta->hwaddr, hwaddr, ETH_ALEN); ++ index = wifi_mac_hash(hwaddr); ++ if (index >= NUM_STA) { ++ psta = NULL; ++ goto exit; ++ } ++ phash_list = &pstapriv->sta_hash[index]; ++ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ ++ list_add_tail(&psta->hash_list, phash_list); ++ ++ pstapriv->asoc_sta_count++; ++ ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++/* Commented by Albert 2009/08/13 */ ++/* For the SMC router, the sequence number of first packet of WPS handshake will be 0. */ ++/* In this case, this packet will be dropped by recv_decache function if we use the 0x00 as the default value for tid_rxseq variable. */ ++/* So, we initialize the tid_rxseq variable as the 0xffff. */ ++ ++ for (i = 0; i < 16; i++) ++ memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2); ++ ++ init_addba_retry_timer(pstapriv->padapter, psta); ++ ++ /* for A-MPDU Rx reordering buffer control */ ++ for (i = 0; i < 16; i++) { ++ preorder_ctrl = &psta->recvreorder_ctrl[i]; ++ ++ preorder_ctrl->padapter = pstapriv->padapter; ++ ++ preorder_ctrl->enable = false; ++ ++ preorder_ctrl->indicate_seq = 0xffff; ++ preorder_ctrl->wend_b = 0xffff; ++ preorder_ctrl->wsize_b = 64;/* 64; */ ++ ++ _rtw_init_queue(&preorder_ctrl->pending_recvframe_queue); ++ ++ rtw_init_recv_timer(preorder_ctrl); ++ } ++ ++ /* init for DM */ ++ psta->rssi_stat.UndecoratedSmoothedPWDB = (-1); ++ psta->rssi_stat.UndecoratedSmoothedCCK = (-1); ++ ++ /* init for the sequence number of received management frame */ ++ psta->RxMgmtFrameSeqNum = 0xffff; ++ } ++ ++exit: ++ ++ return psta; ++} ++ ++/* using pstapriv->sta_hash_lock to protect */ ++u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta) ++{ ++ int i; ++ struct __queue *pfree_sta_queue; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ struct sta_xmit_priv *pstaxmitpriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ if (!psta) ++ goto exit; ++ ++ pfree_sta_queue = &pstapriv->free_sta_queue; ++ ++ pstaxmitpriv = &psta->sta_xmitpriv; ++ ++ spin_lock_bh(&pxmitpriv->lock); ++ ++ rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q); ++ psta->sleepq_len = 0; ++ ++ rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending); ++ ++ list_del_init(&pstaxmitpriv->vo_q.tx_pending); ++ ++ rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending); ++ ++ list_del_init(&pstaxmitpriv->vi_q.tx_pending); ++ ++ rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending); ++ ++ list_del_init(&pstaxmitpriv->bk_q.tx_pending); ++ ++ rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending); ++ ++ list_del_init(&pstaxmitpriv->be_q.tx_pending); ++ ++ spin_unlock_bh(&pxmitpriv->lock); ++ ++ list_del_init(&psta->hash_list); ++ pstapriv->asoc_sta_count--; ++ ++ /* re-init sta_info; 20061114 */ ++ _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv); ++ _rtw_init_sta_recv_priv(&psta->sta_recvpriv); ++ ++ _cancel_timer_ex(&psta->addba_retry_timer); ++ ++ /* for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer */ ++ for (i = 0; i < 16 ; i++) { ++ struct list_head *phead, *plist; ++ struct recv_frame *prframe; ++ struct __queue *ppending_recvframe_queue; ++ struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; ++ ++ preorder_ctrl = &psta->recvreorder_ctrl[i]; ++ ++ _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer); ++ ++ ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; ++ ++ spin_lock_bh(&ppending_recvframe_queue->lock); ++ ++ phead = get_list_head(ppending_recvframe_queue); ++ plist = phead->next; ++ ++ while (!list_empty(phead)) { ++ prframe = container_of(plist, struct recv_frame, list); ++ ++ plist = plist->next; ++ ++ list_del_init(&prframe->list); ++ ++ rtw_free_recvframe(prframe, pfree_recv_queue); ++ } ++ ++ spin_unlock_bh(&ppending_recvframe_queue->lock); ++ } ++ ++ if (!(psta->state & WIFI_AP_STATE)) ++ rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, false); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++ spin_lock_bh(&pstapriv->auth_list_lock); ++ if (!list_empty(&psta->auth_list)) { ++ list_del_init(&psta->auth_list); ++ pstapriv->auth_list_cnt--; ++ } ++ spin_unlock_bh(&pstapriv->auth_list_lock); ++ ++ psta->expire_to = 0; ++ ++ psta->sleepq_ac_len = 0; ++ psta->qos_info = 0; ++ ++ psta->max_sp_len = 0; ++ psta->uapsd_bk = 0; ++ psta->uapsd_be = 0; ++ psta->uapsd_vi = 0; ++ psta->uapsd_vo = 0; ++ psta->has_legacy_ac = 0; ++ ++ pstapriv->sta_dz_bitmap &= ~BIT(psta->aid); ++ pstapriv->tim_bitmap &= ~BIT(psta->aid); ++ ++ if ((psta->aid > 0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) { ++ pstapriv->sta_aid[psta->aid - 1] = NULL; ++ psta->aid = 0; ++ } ++ ++ psta->under_exist_checking = 0; ++ ++#endif /* CONFIG_88EU_AP_MODE */ ++ ++ spin_lock_bh(&pfree_sta_queue->lock); ++ list_add_tail(&psta->list, get_list_head(pfree_sta_queue)); ++ spin_unlock_bh(&pfree_sta_queue->lock); ++ ++exit: ++ ++ return _SUCCESS; ++} ++ ++/* free all stainfo which in sta_hash[all] */ ++void rtw_free_all_stainfo(struct adapter *padapter) ++{ ++ struct list_head *plist, *phead; ++ s32 index; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo(padapter); ++ ++ if (pstapriv->asoc_sta_count == 1) ++ return; ++ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ ++ for (index = 0; index < NUM_STA; index++) { ++ phead = &pstapriv->sta_hash[index]; ++ plist = phead->next; ++ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, hash_list); ++ ++ plist = plist->next; ++ ++ if (pbcmc_stainfo != psta) ++ rtw_free_stainfo(padapter, psta); ++ } ++ } ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++} ++ ++/* any station allocated can be searched by hash list */ ++struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) ++{ ++ struct list_head *plist, *phead; ++ struct sta_info *psta = NULL; ++ u32 index; ++ u8 *addr; ++ u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ ++ if (!hwaddr) ++ return NULL; ++ ++ if (IS_MCAST(hwaddr)) ++ addr = bc_addr; ++ else ++ addr = hwaddr; ++ ++ index = wifi_mac_hash(addr); ++ ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ ++ phead = &pstapriv->sta_hash[index]; ++ plist = phead->next; ++ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, hash_list); ++ ++ if ((!memcmp(psta->hwaddr, addr, ETH_ALEN))) { ++ /* if found the matched address */ ++ break; ++ } ++ psta = NULL; ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ ++ return psta; ++} ++ ++u32 rtw_init_bcmc_stainfo(struct adapter *padapter) ++{ ++ struct sta_info *psta; ++ u32 res = _SUCCESS; ++ unsigned char bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ psta = rtw_alloc_stainfo(pstapriv, bcast_addr); ++ ++ if (!psta) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ /* default broadcast & multicast use macid 1 */ ++ psta->mac_id = 1; ++ ++exit: ++ ++ return res; ++} ++ ++struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter) ++{ ++ struct sta_info *psta; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ ++ psta = rtw_get_stainfo(pstapriv, bc_addr); ++ ++ return psta; ++} ++ ++u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr) ++{ ++ u8 res = true; ++#ifdef CONFIG_88EU_AP_MODE ++ struct list_head *plist, *phead; ++ struct rtw_wlan_acl_node *paclnode; ++ u8 match = false; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; ++ struct __queue *pacl_node_q = &pacl_list->acl_node_q; ++ ++ spin_lock_bh(&pacl_node_q->lock); ++ phead = get_list_head(pacl_node_q); ++ plist = phead->next; ++ while (phead != plist) { ++ paclnode = container_of(plist, struct rtw_wlan_acl_node, list); ++ plist = plist->next; ++ ++ if (!memcmp(paclnode->addr, mac_addr, ETH_ALEN)) { ++ if (paclnode->valid) { ++ match = true; ++ break; ++ } ++ } ++ } ++ spin_unlock_bh(&pacl_node_q->lock); ++ ++ if (pacl_list->mode == 1)/* accept unless in deny list */ ++ res = (match) ? false : true; ++ else if (pacl_list->mode == 2)/* deny unless in accept list */ ++ res = (match) ? true : false; ++ else ++ res = true; ++ ++#endif ++ ++ return res; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_wlan_util.c b/drivers/staging/r8188eu/core/rtw_wlan_util.c +new file mode 100644 +index 000000000000..a3a5e1c64c4a +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_wlan_util.c +@@ -0,0 +1,1643 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_WLAN_UTIL_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wifi.h" ++ ++static unsigned char ARTHEROS_OUI1[] = {0x00, 0x03, 0x7f}; ++static unsigned char ARTHEROS_OUI2[] = {0x00, 0x13, 0x74}; ++ ++static unsigned char BROADCOM_OUI1[] = {0x00, 0x10, 0x18}; ++static unsigned char BROADCOM_OUI2[] = {0x00, 0x0a, 0xf7}; ++ ++static unsigned char CISCO_OUI[] = {0x00, 0x40, 0x96}; ++static unsigned char MARVELL_OUI[] = {0x00, 0x50, 0x43}; ++static unsigned char RALINK_OUI[] = {0x00, 0x0c, 0x43}; ++static unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c}; ++static unsigned char AIRGOCAP_OUI[] = {0x00, 0x0a, 0xf5}; ++static unsigned char EPIGRAM_OUI[] = {0x00, 0x90, 0x4c}; ++ ++unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20}; ++ ++#define R2T_PHY_DELAY (0) ++ ++/* define WAIT_FOR_BCN_TO_M (3000) */ ++#define WAIT_FOR_BCN_TO_MIN (6000) ++#define WAIT_FOR_BCN_TO_MAX (20000) ++ ++static u8 rtw_basic_rate_cck[4] = { ++ IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK, ++ IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK ++}; ++ ++static u8 rtw_basic_rate_ofdm[3] = { ++ IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK, ++ IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK ++}; ++ ++static u8 rtw_basic_rate_mix[7] = { ++ IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK, ++ IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK, ++ IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK, ++ IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK ++}; ++ ++int cckrates_included(unsigned char *rate, int ratelen) ++{ ++ int i; ++ ++ for (i = 0; i < ratelen; i++) { ++ if ((((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) || ++ (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22)) ++ return true; ++ } ++ return false; ++} ++ ++int cckratesonly_included(unsigned char *rate, int ratelen) ++{ ++ int i; ++ ++ for (i = 0; i < ratelen; i++) { ++ if ((((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && ++ (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22)) ++ return false; ++ } ++ ++ return true; ++} ++ ++unsigned char networktype_to_raid(unsigned char network_type) ++{ ++ unsigned char raid; ++ ++ switch (network_type) { ++ case WIRELESS_11B: ++ raid = RATR_INX_WIRELESS_B; ++ break; ++ case WIRELESS_11G: ++ raid = RATR_INX_WIRELESS_G; ++ break; ++ case WIRELESS_11BG: ++ raid = RATR_INX_WIRELESS_GB; ++ break; ++ case WIRELESS_11_24N: ++ raid = RATR_INX_WIRELESS_N; ++ break; ++ case WIRELESS_11G_24N: ++ raid = RATR_INX_WIRELESS_NG; ++ break; ++ case WIRELESS_11BG_24N: ++ raid = RATR_INX_WIRELESS_NGB; ++ break; ++ default: ++ raid = RATR_INX_WIRELESS_GB; ++ break; ++ } ++ return raid; ++} ++ ++u8 judge_network_type(struct adapter *padapter, unsigned char *rate, int ratelen) ++{ ++ u8 network_type = 0; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pmlmeext->cur_channel > 14) { ++ network_type |= WIRELESS_INVALID; ++ } else { ++ if (pmlmeinfo->HT_enable) ++ network_type = WIRELESS_11_24N; ++ ++ if (cckratesonly_included(rate, ratelen)) ++ network_type |= WIRELESS_11B; ++ else if (cckrates_included(rate, ratelen)) ++ network_type |= WIRELESS_11BG; ++ else ++ network_type |= WIRELESS_11G; ++ } ++ return network_type; ++} ++ ++static unsigned char ratetbl_val_2wifirate(unsigned char rate) ++{ ++ unsigned char val = 0; ++ ++ switch (rate & 0x7f) { ++ case 0: ++ val = IEEE80211_CCK_RATE_1MB; ++ break; ++ case 1: ++ val = IEEE80211_CCK_RATE_2MB; ++ break; ++ case 2: ++ val = IEEE80211_CCK_RATE_5MB; ++ break; ++ case 3: ++ val = IEEE80211_CCK_RATE_11MB; ++ break; ++ case 4: ++ val = IEEE80211_OFDM_RATE_6MB; ++ break; ++ case 5: ++ val = IEEE80211_OFDM_RATE_9MB; ++ break; ++ case 6: ++ val = IEEE80211_OFDM_RATE_12MB; ++ break; ++ case 7: ++ val = IEEE80211_OFDM_RATE_18MB; ++ break; ++ case 8: ++ val = IEEE80211_OFDM_RATE_24MB; ++ break; ++ case 9: ++ val = IEEE80211_OFDM_RATE_36MB; ++ break; ++ case 10: ++ val = IEEE80211_OFDM_RATE_48MB; ++ break; ++ case 11: ++ val = IEEE80211_OFDM_RATE_54MB; ++ break; ++ } ++ return val; ++} ++ ++static int is_basicrate(struct adapter *padapter, unsigned char rate) ++{ ++ int i; ++ unsigned char val; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ for (i = 0; i < NumRates; i++) { ++ val = pmlmeext->basicrate[i]; ++ ++ if ((val != 0xff) && (val != 0xfe)) { ++ if (rate == ratetbl_val_2wifirate(val)) ++ return true; ++ } ++ } ++ return false; ++} ++ ++static unsigned int ratetbl2rateset(struct adapter *padapter, unsigned char *rateset) ++{ ++ int i; ++ unsigned char rate; ++ unsigned int len = 0; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ for (i = 0; i < NumRates; i++) { ++ rate = pmlmeext->datarate[i]; ++ ++ switch (rate) { ++ case 0xff: ++ return len; ++ case 0xfe: ++ continue; ++ default: ++ rate = ratetbl_val_2wifirate(rate); ++ ++ if (is_basicrate(padapter, rate)) ++ rate |= IEEE80211_BASIC_RATE_MASK; ++ ++ rateset[len] = rate; ++ len++; ++ break; ++ } ++ } ++ return len; ++} ++ ++void get_rate_set(struct adapter *padapter, unsigned char *pbssrate, int *bssrate_len) ++{ ++ unsigned char supportedrates[NumRates]; ++ ++ memset(supportedrates, 0, NumRates); ++ *bssrate_len = ratetbl2rateset(padapter, supportedrates); ++ memcpy(pbssrate, supportedrates, *bssrate_len); ++} ++ ++void UpdateBrateTbl(struct adapter *Adapter, u8 *mbrate) ++{ ++ u8 i; ++ u8 rate; ++ ++ /* 1M, 2M, 5.5M, 11M, 6M, 12M, 24M are mandatory. */ ++ for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { ++ rate = mbrate[i] & 0x7f; ++ switch (rate) { ++ case IEEE80211_CCK_RATE_1MB: ++ case IEEE80211_CCK_RATE_2MB: ++ case IEEE80211_CCK_RATE_5MB: ++ case IEEE80211_CCK_RATE_11MB: ++ case IEEE80211_OFDM_RATE_6MB: ++ case IEEE80211_OFDM_RATE_12MB: ++ case IEEE80211_OFDM_RATE_24MB: ++ mbrate[i] |= IEEE80211_BASIC_RATE_MASK; ++ break; ++ } ++ } ++} ++ ++void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen) ++{ ++ u8 i; ++ u8 rate; ++ ++ for (i = 0; i < bssratelen; i++) { ++ rate = bssrateset[i] & 0x7f; ++ switch (rate) { ++ case IEEE80211_CCK_RATE_1MB: ++ case IEEE80211_CCK_RATE_2MB: ++ case IEEE80211_CCK_RATE_5MB: ++ case IEEE80211_CCK_RATE_11MB: ++ bssrateset[i] |= IEEE80211_BASIC_RATE_MASK; ++ break; ++ } ++ } ++} ++ ++void Save_DM_Func_Flag(struct adapter *padapter) ++{ ++ u8 saveflag = true; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&saveflag)); ++} ++ ++void Restore_DM_Func_Flag(struct adapter *padapter) ++{ ++ u8 saveflag = false; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&saveflag)); ++} ++ ++void Switch_DM_Func(struct adapter *padapter, u32 mode, u8 enable) ++{ ++ if (enable) ++ rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_SET, (u8 *)(&mode)); ++ else ++ rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_CLR, (u8 *)(&mode)); ++} ++ ++static void Set_NETYPE0_MSR(struct adapter *padapter, u8 type) ++{ ++ rtw_hal_set_hwreg(padapter, HW_VAR_MEDIA_STATUS, (u8 *)(&type)); ++} ++ ++void Set_MSR(struct adapter *padapter, u8 type) ++{ ++ Set_NETYPE0_MSR(padapter, type); ++} ++ ++inline u8 rtw_get_oper_ch(struct adapter *adapter) ++{ ++ return adapter->mlmeextpriv.oper_channel; ++} ++ ++inline void rtw_set_oper_ch(struct adapter *adapter, u8 ch) ++{ ++ adapter->mlmeextpriv.oper_channel = ch; ++} ++ ++inline u8 rtw_get_oper_bw(struct adapter *adapter) ++{ ++ return adapter->mlmeextpriv.oper_bwmode; ++} ++ ++inline void rtw_set_oper_bw(struct adapter *adapter, u8 bw) ++{ ++ adapter->mlmeextpriv.oper_bwmode = bw; ++} ++ ++inline u8 rtw_get_oper_choffset(struct adapter *adapter) ++{ ++ return adapter->mlmeextpriv.oper_ch_offset; ++} ++ ++inline void rtw_set_oper_choffset(struct adapter *adapter, u8 offset) ++{ ++ adapter->mlmeextpriv.oper_ch_offset = offset; ++} ++ ++void SelectChannel(struct adapter *padapter, unsigned char channel) ++{ ++ /* saved channel info */ ++ rtw_set_oper_ch(padapter, channel); ++ rtw_hal_set_chan(padapter, channel); ++} ++ ++void SetBWMode(struct adapter *padapter, unsigned short bwmode, ++ unsigned char channel_offset) ++{ ++ /* saved bw info */ ++ rtw_set_oper_bw(padapter, bwmode); ++ rtw_set_oper_choffset(padapter, channel_offset); ++ ++ rtw_hal_set_bwmode(padapter, (enum ht_channel_width)bwmode, channel_offset); ++} ++ ++void set_channel_bwmode(struct adapter *padapter, unsigned char channel, unsigned char channel_offset, unsigned short bwmode) ++{ ++ u8 center_ch; ++ ++ if (padapter->bNotifyChannelChange) ++ DBG_88E("[%s] ch = %d, offset = %d, bwmode = %d\n", __func__, channel, channel_offset, bwmode); ++ ++ if ((bwmode == HT_CHANNEL_WIDTH_20) || ++ (channel_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)) { ++ /* SelectChannel(padapter, channel); */ ++ center_ch = channel; ++ } else { ++ /* switch to the proper channel */ ++ if (channel_offset == HAL_PRIME_CHNL_OFFSET_LOWER) { ++ /* SelectChannel(padapter, channel + 2); */ ++ center_ch = channel + 2; ++ } else { ++ /* SelectChannel(padapter, channel - 2); */ ++ center_ch = channel - 2; ++ } ++ } ++ ++ /* set Channel */ ++ /* saved channel/bw info */ ++ rtw_set_oper_ch(padapter, channel); ++ rtw_set_oper_bw(padapter, bwmode); ++ rtw_set_oper_choffset(padapter, channel_offset); ++ ++ rtw_hal_set_chan(padapter, center_ch); /* set center channel */ ++ SetBWMode(padapter, bwmode, channel_offset); ++} ++ ++int get_bsstype(unsigned short capability) ++{ ++ if (capability & BIT(0)) ++ return WIFI_FW_AP_STATE; ++ else if (capability & BIT(1)) ++ return WIFI_FW_ADHOC_STATE; ++ else ++ return 0; ++} ++ ++__inline u8 *get_my_bssid(struct wlan_bssid_ex *pnetwork) ++{ ++ return pnetwork->MacAddress; ++} ++ ++u16 get_beacon_interval(struct wlan_bssid_ex *bss) ++{ ++ __le16 val; ++ memcpy((unsigned char *)&val, rtw_get_beacon_interval_from_ie(bss->IEs), 2); ++ ++ return le16_to_cpu(val); ++} ++ ++int is_client_associated_to_ap(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext; ++ struct mlme_ext_info *pmlmeinfo; ++ ++ if (!padapter) ++ return _FAIL; ++ ++ pmlmeext = &padapter->mlmeextpriv; ++ pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)) ++ return true; ++ else ++ return _FAIL; ++} ++ ++int is_client_associated_to_ibss(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) ++ return true; ++ else ++ return _FAIL; ++} ++ ++int is_IBSS_empty(struct adapter *padapter) ++{ ++ unsigned int i; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) { ++ if (pmlmeinfo->FW_sta_info[i].status == 1) ++ return _FAIL; ++ } ++ return true; ++} ++ ++unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval) ++{ ++ if ((bcn_interval << 2) < WAIT_FOR_BCN_TO_MIN) ++ return WAIT_FOR_BCN_TO_MIN; ++ else if ((bcn_interval << 2) > WAIT_FOR_BCN_TO_MAX) ++ return WAIT_FOR_BCN_TO_MAX; ++ else ++ return bcn_interval << 2; ++} ++ ++void CAM_empty_entry(struct adapter *Adapter, u8 ucIndex) ++{ ++ rtw_hal_set_hwreg(Adapter, HW_VAR_CAM_EMPTY_ENTRY, (u8 *)(&ucIndex)); ++} ++ ++void invalidate_cam_all(struct adapter *padapter) ++{ ++ rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, NULL); ++} ++ ++void write_cam(struct adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key) ++{ ++ unsigned int i, val, addr; ++ int j; ++ u32 cam_val[2]; ++ ++ addr = entry << 3; ++ ++ for (j = 5; j >= 0; j--) { ++ switch (j) { ++ case 0: ++ val = (ctrl | (mac[0] << 16) | (mac[1] << 24)); ++ break; ++ case 1: ++ val = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24)); ++ break; ++ default: ++ i = (j - 2) << 2; ++ val = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24)); ++ break; ++ } ++ ++ cam_val[0] = val; ++ cam_val[1] = addr + (unsigned int)j; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_CAM_WRITE, (u8 *)cam_val); ++ } ++} ++ ++void clear_cam_entry(struct adapter *padapter, u8 entry) ++{ ++ unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; ++ unsigned char null_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; ++ ++ write_cam(padapter, entry, 0, null_sta, null_key); ++} ++ ++int allocate_fw_sta_entry(struct adapter *padapter) ++{ ++ unsigned int mac_id; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ for (mac_id = IBSS_START_MAC_ID; mac_id < NUM_STA; mac_id++) { ++ if (pmlmeinfo->FW_sta_info[mac_id].status == 0) { ++ pmlmeinfo->FW_sta_info[mac_id].status = 1; ++ pmlmeinfo->FW_sta_info[mac_id].retry = 0; ++ break; ++ } ++ } ++ ++ return mac_id; ++} ++ ++void flush_all_cam_entry(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, NULL); ++ ++ memset((u8 *)(pmlmeinfo->FW_sta_info), 0, sizeof(pmlmeinfo->FW_sta_info)); ++} ++ ++int WMM_param_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE) ++{ ++ /* struct registry_priv *pregpriv = &padapter->registrypriv; */ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pmlmepriv->qospriv.qos_option == 0) { ++ pmlmeinfo->WMM_enable = 0; ++ return _FAIL; ++ } ++ ++ pmlmeinfo->WMM_enable = 1; ++ memcpy(&pmlmeinfo->WMM_param, pIE->data + 6, sizeof(struct WMM_para_element)); ++ return true; ++} ++ ++void WMMOnAssocRsp(struct adapter *padapter) ++{ ++ u8 ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime; ++ u8 acm_mask; ++ u16 TXOP; ++ u32 acParm, i; ++ u32 edca[4], inx[4]; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ ++ if (pmlmeinfo->WMM_enable == 0) { ++ padapter->mlmepriv.acm_mask = 0; ++ return; ++ } ++ ++ acm_mask = 0; ++ ++ if (pmlmeext->cur_wireless_mode == WIRELESS_11B) ++ aSifsTime = 10; ++ else ++ aSifsTime = 16; ++ ++ for (i = 0; i < 4; i++) { ++ ACI = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 5) & 0x03; ++ ACM = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 4) & 0x01; ++ ++ /* AIFS = AIFSN * slot time + SIFS - r2t phy delay */ ++ AIFS = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN & 0x0f) * pmlmeinfo->slotTime + aSifsTime; ++ ++ ECWMin = (pmlmeinfo->WMM_param.ac_param[i].CW & 0x0f); ++ ECWMax = (pmlmeinfo->WMM_param.ac_param[i].CW & 0xf0) >> 4; ++ TXOP = le16_to_cpu(pmlmeinfo->WMM_param.ac_param[i].TXOP_limit); ++ ++ acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16); ++ ++ switch (ACI) { ++ case 0x0: ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm)); ++ acm_mask |= (ACM ? BIT(1) : 0); ++ edca[XMIT_BE_QUEUE] = acParm; ++ break; ++ case 0x1: ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm)); ++ edca[XMIT_BK_QUEUE] = acParm; ++ break; ++ case 0x2: ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm)); ++ acm_mask |= (ACM ? BIT(2) : 0); ++ edca[XMIT_VI_QUEUE] = acParm; ++ break; ++ case 0x3: ++ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm)); ++ acm_mask |= (ACM ? BIT(3) : 0); ++ edca[XMIT_VO_QUEUE] = acParm; ++ break; ++ } ++ ++ DBG_88E("WMM(%x): %x, %x\n", ACI, ACM, acParm); ++ } ++ ++ if (padapter->registrypriv.acm_method == 1) ++ rtw_hal_set_hwreg(padapter, HW_VAR_ACM_CTRL, (u8 *)(&acm_mask)); ++ else ++ padapter->mlmepriv.acm_mask = acm_mask; ++ ++ inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3; ++ ++ if (pregpriv->wifi_spec == 1) { ++ u32 j, tmp, change_inx = false; ++ ++ /* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */ ++ for (i = 0; i < 4; i++) { ++ for (j = i + 1; j < 4; j++) { ++ /* compare CW and AIFS */ ++ if ((edca[j] & 0xFFFF) < (edca[i] & 0xFFFF)) { ++ change_inx = true; ++ } else if ((edca[j] & 0xFFFF) == (edca[i] & 0xFFFF)) { ++ /* compare TXOP */ ++ if ((edca[j] >> 16) > (edca[i] >> 16)) ++ change_inx = true; ++ } ++ ++ if (change_inx) { ++ tmp = edca[i]; ++ edca[i] = edca[j]; ++ edca[j] = tmp; ++ ++ tmp = inx[i]; ++ inx[i] = inx[j]; ++ inx[j] = tmp; ++ ++ change_inx = false; ++ } ++ } ++ } ++ } ++ ++ for (i = 0; i < 4; i++) { ++ pxmitpriv->wmm_para_seq[i] = inx[i]; ++ DBG_88E("wmm_para_seq(%d): %d\n", i, pxmitpriv->wmm_para_seq[i]); ++ } ++} ++ ++static void bwmode_update_check(struct adapter *padapter, struct ndis_802_11_var_ie *pIE) ++{ ++ unsigned char new_bwmode; ++ unsigned char new_ch_offset; ++ struct HT_info_element *pHT_info; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ ++ if (!pIE) ++ return; ++ ++ if (!phtpriv) ++ return; ++ ++ if (pIE->Length > sizeof(struct HT_info_element)) ++ return; ++ ++ pHT_info = (struct HT_info_element *)pIE->data; ++ ++ if ((pHT_info->infos[0] & BIT(2)) && pregistrypriv->cbw40_enable) { ++ new_bwmode = HT_CHANNEL_WIDTH_40; ++ ++ switch (pHT_info->infos[0] & 0x3) { ++ case 1: ++ new_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; ++ break; ++ case 3: ++ new_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; ++ break; ++ default: ++ new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ break; ++ } ++ } else { ++ new_bwmode = HT_CHANNEL_WIDTH_20; ++ new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ } ++ ++ if ((new_bwmode != pmlmeext->cur_bwmode) || ++ (new_ch_offset != pmlmeext->cur_ch_offset)) { ++ pmlmeinfo->bwmode_updated = true; ++ ++ pmlmeext->cur_bwmode = new_bwmode; ++ pmlmeext->cur_ch_offset = new_ch_offset; ++ ++ /* update HT info also */ ++ HT_info_handler(padapter, pIE); ++ } else { ++ pmlmeinfo->bwmode_updated = false; ++ } ++ ++ if (pmlmeinfo->bwmode_updated) { ++ struct sta_info *psta; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ /* set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */ ++ ++ /* update ap's stainfo */ ++ psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress); ++ if (psta) { ++ struct ht_priv *phtpriv_sta = &psta->htpriv; ++ ++ if (phtpriv_sta->ht_option) { ++ /* bwmode */ ++ phtpriv_sta->bwmode = pmlmeext->cur_bwmode; ++ phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset; ++ } else { ++ phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20; ++ phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ } ++ } ++ } ++} ++ ++void HT_caps_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE) ++{ ++ unsigned int i; ++ u8 rf_type; ++ u8 max_AMPDU_len, min_MPDU_spacing; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ ++ if (!pIE) ++ return; ++ ++ if (!phtpriv->ht_option) ++ return; ++ ++ pmlmeinfo->HT_caps_enable = 1; ++ ++ for (i = 0; i < (pIE->Length); i++) { ++ if (i != 2) { ++ /* Got the endian issue here. */ ++ pmlmeinfo->HT_caps.u.HT_cap[i] &= (pIE->data[i]); ++ } else { ++ /* modify from fw by Thomas 2010/11/17 */ ++ if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3) > (pIE->data[i] & 0x3)) ++ max_AMPDU_len = (pIE->data[i] & 0x3); ++ else ++ max_AMPDU_len = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3); ++ ++ if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) > (pIE->data[i] & 0x1c)) ++ min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c); ++ else ++ min_MPDU_spacing = (pIE->data[i] & 0x1c); ++ ++ pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para = max_AMPDU_len | min_MPDU_spacing; ++ } ++ } ++ ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ ++ /* update the MCS rates */ ++ for (i = 0; i < 16; i++) { ++ if ((rf_type == RF_1T1R) || (rf_type == RF_1T2R)) ++ pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; ++ else ++ pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i]; ++ } ++} ++ ++void HT_info_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ht_priv *phtpriv = &pmlmepriv->htpriv; ++ ++ if (!pIE) ++ return; ++ ++ if (!phtpriv->ht_option) ++ return; ++ ++ if (pIE->Length > sizeof(struct HT_info_element)) ++ return; ++ ++ pmlmeinfo->HT_info_enable = 1; ++ memcpy(&pmlmeinfo->HT_info, pIE->data, pIE->Length); ++} ++ ++void HTOnAssocRsp(struct adapter *padapter) ++{ ++ unsigned char max_AMPDU_len; ++ unsigned char min_MPDU_spacing; ++ /* struct registry_priv *pregpriv = &padapter->registrypriv; */ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ DBG_88E("%s\n", __func__); ++ ++ if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable)) { ++ pmlmeinfo->HT_enable = 1; ++ } else { ++ pmlmeinfo->HT_enable = 0; ++ return; ++ } ++ ++ /* handle A-MPDU parameter field */ ++ /* ++ AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k ++ AMPDU_para [4:2]:Min MPDU Start Spacing ++ */ ++ max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03; ++ ++ min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2; ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing)); ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len)); ++} ++ ++void ERP_IE_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pIE->Length > 1) ++ return; ++ ++ pmlmeinfo->ERP_enable = 1; ++ memcpy(&pmlmeinfo->ERP_IE, pIE->data, pIE->Length); ++} ++ ++void VCS_update(struct adapter *padapter, struct sta_info *psta) ++{ ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ switch (pregpriv->vrtl_carrier_sense) { /* 0:off 1:on 2:auto */ ++ case 0: /* off */ ++ psta->rtsen = 0; ++ psta->cts2self = 0; ++ break; ++ case 1: /* on */ ++ if (pregpriv->vcs_type == 1) { /* 1:RTS/CTS 2:CTS to self */ ++ psta->rtsen = 1; ++ psta->cts2self = 0; ++ } else { ++ psta->rtsen = 0; ++ psta->cts2self = 1; ++ } ++ break; ++ case 2: /* auto */ ++ default: ++ if ((pmlmeinfo->ERP_enable) && (pmlmeinfo->ERP_IE & BIT(1))) { ++ if (pregpriv->vcs_type == 1) { ++ psta->rtsen = 1; ++ psta->cts2self = 0; ++ } else { ++ psta->rtsen = 0; ++ psta->cts2self = 1; ++ } ++ } else { ++ psta->rtsen = 0; ++ psta->cts2self = 0; ++ } ++ break; ++ } ++} ++ ++int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len) ++{ ++ unsigned int len; ++ unsigned char *p; ++ unsigned short val16, subtype; ++ struct wlan_network *cur_network = &Adapter->mlmepriv.cur_network; ++ /* u8 wpa_ie[255], rsn_ie[255]; */ ++ u16 wpa_len = 0, rsn_len = 0; ++ u8 encryp_protocol = 0; ++ struct wlan_bssid_ex *bssid; ++ int group_cipher = 0, pairwise_cipher = 0, is_8021x = 0; ++ unsigned char *pbuf; ++ u32 wpa_ielen = 0; ++ u8 *pbssid = GetAddr3Ptr(pframe); ++ u32 hidden_ssid = 0; ++ struct HT_info_element *pht_info = NULL; ++ struct ieee80211_ht_cap *pht_cap = NULL; ++ u32 bcn_channel; ++ unsigned short ht_cap_info; ++ unsigned char ht_info_infos_0; ++ ++ if (!is_client_associated_to_ap(Adapter)) ++ return true; ++ ++ len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ if (len > MAX_IE_SZ) { ++ DBG_88E("%s IE too long for survey event\n", __func__); ++ return _FAIL; ++ } ++ ++ if (memcmp(cur_network->network.MacAddress, pbssid, 6)) { ++ DBG_88E("Oops: rtw_check_network_encrypt linked but recv other bssid bcn\n%pM %pM\n", ++ (pbssid), (cur_network->network.MacAddress)); ++ return true; ++ } ++ ++ bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC); ++ if (!bssid) ++ return _FAIL; ++ ++ subtype = GetFrameSubType(pframe) >> 4; ++ ++ if (subtype == WIFI_BEACON) ++ bssid->Reserved[0] = 1; ++ ++ bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len; ++ ++ /* below is to copy the information element */ ++ bssid->IELength = len; ++ memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength); ++ ++ /* check bw and channel offset */ ++ /* parsing HT_CAP_IE */ ++ p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); ++ if (p && len > 0) { ++ pht_cap = (struct ieee80211_ht_cap *)(p + 2); ++ ht_cap_info = le16_to_cpu(pht_cap->cap_info); ++ } else { ++ ht_cap_info = 0; ++ } ++ /* parsing HT_INFO_IE */ ++ p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); ++ if (p && len > 0) { ++ pht_info = (struct HT_info_element *)(p + 2); ++ ht_info_infos_0 = pht_info->infos[0]; ++ } else { ++ ht_info_infos_0 = 0; ++ } ++ if (ht_cap_info != cur_network->BcnInfo.ht_cap_info || ++ ((ht_info_infos_0 & 0x03) != (cur_network->BcnInfo.ht_info_infos_0 & 0x03))) { ++ DBG_88E("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n", __func__, ++ ht_cap_info, ht_info_infos_0); ++ DBG_88E("%s bcn link: ht_cap_info:%x ht_info_infos_0:%x\n", __func__, ++ cur_network->BcnInfo.ht_cap_info, cur_network->BcnInfo.ht_info_infos_0); ++ DBG_88E("%s bw mode change, disconnect\n", __func__); ++ /* bcn_info_update */ ++ cur_network->BcnInfo.ht_cap_info = ht_cap_info; ++ cur_network->BcnInfo.ht_info_infos_0 = ht_info_infos_0; ++ /* to do : need to check that whether modify related register of BB or not */ ++ /* goto _mismatch; */ ++ } ++ ++ /* Checking for channel */ ++ p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _DSSET_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); ++ if (p) { ++ bcn_channel = *(p + 2); ++ } else {/* In 5G, some ap do not have DSSET IE checking HT info for channel */ ++ p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); ++ if (pht_info) { ++ bcn_channel = pht_info->primary_channel; ++ } else { /* we don't find channel IE, so don't check it */ ++ DBG_88E("Oops: %s we don't find channel IE, so don't check it\n", __func__); ++ bcn_channel = Adapter->mlmeextpriv.cur_channel; ++ } ++ } ++ if (bcn_channel != Adapter->mlmeextpriv.cur_channel) { ++ DBG_88E("%s beacon channel:%d cur channel:%d disconnect\n", __func__, ++ bcn_channel, Adapter->mlmeextpriv.cur_channel); ++ goto _mismatch; ++ } ++ ++ /* checking SSID */ ++ p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SSID_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); ++ if (!p) { ++ DBG_88E("%s marc: cannot find SSID for survey event\n", __func__); ++ hidden_ssid = true; ++ } else { ++ hidden_ssid = false; ++ } ++ ++ if ((NULL != p) && (false == hidden_ssid && (*(p + 1)))) { ++ memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1)); ++ bssid->Ssid.SsidLength = *(p + 1); ++ } else { ++ bssid->Ssid.SsidLength = 0; ++ bssid->Ssid.Ssid[0] = '\0'; ++ } ++ ++ if (memcmp(bssid->Ssid.Ssid, cur_network->network.Ssid.Ssid, 32) || ++ bssid->Ssid.SsidLength != cur_network->network.Ssid.SsidLength) { ++ if (bssid->Ssid.Ssid[0] != '\0' && bssid->Ssid.SsidLength != 0) { /* not hidden ssid */ ++ DBG_88E("%s(), SSID is not match return FAIL\n", __func__); ++ goto _mismatch; ++ } ++ } ++ ++ /* check encryption info */ ++ val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid); ++ ++ if (val16 & BIT(4)) ++ bssid->Privacy = 1; ++ else ++ bssid->Privacy = 0; ++ ++ if (cur_network->network.Privacy != bssid->Privacy) { ++ DBG_88E("%s(), privacy is not match return FAIL\n", __func__); ++ goto _mismatch; ++ } ++ ++ rtw_get_sec_ie(bssid->IEs, bssid->IELength, NULL, &rsn_len, NULL, &wpa_len); ++ ++ if (rsn_len > 0) { ++ encryp_protocol = ENCRYP_PROTOCOL_WPA2; ++ } else if (wpa_len > 0) { ++ encryp_protocol = ENCRYP_PROTOCOL_WPA; ++ } else { ++ if (bssid->Privacy) ++ encryp_protocol = ENCRYP_PROTOCOL_WEP; ++ } ++ ++ if (cur_network->BcnInfo.encryp_protocol != encryp_protocol) { ++ DBG_88E("%s(): enctyp is not match , return FAIL\n", __func__); ++ goto _mismatch; ++ } ++ ++ if (encryp_protocol == ENCRYP_PROTOCOL_WPA || encryp_protocol == ENCRYP_PROTOCOL_WPA2) { ++ pbuf = rtw_get_wpa_ie(&bssid->IEs[12], &wpa_ielen, bssid->IELength - 12); ++ if (pbuf && (wpa_ielen > 0)) { ++ rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is_8021x); ++ } else { ++ pbuf = rtw_get_wpa2_ie(&bssid->IEs[12], &wpa_ielen, bssid->IELength - 12); ++ ++ if (pbuf && (wpa_ielen > 0)) ++ rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is_8021x); ++ } ++ ++ if (pairwise_cipher != cur_network->BcnInfo.pairwise_cipher || group_cipher != cur_network->BcnInfo.group_cipher) { ++ DBG_88E("%s pairwise_cipher(%x:%x) or group_cipher(%x:%x) is not match , return FAIL\n", __func__, ++ pairwise_cipher, cur_network->BcnInfo.pairwise_cipher, ++ group_cipher, cur_network->BcnInfo.group_cipher); ++ goto _mismatch; ++ } ++ ++ if (is_8021x != cur_network->BcnInfo.is_8021x) { ++ DBG_88E("%s authentication is not match , return FAIL\n", __func__); ++ goto _mismatch; ++ } ++ } ++ ++ kfree(bssid); ++ ++ return _SUCCESS; ++ ++_mismatch: ++ kfree(bssid); ++ ++ return _FAIL; ++} ++ ++void update_beacon_info(struct adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta) ++{ ++ unsigned int i; ++ unsigned int len; ++ struct ndis_802_11_var_ie *pIE; ++ ++ len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN); ++ ++ for (i = 0; i < len;) { ++ pIE = (struct ndis_802_11_var_ie *)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i); ++ ++ switch (pIE->ElementID) { ++ case _HT_EXTRA_INFO_IE_: /* HT info */ ++ /* HT_info_handler(padapter, pIE); */ ++ bwmode_update_check(padapter, pIE); ++ break; ++ case _ERPINFO_IE_: ++ ERP_IE_handler(padapter, pIE); ++ VCS_update(padapter, psta); ++ break; ++ default: ++ break; ++ } ++ ++ i += (pIE->Length + 2); ++ } ++} ++ ++unsigned int is_ap_in_tkip(struct adapter *padapter) ++{ ++ u32 i; ++ struct ndis_802_11_var_ie *pIE; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ ++ if (rtw_get_capability((struct wlan_bssid_ex *)cur_network) & WLAN_CAPABILITY_PRIVACY) { ++ for (i = sizeof(struct ndis_802_11_fixed_ie); i < pmlmeinfo->network.IELength;) { ++ pIE = (struct ndis_802_11_var_ie *)(pmlmeinfo->network.IEs + i); ++ ++ switch (pIE->ElementID) { ++ case _VENDOR_SPECIFIC_IE_: ++ if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) && (!memcmp((pIE->data + 12), WPA_TKIP_CIPHER, 4))) ++ return true; ++ break; ++ case _RSN_IE_2_: ++ if (!memcmp((pIE->data + 8), RSN_TKIP_CIPHER, 4)) ++ return true; ++ break; ++ default: ++ break; ++ } ++ ++ i += (pIE->Length + 2); ++ } ++ return false; ++ } else { ++ return false; ++ } ++} ++ ++unsigned int should_forbid_n_rate(struct adapter *padapter) ++{ ++ u32 i; ++ struct ndis_802_11_var_ie *pIE; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *cur_network = &pmlmepriv->cur_network.network; ++ ++ if (rtw_get_capability((struct wlan_bssid_ex *)cur_network) & WLAN_CAPABILITY_PRIVACY) { ++ for (i = sizeof(struct ndis_802_11_fixed_ie); i < cur_network->IELength;) { ++ pIE = (struct ndis_802_11_var_ie *)(cur_network->IEs + i); ++ ++ switch (pIE->ElementID) { ++ case _VENDOR_SPECIFIC_IE_: ++ if (!memcmp(pIE->data, RTW_WPA_OUI, 4) && ++ ((!memcmp((pIE->data + 12), WPA_CIPHER_SUITE_CCMP, 4)) || ++ (!memcmp((pIE->data + 16), WPA_CIPHER_SUITE_CCMP, 4)))) ++ return false; ++ break; ++ case _RSN_IE_2_: ++ if ((!memcmp((pIE->data + 8), RSN_CIPHER_SUITE_CCMP, 4)) || ++ (!memcmp((pIE->data + 12), RSN_CIPHER_SUITE_CCMP, 4))) ++ return false; ++ break; ++ default: ++ break; ++ } ++ ++ i += (pIE->Length + 2); ++ } ++ ++ return true; ++ } else { ++ return false; ++ } ++} ++ ++unsigned int is_ap_in_wep(struct adapter *padapter) ++{ ++ u32 i; ++ struct ndis_802_11_var_ie *pIE; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ ++ if (rtw_get_capability((struct wlan_bssid_ex *)cur_network) & WLAN_CAPABILITY_PRIVACY) { ++ for (i = sizeof(struct ndis_802_11_fixed_ie); i < pmlmeinfo->network.IELength;) { ++ pIE = (struct ndis_802_11_var_ie *)(pmlmeinfo->network.IEs + i); ++ ++ switch (pIE->ElementID) { ++ case _VENDOR_SPECIFIC_IE_: ++ if (!memcmp(pIE->data, RTW_WPA_OUI, 4)) ++ return false; ++ break; ++ case _RSN_IE_2_: ++ return false; ++ default: ++ break; ++ } ++ i += (pIE->Length + 2); ++ } ++ return true; ++ } else { ++ return false; ++ } ++} ++ ++int wifirate2_ratetbl_inx(unsigned char rate) ++{ ++ int inx = 0; ++ rate = rate & 0x7f; ++ ++ switch (rate) { ++ case 54 * 2: ++ inx = 11; ++ break; ++ case 48 * 2: ++ inx = 10; ++ break; ++ case 36 * 2: ++ inx = 9; ++ break; ++ case 24 * 2: ++ inx = 8; ++ break; ++ case 18 * 2: ++ inx = 7; ++ break; ++ case 12 * 2: ++ inx = 6; ++ break; ++ case 9 * 2: ++ inx = 5; ++ break; ++ case 6 * 2: ++ inx = 4; ++ break; ++ case 11 * 2: ++ inx = 3; ++ break; ++ case 11: ++ inx = 2; ++ break; ++ case 2 * 2: ++ inx = 1; ++ break; ++ case 1 * 2: ++ inx = 0; ++ break; ++ } ++ return inx; ++} ++ ++unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz) ++{ ++ unsigned int i, num_of_rate; ++ unsigned int mask = 0; ++ ++ num_of_rate = (ptn_sz > NumRates) ? NumRates : ptn_sz; ++ ++ for (i = 0; i < num_of_rate; i++) { ++ if ((*(ptn + i)) & 0x80) ++ mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i)); ++ } ++ return mask; ++} ++ ++unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz) ++{ ++ unsigned int i, num_of_rate; ++ unsigned int mask = 0; ++ ++ num_of_rate = (ptn_sz > NumRates) ? NumRates : ptn_sz; ++ ++ for (i = 0; i < num_of_rate; i++) ++ mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i)); ++ return mask; ++} ++ ++unsigned int update_MSC_rate(struct HT_caps_element *pHT_caps) ++{ ++ unsigned int mask = 0; ++ ++ mask = ((pHT_caps->u.HT_cap_element.MCS_rate[0] << 12) | (pHT_caps->u.HT_cap_element.MCS_rate[1] << 20)); ++ ++ return mask; ++} ++ ++int support_short_GI(struct adapter *padapter, struct HT_caps_element *pHT_caps) ++{ ++ unsigned char bit_offset; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (!(pmlmeinfo->HT_enable)) ++ return _FAIL; ++ ++ if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_RALINK) ++ return _FAIL; ++ ++ bit_offset = (pmlmeext->cur_bwmode & HT_CHANNEL_WIDTH_40) ? 6 : 5; ++ ++ if (__le16_to_cpu(pHT_caps->u.HT_cap_element.HT_caps_info) & (0x1 << bit_offset)) ++ return _SUCCESS; ++ else ++ return _FAIL; ++} ++ ++unsigned char get_highest_rate_idx(u32 mask) ++{ ++ int i; ++ unsigned char rate_idx = 0; ++ ++ for (i = 27; i >= 0; i--) { ++ if (mask & BIT(i)) { ++ rate_idx = i; ++ break; ++ } ++ } ++ return rate_idx; ++} ++ ++void Update_RA_Entry(struct adapter *padapter, u32 mac_id) ++{ ++ rtw_hal_update_ra_mask(padapter, mac_id, 0); ++} ++ ++static void enable_rate_adaptive(struct adapter *padapter, u32 mac_id) ++{ ++ Update_RA_Entry(padapter, mac_id); ++} ++ ++void set_sta_rate(struct adapter *padapter, struct sta_info *psta) ++{ ++ /* rate adaptive */ ++ enable_rate_adaptive(padapter, psta->mac_id); ++} ++ ++/* Update RRSR and Rate for USERATE */ ++void update_tx_basic_rate(struct adapter *padapter, u8 wirelessmode) ++{ ++ unsigned char supported_rates[NDIS_802_11_LENGTH_RATES_EX]; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ /* Added by Albert 2011/03/22 */ ++ /* In the P2P mode, the driver should not support the b mode. */ ++ /* So, the Tx packet shouldn't use the CCK rate */ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) ++ return; ++#endif /* CONFIG_88EU_P2P */ ++ memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX); ++ ++ if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B)) ++ memcpy(supported_rates, rtw_basic_rate_cck, 4); ++ else if (wirelessmode & WIRELESS_11B) ++ memcpy(supported_rates, rtw_basic_rate_mix, 7); ++ else ++ memcpy(supported_rates, rtw_basic_rate_ofdm, 3); ++ ++ if (wirelessmode & WIRELESS_11B) ++ update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB); ++ else ++ update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB); ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, supported_rates); ++} ++ ++unsigned char check_assoc_AP(u8 *pframe, uint len) ++{ ++ unsigned int i; ++ struct ndis_802_11_var_ie *pIE; ++ u8 epigram_vendor_flag; ++ u8 ralink_vendor_flag; ++ epigram_vendor_flag = 0; ++ ralink_vendor_flag = 0; ++ ++ for (i = sizeof(struct ndis_802_11_fixed_ie); i < len;) { ++ pIE = (struct ndis_802_11_var_ie *)(pframe + i); ++ ++ switch (pIE->ElementID) { ++ case _VENDOR_SPECIFIC_IE_: ++ if ((!memcmp(pIE->data, ARTHEROS_OUI1, 3)) || ++ (!memcmp(pIE->data, ARTHEROS_OUI2, 3))) { ++ DBG_88E("link to Artheros AP\n"); ++ return HT_IOT_PEER_ATHEROS; ++ } else if ((!memcmp(pIE->data, BROADCOM_OUI1, 3)) || ++ (!memcmp(pIE->data, BROADCOM_OUI2, 3)) || ++ (!memcmp(pIE->data, BROADCOM_OUI2, 3))) { ++ DBG_88E("link to Broadcom AP\n"); ++ return HT_IOT_PEER_BROADCOM; ++ } else if (!memcmp(pIE->data, MARVELL_OUI, 3)) { ++ DBG_88E("link to Marvell AP\n"); ++ return HT_IOT_PEER_MARVELL; ++ } else if (!memcmp(pIE->data, RALINK_OUI, 3)) { ++ if (!ralink_vendor_flag) { ++ ralink_vendor_flag = 1; ++ } else { ++ DBG_88E("link to Ralink AP\n"); ++ return HT_IOT_PEER_RALINK; ++ } ++ } else if (!memcmp(pIE->data, CISCO_OUI, 3)) { ++ DBG_88E("link to Cisco AP\n"); ++ return HT_IOT_PEER_CISCO; ++ } else if (!memcmp(pIE->data, REALTEK_OUI, 3)) { ++ DBG_88E("link to Realtek 96B\n"); ++ return HT_IOT_PEER_REALTEK; ++ } else if (!memcmp(pIE->data, AIRGOCAP_OUI, 3)) { ++ DBG_88E("link to Airgo Cap\n"); ++ return HT_IOT_PEER_AIRGO; ++ } else if (!memcmp(pIE->data, EPIGRAM_OUI, 3)) { ++ epigram_vendor_flag = 1; ++ if (ralink_vendor_flag) { ++ DBG_88E("link to Tenda W311R AP\n"); ++ return HT_IOT_PEER_TENDA; ++ } else { ++ DBG_88E("Capture EPIGRAM_OUI\n"); ++ } ++ } else { ++ break; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ i += (pIE->Length + 2); ++ } ++ ++ if (ralink_vendor_flag && !epigram_vendor_flag) { ++ DBG_88E("link to Ralink AP\n"); ++ return HT_IOT_PEER_RALINK; ++ } else if (ralink_vendor_flag && epigram_vendor_flag) { ++ DBG_88E("link to Tenda W311R AP\n"); ++ return HT_IOT_PEER_TENDA; ++ } else { ++ DBG_88E("link to new AP\n"); ++ return HT_IOT_PEER_UNKNOWN; ++ } ++} ++ ++void update_IOT_info(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ switch (pmlmeinfo->assoc_AP_vendor) { ++ case HT_IOT_PEER_MARVELL: ++ pmlmeinfo->turboMode_cts2self = 1; ++ pmlmeinfo->turboMode_rtsen = 0; ++ break; ++ case HT_IOT_PEER_RALINK: ++ pmlmeinfo->turboMode_cts2self = 0; ++ pmlmeinfo->turboMode_rtsen = 1; ++ /* disable high power */ ++ Switch_DM_Func(padapter, (~DYNAMIC_BB_DYNAMIC_TXPWR), false); ++ break; ++ case HT_IOT_PEER_REALTEK: ++ /* rtw_write16(padapter, 0x4cc, 0xffff); */ ++ /* rtw_write16(padapter, 0x546, 0x01c0); */ ++ /* disable high power */ ++ Switch_DM_Func(padapter, (~DYNAMIC_BB_DYNAMIC_TXPWR), false); ++ break; ++ default: ++ pmlmeinfo->turboMode_cts2self = 0; ++ pmlmeinfo->turboMode_rtsen = 1; ++ break; ++ } ++} ++ ++void update_capinfo(struct adapter *Adapter, u16 updateCap) ++{ ++ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ bool ShortPreamble; ++ ++ /* Check preamble mode, 2005.01.06, by rcnjko. */ ++ /* Mark to update preamble value forever, 2008.03.18 by lanhsin */ ++ ++ if (updateCap & cShortPreamble) { /* Short Preamble */ ++ if (pmlmeinfo->preamble_mode != PREAMBLE_SHORT) { /* PREAMBLE_LONG or PREAMBLE_AUTO */ ++ ShortPreamble = true; ++ pmlmeinfo->preamble_mode = PREAMBLE_SHORT; ++ rtw_hal_set_hwreg(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble); ++ } ++ } else { /* Long Preamble */ ++ if (pmlmeinfo->preamble_mode != PREAMBLE_LONG) { /* PREAMBLE_SHORT or PREAMBLE_AUTO */ ++ ShortPreamble = false; ++ pmlmeinfo->preamble_mode = PREAMBLE_LONG; ++ rtw_hal_set_hwreg(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble); ++ } ++ } ++ ++ if (updateCap & cIBSS) { ++ /* Filen: See 802.11-2007 p.91 */ ++ pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME; ++ } else { /* Filen: See 802.11-2007 p.90 */ ++ if (pmlmeext->cur_wireless_mode & (WIRELESS_11G | WIRELESS_11_24N)) { ++ if (updateCap & cShortSlotTime) { /* Short Slot Time */ ++ if (pmlmeinfo->slotTime != SHORT_SLOT_TIME) ++ pmlmeinfo->slotTime = SHORT_SLOT_TIME; ++ } else { /* Long Slot Time */ ++ if (pmlmeinfo->slotTime != NON_SHORT_SLOT_TIME) ++ pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME; ++ } ++ } else { ++ /* B Mode */ ++ pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME; ++ } ++ } ++ ++ rtw_hal_set_hwreg(Adapter, HW_VAR_SLOT_TIME, &pmlmeinfo->slotTime); ++} ++ ++void update_wireless_mode(struct adapter *padapter) ++{ ++ int ratelen, network_type = 0; ++ u32 SIFS_Timer; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ unsigned char *rate = cur_network->SupportedRates; ++ ++ ratelen = rtw_get_rateset_len(cur_network->SupportedRates); ++ ++ if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable)) ++ pmlmeinfo->HT_enable = 1; ++ ++ if (pmlmeext->cur_channel > 14) { ++ network_type |= WIRELESS_INVALID; ++ } else { ++ if (pmlmeinfo->HT_enable) ++ network_type = WIRELESS_11_24N; ++ ++ if (cckratesonly_included(rate, ratelen)) ++ network_type |= WIRELESS_11B; ++ else if (cckrates_included(rate, ratelen)) ++ network_type |= WIRELESS_11BG; ++ else ++ network_type |= WIRELESS_11G; ++ } ++ ++ pmlmeext->cur_wireless_mode = network_type & padapter->registrypriv.wireless_mode; ++ ++ SIFS_Timer = 0x0a0a0808;/* 0x0808 -> for CCK, 0x0a0a -> for OFDM */ ++ /* change this value if having IOT issues. */ ++ ++ padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_RESP_SIFS, (u8 *)&SIFS_Timer); ++ ++ if (pmlmeext->cur_wireless_mode & WIRELESS_11B) ++ update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB); ++ else ++ update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB); ++} ++ ++void update_bmc_sta_support_rate(struct adapter *padapter, u32 mac_id) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pmlmeext->cur_wireless_mode & WIRELESS_11B) { ++ /* Only B, B/G, and B/G/N AP could use CCK rate */ ++ memcpy((pmlmeinfo->FW_sta_info[mac_id].SupportedRates), rtw_basic_rate_cck, 4); ++ } else { ++ memcpy((pmlmeinfo->FW_sta_info[mac_id].SupportedRates), rtw_basic_rate_ofdm, 3); ++ } ++} ++ ++int update_sta_support_rate(struct adapter *padapter, u8 *pvar_ie, uint var_ie_len, int cam_idx) ++{ ++ unsigned int ie_len; ++ struct ndis_802_11_var_ie *pIE; ++ int supportRateNum = 0; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ pIE = (struct ndis_802_11_var_ie *)rtw_get_ie(pvar_ie, _SUPPORTEDRATES_IE_, &ie_len, var_ie_len); ++ if (!pIE) ++ return _FAIL; ++ ++ memcpy(pmlmeinfo->FW_sta_info[cam_idx].SupportedRates, pIE->data, ie_len); ++ supportRateNum = ie_len; ++ ++ pIE = (struct ndis_802_11_var_ie *)rtw_get_ie(pvar_ie, _EXT_SUPPORTEDRATES_IE_, &ie_len, var_ie_len); ++ if (pIE) ++ memcpy((pmlmeinfo->FW_sta_info[cam_idx].SupportedRates + supportRateNum), pIE->data, ie_len); ++ ++ return _SUCCESS; ++} ++ ++void process_addba_req(struct adapter *padapter, u8 *paddba_req, u8 *addr) ++{ ++ struct sta_info *psta; ++ u16 tid; ++ u16 param; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct ADDBA_request *preq = (struct ADDBA_request *)paddba_req; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ psta = rtw_get_stainfo(pstapriv, addr); ++ ++ if (psta) { ++ param = le16_to_cpu(preq->BA_para_set); ++ tid = (param >> 2) & 0x0f; ++ preorder_ctrl = &psta->recvreorder_ctrl[tid]; ++ preorder_ctrl->indicate_seq = 0xffff; ++ preorder_ctrl->enable = (pmlmeinfo->bAcceptAddbaReq) ? true : false; ++ } ++} ++ ++void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len) ++{ ++ u8 *pIE; ++ __le32 *pbuf; ++ ++ pIE = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); ++ pbuf = (__le32 *)pIE; ++ ++ pmlmeext->TSFValue = le32_to_cpu(*(pbuf + 1)); ++ ++ pmlmeext->TSFValue = pmlmeext->TSFValue << 32; ++ ++ pmlmeext->TSFValue |= le32_to_cpu(*pbuf); ++} ++ ++void correct_TSF(struct adapter *padapter, struct mlme_ext_priv *pmlmeext) ++{ ++ rtw_hal_set_hwreg(padapter, HW_VAR_CORRECT_TSF, NULL); ++} ++ ++void beacon_timing_control(struct adapter *padapter) ++{ ++ rtw_hal_bcn_related_reg_setting(padapter); ++} ++ ++static struct adapter *pbuddy_padapter; ++ ++int rtw_handle_dualmac(struct adapter *adapter, bool init) ++{ ++ int status = _SUCCESS; ++ ++ if (init) { ++ if (!pbuddy_padapter) { ++ pbuddy_padapter = adapter; ++ DBG_88E("%s(): pbuddy_padapter == NULL, Set pbuddy_padapter\n", __func__); ++ } else { ++ adapter->pbuddy_adapter = pbuddy_padapter; ++ pbuddy_padapter->pbuddy_adapter = adapter; ++ /* clear global value */ ++ pbuddy_padapter = NULL; ++ DBG_88E("%s(): pbuddy_padapter exist, Exchange Information\n", __func__); ++ } ++ } else { ++ pbuddy_padapter = NULL; ++ } ++ return status; ++} +diff --git a/drivers/staging/r8188eu/core/rtw_xmit.c b/drivers/staging/r8188eu/core/rtw_xmit.c +new file mode 100644 +index 000000000000..46fe62c7c32c +--- /dev/null ++++ b/drivers/staging/r8188eu/core/rtw_xmit.c +@@ -0,0 +1,2240 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _RTW_XMIT_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wifi.h" ++#include "../include/osdep_intf.h" ++#include "../include/usb_ops.h" ++#include "../include/usb_osintf.h" ++ ++static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; ++static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; ++ ++static void _init_txservq(struct tx_servq *ptxservq) ++{ ++ ++ INIT_LIST_HEAD(&ptxservq->tx_pending); ++ _rtw_init_queue(&ptxservq->sta_pending); ++ ptxservq->qcnt = 0; ++ ++} ++ ++void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv) ++{ ++ ++ memset((unsigned char *)psta_xmitpriv, 0, sizeof(struct sta_xmit_priv)); ++ spin_lock_init(&psta_xmitpriv->lock); ++ _init_txservq(&psta_xmitpriv->be_q); ++ _init_txservq(&psta_xmitpriv->bk_q); ++ _init_txservq(&psta_xmitpriv->vi_q); ++ _init_txservq(&psta_xmitpriv->vo_q); ++ INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz); ++ INIT_LIST_HEAD(&psta_xmitpriv->apsd); ++ ++} ++ ++s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) ++{ ++ int i; ++ struct xmit_buf *pxmitbuf; ++ struct xmit_frame *pxframe; ++ int res = _SUCCESS; ++ u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; ++ u32 num_xmit_extbuf = NR_XMIT_EXTBUFF; ++ ++ /* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */ ++ ++ spin_lock_init(&pxmitpriv->lock); ++ sema_init(&pxmitpriv->xmit_sema, 0); ++ sema_init(&pxmitpriv->terminate_xmitthread_sema, 0); ++ ++ /* ++ Please insert all the queue initializaiton using _rtw_init_queue below ++ */ ++ ++ pxmitpriv->adapter = padapter; ++ ++ _rtw_init_queue(&pxmitpriv->be_pending); ++ _rtw_init_queue(&pxmitpriv->bk_pending); ++ _rtw_init_queue(&pxmitpriv->vi_pending); ++ _rtw_init_queue(&pxmitpriv->vo_pending); ++ _rtw_init_queue(&pxmitpriv->bm_pending); ++ ++ _rtw_init_queue(&pxmitpriv->free_xmit_queue); ++ ++ /* ++ Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME, ++ and initialize free_xmit_frame below. ++ Please also apply free_txobj to link_up all the xmit_frames... ++ */ ++ ++ pxmitpriv->pallocated_frame_buf = vzalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4); ++ ++ if (!pxmitpriv->pallocated_frame_buf) { ++ pxmitpriv->pxmit_frame_buf = NULL; ++ res = _FAIL; ++ goto exit; ++ } ++ pxmitpriv->pxmit_frame_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_frame_buf), 4); ++ /* pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 - */ ++ /* ((size_t) (pxmitpriv->pallocated_frame_buf) &3); */ ++ ++ pxframe = (struct xmit_frame *)pxmitpriv->pxmit_frame_buf; ++ ++ for (i = 0; i < NR_XMITFRAME; i++) { ++ INIT_LIST_HEAD(&pxframe->list); ++ ++ pxframe->padapter = padapter; ++ pxframe->frame_tag = NULL_FRAMETAG; ++ ++ pxframe->pkt = NULL; ++ ++ pxframe->buf_addr = NULL; ++ pxframe->pxmitbuf = NULL; ++ ++ list_add_tail(&pxframe->list, &pxmitpriv->free_xmit_queue.queue); ++ ++ pxframe++; ++ } ++ ++ pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME; ++ ++ pxmitpriv->frag_len = MAX_FRAG_THRESHOLD; ++ ++ /* init xmit_buf */ ++ _rtw_init_queue(&pxmitpriv->free_xmitbuf_queue); ++ _rtw_init_queue(&pxmitpriv->pending_xmitbuf_queue); ++ ++ pxmitpriv->pallocated_xmitbuf = vzalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4); ++ ++ if (!pxmitpriv->pallocated_xmitbuf) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pxmitpriv->pxmitbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_xmitbuf), 4); ++ /* pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - */ ++ /* ((size_t) (pxmitpriv->pallocated_xmitbuf) &3); */ ++ ++ pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; ++ ++ for (i = 0; i < NR_XMITBUFF; i++) { ++ INIT_LIST_HEAD(&pxmitbuf->list); ++ ++ pxmitbuf->priv_data = NULL; ++ pxmitbuf->padapter = padapter; ++ pxmitbuf->ext_tag = false; ++ ++ /* Tx buf allocation may fail sometimes, so sleep and retry. */ ++ res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ)); ++ if (res == _FAIL) { ++ msleep(10); ++ res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ)); ++ if (res == _FAIL) { ++ goto exit; ++ } ++ } ++ ++ pxmitbuf->flags = XMIT_VO_QUEUE; ++ ++ list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmitbuf_queue.queue); ++ pxmitbuf++; ++ } ++ ++ pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF; ++ ++ /* Init xmit extension buff */ ++ _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue); ++ ++ pxmitpriv->pallocated_xmit_extbuf = vzalloc(num_xmit_extbuf * sizeof(struct xmit_buf) + 4); ++ ++ if (!pxmitpriv->pallocated_xmit_extbuf) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_xmit_extbuf), 4); ++ ++ pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; ++ ++ for (i = 0; i < num_xmit_extbuf; i++) { ++ INIT_LIST_HEAD(&pxmitbuf->list); ++ ++ pxmitbuf->priv_data = NULL; ++ pxmitbuf->padapter = padapter; ++ pxmitbuf->ext_tag = true; ++ ++ res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ); ++ if (res == _FAIL) { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmit_extbuf_queue.queue); ++ pxmitbuf++; ++ } ++ ++ pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf; ++ ++ rtw_alloc_hwxmits(padapter); ++ rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); ++ ++ for (i = 0; i < 4; i++) ++ pxmitpriv->wmm_para_seq[i] = i; ++ ++ pxmitpriv->txirp_cnt = 1; ++ ++ sema_init(&pxmitpriv->tx_retevt, 0); ++ ++ /* per AC pending irp */ ++ pxmitpriv->beq_cnt = 0; ++ pxmitpriv->bkq_cnt = 0; ++ pxmitpriv->viq_cnt = 0; ++ pxmitpriv->voq_cnt = 0; ++ ++ pxmitpriv->ack_tx = false; ++ _rtw_mutex_init(&pxmitpriv->ack_tx_mutex); ++ rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0); ++ ++ rtw_hal_init_xmit_priv(padapter); ++ ++exit: ++ ++ return res; ++} ++ ++void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv) ++{ ++ int i; ++ struct adapter *padapter = pxmitpriv->adapter; ++ struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitpriv->pxmit_frame_buf; ++ struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; ++ u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; ++ u32 num_xmit_extbuf = NR_XMIT_EXTBUFF; ++ ++ if (!pxmitpriv->pxmit_frame_buf) ++ return; ++ ++ for (i = 0; i < NR_XMITFRAME; i++) { ++ rtw_os_xmit_complete(padapter, pxmitframe); ++ ++ pxmitframe++; ++ } ++ ++ for (i = 0; i < NR_XMITBUFF; i++) { ++ rtw_os_xmit_resource_free(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ)); ++ pxmitbuf++; ++ } ++ ++ vfree(pxmitpriv->pallocated_frame_buf); ++ ++ vfree(pxmitpriv->pallocated_xmitbuf); ++ ++ pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; ++ for (i = 0; i < num_xmit_extbuf; i++) { ++ rtw_os_xmit_resource_free(padapter, pxmitbuf, (max_xmit_extbuf_size + XMITBUF_ALIGN_SZ)); ++ pxmitbuf++; ++ } ++ ++ vfree(pxmitpriv->pallocated_xmit_extbuf); ++ ++ rtw_free_hwxmits(padapter); ++ ++ _rtw_mutex_free(&pxmitpriv->ack_tx_mutex); ++} ++ ++static void update_attrib_vcs_info(struct adapter *padapter, struct xmit_frame *pxmitframe) ++{ ++ u32 sz; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ struct sta_info *psta = pattrib->psta; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pattrib->nr_frags != 1) ++ sz = padapter->xmitpriv.frag_len; ++ else /* no frag */ ++ sz = pattrib->last_txcmdsz; ++ ++ /* (1) RTS_Threshold is compared to the MPDU, not MSDU. */ ++ /* (2) If there are more than one frag in this MSDU, only the first frag uses protection frame. */ ++ /* Other fragments are protected by previous fragment. */ ++ /* So we only need to check the length of first fragment. */ ++ if (pmlmeext->cur_wireless_mode < WIRELESS_11_24N || padapter->registrypriv.wifi_spec) { ++ if (sz > padapter->registrypriv.rts_thresh) { ++ pattrib->vcs_mode = RTS_CTS; ++ } else { ++ if (psta->rtsen) ++ pattrib->vcs_mode = RTS_CTS; ++ else if (psta->cts2self) ++ pattrib->vcs_mode = CTS_TO_SELF; ++ else ++ pattrib->vcs_mode = NONE_VCS; ++ } ++ } else { ++ while (true) { ++ /* IOT action */ ++ if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS) && pattrib->ampdu_en && ++ (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) { ++ pattrib->vcs_mode = CTS_TO_SELF; ++ break; ++ } ++ ++ /* check ERP protection */ ++ if (psta->rtsen || psta->cts2self) { ++ if (psta->rtsen) ++ pattrib->vcs_mode = RTS_CTS; ++ else if (psta->cts2self) ++ pattrib->vcs_mode = CTS_TO_SELF; ++ ++ break; ++ } ++ ++ /* check HT op mode */ ++ if (pattrib->ht_en) { ++ u8 htopmode = pmlmeinfo->HT_protection; ++ if ((pmlmeext->cur_bwmode && (htopmode == 2 || htopmode == 3)) || ++ (!pmlmeext->cur_bwmode && htopmode == 3)) { ++ pattrib->vcs_mode = RTS_CTS; ++ break; ++ } ++ } ++ ++ /* check rts */ ++ if (sz > padapter->registrypriv.rts_thresh) { ++ pattrib->vcs_mode = RTS_CTS; ++ break; ++ } ++ ++ /* to do list: check MIMO power save condition. */ ++ ++ /* check AMPDU aggregation for TXOP */ ++ if (pattrib->ampdu_en) { ++ pattrib->vcs_mode = RTS_CTS; ++ break; ++ } ++ ++ pattrib->vcs_mode = NONE_VCS; ++ break; ++ } ++ } ++} ++ ++static void update_attrib_phy_info(struct pkt_attrib *pattrib, struct sta_info *psta) ++{ ++ /*if (psta->rtsen) ++ pattrib->vcs_mode = RTS_CTS; ++ else if (psta->cts2self) ++ pattrib->vcs_mode = CTS_TO_SELF; ++ else ++ pattrib->vcs_mode = NONE_VCS;*/ ++ ++ pattrib->mdata = 0; ++ pattrib->eosp = 0; ++ pattrib->triggered = 0; ++ ++ /* qos_en, ht_en, init rate, , bw, ch_offset, sgi */ ++ pattrib->qos_en = psta->qos_option; ++ ++ pattrib->raid = psta->raid; ++ pattrib->ht_en = psta->htpriv.ht_option; ++ pattrib->bwmode = psta->htpriv.bwmode; ++ pattrib->ch_offset = psta->htpriv.ch_offset; ++ pattrib->sgi = psta->htpriv.sgi; ++ pattrib->ampdu_en = false; ++ pattrib->retry_ctrl = false; ++} ++ ++u8 qos_acm(u8 acm_mask, u8 priority) ++{ ++ u8 change_priority = priority; ++ ++ switch (priority) { ++ case 0: ++ case 3: ++ if (acm_mask & BIT(1)) ++ change_priority = 1; ++ break; ++ case 1: ++ case 2: ++ break; ++ case 4: ++ case 5: ++ if (acm_mask & BIT(2)) ++ change_priority = 0; ++ break; ++ case 6: ++ case 7: ++ if (acm_mask & BIT(3)) ++ change_priority = 5; ++ break; ++ default: ++ DBG_88E("qos_acm(): invalid pattrib->priority: %d!!!\n", priority); ++ break; ++ } ++ ++ return change_priority; ++} ++ ++static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib) ++{ ++ struct ethhdr etherhdr; ++ struct iphdr ip_hdr; ++ s32 user_prio = 0; ++ ++ _rtw_open_pktfile(ppktfile->pkt, ppktfile); ++ _rtw_pktfile_read(ppktfile, (unsigned char *)ðerhdr, ETH_HLEN); ++ ++ /* get user_prio from IP hdr */ ++ if (pattrib->ether_type == 0x0800) { ++ _rtw_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr)); ++/* user_prio = (ntohs(ip_hdr.tos) >> 5) & 0x3; */ ++ user_prio = ip_hdr.tos >> 5; ++ } else if (pattrib->ether_type == 0x888e) { ++ /* "When priority processing of data frames is supported, */ ++ /* a STA's SME should send EAPOL-Key frames at the highest priority." */ ++ user_prio = 7; ++ } ++ ++ pattrib->priority = user_prio; ++ pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN; ++ pattrib->subtype = WIFI_QOS_DATA_TYPE; ++} ++ ++static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct pkt_attrib *pattrib) ++{ ++ struct pkt_file pktfile; ++ struct sta_info *psta = NULL; ++ struct ethhdr etherhdr; ++ ++ bool bmcast; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct qos_priv *pqospriv = &pmlmepriv->qospriv; ++ int res = _SUCCESS; ++ ++ ++ ++ _rtw_open_pktfile(pkt, &pktfile); ++ _rtw_pktfile_read(&pktfile, (u8 *)ðerhdr, ETH_HLEN); ++ ++ pattrib->ether_type = ntohs(etherhdr.h_proto); ++ ++ memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN); ++ memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN); ++ ++ pattrib->pctrl = 0; ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); ++ memcpy(pattrib->ta, pattrib->src, ETH_ALEN); ++ } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); ++ memcpy(pattrib->ta, pattrib->src, ETH_ALEN); ++ } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); ++ memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN); ++ } ++ ++ pattrib->pktlen = pktfile.pkt_len; ++ ++ if (ETH_P_IP == pattrib->ether_type) { ++ /* The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time */ ++ /* to prevent DHCP protocol fail */ ++ u8 tmp[24]; ++ _rtw_pktfile_read(&pktfile, &tmp[0], 24); ++ pattrib->dhcp_pkt = 0; ++ if (pktfile.pkt_len > 282) {/* MINIMUM_DHCP_PACKET_SIZE) { */ ++ if (ETH_P_IP == pattrib->ether_type) {/* IP header */ ++ if (((tmp[21] == 68) && (tmp[23] == 67)) || ++ ((tmp[21] == 67) && (tmp[23] == 68))) { ++ /* 68 : UDP BOOTP client */ ++ /* 67 : UDP BOOTP server */ ++ /* Use low rate to send DHCP packet. */ ++ pattrib->dhcp_pkt = 1; ++ } ++ } ++ } ++ } else if (0x888e == pattrib->ether_type) { ++ DBG_88E_LEVEL(_drv_info_, "send eapol packet\n"); ++ } ++ ++ if ((pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1)) ++ rtw_set_scan_deny(padapter, 3000); ++ ++ /* If EAPOL , ARP , OR DHCP packet, driver must be in active mode. */ ++ if ((pattrib->ether_type == 0x0806) || (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1)) ++ rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1); ++ ++ bmcast = is_multicast_ether_addr(pattrib->ra); ++ ++ /* get sta_info */ ++ if (bmcast) { ++ psta = rtw_get_bcmc_stainfo(padapter); ++ } else { ++ psta = rtw_get_stainfo(pstapriv, pattrib->ra); ++ if (!psta) { /* if we cannot get psta => drrp the pkt */ ++ res = _FAIL; ++ goto exit; ++ } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) && !(psta->state & _FW_LINKED)) { ++ res = _FAIL; ++ goto exit; ++ } ++ } ++ ++ if (psta) { ++ pattrib->mac_id = psta->mac_id; ++ /* DBG_88E("%s ==> mac_id(%d)\n", __func__, pattrib->mac_id); */ ++ pattrib->psta = psta; ++ } else { ++ /* if we cannot get psta => drop the pkt */ ++ res = _FAIL; ++ goto exit; ++ } ++ ++ pattrib->ack_policy = 0; ++ /* get ether_hdr_len */ ++ pattrib->pkt_hdrlen = ETH_HLEN;/* pattrib->ether_type == 0x8100) ? (14 + 4): 14; vlan tag */ ++ ++ pattrib->hdrlen = WLAN_HDR_A3_LEN; ++ pattrib->subtype = WIFI_DATA_TYPE; ++ pattrib->priority = 0; ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) { ++ if (psta->qos_option) ++ set_qos(&pktfile, pattrib); ++ } else { ++ if (pqospriv->qos_option) { ++ set_qos(&pktfile, pattrib); ++ ++ if (pmlmepriv->acm_mask != 0) ++ pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority); ++ } ++ } ++ ++ if (psta->ieee8021x_blocked) { ++ pattrib->encrypt = 0; ++ ++ if ((pattrib->ether_type != 0x888e) && !check_fwstate(pmlmepriv, WIFI_MP_STATE)) { ++ res = _FAIL; ++ goto exit; ++ } ++ } else { ++ GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast); ++ ++ switch (psecuritypriv->dot11AuthAlgrthm) { ++ case dot11AuthAlgrthm_Open: ++ case dot11AuthAlgrthm_Shared: ++ case dot11AuthAlgrthm_Auto: ++ pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex; ++ break; ++ case dot11AuthAlgrthm_8021X: ++ if (bmcast) ++ pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid; ++ else ++ pattrib->key_idx = 0; ++ break; ++ default: ++ pattrib->key_idx = 0; ++ break; ++ } ++ } ++ ++ switch (pattrib->encrypt) { ++ case _WEP40_: ++ case _WEP104_: ++ pattrib->iv_len = 4; ++ pattrib->icv_len = 4; ++ break; ++ case _TKIP_: ++ pattrib->iv_len = 8; ++ pattrib->icv_len = 4; ++ ++ if (padapter->securitypriv.busetkipkey == _FAIL) { ++ res = _FAIL; ++ goto exit; ++ } ++ break; ++ case _AES_: ++ pattrib->iv_len = 8; ++ pattrib->icv_len = 8; ++ break; ++ default: ++ pattrib->iv_len = 0; ++ pattrib->icv_len = 0; ++ break; ++ } ++ ++ if (pattrib->encrypt && ++ (padapter->securitypriv.sw_encrypt || !psecuritypriv->hw_decrypted)) ++ pattrib->bswenc = true; ++ else ++ pattrib->bswenc = false; ++ ++ rtw_set_tx_chksum_offload(pkt, pattrib); ++ ++ update_attrib_phy_info(pattrib, psta); ++ ++exit: ++ ++ return res; ++} ++ ++static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitframe) ++{ ++ int curfragnum, length; ++ u8 *pframe, *payload, mic[8]; ++ struct mic_data micdata; ++ struct sta_info *stainfo; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ u8 priority[4] = {0x0, 0x0, 0x0, 0x0}; ++ u8 hw_hdr_offset = 0; ++ ++ if (pattrib->psta) ++ stainfo = pattrib->psta; ++ else ++ stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]); ++ ++ hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ); ++ ++ if (pattrib->encrypt == _TKIP_) {/* if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_PRIVACY_) */ ++ /* encode mic code */ ++ if (stainfo) { ++ u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0}; ++ ++ pframe = pxmitframe->buf_addr + hw_hdr_offset; ++ ++ if (is_multicast_ether_addr(pattrib->ra)) { ++ if (!memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16)) ++ return _FAIL; ++ /* start to calculate the mic code */ ++ rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey); ++ } else { ++ if (!memcmp(&stainfo->dot11tkiptxmickey.skey[0], null_key, 16)) { ++ /* msleep(10); */ ++ return _FAIL; ++ } ++ /* start to calculate the mic code */ ++ rtw_secmicsetkey(&micdata, &stainfo->dot11tkiptxmickey.skey[0]); ++ } ++ ++ if (pframe[1] & 1) { /* ToDS == 1 */ ++ rtw_secmicappend(&micdata, &pframe[16], 6); /* DA */ ++ if (pframe[1] & 2) /* From Ds == 1 */ ++ rtw_secmicappend(&micdata, &pframe[24], 6); ++ else ++ rtw_secmicappend(&micdata, &pframe[10], 6); ++ } else { /* ToDS == 0 */ ++ rtw_secmicappend(&micdata, &pframe[4], 6); /* DA */ ++ if (pframe[1] & 2) /* From Ds == 1 */ ++ rtw_secmicappend(&micdata, &pframe[16], 6); ++ else ++ rtw_secmicappend(&micdata, &pframe[10], 6); ++ } ++ ++ if (pattrib->qos_en) ++ priority[0] = (u8)pxmitframe->attrib.priority; ++ ++ rtw_secmicappend(&micdata, &priority[0], 4); ++ ++ payload = pframe; ++ ++ for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { ++ payload = (u8 *)RND4((size_t)(payload)); ++ ++ payload = payload + pattrib->hdrlen + pattrib->iv_len; ++ if ((curfragnum + 1) == pattrib->nr_frags) { ++ length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - ((pattrib->bswenc) ? pattrib->icv_len : 0); ++ rtw_secmicappend(&micdata, payload, length); ++ payload = payload + length; ++ } else { ++ length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - ((pattrib->bswenc) ? pattrib->icv_len : 0); ++ rtw_secmicappend(&micdata, payload, length); ++ payload = payload + length + pattrib->icv_len; ++ } ++ } ++ rtw_secgetmic(&micdata, &mic[0]); ++ /* add mic code and add the mic code length in last_txcmdsz */ ++ ++ memcpy(payload, &mic[0], 8); ++ pattrib->last_txcmdsz += 8; ++ ++ payload = payload - pattrib->last_txcmdsz + 8; ++ } ++ } ++ ++ return _SUCCESS; ++} ++ ++static s32 xmitframe_swencrypt(struct adapter *padapter, struct xmit_frame *pxmitframe) ++{ ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ ++ if (pattrib->bswenc) { ++ switch (pattrib->encrypt) { ++ case _WEP40_: ++ case _WEP104_: ++ rtw_wep_encrypt(padapter, (u8 *)pxmitframe); ++ break; ++ case _TKIP_: ++ rtw_tkip_encrypt(padapter, (u8 *)pxmitframe); ++ break; ++ case _AES_: ++ rtw_aes_encrypt(padapter, (u8 *)pxmitframe); ++ break; ++ default: ++ break; ++ } ++ } ++ ++ return _SUCCESS; ++} ++ ++s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib) ++{ ++ u16 *qc; ++ ++ struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct qos_priv *pqospriv = &pmlmepriv->qospriv; ++ u8 qos_option = false; ++ ++ int res = _SUCCESS; ++ __le16 *fctrl = &pwlanhdr->frame_ctl; ++ ++ struct sta_info *psta; ++ ++ if (pattrib->psta) { ++ psta = pattrib->psta; ++ } else { ++ if (is_multicast_ether_addr(pattrib->ra)) { ++ psta = rtw_get_bcmc_stainfo(padapter); ++ } else { ++ psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); ++ } ++ } ++ ++ memset(hdr, 0, WLANHDR_OFFSET); ++ ++ SetFrameSubType(fctrl, pattrib->subtype); ++ ++ if (pattrib->subtype & WIFI_DATA_TYPE) { ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ++ /* to_ds = 1, fr_ds = 0; */ ++ /* Data transfer to AP */ ++ SetToDs(fctrl); ++ memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); ++ ++ if (pqospriv->qos_option) ++ qos_option = true; ++ } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ /* to_ds = 0, fr_ds = 1; */ ++ SetFrDs(fctrl); ++ memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN); ++ ++ if (psta->qos_option) ++ qos_option = true; ++ } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN); ++ ++ if (psta->qos_option) ++ qos_option = true; ++ } else { ++ res = _FAIL; ++ goto exit; ++ } ++ ++ if (pattrib->mdata) ++ SetMData(fctrl); ++ ++ if (pattrib->encrypt) ++ SetPrivacy(fctrl); ++ ++ if (qos_option) { ++ qc = (unsigned short *)(hdr + pattrib->hdrlen - 2); ++ ++ if (pattrib->priority) ++ SetPriority(qc, pattrib->priority); ++ ++ SetEOSP(qc, pattrib->eosp); ++ ++ SetAckpolicy(qc, pattrib->ack_policy); ++ } ++ ++ /* TODO: fill HT Control Field */ ++ ++ /* Update Seq Num will be handled by f/w */ ++ if (psta) { ++ psta->sta_xmitpriv.txseq_tid[pattrib->priority]++; ++ psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF; ++ ++ pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority]; ++ ++ SetSeqNum(hdr, pattrib->seqnum); ++ ++ /* check if enable ampdu */ ++ if (pattrib->ht_en && psta->htpriv.ampdu_enable) { ++ if (psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority)) ++ pattrib->ampdu_en = true; ++ } ++ ++ /* re-check if enable ampdu by BA_starting_seqctrl */ ++ if (pattrib->ampdu_en) { ++ u16 tx_seq; ++ ++ tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f]; ++ ++ /* check BA_starting_seqctrl */ ++ if (SN_LESS(pattrib->seqnum, tx_seq)) { ++ pattrib->ampdu_en = false;/* AGG BK */ ++ } else if (SN_EQUAL(pattrib->seqnum, tx_seq)) { ++ psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq + 1) & 0xfff; ++ ++ pattrib->ampdu_en = true;/* AGG EN */ ++ } else { ++ psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum + 1) & 0xfff; ++ pattrib->ampdu_en = true;/* AGG EN */ ++ } ++ } ++ } ++ } ++exit: ++ ++ return res; ++} ++ ++s32 rtw_txframes_pending(struct adapter *padapter) ++{ ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ return (!list_empty(&pxmitpriv->be_pending.queue) || ++ !list_empty(&pxmitpriv->bk_pending.queue) || ++ !list_empty(&pxmitpriv->vi_pending.queue) || ++ !list_empty(&pxmitpriv->vo_pending.queue)); ++} ++ ++s32 rtw_txframes_sta_ac_pending(struct adapter *padapter, struct pkt_attrib *pattrib) ++{ ++ struct sta_info *psta; ++ struct tx_servq *ptxservq; ++ int priority = pattrib->priority; ++ ++ psta = pattrib->psta; ++ ++ switch (priority) { ++ case 1: ++ case 2: ++ ptxservq = &psta->sta_xmitpriv.bk_q; ++ break; ++ case 4: ++ case 5: ++ ptxservq = &psta->sta_xmitpriv.vi_q; ++ break; ++ case 6: ++ case 7: ++ ptxservq = &psta->sta_xmitpriv.vo_q; ++ break; ++ case 0: ++ case 3: ++ default: ++ ptxservq = &psta->sta_xmitpriv.be_q; ++ break; ++ } ++ ++ if (ptxservq) ++ return ptxservq->qcnt; ++ return 0; ++} ++ ++/* ++ * Calculate wlan 802.11 packet MAX size from pkt_attrib ++ * This function doesn't consider fragment case ++ */ ++u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib) ++{ ++ u32 len = 0; ++ ++ len = pattrib->hdrlen + pattrib->iv_len; /* WLAN Header and IV */ ++ len += SNAP_SIZE + sizeof(u16); /* LLC */ ++ len += pattrib->pktlen; ++ if (pattrib->encrypt == _TKIP_) ++ len += 8; /* MIC */ ++ len += ((pattrib->bswenc) ? pattrib->icv_len : 0); /* ICV */ ++ ++ return len; ++} ++ ++/* ++ ++This sub-routine will perform all the following: ++ ++1. remove 802.3 header. ++2. create wlan_header, based on the info in pxmitframe ++3. append sta's iv/ext-iv ++4. append LLC ++5. move frag chunk from pframe to pxmitframe->mem ++6. apply sw-encrypt, if necessary. ++ ++*/ ++s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct xmit_frame *pxmitframe) ++{ ++ struct pkt_file pktfile; ++ s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz; ++ size_t addr; ++ u8 *pframe, *mem_start; ++ u8 hw_hdr_offset; ++ struct sta_info *psta; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ u8 *pbuf_start; ++ bool bmcst = is_multicast_ether_addr(pattrib->ra); ++ s32 res = _SUCCESS; ++ ++ if (!pkt) ++ return _FAIL; ++ ++ psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); ++ ++ if (!psta) ++ return _FAIL; ++ ++ if (!pxmitframe->buf_addr) { ++ DBG_88E("==> %s buf_addr == NULL\n", __func__); ++ return _FAIL; ++ } ++ ++ pbuf_start = pxmitframe->buf_addr; ++ ++ hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ); ++ ++ mem_start = pbuf_start + hw_hdr_offset; ++ ++ if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) { ++ DBG_88E("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n"); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ _rtw_open_pktfile(pkt, &pktfile); ++ _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen); ++ ++ frg_inx = 0; ++ frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */ ++ ++ while (1) { ++ llc_sz = 0; ++ ++ mpdu_len = frg_len; ++ ++ pframe = mem_start; ++ ++ SetMFrag(mem_start); ++ ++ pframe += pattrib->hdrlen; ++ mpdu_len -= pattrib->hdrlen; ++ ++ /* adding icv, if necessary... */ ++ if (pattrib->iv_len) { ++ if (psta) { ++ switch (pattrib->encrypt) { ++ case _WEP40_: ++ case _WEP104_: ++ WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); ++ break; ++ case _TKIP_: ++ if (bmcst) ++ TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); ++ else ++ TKIP_IV(pattrib->iv, psta->dot11txpn, 0); ++ break; ++ case _AES_: ++ if (bmcst) ++ AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); ++ else ++ AES_IV(pattrib->iv, psta->dot11txpn, 0); ++ break; ++ } ++ } ++ ++ memcpy(pframe, pattrib->iv, pattrib->iv_len); ++ ++ pframe += pattrib->iv_len; ++ ++ mpdu_len -= pattrib->iv_len; ++ } ++ ++ if (frg_inx == 0) { ++ llc_sz = rtw_put_snap(pframe, pattrib->ether_type); ++ pframe += llc_sz; ++ mpdu_len -= llc_sz; ++ } ++ ++ if ((pattrib->icv_len > 0) && (pattrib->bswenc)) { ++ mpdu_len -= pattrib->icv_len; ++ } ++ ++ if (bmcst) { ++ /* don't do fragment to broadcat/multicast packets */ ++ mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen); ++ } else { ++ mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len); ++ } ++ ++ pframe += mem_sz; ++ ++ if ((pattrib->icv_len > 0) && (pattrib->bswenc)) { ++ memcpy(pframe, pattrib->icv, pattrib->icv_len); ++ pframe += pattrib->icv_len; ++ } ++ ++ frg_inx++; ++ ++ if (bmcst || rtw_endofpktfile(&pktfile)) { ++ pattrib->nr_frags = frg_inx; ++ ++ pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + ((pattrib->nr_frags == 1) ? llc_sz : 0) + ++ ((pattrib->bswenc) ? pattrib->icv_len : 0) + mem_sz; ++ ++ ClearMFrag(mem_start); ++ ++ break; ++ } ++ ++ addr = (size_t)(pframe); ++ ++ mem_start = (unsigned char *)RND4(addr) + hw_hdr_offset; ++ memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen); ++ } ++ ++ if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) { ++ DBG_88E("xmitframe_addmic(padapter, pxmitframe) == _FAIL\n"); ++ res = _FAIL; ++ goto exit; ++ } ++ ++ xmitframe_swencrypt(padapter, pxmitframe); ++ ++ if (!bmcst) ++ update_attrib_vcs_info(padapter, pxmitframe); ++ else ++ pattrib->vcs_mode = NONE_VCS; ++ ++exit: ++ ++ return res; ++} ++ ++/* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header ++ * IEEE LLC/SNAP header contains 8 octets ++ * First 3 octets comprise the LLC portion ++ * SNAP portion, 5 octets, is divided into two fields: ++ * Organizationally Unique Identifier(OUI), 3 octets, ++ * type, defined by that organization, 2 octets. ++ */ ++s32 rtw_put_snap(u8 *data, u16 h_proto) ++{ ++ struct ieee80211_snap_hdr *snap; ++ u8 *oui; ++ ++ snap = (struct ieee80211_snap_hdr *)data; ++ snap->dsap = 0xaa; ++ snap->ssap = 0xaa; ++ snap->ctrl = 0x03; ++ ++ if (h_proto == 0x8137 || h_proto == 0x80f3) ++ oui = P802_1H_OUI; ++ else ++ oui = RFC1042_OUI; ++ ++ snap->oui[0] = oui[0]; ++ snap->oui[1] = oui[1]; ++ snap->oui[2] = oui[2]; ++ ++ *(__be16 *)(data + SNAP_SIZE) = htons(h_proto); ++ ++ return SNAP_SIZE + sizeof(u16); ++} ++ ++void rtw_update_protection(struct adapter *padapter, u8 *ie, uint ie_len) ++{ ++ uint protection; ++ u8 *perp; ++ int erp_len; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ ++ switch (pxmitpriv->vcs_setting) { ++ case DISABLE_VCS: ++ pxmitpriv->vcs = NONE_VCS; ++ break; ++ case ENABLE_VCS: ++ break; ++ case AUTO_VCS: ++ default: ++ perp = rtw_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len); ++ if (!perp) { ++ pxmitpriv->vcs = NONE_VCS; ++ } else { ++ protection = (*(perp + 2)) & BIT(1); ++ if (protection) { ++ if (pregistrypriv->vcs_type == RTS_CTS) ++ pxmitpriv->vcs = RTS_CTS; ++ else ++ pxmitpriv->vcs = CTS_TO_SELF; ++ } else { ++ pxmitpriv->vcs = NONE_VCS; ++ } ++ } ++ break; ++ } ++ ++} ++ ++void rtw_count_tx_stats(struct adapter *padapter, struct xmit_frame *pxmitframe, int sz) ++{ ++ struct sta_info *psta = NULL; ++ struct stainfo_stats *pstats = NULL; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) { ++ pxmitpriv->tx_bytes += sz; ++ pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pxmitframe->agg_num; ++ ++ psta = pxmitframe->attrib.psta; ++ if (psta) { ++ pstats = &psta->sta_stats; ++ pstats->tx_pkts += pxmitframe->agg_num; ++ pstats->tx_bytes += sz; ++ } ++ } ++} ++ ++struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv) ++{ ++ struct xmit_buf *pxmitbuf = NULL; ++ struct list_head *plist, *phead; ++ struct __queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&pfree_queue->lock, flags); ++ ++ if (list_empty(&pfree_queue->queue)) { ++ pxmitbuf = NULL; ++ } else { ++ phead = get_list_head(pfree_queue); ++ ++ plist = phead->next; ++ ++ pxmitbuf = container_of(plist, struct xmit_buf, list); ++ ++ list_del_init(&pxmitbuf->list); ++ } ++ ++ if (pxmitbuf) { ++ pxmitpriv->free_xmit_extbuf_cnt--; ++ ++ pxmitbuf->priv_data = NULL; ++ /* pxmitbuf->ext_tag = true; */ ++ ++ if (pxmitbuf->sctx) { ++ DBG_88E("%s pxmitbuf->sctx is not NULL\n", __func__); ++ rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC); ++ } ++ } ++ ++ spin_unlock_irqrestore(&pfree_queue->lock, flags); ++ ++ return pxmitbuf; ++} ++ ++s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) ++{ ++ struct __queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue; ++ unsigned long flags; ++ ++ if (!pxmitbuf) ++ return _FAIL; ++ ++ spin_lock_irqsave(&pfree_queue->lock, flags); ++ ++ list_del_init(&pxmitbuf->list); ++ ++ list_add_tail(&pxmitbuf->list, get_list_head(pfree_queue)); ++ pxmitpriv->free_xmit_extbuf_cnt++; ++ ++ spin_unlock_irqrestore(&pfree_queue->lock, flags); ++ ++ return _SUCCESS; ++} ++ ++struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv) ++{ ++ struct xmit_buf *pxmitbuf = NULL; ++ struct list_head *plist, *phead; ++ struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; ++ unsigned long flags; ++ ++ /* DBG_88E("+rtw_alloc_xmitbuf\n"); */ ++ ++ spin_lock_irqsave(&pfree_xmitbuf_queue->lock, flags); ++ ++ if (list_empty(&pfree_xmitbuf_queue->queue)) { ++ pxmitbuf = NULL; ++ } else { ++ phead = get_list_head(pfree_xmitbuf_queue); ++ ++ plist = phead->next; ++ ++ pxmitbuf = container_of(plist, struct xmit_buf, list); ++ ++ list_del_init(&pxmitbuf->list); ++ } ++ ++ if (pxmitbuf) { ++ pxmitpriv->free_xmitbuf_cnt--; ++ pxmitbuf->priv_data = NULL; ++ if (pxmitbuf->sctx) { ++ DBG_88E("%s pxmitbuf->sctx is not NULL\n", __func__); ++ rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC); ++ } ++ } ++ spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, flags); ++ ++ return pxmitbuf; ++} ++ ++s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) ++{ ++ struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; ++ unsigned long flags; ++ ++ if (!pxmitbuf) ++ return _FAIL; ++ ++ if (pxmitbuf->sctx) { ++ DBG_88E("%s pxmitbuf->sctx is not NULL\n", __func__); ++ rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE); ++ } ++ ++ if (pxmitbuf->ext_tag) { ++ rtw_free_xmitbuf_ext(pxmitpriv, pxmitbuf); ++ } else { ++ spin_lock_irqsave(&pfree_xmitbuf_queue->lock, flags); ++ ++ list_del_init(&pxmitbuf->list); ++ ++ list_add_tail(&pxmitbuf->list, get_list_head(pfree_xmitbuf_queue)); ++ ++ pxmitpriv->free_xmitbuf_cnt++; ++ spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, flags); ++ } ++ ++ return _SUCCESS; ++} ++ ++/* ++Calling context: ++1. OS_TXENTRY ++2. RXENTRY (rx_thread or RX_ISR/RX_CallBack) ++ ++If we turn on USE_RXTHREAD, then, no need for critical section. ++Otherwise, we must use _enter/_exit critical to protect free_xmit_queue... ++ ++Must be very very cautious... ++ ++*/ ++ ++struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* _queue *pfree_xmit_queue) */ ++{ ++ /* ++ Please remember to use all the osdep_service api, ++ and lock/unlock or _enter/_exit critical to protect ++ pfree_xmit_queue ++ */ ++ ++ struct xmit_frame *pxframe = NULL; ++ struct list_head *plist, *phead; ++ struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; ++ ++ spin_lock_bh(&pfree_xmit_queue->lock); ++ ++ if (list_empty(&pfree_xmit_queue->queue)) { ++ pxframe = NULL; ++ } else { ++ phead = get_list_head(pfree_xmit_queue); ++ ++ plist = phead->next; ++ ++ pxframe = container_of(plist, struct xmit_frame, list); ++ ++ list_del_init(&pxframe->list); ++ } ++ ++ if (pxframe) { /* default value setting */ ++ pxmitpriv->free_xmitframe_cnt--; ++ ++ pxframe->buf_addr = NULL; ++ pxframe->pxmitbuf = NULL; ++ ++ memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib)); ++ /* pxframe->attrib.psta = NULL; */ ++ ++ pxframe->frame_tag = DATA_FRAMETAG; ++ ++ pxframe->pkt = NULL; ++ pxframe->pkt_offset = 1;/* default use pkt_offset to fill tx desc */ ++ ++ pxframe->agg_num = 1; ++ pxframe->ack_report = 0; ++ } ++ ++ spin_unlock_bh(&pfree_xmit_queue->lock); ++ ++ return pxframe; ++} ++ ++s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe) ++{ ++ struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; ++ struct adapter *padapter = pxmitpriv->adapter; ++ struct sk_buff *pndis_pkt = NULL; ++ ++ if (!pxmitframe) ++ goto exit; ++ ++ spin_lock_bh(&pfree_xmit_queue->lock); ++ ++ list_del_init(&pxmitframe->list); ++ ++ if (pxmitframe->pkt) { ++ pndis_pkt = pxmitframe->pkt; ++ pxmitframe->pkt = NULL; ++ } ++ ++ list_add_tail(&pxmitframe->list, get_list_head(pfree_xmit_queue)); ++ ++ pxmitpriv->free_xmitframe_cnt++; ++ ++ spin_unlock_bh(&pfree_xmit_queue->lock); ++ ++ if (pndis_pkt) ++ rtw_os_pkt_complete(padapter, pndis_pkt); ++ ++exit: ++ ++ return _SUCCESS; ++} ++ ++void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, struct __queue *pframequeue) ++{ ++ struct list_head *plist, *phead; ++ struct xmit_frame *pxmitframe; ++ ++ spin_lock_bh(&pframequeue->lock); ++ ++ phead = get_list_head(pframequeue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pxmitframe = container_of(plist, struct xmit_frame, list); ++ ++ plist = plist->next; ++ ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ } ++ spin_unlock_bh(&pframequeue->lock); ++ ++} ++ ++s32 rtw_xmitframe_enqueue(struct adapter *padapter, struct xmit_frame *pxmitframe) ++{ ++ if (rtw_xmit_classifier(padapter, pxmitframe) == _FAIL) { ++/* pxmitframe->pkt = NULL; */ ++ return _FAIL; ++ } ++ ++ return _SUCCESS; ++} ++ ++static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, struct __queue *pframe_queue) ++{ ++ struct list_head *xmitframe_plist, *xmitframe_phead; ++ struct xmit_frame *pxmitframe = NULL; ++ ++ xmitframe_phead = get_list_head(pframe_queue); ++ xmitframe_plist = xmitframe_phead->next; ++ ++ if (xmitframe_phead != xmitframe_plist) { ++ pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); ++ ++ xmitframe_plist = xmitframe_plist->next; ++ ++ list_del_init(&pxmitframe->list); ++ ++ ptxservq->qcnt--; ++ } ++ return pxmitframe; ++} ++ ++struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, int entry) ++{ ++ struct list_head *sta_plist, *sta_phead; ++ struct hw_xmit *phwxmit; ++ struct tx_servq *ptxservq = NULL; ++ struct __queue *pframe_queue = NULL; ++ struct xmit_frame *pxmitframe = NULL; ++ struct adapter *padapter = pxmitpriv->adapter; ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ int i, inx[4]; ++ ++ inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3; ++ ++ if (pregpriv->wifi_spec == 1) { ++ int j; ++ ++ for (j = 0; j < 4; j++) ++ inx[j] = pxmitpriv->wmm_para_seq[j]; ++ } ++ ++ spin_lock_bh(&pxmitpriv->lock); ++ ++ for (i = 0; i < entry; i++) { ++ phwxmit = phwxmit_i + inx[i]; ++ ++ sta_phead = get_list_head(phwxmit->sta_queue); ++ sta_plist = sta_phead->next; ++ ++ while (sta_phead != sta_plist) { ++ ptxservq = container_of(sta_plist, struct tx_servq, tx_pending); ++ ++ pframe_queue = &ptxservq->sta_pending; ++ ++ pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue); ++ ++ if (pxmitframe) { ++ phwxmit->accnt--; ++ ++ /* Remove sta node when there are no pending packets. */ ++ if (list_empty(&pframe_queue->queue)) /* must be done after get_next and before break */ ++ list_del_init(&ptxservq->tx_pending); ++ goto exit; ++ } ++ ++ sta_plist = sta_plist->next; ++ } ++ } ++exit: ++ spin_unlock_bh(&pxmitpriv->lock); ++ ++ return pxmitframe; ++} ++ ++struct tx_servq *rtw_get_sta_pending(struct adapter *padapter, struct sta_info *psta, int up, u8 *ac) ++{ ++ struct tx_servq *ptxservq; ++ ++ switch (up) { ++ case 1: ++ case 2: ++ ptxservq = &psta->sta_xmitpriv.bk_q; ++ *(ac) = 3; ++ break; ++ case 4: ++ case 5: ++ ptxservq = &psta->sta_xmitpriv.vi_q; ++ *(ac) = 1; ++ break; ++ case 6: ++ case 7: ++ ptxservq = &psta->sta_xmitpriv.vo_q; ++ *(ac) = 0; ++ break; ++ case 0: ++ case 3: ++ default: ++ ptxservq = &psta->sta_xmitpriv.be_q; ++ *(ac) = 2; ++ break; ++ } ++ ++ return ptxservq; ++} ++ ++/* ++ * Will enqueue pxmitframe to the proper queue, ++ * and indicate it to xx_pending list..... ++ */ ++s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe) ++{ ++ u8 ac_index; ++ struct sta_info *psta; ++ struct tx_servq *ptxservq; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; ++ int res = _SUCCESS; ++ ++ if (pattrib->psta) { ++ psta = pattrib->psta; ++ } else { ++ psta = rtw_get_stainfo(pstapriv, pattrib->ra); ++ } ++ ++ if (!psta) { ++ res = _FAIL; ++ DBG_88E("rtw_xmit_classifier: psta == NULL\n"); ++ goto exit; ++ } ++ ++ ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index)); ++ ++ if (list_empty(&ptxservq->tx_pending)) ++ list_add_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue)); ++ ++ list_add_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending)); ++ ptxservq->qcnt++; ++ phwxmits[ac_index].accnt++; ++exit: ++ ++ return res; ++} ++ ++void rtw_alloc_hwxmits(struct adapter *padapter) ++{ ++ struct hw_xmit *hwxmits; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ pxmitpriv->hwxmit_entry = HWXMIT_ENTRY; ++ ++ pxmitpriv->hwxmits = kzalloc(sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry, GFP_KERNEL); ++ ++ hwxmits = pxmitpriv->hwxmits; ++ ++ if (pxmitpriv->hwxmit_entry == 5) { ++ hwxmits[0] .sta_queue = &pxmitpriv->bm_pending; ++ hwxmits[1] .sta_queue = &pxmitpriv->vo_pending; ++ hwxmits[2] .sta_queue = &pxmitpriv->vi_pending; ++ hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; ++ hwxmits[4] .sta_queue = &pxmitpriv->be_pending; ++ } else if (pxmitpriv->hwxmit_entry == 4) { ++ hwxmits[0] .sta_queue = &pxmitpriv->vo_pending; ++ hwxmits[1] .sta_queue = &pxmitpriv->vi_pending; ++ hwxmits[2] .sta_queue = &pxmitpriv->be_pending; ++ hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; ++ } else { ++ } ++} ++ ++void rtw_free_hwxmits(struct adapter *padapter) ++{ ++ struct hw_xmit *hwxmits; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ hwxmits = pxmitpriv->hwxmits; ++ kfree(hwxmits); ++} ++ ++void rtw_init_hwxmits(struct hw_xmit *phwxmit, int entry) ++{ ++ int i; ++ ++ for (i = 0; i < entry; i++, phwxmit++) ++ phwxmit->accnt = 0; ++ ++} ++ ++static int rtw_br_client_tx(struct adapter *padapter, struct sk_buff **pskb) ++{ ++ struct sk_buff *skb = *pskb; ++ int res, is_vlan_tag = 0, i, do_nat25 = 1; ++ unsigned short vlan_hdr = 0; ++ void *br_port = NULL; ++ ++ rcu_read_lock(); ++ br_port = rcu_dereference(padapter->pnetdev->rx_handler_data); ++ rcu_read_unlock(); ++ spin_lock_bh(&padapter->br_ext_lock); ++ if (!(skb->data[0] & 1) && br_port && ++ memcmp(skb->data + MACADDRLEN, padapter->br_mac, MACADDRLEN) && ++ *((__be16 *)(skb->data + MACADDRLEN * 2)) != __constant_htons(ETH_P_8021Q) && ++ *((__be16 *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP) && ++ !memcmp(padapter->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN) && padapter->scdb_entry) { ++ memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN); ++ padapter->scdb_entry->ageing_timer = jiffies; ++ spin_unlock_bh(&padapter->br_ext_lock); ++ } else { ++ if (*((__be16 *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_8021Q)) { ++ is_vlan_tag = 1; ++ vlan_hdr = *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)); ++ for (i = 0; i < 6; i++) ++ *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + MACADDRLEN * 2 - 2 - i * 2)); ++ skb_pull(skb, 4); ++ } ++ if (!memcmp(skb->data + MACADDRLEN, padapter->br_mac, MACADDRLEN) && ++ (*((__be16 *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP))) ++ memcpy(padapter->br_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4); ++ ++ if (*((__be16 *)(skb->data + MACADDRLEN * 2)) == __constant_htons(ETH_P_IP)) { ++ if (memcmp(padapter->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN)) { ++ padapter->scdb_entry = (struct nat25_network_db_entry *)scdb_findEntry(padapter, ++ skb->data + MACADDRLEN, skb->data + WLAN_ETHHDR_LEN + 12); ++ if (padapter->scdb_entry) { ++ memcpy(padapter->scdb_mac, skb->data + MACADDRLEN, MACADDRLEN); ++ memcpy(padapter->scdb_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4); ++ padapter->scdb_entry->ageing_timer = jiffies; ++ do_nat25 = 0; ++ } ++ } else { ++ if (padapter->scdb_entry) { ++ padapter->scdb_entry->ageing_timer = jiffies; ++ do_nat25 = 0; ++ } else { ++ memset(padapter->scdb_mac, 0, MACADDRLEN); ++ memset(padapter->scdb_ip, 0, 4); ++ } ++ } ++ } ++ spin_unlock_bh(&padapter->br_ext_lock); ++ if (do_nat25) { ++ if (nat25_db_handle(padapter, skb, NAT25_CHECK) == 0) { ++ struct sk_buff *newskb; ++ ++ if (is_vlan_tag) { ++ skb_push(skb, 4); ++ for (i = 0; i < 6; i++) ++ *((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2)); ++ *((__be16 *)(skb->data + MACADDRLEN * 2)) = __constant_htons(ETH_P_8021Q); ++ *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)) = vlan_hdr; ++ } ++ ++ newskb = skb_copy(skb, GFP_ATOMIC); ++ if (!newskb) { ++ DEBUG_ERR("TX DROP: skb_copy fail!\n"); ++ return -1; ++ } ++ dev_kfree_skb_any(skb); ++ ++ *pskb = skb = newskb; ++ if (is_vlan_tag) { ++ vlan_hdr = *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)); ++ for (i = 0; i < 6; i++) ++ *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + MACADDRLEN * 2 - 2 - i * 2)); ++ skb_pull(skb, 4); ++ } ++ } ++ ++ if (skb_is_nonlinear(skb)) ++ DEBUG_ERR("%s(): skb_is_nonlinear!!\n", __func__); ++ ++ res = skb_linearize(skb); ++ if (res < 0) { ++ DEBUG_ERR("TX DROP: skb_linearize fail!\n"); ++ return -1; ++ } ++ ++ res = nat25_db_handle(padapter, skb, NAT25_INSERT); ++ if (res < 0) { ++ if (res == -2) { ++ DEBUG_ERR("TX DROP: nat25_db_handle fail!\n"); ++ return -1; ++ } ++ return 0; ++ } ++ } ++ ++ memcpy(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN); ++ ++ dhcp_flag_bcast(padapter, skb); ++ ++ if (is_vlan_tag) { ++ skb_push(skb, 4); ++ for (i = 0; i < 6; i++) ++ *((unsigned short *)(skb->data + i * 2)) = *((unsigned short *)(skb->data + 4 + i * 2)); ++ *((__be16 *)(skb->data + MACADDRLEN * 2)) = __constant_htons(ETH_P_8021Q); ++ *((unsigned short *)(skb->data + MACADDRLEN * 2 + 2)) = vlan_hdr; ++ } ++ } ++ ++ /* check if SA is equal to our MAC */ ++ if (memcmp(skb->data + MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN)) { ++ DEBUG_ERR("TX DROP: untransformed frame SA:%02X%02X%02X%02X%02X%02X!\n", ++ skb->data[6], skb->data[7], skb->data[8], skb->data[9], skb->data[10], skb->data[11]); ++ return -1; ++ } ++ return 0; ++} ++ ++u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe) ++{ ++ u32 addr; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ ++ switch (pattrib->qsel) { ++ case 0: ++ case 3: ++ addr = BE_QUEUE_INX; ++ break; ++ case 1: ++ case 2: ++ addr = BK_QUEUE_INX; ++ break; ++ case 4: ++ case 5: ++ addr = VI_QUEUE_INX; ++ break; ++ case 6: ++ case 7: ++ addr = VO_QUEUE_INX; ++ break; ++ case 0x10: ++ addr = BCN_QUEUE_INX; ++ break; ++ case 0x11:/* BC/MC in PS (HIQ) */ ++ addr = HIGH_QUEUE_INX; ++ break; ++ case 0x12: ++ default: ++ addr = MGT_QUEUE_INX; ++ break; ++ } ++ ++ return addr; ++} ++ ++static void do_queue_select(struct adapter *padapter, struct pkt_attrib *pattrib) ++{ ++ u8 qsel; ++ ++ qsel = pattrib->priority; ++ ++ pattrib->qsel = qsel; ++} ++ ++/* ++ * The main transmit(tx) entry ++ * ++ * Return ++ * 1 enqueue ++ * 0 success, hardware will handle this xmit frame(packet) ++ * <0 fail ++ */ ++s32 rtw_xmit(struct adapter *padapter, struct sk_buff **ppkt) ++{ ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct xmit_frame *pxmitframe = NULL; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ void *br_port = NULL; ++ s32 res; ++ ++ pxmitframe = rtw_alloc_xmitframe(pxmitpriv); ++ if (!pxmitframe) { ++ DBG_88E("DBG_TX_DROP_FRAME %s no more pxmitframe\n", __func__); ++ return -1; ++ } ++ ++ rcu_read_lock(); ++ br_port = rcu_dereference(padapter->pnetdev->rx_handler_data); ++ rcu_read_unlock(); ++ ++ if (br_port && check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE)) { ++ res = rtw_br_client_tx(padapter, ppkt); ++ if (res == -1) { ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ return -1; ++ } ++ } ++ ++ res = update_attrib(padapter, *ppkt, &pxmitframe->attrib); ++ ++ if (res == _FAIL) { ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ return -1; ++ } ++ pxmitframe->pkt = *ppkt; ++ ++ rtw_led_control(padapter, LED_CTL_TX); ++ ++ do_queue_select(padapter, &pxmitframe->attrib); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ spin_lock_bh(&pxmitpriv->lock); ++ if (xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe)) { ++ spin_unlock_bh(&pxmitpriv->lock); ++ return 1; ++ } ++ spin_unlock_bh(&pxmitpriv->lock); ++#endif ++ ++ if (!rtw_hal_xmit(padapter, pxmitframe)) ++ return 1; ++ ++ return 0; ++} ++ ++#if defined(CONFIG_88EU_AP_MODE) ++ ++int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_frame *pxmitframe) ++{ ++ int ret = false; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ bool bmcst = is_multicast_ether_addr(pattrib->ra); ++ ++ if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ return ret; ++ ++ if (pattrib->psta) ++ psta = pattrib->psta; ++ else ++ psta = rtw_get_stainfo(pstapriv, pattrib->ra); ++ ++ if (!psta) ++ return ret; ++ ++ if (pattrib->triggered == 1) { ++ if (bmcst) ++ pattrib->qsel = 0x11;/* HIQ */ ++ return ret; ++ } ++ ++ if (bmcst) { ++ spin_lock_bh(&psta->sleep_q.lock); ++ ++ if (pstapriv->sta_dz_bitmap) {/* if any one sta is in ps mode */ ++ list_del_init(&pxmitframe->list); ++ ++ list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q)); ++ ++ psta->sleepq_len++; ++ ++ pstapriv->tim_bitmap |= BIT(0);/* */ ++ pstapriv->sta_dz_bitmap |= BIT(0); ++ ++ update_beacon(padapter, _TIM_IE_, NULL, false);/* tx bc/mc packets after upate bcn */ ++ ++ ret = true; ++ } ++ ++ spin_unlock_bh(&psta->sleep_q.lock); ++ ++ return ret; ++ } ++ ++ spin_lock_bh(&psta->sleep_q.lock); ++ ++ if (psta->state & WIFI_SLEEP_STATE) { ++ u8 wmmps_ac = 0; ++ ++ if (pstapriv->sta_dz_bitmap & BIT(psta->aid)) { ++ list_del_init(&pxmitframe->list); ++ ++ list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q)); ++ ++ psta->sleepq_len++; ++ ++ switch (pattrib->priority) { ++ case 1: ++ case 2: ++ wmmps_ac = psta->uapsd_bk & BIT(0); ++ break; ++ case 4: ++ case 5: ++ wmmps_ac = psta->uapsd_vi & BIT(0); ++ break; ++ case 6: ++ case 7: ++ wmmps_ac = psta->uapsd_vo & BIT(0); ++ break; ++ case 0: ++ case 3: ++ default: ++ wmmps_ac = psta->uapsd_be & BIT(0); ++ break; ++ } ++ ++ if (wmmps_ac) ++ psta->sleepq_ac_len++; ++ ++ if (((psta->has_legacy_ac) && (!wmmps_ac)) || ++ ((!psta->has_legacy_ac) && (wmmps_ac))) { ++ pstapriv->tim_bitmap |= BIT(psta->aid); ++ ++ if (psta->sleepq_len == 1) { ++ /* upate BCN for TIM IE */ ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++ } ++ } ++ ret = true; ++ } ++ } ++ ++ spin_unlock_bh(&psta->sleep_q.lock); ++ ++ return ret; ++} ++ ++static void dequeue_xmitframes_to_sleeping_queue(struct adapter *padapter, struct sta_info *psta, struct __queue *pframequeue) ++{ ++ struct list_head *plist, *phead; ++ u8 ac_index; ++ struct tx_servq *ptxservq; ++ struct pkt_attrib *pattrib; ++ struct xmit_frame *pxmitframe; ++ struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; ++ ++ phead = get_list_head(pframequeue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pxmitframe = container_of(plist, struct xmit_frame, list); ++ ++ plist = plist->next; ++ ++ xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe); ++ ++ pattrib = &pxmitframe->attrib; ++ ++ ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index)); ++ ++ ptxservq->qcnt--; ++ phwxmits[ac_index].accnt--; ++ } ++} ++ ++void stop_sta_xmit(struct adapter *padapter, struct sta_info *psta) ++{ ++ struct sta_info *psta_bmc; ++ struct sta_xmit_priv *pstaxmitpriv; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ pstaxmitpriv = &psta->sta_xmitpriv; ++ ++ /* for BC/MC Frames */ ++ psta_bmc = rtw_get_bcmc_stainfo(padapter); ++ ++ spin_lock_bh(&pxmitpriv->lock); ++ ++ psta->state |= WIFI_SLEEP_STATE; ++ ++ pstapriv->sta_dz_bitmap |= BIT(psta->aid); ++ ++ dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending); ++ list_del_init(&pstaxmitpriv->vo_q.tx_pending); ++ ++ dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending); ++ list_del_init(&pstaxmitpriv->vi_q.tx_pending); ++ ++ dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending); ++ list_del_init(&pstaxmitpriv->be_q.tx_pending); ++ ++ dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending); ++ list_del_init(&pstaxmitpriv->bk_q.tx_pending); ++ ++ /* for BC/MC Frames */ ++ pstaxmitpriv = &psta_bmc->sta_xmitpriv; ++ dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->be_q.sta_pending); ++ list_del_init(&pstaxmitpriv->be_q.tx_pending); ++ ++ spin_unlock_bh(&pxmitpriv->lock); ++} ++ ++void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta) ++{ ++ u8 update_mask = 0, wmmps_ac = 0; ++ struct sta_info *psta_bmc; ++ struct list_head *xmitframe_plist, *xmitframe_phead; ++ struct xmit_frame *pxmitframe = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ spin_lock_bh(&psta->sleep_q.lock); ++ ++ xmitframe_phead = get_list_head(&psta->sleep_q); ++ xmitframe_plist = xmitframe_phead->next; ++ ++ while (xmitframe_phead != xmitframe_plist) { ++ pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); ++ ++ xmitframe_plist = xmitframe_plist->next; ++ ++ list_del_init(&pxmitframe->list); ++ ++ switch (pxmitframe->attrib.priority) { ++ case 1: ++ case 2: ++ wmmps_ac = psta->uapsd_bk & BIT(1); ++ break; ++ case 4: ++ case 5: ++ wmmps_ac = psta->uapsd_vi & BIT(1); ++ break; ++ case 6: ++ case 7: ++ wmmps_ac = psta->uapsd_vo & BIT(1); ++ break; ++ case 0: ++ case 3: ++ default: ++ wmmps_ac = psta->uapsd_be & BIT(1); ++ break; ++ } ++ ++ psta->sleepq_len--; ++ if (psta->sleepq_len > 0) ++ pxmitframe->attrib.mdata = 1; ++ else ++ pxmitframe->attrib.mdata = 0; ++ ++ if (wmmps_ac) { ++ psta->sleepq_ac_len--; ++ if (psta->sleepq_ac_len > 0) { ++ pxmitframe->attrib.mdata = 1; ++ pxmitframe->attrib.eosp = 0; ++ } else { ++ pxmitframe->attrib.mdata = 0; ++ pxmitframe->attrib.eosp = 1; ++ } ++ } ++ ++ pxmitframe->attrib.triggered = 1; ++ ++ spin_unlock_bh(&psta->sleep_q.lock); ++ if (rtw_hal_xmit(padapter, pxmitframe)) ++ rtw_os_xmit_complete(padapter, pxmitframe); ++ spin_lock_bh(&psta->sleep_q.lock); ++ } ++ ++ if (psta->sleepq_len == 0) { ++ pstapriv->tim_bitmap &= ~BIT(psta->aid); ++ ++ update_mask = BIT(0); ++ ++ if (psta->state & WIFI_SLEEP_STATE) ++ psta->state ^= WIFI_SLEEP_STATE; ++ ++ if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { ++ psta->expire_to = pstapriv->expire_to; ++ psta->state ^= WIFI_STA_ALIVE_CHK_STATE; ++ } ++ ++ pstapriv->sta_dz_bitmap &= ~BIT(psta->aid); ++ } ++ ++ spin_unlock_bh(&psta->sleep_q.lock); ++ ++ /* for BC/MC Frames */ ++ psta_bmc = rtw_get_bcmc_stainfo(padapter); ++ if (!psta_bmc) ++ return; ++ ++ if ((pstapriv->sta_dz_bitmap & 0xfffe) == 0x0) { /* no any sta in ps mode */ ++ spin_lock_bh(&psta_bmc->sleep_q.lock); ++ ++ xmitframe_phead = get_list_head(&psta_bmc->sleep_q); ++ xmitframe_plist = xmitframe_phead->next; ++ ++ while (xmitframe_phead != xmitframe_plist) { ++ pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); ++ ++ xmitframe_plist = xmitframe_plist->next; ++ ++ list_del_init(&pxmitframe->list); ++ ++ psta_bmc->sleepq_len--; ++ if (psta_bmc->sleepq_len > 0) ++ pxmitframe->attrib.mdata = 1; ++ else ++ pxmitframe->attrib.mdata = 0; ++ ++ pxmitframe->attrib.triggered = 1; ++ ++ spin_unlock_bh(&psta_bmc->sleep_q.lock); ++ if (rtw_hal_xmit(padapter, pxmitframe)) ++ rtw_os_xmit_complete(padapter, pxmitframe); ++ spin_lock_bh(&psta_bmc->sleep_q.lock); ++ } ++ ++ if (psta_bmc->sleepq_len == 0) { ++ pstapriv->tim_bitmap &= ~BIT(0); ++ pstapriv->sta_dz_bitmap &= ~BIT(0); ++ ++ update_mask |= BIT(1); ++ } ++ ++ spin_unlock_bh(&psta_bmc->sleep_q.lock); ++ } ++ ++ if (update_mask) ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++} ++ ++void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *psta) ++{ ++ u8 wmmps_ac = 0; ++ struct list_head *xmitframe_plist, *xmitframe_phead; ++ struct xmit_frame *pxmitframe = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ spin_lock_bh(&psta->sleep_q.lock); ++ ++ xmitframe_phead = get_list_head(&psta->sleep_q); ++ xmitframe_plist = xmitframe_phead->next; ++ ++ while (xmitframe_phead != xmitframe_plist) { ++ pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); ++ ++ xmitframe_plist = xmitframe_plist->next; ++ ++ switch (pxmitframe->attrib.priority) { ++ case 1: ++ case 2: ++ wmmps_ac = psta->uapsd_bk & BIT(1); ++ break; ++ case 4: ++ case 5: ++ wmmps_ac = psta->uapsd_vi & BIT(1); ++ break; ++ case 6: ++ case 7: ++ wmmps_ac = psta->uapsd_vo & BIT(1); ++ break; ++ case 0: ++ case 3: ++ default: ++ wmmps_ac = psta->uapsd_be & BIT(1); ++ break; ++ } ++ ++ if (!wmmps_ac) ++ continue; ++ ++ list_del_init(&pxmitframe->list); ++ ++ psta->sleepq_len--; ++ psta->sleepq_ac_len--; ++ ++ if (psta->sleepq_ac_len > 0) { ++ pxmitframe->attrib.mdata = 1; ++ pxmitframe->attrib.eosp = 0; ++ } else { ++ pxmitframe->attrib.mdata = 0; ++ pxmitframe->attrib.eosp = 1; ++ } ++ ++ pxmitframe->attrib.triggered = 1; ++ ++ if (rtw_hal_xmit(padapter, pxmitframe)) ++ rtw_os_xmit_complete(padapter, pxmitframe); ++ ++ if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) && (wmmps_ac)) { ++ pstapriv->tim_bitmap &= ~BIT(psta->aid); ++ ++ /* upate BCN for TIM IE */ ++ update_beacon(padapter, _TIM_IE_, NULL, false); ++ } ++ } ++ ++ spin_unlock_bh(&psta->sleep_q.lock); ++} ++ ++#endif ++ ++void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms) ++{ ++ sctx->timeout_ms = timeout_ms; ++ sctx->submit_time = jiffies; ++ init_completion(&sctx->done); ++ sctx->status = RTW_SCTX_SUBMITTED; ++} ++ ++int rtw_sctx_wait(struct submit_ctx *sctx) ++{ ++ int ret = _FAIL; ++ unsigned long expire; ++ int status = 0; ++ ++ expire = sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) : MAX_SCHEDULE_TIMEOUT; ++ if (!wait_for_completion_timeout(&sctx->done, expire)) { ++ /* timeout, do something?? */ ++ status = RTW_SCTX_DONE_TIMEOUT; ++ DBG_88E("%s timeout\n", __func__); ++ } else { ++ status = sctx->status; ++ } ++ ++ if (status == RTW_SCTX_DONE_SUCCESS) ++ ret = _SUCCESS; ++ ++ return ret; ++} ++ ++static bool rtw_sctx_chk_waring_status(int status) ++{ ++ switch (status) { ++ case RTW_SCTX_DONE_UNKNOWN: ++ case RTW_SCTX_DONE_BUF_ALLOC: ++ case RTW_SCTX_DONE_BUF_FREE: ++ ++ case RTW_SCTX_DONE_DRV_STOP: ++ case RTW_SCTX_DONE_DEV_REMOVE: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++void rtw_sctx_done_err(struct submit_ctx **sctx, int status) ++{ ++ if (*sctx) { ++ if (rtw_sctx_chk_waring_status(status)) ++ DBG_88E("%s status:%d\n", __func__, status); ++ (*sctx)->status = status; ++ complete(&((*sctx)->done)); ++ *sctx = NULL; ++ } ++} ++ ++void rtw_sctx_done(struct submit_ctx **sctx) ++{ ++ rtw_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS); ++} ++ ++int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms) ++{ ++ struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops; ++ ++ pack_tx_ops->submit_time = jiffies; ++ pack_tx_ops->timeout_ms = timeout_ms; ++ pack_tx_ops->status = RTW_SCTX_SUBMITTED; ++ ++ return rtw_sctx_wait(pack_tx_ops); ++} ++ ++void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status) ++{ ++ struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops; ++ ++ if (pxmitpriv->ack_tx) ++ rtw_sctx_done_err(&pack_tx_ops, status); ++ else ++ DBG_88E("%s ack_tx not set\n", __func__); ++} +diff --git a/drivers/staging/r8188eu/hal/Hal8188EPwrSeq.c b/drivers/staging/r8188eu/hal/Hal8188EPwrSeq.c +new file mode 100644 +index 000000000000..48ede610cd28 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/Hal8188EPwrSeq.c +@@ -0,0 +1,69 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/Hal8188EPwrSeq.h" ++#include "../include/rtl8188e_hal.h" ++ ++/* ++ drivers should parse below arrays and do the corresponding actions ++*/ ++/* 3 Power on Array */ ++struct wl_pwr_cfg rtl8188E_power_on_flow[RTL8188E_TRANS_CARDEMU_TO_ACT_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ RTL8188E_TRANS_CARDEMU_TO_ACT ++ RTL8188E_TRANS_END ++}; ++ ++/* 3Radio off Array */ ++struct wl_pwr_cfg rtl8188E_radio_off_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ RTL8188E_TRANS_ACT_TO_CARDEMU ++ RTL8188E_TRANS_END ++}; ++ ++/* 3Card Disable Array */ ++struct wl_pwr_cfg rtl8188E_card_disable_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ RTL8188E_TRANS_ACT_TO_CARDEMU ++ RTL8188E_TRANS_CARDEMU_TO_CARDDIS ++ RTL8188E_TRANS_END ++}; ++ ++/* 3 Card Enable Array */ ++struct wl_pwr_cfg rtl8188E_card_enable_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ RTL8188E_TRANS_CARDDIS_TO_CARDEMU ++ RTL8188E_TRANS_CARDEMU_TO_ACT ++ RTL8188E_TRANS_END ++}; ++ ++/* 3Suspend Array */ ++struct wl_pwr_cfg rtl8188E_suspend_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ RTL8188E_TRANS_ACT_TO_CARDEMU ++ RTL8188E_TRANS_CARDEMU_TO_SUS ++ RTL8188E_TRANS_END ++}; ++ ++/* 3 Resume Array */ ++struct wl_pwr_cfg rtl8188E_resume_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ RTL8188E_TRANS_SUS_TO_CARDEMU ++ RTL8188E_TRANS_CARDEMU_TO_ACT ++ RTL8188E_TRANS_END ++}; ++ ++/* 3HWPDN Array */ ++struct wl_pwr_cfg rtl8188E_hwpdn_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ RTL8188E_TRANS_ACT_TO_CARDEMU ++ RTL8188E_TRANS_CARDEMU_TO_PDN ++ RTL8188E_TRANS_END ++}; ++ ++/* 3 Enter LPS */ ++struct wl_pwr_cfg rtl8188E_enter_lps_flow[RTL8188E_TRANS_ACT_TO_LPS_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ /* FW behavior */ ++ RTL8188E_TRANS_ACT_TO_LPS ++ RTL8188E_TRANS_END ++}; ++ ++/* 3 Leave LPS */ ++struct wl_pwr_cfg rtl8188E_leave_lps_flow[RTL8188E_TRANS_LPS_TO_ACT_STEPS + RTL8188E_TRANS_END_STEPS] = { ++ /* FW behavior */ ++ RTL8188E_TRANS_LPS_TO_ACT ++ RTL8188E_TRANS_END ++}; +diff --git a/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c +new file mode 100644 +index 000000000000..d873672feb27 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c +@@ -0,0 +1,664 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright (c) Realtek Semiconductor Corp. ++Module Name: ++ RateAdaptive.c ++ ++Abstract: ++ Implement Rate Adaptive functions for common operations. ++ ++Major Change History: ++ When Who What ++ ---------- --------------- ------------------------------- ++ 2011-08-12 Page Create. ++ ++--*/ ++#include "../include/odm_precomp.h" ++ ++/* Rate adaptive parameters */ ++ ++static u8 RETRY_PENALTY[PERENTRY][RETRYSIZE + 1] = { ++ {5, 4, 3, 2, 0, 3}, /* 92 , idx = 0 */ ++ {6, 5, 4, 3, 0, 4}, /* 86 , idx = 1 */ ++ {6, 5, 4, 2, 0, 4}, /* 81 , idx = 2 */ ++ {8, 7, 6, 4, 0, 6}, /* 75 , idx = 3 */ ++ {10, 9, 8, 6, 0, 8}, /* 71 , idx = 4 */ ++ {10, 9, 8, 4, 0, 8}, /* 66 , idx = 5 */ ++ {10, 9, 8, 2, 0, 8}, /* 62 , idx = 6 */ ++ {10, 9, 8, 0, 0, 8}, /* 59 , idx = 7 */ ++ {18, 17, 16, 8, 0, 16}, /* 53 , idx = 8 */ ++ {26, 25, 24, 16, 0, 24}, /* 50 , idx = 9 */ ++ {34, 33, 32, 24, 0, 32}, /* 47 , idx = 0x0a */ ++ {34, 31, 28, 20, 0, 32}, /* 43 , idx = 0x0b */ ++ {34, 31, 27, 18, 0, 32}, /* 40 , idx = 0x0c */ ++ {34, 31, 26, 16, 0, 32}, /* 37 , idx = 0x0d */ ++ {34, 30, 22, 16, 0, 32}, /* 32 , idx = 0x0e */ ++ {34, 30, 24, 16, 0, 32}, /* 26 , idx = 0x0f */ ++ {49, 46, 40, 16, 0, 48}, /* 20 , idx = 0x10 */ ++ {49, 45, 32, 0, 0, 48}, /* 17 , idx = 0x11 */ ++ {49, 45, 22, 18, 0, 48}, /* 15 , idx = 0x12 */ ++ {49, 40, 24, 16, 0, 48}, /* 12 , idx = 0x13 */ ++ {49, 32, 18, 12, 0, 48}, /* 9 , idx = 0x14 */ ++ {49, 22, 18, 14, 0, 48}, /* 6 , idx = 0x15 */ ++ {49, 16, 16, 0, 0, 48} ++ }; /* 3, idx = 0x16 */ ++ ++static u8 PT_PENALTY[RETRYSIZE + 1] = {34, 31, 30, 24, 0, 32}; ++ ++/* wilson modify */ ++static u8 RETRY_PENALTY_IDX[2][RATESIZE] = { ++ {4, 4, 4, 5, 4, 4, 5, 7, 7, 7, 8, 0x0a, /* SS>TH */ ++ 4, 4, 4, 4, 6, 0x0a, 0x0b, 0x0d, ++ 5, 5, 7, 7, 8, 0x0b, 0x0d, 0x0f}, /* 0329 R01 */ ++ {0x0a, 0x0a, 0x0b, 0x0c, 0x0a, ++ 0x0a, 0x0b, 0x0c, 0x0d, 0x10, 0x13, 0x14, /* SSTH */ ++ 0x0f, 0x10, 0x10, 0x12, 0x12, 0x13, 0x14, 0x15, ++ 0x11, 0x11, 0x12, 0x13, 0x13, 0x13, 0x14, 0x15}; ++ ++static u8 RSSI_THRESHOLD[RATESIZE] = { ++ 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0x24, 0x26, 0x2a, ++ 0x18, 0x1a, 0x1d, 0x1f, 0x21, 0x27, 0x29, 0x2a, ++ 0, 0, 0, 0x1f, 0x23, 0x28, 0x2a, 0x2c}; ++ ++static u16 N_THRESHOLD_HIGH[RATESIZE] = { ++ 4, 4, 8, 16, ++ 24, 36, 48, 72, 96, 144, 192, 216, ++ 60, 80, 100, 160, 240, 400, 560, 640, ++ 300, 320, 480, 720, 1000, 1200, 1600, 2000}; ++static u16 N_THRESHOLD_LOW[RATESIZE] = { ++ 2, 2, 4, 8, ++ 12, 18, 24, 36, 48, 72, 96, 108, ++ 30, 40, 50, 80, 120, 200, 280, 320, ++ 150, 160, 240, 360, 500, 600, 800, 1000}; ++ ++static u8 DROPING_NECESSARY[RATESIZE] = { ++ 1, 1, 1, 1, ++ 1, 2, 3, 4, 5, 6, 7, 8, ++ 1, 2, 3, 4, 5, 6, 7, 8, ++ 5, 6, 7, 8, 9, 10, 11, 12}; ++ ++static u8 PendingForRateUpFail[5] = {2, 10, 24, 40, 60}; ++static u16 DynamicTxRPTTiming[6] = { ++ 0x186a, 0x30d4, 0x493e, 0x61a8, 0x7a12, 0x927c}; /* 200ms-1200ms */ ++ ++/* End Rate adaptive parameters */ ++ ++static void odm_SetTxRPTTiming_8188E( ++ struct odm_dm_struct *dm_odm, ++ struct odm_ra_info *pRaInfo, ++ u8 extend ++ ) ++{ ++ u8 idx = 0; ++ ++ for (idx = 0; idx < 5; idx++) ++ if (DynamicTxRPTTiming[idx] == pRaInfo->RptTime) ++ break; ++ ++ if (extend == 0) { /* back to default timing */ ++ idx = 0; /* 200ms */ ++ } else if (extend == 1) {/* increase the timing */ ++ idx += 1; ++ if (idx > 5) ++ idx = 5; ++ } else if (extend == 2) {/* decrease the timing */ ++ if (idx != 0) ++ idx -= 1; ++ } ++ pRaInfo->RptTime = DynamicTxRPTTiming[idx]; ++} ++ ++static int odm_RateDown_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_info *pRaInfo) ++{ ++ u8 RateID, LowestRate, HighestRate; ++ u8 i; ++ ++ if (NULL == pRaInfo) ++ return -1; ++ RateID = pRaInfo->PreRate; ++ LowestRate = pRaInfo->LowestRate; ++ HighestRate = pRaInfo->HighestRate; ++ ++ if (RateID > HighestRate) { ++ RateID = HighestRate; ++ } else if (pRaInfo->RateSGI) { ++ pRaInfo->RateSGI = 0; ++ } else if (RateID > LowestRate) { ++ if (RateID > 0) { ++ for (i = RateID - 1; i > LowestRate; i--) { ++ if (pRaInfo->RAUseRate & BIT(i)) { ++ RateID = i; ++ goto RateDownFinish; ++ } ++ } ++ } ++ } else if (RateID <= LowestRate) { ++ RateID = LowestRate; ++ } ++RateDownFinish: ++ if (pRaInfo->RAWaitingCounter == 1) { ++ pRaInfo->RAWaitingCounter += 1; ++ pRaInfo->RAPendingCounter += 1; ++ } else if (pRaInfo->RAWaitingCounter == 0) { ++ ; ++ } else { ++ pRaInfo->RAWaitingCounter = 0; ++ pRaInfo->RAPendingCounter = 0; ++ } ++ ++ if (pRaInfo->RAPendingCounter >= 4) ++ pRaInfo->RAPendingCounter = 4; ++ ++ pRaInfo->DecisionRate = RateID; ++ odm_SetTxRPTTiming_8188E(dm_odm, pRaInfo, 2); ++ return 0; ++} ++ ++static int odm_RateUp_8188E( ++ struct odm_dm_struct *dm_odm, ++ struct odm_ra_info *pRaInfo ++ ) ++{ ++ u8 RateID, HighestRate; ++ u8 i; ++ ++ if (NULL == pRaInfo) ++ return -1; ++ RateID = pRaInfo->PreRate; ++ HighestRate = pRaInfo->HighestRate; ++ if (pRaInfo->RAWaitingCounter == 1) { ++ pRaInfo->RAWaitingCounter = 0; ++ pRaInfo->RAPendingCounter = 0; ++ } else if (pRaInfo->RAWaitingCounter > 1) { ++ pRaInfo->PreRssiStaRA = pRaInfo->RssiStaRA; ++ goto RateUpfinish; ++ } ++ odm_SetTxRPTTiming_8188E(dm_odm, pRaInfo, 0); ++ ++ if (RateID < HighestRate) { ++ for (i = RateID + 1; i <= HighestRate; i++) { ++ if (pRaInfo->RAUseRate & BIT(i)) { ++ RateID = i; ++ goto RateUpfinish; ++ } ++ } ++ } else if (RateID == HighestRate) { ++ if (pRaInfo->SGIEnable && (pRaInfo->RateSGI != 1)) ++ pRaInfo->RateSGI = 1; ++ else if ((pRaInfo->SGIEnable) != 1) ++ pRaInfo->RateSGI = 0; ++ } else { ++ RateID = HighestRate; ++ } ++RateUpfinish: ++ if (pRaInfo->RAWaitingCounter == (4 + PendingForRateUpFail[pRaInfo->RAPendingCounter])) ++ pRaInfo->RAWaitingCounter = 0; ++ else ++ pRaInfo->RAWaitingCounter++; ++ ++ pRaInfo->DecisionRate = RateID; ++ return 0; ++} ++ ++static void odm_ResetRaCounter_8188E(struct odm_ra_info *pRaInfo) ++{ ++ u8 RateID; ++ ++ RateID = pRaInfo->DecisionRate; ++ pRaInfo->NscUp = (N_THRESHOLD_HIGH[RateID] + N_THRESHOLD_LOW[RateID]) >> 1; ++ pRaInfo->NscDown = (N_THRESHOLD_HIGH[RateID] + N_THRESHOLD_LOW[RateID]) >> 1; ++} ++ ++static void odm_RateDecision_8188E(struct odm_dm_struct *dm_odm, ++ struct odm_ra_info *pRaInfo ++ ) ++{ ++ u8 RateID = 0, RtyPtID = 0, PenaltyID1 = 0, PenaltyID2 = 0; ++ /* u32 pool_retry; */ ++ static u8 DynamicTxRPTTimingCounter; ++ ++ if (pRaInfo->Active && (pRaInfo->TOTAL > 0)) { /* STA used and data packet exits */ ++ if ((pRaInfo->RssiStaRA < (pRaInfo->PreRssiStaRA - 3)) || ++ (pRaInfo->RssiStaRA > (pRaInfo->PreRssiStaRA + 3))) { ++ pRaInfo->RAWaitingCounter = 0; ++ pRaInfo->RAPendingCounter = 0; ++ } ++ /* Start RA decision */ ++ if (pRaInfo->PreRate > pRaInfo->HighestRate) ++ RateID = pRaInfo->HighestRate; ++ else ++ RateID = pRaInfo->PreRate; ++ if (pRaInfo->RssiStaRA > RSSI_THRESHOLD[RateID]) ++ RtyPtID = 0; ++ else ++ RtyPtID = 1; ++ PenaltyID1 = RETRY_PENALTY_IDX[RtyPtID][RateID]; /* TODO by page */ ++ ++ pRaInfo->NscDown += pRaInfo->RTY[0] * RETRY_PENALTY[PenaltyID1][0]; ++ pRaInfo->NscDown += pRaInfo->RTY[1] * RETRY_PENALTY[PenaltyID1][1]; ++ pRaInfo->NscDown += pRaInfo->RTY[2] * RETRY_PENALTY[PenaltyID1][2]; ++ pRaInfo->NscDown += pRaInfo->RTY[3] * RETRY_PENALTY[PenaltyID1][3]; ++ pRaInfo->NscDown += pRaInfo->RTY[4] * RETRY_PENALTY[PenaltyID1][4]; ++ if (pRaInfo->NscDown > (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5])) ++ pRaInfo->NscDown -= pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5]; ++ else ++ pRaInfo->NscDown = 0; ++ ++ /* rate up */ ++ PenaltyID2 = RETRY_PENALTY_UP_IDX[RateID]; ++ pRaInfo->NscUp += pRaInfo->RTY[0] * RETRY_PENALTY[PenaltyID2][0]; ++ pRaInfo->NscUp += pRaInfo->RTY[1] * RETRY_PENALTY[PenaltyID2][1]; ++ pRaInfo->NscUp += pRaInfo->RTY[2] * RETRY_PENALTY[PenaltyID2][2]; ++ pRaInfo->NscUp += pRaInfo->RTY[3] * RETRY_PENALTY[PenaltyID2][3]; ++ pRaInfo->NscUp += pRaInfo->RTY[4] * RETRY_PENALTY[PenaltyID2][4]; ++ if (pRaInfo->NscUp > (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID2][5])) ++ pRaInfo->NscUp -= pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID2][5]; ++ else ++ pRaInfo->NscUp = 0; ++ ++ if ((pRaInfo->NscDown < N_THRESHOLD_LOW[RateID]) || ++ (pRaInfo->DROP > DROPING_NECESSARY[RateID])) ++ odm_RateDown_8188E(dm_odm, pRaInfo); ++ else if (pRaInfo->NscUp > N_THRESHOLD_HIGH[RateID]) ++ odm_RateUp_8188E(dm_odm, pRaInfo); ++ ++ if (pRaInfo->DecisionRate > pRaInfo->HighestRate) ++ pRaInfo->DecisionRate = pRaInfo->HighestRate; ++ ++ if ((pRaInfo->DecisionRate) == (pRaInfo->PreRate)) ++ DynamicTxRPTTimingCounter += 1; ++ else ++ DynamicTxRPTTimingCounter = 0; ++ ++ if (DynamicTxRPTTimingCounter >= 4) { ++ odm_SetTxRPTTiming_8188E(dm_odm, pRaInfo, 1); ++ DynamicTxRPTTimingCounter = 0; ++ } ++ ++ pRaInfo->PreRate = pRaInfo->DecisionRate; /* YJ, add, 120120 */ ++ ++ odm_ResetRaCounter_8188E(pRaInfo); ++ } ++} ++ ++static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_info *pRaInfo) ++{ /* Wilson 2011/10/26 */ ++ u32 MaskFromReg; ++ s8 i; ++ ++ switch (pRaInfo->RateID) { ++ case RATR_INX_WIRELESS_NGB: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0f8ff015; ++ break; ++ case RATR_INX_WIRELESS_NG: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0f8ff010; ++ break; ++ case RATR_INX_WIRELESS_NB: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0f8ff005; ++ break; ++ case RATR_INX_WIRELESS_N: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0f8ff000; ++ break; ++ case RATR_INX_WIRELESS_GB: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x00000ff5; ++ break; ++ case RATR_INX_WIRELESS_G: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x00000ff0; ++ break; ++ case RATR_INX_WIRELESS_B: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0000000d; ++ break; ++ case 12: ++ MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR0); ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg; ++ break; ++ case 13: ++ MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR1); ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg; ++ break; ++ case 14: ++ MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR2); ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg; ++ break; ++ case 15: ++ MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR3); ++ pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg; ++ break; ++ default: ++ pRaInfo->RAUseRate = (pRaInfo->RateMask); ++ break; ++ } ++ /* Highest rate */ ++ if (pRaInfo->RAUseRate) { ++ for (i = RATESIZE; i >= 0; i--) { ++ if ((pRaInfo->RAUseRate) & BIT(i)) { ++ pRaInfo->HighestRate = i; ++ break; ++ } ++ } ++ } else { ++ pRaInfo->HighestRate = 0; ++ } ++ /* Lowest rate */ ++ if (pRaInfo->RAUseRate) { ++ for (i = 0; i < RATESIZE; i++) { ++ if ((pRaInfo->RAUseRate) & BIT(i)) { ++ pRaInfo->LowestRate = i; ++ break; ++ } ++ } ++ } else { ++ pRaInfo->LowestRate = 0; ++ } ++ if (pRaInfo->HighestRate > 0x13) ++ pRaInfo->PTModeSS = 3; ++ else if (pRaInfo->HighestRate > 0x0b) ++ pRaInfo->PTModeSS = 2; ++ else if (pRaInfo->HighestRate > 0x03) ++ pRaInfo->PTModeSS = 1; ++ else ++ pRaInfo->PTModeSS = 0; ++ ++ if (pRaInfo->DecisionRate > pRaInfo->HighestRate) ++ pRaInfo->DecisionRate = pRaInfo->HighestRate; ++ ++ return 0; ++} ++ ++static void odm_PTTryState_8188E(struct odm_ra_info *pRaInfo) ++{ ++ pRaInfo->PTTryState = 0; ++ switch (pRaInfo->PTModeSS) { ++ case 3: ++ if (pRaInfo->DecisionRate >= 0x19) ++ pRaInfo->PTTryState = 1; ++ break; ++ case 2: ++ if (pRaInfo->DecisionRate >= 0x11) ++ pRaInfo->PTTryState = 1; ++ break; ++ case 1: ++ if (pRaInfo->DecisionRate >= 0x0a) ++ pRaInfo->PTTryState = 1; ++ break; ++ case 0: ++ if (pRaInfo->DecisionRate >= 0x03) ++ pRaInfo->PTTryState = 1; ++ break; ++ default: ++ pRaInfo->PTTryState = 0; ++ break; ++ } ++ ++ if (pRaInfo->RssiStaRA < 48) { ++ pRaInfo->PTStage = 0; ++ } else if (pRaInfo->PTTryState == 1) { ++ if ((pRaInfo->PTStopCount >= 10) || ++ (pRaInfo->PTPreRssi > pRaInfo->RssiStaRA + 5) || ++ (pRaInfo->PTPreRssi < pRaInfo->RssiStaRA - 5) || ++ (pRaInfo->DecisionRate != pRaInfo->PTPreRate)) { ++ if (pRaInfo->PTStage == 0) ++ pRaInfo->PTStage = 1; ++ else if (pRaInfo->PTStage == 1) ++ pRaInfo->PTStage = 3; ++ else ++ pRaInfo->PTStage = 5; ++ ++ pRaInfo->PTPreRssi = pRaInfo->RssiStaRA; ++ pRaInfo->PTStopCount = 0; ++ } else { ++ pRaInfo->RAstage = 0; ++ pRaInfo->PTStopCount++; ++ } ++ } else { ++ pRaInfo->PTStage = 0; ++ pRaInfo->RAstage = 0; ++ } ++ pRaInfo->PTPreRate = pRaInfo->DecisionRate; ++} ++ ++static void odm_PTDecision_8188E(struct odm_ra_info *pRaInfo) ++{ ++ u8 j; ++ u8 temp_stage; ++ u32 numsc; ++ u32 num_total; ++ u8 stage_id; ++ ++ numsc = 0; ++ num_total = pRaInfo->TOTAL * PT_PENALTY[5]; ++ for (j = 0; j <= 4; j++) { ++ numsc += pRaInfo->RTY[j] * PT_PENALTY[j]; ++ if (numsc > num_total) ++ break; ++ } ++ ++ j = j >> 1; ++ temp_stage = (pRaInfo->PTStage + 1) >> 1; ++ if (temp_stage > j) ++ stage_id = temp_stage - j; ++ else ++ stage_id = 0; ++ ++ pRaInfo->PTSmoothFactor = (pRaInfo->PTSmoothFactor >> 1) + (pRaInfo->PTSmoothFactor >> 2) + stage_id * 16 + 2; ++ if (pRaInfo->PTSmoothFactor > 192) ++ pRaInfo->PTSmoothFactor = 192; ++ stage_id = pRaInfo->PTSmoothFactor >> 6; ++ temp_stage = stage_id * 2; ++ if (temp_stage != 0) ++ temp_stage -= 1; ++ if (pRaInfo->DROP > 3) ++ temp_stage = 0; ++ pRaInfo->PTStage = temp_stage; ++} ++ ++static void ++odm_RATxRPTTimerSetting( ++ struct odm_dm_struct *dm_odm, ++ u16 minRptTime ++) ++{ ++ if (dm_odm->CurrminRptTime != minRptTime) { ++ rtw_rpt_timer_cfg_cmd(dm_odm->Adapter, minRptTime); ++ dm_odm->CurrminRptTime = minRptTime; ++ } ++} ++ ++void ++ODM_RASupport_Init( ++ struct odm_dm_struct *dm_odm ++ ) ++{ ++ /* 2012/02/14 MH Be noticed, the init must be after IC type is recognized!!!!! */ ++ if (dm_odm->SupportICType == ODM_RTL8188E) ++ dm_odm->RaSupport88E = true; ++} ++ ++int ODM_RAInfo_Init(struct odm_dm_struct *dm_odm, u8 macid) ++{ ++ struct odm_ra_info *pRaInfo = &dm_odm->RAInfo[macid]; ++ u8 WirelessMode = 0xFF; /* invalid value */ ++ u8 max_rate_idx = 0x13; /* MCS7 */ ++ if (dm_odm->pWirelessMode) ++ WirelessMode = *dm_odm->pWirelessMode; ++ ++ if (WirelessMode != 0xFF) { ++ if (WirelessMode & ODM_WM_N24G) ++ max_rate_idx = 0x13; ++ else if (WirelessMode & ODM_WM_G) ++ max_rate_idx = 0x0b; ++ else if (WirelessMode & ODM_WM_B) ++ max_rate_idx = 0x03; ++ } ++ ++ pRaInfo->DecisionRate = max_rate_idx; ++ pRaInfo->PreRate = max_rate_idx; ++ pRaInfo->HighestRate = max_rate_idx; ++ pRaInfo->LowestRate = 0; ++ pRaInfo->RateID = 0; ++ pRaInfo->RateMask = 0xffffffff; ++ pRaInfo->RssiStaRA = 0; ++ pRaInfo->PreRssiStaRA = 0; ++ pRaInfo->SGIEnable = 0; ++ pRaInfo->RAUseRate = 0xffffffff; ++ pRaInfo->NscDown = (N_THRESHOLD_HIGH[0x13] + N_THRESHOLD_LOW[0x13]) / 2; ++ pRaInfo->NscUp = (N_THRESHOLD_HIGH[0x13] + N_THRESHOLD_LOW[0x13]) / 2; ++ pRaInfo->RateSGI = 0; ++ pRaInfo->Active = 1; /* Active is not used at present. by page, 110819 */ ++ pRaInfo->RptTime = 0x927c; ++ pRaInfo->DROP = 0; ++ pRaInfo->RTY[0] = 0; ++ pRaInfo->RTY[1] = 0; ++ pRaInfo->RTY[2] = 0; ++ pRaInfo->RTY[3] = 0; ++ pRaInfo->RTY[4] = 0; ++ pRaInfo->TOTAL = 0; ++ pRaInfo->RAWaitingCounter = 0; ++ pRaInfo->RAPendingCounter = 0; ++ pRaInfo->PTActive = 1; /* Active when this STA is use */ ++ pRaInfo->PTTryState = 0; ++ pRaInfo->PTStage = 5; /* Need to fill into HW_PWR_STATUS */ ++ pRaInfo->PTSmoothFactor = 192; ++ pRaInfo->PTStopCount = 0; ++ pRaInfo->PTPreRate = 0; ++ pRaInfo->PTPreRssi = 0; ++ pRaInfo->PTModeSS = 0; ++ pRaInfo->RAstage = 0; ++ return 0; ++} ++ ++int ODM_RAInfo_Init_all(struct odm_dm_struct *dm_odm) ++{ ++ u8 macid = 0; ++ ++ dm_odm->CurrminRptTime = 0; ++ ++ for (macid = 0; macid < ODM_ASSOCIATE_ENTRY_NUM; macid++) ++ ODM_RAInfo_Init(dm_odm, macid); ++ ++ return 0; ++} ++ ++u8 ODM_RA_GetShortGI_8188E(struct odm_dm_struct *dm_odm, u8 macid) ++{ ++ if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) ++ return 0; ++ return dm_odm->RAInfo[macid].RateSGI; ++} ++ ++u8 ODM_RA_GetDecisionRate_8188E(struct odm_dm_struct *dm_odm, u8 macid) ++{ ++ u8 DecisionRate = 0; ++ ++ if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) ++ return 0; ++ DecisionRate = (dm_odm->RAInfo[macid].DecisionRate); ++ return DecisionRate; ++} ++ ++u8 ODM_RA_GetHwPwrStatus_8188E(struct odm_dm_struct *dm_odm, u8 macid) ++{ ++ u8 PTStage = 5; ++ ++ if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) ++ return 0; ++ PTStage = (dm_odm->RAInfo[macid].PTStage); ++ return PTStage; ++} ++ ++void ODM_RA_UpdateRateInfo_8188E(struct odm_dm_struct *dm_odm, u8 macid, u8 RateID, u32 RateMask, u8 SGIEnable) ++{ ++ struct odm_ra_info *pRaInfo = NULL; ++ ++ if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) ++ return; ++ ++ pRaInfo = &dm_odm->RAInfo[macid]; ++ pRaInfo->RateID = RateID; ++ pRaInfo->RateMask = RateMask; ++ pRaInfo->SGIEnable = SGIEnable; ++ odm_ARFBRefresh_8188E(dm_odm, pRaInfo); ++} ++ ++void ODM_RA_SetRSSI_8188E(struct odm_dm_struct *dm_odm, u8 macid, u8 Rssi) ++{ ++ struct odm_ra_info *pRaInfo = NULL; ++ ++ if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) ++ return; ++ ++ pRaInfo = &dm_odm->RAInfo[macid]; ++ pRaInfo->RssiStaRA = Rssi; ++} ++ ++void ODM_RA_Set_TxRPT_Time(struct odm_dm_struct *dm_odm, u16 minRptTime) ++{ ++ ODM_Write2Byte(dm_odm, REG_TX_RPT_TIME, minRptTime); ++} ++ ++void ODM_RA_TxRPT2Handle_8188E(struct odm_dm_struct *dm_odm, u8 *TxRPT_Buf, u16 TxRPT_Len, u32 macid_entry0, u32 macid_entry1) ++{ ++ struct odm_ra_info *pRAInfo = NULL; ++ u8 MacId = 0; ++ u8 *pBuffer = NULL; ++ u32 valid = 0, ItemNum = 0; ++ u16 minRptTime = 0x927c; ++ ++ ItemNum = TxRPT_Len >> 3; ++ pBuffer = TxRPT_Buf; ++ ++ do { ++ if (MacId >= ASSOCIATE_ENTRY_NUM) ++ valid = 0; ++ else if (MacId >= 32) ++ valid = (1 << (MacId - 32)) & macid_entry1; ++ else ++ valid = (1 << MacId) & macid_entry0; ++ ++ pRAInfo = &dm_odm->RAInfo[MacId]; ++ if (valid) { ++ pRAInfo->RTY[0] = (u16)GET_TX_REPORT_TYPE1_RERTY_0(pBuffer); ++ pRAInfo->RTY[1] = (u16)GET_TX_REPORT_TYPE1_RERTY_1(pBuffer); ++ pRAInfo->RTY[2] = (u16)GET_TX_REPORT_TYPE1_RERTY_2((u8 *)pBuffer); ++ pRAInfo->RTY[3] = (u16)GET_TX_REPORT_TYPE1_RERTY_3(pBuffer); ++ pRAInfo->RTY[4] = (u16)GET_TX_REPORT_TYPE1_RERTY_4(pBuffer); ++ pRAInfo->DROP = (u16)GET_TX_REPORT_TYPE1_DROP_0(pBuffer); ++ pRAInfo->TOTAL = pRAInfo->RTY[0] + pRAInfo->RTY[1] + ++ pRAInfo->RTY[2] + pRAInfo->RTY[3] + ++ pRAInfo->RTY[4] + pRAInfo->DROP; ++ if (pRAInfo->TOTAL != 0) { ++ if (pRAInfo->PTActive) { ++ if (pRAInfo->RAstage < 5) ++ odm_RateDecision_8188E(dm_odm, pRAInfo); ++ else if (pRAInfo->RAstage == 5) /* Power training try state */ ++ odm_PTTryState_8188E(pRAInfo); ++ else /* RAstage == 6 */ ++ odm_PTDecision_8188E(pRAInfo); ++ ++ /* Stage_RA counter */ ++ if (pRAInfo->RAstage <= 5) ++ pRAInfo->RAstage++; ++ else ++ pRAInfo->RAstage = 0; ++ } else { ++ odm_RateDecision_8188E(dm_odm, pRAInfo); ++ } ++ } ++ } ++ ++ if (minRptTime > pRAInfo->RptTime) ++ minRptTime = pRAInfo->RptTime; ++ ++ pBuffer += TX_RPT2_ITEM_SIZE; ++ MacId++; ++ } while (MacId < ItemNum); ++ ++ odm_RATxRPTTimerSetting(dm_odm, minRptTime); ++} +diff --git a/drivers/staging/r8188eu/hal/HalHWImg8188E_BB.c b/drivers/staging/r8188eu/hal/HalHWImg8188E_BB.c +new file mode 100644 +index 000000000000..55aa20a30342 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/HalHWImg8188E_BB.c +@@ -0,0 +1,702 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++#include "../include/rtw_iol.h" ++ ++#define read_next_pair(array, v1, v2, i) \ ++ do { \ ++ i += 2; \ ++ v1 = array[i]; \ ++ v2 = array[i + 1]; \ ++ } while (0) ++ ++static bool CheckCondition(const u32 condition, const u32 hex) ++{ ++ u32 _board = (hex & 0x000000FF); ++ u32 _interface = (hex & 0x0000FF00) >> 8; ++ u32 _platform = (hex & 0x00FF0000) >> 16; ++ u32 cond = condition; ++ ++ if (condition == 0xCDCDCDCD) ++ return true; ++ ++ cond = condition & 0x000000FF; ++ if ((_board == cond) && cond != 0x00) ++ return false; ++ ++ cond = condition & 0x0000FF00; ++ cond = cond >> 8; ++ if ((_interface & cond) == 0 && cond != 0x07) ++ return false; ++ ++ cond = condition & 0x00FF0000; ++ cond = cond >> 16; ++ if ((_platform & cond) == 0 && cond != 0x0F) ++ return false; ++ return true; ++} ++ ++/****************************************************************************** ++* AGC_TAB_1T.TXT ++******************************************************************************/ ++ ++static u32 array_agc_tab_1t_8188e[] = { ++ 0xC78, 0xFB000001, ++ 0xC78, 0xFB010001, ++ 0xC78, 0xFB020001, ++ 0xC78, 0xFB030001, ++ 0xC78, 0xFB040001, ++ 0xC78, 0xFB050001, ++ 0xC78, 0xFA060001, ++ 0xC78, 0xF9070001, ++ 0xC78, 0xF8080001, ++ 0xC78, 0xF7090001, ++ 0xC78, 0xF60A0001, ++ 0xC78, 0xF50B0001, ++ 0xC78, 0xF40C0001, ++ 0xC78, 0xF30D0001, ++ 0xC78, 0xF20E0001, ++ 0xC78, 0xF10F0001, ++ 0xC78, 0xF0100001, ++ 0xC78, 0xEF110001, ++ 0xC78, 0xEE120001, ++ 0xC78, 0xED130001, ++ 0xC78, 0xEC140001, ++ 0xC78, 0xEB150001, ++ 0xC78, 0xEA160001, ++ 0xC78, 0xE9170001, ++ 0xC78, 0xE8180001, ++ 0xC78, 0xE7190001, ++ 0xC78, 0xE61A0001, ++ 0xC78, 0xE51B0001, ++ 0xC78, 0xE41C0001, ++ 0xC78, 0xE31D0001, ++ 0xC78, 0xE21E0001, ++ 0xC78, 0xE11F0001, ++ 0xC78, 0x8A200001, ++ 0xC78, 0x89210001, ++ 0xC78, 0x88220001, ++ 0xC78, 0x87230001, ++ 0xC78, 0x86240001, ++ 0xC78, 0x85250001, ++ 0xC78, 0x84260001, ++ 0xC78, 0x83270001, ++ 0xC78, 0x82280001, ++ 0xC78, 0x6B290001, ++ 0xC78, 0x6A2A0001, ++ 0xC78, 0x692B0001, ++ 0xC78, 0x682C0001, ++ 0xC78, 0x672D0001, ++ 0xC78, 0x662E0001, ++ 0xC78, 0x652F0001, ++ 0xC78, 0x64300001, ++ 0xC78, 0x63310001, ++ 0xC78, 0x62320001, ++ 0xC78, 0x61330001, ++ 0xC78, 0x46340001, ++ 0xC78, 0x45350001, ++ 0xC78, 0x44360001, ++ 0xC78, 0x43370001, ++ 0xC78, 0x42380001, ++ 0xC78, 0x41390001, ++ 0xC78, 0x403A0001, ++ 0xC78, 0x403B0001, ++ 0xC78, 0x403C0001, ++ 0xC78, 0x403D0001, ++ 0xC78, 0x403E0001, ++ 0xC78, 0x403F0001, ++ 0xC78, 0xFB400001, ++ 0xC78, 0xFB410001, ++ 0xC78, 0xFB420001, ++ 0xC78, 0xFB430001, ++ 0xC78, 0xFB440001, ++ 0xC78, 0xFB450001, ++ 0xC78, 0xFB460001, ++ 0xC78, 0xFB470001, ++ 0xC78, 0xFB480001, ++ 0xC78, 0xFA490001, ++ 0xC78, 0xF94A0001, ++ 0xC78, 0xF84B0001, ++ 0xC78, 0xF74C0001, ++ 0xC78, 0xF64D0001, ++ 0xC78, 0xF54E0001, ++ 0xC78, 0xF44F0001, ++ 0xC78, 0xF3500001, ++ 0xC78, 0xF2510001, ++ 0xC78, 0xF1520001, ++ 0xC78, 0xF0530001, ++ 0xC78, 0xEF540001, ++ 0xC78, 0xEE550001, ++ 0xC78, 0xED560001, ++ 0xC78, 0xEC570001, ++ 0xC78, 0xEB580001, ++ 0xC78, 0xEA590001, ++ 0xC78, 0xE95A0001, ++ 0xC78, 0xE85B0001, ++ 0xC78, 0xE75C0001, ++ 0xC78, 0xE65D0001, ++ 0xC78, 0xE55E0001, ++ 0xC78, 0xE45F0001, ++ 0xC78, 0xE3600001, ++ 0xC78, 0xE2610001, ++ 0xC78, 0xC3620001, ++ 0xC78, 0xC2630001, ++ 0xC78, 0xC1640001, ++ 0xC78, 0x8B650001, ++ 0xC78, 0x8A660001, ++ 0xC78, 0x89670001, ++ 0xC78, 0x88680001, ++ 0xC78, 0x87690001, ++ 0xC78, 0x866A0001, ++ 0xC78, 0x856B0001, ++ 0xC78, 0x846C0001, ++ 0xC78, 0x676D0001, ++ 0xC78, 0x666E0001, ++ 0xC78, 0x656F0001, ++ 0xC78, 0x64700001, ++ 0xC78, 0x63710001, ++ 0xC78, 0x62720001, ++ 0xC78, 0x61730001, ++ 0xC78, 0x60740001, ++ 0xC78, 0x46750001, ++ 0xC78, 0x45760001, ++ 0xC78, 0x44770001, ++ 0xC78, 0x43780001, ++ 0xC78, 0x42790001, ++ 0xC78, 0x417A0001, ++ 0xC78, 0x407B0001, ++ 0xC78, 0x407C0001, ++ 0xC78, 0x407D0001, ++ 0xC78, 0x407E0001, ++ 0xC78, 0x407F0001, ++}; ++ ++enum HAL_STATUS ODM_ReadAndConfig_AGC_TAB_1T_8188E(struct odm_dm_struct *dm_odm) ++{ ++ u32 hex = 0; ++ u32 i = 0; ++ u8 platform = dm_odm->SupportPlatform; ++ u8 interfaceValue = dm_odm->SupportInterface; ++ u8 board = dm_odm->BoardType; ++ u32 arraylen = sizeof(array_agc_tab_1t_8188e) / sizeof(u32); ++ u32 *array = array_agc_tab_1t_8188e; ++ bool biol = false; ++ struct adapter *adapter = dm_odm->Adapter; ++ struct xmit_frame *pxmit_frame = NULL; ++ u8 bndy_cnt = 1; ++ enum HAL_STATUS rst = HAL_STATUS_SUCCESS; ++ ++ hex += board; ++ hex += interfaceValue << 8; ++ hex += platform << 16; ++ hex += 0xFF000000; ++ biol = rtw_IOL_applied(adapter); ++ ++ if (biol) { ++ pxmit_frame = rtw_IOL_accquire_xmit_frame(adapter); ++ if (!pxmit_frame) { ++ pr_info("rtw_IOL_accquire_xmit_frame failed\n"); ++ return HAL_STATUS_FAILURE; ++ } ++ } ++ ++ for (i = 0; i < arraylen; i += 2) { ++ u32 v1 = array[i]; ++ u32 v2 = array[i + 1]; ++ ++ /* This (offset, data) pair meets the condition. */ ++ if (v1 < 0xCDCDCDCD) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord); ++ } else { ++ odm_ConfigBB_AGC_8188E(dm_odm, v1, bMaskDWord, v2); ++ } ++ continue; ++ } else { ++ /* This line is the start line of branch. */ ++ if (!CheckCondition(array[i], hex)) { ++ /* Discard the following (offset, data) pairs. */ ++ read_next_pair(array, v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < arraylen - 2) ++ read_next_pair(array, v1, v2, i); ++ i -= 2; /* prevent from for-loop += 2 */ ++ } else { /* Configure matched pairs and skip to end of if-else. */ ++ read_next_pair(array, v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < arraylen - 2) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord); ++ } else { ++ odm_ConfigBB_AGC_8188E(dm_odm, v1, bMaskDWord, v2); ++ } ++ read_next_pair(array, v1, v2, i); ++ } ++ ++ while (v2 != 0xDEAD && i < arraylen - 2) ++ read_next_pair(array, v1, v2, i); ++ } ++ } ++ } ++ if (biol) { ++ if (!rtw_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { ++ printk("~~~ %s IOL_exec_cmds Failed !!!\n", __func__); ++ rst = HAL_STATUS_FAILURE; ++ } ++ } ++ return rst; ++} ++ ++/****************************************************************************** ++* PHY_REG_1T.TXT ++******************************************************************************/ ++ ++static u32 array_phy_reg_1t_8188e[] = { ++ 0x800, 0x80040000, ++ 0x804, 0x00000003, ++ 0x808, 0x0000FC00, ++ 0x80C, 0x0000000A, ++ 0x810, 0x10001331, ++ 0x814, 0x020C3D10, ++ 0x818, 0x02200385, ++ 0x81C, 0x00000000, ++ 0x820, 0x01000100, ++ 0x824, 0x00390204, ++ 0x828, 0x00000000, ++ 0x82C, 0x00000000, ++ 0x830, 0x00000000, ++ 0x834, 0x00000000, ++ 0x838, 0x00000000, ++ 0x83C, 0x00000000, ++ 0x840, 0x00010000, ++ 0x844, 0x00000000, ++ 0x848, 0x00000000, ++ 0x84C, 0x00000000, ++ 0x850, 0x00000000, ++ 0x854, 0x00000000, ++ 0x858, 0x569A11A9, ++ 0x85C, 0x01000014, ++ 0x860, 0x66F60110, ++ 0x864, 0x061F0649, ++ 0x868, 0x00000000, ++ 0x86C, 0x27272700, ++ 0x870, 0x07000760, ++ 0x874, 0x25004000, ++ 0x878, 0x00000808, ++ 0x87C, 0x00000000, ++ 0x880, 0xB0000C1C, ++ 0x884, 0x00000001, ++ 0x888, 0x00000000, ++ 0x88C, 0xCCC000C0, ++ 0x890, 0x00000800, ++ 0x894, 0xFFFFFFFE, ++ 0x898, 0x40302010, ++ 0x89C, 0x00706050, ++ 0x900, 0x00000000, ++ 0x904, 0x00000023, ++ 0x908, 0x00000000, ++ 0x90C, 0x81121111, ++ 0x910, 0x00000002, ++ 0x914, 0x00000201, ++ 0xA00, 0x00D047C8, ++ 0xA04, 0x80FF000C, ++ 0xA08, 0x8C838300, ++ 0xA0C, 0x2E7F120F, ++ 0xA10, 0x9500BB78, ++ 0xA14, 0x1114D028, ++ 0xA18, 0x00881117, ++ 0xA1C, 0x89140F00, ++ 0xA20, 0x1A1B0000, ++ 0xA24, 0x090E1317, ++ 0xA28, 0x00000204, ++ 0xA2C, 0x00D30000, ++ 0xA70, 0x101FBF00, ++ 0xA74, 0x00000007, ++ 0xA78, 0x00000900, ++ 0xA7C, 0x225B0606, ++ 0xA80, 0x218075B1, ++ 0xB2C, 0x80000000, ++ 0xC00, 0x48071D40, ++ 0xC04, 0x03A05611, ++ 0xC08, 0x000000E4, ++ 0xC0C, 0x6C6C6C6C, ++ 0xC10, 0x08800000, ++ 0xC14, 0x40000100, ++ 0xC18, 0x08800000, ++ 0xC1C, 0x40000100, ++ 0xC20, 0x00000000, ++ 0xC24, 0x00000000, ++ 0xC28, 0x00000000, ++ 0xC2C, 0x00000000, ++ 0xC30, 0x69E9AC47, ++ 0xC34, 0x469652AF, ++ 0xC38, 0x49795994, ++ 0xC3C, 0x0A97971C, ++ 0xC40, 0x1F7C403F, ++ 0xC44, 0x000100B7, ++ 0xC48, 0xEC020107, ++ 0xC4C, 0x007F037F, ++ 0xC50, 0x69553420, ++ 0xC54, 0x43BC0094, ++ 0xC58, 0x00013169, ++ 0xC5C, 0x00250492, ++ 0xC60, 0x00000000, ++ 0xC64, 0x7112848B, ++ 0xC68, 0x47C00BFF, ++ 0xC6C, 0x00000036, ++ 0xC70, 0x2C7F000D, ++ 0xC74, 0x020610DB, ++ 0xC78, 0x0000001F, ++ 0xC7C, 0x00B91612, ++ 0xC80, 0x390000E4, ++ 0xC84, 0x20F60000, ++ 0xC88, 0x40000100, ++ 0xC8C, 0x20200000, ++ 0xC90, 0x00091521, ++ 0xC94, 0x00000000, ++ 0xC98, 0x00121820, ++ 0xC9C, 0x00007F7F, ++ 0xCA0, 0x00000000, ++ 0xCA4, 0x000300A0, ++ 0xCA8, 0x00000000, ++ 0xCAC, 0x00000000, ++ 0xCB0, 0x00000000, ++ 0xCB4, 0x00000000, ++ 0xCB8, 0x00000000, ++ 0xCBC, 0x28000000, ++ 0xCC0, 0x00000000, ++ 0xCC4, 0x00000000, ++ 0xCC8, 0x00000000, ++ 0xCCC, 0x00000000, ++ 0xCD0, 0x00000000, ++ 0xCD4, 0x00000000, ++ 0xCD8, 0x64B22427, ++ 0xCDC, 0x00766932, ++ 0xCE0, 0x00222222, ++ 0xCE4, 0x00000000, ++ 0xCE8, 0x37644302, ++ 0xCEC, 0x2F97D40C, ++ 0xD00, 0x00000740, ++ 0xD04, 0x00020401, ++ 0xD08, 0x0000907F, ++ 0xD0C, 0x20010201, ++ 0xD10, 0xA0633333, ++ 0xD14, 0x3333BC43, ++ 0xD18, 0x7A8F5B6F, ++ 0xD2C, 0xCC979975, ++ 0xD30, 0x00000000, ++ 0xD34, 0x80608000, ++ 0xD38, 0x00000000, ++ 0xD3C, 0x00127353, ++ 0xD40, 0x00000000, ++ 0xD44, 0x00000000, ++ 0xD48, 0x00000000, ++ 0xD4C, 0x00000000, ++ 0xD50, 0x6437140A, ++ 0xD54, 0x00000000, ++ 0xD58, 0x00000282, ++ 0xD5C, 0x30032064, ++ 0xD60, 0x4653DE68, ++ 0xD64, 0x04518A3C, ++ 0xD68, 0x00002101, ++ 0xD6C, 0x2A201C16, ++ 0xD70, 0x1812362E, ++ 0xD74, 0x322C2220, ++ 0xD78, 0x000E3C24, ++ 0xE00, 0x2D2D2D2D, ++ 0xE04, 0x2D2D2D2D, ++ 0xE08, 0x0390272D, ++ 0xE10, 0x2D2D2D2D, ++ 0xE14, 0x2D2D2D2D, ++ 0xE18, 0x2D2D2D2D, ++ 0xE1C, 0x2D2D2D2D, ++ 0xE28, 0x00000000, ++ 0xE30, 0x1000DC1F, ++ 0xE34, 0x10008C1F, ++ 0xE38, 0x02140102, ++ 0xE3C, 0x681604C2, ++ 0xE40, 0x01007C00, ++ 0xE44, 0x01004800, ++ 0xE48, 0xFB000000, ++ 0xE4C, 0x000028D1, ++ 0xE50, 0x1000DC1F, ++ 0xE54, 0x10008C1F, ++ 0xE58, 0x02140102, ++ 0xE5C, 0x28160D05, ++ 0xE60, 0x00000008, ++ 0xE68, 0x001B25A4, ++ 0xE6C, 0x00C00014, ++ 0xE70, 0x00C00014, ++ 0xE74, 0x01000014, ++ 0xE78, 0x01000014, ++ 0xE7C, 0x01000014, ++ 0xE80, 0x01000014, ++ 0xE84, 0x00C00014, ++ 0xE88, 0x01000014, ++ 0xE8C, 0x00C00014, ++ 0xED0, 0x00C00014, ++ 0xED4, 0x00C00014, ++ 0xED8, 0x00C00014, ++ 0xEDC, 0x00000014, ++ 0xEE0, 0x00000014, ++ 0xEEC, 0x01C00014, ++ 0xF14, 0x00000003, ++ 0xF4C, 0x00000000, ++ 0xF00, 0x00000300, ++}; ++ ++enum HAL_STATUS ODM_ReadAndConfig_PHY_REG_1T_8188E(struct odm_dm_struct *dm_odm) ++{ ++ u32 hex = 0; ++ u32 i = 0; ++ u8 platform = dm_odm->SupportPlatform; ++ u8 interfaceValue = dm_odm->SupportInterface; ++ u8 board = dm_odm->BoardType; ++ u32 arraylen = sizeof(array_phy_reg_1t_8188e) / sizeof(u32); ++ u32 *array = array_phy_reg_1t_8188e; ++ bool biol = false; ++ struct adapter *adapter = dm_odm->Adapter; ++ struct xmit_frame *pxmit_frame = NULL; ++ u8 bndy_cnt = 1; ++ enum HAL_STATUS rst = HAL_STATUS_SUCCESS; ++ hex += board; ++ hex += interfaceValue << 8; ++ hex += platform << 16; ++ hex += 0xFF000000; ++ biol = rtw_IOL_applied(adapter); ++ ++ if (biol) { ++ pxmit_frame = rtw_IOL_accquire_xmit_frame(adapter); ++ if (!pxmit_frame) { ++ pr_info("rtw_IOL_accquire_xmit_frame failed\n"); ++ return HAL_STATUS_FAILURE; ++ } ++ } ++ ++ for (i = 0; i < arraylen; i += 2) { ++ u32 v1 = array[i]; ++ u32 v2 = array[i + 1]; ++ ++ /* This (offset, data) pair meets the condition. */ ++ if (v1 < 0xCDCDCDCD) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ if (v1 == 0xfe) { ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50); ++ } else if (v1 == 0xfd) { ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5); ++ } else if (v1 == 0xfc) { ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1); ++ } else if (v1 == 0xfb) { ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50); ++ } else if (v1 == 0xfa) { ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5); ++ } else if (v1 == 0xf9) { ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1); ++ } else { ++ if (v1 == 0xa24) ++ dm_odm->RFCalibrateInfo.RegA24 = v2; ++ rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord); ++ } ++ } else { ++ odm_ConfigBB_PHY_8188E(dm_odm, v1, bMaskDWord, v2); ++ } ++ continue; ++ } else { /* This line is the start line of branch. */ ++ if (!CheckCondition(array[i], hex)) { ++ /* Discard the following (offset, data) pairs. */ ++ read_next_pair(array, v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < arraylen - 2) ++ read_next_pair(array, v1, v2, i); ++ i -= 2; /* prevent from for-loop += 2 */ ++ } else { /* Configure matched pairs and skip to end of if-else. */ ++ read_next_pair(array, v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < arraylen - 2) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ if (v1 == 0xfe) { ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50); ++ } else if (v1 == 0xfd) { ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5); ++ } else if (v1 == 0xfc) { ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1); ++ } else if (v1 == 0xfb) { ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50); ++ } else if (v1 == 0xfa) { ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5); ++ } else if (v1 == 0xf9) { ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1); ++ } else { ++ if (v1 == 0xa24) ++ dm_odm->RFCalibrateInfo.RegA24 = v2; ++ ++ rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord); ++ } ++ } else { ++ odm_ConfigBB_PHY_8188E(dm_odm, v1, bMaskDWord, v2); ++ } ++ read_next_pair(array, v1, v2, i); ++ } ++ ++ while (v2 != 0xDEAD && i < arraylen - 2) ++ read_next_pair(array, v1, v2, i); ++ } ++ } ++ } ++ if (biol) { ++ if (!rtw_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { ++ rst = HAL_STATUS_FAILURE; ++ pr_info("~~~ IOL Config %s Failed !!!\n", __func__); ++ } ++ } ++ return rst; ++} ++ ++/****************************************************************************** ++* PHY_REG_PG.TXT ++******************************************************************************/ ++ ++static u32 array_phy_reg_pg_8188e[] = { ++ 0xE00, 0xFFFFFFFF, 0x06070809, ++ 0xE04, 0xFFFFFFFF, 0x02020405, ++ 0xE08, 0x0000FF00, 0x00000006, ++ 0x86C, 0xFFFFFF00, 0x00020400, ++ 0xE10, 0xFFFFFFFF, 0x08090A0B, ++ 0xE14, 0xFFFFFFFF, 0x01030607, ++ 0xE18, 0xFFFFFFFF, 0x08090A0B, ++ 0xE1C, 0xFFFFFFFF, 0x01030607, ++ 0xE00, 0xFFFFFFFF, 0x00000000, ++ 0xE04, 0xFFFFFFFF, 0x00000000, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x00000000, ++ 0xE14, 0xFFFFFFFF, 0x00000000, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x02020202, ++ 0xE04, 0xFFFFFFFF, 0x00020202, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x04040404, ++ 0xE14, 0xFFFFFFFF, 0x00020404, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x02020202, ++ 0xE04, 0xFFFFFFFF, 0x00020202, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x04040404, ++ 0xE14, 0xFFFFFFFF, 0x00020404, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x00000000, ++ 0xE04, 0xFFFFFFFF, 0x00000000, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x00000000, ++ 0xE14, 0xFFFFFFFF, 0x00000000, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x02020202, ++ 0xE04, 0xFFFFFFFF, 0x00020202, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x04040404, ++ 0xE14, 0xFFFFFFFF, 0x00020404, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x00000000, ++ 0xE04, 0xFFFFFFFF, 0x00000000, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x00000000, ++ 0xE14, 0xFFFFFFFF, 0x00000000, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x00000000, ++ 0xE04, 0xFFFFFFFF, 0x00000000, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x00000000, ++ 0xE14, 0xFFFFFFFF, 0x00000000, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x00000000, ++ 0xE04, 0xFFFFFFFF, 0x00000000, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x00000000, ++ 0xE14, 0xFFFFFFFF, 0x00000000, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x00000000, ++ 0xE04, 0xFFFFFFFF, 0x00000000, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x00000000, ++ 0xE14, 0xFFFFFFFF, 0x00000000, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ 0xE00, 0xFFFFFFFF, 0x00000000, ++ 0xE04, 0xFFFFFFFF, 0x00000000, ++ 0xE08, 0x0000FF00, 0x00000000, ++ 0x86C, 0xFFFFFF00, 0x00000000, ++ 0xE10, 0xFFFFFFFF, 0x00000000, ++ 0xE14, 0xFFFFFFFF, 0x00000000, ++ 0xE18, 0xFFFFFFFF, 0x00000000, ++ 0xE1C, 0xFFFFFFFF, 0x00000000, ++ ++}; ++ ++void ODM_ReadAndConfig_PHY_REG_PG_8188E(struct odm_dm_struct *dm_odm) ++{ ++ u32 hex; ++ u32 i = 0; ++ u8 platform = dm_odm->SupportPlatform; ++ u8 interfaceValue = dm_odm->SupportInterface; ++ u8 board = dm_odm->BoardType; ++ u32 arraylen = sizeof(array_phy_reg_pg_8188e) / sizeof(u32); ++ u32 *array = array_phy_reg_pg_8188e; ++ ++ hex = board + (interfaceValue << 8); ++ hex += (platform << 16) + 0xFF000000; ++ ++ for (i = 0; i < arraylen; i += 3) { ++ u32 v1 = array[i]; ++ u32 v2 = array[i + 1]; ++ u32 v3 = array[i + 2]; ++ ++ /* this line is a line of pure_body */ ++ if (v1 < 0xCDCDCDCD) { ++ odm_ConfigBB_PHY_REG_PG_8188E(dm_odm, v1, v2, v3); ++ continue; ++ } else { /* this line is the start of branch */ ++ if (!CheckCondition(array[i], hex)) { ++ /* don't need the hw_body */ ++ i += 2; /* skip the pair of expression */ ++ v1 = array[i]; ++ v2 = array[i + 1]; ++ v3 = array[i + 2]; ++ while (v2 != 0xDEAD) { ++ i += 3; ++ v1 = array[i]; ++ v2 = array[i + 1]; ++ v3 = array[i + 1]; ++ } ++ } ++ } ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/HalHWImg8188E_MAC.c b/drivers/staging/r8188eu/hal/HalHWImg8188E_MAC.c +new file mode 100644 +index 000000000000..0ff2609c26bb +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/HalHWImg8188E_MAC.c +@@ -0,0 +1,213 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++#include "../include/rtw_iol.h" ++ ++static bool Checkcondition(const u32 condition, const u32 hex) ++{ ++ u32 _board = (hex & 0x000000FF); ++ u32 _interface = (hex & 0x0000FF00) >> 8; ++ u32 _platform = (hex & 0x00FF0000) >> 16; ++ u32 cond = condition; ++ ++ if (condition == 0xCDCDCDCD) ++ return true; ++ ++ cond = condition & 0x000000FF; ++ if ((_board == cond) && cond != 0x00) ++ return false; ++ ++ cond = condition & 0x0000FF00; ++ cond = cond >> 8; ++ if ((_interface & cond) == 0 && cond != 0x07) ++ return false; ++ ++ cond = condition & 0x00FF0000; ++ cond = cond >> 16; ++ if ((_platform & cond) == 0 && cond != 0x0F) ++ return false; ++ return true; ++} ++ ++/****************************************************************************** ++* MAC_REG.TXT ++******************************************************************************/ ++ ++static u32 array_MAC_REG_8188E[] = { ++ 0x026, 0x00000041, ++ 0x027, 0x00000035, ++ 0x428, 0x0000000A, ++ 0x429, 0x00000010, ++ 0x430, 0x00000000, ++ 0x431, 0x00000001, ++ 0x432, 0x00000002, ++ 0x433, 0x00000004, ++ 0x434, 0x00000005, ++ 0x435, 0x00000006, ++ 0x436, 0x00000007, ++ 0x437, 0x00000008, ++ 0x438, 0x00000000, ++ 0x439, 0x00000000, ++ 0x43A, 0x00000001, ++ 0x43B, 0x00000002, ++ 0x43C, 0x00000004, ++ 0x43D, 0x00000005, ++ 0x43E, 0x00000006, ++ 0x43F, 0x00000007, ++ 0x440, 0x0000005D, ++ 0x441, 0x00000001, ++ 0x442, 0x00000000, ++ 0x444, 0x00000015, ++ 0x445, 0x000000F0, ++ 0x446, 0x0000000F, ++ 0x447, 0x00000000, ++ 0x458, 0x00000041, ++ 0x459, 0x000000A8, ++ 0x45A, 0x00000072, ++ 0x45B, 0x000000B9, ++ 0x460, 0x00000066, ++ 0x461, 0x00000066, ++ 0x480, 0x00000008, ++ 0x4C8, 0x000000FF, ++ 0x4C9, 0x00000008, ++ 0x4CC, 0x000000FF, ++ 0x4CD, 0x000000FF, ++ 0x4CE, 0x00000001, ++ 0x4D3, 0x00000001, ++ 0x500, 0x00000026, ++ 0x501, 0x000000A2, ++ 0x502, 0x0000002F, ++ 0x503, 0x00000000, ++ 0x504, 0x00000028, ++ 0x505, 0x000000A3, ++ 0x506, 0x0000005E, ++ 0x507, 0x00000000, ++ 0x508, 0x0000002B, ++ 0x509, 0x000000A4, ++ 0x50A, 0x0000005E, ++ 0x50B, 0x00000000, ++ 0x50C, 0x0000004F, ++ 0x50D, 0x000000A4, ++ 0x50E, 0x00000000, ++ 0x50F, 0x00000000, ++ 0x512, 0x0000001C, ++ 0x514, 0x0000000A, ++ 0x516, 0x0000000A, ++ 0x525, 0x0000004F, ++ 0x550, 0x00000010, ++ 0x551, 0x00000010, ++ 0x559, 0x00000002, ++ 0x55D, 0x000000FF, ++ 0x605, 0x00000030, ++ 0x608, 0x0000000E, ++ 0x609, 0x0000002A, ++ 0x620, 0x000000FF, ++ 0x621, 0x000000FF, ++ 0x622, 0x000000FF, ++ 0x623, 0x000000FF, ++ 0x624, 0x000000FF, ++ 0x625, 0x000000FF, ++ 0x626, 0x000000FF, ++ 0x627, 0x000000FF, ++ 0x652, 0x00000020, ++ 0x63C, 0x0000000A, ++ 0x63D, 0x0000000A, ++ 0x63E, 0x0000000E, ++ 0x63F, 0x0000000E, ++ 0x640, 0x00000040, ++ 0x66E, 0x00000005, ++ 0x700, 0x00000021, ++ 0x701, 0x00000043, ++ 0x702, 0x00000065, ++ 0x703, 0x00000087, ++ 0x708, 0x00000021, ++ 0x709, 0x00000043, ++ 0x70A, 0x00000065, ++ 0x70B, 0x00000087, ++}; ++ ++enum HAL_STATUS ODM_ReadAndConfig_MAC_REG_8188E(struct odm_dm_struct *dm_odm) ++{ ++ #define READ_NEXT_PAIR(v1, v2, i) do { i += 2; v1 = array[i]; v2 = array[i + 1]; } while (0) ++ ++ u32 hex = 0; ++ u32 i; ++ u8 platform = dm_odm->SupportPlatform; ++ u8 interface_val = dm_odm->SupportInterface; ++ u8 board = dm_odm->BoardType; ++ u32 array_len = sizeof(array_MAC_REG_8188E) / sizeof(u32); ++ u32 *array = array_MAC_REG_8188E; ++ bool biol = false; ++ ++ struct adapter *adapt = dm_odm->Adapter; ++ struct xmit_frame *pxmit_frame = NULL; ++ u8 bndy_cnt = 1; ++ enum HAL_STATUS rst = HAL_STATUS_SUCCESS; ++ hex += board; ++ hex += interface_val << 8; ++ hex += platform << 16; ++ hex += 0xFF000000; ++ ++ biol = rtw_IOL_applied(adapt); ++ ++ if (biol) { ++ pxmit_frame = rtw_IOL_accquire_xmit_frame(adapt); ++ if (!pxmit_frame) { ++ pr_info("rtw_IOL_accquire_xmit_frame failed\n"); ++ return HAL_STATUS_FAILURE; ++ } ++ } ++ ++ for (i = 0; i < array_len; i += 2) { ++ u32 v1 = array[i]; ++ u32 v2 = array[i + 1]; ++ ++ /* This (offset, data) pair meets the condition. */ ++ if (v1 < 0xCDCDCDCD) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ rtw_IOL_append_WB_cmd(pxmit_frame, (u16)v1, (u8)v2, 0xFF); ++ } else { ++ odm_ConfigMAC_8188E(dm_odm, v1, (u8)v2); ++ } ++ continue; ++ } else { /* This line is the start line of branch. */ ++ if (!Checkcondition(array[i], hex)) { ++ /* Discard the following (offset, data) pairs. */ ++ READ_NEXT_PAIR(v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < array_len - 2) { ++ READ_NEXT_PAIR(v1, v2, i); ++ } ++ i -= 2; /* prevent from for-loop += 2 */ ++ } else { /* Configure matched pairs and skip to end of if-else. */ ++ READ_NEXT_PAIR(v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < array_len - 2) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ rtw_IOL_append_WB_cmd(pxmit_frame, (u16)v1, (u8)v2, 0xFF); ++ } else { ++ odm_ConfigMAC_8188E(dm_odm, v1, (u8)v2); ++ } ++ ++ READ_NEXT_PAIR(v1, v2, i); ++ } ++ while (v2 != 0xDEAD && i < array_len - 2) ++ READ_NEXT_PAIR(v1, v2, i); ++ } ++ } ++ } ++ if (biol) { ++ if (!rtw_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { ++ pr_info("~~~ MAC IOL_exec_cmds Failed !!!\n"); ++ rst = HAL_STATUS_FAILURE; ++ } ++ } ++ return rst; ++} +diff --git a/drivers/staging/r8188eu/hal/HalHWImg8188E_RF.c b/drivers/staging/r8188eu/hal/HalHWImg8188E_RF.c +new file mode 100644 +index 000000000000..55e4b4a877a4 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/HalHWImg8188E_RF.c +@@ -0,0 +1,250 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++#include "../include/rtw_iol.h" ++ ++static bool CheckCondition(const u32 Condition, const u32 Hex) ++{ ++ u32 _board = (Hex & 0x000000FF); ++ u32 _interface = (Hex & 0x0000FF00) >> 8; ++ u32 _platform = (Hex & 0x00FF0000) >> 16; ++ u32 cond = Condition; ++ ++ if (Condition == 0xCDCDCDCD) ++ return true; ++ ++ cond = Condition & 0x000000FF; ++ if ((_board == cond) && cond != 0x00) ++ return false; ++ ++ cond = Condition & 0x0000FF00; ++ cond = cond >> 8; ++ if ((_interface & cond) == 0 && cond != 0x07) ++ return false; ++ ++ cond = Condition & 0x00FF0000; ++ cond = cond >> 16; ++ if ((_platform & cond) == 0 && cond != 0x0F) ++ return false; ++ return true; ++} ++ ++/****************************************************************************** ++* RadioA_1T.TXT ++******************************************************************************/ ++ ++static u32 Array_RadioA_1T_8188E[] = { ++ 0x000, 0x00030000, ++ 0x008, 0x00084000, ++ 0x018, 0x00000407, ++ 0x019, 0x00000012, ++ 0x01E, 0x00080009, ++ 0x01F, 0x00000880, ++ 0x02F, 0x0001A060, ++ 0x03F, 0x00000000, ++ 0x042, 0x000060C0, ++ 0x057, 0x000D0000, ++ 0x058, 0x000BE180, ++ 0x067, 0x00001552, ++ 0x083, 0x00000000, ++ 0x0B0, 0x000FF8FC, ++ 0x0B1, 0x00054400, ++ 0x0B2, 0x000CCC19, ++ 0x0B4, 0x00043003, ++ 0x0B6, 0x0004953E, ++ 0x0B7, 0x0001C718, ++ 0x0B8, 0x000060FF, ++ 0x0B9, 0x00080001, ++ 0x0BA, 0x00040000, ++ 0x0BB, 0x00000400, ++ 0x0BF, 0x000C0000, ++ 0x0C2, 0x00002400, ++ 0x0C3, 0x00000009, ++ 0x0C4, 0x00040C91, ++ 0x0C5, 0x00099999, ++ 0x0C6, 0x000000A3, ++ 0x0C7, 0x00088820, ++ 0x0C8, 0x00076C06, ++ 0x0C9, 0x00000000, ++ 0x0CA, 0x00080000, ++ 0x0DF, 0x00000180, ++ 0x0EF, 0x000001A0, ++ 0x051, 0x0006B27D, ++ 0xFF0F041F, 0xABCD, ++ 0x052, 0x0007E4DD, ++ 0xCDCDCDCD, 0xCDCD, ++ 0x052, 0x0007E49D, ++ 0xFF0F041F, 0xDEAD, ++ 0x053, 0x00000073, ++ 0x056, 0x00051FF3, ++ 0x035, 0x00000086, ++ 0x035, 0x00000186, ++ 0x035, 0x00000286, ++ 0x036, 0x00001C25, ++ 0x036, 0x00009C25, ++ 0x036, 0x00011C25, ++ 0x036, 0x00019C25, ++ 0x0B6, 0x00048538, ++ 0x018, 0x00000C07, ++ 0x05A, 0x0004BD00, ++ 0x019, 0x000739D0, ++ 0x034, 0x0000ADF3, ++ 0x034, 0x00009DF0, ++ 0x034, 0x00008DED, ++ 0x034, 0x00007DEA, ++ 0x034, 0x00006DE7, ++ 0x034, 0x000054EE, ++ 0x034, 0x000044EB, ++ 0x034, 0x000034E8, ++ 0x034, 0x0000246B, ++ 0x034, 0x00001468, ++ 0x034, 0x0000006D, ++ 0x000, 0x00030159, ++ 0x084, 0x00068200, ++ 0x086, 0x000000CE, ++ 0x087, 0x00048A00, ++ 0x08E, 0x00065540, ++ 0x08F, 0x00088000, ++ 0x0EF, 0x000020A0, ++ 0x03B, 0x000F02B0, ++ 0x03B, 0x000EF7B0, ++ 0x03B, 0x000D4FB0, ++ 0x03B, 0x000CF060, ++ 0x03B, 0x000B0090, ++ 0x03B, 0x000A0080, ++ 0x03B, 0x00090080, ++ 0x03B, 0x0008F780, ++ 0x03B, 0x000722B0, ++ 0x03B, 0x0006F7B0, ++ 0x03B, 0x00054FB0, ++ 0x03B, 0x0004F060, ++ 0x03B, 0x00030090, ++ 0x03B, 0x00020080, ++ 0x03B, 0x00010080, ++ 0x03B, 0x0000F780, ++ 0x0EF, 0x000000A0, ++ 0x000, 0x00010159, ++ 0x018, 0x0000F407, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0x01F, 0x00080003, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0x01E, 0x00000001, ++ 0x01F, 0x00080000, ++ 0x000, 0x00033E60, ++}; ++ ++enum HAL_STATUS ODM_ReadAndConfig_RadioA_1T_8188E(struct odm_dm_struct *pDM_Odm) ++{ ++ #define READ_NEXT_PAIR(v1, v2, i) do \ ++ { i += 2; v1 = Array[i]; \ ++ v2 = Array[i + 1]; } while (0) ++ ++ u32 hex = 0; ++ u32 i = 0; ++ u8 platform = pDM_Odm->SupportPlatform; ++ u8 interfaceValue = pDM_Odm->SupportInterface; ++ u8 board = pDM_Odm->BoardType; ++ u32 ArrayLen = sizeof(Array_RadioA_1T_8188E) / sizeof(u32); ++ u32 *Array = Array_RadioA_1T_8188E; ++ bool biol = false; ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ struct xmit_frame *pxmit_frame = NULL; ++ u8 bndy_cnt = 1; ++ enum HAL_STATUS rst = HAL_STATUS_SUCCESS; ++ ++ hex += board; ++ hex += interfaceValue << 8; ++ hex += platform << 16; ++ hex += 0xFF000000; ++ biol = rtw_IOL_applied(Adapter); ++ ++ if (biol) { ++ pxmit_frame = rtw_IOL_accquire_xmit_frame(Adapter); ++ if (!pxmit_frame) { ++ pr_info("rtw_IOL_accquire_xmit_frame failed\n"); ++ return HAL_STATUS_FAILURE; ++ } ++ } ++ ++ for (i = 0; i < ArrayLen; i += 2) { ++ u32 v1 = Array[i]; ++ u32 v2 = Array[i + 1]; ++ ++ /* This (offset, data) pair meets the condition. */ ++ if (v1 < 0xCDCDCDCD) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ ++ if (v1 == 0xffe) ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50); ++ else if (v1 == 0xfd) ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5); ++ else if (v1 == 0xfc) ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1); ++ else if (v1 == 0xfb) ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50); ++ else if (v1 == 0xfa) ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5); ++ else if (v1 == 0xf9) ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1); ++ else ++ rtw_IOL_append_WRF_cmd(pxmit_frame, RF_PATH_A, (u16)v1, v2, bRFRegOffsetMask); ++ } else { ++ odm_ConfigRF_RadioA_8188E(pDM_Odm, v1, v2); ++ } ++ continue; ++ } else { /* This line is the start line of branch. */ ++ if (!CheckCondition(Array[i], hex)) { ++ /* Discard the following (offset, data) pairs. */ ++ READ_NEXT_PAIR(v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < ArrayLen - 2) ++ READ_NEXT_PAIR(v1, v2, i); ++ i -= 2; /* prevent from for-loop += 2 */ ++ } else { /* Configure matched pairs and skip to end of if-else. */ ++ READ_NEXT_PAIR(v1, v2, i); ++ while (v2 != 0xDEAD && ++ v2 != 0xCDEF && ++ v2 != 0xCDCD && i < ArrayLen - 2) { ++ if (biol) { ++ if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) ++ bndy_cnt++; ++ ++ if (v1 == 0xffe) ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50); ++ else if (v1 == 0xfd) ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5); ++ else if (v1 == 0xfc) ++ rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1); ++ else if (v1 == 0xfb) ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50); ++ else if (v1 == 0xfa) ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5); ++ else if (v1 == 0xf9) ++ rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1); ++ else ++ rtw_IOL_append_WRF_cmd(pxmit_frame, RF_PATH_A, (u16)v1, v2, bRFRegOffsetMask); ++ } else { ++ odm_ConfigRF_RadioA_8188E(pDM_Odm, v1, v2); ++ } ++ READ_NEXT_PAIR(v1, v2, i); ++ } ++ ++ while (v2 != 0xDEAD && i < ArrayLen - 2) ++ READ_NEXT_PAIR(v1, v2, i); ++ } ++ } ++ } ++ if (biol) { ++ if (!rtw_IOL_exec_cmds_sync(pDM_Odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { ++ rst = HAL_STATUS_FAILURE; ++ pr_info("~~~ IOL Config %s Failed !!!\n", __func__); ++ } ++ } ++ return rst; ++} +diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c +new file mode 100644 +index 000000000000..356885e27edd +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c +@@ -0,0 +1,1264 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++ ++/*---------------------------Define Local Constant---------------------------*/ ++/* 2010/04/25 MH Define the max tx power tracking tx agc power. */ ++#define ODM_TXPWRTRACK_MAX_IDX_88E 6 ++ ++/*---------------------------Define Local Constant---------------------------*/ ++ ++/* 3============================================================ */ ++/* 3 Tx Power Tracking */ ++/* 3============================================================ */ ++/*----------------------------------------------------------------------------- ++ * Function: ODM_TxPwrTrackAdjust88E() ++ * ++ * Overview: 88E we can not write 0xc80/c94/c4c/ 0xa2x. Instead of write TX agc. ++ * No matter OFDM & CCK use the same method. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 04/23/2012 MHC Create Version 0. ++ * 04/23/2012 MHC Adjust TX agc directly not throughput BB digital. ++ * ++ *---------------------------------------------------------------------------*/ ++void ODM_TxPwrTrackAdjust88E(struct odm_dm_struct *dm_odm, u8 Type,/* 0 = OFDM, 1 = CCK */ ++ u8 *pDirection, /* 1 = +(increase) 2 = -(decrease) */ ++ u32 *pOutWriteVal /* Tx tracking CCK/OFDM BB swing index adjust */ ++ ) ++{ ++ u8 pwr_value = 0; ++ /* Tx power tracking BB swing table. */ ++ /* The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */ ++ if (Type == 0) { /* For OFDM afjust */ ++ if (dm_odm->BbSwingIdxOfdm <= dm_odm->BbSwingIdxOfdmBase) { ++ *pDirection = 1; ++ pwr_value = (dm_odm->BbSwingIdxOfdmBase - dm_odm->BbSwingIdxOfdm); ++ } else { ++ *pDirection = 2; ++ pwr_value = (dm_odm->BbSwingIdxOfdm - dm_odm->BbSwingIdxOfdmBase); ++ } ++ } else if (Type == 1) { /* For CCK adjust. */ ++ if (dm_odm->BbSwingIdxCck <= dm_odm->BbSwingIdxCckBase) { ++ *pDirection = 1; ++ pwr_value = (dm_odm->BbSwingIdxCckBase - dm_odm->BbSwingIdxCck); ++ } else { ++ *pDirection = 2; ++ pwr_value = (dm_odm->BbSwingIdxCck - dm_odm->BbSwingIdxCckBase); ++ } ++ } ++ ++ /* */ ++ /* 2012/04/25 MH According to Ed/Luke.Lees estimate for EVM the max tx power tracking */ ++ /* need to be less than 6 power index for 88E. */ ++ /* */ ++ if (pwr_value >= ODM_TXPWRTRACK_MAX_IDX_88E && *pDirection == 1) ++ pwr_value = ODM_TXPWRTRACK_MAX_IDX_88E; ++ ++ *pOutWriteVal = pwr_value | (pwr_value << 8) | (pwr_value << 16) | (pwr_value << 24); ++} /* ODM_TxPwrTrackAdjust88E */ ++ ++/*----------------------------------------------------------------------------- ++ * Function: odm_TxPwrTrackSetPwr88E() ++ * ++ * Overview: 88E change all channel tx power accordign to flag. ++ * OFDM & CCK are all different. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 04/23/2012 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++static void odm_TxPwrTrackSetPwr88E(struct odm_dm_struct *dm_odm) ++{ ++ if (dm_odm->BbSwingFlagOfdm || dm_odm->BbSwingFlagCck) { ++ PHY_SetTxPowerLevel8188E(dm_odm->Adapter, *dm_odm->pChannel); ++ dm_odm->BbSwingFlagOfdm = false; ++ dm_odm->BbSwingFlagCck = false; ++ } ++} /* odm_TxPwrTrackSetPwr88E */ ++ ++/* 091212 chiyokolin */ ++void ++odm_TXPowerTrackingCallback_ThermalMeter_8188E( ++ struct adapter *Adapter ++ ) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u8 ThermalValue = 0, delta, delta_LCK, delta_IQK, offset; ++ u8 ThermalValue_AVG_count = 0; ++ u32 ThermalValue_AVG = 0; ++ s32 ele_A = 0, ele_D, TempCCk, X, value32; ++ s32 Y, ele_C = 0; ++ s8 OFDM_index[2], CCK_index = 0; ++ s8 OFDM_index_old[2] = {0, 0}, CCK_index_old = 0; ++ u32 i = 0, j = 0; ++ bool is2t = false; ++ ++ u8 OFDM_min_index = 6, rf; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */ ++ u8 Indexforchannel = 0/*GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/; ++ s8 OFDM_index_mapping[2][index_mapping_NUM_88E] = { ++ {0, 0, 2, 3, 4, 4, /* 2.4G, decrease power */ ++ 5, 6, 7, 7, 8, 9, ++ 10, 10, 11}, /* For lower temperature, 20120220 updated on 20120220. */ ++ {0, 0, -1, -2, -3, -4, /* 2.4G, increase power */ ++ -4, -4, -4, -5, -7, -8, ++ -9, -9, -10}, ++ }; ++ u8 Thermal_mapping[2][index_mapping_NUM_88E] = { ++ {0, 2, 4, 6, 8, 10, /* 2.4G, decrease power */ ++ 12, 14, 16, 18, 20, 22, ++ 24, 26, 27}, ++ {0, 2, 4, 6, 8, 10, /* 2.4G,, increase power */ ++ 12, 14, 16, 18, 20, 22, ++ 25, 25, 25}, ++ }; ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ /* 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */ ++ odm_TxPwrTrackSetPwr88E(dm_odm); ++ ++ dm_odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++; /* cosa add for debug */ ++ dm_odm->RFCalibrateInfo.bTXPowerTrackingInit = true; ++ ++ /* RFCalibrateInfo.RegA24 will be initialized when ODM HW configuring, but MP configures with para files. */ ++ dm_odm->RFCalibrateInfo.RegA24 = 0x090e1317; ++ ++ ThermalValue = (u8)ODM_GetRFReg(dm_odm, RF_PATH_A, RF_T_METER_88E, 0xfc00); /* 0x42: RF Reg[15:10] 88E */ ++ ++ if (is2t) ++ rf = 2; ++ else ++ rf = 1; ++ ++ if (ThermalValue) { ++ /* Query OFDM path A default setting */ ++ ele_D = ODM_GetBBReg(dm_odm, rOFDM0_XATxIQImbalance, bMaskDWord) & bMaskOFDM_D; ++ for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) { /* find the index */ ++ if (ele_D == (OFDMSwingTable[i] & bMaskOFDM_D)) { ++ OFDM_index_old[0] = (u8)i; ++ dm_odm->BbSwingIdxOfdmBase = (u8)i; ++ break; ++ } ++ } ++ ++ /* Query OFDM path B default setting */ ++ if (is2t) { ++ ele_D = ODM_GetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord) & bMaskOFDM_D; ++ for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) { /* find the index */ ++ if (ele_D == (OFDMSwingTable[i] & bMaskOFDM_D)) { ++ OFDM_index_old[1] = (u8)i; ++ break; ++ } ++ } ++ } ++ ++ /* Query CCK default setting From 0xa24 */ ++ TempCCk = dm_odm->RFCalibrateInfo.RegA24; ++ ++ for (i = 0; i < CCK_TABLE_SIZE; i++) { ++ if (dm_odm->RFCalibrateInfo.bCCKinCH14) { ++ if (ODM_CompareMemory(dm_odm, (void *)&TempCCk, (void *)&CCKSwingTable_Ch14[i][2], 4) == 0) { ++ CCK_index_old = (u8)i; ++ dm_odm->BbSwingIdxCckBase = (u8)i; ++ break; ++ } ++ } else { ++ if (ODM_CompareMemory(dm_odm, (void *)&TempCCk, (void *)&CCKSwingTable_Ch1_Ch13[i][2], 4) == 0) { ++ CCK_index_old = (u8)i; ++ dm_odm->BbSwingIdxCckBase = (u8)i; ++ break; ++ } ++ } ++ } ++ ++ if (!dm_odm->RFCalibrateInfo.ThermalValue) { ++ dm_odm->RFCalibrateInfo.ThermalValue = pHalData->EEPROMThermalMeter; ++ dm_odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue; ++ dm_odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue; ++ ++ for (i = 0; i < rf; i++) ++ dm_odm->RFCalibrateInfo.OFDM_index[i] = OFDM_index_old[i]; ++ dm_odm->RFCalibrateInfo.CCK_index = CCK_index_old; ++ } ++ ++ /* calculate average thermal meter */ ++ dm_odm->RFCalibrateInfo.ThermalValue_AVG[dm_odm->RFCalibrateInfo.ThermalValue_AVG_index] = ThermalValue; ++ dm_odm->RFCalibrateInfo.ThermalValue_AVG_index++; ++ if (dm_odm->RFCalibrateInfo.ThermalValue_AVG_index == AVG_THERMAL_NUM_88E) ++ dm_odm->RFCalibrateInfo.ThermalValue_AVG_index = 0; ++ ++ for (i = 0; i < AVG_THERMAL_NUM_88E; i++) { ++ if (dm_odm->RFCalibrateInfo.ThermalValue_AVG[i]) { ++ ThermalValue_AVG += dm_odm->RFCalibrateInfo.ThermalValue_AVG[i]; ++ ThermalValue_AVG_count++; ++ } ++ } ++ ++ if (ThermalValue_AVG_count) ++ ThermalValue = (u8)(ThermalValue_AVG / ThermalValue_AVG_count); ++ ++ if (dm_odm->RFCalibrateInfo.bReloadtxpowerindex) { ++ delta = ThermalValue > pHalData->EEPROMThermalMeter ? ++ (ThermalValue - pHalData->EEPROMThermalMeter) : ++ (pHalData->EEPROMThermalMeter - ThermalValue); ++ dm_odm->RFCalibrateInfo.bReloadtxpowerindex = false; ++ dm_odm->RFCalibrateInfo.bDoneTxpower = false; ++ } else if (dm_odm->RFCalibrateInfo.bDoneTxpower) { ++ delta = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue) ? ++ (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue) : ++ (dm_odm->RFCalibrateInfo.ThermalValue - ThermalValue); ++ } else { ++ delta = ThermalValue > pHalData->EEPROMThermalMeter ? ++ (ThermalValue - pHalData->EEPROMThermalMeter) : ++ (pHalData->EEPROMThermalMeter - ThermalValue); ++ } ++ delta_LCK = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue_LCK) ? ++ (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue_LCK) : ++ (dm_odm->RFCalibrateInfo.ThermalValue_LCK - ThermalValue); ++ delta_IQK = (ThermalValue > dm_odm->RFCalibrateInfo.ThermalValue_IQK) ? ++ (ThermalValue - dm_odm->RFCalibrateInfo.ThermalValue_IQK) : ++ (dm_odm->RFCalibrateInfo.ThermalValue_IQK - ThermalValue); ++ ++ if ((delta_LCK >= 8)) { /* Delta temperature is equal to or larger than 20 centigrade. */ ++ dm_odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue; ++ PHY_LCCalibrate_8188E(Adapter); ++ } ++ ++ if (delta > 0 && dm_odm->RFCalibrateInfo.TxPowerTrackControl) { ++ delta = ThermalValue > pHalData->EEPROMThermalMeter ? ++ (ThermalValue - pHalData->EEPROMThermalMeter) : ++ (pHalData->EEPROMThermalMeter - ThermalValue); ++ /* calculate new OFDM / CCK offset */ ++ if (ThermalValue > pHalData->EEPROMThermalMeter) ++ j = 1; ++ else ++ j = 0; ++ for (offset = 0; offset < index_mapping_NUM_88E; offset++) { ++ if (delta < Thermal_mapping[j][offset]) { ++ if (offset != 0) ++ offset--; ++ break; ++ } ++ } ++ if (offset >= index_mapping_NUM_88E) ++ offset = index_mapping_NUM_88E - 1; ++ for (i = 0; i < rf; i++) ++ OFDM_index[i] = dm_odm->RFCalibrateInfo.OFDM_index[i] + OFDM_index_mapping[j][offset]; ++ CCK_index = dm_odm->RFCalibrateInfo.CCK_index + OFDM_index_mapping[j][offset]; ++ ++ for (i = 0; i < rf; i++) { ++ if (OFDM_index[i] > OFDM_TABLE_SIZE_92D - 1) ++ OFDM_index[i] = OFDM_TABLE_SIZE_92D - 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; ++ ++ /* 2 temporarily remove bNOPG */ ++ /* Config by SwingTable */ ++ if (dm_odm->RFCalibrateInfo.TxPowerTrackControl) { ++ dm_odm->RFCalibrateInfo.bDoneTxpower = true; ++ ++ /* Adujst OFDM Ant_A according to IQK result */ ++ ele_D = (OFDMSwingTable[(u8)OFDM_index[0]] & 0xFFC00000) >> 22; ++ X = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][0]; ++ Y = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][1]; ++ ++ /* Revse TX power table. */ ++ dm_odm->BbSwingIdxOfdm = (u8)OFDM_index[0]; ++ dm_odm->BbSwingIdxCck = (u8)CCK_index; ++ ++ if (dm_odm->BbSwingIdxOfdmCurrent != dm_odm->BbSwingIdxOfdm) { ++ dm_odm->BbSwingIdxOfdmCurrent = dm_odm->BbSwingIdxOfdm; ++ dm_odm->BbSwingFlagOfdm = true; ++ } ++ ++ if (dm_odm->BbSwingIdxCckCurrent != dm_odm->BbSwingIdxCck) { ++ dm_odm->BbSwingIdxCckCurrent = dm_odm->BbSwingIdxCck; ++ dm_odm->BbSwingFlagCck = true; ++ } ++ ++ if (X != 0) { ++ if ((X & 0x00000200) != 0) ++ X = X | 0xFFFFFC00; ++ ele_A = ((X * ele_D) >> 8) & 0x000003FF; ++ ++ /* new element C = element D x Y */ ++ if ((Y & 0x00000200) != 0) ++ Y = Y | 0xFFFFFC00; ++ ele_C = ((Y * ele_D) >> 8) & 0x000003FF; ++ ++ /* 2012/04/23 MH According to Luke's suggestion, we can not write BB digital */ ++ /* to increase TX power. Otherwise, EVM will be bad. */ ++ } ++ ++ if (is2t) { ++ ele_D = (OFDMSwingTable[(u8)OFDM_index[1]] & 0xFFC00000) >> 22; ++ ++ /* new element A = element D x X */ ++ X = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][4]; ++ Y = dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][5]; ++ ++ if ((X != 0) && (*dm_odm->pBandType == ODM_BAND_2_4G)) { ++ if ((X & 0x00000200) != 0) /* consider minus */ ++ X = X | 0xFFFFFC00; ++ ele_A = ((X * ele_D) >> 8) & 0x000003FF; ++ ++ /* new element C = element D x Y */ ++ if ((Y & 0x00000200) != 0) ++ Y = Y | 0xFFFFFC00; ++ ele_C = ((Y * ele_D) >> 8) & 0x00003FF; ++ ++ /* wtite new elements A, C, D to regC88 and regC9C, element B is always 0 */ ++ value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A; ++ ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord, value32); ++ ++ value32 = (ele_C & 0x000003C0) >> 6; ++ ODM_SetBBReg(dm_odm, rOFDM0_XDTxAFE, bMaskH4Bits, value32); ++ ++ value32 = ((X * ele_D) >> 7) & 0x01; ++ ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(28), value32); ++ } else { ++ ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable[(u8)OFDM_index[1]]); ++ ODM_SetBBReg(dm_odm, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00); ++ ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(28), 0x00); ++ } ++ } ++ } ++ } ++ ++ if (delta_IQK >= 8) { /* Delta temperature is equal to or larger than 20 centigrade. */ ++ dm_odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue; ++ PHY_IQCalibrate_8188E(Adapter, false); ++ } ++ /* update thermal meter value */ ++ if (dm_odm->RFCalibrateInfo.TxPowerTrackControl) ++ dm_odm->RFCalibrateInfo.ThermalValue = ThermalValue; ++ } ++ dm_odm->RFCalibrateInfo.TXPowercount = 0; ++} ++ ++/* 1 7. IQK */ ++#define MAX_TOLERANCE 5 ++#define IQK_DELAY_TIME 1 /* ms */ ++ ++static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ ++phy_PathA_IQK_8188E(struct adapter *adapt, bool configPathB) ++{ ++ u32 regeac, regE94, regE9C; ++ u8 result = 0x00; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ /* 1 Tx IQK */ ++ /* path-A IQK setting */ ++ ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c); ++ ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c); ++ ODM_SetBBReg(dm_odm, rTx_IQK_PI_A, bMaskDWord, 0x8214032a); ++ ODM_SetBBReg(dm_odm, rRx_IQK_PI_A, bMaskDWord, 0x28160000); ++ ++ /* LO calibration setting */ ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Rsp, bMaskDWord, 0x00462911); ++ ++ /* One shot, path A LOK & IQK */ ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); ++ ++ /* delay x ms */ ++ /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */ ++ ODM_delay_ms(IQK_DELAY_TIME_88E); ++ ++ /* Check failed */ ++ regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord); ++ regE94 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord); ++ regE9C = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord); ++ ++ if (!(regeac & BIT(28)) && ++ (((regE94 & 0x03FF0000) >> 16) != 0x142) && ++ (((regE9C & 0x03FF0000) >> 16) != 0x42)) ++ result |= 0x01; ++ return result; ++} ++ ++static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ ++phy_PathA_RxIQK(struct adapter *adapt, bool configPathB) ++{ ++ u32 regeac, regE94, regE9C, regEA4, u4tmp; ++ u8 result = 0x00; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ /* 1 Get TXIMR setting */ ++ /* modify RXIQK mode table */ ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x00000000); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf117B); ++ ++ /* PA,PAD off */ ++ ODM_SetRFReg(dm_odm, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000); ++ ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000); ++ ++ /* IQK setting */ ++ ODM_SetBBReg(dm_odm, rTx_IQK, bMaskDWord, 0x01007c00); ++ ODM_SetBBReg(dm_odm, rRx_IQK, bMaskDWord, 0x81004800); ++ ++ /* path-A IQK setting */ ++ ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c); ++ ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c); ++ ODM_SetBBReg(dm_odm, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f); ++ ODM_SetBBReg(dm_odm, rRx_IQK_PI_A, bMaskDWord, 0x28160000); ++ ++ /* LO calibration setting */ ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911); ++ ++ /* One shot, path A LOK & IQK */ ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); ++ ++ /* delay x ms */ ++ ODM_delay_ms(IQK_DELAY_TIME_88E); ++ ++ /* Check failed */ ++ regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord); ++ regE94 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord); ++ regE9C = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord); ++ ++ if (!(regeac & BIT(28)) && ++ (((regE94 & 0x03FF0000) >> 16) != 0x142) && ++ (((regE9C & 0x03FF0000) >> 16) != 0x42)) ++ result |= 0x01; ++ else /* if Tx not OK, ignore Rx */ ++ return result; ++ ++ u4tmp = 0x80007C00 | (regE94 & 0x3FF0000) | ((regE9C & 0x3FF0000) >> 16); ++ ODM_SetBBReg(dm_odm, rTx_IQK, bMaskDWord, u4tmp); ++ ++ /* 1 RX IQK */ ++ /* modify RXIQK mode table */ ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x00000000); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ffa); ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000); ++ ++ /* IQK setting */ ++ ODM_SetBBReg(dm_odm, rRx_IQK, bMaskDWord, 0x01004800); ++ ++ /* path-A IQK setting */ ++ ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c); ++ ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c); ++ ODM_SetBBReg(dm_odm, rTx_IQK_PI_A, bMaskDWord, 0x82160c05); ++ ODM_SetBBReg(dm_odm, rRx_IQK_PI_A, bMaskDWord, 0x28160c1f); ++ ++ /* LO calibration setting */ ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911); ++ ++ /* One shot, path A LOK & IQK */ ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); ++ ++ /* delay x ms */ ++ /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */ ++ ODM_delay_ms(IQK_DELAY_TIME_88E); ++ ++ /* Check failed */ ++ regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord); ++ regE94 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord); ++ regE9C = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord); ++ regEA4 = ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_A_2, bMaskDWord); ++ ++ /* reload RF 0xdf */ ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x00000000); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180); ++ ++ if (!(regeac & BIT(27)) && /* if Tx is OK, check whether Rx is OK */ ++ (((regEA4 & 0x03FF0000) >> 16) != 0x132) && ++ (((regeac & 0x03FF0000) >> 16) != 0x36)) ++ result |= 0x02; ++ ++ return result; ++} ++ ++static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ ++phy_PathB_IQK_8188E(struct adapter *adapt) ++{ ++ u32 regeac, regeb4, regebc, regec4, regecc; ++ u8 result = 0x00; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ /* One shot, path B LOK & IQK */ ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Cont, bMaskDWord, 0x00000002); ++ ODM_SetBBReg(dm_odm, rIQK_AGC_Cont, bMaskDWord, 0x00000000); ++ ++ /* delay x ms */ ++ ODM_delay_ms(IQK_DELAY_TIME_88E); ++ ++ /* Check failed */ ++ regeac = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord); ++ regeb4 = ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_B, bMaskDWord); ++ regebc = ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_B, bMaskDWord); ++ regec4 = ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_B_2, bMaskDWord); ++ regecc = ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_B_2, bMaskDWord); ++ ++ if (!(regeac & BIT(31)) && ++ (((regeb4 & 0x03FF0000) >> 16) != 0x142) && ++ (((regebc & 0x03FF0000) >> 16) != 0x42)) ++ result |= 0x01; ++ else ++ return result; ++ ++ if (!(regeac & BIT(30)) && ++ (((regec4 & 0x03FF0000) >> 16) != 0x132) && ++ (((regecc & 0x03FF0000) >> 16) != 0x36)) ++ result |= 0x02; ++ ++ return result; ++} ++ ++static void patha_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8], u8 final_candidate, bool txonly) ++{ ++ u32 Oldval_0, X, TX0_A, reg; ++ s32 Y, TX0_C; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ if (final_candidate == 0xFF) { ++ return; ++ } else if (iqkok) { ++ Oldval_0 = (ODM_GetBBReg(dm_odm, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF; ++ ++ X = result[final_candidate][0]; ++ if ((X & 0x00000200) != 0) ++ X = X | 0xFFFFFC00; ++ TX0_A = (X * Oldval_0) >> 8; ++ ODM_SetBBReg(dm_odm, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A); ++ ++ ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(31), ((X * Oldval_0 >> 7) & 0x1)); ++ ++ Y = result[final_candidate][1]; ++ if ((Y & 0x00000200) != 0) ++ Y = Y | 0xFFFFFC00; ++ ++ TX0_C = (Y * Oldval_0) >> 8; ++ ODM_SetBBReg(dm_odm, rOFDM0_XCTxAFE, 0xF0000000, ((TX0_C & 0x3C0) >> 6)); ++ ODM_SetBBReg(dm_odm, rOFDM0_XATxIQImbalance, 0x003F0000, (TX0_C & 0x3F)); ++ ++ ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(29), ((Y * Oldval_0 >> 7) & 0x1)); ++ ++ if (txonly) ++ return; ++ ++ reg = result[final_candidate][2]; ++ ODM_SetBBReg(dm_odm, rOFDM0_XARxIQImbalance, 0x3FF, reg); ++ ++ reg = result[final_candidate][3] & 0x3F; ++ ODM_SetBBReg(dm_odm, rOFDM0_XARxIQImbalance, 0xFC00, reg); ++ ++ reg = (result[final_candidate][3] >> 6) & 0xF; ++ ODM_SetBBReg(dm_odm, rOFDM0_RxIQExtAnta, 0xF0000000, reg); ++ } ++} ++ ++static void pathb_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8], u8 final_candidate, bool txonly) ++{ ++ u32 Oldval_1, X, TX1_A, reg; ++ s32 Y, TX1_C; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ if (final_candidate == 0xFF) { ++ return; ++ } else if (iqkok) { ++ Oldval_1 = (ODM_GetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF; ++ ++ X = result[final_candidate][4]; ++ if ((X & 0x00000200) != 0) ++ X = X | 0xFFFFFC00; ++ TX1_A = (X * Oldval_1) >> 8; ++ ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, 0x3FF, TX1_A); ++ ++ ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(27), ((X * Oldval_1 >> 7) & 0x1)); ++ ++ Y = result[final_candidate][5]; ++ if ((Y & 0x00000200) != 0) ++ Y = Y | 0xFFFFFC00; ++ ++ TX1_C = (Y * Oldval_1) >> 8; ++ ODM_SetBBReg(dm_odm, rOFDM0_XDTxAFE, 0xF0000000, ((TX1_C & 0x3C0) >> 6)); ++ ODM_SetBBReg(dm_odm, rOFDM0_XBTxIQImbalance, 0x003F0000, (TX1_C & 0x3F)); ++ ++ ODM_SetBBReg(dm_odm, rOFDM0_ECCAThreshold, BIT(25), ((Y * Oldval_1 >> 7) & 0x1)); ++ ++ if (txonly) ++ return; ++ ++ reg = result[final_candidate][6]; ++ ODM_SetBBReg(dm_odm, rOFDM0_XBRxIQImbalance, 0x3FF, reg); ++ ++ reg = result[final_candidate][7] & 0x3F; ++ ODM_SetBBReg(dm_odm, rOFDM0_XBRxIQImbalance, 0xFC00, reg); ++ ++ reg = (result[final_candidate][7] >> 6) & 0xF; ++ ODM_SetBBReg(dm_odm, rOFDM0_AGCRSSITable, 0x0000F000, reg); ++ } ++} ++ ++/* */ ++/* 2011/07/26 MH Add an API for testing IQK fail case. */ ++/* */ ++/* MP Already declare in odm.c */ ++static bool ODM_CheckPowerStatus(struct adapter *Adapter) ++{ ++ return true; ++} ++ ++void _PHY_SaveADDARegisters(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegisterNum) ++{ ++ u32 i; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ if (!ODM_CheckPowerStatus(adapt)) ++ return; ++ ++ for (i = 0; i < RegisterNum; i++) { ++ ADDABackup[i] = ODM_GetBBReg(dm_odm, ADDAReg[i], bMaskDWord); ++ } ++} ++ ++static void _PHY_SaveMACRegisters( ++ struct adapter *adapt, ++ u32 *MACReg, ++ u32 *MACBackup ++ ) ++{ ++ u32 i; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) { ++ MACBackup[i] = ODM_Read1Byte(dm_odm, MACReg[i]); ++ } ++ MACBackup[i] = ODM_Read4Byte(dm_odm, MACReg[i]); ++} ++ ++static void reload_adda_reg(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegiesterNum) ++{ ++ u32 i; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ for (i = 0; i < RegiesterNum; i++) ++ ODM_SetBBReg(dm_odm, ADDAReg[i], bMaskDWord, ADDABackup[i]); ++} ++ ++static void ++_PHY_ReloadMACRegisters( ++ struct adapter *adapt, ++ u32 *MACReg, ++ u32 *MACBackup ++ ) ++{ ++ u32 i; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) { ++ ODM_Write1Byte(dm_odm, MACReg[i], (u8)MACBackup[i]); ++ } ++ ODM_Write4Byte(dm_odm, MACReg[i], MACBackup[i]); ++} ++ ++void ++_PHY_PathADDAOn( ++ struct adapter *adapt, ++ u32 *ADDAReg, ++ bool isPathAOn, ++ bool is2t ++ ) ++{ ++ u32 pathOn; ++ u32 i; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ pathOn = isPathAOn ? 0x04db25a4 : 0x0b1b25a4; ++ if (!is2t) { ++ pathOn = 0x0bdb25a0; ++ ODM_SetBBReg(dm_odm, ADDAReg[0], bMaskDWord, 0x0b1b25a0); ++ } else { ++ ODM_SetBBReg(dm_odm, ADDAReg[0], bMaskDWord, pathOn); ++ } ++ ++ for (i = 1; i < IQK_ADDA_REG_NUM; i++) ++ ODM_SetBBReg(dm_odm, ADDAReg[i], bMaskDWord, pathOn); ++} ++ ++void ++_PHY_MACSettingCalibration( ++ struct adapter *adapt, ++ u32 *MACReg, ++ u32 *MACBackup ++ ) ++{ ++ u32 i = 0; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ ODM_Write1Byte(dm_odm, MACReg[i], 0x3F); ++ ++ for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) { ++ ODM_Write1Byte(dm_odm, MACReg[i], (u8)(MACBackup[i] & (~BIT(3)))); ++ } ++ ODM_Write1Byte(dm_odm, MACReg[i], (u8)(MACBackup[i] & (~BIT(5)))); ++} ++ ++void ++_PHY_PathAStandBy( ++ struct adapter *adapt ++ ) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x0); ++ ODM_SetBBReg(dm_odm, 0x840, bMaskDWord, 0x00010000); ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000); ++} ++ ++static void _PHY_PIModeSwitch( ++ struct adapter *adapt, ++ bool PIMode ++ ) ++{ ++ u32 mode; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ mode = PIMode ? 0x01000100 : 0x01000000; ++ ODM_SetBBReg(dm_odm, rFPGA0_XA_HSSIParameter1, bMaskDWord, mode); ++ ODM_SetBBReg(dm_odm, rFPGA0_XB_HSSIParameter1, bMaskDWord, mode); ++} ++ ++static bool phy_SimularityCompare_8188E( ++ struct adapter *adapt, ++ s32 resulta[][8], ++ u8 c1, ++ u8 c2 ++ ) ++{ ++ u32 i, j, diff, sim_bitmap, bound = 0; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */ ++ bool result = true; ++ bool is2t; ++ s32 tmp1 = 0, tmp2 = 0; ++ ++ if ((dm_odm->RFType == ODM_2T2R) || (dm_odm->RFType == ODM_2T3R) || (dm_odm->RFType == ODM_2T4R)) ++ is2t = true; ++ else ++ is2t = false; ++ ++ if (is2t) ++ bound = 8; ++ else ++ bound = 4; ++ ++ sim_bitmap = 0; ++ ++ for (i = 0; i < bound; i++) { ++ if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) { ++ if ((resulta[c1][i] & 0x00000200) != 0) ++ tmp1 = resulta[c1][i] | 0xFFFFFC00; ++ else ++ tmp1 = resulta[c1][i]; ++ ++ if ((resulta[c2][i] & 0x00000200) != 0) ++ tmp2 = resulta[c2][i] | 0xFFFFFC00; ++ else ++ tmp2 = resulta[c2][i]; ++ } else { ++ tmp1 = resulta[c1][i]; ++ tmp2 = resulta[c2][i]; ++ } ++ ++ diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1); ++ ++ if (diff > MAX_TOLERANCE) { ++ if ((i == 2 || i == 6) && !sim_bitmap) { ++ if (resulta[c1][i] + resulta[c1][i + 1] == 0) ++ final_candidate[(i / 4)] = c2; ++ else if (resulta[c2][i] + resulta[c2][i + 1] == 0) ++ final_candidate[(i / 4)] = c1; ++ else ++ sim_bitmap = sim_bitmap | (1 << i); ++ } else { ++ sim_bitmap = sim_bitmap | (1 << i); ++ } ++ } ++ } ++ ++ if (sim_bitmap == 0) { ++ for (i = 0; i < (bound / 4); i++) { ++ if (final_candidate[i] != 0xFF) { ++ for (j = i * 4; j < (i + 1) * 4 - 2; j++) ++ resulta[3][j] = resulta[final_candidate[i]][j]; ++ result = false; ++ } ++ } ++ return result; ++ } else { ++ if (!(sim_bitmap & 0x03)) { /* path A TX OK */ ++ for (i = 0; i < 2; i++) ++ resulta[3][i] = resulta[c1][i]; ++ } ++ if (!(sim_bitmap & 0x0c)) { /* path A RX OK */ ++ for (i = 2; i < 4; i++) ++ resulta[3][i] = resulta[c1][i]; ++ } ++ ++ if (!(sim_bitmap & 0x30)) { /* path B TX OK */ ++ for (i = 4; i < 6; i++) ++ resulta[3][i] = resulta[c1][i]; ++ } ++ ++ if (!(sim_bitmap & 0xc0)) { /* path B RX OK */ ++ for (i = 6; i < 8; i++) ++ resulta[3][i] = resulta[c1][i]; ++ } ++ return false; ++ } ++} ++ ++static void phy_IQCalibrate_8188E(struct adapter *adapt, s32 result[][8], u8 t, bool is2t) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ u32 i; ++ u8 PathAOK, PathBOK; ++ u32 ADDA_REG[IQK_ADDA_REG_NUM] = { ++ rFPGA0_XCD_SwitchControl, rBlue_Tooth, ++ rRx_Wait_CCA, rTx_CCK_RFON, ++ rTx_CCK_BBON, rTx_OFDM_RFON, ++ rTx_OFDM_BBON, rTx_To_Rx, ++ rTx_To_Tx, rRx_CCK, ++ rRx_OFDM, rRx_Wait_RIFS, ++ rRx_TO_Rx, rStandby, ++ rSleep, rPMPD_ANAEN }; ++ u32 IQK_MAC_REG[IQK_MAC_REG_NUM] = { ++ REG_TXPAUSE, REG_BCN_CTRL, ++ REG_BCN_CTRL_1, REG_GPIO_MUXCFG}; ++ ++ /* since 92C & 92D have the different define in IQK_BB_REG */ ++ u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = { ++ rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar, ++ rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB, ++ rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE, ++ rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD ++ }; ++ ++ u32 retryCount = 9; ++ if (*dm_odm->mp_mode == 1) ++ retryCount = 9; ++ else ++ retryCount = 2; ++ /* Note: IQ calibration must be performed after loading */ ++ /* PHY_REG.txt , and radio_a, radio_b.txt */ ++ ++ if (t == 0) { ++ /* Save ADDA parameters, turn Path A ADDA on */ ++ _PHY_SaveADDARegisters(adapt, ADDA_REG, dm_odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM); ++ _PHY_SaveMACRegisters(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup); ++ _PHY_SaveADDARegisters(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM); ++ } ++ ++ _PHY_PathADDAOn(adapt, ADDA_REG, true, is2t); ++ if (t == 0) ++ dm_odm->RFCalibrateInfo.bRfPiEnable = (u8)ODM_GetBBReg(dm_odm, rFPGA0_XA_HSSIParameter1, BIT(8)); ++ ++ if (!dm_odm->RFCalibrateInfo.bRfPiEnable) { ++ /* Switch BB to PI mode to do IQ Calibration. */ ++ _PHY_PIModeSwitch(adapt, true); ++ } ++ ++ /* BB setting */ ++ ODM_SetBBReg(dm_odm, rFPGA0_RFMOD, BIT(24), 0x00); ++ ODM_SetBBReg(dm_odm, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600); ++ ODM_SetBBReg(dm_odm, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4); ++ ODM_SetBBReg(dm_odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000); ++ ++ ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0x01); ++ ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0x01); ++ ODM_SetBBReg(dm_odm, rFPGA0_XA_RFInterfaceOE, BIT(10), 0x00); ++ ODM_SetBBReg(dm_odm, rFPGA0_XB_RFInterfaceOE, BIT(10), 0x00); ++ ++ if (is2t) { ++ ODM_SetBBReg(dm_odm, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00010000); ++ ODM_SetBBReg(dm_odm, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00010000); ++ } ++ ++ /* MAC settings */ ++ _PHY_MACSettingCalibration(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup); ++ ++ /* Page B init */ ++ /* AP or IQK */ ++ ODM_SetBBReg(dm_odm, rConfig_AntA, bMaskDWord, 0x0f600000); ++ ++ if (is2t) ++ ODM_SetBBReg(dm_odm, rConfig_AntB, bMaskDWord, 0x0f600000); ++ ++ /* IQ calibration setting */ ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80800000); ++ ODM_SetBBReg(dm_odm, rTx_IQK, bMaskDWord, 0x01007c00); ++ ODM_SetBBReg(dm_odm, rRx_IQK, bMaskDWord, 0x81004800); ++ ++ for (i = 0; i < retryCount; i++) { ++ PathAOK = phy_PathA_IQK_8188E(adapt, is2t); ++ if (PathAOK == 0x01) { ++ result[t][0] = (ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_A, bMaskDWord) & 0x3FF0000) >> 16; ++ result[t][1] = (ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_A, bMaskDWord) & 0x3FF0000) >> 16; ++ break; ++ } ++ } ++ ++ for (i = 0; i < retryCount; i++) { ++ PathAOK = phy_PathA_RxIQK(adapt, is2t); ++ if (PathAOK == 0x03) { ++ result[t][2] = (ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_A_2, bMaskDWord) & 0x3FF0000) >> 16; ++ result[t][3] = (ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_A_2, bMaskDWord) & 0x3FF0000) >> 16; ++ break; ++ } ++ } ++ ++ if (is2t) { ++ _PHY_PathAStandBy(adapt); ++ ++ /* Turn Path B ADDA on */ ++ _PHY_PathADDAOn(adapt, ADDA_REG, false, is2t); ++ ++ for (i = 0; i < retryCount; i++) { ++ PathBOK = phy_PathB_IQK_8188E(adapt); ++ if (PathBOK == 0x03) { ++ result[t][4] = (ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_B, bMaskDWord) & 0x3FF0000) >> 16; ++ result[t][5] = (ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_B, bMaskDWord) & 0x3FF0000) >> 16; ++ result[t][6] = (ODM_GetBBReg(dm_odm, rRx_Power_Before_IQK_B_2, bMaskDWord) & 0x3FF0000) >> 16; ++ result[t][7] = (ODM_GetBBReg(dm_odm, rRx_Power_After_IQK_B_2, bMaskDWord) & 0x3FF0000) >> 16; ++ break; ++ } else if (i == (retryCount - 1) && PathBOK == 0x01) { /* Tx IQK OK */ ++ result[t][4] = (ODM_GetBBReg(dm_odm, rTx_Power_Before_IQK_B, bMaskDWord) & 0x3FF0000) >> 16; ++ result[t][5] = (ODM_GetBBReg(dm_odm, rTx_Power_After_IQK_B, bMaskDWord) & 0x3FF0000) >> 16; ++ } ++ } ++ } ++ ++ /* Back to BB mode, load original value */ ++ ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0); ++ ++ if (t != 0) { ++ if (!dm_odm->RFCalibrateInfo.bRfPiEnable) { ++ /* Switch back BB to SI mode after finish IQ Calibration. */ ++ _PHY_PIModeSwitch(adapt, false); ++ } ++ ++ /* Reload ADDA power saving parameters */ ++ reload_adda_reg(adapt, ADDA_REG, dm_odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM); ++ ++ /* Reload MAC parameters */ ++ _PHY_ReloadMACRegisters(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup); ++ ++ reload_adda_reg(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM); ++ ++ /* Restore RX initial gain */ ++ ODM_SetBBReg(dm_odm, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00032ed3); ++ if (is2t) ++ ODM_SetBBReg(dm_odm, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00032ed3); ++ ++ /* load 0xe30 IQC default value */ ++ ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00); ++ ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00); ++ } ++} ++ ++static void phy_LCCalibrate_8188E(struct adapter *adapt, bool is2t) ++{ ++ u8 tmpreg; ++ u32 RF_Amode = 0, RF_Bmode = 0, LC_Cal; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ /* Check continuous TX and Packet TX */ ++ tmpreg = ODM_Read1Byte(dm_odm, 0xd03); ++ ++ if ((tmpreg & 0x70) != 0) /* Deal with contisuous TX case */ ++ ODM_Write1Byte(dm_odm, 0xd03, tmpreg & 0x8F); /* disable all continuous TX */ ++ else /* Deal with Packet TX case */ ++ ODM_Write1Byte(dm_odm, REG_TXPAUSE, 0xFF); /* block all queues */ ++ ++ if ((tmpreg & 0x70) != 0) { ++ /* 1. Read original RF mode */ ++ /* Path-A */ ++ RF_Amode = PHY_QueryRFReg(adapt, RF_PATH_A, RF_AC, bMask12Bits); ++ ++ /* Path-B */ ++ if (is2t) ++ RF_Bmode = PHY_QueryRFReg(adapt, RF_PATH_B, RF_AC, bMask12Bits); ++ ++ /* 2. Set RF mode = standby mode */ ++ /* Path-A */ ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_AC, bMask12Bits, (RF_Amode & 0x8FFFF) | 0x10000); ++ ++ /* Path-B */ ++ if (is2t) ++ ODM_SetRFReg(dm_odm, RF_PATH_B, RF_AC, bMask12Bits, (RF_Bmode & 0x8FFFF) | 0x10000); ++ } ++ ++ /* 3. Read RF reg18 */ ++ LC_Cal = PHY_QueryRFReg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits); ++ ++ /* 4. Set LC calibration begin bit15 */ ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal | 0x08000); ++ ++ ODM_sleep_ms(100); ++ ++ /* Restore original situation */ ++ if ((tmpreg & 0x70) != 0) { ++ /* Deal with continuous TX case */ ++ /* Path-A */ ++ ODM_Write1Byte(dm_odm, 0xd03, tmpreg); ++ ODM_SetRFReg(dm_odm, RF_PATH_A, RF_AC, bMask12Bits, RF_Amode); ++ ++ /* Path-B */ ++ if (is2t) ++ ODM_SetRFReg(dm_odm, RF_PATH_B, RF_AC, bMask12Bits, RF_Bmode); ++ } else { ++ /* Deal with Packet TX case */ ++ ODM_Write1Byte(dm_odm, REG_TXPAUSE, 0x00); ++ } ++} ++ ++void PHY_IQCalibrate_8188E(struct adapter *adapt, bool recovery) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ struct mpt_context *pMptCtx = &adapt->mppriv.MptCtx; ++ s32 result[4][8]; /* last is final result */ ++ u8 i, final_candidate; ++ bool pathaok, pathbok; ++ s32 RegE94, RegE9C, RegEA4, RegEB4, RegEBC, RegEC4; ++ bool is12simular, is13simular, is23simular; ++ bool singletone = false, carrier_sup = false; ++ u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = { ++ rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance, ++ rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable, ++ rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance, ++ rOFDM0_XCTxAFE, rOFDM0_XDTxAFE, ++ rOFDM0_RxIQExtAnta}; ++ bool is2t; ++ ++ is2t = (dm_odm->RFType == ODM_2T2R) ? true : false; ++ if (!ODM_CheckPowerStatus(adapt)) ++ return; ++ ++ if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION)) ++ return; ++ ++ if (*dm_odm->mp_mode == 1) { ++ singletone = pMptCtx->bSingleTone; ++ carrier_sup = pMptCtx->bCarrierSuppression; ++ } ++ ++ /* 20120213 Turn on when continuous Tx to pass lab testing. (required by Edlu) */ ++ if (singletone || carrier_sup) ++ return; ++ ++ if (recovery) { ++ reload_adda_reg(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9); ++ return; ++ } ++ ++ for (i = 0; i < 8; i++) { ++ result[0][i] = 0; ++ result[1][i] = 0; ++ result[2][i] = 0; ++ if ((i == 0) || (i == 2) || (i == 4) || (i == 6)) ++ result[3][i] = 0x100; ++ else ++ result[3][i] = 0; ++ } ++ final_candidate = 0xff; ++ pathaok = false; ++ pathbok = false; ++ is12simular = false; ++ is23simular = false; ++ is13simular = false; ++ ++ for (i = 0; i < 3; i++) { ++ phy_IQCalibrate_8188E(adapt, result, i, is2t); ++ ++ if (i == 1) { ++ is12simular = phy_SimularityCompare_8188E(adapt, result, 0, 1); ++ if (is12simular) { ++ final_candidate = 0; ++ break; ++ } ++ } ++ ++ if (i == 2) { ++ is13simular = phy_SimularityCompare_8188E(adapt, result, 0, 2); ++ if (is13simular) { ++ final_candidate = 0; ++ ++ break; ++ } ++ is23simular = phy_SimularityCompare_8188E(adapt, result, 1, 2); ++ if (is23simular) { ++ final_candidate = 1; ++ } else { ++ final_candidate = 3; ++ } ++ } ++ } ++ ++ for (i = 0; i < 4; i++) { ++ RegE94 = result[i][0]; ++ RegE9C = result[i][1]; ++ RegEA4 = result[i][2]; ++ RegEB4 = result[i][4]; ++ RegEBC = result[i][5]; ++ RegEC4 = result[i][6]; ++ } ++ ++ if (final_candidate != 0xff) { ++ RegE94 = result[final_candidate][0]; ++ RegE9C = result[final_candidate][1]; ++ RegEA4 = result[final_candidate][2]; ++ RegEB4 = result[final_candidate][4]; ++ RegEBC = result[final_candidate][5]; ++ dm_odm->RFCalibrateInfo.RegE94 = RegE94; ++ dm_odm->RFCalibrateInfo.RegE9C = RegE9C; ++ dm_odm->RFCalibrateInfo.RegEB4 = RegEB4; ++ dm_odm->RFCalibrateInfo.RegEBC = RegEBC; ++ RegEC4 = result[final_candidate][6]; ++ pathaok = true; ++ pathbok = true; ++ } else { ++ dm_odm->RFCalibrateInfo.RegE94 = 0x100; ++ dm_odm->RFCalibrateInfo.RegEB4 = 0x100; /* X default value */ ++ dm_odm->RFCalibrateInfo.RegE9C = 0x0; ++ dm_odm->RFCalibrateInfo.RegEBC = 0x0; /* Y default value */ ++ } ++ if (RegE94 != 0) ++ patha_fill_iqk(adapt, pathaok, result, final_candidate, (RegEA4 == 0)); ++ if (is2t) { ++ if (RegEB4 != 0) ++ pathb_fill_iqk(adapt, pathbok, result, final_candidate, (RegEC4 == 0)); ++ } ++ ++/* To Fix BSOD when final_candidate is 0xff */ ++/* by sherry 20120321 */ ++ if (final_candidate < 4) { ++ for (i = 0; i < IQK_Matrix_REG_NUM; i++) ++ dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[0].Value[0][i] = result[final_candidate][i]; ++ dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[0].bIQKDone = true; ++ } ++ ++ _PHY_SaveADDARegisters(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9); ++} ++ ++void PHY_LCCalibrate_8188E(struct adapter *adapt) ++{ ++ bool singletone = false, carrier_sup = false; ++ u32 timeout = 2000, timecount = 0; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ struct mpt_context *pMptCtx = &adapt->mppriv.MptCtx; ++ ++ if (*dm_odm->mp_mode == 1) { ++ singletone = pMptCtx->bSingleTone; ++ carrier_sup = pMptCtx->bCarrierSuppression; ++ } ++ if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION)) ++ return; ++ /* 20120213 Turn on when continuous Tx to pass lab testing. (required by Edlu) */ ++ if (singletone || carrier_sup) ++ return; ++ ++ while (*dm_odm->pbScanInProcess && timecount < timeout) { ++ ODM_delay_ms(50); ++ timecount += 50; ++ } ++ ++ dm_odm->RFCalibrateInfo.bLCKInProgress = true; ++ ++ if (dm_odm->RFType == ODM_2T2R) { ++ phy_LCCalibrate_8188E(adapt, true); ++ } else { ++ /* For 88C 1T1R */ ++ phy_LCCalibrate_8188E(adapt, false); ++ } ++ ++ dm_odm->RFCalibrateInfo.bLCKInProgress = false; ++} ++ ++static void phy_setrfpathswitch_8188e(struct adapter *adapt, bool main, bool is2t) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ if (!adapt->hw_init_completed) { ++ u8 u1btmp; ++ u1btmp = ODM_Read1Byte(dm_odm, REG_LEDCFG2) | BIT(7); ++ ODM_Write1Byte(dm_odm, REG_LEDCFG2, u1btmp); ++ ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFParameter, BIT(13), 0x01); ++ } ++ ++ if (is2t) { /* 92C */ ++ if (main) ++ ODM_SetBBReg(dm_odm, rFPGA0_XB_RFInterfaceOE, BIT(5) | BIT(6), 0x1); /* 92C_Path_A */ ++ else ++ ODM_SetBBReg(dm_odm, rFPGA0_XB_RFInterfaceOE, BIT(5) | BIT(6), 0x2); /* BT */ ++ } else { /* 88C */ ++ if (main) ++ ODM_SetBBReg(dm_odm, rFPGA0_XA_RFInterfaceOE, BIT(8) | BIT(9), 0x2); /* Main */ ++ else ++ ODM_SetBBReg(dm_odm, rFPGA0_XA_RFInterfaceOE, BIT(8) | BIT(9), 0x1); /* Aux */ ++ } ++} ++ ++void PHY_SetRFPathSwitch_8188E(struct adapter *adapt, bool main) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt); ++ struct odm_dm_struct *dm_odm = &pHalData->odmpriv; ++ ++ if (dm_odm->RFType == ODM_2T2R) { ++ phy_setrfpathswitch_8188e(adapt, main, true); ++ } else { ++ /* For 88C 1T1R */ ++ phy_setrfpathswitch_8188e(adapt, main, false); ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c +new file mode 100644 +index 000000000000..0fd11aca7ac7 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c +@@ -0,0 +1,95 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++/*++ ++ ++Module Name: ++ HalPwrSeqCmd.c ++ ++Abstract: ++ Implement HW Power sequence configuration CMD handling routine for Realtek devices. ++ ++Major Change History: ++ When Who What ++ ---------- --------------- ------------------------------- ++ 2011-10-26 Lucas Modify to be compatible with SD4-CE driver. ++ 2011-07-07 Roger Create. ++ ++--*/ ++ ++#include "../include/HalPwrSeqCmd.h" ++ ++/* Description: */ ++/* This routine deals with the Power Configuration CMDs parsing ++ * for RTL8723/RTL8188E Series IC. ++ * Assumption: ++ * We should follow specific format which was released from HW SD. ++ */ ++u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers, ++ u8 ifacetype, struct wl_pwr_cfg pwrseqcmd[]) ++{ ++ struct wl_pwr_cfg pwrcfgcmd = {0}; ++ u8 poll_bit = false; ++ u32 aryidx = 0; ++ u8 value = 0; ++ u32 offset = 0; ++ u32 poll_count = 0; /* polling autoload done. */ ++ u32 max_poll_count = 5000; ++ ++ do { ++ pwrcfgcmd = pwrseqcmd[aryidx]; ++ ++ /* 2 Only Handle the command whose FAB, CUT, and Interface are matched */ ++ if ((GET_PWR_CFG_FAB_MASK(pwrcfgcmd) & fab_vers) && ++ (GET_PWR_CFG_CUT_MASK(pwrcfgcmd) & cut_vers) && ++ (GET_PWR_CFG_INTF_MASK(pwrcfgcmd) & ifacetype)) { ++ switch (GET_PWR_CFG_CMD(pwrcfgcmd)) { ++ case PWR_CMD_WRITE: ++ offset = GET_PWR_CFG_OFFSET(pwrcfgcmd); ++ ++ /* Read the value from system register */ ++ value = rtw_read8(padapter, offset); ++ ++ value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd)); ++ value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd)); ++ ++ /* Write the value back to system register */ ++ rtw_write8(padapter, offset, value); ++ break; ++ case PWR_CMD_POLLING: ++ poll_bit = false; ++ offset = GET_PWR_CFG_OFFSET(pwrcfgcmd); ++ do { ++ value = rtw_read8(padapter, offset); ++ ++ value &= GET_PWR_CFG_MASK(pwrcfgcmd); ++ if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd))) ++ poll_bit = true; ++ else ++ udelay(10); ++ ++ if (poll_count++ > max_poll_count) { ++ DBG_88E("Fail to polling Offset[%#x]\n", offset); ++ return false; ++ } ++ } while (!poll_bit); ++ break; ++ case PWR_CMD_DELAY: ++ if (GET_PWR_CFG_VALUE(pwrcfgcmd) == PWRSEQ_DELAY_US) ++ udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd)); ++ else ++ udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd) * 1000); ++ break; ++ case PWR_CMD_END: ++ /* When this command is parsed, end the process */ ++ return true; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ aryidx++;/* Add Array Index */ ++ } while (1); ++ return true; ++} +diff --git a/drivers/staging/r8188eu/hal/hal_com.c b/drivers/staging/r8188eu/hal/hal_com.c +new file mode 100644 +index 000000000000..f09d4d49b159 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/hal_com.c +@@ -0,0 +1,358 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++ ++#include "../include/hal_intf.h" ++#include "../include/hal_com.h" ++#include "../include/rtl8188e_hal.h" ++ ++#define _HAL_INIT_C_ ++ ++void dump_chip_info(struct HAL_VERSION chip_vers) ++{ ++ uint cnt = 0; ++ char buf[128]; ++ ++ if (IS_81XXC(chip_vers)) { ++ cnt += sprintf((buf + cnt), "Chip Version Info: %s_", ++ IS_92C_SERIAL(chip_vers) ? ++ "CHIP_8192C" : "CHIP_8188C"); ++ } else if (IS_92D(chip_vers)) { ++ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192D_"); ++ } else if (IS_8723_SERIES(chip_vers)) { ++ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723A_"); ++ } else if (IS_8188E(chip_vers)) { ++ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_"); ++ } ++ ++ cnt += sprintf((buf + cnt), "%s_", IS_NORMAL_CHIP(chip_vers) ? ++ "Normal_Chip" : "Test_Chip"); ++ cnt += sprintf((buf + cnt), "%s_", IS_CHIP_VENDOR_TSMC(chip_vers) ? ++ "TSMC" : "UMC"); ++ if (IS_A_CUT(chip_vers)) ++ cnt += sprintf((buf + cnt), "A_CUT_"); ++ else if (IS_B_CUT(chip_vers)) ++ cnt += sprintf((buf + cnt), "B_CUT_"); ++ else if (IS_C_CUT(chip_vers)) ++ cnt += sprintf((buf + cnt), "C_CUT_"); ++ else if (IS_D_CUT(chip_vers)) ++ cnt += sprintf((buf + cnt), "D_CUT_"); ++ else if (IS_E_CUT(chip_vers)) ++ cnt += sprintf((buf + cnt), "E_CUT_"); ++ else ++ cnt += sprintf((buf + cnt), "UNKNOWN_CUT(%d)_", ++ chip_vers.CUTVersion); ++ ++ if (IS_1T1R(chip_vers)) ++ cnt += sprintf((buf + cnt), "1T1R_"); ++ else if (IS_1T2R(chip_vers)) ++ cnt += sprintf((buf + cnt), "1T2R_"); ++ else if (IS_2T2R(chip_vers)) ++ cnt += sprintf((buf + cnt), "2T2R_"); ++ else ++ cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ++ chip_vers.RFType); ++ ++ cnt += sprintf((buf + cnt), "RomVer(%d)\n", chip_vers.ROMVer); ++ ++ pr_info("%s", buf); ++} ++ ++#define CHAN_PLAN_HW 0x80 ++ ++u8 /* return the final channel plan decision */ ++hal_com_get_channel_plan(struct adapter *padapter, u8 hw_channel_plan, ++ u8 sw_channel_plan, u8 def_channel_plan, ++ bool load_fail) ++{ ++ u8 sw_cfg; ++ u8 chnlplan; ++ ++ sw_cfg = true; ++ if (!load_fail) { ++ if (!rtw_is_channel_plan_valid(sw_channel_plan)) ++ sw_cfg = false; ++ if (hw_channel_plan & CHAN_PLAN_HW) ++ sw_cfg = false; ++ } ++ ++ if (sw_cfg) ++ chnlplan = sw_channel_plan; ++ else ++ chnlplan = hw_channel_plan & (~CHAN_PLAN_HW); ++ ++ if (!rtw_is_channel_plan_valid(chnlplan)) ++ chnlplan = def_channel_plan; ++ ++ return chnlplan; ++} ++ ++u8 MRateToHwRate(u8 rate) ++{ ++ u8 ret = DESC_RATE1M; ++ ++ switch (rate) { ++ /* CCK and OFDM non-HT rates */ ++ case IEEE80211_CCK_RATE_1MB: ++ ret = DESC_RATE1M; ++ break; ++ case IEEE80211_CCK_RATE_2MB: ++ ret = DESC_RATE2M; ++ break; ++ case IEEE80211_CCK_RATE_5MB: ++ ret = DESC_RATE5_5M; ++ break; ++ case IEEE80211_CCK_RATE_11MB: ++ ret = DESC_RATE11M; ++ break; ++ case IEEE80211_OFDM_RATE_6MB: ++ ret = DESC_RATE6M; ++ break; ++ case IEEE80211_OFDM_RATE_9MB: ++ ret = DESC_RATE9M; ++ break; ++ case IEEE80211_OFDM_RATE_12MB: ++ ret = DESC_RATE12M; ++ break; ++ case IEEE80211_OFDM_RATE_18MB: ++ ret = DESC_RATE18M; ++ break; ++ case IEEE80211_OFDM_RATE_24MB: ++ ret = DESC_RATE24M; ++ break; ++ case IEEE80211_OFDM_RATE_36MB: ++ ret = DESC_RATE36M; ++ break; ++ case IEEE80211_OFDM_RATE_48MB: ++ ret = DESC_RATE48M; ++ break; ++ case IEEE80211_OFDM_RATE_54MB: ++ ret = DESC_RATE54M; ++ break; ++ default: ++ break; ++ } ++ return ret; ++} ++ ++void HalSetBrateCfg(struct adapter *adapt, u8 *brates, u16 *rate_cfg) ++{ ++ u8 i, is_brate, brate; ++ ++ for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { ++ is_brate = brates[i] & IEEE80211_BASIC_RATE_MASK; ++ brate = brates[i] & 0x7f; ++ ++ if (is_brate) { ++ switch (brate) { ++ case IEEE80211_CCK_RATE_1MB: ++ *rate_cfg |= RATE_1M; ++ break; ++ case IEEE80211_CCK_RATE_2MB: ++ *rate_cfg |= RATE_2M; ++ break; ++ case IEEE80211_CCK_RATE_5MB: ++ *rate_cfg |= RATE_5_5M; ++ break; ++ case IEEE80211_CCK_RATE_11MB: ++ *rate_cfg |= RATE_11M; ++ break; ++ case IEEE80211_OFDM_RATE_6MB: ++ *rate_cfg |= RATE_6M; ++ break; ++ case IEEE80211_OFDM_RATE_9MB: ++ *rate_cfg |= RATE_9M; ++ break; ++ case IEEE80211_OFDM_RATE_12MB: ++ *rate_cfg |= RATE_12M; ++ break; ++ case IEEE80211_OFDM_RATE_18MB: ++ *rate_cfg |= RATE_18M; ++ break; ++ case IEEE80211_OFDM_RATE_24MB: ++ *rate_cfg |= RATE_24M; ++ break; ++ case IEEE80211_OFDM_RATE_36MB: ++ *rate_cfg |= RATE_36M; ++ break; ++ case IEEE80211_OFDM_RATE_48MB: ++ *rate_cfg |= RATE_48M; ++ break; ++ case IEEE80211_OFDM_RATE_54MB: ++ *rate_cfg |= RATE_54M; ++ break; ++ } ++ } ++ } ++} ++ ++static void one_out_pipe(struct adapter *adapter) ++{ ++ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapter); ++ ++ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ ++ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */ ++ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */ ++ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */ ++ ++ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ ++ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ ++ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ ++ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ ++} ++ ++static void two_out_pipe(struct adapter *adapter, bool wifi_cfg) ++{ ++ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapter); ++ ++ if (wifi_cfg) { /* WMM */ ++ /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ ++ /* 0, 1, 0, 1, 0, 0, 0, 0, 0}; */ ++ /* 0:H, 1:L */ ++ ++ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */ ++ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */ ++ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */ ++ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */ ++ ++ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ ++ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ ++ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ ++ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ ++ ++ } else {/* typical setting */ ++ /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ ++ /* 1, 1, 0, 0, 0, 0, 0, 0, 0}; */ ++ /* 0:H, 1:L */ ++ ++ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ ++ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */ ++ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */ ++ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */ ++ ++ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ ++ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ ++ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ ++ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ ++ } ++} ++ ++static void three_out_pipe(struct adapter *adapter, bool wifi_cfg) ++{ ++ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapter); ++ ++ if (wifi_cfg) {/* for WMM */ ++ /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ ++ /* 1, 2, 1, 0, 0, 0, 0, 0, 0}; */ ++ /* 0:H, 1:N, 2:L */ ++ ++ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ ++ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */ ++ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */ ++ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */ ++ ++ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ ++ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ ++ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ ++ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ ++ ++ } else {/* typical setting */ ++ /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ ++ /* 2, 2, 1, 0, 0, 0, 0, 0, 0}; */ ++ /* 0:H, 1:N, 2:L */ ++ ++ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ ++ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */ ++ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */ ++ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */ ++ ++ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ ++ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ ++ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ ++ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ ++ } ++} ++ ++bool Hal_MappingOutPipe(struct adapter *adapter, u8 numoutpipe) ++{ ++ struct registry_priv *pregistrypriv = &adapter->registrypriv; ++ bool wifi_cfg = (pregistrypriv->wifi_spec) ? true : false; ++ bool result = true; ++ ++ switch (numoutpipe) { ++ case 2: ++ two_out_pipe(adapter, wifi_cfg); ++ break; ++ case 3: ++ three_out_pipe(adapter, wifi_cfg); ++ break; ++ case 1: ++ one_out_pipe(adapter); ++ break; ++ default: ++ result = false; ++ break; ++ } ++ return result; ++} ++ ++void hal_init_macaddr(struct adapter *adapter) ++{ ++ rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR, ++ adapter->eeprompriv.mac_addr); ++} ++ ++/* ++* C2H event format: ++* Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID ++* BITS [127:120] [119:16] [15:8] [7:4] [3:0] ++*/ ++ ++void c2h_evt_clear(struct adapter *adapter) ++{ ++ rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); ++} ++ ++s32 c2h_evt_read(struct adapter *adapter, u8 *buf) ++{ ++ s32 ret = _FAIL; ++ struct c2h_evt_hdr *c2h_evt; ++ int i; ++ u8 trigger; ++ ++ if (!buf) ++ goto exit; ++ ++ trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR); ++ ++ if (trigger == C2H_EVT_HOST_CLOSE) ++ goto exit; /* Not ready */ ++ else if (trigger != C2H_EVT_FW_CLOSE) ++ goto clear_evt; /* Not a valid value */ ++ ++ c2h_evt = (struct c2h_evt_hdr *)buf; ++ ++ memset(c2h_evt, 0, 16); ++ ++ *buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL); ++ *(buf + 1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1); ++ ++ /* Read the content */ ++ for (i = 0; i < c2h_evt->plen; i++) ++ c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + ++ sizeof(*c2h_evt) + i); ++ ++ ret = _SUCCESS; ++ ++clear_evt: ++ /* ++ * Clear event to notify FW we have read the command. ++ * If this field isn't clear, the FW won't update the next ++ * command message. ++ */ ++ c2h_evt_clear(adapter); ++exit: ++ return ret; ++} +diff --git a/drivers/staging/r8188eu/hal/hal_intf.c b/drivers/staging/r8188eu/hal/hal_intf.c +new file mode 100644 +index 000000000000..a6d589e89aeb +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/hal_intf.c +@@ -0,0 +1,441 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _HAL_INTF_C_ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/hal_intf.h" ++ ++void rtw_hal_chip_configure(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.intf_chip_configure) ++ adapt->HalFunc.intf_chip_configure(adapt); ++} ++ ++void rtw_hal_read_chip_info(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.read_adapter_info) ++ adapt->HalFunc.read_adapter_info(adapt); ++} ++ ++void rtw_hal_read_chip_version(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.read_chip_version) ++ adapt->HalFunc.read_chip_version(adapt); ++} ++ ++void rtw_hal_def_value_init(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.init_default_value) ++ adapt->HalFunc.init_default_value(adapt); ++} ++ ++void rtw_hal_free_data(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.free_hal_data) ++ adapt->HalFunc.free_hal_data(adapt); ++} ++ ++void rtw_hal_dm_init(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.dm_init) ++ adapt->HalFunc.dm_init(adapt); ++} ++ ++void rtw_hal_dm_deinit(struct adapter *adapt) ++{ ++ /* cancel dm timer */ ++ if (adapt->HalFunc.dm_deinit) ++ adapt->HalFunc.dm_deinit(adapt); ++} ++ ++void rtw_hal_sw_led_init(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.InitSwLeds) ++ adapt->HalFunc.InitSwLeds(adapt); ++} ++ ++void rtw_hal_sw_led_deinit(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.DeInitSwLeds) ++ adapt->HalFunc.DeInitSwLeds(adapt); ++} ++ ++u32 rtw_hal_power_on(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.hal_power_on) ++ return adapt->HalFunc.hal_power_on(adapt); ++ return _FAIL; ++} ++ ++uint rtw_hal_init(struct adapter *adapt) ++{ ++ uint status = _SUCCESS; ++ ++ adapt->hw_init_completed = false; ++ ++ status = adapt->HalFunc.hal_init(adapt); ++ ++ if (status == _SUCCESS) { ++ adapt->hw_init_completed = true; ++ ++ if (adapt->registrypriv.notch_filter == 1) ++ rtw_hal_notch_filter(adapt, 1); ++ ++ rtw_hal_reset_security_engine(adapt); ++ } else { ++ adapt->hw_init_completed = false; ++ DBG_88E("rtw_hal_init: hal__init fail\n"); ++ } ++ ++ return status; ++} ++ ++uint rtw_hal_deinit(struct adapter *adapt) ++{ ++ uint status = _SUCCESS; ++ ++ status = adapt->HalFunc.hal_deinit(adapt); ++ ++ if (status == _SUCCESS) ++ adapt->hw_init_completed = false; ++ else ++ DBG_88E("\n rtw_hal_deinit: hal_init fail\n"); ++ ++ return status; ++} ++ ++void rtw_hal_set_hwreg(struct adapter *adapt, u8 variable, u8 *val) ++{ ++ if (adapt->HalFunc.SetHwRegHandler) ++ adapt->HalFunc.SetHwRegHandler(adapt, variable, val); ++} ++ ++void rtw_hal_get_hwreg(struct adapter *adapt, u8 variable, u8 *val) ++{ ++ if (adapt->HalFunc.GetHwRegHandler) ++ adapt->HalFunc.GetHwRegHandler(adapt, variable, val); ++} ++ ++u8 rtw_hal_set_def_var(struct adapter *adapt, enum hal_def_variable var, ++ void *val) ++{ ++ if (adapt->HalFunc.SetHalDefVarHandler) ++ return adapt->HalFunc.SetHalDefVarHandler(adapt, var, val); ++ return _FAIL; ++} ++ ++u8 rtw_hal_get_def_var(struct adapter *adapt, ++ enum hal_def_variable var, void *val) ++{ ++ if (adapt->HalFunc.GetHalDefVarHandler) ++ return adapt->HalFunc.GetHalDefVarHandler(adapt, var, val); ++ return _FAIL; ++} ++ ++void rtw_hal_set_odm_var(struct adapter *adapt, ++ enum hal_odm_variable var, void *val1, ++ bool set) ++{ ++ if (adapt->HalFunc.SetHalODMVarHandler) ++ adapt->HalFunc.SetHalODMVarHandler(adapt, var, ++ val1, set); ++} ++ ++void rtw_hal_get_odm_var(struct adapter *adapt, ++ enum hal_odm_variable var, void *val1, ++ bool set) ++{ ++ if (adapt->HalFunc.GetHalODMVarHandler) ++ adapt->HalFunc.GetHalODMVarHandler(adapt, var, ++ val1, set); ++} ++ ++void rtw_hal_enable_interrupt(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.enable_interrupt) ++ adapt->HalFunc.enable_interrupt(adapt); ++ else ++ DBG_88E("%s: HalFunc.enable_interrupt is NULL!\n", __func__); ++} ++ ++void rtw_hal_disable_interrupt(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.disable_interrupt) ++ adapt->HalFunc.disable_interrupt(adapt); ++ else ++ DBG_88E("%s: HalFunc.disable_interrupt is NULL!\n", __func__); ++} ++ ++u32 rtw_hal_inirp_init(struct adapter *adapt) ++{ ++ u32 rst = _FAIL; ++ ++ if (adapt->HalFunc.inirp_init) ++ rst = adapt->HalFunc.inirp_init(adapt); ++ else ++ DBG_88E(" %s HalFunc.inirp_init is NULL!!!\n", __func__); ++ return rst; ++} ++ ++u32 rtw_hal_inirp_deinit(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.inirp_deinit) ++ return adapt->HalFunc.inirp_deinit(adapt); ++ ++ return _FAIL; ++} ++ ++u8 rtw_hal_intf_ps_func(struct adapter *adapt, ++ enum hal_intf_ps_func efunc_id, u8 *val) ++{ ++ if (adapt->HalFunc.interface_ps_func) ++ return adapt->HalFunc.interface_ps_func(adapt, efunc_id, ++ val); ++ return _FAIL; ++} ++ ++s32 rtw_hal_xmitframe_enqueue(struct adapter *padapter, ++ struct xmit_frame *pxmitframe) ++{ ++ if (padapter->HalFunc.hal_xmitframe_enqueue) ++ return padapter->HalFunc.hal_xmitframe_enqueue(padapter, pxmitframe); ++ return false; ++} ++ ++s32 rtw_hal_xmit(struct adapter *adapt, struct xmit_frame *pxmitframe) ++{ ++ if (adapt->HalFunc.hal_xmit) ++ return adapt->HalFunc.hal_xmit(adapt, pxmitframe); ++ ++ return false; ++} ++ ++s32 rtw_hal_mgnt_xmit(struct adapter *adapt, struct xmit_frame *pmgntframe) ++{ ++ s32 ret = _FAIL; ++ if (adapt->HalFunc.mgnt_xmit) ++ ret = adapt->HalFunc.mgnt_xmit(adapt, pmgntframe); ++ return ret; ++} ++ ++s32 rtw_hal_init_xmit_priv(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.init_xmit_priv) ++ return adapt->HalFunc.init_xmit_priv(adapt); ++ return _FAIL; ++} ++ ++s32 rtw_hal_init_recv_priv(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.init_recv_priv) ++ return adapt->HalFunc.init_recv_priv(adapt); ++ ++ return _FAIL; ++} ++ ++void rtw_hal_free_recv_priv(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.free_recv_priv) ++ adapt->HalFunc.free_recv_priv(adapt); ++} ++ ++void rtw_hal_update_ra_mask(struct adapter *adapt, u32 mac_id, u8 rssi_level) ++{ ++ struct mlme_priv *pmlmepriv = &adapt->mlmepriv; ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++#ifdef CONFIG_88EU_AP_MODE ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &adapt->stapriv; ++ if ((mac_id - 1) > 0) ++ psta = pstapriv->sta_aid[(mac_id - 1) - 1]; ++ if (psta) ++ add_RATid(adapt, psta, 0);/* todo: based on rssi_level*/ ++#endif ++ } else { ++ if (adapt->HalFunc.UpdateRAMaskHandler) ++ adapt->HalFunc.UpdateRAMaskHandler(adapt, mac_id, ++ rssi_level); ++ } ++} ++ ++void rtw_hal_add_ra_tid(struct adapter *adapt, u32 bitmap, u8 arg, ++ u8 rssi_level) ++{ ++ if (adapt->HalFunc.Add_RateATid) ++ adapt->HalFunc.Add_RateATid(adapt, bitmap, arg, ++ rssi_level); ++} ++ ++/* Start specifical interface thread */ ++void rtw_hal_start_thread(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.run_thread) ++ adapt->HalFunc.run_thread(adapt); ++} ++ ++/* Start specifical interface thread */ ++void rtw_hal_stop_thread(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.cancel_thread) ++ adapt->HalFunc.cancel_thread(adapt); ++} ++ ++u32 rtw_hal_read_bbreg(struct adapter *adapt, u32 regaddr, u32 bitmask) ++{ ++ u32 data = 0; ++ ++ if (adapt->HalFunc.read_bbreg) ++ data = adapt->HalFunc.read_bbreg(adapt, regaddr, bitmask); ++ return data; ++} ++ ++void rtw_hal_write_bbreg(struct adapter *adapt, u32 regaddr, u32 bitmask, ++ u32 data) ++{ ++ if (adapt->HalFunc.write_bbreg) ++ adapt->HalFunc.write_bbreg(adapt, regaddr, bitmask, data); ++} ++ ++u32 rtw_hal_read_rfreg(struct adapter *adapt, enum rf_radio_path rfpath, ++ u32 regaddr, u32 bitmask) ++{ ++ u32 data = 0; ++ ++ if (adapt->HalFunc.read_rfreg) ++ data = adapt->HalFunc.read_rfreg(adapt, rfpath, regaddr, ++ bitmask); ++ return data; ++} ++ ++void rtw_hal_write_rfreg(struct adapter *adapt, enum rf_radio_path rfpath, ++ u32 regaddr, u32 bitmask, u32 data) ++{ ++ if (adapt->HalFunc.write_rfreg) ++ adapt->HalFunc.write_rfreg(adapt, rfpath, regaddr, ++ bitmask, data); ++} ++ ++s32 rtw_hal_interrupt_handler(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.interrupt_handler) ++ return adapt->HalFunc.interrupt_handler(adapt); ++ return _FAIL; ++} ++ ++void rtw_hal_set_bwmode(struct adapter *adapt, ++ enum ht_channel_width bandwidth, u8 offset) ++{ ++ if (adapt->HalFunc.set_bwmode_handler) ++ adapt->HalFunc.set_bwmode_handler(adapt, bandwidth, ++ offset); ++} ++ ++void rtw_hal_set_chan(struct adapter *adapt, u8 channel) ++{ ++ if (adapt->HalFunc.set_channel_handler) ++ adapt->HalFunc.set_channel_handler(adapt, channel); ++} ++ ++void rtw_hal_dm_watchdog(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.hal_dm_watchdog) ++ adapt->HalFunc.hal_dm_watchdog(adapt); ++} ++ ++void rtw_hal_bcn_related_reg_setting(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.SetBeaconRelatedRegistersHandler) ++ adapt->HalFunc.SetBeaconRelatedRegistersHandler(adapt); ++} ++ ++u8 rtw_hal_antdiv_before_linked(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.AntDivBeforeLinkHandler) ++ return adapt->HalFunc.AntDivBeforeLinkHandler(adapt); ++ return false; ++} ++ ++void rtw_hal_antdiv_rssi_compared(struct adapter *adapt, ++ struct wlan_bssid_ex *dst, ++ struct wlan_bssid_ex *src) ++{ ++ if (adapt->HalFunc.AntDivCompareHandler) ++ adapt->HalFunc.AntDivCompareHandler(adapt, dst, src); ++} ++ ++void rtw_hal_sreset_init(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.sreset_init_value) ++ adapt->HalFunc.sreset_init_value(adapt); ++} ++ ++void rtw_hal_sreset_reset(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.silentreset) ++ adapt->HalFunc.silentreset(adapt); ++} ++ ++void rtw_hal_sreset_reset_value(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.sreset_reset_value) ++ adapt->HalFunc.sreset_reset_value(adapt); ++} ++ ++void rtw_hal_sreset_xmit_status_check(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.sreset_xmit_status_check) ++ adapt->HalFunc.sreset_xmit_status_check(adapt); ++} ++ ++void rtw_hal_sreset_linked_status_check(struct adapter *adapt) ++{ ++ if (adapt->HalFunc.sreset_linked_status_check) ++ adapt->HalFunc.sreset_linked_status_check(adapt); ++} ++ ++u8 rtw_hal_sreset_get_wifi_status(struct adapter *adapt) ++{ ++ u8 status = 0; ++ ++ if (adapt->HalFunc.sreset_get_wifi_status) ++ status = adapt->HalFunc.sreset_get_wifi_status(adapt); ++ return status; ++} ++ ++int rtw_hal_iol_cmd(struct adapter *adapter, struct xmit_frame *xmit_frame, ++ u32 max_wating_ms, u32 bndy_cnt) ++{ ++ if (adapter->HalFunc.IOL_exec_cmds_sync) ++ return adapter->HalFunc.IOL_exec_cmds_sync(adapter, xmit_frame, ++ max_wating_ms, ++ bndy_cnt); ++ return _FAIL; ++} ++ ++void rtw_hal_notch_filter(struct adapter *adapter, bool enable) ++{ ++ if (adapter->HalFunc.hal_notch_filter) ++ adapter->HalFunc.hal_notch_filter(adapter, enable); ++} ++ ++void rtw_hal_reset_security_engine(struct adapter *adapter) ++{ ++ if (adapter->HalFunc.hal_reset_security_engine) ++ adapter->HalFunc.hal_reset_security_engine(adapter); ++} ++ ++s32 rtw_hal_c2h_handler(struct adapter *adapter, struct c2h_evt_hdr *c2h_evt) ++{ ++ s32 ret = _FAIL; ++ ++ if (adapter->HalFunc.c2h_handler) ++ ret = adapter->HalFunc.c2h_handler(adapter, c2h_evt); ++ return ret; ++} ++ ++c2h_id_filter rtw_hal_c2h_id_filter_ccx(struct adapter *adapter) ++{ ++ return adapter->HalFunc.c2h_id_filter_ccx; ++} +diff --git a/drivers/staging/r8188eu/hal/odm.c b/drivers/staging/r8188eu/hal/odm.c +new file mode 100644 +index 000000000000..ed94f64d878d +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/odm.c +@@ -0,0 +1,1968 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++/* include files */ ++ ++#include "../include/odm_precomp.h" ++ ++static const u16 dB_Invert_Table[8][12] = { ++ {1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4}, ++ {4, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16}, ++ {18, 20, 22, 25, 28, 32, 35, 40, 45, 50, 56, 63}, ++ {71, 79, 89, 100, 112, 126, 141, 158, 178, 200, 224, 251}, ++ {282, 316, 355, 398, 447, 501, 562, 631, 708, 794, 891, 1000}, ++ {1122, 1259, 1413, 1585, 1778, 1995, 2239, 2512, 2818, 3162, 3548, 3981}, ++ {4467, 5012, 5623, 6310, 7079, 7943, 8913, 10000, 11220, 12589, 14125, 15849}, ++ {17783, 19953, 22387, 25119, 28184, 31623, 35481, 39811, 44668, 50119, 56234, 65535} ++}; ++ ++/* avoid to warn in FreeBSD ==> To DO modify */ ++static u32 EDCAParam[HT_IOT_PEER_MAX][3] = { ++ /* UL DL */ ++ {0x5ea42b, 0x5ea42b, 0x5ea42b}, /* 0:unknown AP */ ++ {0xa44f, 0x5ea44f, 0x5e431c}, /* 1:realtek AP */ ++ {0x5ea42b, 0x5ea42b, 0x5ea42b}, /* 2:unknown AP => realtek_92SE */ ++ {0x5ea32b, 0x5ea42b, 0x5e4322}, /* 3:broadcom AP */ ++ {0x5ea422, 0x00a44f, 0x00a44f}, /* 4:ralink AP */ ++ {0x5ea322, 0x00a630, 0x00a44f}, /* 5:atheros AP */ ++ {0x5e4322, 0x5e4322, 0x5e4322},/* 6:cisco AP */ ++ {0x5ea44f, 0x00a44f, 0x5ea42b}, /* 8:marvell AP */ ++ {0x5ea42b, 0x5ea42b, 0x5ea42b}, /* 10:unknown AP=> 92U AP */ ++ {0x5ea42b, 0xa630, 0x5e431c}, /* 11:airgocap AP */ ++}; ++ ++/* Global var */ ++u32 OFDMSwingTable[OFDM_TABLE_SIZE_92D] = { ++ 0x7f8001fe, /* 0, +6.0dB */ ++ 0x788001e2, /* 1, +5.5dB */ ++ 0x71c001c7, /* 2, +5.0dB */ ++ 0x6b8001ae, /* 3, +4.5dB */ ++ 0x65400195, /* 4, +4.0dB */ ++ 0x5fc0017f, /* 5, +3.5dB */ ++ 0x5a400169, /* 6, +3.0dB */ ++ 0x55400155, /* 7, +2.5dB */ ++ 0x50800142, /* 8, +2.0dB */ ++ 0x4c000130, /* 9, +1.5dB */ ++ 0x47c0011f, /* 10, +1.0dB */ ++ 0x43c0010f, /* 11, +0.5dB */ ++ 0x40000100, /* 12, +0dB */ ++ 0x3c8000f2, /* 13, -0.5dB */ ++ 0x390000e4, /* 14, -1.0dB */ ++ 0x35c000d7, /* 15, -1.5dB */ ++ 0x32c000cb, /* 16, -2.0dB */ ++ 0x300000c0, /* 17, -2.5dB */ ++ 0x2d4000b5, /* 18, -3.0dB */ ++ 0x2ac000ab, /* 19, -3.5dB */ ++ 0x288000a2, /* 20, -4.0dB */ ++ 0x26000098, /* 21, -4.5dB */ ++ 0x24000090, /* 22, -5.0dB */ ++ 0x22000088, /* 23, -5.5dB */ ++ 0x20000080, /* 24, -6.0dB */ ++ 0x1e400079, /* 25, -6.5dB */ ++ 0x1c800072, /* 26, -7.0dB */ ++ 0x1b00006c, /* 27. -7.5dB */ ++ 0x19800066, /* 28, -8.0dB */ ++ 0x18000060, /* 29, -8.5dB */ ++ 0x16c0005b, /* 30, -9.0dB */ ++ 0x15800056, /* 31, -9.5dB */ ++ 0x14400051, /* 32, -10.0dB */ ++ 0x1300004c, /* 33, -10.5dB */ ++ 0x12000048, /* 34, -11.0dB */ ++ 0x11000044, /* 35, -11.5dB */ ++ 0x10000040, /* 36, -12.0dB */ ++ 0x0f00003c,/* 37, -12.5dB */ ++ 0x0e400039,/* 38, -13.0dB */ ++ 0x0d800036,/* 39, -13.5dB */ ++ 0x0cc00033,/* 40, -14.0dB */ ++ 0x0c000030,/* 41, -14.5dB */ ++ 0x0b40002d,/* 42, -15.0dB */ ++}; ++ ++u8 CCKSwingTable_Ch1_Ch13[CCK_TABLE_SIZE][8] = { ++ {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */ ++ {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */ ++ {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB */ ++ {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB */ ++ {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */ ++ {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB */ ++ {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB */ ++ {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB */ ++ {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */ ++ {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB */ ++ {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */ ++ {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB */ ++ {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB */ ++ {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB */ ++ {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */ ++ {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB */ ++ {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */ ++ {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB */ ++ {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */ ++ {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB */ ++ {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB */ ++ {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB */ ++ {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB */ ++ {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB */ ++ {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB */ ++ {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB */ ++ {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB */ ++ {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB */ ++ {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB */ ++ {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB */ ++ {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB */ ++ {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB */ ++ {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB */ ++}; ++ ++u8 CCKSwingTable_Ch14[CCK_TABLE_SIZE][8] = { ++ {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */ ++ {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */ ++ {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */ ++ {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB */ ++ {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */ ++ {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB */ ++ {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */ ++ {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */ ++ {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */ ++ {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB */ ++ {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */ ++ {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB */ ++ {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB */ ++ {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */ ++ {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */ ++ {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB */ ++ {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */ ++ {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB */ ++ {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */ ++ {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB */ ++ {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB */ ++ {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB */ ++ {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB */ ++ {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB */ ++ {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB */ ++ {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB */ ++ {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB */ ++ {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB */ ++ {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB */ ++ {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB */ ++ {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB */ ++ {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB */ ++ {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB */ ++}; ++ ++#define RxDefaultAnt1 0x65a9 ++#define RxDefaultAnt2 0x569a ++ ++/* 3 Export Interface */ ++ ++/* 2011/09/21 MH Add to describe different team necessary resource allocate?? */ ++void ODM_DMInit(struct odm_dm_struct *pDM_Odm) ++{ ++ /* 2012.05.03 Luke: For all IC series */ ++ odm_CommonInfoSelfInit(pDM_Odm); ++ odm_DIGInit(pDM_Odm); ++ odm_RateAdaptiveMaskInit(pDM_Odm); ++ ++ if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) { ++ ; ++ } else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) { ++ odm_PrimaryCCA_Init(pDM_Odm); /* Gary */ ++ odm_DynamicBBPowerSavingInit(pDM_Odm); ++ odm_DynamicTxPowerInit(pDM_Odm); ++ odm_TXPowerTrackingInit(pDM_Odm); ++ ODM_EdcaTurboInit(pDM_Odm); ++ ODM_RAInfo_Init_all(pDM_Odm); ++ if ((pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) || ++ (pDM_Odm->AntDivType == CGCS_RX_HW_ANTDIV) || ++ (pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV)) ++ odm_InitHybridAntDiv(pDM_Odm); ++ else if (pDM_Odm->AntDivType == CGCS_RX_SW_ANTDIV) ++ odm_SwAntDivInit(pDM_Odm); ++ } ++} ++ ++/* 2011/09/20 MH This is the entry pointer for all team to execute HW out source DM. */ ++/* You can not add any dummy function here, be care, you can only use DM structure */ ++/* to perform any new ODM_DM. */ ++void ODM_DMWatchdog(struct odm_dm_struct *pDM_Odm) ++{ ++ /* 2012.05.03 Luke: For all IC series */ ++ odm_GlobalAdapterCheck(); ++ odm_CommonInfoSelfUpdate(pDM_Odm); ++ odm_FalseAlarmCounterStatistics(pDM_Odm); ++ odm_RSSIMonitorCheck(pDM_Odm); ++ ++ /* For CE Platform(SPRD or Tablet) */ ++ /* 8723A or 8189ES platform */ ++ /* NeilChen--2012--08--24-- */ ++ /* Fix Leave LPS issue */ ++ if ((pDM_Odm->Adapter->pwrctrlpriv.pwr_mode != PS_MODE_ACTIVE) &&/* in LPS mode */ ++ ((pDM_Odm->SupportICType & (ODM_RTL8723A)) || ++ (pDM_Odm->SupportICType & (ODM_RTL8188E) && ++ ((pDM_Odm->SupportInterface == ODM_ITRF_SDIO))))) ++ odm_DIGbyRSSI_LPS(pDM_Odm); ++ else ++ odm_DIG(pDM_Odm); ++ odm_CCKPacketDetectionThresh(pDM_Odm); ++ ++ if (*pDM_Odm->pbPowerSaving) ++ return; ++ ++ odm_RefreshRateAdaptiveMask(pDM_Odm); ++ ++ odm_DynamicBBPowerSaving(pDM_Odm); ++ if ((pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) || ++ (pDM_Odm->AntDivType == CGCS_RX_HW_ANTDIV) || ++ (pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV)) ++ odm_HwAntDiv(pDM_Odm); ++ else if (pDM_Odm->AntDivType == CGCS_RX_SW_ANTDIV) ++ odm_SwAntDivChkAntSwitch(pDM_Odm, SWAW_STEP_PEAK); ++ ++ if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) { ++ ; ++ } else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) { ++ ODM_TXPowerTrackingCheck(pDM_Odm); ++ odm_EdcaTurboCheck(pDM_Odm); ++ odm_DynamicTxPower(pDM_Odm); ++ } ++ odm_dtc(pDM_Odm); ++} ++ ++/* Init /.. Fixed HW value. Only init time. */ ++void ODM_CmnInfoInit(struct odm_dm_struct *pDM_Odm, enum odm_common_info_def CmnInfo, u32 Value) ++{ ++ /* This section is used for init value */ ++ switch (CmnInfo) { ++ /* Fixed ODM value. */ ++ case ODM_CMNINFO_ABILITY: ++ pDM_Odm->SupportAbility = (u32)Value; ++ break; ++ case ODM_CMNINFO_PLATFORM: ++ pDM_Odm->SupportPlatform = (u8)Value; ++ break; ++ case ODM_CMNINFO_INTERFACE: ++ pDM_Odm->SupportInterface = (u8)Value; ++ break; ++ case ODM_CMNINFO_MP_TEST_CHIP: ++ pDM_Odm->bIsMPChip = (u8)Value; ++ break; ++ case ODM_CMNINFO_IC_TYPE: ++ pDM_Odm->SupportICType = Value; ++ break; ++ case ODM_CMNINFO_CUT_VER: ++ pDM_Odm->CutVersion = (u8)Value; ++ break; ++ case ODM_CMNINFO_FAB_VER: ++ pDM_Odm->FabVersion = (u8)Value; ++ break; ++ case ODM_CMNINFO_RF_TYPE: ++ pDM_Odm->RFType = (u8)Value; ++ break; ++ case ODM_CMNINFO_RF_ANTENNA_TYPE: ++ pDM_Odm->AntDivType = (u8)Value; ++ break; ++ case ODM_CMNINFO_BOARD_TYPE: ++ pDM_Odm->BoardType = (u8)Value; ++ break; ++ case ODM_CMNINFO_EXT_LNA: ++ pDM_Odm->ExtLNA = (u8)Value; ++ break; ++ case ODM_CMNINFO_EXT_PA: ++ pDM_Odm->ExtPA = (u8)Value; ++ break; ++ case ODM_CMNINFO_EXT_TRSW: ++ pDM_Odm->ExtTRSW = (u8)Value; ++ break; ++ case ODM_CMNINFO_PATCH_ID: ++ pDM_Odm->PatchID = (u8)Value; ++ break; ++ case ODM_CMNINFO_BINHCT_TEST: ++ pDM_Odm->bInHctTest = (bool)Value; ++ break; ++ case ODM_CMNINFO_BWIFI_TEST: ++ pDM_Odm->bWIFITest = (bool)Value; ++ break; ++ case ODM_CMNINFO_SMART_CONCURRENT: ++ pDM_Odm->bDualMacSmartConcurrent = (bool)Value; ++ break; ++ /* To remove the compiler warning, must add an empty default statement to handle the other values. */ ++ default: ++ /* do nothing */ ++ break; ++ } ++ ++ /* Tx power tracking BB swing table. */ ++ /* The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */ ++ pDM_Odm->BbSwingIdxOfdm = 12; /* Set defalut value as index 12. */ ++ pDM_Odm->BbSwingIdxOfdmCurrent = 12; ++ pDM_Odm->BbSwingFlagOfdm = false; ++} ++ ++void ODM_CmnInfoHook(struct odm_dm_struct *pDM_Odm, enum odm_common_info_def CmnInfo, void *pValue) ++{ ++ /* */ ++ /* Hook call by reference pointer. */ ++ /* */ ++ switch (CmnInfo) { ++ /* Dynamic call by reference pointer. */ ++ case ODM_CMNINFO_MAC_PHY_MODE: ++ pDM_Odm->pMacPhyMode = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_TX_UNI: ++ pDM_Odm->pNumTxBytesUnicast = (u64 *)pValue; ++ break; ++ case ODM_CMNINFO_RX_UNI: ++ pDM_Odm->pNumRxBytesUnicast = (u64 *)pValue; ++ break; ++ case ODM_CMNINFO_WM_MODE: ++ pDM_Odm->pWirelessMode = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_BAND: ++ pDM_Odm->pBandType = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_SEC_CHNL_OFFSET: ++ pDM_Odm->pSecChOffset = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_SEC_MODE: ++ pDM_Odm->pSecurity = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_BW: ++ pDM_Odm->pBandWidth = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_CHNL: ++ pDM_Odm->pChannel = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_DMSP_GET_VALUE: ++ pDM_Odm->pbGetValueFromOtherMac = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_BUDDY_ADAPTOR: ++ pDM_Odm->pBuddyAdapter = (struct adapter **)pValue; ++ break; ++ case ODM_CMNINFO_DMSP_IS_MASTER: ++ pDM_Odm->pbMasterOfDMSP = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_SCAN: ++ pDM_Odm->pbScanInProcess = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_POWER_SAVING: ++ pDM_Odm->pbPowerSaving = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_ONE_PATH_CCA: ++ pDM_Odm->pOnePathCCA = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_DRV_STOP: ++ pDM_Odm->pbDriverStopped = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_PNP_IN: ++ pDM_Odm->pbDriverIsGoingToPnpSetPowerSleep = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_INIT_ON: ++ pDM_Odm->pinit_adpt_in_progress = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_ANT_TEST: ++ pDM_Odm->pAntennaTest = (u8 *)pValue; ++ break; ++ case ODM_CMNINFO_NET_CLOSED: ++ pDM_Odm->pbNet_closed = (bool *)pValue; ++ break; ++ case ODM_CMNINFO_MP_MODE: ++ pDM_Odm->mp_mode = (u8 *)pValue; ++ break; ++ /* To remove the compiler warning, must add an empty default statement to handle the other values. */ ++ default: ++ /* do nothing */ ++ break; ++ } ++} ++ ++void ODM_CmnInfoPtrArrayHook(struct odm_dm_struct *pDM_Odm, enum odm_common_info_def CmnInfo, u16 Index, void *pValue) ++{ ++ /* Hook call by reference pointer. */ ++ switch (CmnInfo) { ++ /* Dynamic call by reference pointer. */ ++ case ODM_CMNINFO_STA_STATUS: ++ pDM_Odm->pODM_StaInfo[Index] = (struct sta_info *)pValue; ++ break; ++ /* To remove the compiler warning, must add an empty default statement to handle the other values. */ ++ default: ++ /* do nothing */ ++ break; ++ } ++} ++ ++/* Update Band/CHannel/.. The values are dynamic but non-per-packet. */ ++void ODM_CmnInfoUpdate(struct odm_dm_struct *pDM_Odm, u32 CmnInfo, u64 Value) ++{ ++ /* */ ++ /* This init variable may be changed in run time. */ ++ /* */ ++ switch (CmnInfo) { ++ case ODM_CMNINFO_ABILITY: ++ pDM_Odm->SupportAbility = (u32)Value; ++ break; ++ case ODM_CMNINFO_RF_TYPE: ++ pDM_Odm->RFType = (u8)Value; ++ break; ++ case ODM_CMNINFO_WIFI_DIRECT: ++ pDM_Odm->bWIFI_Direct = (bool)Value; ++ break; ++ case ODM_CMNINFO_WIFI_DISPLAY: ++ pDM_Odm->bWIFI_Display = (bool)Value; ++ break; ++ case ODM_CMNINFO_LINK: ++ pDM_Odm->bLinked = (bool)Value; ++ break; ++ case ODM_CMNINFO_RSSI_MIN: ++ pDM_Odm->RSSI_Min = (u8)Value; ++ break; ++ case ODM_CMNINFO_RA_THRESHOLD_HIGH: ++ pDM_Odm->RateAdaptive.HighRSSIThresh = (u8)Value; ++ break; ++ case ODM_CMNINFO_RA_THRESHOLD_LOW: ++ pDM_Odm->RateAdaptive.LowRSSIThresh = (u8)Value; ++ break; ++ } ++} ++ ++void odm_CommonInfoSelfInit(struct odm_dm_struct *pDM_Odm) ++{ ++ pDM_Odm->bCckHighPower = (bool)ODM_GetBBReg(pDM_Odm, 0x824, BIT(9)); ++ pDM_Odm->RFPathRxEnable = (u8)ODM_GetBBReg(pDM_Odm, 0xc04, 0x0F); ++ if (pDM_Odm->SupportICType & (ODM_RTL8192C | ODM_RTL8192D)) ++ pDM_Odm->AntDivType = CG_TRX_HW_ANTDIV; ++ if (pDM_Odm->SupportICType & (ODM_RTL8723A)) ++ pDM_Odm->AntDivType = CGCS_RX_SW_ANTDIV; ++} ++ ++void odm_CommonInfoSelfUpdate(struct odm_dm_struct *pDM_Odm) ++{ ++ u8 EntryCnt = 0; ++ u8 i; ++ struct sta_info *pEntry; ++ ++ if (*pDM_Odm->pBandWidth == ODM_BW40M) { ++ if (*pDM_Odm->pSecChOffset == 1) ++ pDM_Odm->ControlChannel = *pDM_Odm->pChannel - 2; ++ else if (*pDM_Odm->pSecChOffset == 2) ++ pDM_Odm->ControlChannel = *pDM_Odm->pChannel + 2; ++ } else { ++ pDM_Odm->ControlChannel = *pDM_Odm->pChannel; ++ } ++ ++ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { ++ pEntry = pDM_Odm->pODM_StaInfo[i]; ++ if (IS_STA_VALID(pEntry)) ++ EntryCnt++; ++ } ++ if (EntryCnt == 1) ++ pDM_Odm->bOneEntryOnly = true; ++ else ++ pDM_Odm->bOneEntryOnly = false; ++} ++ ++static int getIGIForDiff(int value_IGI) ++{ ++ #define ONERCCA_LOW_TH 0x30 ++ #define ONERCCA_LOW_DIFF 8 ++ ++ if (value_IGI < ONERCCA_LOW_TH) { ++ if ((ONERCCA_LOW_TH - value_IGI) < ONERCCA_LOW_DIFF) ++ return ONERCCA_LOW_TH; ++ else ++ return value_IGI + ONERCCA_LOW_DIFF; ++ } else { ++ return value_IGI; ++ } ++} ++ ++void ODM_Write_DIG(struct odm_dm_struct *pDM_Odm, u8 CurrentIGI) ++{ ++ struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable; ++ ++ if (pDM_DigTable->CurIGValue != CurrentIGI) { ++ if (pDM_Odm->SupportPlatform & (ODM_CE | ODM_MP)) { ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); ++ if (pDM_Odm->SupportICType != ODM_RTL8188E) ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); ++ } else if (pDM_Odm->SupportPlatform & (ODM_AP | ODM_ADSL)) { ++ switch (*pDM_Odm->pOnePathCCA) { ++ case ODM_CCA_2R: ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); ++ if (pDM_Odm->SupportICType != ODM_RTL8188E) ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); ++ break; ++ case ODM_CCA_1R_A: ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); ++ if (pDM_Odm->SupportICType != ODM_RTL8188E) ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B, pDM_Odm), ODM_BIT(IGI, pDM_Odm), getIGIForDiff(CurrentIGI)); ++ break; ++ case ODM_CCA_1R_B: ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), getIGIForDiff(CurrentIGI)); ++ if (pDM_Odm->SupportICType != ODM_RTL8188E) ++ ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_B, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); ++ break; ++ } ++ } ++ /* pDM_DigTable->PreIGValue = pDM_DigTable->CurIGValue; */ ++ pDM_DigTable->CurIGValue = CurrentIGI; ++ } ++/* Add by Neil Chen to enable edcca to MP Platform */ ++} ++ ++/* Need LPS mode for CE platform --2012--08--24--- */ ++/* 8723AS/8189ES */ ++void odm_DIGbyRSSI_LPS(struct odm_dm_struct *pDM_Odm) ++{ ++ struct adapter *pAdapter = pDM_Odm->Adapter; ++ struct false_alarm_stats *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; ++ ++ u8 RSSI_Lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */ ++ u8 bFwCurrentInPSMode = false; ++ u8 CurrentIGI = pDM_Odm->RSSI_Min; ++ ++ if (!(pDM_Odm->SupportICType & (ODM_RTL8723A | ODM_RTL8188E))) ++ return; ++ ++ CurrentIGI = CurrentIGI + RSSI_OFFSET_DIG; ++ bFwCurrentInPSMode = pAdapter->pwrctrlpriv.bFwCurrentInPSMode; ++ ++ /* Using FW PS mode to make IGI */ ++ if (bFwCurrentInPSMode) { ++ /* Adjust by FA in LPS MODE */ ++ if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_LPS) ++ CurrentIGI = CurrentIGI + 2; ++ else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_LPS) ++ CurrentIGI = CurrentIGI + 1; ++ else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_LPS) ++ CurrentIGI = CurrentIGI - 1; ++ } else { ++ CurrentIGI = RSSI_Lower; ++ } ++ ++ /* Lower bound checking */ ++ ++ /* RSSI Lower bound check */ ++ if ((pDM_Odm->RSSI_Min - 10) > DM_DIG_MIN_NIC) ++ RSSI_Lower = (pDM_Odm->RSSI_Min - 10); ++ else ++ RSSI_Lower = DM_DIG_MIN_NIC; ++ ++ /* Upper and Lower Bound checking */ ++ if (CurrentIGI > DM_DIG_MAX_NIC) ++ CurrentIGI = DM_DIG_MAX_NIC; ++ else if (CurrentIGI < RSSI_Lower) ++ CurrentIGI = RSSI_Lower; ++ ++ ODM_Write_DIG(pDM_Odm, CurrentIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */ ++} ++ ++void odm_DIGInit(struct odm_dm_struct *pDM_Odm) ++{ ++ struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable; ++ ++ pDM_DigTable->CurIGValue = (u8)ODM_GetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm)); ++ pDM_DigTable->RssiLowThresh = DM_DIG_THRESH_LOW; ++ pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH; ++ pDM_DigTable->FALowThresh = DM_false_ALARM_THRESH_LOW; ++ pDM_DigTable->FAHighThresh = DM_false_ALARM_THRESH_HIGH; ++ if (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) { ++ pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; ++ pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC; ++ } else { ++ pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; ++ pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC; ++ } ++ pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT; ++ pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX; ++ pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN; ++ pDM_DigTable->PreCCK_CCAThres = 0xFF; ++ pDM_DigTable->CurCCK_CCAThres = 0x83; ++ pDM_DigTable->ForbiddenIGI = DM_DIG_MIN_NIC; ++ pDM_DigTable->LargeFAHit = 0; ++ pDM_DigTable->Recover_cnt = 0; ++ pDM_DigTable->DIG_Dynamic_MIN_0 = DM_DIG_MIN_NIC; ++ pDM_DigTable->DIG_Dynamic_MIN_1 = DM_DIG_MIN_NIC; ++ pDM_DigTable->bMediaConnect_0 = false; ++ pDM_DigTable->bMediaConnect_1 = false; ++ ++ /* To Initialize pDM_Odm->bDMInitialGainEnable == false to avoid DIG error */ ++ pDM_Odm->bDMInitialGainEnable = true; ++} ++ ++void odm_DIG(struct odm_dm_struct *pDM_Odm) ++{ ++ struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable; ++ struct false_alarm_stats *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; ++ u8 DIG_Dynamic_MIN; ++ u8 DIG_MaxOfMin; ++ bool FirstConnect, FirstDisConnect; ++ u8 dm_dig_max, dm_dig_min; ++ u8 CurrentIGI = pDM_DigTable->CurIGValue; ++ ++ if ((!(pDM_Odm->SupportAbility & ODM_BB_DIG)) || (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))) ++ return; ++ ++ if (*pDM_Odm->pbScanInProcess) ++ return; ++ ++ /* add by Neil Chen to avoid PSD is processing */ ++ if (!pDM_Odm->bDMInitialGainEnable) ++ return; ++ ++ if (pDM_Odm->SupportICType == ODM_RTL8192D) { ++ if (*pDM_Odm->pMacPhyMode == ODM_DMSP) { ++ if (*pDM_Odm->pbMasterOfDMSP) { ++ DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0; ++ FirstConnect = (pDM_Odm->bLinked) && (!pDM_DigTable->bMediaConnect_0); ++ FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0); ++ } else { ++ DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_1; ++ FirstConnect = (pDM_Odm->bLinked) && (!pDM_DigTable->bMediaConnect_1); ++ FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_1); ++ } ++ } else { ++ DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_1; ++ FirstConnect = (pDM_Odm->bLinked) && (!pDM_DigTable->bMediaConnect_1); ++ FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_1); ++ } ++ } else { ++ DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0; ++ FirstConnect = (pDM_Odm->bLinked) && (!pDM_DigTable->bMediaConnect_0); ++ FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0); ++ } ++ ++ /* 1 Boundary Decision */ ++ if ((pDM_Odm->SupportICType & (ODM_RTL8192C | ODM_RTL8723A)) && ++ ((pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) || pDM_Odm->ExtLNA)) { ++ if (pDM_Odm->SupportPlatform & (ODM_AP | ODM_ADSL)) { ++ dm_dig_max = DM_DIG_MAX_AP_HP; ++ dm_dig_min = DM_DIG_MIN_AP_HP; ++ } else { ++ dm_dig_max = DM_DIG_MAX_NIC_HP; ++ dm_dig_min = DM_DIG_MIN_NIC_HP; ++ } ++ DIG_MaxOfMin = DM_DIG_MAX_AP_HP; ++ } else { ++ if (pDM_Odm->SupportPlatform & (ODM_AP | ODM_ADSL)) { ++ dm_dig_max = DM_DIG_MAX_AP; ++ dm_dig_min = DM_DIG_MIN_AP; ++ DIG_MaxOfMin = dm_dig_max; ++ } else { ++ dm_dig_max = DM_DIG_MAX_NIC; ++ dm_dig_min = DM_DIG_MIN_NIC; ++ DIG_MaxOfMin = DM_DIG_MAX_AP; ++ } ++ } ++ if (pDM_Odm->bLinked) { ++ /* 2 8723A Series, offset need to be 10 */ ++ if (pDM_Odm->SupportICType == (ODM_RTL8723A)) { ++ /* 2 Upper Bound */ ++ if ((pDM_Odm->RSSI_Min + 10) > DM_DIG_MAX_NIC) ++ pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; ++ else if ((pDM_Odm->RSSI_Min + 10) < DM_DIG_MIN_NIC) ++ pDM_DigTable->rx_gain_range_max = DM_DIG_MIN_NIC; ++ else ++ pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + 10; ++ /* 2 If BT is Concurrent, need to set Lower Bound */ ++ DIG_Dynamic_MIN = DM_DIG_MIN_NIC; ++ } else { ++ /* 2 Modify DIG upper bound */ ++ if ((pDM_Odm->RSSI_Min + 20) > dm_dig_max) ++ pDM_DigTable->rx_gain_range_max = dm_dig_max; ++ else if ((pDM_Odm->RSSI_Min + 20) < dm_dig_min) ++ pDM_DigTable->rx_gain_range_max = dm_dig_min; ++ else ++ pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + 20; ++ /* 2 Modify DIG lower bound */ ++ if (pDM_Odm->bOneEntryOnly) { ++ if (pDM_Odm->RSSI_Min < dm_dig_min) ++ DIG_Dynamic_MIN = dm_dig_min; ++ else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin) ++ DIG_Dynamic_MIN = DIG_MaxOfMin; ++ else ++ DIG_Dynamic_MIN = pDM_Odm->RSSI_Min; ++ } else if ((pDM_Odm->SupportICType == ODM_RTL8188E) && ++ (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) { ++ /* 1 Lower Bound for 88E AntDiv */ ++ if (pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) ++ DIG_Dynamic_MIN = (u8)pDM_DigTable->AntDiv_RSSI_max; ++ } else { ++ DIG_Dynamic_MIN = dm_dig_min; ++ } ++ } ++ } else { ++ pDM_DigTable->rx_gain_range_max = dm_dig_max; ++ DIG_Dynamic_MIN = dm_dig_min; ++ } ++ ++ /* 1 Modify DIG lower bound, deal with abnormally large false alarm */ ++ if (pFalseAlmCnt->Cnt_all > 10000) { ++ if (pDM_DigTable->LargeFAHit != 3) ++ pDM_DigTable->LargeFAHit++; ++ if (pDM_DigTable->ForbiddenIGI < CurrentIGI) { ++ pDM_DigTable->ForbiddenIGI = CurrentIGI; ++ pDM_DigTable->LargeFAHit = 1; ++ } ++ ++ if (pDM_DigTable->LargeFAHit >= 3) { ++ if ((pDM_DigTable->ForbiddenIGI + 1) > pDM_DigTable->rx_gain_range_max) ++ pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max; ++ else ++ pDM_DigTable->rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 1); ++ pDM_DigTable->Recover_cnt = 3600; /* 3600=2hr */ ++ } ++ ++ } else { ++ /* Recovery mechanism for IGI lower bound */ ++ if (pDM_DigTable->Recover_cnt != 0) { ++ pDM_DigTable->Recover_cnt--; ++ } else { ++ if (pDM_DigTable->LargeFAHit < 3) { ++ if ((pDM_DigTable->ForbiddenIGI - 1) < DIG_Dynamic_MIN) { /* DM_DIG_MIN) */ ++ pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */ ++ pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */ ++ } else { ++ pDM_DigTable->ForbiddenIGI--; ++ pDM_DigTable->rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 1); ++ } ++ } else { ++ pDM_DigTable->LargeFAHit = 0; ++ } ++ } ++ } ++ ++ /* 1 Adjust initial gain by false alarm */ ++ if (pDM_Odm->bLinked) { ++ if (FirstConnect) { ++ CurrentIGI = pDM_Odm->RSSI_Min; ++ } else { ++ if (pDM_Odm->SupportICType == ODM_RTL8192D) { ++ if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_92D) ++ CurrentIGI = CurrentIGI + 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+2; */ ++ else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_92D) ++ CurrentIGI = CurrentIGI + 1; /* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+1; */ ++ else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_92D) ++ CurrentIGI = CurrentIGI - 1;/* pDM_DigTable->CurIGValue =pDM_DigTable->PreIGValue-1; */ ++ } else { ++ if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2) ++ CurrentIGI = CurrentIGI + 4;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+2; */ ++ else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1) ++ CurrentIGI = CurrentIGI + 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+1; */ ++ else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0) ++ CurrentIGI = CurrentIGI - 2;/* pDM_DigTable->CurIGValue =pDM_DigTable->PreIGValue-1; */ ++ } ++ } ++ } else { ++ if (FirstDisConnect) { ++ CurrentIGI = pDM_DigTable->rx_gain_range_min; ++ } else { ++ /* 2012.03.30 LukeLee: enable DIG before link but with very high thresholds */ ++ if (pFalseAlmCnt->Cnt_all > 10000) ++ CurrentIGI = CurrentIGI + 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+2; */ ++ else if (pFalseAlmCnt->Cnt_all > 8000) ++ CurrentIGI = CurrentIGI + 1;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+1; */ ++ else if (pFalseAlmCnt->Cnt_all < 500) ++ CurrentIGI = CurrentIGI - 1;/* pDM_DigTable->CurIGValue =pDM_DigTable->PreIGValue-1; */ ++ } ++ } ++ /* 1 Check initial gain by upper/lower bound */ ++ if (CurrentIGI > pDM_DigTable->rx_gain_range_max) ++ CurrentIGI = pDM_DigTable->rx_gain_range_max; ++ if (CurrentIGI < pDM_DigTable->rx_gain_range_min) ++ CurrentIGI = pDM_DigTable->rx_gain_range_min; ++ ++ /* 2 High power RSSI threshold */ ++ ++ ODM_Write_DIG(pDM_Odm, CurrentIGI);/* ODM_Write_DIG(pDM_Odm, pDM_DigTable->CurIGValue); */ ++ pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked; ++ pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN; ++} ++ ++/* 3============================================================ */ ++/* 3 FASLE ALARM CHECK */ ++/* 3============================================================ */ ++ ++void odm_FalseAlarmCounterStatistics(struct odm_dm_struct *pDM_Odm) ++{ ++ u32 ret_value; ++ struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; ++ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) ++ return; ++ ++ if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) { ++ /* hold ofdm counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1); /* hold page C counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 1); /* hold page D counter */ ++ ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord); ++ FalseAlmCnt->Cnt_Fast_Fsync = (ret_value & 0xffff); ++ FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value & 0xffff0000) >> 16); ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord); ++ FalseAlmCnt->Cnt_OFDM_CCA = (ret_value & 0xffff); ++ FalseAlmCnt->Cnt_Parity_Fail = ((ret_value & 0xffff0000) >> 16); ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord); ++ FalseAlmCnt->Cnt_Rate_Illegal = (ret_value & 0xffff); ++ FalseAlmCnt->Cnt_Crc8_fail = ((ret_value & 0xffff0000) >> 16); ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord); ++ FalseAlmCnt->Cnt_Mcs_fail = (ret_value & 0xffff); ++ ++ FalseAlmCnt->Cnt_Ofdm_fail = FalseAlmCnt->Cnt_Parity_Fail + FalseAlmCnt->Cnt_Rate_Illegal + ++ FalseAlmCnt->Cnt_Crc8_fail + FalseAlmCnt->Cnt_Mcs_fail + ++ FalseAlmCnt->Cnt_Fast_Fsync + FalseAlmCnt->Cnt_SB_Search_fail; ++ ++ if (pDM_Odm->SupportICType == ODM_RTL8188E) { ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_SC_CNT_11N, bMaskDWord); ++ FalseAlmCnt->Cnt_BW_LSC = (ret_value & 0xffff); ++ FalseAlmCnt->Cnt_BW_USC = ((ret_value & 0xffff0000) >> 16); ++ } ++ ++ /* hold cck counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(12), 1); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(14), 1); ++ ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_LSB_11N, bMaskByte0); ++ FalseAlmCnt->Cnt_Cck_fail = ret_value; ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_MSB_11N, bMaskByte3); ++ FalseAlmCnt->Cnt_Cck_fail += (ret_value & 0xff) << 8; ++ ++ ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord); ++ FalseAlmCnt->Cnt_CCK_CCA = ((ret_value & 0xFF) << 8) | ((ret_value & 0xFF00) >> 8); ++ ++ FalseAlmCnt->Cnt_all = (FalseAlmCnt->Cnt_Fast_Fsync + ++ FalseAlmCnt->Cnt_SB_Search_fail + ++ FalseAlmCnt->Cnt_Parity_Fail + ++ FalseAlmCnt->Cnt_Rate_Illegal + ++ FalseAlmCnt->Cnt_Crc8_fail + ++ FalseAlmCnt->Cnt_Mcs_fail + ++ FalseAlmCnt->Cnt_Cck_fail); ++ ++ FalseAlmCnt->Cnt_CCA_all = FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA; ++ ++ if (pDM_Odm->SupportICType >= ODM_RTL8723A) { ++ /* reset false alarm counter registers */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31), 1); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31), 0); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), 1); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), 0); ++ /* update ofdm counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0); /* update page C counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 0); /* update page D counter */ ++ ++ /* reset CCK CCA counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2); ++ /* reset CCK FA counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2); ++ } ++ } else { /* FOR ODM_IC_11AC_SERIES */ ++ /* read OFDM FA counter */ ++ FalseAlmCnt->Cnt_Ofdm_fail = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_11AC, bMaskLWord); ++ FalseAlmCnt->Cnt_Cck_fail = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_11AC, bMaskLWord); ++ FalseAlmCnt->Cnt_all = FalseAlmCnt->Cnt_Ofdm_fail + FalseAlmCnt->Cnt_Cck_fail; ++ ++ /* reset OFDM FA coutner */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0); ++ /* reset CCK FA counter */ ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0); ++ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1); ++ } ++} ++ ++/* 3============================================================ */ ++/* 3 CCK Packet Detect Threshold */ ++/* 3============================================================ */ ++ ++void odm_CCKPacketDetectionThresh(struct odm_dm_struct *pDM_Odm) ++{ ++ u8 CurCCK_CCAThres; ++ struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; ++ ++ if (!(pDM_Odm->SupportAbility & (ODM_BB_CCK_PD | ODM_BB_FA_CNT))) ++ return; ++ if (pDM_Odm->ExtLNA) ++ return; ++ if (pDM_Odm->bLinked) { ++ if (pDM_Odm->RSSI_Min > 25) { ++ CurCCK_CCAThres = 0xcd; ++ } else if ((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10)) { ++ CurCCK_CCAThres = 0x83; ++ } else { ++ if (FalseAlmCnt->Cnt_Cck_fail > 1000) ++ CurCCK_CCAThres = 0x83; ++ else ++ CurCCK_CCAThres = 0x40; ++ } ++ } else { ++ if (FalseAlmCnt->Cnt_Cck_fail > 1000) ++ CurCCK_CCAThres = 0x83; ++ else ++ CurCCK_CCAThres = 0x40; ++ } ++ ODM_Write_CCK_CCA_Thres(pDM_Odm, CurCCK_CCAThres); ++} ++ ++void ODM_Write_CCK_CCA_Thres(struct odm_dm_struct *pDM_Odm, u8 CurCCK_CCAThres) ++{ ++ struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable; ++ ++ if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres) /* modify by Guo.Mingzhi 2012-01-03 */ ++ ODM_Write1Byte(pDM_Odm, ODM_REG(CCK_CCA, pDM_Odm), CurCCK_CCAThres); ++ pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres; ++ pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres; ++} ++ ++/* 3============================================================ */ ++/* 3 BB Power Save */ ++/* 3============================================================ */ ++void odm_DynamicBBPowerSavingInit(struct odm_dm_struct *pDM_Odm) ++{ ++ struct rtl_ps *pDM_PSTable = &pDM_Odm->DM_PSTable; ++ ++ pDM_PSTable->pre_cca_state = CCA_MAX; ++ pDM_PSTable->cur_cca_state = CCA_MAX; ++ pDM_PSTable->pre_rf_state = RF_MAX; ++ pDM_PSTable->cur_rf_state = RF_MAX; ++ pDM_PSTable->rssi_val_min = 0; ++ pDM_PSTable->initialize = 0; ++} ++ ++void odm_DynamicBBPowerSaving(struct odm_dm_struct *pDM_Odm) ++{ ++ if ((pDM_Odm->SupportICType != ODM_RTL8192C) && (pDM_Odm->SupportICType != ODM_RTL8723A)) ++ return; ++ if (!(pDM_Odm->SupportAbility & ODM_BB_PWR_SAVE)) ++ return; ++ if (!(pDM_Odm->SupportPlatform & (ODM_MP | ODM_CE))) ++ return; ++ ++ /* 1 2.Power Saving for 92C */ ++ if ((pDM_Odm->SupportICType == ODM_RTL8192C) && (pDM_Odm->RFType == ODM_2T2R)) { ++ odm_1R_CCA(pDM_Odm); ++ } else { ++ /* 20100628 Joseph: Turn off BB power save for 88CE because it makesthroughput unstable. */ ++ /* 20100831 Joseph: Turn ON BB power save again after modifying AGC delay from 900ns ot 600ns. */ ++ /* 1 3.Power Saving for 88C */ ++ ODM_RF_Saving(pDM_Odm, false); ++ } ++} ++ ++void odm_1R_CCA(struct odm_dm_struct *pDM_Odm) ++{ ++ struct rtl_ps *pDM_PSTable = &pDM_Odm->DM_PSTable; ++ ++ if (pDM_Odm->RSSI_Min != 0xFF) { ++ if (pDM_PSTable->pre_cca_state == CCA_2R) { ++ if (pDM_Odm->RSSI_Min >= 35) ++ pDM_PSTable->cur_cca_state = CCA_1R; ++ else ++ pDM_PSTable->cur_cca_state = CCA_2R; ++ } else { ++ if (pDM_Odm->RSSI_Min <= 30) ++ pDM_PSTable->cur_cca_state = CCA_2R; ++ else ++ pDM_PSTable->cur_cca_state = CCA_1R; ++ } ++ } else { ++ pDM_PSTable->cur_cca_state = CCA_MAX; ++ } ++ ++ if (pDM_PSTable->pre_cca_state != pDM_PSTable->cur_cca_state) { ++ if (pDM_PSTable->cur_cca_state == CCA_1R) { ++ if (pDM_Odm->RFType == ODM_2T2R) ++ ODM_SetBBReg(pDM_Odm, 0xc04, bMaskByte0, 0x13); ++ else ++ ODM_SetBBReg(pDM_Odm, 0xc04, bMaskByte0, 0x23); ++ } else { ++ ODM_SetBBReg(pDM_Odm, 0xc04, bMaskByte0, 0x33); ++ } ++ pDM_PSTable->pre_cca_state = pDM_PSTable->cur_cca_state; ++ } ++} ++ ++void ODM_RF_Saving(struct odm_dm_struct *pDM_Odm, u8 bForceInNormal) ++{ ++ struct rtl_ps *pDM_PSTable = &pDM_Odm->DM_PSTable; ++ u8 Rssi_Up_bound = 30; ++ u8 Rssi_Low_bound = 25; ++ ++ if (pDM_Odm->PatchID == 40) { /* RT_CID_819x_FUNAI_TV */ ++ Rssi_Up_bound = 50; ++ Rssi_Low_bound = 45; ++ } ++ if (pDM_PSTable->initialize == 0) { ++ pDM_PSTable->reg_874 = (ODM_GetBBReg(pDM_Odm, 0x874, bMaskDWord) & 0x1CC000) >> 14; ++ pDM_PSTable->reg_c70 = (ODM_GetBBReg(pDM_Odm, 0xc70, bMaskDWord) & BIT(3)) >> 3; ++ pDM_PSTable->reg_85c = (ODM_GetBBReg(pDM_Odm, 0x85c, bMaskDWord) & 0xFF000000) >> 24; ++ pDM_PSTable->reg_a74 = (ODM_GetBBReg(pDM_Odm, 0xa74, bMaskDWord) & 0xF000) >> 12; ++ pDM_PSTable->initialize = 1; ++ } ++ ++ if (!bForceInNormal) { ++ if (pDM_Odm->RSSI_Min != 0xFF) { ++ if (pDM_PSTable->pre_rf_state == RF_Normal) { ++ if (pDM_Odm->RSSI_Min >= Rssi_Up_bound) ++ pDM_PSTable->cur_rf_state = RF_Save; ++ else ++ pDM_PSTable->cur_rf_state = RF_Normal; ++ } else { ++ if (pDM_Odm->RSSI_Min <= Rssi_Low_bound) ++ pDM_PSTable->cur_rf_state = RF_Normal; ++ else ++ pDM_PSTable->cur_rf_state = RF_Save; ++ } ++ } else { ++ pDM_PSTable->cur_rf_state = RF_MAX; ++ } ++ } else { ++ pDM_PSTable->cur_rf_state = RF_Normal; ++ } ++ ++ if (pDM_PSTable->pre_rf_state != pDM_PSTable->cur_rf_state) { ++ if (pDM_PSTable->cur_rf_state == RF_Save) { ++ /* 8723 RSSI report will be wrong. Set 0x874[5]=1 when enter BB power saving mode. */ ++ /* Suggested by SD3 Yu-Nan. 2011.01.20. */ ++ if (pDM_Odm->SupportICType == ODM_RTL8723A) ++ ODM_SetBBReg(pDM_Odm, 0x874, BIT(5), 0x1); /* Reg874[5]=1b'1 */ ++ ODM_SetBBReg(pDM_Odm, 0x874, 0x1C0000, 0x2); /* Reg874[20:18]=3'b010 */ ++ ODM_SetBBReg(pDM_Odm, 0xc70, BIT(3), 0); /* RegC70[3]=1'b0 */ ++ ODM_SetBBReg(pDM_Odm, 0x85c, 0xFF000000, 0x63); /* Reg85C[31:24]=0x63 */ ++ ODM_SetBBReg(pDM_Odm, 0x874, 0xC000, 0x2); /* Reg874[15:14]=2'b10 */ ++ ODM_SetBBReg(pDM_Odm, 0xa74, 0xF000, 0x3); /* RegA75[7:4]=0x3 */ ++ ODM_SetBBReg(pDM_Odm, 0x818, BIT(28), 0x0); /* Reg818[28]=1'b0 */ ++ ODM_SetBBReg(pDM_Odm, 0x818, BIT(28), 0x1); /* Reg818[28]=1'b1 */ ++ } else { ++ ODM_SetBBReg(pDM_Odm, 0x874, 0x1CC000, pDM_PSTable->reg_874); ++ ODM_SetBBReg(pDM_Odm, 0xc70, BIT(3), pDM_PSTable->reg_c70); ++ ODM_SetBBReg(pDM_Odm, 0x85c, 0xFF000000, pDM_PSTable->reg_85c); ++ ODM_SetBBReg(pDM_Odm, 0xa74, 0xF000, pDM_PSTable->reg_a74); ++ ODM_SetBBReg(pDM_Odm, 0x818, BIT(28), 0x0); ++ ++ if (pDM_Odm->SupportICType == ODM_RTL8723A) ++ ODM_SetBBReg(pDM_Odm, 0x874, BIT(5), 0x0); /* Reg874[5]=1b'0 */ ++ } ++ pDM_PSTable->pre_rf_state = pDM_PSTable->cur_rf_state; ++ } ++} ++ ++/* 3============================================================ */ ++/* 3 RATR MASK */ ++/* 3============================================================ */ ++/* 3============================================================ */ ++/* 3 Rate Adaptive */ ++/* 3============================================================ */ ++ ++void odm_RateAdaptiveMaskInit(struct odm_dm_struct *pDM_Odm) ++{ ++ struct odm_rate_adapt *pOdmRA = &pDM_Odm->RateAdaptive; ++ ++ pOdmRA->Type = DM_Type_ByDriver; ++ if (pOdmRA->Type == DM_Type_ByDriver) ++ pDM_Odm->bUseRAMask = true; ++ else ++ pDM_Odm->bUseRAMask = false; ++ ++ pOdmRA->RATRState = DM_RATR_STA_INIT; ++ pOdmRA->HighRSSIThresh = 50; ++ pOdmRA->LowRSSIThresh = 20; ++} ++ ++u32 ODM_Get_Rate_Bitmap(struct odm_dm_struct *pDM_Odm, u32 macid, u32 ra_mask, u8 rssi_level) ++{ ++ struct sta_info *pEntry; ++ u32 rate_bitmap = 0x0fffffff; ++ u8 WirelessMode; ++ ++ pEntry = pDM_Odm->pODM_StaInfo[macid]; ++ if (!IS_STA_VALID(pEntry)) ++ return ra_mask; ++ ++ WirelessMode = pEntry->wireless_mode; ++ ++ switch (WirelessMode) { ++ case ODM_WM_B: ++ if (ra_mask & 0x0000000c) /* 11M or 5.5M enable */ ++ rate_bitmap = 0x0000000d; ++ else ++ rate_bitmap = 0x0000000f; ++ break; ++ case (ODM_WM_B | ODM_WM_G): ++ if (rssi_level == DM_RATR_STA_HIGH) ++ rate_bitmap = 0x00000f00; ++ else if (rssi_level == DM_RATR_STA_MIDDLE) ++ rate_bitmap = 0x00000ff0; ++ else ++ rate_bitmap = 0x00000ff5; ++ break; ++ case (ODM_WM_B | ODM_WM_G | ODM_WM_N24G): ++ if (pDM_Odm->RFType == ODM_1T2R || pDM_Odm->RFType == ODM_1T1R) { ++ if (rssi_level == DM_RATR_STA_HIGH) { ++ rate_bitmap = 0x000f0000; ++ } else if (rssi_level == DM_RATR_STA_MIDDLE) { ++ rate_bitmap = 0x000ff000; ++ } else { ++ if (*pDM_Odm->pBandWidth == ODM_BW40M) ++ rate_bitmap = 0x000ff015; ++ else ++ rate_bitmap = 0x000ff005; ++ } ++ } else { ++ if (rssi_level == DM_RATR_STA_HIGH) { ++ rate_bitmap = 0x0f8f0000; ++ } else if (rssi_level == DM_RATR_STA_MIDDLE) { ++ rate_bitmap = 0x0f8ff000; ++ } else { ++ if (*pDM_Odm->pBandWidth == ODM_BW40M) ++ rate_bitmap = 0x0f8ff015; ++ else ++ rate_bitmap = 0x0f8ff005; ++ } ++ } ++ break; ++ default: ++ /* case WIRELESS_11_24N: */ ++ if (pDM_Odm->RFType == RF_1T2R) ++ rate_bitmap = 0x000fffff; ++ else ++ rate_bitmap = 0x0fffffff; ++ break; ++ } ++ ++ return rate_bitmap; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: odm_RefreshRateAdaptiveMask() ++ * ++ * Overview: Update rate table mask according to rssi ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 05/27/2009 hpfan Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++void odm_RefreshRateAdaptiveMask(struct odm_dm_struct *pDM_Odm) ++{ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_RA_MASK)) ++ return; ++ /* */ ++ /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ ++ /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ ++ /* HW dynamic mechanism. */ ++ /* */ ++ switch (pDM_Odm->SupportPlatform) { ++ case ODM_MP: ++ odm_RefreshRateAdaptiveMaskMP(pDM_Odm); ++ break; ++ case ODM_CE: ++ odm_RefreshRateAdaptiveMaskCE(pDM_Odm); ++ break; ++ case ODM_AP: ++ case ODM_ADSL: ++ odm_RefreshRateAdaptiveMaskAPADSL(pDM_Odm); ++ break; ++ } ++} ++ ++void odm_RefreshRateAdaptiveMaskMP(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++void odm_RefreshRateAdaptiveMaskCE(struct odm_dm_struct *pDM_Odm) ++{ ++ u8 i; ++ struct adapter *pAdapter = pDM_Odm->Adapter; ++ ++ if (pAdapter->bDriverStopped) ++ return; ++ ++ if (!pDM_Odm->bUseRAMask) ++ return; ++ ++ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { ++ struct sta_info *pstat = pDM_Odm->pODM_StaInfo[i]; ++ if (IS_STA_VALID(pstat)) { ++ if (ODM_RAStateCheck(pDM_Odm, pstat->rssi_stat.UndecoratedSmoothedPWDB, false, &pstat->rssi_level)) ++ rtw_hal_update_ra_mask(pAdapter, i, pstat->rssi_level); ++ } ++ } ++} ++ ++void odm_RefreshRateAdaptiveMaskAPADSL(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++/* Return Value: bool */ ++/* - true: RATRState is changed. */ ++bool ODM_RAStateCheck(struct odm_dm_struct *pDM_Odm, s32 RSSI, bool bForceUpdate, u8 *pRATRState) ++{ ++ struct odm_rate_adapt *pRA = &pDM_Odm->RateAdaptive; ++ const u8 GoUpGap = 5; ++ u8 HighRSSIThreshForRA = pRA->HighRSSIThresh; ++ u8 LowRSSIThreshForRA = pRA->LowRSSIThresh; ++ u8 RATRState; ++ ++ /* Threshold Adjustment: */ ++ /* when RSSI state trends to go up one or two levels, make sure RSSI is high enough. */ ++ /* Here GoUpGap is added to solve the boundary's level alternation issue. */ ++ switch (*pRATRState) { ++ case DM_RATR_STA_INIT: ++ case DM_RATR_STA_HIGH: ++ break; ++ case DM_RATR_STA_MIDDLE: ++ HighRSSIThreshForRA += GoUpGap; ++ break; ++ case DM_RATR_STA_LOW: ++ HighRSSIThreshForRA += GoUpGap; ++ LowRSSIThreshForRA += GoUpGap; ++ break; ++ default: ++ break; ++ } ++ ++ /* Decide RATRState by RSSI. */ ++ if (RSSI > HighRSSIThreshForRA) ++ RATRState = DM_RATR_STA_HIGH; ++ else if (RSSI > LowRSSIThreshForRA) ++ RATRState = DM_RATR_STA_MIDDLE; ++ else ++ RATRState = DM_RATR_STA_LOW; ++ ++ if (*pRATRState != RATRState || bForceUpdate) { ++ *pRATRState = RATRState; ++ return true; ++ } ++ return false; ++} ++ ++/* 3============================================================ */ ++/* 3 Dynamic Tx Power */ ++/* 3============================================================ */ ++ ++void odm_DynamicTxPowerInit(struct odm_dm_struct *pDM_Odm) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &pHalData->dmpriv; ++ pdmpriv->bDynamicTxPowerEnable = false; ++ pdmpriv->LastDTPLvl = TxHighPwrLevel_Normal; ++ pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; ++} ++ ++void odm_DynamicTxPower(struct odm_dm_struct *pDM_Odm) ++{ ++ /* For AP/ADSL use struct rtl8192cd_priv * */ ++ /* For CE/NIC use struct adapter * */ ++ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_DYNAMIC_TXPWR)) ++ return; ++ ++ /* 2012/01/12 MH According to Luke's suggestion, only high power will support the feature. */ ++ if (!pDM_Odm->ExtPA) ++ return; ++ ++ /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ ++ /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ ++ /* HW dynamic mechanism. */ ++ switch (pDM_Odm->SupportPlatform) { ++ case ODM_MP: ++ case ODM_CE: ++ odm_DynamicTxPowerNIC(pDM_Odm); ++ break; ++ case ODM_AP: ++ odm_DynamicTxPowerAP(pDM_Odm); ++ break; ++ case ODM_ADSL: ++ break; ++ } ++} ++ ++void odm_DynamicTxPowerNIC(struct odm_dm_struct *pDM_Odm) ++{ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_DYNAMIC_TXPWR)) ++ return; ++ ++ if (pDM_Odm->SupportICType == ODM_RTL8188E) { ++ /* ??? */ ++ /* This part need to be redefined. */ ++ } ++} ++ ++void odm_DynamicTxPowerAP(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++/* 3============================================================ */ ++/* 3 RSSI Monitor */ ++/* 3============================================================ */ ++ ++void odm_RSSIMonitorCheck(struct odm_dm_struct *pDM_Odm) ++{ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_RSSI_MONITOR)) ++ return; ++ ++ /* */ ++ /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ ++ /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ ++ /* HW dynamic mechanism. */ ++ /* */ ++ switch (pDM_Odm->SupportPlatform) { ++ case ODM_MP: ++ odm_RSSIMonitorCheckMP(pDM_Odm); ++ break; ++ case ODM_CE: ++ odm_RSSIMonitorCheckCE(pDM_Odm); ++ break; ++ case ODM_AP: ++ odm_RSSIMonitorCheckAP(pDM_Odm); ++ break; ++ case ODM_ADSL: ++ /* odm_DIGAP(pDM_Odm); */ ++ break; ++ } ++ ++} /* odm_RSSIMonitorCheck */ ++ ++void odm_RSSIMonitorCheckMP(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++static void FindMinimumRSSI(struct adapter *pAdapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ struct dm_priv *pdmpriv = &pHalData->dmpriv; ++ struct mlme_priv *pmlmepriv = &pAdapter->mlmepriv; ++ ++ /* 1 1.Determine the minimum RSSI */ ++ if (!check_fwstate(pmlmepriv, _FW_LINKED) && ++ pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0) ++ pdmpriv->MinUndecoratedPWDBForDM = 0; ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) /* Default port */ ++ pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB; ++ else /* associated entry pwdb */ ++ pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB; ++} ++ ++void odm_RSSIMonitorCheckCE(struct odm_dm_struct *pDM_Odm) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &pHalData->dmpriv; ++ int i; ++ int tmpEntryMaxPWDB = 0, tmpEntryMinPWDB = 0xff; ++ u8 sta_cnt = 0; ++ u32 PWDB_rssi[NUM_STA] = {0};/* 0~15]:MACID, [16~31]:PWDB_rssi */ ++ struct sta_info *psta; ++ u8 bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ ++ if (!check_fwstate(&Adapter->mlmepriv, _FW_LINKED)) ++ return; ++ ++ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { ++ psta = pDM_Odm->pODM_StaInfo[i]; ++ if (IS_STA_VALID(psta) && ++ (psta->state & WIFI_ASOC_STATE) && ++ memcmp(psta->hwaddr, bcast_addr, ETH_ALEN) && ++ memcmp(psta->hwaddr, myid(&Adapter->eeprompriv), ETH_ALEN)) { ++ if (psta->rssi_stat.UndecoratedSmoothedPWDB < tmpEntryMinPWDB) ++ tmpEntryMinPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB; ++ ++ if (psta->rssi_stat.UndecoratedSmoothedPWDB > tmpEntryMaxPWDB) ++ tmpEntryMaxPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB; ++ if (psta->rssi_stat.UndecoratedSmoothedPWDB != (-1)) ++ PWDB_rssi[sta_cnt++] = (psta->mac_id | (psta->rssi_stat.UndecoratedSmoothedPWDB << 16)); ++ } ++ } ++ ++ for (i = 0; i < sta_cnt; i++) { ++ if (PWDB_rssi[i] != (0)) { ++ if (pHalData->fw_ractrl) { ++ /* Report every sta's RSSI to FW */ ++ } else { ++ ODM_RA_SetRSSI_8188E( ++ &pHalData->odmpriv, (PWDB_rssi[i] & 0xFF), (u8)((PWDB_rssi[i] >> 16) & 0xFF)); ++ } ++ } ++ } ++ ++ if (tmpEntryMaxPWDB != 0) /* If associated entry is found */ ++ pdmpriv->EntryMaxUndecoratedSmoothedPWDB = tmpEntryMaxPWDB; ++ else ++ pdmpriv->EntryMaxUndecoratedSmoothedPWDB = 0; ++ ++ if (tmpEntryMinPWDB != 0xff) /* If associated entry is found */ ++ pdmpriv->EntryMinUndecoratedSmoothedPWDB = tmpEntryMinPWDB; ++ else ++ pdmpriv->EntryMinUndecoratedSmoothedPWDB = 0; ++ ++ FindMinimumRSSI(Adapter); ++ ODM_CmnInfoUpdate(&pHalData->odmpriv, ODM_CMNINFO_RSSI_MIN, pdmpriv->MinUndecoratedPWDBForDM); ++} ++ ++void odm_RSSIMonitorCheckAP(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++void ODM_InitAllTimers(struct odm_dm_struct *pDM_Odm) ++{ ++ timer_setup(&pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer, odm_SwAntDivChkAntSwitchCallback, 0); ++} ++ ++void ODM_CancelAllTimers(struct odm_dm_struct *pDM_Odm) ++{ ++ ODM_CancelTimer(pDM_Odm, &pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer); ++} ++ ++void ODM_ReleaseAllTimers(struct odm_dm_struct *pDM_Odm) ++{ ++ ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer); ++ ++ ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->FastAntTrainingTimer); ++} ++ ++/* 3============================================================ */ ++/* 3 Tx Power Tracking */ ++/* 3============================================================ */ ++ ++void odm_TXPowerTrackingInit(struct odm_dm_struct *pDM_Odm) ++{ ++ odm_TXPowerTrackingThermalMeterInit(pDM_Odm); ++} ++ ++void odm_TXPowerTrackingThermalMeterInit(struct odm_dm_struct *pDM_Odm) ++{ ++ pDM_Odm->RFCalibrateInfo.bTXPowerTracking = true; ++ pDM_Odm->RFCalibrateInfo.TXPowercount = 0; ++ pDM_Odm->RFCalibrateInfo.bTXPowerTrackingInit = false; ++ if (*pDM_Odm->mp_mode != 1) ++ pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = true; ++ MSG_88E("pDM_Odm TxPowerTrackControl = %d\n", pDM_Odm->RFCalibrateInfo.TxPowerTrackControl); ++ ++ pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = true; ++} ++ ++void ODM_TXPowerTrackingCheck(struct odm_dm_struct *pDM_Odm) ++{ ++ /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ ++ /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ ++ /* HW dynamic mechanism. */ ++ switch (pDM_Odm->SupportPlatform) { ++ case ODM_MP: ++ odm_TXPowerTrackingCheckMP(pDM_Odm); ++ break; ++ case ODM_CE: ++ odm_TXPowerTrackingCheckCE(pDM_Odm); ++ break; ++ case ODM_AP: ++ odm_TXPowerTrackingCheckAP(pDM_Odm); ++ break; ++ case ODM_ADSL: ++ break; ++ } ++} ++ ++void odm_TXPowerTrackingCheckCE(struct odm_dm_struct *pDM_Odm) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ ++ if (!(pDM_Odm->SupportAbility & ODM_RF_TX_PWR_TRACK)) ++ return; ++ ++ if (!pDM_Odm->RFCalibrateInfo.TM_Trigger) { /* at least delay 1 sec */ ++ PHY_SetRFReg(Adapter, RF_PATH_A, RF_T_METER_88E, BIT(17) | BIT(16), 0x03); ++ ++ pDM_Odm->RFCalibrateInfo.TM_Trigger = 1; ++ return; ++ } else { ++ odm_TXPowerTrackingCallback_ThermalMeter_8188E(Adapter); ++ pDM_Odm->RFCalibrateInfo.TM_Trigger = 0; ++ } ++} ++ ++void odm_TXPowerTrackingCheckMP(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++void odm_TXPowerTrackingCheckAP(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++/* antenna mapping info */ ++/* 1: right-side antenna */ ++/* 2/0: left-side antenna */ ++/* PDM_SWAT_Table->CCK_Ant1_Cnt /OFDM_Ant1_Cnt: for right-side antenna: Ant:1 RxDefaultAnt1 */ ++/* PDM_SWAT_Table->CCK_Ant2_Cnt /OFDM_Ant2_Cnt: for left-side antenna: Ant:0 RxDefaultAnt2 */ ++/* We select left antenna as default antenna in initial process, modify it as needed */ ++/* */ ++ ++/* 3============================================================ */ ++/* 3 SW Antenna Diversity */ ++/* 3============================================================ */ ++void odm_SwAntDivInit(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++void ODM_SwAntDivChkPerPktRssi(struct odm_dm_struct *pDM_Odm, u8 StationID, struct odm_phy_status_info *pPhyInfo) ++{ ++} ++ ++void odm_SwAntDivChkAntSwitch(struct odm_dm_struct *pDM_Odm, u8 Step) ++{ ++} ++ ++void ODM_SwAntDivRestAfterLink(struct odm_dm_struct *pDM_Odm) ++{ ++} ++ ++void odm_SwAntDivChkAntSwitchCallback(struct timer_list *t) ++{ ++} ++ ++/* 3============================================================ */ ++/* 3 SW Antenna Diversity */ ++/* 3============================================================ */ ++ ++void odm_InitHybridAntDiv(struct odm_dm_struct *pDM_Odm) ++{ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) ++ return; ++ ++ if (pDM_Odm->SupportICType & (ODM_RTL8192C | ODM_RTL8192D)) ++ ; ++ else if (pDM_Odm->SupportICType == ODM_RTL8188E) ++ ODM_AntennaDiversityInit_88E(pDM_Odm); ++} ++ ++void ODM_AntselStatistics_88C(struct odm_dm_struct *pDM_Odm, u8 MacId, u32 PWDBAll, bool isCCKrate) ++{ ++ struct sw_ant_switch *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; ++ ++ if (pDM_SWAT_Table->antsel == 1) { ++ if (isCCKrate) { ++ pDM_SWAT_Table->CCK_Ant1_Cnt[MacId]++; ++ } else { ++ pDM_SWAT_Table->OFDM_Ant1_Cnt[MacId]++; ++ pDM_SWAT_Table->RSSI_Ant1_Sum[MacId] += PWDBAll; ++ } ++ } else { ++ if (isCCKrate) { ++ pDM_SWAT_Table->CCK_Ant2_Cnt[MacId]++; ++ } else { ++ pDM_SWAT_Table->OFDM_Ant2_Cnt[MacId]++; ++ pDM_SWAT_Table->RSSI_Ant2_Sum[MacId] += PWDBAll; ++ } ++ } ++} ++ ++void odm_HwAntDiv(struct odm_dm_struct *pDM_Odm) ++{ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) ++ return; ++ ++ if (pDM_Odm->SupportICType == ODM_RTL8188E) ++ ODM_AntennaDiversity_88E(pDM_Odm); ++} ++ ++/* EDCA Turbo */ ++void ODM_EdcaTurboInit(struct odm_dm_struct *pDM_Odm) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false; ++ pDM_Odm->DM_EDCA_Table.bIsCurRDLState = false; ++ Adapter->recvpriv.bIsAnyNonBEPkts = false; ++ ++} /* ODM_InitEdcaTurbo */ ++ ++void odm_EdcaTurboCheck(struct odm_dm_struct *pDM_Odm) ++{ ++ /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ ++ /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ ++ /* HW dynamic mechanism. */ ++ if (!(pDM_Odm->SupportAbility & ODM_MAC_EDCA_TURBO)) ++ return; ++ ++ switch (pDM_Odm->SupportPlatform) { ++ case ODM_MP: ++ break; ++ case ODM_CE: ++ odm_EdcaTurboCheckCE(pDM_Odm); ++ break; ++ case ODM_AP: ++ case ODM_ADSL: ++ break; ++ } ++} /* odm_CheckEdcaTurbo */ ++ ++void odm_EdcaTurboCheckCE(struct odm_dm_struct *pDM_Odm) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ u32 trafficIndex; ++ u32 edca_param; ++ u64 cur_tx_bytes = 0; ++ u64 cur_rx_bytes = 0; ++ u8 bbtchange = false; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct xmit_priv *pxmitpriv = &Adapter->xmitpriv; ++ struct recv_priv *precvpriv = &Adapter->recvpriv; ++ struct registry_priv *pregpriv = &Adapter->registrypriv; ++ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (pregpriv->wifi_spec == 1) ++ goto dm_CheckEdcaTurbo_EXIT; ++ ++ if (pmlmeinfo->assoc_AP_vendor >= HT_IOT_PEER_MAX) ++ goto dm_CheckEdcaTurbo_EXIT; ++ ++ /* Check if the status needs to be changed. */ ++ if ((bbtchange) || (!precvpriv->bIsAnyNonBEPkts)) { ++ cur_tx_bytes = pxmitpriv->tx_bytes - pxmitpriv->last_tx_bytes; ++ cur_rx_bytes = precvpriv->rx_bytes - precvpriv->last_rx_bytes; ++ ++ /* traffic, TX or RX */ ++ if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_RALINK) || ++ (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS)) { ++ if (cur_tx_bytes > (cur_rx_bytes << 2)) { ++ /* Uplink TP is present. */ ++ trafficIndex = UP_LINK; ++ } else { ++ /* Balance TP is present. */ ++ trafficIndex = DOWN_LINK; ++ } ++ } else { ++ if (cur_rx_bytes > (cur_tx_bytes << 2)) { ++ /* Downlink TP is present. */ ++ trafficIndex = DOWN_LINK; ++ } else { ++ /* Balance TP is present. */ ++ trafficIndex = UP_LINK; ++ } ++ } ++ ++ if ((pDM_Odm->DM_EDCA_Table.prv_traffic_idx != trafficIndex) || (!pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA)) { ++ if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_CISCO) && (pmlmeext->cur_wireless_mode & WIRELESS_11_24N)) ++ edca_param = EDCAParam[pmlmeinfo->assoc_AP_vendor][trafficIndex]; ++ else ++ edca_param = EDCAParam[HT_IOT_PEER_UNKNOWN][trafficIndex]; ++ ++ rtw_write32(Adapter, REG_EDCA_BE_PARAM, edca_param); ++ ++ pDM_Odm->DM_EDCA_Table.prv_traffic_idx = trafficIndex; ++ } ++ ++ pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = true; ++ } else { ++ /* Turn Off EDCA turbo here. */ ++ /* Restore original EDCA according to the declaration of AP. */ ++ if (pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA) { ++ rtw_write32(Adapter, REG_EDCA_BE_PARAM, pHalData->AcParam_BE); ++ pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false; ++ } ++ } ++ ++dm_CheckEdcaTurbo_EXIT: ++ /* Set variables for next time. */ ++ precvpriv->bIsAnyNonBEPkts = false; ++ pxmitpriv->last_tx_bytes = pxmitpriv->tx_bytes; ++ precvpriv->last_rx_bytes = precvpriv->rx_bytes; ++} ++ ++/* need to ODM CE Platform */ ++/* move to here for ANT detection mechanism using */ ++ ++u32 GetPSDData(struct odm_dm_struct *pDM_Odm, unsigned int point, u8 initial_gain_psd) ++{ ++ u32 psd_report; ++ ++ /* Set DCO frequency index, offset=(40MHz/SamplePts)*point */ ++ ODM_SetBBReg(pDM_Odm, 0x808, 0x3FF, point); ++ ++ /* Start PSD calculation, Reg808[22]=0->1 */ ++ ODM_SetBBReg(pDM_Odm, 0x808, BIT(22), 1); ++ /* Need to wait for HW PSD report */ ++ ODM_StallExecution(30); ++ ODM_SetBBReg(pDM_Odm, 0x808, BIT(22), 0); ++ /* Read PSD report, Reg8B4[15:0] */ ++ psd_report = ODM_GetBBReg(pDM_Odm, 0x8B4, bMaskDWord) & 0x0000FFFF; ++ ++ psd_report = (u32)(ConvertTo_dB(psd_report)) + (u32)(initial_gain_psd - 0x1c); ++ ++ return psd_report; ++} ++ ++u32 ConvertTo_dB(u32 Value) ++{ ++ u8 i; ++ u8 j; ++ u32 dB; ++ ++ Value = Value & 0xFFFF; ++ for (i = 0; i < 8; i++) { ++ if (Value <= dB_Invert_Table[i][11]) ++ break; ++ } ++ ++ if (i >= 8) ++ return 96; /* maximum 96 dB */ ++ ++ for (j = 0; j < 12; j++) { ++ if (Value <= dB_Invert_Table[i][j]) ++ break; ++ } ++ ++ dB = i * 12 + j + 1; ++ ++ return dB; ++} ++ ++/* 2011/09/22 MH Add for 92D global spin lock utilization. */ ++void odm_GlobalAdapterCheck(void) ++{ ++} /* odm_GlobalAdapterCheck */ ++ ++/* Description: */ ++/* Set Single/Dual Antenna default setting for products that do not do detection in advance. */ ++/* Added by Joseph, 2012.03.22 */ ++void ODM_SingleDualAntennaDefaultSetting(struct odm_dm_struct *pDM_Odm) ++{ ++ struct sw_ant_switch *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; ++ ++ pDM_SWAT_Table->ANTA_ON = true; ++ pDM_SWAT_Table->ANTB_ON = true; ++} ++ ++/* 2 8723A ANT DETECT */ ++ ++static void odm_PHY_SaveAFERegisters(struct odm_dm_struct *pDM_Odm, u32 *AFEReg, u32 *AFEBackup, u32 RegisterNum) ++{ ++ u32 i; ++ ++ /* RTPRINT(FINIT, INIT_IQK, ("Save ADDA parameters.\n")); */ ++ for (i = 0; i < RegisterNum; i++) ++ AFEBackup[i] = ODM_GetBBReg(pDM_Odm, AFEReg[i], bMaskDWord); ++} ++ ++static void odm_PHY_ReloadAFERegisters(struct odm_dm_struct *pDM_Odm, u32 *AFEReg, u32 *AFEBackup, u32 RegiesterNum) ++{ ++ u32 i; ++ ++ for (i = 0; i < RegiesterNum; i++) ++ ODM_SetBBReg(pDM_Odm, AFEReg[i], bMaskDWord, AFEBackup[i]); ++} ++ ++/* 2 8723A ANT DETECT */ ++/* Description: */ ++/* Implement IQK single tone for RF DPK loopback and BB PSD scanning. */ ++/* This function is cooperated with BB team Neil. */ ++bool ODM_SingleDualAntennaDetection(struct odm_dm_struct *pDM_Odm, u8 mode) ++{ ++ struct sw_ant_switch *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; ++ u32 CurrentChannel, RfLoopReg; ++ u8 n; ++ u32 Reg88c, Regc08, Reg874, Regc50; ++ u8 initial_gain = 0x5a; ++ u32 PSD_report_tmp; ++ u32 AntA_report = 0x0, AntB_report = 0x0, AntO_report = 0x0; ++ bool bResult = true; ++ u32 AFE_Backup[16]; ++ u32 AFE_REG_8723A[16] = { ++ rRx_Wait_CCA, rTx_CCK_RFON, ++ rTx_CCK_BBON, rTx_OFDM_RFON, ++ rTx_OFDM_BBON, rTx_To_Rx, ++ rTx_To_Tx, rRx_CCK, ++ rRx_OFDM, rRx_Wait_RIFS, ++ rRx_TO_Rx, rStandby, ++ rSleep, rPMPD_ANAEN, ++ rFPGA0_XCD_SwitchControl, rBlue_Tooth}; ++ ++ if (!(pDM_Odm->SupportICType & (ODM_RTL8723A | ODM_RTL8192C))) ++ return bResult; ++ ++ if (!(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) ++ return bResult; ++ ++ if (pDM_Odm->SupportICType == ODM_RTL8192C) { ++ /* Which path in ADC/DAC is turnned on for PSD: both I/Q */ ++ ODM_SetBBReg(pDM_Odm, 0x808, BIT(10) | BIT(11), 0x3); ++ /* Ageraged number: 8 */ ++ ODM_SetBBReg(pDM_Odm, 0x808, BIT(12) | BIT(13), 0x1); ++ /* pts = 128; */ ++ ODM_SetBBReg(pDM_Odm, 0x808, BIT(14) | BIT(15), 0x0); ++ } ++ ++ /* 1 Backup Current RF/BB Settings */ ++ ++ CurrentChannel = ODM_GetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask); ++ RfLoopReg = ODM_GetRFReg(pDM_Odm, RF_PATH_A, 0x00, bRFRegOffsetMask); ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, ODM_DPDT, Antenna_A); /* change to Antenna A */ ++ /* Step 1: USE IQK to transmitter single tone */ ++ ++ ODM_StallExecution(10); ++ ++ /* Store A Path Register 88c, c08, 874, c50 */ ++ Reg88c = ODM_GetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord); ++ Regc08 = ODM_GetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord); ++ Reg874 = ODM_GetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord); ++ Regc50 = ODM_GetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskDWord); ++ ++ /* Store AFE Registers */ ++ odm_PHY_SaveAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16); ++ ++ /* Set PSD 128 pts */ ++ ODM_SetBBReg(pDM_Odm, rFPGA0_PSDFunction, BIT(14) | BIT(15), 0x0); /* 128 pts */ ++ ++ /* To SET CH1 to do */ ++ ODM_SetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask, 0x01); /* Channel 1 */ ++ ++ /* AFE all on step */ ++ ODM_SetBBReg(pDM_Odm, rRx_Wait_CCA, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rTx_CCK_RFON, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rTx_CCK_BBON, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rTx_OFDM_RFON, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rTx_OFDM_BBON, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rTx_To_Rx, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rTx_To_Tx, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rRx_CCK, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rRx_OFDM, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rRx_Wait_RIFS, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rRx_TO_Rx, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rStandby, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rSleep, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rPMPD_ANAEN, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_SwitchControl, bMaskDWord, 0x6FDB25A4); ++ ODM_SetBBReg(pDM_Odm, rBlue_Tooth, bMaskDWord, 0x6FDB25A4); ++ ++ /* 3 wire Disable */ ++ ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord, 0xCCF000C0); ++ ++ /* BB IQK Setting */ ++ ODM_SetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord, 0x000800E4); ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22208000); ++ ++ /* IQK setting tone@ 4.34Mhz */ ++ ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x10008C1C); ++ ODM_SetBBReg(pDM_Odm, rTx_IQK, bMaskDWord, 0x01007c00); ++ ++ /* Page B init */ ++ ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x00080000); ++ ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x0f600000); ++ ODM_SetBBReg(pDM_Odm, rRx_IQK, bMaskDWord, 0x01004800); ++ ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x10008c1f); ++ ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x82150008); ++ ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_A, bMaskDWord, 0x28150008); ++ ODM_SetBBReg(pDM_Odm, rIQK_AGC_Rsp, bMaskDWord, 0x001028d0); ++ ++ /* RF loop Setting */ ++ ODM_SetRFReg(pDM_Odm, RF_PATH_A, 0x0, 0xFFFFF, 0x50008); ++ ++ /* IQK Single tone start */ ++ ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskDWord, 0x80800000); ++ ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); ++ ODM_StallExecution(1000); ++ PSD_report_tmp = 0x0; ++ ++ for (n = 0; n < 2; n++) { ++ PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain); ++ if (PSD_report_tmp > AntA_report) ++ AntA_report = PSD_report_tmp; ++ } ++ ++ PSD_report_tmp = 0x0; ++ ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_B); /* change to Antenna B */ ++ ODM_StallExecution(10); ++ ++ for (n = 0; n < 2; n++) { ++ PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain); ++ if (PSD_report_tmp > AntB_report) ++ AntB_report = PSD_report_tmp; ++ } ++ ++ /* change to open case */ ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, 0); /* change to Ant A and B all open case */ ++ ODM_StallExecution(10); ++ ++ for (n = 0; n < 2; n++) { ++ PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain); ++ if (PSD_report_tmp > AntO_report) ++ AntO_report = PSD_report_tmp; ++ } ++ ++ /* Close IQK Single Tone function */ ++ ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskDWord, 0x00000000); ++ PSD_report_tmp = 0x0; ++ ++ /* 1 Return to antanna A */ ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_A); ++ ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord, Reg88c); ++ ODM_SetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord, Regc08); ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, Reg874); ++ ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, 0x7F, 0x40); ++ ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskDWord, Regc50); ++ ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, CurrentChannel); ++ ODM_SetRFReg(pDM_Odm, RF_PATH_A, 0x00, bRFRegOffsetMask, RfLoopReg); ++ ++ /* Reload AFE Registers */ ++ odm_PHY_ReloadAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16); ++ ++ if (pDM_Odm->SupportICType == ODM_RTL8723A) { ++ /* 2 Test Ant B based on Ant A is ON */ ++ if (mode == ANTTESTB) { ++ if (AntA_report >= 100) { ++ if (AntB_report > (AntA_report + 1)) ++ pDM_SWAT_Table->ANTB_ON = false; ++ else ++ pDM_SWAT_Table->ANTB_ON = true; ++ } else { ++ pDM_SWAT_Table->ANTB_ON = false; /* Set Antenna B off as default */ ++ bResult = false; ++ } ++ } else if (mode == ANTTESTALL) { ++ /* 2 Test Ant A and B based on DPDT Open */ ++ if ((AntO_report >= 100) & (AntO_report < 118)) { ++ if (AntA_report > (AntO_report + 1)) ++ pDM_SWAT_Table->ANTA_ON = false; ++ else ++ pDM_SWAT_Table->ANTA_ON = true; ++ ++ if (AntB_report > (AntO_report + 2)) ++ pDM_SWAT_Table->ANTB_ON = false; ++ else ++ pDM_SWAT_Table->ANTB_ON = true; ++ } ++ } ++ } else if (pDM_Odm->SupportICType == ODM_RTL8192C) { ++ if (AntA_report >= 100) { ++ if (AntB_report > (AntA_report + 2)) { ++ pDM_SWAT_Table->ANTA_ON = false; ++ pDM_SWAT_Table->ANTB_ON = true; ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_B); ++ } else if (AntA_report > (AntB_report + 2)) { ++ pDM_SWAT_Table->ANTA_ON = true; ++ pDM_SWAT_Table->ANTB_ON = false; ++ ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_A); ++ } else { ++ pDM_SWAT_Table->ANTA_ON = true; ++ pDM_SWAT_Table->ANTB_ON = true; ++ } ++ } else { ++ pDM_SWAT_Table->ANTA_ON = true; /* Set Antenna A on as default */ ++ pDM_SWAT_Table->ANTB_ON = false; /* Set Antenna B off as default */ ++ bResult = false; ++ } ++ } ++ return bResult; ++} ++ ++/* Justin: According to the current RRSI to adjust Response Frame TX power, 2012/11/05 */ ++void odm_dtc(struct odm_dm_struct *pDM_Odm) ++{ ++} +diff --git a/drivers/staging/r8188eu/hal/odm_HWConfig.c b/drivers/staging/r8188eu/hal/odm_HWConfig.c +new file mode 100644 +index 000000000000..ada22a526fee +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/odm_HWConfig.c +@@ -0,0 +1,567 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++ ++#define READ_AND_CONFIG READ_AND_CONFIG_MP ++ ++#define READ_AND_CONFIG_MP(ic, txt) (ODM_ReadAndConfig##txt##ic(dm_odm)) ++#define READ_AND_CONFIG_TC(ic, txt) (ODM_ReadAndConfig_TC##txt##ic(dm_odm)) ++ ++static u8 odm_QueryRxPwrPercentage(s8 AntPower) ++{ ++ if ((AntPower <= -100) || (AntPower >= 20)) ++ return 0; ++ else if (AntPower >= 0) ++ return 100; ++ else ++ return 100 + AntPower; ++} ++ ++/* 2012/01/12 MH MOve some signal strength smooth method to MP HAL layer. */ ++/* IF other SW team do not support the feature, remove this section.?? */ ++static s32 odm_sig_patch_lenove(struct odm_dm_struct *dm_odm, s32 CurrSig) ++{ ++ return 0; ++} ++ ++static s32 odm_sig_patch_netcore(struct odm_dm_struct *dm_odm, s32 CurrSig) ++{ ++ return 0; ++} ++ ++static s32 odm_SignalScaleMapping_92CSeries(struct odm_dm_struct *dm_odm, s32 CurrSig) ++{ ++ s32 RetSig = 0; ++ ++ if ((dm_odm->SupportInterface == ODM_ITRF_USB) || ++ (dm_odm->SupportInterface == ODM_ITRF_SDIO)) { ++ if (CurrSig >= 51 && CurrSig <= 100) ++ RetSig = 100; ++ else if (CurrSig >= 41 && CurrSig <= 50) ++ RetSig = 80 + ((CurrSig - 40) * 2); ++ else if (CurrSig >= 31 && CurrSig <= 40) ++ RetSig = 66 + (CurrSig - 30); ++ else if (CurrSig >= 21 && CurrSig <= 30) ++ RetSig = 54 + (CurrSig - 20); ++ else if (CurrSig >= 10 && CurrSig <= 20) ++ RetSig = 42 + (((CurrSig - 10) * 2) / 3); ++ else if (CurrSig >= 5 && CurrSig <= 9) ++ RetSig = 22 + (((CurrSig - 5) * 3) / 2); ++ else if (CurrSig >= 1 && CurrSig <= 4) ++ RetSig = 6 + (((CurrSig - 1) * 3) / 2); ++ else ++ RetSig = CurrSig; ++ } ++ return RetSig; ++} ++ ++static s32 odm_SignalScaleMapping(struct odm_dm_struct *dm_odm, s32 CurrSig) ++{ ++ if ((dm_odm->SupportPlatform == ODM_MP) && ++ (dm_odm->SupportInterface != ODM_ITRF_PCIE) && /* USB & SDIO */ ++ (dm_odm->PatchID == 10)) ++ return odm_sig_patch_netcore(dm_odm, CurrSig); ++ else if ((dm_odm->SupportPlatform == ODM_MP) && ++ (dm_odm->SupportInterface == ODM_ITRF_PCIE) && ++ (dm_odm->PatchID == 19)) ++ return odm_sig_patch_lenove(dm_odm, CurrSig); ++ else ++ return odm_SignalScaleMapping_92CSeries(dm_odm, CurrSig); ++} ++ ++/* pMgntInfo->CustomerID == RT_CID_819x_Lenovo */ ++static u8 odm_SQ_process_patch_RT_CID_819x_Lenovo(struct odm_dm_struct *dm_odm, ++ u8 isCCKrate, u8 PWDB_ALL, u8 path, u8 RSSI) ++{ ++ return 0; ++} ++ ++static u8 odm_evm_db_to_percentage(s8 value) ++{ ++ /* -33dB~0dB to 0%~99% */ ++ s8 ret_val = clamp(-value, 0, 33) * 3; ++ ++ if (ret_val == 99) ++ ret_val = 100; ++ ++ return ret_val; ++} ++ ++static void odm_RxPhyStatus92CSeries_Parsing(struct odm_dm_struct *dm_odm, ++ struct odm_phy_status_info *pPhyInfo, ++ u8 *pPhyStatus, ++ struct odm_per_pkt_info *pPktinfo, ++ struct adapter *adapt) ++{ ++ struct sw_ant_switch *pDM_SWAT_Table = &dm_odm->DM_SWAT_Table; ++ u8 i, Max_spatial_stream; ++ s8 rx_pwr[4], rx_pwr_all = 0; ++ u8 EVM, PWDB_ALL = 0, PWDB_ALL_BT; ++ u8 RSSI, total_rssi = 0; ++ u8 isCCKrate = 0; ++ u8 rf_rx_num = 0; ++ u8 cck_highpwr = 0; ++ u8 LNA_idx, VGA_idx; ++ ++ struct phy_status_rpt *pPhyStaRpt = (struct phy_status_rpt *)pPhyStatus; ++ ++ isCCKrate = ((pPktinfo->Rate >= DESC92C_RATE1M) && (pPktinfo->Rate <= DESC92C_RATE11M)) ? true : false; ++ ++ pPhyInfo->RxMIMOSignalQuality[RF_PATH_A] = -1; ++ pPhyInfo->RxMIMOSignalQuality[RF_PATH_B] = -1; ++ ++ if (isCCKrate) { ++ u8 report; ++ u8 cck_agc_rpt; ++ ++ dm_odm->PhyDbgInfo.NumQryPhyStatusCCK++; ++ /* (1)Hardware does not provide RSSI for CCK */ ++ /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */ ++ ++ cck_highpwr = dm_odm->bCckHighPower; ++ ++ cck_agc_rpt = pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a; ++ ++ /* 2011.11.28 LukeLee: 88E use different LNA & VGA gain table */ ++ /* The RSSI formula should be modified according to the gain table */ ++ /* In 88E, cck_highpwr is always set to 1 */ ++ if (dm_odm->SupportICType & (ODM_RTL8188E | ODM_RTL8812)) { ++ LNA_idx = ((cck_agc_rpt & 0xE0) >> 5); ++ VGA_idx = (cck_agc_rpt & 0x1F); ++ switch (LNA_idx) { ++ case 7: ++ if (VGA_idx <= 27) ++ rx_pwr_all = -100 + 2 * (27 - VGA_idx); /* VGA_idx = 27~2 */ ++ else ++ rx_pwr_all = -100; ++ break; ++ case 6: ++ rx_pwr_all = -48 + 2 * (2 - VGA_idx); /* VGA_idx = 2~0 */ ++ break; ++ case 5: ++ rx_pwr_all = -42 + 2 * (7 - VGA_idx); /* VGA_idx = 7~5 */ ++ break; ++ case 4: ++ rx_pwr_all = -36 + 2 * (7 - VGA_idx); /* VGA_idx = 7~4 */ ++ break; ++ case 3: ++ rx_pwr_all = -24 + 2 * (7 - VGA_idx); /* VGA_idx = 7~0 */ ++ break; ++ case 2: ++ if (cck_highpwr) ++ rx_pwr_all = -12 + 2 * (5 - VGA_idx); /* VGA_idx = 5~0 */ ++ else ++ rx_pwr_all = -6 + 2 * (5 - VGA_idx); ++ break; ++ case 1: ++ rx_pwr_all = 8 - 2 * VGA_idx; ++ break; ++ case 0: ++ rx_pwr_all = 14 - 2 * VGA_idx; ++ break; ++ default: ++ break; ++ } ++ rx_pwr_all += 6; ++ PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); ++ if (!cck_highpwr) { ++ if (PWDB_ALL >= 80) ++ PWDB_ALL = ((PWDB_ALL - 80) << 1) + ((PWDB_ALL - 80) >> 1) + 80; ++ else if ((PWDB_ALL <= 78) && (PWDB_ALL >= 20)) ++ PWDB_ALL += 3; ++ if (PWDB_ALL > 100) ++ PWDB_ALL = 100; ++ } ++ } else { ++ if (!cck_highpwr) { ++ report = (cck_agc_rpt & 0xc0) >> 6; ++ switch (report) { ++ /* 03312009 modified by cosa */ ++ /* Modify the RF RNA gain value to -40, -20, -2, 14 by Jenyu's suggestion */ ++ /* Note: different RF with the different RNA gain. */ ++ case 0x3: ++ rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); ++ break; ++ case 0x2: ++ rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); ++ break; ++ case 0x1: ++ rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); ++ break; ++ case 0x0: ++ rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); ++ break; ++ } ++ } else { ++ report = (cck_agc_rpt & 0x60) >> 5; ++ switch (report) { ++ case 0x3: ++ rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); ++ break; ++ case 0x2: ++ rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); ++ break; ++ case 0x1: ++ rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); ++ break; ++ case 0x0: ++ rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); ++ break; ++ } ++ } ++ ++ PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); ++ ++ /* Modification for ext-LNA board */ ++ if (dm_odm->BoardType == ODM_BOARD_HIGHPWR) { ++ if ((cck_agc_rpt >> 7) == 0) { ++ PWDB_ALL = (PWDB_ALL > 94) ? 100 : (PWDB_ALL + 6); ++ } else { ++ if (PWDB_ALL > 38) ++ PWDB_ALL -= 16; ++ else ++ PWDB_ALL = (PWDB_ALL <= 16) ? (PWDB_ALL >> 2) : (PWDB_ALL - 12); ++ } ++ ++ /* CCK modification */ ++ if (PWDB_ALL > 25 && PWDB_ALL <= 60) ++ PWDB_ALL += 6; ++ } else {/* Modification for int-LNA board */ ++ if (PWDB_ALL > 99) ++ PWDB_ALL -= 8; ++ else if (PWDB_ALL > 50 && PWDB_ALL <= 68) ++ PWDB_ALL += 4; ++ } ++ } ++ ++ pPhyInfo->RxPWDBAll = PWDB_ALL; ++ pPhyInfo->BTRxRSSIPercentage = PWDB_ALL; ++ pPhyInfo->RecvSignalPower = rx_pwr_all; ++ /* (3) Get Signal Quality (EVM) */ ++ if (pPktinfo->bPacketMatchBSSID) { ++ u8 SQ, SQ_rpt; ++ ++ if ((dm_odm->SupportPlatform == ODM_MP) && (dm_odm->PatchID == 19)) { ++ SQ = odm_SQ_process_patch_RT_CID_819x_Lenovo(dm_odm, isCCKrate, PWDB_ALL, 0, 0); ++ } else if (pPhyInfo->RxPWDBAll > 40 && !dm_odm->bInHctTest) { ++ SQ = 100; ++ } else { ++ SQ_rpt = pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all; ++ ++ if (SQ_rpt > 64) ++ SQ = 0; ++ else if (SQ_rpt < 20) ++ SQ = 100; ++ else ++ SQ = ((64 - SQ_rpt) * 100) / 44; ++ } ++ pPhyInfo->SignalQuality = SQ; ++ pPhyInfo->RxMIMOSignalQuality[RF_PATH_A] = SQ; ++ pPhyInfo->RxMIMOSignalQuality[RF_PATH_B] = -1; ++ } ++ } else { /* is OFDM rate */ ++ dm_odm->PhyDbgInfo.NumQryPhyStatusOFDM++; ++ ++ /* (1)Get RSSI for HT rate */ ++ ++ for (i = RF_PATH_A; i < RF_PATH_MAX; i++) { ++ /* 2008/01/30 MH we will judge RF RX path now. */ ++ if (dm_odm->RFPathRxEnable & BIT(i)) ++ rf_rx_num++; ++ ++ rx_pwr[i] = ((pPhyStaRpt->path_agc[i].gain & 0x3F) * 2) - 110; ++ if (i == RF_PATH_A) ++ adapt->signal_strength = rx_pwr[i]; ++ ++ pPhyInfo->RxPwr[i] = rx_pwr[i]; ++ ++ /* Translate DBM to percentage. */ ++ RSSI = odm_QueryRxPwrPercentage(rx_pwr[i]); ++ total_rssi += RSSI; ++ ++ /* Modification for ext-LNA board */ ++ if (dm_odm->BoardType == ODM_BOARD_HIGHPWR) { ++ if ((pPhyStaRpt->path_agc[i].trsw) == 1) ++ RSSI = (RSSI > 94) ? 100 : (RSSI + 6); ++ else ++ RSSI = (RSSI <= 16) ? (RSSI >> 3) : (RSSI - 16); ++ ++ if ((RSSI <= 34) && (RSSI >= 4)) ++ RSSI -= 4; ++ } ++ ++ pPhyInfo->RxMIMOSignalStrength[i] = (u8)RSSI; ++ ++ /* Get Rx snr value in DB */ ++ pPhyInfo->RxSNR[i] = (s32)(pPhyStaRpt->path_rxsnr[i] / 2); ++ dm_odm->PhyDbgInfo.RxSNRdB[i] = (s32)(pPhyStaRpt->path_rxsnr[i] / 2); ++ ++ /* Record Signal Strength for next packet */ ++ if (pPktinfo->bPacketMatchBSSID) { ++ if ((dm_odm->SupportPlatform == ODM_MP) && (dm_odm->PatchID == 19)) { ++ if (i == RF_PATH_A) ++ pPhyInfo->SignalQuality = odm_SQ_process_patch_RT_CID_819x_Lenovo(dm_odm, isCCKrate, PWDB_ALL, i, RSSI); ++ } ++ } ++ } ++ /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */ ++ rx_pwr_all = (((pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all) >> 1) & 0x7f) - 110; ++ ++ PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); ++ PWDB_ALL_BT = PWDB_ALL; ++ ++ pPhyInfo->RxPWDBAll = PWDB_ALL; ++ pPhyInfo->BTRxRSSIPercentage = PWDB_ALL_BT; ++ pPhyInfo->RxPower = rx_pwr_all; ++ pPhyInfo->RecvSignalPower = rx_pwr_all; ++ ++ if ((dm_odm->SupportPlatform == ODM_MP) && (dm_odm->PatchID == 19)) { ++ /* do nothing */ ++ } else { ++ /* (3)EVM of HT rate */ ++ if (pPktinfo->Rate >= DESC92C_RATEMCS8 && pPktinfo->Rate <= DESC92C_RATEMCS15) ++ Max_spatial_stream = 2; /* both spatial stream make sense */ ++ else ++ Max_spatial_stream = 1; /* only spatial stream 1 makes sense */ ++ ++ for (i = 0; i < Max_spatial_stream; i++) { ++ /* Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment */ ++ /* fill most significant bit to "zero" when doing shifting operation which may change a negative */ ++ /* value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore. */ ++ EVM = odm_evm_db_to_percentage((pPhyStaRpt->stream_rxevm[i])); /* dbm */ ++ ++ if (pPktinfo->bPacketMatchBSSID) { ++ if (i == RF_PATH_A) /* Fill value in RFD, Get the first spatial stream only */ ++ pPhyInfo->SignalQuality = (u8)(EVM & 0xff); ++ pPhyInfo->RxMIMOSignalQuality[i] = (u8)(EVM & 0xff); ++ } ++ } ++ } ++ } ++ /* UI BSS List signal strength(in percentage), make it good looking, from 0~100. */ ++ /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */ ++ if (isCCKrate) { ++ pPhyInfo->SignalStrength = (u8)(odm_SignalScaleMapping(dm_odm, PWDB_ALL));/* PWDB_ALL; */ ++ } else { ++ if (rf_rx_num != 0) ++ pPhyInfo->SignalStrength = (u8)(odm_SignalScaleMapping(dm_odm, total_rssi /= rf_rx_num)); ++ } ++ ++ /* For 92C/92D HW (Hybrid) Antenna Diversity */ ++ pDM_SWAT_Table->antsel = pPhyStaRpt->ant_sel; ++ /* For 88E HW Antenna Diversity */ ++ dm_odm->DM_FatTable.antsel_rx_keep_0 = pPhyStaRpt->ant_sel; ++ dm_odm->DM_FatTable.antsel_rx_keep_1 = pPhyStaRpt->ant_sel_b; ++ dm_odm->DM_FatTable.antsel_rx_keep_2 = pPhyStaRpt->antsel_rx_keep_2; ++} ++ ++void odm_Init_RSSIForDM(struct odm_dm_struct *dm_odm) ++{ ++} ++ ++static void odm_Process_RSSIForDM(struct odm_dm_struct *dm_odm, ++ struct odm_phy_status_info *pPhyInfo, ++ struct odm_per_pkt_info *pPktinfo) ++{ ++ s32 UndecoratedSmoothedPWDB, UndecoratedSmoothedCCK; ++ s32 UndecoratedSmoothedOFDM, RSSI_Ave; ++ u8 isCCKrate = 0; ++ u8 RSSI_max, RSSI_min, i; ++ u32 OFDM_pkt = 0; ++ u32 Weighting = 0; ++ struct sta_info *pEntry; ++ ++ if (pPktinfo->StationID == 0xFF) ++ return; ++ pEntry = dm_odm->pODM_StaInfo[pPktinfo->StationID]; ++ if (!IS_STA_VALID(pEntry)) ++ return; ++ if ((!pPktinfo->bPacketMatchBSSID)) ++ return; ++ ++ isCCKrate = ((pPktinfo->Rate >= DESC92C_RATE1M) && (pPktinfo->Rate <= DESC92C_RATE11M)) ? true : false; ++ ++ /* Smart Antenna Debug Message------------------ */ ++ if (dm_odm->SupportICType == ODM_RTL8188E) { ++ u8 antsel_tr_mux; ++ struct fast_ant_train *pDM_FatTable = &dm_odm->DM_FatTable; ++ ++ if (dm_odm->AntDivType == CG_TRX_SMART_ANTDIV) { ++ if (pDM_FatTable->FAT_State == FAT_TRAINING_STATE) { ++ if (pPktinfo->bPacketToSelf) { ++ antsel_tr_mux = (pDM_FatTable->antsel_rx_keep_2 << 2) | ++ (pDM_FatTable->antsel_rx_keep_1 << 1) | ++ pDM_FatTable->antsel_rx_keep_0; ++ pDM_FatTable->antSumRSSI[antsel_tr_mux] += pPhyInfo->RxPWDBAll; ++ pDM_FatTable->antRSSIcnt[antsel_tr_mux]++; ++ } ++ } ++ } else if ((dm_odm->AntDivType == CG_TRX_HW_ANTDIV) || (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV)) { ++ if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) { ++ antsel_tr_mux = (pDM_FatTable->antsel_rx_keep_2 << 2) | ++ (pDM_FatTable->antsel_rx_keep_1 << 1) | pDM_FatTable->antsel_rx_keep_0; ++ ODM_AntselStatistics_88E(dm_odm, antsel_tr_mux, pPktinfo->StationID, pPhyInfo->RxPWDBAll); ++ } ++ } ++ } ++ /* Smart Antenna Debug Message------------------ */ ++ ++ UndecoratedSmoothedCCK = pEntry->rssi_stat.UndecoratedSmoothedCCK; ++ UndecoratedSmoothedOFDM = pEntry->rssi_stat.UndecoratedSmoothedOFDM; ++ UndecoratedSmoothedPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB; ++ ++ if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) { ++ if (!isCCKrate) { /* ofdm rate */ ++ if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_B] == 0) { ++ RSSI_Ave = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A]; ++ } else { ++ if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_A] > pPhyInfo->RxMIMOSignalStrength[RF_PATH_B]) { ++ RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A]; ++ RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B]; ++ } else { ++ RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B]; ++ RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A]; ++ } ++ if ((RSSI_max - RSSI_min) < 3) ++ RSSI_Ave = RSSI_max; ++ else if ((RSSI_max - RSSI_min) < 6) ++ RSSI_Ave = RSSI_max - 1; ++ else if ((RSSI_max - RSSI_min) < 10) ++ RSSI_Ave = RSSI_max - 2; ++ else ++ RSSI_Ave = RSSI_max - 3; ++ } ++ ++ /* 1 Process OFDM RSSI */ ++ if (UndecoratedSmoothedOFDM <= 0) { /* initialize */ ++ UndecoratedSmoothedOFDM = pPhyInfo->RxPWDBAll; ++ } else { ++ if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedOFDM) { ++ UndecoratedSmoothedOFDM = ++ (((UndecoratedSmoothedOFDM) * (Rx_Smooth_Factor - 1)) + ++ (RSSI_Ave)) / (Rx_Smooth_Factor); ++ UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM + 1; ++ } else { ++ UndecoratedSmoothedOFDM = ++ (((UndecoratedSmoothedOFDM) * (Rx_Smooth_Factor - 1)) + ++ (RSSI_Ave)) / (Rx_Smooth_Factor); ++ } ++ } ++ ++ pEntry->rssi_stat.PacketMap = (pEntry->rssi_stat.PacketMap << 1) | BIT(0); ++ ++ } else { ++ RSSI_Ave = pPhyInfo->RxPWDBAll; ++ ++ /* 1 Process CCK RSSI */ ++ if (UndecoratedSmoothedCCK <= 0) { /* initialize */ ++ UndecoratedSmoothedCCK = pPhyInfo->RxPWDBAll; ++ } else { ++ if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedCCK) { ++ UndecoratedSmoothedCCK = ++ ((UndecoratedSmoothedCCK * (Rx_Smooth_Factor - 1)) + ++ pPhyInfo->RxPWDBAll) / Rx_Smooth_Factor; ++ UndecoratedSmoothedCCK = UndecoratedSmoothedCCK + 1; ++ } else { ++ UndecoratedSmoothedCCK = ++ ((UndecoratedSmoothedCCK * (Rx_Smooth_Factor - 1)) + ++ pPhyInfo->RxPWDBAll) / Rx_Smooth_Factor; ++ } ++ } ++ pEntry->rssi_stat.PacketMap = pEntry->rssi_stat.PacketMap << 1; ++ } ++ /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */ ++ if (pEntry->rssi_stat.ValidBit >= 64) ++ pEntry->rssi_stat.ValidBit = 64; ++ else ++ pEntry->rssi_stat.ValidBit++; ++ ++ for (i = 0; i < pEntry->rssi_stat.ValidBit; i++) ++ OFDM_pkt += (u8)(pEntry->rssi_stat.PacketMap >> i) & BIT(0); ++ ++ if (pEntry->rssi_stat.ValidBit == 64) { ++ Weighting = ((OFDM_pkt << 4) > 64) ? 64 : (OFDM_pkt << 4); ++ UndecoratedSmoothedPWDB = (Weighting * UndecoratedSmoothedOFDM + (64 - Weighting) * UndecoratedSmoothedCCK) >> 6; ++ } else { ++ if (pEntry->rssi_stat.ValidBit != 0) ++ UndecoratedSmoothedPWDB = (OFDM_pkt * UndecoratedSmoothedOFDM + ++ (pEntry->rssi_stat.ValidBit - OFDM_pkt) * ++ UndecoratedSmoothedCCK) / pEntry->rssi_stat.ValidBit; ++ else ++ UndecoratedSmoothedPWDB = 0; ++ } ++ pEntry->rssi_stat.UndecoratedSmoothedCCK = UndecoratedSmoothedCCK; ++ pEntry->rssi_stat.UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM; ++ pEntry->rssi_stat.UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB; ++ } ++} ++ ++/* Endianness before calling this API */ ++static void ODM_PhyStatusQuery_92CSeries(struct odm_dm_struct *dm_odm, ++ struct odm_phy_status_info *pPhyInfo, ++ u8 *pPhyStatus, ++ struct odm_per_pkt_info *pPktinfo, ++ struct adapter *adapt) ++{ ++ odm_RxPhyStatus92CSeries_Parsing(dm_odm, pPhyInfo, pPhyStatus, ++ pPktinfo, adapt); ++ if (dm_odm->RSSI_test) { ++ /* Select the packets to do RSSI checking for antenna switching. */ ++ if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) ++ ODM_SwAntDivChkPerPktRssi(dm_odm, pPktinfo->StationID, pPhyInfo); ++ } else { ++ odm_Process_RSSIForDM(dm_odm, pPhyInfo, pPktinfo); ++ } ++} ++ ++void ODM_PhyStatusQuery(struct odm_dm_struct *dm_odm, ++ struct odm_phy_status_info *pPhyInfo, ++ u8 *pPhyStatus, struct odm_per_pkt_info *pPktinfo, ++ struct adapter *adapt) ++{ ++ ODM_PhyStatusQuery_92CSeries(dm_odm, pPhyInfo, pPhyStatus, pPktinfo, adapt); ++} ++ ++/* For future use. */ ++void ODM_MacStatusQuery(struct odm_dm_struct *dm_odm, u8 *mac_stat, ++ u8 macid, bool pkt_match_bssid, ++ bool pkttoself, bool pkt_beacon) ++{ ++ /* 2011/10/19 Driver team will handle in the future. */ ++} ++ ++enum HAL_STATUS ODM_ConfigRFWithHeaderFile(struct odm_dm_struct *dm_odm, ++ enum rf_radio_path content, ++ enum rf_radio_path rfpath) ++{ ++ if (dm_odm->SupportICType == ODM_RTL8188E) { ++ if (rfpath == RF_PATH_A) ++ READ_AND_CONFIG(8188E, _RadioA_1T_); ++ } ++ ++ return HAL_STATUS_SUCCESS; ++} ++ ++enum HAL_STATUS ODM_ConfigBBWithHeaderFile(struct odm_dm_struct *dm_odm, ++ enum odm_bb_config_type config_tp) ++{ ++ if (dm_odm->SupportICType == ODM_RTL8188E) { ++ if (config_tp == CONFIG_BB_PHY_REG) { ++ READ_AND_CONFIG(8188E, _PHY_REG_1T_); ++ } else if (config_tp == CONFIG_BB_AGC_TAB) { ++ READ_AND_CONFIG(8188E, _AGC_TAB_1T_); ++ } else if (config_tp == CONFIG_BB_PHY_REG_PG) { ++ READ_AND_CONFIG(8188E, _PHY_REG_PG_); ++ } ++ } ++ return HAL_STATUS_SUCCESS; ++} ++ ++enum HAL_STATUS ODM_ConfigMACWithHeaderFile(struct odm_dm_struct *dm_odm) ++{ ++ u8 result = HAL_STATUS_SUCCESS; ++ if (dm_odm->SupportICType == ODM_RTL8188E) ++ result = READ_AND_CONFIG(8188E, _MAC_REG_); ++ return result; ++} +diff --git a/drivers/staging/r8188eu/hal/odm_RTL8188E.c b/drivers/staging/r8188eu/hal/odm_RTL8188E.c +new file mode 100644 +index 000000000000..c64a291f9966 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/odm_RTL8188E.c +@@ -0,0 +1,337 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++ ++void ODM_DIG_LowerBound_88E(struct odm_dm_struct *dm_odm) ++{ ++ struct rtw_dig *pDM_DigTable = &dm_odm->DM_DigTable; ++ ++ if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ++ pDM_DigTable->rx_gain_range_min = (u8)pDM_DigTable->AntDiv_RSSI_max; ++ /* If only one Entry connected */ ++} ++ ++static void odm_RX_HWAntDivInit(struct odm_dm_struct *dm_odm) ++{ ++ u32 value32; ++ ++ if (*dm_odm->mp_mode == 1) { ++ dm_odm->AntDivType = CGCS_RX_SW_ANTDIV; ++ ODM_SetBBReg(dm_odm, ODM_REG_IGI_A_11N, BIT(7), 0); /* disable HW AntDiv */ ++ ODM_SetBBReg(dm_odm, ODM_REG_LNA_SWITCH_11N, BIT(31), 1); /* 1:CG, 0:CS */ ++ return; ++ } ++ ++ /* MAC Setting */ ++ value32 = ODM_GetMACReg(dm_odm, ODM_REG_ANTSEL_PIN_11N, bMaskDWord); ++ ODM_SetMACReg(dm_odm, ODM_REG_ANTSEL_PIN_11N, bMaskDWord, value32 | (BIT(23) | BIT(25))); /* Reg4C[25]=1, Reg4C[23]=1 for pin output */ ++ /* Pin Settings */ ++ ODM_SetBBReg(dm_odm, ODM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);/* Reg870[8]=1'b0, Reg870[9]=1'b0 antsel antselb by HW */ ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(10), 0); /* Reg864[10]=1'b0 antsel2 by HW */ ++ ODM_SetBBReg(dm_odm, ODM_REG_LNA_SWITCH_11N, BIT(22), 1); /* Regb2c[22]=1'b0 disable CS/CG switch */ ++ ODM_SetBBReg(dm_odm, ODM_REG_LNA_SWITCH_11N, BIT(31), 1); /* Regb2c[31]=1'b1 output at CG only */ ++ /* OFDM Settings */ ++ ODM_SetBBReg(dm_odm, ODM_REG_ANTDIV_PARA1_11N, bMaskDWord, 0x000000a0); ++ /* CCK Settings */ ++ ODM_SetBBReg(dm_odm, ODM_REG_BB_PWR_SAV4_11N, BIT(7), 1); /* Fix CCK PHY status report issue */ ++ ODM_SetBBReg(dm_odm, ODM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1); /* CCK complete HW AntDiv within 64 samples */ ++ ODM_UpdateRxIdleAnt_88E(dm_odm, MAIN_ANT); ++ ODM_SetBBReg(dm_odm, ODM_REG_ANT_MAPPING1_11N, 0xFFFF, 0x0201); /* antenna mapping table */ ++} ++ ++static void odm_TRX_HWAntDivInit(struct odm_dm_struct *dm_odm) ++{ ++ u32 value32; ++ ++ if (*dm_odm->mp_mode == 1) { ++ dm_odm->AntDivType = CGCS_RX_SW_ANTDIV; ++ ODM_SetBBReg(dm_odm, ODM_REG_IGI_A_11N, BIT(7), 0); /* disable HW AntDiv */ ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(5) | BIT(4) | BIT(3), 0); /* Default RX (0/1) */ ++ return; ++ } ++ ++ /* MAC Setting */ ++ value32 = ODM_GetMACReg(dm_odm, ODM_REG_ANTSEL_PIN_11N, bMaskDWord); ++ ODM_SetMACReg(dm_odm, ODM_REG_ANTSEL_PIN_11N, bMaskDWord, value32 | (BIT(23) | BIT(25))); /* Reg4C[25]=1, Reg4C[23]=1 for pin output */ ++ /* Pin Settings */ ++ ODM_SetBBReg(dm_odm, ODM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);/* Reg870[8]=1'b0, Reg870[9]=1'b0 antsel antselb by HW */ ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(10), 0); /* Reg864[10]=1'b0 antsel2 by HW */ ++ ODM_SetBBReg(dm_odm, ODM_REG_LNA_SWITCH_11N, BIT(22), 0); /* Regb2c[22]=1'b0 disable CS/CG switch */ ++ ODM_SetBBReg(dm_odm, ODM_REG_LNA_SWITCH_11N, BIT(31), 1); /* Regb2c[31]=1'b1 output at CG only */ ++ /* OFDM Settings */ ++ ODM_SetBBReg(dm_odm, ODM_REG_ANTDIV_PARA1_11N, bMaskDWord, 0x000000a0); ++ /* CCK Settings */ ++ ODM_SetBBReg(dm_odm, ODM_REG_BB_PWR_SAV4_11N, BIT(7), 1); /* Fix CCK PHY status report issue */ ++ ODM_SetBBReg(dm_odm, ODM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1); /* CCK complete HW AntDiv within 64 samples */ ++ /* Tx Settings */ ++ ODM_SetBBReg(dm_odm, ODM_REG_TX_ANT_CTRL_11N, BIT(21), 0); /* Reg80c[21]=1'b0 from TX Reg */ ++ ODM_UpdateRxIdleAnt_88E(dm_odm, MAIN_ANT); ++ ++ /* antenna mapping table */ ++ if (!dm_odm->bIsMPChip) { /* testchip */ ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_DEFUALT_A_11N, BIT(10) | BIT(9) | BIT(8), 1); /* Reg858[10:8]=3'b001 */ ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_DEFUALT_A_11N, BIT(13) | BIT(12) | BIT(11), 2); /* Reg858[13:11]=3'b010 */ ++ } else { /* MPchip */ ++ ODM_SetBBReg(dm_odm, ODM_REG_ANT_MAPPING1_11N, bMaskDWord, 0x0201); /* Reg914=3'b010, Reg915=3'b001 */ ++ } ++} ++ ++static void odm_FastAntTrainingInit(struct odm_dm_struct *dm_odm) ++{ ++ u32 value32, i; ++ struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable; ++ u32 AntCombination = 2; ++ ++ if (*dm_odm->mp_mode == 1) ++ return; ++ ++ for (i = 0; i < 6; i++) { ++ dm_fat_tbl->Bssid[i] = 0; ++ dm_fat_tbl->antSumRSSI[i] = 0; ++ dm_fat_tbl->antRSSIcnt[i] = 0; ++ dm_fat_tbl->antAveRSSI[i] = 0; ++ } ++ dm_fat_tbl->TrainIdx = 0; ++ dm_fat_tbl->FAT_State = FAT_NORMAL_STATE; ++ ++ /* MAC Setting */ ++ value32 = ODM_GetMACReg(dm_odm, 0x4c, bMaskDWord); ++ ODM_SetMACReg(dm_odm, 0x4c, bMaskDWord, value32 | (BIT(23) | BIT(25))); /* Reg4C[25]=1, Reg4C[23]=1 for pin output */ ++ value32 = ODM_GetMACReg(dm_odm, 0x7B4, bMaskDWord); ++ ODM_SetMACReg(dm_odm, 0x7b4, bMaskDWord, value32 | (BIT(16) | BIT(17))); /* Reg7B4[16]=1 enable antenna training, Reg7B4[17]=1 enable A2 match */ ++ ++ /* Match MAC ADDR */ ++ ODM_SetMACReg(dm_odm, 0x7b4, 0xFFFF, 0); ++ ODM_SetMACReg(dm_odm, 0x7b0, bMaskDWord, 0); ++ ++ ODM_SetBBReg(dm_odm, 0x870, BIT(9) | BIT(8), 0);/* Reg870[8]=1'b0, Reg870[9]=1'b0 antsel antselb by HW */ ++ ODM_SetBBReg(dm_odm, 0x864, BIT(10), 0); /* Reg864[10]=1'b0 antsel2 by HW */ ++ ODM_SetBBReg(dm_odm, 0xb2c, BIT(22), 0); /* Regb2c[22]=1'b0 disable CS/CG switch */ ++ ODM_SetBBReg(dm_odm, 0xb2c, BIT(31), 1); /* Regb2c[31]=1'b1 output at CG only */ ++ ODM_SetBBReg(dm_odm, 0xca4, bMaskDWord, 0x000000a0); ++ ++ /* antenna mapping table */ ++ if (AntCombination == 2) { ++ if (!dm_odm->bIsMPChip) { /* testchip */ ++ ODM_SetBBReg(dm_odm, 0x858, BIT(10) | BIT(9) | BIT(8), 1); /* Reg858[10:8]=3'b001 */ ++ ODM_SetBBReg(dm_odm, 0x858, BIT(13) | BIT(12) | BIT(11), 2); /* Reg858[13:11]=3'b010 */ ++ } else { /* MPchip */ ++ ODM_SetBBReg(dm_odm, 0x914, bMaskByte0, 1); ++ ODM_SetBBReg(dm_odm, 0x914, bMaskByte1, 2); ++ } ++ } else if (AntCombination == 7) { ++ if (!dm_odm->bIsMPChip) { /* testchip */ ++ ODM_SetBBReg(dm_odm, 0x858, BIT(10) | BIT(9) | BIT(8), 0); /* Reg858[10:8]=3'b000 */ ++ ODM_SetBBReg(dm_odm, 0x858, BIT(13) | BIT(12) | BIT(11), 1); /* Reg858[13:11]=3'b001 */ ++ ODM_SetBBReg(dm_odm, 0x878, BIT(16), 0); ++ ODM_SetBBReg(dm_odm, 0x858, BIT(15) | BIT(14), 2); /* Reg878[0],Reg858[14:15])=3'b010 */ ++ ODM_SetBBReg(dm_odm, 0x878, BIT(19) | BIT(18) | BIT(17), 3);/* Reg878[3:1]=3b'011 */ ++ ODM_SetBBReg(dm_odm, 0x878, BIT(22) | BIT(21) | BIT(20), 4);/* Reg878[6:4]=3b'100 */ ++ ODM_SetBBReg(dm_odm, 0x878, BIT(25) | BIT(24) | BIT(23), 5);/* Reg878[9:7]=3b'101 */ ++ ODM_SetBBReg(dm_odm, 0x878, BIT(28) | BIT(27) | BIT(26), 6);/* Reg878[12:10]=3b'110 */ ++ ODM_SetBBReg(dm_odm, 0x878, BIT(31) | BIT(30) | BIT(29), 7);/* Reg878[15:13]=3b'111 */ ++ } else { /* MPchip */ ++ ODM_SetBBReg(dm_odm, 0x914, bMaskByte0, 0); ++ ODM_SetBBReg(dm_odm, 0x914, bMaskByte1, 1); ++ ODM_SetBBReg(dm_odm, 0x914, bMaskByte2, 2); ++ ODM_SetBBReg(dm_odm, 0x914, bMaskByte3, 3); ++ ODM_SetBBReg(dm_odm, 0x918, bMaskByte0, 4); ++ ODM_SetBBReg(dm_odm, 0x918, bMaskByte1, 5); ++ ODM_SetBBReg(dm_odm, 0x918, bMaskByte2, 6); ++ ODM_SetBBReg(dm_odm, 0x918, bMaskByte3, 7); ++ } ++ } ++ ++ /* Default Ant Setting when no fast training */ ++ ODM_SetBBReg(dm_odm, 0x80c, BIT(21), 1); /* Reg80c[21]=1'b1 from TX Info */ ++ ODM_SetBBReg(dm_odm, 0x864, BIT(5) | BIT(4) | BIT(3), 0); /* Default RX */ ++ ODM_SetBBReg(dm_odm, 0x864, BIT(8) | BIT(7) | BIT(6), 1); /* Optional RX */ ++ ++ /* Enter Traing state */ ++ ODM_SetBBReg(dm_odm, 0x864, BIT(2) | BIT(1) | BIT(0), (AntCombination - 1)); /* Reg864[2:0]=3'd6 ant combination=reg864[2:0]+1 */ ++ ODM_SetBBReg(dm_odm, 0xc50, BIT(7), 1); /* RegC50[7]=1'b1 enable HW AntDiv */ ++} ++ ++void ODM_AntennaDiversityInit_88E(struct odm_dm_struct *dm_odm) ++{ ++ if (dm_odm->SupportICType != ODM_RTL8188E) ++ return; ++ ++ if (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV) ++ odm_RX_HWAntDivInit(dm_odm); ++ else if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ++ odm_TRX_HWAntDivInit(dm_odm); ++ else if (dm_odm->AntDivType == CG_TRX_SMART_ANTDIV) ++ odm_FastAntTrainingInit(dm_odm); ++} ++ ++void ODM_UpdateRxIdleAnt_88E(struct odm_dm_struct *dm_odm, u8 Ant) ++{ ++ struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable; ++ u32 DefaultAnt, OptionalAnt; ++ ++ if (dm_fat_tbl->RxIdleAnt != Ant) { ++ if (Ant == MAIN_ANT) { ++ DefaultAnt = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ? MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX; ++ OptionalAnt = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ? AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX; ++ } else { ++ DefaultAnt = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ? AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX; ++ OptionalAnt = (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ? MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX; ++ } ++ ++ if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) { ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(5) | BIT(4) | BIT(3), DefaultAnt); /* Default RX */ ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(8) | BIT(7) | BIT(6), OptionalAnt); /* Optional RX */ ++ ODM_SetBBReg(dm_odm, ODM_REG_ANTSEL_CTRL_11N, BIT(14) | BIT(13) | BIT(12), DefaultAnt); /* Default TX */ ++ ODM_SetMACReg(dm_odm, ODM_REG_RESP_TX_11N, BIT(6) | BIT(7), DefaultAnt); /* Resp Tx */ ++ } else if (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV) { ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(5) | BIT(4) | BIT(3), DefaultAnt); /* Default RX */ ++ ODM_SetBBReg(dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(8) | BIT(7) | BIT(6), OptionalAnt); /* Optional RX */ ++ } ++ } ++ dm_fat_tbl->RxIdleAnt = Ant; ++ if (Ant != MAIN_ANT) ++ pr_info("RxIdleAnt=AUX_ANT\n"); ++} ++ ++static void odm_UpdateTxAnt_88E(struct odm_dm_struct *dm_odm, u8 Ant, u32 MacId) ++{ ++ struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable; ++ u8 TargetAnt; ++ ++ if (Ant == MAIN_ANT) ++ TargetAnt = MAIN_ANT_CG_TRX; ++ else ++ TargetAnt = AUX_ANT_CG_TRX; ++ dm_fat_tbl->antsel_a[MacId] = TargetAnt & BIT(0); ++ dm_fat_tbl->antsel_b[MacId] = (TargetAnt & BIT(1)) >> 1; ++ dm_fat_tbl->antsel_c[MacId] = (TargetAnt & BIT(2)) >> 2; ++} ++ ++void ODM_SetTxAntByTxInfo_88E(struct odm_dm_struct *dm_odm, u8 *pDesc, u8 macId) ++{ ++ struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable; ++ ++ if ((dm_odm->AntDivType == CG_TRX_HW_ANTDIV) || (dm_odm->AntDivType == CG_TRX_SMART_ANTDIV)) { ++ SET_TX_DESC_ANTSEL_A_88E(pDesc, dm_fat_tbl->antsel_a[macId]); ++ SET_TX_DESC_ANTSEL_B_88E(pDesc, dm_fat_tbl->antsel_b[macId]); ++ SET_TX_DESC_ANTSEL_C_88E(pDesc, dm_fat_tbl->antsel_c[macId]); ++ } ++} ++ ++void ODM_AntselStatistics_88E(struct odm_dm_struct *dm_odm, u8 antsel_tr_mux, u32 MacId, u8 RxPWDBAll) ++{ ++ struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable; ++ if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) { ++ if (antsel_tr_mux == MAIN_ANT_CG_TRX) { ++ dm_fat_tbl->MainAnt_Sum[MacId] += RxPWDBAll; ++ dm_fat_tbl->MainAnt_Cnt[MacId]++; ++ } else { ++ dm_fat_tbl->AuxAnt_Sum[MacId] += RxPWDBAll; ++ dm_fat_tbl->AuxAnt_Cnt[MacId]++; ++ } ++ } else if (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV) { ++ if (antsel_tr_mux == MAIN_ANT_CGCS_RX) { ++ dm_fat_tbl->MainAnt_Sum[MacId] += RxPWDBAll; ++ dm_fat_tbl->MainAnt_Cnt[MacId]++; ++ } else { ++ dm_fat_tbl->AuxAnt_Sum[MacId] += RxPWDBAll; ++ dm_fat_tbl->AuxAnt_Cnt[MacId]++; ++ } ++ } ++} ++ ++static void odm_HWAntDiv(struct odm_dm_struct *dm_odm) ++{ ++ u32 i, MinRSSI = 0xFF, AntDivMaxRSSI = 0, MaxRSSI = 0, LocalMinRSSI, LocalMaxRSSI; ++ u32 Main_RSSI, Aux_RSSI; ++ u8 RxIdleAnt = 0, TargetAnt = 7; ++ struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable; ++ struct rtw_dig *pDM_DigTable = &dm_odm->DM_DigTable; ++ struct sta_info *pEntry; ++ ++ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { ++ pEntry = dm_odm->pODM_StaInfo[i]; ++ if (IS_STA_VALID(pEntry)) { ++ /* 2 Caculate RSSI per Antenna */ ++ Main_RSSI = (dm_fat_tbl->MainAnt_Cnt[i] != 0) ? (dm_fat_tbl->MainAnt_Sum[i] / dm_fat_tbl->MainAnt_Cnt[i]) : 0; ++ Aux_RSSI = (dm_fat_tbl->AuxAnt_Cnt[i] != 0) ? (dm_fat_tbl->AuxAnt_Sum[i] / dm_fat_tbl->AuxAnt_Cnt[i]) : 0; ++ TargetAnt = (Main_RSSI >= Aux_RSSI) ? MAIN_ANT : AUX_ANT; ++ /* 2 Select MaxRSSI for DIG */ ++ LocalMaxRSSI = (Main_RSSI > Aux_RSSI) ? Main_RSSI : Aux_RSSI; ++ if ((LocalMaxRSSI > AntDivMaxRSSI) && (LocalMaxRSSI < 40)) ++ AntDivMaxRSSI = LocalMaxRSSI; ++ if (LocalMaxRSSI > MaxRSSI) ++ MaxRSSI = LocalMaxRSSI; ++ ++ /* 2 Select RX Idle Antenna */ ++ if ((dm_fat_tbl->RxIdleAnt == MAIN_ANT) && (Main_RSSI == 0)) ++ Main_RSSI = Aux_RSSI; ++ else if ((dm_fat_tbl->RxIdleAnt == AUX_ANT) && (Aux_RSSI == 0)) ++ Aux_RSSI = Main_RSSI; ++ ++ LocalMinRSSI = (Main_RSSI > Aux_RSSI) ? Aux_RSSI : Main_RSSI; ++ if (LocalMinRSSI < MinRSSI) { ++ MinRSSI = LocalMinRSSI; ++ RxIdleAnt = TargetAnt; ++ } ++ /* 2 Select TRX Antenna */ ++ if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ++ odm_UpdateTxAnt_88E(dm_odm, TargetAnt, i); ++ } ++ dm_fat_tbl->MainAnt_Sum[i] = 0; ++ dm_fat_tbl->AuxAnt_Sum[i] = 0; ++ dm_fat_tbl->MainAnt_Cnt[i] = 0; ++ dm_fat_tbl->AuxAnt_Cnt[i] = 0; ++ } ++ ++ /* 2 Set RX Idle Antenna */ ++ ODM_UpdateRxIdleAnt_88E(dm_odm, RxIdleAnt); ++ ++ pDM_DigTable->AntDiv_RSSI_max = AntDivMaxRSSI; ++ pDM_DigTable->RSSI_max = MaxRSSI; ++} ++ ++void ODM_AntennaDiversity_88E(struct odm_dm_struct *dm_odm) ++{ ++ struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable; ++ if ((dm_odm->SupportICType != ODM_RTL8188E) || (!(dm_odm->SupportAbility & ODM_BB_ANT_DIV))) ++ return; ++ if (!dm_odm->bLinked) { ++ if (dm_fat_tbl->bBecomeLinked) { ++ ODM_SetBBReg(dm_odm, ODM_REG_IGI_A_11N, BIT(7), 0); /* RegC50[7]=1'b1 enable HW AntDiv */ ++ ODM_SetBBReg(dm_odm, ODM_REG_CCK_ANTDIV_PARA1_11N, BIT(15), 0); /* Enable CCK AntDiv */ ++ if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ++ ODM_SetBBReg(dm_odm, ODM_REG_TX_ANT_CTRL_11N, BIT(21), 0); /* Reg80c[21]=1'b0 from TX Reg */ ++ dm_fat_tbl->bBecomeLinked = dm_odm->bLinked; ++ } ++ return; ++ } else { ++ if (!dm_fat_tbl->bBecomeLinked) { ++ /* Because HW AntDiv is disabled before Link, we enable HW AntDiv after link */ ++ ODM_SetBBReg(dm_odm, ODM_REG_IGI_A_11N, BIT(7), 1); /* RegC50[7]=1'b1 enable HW AntDiv */ ++ ODM_SetBBReg(dm_odm, ODM_REG_CCK_ANTDIV_PARA1_11N, BIT(15), 1); /* Enable CCK AntDiv */ ++ if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) ++ ODM_SetBBReg(dm_odm, ODM_REG_TX_ANT_CTRL_11N, BIT(21), 1); /* Reg80c[21]=1'b1 from TX Info */ ++ dm_fat_tbl->bBecomeLinked = dm_odm->bLinked; ++ } ++ } ++ if ((dm_odm->AntDivType == CG_TRX_HW_ANTDIV) || (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV)) ++ odm_HWAntDiv(dm_odm); ++} ++ ++/* 3============================================================ */ ++/* 3 Dynamic Primary CCA */ ++/* 3============================================================ */ ++ ++void odm_PrimaryCCA_Init(struct odm_dm_struct *dm_odm) ++{ ++ struct dyn_primary_cca *PrimaryCCA = &dm_odm->DM_PriCCA; ++ ++ PrimaryCCA->dup_rts_flag = 0; ++ PrimaryCCA->intf_flag = 0; ++ PrimaryCCA->intf_type = 0; ++ PrimaryCCA->monitor_flag = 0; ++ PrimaryCCA->pri_cca_flag = 0; ++} +diff --git a/drivers/staging/r8188eu/hal/odm_RegConfig8188E.c b/drivers/staging/r8188eu/hal/odm_RegConfig8188E.c +new file mode 100644 +index 000000000000..1bc3b49cd67f +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/odm_RegConfig8188E.c +@@ -0,0 +1,98 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++ ++void odm_ConfigRFReg_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, ++ u32 Data, enum rf_radio_path RF_PATH, ++ u32 RegAddr) ++{ ++ if (Addr == 0xffe) { ++ ODM_sleep_ms(50); ++ } else if (Addr == 0xfd) { ++ ODM_delay_ms(5); ++ } else if (Addr == 0xfc) { ++ ODM_delay_ms(1); ++ } else if (Addr == 0xfb) { ++ ODM_delay_us(50); ++ } else if (Addr == 0xfa) { ++ ODM_delay_us(5); ++ } else if (Addr == 0xf9) { ++ ODM_delay_us(1); ++ } else { ++ ODM_SetRFReg(pDM_Odm, RF_PATH, RegAddr, bRFRegOffsetMask, Data); ++ /* Add 1us delay between BB/RF register setting. */ ++ ODM_delay_us(1); ++ } ++} ++ ++void odm_ConfigRF_RadioA_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Data) ++{ ++ u32 content = 0x1000; /* RF_Content: radioa_txt */ ++ u32 maskforPhySet = (u32)(content & 0xE000); ++ ++ odm_ConfigRFReg_8188E(pDM_Odm, Addr, Data, RF_PATH_A, Addr | maskforPhySet); ++} ++ ++void odm_ConfigRF_RadioB_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Data) ++{ ++ u32 content = 0x1001; /* RF_Content: radiob_txt */ ++ u32 maskforPhySet = (u32)(content & 0xE000); ++ ++ odm_ConfigRFReg_8188E(pDM_Odm, Addr, Data, RF_PATH_B, Addr | maskforPhySet); ++} ++ ++void odm_ConfigMAC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u8 Data) ++{ ++ ODM_Write1Byte(pDM_Odm, Addr, Data); ++} ++ ++void odm_ConfigBB_AGC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data) ++{ ++ ODM_SetBBReg(pDM_Odm, Addr, Bitmask, Data); ++ /* Add 1us delay between BB/RF register setting. */ ++ ODM_delay_us(1); ++} ++ ++void odm_ConfigBB_PHY_REG_PG_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, ++ u32 Bitmask, u32 Data) ++{ ++ if (Addr == 0xfe) ++ ODM_sleep_ms(50); ++ else if (Addr == 0xfd) ++ ODM_delay_ms(5); ++ else if (Addr == 0xfc) ++ ODM_delay_ms(1); ++ else if (Addr == 0xfb) ++ ODM_delay_us(50); ++ else if (Addr == 0xfa) ++ ODM_delay_us(5); ++ else if (Addr == 0xf9) ++ ODM_delay_us(1); ++ else ++ storePwrIndexDiffRateOffset(pDM_Odm->Adapter, Addr, Bitmask, Data); ++} ++ ++void odm_ConfigBB_PHY_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data) ++{ ++ if (Addr == 0xfe) { ++ ODM_sleep_ms(50); ++ } else if (Addr == 0xfd) { ++ ODM_delay_ms(5); ++ } else if (Addr == 0xfc) { ++ ODM_delay_ms(1); ++ } else if (Addr == 0xfb) { ++ ODM_delay_us(50); ++ } else if (Addr == 0xfa) { ++ ODM_delay_us(5); ++ } else if (Addr == 0xf9) { ++ ODM_delay_us(1); ++ } else { ++ if (Addr == 0xa24) ++ pDM_Odm->RFCalibrateInfo.RegA24 = Data; ++ ODM_SetBBReg(pDM_Odm, Addr, Bitmask, Data); ++ ++ /* Add 1us delay between BB/RF register setting. */ ++ ODM_delay_us(1); ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/odm_debug.c b/drivers/staging/r8188eu/hal/odm_debug.c +new file mode 100644 +index 000000000000..7029ec4f771e +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/odm_debug.c +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++ ++u32 GlobalDebugLevel; +diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c +new file mode 100644 +index 000000000000..5a01495d74bc +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/odm_interface.c +@@ -0,0 +1,178 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/odm_precomp.h" ++/* ODM IO Relative API. */ ++ ++u8 ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ return rtw_read8(Adapter, RegAddr); ++} ++ ++u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ return rtw_read16(Adapter, RegAddr); ++} ++ ++u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ return rtw_read32(Adapter, RegAddr); ++} ++ ++void ODM_Write1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 Data) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ rtw_write8(Adapter, RegAddr, Data); ++} ++ ++void ODM_Write2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 Data) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ rtw_write16(Adapter, RegAddr, Data); ++} ++ ++void ODM_Write4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 Data) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ rtw_write32(Adapter, RegAddr, Data); ++} ++ ++void ODM_SetMACReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 BitMask, u32 Data) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ PHY_SetBBReg(Adapter, RegAddr, BitMask, Data); ++} ++ ++u32 ODM_GetMACReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 BitMask) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ return PHY_QueryBBReg(Adapter, RegAddr, BitMask); ++} ++ ++void ODM_SetBBReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 BitMask, u32 Data) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ PHY_SetBBReg(Adapter, RegAddr, BitMask, Data); ++} ++ ++u32 ODM_GetBBReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 BitMask) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ return PHY_QueryBBReg(Adapter, RegAddr, BitMask); ++} ++ ++void ODM_SetRFReg(struct odm_dm_struct *pDM_Odm, enum rf_radio_path eRFPath, u32 RegAddr, u32 BitMask, u32 Data) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ PHY_SetRFReg(Adapter, (enum rf_radio_path)eRFPath, RegAddr, BitMask, Data); ++} ++ ++u32 ODM_GetRFReg(struct odm_dm_struct *pDM_Odm, enum rf_radio_path eRFPath, u32 RegAddr, u32 BitMask) ++{ ++ struct adapter *Adapter = pDM_Odm->Adapter; ++ return PHY_QueryRFReg(Adapter, (enum rf_radio_path)eRFPath, RegAddr, BitMask); ++} ++ ++/* ODM Memory relative API. */ ++void ODM_AllocateMemory(struct odm_dm_struct *pDM_Odm, void **pPtr, u32 length) ++{ ++ *pPtr = vzalloc(length); ++} ++ ++/* length could be ignored, used to detect memory leakage. */ ++void ODM_FreeMemory(struct odm_dm_struct *pDM_Odm, void *pPtr, u32 length) ++{ ++ vfree(pPtr); ++} ++ ++s32 ODM_CompareMemory(struct odm_dm_struct *pDM_Odm, void *pBuf1, void *pBuf2, u32 length) ++{ ++ return !memcmp(pBuf1, pBuf2, length); ++} ++ ++/* ODM MISC relative API. */ ++void ODM_AcquireSpinLock(struct odm_dm_struct *pDM_Odm, enum RT_SPINLOCK_TYPE type) ++{ ++} ++ ++void ODM_ReleaseSpinLock(struct odm_dm_struct *pDM_Odm, enum RT_SPINLOCK_TYPE type) ++{ ++} ++ ++/* Work item relative API. FOr MP driver only~! */ ++void ODM_InitializeWorkItem(struct odm_dm_struct *pDM_Odm, void *pRtWorkItem, ++ RT_WORKITEM_CALL_BACK RtWorkItemCallback, ++ void *pContext, const char *szID) ++{ ++} ++ ++void ODM_StartWorkItem(void *pRtWorkItem) ++{ ++} ++ ++void ODM_StopWorkItem(void *pRtWorkItem) ++{ ++} ++ ++void ODM_FreeWorkItem(void *pRtWorkItem) ++{ ++} ++ ++void ODM_ScheduleWorkItem(void *pRtWorkItem) ++{ ++} ++ ++void ODM_IsWorkItemScheduled(void *pRtWorkItem) ++{ ++} ++ ++/* ODM Timer relative API. */ ++void ODM_StallExecution(u32 usDelay) ++{ ++ udelay(usDelay); ++} ++ ++void ODM_delay_ms(u32 ms) ++{ ++ mdelay(ms); ++} ++ ++void ODM_delay_us(u32 us) ++{ ++ udelay(us); ++} ++ ++void ODM_sleep_ms(u32 ms) ++{ ++ msleep(ms); ++} ++ ++void ODM_sleep_us(u32 us) ++{ ++ rtw_usleep_os(us); ++} ++ ++void ODM_SetTimer(struct odm_dm_struct *pDM_Odm, struct timer_list *pTimer, u32 msDelay) ++{ ++ _set_timer(pTimer, msDelay); /* ms */ ++} ++ ++void ODM_CancelTimer(struct odm_dm_struct *pDM_Odm, struct timer_list *pTimer) ++{ ++ _cancel_timer_ex(pTimer); ++} ++ ++void ODM_ReleaseTimer(struct odm_dm_struct *pDM_Odm, struct timer_list *pTimer) ++{ ++} ++ ++/* ODM FW relative API. */ ++u32 ODM_FillH2CCmd(u8 *pH2CBuffer, u32 H2CBufferLen, u32 CmdNum, ++ u32 *pElementID, u32 *pCmdLen, ++ u8 **pCmbBuffer, u8 *CmdStartSeq) ++{ ++ return true; ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c +new file mode 100644 +index 000000000000..7d50d64cf34d +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c +@@ -0,0 +1,737 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188E_CMD_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/mlme_osdep.h" ++#include "../include/rtw_ioctl_set.h" ++ ++#include "../include/rtl8188e_hal.h" ++ ++#define RTL88E_MAX_H2C_BOX_NUMS 4 ++#define RTL88E_MAX_CMD_LEN 7 ++#define RTL88E_MESSAGE_BOX_SIZE 4 ++#define RTL88E_EX_MESSAGE_BOX_SIZE 4 ++ ++static u8 _is_fw_read_cmd_down(struct adapter *adapt, u8 msgbox_num) ++{ ++ u8 read_down = false; ++ int retry_cnts = 100; ++ ++ u8 valid; ++ ++ do { ++ valid = rtw_read8(adapt, REG_HMETFR) & BIT(msgbox_num); ++ if (0 == valid) ++ read_down = true; ++ } while ((!read_down) && (retry_cnts--)); ++ ++ return read_down; ++} ++ ++/***************************************** ++* H2C Msg format : ++* 0x1DF - 0x1D0 ++*| 31 - 8 | 7-5 4 - 0 | ++*| h2c_msg |Class_ID CMD_ID | ++* ++* Extend 0x1FF - 0x1F0 ++*|31 - 0 | ++*|ext_msg| ++******************************************/ ++static s32 FillH2CCmd_88E(struct adapter *adapt, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer) ++{ ++ u8 bcmd_down = false; ++ s32 retry_cnts = 100; ++ u8 h2c_box_num; ++ u32 msgbox_addr; ++ u32 msgbox_ex_addr; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ u8 cmd_idx, ext_cmd_len; ++ u32 h2c_cmd = 0; ++ u32 h2c_cmd_ex = 0; ++ s32 ret = _FAIL; ++ ++ if (!adapt->bFWReady) { ++ DBG_88E("FillH2CCmd_88E(): return H2C cmd because fw is not ready\n"); ++ return ret; ++ } ++ ++ if (!pCmdBuffer) ++ goto exit; ++ if (CmdLen > RTL88E_MAX_CMD_LEN) ++ goto exit; ++ if (adapt->bSurpriseRemoved) ++ goto exit; ++ ++ /* pay attention to if race condition happened in H2C cmd setting. */ ++ do { ++ h2c_box_num = haldata->LastHMEBoxNum; ++ ++ if (!_is_fw_read_cmd_down(adapt, h2c_box_num)) { ++ DBG_88E(" fw read cmd failed...\n"); ++ goto exit; ++ } ++ ++ *(u8 *)(&h2c_cmd) = ElementID; ++ ++ if (CmdLen <= 3) { ++ memcpy((u8 *)(&h2c_cmd) + 1, pCmdBuffer, CmdLen); ++ } else { ++ memcpy((u8 *)(&h2c_cmd) + 1, pCmdBuffer, 3); ++ ext_cmd_len = CmdLen - 3; ++ memcpy((u8 *)(&h2c_cmd_ex), pCmdBuffer + 3, ext_cmd_len); ++ ++ /* Write Ext command */ ++ msgbox_ex_addr = REG_HMEBOX_EXT_0 + (h2c_box_num * RTL88E_EX_MESSAGE_BOX_SIZE); ++ for (cmd_idx = 0; cmd_idx < ext_cmd_len; cmd_idx++) { ++ rtw_write8(adapt, msgbox_ex_addr + cmd_idx, *((u8 *)(&h2c_cmd_ex) + cmd_idx)); ++ } ++ } ++ /* Write command */ ++ msgbox_addr = REG_HMEBOX_0 + (h2c_box_num * RTL88E_MESSAGE_BOX_SIZE); ++ for (cmd_idx = 0; cmd_idx < RTL88E_MESSAGE_BOX_SIZE; cmd_idx++) { ++ rtw_write8(adapt, msgbox_addr + cmd_idx, *((u8 *)(&h2c_cmd) + cmd_idx)); ++ } ++ bcmd_down = true; ++ ++ haldata->LastHMEBoxNum = (h2c_box_num + 1) % RTL88E_MAX_H2C_BOX_NUMS; ++ ++ } while ((!bcmd_down) && (retry_cnts--)); ++ ++ ret = _SUCCESS; ++ ++exit: ++ ++ return ret; ++} ++ ++u8 rtl8188e_set_rssi_cmd(struct adapter *adapt, u8 *param) ++{ ++ u8 res = _SUCCESS; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ ++ if (haldata->fw_ractrl) { ++ ; ++ } else { ++ DBG_88E("==>%s fw dont support RA\n", __func__); ++ res = _FAIL; ++ } ++ ++ return res; ++} ++ ++u8 rtl8188e_set_raid_cmd(struct adapter *adapt, u32 mask) ++{ ++ u8 buf[3]; ++ u8 res = _SUCCESS; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ ++ if (haldata->fw_ractrl) { ++ __le32 lmask; ++ ++ memset(buf, 0, 3); ++ lmask = cpu_to_le32(mask); ++ memcpy(buf, &lmask, 3); ++ ++ FillH2CCmd_88E(adapt, H2C_DM_MACID_CFG, 3, buf); ++ } else { ++ DBG_88E("==>%s fw dont support RA\n", __func__); ++ res = _FAIL; ++ } ++ ++ return res; ++} ++ ++/* bitmap[0:27] = tx_rate_bitmap */ ++/* bitmap[28:31]= Rate Adaptive id */ ++/* arg[0:4] = macid */ ++/* arg[5] = Short GI */ ++void rtl8188e_Add_RateATid(struct adapter *pAdapter, u32 bitmap, u8 arg, u8 rssi_level) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(pAdapter); ++ ++ u8 macid, raid, short_gi_rate = false; ++ ++ macid = arg & 0x1f; ++ ++ raid = (bitmap >> 28) & 0x0f; ++ bitmap &= 0x0fffffff; ++ ++ if (rssi_level != DM_RATR_STA_INIT) ++ bitmap = ODM_Get_Rate_Bitmap(&haldata->odmpriv, macid, bitmap, rssi_level); ++ ++ bitmap |= ((raid << 28) & 0xf0000000); ++ ++ short_gi_rate = (arg & BIT(5)) ? true : false; ++ ++ raid = (bitmap >> 28) & 0x0f; ++ ++ bitmap &= 0x0fffffff; ++ ++ ODM_RA_UpdateRateInfo_8188E(&haldata->odmpriv, macid, raid, bitmap, short_gi_rate); ++} ++ ++void rtl8188e_set_FwPwrMode_cmd(struct adapter *adapt, u8 Mode) ++{ ++ struct setpwrmode_parm H2CSetPwrMode; ++ struct pwrctrl_priv *pwrpriv = &adapt->pwrctrlpriv; ++ u8 RLBM = 0; /* 0:Min, 1:Max, 2:User define */ ++ ++ DBG_88E("%s: Mode=%d SmartPS=%d UAPSD=%d\n", __func__, ++ Mode, pwrpriv->smart_ps, adapt->registrypriv.uapsd_enable); ++ ++ switch (Mode) { ++ case PS_MODE_ACTIVE: ++ H2CSetPwrMode.Mode = 0; ++ break; ++ case PS_MODE_MIN: ++ H2CSetPwrMode.Mode = 1; ++ break; ++ case PS_MODE_MAX: ++ RLBM = 1; ++ H2CSetPwrMode.Mode = 1; ++ break; ++ case PS_MODE_DTIM: ++ RLBM = 2; ++ H2CSetPwrMode.Mode = 1; ++ break; ++ case PS_MODE_UAPSD_WMM: ++ H2CSetPwrMode.Mode = 2; ++ break; ++ default: ++ H2CSetPwrMode.Mode = 0; ++ break; ++ } ++ ++ H2CSetPwrMode.SmartPS_RLBM = (((pwrpriv->smart_ps << 4) & 0xf0) | (RLBM & 0x0f)); ++ ++ H2CSetPwrMode.AwakeInterval = 1; ++ ++ H2CSetPwrMode.bAllQueueUAPSD = adapt->registrypriv.uapsd_enable; ++ ++ if (Mode > 0) ++ H2CSetPwrMode.PwrState = 0x00;/* AllON(0x0C), RFON(0x04), RFOFF(0x00) */ ++ else ++ H2CSetPwrMode.PwrState = 0x0C;/* AllON(0x0C), RFON(0x04), RFOFF(0x00) */ ++ ++ FillH2CCmd_88E(adapt, H2C_PS_PWR_MODE, sizeof(H2CSetPwrMode), (u8 *)&H2CSetPwrMode); ++ ++} ++ ++void rtl8188e_set_FwMediaStatus_cmd(struct adapter *adapt, __le16 mstatus_rpt) ++{ ++ u8 opmode, macid; ++ u16 mst_rpt = le16_to_cpu(mstatus_rpt); ++ opmode = (u8)mst_rpt; ++ macid = (u8)(mst_rpt >> 8); ++ ++ DBG_88E("### %s: MStatus=%x MACID=%d\n", __func__, opmode, macid); ++ FillH2CCmd_88E(adapt, H2C_COM_MEDIA_STATUS_RPT, sizeof(mst_rpt), (u8 *)&mst_rpt); ++} ++ ++static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength) ++{ ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ u32 rate_len, pktlen; ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++ ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ ++ memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&adapt->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); ++ SetFrameSubType(pframe, WIFI_BEACON); ++ ++ pframe += sizeof(struct rtw_ieee80211_hdr_3addr); ++ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ ++ /* timestamp will be inserted by hardware */ ++ pframe += 8; ++ pktlen += 8; ++ ++ /* beacon interval: 2 bytes */ ++ memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); ++ ++ pframe += 2; ++ pktlen += 2; ++ ++ /* capability info: 2 bytes */ ++ memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); ++ ++ pframe += 2; ++ pktlen += 2; ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { ++ pktlen += cur_network->IELength - sizeof(struct ndis_802_11_fixed_ie); ++ memcpy(pframe, cur_network->IEs + sizeof(struct ndis_802_11_fixed_ie), pktlen); ++ ++ goto _ConstructBeacon; ++ } ++ ++ /* below for ad-hoc mode */ ++ ++ /* SSID */ ++ pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen); ++ ++ /* supported rates... */ ++ rate_len = rtw_get_rateset_len(cur_network->SupportedRates); ++ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen); ++ ++ /* DS parameter set */ ++ pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&cur_network->Configuration.DSConfig, &pktlen); ++ ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { ++ u32 ATIMWindow; ++ /* IBSS Parameter Set... */ ++ ATIMWindow = 0; ++ pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen); ++ } ++ ++ /* todo: ERP IE */ ++ ++ /* EXTERNDED SUPPORTED RATE */ ++ if (rate_len > 8) ++ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen); ++ ++ /* todo:HT for adhoc */ ++ ++_ConstructBeacon: ++ ++ if ((pktlen + TXDESC_SIZE) > 512) { ++ DBG_88E("beacon frame too large\n"); ++ return; ++ } ++ ++ *pLength = pktlen; ++} ++ ++static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength) ++{ ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ __le16 *fctrl; ++ ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ /* Frame control. */ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ SetPwrMgt(fctrl); ++ SetFrameSubType(pframe, WIFI_PSPOLL); ++ ++ /* AID. */ ++ SetDuration(pframe, (pmlmeinfo->aid | 0xc000)); ++ ++ /* BSSID. */ ++ memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ ++ /* TA. */ ++ memcpy(pwlanhdr->addr2, myid(&adapt->eeprompriv), ETH_ALEN); ++ ++ *pLength = 16; ++} ++ ++static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe, ++ u32 *pLength, ++ u8 *StaAddr, ++ u8 bQoS, ++ u8 AC, ++ u8 bEosp, ++ u8 bForcePowerSave) ++{ ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ u32 pktlen; ++ struct mlme_priv *pmlmepriv = &adapt->mlmepriv; ++ struct wlan_network *cur_network = &pmlmepriv->cur_network; ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ if (bForcePowerSave) ++ SetPwrMgt(fctrl); ++ ++ switch (cur_network->network.InfrastructureMode) { ++ case Ndis802_11Infrastructure: ++ SetToDs(fctrl); ++ memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&adapt->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN); ++ break; ++ case Ndis802_11APMode: ++ SetFrDs(fctrl); ++ memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, myid(&adapt->eeprompriv), ETH_ALEN); ++ break; ++ case Ndis802_11IBSS: ++ default: ++ memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, myid(&adapt->eeprompriv), ETH_ALEN); ++ memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); ++ break; ++ } ++ ++ SetSeqNum(pwlanhdr, 0); ++ ++ if (bQoS) { ++ struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr; ++ ++ SetFrameSubType(pframe, WIFI_QOS_DATA_NULL); ++ ++ pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe; ++ SetPriority(&pwlanqoshdr->qc, AC); ++ SetEOSP(&pwlanqoshdr->qc, bEosp); ++ ++ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos); ++ } else { ++ SetFrameSubType(pframe, WIFI_DATA_NULL); ++ ++ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ } ++ ++ *pLength = pktlen; ++} ++ ++static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u8 *StaAddr, bool bHideSSID) ++{ ++ struct rtw_ieee80211_hdr *pwlanhdr; ++ __le16 *fctrl; ++ u8 *mac, *bssid; ++ u32 pktlen; ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ ++ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; ++ ++ mac = myid(&adapt->eeprompriv); ++ bssid = cur_network->MacAddress; ++ ++ fctrl = &pwlanhdr->frame_ctl; ++ *(fctrl) = 0; ++ memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); ++ memcpy(pwlanhdr->addr2, mac, ETH_ALEN); ++ memcpy(pwlanhdr->addr3, bssid, ETH_ALEN); ++ ++ SetSeqNum(pwlanhdr, 0); ++ SetFrameSubType(fctrl, WIFI_PROBERSP); ++ ++ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); ++ pframe += pktlen; ++ ++ if (cur_network->IELength > MAX_IE_SZ) ++ return; ++ ++ memcpy(pframe, cur_network->IEs, cur_network->IELength); ++ pframe += cur_network->IELength; ++ pktlen += cur_network->IELength; ++ ++ *pLength = pktlen; ++} ++ ++/* To check if reserved page content is destroyed by beacon because beacon is too large. */ ++/* 2010.06.23. Added by tynli. */ ++void CheckFwRsvdPageContent(struct adapter *Adapter) ++{ ++} ++ ++/* */ ++/* Description: Fill the reserved packets that FW will use to RSVD page. */ ++/* Now we just send 4 types packet to rsvd page. */ ++/* (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp. */ ++/* Input: */ ++/* bDLFinished - false: At the first time we will send all the packets as a large packet to Hw, */ ++/* so we need to set the packet length to total length. */ ++/* true: At the second time, we should send the first packet (default:beacon) */ ++/* to Hw again and set the length in descriptor to the real beacon length. */ ++/* 2009.10.15 by tynli. */ ++static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished) ++{ ++ struct hal_data_8188e *haldata; ++ struct xmit_frame *pmgntframe; ++ struct pkt_attrib *pattrib; ++ struct xmit_priv *pxmitpriv; ++ struct mlme_ext_priv *pmlmeext; ++ struct mlme_ext_info *pmlmeinfo; ++ u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength; ++ u32 NullDataLength, QosNullLength; ++ u8 *ReservedPagePacket; ++ u8 PageNum, PageNeed, TxDescLen; ++ u16 BufIndex; ++ u32 TotalPacketLen; ++ struct rsvdpage_loc RsvdPageLoc; ++ ++ DBG_88E("%s\n", __func__); ++ ReservedPagePacket = kzalloc(1000, GFP_KERNEL); ++ if (!ReservedPagePacket) { ++ DBG_88E("%s: alloc ReservedPagePacket fail!\n", __func__); ++ return; ++ } ++ ++ haldata = GET_HAL_DATA(adapt); ++ pxmitpriv = &adapt->xmitpriv; ++ pmlmeext = &adapt->mlmeextpriv; ++ pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ TxDescLen = TXDESC_SIZE; ++ PageNum = 0; ++ ++ /* 3 (1) beacon * 2 pages */ ++ BufIndex = TXDESC_OFFSET; ++ ConstructBeacon(adapt, &ReservedPagePacket[BufIndex], &BeaconLength); ++ ++ /* When we count the first page size, we need to reserve description size for the RSVD */ ++ /* packet, it will be filled in front of the packet in TXPKTBUF. */ ++ PageNeed = (u8)PageNum_128(TxDescLen + BeaconLength); ++ /* To reserved 2 pages for beacon buffer. 2010.06.24. */ ++ if (PageNeed == 1) ++ PageNeed += 1; ++ PageNum += PageNeed; ++ haldata->FwRsvdPageStartOffset = PageNum; ++ ++ BufIndex += PageNeed * 128; ++ ++ /* 3 (2) ps-poll *1 page */ ++ RsvdPageLoc.LocPsPoll = PageNum; ++ ConstructPSPoll(adapt, &ReservedPagePacket[BufIndex], &PSPollLength); ++ rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex - TxDescLen], PSPollLength, true, false); ++ ++ PageNeed = (u8)PageNum_128(TxDescLen + PSPollLength); ++ PageNum += PageNeed; ++ ++ BufIndex += PageNeed * 128; ++ ++ /* 3 (3) null data * 1 page */ ++ RsvdPageLoc.LocNullData = PageNum; ++ ConstructNullFunctionData(adapt, &ReservedPagePacket[BufIndex], &NullDataLength, get_my_bssid(&pmlmeinfo->network), false, 0, 0, false); ++ rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex - TxDescLen], NullDataLength, false, false); ++ ++ PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength); ++ PageNum += PageNeed; ++ ++ BufIndex += PageNeed * 128; ++ ++ /* 3 (4) probe response * 1page */ ++ RsvdPageLoc.LocProbeRsp = PageNum; ++ ConstructProbeRsp(adapt, &ReservedPagePacket[BufIndex], &ProbeRspLength, get_my_bssid(&pmlmeinfo->network), false); ++ rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex - TxDescLen], ProbeRspLength, false, false); ++ ++ PageNeed = (u8)PageNum_128(TxDescLen + ProbeRspLength); ++ PageNum += PageNeed; ++ ++ BufIndex += PageNeed * 128; ++ ++ /* 3 (5) Qos null data */ ++ RsvdPageLoc.LocQosNull = PageNum; ++ ConstructNullFunctionData(adapt, &ReservedPagePacket[BufIndex], ++ &QosNullLength, get_my_bssid(&pmlmeinfo->network), true, 0, 0, false); ++ rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex - TxDescLen], QosNullLength, false, false); ++ ++ PageNeed = (u8)PageNum_128(TxDescLen + QosNullLength); ++ PageNum += PageNeed; ++ ++ TotalPacketLen = BufIndex + QosNullLength; ++ pmgntframe = alloc_mgtxmitframe(pxmitpriv); ++ if (!pmgntframe) ++ goto exit; ++ ++ /* update attribute */ ++ pattrib = &pmgntframe->attrib; ++ update_mgntframe_attrib(adapt, pattrib); ++ pattrib->qsel = 0x10; ++ pattrib->last_txcmdsz = TotalPacketLen - TXDESC_OFFSET; ++ pattrib->pktlen = pattrib->last_txcmdsz; ++ memcpy(pmgntframe->buf_addr, ReservedPagePacket, TotalPacketLen); ++ ++ rtw_hal_mgnt_xmit(adapt, pmgntframe); ++ ++ DBG_88E("%s: Set RSVD page location to Fw\n", __func__); ++ FillH2CCmd_88E(adapt, H2C_COM_RSVD_PAGE, sizeof(RsvdPageLoc), (u8 *)&RsvdPageLoc); ++ ++exit: ++ kfree(ReservedPagePacket); ++} ++ ++void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ bool bSendBeacon = false; ++ bool bcn_valid = false; ++ u8 DLBcnCount = 0; ++ u32 poll = 0; ++ ++ DBG_88E("%s mstatus(%x)\n", __func__, mstatus); ++ ++ if (mstatus == 1) { ++ /* We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C. */ ++ /* Suggested by filen. Added by tynli. */ ++ rtw_write16(adapt, REG_BCN_PSR_RPT, (0xC000 | pmlmeinfo->aid)); ++ /* Do not set TSF again here or vWiFi beacon DMA INT will not work. */ ++ ++ /* Set REG_CR bit 8. DMA beacon by SW. */ ++ haldata->RegCR_1 |= BIT(0); ++ rtw_write8(adapt, REG_CR + 1, haldata->RegCR_1); ++ ++ /* Disable Hw protection for a time which revserd for Hw sending beacon. */ ++ /* Fix download reserved page packet fail that access collision with the protection time. */ ++ /* 2010.05.11. Added by tynli. */ ++ rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(3))); ++ rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(4)); ++ ++ if (haldata->RegFwHwTxQCtrl & BIT(6)) { ++ DBG_88E("HalDownloadRSVDPage(): There is an Adapter is sending beacon.\n"); ++ bSendBeacon = true; ++ } ++ ++ /* Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame. */ ++ rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl & (~BIT(6)))); ++ haldata->RegFwHwTxQCtrl &= (~BIT(6)); ++ ++ /* Clear beacon valid check bit. */ ++ rtw_hal_set_hwreg(adapt, HW_VAR_BCN_VALID, NULL); ++ DLBcnCount = 0; ++ poll = 0; ++ do { ++ /* download rsvd page. */ ++ SetFwRsvdPagePkt(adapt, false); ++ DLBcnCount++; ++ do { ++ yield(); ++ /* mdelay(10); */ ++ /* check rsvd page download OK. */ ++ rtw_hal_get_hwreg(adapt, HW_VAR_BCN_VALID, (u8 *)(&bcn_valid)); ++ poll++; ++ } while (!bcn_valid && (poll % 10) != 0 && !adapt->bSurpriseRemoved && !adapt->bDriverStopped); ++ } while (!bcn_valid && DLBcnCount <= 100 && !adapt->bSurpriseRemoved && !adapt->bDriverStopped); ++ ++ if (adapt->bSurpriseRemoved || adapt->bDriverStopped) ++ ; ++ else if (!bcn_valid) ++ DBG_88E("%s: 1 Download RSVD page failed! DLBcnCount:%u, poll:%u\n", __func__, DLBcnCount, poll); ++ else ++ DBG_88E("%s: 1 Download RSVD success! DLBcnCount:%u, poll:%u\n", __func__, DLBcnCount, poll); ++ /* */ ++ /* We just can send the reserved page twice during the time that Tx thread is stopped (e.g. pnpsetpower) */ ++ /* because we need to free the Tx BCN Desc which is used by the first reserved page packet. */ ++ /* At run time, we cannot get the Tx Desc until it is released in TxHandleInterrupt() so we will return */ ++ /* the beacon TCB in the following code. 2011.11.23. by tynli. */ ++ /* */ ++ ++ /* Enable Bcn */ ++ rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(3)); ++ rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(4))); ++ ++ /* To make sure that if there exists an adapter which would like to send beacon. */ ++ /* If exists, the origianl value of 0x422[6] will be 1, we should check this to */ ++ /* prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */ ++ /* the beacon cannot be sent by HW. */ ++ /* 2010.06.23. Added by tynli. */ ++ if (bSendBeacon) { ++ rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl | BIT(6))); ++ haldata->RegFwHwTxQCtrl |= BIT(6); ++ } ++ ++ /* Update RSVD page location H2C to Fw. */ ++ if (bcn_valid) { ++ rtw_hal_set_hwreg(adapt, HW_VAR_BCN_VALID, NULL); ++ DBG_88E("Set RSVD page location to Fw.\n"); ++ } ++ ++ /* Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli. */ ++ /* Clear CR[8] or beacon packet will not be send to TxBuf anymore. */ ++ haldata->RegCR_1 &= (~BIT(0)); ++ rtw_write8(adapt, REG_CR + 1, haldata->RegCR_1); ++ } ++ ++} ++ ++void rtl8188e_set_p2p_ps_offload_cmd(struct adapter *adapt, u8 p2p_ps_state) ++{ ++#ifdef CONFIG_88EU_P2P ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ struct wifidirect_info *pwdinfo = &adapt->wdinfo; ++ struct P2P_PS_Offload_t *p2p_ps_offload = &haldata->p2p_ps_offload; ++ u8 i; ++ ++ switch (p2p_ps_state) { ++ case P2P_PS_DISABLE: ++ DBG_88E("P2P_PS_DISABLE\n"); ++ memset(p2p_ps_offload, 0, 1); ++ break; ++ case P2P_PS_ENABLE: ++ DBG_88E("P2P_PS_ENABLE\n"); ++ /* update CTWindow value. */ ++ if (pwdinfo->ctwindow > 0) { ++ p2p_ps_offload->CTWindow_En = 1; ++ rtw_write8(adapt, REG_P2P_CTWIN, pwdinfo->ctwindow); ++ } ++ ++ /* hw only support 2 set of NoA */ ++ for (i = 0; i < pwdinfo->noa_num; i++) { ++ /* To control the register setting for which NOA */ ++ rtw_write8(adapt, REG_NOA_DESC_SEL, (i << 4)); ++ if (i == 0) ++ p2p_ps_offload->NoA0_En = 1; ++ else ++ p2p_ps_offload->NoA1_En = 1; ++ ++ /* config P2P NoA Descriptor Register */ ++ rtw_write32(adapt, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]); ++ rtw_write32(adapt, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]); ++ rtw_write32(adapt, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]); ++ rtw_write8(adapt, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]); ++ } ++ ++ if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) { ++ /* rst p2p circuit */ ++ rtw_write8(adapt, REG_DUAL_TSF_RST, BIT(4)); ++ ++ p2p_ps_offload->Offload_En = 1; ++ ++ if (pwdinfo->role == P2P_ROLE_GO) { ++ p2p_ps_offload->role = 1; ++ p2p_ps_offload->AllStaSleep = 0; ++ } else { ++ p2p_ps_offload->role = 0; ++ } ++ ++ p2p_ps_offload->discovery = 0; ++ } ++ break; ++ case P2P_PS_SCAN: ++ DBG_88E("P2P_PS_SCAN\n"); ++ p2p_ps_offload->discovery = 1; ++ break; ++ case P2P_PS_SCAN_DONE: ++ DBG_88E("P2P_PS_SCAN_DONE\n"); ++ p2p_ps_offload->discovery = 0; ++ pwdinfo->p2p_ps_state = P2P_PS_ENABLE; ++ break; ++ default: ++ break; ++ } ++ ++ FillH2CCmd_88E(adapt, H2C_PS_P2P_OFFLOAD, 1, (u8 *)p2p_ps_offload); ++#endif ++ ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_dm.c b/drivers/staging/r8188eu/hal/rtl8188e_dm.c +new file mode 100644 +index 000000000000..78552303c990 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_dm.c +@@ -0,0 +1,238 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++/* This file is for 92CE/92CU dynamic mechanism only */ ++#define _RTL8188E_DM_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtl8188e_hal.h" ++ ++static void dm_CheckStatistics(struct adapter *Adapter) ++{ ++} ++ ++/* Initialize GPIO setting registers */ ++static void dm_InitGPIOSetting(struct adapter *Adapter) ++{ ++ u8 tmp1byte; ++ ++ tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG); ++ tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT); ++ ++ rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte); ++} ++ ++/* */ ++/* functions */ ++/* */ ++static void Init_ODM_ComInfo_88E(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &hal_data->dmpriv; ++ struct odm_dm_struct *dm_odm = &hal_data->odmpriv; ++ u8 cut_ver, fab_ver; ++ ++ /* Init Value */ ++ memset(dm_odm, 0, sizeof(*dm_odm)); ++ ++ dm_odm->Adapter = Adapter; ++ ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_PLATFORM, ODM_CE); ++ ++ if (Adapter->interface_type == RTW_GSPI) ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_INTERFACE, ODM_ITRF_SDIO); ++ else ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_INTERFACE, Adapter->interface_type);/* RTL871X_HCI_TYPE */ ++ ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_IC_TYPE, ODM_RTL8188E); ++ ++ fab_ver = ODM_TSMC; ++ cut_ver = ODM_CUT_A; ++ ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_FAB_VER, fab_ver); ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_CUT_VER, cut_ver); ++ ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_MP_TEST_CHIP, IS_NORMAL_CHIP(hal_data->VersionID)); ++ ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_PATCH_ID, hal_data->CustomerID); ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_BWIFI_TEST, Adapter->registrypriv.wifi_spec); ++ ++ if (hal_data->rf_type == RF_1T1R) ++ ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_RF_TYPE, ODM_1T1R); ++ else if (hal_data->rf_type == RF_2T2R) ++ ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_RF_TYPE, ODM_2T2R); ++ else if (hal_data->rf_type == RF_1T2R) ++ ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_RF_TYPE, ODM_1T2R); ++ ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_RF_ANTENNA_TYPE, hal_data->TRxAntDivType); ++ ++ pdmpriv->InitODMFlag = ODM_RF_CALIBRATION | ++ ODM_RF_TX_PWR_TRACK; ++ ++ ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_ABILITY, pdmpriv->InitODMFlag); ++} ++ ++static void Update_ODM_ComInfo_88E(struct adapter *Adapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; ++ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; ++ struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv; ++ struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); ++ struct odm_dm_struct *dm_odm = &hal_data->odmpriv; ++ struct dm_priv *pdmpriv = &hal_data->dmpriv; ++ int i; ++ ++ pdmpriv->InitODMFlag = ODM_BB_DIG | ++ ODM_BB_RA_MASK | ++ ODM_BB_DYNAMIC_TXPWR | ++ ODM_BB_FA_CNT | ++ ODM_BB_RSSI_MONITOR | ++ ODM_BB_CCK_PD | ++ ODM_BB_PWR_SAVE | ++ ODM_MAC_EDCA_TURBO | ++ ODM_RF_CALIBRATION | ++ ODM_RF_TX_PWR_TRACK; ++ if (hal_data->AntDivCfg) ++ pdmpriv->InitODMFlag |= ODM_BB_ANT_DIV; ++ ++ if (Adapter->registrypriv.mp_mode == 1) { ++ pdmpriv->InitODMFlag = ODM_RF_CALIBRATION | ++ ODM_RF_TX_PWR_TRACK; ++ } ++ ++ ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_ABILITY, pdmpriv->InitODMFlag); ++ ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_TX_UNI, &Adapter->xmitpriv.tx_bytes); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_RX_UNI, &Adapter->recvpriv.rx_bytes); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_WM_MODE, &pmlmeext->cur_wireless_mode); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_SEC_CHNL_OFFSET, &hal_data->nCur40MhzPrimeSC); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_SEC_MODE, &Adapter->securitypriv.dot11PrivacyAlgrthm); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_BW, &hal_data->CurrentChannelBW); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_CHNL, &hal_data->CurrentChannel); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_NET_CLOSED, &Adapter->net_closed); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_MP_MODE, &Adapter->registrypriv.mp_mode); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_SCAN, &pmlmepriv->bScanInProcess); ++ ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_POWER_SAVING, &pwrctrlpriv->bpower_saving); ++ ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_RF_ANTENNA_TYPE, hal_data->TRxAntDivType); ++ ++ for (i = 0; i < NUM_STA; i++) ++ ODM_CmnInfoPtrArrayHook(dm_odm, ODM_CMNINFO_STA_STATUS, i, NULL); ++} ++ ++void rtl8188e_InitHalDm(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &hal_data->dmpriv; ++ struct odm_dm_struct *dm_odm = &hal_data->odmpriv; ++ ++ dm_InitGPIOSetting(Adapter); ++ pdmpriv->DM_Type = DM_Type_ByDriver; ++ pdmpriv->DMFlag = DYNAMIC_FUNC_DISABLE; ++ Update_ODM_ComInfo_88E(Adapter); ++ ODM_DMInit(dm_odm); ++ Adapter->fix_rate = 0xFF; ++} ++ ++void rtl8188e_HalDmWatchDog(struct adapter *Adapter) ++{ ++ bool fw_cur_in_ps = false; ++ bool fw_ps_awake = true; ++ u8 hw_init_completed = false; ++ struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); ++ ++ ++ hw_init_completed = Adapter->hw_init_completed; ++ ++ if (!hw_init_completed) ++ return; ++ ++ fw_cur_in_ps = Adapter->pwrctrlpriv.bFwCurrentInPSMode; ++ rtw_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&fw_ps_awake)); ++ ++ /* Fw is under p2p powersaving mode, driver should stop dynamic mechanism. */ ++ /* modifed by thomas. 2011.06.11. */ ++ if (Adapter->wdinfo.p2p_ps_mode) ++ fw_ps_awake = false; ++ ++ if (hw_init_completed && ((!fw_cur_in_ps) && fw_ps_awake)) { ++ /* Calculate Tx/Rx statistics. */ ++ dm_CheckStatistics(Adapter); ++ ++ ++ } ++ ++ /* ODM */ ++ if (hw_init_completed) { ++ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; ++ u8 bLinked = false; ++ ++ if ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) || ++ (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))) { ++ if (Adapter->stapriv.asoc_sta_count > 2) ++ bLinked = true; ++ } else {/* Station mode */ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ bLinked = true; ++ } ++ ++ ODM_CmnInfoUpdate(&hal_data->odmpriv, ODM_CMNINFO_LINK, bLinked); ++ ODM_DMWatchdog(&hal_data->odmpriv); ++ } ++} ++ ++void rtl8188e_init_dm_priv(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &hal_data->dmpriv; ++ ++ memset(pdmpriv, 0, sizeof(struct dm_priv)); ++ Init_ODM_ComInfo_88E(Adapter); ++} ++ ++void rtl8188e_deinit_dm_priv(struct adapter *Adapter) ++{ ++} ++ ++/* Add new function to reset the state of antenna diversity before link. */ ++/* Compare RSSI for deciding antenna */ ++void AntDivCompare8188E(struct adapter *Adapter, struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src) ++{ ++ struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); ++ ++ if (0 != hal_data->AntDivCfg) { ++ /* select optimum_antenna for before linked =>For antenna diversity */ ++ if (dst->Rssi >= src->Rssi) {/* keep org parameter */ ++ src->Rssi = dst->Rssi; ++ src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna; ++ } ++ } ++} ++ ++/* Add new function to reset the state of antenna diversity before link. */ ++u8 AntDivBeforeLink8188E(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); ++ struct odm_dm_struct *dm_odm = &hal_data->odmpriv; ++ struct sw_ant_switch *dm_swat_tbl = &dm_odm->DM_SWAT_Table; ++ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; ++ ++ /* Condition that does not need to use antenna diversity. */ ++ if (hal_data->AntDivCfg == 0) ++ return false; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ return false; ++ ++ if (dm_swat_tbl->SWAS_NoLink_State == 0) { ++ /* switch channel */ ++ dm_swat_tbl->SWAS_NoLink_State = 1; ++ dm_swat_tbl->CurAntenna = (dm_swat_tbl->CurAntenna == Antenna_A) ? Antenna_B : Antenna_A; ++ ++ rtw_antenna_select_cmd(Adapter, dm_swat_tbl->CurAntenna, false); ++ return true; ++ } else { ++ dm_swat_tbl->SWAS_NoLink_State = 0; ++ return false; ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c +new file mode 100644 +index 000000000000..14758361960c +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c +@@ -0,0 +1,2304 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _HAL_INIT_C_ ++ ++#include "../include/linux/firmware.h" ++#include "../include/drv_types.h" ++#include "../include/rtw_efuse.h" ++#include "../include/rtl8188e_hal.h" ++#include "../include/rtw_iol.h" ++#include "../include/usb_ops.h" ++ ++static void iol_mode_enable(struct adapter *padapter, u8 enable) ++{ ++ u8 reg_0xf0 = 0; ++ ++ if (enable) { ++ /* Enable initial offload */ ++ reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG); ++ rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN); ++ ++ if (!padapter->bFWReady) { ++ DBG_88E("bFWReady == false call reset 8051...\n"); ++ _8051Reset88E(padapter); ++ } ++ ++ } else { ++ /* disable initial offload */ ++ reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG); ++ rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN); ++ } ++} ++ ++static s32 iol_execute(struct adapter *padapter, u8 control) ++{ ++ s32 status = _FAIL; ++ u8 reg_0x88 = 0; ++ u32 start = 0, passing_time = 0; ++ ++ control = control & 0x0f; ++ reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0); ++ rtw_write8(padapter, REG_HMEBOX_E0, reg_0x88 | control); ++ ++ start = jiffies; ++ while ((reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0)) & control && ++ (passing_time = rtw_get_passing_time_ms(start)) < 1000) { ++ ; ++ } ++ ++ reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0); ++ status = (reg_0x88 & control) ? _FAIL : _SUCCESS; ++ if (reg_0x88 & control << 4) ++ status = _FAIL; ++ return status; ++} ++ ++static s32 iol_InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy) ++{ ++ s32 rst = _SUCCESS; ++ iol_mode_enable(padapter, 1); ++ rtw_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy); ++ rst = iol_execute(padapter, CMD_INIT_LLT); ++ iol_mode_enable(padapter, 0); ++ return rst; ++} ++ ++static void ++efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) ++{ ++ u8 *efuseTbl = NULL; ++ u8 rtemp8; ++ u16 eFuse_Addr = 0; ++ u8 offset, wren; ++ u16 i, j; ++ u16 **eFuseWord = NULL; ++ u16 efuse_utilized = 0; ++ u8 u1temp = 0; ++ ++ efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL); ++ if (!efuseTbl) { ++ DBG_88E("%s: alloc efuseTbl fail!\n", __func__); ++ goto exit; ++ } ++ ++ eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16)); ++ if (!eFuseWord) { ++ DBG_88E("%s: alloc eFuseWord fail!\n", __func__); ++ goto exit; ++ } ++ ++ /* 0. Refresh efuse init map as all oxFF. */ ++ for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) ++ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) ++ eFuseWord[i][j] = 0xFFFF; ++ ++ /* */ ++ /* 1. Read the first byte to check if efuse is empty!!! */ ++ /* */ ++ /* */ ++ rtemp8 = *(phymap + eFuse_Addr); ++ if (rtemp8 != 0xFF) { ++ efuse_utilized++; ++ eFuse_Addr++; ++ } else { ++ DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, rtemp8); ++ goto exit; ++ } ++ ++ /* */ ++ /* 2. Read real efuse content. Filter PG header and every section data. */ ++ /* */ ++ while ((rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) { ++ /* Check PG header for section num. */ ++ if ((rtemp8 & 0x1F) == 0x0F) { /* extended header */ ++ u1temp = ((rtemp8 & 0xE0) >> 5); ++ rtemp8 = *(phymap + eFuse_Addr); ++ if ((rtemp8 & 0x0F) == 0x0F) { ++ eFuse_Addr++; ++ rtemp8 = *(phymap + eFuse_Addr); ++ ++ if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) ++ eFuse_Addr++; ++ continue; ++ } else { ++ offset = ((rtemp8 & 0xF0) >> 1) | u1temp; ++ wren = (rtemp8 & 0x0F); ++ eFuse_Addr++; ++ } ++ } else { ++ offset = ((rtemp8 >> 4) & 0x0f); ++ wren = (rtemp8 & 0x0f); ++ } ++ ++ if (offset < EFUSE_MAX_SECTION_88E) { ++ /* Get word enable value from PG header */ ++ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { ++ /* Check word enable condition in the section */ ++ if (!(wren & 0x01)) { ++ rtemp8 = *(phymap + eFuse_Addr); ++ eFuse_Addr++; ++ efuse_utilized++; ++ eFuseWord[offset][i] = (rtemp8 & 0xff); ++ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) ++ break; ++ rtemp8 = *(phymap + eFuse_Addr); ++ eFuse_Addr++; ++ efuse_utilized++; ++ eFuseWord[offset][i] |= (((u16)rtemp8 << 8) & 0xff00); ++ ++ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) ++ break; ++ } ++ wren >>= 1; ++ } ++ } ++ /* Read next PG header */ ++ rtemp8 = *(phymap + eFuse_Addr); ++ ++ if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) { ++ efuse_utilized++; ++ eFuse_Addr++; ++ } ++ } ++ ++ /* */ ++ /* 3. Collect 16 sections and 4 word unit into Efuse map. */ ++ /* */ ++ for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) { ++ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) { ++ efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff); ++ efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff); ++ } ++ } ++ ++ /* */ ++ /* 4. Copy from Efuse map to output pointer memory!!! */ ++ /* */ ++ for (i = 0; i < _size_byte; i++) ++ pbuf[i] = efuseTbl[_offset + i]; ++ ++ /* */ ++ /* 5. Calculate Efuse utilization. */ ++ /* */ ++ ++exit: ++ kfree(efuseTbl); ++ kfree(eFuseWord); ++} ++ ++static void efuse_read_phymap_from_txpktbuf( ++ struct adapter *adapter, ++ int bcnhead, /* beacon head, where FW store len(2-byte) and efuse physical map. */ ++ u8 *content, /* buffer to store efuse physical map */ ++ u16 *size /* for efuse content: the max byte to read. will update to byte read */ ++ ) ++{ ++ u16 dbg_addr = 0; ++ u32 start = 0, passing_time = 0; ++ u8 reg_0x143 = 0; ++ __le32 lo32 = 0, hi32 = 0; ++ u16 len = 0, count = 0; ++ int i = 0; ++ u16 limit = *size; ++ ++ u8 *pos = content; ++ ++ if (bcnhead < 0) /* if not valid */ ++ bcnhead = rtw_read8(adapter, REG_TDECTRL + 1); ++ ++ DBG_88E("%s bcnhead:%d\n", __func__, bcnhead); ++ ++ rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT); ++ ++ dbg_addr = bcnhead * 128 / 8; /* 8-bytes addressing */ ++ ++ while (1) { ++ rtw_write16(adapter, REG_PKTBUF_DBG_ADDR, dbg_addr + i); ++ ++ rtw_write8(adapter, REG_TXPKTBUF_DBG, 0); ++ start = jiffies; ++ while (!(reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG)) && ++ (passing_time = rtw_get_passing_time_ms(start)) < 1000) { ++ DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, rtw_read8(adapter, 0x106)); ++ rtw_usleep_os(100); ++ } ++ ++ /* data from EEPROM needs to be in LE */ ++ lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L)); ++ hi32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H)); ++ ++ if (i == 0) { ++ /* Although lenc is only used in a debug statement, ++ * do not remove it as the rtw_read16() call consumes ++ * 2 bytes from the EEPROM source. ++ */ ++ u16 lenc = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L); ++ ++ len = le32_to_cpu(lo32) & 0x0000ffff; ++ ++ limit = (len - 2 < limit) ? len - 2 : limit; ++ ++ DBG_88E("%s len:%u, lenc:%u\n", __func__, len, lenc); ++ ++ memcpy(pos, ((u8 *)&lo32) + 2, (limit >= count + 2) ? 2 : limit - count); ++ count += (limit >= count + 2) ? 2 : limit - count; ++ pos = content + count; ++ } else { ++ memcpy(pos, ((u8 *)&lo32), (limit >= count + 4) ? 4 : limit - count); ++ count += (limit >= count + 4) ? 4 : limit - count; ++ pos = content + count; ++ } ++ ++ if (limit > count && len - 2 > count) { ++ memcpy(pos, (u8 *)&hi32, (limit >= count + 4) ? 4 : limit - count); ++ count += (limit >= count + 4) ? 4 : limit - count; ++ pos = content + count; ++ } ++ ++ if (limit <= count || len - 2 <= count) ++ break; ++ i++; ++ } ++ rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS); ++ DBG_88E("%s read count:%u\n", __func__, count); ++ *size = count; ++} ++ ++static s32 iol_read_efuse(struct adapter *padapter, u8 txpktbuf_bndy, u16 offset, u16 size_byte, u8 *logical_map) ++{ ++ s32 status = _FAIL; ++ u8 physical_map[512]; ++ u16 size = 512; ++ ++ rtw_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy); ++ memset(physical_map, 0xFF, 512); ++ rtw_write8(padapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT); ++ status = iol_execute(padapter, CMD_READ_EFUSE_MAP); ++ if (status == _SUCCESS) ++ efuse_read_phymap_from_txpktbuf(padapter, txpktbuf_bndy, physical_map, &size); ++ efuse_phymap_to_logical(physical_map, offset, size_byte, logical_map); ++ return status; ++} ++ ++s32 rtl8188e_iol_efuse_patch(struct adapter *padapter) ++{ ++ s32 result = _SUCCESS; ++ ++ DBG_88E("==> %s\n", __func__); ++ if (rtw_IOL_applied(padapter)) { ++ iol_mode_enable(padapter, 1); ++ result = iol_execute(padapter, CMD_READ_EFUSE_MAP); ++ if (result == _SUCCESS) ++ result = iol_execute(padapter, CMD_EFUSE_PATCH); ++ ++ iol_mode_enable(padapter, 0); ++ } ++ return result; ++} ++ ++static s32 iol_ioconfig(struct adapter *padapter, u8 iocfg_bndy) ++{ ++ s32 rst = _SUCCESS; ++ ++ rtw_write8(padapter, REG_TDECTRL + 1, iocfg_bndy); ++ rst = iol_execute(padapter, CMD_IOCONFIG); ++ return rst; ++} ++ ++static int rtl8188e_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt) ++{ ++ struct pkt_attrib *pattrib = &xmit_frame->attrib; ++ u8 i; ++ int ret = _FAIL; ++ ++ if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS) ++ goto exit; ++ if (rtw_usb_bulk_size_boundary(adapter, TXDESC_SIZE + pattrib->last_txcmdsz)) { ++ if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS) ++ goto exit; ++ } ++ ++ dump_mgntframe_and_wait(adapter, xmit_frame, max_wating_ms); ++ ++ iol_mode_enable(adapter, 1); ++ for (i = 0; i < bndy_cnt; i++) { ++ u8 page_no = 0; ++ page_no = i * 2; ++ ret = iol_ioconfig(adapter, page_no); ++ if (ret != _SUCCESS) ++ break; ++ } ++ iol_mode_enable(adapter, 0); ++exit: ++ /* restore BCN_HEAD */ ++ rtw_write8(adapter, REG_TDECTRL + 1, 0); ++ return ret; ++} ++ ++void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len) ++{ ++ u32 fifo_data, reg_140; ++ u32 addr, rstatus, loop = 0; ++ u16 data_cnts = (data_len / 8) + 1; ++ u8 *pbuf = vzalloc(data_len + 10); ++ DBG_88E("###### %s ######\n", __func__); ++ ++ rtw_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT); ++ if (pbuf) { ++ for (addr = 0; addr < data_cnts; addr++) { ++ rtw_write32(Adapter, 0x140, addr); ++ rtw_usleep_os(2); ++ loop = 0; ++ do { ++ rstatus = (reg_140 = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL) & BIT(24)); ++ if (rstatus) { ++ fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L); ++ memcpy(pbuf + (addr * 8), &fifo_data, 4); ++ ++ fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H); ++ memcpy(pbuf + (addr * 8 + 4), &fifo_data, 4); ++ } ++ rtw_usleep_os(2); ++ } while (!rstatus && (loop++ < 10)); ++ } ++ rtw_IOL_cmd_buf_dump(Adapter, data_len, pbuf); ++ vfree(pbuf); ++ } ++ DBG_88E("###### %s ######\n", __func__); ++} ++ ++static void _FWDownloadEnable(struct adapter *padapter, bool enable) ++{ ++ u8 tmp; ++ ++ if (enable) { ++ /* MCU firmware download enable. */ ++ tmp = rtw_read8(padapter, REG_MCUFWDL); ++ rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01); ++ ++ /* 8051 reset */ ++ tmp = rtw_read8(padapter, REG_MCUFWDL + 2); ++ rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7); ++ } else { ++ /* MCU firmware download disable. */ ++ tmp = rtw_read8(padapter, REG_MCUFWDL); ++ rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe); ++ ++ /* Reserved for fw extension. */ ++ rtw_write8(padapter, REG_MCUFWDL + 1, 0x00); ++ } ++} ++ ++#define MAX_REG_BOLCK_SIZE 196 ++ ++static int _BlockWrite(struct adapter *padapter, void *buffer, u32 buffSize) ++{ ++ int ret = _SUCCESS; ++ u32 blockSize_p1 = 4; /* (Default) Phase #1 : PCI muse use 4-byte write to download FW */ ++ u32 blockSize_p2 = 8; /* Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */ ++ u32 blockSize_p3 = 1; /* Phase #3 : Use 1-byte, the remnant of FW image. */ ++ u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0; ++ u32 remainSize_p1 = 0, remainSize_p2 = 0; ++ u8 *bufferPtr = (u8 *)buffer; ++ u32 i = 0, offset = 0; ++ ++ blockSize_p1 = MAX_REG_BOLCK_SIZE; ++ ++ /* 3 Phase #1 */ ++ blockCount_p1 = buffSize / blockSize_p1; ++ remainSize_p1 = buffSize % blockSize_p1; ++ ++ for (i = 0; i < blockCount_p1; i++) { ++ ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1)); ++ if (ret == _FAIL) ++ goto exit; ++ } ++ ++ /* 3 Phase #2 */ ++ if (remainSize_p1) { ++ offset = blockCount_p1 * blockSize_p1; ++ ++ blockCount_p2 = remainSize_p1 / blockSize_p2; ++ remainSize_p2 = remainSize_p1 % blockSize_p2; ++ ++ for (i = 0; i < blockCount_p2; i++) { ++ ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + offset + i * blockSize_p2), blockSize_p2, (bufferPtr + offset + i * blockSize_p2)); ++ ++ if (ret == _FAIL) ++ goto exit; ++ } ++ } ++ ++ /* 3 Phase #3 */ ++ if (remainSize_p2) { ++ offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2); ++ ++ blockCount_p3 = remainSize_p2 / blockSize_p3; ++ ++ for (i = 0; i < blockCount_p3; i++) { ++ ret = rtw_write8(padapter, (FW_8188E_START_ADDRESS + offset + i), *(bufferPtr + offset + i)); ++ ++ if (ret == _FAIL) ++ goto exit; ++ } ++ } ++ ++exit: ++ return ret; ++} ++ ++static int _PageWrite(struct adapter *padapter, u32 page, void *buffer, u32 size) ++{ ++ u8 value8; ++ u8 u8Page = (u8)(page & 0x07); ++ ++ value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page; ++ rtw_write8(padapter, REG_MCUFWDL + 2, value8); ++ ++ return _BlockWrite(padapter, buffer, size); ++} ++ ++static int _WriteFW(struct adapter *padapter, void *buffer, u32 size) ++{ ++ /* Since we need dynamic decide method of dwonload fw, so we call this function to get chip version. */ ++ /* We can remove _ReadChipVersion from ReadpadapterInfo8192C later. */ ++ int ret = _SUCCESS; ++ u32 pageNums, remainSize; ++ u32 page, offset; ++ u8 *bufferPtr = (u8 *)buffer; ++ ++ pageNums = size / MAX_PAGE_SIZE; ++ remainSize = size % MAX_PAGE_SIZE; ++ ++ for (page = 0; page < pageNums; page++) { ++ offset = page * MAX_PAGE_SIZE; ++ ret = _PageWrite(padapter, page, bufferPtr + offset, MAX_PAGE_SIZE); ++ ++ if (ret == _FAIL) ++ goto exit; ++ } ++ if (remainSize) { ++ offset = pageNums * MAX_PAGE_SIZE; ++ page = pageNums; ++ ret = _PageWrite(padapter, page, bufferPtr + offset, remainSize); ++ ++ if (ret == _FAIL) ++ goto exit; ++ } ++exit: ++ return ret; ++} ++ ++void _8051Reset88E(struct adapter *padapter) ++{ ++ u8 u1bTmp; ++ ++ u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); ++ rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp & (~BIT(2))); ++ rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp | (BIT(2))); ++ DBG_88E("=====> _8051Reset88E(): 8051 reset success .\n"); ++} ++ ++static s32 _FWFreeToGo(struct adapter *padapter) ++{ ++ u32 counter = 0; ++ u32 value32; ++ ++ /* polling CheckSum report */ ++ do { ++ value32 = rtw_read32(padapter, REG_MCUFWDL); ++ if (value32 & FWDL_ChkSum_rpt) ++ break; ++ } while (counter++ < POLLING_READY_TIMEOUT_COUNT); ++ ++ if (counter >= POLLING_READY_TIMEOUT_COUNT) { ++ DBG_88E("%s: chksum report fail! REG_MCUFWDL:0x%08x\n", __func__, value32); ++ return _FAIL; ++ } ++ DBG_88E("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__, value32); ++ ++ value32 = rtw_read32(padapter, REG_MCUFWDL); ++ value32 |= MCUFWDL_RDY; ++ value32 &= ~WINTINI_RDY; ++ rtw_write32(padapter, REG_MCUFWDL, value32); ++ ++ _8051Reset88E(padapter); ++ ++ /* polling for FW ready */ ++ counter = 0; ++ do { ++ value32 = rtw_read32(padapter, REG_MCUFWDL); ++ if (value32 & WINTINI_RDY) { ++ DBG_88E("%s: Polling FW ready success!! REG_MCUFWDL:0x%08x\n", __func__, value32); ++ return _SUCCESS; ++ } ++ udelay(5); ++ } while (counter++ < POLLING_READY_TIMEOUT_COUNT); ++ ++ DBG_88E("%s: Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", __func__, value32); ++ return _FAIL; ++} ++ ++#define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0) ++ ++static int load_firmware(struct rt_firmware *pFirmware, struct device *device) ++{ ++ s32 rtStatus = _SUCCESS; ++ const struct firmware *fw; ++ const char *fw_name = "rtlwifi/rtl8188eufw.bin"; ++ int err = request_firmware(&fw, fw_name, device); ++ ++ if (err) { ++ pr_err("Request firmware failed with error 0x%x\n", err); ++ rtStatus = _FAIL; ++ goto Exit; ++ } ++ if (!fw) { ++ pr_err("Firmware %s not available\n", fw_name); ++ rtStatus = _FAIL; ++ goto Exit; ++ } ++ if (fw->size > FW_8188E_SIZE) { ++ rtStatus = _FAIL; ++ goto Exit; ++ } ++ ++ pFirmware->szFwBuffer = kzalloc(FW_8188E_SIZE, GFP_KERNEL); ++ if (!pFirmware->szFwBuffer) { ++ pr_err("Failed to allocate pFirmware->szFwBuffer\n"); ++ rtStatus = _FAIL; ++ goto Exit; ++ } ++ memcpy(pFirmware->szFwBuffer, fw->data, fw->size); ++ pFirmware->ulFwLength = fw->size; ++ release_firmware(fw); ++ DBG_88E_LEVEL(_drv_info_, "+%s: !bUsedWoWLANFw, FmrmwareLen:%d+\n", __func__, pFirmware->ulFwLength); ++ ++Exit: ++ return rtStatus; ++} ++ ++s32 rtl8188e_FirmwareDownload(struct adapter *padapter) ++{ ++ s32 rtStatus = _SUCCESS; ++ u8 writeFW_retry = 0; ++ u32 fwdl_start_time; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); ++ struct device *device = dvobj_to_dev(dvobj); ++ struct rt_firmware_hdr *pFwHdr = NULL; ++ u8 *pFirmwareBuf; ++ u32 FirmwareLen; ++ static int log_version; ++ ++ if (!dvobj->firmware.szFwBuffer) ++ rtStatus = load_firmware(&dvobj->firmware, device); ++ if (rtStatus == _FAIL) { ++ dvobj->firmware.szFwBuffer = NULL; ++ goto Exit; ++ } ++ pFirmwareBuf = dvobj->firmware.szFwBuffer; ++ FirmwareLen = dvobj->firmware.ulFwLength; ++ ++ /* To Check Fw header. Added by tynli. 2009.12.04. */ ++ pFwHdr = (struct rt_firmware_hdr *)dvobj->firmware.szFwBuffer; ++ ++ pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version); ++ pHalData->FirmwareSubVersion = pFwHdr->Subversion; ++ pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature); ++ ++ if (!log_version++) ++ pr_info("%sFirmware Version %d, SubVersion %d, Signature 0x%x\n", ++ DRIVER_PREFIX, pHalData->FirmwareVersion, ++ pHalData->FirmwareSubVersion, pHalData->FirmwareSignature); ++ ++ if (IS_FW_HEADER_EXIST(pFwHdr)) { ++ /* Shift 32 bytes for FW header */ ++ pFirmwareBuf = pFirmwareBuf + 32; ++ FirmwareLen = FirmwareLen - 32; ++ } ++ ++ /* Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */ ++ /* or it will cause download Fw fail. 2010.02.01. by tynli. */ ++ if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */ ++ rtw_write8(padapter, REG_MCUFWDL, 0x00); ++ _8051Reset88E(padapter); ++ } ++ ++ _FWDownloadEnable(padapter, true); ++ fwdl_start_time = jiffies; ++ while (1) { ++ /* reset the FWDL chksum */ ++ rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt); ++ ++ rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen); ++ ++ if (rtStatus == _SUCCESS || ++ (rtw_get_passing_time_ms(fwdl_start_time) > 500 && writeFW_retry++ >= 3)) ++ break; ++ ++ DBG_88E("%s writeFW_retry:%u, time after fwdl_start_time:%ums\n", ++ __func__, writeFW_retry, rtw_get_passing_time_ms(fwdl_start_time) ++ ); ++ } ++ _FWDownloadEnable(padapter, false); ++ if (_SUCCESS != rtStatus) { ++ DBG_88E("DL Firmware failed!\n"); ++ goto Exit; ++ } ++ ++ rtStatus = _FWFreeToGo(padapter); ++ if (_SUCCESS != rtStatus) { ++ DBG_88E("DL Firmware failed!\n"); ++ goto Exit; ++ } ++ ++Exit: ++ return rtStatus; ++} ++ ++void rtl8188e_InitializeFirmwareVars(struct adapter *padapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ ++ /* Init Fw LPS related. */ ++ padapter->pwrctrlpriv.bFwCurrentInPSMode = false; ++ ++ /* Init H2C counter. by tynli. 2009.12.09. */ ++ pHalData->LastHMEBoxNum = 0; ++} ++ ++static void rtl8188e_free_hal_data(struct adapter *padapter) ++{ ++ ++ kfree(padapter->HalData); ++ padapter->HalData = NULL; ++ ++} ++ ++/* */ ++/* Efuse related code */ ++/* */ ++enum{ ++ VOLTAGE_V25 = 0x03, ++ LDOE25_SHIFT = 28, ++ }; ++ ++static bool ++hal_EfusePgPacketWrite2ByteHeader( ++ struct adapter *pAdapter, ++ u8 efuseType, ++ u16 *pAddr, ++ struct pgpkt *pTargetPkt, ++ bool bPseudoTest); ++static bool ++hal_EfusePgPacketWrite1ByteHeader( ++ struct adapter *pAdapter, ++ u8 efuseType, ++ u16 *pAddr, ++ struct pgpkt *pTargetPkt, ++ bool bPseudoTest); ++static bool ++hal_EfusePgPacketWriteData( ++ struct adapter *pAdapter, ++ u8 efuseType, ++ u16 *pAddr, ++ struct pgpkt *pTargetPkt, ++ bool bPseudoTest); ++ ++static void ++hal_EfusePowerSwitch_RTL8188E( ++ struct adapter *pAdapter, ++ u8 bWrite, ++ u8 PwrState) ++{ ++ u8 tempval; ++ u16 tmpV16; ++ ++ if (PwrState) { ++ rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); ++ ++ /* 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */ ++ tmpV16 = rtw_read16(pAdapter, REG_SYS_ISO_CTRL); ++ if (!(tmpV16 & PWC_EV12V)) { ++ tmpV16 |= PWC_EV12V; ++ rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16); ++ } ++ /* Reset: 0x0000h[28], default valid */ ++ tmpV16 = rtw_read16(pAdapter, REG_SYS_FUNC_EN); ++ if (!(tmpV16 & FEN_ELDR)) { ++ tmpV16 |= FEN_ELDR; ++ rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16); ++ } ++ ++ /* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */ ++ tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR); ++ if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) { ++ tmpV16 |= (LOADER_CLK_EN | ANA8M); ++ rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16); ++ } ++ ++ if (bWrite) { ++ /* Enable LDO 2.5V before read/write action */ ++ tempval = rtw_read8(pAdapter, EFUSE_TEST + 3); ++ tempval &= 0x0F; ++ tempval |= (VOLTAGE_V25 << 4); ++ rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval | 0x80)); ++ } ++ } else { ++ rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); ++ ++ if (bWrite) { ++ /* Disable LDO 2.5V after read/write action */ ++ tempval = rtw_read8(pAdapter, EFUSE_TEST + 3); ++ rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval & 0x7F)); ++ } ++ } ++} ++ ++static void ++rtl8188e_EfusePowerSwitch( ++ struct adapter *pAdapter, ++ u8 bWrite, ++ u8 PwrState) ++{ ++ hal_EfusePowerSwitch_RTL8188E(pAdapter, bWrite, PwrState); ++} ++ ++static void Hal_EfuseReadEFuse88E(struct adapter *Adapter, ++ u16 _offset, ++ u16 _size_byte, ++ u8 *pbuf, ++ bool bPseudoTest ++ ) ++{ ++ u8 *efuseTbl = NULL; ++ u8 rtemp8[1]; ++ u16 eFuse_Addr = 0; ++ u8 offset, wren; ++ u16 i, j; ++ u16 **eFuseWord = NULL; ++ u16 efuse_utilized = 0; ++ u8 u1temp = 0; ++ ++ /* */ ++ /* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */ ++ /* */ ++ if ((_offset + _size_byte) > EFUSE_MAP_LEN_88E) {/* total E-Fuse table is 512bytes */ ++ DBG_88E("Hal_EfuseReadEFuse88E(): Invalid offset(%#x) with read bytes(%#x)!!\n", _offset, _size_byte); ++ goto exit; ++ } ++ ++ efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL); ++ if (!efuseTbl) { ++ DBG_88E("%s: alloc efuseTbl fail!\n", __func__); ++ goto exit; ++ } ++ ++ eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16)); ++ if (!eFuseWord) { ++ DBG_88E("%s: alloc eFuseWord fail!\n", __func__); ++ goto exit; ++ } ++ ++ /* 0. Refresh efuse init map as all oxFF. */ ++ for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) ++ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) ++ eFuseWord[i][j] = 0xFFFF; ++ ++ /* */ ++ /* 1. Read the first byte to check if efuse is empty!!! */ ++ /* */ ++ /* */ ++ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); ++ if (*rtemp8 != 0xFF) { ++ efuse_utilized++; ++ eFuse_Addr++; ++ } else { ++ DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, *rtemp8); ++ goto exit; ++ } ++ ++ /* */ ++ /* 2. Read real efuse content. Filter PG header and every section data. */ ++ /* */ ++ while ((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) { ++ /* Check PG header for section num. */ ++ if ((*rtemp8 & 0x1F) == 0x0F) { /* extended header */ ++ u1temp = ((*rtemp8 & 0xE0) >> 5); ++ ++ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); ++ ++ if ((*rtemp8 & 0x0F) == 0x0F) { ++ eFuse_Addr++; ++ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); ++ ++ if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) ++ eFuse_Addr++; ++ continue; ++ } else { ++ offset = ((*rtemp8 & 0xF0) >> 1) | u1temp; ++ wren = (*rtemp8 & 0x0F); ++ eFuse_Addr++; ++ } ++ } else { ++ offset = ((*rtemp8 >> 4) & 0x0f); ++ wren = (*rtemp8 & 0x0f); ++ } ++ ++ if (offset < EFUSE_MAX_SECTION_88E) { ++ /* Get word enable value from PG header */ ++ ++ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { ++ /* Check word enable condition in the section */ ++ if (!(wren & 0x01)) { ++ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); ++ eFuse_Addr++; ++ efuse_utilized++; ++ eFuseWord[offset][i] = (*rtemp8 & 0xff); ++ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) ++ break; ++ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); ++ eFuse_Addr++; ++ efuse_utilized++; ++ eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00); ++ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) ++ break; ++ } ++ wren >>= 1; ++ } ++ } ++ ++ /* Read next PG header */ ++ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); ++ ++ if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) { ++ efuse_utilized++; ++ eFuse_Addr++; ++ } ++ } ++ ++ /* 3. Collect 16 sections and 4 word unit into Efuse map. */ ++ for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) { ++ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) { ++ efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff); ++ efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff); ++ } ++ } ++ ++ /* 4. Copy from Efuse map to output pointer memory!!! */ ++ for (i = 0; i < _size_byte; i++) ++ pbuf[i] = efuseTbl[_offset + i]; ++ ++ /* 5. Calculate Efuse utilization. */ ++ rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_BYTES, (u8 *)&eFuse_Addr); ++ ++exit: ++ kfree(efuseTbl); ++ kfree(eFuseWord); ++} ++ ++static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest) ++{ ++ if (!bPseudoTest) { ++ int ret = _FAIL; ++ if (rtw_IOL_applied(Adapter)) { ++ rtw_hal_power_on(Adapter); ++ ++ iol_mode_enable(Adapter, 1); ++ ret = iol_read_efuse(Adapter, 0, _offset, _size_byte, pbuf); ++ iol_mode_enable(Adapter, 0); ++ ++ if (_SUCCESS == ret) ++ goto exit; ++ } ++ } ++ Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest); ++ ++exit: ++ return; ++} ++ ++static void ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest) ++{ ++ Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest); ++} ++ ++static void rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType, ++ u16 _offset, u16 _size_byte, u8 *pbuf, ++ bool bPseudoTest) ++{ ++ if (bPseudoTest) ++ ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest); ++ else ++ ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest); ++} ++ ++/* Do not support BT */ ++static void Hal_EFUSEGetEfuseDefinition88E(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut) ++{ ++ switch (type) { ++ case TYPE_EFUSE_MAX_SECTION: ++ { ++ u8 *pMax_section; ++ pMax_section = (u8 *)pOut; ++ *pMax_section = EFUSE_MAX_SECTION_88E; ++ } ++ break; ++ case TYPE_EFUSE_REAL_CONTENT_LEN: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E; ++ } ++ break; ++ case TYPE_EFUSE_CONTENT_LEN_BANK: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E; ++ } ++ break; ++ case TYPE_AVAILABLE_EFUSE_BYTES_BANK: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E); ++ } ++ break; ++ case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E); ++ } ++ break; ++ case TYPE_EFUSE_MAP_LEN: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = (u16)EFUSE_MAP_LEN_88E; ++ } ++ break; ++ case TYPE_EFUSE_PROTECT_BYTES_BANK: ++ { ++ u8 *pu1Tmp; ++ pu1Tmp = (u8 *)pOut; ++ *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E); ++ } ++ break; ++ default: ++ { ++ u8 *pu1Tmp; ++ pu1Tmp = (u8 *)pOut; ++ *pu1Tmp = 0; ++ } ++ break; ++ } ++} ++ ++static void Hal_EFUSEGetEfuseDefinition_Pseudo88E(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut) ++{ ++ switch (type) { ++ case TYPE_EFUSE_MAX_SECTION: ++ { ++ u8 *pMax_section; ++ pMax_section = (u8 *)pOut; ++ *pMax_section = EFUSE_MAX_SECTION_88E; ++ } ++ break; ++ case TYPE_EFUSE_REAL_CONTENT_LEN: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E; ++ } ++ break; ++ case TYPE_EFUSE_CONTENT_LEN_BANK: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E; ++ } ++ break; ++ case TYPE_AVAILABLE_EFUSE_BYTES_BANK: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E); ++ } ++ break; ++ case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E); ++ } ++ break; ++ case TYPE_EFUSE_MAP_LEN: ++ { ++ u16 *pu2Tmp; ++ pu2Tmp = (u16 *)pOut; ++ *pu2Tmp = (u16)EFUSE_MAP_LEN_88E; ++ } ++ break; ++ case TYPE_EFUSE_PROTECT_BYTES_BANK: ++ { ++ u8 *pu1Tmp; ++ pu1Tmp = (u8 *)pOut; ++ *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E); ++ } ++ break; ++ default: ++ { ++ u8 *pu1Tmp; ++ pu1Tmp = (u8 *)pOut; ++ *pu1Tmp = 0; ++ } ++ break; ++ } ++} ++ ++static void rtl8188e_EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool bPseudoTest) ++{ ++ if (bPseudoTest) ++ Hal_EFUSEGetEfuseDefinition_Pseudo88E(pAdapter, efuseType, type, pOut); ++ else ++ Hal_EFUSEGetEfuseDefinition88E(pAdapter, efuseType, type, pOut); ++} ++ ++static u8 Hal_EfuseWordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest) ++{ ++ u16 tmpaddr = 0; ++ u16 start_addr = efuse_addr; ++ u8 badworden = 0x0F; ++ u8 tmpdata[8]; ++ ++ memset((void *)tmpdata, 0xff, PGPKT_DATA_SIZE); ++ ++ if (!(word_en & BIT(0))) { ++ tmpaddr = start_addr; ++ efuse_OneByteWrite(pAdapter, start_addr++, data[0], bPseudoTest); ++ efuse_OneByteWrite(pAdapter, start_addr++, data[1], bPseudoTest); ++ ++ efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[0], bPseudoTest); ++ efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[1], bPseudoTest); ++ if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1])) ++ badworden &= (~BIT(0)); ++ } ++ if (!(word_en & BIT(1))) { ++ tmpaddr = start_addr; ++ efuse_OneByteWrite(pAdapter, start_addr++, data[2], bPseudoTest); ++ efuse_OneByteWrite(pAdapter, start_addr++, data[3], bPseudoTest); ++ ++ efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[2], bPseudoTest); ++ efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[3], bPseudoTest); ++ if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3])) ++ badworden &= (~BIT(1)); ++ } ++ if (!(word_en & BIT(2))) { ++ tmpaddr = start_addr; ++ efuse_OneByteWrite(pAdapter, start_addr++, data[4], bPseudoTest); ++ efuse_OneByteWrite(pAdapter, start_addr++, data[5], bPseudoTest); ++ ++ efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[4], bPseudoTest); ++ efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[5], bPseudoTest); ++ if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5])) ++ badworden &= (~BIT(2)); ++ } ++ if (!(word_en & BIT(3))) { ++ tmpaddr = start_addr; ++ efuse_OneByteWrite(pAdapter, start_addr++, data[6], bPseudoTest); ++ efuse_OneByteWrite(pAdapter, start_addr++, data[7], bPseudoTest); ++ ++ efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[6], bPseudoTest); ++ efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[7], bPseudoTest); ++ if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7])) ++ badworden &= (~BIT(3)); ++ } ++ return badworden; ++} ++ ++static u8 Hal_EfuseWordEnableDataWrite_Pseudo(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest) ++{ ++ u8 ret; ++ ++ ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest); ++ return ret; ++} ++ ++static u8 rtl8188e_Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest) ++{ ++ u8 ret = 0; ++ ++ if (bPseudoTest) ++ ret = Hal_EfuseWordEnableDataWrite_Pseudo(pAdapter, efuse_addr, word_en, data, bPseudoTest); ++ else ++ ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest); ++ return ret; ++} ++ ++static u16 hal_EfuseGetCurrentSize_8188e(struct adapter *pAdapter, bool bPseudoTest) ++{ ++ int bContinual = true; ++ u16 efuse_addr = 0; ++ u8 hoffset = 0, hworden = 0; ++ u8 efuse_data, word_cnts = 0; ++ ++ if (bPseudoTest) ++ efuse_addr = (u16)(fakeEfuseUsedBytes); ++ else ++ rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr); ++ ++ while (bContinual && ++ efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest) && ++ AVAILABLE_EFUSE_ADDR(efuse_addr)) { ++ if (efuse_data != 0xFF) { ++ if ((efuse_data & 0x1F) == 0x0F) { /* extended header */ ++ hoffset = efuse_data; ++ efuse_addr++; ++ efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest); ++ if ((efuse_data & 0x0F) == 0x0F) { ++ efuse_addr++; ++ continue; ++ } else { ++ hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); ++ hworden = efuse_data & 0x0F; ++ } ++ } else { ++ hoffset = (efuse_data >> 4) & 0x0F; ++ hworden = efuse_data & 0x0F; ++ } ++ word_cnts = Efuse_CalculateWordCnts(hworden); ++ /* read next header */ ++ efuse_addr = efuse_addr + (word_cnts * 2) + 1; ++ } else { ++ bContinual = false; ++ } ++ } ++ ++ if (bPseudoTest) ++ fakeEfuseUsedBytes = efuse_addr; ++ else ++ rtw_hal_set_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr); ++ ++ return efuse_addr; ++} ++ ++static u16 Hal_EfuseGetCurrentSize_Pseudo(struct adapter *pAdapter, bool bPseudoTest) ++{ ++ u16 ret = 0; ++ ++ ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest); ++ return ret; ++} ++ ++static u16 rtl8188e_EfuseGetCurrentSize(struct adapter *pAdapter, u8 efuseType, bool bPseudoTest) ++{ ++ u16 ret = 0; ++ ++ if (bPseudoTest) ++ ret = Hal_EfuseGetCurrentSize_Pseudo(pAdapter, bPseudoTest); ++ else ++ ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest); ++ return ret; ++} ++ ++static int hal_EfusePgPacketRead_8188e(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest) ++{ ++ u8 ReadState = PG_STATE_HEADER; ++ int bContinual = true; ++ int bDataEmpty = true; ++ u8 efuse_data, word_cnts = 0; ++ u16 efuse_addr = 0; ++ u8 hoffset = 0, hworden = 0; ++ u8 tmpidx = 0; ++ u8 tmpdata[8]; ++ u8 max_section = 0; ++ u8 tmp_header = 0; ++ ++ EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, (void *)&max_section, bPseudoTest); ++ ++ if (!data) ++ return false; ++ if (offset > max_section) ++ return false; ++ ++ memset((void *)data, 0xff, sizeof(u8) * PGPKT_DATA_SIZE); ++ memset((void *)tmpdata, 0xff, sizeof(u8) * PGPKT_DATA_SIZE); ++ ++ /* Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. */ ++ /* Skip dummy parts to prevent unexpected data read from Efuse. */ ++ /* By pass right now. 2009.02.19. */ ++ while (bContinual && AVAILABLE_EFUSE_ADDR(efuse_addr)) { ++ /* Header Read ------------- */ ++ if (ReadState & PG_STATE_HEADER) { ++ if (efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) { ++ if (EXT_HEADER(efuse_data)) { ++ tmp_header = efuse_data; ++ efuse_addr++; ++ efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest); ++ if (!ALL_WORDS_DISABLED(efuse_data)) { ++ hoffset = ((tmp_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); ++ hworden = efuse_data & 0x0F; ++ } else { ++ DBG_88E("Error, All words disabled\n"); ++ efuse_addr++; ++ continue; ++ } ++ } else { ++ hoffset = (efuse_data >> 4) & 0x0F; ++ hworden = efuse_data & 0x0F; ++ } ++ word_cnts = Efuse_CalculateWordCnts(hworden); ++ bDataEmpty = true; ++ ++ if (hoffset == offset) { ++ for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) { ++ if (efuse_OneByteRead(pAdapter, efuse_addr + 1 + tmpidx, &efuse_data, bPseudoTest)) { ++ tmpdata[tmpidx] = efuse_data; ++ if (efuse_data != 0xff) ++ bDataEmpty = false; ++ } ++ } ++ if (!bDataEmpty) { ++ ReadState = PG_STATE_DATA; ++ } else {/* read next header */ ++ efuse_addr = efuse_addr + (word_cnts * 2) + 1; ++ ReadState = PG_STATE_HEADER; ++ } ++ } else {/* read next header */ ++ efuse_addr = efuse_addr + (word_cnts * 2) + 1; ++ ReadState = PG_STATE_HEADER; ++ } ++ } else { ++ bContinual = false; ++ } ++ } else if (ReadState & PG_STATE_DATA) { ++ /* Data section Read ------------- */ ++ efuse_WordEnableDataRead(hworden, tmpdata, data); ++ efuse_addr = efuse_addr + (word_cnts * 2) + 1; ++ ReadState = PG_STATE_HEADER; ++ } ++ ++ } ++ ++ if ((data[0] == 0xff) && (data[1] == 0xff) && (data[2] == 0xff) && (data[3] == 0xff) && ++ (data[4] == 0xff) && (data[5] == 0xff) && (data[6] == 0xff) && (data[7] == 0xff)) ++ return false; ++ else ++ return true; ++} ++ ++static int Hal_EfusePgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest) ++{ ++ int ret; ++ ++ ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest); ++ return ret; ++} ++ ++static int Hal_EfusePgPacketRead_Pseudo(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest) ++{ ++ int ret; ++ ++ ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest); ++ return ret; ++} ++ ++static int rtl8188e_Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest) ++{ ++ int ret; ++ ++ if (bPseudoTest) ++ ret = Hal_EfusePgPacketRead_Pseudo(pAdapter, offset, data, bPseudoTest); ++ else ++ ret = Hal_EfusePgPacketRead(pAdapter, offset, data, bPseudoTest); ++ return ret; ++} ++ ++static bool hal_EfuseFixHeaderProcess(struct adapter *pAdapter, u8 efuseType, struct pgpkt *pFixPkt, u16 *pAddr, bool bPseudoTest) ++{ ++ u8 originaldata[8], badworden = 0; ++ u16 efuse_addr = *pAddr; ++ u32 PgWriteSuccess = 0; ++ ++ memset((void *)originaldata, 0xff, 8); ++ ++ if (Efuse_PgPacketRead(pAdapter, pFixPkt->offset, originaldata, bPseudoTest)) { ++ /* check if data exist */ ++ badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pFixPkt->word_en, originaldata, bPseudoTest); ++ ++ if (badworden != 0xf) { /* write fail */ ++ PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pFixPkt->offset, badworden, originaldata, bPseudoTest); ++ ++ if (!PgWriteSuccess) ++ return false; ++ else ++ efuse_addr = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest); ++ } else { ++ efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1; ++ } ++ } else { ++ efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1; ++ } ++ *pAddr = efuse_addr; ++ return true; ++} ++ ++static bool hal_EfusePgPacketWrite2ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest) ++{ ++ bool bRet = false; ++ u16 efuse_addr = *pAddr, efuse_max_available_len = 0; ++ u8 pg_header = 0, tmp_header = 0, pg_header_temp = 0; ++ u8 repeatcnt = 0; ++ ++ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len, bPseudoTest); ++ ++ while (efuse_addr < efuse_max_available_len) { ++ pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F; ++ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); ++ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); ++ ++ while (tmp_header == 0xFF) { ++ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) ++ return false; ++ ++ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); ++ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); ++ } ++ ++ /* to write ext_header */ ++ if (tmp_header == pg_header) { ++ efuse_addr++; ++ pg_header_temp = pg_header; ++ pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en; ++ ++ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); ++ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); ++ ++ while (tmp_header == 0xFF) { ++ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) ++ return false; ++ ++ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); ++ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); ++ } ++ ++ if ((tmp_header & 0x0F) == 0x0F) { /* word_en PG fail */ ++ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) { ++ return false; ++ } else { ++ efuse_addr++; ++ continue; ++ } ++ } else if (pg_header != tmp_header) { /* offset PG fail */ ++ struct pgpkt fixPkt; ++ fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1); ++ fixPkt.word_en = tmp_header & 0x0F; ++ fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en); ++ if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest)) ++ return false; ++ } else { ++ bRet = true; ++ break; ++ } ++ } else if ((tmp_header & 0x1F) == 0x0F) { /* wrong extended header */ ++ efuse_addr += 2; ++ continue; ++ } ++ } ++ ++ *pAddr = efuse_addr; ++ return bRet; ++} ++ ++static bool hal_EfusePgPacketWrite1ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest) ++{ ++ bool bRet = false; ++ u8 pg_header = 0, tmp_header = 0; ++ u16 efuse_addr = *pAddr; ++ u8 repeatcnt = 0; ++ ++ pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en; ++ ++ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); ++ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); ++ ++ while (tmp_header == 0xFF) { ++ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) ++ return false; ++ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); ++ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); ++ } ++ ++ if (pg_header == tmp_header) { ++ bRet = true; ++ } else { ++ struct pgpkt fixPkt; ++ fixPkt.offset = (tmp_header >> 4) & 0x0F; ++ fixPkt.word_en = tmp_header & 0x0F; ++ fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en); ++ if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest)) ++ return false; ++ } ++ ++ *pAddr = efuse_addr; ++ return bRet; ++} ++ ++static bool hal_EfusePgPacketWriteData(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest) ++{ ++ u16 efuse_addr = *pAddr; ++ u8 badworden = 0; ++ u32 PgWriteSuccess = 0; ++ ++ badworden = 0x0f; ++ badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest); ++ if (badworden == 0x0F) { ++ /* write ok */ ++ return true; ++ } else { ++ /* reorganize other pg packet */ ++ PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest); ++ if (!PgWriteSuccess) ++ return false; ++ else ++ return true; ++ } ++} ++ ++static bool ++hal_EfusePgPacketWriteHeader( ++ struct adapter *pAdapter, ++ u8 efuseType, ++ u16 *pAddr, ++ struct pgpkt *pTargetPkt, ++ bool bPseudoTest) ++{ ++ bool bRet = false; ++ ++ if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE) ++ bRet = hal_EfusePgPacketWrite2ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest); ++ else ++ bRet = hal_EfusePgPacketWrite1ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest); ++ ++ return bRet; ++} ++ ++static bool wordEnMatched(struct pgpkt *pTargetPkt, struct pgpkt *pCurPkt, ++ u8 *pWden) ++{ ++ u8 match_word_en = 0x0F; /* default all words are disabled */ ++ ++ /* check if the same words are enabled both target and current PG packet */ ++ if (((pTargetPkt->word_en & BIT(0)) == 0) && ++ ((pCurPkt->word_en & BIT(0)) == 0)) ++ match_word_en &= ~BIT(0); /* enable word 0 */ ++ if (((pTargetPkt->word_en & BIT(1)) == 0) && ++ ((pCurPkt->word_en & BIT(1)) == 0)) ++ match_word_en &= ~BIT(1); /* enable word 1 */ ++ if (((pTargetPkt->word_en & BIT(2)) == 0) && ++ ((pCurPkt->word_en & BIT(2)) == 0)) ++ match_word_en &= ~BIT(2); /* enable word 2 */ ++ if (((pTargetPkt->word_en & BIT(3)) == 0) && ++ ((pCurPkt->word_en & BIT(3)) == 0)) ++ match_word_en &= ~BIT(3); /* enable word 3 */ ++ ++ *pWden = match_word_en; ++ ++ if (match_word_en != 0xf) ++ return true; ++ else ++ return false; ++} ++ ++static bool hal_EfuseCheckIfDatafollowed(struct adapter *pAdapter, u8 word_cnts, u16 startAddr, bool bPseudoTest) ++{ ++ bool bRet = false; ++ u8 i, efuse_data; ++ ++ for (i = 0; i < (word_cnts * 2); i++) { ++ if (efuse_OneByteRead(pAdapter, (startAddr + i), &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) ++ bRet = true; ++ } ++ return bRet; ++} ++ ++static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest) ++{ ++ bool bRet = false; ++ u8 i, efuse_data = 0, cur_header = 0; ++ u8 matched_wden = 0, badworden = 0; ++ u16 startAddr = 0, efuse_max_available_len = 0, efuse_max = 0; ++ struct pgpkt curPkt; ++ ++ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len, bPseudoTest); ++ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&efuse_max, bPseudoTest); ++ ++ if (efuseType == EFUSE_WIFI) { ++ if (bPseudoTest) { ++ startAddr = (u16)(fakeEfuseUsedBytes % EFUSE_REAL_CONTENT_LEN); ++ } else { ++ rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr); ++ startAddr %= EFUSE_REAL_CONTENT_LEN; ++ } ++ } else { ++ if (bPseudoTest) ++ startAddr = (u16)(fakeBTEfuseUsedBytes % EFUSE_REAL_CONTENT_LEN); ++ else ++ startAddr = (u16)(BTEfuseUsedBytes % EFUSE_REAL_CONTENT_LEN); ++ } ++ ++ while (1) { ++ if (startAddr >= efuse_max_available_len) { ++ bRet = false; ++ break; ++ } ++ ++ if (efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) { ++ if (EXT_HEADER(efuse_data)) { ++ cur_header = efuse_data; ++ startAddr++; ++ efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest); ++ if (ALL_WORDS_DISABLED(efuse_data)) { ++ bRet = false; ++ break; ++ } else { ++ curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); ++ curPkt.word_en = efuse_data & 0x0F; ++ } ++ } else { ++ cur_header = efuse_data; ++ curPkt.offset = (cur_header >> 4) & 0x0F; ++ curPkt.word_en = cur_header & 0x0F; ++ } ++ ++ curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en); ++ /* if same header is found but no data followed */ ++ /* write some part of data followed by the header. */ ++ if ((curPkt.offset == pTargetPkt->offset) && ++ (!hal_EfuseCheckIfDatafollowed(pAdapter, curPkt.word_cnts, startAddr + 1, bPseudoTest)) && ++ wordEnMatched(pTargetPkt, &curPkt, &matched_wden)) { ++ /* Here to write partial data */ ++ badworden = Efuse_WordEnableDataWrite(pAdapter, startAddr + 1, matched_wden, pTargetPkt->data, bPseudoTest); ++ if (badworden != 0x0F) { ++ u32 PgWriteSuccess = 0; ++ /* if write fail on some words, write these bad words again */ ++ ++ PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest); ++ ++ if (!PgWriteSuccess) { ++ bRet = false; /* write fail, return */ ++ break; ++ } ++ } ++ /* partial write ok, update the target packet for later use */ ++ for (i = 0; i < 4; i++) { ++ if ((matched_wden & (0x1 << i)) == 0) /* this word has been written */ ++ pTargetPkt->word_en |= (0x1 << i); /* disable the word */ ++ } ++ pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en); ++ } ++ /* read from next header */ ++ startAddr = startAddr + (curPkt.word_cnts * 2) + 1; ++ } else { ++ /* not used header, 0xff */ ++ *pAddr = startAddr; ++ bRet = true; ++ break; ++ } ++ } ++ return bRet; ++} ++ ++static bool ++hal_EfusePgCheckAvailableAddr( ++ struct adapter *pAdapter, ++ u8 efuseType, ++ bool bPseudoTest ++ ) ++{ ++ u16 efuse_max_available_len = 0; ++ ++ /* Change to check TYPE_EFUSE_MAP_LEN , because 8188E raw 256, logic map over 256. */ ++ EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&efuse_max_available_len, false); ++ ++ if (Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest) >= efuse_max_available_len) ++ return false; ++ return true; ++} ++ ++static void hal_EfuseConstructPGPkt(u8 offset, u8 word_en, u8 *pData, struct pgpkt *pTargetPkt) ++{ ++ memset((void *)pTargetPkt->data, 0xFF, sizeof(u8) * 8); ++ pTargetPkt->offset = offset; ++ pTargetPkt->word_en = word_en; ++ efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data); ++ pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en); ++} ++ ++static bool hal_EfusePgPacketWrite_8188e(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *pData, bool bPseudoTest) ++{ ++ struct pgpkt targetPkt; ++ u16 startAddr = 0; ++ u8 efuseType = EFUSE_WIFI; ++ ++ if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest)) ++ return false; ++ ++ hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt); ++ ++ if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) ++ return false; ++ ++ if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) ++ return false; ++ ++ if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) ++ return false; ++ ++ return true; ++} ++ ++static int Hal_EfusePgPacketWrite_Pseudo(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest) ++{ ++ int ret; ++ ++ ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest); ++ return ret; ++} ++ ++static int Hal_EfusePgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest) ++{ ++ int ret = 0; ++ ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest); ++ ++ return ret; ++} ++ ++static int rtl8188e_Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest) ++{ ++ int ret; ++ ++ if (bPseudoTest) ++ ret = Hal_EfusePgPacketWrite_Pseudo(pAdapter, offset, word_en, data, bPseudoTest); ++ else ++ ret = Hal_EfusePgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest); ++ return ret; ++} ++ ++static struct HAL_VERSION ReadChipVersion8188E(struct adapter *padapter) ++{ ++ u32 value32; ++ struct HAL_VERSION ChipVersion; ++ struct hal_data_8188e *pHalData; ++ ++ pHalData = GET_HAL_DATA(padapter); ++ ++ value32 = rtw_read32(padapter, REG_SYS_CFG); ++ ChipVersion.ICType = CHIP_8188E; ++ ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP); ++ ++ ChipVersion.RFType = RF_TYPE_1T1R; ++ ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC); ++ ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT; /* IC version (CUT) */ ++ ++ /* For regulator mode. by tynli. 2011.01.14 */ ++ pHalData->RegulatorMode = ((value32 & TRP_BT_EN) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR); ++ ++ ChipVersion.ROMVer = 0; /* ROM code version. */ ++ pHalData->MultiFunc = RT_MULTI_FUNC_NONE; ++ ++ dump_chip_info(ChipVersion); ++ ++ pHalData->VersionID = ChipVersion; ++ ++ if (IS_1T2R(ChipVersion)) { ++ pHalData->rf_type = RF_1T2R; ++ pHalData->NumTotalRFPath = 2; ++ } else if (IS_2T2R(ChipVersion)) { ++ pHalData->rf_type = RF_2T2R; ++ pHalData->NumTotalRFPath = 2; ++ } else { ++ pHalData->rf_type = RF_1T1R; ++ pHalData->NumTotalRFPath = 1; ++ } ++ ++ MSG_88E("RF_Type is %x!!\n", pHalData->rf_type); ++ ++ return ChipVersion; ++} ++ ++static void rtl8188e_read_chip_version(struct adapter *padapter) ++{ ++ ReadChipVersion8188E(padapter); ++} ++ ++static void rtl8188e_GetHalODMVar(struct adapter *Adapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet) ++{ ++} ++ ++static void rtl8188e_SetHalODMVar(struct adapter *Adapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct odm_dm_struct *podmpriv = &pHalData->odmpriv; ++ switch (eVariable) { ++ case HAL_ODM_STA_INFO: ++ { ++ struct sta_info *psta = (struct sta_info *)pValue1; ++ if (bSet) { ++ DBG_88E("### Set STA_(%d) info\n", psta->mac_id); ++ ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta); ++ ODM_RAInfo_Init(podmpriv, psta->mac_id); ++ } else { ++ DBG_88E("### Clean STA_(%d) info\n", psta->mac_id); ++ ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, NULL); ++ } ++ } ++ break; ++ case HAL_ODM_P2P_STATE: ++ ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet); ++ break; ++ case HAL_ODM_WIFI_DISPLAY_STATE: ++ ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet); ++ break; ++ default: ++ break; ++ } ++} ++ ++void rtl8188e_clone_haldata(struct adapter *dst_adapter, struct adapter *src_adapter) ++{ ++ memcpy(dst_adapter->HalData, src_adapter->HalData, dst_adapter->hal_data_sz); ++} ++ ++void rtl8188e_start_thread(struct adapter *padapter) ++{ ++} ++ ++void rtl8188e_stop_thread(struct adapter *padapter) ++{ ++} ++ ++static void hal_notch_filter_8188e(struct adapter *adapter, bool enable) ++{ ++ if (enable) { ++ DBG_88E("Enable notch filter\n"); ++ rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT(1)); ++ } else { ++ DBG_88E("Disable notch filter\n"); ++ rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT(1)); ++ } ++} ++void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc) ++{ ++ pHalFunc->free_hal_data = &rtl8188e_free_hal_data; ++ ++ pHalFunc->dm_init = &rtl8188e_init_dm_priv; ++ pHalFunc->dm_deinit = &rtl8188e_deinit_dm_priv; ++ ++ pHalFunc->read_chip_version = &rtl8188e_read_chip_version; ++ ++ pHalFunc->set_bwmode_handler = &PHY_SetBWMode8188E; ++ pHalFunc->set_channel_handler = &PHY_SwChnl8188E; ++ ++ pHalFunc->hal_dm_watchdog = &rtl8188e_HalDmWatchDog; ++ ++ pHalFunc->Add_RateATid = &rtl8188e_Add_RateATid; ++ pHalFunc->run_thread = &rtl8188e_start_thread; ++ pHalFunc->cancel_thread = &rtl8188e_stop_thread; ++ ++ pHalFunc->AntDivBeforeLinkHandler = &AntDivBeforeLink8188E; ++ pHalFunc->AntDivCompareHandler = &AntDivCompare8188E; ++ pHalFunc->read_bbreg = &rtl8188e_PHY_QueryBBReg; ++ pHalFunc->write_bbreg = &rtl8188e_PHY_SetBBReg; ++ pHalFunc->read_rfreg = &rtl8188e_PHY_QueryRFReg; ++ pHalFunc->write_rfreg = &rtl8188e_PHY_SetRFReg; ++ ++ /* Efuse related function */ ++ pHalFunc->EfusePowerSwitch = &rtl8188e_EfusePowerSwitch; ++ pHalFunc->ReadEFuse = &rtl8188e_ReadEFuse; ++ pHalFunc->EFUSEGetEfuseDefinition = &rtl8188e_EFUSE_GetEfuseDefinition; ++ pHalFunc->EfuseGetCurrentSize = &rtl8188e_EfuseGetCurrentSize; ++ pHalFunc->Efuse_PgPacketRead = &rtl8188e_Efuse_PgPacketRead; ++ pHalFunc->Efuse_PgPacketWrite = &rtl8188e_Efuse_PgPacketWrite; ++ pHalFunc->Efuse_WordEnableDataWrite = &rtl8188e_Efuse_WordEnableDataWrite; ++ ++ pHalFunc->sreset_init_value = &sreset_init_value; ++ pHalFunc->sreset_reset_value = &sreset_reset_value; ++ pHalFunc->silentreset = &rtl8188e_silentreset_for_specific_platform; ++ pHalFunc->sreset_xmit_status_check = &rtl8188e_sreset_xmit_status_check; ++ pHalFunc->sreset_linked_status_check = &rtl8188e_sreset_linked_status_check; ++ pHalFunc->sreset_get_wifi_status = &sreset_get_wifi_status; ++ ++ pHalFunc->GetHalODMVarHandler = &rtl8188e_GetHalODMVar; ++ pHalFunc->SetHalODMVarHandler = &rtl8188e_SetHalODMVar; ++ ++ pHalFunc->IOL_exec_cmds_sync = &rtl8188e_IOL_exec_cmds_sync; ++ ++ pHalFunc->hal_notch_filter = &hal_notch_filter_8188e; ++} ++ ++u8 GetEEPROMSize8188E(struct adapter *padapter) ++{ ++ u8 size = 0; ++ u32 cr; ++ ++ cr = rtw_read16(padapter, REG_9346CR); ++ /* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */ ++ size = (cr & BOOT_FROM_EEPROM) ? 6 : 4; ++ ++ MSG_88E("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46"); ++ ++ return size; ++} ++ ++/* */ ++/* */ ++/* LLT R/W/Init function */ ++/* */ ++/* */ ++static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data) ++{ ++ s32 status = _SUCCESS; ++ s32 count = 0; ++ u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); ++ u16 LLTReg = REG_LLT_INIT; ++ ++ rtw_write32(padapter, LLTReg, value); ++ ++ /* polling */ ++ do { ++ value = rtw_read32(padapter, LLTReg); ++ if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) ++ break; ++ ++ if (count > POLLING_LLT_THRESHOLD) { ++ status = _FAIL; ++ break; ++ } ++ } while (count++); ++ ++ return status; ++} ++ ++s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy) ++{ ++ s32 status = _FAIL; ++ u32 i; ++ u32 Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER;/* 176, 22k */ ++ ++ if (rtw_IOL_applied(padapter)) { ++ status = iol_InitLLTTable(padapter, txpktbuf_bndy); ++ } else { ++ for (i = 0; i < (txpktbuf_bndy - 1); i++) { ++ status = _LLTWrite(padapter, i, i + 1); ++ if (_SUCCESS != status) ++ return status; ++ } ++ ++ /* end of list */ ++ status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF); ++ if (_SUCCESS != status) ++ return status; ++ ++ /* Make the other pages as ring buffer */ ++ /* This ring buffer is used as beacon buffer if we config this MAC as two MAC transfer. */ ++ /* Otherwise used as local loopback buffer. */ ++ for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) { ++ status = _LLTWrite(padapter, i, (i + 1)); ++ if (_SUCCESS != status) ++ return status; ++ } ++ ++ /* Let last entry point to the start entry of ring buffer */ ++ status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy); ++ if (_SUCCESS != status) { ++ return status; ++ } ++ } ++ ++ return status; ++} ++ ++void ++Hal_InitPGData88E(struct adapter *padapter) ++{ ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); ++ ++ if (!pEEPROM->bautoload_fail_flag) { /* autoload OK. */ ++ if (!is_boot_from_eeprom(padapter)) { ++ /* Read EFUSE real map to shadow. */ ++ EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false); ++ } ++ } else {/* autoload fail */ ++ /* update to default value 0xFF */ ++ if (!is_boot_from_eeprom(padapter)) ++ EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false); ++ } ++} ++ ++void ++Hal_EfuseParseIDCode88E( ++ struct adapter *padapter, ++ u8 *hwinfo ++ ) ++{ ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); ++ u16 EEPROMId; ++ ++ /* Check 0x8129 again for making sure autoload status!! */ ++ EEPROMId = le16_to_cpu(*((__le16 *)hwinfo)); ++ if (EEPROMId != RTL_EEPROM_ID) { ++ pr_err("EEPROM ID(%#x) is invalid!!\n", EEPROMId); ++ pEEPROM->bautoload_fail_flag = true; ++ } else { ++ pEEPROM->bautoload_fail_flag = false; ++ } ++ ++ pr_info("EEPROM ID = 0x%04x\n", EEPROMId); ++} ++ ++static void Hal_ReadPowerValueFromPROM_8188E(struct txpowerinfo24g *pwrInfo24G, u8 *PROMContent, bool AutoLoadFail) ++{ ++ u32 rfPath, eeAddr = EEPROM_TX_PWR_INX_88E, group, TxCount = 0; ++ ++ memset(pwrInfo24G, 0, sizeof(struct txpowerinfo24g)); ++ ++ if (AutoLoadFail) { ++ for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) { ++ /* 2.4G default value */ ++ for (group = 0; group < MAX_CHNL_GROUP_24G; group++) { ++ pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX; ++ pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX; ++ } ++ for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) { ++ if (TxCount == 0) { ++ pwrInfo24G->BW20_Diff[rfPath][0] = EEPROM_DEFAULT_24G_HT20_DIFF; ++ pwrInfo24G->OFDM_Diff[rfPath][0] = EEPROM_DEFAULT_24G_OFDM_DIFF; ++ } else { ++ pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ } ++ } ++ } ++ return; ++ } ++ ++ for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) { ++ /* 2.4G default value */ ++ for (group = 0; group < MAX_CHNL_GROUP_24G; group++) { ++ pwrInfo24G->IndexCCK_Base[rfPath][group] = PROMContent[eeAddr++]; ++ if (pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF) ++ pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX; ++ } ++ for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) { ++ pwrInfo24G->IndexBW40_Base[rfPath][group] = PROMContent[eeAddr++]; ++ if (pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF) ++ pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX; ++ } ++ for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) { ++ if (TxCount == 0) { ++ pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0; ++ if (PROMContent[eeAddr] == 0xFF) { ++ pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_HT20_DIFF; ++ } else { ++ pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4; ++ if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */ ++ pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0; ++ } ++ ++ if (PROMContent[eeAddr] == 0xFF) { ++ pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_OFDM_DIFF; ++ } else { ++ pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f); ++ if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */ ++ pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0; ++ } ++ pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0; ++ eeAddr++; ++ } else { ++ if (PROMContent[eeAddr] == 0xFF) { ++ pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ } else { ++ pwrInfo24G->BW40_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4; ++ if (pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */ ++ pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0; ++ } ++ ++ if (PROMContent[eeAddr] == 0xFF) { ++ pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ } else { ++ pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f); ++ if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */ ++ pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0; ++ } ++ eeAddr++; ++ ++ if (PROMContent[eeAddr] == 0xFF) { ++ pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ } else { ++ pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4; ++ if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */ ++ pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0; ++ } ++ ++ if (PROMContent[eeAddr] == 0xFF) { ++ pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; ++ } else { ++ pwrInfo24G->CCK_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f); ++ if (pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */ ++ pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0; ++ } ++ eeAddr++; ++ } ++ } ++ } ++} ++ ++static void hal_get_chnl_group_88e(u8 chnl, u8 *group) ++{ ++ if (chnl < 3) /* Channel 1-2 */ ++ *group = 0; ++ else if (chnl < 6) /* Channel 3-5 */ ++ *group = 1; ++ else if (chnl < 9) /* Channel 6-8 */ ++ *group = 2; ++ else if (chnl < 12) /* Channel 9-11 */ ++ *group = 3; ++ else if (chnl < 14) /* Channel 12-13 */ ++ *group = 4; ++ else if (chnl == 14) /* Channel 14 */ ++ *group = 5; ++} ++ ++void Hal_ReadPowerSavingMode88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail) ++{ ++ if (AutoLoadFail) { ++ padapter->pwrctrlpriv.bHWPowerdown = false; ++ padapter->pwrctrlpriv.bSupportRemoteWakeup = false; ++ } else { ++ /* hw power down mode selection , 0:rf-off / 1:power down */ ++ ++ if (padapter->registrypriv.hwpdn_mode == 2) ++ padapter->pwrctrlpriv.bHWPowerdown = (hwinfo[EEPROM_RF_FEATURE_OPTION_88E] & BIT(4)); ++ else ++ padapter->pwrctrlpriv.bHWPowerdown = padapter->registrypriv.hwpdn_mode; ++ ++ /* decide hw if support remote wakeup function */ ++ /* if hw supported, 8051 (SIE) will generate WeakUP signal(D+/D- toggle) when autoresume */ ++ padapter->pwrctrlpriv.bSupportRemoteWakeup = (hwinfo[EEPROM_USB_OPTIONAL_FUNCTION0] & BIT(1)) ? true : false; ++ ++ DBG_88E("%s...bHWPwrPindetect(%x)-bHWPowerdown(%x) , bSupportRemoteWakeup(%x)\n", __func__, ++ padapter->pwrctrlpriv.bHWPwrPindetect, padapter->pwrctrlpriv.bHWPowerdown, padapter->pwrctrlpriv.bSupportRemoteWakeup); ++ ++ DBG_88E("### PS params => power_mgnt(%x), usbss_enable(%x) ###\n", padapter->registrypriv.power_mgnt, padapter->registrypriv.usbss_enable); ++ } ++} ++ ++void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *PROMContent, bool AutoLoadFail) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct txpowerinfo24g pwrInfo24G; ++ u8 rfPath, ch, group; ++ u8 TxCount; ++ ++ Hal_ReadPowerValueFromPROM_8188E(&pwrInfo24G, PROMContent, AutoLoadFail); ++ ++ if (!AutoLoadFail) ++ pHalData->bTXPowerDataReadFromEEPORM = true; ++ ++ for (rfPath = 0; rfPath < pHalData->NumTotalRFPath; rfPath++) { ++ for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) { ++ hal_get_chnl_group_88e(ch, &group); ++ ++ pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][group]; ++ if (ch == 14) ++ pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][4]; ++ else ++ pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group]; ++ ++ DBG_88E("======= Path %d, Channel %d =======\n", rfPath, ch); ++ DBG_88E("Index24G_CCK_Base[%d][%d] = 0x%x\n", rfPath, ch, pHalData->Index24G_CCK_Base[rfPath][ch]); ++ DBG_88E("Index24G_BW40_Base[%d][%d] = 0x%x\n", rfPath, ch, pHalData->Index24G_BW40_Base[rfPath][ch]); ++ } ++ for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) { ++ pHalData->CCK_24G_Diff[rfPath][TxCount] = pwrInfo24G.CCK_Diff[rfPath][TxCount]; ++ pHalData->OFDM_24G_Diff[rfPath][TxCount] = pwrInfo24G.OFDM_Diff[rfPath][TxCount]; ++ pHalData->BW20_24G_Diff[rfPath][TxCount] = pwrInfo24G.BW20_Diff[rfPath][TxCount]; ++ pHalData->BW40_24G_Diff[rfPath][TxCount] = pwrInfo24G.BW40_Diff[rfPath][TxCount]; ++ DBG_88E("======= TxCount %d =======\n", TxCount); ++ DBG_88E("CCK_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->CCK_24G_Diff[rfPath][TxCount]); ++ DBG_88E("OFDM_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->OFDM_24G_Diff[rfPath][TxCount]); ++ DBG_88E("BW20_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->BW20_24G_Diff[rfPath][TxCount]); ++ DBG_88E("BW40_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->BW40_24G_Diff[rfPath][TxCount]); ++ } ++ } ++ ++ /* 2010/10/19 MH Add Regulator recognize for CU. */ ++ if (!AutoLoadFail) { ++ pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x7); /* bit0~2 */ ++ if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF) ++ pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION & 0x7); /* bit0~2 */ ++ } else { ++ pHalData->EEPROMRegulatory = 0; ++ } ++ DBG_88E("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory); ++} ++ ++void Hal_EfuseParseXtal_8188E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ ++ if (!AutoLoadFail) { ++ pHalData->CrystalCap = hwinfo[EEPROM_XTAL_88E]; ++ if (pHalData->CrystalCap == 0xFF) ++ pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E; ++ } else { ++ pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E; ++ } ++ DBG_88E("CrystalCap: 0x%2x\n", pHalData->CrystalCap); ++} ++ ++void Hal_EfuseParseBoardType88E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ ++ if (!AutoLoadFail) ++ pHalData->BoardType = ((hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0xE0) >> 5); ++ else ++ pHalData->BoardType = 0; ++ DBG_88E("Board Type: 0x%2x\n", pHalData->BoardType); ++} ++ ++void Hal_EfuseParseEEPROMVer88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ ++ if (!AutoLoadFail) { ++ pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_88E]; ++ if (pHalData->EEPROMVersion == 0xFF) ++ pHalData->EEPROMVersion = EEPROM_Default_Version; ++ } else { ++ pHalData->EEPROMVersion = 1; ++ } ++} ++ ++void rtl8188e_EfuseParseChnlPlan(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail) ++{ ++ padapter->mlmepriv.ChannelPlan = ++ hal_com_get_channel_plan(padapter, ++ hwinfo ? hwinfo[EEPROM_ChannelPlan_88E] : 0xFF, ++ padapter->registrypriv.channel_plan, ++ RT_CHANNEL_DOMAIN_WORLD_WIDE_13, AutoLoadFail); ++ ++ DBG_88E("mlmepriv.ChannelPlan = 0x%02x\n", padapter->mlmepriv.ChannelPlan); ++} ++ ++void Hal_EfuseParseCustomerID88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ ++ if (!AutoLoadFail) { ++ pHalData->EEPROMCustomerID = hwinfo[EEPROM_CUSTOMERID_88E]; ++ } else { ++ pHalData->EEPROMCustomerID = 0; ++ pHalData->EEPROMSubCustomerID = 0; ++ } ++ DBG_88E("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID); ++} ++ ++void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent, bool AutoLoadFail) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ struct registry_priv *registry_par = &pAdapter->registrypriv; ++ ++ if (!AutoLoadFail) { ++ /* Antenna Diversity setting. */ ++ if (registry_par->antdiv_cfg == 2) { /* 2:By EFUSE */ ++ pHalData->AntDivCfg = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x18) >> 3; ++ if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF) ++ pHalData->AntDivCfg = (EEPROM_DEFAULT_BOARD_OPTION & 0x18) >> 3; ++ } else { ++ pHalData->AntDivCfg = registry_par->antdiv_cfg; /* 0:OFF , 1:ON, 2:By EFUSE */ ++ } ++ ++ if (registry_par->antdiv_type == 0) { ++ /* If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead. */ ++ pHalData->TRxAntDivType = PROMContent[EEPROM_RF_ANTENNA_OPT_88E]; ++ if (pHalData->TRxAntDivType == 0xFF) ++ pHalData->TRxAntDivType = CG_TRX_HW_ANTDIV; /* For 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port) */ ++ } else { ++ pHalData->TRxAntDivType = registry_par->antdiv_type; ++ } ++ ++ if (pHalData->TRxAntDivType == CG_TRX_HW_ANTDIV || pHalData->TRxAntDivType == CGCS_RX_HW_ANTDIV) ++ pHalData->AntDivCfg = 1; /* 0xC1[3] is ignored. */ ++ } else { ++ pHalData->AntDivCfg = 0; ++ pHalData->TRxAntDivType = pHalData->TRxAntDivType; /* The value in the driver setting of device manager. */ ++ } ++ DBG_88E("EEPROM : AntDivCfg = %x, TRxAntDivType = %x\n", pHalData->AntDivCfg, pHalData->TRxAntDivType); ++} ++ ++void Hal_ReadThermalMeter_88E(struct adapter *Adapter, u8 *PROMContent, bool AutoloadFail) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ /* ThermalMeter from EEPROM */ ++ if (!AutoloadFail) ++ pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_88E]; ++ else ++ pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E; ++ ++ if (pHalData->EEPROMThermalMeter == 0xff || AutoloadFail) { ++ pHalData->bAPKThermalMeterIgnore = true; ++ pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E; ++ } ++ DBG_88E("ThermalMeter = 0x%x\n", pHalData->EEPROMThermalMeter); ++} ++ ++void Hal_InitChannelPlan(struct adapter *padapter) ++{ ++} ++ ++bool HalDetectPwrDownMode88E(struct adapter *Adapter) ++{ ++ u8 tmpvalue = 0; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv; ++ ++ EFUSE_ShadowRead(Adapter, 1, EEPROM_RF_FEATURE_OPTION_88E, (u32 *)&tmpvalue); ++ ++ /* 2010/08/25 MH INF priority > PDN Efuse value. */ ++ if (tmpvalue & BIT(4) && pwrctrlpriv->reg_pdnmode) ++ pHalData->pwrdown = true; ++ else ++ pHalData->pwrdown = false; ++ ++ DBG_88E("HalDetectPwrDownMode(): PDN =%d\n", pHalData->pwrdown); ++ ++ return pHalData->pwrdown; ++} /* HalDetectPwrDownMode */ ++ ++/* This function is used only for 92C to set REG_BCN_CTRL(0x550) register. */ ++/* We just reserve the value of the register in variable pHalData->RegBcnCtrlVal and then operate */ ++/* the value of the register via atomic operation. */ ++/* This prevents from race condition when setting this register. */ ++/* The value of pHalData->RegBcnCtrlVal is initialized in HwConfigureRTL8192CE() function. */ ++ ++void SetBcnCtrlReg(struct adapter *padapter, u8 SetBits, u8 ClearBits) ++{ ++ struct hal_data_8188e *pHalData; ++ ++ pHalData = GET_HAL_DATA(padapter); ++ ++ pHalData->RegBcnCtrlVal |= SetBits; ++ pHalData->RegBcnCtrlVal &= ~ClearBits; ++ ++ rtw_write8(padapter, REG_BCN_CTRL, (u8)pHalData->RegBcnCtrlVal); ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_mp.c b/drivers/staging/r8188eu/hal/rtl8188e_mp.c +new file mode 100644 +index 000000000000..fc13db705511 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_mp.c +@@ -0,0 +1,798 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188E_MP_C_ ++ ++#include "../include/drv_types.h" ++#include "../include/rtw_mp.h" ++#include "../include/rtl8188e_hal.h" ++#include "../include/rtl8188e_dm.h" ++ ++s32 Hal_SetPowerTracking(struct adapter *padapter, u8 enable) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct odm_dm_struct *pDM_Odm = &pHalData->odmpriv; ++ ++ if (!netif_running(padapter->pnetdev)) ++ return _FAIL; ++ ++ if (!check_fwstate(&padapter->mlmepriv, WIFI_MP_STATE)) ++ return _FAIL; ++ ++ if (enable) ++ pDM_Odm->RFCalibrateInfo.bTXPowerTracking = true; ++ else ++ pDM_Odm->RFCalibrateInfo.bTXPowerTrackingInit = false; ++ ++ return _SUCCESS; ++} ++ ++void Hal_GetPowerTracking(struct adapter *padapter, u8 *enable) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct odm_dm_struct *pDM_Odm = &pHalData->odmpriv; ++ ++ *enable = pDM_Odm->RFCalibrateInfo.TxPowerTrackControl; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: mpt_SwitchRfSetting ++ * ++ * Overview: Change RF Setting when we siwthc channel/rate/BW for MP. ++ * ++ * Input: struct adapter * pAdapter ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 01/08/2009 MHC Suggestion from SD3 Willis for 92S series. ++ * 01/09/2009 MHC Add CCK modification for 40MHZ. Suggestion from SD3. ++ * ++ *---------------------------------------------------------------------------*/ ++void Hal_mpt_SwitchRfSetting(struct adapter *pAdapter) ++{ ++ struct mp_priv *pmp = &pAdapter->mppriv; ++ ++ /* <20120525, Kordan> Dynamic mechanism for APK, asked by Dennis. */ ++ pmp->MptCtx.backup0x52_RF_A = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0); ++ pmp->MptCtx.backup0x52_RF_B = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_B, RF_0x52, 0x000F0); ++ PHY_SetRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0, 0xD); ++ PHY_SetRFReg(pAdapter, RF_PATH_B, RF_0x52, 0x000F0, 0xD); ++} ++/*---------------------------hal\rtl8192c\MPT_Phy.c---------------------------*/ ++ ++/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/ ++void Hal_MPT_CCKTxPowerAdjust(struct adapter *Adapter, bool bInCH14) ++{ ++ u32 TempVal = 0, TempVal2 = 0, TempVal3 = 0; ++ u32 CurrCCKSwingVal = 0, CCKSwingIndex = 12; ++ u8 i; ++ ++ /* get current cck swing value and check 0xa22 & 0xa23 later to match the table. */ ++ CurrCCKSwingVal = read_bbreg(Adapter, rCCK0_TxFilter1, bMaskHWord); ++ ++ if (!bInCH14) { ++ /* Readback the current bb cck swing value and compare with the table to */ ++ /* get the current swing index */ ++ for (i = 0; i < CCK_TABLE_SIZE; i++) { ++ if (((CurrCCKSwingVal & 0xff) == (u32)CCKSwingTable_Ch1_Ch13[i][0]) && ++ (((CurrCCKSwingVal & 0xff00) >> 8) == (u32)CCKSwingTable_Ch1_Ch13[i][1])) { ++ CCKSwingIndex = i; ++ break; ++ } ++ } ++ ++ /* Write 0xa22 0xa23 */ ++ TempVal = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][0] + ++ (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][1] << 8); ++ ++ /* Write 0xa24 ~ 0xa27 */ ++ TempVal2 = 0; ++ TempVal2 = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][2] + ++ (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][3] << 8) + ++ (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][4] << 16) + ++ (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][5] << 24); ++ ++ /* Write 0xa28 0xa29 */ ++ TempVal3 = 0; ++ TempVal3 = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][6] + ++ (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][7] << 8); ++ } else { ++ for (i = 0; i < CCK_TABLE_SIZE; i++) { ++ if (((CurrCCKSwingVal & 0xff) == (u32)CCKSwingTable_Ch14[i][0]) && ++ (((CurrCCKSwingVal & 0xff00) >> 8) == (u32)CCKSwingTable_Ch14[i][1])) { ++ CCKSwingIndex = i; ++ break; ++ } ++ } ++ ++ /* Write 0xa22 0xa23 */ ++ TempVal = CCKSwingTable_Ch14[CCKSwingIndex][0] + ++ (CCKSwingTable_Ch14[CCKSwingIndex][1] << 8); ++ ++ /* Write 0xa24 ~ 0xa27 */ ++ TempVal2 = 0; ++ TempVal2 = CCKSwingTable_Ch14[CCKSwingIndex][2] + ++ (CCKSwingTable_Ch14[CCKSwingIndex][3] << 8) + ++ (CCKSwingTable_Ch14[CCKSwingIndex][4] << 16) + ++ (CCKSwingTable_Ch14[CCKSwingIndex][5] << 24); ++ ++ /* Write 0xa28 0xa29 */ ++ TempVal3 = 0; ++ TempVal3 = CCKSwingTable_Ch14[CCKSwingIndex][6] + ++ (CCKSwingTable_Ch14[CCKSwingIndex][7] << 8); ++ } ++ ++ write_bbreg(Adapter, rCCK0_TxFilter1, bMaskHWord, TempVal); ++ write_bbreg(Adapter, rCCK0_TxFilter2, bMaskDWord, TempVal2); ++ write_bbreg(Adapter, rCCK0_DebugPort, bMaskLWord, TempVal3); ++} ++ ++void Hal_MPT_CCKTxPowerAdjustbyIndex(struct adapter *pAdapter, bool beven) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ struct mpt_context *pMptCtx = &pAdapter->mppriv.MptCtx; ++ struct odm_dm_struct *pDM_Odm = &pHalData->odmpriv; ++ s32 TempCCk; ++ u8 CCK_index, CCK_index_old = 0; ++ u8 Action = 0; /* 0: no action, 1: even->odd, 2:odd->even */ ++ s32 i = 0; ++ ++ if (!IS_92C_SERIAL(pHalData->VersionID)) ++ return; ++ if (beven && !pMptCtx->bMptIndexEven) { ++ /* odd->even */ ++ Action = 2; ++ pMptCtx->bMptIndexEven = true; ++ } else if (!beven && pMptCtx->bMptIndexEven) { ++ /* even->odd */ ++ Action = 1; ++ pMptCtx->bMptIndexEven = false; ++ } ++ ++ if (Action != 0) { ++ /* Query CCK default setting From 0xa24 */ ++ TempCCk = read_bbreg(pAdapter, rCCK0_TxFilter2, bMaskDWord) & bMaskCCK; ++ for (i = 0; i < CCK_TABLE_SIZE; i++) { ++ if (pDM_Odm->RFCalibrateInfo.bCCKinCH14) { ++ if (!memcmp((void *)&TempCCk, (void *)&CCKSwingTable_Ch14[i][2], 4)) { ++ CCK_index_old = (u8)i; ++ break; ++ } ++ } else { ++ if (!memcmp((void *)&TempCCk, (void *)&CCKSwingTable_Ch1_Ch13[i][2], 4)) { ++ CCK_index_old = (u8)i; ++ break; ++ } ++ } ++ } ++ ++ if (Action == 1) ++ CCK_index = CCK_index_old - 1; ++ else ++ CCK_index = CCK_index_old + 1; ++ ++ /* Adjust CCK according to gain index */ ++ if (!pDM_Odm->RFCalibrateInfo.bCCKinCH14) { ++ rtw_write8(pAdapter, 0xa22, CCKSwingTable_Ch1_Ch13[CCK_index][0]); ++ rtw_write8(pAdapter, 0xa23, CCKSwingTable_Ch1_Ch13[CCK_index][1]); ++ rtw_write8(pAdapter, 0xa24, CCKSwingTable_Ch1_Ch13[CCK_index][2]); ++ rtw_write8(pAdapter, 0xa25, CCKSwingTable_Ch1_Ch13[CCK_index][3]); ++ rtw_write8(pAdapter, 0xa26, CCKSwingTable_Ch1_Ch13[CCK_index][4]); ++ rtw_write8(pAdapter, 0xa27, CCKSwingTable_Ch1_Ch13[CCK_index][5]); ++ rtw_write8(pAdapter, 0xa28, CCKSwingTable_Ch1_Ch13[CCK_index][6]); ++ rtw_write8(pAdapter, 0xa29, CCKSwingTable_Ch1_Ch13[CCK_index][7]); ++ } else { ++ rtw_write8(pAdapter, 0xa22, CCKSwingTable_Ch14[CCK_index][0]); ++ rtw_write8(pAdapter, 0xa23, CCKSwingTable_Ch14[CCK_index][1]); ++ rtw_write8(pAdapter, 0xa24, CCKSwingTable_Ch14[CCK_index][2]); ++ rtw_write8(pAdapter, 0xa25, CCKSwingTable_Ch14[CCK_index][3]); ++ rtw_write8(pAdapter, 0xa26, CCKSwingTable_Ch14[CCK_index][4]); ++ rtw_write8(pAdapter, 0xa27, CCKSwingTable_Ch14[CCK_index][5]); ++ rtw_write8(pAdapter, 0xa28, CCKSwingTable_Ch14[CCK_index][6]); ++ rtw_write8(pAdapter, 0xa29, CCKSwingTable_Ch14[CCK_index][7]); ++ } ++ } ++} ++/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/ ++ ++/* ++ * SetChannel ++ * Description ++ * Use H2C command to change channel, ++ * not only modify rf register, but also other setting need to be done. ++ */ ++void Hal_SetChannel(struct adapter *pAdapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ struct mp_priv *pmp = &pAdapter->mppriv; ++ struct odm_dm_struct *pDM_Odm = &pHalData->odmpriv; ++ u8 eRFPath; ++ u8 channel = pmp->channel; ++ ++ /* set RF channel register */ ++ for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) ++ _write_rfreg(pAdapter, eRFPath, ODM_CHANNEL, 0x3FF, channel); ++ Hal_mpt_SwitchRfSetting(pAdapter); ++ ++ SelectChannel(pAdapter, channel); ++ ++ if (pHalData->CurrentChannel == 14 && !pDM_Odm->RFCalibrateInfo.bCCKinCH14) { ++ pDM_Odm->RFCalibrateInfo.bCCKinCH14 = true; ++ Hal_MPT_CCKTxPowerAdjust(pAdapter, pDM_Odm->RFCalibrateInfo.bCCKinCH14); ++ } else if (pHalData->CurrentChannel != 14 && pDM_Odm->RFCalibrateInfo.bCCKinCH14) { ++ pDM_Odm->RFCalibrateInfo.bCCKinCH14 = false; ++ Hal_MPT_CCKTxPowerAdjust(pAdapter, pDM_Odm->RFCalibrateInfo.bCCKinCH14); ++ } ++} ++ ++/* ++ * Notice ++ * Switch bandwitdth may change center frequency(channel) ++ */ ++void Hal_SetBandwidth(struct adapter *pAdapter) ++{ ++ struct mp_priv *pmp = &pAdapter->mppriv; ++ ++ SetBWMode(pAdapter, pmp->bandwidth, pmp->prime_channel_offset); ++ Hal_mpt_SwitchRfSetting(pAdapter); ++} ++ ++void Hal_SetCCKTxPower(struct adapter *pAdapter, u8 *TxPower) ++{ ++ u32 tmpval = 0; ++ ++ /* rf-A cck tx power */ ++ write_bbreg(pAdapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, TxPower[RF_PATH_A]); ++ tmpval = (TxPower[RF_PATH_A] << 16) | (TxPower[RF_PATH_A] << 8) | TxPower[RF_PATH_A]; ++ write_bbreg(pAdapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); ++ ++ /* rf-B cck tx power */ ++ write_bbreg(pAdapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, TxPower[RF_PATH_B]); ++ tmpval = (TxPower[RF_PATH_B] << 16) | (TxPower[RF_PATH_B] << 8) | TxPower[RF_PATH_B]; ++ write_bbreg(pAdapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, tmpval); ++} ++ ++void Hal_SetOFDMTxPower(struct adapter *pAdapter, u8 *TxPower) ++{ ++ u32 TxAGC = 0; ++ u8 tmpval = 0; ++ ++ /* HT Tx-rf(A) */ ++ tmpval = TxPower[RF_PATH_A]; ++ TxAGC = (tmpval << 24) | (tmpval << 16) | (tmpval << 8) | tmpval; ++ ++ write_bbreg(pAdapter, rTxAGC_A_Rate18_06, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_A_Rate54_24, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_A_Mcs03_Mcs00, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_A_Mcs07_Mcs04, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_A_Mcs11_Mcs08, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_A_Mcs15_Mcs12, bMaskDWord, TxAGC); ++ ++ /* HT Tx-rf(B) */ ++ tmpval = TxPower[RF_PATH_B]; ++ TxAGC = (tmpval << 24) | (tmpval << 16) | (tmpval << 8) | tmpval; ++ ++ write_bbreg(pAdapter, rTxAGC_B_Rate18_06, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_B_Rate54_24, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_B_Mcs03_Mcs00, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_B_Mcs07_Mcs04, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_B_Mcs11_Mcs08, bMaskDWord, TxAGC); ++ write_bbreg(pAdapter, rTxAGC_B_Mcs15_Mcs12, bMaskDWord, TxAGC); ++} ++ ++void Hal_SetAntennaPathPower(struct adapter *pAdapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ u8 TxPowerLevel[RF_PATH_MAX]; ++ u8 rfPath; ++ ++ TxPowerLevel[RF_PATH_A] = pAdapter->mppriv.txpoweridx; ++ TxPowerLevel[RF_PATH_B] = pAdapter->mppriv.txpoweridx_b; ++ ++ switch (pAdapter->mppriv.antenna_tx) { ++ case ANTENNA_A: ++ default: ++ rfPath = RF_PATH_A; ++ break; ++ case ANTENNA_B: ++ rfPath = RF_PATH_B; ++ break; ++ case ANTENNA_C: ++ rfPath = RF_PATH_C; ++ break; ++ } ++ ++ switch (pHalData->rf_chip) { ++ case RF_8225: ++ case RF_8256: ++ case RF_6052: ++ Hal_SetCCKTxPower(pAdapter, TxPowerLevel); ++ if (pAdapter->mppriv.rateidx < MPT_RATE_6M) /* CCK rate */ ++ Hal_MPT_CCKTxPowerAdjustbyIndex(pAdapter, TxPowerLevel[rfPath] % 2 == 0); ++ Hal_SetOFDMTxPower(pAdapter, TxPowerLevel); ++ break; ++ default: ++ break; ++ } ++} ++ ++void Hal_SetTxPower(struct adapter *pAdapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ u8 TxPower = pAdapter->mppriv.txpoweridx; ++ u8 TxPowerLevel[RF_PATH_MAX]; ++ u8 rf, rfPath; ++ ++ for (rf = 0; rf < RF_PATH_MAX; rf++) ++ TxPowerLevel[rf] = TxPower; ++ ++ switch (pAdapter->mppriv.antenna_tx) { ++ case ANTENNA_A: ++ default: ++ rfPath = RF_PATH_A; ++ break; ++ case ANTENNA_B: ++ rfPath = RF_PATH_B; ++ break; ++ case ANTENNA_C: ++ rfPath = RF_PATH_C; ++ break; ++ } ++ ++ switch (pHalData->rf_chip) { ++ /* 2008/09/12 MH Test only !! We enable the TX power tracking for MP!!!!! */ ++ /* We should call normal driver API later!! */ ++ case RF_8225: ++ case RF_8256: ++ case RF_6052: ++ Hal_SetCCKTxPower(pAdapter, TxPowerLevel); ++ if (pAdapter->mppriv.rateidx < MPT_RATE_6M) /* CCK rate */ ++ Hal_MPT_CCKTxPowerAdjustbyIndex(pAdapter, TxPowerLevel[rfPath] % 2 == 0); ++ Hal_SetOFDMTxPower(pAdapter, TxPowerLevel); ++ break; ++ default: ++ break; ++ } ++} ++ ++void Hal_SetDataRate(struct adapter *pAdapter) ++{ ++ Hal_mpt_SwitchRfSetting(pAdapter); ++} ++ ++void Hal_SetAntenna(struct adapter *pAdapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ ++ struct ant_sel_ofdm *p_ofdm_tx; /* OFDM Tx register */ ++ struct ant_sel_cck *p_cck_txrx; ++ u8 r_rx_antenna_ofdm = 0, r_ant_select_cck_val = 0; ++ u8 chgTx = 0, chgRx = 0; ++ u32 r_ant_select_ofdm_val = 0, r_ofdm_tx_en_val = 0; ++ ++ p_ofdm_tx = (struct ant_sel_ofdm *)&r_ant_select_ofdm_val; ++ p_cck_txrx = (struct ant_sel_cck *)&r_ant_select_cck_val; ++ ++ p_ofdm_tx->r_ant_ht1 = 0x1; ++ p_ofdm_tx->r_ant_ht2 = 0x2; /* Second TX RF path is A */ ++ p_ofdm_tx->r_ant_non_ht = 0x3; /* 0x1+0x2=0x3 */ ++ ++ switch (pAdapter->mppriv.antenna_tx) { ++ case ANTENNA_A: ++ p_ofdm_tx->r_tx_antenna = 0x1; ++ r_ofdm_tx_en_val = 0x1; ++ p_ofdm_tx->r_ant_l = 0x1; ++ p_ofdm_tx->r_ant_ht_s1 = 0x1; ++ p_ofdm_tx->r_ant_non_ht_s1 = 0x1; ++ p_cck_txrx->r_ccktx_enable = 0x8; ++ chgTx = 1; ++ ++ /* From SD3 Willis suggestion !!! Set RF A=TX and B as standby */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 1); ++ r_ofdm_tx_en_val = 0x3; ++ ++ /* Power save */ ++ ++ /* We need to close RFB by SW control */ ++ if (pHalData->rf_type == RF_2T2R) { ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(26), 1); ++ PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT(10), 0); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT(1), 1); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT(17), 0); ++ } ++ break; ++ case ANTENNA_B: ++ p_ofdm_tx->r_tx_antenna = 0x2; ++ r_ofdm_tx_en_val = 0x2; ++ p_ofdm_tx->r_ant_l = 0x2; ++ p_ofdm_tx->r_ant_ht_s1 = 0x2; ++ p_ofdm_tx->r_ant_non_ht_s1 = 0x2; ++ p_cck_txrx->r_ccktx_enable = 0x4; ++ chgTx = 1; ++ /* From SD3 Willis suggestion !!! Set RF A as standby */ ++ PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 1); ++ PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2); ++ ++ /* Power save */ ++ /* cosa r_ant_select_ofdm_val = 0x22222222; */ ++ ++ /* 2008/10/31 MH From SD3 Willi's suggestion. We must read RF 1T table. */ ++ /* 2009/01/08 MH From Sd3 Willis. We need to close RFA by SW control */ ++ if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_1T2R) { ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(10), 1); ++ PHY_SetBBReg(pAdapter, rFPGA0_XA_RFInterfaceOE, BIT(10), 0); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT(1), 0); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT(17), 1); ++ } ++ break; ++ case ANTENNA_AB: /* For 8192S */ ++ p_ofdm_tx->r_tx_antenna = 0x3; ++ r_ofdm_tx_en_val = 0x3; ++ p_ofdm_tx->r_ant_l = 0x3; ++ p_ofdm_tx->r_ant_ht_s1 = 0x3; ++ p_ofdm_tx->r_ant_non_ht_s1 = 0x3; ++ p_cck_txrx->r_ccktx_enable = 0xC; ++ chgTx = 1; ++ ++ /* From SD3 Willis suggestion !!! Set RF B as standby */ ++ PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2); ++ PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2); ++ ++ /* Disable Power save */ ++ /* cosa r_ant_select_ofdm_val = 0x3321333; */ ++ /* 2009/01/08 MH From Sd3 Willis. We need to enable RFA/B by SW control */ ++ if (pHalData->rf_type == RF_2T2R) { ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT(1), 1); ++ PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT(17), 1); ++ } ++ break; ++ default: ++ break; ++ } ++ ++ /* r_rx_antenna_ofdm, bit0=A, bit1=B, bit2=C, bit3=D */ ++ /* r_cckrx_enable : CCK default, 0=A, 1=B, 2=C, 3=D */ ++ /* r_cckrx_enable_2 : CCK option, 0=A, 1=B, 2=C, 3=D */ ++ switch (pAdapter->mppriv.antenna_rx) { ++ case ANTENNA_A: ++ r_rx_antenna_ofdm = 0x1; /* A */ ++ p_cck_txrx->r_cckrx_enable = 0x0; /* default: A */ ++ p_cck_txrx->r_cckrx_enable_2 = 0x0; /* option: A */ ++ chgRx = 1; ++ break; ++ case ANTENNA_B: ++ r_rx_antenna_ofdm = 0x2; /* B */ ++ p_cck_txrx->r_cckrx_enable = 0x1; /* default: B */ ++ p_cck_txrx->r_cckrx_enable_2 = 0x1; /* option: B */ ++ chgRx = 1; ++ break; ++ case ANTENNA_AB: ++ r_rx_antenna_ofdm = 0x3; /* AB */ ++ p_cck_txrx->r_cckrx_enable = 0x0; /* default:A */ ++ p_cck_txrx->r_cckrx_enable_2 = 0x1; /* option:B */ ++ chgRx = 1; ++ break; ++ default: ++ break; ++ } ++ ++ if (chgTx && chgRx) { ++ switch (pHalData->rf_chip) { ++ case RF_8225: ++ case RF_8256: ++ case RF_6052: ++ /* r_ant_sel_cck_val = r_ant_select_cck_val; */ ++ PHY_SetBBReg(pAdapter, rFPGA1_TxInfo, 0x7fffffff, r_ant_select_ofdm_val); /* OFDM Tx */ ++ PHY_SetBBReg(pAdapter, rFPGA0_TxInfo, 0x0000000f, r_ofdm_tx_en_val); /* OFDM Tx */ ++ PHY_SetBBReg(pAdapter, rOFDM0_TRxPathEnable, 0x0000000f, r_rx_antenna_ofdm); /* OFDM Rx */ ++ PHY_SetBBReg(pAdapter, rOFDM1_TRxPathEnable, 0x0000000f, r_rx_antenna_ofdm); /* OFDM Rx */ ++ PHY_SetBBReg(pAdapter, rCCK0_AFESetting, bMaskByte3, r_ant_select_cck_val); /* CCK TxRx */ ++ ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++s32 Hal_SetThermalMeter(struct adapter *pAdapter, u8 target_ther) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ ++ if (!netif_running(pAdapter->pnetdev)) ++ return _FAIL; ++ ++ if (!check_fwstate(&pAdapter->mlmepriv, WIFI_MP_STATE)) ++ return _FAIL; ++ ++ target_ther &= 0xff; ++ if (target_ther < 0x07) ++ target_ther = 0x07; ++ else if (target_ther > 0x1d) ++ target_ther = 0x1d; ++ ++ pHalData->EEPROMThermalMeter = target_ther; ++ ++ return _SUCCESS; ++} ++ ++void Hal_TriggerRFThermalMeter(struct adapter *pAdapter) ++{ ++ _write_rfreg(pAdapter, RF_PATH_A, RF_T_METER_88E, BIT(17) | BIT(16), 0x03); ++} ++ ++u8 Hal_ReadRFThermalMeter(struct adapter *pAdapter) ++{ ++ u32 ThermalValue = 0; ++ ++ ThermalValue = _read_rfreg(pAdapter, RF_PATH_A, RF_T_METER_88E, 0xfc00); ++ return (u8)ThermalValue; ++} ++ ++void Hal_GetThermalMeter(struct adapter *pAdapter, u8 *value) ++{ ++ Hal_TriggerRFThermalMeter(pAdapter); ++ msleep(1000); ++ *value = Hal_ReadRFThermalMeter(pAdapter); ++} ++ ++void Hal_SetSingleCarrierTx(struct adapter *pAdapter, u8 bStart) ++{ ++ pAdapter->mppriv.MptCtx.bSingleCarrier = bStart; ++ if (bStart) { ++ /* Start Single Carrier. */ ++ /* 1. if OFDM block on? */ ++ if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) ++ write_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable);/* set OFDM block on */ ++ ++ /* 2. set CCK test mode off, set to CCK normal mode */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, bDisable); ++ /* 3. turn on scramble setting */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); ++ /* 4. Turn On Single Carrier Tx and turn off the other test modes. */ ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bEnable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); ++ /* for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); ++ } else { ++ /* Stop Single Carrier. */ ++ /* Turn off all test modes. */ ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); ++ msleep(10); ++ ++ /* BB Reset */ ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); ++ ++ /* Stop for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); ++ } ++} ++ ++void Hal_SetSingleToneTx(struct adapter *pAdapter, u8 bStart) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); ++ bool is92C = IS_92C_SERIAL(pHalData->VersionID); ++ ++ u8 rfPath; ++ u32 reg58 = 0x0; ++ switch (pAdapter->mppriv.antenna_tx) { ++ case ANTENNA_A: ++ default: ++ rfPath = RF_PATH_A; ++ break; ++ case ANTENNA_B: ++ rfPath = RF_PATH_B; ++ break; ++ case ANTENNA_C: ++ rfPath = RF_PATH_C; ++ break; ++ } ++ ++ pAdapter->mppriv.MptCtx.bSingleTone = bStart; ++ if (bStart) { ++ /* Start Single Tone. */ ++ /* <20120326, Kordan> To amplify the power of tone for Xtal calibration. (asked by Edlu) */ ++ if (IS_HARDWARE_TYPE_8188E(pAdapter)) { ++ reg58 = PHY_QueryRFReg(pAdapter, RF_PATH_A, LNA_Low_Gain_3, bRFRegOffsetMask); ++ reg58 &= 0xFFFFFFF0; ++ reg58 += 2; ++ PHY_SetRFReg(pAdapter, RF_PATH_A, LNA_Low_Gain_3, bRFRegOffsetMask, reg58); ++ } ++ PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bCCKEn, 0x0); ++ PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 0x0); ++ ++ if (is92C) { ++ _write_rfreg(pAdapter, RF_PATH_A, 0x21, BIT(19), 0x01); ++ rtw_usleep_os(100); ++ if (rfPath == RF_PATH_A) ++ write_rfreg(pAdapter, RF_PATH_B, 0x00, 0x10000); /* PAD all on. */ ++ else if (rfPath == RF_PATH_B) ++ write_rfreg(pAdapter, RF_PATH_A, 0x00, 0x10000); /* PAD all on. */ ++ write_rfreg(pAdapter, rfPath, 0x00, 0x2001f); /* PAD all on. */ ++ rtw_usleep_os(100); ++ } else { ++ write_rfreg(pAdapter, rfPath, 0x21, 0xd4000); ++ rtw_usleep_os(100); ++ write_rfreg(pAdapter, rfPath, 0x00, 0x2001f); /* PAD all on. */ ++ rtw_usleep_os(100); ++ } ++ ++ /* for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); ++ ++ } else { ++ /* Stop Single Tone. */ ++ /* <20120326, Kordan> To amplify the power of tone for Xtal calibration. (asked by Edlu) */ ++ /* <20120326, Kordan> Only in single tone mode. (asked by Edlu) */ ++ if (IS_HARDWARE_TYPE_8188E(pAdapter)) { ++ reg58 = PHY_QueryRFReg(pAdapter, RF_PATH_A, LNA_Low_Gain_3, bRFRegOffsetMask); ++ reg58 &= 0xFFFFFFF0; ++ PHY_SetRFReg(pAdapter, RF_PATH_A, LNA_Low_Gain_3, bRFRegOffsetMask, reg58); ++ } ++ write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, 0x1); ++ write_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 0x1); ++ if (is92C) { ++ _write_rfreg(pAdapter, RF_PATH_A, 0x21, BIT(19), 0x00); ++ rtw_usleep_os(100); ++ write_rfreg(pAdapter, RF_PATH_A, 0x00, 0x32d75); /* PAD all on. */ ++ write_rfreg(pAdapter, RF_PATH_B, 0x00, 0x32d75); /* PAD all on. */ ++ rtw_usleep_os(100); ++ } else { ++ write_rfreg(pAdapter, rfPath, 0x21, 0x54000); ++ rtw_usleep_os(100); ++ write_rfreg(pAdapter, rfPath, 0x00, 0x30000); /* PAD all on. */ ++ rtw_usleep_os(100); ++ } ++ ++ /* Stop for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); ++ } ++} ++ ++void Hal_SetCarrierSuppressionTx(struct adapter *pAdapter, u8 bStart) ++{ ++ pAdapter->mppriv.MptCtx.bCarrierSuppression = bStart; ++ if (bStart) { ++ /* Start Carrier Suppression. */ ++ if (pAdapter->mppriv.rateidx <= MPT_RATE_11M) { ++ /* 1. if CCK block on? */ ++ if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn)) ++ write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);/* set CCK block on */ ++ ++ /* Turn Off All Test Mode */ ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); ++ ++ write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); /* transmit mode */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKScramble, 0x0); /* turn off scramble setting */ ++ ++ /* Set CCK Tx Test Rate */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKTxRate, 0x0); /* Set FTxRate to 1Mbps */ ++ } ++ ++ /* for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); ++ } else { ++ /* Stop Carrier Suppression. */ ++ if (pAdapter->mppriv.rateidx <= MPT_RATE_11M) { ++ write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); /* normal mode */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKScramble, 0x1); /* turn on scramble setting */ ++ ++ /* BB Reset */ ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); ++ } ++ ++ /* Stop for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); ++ } ++} ++ ++void Hal_SetCCKContinuousTx(struct adapter *pAdapter, u8 bStart) ++{ ++ u32 cckrate; ++ ++ if (bStart) { ++ /* 1. if CCK block on? */ ++ if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn)) ++ write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);/* set CCK block on */ ++ ++ /* Turn Off All Test Mode */ ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); ++ /* Set CCK Tx Test Rate */ ++ cckrate = pAdapter->mppriv.rateidx; ++ write_bbreg(pAdapter, rCCK0_System, bCCKTxRate, cckrate); ++ write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); /* transmit mode */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); /* turn on scramble setting */ ++ ++ /* for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); ++ } else { ++ write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); /* normal mode */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); /* turn on scramble setting */ ++ ++ /* BB Reset */ ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); ++ ++ /* Stop for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); ++ } ++ ++ pAdapter->mppriv.MptCtx.bCckContTx = bStart; ++ pAdapter->mppriv.MptCtx.bOfdmContTx = false; ++} /* mpt_StartCckContTx */ ++ ++void Hal_SetOFDMContinuousTx(struct adapter *pAdapter, u8 bStart) ++{ ++ if (bStart) { ++ /* 1. if OFDM block on? */ ++ if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) ++ write_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable);/* set OFDM block on */ ++ ++ /* 2. set CCK test mode off, set to CCK normal mode */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, bDisable); ++ ++ /* 3. turn on scramble setting */ ++ write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); ++ /* 4. Turn On Continue Tx and turn off the other test modes. */ ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bEnable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); ++ ++ /* for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); ++ ++ } else { ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); ++ write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); ++ /* Delay 10 ms */ ++ msleep(10); ++ /* BB Reset */ ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); ++ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); ++ ++ /* Stop for dynamic set Power index. */ ++ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); ++ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); ++ } ++ ++ pAdapter->mppriv.MptCtx.bCckContTx = false; ++ pAdapter->mppriv.MptCtx.bOfdmContTx = bStart; ++} /* mpt_StartOfdmContTx */ ++ ++void Hal_SetContinuousTx(struct adapter *pAdapter, u8 bStart) ++{ ++ pAdapter->mppriv.MptCtx.bStartContTx = bStart; ++ if (pAdapter->mppriv.rateidx <= MPT_RATE_11M) ++ Hal_SetCCKContinuousTx(pAdapter, bStart); ++ else if ((pAdapter->mppriv.rateidx >= MPT_RATE_6M) && ++ (pAdapter->mppriv.rateidx <= MPT_RATE_MCS15)) ++ Hal_SetOFDMContinuousTx(pAdapter, bStart); ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c +new file mode 100644 +index 000000000000..30a9dca8f453 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c +@@ -0,0 +1,1105 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188E_PHYCFG_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtw_iol.h" ++#include "../include/rtl8188e_hal.h" ++ ++/*---------------------------Define Local Constant---------------------------*/ ++/* Channel switch:The size of command tables for switch channel*/ ++#define MAX_PRECMD_CNT 16 ++#define MAX_RFDEPENDCMD_CNT 16 ++#define MAX_POSTCMD_CNT 16 ++ ++#define MAX_DOZE_WAITING_TIMES_9x 64 ++ ++/*---------------------------Define Local Constant---------------------------*/ ++ ++/*------------------------Define global variable-----------------------------*/ ++ ++/*------------------------Define local variable------------------------------*/ ++ ++/*--------------------Define export function prototype-----------------------*/ ++/* Please refer to header file */ ++/*--------------------Define export function prototype-----------------------*/ ++ ++/*----------------------------Function Body----------------------------------*/ ++/* */ ++/* 1. BB register R/W API */ ++/* */ ++ ++/** ++* Function: phy_CalculateBitShift ++* ++* OverView: Get shifted position of the BitMask ++* ++* Input: ++* u32 BitMask, ++* ++* Output: none ++* Return: u32 Return the shift bit bit position of the mask ++*/ ++static u32 phy_CalculateBitShift(u32 BitMask) ++{ ++ u32 i; ++ ++ for (i = 0; i <= 31; i++) { ++ if (((BitMask >> i) & 0x1) == 1) ++ break; ++ } ++ return i; ++} ++ ++/** ++* Function: PHY_QueryBBReg ++* ++* OverView: Read "sepcific bits" from BB register ++* ++* Input: ++* struct adapter *Adapter, ++* u32 RegAddr, The target address to be readback ++* u32 BitMask The target bit position in the target address ++* to be readback ++* Output: None ++* Return: u32 Data The readback register value ++* Note: This function is equal to "GetRegSetting" in PHY programming guide ++*/ ++u32 ++rtl8188e_PHY_QueryBBReg( ++ struct adapter *Adapter, ++ u32 RegAddr, ++ u32 BitMask ++ ) ++{ ++ u32 ReturnValue = 0, OriginalValue, BitShift; ++ ++ OriginalValue = rtw_read32(Adapter, RegAddr); ++ BitShift = phy_CalculateBitShift(BitMask); ++ ReturnValue = (OriginalValue & BitMask) >> BitShift; ++ return ReturnValue; ++} ++ ++/** ++* Function: PHY_SetBBReg ++* ++* OverView: Write "Specific bits" to BB register (page 8~) ++* ++* Input: ++* struct adapter *Adapter, ++* u32 RegAddr, The target address to be modified ++* u32 BitMask The target bit position in the target address ++* to be modified ++* u32 Data The new register value in the target bit position ++* of the target address ++* ++* Output: None ++* Return: None ++* Note: This function is equal to "PutRegSetting" in PHY programming guide ++*/ ++ ++void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data) ++{ ++ u32 OriginalValue, BitShift; ++ ++ if (BitMask != bMaskDWord) { /* if not "double word" write */ ++ OriginalValue = rtw_read32(Adapter, RegAddr); ++ BitShift = phy_CalculateBitShift(BitMask); ++ Data = ((OriginalValue & (~BitMask)) | (Data << BitShift)); ++ } ++ ++ rtw_write32(Adapter, RegAddr, Data); ++} ++ ++/* */ ++/* 2. RF register R/W API */ ++/* */ ++/** ++* Function: phy_RFSerialRead ++* ++* OverView: Read regster from RF chips ++* ++* Input: ++* struct adapter *Adapter, ++* enum rf_radio_path eRFPath, Radio path of A/B/C/D ++* u32 Offset, The target address to be read ++* ++* Output: None ++* Return: u32 reback value ++* Note: Threre are three types of serial operations: ++* 1. Software serial write ++* 2. Hardware LSSI-Low Speed Serial Interface ++* 3. Hardware HSSI-High speed ++* serial write. Driver need to implement (1) and (2). ++* This function is equal to the combination of RF_ReadReg() and RFLSSIRead() ++*/ ++static u32 ++phy_RFSerialRead( ++ struct adapter *Adapter, ++ enum rf_radio_path eRFPath, ++ u32 Offset ++ ) ++{ ++ u32 retValue = 0; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct bb_reg_def *pPhyReg = &pHalData->PHYRegDef[eRFPath]; ++ u32 NewOffset; ++ u32 tmplong, tmplong2; ++ u8 RfPiEnable = 0; ++ /* */ ++ /* Make sure RF register offset is correct */ ++ /* */ ++ Offset &= 0xff; ++ ++ /* */ ++ /* Switch page for 8256 RF IC */ ++ /* */ ++ NewOffset = Offset; ++ ++ /* For 92S LSSI Read RFLSSIRead */ ++ /* For RF A/B write 0x824/82c(does not work in the future) */ ++ /* We must use 0x824 for RF A and B to execute read trigger */ ++ tmplong = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord); ++ if (eRFPath == RF_PATH_A) ++ tmplong2 = tmplong; ++ else ++ tmplong2 = PHY_QueryBBReg(Adapter, pPhyReg->rfHSSIPara2, bMaskDWord); ++ ++ tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset << 23) | bLSSIReadEdge; /* T65 RF */ ++ ++ PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord, tmplong & (~bLSSIReadEdge)); ++ udelay(10);/* PlatformStallExecution(10); */ ++ ++ PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, bMaskDWord, tmplong2); ++ udelay(100);/* PlatformStallExecution(100); */ ++ ++ udelay(10);/* PlatformStallExecution(10); */ ++ ++ if (eRFPath == RF_PATH_A) ++ RfPiEnable = (u8)PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter1, BIT(8)); ++ else if (eRFPath == RF_PATH_B) ++ RfPiEnable = (u8)PHY_QueryBBReg(Adapter, rFPGA0_XB_HSSIParameter1, BIT(8)); ++ ++ if (RfPiEnable) { /* Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */ ++ retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi, bLSSIReadBackData); ++ } else { /* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */ ++ retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack, bLSSIReadBackData); ++ } ++ return retValue; ++} ++ ++/** ++* Function: phy_RFSerialWrite ++* ++* OverView: Write data to RF register (page 8~) ++* ++* Input: ++* struct adapter *Adapter, ++* enum rf_radio_path eRFPath, Radio path of A/B/C/D ++* u32 Offset, The target address to be read ++* u32 Data The new register Data in the target bit position ++* of the target to be read ++* ++* Output: None ++* Return: None ++* Note: Threre are three types of serial operations: ++* 1. Software serial write ++* 2. Hardware LSSI-Low Speed Serial Interface ++* 3. Hardware HSSI-High speed ++* serial write. Driver need to implement (1) and (2). ++* This function is equal to the combination of RF_ReadReg() and RFLSSIRead() ++ * ++ * Note: For RF8256 only ++ * The total count of RTL8256(Zebra4) register is around 36 bit it only employs ++ * 4-bit RF address. RTL8256 uses "register mode control bit" (Reg00[12], Reg00[10]) ++ * to access register address bigger than 0xf. See "Appendix-4 in PHY Configuration ++ * programming guide" for more details. ++ * Thus, we define a sub-finction for RTL8526 register address conversion ++ * =========================================================== ++ * Register Mode RegCTL[1] RegCTL[0] Note ++ * (Reg00[12]) (Reg00[10]) ++ * =========================================================== ++ * Reg_Mode0 0 x Reg 0 ~15(0x0 ~ 0xf) ++ * ------------------------------------------------------------------ ++ * Reg_Mode1 1 0 Reg 16 ~30(0x1 ~ 0xf) ++ * ------------------------------------------------------------------ ++ * Reg_Mode2 1 1 Reg 31 ~ 45(0x1 ~ 0xf) ++ * ------------------------------------------------------------------ ++ * ++ * 2008/09/02 MH Add 92S RF definition ++ * ++ * ++ * ++*/ ++static void ++phy_RFSerialWrite( ++ struct adapter *Adapter, ++ enum rf_radio_path eRFPath, ++ u32 Offset, ++ u32 Data ++ ) ++{ ++ u32 DataAndAddr = 0; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct bb_reg_def *pPhyReg = &pHalData->PHYRegDef[eRFPath]; ++ u32 NewOffset; ++ ++ /* 2009/06/17 MH We can not execute IO for power save or other accident mode. */ ++ ++ Offset &= 0xff; ++ ++ /* */ ++ /* Switch page for 8256 RF IC */ ++ /* */ ++ NewOffset = Offset; ++ ++ /* */ ++ /* Put write addr in [5:0] and write data in [31:16] */ ++ /* */ ++ DataAndAddr = ((NewOffset << 20) | (Data & 0x000fffff)) & 0x0fffffff; /* T65 RF */ ++ ++ /* */ ++ /* Write Operation */ ++ /* */ ++ PHY_SetBBReg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); ++} ++ ++/** ++* Function: PHY_QueryRFReg ++* ++* OverView: Query "Specific bits" to RF register (page 8~) ++* ++* Input: ++* struct adapter *Adapter, ++* enum rf_radio_path eRFPath, Radio path of A/B/C/D ++* u32 RegAddr, The target address to be read ++* u32 BitMask The target bit position in the target address ++* to be read ++* ++* Output: None ++* Return: u32 Readback value ++* Note: This function is equal to "GetRFRegSetting" in PHY programming guide ++*/ ++u32 rtl8188e_PHY_QueryRFReg(struct adapter *Adapter, enum rf_radio_path eRFPath, ++ u32 RegAddr, u32 BitMask) ++{ ++ u32 Original_Value, Readback_Value, BitShift; ++ ++ Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr); ++ ++ BitShift = phy_CalculateBitShift(BitMask); ++ Readback_Value = (Original_Value & BitMask) >> BitShift; ++ return Readback_Value; ++} ++ ++/** ++* Function: PHY_SetRFReg ++* ++* OverView: Write "Specific bits" to RF register (page 8~) ++* ++* Input: ++* struct adapter *Adapter, ++* enum rf_radio_path eRFPath, Radio path of A/B/C/D ++* u32 RegAddr, The target address to be modified ++* u32 BitMask The target bit position in the target address ++* to be modified ++* u32 Data The new register Data in the target bit position ++* of the target address ++* ++* Output: None ++* Return: None ++* Note: This function is equal to "PutRFRegSetting" in PHY programming guide ++*/ ++void ++rtl8188e_PHY_SetRFReg( ++ struct adapter *Adapter, ++ enum rf_radio_path eRFPath, ++ u32 RegAddr, ++ u32 BitMask, ++ u32 Data ++ ) ++{ ++ u32 Original_Value, BitShift; ++ ++ /* RF data is 12 bits only */ ++ if (BitMask != bRFRegOffsetMask) { ++ Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr); ++ BitShift = phy_CalculateBitShift(BitMask); ++ Data = ((Original_Value & (~BitMask)) | (Data << BitShift)); ++ } ++ ++ phy_RFSerialWrite(Adapter, eRFPath, RegAddr, Data); ++} ++ ++/* */ ++/* 3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */ ++/* */ ++ ++/*----------------------------------------------------------------------------- ++ * Function: PHY_MACConfig8192C ++ * ++ * Overview: Condig MAC by header file or parameter file. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 08/12/2008 MHC Create Version 0. ++ * ++ *---------------------------------------------------------------------------*/ ++s32 PHY_MACConfig8188E(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ int rtStatus = _SUCCESS; ++ ++ /* */ ++ /* Config MAC */ ++ /* */ ++ if (HAL_STATUS_FAILURE == ODM_ConfigMACWithHeaderFile(&pHalData->odmpriv)) ++ rtStatus = _FAIL; ++ ++ /* 2010.07.13 AMPDU aggregation number B */ ++ rtw_write16(Adapter, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); ++ ++ return rtStatus; ++} ++ ++/** ++* Function: phy_InitBBRFRegisterDefinition ++* ++* OverView: Initialize Register definition offset for Radio Path A/B/C/D ++* ++* Input: ++* struct adapter *Adapter, ++* ++* Output: None ++* Return: None ++* Note: The initialization value is constant and it should never be changes ++*/ ++static void ++phy_InitBBRFRegisterDefinition( ++ struct adapter *Adapter ++) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ /* RF Interface Sowrtware Control */ ++ pHalData->PHYRegDef[RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; /* 16 LSBs if read 32-bit from 0x870 */ ++ pHalData->PHYRegDef[RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; /* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */ ++ pHalData->PHYRegDef[RF_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;/* 16 LSBs if read 32-bit from 0x874 */ ++ pHalData->PHYRegDef[RF_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;/* 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) */ ++ ++ /* RF Interface Readback Value */ ++ pHalData->PHYRegDef[RF_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; /* 16 LSBs if read 32-bit from 0x8E0 */ ++ pHalData->PHYRegDef[RF_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;/* 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */ ++ pHalData->PHYRegDef[RF_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB;/* 16 LSBs if read 32-bit from 0x8E4 */ ++ pHalData->PHYRegDef[RF_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB;/* 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6) */ ++ ++ /* RF Interface Output (and Enable) */ ++ pHalData->PHYRegDef[RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; /* 16 LSBs if read 32-bit from 0x860 */ ++ pHalData->PHYRegDef[RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; /* 16 LSBs if read 32-bit from 0x864 */ ++ ++ /* RF Interface (Output and) Enable */ ++ pHalData->PHYRegDef[RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */ ++ pHalData->PHYRegDef[RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; /* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */ ++ ++ /* Addr of LSSI. Wirte RF register by driver */ ++ pHalData->PHYRegDef[RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; /* LSSI Parameter */ ++ pHalData->PHYRegDef[RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; ++ ++ /* RF parameter */ ++ pHalData->PHYRegDef[RF_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter; /* BB Band Select */ ++ pHalData->PHYRegDef[RF_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter; ++ pHalData->PHYRegDef[RF_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter; ++ pHalData->PHYRegDef[RF_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter; ++ ++ /* Tx AGC Gain Stage (same for all path. Should we remove this?) */ ++ pHalData->PHYRegDef[RF_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */ ++ pHalData->PHYRegDef[RF_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */ ++ pHalData->PHYRegDef[RF_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */ ++ pHalData->PHYRegDef[RF_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */ ++ ++ /* Tranceiver A~D HSSI Parameter-1 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; /* wire control parameter1 */ ++ pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1; /* wire control parameter1 */ ++ ++ /* Tranceiver A~D HSSI Parameter-2 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; /* wire control parameter2 */ ++ pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; /* wire control parameter2 */ ++ ++ /* RF switch Control */ ++ pHalData->PHYRegDef[RF_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; /* TR/Ant switch control */ ++ pHalData->PHYRegDef[RF_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl; ++ pHalData->PHYRegDef[RF_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl; ++ pHalData->PHYRegDef[RF_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl; ++ ++ /* AGC control 1 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1; ++ pHalData->PHYRegDef[RF_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1; ++ pHalData->PHYRegDef[RF_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1; ++ pHalData->PHYRegDef[RF_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1; ++ ++ /* AGC control 2 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2; ++ pHalData->PHYRegDef[RF_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2; ++ pHalData->PHYRegDef[RF_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2; ++ pHalData->PHYRegDef[RF_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2; ++ ++ /* RX AFE control 1 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance; ++ pHalData->PHYRegDef[RF_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance; ++ pHalData->PHYRegDef[RF_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance; ++ pHalData->PHYRegDef[RF_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance; ++ ++ /* RX AFE control 1 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfRxAFE = rOFDM0_XARxAFE; ++ pHalData->PHYRegDef[RF_PATH_B].rfRxAFE = rOFDM0_XBRxAFE; ++ pHalData->PHYRegDef[RF_PATH_C].rfRxAFE = rOFDM0_XCRxAFE; ++ pHalData->PHYRegDef[RF_PATH_D].rfRxAFE = rOFDM0_XDRxAFE; ++ ++ /* Tx AFE control 1 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance; ++ pHalData->PHYRegDef[RF_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance; ++ pHalData->PHYRegDef[RF_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance; ++ pHalData->PHYRegDef[RF_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance; ++ ++ /* Tx AFE control 2 */ ++ pHalData->PHYRegDef[RF_PATH_A].rfTxAFE = rOFDM0_XATxAFE; ++ pHalData->PHYRegDef[RF_PATH_B].rfTxAFE = rOFDM0_XBTxAFE; ++ pHalData->PHYRegDef[RF_PATH_C].rfTxAFE = rOFDM0_XCTxAFE; ++ pHalData->PHYRegDef[RF_PATH_D].rfTxAFE = rOFDM0_XDTxAFE; ++ ++ /* Tranceiver LSSI Readback SI mode */ ++ pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; ++ pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack; ++ pHalData->PHYRegDef[RF_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack; ++ pHalData->PHYRegDef[RF_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack; ++ ++ /* Tranceiver LSSI Readback PI mode */ ++ pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBackPi = TransceiverA_HSPI_Readback; ++ pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBackPi = TransceiverB_HSPI_Readback; ++} ++ ++void storePwrIndexDiffRateOffset(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ if (RegAddr == rTxAGC_A_Rate18_06) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0] = Data; ++ if (RegAddr == rTxAGC_A_Rate54_24) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][1] = Data; ++ if (RegAddr == rTxAGC_A_CCK1_Mcs32) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][6] = Data; ++ if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0xffffff00) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][7] = Data; ++ if (RegAddr == rTxAGC_A_Mcs03_Mcs00) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][2] = Data; ++ if (RegAddr == rTxAGC_A_Mcs07_Mcs04) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][3] = Data; ++ if (RegAddr == rTxAGC_A_Mcs11_Mcs08) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][4] = Data; ++ if (RegAddr == rTxAGC_A_Mcs15_Mcs12) { ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][5] = Data; ++ if (pHalData->rf_type == RF_1T1R) ++ pHalData->pwrGroupCnt++; ++ } ++ if (RegAddr == rTxAGC_B_Rate18_06) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][8] = Data; ++ if (RegAddr == rTxAGC_B_Rate54_24) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][9] = Data; ++ if (RegAddr == rTxAGC_B_CCK1_55_Mcs32) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][14] = Data; ++ if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0x000000ff) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][15] = Data; ++ if (RegAddr == rTxAGC_B_Mcs03_Mcs00) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][10] = Data; ++ if (RegAddr == rTxAGC_B_Mcs07_Mcs04) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][11] = Data; ++ if (RegAddr == rTxAGC_B_Mcs11_Mcs08) ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][12] = Data; ++ if (RegAddr == rTxAGC_B_Mcs15_Mcs12) { ++ pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][13] = Data; ++ if (pHalData->rf_type != RF_1T1R) ++ pHalData->pwrGroupCnt++; ++ } ++} ++ ++static int phy_BB8188E_Config_ParaFile(struct adapter *Adapter) ++{ ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter); ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ int rtStatus = _SUCCESS; ++ ++ /* */ ++ /* 1. Read PHY_REG.TXT BB INIT!! */ ++ /* We will separate as 88C / 92C according to chip version */ ++ /* */ ++ if (HAL_STATUS_FAILURE == ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG)) ++ rtStatus = _FAIL; ++ if (rtStatus != _SUCCESS) ++ goto phy_BB8190_Config_ParaFile_Fail; ++ ++ /* 2. If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt */ ++ if (!pEEPROM->bautoload_fail_flag) { ++ pHalData->pwrGroupCnt = 0; ++ ++ if (HAL_STATUS_FAILURE == ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG_PG)) ++ rtStatus = _FAIL; ++ } ++ ++ if (rtStatus != _SUCCESS) ++ goto phy_BB8190_Config_ParaFile_Fail; ++ ++ /* 3. BB AGC table Initialization */ ++ if (HAL_STATUS_FAILURE == ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_AGC_TAB)) ++ rtStatus = _FAIL; ++ ++ if (rtStatus != _SUCCESS) ++ goto phy_BB8190_Config_ParaFile_Fail; ++ ++phy_BB8190_Config_ParaFile_Fail: ++ ++ return rtStatus; ++} ++ ++int ++PHY_BBConfig8188E( ++ struct adapter *Adapter ++ ) ++{ ++ int rtStatus = _SUCCESS; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u32 RegVal; ++ u8 CrystalCap; ++ ++ phy_InitBBRFRegisterDefinition(Adapter); ++ ++ /* Enable BB and RF */ ++ RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN); ++ rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal | BIT(13) | BIT(0) | BIT(1))); ++ ++ /* 20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */ ++ ++ rtw_write8(Adapter, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); ++ ++ rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | FEN_BB_GLB_RSTn | FEN_BBRSTB); ++ ++ /* Config BB and AGC */ ++ rtStatus = phy_BB8188E_Config_ParaFile(Adapter); ++ ++ /* write 0x24[16:11] = 0x24[22:17] = CrystalCap */ ++ CrystalCap = pHalData->CrystalCap & 0x3F; ++ PHY_SetBBReg(Adapter, REG_AFE_XTAL_CTRL, 0x7ff800, (CrystalCap | (CrystalCap << 6))); ++ ++ return rtStatus; ++} ++ ++int PHY_RFConfig8188E(struct adapter *Adapter) ++{ ++ int rtStatus = _SUCCESS; ++ ++ /* RF config */ ++ rtStatus = PHY_RF6052_Config8188E(Adapter); ++ return rtStatus; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: PHY_ConfigRFWithParaFile() ++ * ++ * Overview: This function read RF parameters from general file format, and do RF 3-wire ++ * ++ * Input: struct adapter *Adapter ++ * ps8 pFileName ++ * enum rf_radio_path eRFPath ++ * ++ * Output: NONE ++ * ++ * Return: RT_STATUS_SUCCESS: configuration file exist ++ * ++ * Note: Delay may be required for RF configuration ++ *---------------------------------------------------------------------------*/ ++int rtl8188e_PHY_ConfigRFWithParaFile(struct adapter *Adapter, u8 *pFileName, enum rf_radio_path eRFPath) ++{ ++ return _SUCCESS; ++} ++ ++void ++rtl8192c_PHY_GetHWRegOriginalValue( ++ struct adapter *Adapter ++ ) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ /* read rx initial gain */ ++ pHalData->DefaultInitialGain[0] = (u8)PHY_QueryBBReg(Adapter, rOFDM0_XAAGCCore1, bMaskByte0); ++ pHalData->DefaultInitialGain[1] = (u8)PHY_QueryBBReg(Adapter, rOFDM0_XBAGCCore1, bMaskByte0); ++ pHalData->DefaultInitialGain[2] = (u8)PHY_QueryBBReg(Adapter, rOFDM0_XCAGCCore1, bMaskByte0); ++ pHalData->DefaultInitialGain[3] = (u8)PHY_QueryBBReg(Adapter, rOFDM0_XDAGCCore1, bMaskByte0); ++ ++ /* read framesync */ ++ pHalData->framesync = (u8)PHY_QueryBBReg(Adapter, rOFDM0_RxDetector3, bMaskByte0); ++ pHalData->framesyncC34 = PHY_QueryBBReg(Adapter, rOFDM0_RxDetector2, bMaskDWord); ++} ++ ++/* */ ++/* Description: */ ++/* Map dBm into Tx power index according to */ ++/* current HW model, for example, RF and PA, and */ ++/* current wireless mode. */ ++/* By Bruce, 2008-01-29. */ ++/* */ ++static u8 phy_DbmToTxPwrIdx(struct adapter *Adapter, enum wireless_mode WirelessMode, int PowerInDbm) ++{ ++ u8 TxPwrIdx = 0; ++ int Offset = 0; ++ ++ /* */ ++ /* Tested by MP, we found that CCK Index 0 equals to 8dbm, OFDM legacy equals to */ ++ /* 3dbm, and OFDM HT equals to 0dbm respectively. */ ++ /* Note: */ ++ /* The mapping may be different by different NICs. Do not use this formula for what needs accurate result. */ ++ /* By Bruce, 2008-01-29. */ ++ /* */ ++ switch (WirelessMode) { ++ case WIRELESS_MODE_B: ++ Offset = -7; ++ break; ++ ++ case WIRELESS_MODE_G: ++ case WIRELESS_MODE_N_24G: ++ default: ++ Offset = -8; ++ break; ++ } ++ ++ if ((PowerInDbm - Offset) > 0) ++ TxPwrIdx = (u8)((PowerInDbm - Offset) * 2); ++ else ++ TxPwrIdx = 0; ++ ++ /* Tx Power Index is too large. */ ++ if (TxPwrIdx > MAX_TXPWR_IDX_NMODE_92S) ++ TxPwrIdx = MAX_TXPWR_IDX_NMODE_92S; ++ ++ return TxPwrIdx; ++} ++ ++/* */ ++/* Description: */ ++/* Map Tx power index into dBm according to */ ++/* current HW model, for example, RF and PA, and */ ++/* current wireless mode. */ ++/* By Bruce, 2008-01-29. */ ++/* */ ++static int phy_TxPwrIdxToDbm(struct adapter *Adapter, enum wireless_mode WirelessMode, u8 TxPwrIdx) ++{ ++ int Offset = 0; ++ int PwrOutDbm = 0; ++ ++ /* */ ++ /* Tested by MP, we found that CCK Index 0 equals to -7dbm, OFDM legacy equals to -8dbm. */ ++ /* Note: */ ++ /* The mapping may be different by different NICs. Do not use this formula for what needs accurate result. */ ++ /* By Bruce, 2008-01-29. */ ++ /* */ ++ switch (WirelessMode) { ++ case WIRELESS_MODE_B: ++ Offset = -7; ++ break; ++ case WIRELESS_MODE_G: ++ case WIRELESS_MODE_N_24G: ++ default: ++ Offset = -8; ++ break; ++ } ++ ++ PwrOutDbm = TxPwrIdx / 2 + Offset; /* Discard the decimal part. */ ++ ++ return PwrOutDbm; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: GetTxPowerLevel8190() ++ * ++ * Overview: This function is export to "common" moudule ++ * ++ * Input: struct adapter *Adapter ++ * psByte Power Level ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ *---------------------------------------------------------------------------*/ ++void PHY_GetTxPowerLevel8188E(struct adapter *Adapter, u32 *powerlevel) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u8 TxPwrLevel = 0; ++ int TxPwrDbm; ++ ++ /* */ ++ /* Because the Tx power indexes are different, we report the maximum of them to */ ++ /* meet the CCX TPC request. By Bruce, 2008-01-31. */ ++ /* */ ++ ++ /* CCK */ ++ TxPwrLevel = pHalData->CurrentCckTxPwrIdx; ++ TxPwrDbm = phy_TxPwrIdxToDbm(Adapter, WIRELESS_MODE_B, TxPwrLevel); ++ ++ /* Legacy OFDM */ ++ TxPwrLevel = pHalData->CurrentOfdm24GTxPwrIdx + pHalData->LegacyHTTxPowerDiff; ++ ++ /* Compare with Legacy OFDM Tx power. */ ++ if (phy_TxPwrIdxToDbm(Adapter, WIRELESS_MODE_G, TxPwrLevel) > TxPwrDbm) ++ TxPwrDbm = phy_TxPwrIdxToDbm(Adapter, WIRELESS_MODE_G, TxPwrLevel); ++ ++ /* HT OFDM */ ++ TxPwrLevel = pHalData->CurrentOfdm24GTxPwrIdx; ++ ++ /* Compare with HT OFDM Tx power. */ ++ if (phy_TxPwrIdxToDbm(Adapter, WIRELESS_MODE_N_24G, TxPwrLevel) > TxPwrDbm) ++ TxPwrDbm = phy_TxPwrIdxToDbm(Adapter, WIRELESS_MODE_N_24G, TxPwrLevel); ++ ++ *powerlevel = TxPwrDbm; ++} ++ ++static void getTxPowerIndex88E(struct adapter *Adapter, u8 channel, u8 *cckPowerLevel, ++ u8 *ofdmPowerLevel, u8 *BW20PowerLevel, ++ u8 *BW40PowerLevel) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u8 index = (channel - 1); ++ u8 TxCount = 0, path_nums; ++ ++ if ((RF_1T2R == pHalData->rf_type) || (RF_1T1R == pHalData->rf_type)) ++ path_nums = 1; ++ else ++ path_nums = 2; ++ ++ for (TxCount = 0; TxCount < path_nums; TxCount++) { ++ if (TxCount == RF_PATH_A) { ++ /* 1. CCK */ ++ cckPowerLevel[TxCount] = pHalData->Index24G_CCK_Base[TxCount][index]; ++ /* 2. OFDM */ ++ ofdmPowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->OFDM_24G_Diff[TxCount][RF_PATH_A]; ++ /* 1. BW20 */ ++ BW20PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[TxCount][RF_PATH_A]; ++ /* 2. BW40 */ ++ BW40PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[TxCount][index]; ++ } else if (TxCount == RF_PATH_B) { ++ /* 1. CCK */ ++ cckPowerLevel[TxCount] = pHalData->Index24G_CCK_Base[TxCount][index]; ++ /* 2. OFDM */ ++ ofdmPowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[TxCount][index]; ++ /* 1. BW20 */ ++ BW20PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[TxCount][RF_PATH_A] + ++ pHalData->BW20_24G_Diff[TxCount][index]; ++ /* 2. BW40 */ ++ BW40PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[TxCount][index]; ++ } else if (TxCount == RF_PATH_C) { ++ /* 1. CCK */ ++ cckPowerLevel[TxCount] = pHalData->Index24G_CCK_Base[TxCount][index]; ++ /* 2. OFDM */ ++ ofdmPowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_B][index] + ++ pHalData->BW20_24G_Diff[TxCount][index]; ++ /* 1. BW20 */ ++ BW20PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_B][index] + ++ pHalData->BW20_24G_Diff[TxCount][index]; ++ /* 2. BW40 */ ++ BW40PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[TxCount][index]; ++ } else if (TxCount == RF_PATH_D) { ++ /* 1. CCK */ ++ cckPowerLevel[TxCount] = pHalData->Index24G_CCK_Base[TxCount][index]; ++ /* 2. OFDM */ ++ ofdmPowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_B][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_C][index] + ++ pHalData->BW20_24G_Diff[TxCount][index]; ++ ++ /* 1. BW20 */ ++ BW20PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_A][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_B][index] + ++ pHalData->BW20_24G_Diff[RF_PATH_C][index] + ++ pHalData->BW20_24G_Diff[TxCount][index]; ++ ++ /* 2. BW40 */ ++ BW40PowerLevel[TxCount] = pHalData->Index24G_BW40_Base[TxCount][index]; ++ } ++ } ++} ++ ++static void phy_PowerIndexCheck88E(struct adapter *Adapter, u8 channel, u8 *cckPowerLevel, ++ u8 *ofdmPowerLevel, u8 *BW20PowerLevel, u8 *BW40PowerLevel) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ pHalData->CurrentCckTxPwrIdx = cckPowerLevel[0]; ++ pHalData->CurrentOfdm24GTxPwrIdx = ofdmPowerLevel[0]; ++ pHalData->CurrentBW2024GTxPwrIdx = BW20PowerLevel[0]; ++ pHalData->CurrentBW4024GTxPwrIdx = BW40PowerLevel[0]; ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: SetTxPowerLevel8190() ++ * ++ * Overview: This function is export to "HalCommon" moudule ++ * We must consider RF path later!!!!!!! ++ * ++ * Input: struct adapter *Adapter ++ * u8 channel ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * 2008/11/04 MHC We remove EEPROM_93C56. ++ * We need to move CCX relative code to independet file. ++ * 2009/01/21 MHC Support new EEPROM format from SD3 requirement. ++ * ++ *---------------------------------------------------------------------------*/ ++void ++PHY_SetTxPowerLevel8188E( ++ struct adapter *Adapter, ++ u8 channel ++ ) ++{ ++ u8 cckPowerLevel[MAX_TX_COUNT] = {0}; ++ u8 ofdmPowerLevel[MAX_TX_COUNT] = {0};/* [0]:RF-A, [1]:RF-B */ ++ u8 BW20PowerLevel[MAX_TX_COUNT] = {0}; ++ u8 BW40PowerLevel[MAX_TX_COUNT] = {0}; ++ ++ getTxPowerIndex88E(Adapter, channel, &cckPowerLevel[0], &ofdmPowerLevel[0], &BW20PowerLevel[0], &BW40PowerLevel[0]); ++ ++ phy_PowerIndexCheck88E(Adapter, channel, &cckPowerLevel[0], &ofdmPowerLevel[0], &BW20PowerLevel[0], &BW40PowerLevel[0]); ++ ++ rtl8188e_PHY_RF6052SetCckTxPower(Adapter, &cckPowerLevel[0]); ++ rtl8188e_PHY_RF6052SetOFDMTxPower(Adapter, &ofdmPowerLevel[0], &BW20PowerLevel[0], &BW40PowerLevel[0], channel); ++} ++ ++/* */ ++/* Description: */ ++/* Update transmit power level of all channel supported. */ ++/* */ ++/* TODO: */ ++/* A mode. */ ++/* By Bruce, 2008-02-04. */ ++/* */ ++bool ++PHY_UpdateTxPowerDbm8188E( ++ struct adapter *Adapter, ++ int powerInDbm ++ ) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u8 idx; ++ u8 rf_path; ++ ++ /* TODO: A mode Tx power. */ ++ u8 CckTxPwrIdx = phy_DbmToTxPwrIdx(Adapter, WIRELESS_MODE_B, powerInDbm); ++ u8 OfdmTxPwrIdx = phy_DbmToTxPwrIdx(Adapter, WIRELESS_MODE_N_24G, powerInDbm); ++ ++ if (OfdmTxPwrIdx - pHalData->LegacyHTTxPowerDiff > 0) ++ OfdmTxPwrIdx -= pHalData->LegacyHTTxPowerDiff; ++ else ++ OfdmTxPwrIdx = 0; ++ ++ for (idx = 0; idx < 14; idx++) { ++ for (rf_path = 0; rf_path < 2; rf_path++) { ++ pHalData->TxPwrLevelCck[rf_path][idx] = CckTxPwrIdx; ++ pHalData->TxPwrLevelHT40_1S[rf_path][idx] = ++ pHalData->TxPwrLevelHT40_2S[rf_path][idx] = OfdmTxPwrIdx; ++ } ++ } ++ return true; ++} ++ ++void ++PHY_ScanOperationBackup8188E( ++ struct adapter *Adapter, ++ u8 Operation ++ ) ++{ ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: PHY_SetBWModeCallback8192C() ++ * ++ * Overview: Timer callback function for SetSetBWMode ++ * ++ * Input: PRT_TIMER pTimer ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Note: (1) We do not take j mode into consideration now ++ * (2) Will two workitem of "switch channel" and "switch channel bandwidth" run ++ * concurrently? ++ *---------------------------------------------------------------------------*/ ++static void ++_PHY_SetBWMode92C( ++ struct adapter *Adapter ++) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u8 regBwOpMode; ++ u8 regRRSR_RSC; ++ ++ if (pHalData->rf_chip == RF_PSEUDO_11N) ++ return; ++ ++ /* There is no 40MHz mode in RF_8225. */ ++ if (pHalData->rf_chip == RF_8225) ++ return; ++ ++ if (Adapter->bDriverStopped) ++ return; ++ ++ /* 3 */ ++ /* 3<1>Set MAC register */ ++ /* 3 */ ++ ++ regBwOpMode = rtw_read8(Adapter, REG_BWOPMODE); ++ regRRSR_RSC = rtw_read8(Adapter, REG_RRSR + 2); ++ ++ switch (pHalData->CurrentChannelBW) { ++ case HT_CHANNEL_WIDTH_20: ++ regBwOpMode |= BW_OPMODE_20MHZ; ++ /* 2007/02/07 Mark by Emily because we have not verify whether this register works */ ++ rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode); ++ break; ++ case HT_CHANNEL_WIDTH_40: ++ regBwOpMode &= ~BW_OPMODE_20MHZ; ++ /* 2007/02/07 Mark by Emily because we have not verify whether this register works */ ++ rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode); ++ regRRSR_RSC = (regRRSR_RSC & 0x90) | (pHalData->nCur40MhzPrimeSC << 5); ++ rtw_write8(Adapter, REG_RRSR + 2, regRRSR_RSC); ++ break; ++ default: ++ break; ++ } ++ ++ /* 3 */ ++ /* 3 <2>Set PHY related register */ ++ /* 3 */ ++ switch (pHalData->CurrentChannelBW) { ++ /* 20 MHz channel*/ ++ case HT_CHANNEL_WIDTH_20: ++ PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0); ++ PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0); ++ break; ++ /* 40 MHz channel*/ ++ case HT_CHANNEL_WIDTH_40: ++ PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1); ++ PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1); ++ /* Set Control channel to upper or lower. These settings are required only for 40MHz */ ++ PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand, (pHalData->nCur40MhzPrimeSC >> 1)); ++ PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00, pHalData->nCur40MhzPrimeSC); ++ PHY_SetBBReg(Adapter, 0x818, (BIT(26) | BIT(27)), ++ (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); ++ break; ++ default: ++ break; ++ } ++ /* Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315 */ ++ ++ /* 3<3>Set RF related register */ ++ switch (pHalData->rf_chip) { ++ case RF_8225: ++ break; ++ case RF_8256: ++ /* Please implement this function in Hal8190PciPhy8256.c */ ++ break; ++ case RF_PSEUDO_11N: ++ break; ++ case RF_6052: ++ rtl8188e_PHY_RF6052SetBandwidth(Adapter, pHalData->CurrentChannelBW); ++ break; ++ default: ++ break; ++ } ++} ++ ++ /*----------------------------------------------------------------------------- ++ * Function: SetBWMode8190Pci() ++ * ++ * Overview: This function is export to "HalCommon" moudule ++ * ++ * Input: struct adapter *Adapter ++ * enum ht_channel_width Bandwidth 20M or 40M ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Note: We do not take j mode into consideration now ++ *---------------------------------------------------------------------------*/ ++void PHY_SetBWMode8188E(struct adapter *Adapter, enum ht_channel_width Bandwidth, /* 20M or 40M */ ++ unsigned char Offset) /* Upper, Lower, or Don't care */ ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ enum ht_channel_width tmpBW = pHalData->CurrentChannelBW; ++ ++ pHalData->CurrentChannelBW = Bandwidth; ++ ++ pHalData->nCur40MhzPrimeSC = Offset; ++ ++ if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) ++ _PHY_SetBWMode92C(Adapter); ++ else ++ pHalData->CurrentChannelBW = tmpBW; ++} ++ ++static void _PHY_SwChnl8192C(struct adapter *Adapter, u8 channel) ++{ ++ u8 eRFPath; ++ u32 param1, param2; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ if (Adapter->bNotifyChannelChange) ++ DBG_88E("[%s] ch = %d\n", __func__, channel); ++ ++ /* s1. pre common command - CmdID_SetTxPowerLevel */ ++ PHY_SetTxPowerLevel8188E(Adapter, channel); ++ ++ /* s2. RF dependent command - CmdID_RF_WriteReg, param1=RF_CHNLBW, param2=channel */ ++ param1 = RF_CHNLBW; ++ param2 = channel; ++ for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) { ++ pHalData->RfRegChnlVal[eRFPath] = ((pHalData->RfRegChnlVal[eRFPath] & 0xfffffc00) | param2); ++ PHY_SetRFReg(Adapter, (enum rf_radio_path)eRFPath, param1, bRFRegOffsetMask, pHalData->RfRegChnlVal[eRFPath]); ++ } ++} ++ ++void PHY_SwChnl8188E(struct adapter *Adapter, u8 channel) ++{ ++ /* Call after initialization */ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ if (pHalData->rf_chip == RF_PSEUDO_11N) ++ return; /* return immediately if it is peudo-phy */ ++ ++ if (channel == 0) ++ channel = 1; ++ ++ if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) { ++ pHalData->CurrentChannel = channel; ++ _PHY_SwChnl8192C(Adapter, channel); ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_rf6052.c b/drivers/staging/r8188eu/hal/rtl8188e_rf6052.c +new file mode 100644 +index 000000000000..ad0782259654 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_rf6052.c +@@ -0,0 +1,550 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++/****************************************************************************** ++ * ++ * ++ * Module: rtl8192c_rf6052.c ( Source C File) ++ * ++ * Note: Provide RF 6052 series relative API. ++ * ++ * Function: ++ * ++ * Export: ++ * ++ * Abbrev: ++ * ++ * History: ++ * Data Who Remark ++ * ++ * 09/25/2008 MHC Create initial version. ++ * 11/05/2008 MHC Add API for tw power setting. ++ * ++ * ++******************************************************************************/ ++ ++#define _RTL8188E_RF6052_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtl8188e_hal.h" ++ ++/*---------------------------Define Local Constant---------------------------*/ ++/* Define local structure for debug!!!!! */ ++struct rf_shadow { ++ /* Shadow register value */ ++ u32 Value; ++ /* Compare or not flag */ ++ u8 Compare; ++ /* Record If it had ever modified unpredicted */ ++ u8 ErrorOrNot; ++ /* Recorver Flag */ ++ u8 Recorver; ++ /* */ ++ u8 Driver_Write; ++}; ++ ++/*---------------------------Define Local Constant---------------------------*/ ++ ++/*------------------------Define global variable-----------------------------*/ ++ ++/*------------------------Define local variable------------------------------*/ ++ ++/*----------------------------------------------------------------------------- ++ * Function: RF_ChangeTxPath ++ * ++ * Overview: For RL6052, we must change some RF settign for 1T or 2T. ++ * ++ * Input: u16 DataRate 0x80-8f, 0x90-9f ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 09/25/2008 MHC Create Version 0. ++ * Firmwaer support the utility later. ++ * ++ *---------------------------------------------------------------------------*/ ++void rtl8188e_RF_ChangeTxPath(struct adapter *Adapter, u16 DataRate) ++{ ++/* We do not support gain table change inACUT now !!!! Delete later !!! */ ++} /* RF_ChangeTxPath */ ++ ++/*----------------------------------------------------------------------------- ++ * Function: PHY_RF6052SetBandwidth() ++ * ++ * Overview: This function is called by SetBWModeCallback8190Pci() only ++ * ++ * Input: struct adapter *Adapter ++ * WIRELESS_BANDWIDTH_E Bandwidth 20M or 40M ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Note: For RF type 0222D ++ *---------------------------------------------------------------------------*/ ++void rtl8188e_PHY_RF6052SetBandwidth(struct adapter *Adapter, ++ enum ht_channel_width Bandwidth) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ ++ switch (Bandwidth) { ++ case HT_CHANNEL_WIDTH_20: ++ pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff) | BIT(10) | BIT(11)); ++ PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]); ++ break; ++ case HT_CHANNEL_WIDTH_40: ++ pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff) | BIT(10)); ++ PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]); ++ break; ++ default: ++ break; ++ } ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: PHY_RF6052SetCckTxPower ++ * ++ * Overview: ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/05/2008 MHC Simulate 8192series.. ++ * ++ *---------------------------------------------------------------------------*/ ++ ++void ++rtl8188e_PHY_RF6052SetCckTxPower( ++ struct adapter *Adapter, ++ u8 *pPowerlevel) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &pHalData->dmpriv; ++ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; ++ u32 TxAGC[2] = {0, 0}, tmpval = 0, pwrtrac_value; ++ bool TurboScanOff = false; ++ u8 idx1, idx2; ++ u8 *ptr; ++ u8 direction; ++ /* FOR CE ,must disable turbo scan */ ++ TurboScanOff = true; ++ ++ if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { ++ TxAGC[RF_PATH_A] = 0x3f3f3f3f; ++ TxAGC[RF_PATH_B] = 0x3f3f3f3f; ++ ++ TurboScanOff = true;/* disable turbo scan */ ++ ++ if (TurboScanOff) { ++ for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) { ++ TxAGC[idx1] = ++ pPowerlevel[idx1] | (pPowerlevel[idx1] << 8) | ++ (pPowerlevel[idx1] << 16) | (pPowerlevel[idx1] << 24); ++ /* 2010/10/18 MH For external PA module. We need to limit power index to be less than 0x20. */ ++ if (TxAGC[idx1] > 0x20 && pHalData->ExternalPA) ++ TxAGC[idx1] = 0x20; ++ } ++ } ++ } else { ++ /* Driver dynamic Tx power shall not affect Tx power. ++ * It shall be determined by power training mechanism. ++i * Currently, we cannot fully disable driver dynamic ++ * tx power mechanism because it is referenced by BT ++ * coexist mechanism. ++ * In the future, two mechanism shall be separated from ++ * each other and maintained independently. */ ++ if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) { ++ TxAGC[RF_PATH_A] = 0x10101010; ++ TxAGC[RF_PATH_B] = 0x10101010; ++ } else if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level2) { ++ TxAGC[RF_PATH_A] = 0x00000000; ++ TxAGC[RF_PATH_B] = 0x00000000; ++ } else { ++ for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) { ++ TxAGC[idx1] = ++ pPowerlevel[idx1] | (pPowerlevel[idx1] << 8) | ++ (pPowerlevel[idx1] << 16) | (pPowerlevel[idx1] << 24); ++ } ++ if (pHalData->EEPROMRegulatory == 0) { ++ tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][6]) + ++ (pHalData->MCSTxPowerLevelOriginalOffset[0][7] << 8); ++ TxAGC[RF_PATH_A] += tmpval; ++ ++ tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][14]) + ++ (pHalData->MCSTxPowerLevelOriginalOffset[0][15] << 24); ++ TxAGC[RF_PATH_B] += tmpval; ++ } ++ } ++ } ++ for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) { ++ ptr = (u8 *)(&TxAGC[idx1]); ++ for (idx2 = 0; idx2 < 4; idx2++) { ++ if (*ptr > RF6052_MAX_TX_PWR) ++ *ptr = RF6052_MAX_TX_PWR; ++ ptr++; ++ } ++ } ++ ODM_TxPwrTrackAdjust88E(&pHalData->odmpriv, 1, &direction, &pwrtrac_value); ++ ++ if (direction == 1) { ++ /* Increase TX power */ ++ TxAGC[0] += pwrtrac_value; ++ TxAGC[1] += pwrtrac_value; ++ } else if (direction == 2) { ++ /* Decrease TX power */ ++ TxAGC[0] -= pwrtrac_value; ++ TxAGC[1] -= pwrtrac_value; ++ } ++ ++ /* rf-A cck tx power */ ++ tmpval = TxAGC[RF_PATH_A] & 0xff; ++ PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, tmpval); ++ tmpval = TxAGC[RF_PATH_A] >> 8; ++ PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); ++ ++ /* rf-B cck tx power */ ++ tmpval = TxAGC[RF_PATH_B] >> 24; ++ PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, tmpval); ++ tmpval = TxAGC[RF_PATH_B] & 0x00ffffff; ++ PHY_SetBBReg(Adapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, tmpval); ++} /* PHY_RF6052SetCckTxPower */ ++ ++/* */ ++/* powerbase0 for OFDM rates */ ++/* powerbase1 for HT MCS rates */ ++/* */ ++static void getpowerbase88e(struct adapter *Adapter, u8 *pPowerLevelOFDM, ++ u8 *pPowerLevelBW20, u8 *pPowerLevelBW40, u8 Channel, u32 *OfdmBase, u32 *MCSBase) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u32 powerBase0, powerBase1; ++ u8 i, powerlevel[2]; ++ ++ for (i = 0; i < 2; i++) { ++ powerBase0 = pPowerLevelOFDM[i]; ++ ++ powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | (powerBase0 << 8) | powerBase0; ++ *(OfdmBase + i) = powerBase0; ++ } ++ for (i = 0; i < pHalData->NumTotalRFPath; i++) { ++ /* Check HT20 to HT40 diff */ ++ if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20) ++ powerlevel[i] = pPowerLevelBW20[i]; ++ else ++ powerlevel[i] = pPowerLevelBW40[i]; ++ powerBase1 = powerlevel[i]; ++ powerBase1 = (powerBase1 << 24) | (powerBase1 << 16) | (powerBase1 << 8) | powerBase1; ++ *(MCSBase + i) = powerBase1; ++ } ++} ++static void get_rx_power_val_by_reg(struct adapter *Adapter, u8 Channel, ++ u8 index, u32 *powerBase0, u32 *powerBase1, ++ u32 *pOutWriteVal) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &pHalData->dmpriv; ++ u8 i, chnlGroup = 0, pwr_diff_limit[4], customer_pwr_limit; ++ s8 pwr_diff = 0; ++ u32 writeVal, customer_limit, rf; ++ u8 Regulatory = pHalData->EEPROMRegulatory; ++ ++ /* Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate */ ++ ++ for (rf = 0; rf < 2; rf++) { ++ switch (Regulatory) { ++ case 0: /* Realtek better performance */ ++ /* increase power diff defined by Realtek for large power */ ++ chnlGroup = 0; ++ writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index + (rf ? 8 : 0)] + ++ ((index < 2) ? powerBase0[rf] : powerBase1[rf]); ++ break; ++ case 1: /* Realtek regulatory */ ++ /* increase power diff defined by Realtek for regulatory */ ++ if (pHalData->pwrGroupCnt == 1) ++ chnlGroup = 0; ++ if (pHalData->pwrGroupCnt >= pHalData->PGMaxGroup) { ++ if (Channel < 3) /* Channel 1-2 */ ++ chnlGroup = 0; ++ else if (Channel < 6) /* Channel 3-5 */ ++ chnlGroup = 1; ++ else if (Channel < 9) /* Channel 6-8 */ ++ chnlGroup = 2; ++ else if (Channel < 12) /* Channel 9-11 */ ++ chnlGroup = 3; ++ else if (Channel < 14) /* Channel 12-13 */ ++ chnlGroup = 4; ++ else if (Channel == 14) /* Channel 14 */ ++ chnlGroup = 5; ++ } ++ writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index + (rf ? 8 : 0)] + ++ ((index < 2) ? powerBase0[rf] : powerBase1[rf]); ++ break; ++ case 2: /* Better regulatory */ ++ /* don't increase any power diff */ ++ writeVal = ((index < 2) ? powerBase0[rf] : powerBase1[rf]); ++ break; ++ case 3: /* Customer defined power diff. */ ++ /* increase power diff defined by customer. */ ++ chnlGroup = 0; ++ ++ if (index < 2) ++ pwr_diff = pHalData->TxPwrLegacyHtDiff[rf][Channel - 1]; ++ else if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20) ++ pwr_diff = pHalData->TxPwrHt20Diff[rf][Channel - 1]; ++ ++ if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_40) ++ customer_pwr_limit = pHalData->PwrGroupHT40[rf][Channel - 1]; ++ else ++ customer_pwr_limit = pHalData->PwrGroupHT20[rf][Channel - 1]; ++ ++ if (pwr_diff >= customer_pwr_limit) ++ pwr_diff = 0; ++ else ++ pwr_diff = customer_pwr_limit - pwr_diff; ++ ++ for (i = 0; i < 4; i++) { ++ pwr_diff_limit[i] = (u8)((pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index + (rf ? 8 : 0)] & (0x7f << (i * 8))) >> (i * 8)); ++ ++ if (pwr_diff_limit[i] > pwr_diff) ++ pwr_diff_limit[i] = pwr_diff; ++ } ++ customer_limit = (pwr_diff_limit[3] << 24) | (pwr_diff_limit[2] << 16) | ++ (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); ++ writeVal = customer_limit + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); ++ break; ++ default: ++ chnlGroup = 0; ++ writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index + (rf ? 8 : 0)] + ++ ((index < 2) ? powerBase0[rf] : powerBase1[rf]); ++ break; ++ } ++/* 20100427 Joseph: Driver dynamic Tx power shall not affect Tx power. It shall be determined by power training mechanism. */ ++/* Currently, we cannot fully disable driver dynamic tx power mechanism because it is referenced by BT coexist mechanism. */ ++/* In the future, two mechanism shall be separated from each other and maintained independently. Thanks for Lanhsin's reminder. */ ++ /* 92d do not need this */ ++ if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) ++ writeVal = 0x14141414; ++ else if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level2) ++ writeVal = 0x00000000; ++ ++ /* 20100628 Joseph: High power mode for BT-Coexist mechanism. */ ++ /* This mechanism is only applied when Driver-Highpower-Mechanism is OFF. */ ++ if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_BT1) ++ writeVal = writeVal - 0x06060606; ++ *(pOutWriteVal + rf) = writeVal; ++ } ++} ++static void writeOFDMPowerReg88E(struct adapter *Adapter, u8 index, u32 *pValue) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u16 regoffset_a[6] = { ++ rTxAGC_A_Rate18_06, rTxAGC_A_Rate54_24, ++ rTxAGC_A_Mcs03_Mcs00, rTxAGC_A_Mcs07_Mcs04, ++ rTxAGC_A_Mcs11_Mcs08, rTxAGC_A_Mcs15_Mcs12}; ++ u16 regoffset_b[6] = { ++ rTxAGC_B_Rate18_06, rTxAGC_B_Rate54_24, ++ rTxAGC_B_Mcs03_Mcs00, rTxAGC_B_Mcs07_Mcs04, ++ rTxAGC_B_Mcs11_Mcs08, rTxAGC_B_Mcs15_Mcs12}; ++ u8 i, rf, pwr_val[4]; ++ u32 writeVal; ++ u16 regoffset; ++ ++ for (rf = 0; rf < 2; rf++) { ++ writeVal = pValue[rf]; ++ for (i = 0; i < 4; i++) { ++ pwr_val[i] = (u8)((writeVal & (0x7f << (i * 8))) >> (i * 8)); ++ if (pwr_val[i] > RF6052_MAX_TX_PWR) ++ pwr_val[i] = RF6052_MAX_TX_PWR; ++ } ++ writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) | (pwr_val[1] << 8) | pwr_val[0]; ++ ++ if (rf == 0) ++ regoffset = regoffset_a[index]; ++ else ++ regoffset = regoffset_b[index]; ++ ++ PHY_SetBBReg(Adapter, regoffset, bMaskDWord, writeVal); ++ ++ /* 201005115 Joseph: Set Tx Power diff for Tx power training mechanism. */ ++ if (((pHalData->rf_type == RF_2T2R) && ++ (regoffset == rTxAGC_A_Mcs15_Mcs12 || regoffset == rTxAGC_B_Mcs15_Mcs12)) || ++ ((pHalData->rf_type != RF_2T2R) && ++ (regoffset == rTxAGC_A_Mcs07_Mcs04 || regoffset == rTxAGC_B_Mcs07_Mcs04))) { ++ writeVal = pwr_val[3]; ++ if (regoffset == rTxAGC_A_Mcs15_Mcs12 || regoffset == rTxAGC_A_Mcs07_Mcs04) ++ regoffset = 0xc90; ++ if (regoffset == rTxAGC_B_Mcs15_Mcs12 || regoffset == rTxAGC_B_Mcs07_Mcs04) ++ regoffset = 0xc98; ++ for (i = 0; i < 3; i++) { ++ if (i != 2) ++ writeVal = (writeVal > 8) ? (writeVal - 8) : 0; ++ else ++ writeVal = (writeVal > 6) ? (writeVal - 6) : 0; ++ rtw_write8(Adapter, (u32)(regoffset + i), (u8)writeVal); ++ } ++ } ++ } ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: PHY_RF6052SetOFDMTxPower ++ * ++ * Overview: For legacy and HY OFDM, we must read EEPROM TX power index for ++ * different channel and read original value in TX power register area from ++ * 0xe00. We increase offset and original value to be correct tx pwr. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 11/05/2008 MHC Simulate 8192 series method. ++ * 01/06/2009 MHC 1. Prevent Path B tx power overflow or underflow dure to ++ * A/B pwr difference or legacy/HT pwr diff. ++ * 2. We concern with path B legacy/HT OFDM difference. ++ * 01/22/2009 MHC Support new EPRO format from SD3. ++ * ++ *---------------------------------------------------------------------------*/ ++ ++void ++rtl8188e_PHY_RF6052SetOFDMTxPower( ++ struct adapter *Adapter, ++ u8 *pPowerLevelOFDM, ++ u8 *pPowerLevelBW20, ++ u8 *pPowerLevelBW40, ++ u8 Channel) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u32 writeVal[2], powerBase0[2], powerBase1[2], pwrtrac_value; ++ u8 direction; ++ u8 index = 0; ++ ++ getpowerbase88e(Adapter, pPowerLevelOFDM, pPowerLevelBW20, pPowerLevelBW40, Channel, &powerBase0[0], &powerBase1[0]); ++ ++ /* 2012/04/23 MH According to power tracking value, we need to revise OFDM tx power. */ ++ /* This is ued to fix unstable power tracking mode. */ ++ ODM_TxPwrTrackAdjust88E(&pHalData->odmpriv, 0, &direction, &pwrtrac_value); ++ ++ for (index = 0; index < 6; index++) { ++ get_rx_power_val_by_reg(Adapter, Channel, index, ++ &powerBase0[0], &powerBase1[0], ++ &writeVal[0]); ++ ++ if (direction == 1) { ++ writeVal[0] += pwrtrac_value; ++ writeVal[1] += pwrtrac_value; ++ } else if (direction == 2) { ++ writeVal[0] -= pwrtrac_value; ++ writeVal[1] -= pwrtrac_value; ++ } ++ writeOFDMPowerReg88E(Adapter, index, &writeVal[0]); ++ } ++} ++ ++static int phy_RF6052_Config_ParaFile(struct adapter *Adapter) ++{ ++ struct bb_reg_def *pPhyReg; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ u32 u4RegValue = 0; ++ u8 eRFPath; ++ int rtStatus = _SUCCESS; ++ ++ /* 3----------------------------------------------------------------- */ ++ /* 3 <2> Initialize RF */ ++ /* 3----------------------------------------------------------------- */ ++ for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) { ++ pPhyReg = &pHalData->PHYRegDef[eRFPath]; ++ ++ /*----Store original RFENV control type----*/ ++ switch (eRFPath) { ++ case RF_PATH_A: ++ case RF_PATH_C: ++ u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV); ++ break; ++ case RF_PATH_B: ++ case RF_PATH_D: ++ u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV << 16); ++ break; ++ } ++ /*----Set RF_ENV enable----*/ ++ PHY_SetBBReg(Adapter, pPhyReg->rfintfe, bRFSI_RFENV << 16, 0x1); ++ udelay(1);/* PlatformStallExecution(1); */ ++ ++ /*----Set RF_ENV output high----*/ ++ PHY_SetBBReg(Adapter, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); ++ udelay(1);/* PlatformStallExecution(1); */ ++ ++ /* Set bit number of Address and Data for RF register */ ++ PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); /* Set 1 to 4 bits for 8255 */ ++ udelay(1);/* PlatformStallExecution(1); */ ++ ++ PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); /* Set 0 to 12 bits for 8255 */ ++ udelay(1);/* PlatformStallExecution(1); */ ++ ++ /*----Initialize RF fom connfiguration file----*/ ++ switch (eRFPath) { ++ case RF_PATH_A: ++ if (HAL_STATUS_FAILURE == ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv, (enum rf_radio_path)eRFPath, (enum rf_radio_path)eRFPath)) ++ rtStatus = _FAIL; ++ break; ++ case RF_PATH_B: ++ if (HAL_STATUS_FAILURE == ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv, (enum rf_radio_path)eRFPath, (enum rf_radio_path)eRFPath)) ++ rtStatus = _FAIL; ++ break; ++ case RF_PATH_C: ++ break; ++ case RF_PATH_D: ++ break; ++ } ++ /*----Restore RFENV control type----*/; ++ switch (eRFPath) { ++ case RF_PATH_A: ++ case RF_PATH_C: ++ PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue); ++ break; ++ case RF_PATH_B: ++ case RF_PATH_D: ++ PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV << 16, u4RegValue); ++ break; ++ } ++ if (rtStatus != _SUCCESS) ++ goto phy_RF6052_Config_ParaFile_Fail; ++ } ++ return rtStatus; ++ ++phy_RF6052_Config_ParaFile_Fail: ++ return rtStatus; ++} ++ ++int PHY_RF6052_Config8188E(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); ++ int rtStatus = _SUCCESS; ++ ++ /* */ ++ /* Initialize general global value */ ++ /* */ ++ /* TODO: Extend RF_PATH_C and RF_PATH_D in the future */ ++ if (pHalData->rf_type == RF_1T1R) ++ pHalData->NumTotalRFPath = 1; ++ else ++ pHalData->NumTotalRFPath = 2; ++ ++ /* */ ++ /* Config BB and RF */ ++ /* */ ++ rtStatus = phy_RF6052_Config_ParaFile(Adapter); ++ return rtStatus; ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c +new file mode 100644 +index 000000000000..244286789b6d +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c +@@ -0,0 +1,186 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188E_REDESC_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtl8188e_hal.h" ++ ++static void process_rssi(struct adapter *padapter, struct recv_frame *prframe) ++{ ++ struct rx_pkt_attrib *pattrib = &prframe->attrib; ++ struct signal_stat *signal_stat = &padapter->recvpriv.signal_strength_data; ++ ++ if (signal_stat->update_req) { ++ signal_stat->total_num = 0; ++ signal_stat->total_val = 0; ++ signal_stat->update_req = 0; ++ } ++ ++ signal_stat->total_num++; ++ signal_stat->total_val += pattrib->phy_info.SignalStrength; ++ signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num; ++} /* Process_UI_RSSI_8192C */ ++ ++static void process_link_qual(struct adapter *padapter, struct recv_frame *prframe) ++{ ++ struct rx_pkt_attrib *pattrib; ++ struct signal_stat *signal_stat; ++ ++ if (!prframe || !padapter) ++ return; ++ ++ pattrib = &prframe->attrib; ++ signal_stat = &padapter->recvpriv.signal_qual_data; ++ ++ if (signal_stat->update_req) { ++ signal_stat->total_num = 0; ++ signal_stat->total_val = 0; ++ signal_stat->update_req = 0; ++ } ++ ++ signal_stat->total_num++; ++ signal_stat->total_val += pattrib->phy_info.SignalQuality; ++ signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num; ++} ++ ++void rtl8188e_process_phy_info(struct adapter *padapter, void *prframe) ++{ ++ struct recv_frame *precvframe = (struct recv_frame *)prframe; ++ ++ /* Check RSSI */ ++ process_rssi(padapter, precvframe); ++ /* Check EVM */ ++ process_link_qual(padapter, precvframe); ++} ++ ++void update_recvframe_attrib_88e(struct recv_frame *precvframe, struct recv_stat *prxstat) ++{ ++ struct rx_pkt_attrib *pattrib; ++ struct recv_stat report; ++ ++ report.rxdw0 = prxstat->rxdw0; ++ report.rxdw1 = prxstat->rxdw1; ++ report.rxdw2 = prxstat->rxdw2; ++ report.rxdw3 = prxstat->rxdw3; ++ report.rxdw4 = prxstat->rxdw4; ++ report.rxdw5 = prxstat->rxdw5; ++ ++ pattrib = &precvframe->attrib; ++ memset(pattrib, 0, sizeof(struct rx_pkt_attrib)); ++ ++ pattrib->crc_err = (u8)((le32_to_cpu(report.rxdw0) >> 14) & 0x1);/* u8)prxreport->crc32; */ ++ ++ /* update rx report to recv_frame attribute */ ++ pattrib->pkt_rpt_type = (u8)((le32_to_cpu(report.rxdw3) >> 14) & 0x3);/* prxreport->rpt_sel; */ ++ ++ if (pattrib->pkt_rpt_type == NORMAL_RX) { /* Normal rx packet */ ++ pattrib->pkt_len = (u16)(le32_to_cpu(report.rxdw0) & 0x00003fff);/* u16)prxreport->pktlen; */ ++ pattrib->drvinfo_sz = (u8)((le32_to_cpu(report.rxdw0) >> 16) & 0xf) * 8;/* u8)(prxreport->drvinfosize << 3); */ ++ ++ pattrib->physt = (u8)((le32_to_cpu(report.rxdw0) >> 26) & 0x1);/* u8)prxreport->physt; */ ++ ++ pattrib->bdecrypted = (le32_to_cpu(report.rxdw0) & BIT(27)) ? 0 : 1;/* u8)(prxreport->swdec ? 0 : 1); */ ++ pattrib->encrypt = (u8)((le32_to_cpu(report.rxdw0) >> 20) & 0x7);/* u8)prxreport->security; */ ++ ++ pattrib->qos = (u8)((le32_to_cpu(report.rxdw0) >> 23) & 0x1);/* u8)prxreport->qos; */ ++ pattrib->priority = (u8)((le32_to_cpu(report.rxdw1) >> 8) & 0xf);/* u8)prxreport->tid; */ ++ ++ pattrib->amsdu = (u8)((le32_to_cpu(report.rxdw1) >> 13) & 0x1);/* u8)prxreport->amsdu; */ ++ ++ pattrib->seq_num = (u16)(le32_to_cpu(report.rxdw2) & 0x00000fff);/* u16)prxreport->seq; */ ++ pattrib->frag_num = (u8)((le32_to_cpu(report.rxdw2) >> 12) & 0xf);/* u8)prxreport->frag; */ ++ pattrib->mfrag = (u8)((le32_to_cpu(report.rxdw1) >> 27) & 0x1);/* u8)prxreport->mf; */ ++ pattrib->mdata = (u8)((le32_to_cpu(report.rxdw1) >> 26) & 0x1);/* u8)prxreport->md; */ ++ ++ pattrib->mcs_rate = (u8)(le32_to_cpu(report.rxdw3) & 0x3f);/* u8)prxreport->rxmcs; */ ++ pattrib->rxht = (u8)((le32_to_cpu(report.rxdw3) >> 6) & 0x1);/* u8)prxreport->rxht; */ ++ ++ pattrib->icv_err = (u8)((le32_to_cpu(report.rxdw0) >> 15) & 0x1);/* u8)prxreport->icverr; */ ++ pattrib->shift_sz = (u8)((le32_to_cpu(report.rxdw0) >> 24) & 0x3); ++ } else if (pattrib->pkt_rpt_type == TX_REPORT1) { /* CCX */ ++ pattrib->pkt_len = TX_RPT1_PKT_LEN; ++ pattrib->drvinfo_sz = 0; ++ } else if (pattrib->pkt_rpt_type == TX_REPORT2) { /* TX RPT */ ++ pattrib->pkt_len = (u16)(le32_to_cpu(report.rxdw0) & 0x3FF);/* Rx length[9:0] */ ++ pattrib->drvinfo_sz = 0; ++ ++ /* */ ++ /* Get TX report MAC ID valid. */ ++ /* */ ++ pattrib->MacIDValidEntry[0] = le32_to_cpu(report.rxdw4); ++ pattrib->MacIDValidEntry[1] = le32_to_cpu(report.rxdw5); ++ ++ } else if (pattrib->pkt_rpt_type == HIS_REPORT) { /* USB HISR RPT */ ++ pattrib->pkt_len = (u16)(le32_to_cpu(report.rxdw0) & 0x00003fff);/* u16)prxreport->pktlen; */ ++ } ++} ++ ++/* ++ * Notice: ++ * Before calling this function, ++ * precvframe->rx_data should be ready! ++ */ ++void update_recvframe_phyinfo_88e(struct recv_frame *precvframe, struct phy_stat *pphy_status) ++{ ++ struct adapter *padapter = precvframe->adapter; ++ struct rx_pkt_attrib *pattrib = &precvframe->attrib; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct odm_phy_status_info *pPHYInfo = (struct odm_phy_status_info *)(&pattrib->phy_info); ++ u8 *wlanhdr; ++ struct odm_per_pkt_info pkt_info; ++ u8 *sa = NULL; ++ struct sta_priv *pstapriv; ++ struct sta_info *psta; ++ ++ pkt_info.bPacketMatchBSSID = false; ++ pkt_info.bPacketToSelf = false; ++ pkt_info.bPacketBeacon = false; ++ ++ wlanhdr = get_recvframe_data(precvframe); ++ ++ pkt_info.bPacketMatchBSSID = ((!IsFrameTypeCtrl(wlanhdr)) && ++ !pattrib->icv_err && !pattrib->crc_err && ++ !memcmp(get_hdr_bssid(wlanhdr), ++ get_bssid(&padapter->mlmepriv), ETH_ALEN)); ++ ++ pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && ++ (!memcmp(get_da(wlanhdr), ++ myid(&padapter->eeprompriv), ETH_ALEN)); ++ ++ pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && ++ (GetFrameSubType(wlanhdr) == WIFI_BEACON); ++ ++ if (pkt_info.bPacketBeacon) { ++ if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) ++ sa = padapter->mlmepriv.cur_network.network.MacAddress; ++ /* to do Ad-hoc */ ++ } else { ++ sa = get_sa(wlanhdr); ++ } ++ ++ pstapriv = &padapter->stapriv; ++ pkt_info.StationID = 0xFF; ++ psta = rtw_get_stainfo(pstapriv, sa); ++ if (psta) ++ pkt_info.StationID = psta->mac_id; ++ pkt_info.Rate = pattrib->mcs_rate; ++ ++ ODM_PhyStatusQuery(&pHalData->odmpriv, pPHYInfo, (u8 *)pphy_status, &(pkt_info), padapter); ++ ++ precvframe->psta = NULL; ++ if (pkt_info.bPacketMatchBSSID && ++ (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE))) { ++ if (psta) { ++ precvframe->psta = psta; ++ rtl8188e_process_phy_info(padapter, precvframe); ++ } ++ } else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) { ++ if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) { ++ if (psta) ++ precvframe->psta = psta; ++ } ++ rtl8188e_process_phy_info(padapter, precvframe); ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c +new file mode 100644 +index 000000000000..16fa249e35d3 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c +@@ -0,0 +1,64 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188E_SRESET_C_ ++ ++#include "../include/rtl8188e_sreset.h" ++#include "../include/rtl8188e_hal.h" ++ ++void rtl8188e_silentreset_for_specific_platform(struct adapter *padapter) ++{ ++} ++ ++void rtl8188e_sreset_xmit_status_check(struct adapter *padapter) ++{ ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ struct sreset_priv *psrtpriv = &pHalData->srestpriv; ++ ++ unsigned long current_time; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ unsigned int diff_time; ++ u32 txdma_status; ++ ++ txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS); ++ if (txdma_status != 0x00) { ++ DBG_88E("%s REG_TXDMA_STATUS:0x%08x\n", __func__, txdma_status); ++ rtw_write32(padapter, REG_TXDMA_STATUS, txdma_status); ++ rtl8188e_silentreset_for_specific_platform(padapter); ++ } ++ /* total xmit irp = 4 */ ++ current_time = jiffies; ++ if (0 == pxmitpriv->free_xmitbuf_cnt) { ++ diff_time = jiffies_to_msecs(current_time - psrtpriv->last_tx_time); ++ ++ if (diff_time > 2000) { ++ if (psrtpriv->last_tx_complete_time == 0) { ++ psrtpriv->last_tx_complete_time = current_time; ++ } else { ++ diff_time = jiffies_to_msecs(current_time - psrtpriv->last_tx_complete_time); ++ if (diff_time > 4000) { ++ DBG_88E("%s tx hang\n", __func__); ++ rtl8188e_silentreset_for_specific_platform(padapter); ++ } ++ } ++ } ++ } ++} ++ ++void rtl8188e_sreset_linked_status_check(struct adapter *padapter) ++{ ++ u32 rx_dma_status = 0; ++ u8 fw_status = 0; ++ rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS); ++ if (rx_dma_status != 0x00) { ++ DBG_88E("%s REG_RXDMA_STATUS:0x%08x\n", __func__, rx_dma_status); ++ rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status); ++ } ++ fw_status = rtw_read8(padapter, REG_FMETHR); ++ if (fw_status != 0x00) { ++ if (fw_status == 1) ++ DBG_88E("%s REG_FW_STATUS (0x%02x), Read_Efuse_Fail !!\n", __func__, fw_status); ++ else if (fw_status == 2) ++ DBG_88E("%s REG_FW_STATUS (0x%02x), Condition_No_Match !!\n", __func__, fw_status); ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188e_xmit.c b/drivers/staging/r8188eu/hal/rtl8188e_xmit.c +new file mode 100644 +index 000000000000..46b871f3f631 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188e_xmit.c +@@ -0,0 +1,22 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188E_XMIT_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtl8188e_hal.h" ++ ++void handle_txrpt_ccx_88e(struct adapter *adapter, u8 *buf) ++{ ++ struct txrpt_ccx_88e *txrpt_ccx = (struct txrpt_ccx_88e *)buf; ++ ++ if (txrpt_ccx->int_ccx) { ++ if (txrpt_ccx->pkt_ok) ++ rtw_ack_tx_done(&adapter->xmitpriv, ++ RTW_SCTX_DONE_SUCCESS); ++ else ++ rtw_ack_tx_done(&adapter->xmitpriv, ++ RTW_SCTX_DONE_CCX_PKT_FAIL); ++ } ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188eu_led.c b/drivers/staging/r8188eu/hal/rtl8188eu_led.c +new file mode 100644 +index 000000000000..452d4bb87aba +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188eu_led.c +@@ -0,0 +1,94 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtl8188e_hal.h" ++#include "../include/rtl8188e_led.h" ++ ++/* LED object. */ ++ ++/* LED_819xUsb routines. */ ++/* Description: */ ++/* Turn on LED according to LedPin specified. */ ++void SwLedOn(struct adapter *padapter, struct LED_871x *pLed) ++{ ++ u8 LedCfg; ++ ++ if (padapter->bSurpriseRemoved || padapter->bDriverStopped) ++ return; ++ LedCfg = rtw_read8(padapter, REG_LEDCFG2); ++ switch (pLed->LedPin) { ++ case LED_PIN_LED0: ++ rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0xf0) | BIT(5) | BIT(6)); /* SW control led0 on. */ ++ break; ++ case LED_PIN_LED1: ++ rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0x0f) | BIT(5)); /* SW control led1 on. */ ++ break; ++ default: ++ break; ++ } ++ pLed->bLedOn = true; ++} ++ ++/* Description: */ ++/* Turn off LED according to LedPin specified. */ ++void SwLedOff(struct adapter *padapter, struct LED_871x *pLed) ++{ ++ u8 LedCfg; ++ struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); ++ ++ if (padapter->bSurpriseRemoved || padapter->bDriverStopped) ++ goto exit; ++ ++ LedCfg = rtw_read8(padapter, REG_LEDCFG2);/* 0x4E */ ++ ++ switch (pLed->LedPin) { ++ case LED_PIN_LED0: ++ if (pHalData->bLedOpenDrain) { ++ /* Open-drain arrangement for controlling the LED) */ ++ LedCfg &= 0x90; /* Set to software control. */ ++ rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3))); ++ LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG); ++ LedCfg &= 0xFE; ++ rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg); ++ } else { ++ rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3) | BIT(5) | BIT(6))); ++ } ++ break; ++ case LED_PIN_LED1: ++ LedCfg &= 0x0f; /* Set to software control. */ ++ rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3))); ++ break; ++ default: ++ break; ++ } ++exit: ++ pLed->bLedOn = false; ++} ++ ++/* Interface to manipulate LED objects. */ ++/* Default LED behavior. */ ++ ++/* Description: */ ++/* Initialize all LED_871x objects. */ ++void rtl8188eu_InitSwLeds(struct adapter *padapter) ++{ ++ struct led_priv *pledpriv = &padapter->ledpriv; ++ ++ pledpriv->LedControlHandler = LedControl8188eu; ++ ++ InitLed871x(padapter, &pledpriv->SwLed0, LED_PIN_LED0); ++ ++ InitLed871x(padapter, &pledpriv->SwLed1, LED_PIN_LED1); ++} ++ ++/* Description: */ ++/* DeInitialize all LED_819xUsb objects. */ ++void rtl8188eu_DeInitSwLeds(struct adapter *padapter) ++{ ++ struct led_priv *ledpriv = &padapter->ledpriv; ++ ++ DeInitLed871x(&ledpriv->SwLed0); ++ DeInitLed871x(&ledpriv->SwLed1); ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188eu_recv.c b/drivers/staging/r8188eu/hal/rtl8188eu_recv.c +new file mode 100644 +index 000000000000..2da7bde80cc0 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188eu_recv.c +@@ -0,0 +1,117 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188EU_RECV_C_ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/mlme_osdep.h" ++ ++#include "../include/usb_ops.h" ++#include "../include/wifi.h" ++ ++#include "../include/rtl8188e_hal.h" ++ ++void rtl8188eu_init_recvbuf(struct adapter *padapter, struct recv_buf *precvbuf) ++{ ++ precvbuf->transfer_len = 0; ++ ++ precvbuf->len = 0; ++ ++ precvbuf->ref_cnt = 0; ++ ++ if (precvbuf->pbuf) { ++ precvbuf->pdata = precvbuf->pbuf; ++ precvbuf->phead = precvbuf->pbuf; ++ precvbuf->ptail = precvbuf->pbuf; ++ precvbuf->pend = precvbuf->pdata + MAX_RECVBUF_SZ; ++ } ++} ++ ++int rtl8188eu_init_recv_priv(struct adapter *padapter) ++{ ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ int i, res = _SUCCESS; ++ struct recv_buf *precvbuf; ++ ++ tasklet_init(&precvpriv->recv_tasklet, ++ rtl8188eu_recv_tasklet, ++ (unsigned long)padapter); ++ ++ /* init recv_buf */ ++ _rtw_init_queue(&precvpriv->free_recv_buf_queue); ++ ++ precvpriv->pallocated_recv_buf = kzalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4, ++ GFP_KERNEL); ++ if (!precvpriv->pallocated_recv_buf) { ++ res = _FAIL; ++ goto exit; ++ } ++ memset(precvpriv->pallocated_recv_buf, 0, NR_RECVBUFF * sizeof(struct recv_buf) + 4); ++ ++ precvpriv->precv_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(precvpriv->pallocated_recv_buf), 4); ++ ++ precvbuf = (struct recv_buf *)precvpriv->precv_buf; ++ ++ for (i = 0; i < NR_RECVBUFF; i++) { ++ INIT_LIST_HEAD(&precvbuf->list); ++ spin_lock_init(&precvbuf->recvbuf_lock); ++ precvbuf->alloc_sz = MAX_RECVBUF_SZ; ++ res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf); ++ if (res == _FAIL) ++ break; ++ precvbuf->ref_cnt = 0; ++ precvbuf->adapter = padapter; ++ precvbuf++; ++ } ++ precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF; ++ skb_queue_head_init(&precvpriv->rx_skb_queue); ++ { ++ int i; ++ size_t tmpaddr = 0; ++ size_t alignment = 0; ++ struct sk_buff *pskb = NULL; ++ ++ skb_queue_head_init(&precvpriv->free_recv_skb_queue); ++ ++ for (i = 0; i < NR_PREALLOC_RECV_SKB; i++) { ++ pskb = __netdev_alloc_skb(padapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, GFP_KERNEL); ++ if (pskb) { ++ pskb->dev = padapter->pnetdev; ++ tmpaddr = (size_t)pskb->data; ++ alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); ++ skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment)); ++ ++ skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); ++ } ++ pskb = NULL; ++ } ++ } ++exit: ++ return res; ++} ++ ++void rtl8188eu_free_recv_priv(struct adapter *padapter) ++{ ++ int i; ++ struct recv_buf *precvbuf; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ ++ precvbuf = (struct recv_buf *)precvpriv->precv_buf; ++ ++ for (i = 0; i < NR_RECVBUFF; i++) { ++ rtw_os_recvbuf_resource_free(padapter, precvbuf); ++ precvbuf++; ++ } ++ ++ kfree(precvpriv->pallocated_recv_buf); ++ ++ if (skb_queue_len(&precvpriv->rx_skb_queue)) ++ DBG_88E(KERN_WARNING "rx_skb_queue not empty\n"); ++ skb_queue_purge(&precvpriv->rx_skb_queue); ++ ++ if (skb_queue_len(&precvpriv->free_recv_skb_queue)) ++ DBG_88E(KERN_WARNING "free_recv_skb_queue not empty, %d\n", skb_queue_len(&precvpriv->free_recv_skb_queue)); ++ ++ skb_queue_purge(&precvpriv->free_recv_skb_queue); ++} +diff --git a/drivers/staging/r8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/r8188eu/hal/rtl8188eu_xmit.c +new file mode 100644 +index 000000000000..17be67ac5fae +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/rtl8188eu_xmit.c +@@ -0,0 +1,672 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RTL8188E_XMIT_C_ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wifi.h" ++#include "../include/osdep_intf.h" ++#include "../include/usb_ops.h" ++#include "../include/rtl8188e_hal.h" ++ ++s32 rtl8188eu_init_xmit_priv(struct adapter *adapt) ++{ ++ struct xmit_priv *pxmitpriv = &adapt->xmitpriv; ++ ++ tasklet_init(&pxmitpriv->xmit_tasklet, ++ rtl8188eu_xmit_tasklet, ++ (unsigned long)adapt); ++ return _SUCCESS; ++} ++ ++static u8 urb_zero_packet_chk(struct adapter *adapt, int sz) ++{ ++ u8 set_tx_desc_offset; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ set_tx_desc_offset = (((sz + TXDESC_SIZE) % haldata->UsbBulkOutSize) == 0) ? 1 : 0; ++ ++ return set_tx_desc_offset; ++} ++ ++static void rtl8188eu_cal_txdesc_chksum(struct tx_desc *ptxdesc) ++{ ++ u16 *usptr = (u16 *)ptxdesc; ++ u32 count = 16; /* (32 bytes / 2 bytes per XOR) => 16 times */ ++ u32 index; ++ u16 checksum = 0; ++ ++ /* Clear first */ ++ ptxdesc->txdw7 &= cpu_to_le32(0xffff0000); ++ ++ for (index = 0; index < count; index++) ++ checksum = checksum ^ le16_to_cpu(*(__le16 *)(usptr + index)); ++ ptxdesc->txdw7 |= cpu_to_le32(0x0000ffff & checksum); ++} ++ ++/* Description: In normal chip, we should send some packet to Hw which will be used by Fw */ ++/* in FW LPS mode. The function is to fill the Tx descriptor of this packets, then */ ++/* Fw can tell Hw to send these packet derectly. */ ++void rtl8188e_fill_fake_txdesc(struct adapter *adapt, u8 *desc, u32 BufferLen, u8 ispspoll, u8 is_btqosnull) ++{ ++ struct tx_desc *ptxdesc; ++ ++ /* Clear all status */ ++ ptxdesc = (struct tx_desc *)desc; ++ memset(desc, 0, TXDESC_SIZE); ++ ++ /* offset 0 */ ++ ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); /* own, bFirstSeg, bLastSeg; */ ++ ++ ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00ff0000); /* 32 bytes for TX Desc */ ++ ++ ptxdesc->txdw0 |= cpu_to_le32(BufferLen & 0x0000ffff); /* Buffer size + command header */ ++ ++ /* offset 4 */ ++ ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT << QSEL_SHT) & 0x00001f00); /* Fixed queue of Mgnt queue */ ++ ++ /* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw. */ ++ if (ispspoll) { ++ ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR); ++ } else { ++ ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); /* Hw set sequence number */ ++ ptxdesc->txdw3 |= cpu_to_le32((8 << 28)); /* set bit3 to 1. Suugested by TimChen. 2009.12.29. */ ++ } ++ ++ if (is_btqosnull) ++ ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); /* BT NULL */ ++ ++ /* offset 16 */ ++ ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */ ++ ++ /* USB interface drop packet if the checksum of descriptor isn't correct. */ ++ /* Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.). */ ++ rtl8188eu_cal_txdesc_chksum(ptxdesc); ++} ++ ++static void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc) ++{ ++ if ((pattrib->encrypt > 0) && !pattrib->bswenc) { ++ switch (pattrib->encrypt) { ++ /* SEC_TYPE : 0:NO_ENC,1:WEP40/TKIP,2:WAPI,3:AES */ ++ case _WEP40_: ++ case _WEP104_: ++ ptxdesc->txdw1 |= cpu_to_le32((0x01 << SEC_TYPE_SHT) & 0x00c00000); ++ ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT); ++ break; ++ case _TKIP_: ++ case _TKIP_WTMIC_: ++ ptxdesc->txdw1 |= cpu_to_le32((0x01 << SEC_TYPE_SHT) & 0x00c00000); ++ ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT); ++ break; ++ case _AES_: ++ ptxdesc->txdw1 |= cpu_to_le32((0x03 << SEC_TYPE_SHT) & 0x00c00000); ++ ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT); ++ break; ++ case _NO_PRIVACY_: ++ default: ++ break; ++ } ++ } ++} ++ ++static void fill_txdesc_vcs(struct pkt_attrib *pattrib, __le32 *pdw) ++{ ++ switch (pattrib->vcs_mode) { ++ case RTS_CTS: ++ *pdw |= cpu_to_le32(RTS_EN); ++ break; ++ case CTS_TO_SELF: ++ *pdw |= cpu_to_le32(CTS_2_SELF); ++ break; ++ case NONE_VCS: ++ default: ++ break; ++ } ++ if (pattrib->vcs_mode) { ++ *pdw |= cpu_to_le32(HW_RTS_EN); ++ /* Set RTS BW */ ++ if (pattrib->ht_en) { ++ *pdw |= (pattrib->bwmode & HT_CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(27)) : 0; ++ ++ if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) ++ *pdw |= cpu_to_le32((0x01 << 28) & 0x30000000); ++ else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER) ++ *pdw |= cpu_to_le32((0x02 << 28) & 0x30000000); ++ else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ++ *pdw |= 0; ++ else ++ *pdw |= cpu_to_le32((0x03 << 28) & 0x30000000); ++ } ++ } ++} ++ ++static void fill_txdesc_phy(struct pkt_attrib *pattrib, __le32 *pdw) ++{ ++ if (pattrib->ht_en) { ++ *pdw |= (pattrib->bwmode & HT_CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(25)) : 0; ++ ++ if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) ++ *pdw |= cpu_to_le32((0x01 << DATA_SC_SHT) & 0x003f0000); ++ else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER) ++ *pdw |= cpu_to_le32((0x02 << DATA_SC_SHT) & 0x003f0000); ++ else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ++ *pdw |= 0; ++ else ++ *pdw |= cpu_to_le32((0x03 << DATA_SC_SHT) & 0x003f0000); ++ } ++} ++ ++static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt) ++{ ++ int pull = 0; ++ uint qsel; ++ u8 data_rate, pwr_status, offset; ++ struct adapter *adapt = pxmitframe->padapter; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ struct tx_desc *ptxdesc = (struct tx_desc *)pmem; ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if (adapt->registrypriv.mp_mode == 0) { ++ if ((!bagg_pkt) && (urb_zero_packet_chk(adapt, sz) == 0)) { ++ ptxdesc = (struct tx_desc *)(pmem + PACKET_OFFSET_SZ); ++ pull = 1; ++ } ++ } ++ ++ memset(ptxdesc, 0, sizeof(struct tx_desc)); ++ ++ /* 4 offset 0 */ ++ ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); ++ ptxdesc->txdw0 |= cpu_to_le32(sz & 0x0000ffff);/* update TXPKTSIZE */ ++ ++ offset = TXDESC_SIZE + OFFSET_SZ; ++ ++ ptxdesc->txdw0 |= cpu_to_le32(((offset) << OFFSET_SHT) & 0x00ff0000);/* 32 bytes for TX Desc */ ++ ++ if (is_multicast_ether_addr(pattrib->ra)) ++ ptxdesc->txdw0 |= cpu_to_le32(BMC); ++ ++ if (adapt->registrypriv.mp_mode == 0) { ++ if (!bagg_pkt) { ++ if ((pull) && (pxmitframe->pkt_offset > 0)) ++ pxmitframe->pkt_offset = pxmitframe->pkt_offset - 1; ++ } ++ } ++ ++ /* pkt_offset, unit:8 bytes padding */ ++ if (pxmitframe->pkt_offset > 0) ++ ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000); ++ ++ /* driver uses rate */ ++ ptxdesc->txdw4 |= cpu_to_le32(USERATE);/* rate control always by driver */ ++ ++ if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) { ++ /* offset 4 */ ++ ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x3F); ++ ++ qsel = (uint)(pattrib->qsel & 0x0000001f); ++ ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); ++ ++ ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000F0000); ++ ++ fill_txdesc_sectype(pattrib, ptxdesc); ++ ++ if (pattrib->ampdu_en) { ++ ptxdesc->txdw2 |= cpu_to_le32(AGG_EN);/* AGG EN */ ++ ptxdesc->txdw6 = cpu_to_le32(0x6666f800); ++ } else { ++ ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);/* AGG BK */ ++ } ++ ++ /* offset 8 */ ++ ++ /* offset 12 */ ++ ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0FFF0000); ++ ++ /* offset 16 , offset 20 */ ++ if (pattrib->qos_en) ++ ptxdesc->txdw4 |= cpu_to_le32(QOS);/* QoS */ ++ ++ /* offset 20 */ ++ if (pxmitframe->agg_num > 1) ++ ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << USB_TXAGG_NUM_SHT) & 0xFF000000); ++ ++ if ((pattrib->ether_type != 0x888e) && ++ (pattrib->ether_type != 0x0806) && ++ (pattrib->ether_type != 0x88b4) && ++ (pattrib->dhcp_pkt != 1)) { ++ /* Non EAP & ARP & DHCP type data packet */ ++ ++ fill_txdesc_vcs(pattrib, &ptxdesc->txdw4); ++ fill_txdesc_phy(pattrib, &ptxdesc->txdw4); ++ ++ ptxdesc->txdw4 |= cpu_to_le32(0x00000008);/* RTS Rate=24M */ ++ ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);/* DATA/RTS Rate FB LMT */ ++ ++ if (pattrib->ht_en) { ++ if (ODM_RA_GetShortGI_8188E(&haldata->odmpriv, pattrib->mac_id)) ++ ptxdesc->txdw5 |= cpu_to_le32(SGI);/* SGI */ ++ } ++ data_rate = ODM_RA_GetDecisionRate_8188E(&haldata->odmpriv, pattrib->mac_id); ++ ptxdesc->txdw5 |= cpu_to_le32(data_rate & 0x3F); ++ pwr_status = ODM_RA_GetHwPwrStatus_8188E(&haldata->odmpriv, pattrib->mac_id); ++ ptxdesc->txdw4 |= cpu_to_le32((pwr_status & 0x7) << PWR_STATUS_SHT); ++ } else { ++ /* EAP data packet and ARP packet and DHCP. */ ++ /* Use the 1M data rate to send the EAP/ARP packet. */ ++ /* This will maybe make the handshake smooth. */ ++ ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);/* AGG BK */ ++ if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) ++ ptxdesc->txdw4 |= cpu_to_le32(BIT(24));/* DATA_SHORT */ ++ ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); ++ } ++ } else if ((pxmitframe->frame_tag & 0x0f) == MGNT_FRAMETAG) { ++ /* offset 4 */ ++ ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x3f); ++ ++ qsel = (uint)(pattrib->qsel & 0x0000001f); ++ ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); ++ ++ ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000f0000); ++ ++ /* offset 8 */ ++ /* CCX-TXRPT ack for xmit mgmt frames. */ ++ if (pxmitframe->ack_report) ++ ptxdesc->txdw2 |= cpu_to_le32(BIT(19)); ++ ++ /* offset 12 */ ++ ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0FFF0000); ++ ++ /* offset 20 */ ++ ptxdesc->txdw5 |= cpu_to_le32(RTY_LMT_EN);/* retry limit enable */ ++ if (pattrib->retry_ctrl) ++ ptxdesc->txdw5 |= cpu_to_le32(0x00180000);/* retry limit = 6 */ ++ else ++ ptxdesc->txdw5 |= cpu_to_le32(0x00300000);/* retry limit = 12 */ ++ ++ ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); ++ } else if ((pxmitframe->frame_tag & 0x0f) == TXAGG_FRAMETAG) { ++ DBG_88E("pxmitframe->frame_tag == TXAGG_FRAMETAG\n"); ++ } else if (((pxmitframe->frame_tag & 0x0f) == MP_FRAMETAG) && ++ (adapt->registrypriv.mp_mode == 1)) { ++ fill_txdesc_for_mp(adapt, ptxdesc); ++ } else { ++ DBG_88E("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag); ++ ++ /* offset 4 */ ++ ptxdesc->txdw1 |= cpu_to_le32((4) & 0x3f);/* CAM_ID(MAC_ID) */ ++ ++ ptxdesc->txdw1 |= cpu_to_le32((6 << RATE_ID_SHT) & 0x000f0000);/* raid */ ++ ++ /* offset 8 */ ++ ++ /* offset 12 */ ++ ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0fff0000); ++ ++ /* offset 20 */ ++ ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); ++ } ++ ++ /* 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. */ ++ /* (1) The sequence number of each non-Qos frame / broadcast / multicast / */ ++ /* mgnt frame should be controlled by Hw because Fw will also send null data */ ++ /* which we cannot control when Fw LPS enable. */ ++ /* --> default enable non-Qos data sequense number. 2010.06.23. by tynli. */ ++ /* (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. */ ++ /* (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. */ ++ /* 2010.06.23. Added by tynli. */ ++ if (!pattrib->qos_en) { ++ ptxdesc->txdw3 |= cpu_to_le32(EN_HWSEQ); /* Hw set sequence number */ ++ ptxdesc->txdw4 |= cpu_to_le32(HW_SSN); /* Hw set sequence number */ ++ } ++ ++ ODM_SetTxAntByTxInfo_88E(&haldata->odmpriv, pmem, pattrib->mac_id); ++ ++ rtl8188eu_cal_txdesc_chksum(ptxdesc); ++ return pull; ++} ++ ++/* for non-agg data frame or management frame */ ++static s32 rtw_dump_xframe(struct adapter *adapt, struct xmit_frame *pxmitframe) ++{ ++ s32 ret = _SUCCESS; ++ s32 inner_ret = _SUCCESS; ++ int t, sz, w_sz, pull = 0; ++ u8 *mem_addr; ++ u32 ff_hwaddr; ++ struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ struct xmit_priv *pxmitpriv = &adapt->xmitpriv; ++ struct security_priv *psecuritypriv = &adapt->securitypriv; ++ if ((pxmitframe->frame_tag == DATA_FRAMETAG) && ++ (pxmitframe->attrib.ether_type != 0x0806) && ++ (pxmitframe->attrib.ether_type != 0x888e) && ++ (pxmitframe->attrib.ether_type != 0x88b4) && ++ (pxmitframe->attrib.dhcp_pkt != 1)) ++ rtw_issue_addbareq_cmd(adapt, pxmitframe); ++ mem_addr = pxmitframe->buf_addr; ++ ++ for (t = 0; t < pattrib->nr_frags; t++) { ++ if (inner_ret != _SUCCESS && ret == _SUCCESS) ++ ret = _FAIL; ++ ++ if (t != (pattrib->nr_frags - 1)) { ++ sz = pxmitpriv->frag_len; ++ sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len); ++ } else { ++ /* no frag */ ++ sz = pattrib->last_txcmdsz; ++ } ++ ++ pull = update_txdesc(pxmitframe, mem_addr, sz, false); ++ ++ if (pull) { ++ mem_addr += PACKET_OFFSET_SZ; /* pull txdesc head */ ++ pxmitframe->buf_addr = mem_addr; ++ w_sz = sz + TXDESC_SIZE; ++ } else { ++ w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ; ++ } ++ ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe); ++ ++ inner_ret = rtw_write_port(adapt, ff_hwaddr, w_sz, (unsigned char *)pxmitbuf); ++ ++ rtw_count_tx_stats(adapt, pxmitframe, sz); ++ ++ mem_addr += w_sz; ++ ++ mem_addr = (u8 *)RND4(((size_t)(mem_addr))); ++ } ++ ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ ++ if (ret != _SUCCESS) ++ rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN); ++ ++ return ret; ++} ++ ++static u32 xmitframe_need_length(struct xmit_frame *pxmitframe) ++{ ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ ++ u32 len = 0; ++ ++ /* no consider fragement */ ++ len = pattrib->hdrlen + pattrib->iv_len + ++ SNAP_SIZE + sizeof(u16) + ++ pattrib->pktlen + ++ ((pattrib->bswenc) ? pattrib->icv_len : 0); ++ ++ if (pattrib->encrypt == _TKIP_) ++ len += 8; ++ ++ return len; ++} ++ ++s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ struct xmit_frame *pxmitframe = NULL; ++ struct xmit_frame *pfirstframe = NULL; ++ ++ /* aggregate variable */ ++ struct hw_xmit *phwxmit; ++ struct sta_info *psta = NULL; ++ struct tx_servq *ptxservq = NULL; ++ struct list_head *xmitframe_plist = NULL, *xmitframe_phead = NULL; ++ ++ u32 pbuf; /* next pkt address */ ++ u32 pbuf_tail; /* last pkt tail */ ++ u32 len; /* packet length, except TXDESC_SIZE and PKT_OFFSET */ ++ ++ u32 bulksize = haldata->UsbBulkOutSize; ++ u8 desc_cnt; ++ u32 bulkptr; ++ ++ /* dump frame variable */ ++ u32 ff_hwaddr; ++ ++ /* check xmitbuffer is ok */ ++ if (!pxmitbuf) { ++ pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); ++ if (!pxmitbuf) ++ return false; ++ } ++ ++ /* 3 1. pick up first frame */ ++ do { ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ ++ pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); ++ if (!pxmitframe) { ++ /* no more xmit frame, release xmit buffer */ ++ rtw_free_xmitbuf(pxmitpriv, pxmitbuf); ++ return false; ++ } ++ ++ pxmitframe->pxmitbuf = pxmitbuf; ++ pxmitframe->buf_addr = pxmitbuf->pbuf; ++ pxmitbuf->priv_data = pxmitframe; ++ ++ pxmitframe->agg_num = 1; /* alloc xmitframe should assign to 1. */ ++ pxmitframe->pkt_offset = 1; /* first frame of aggregation, reserve offset */ ++ ++ rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe); ++ ++ /* always return ndis_packet after rtw_xmitframe_coalesce */ ++ rtw_os_xmit_complete(adapt, pxmitframe); ++ ++ break; ++ } while (1); ++ ++ /* 3 2. aggregate same priority and same DA(AP or STA) frames */ ++ pfirstframe = pxmitframe; ++ len = xmitframe_need_length(pfirstframe) + TXDESC_SIZE + (pfirstframe->pkt_offset * PACKET_OFFSET_SZ); ++ pbuf_tail = len; ++ pbuf = _RND8(pbuf_tail); ++ ++ /* check pkt amount in one bulk */ ++ desc_cnt = 0; ++ bulkptr = bulksize; ++ if (pbuf < bulkptr) { ++ desc_cnt++; ++ } else { ++ desc_cnt = 0; ++ bulkptr = ((pbuf / bulksize) + 1) * bulksize; /* round to next bulksize */ ++ } ++ ++ /* dequeue same priority packet from station tx queue */ ++ psta = pfirstframe->attrib.psta; ++ switch (pfirstframe->attrib.priority) { ++ case 1: ++ case 2: ++ ptxservq = &psta->sta_xmitpriv.bk_q; ++ phwxmit = pxmitpriv->hwxmits + 3; ++ break; ++ case 4: ++ case 5: ++ ptxservq = &psta->sta_xmitpriv.vi_q; ++ phwxmit = pxmitpriv->hwxmits + 1; ++ break; ++ case 6: ++ case 7: ++ ptxservq = &psta->sta_xmitpriv.vo_q; ++ phwxmit = pxmitpriv->hwxmits; ++ break; ++ case 0: ++ case 3: ++ default: ++ ptxservq = &psta->sta_xmitpriv.be_q; ++ phwxmit = pxmitpriv->hwxmits + 2; ++ break; ++ } ++ spin_lock_bh(&pxmitpriv->lock); ++ ++ xmitframe_phead = get_list_head(&ptxservq->sta_pending); ++ xmitframe_plist = xmitframe_phead->next; ++ ++ while (xmitframe_phead != xmitframe_plist) { ++ pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); ++ xmitframe_plist = xmitframe_plist->next; ++ ++ pxmitframe->agg_num = 0; /* not first frame of aggregation */ ++ pxmitframe->pkt_offset = 0; /* not first frame of aggregation, no need to reserve offset */ ++ ++ len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ); ++ ++ if (_RND8(pbuf + len) > MAX_XMITBUF_SZ) { ++ pxmitframe->agg_num = 1; ++ pxmitframe->pkt_offset = 1; ++ break; ++ } ++ list_del_init(&pxmitframe->list); ++ ptxservq->qcnt--; ++ phwxmit->accnt--; ++ ++ pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf; ++ ++ rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe); ++ /* always return ndis_packet after rtw_xmitframe_coalesce */ ++ rtw_os_xmit_complete(adapt, pxmitframe); ++ ++ /* (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz */ ++ update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, true); ++ ++ /* don't need xmitframe any more */ ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ ++ /* handle pointer and stop condition */ ++ pbuf_tail = pbuf + len; ++ pbuf = _RND8(pbuf_tail); ++ ++ pfirstframe->agg_num++; ++ if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num) ++ break; ++ ++ if (pbuf < bulkptr) { ++ desc_cnt++; ++ if (desc_cnt == haldata->UsbTxAggDescNum) ++ break; ++ } else { ++ desc_cnt = 0; ++ bulkptr = ((pbuf / bulksize) + 1) * bulksize; ++ } ++ } /* end while (aggregate same priority and same DA(AP or STA) frames) */ ++ ++ if (list_empty(&ptxservq->sta_pending.queue)) ++ list_del_init(&ptxservq->tx_pending); ++ ++ spin_unlock_bh(&pxmitpriv->lock); ++ if ((pfirstframe->attrib.ether_type != 0x0806) && ++ (pfirstframe->attrib.ether_type != 0x888e) && ++ (pfirstframe->attrib.ether_type != 0x88b4) && ++ (pfirstframe->attrib.dhcp_pkt != 1)) ++ rtw_issue_addbareq_cmd(adapt, pfirstframe); ++ /* 3 3. update first frame txdesc */ ++ if ((pbuf_tail % bulksize) == 0) { ++ /* remove pkt_offset */ ++ pbuf_tail -= PACKET_OFFSET_SZ; ++ pfirstframe->buf_addr += PACKET_OFFSET_SZ; ++ pfirstframe->pkt_offset--; ++ } ++ ++ update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, true); ++ ++ /* 3 4. write xmit buffer to USB FIFO */ ++ ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe); ++ rtw_write_port(adapt, ff_hwaddr, pbuf_tail, (u8 *)pxmitbuf); ++ ++ /* 3 5. update statisitc */ ++ pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE); ++ pbuf_tail -= (pfirstframe->pkt_offset * PACKET_OFFSET_SZ); ++ ++ rtw_count_tx_stats(adapt, pfirstframe, pbuf_tail); ++ ++ rtw_free_xmitframe(pxmitpriv, pfirstframe); ++ ++ return true; ++} ++ ++static s32 xmitframe_direct(struct adapter *adapt, struct xmit_frame *pxmitframe) ++{ ++ s32 res = _SUCCESS; ++ ++ res = rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe); ++ if (res == _SUCCESS) ++ rtw_dump_xframe(adapt, pxmitframe); ++ else ++ DBG_88E("==> %s xmitframe_coalsece failed\n", __func__); ++ return res; ++} ++ ++/* ++ * Return ++ * true dump packet directly ++ * false enqueue packet ++ */ ++static s32 pre_xmitframe(struct adapter *adapt, struct xmit_frame *pxmitframe) ++{ ++ s32 res; ++ struct xmit_buf *pxmitbuf = NULL; ++ struct xmit_priv *pxmitpriv = &adapt->xmitpriv; ++ struct pkt_attrib *pattrib = &pxmitframe->attrib; ++ struct mlme_priv *pmlmepriv = &adapt->mlmepriv; ++ ++ spin_lock_bh(&pxmitpriv->lock); ++ ++ if (rtw_txframes_sta_ac_pending(adapt, pattrib) > 0) ++ goto enqueue; ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) ++ goto enqueue; ++ ++ pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); ++ if (!pxmitbuf) ++ goto enqueue; ++ ++ spin_unlock_bh(&pxmitpriv->lock); ++ ++ pxmitframe->pxmitbuf = pxmitbuf; ++ pxmitframe->buf_addr = pxmitbuf->pbuf; ++ pxmitbuf->priv_data = pxmitframe; ++ ++ if (xmitframe_direct(adapt, pxmitframe) != _SUCCESS) { ++ rtw_free_xmitbuf(pxmitpriv, pxmitbuf); ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ } ++ ++ return true; ++ ++enqueue: ++ res = rtw_xmitframe_enqueue(adapt, pxmitframe); ++ spin_unlock_bh(&pxmitpriv->lock); ++ ++ if (res != _SUCCESS) { ++ rtw_free_xmitframe(pxmitpriv, pxmitframe); ++ ++ /* Trick, make the statistics correct */ ++ pxmitpriv->tx_pkts--; ++ pxmitpriv->tx_drop++; ++ return true; ++ } ++ ++ return false; ++} ++ ++s32 rtl8188eu_mgnt_xmit(struct adapter *adapt, struct xmit_frame *pmgntframe) ++{ ++ return rtw_dump_xframe(adapt, pmgntframe); ++} ++ ++/* ++ * Return ++ * true dump packet directly ok ++ * false temporary can't transmit packets to hardware ++ */ ++s32 rtl8188eu_hal_xmit(struct adapter *adapt, struct xmit_frame *pxmitframe) ++{ ++ return pre_xmitframe(adapt, pxmitframe); ++} +diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c +new file mode 100644 +index 000000000000..5cdabf43d4fd +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/usb_halinit.c +@@ -0,0 +1,2271 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _HCI_HAL_INIT_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/rtw_efuse.h" ++ ++#include "../include/rtl8188e_hal.h" ++#include "../include/rtl8188e_led.h" ++#include "../include/rtw_iol.h" ++#include "../include/usb_ops.h" ++#include "../include/usb_osintf.h" ++ ++#define HAL_MAC_ENABLE 1 ++#define HAL_BB_ENABLE 1 ++#define HAL_RF_ENABLE 1 ++ ++static void _ConfigNormalChipOutEP_8188E(struct adapter *adapt, u8 NumOutPipe) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ ++ switch (NumOutPipe) { ++ case 3: ++ haldata->OutEpQueueSel = TX_SELE_HQ | TX_SELE_LQ | TX_SELE_NQ; ++ haldata->OutEpNumber = 3; ++ break; ++ case 2: ++ haldata->OutEpQueueSel = TX_SELE_HQ | TX_SELE_NQ; ++ haldata->OutEpNumber = 2; ++ break; ++ case 1: ++ haldata->OutEpQueueSel = TX_SELE_HQ; ++ haldata->OutEpNumber = 1; ++ break; ++ default: ++ break; ++ } ++ DBG_88E("%s OutEpQueueSel(0x%02x), OutEpNumber(%d)\n", __func__, haldata->OutEpQueueSel, haldata->OutEpNumber); ++} ++ ++static bool HalUsbSetQueuePipeMapping8188EUsb(struct adapter *adapt, u8 NumInPipe, u8 NumOutPipe) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ bool result = false; ++ ++ _ConfigNormalChipOutEP_8188E(adapt, NumOutPipe); ++ ++ /* Normal chip with one IN and one OUT doesn't have interrupt IN EP. */ ++ if (1 == haldata->OutEpNumber) { ++ if (1 != NumInPipe) ++ return result; ++ } ++ ++ /* All config other than above support one Bulk IN and one Interrupt IN. */ ++ ++ result = Hal_MappingOutPipe(adapt, NumOutPipe); ++ ++ return result; ++} ++ ++static void rtl8188eu_interface_configure(struct adapter *adapt) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapt); ++ ++ if (pdvobjpriv->ishighspeed) ++ haldata->UsbBulkOutSize = USB_HIGH_SPEED_BULK_SIZE;/* 512 bytes */ ++ else ++ haldata->UsbBulkOutSize = USB_FULL_SPEED_BULK_SIZE;/* 64 bytes */ ++ ++ haldata->interfaceIndex = pdvobjpriv->InterfaceNumber; ++ ++ haldata->UsbTxAggMode = 1; ++ haldata->UsbTxAggDescNum = 0x6; /* only 4 bits */ ++ ++ haldata->UsbRxAggMode = USB_RX_AGG_DMA;/* USB_RX_AGG_DMA; */ ++ haldata->UsbRxAggBlockCount = 8; /* unit : 512b */ ++ haldata->UsbRxAggBlockTimeout = 0x6; ++ haldata->UsbRxAggPageCount = 48; /* uint :128 b 0x0A; 10 = MAX_RX_DMA_BUFFER_SIZE/2/haldata->UsbBulkOutSize */ ++ haldata->UsbRxAggPageTimeout = 0x4; /* 6, absolute time = 34ms/(2^6) */ ++ ++ HalUsbSetQueuePipeMapping8188EUsb(adapt, ++ pdvobjpriv->RtNumInPipes, pdvobjpriv->RtNumOutPipes); ++} ++ ++static u32 rtl8188eu_InitPowerOn(struct adapter *adapt) ++{ ++ u16 value16; ++ /* HW Power on sequence */ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ if (haldata->bMacPwrCtrlOn) ++ return _SUCCESS; ++ ++ if (!HalPwrSeqCmdParsing(adapt, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_PWR_ON_FLOW)) { ++ DBG_88E(KERN_ERR "%s: run power on flow fail\n", __func__); ++ return _FAIL; ++ } ++ ++ /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */ ++ /* Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */ ++ rtw_write16(adapt, REG_CR, 0x00); /* suggseted by zhouzhou, by page, 20111230 */ ++ ++ /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */ ++ value16 = rtw_read16(adapt, REG_CR); ++ value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN ++ | PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN); ++ /* for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */ ++ ++ rtw_write16(adapt, REG_CR, value16); ++ haldata->bMacPwrCtrlOn = true; ++ ++ return _SUCCESS; ++} ++ ++/* Shall USB interface init this? */ ++static void _InitInterrupt(struct adapter *Adapter) ++{ ++ u32 imr, imr_ex; ++ u8 usb_opt; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ /* HISR write one to clear */ ++ rtw_write32(Adapter, REG_HISR_88E, 0xFFFFFFFF); ++ /* HIMR - */ ++ imr = IMR_PSTIMEOUT_88E | IMR_TBDER_88E | IMR_CPWM_88E | IMR_CPWM2_88E; ++ rtw_write32(Adapter, REG_HIMR_88E, imr); ++ haldata->IntrMask[0] = imr; ++ ++ imr_ex = IMR_TXERR_88E | IMR_RXERR_88E | IMR_TXFOVW_88E | IMR_RXFOVW_88E; ++ rtw_write32(Adapter, REG_HIMRE_88E, imr_ex); ++ haldata->IntrMask[1] = imr_ex; ++ ++ /* REG_USB_SPECIAL_OPTION - BIT(4) */ ++ /* 0; Use interrupt endpoint to upload interrupt pkt */ ++ /* 1; Use bulk endpoint to upload interrupt pkt, */ ++ usb_opt = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION); ++ ++ if (!adapter_to_dvobj(Adapter)->ishighspeed) ++ usb_opt = usb_opt & (~INT_BULK_SEL); ++ else ++ usb_opt = usb_opt | (INT_BULK_SEL); ++ ++ rtw_write8(Adapter, REG_USB_SPECIAL_OPTION, usb_opt); ++} ++ ++static void _InitQueueReservedPage(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ struct registry_priv *pregistrypriv = &Adapter->registrypriv; ++ u32 numHQ = 0; ++ u32 numLQ = 0; ++ u32 numNQ = 0; ++ u32 numPubQ; ++ u32 value32; ++ u8 value8; ++ bool bWiFiConfig = pregistrypriv->wifi_spec; ++ ++ if (bWiFiConfig) { ++ if (haldata->OutEpQueueSel & TX_SELE_HQ) ++ numHQ = 0x29; ++ ++ if (haldata->OutEpQueueSel & TX_SELE_LQ) ++ numLQ = 0x1C; ++ ++ /* NOTE: This step shall be proceed before writting REG_RQPN. */ ++ if (haldata->OutEpQueueSel & TX_SELE_NQ) ++ numNQ = 0x1C; ++ value8 = (u8)_NPQ(numNQ); ++ rtw_write8(Adapter, REG_RQPN_NPQ, value8); ++ ++ numPubQ = 0xA8 - numHQ - numLQ - numNQ; ++ ++ /* TX DMA */ ++ value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN; ++ rtw_write32(Adapter, REG_RQPN, value32); ++ } else { ++ rtw_write16(Adapter, REG_RQPN_NPQ, 0x0000);/* Just follow MP Team,??? Georgia 03/28 */ ++ rtw_write16(Adapter, REG_RQPN_NPQ, 0x0d); ++ rtw_write32(Adapter, REG_RQPN, 0x808E000d);/* reserve 7 page for LPS */ ++ } ++} ++ ++static void _InitTxBufferBoundary(struct adapter *Adapter, u8 txpktbuf_bndy) ++{ ++ rtw_write8(Adapter, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); ++ rtw_write8(Adapter, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); ++ rtw_write8(Adapter, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy); ++ rtw_write8(Adapter, REG_TRXFF_BNDY, txpktbuf_bndy); ++ rtw_write8(Adapter, REG_TDECTRL + 1, txpktbuf_bndy); ++} ++ ++static void _InitPageBoundary(struct adapter *Adapter) ++{ ++ /* RX Page Boundary */ ++ /* */ ++ u16 rxff_bndy = MAX_RX_DMA_BUFFER_SIZE_88E - 1; ++ ++ rtw_write16(Adapter, (REG_TRXFF_BNDY + 2), rxff_bndy); ++} ++ ++static void _InitNormalChipRegPriority(struct adapter *Adapter, u16 beQ, ++ u16 bkQ, u16 viQ, u16 voQ, u16 mgtQ, ++ u16 hiQ) ++{ ++ u16 value16 = (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7); ++ ++ value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) | ++ _TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) | ++ _TXDMA_MGQ_MAP(mgtQ) | _TXDMA_HIQ_MAP(hiQ); ++ ++ rtw_write16(Adapter, REG_TRXDMA_CTRL, value16); ++} ++ ++static void _InitNormalChipOneOutEpPriority(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ u16 value = 0; ++ switch (haldata->OutEpQueueSel) { ++ case TX_SELE_HQ: ++ value = QUEUE_HIGH; ++ break; ++ case TX_SELE_LQ: ++ value = QUEUE_LOW; ++ break; ++ case TX_SELE_NQ: ++ value = QUEUE_NORMAL; ++ break; ++ default: ++ break; ++ } ++ _InitNormalChipRegPriority(Adapter, value, value, value, value, ++ value, value); ++} ++ ++static void _InitNormalChipTwoOutEpPriority(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ struct registry_priv *pregistrypriv = &Adapter->registrypriv; ++ u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ; ++ u16 valueHi = 0; ++ u16 valueLow = 0; ++ ++ switch (haldata->OutEpQueueSel) { ++ case (TX_SELE_HQ | TX_SELE_LQ): ++ valueHi = QUEUE_HIGH; ++ valueLow = QUEUE_LOW; ++ break; ++ case (TX_SELE_NQ | TX_SELE_LQ): ++ valueHi = QUEUE_NORMAL; ++ valueLow = QUEUE_LOW; ++ break; ++ case (TX_SELE_HQ | TX_SELE_NQ): ++ valueHi = QUEUE_HIGH; ++ valueLow = QUEUE_NORMAL; ++ break; ++ default: ++ break; ++ } ++ ++ if (!pregistrypriv->wifi_spec) { ++ beQ = valueLow; ++ bkQ = valueLow; ++ viQ = valueHi; ++ voQ = valueHi; ++ mgtQ = valueHi; ++ hiQ = valueHi; ++ } else {/* for WMM ,CONFIG_OUT_EP_WIFI_MODE */ ++ beQ = valueLow; ++ bkQ = valueHi; ++ viQ = valueHi; ++ voQ = valueLow; ++ mgtQ = valueHi; ++ hiQ = valueHi; ++ } ++ _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ); ++} ++ ++static void _InitNormalChipThreeOutEpPriority(struct adapter *Adapter) ++{ ++ struct registry_priv *pregistrypriv = &Adapter->registrypriv; ++ u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ; ++ ++ if (!pregistrypriv->wifi_spec) {/* typical setting */ ++ beQ = QUEUE_LOW; ++ bkQ = QUEUE_LOW; ++ viQ = QUEUE_NORMAL; ++ voQ = QUEUE_HIGH; ++ mgtQ = QUEUE_HIGH; ++ hiQ = QUEUE_HIGH; ++ } else {/* for WMM */ ++ beQ = QUEUE_LOW; ++ bkQ = QUEUE_NORMAL; ++ viQ = QUEUE_NORMAL; ++ voQ = QUEUE_HIGH; ++ mgtQ = QUEUE_HIGH; ++ hiQ = QUEUE_HIGH; ++ } ++ _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ); ++} ++ ++static void _InitQueuePriority(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ switch (haldata->OutEpNumber) { ++ case 1: ++ _InitNormalChipOneOutEpPriority(Adapter); ++ break; ++ case 2: ++ _InitNormalChipTwoOutEpPriority(Adapter); ++ break; ++ case 3: ++ _InitNormalChipThreeOutEpPriority(Adapter); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void _InitNetworkType(struct adapter *Adapter) ++{ ++ u32 value32; ++ ++ value32 = rtw_read32(Adapter, REG_CR); ++ /* TODO: use the other function to set network type */ ++ value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP); ++ ++ rtw_write32(Adapter, REG_CR, value32); ++} ++ ++static void _InitTransferPageSize(struct adapter *Adapter) ++{ ++ /* Tx page size is always 128. */ ++ ++ u8 value8; ++ value8 = _PSRX(PBP_128) | _PSTX(PBP_128); ++ rtw_write8(Adapter, REG_PBP, value8); ++} ++ ++static void _InitDriverInfoSize(struct adapter *Adapter, u8 drvInfoSize) ++{ ++ rtw_write8(Adapter, REG_RX_DRVINFO_SZ, drvInfoSize); ++} ++ ++static void _InitWMACSetting(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ haldata->ReceiveConfig = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | ++ RCR_CBSSID_DATA | RCR_CBSSID_BCN | ++ RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL | ++ RCR_APP_MIC | RCR_APP_PHYSTS; ++ ++ /* some REG_RCR will be modified later by phy_ConfigMACWithHeaderFile() */ ++ rtw_write32(Adapter, REG_RCR, haldata->ReceiveConfig); ++ ++ /* Accept all multicast address */ ++ rtw_write32(Adapter, REG_MAR, 0xFFFFFFFF); ++ rtw_write32(Adapter, REG_MAR + 4, 0xFFFFFFFF); ++} ++ ++static void _InitAdaptiveCtrl(struct adapter *Adapter) ++{ ++ u16 value16; ++ u32 value32; ++ ++ /* Response Rate Set */ ++ value32 = rtw_read32(Adapter, REG_RRSR); ++ value32 &= ~RATE_BITMAP_ALL; ++ value32 |= RATE_RRSR_CCK_ONLY_1M; ++ rtw_write32(Adapter, REG_RRSR, value32); ++ ++ /* CF-END Threshold */ ++ ++ /* SIFS (used in NAV) */ ++ value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10); ++ rtw_write16(Adapter, REG_SPEC_SIFS, value16); ++ ++ /* Retry Limit */ ++ value16 = _LRL(0x30) | _SRL(0x30); ++ rtw_write16(Adapter, REG_RL, value16); ++} ++ ++static void _InitEDCA(struct adapter *Adapter) ++{ ++ /* Set Spec SIFS (used in NAV) */ ++ rtw_write16(Adapter, REG_SPEC_SIFS, 0x100a); ++ rtw_write16(Adapter, REG_MAC_SPEC_SIFS, 0x100a); ++ ++ /* Set SIFS for CCK */ ++ rtw_write16(Adapter, REG_SIFS_CTX, 0x100a); ++ ++ /* Set SIFS for OFDM */ ++ rtw_write16(Adapter, REG_SIFS_TRX, 0x100a); ++ ++ /* TXOP */ ++ rtw_write32(Adapter, REG_EDCA_BE_PARAM, 0x005EA42B); ++ rtw_write32(Adapter, REG_EDCA_BK_PARAM, 0x0000A44F); ++ rtw_write32(Adapter, REG_EDCA_VI_PARAM, 0x005EA324); ++ rtw_write32(Adapter, REG_EDCA_VO_PARAM, 0x002FA226); ++} ++ ++static void _InitBeaconMaxError(struct adapter *Adapter, bool InfraMode) ++{ ++} ++ ++static void _InitHWLed(struct adapter *Adapter) ++{ ++ struct led_priv *pledpriv = &Adapter->ledpriv; ++ ++ if (pledpriv->LedStrategy != HW_LED) ++ return; ++ ++/* HW led control */ ++/* to do .... */ ++/* must consider cases of antenna diversity/ commbo card/solo card/mini card */ ++} ++ ++static void _InitRDGSetting(struct adapter *Adapter) ++{ ++ rtw_write8(Adapter, REG_RD_CTRL, 0xFF); ++ rtw_write16(Adapter, REG_RD_NAV_NXT, 0x200); ++ rtw_write8(Adapter, REG_RD_RESP_PKT_TH, 0x05); ++} ++ ++static void _InitRxSetting(struct adapter *Adapter) ++{ ++ rtw_write32(Adapter, REG_MACID, 0x87654321); ++ rtw_write32(Adapter, 0x0700, 0x87654321); ++} ++ ++static void _InitRetryFunction(struct adapter *Adapter) ++{ ++ u8 value8; ++ ++ value8 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL); ++ value8 |= EN_AMPDU_RTY_NEW; ++ rtw_write8(Adapter, REG_FWHW_TXQ_CTRL, value8); ++ ++ /* Set ACK timeout */ ++ rtw_write8(Adapter, REG_ACKTO, 0x40); ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: usb_AggSettingTxUpdate() ++ * ++ * Overview: Separate TX/RX parameters update independent for TP detection and ++ * dynamic TX/RX aggreagtion parameters update. ++ * ++ * Input: struct adapter * ++ * ++ * Output/Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 12/10/2010 MHC Separate to smaller function. ++ * ++ *---------------------------------------------------------------------------*/ ++static void usb_AggSettingTxUpdate(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ u32 value32; ++ ++ if (Adapter->registrypriv.wifi_spec) ++ haldata->UsbTxAggMode = false; ++ ++ if (haldata->UsbTxAggMode) { ++ value32 = rtw_read32(Adapter, REG_TDECTRL); ++ value32 = value32 & ~(BLK_DESC_NUM_MASK << BLK_DESC_NUM_SHIFT); ++ value32 |= ((haldata->UsbTxAggDescNum & BLK_DESC_NUM_MASK) << BLK_DESC_NUM_SHIFT); ++ ++ rtw_write32(Adapter, REG_TDECTRL, value32); ++ } ++} /* usb_AggSettingTxUpdate */ ++ ++/*----------------------------------------------------------------------------- ++ * Function: usb_AggSettingRxUpdate() ++ * ++ * Overview: Separate TX/RX parameters update independent for TP detection and ++ * dynamic TX/RX aggreagtion parameters update. ++ * ++ * Input: struct adapter * ++ * ++ * Output/Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 12/10/2010 MHC Separate to smaller function. ++ * ++ *---------------------------------------------------------------------------*/ ++static void ++usb_AggSettingRxUpdate( ++ struct adapter *Adapter ++ ) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ u8 valueDMA; ++ u8 valueUSB; ++ ++ valueDMA = rtw_read8(Adapter, REG_TRXDMA_CTRL); ++ valueUSB = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION); ++ ++ switch (haldata->UsbRxAggMode) { ++ case USB_RX_AGG_DMA: ++ valueDMA |= RXDMA_AGG_EN; ++ valueUSB &= ~USB_AGG_EN; ++ break; ++ case USB_RX_AGG_USB: ++ valueDMA &= ~RXDMA_AGG_EN; ++ valueUSB |= USB_AGG_EN; ++ break; ++ case USB_RX_AGG_MIX: ++ valueDMA |= RXDMA_AGG_EN; ++ valueUSB |= USB_AGG_EN; ++ break; ++ case USB_RX_AGG_DISABLE: ++ default: ++ valueDMA &= ~RXDMA_AGG_EN; ++ valueUSB &= ~USB_AGG_EN; ++ break; ++ } ++ ++ rtw_write8(Adapter, REG_TRXDMA_CTRL, valueDMA); ++ rtw_write8(Adapter, REG_USB_SPECIAL_OPTION, valueUSB); ++ ++ switch (haldata->UsbRxAggMode) { ++ case USB_RX_AGG_DMA: ++ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, haldata->UsbRxAggPageCount); ++ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH + 1, haldata->UsbRxAggPageTimeout); ++ break; ++ case USB_RX_AGG_USB: ++ rtw_write8(Adapter, REG_USB_AGG_TH, haldata->UsbRxAggBlockCount); ++ rtw_write8(Adapter, REG_USB_AGG_TO, haldata->UsbRxAggBlockTimeout); ++ break; ++ case USB_RX_AGG_MIX: ++ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, haldata->UsbRxAggPageCount); ++ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH + 1, (haldata->UsbRxAggPageTimeout & 0x1F));/* 0x280[12:8] */ ++ rtw_write8(Adapter, REG_USB_AGG_TH, haldata->UsbRxAggBlockCount); ++ rtw_write8(Adapter, REG_USB_AGG_TO, haldata->UsbRxAggBlockTimeout); ++ break; ++ case USB_RX_AGG_DISABLE: ++ default: ++ /* TODO: */ ++ break; ++ } ++ ++ switch (PBP_128) { ++ case PBP_128: ++ haldata->HwRxPageSize = 128; ++ break; ++ case PBP_64: ++ haldata->HwRxPageSize = 64; ++ break; ++ case PBP_256: ++ haldata->HwRxPageSize = 256; ++ break; ++ case PBP_512: ++ haldata->HwRxPageSize = 512; ++ break; ++ case PBP_1024: ++ haldata->HwRxPageSize = 1024; ++ break; ++ default: ++ break; ++ } ++} /* usb_AggSettingRxUpdate */ ++ ++static void InitUsbAggregationSetting(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ /* Tx aggregation setting */ ++ usb_AggSettingTxUpdate(Adapter); ++ ++ /* Rx aggregation setting */ ++ usb_AggSettingRxUpdate(Adapter); ++ ++ /* 201/12/10 MH Add for USB agg mode dynamic switch. */ ++ haldata->UsbRxHighSpeedMode = false; ++} ++ ++static void _InitOperationMode(struct adapter *Adapter) ++{ ++} ++ ++static void _InitBeaconParameters(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ rtw_write16(Adapter, REG_BCN_CTRL, 0x1010); ++ ++ /* TODO: Remove these magic number */ ++ rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0x6404);/* ms */ ++ rtw_write8(Adapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);/* 5ms */ ++ rtw_write8(Adapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); /* 2ms */ ++ ++ /* Suggested by designer timchen. Change beacon AIFS to the largest number */ ++ /* beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */ ++ rtw_write16(Adapter, REG_BCNTCFG, 0x660F); ++ ++ haldata->RegBcnCtrlVal = rtw_read8(Adapter, REG_BCN_CTRL); ++ haldata->RegTxPause = rtw_read8(Adapter, REG_TXPAUSE); ++ haldata->RegFwHwTxQCtrl = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2); ++ haldata->RegReg542 = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2); ++ haldata->RegCR_1 = rtw_read8(Adapter, REG_CR + 1); ++} ++ ++static void _BeaconFunctionEnable(struct adapter *Adapter, ++ bool Enable, bool Linked) ++{ ++ rtw_write8(Adapter, REG_BCN_CTRL, (BIT(4) | BIT(3) | BIT(1))); ++ ++ rtw_write8(Adapter, REG_RD_CTRL + 1, 0x6F); ++} ++ ++/* Set CCK and OFDM Block "ON" */ ++static void _BBTurnOnBlock(struct adapter *Adapter) ++{ ++ PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bCCKEn, 0x1); ++ PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bOFDMEn, 0x1); ++} ++ ++enum { ++ Antenna_Lfet = 1, ++ Antenna_Right = 2, ++}; ++ ++static void _InitAntenna_Selection(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ if (haldata->AntDivCfg == 0) ++ return; ++ DBG_88E("==> %s ....\n", __func__); ++ ++ rtw_write32(Adapter, REG_LEDCFG0, rtw_read32(Adapter, REG_LEDCFG0) | BIT(23)); ++ PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, BIT(13), 0x01); ++ ++ if (PHY_QueryBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300) == Antenna_A) ++ haldata->CurAntenna = Antenna_A; ++ else ++ haldata->CurAntenna = Antenna_B; ++ DBG_88E("%s,Cur_ant:(%x)%s\n", __func__, haldata->CurAntenna, (haldata->CurAntenna == Antenna_A) ? "Antenna_A" : "Antenna_B"); ++} ++ ++/*----------------------------------------------------------------------------- ++ * Function: HwSuspendModeEnable92Cu() ++ * ++ * Overview: HW suspend mode switch. ++ * ++ * Input: NONE ++ * ++ * Output: NONE ++ * ++ * Return: NONE ++ * ++ * Revised History: ++ * When Who Remark ++ * 08/23/2010 MHC HW suspend mode switch test.. ++ *---------------------------------------------------------------------------*/ ++enum rt_rf_power_state RfOnOffDetect(struct adapter *adapt) ++{ ++ u8 val8; ++ enum rt_rf_power_state rfpowerstate = rf_off; ++ ++ if (adapt->pwrctrlpriv.bHWPowerdown) { ++ val8 = rtw_read8(adapt, REG_HSISR); ++ DBG_88E("pwrdown, 0x5c(BIT(7))=%02x\n", val8); ++ rfpowerstate = (val8 & BIT(7)) ? rf_off : rf_on; ++ } else { /* rf on/off */ ++ rtw_write8(adapt, REG_MAC_PINMUX_CFG, rtw_read8(adapt, REG_MAC_PINMUX_CFG) & ~(BIT(3))); ++ val8 = rtw_read8(adapt, REG_GPIO_IO_SEL); ++ DBG_88E("GPIO_IN=%02x\n", val8); ++ rfpowerstate = (val8 & BIT(3)) ? rf_on : rf_off; ++ } ++ return rfpowerstate; ++} /* HalDetectPwrDownMode */ ++ ++static u32 rtl8188eu_hal_init(struct adapter *Adapter) ++{ ++ u8 value8 = 0; ++ u16 value16; ++ u8 txpktbuf_bndy; ++ u32 status = _SUCCESS; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv; ++ struct registry_priv *pregistrypriv = &Adapter->registrypriv; ++ u32 init_start_time = jiffies; ++ ++ #define HAL_INIT_PROFILE_TAG(stage) do {} while (0) ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BEGIN); ++ ++ if (Adapter->pwrctrlpriv.bkeepfwalive) { ++ _ps_open_RF(Adapter); ++ ++ if (haldata->odmpriv.RFCalibrateInfo.bIQKInitialized) { ++ PHY_IQCalibrate_8188E(Adapter, true); ++ } else { ++ PHY_IQCalibrate_8188E(Adapter, false); ++ haldata->odmpriv.RFCalibrateInfo.bIQKInitialized = true; ++ } ++ ++ ODM_TXPowerTrackingCheck(&haldata->odmpriv); ++ PHY_LCCalibrate_8188E(Adapter); ++ ++ goto exit; ++ } ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PW_ON); ++ status = rtl8188eu_InitPowerOn(Adapter); ++ if (status == _FAIL) ++ goto exit; ++ ++ /* Save target channel */ ++ haldata->CurrentChannel = 6;/* default set to 6 */ ++ ++ if (pwrctrlpriv->reg_rfoff) { ++ pwrctrlpriv->rf_pwrstate = rf_off; ++ } ++ ++ /* 2010/08/09 MH We need to check if we need to turnon or off RF after detecting */ ++ /* HW GPIO pin. Before PHY_RFConfig8192C. */ ++ /* 2010/08/26 MH If Efuse does not support sective suspend then disable the function. */ ++ ++ if (!pregistrypriv->wifi_spec) { ++ txpktbuf_bndy = TX_PAGE_BOUNDARY_88E; ++ } else { ++ /* for WMM */ ++ txpktbuf_bndy = WMM_NORMAL_TX_PAGE_BOUNDARY_88E; ++ } ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC01); ++ _InitQueueReservedPage(Adapter); ++ _InitQueuePriority(Adapter); ++ _InitPageBoundary(Adapter); ++ _InitTransferPageSize(Adapter); ++ ++ _InitTxBufferBoundary(Adapter, 0); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_DOWNLOAD_FW); ++ if (Adapter->registrypriv.mp_mode == 1) { ++ _InitRxSetting(Adapter); ++ Adapter->bFWReady = false; ++ haldata->fw_ractrl = false; ++ } else { ++ status = rtl8188e_FirmwareDownload(Adapter); ++ ++ if (status != _SUCCESS) { ++ DBG_88E("%s: Download Firmware failed!!\n", __func__); ++ Adapter->bFWReady = false; ++ haldata->fw_ractrl = false; ++ return status; ++ } else { ++ Adapter->bFWReady = true; ++ haldata->fw_ractrl = false; ++ } ++ } ++ rtl8188e_InitializeFirmwareVars(Adapter); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MAC); ++#if (HAL_MAC_ENABLE == 1) ++ status = PHY_MACConfig8188E(Adapter); ++ if (status == _FAIL) { ++ DBG_88E(" ### Failed to init MAC ......\n "); ++ goto exit; ++ } ++#endif ++ ++ /* */ ++ /* d. Initialize BB related configurations. */ ++ /* */ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BB); ++#if (HAL_BB_ENABLE == 1) ++ status = PHY_BBConfig8188E(Adapter); ++ if (status == _FAIL) { ++ DBG_88E(" ### Failed to init BB ......\n "); ++ goto exit; ++ } ++#endif ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_RF); ++#if (HAL_RF_ENABLE == 1) ++ status = PHY_RFConfig8188E(Adapter); ++ if (status == _FAIL) { ++ DBG_88E(" ### Failed to init RF ......\n "); ++ goto exit; ++ } ++#endif ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_EFUSE_PATCH); ++ status = rtl8188e_iol_efuse_patch(Adapter); ++ if (status == _FAIL) { ++ DBG_88E("%s rtl8188e_iol_efuse_patch failed\n", __func__); ++ goto exit; ++ } ++ ++ _InitTxBufferBoundary(Adapter, txpktbuf_bndy); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_LLTT); ++ status = InitLLTTable(Adapter, txpktbuf_bndy); ++ if (status == _FAIL) ++ goto exit; ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC02); ++ /* Get Rx PHY status in order to report RSSI and others. */ ++ _InitDriverInfoSize(Adapter, DRVINFO_SZ); ++ ++ _InitInterrupt(Adapter); ++ hal_init_macaddr(Adapter);/* set mac_address */ ++ _InitNetworkType(Adapter);/* set msr */ ++ _InitWMACSetting(Adapter); ++ _InitAdaptiveCtrl(Adapter); ++ _InitEDCA(Adapter); ++ _InitRetryFunction(Adapter); ++ InitUsbAggregationSetting(Adapter); ++ _InitOperationMode(Adapter);/* todo */ ++ _InitBeaconParameters(Adapter); ++ _InitBeaconMaxError(Adapter, true); ++ ++ /* */ ++ /* Init CR MACTXEN, MACRXEN after setting RxFF boundary REG_TRXFF_BNDY to patch */ ++ /* Hw bug which Hw initials RxFF boundary size to a value which is larger than the real Rx buffer size in 88E. */ ++ /* */ ++ /* Enable MACTXEN/MACRXEN block */ ++ value16 = rtw_read16(Adapter, REG_CR); ++ value16 |= (MACTXEN | MACRXEN); ++ rtw_write8(Adapter, REG_CR, value16); ++ ++ if (haldata->bRDGEnable) ++ _InitRDGSetting(Adapter); ++ ++ /* Enable TX Report */ ++ /* Enable Tx Report Timer */ ++ value8 = rtw_read8(Adapter, REG_TX_RPT_CTRL); ++ rtw_write8(Adapter, REG_TX_RPT_CTRL, (value8 | BIT(1) | BIT(0))); ++ /* Set MAX RPT MACID */ ++ rtw_write8(Adapter, REG_TX_RPT_CTRL + 1, 2);/* FOR sta mode ,0: bc/mc ,1:AP */ ++ /* Tx RPT Timer. Unit: 32us */ ++ rtw_write16(Adapter, REG_TX_RPT_TIME, 0xCdf0); ++ ++ rtw_write8(Adapter, REG_EARLY_MODE_CONTROL, 0); ++ ++ rtw_write16(Adapter, REG_PKT_VO_VI_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */ ++ rtw_write16(Adapter, REG_PKT_BE_BK_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */ ++ ++ _InitHWLed(Adapter); ++ ++ /* Keep RfRegChnlVal for later use. */ ++ haldata->RfRegChnlVal[0] = PHY_QueryRFReg(Adapter, (enum rf_radio_path)0, RF_CHNLBW, bRFRegOffsetMask); ++ haldata->RfRegChnlVal[1] = PHY_QueryRFReg(Adapter, (enum rf_radio_path)1, RF_CHNLBW, bRFRegOffsetMask); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_TURN_ON_BLOCK); ++ _BBTurnOnBlock(Adapter); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_SECURITY); ++ invalidate_cam_all(Adapter); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC11); ++ /* 2010/12/17 MH We need to set TX power according to EFUSE content at first. */ ++ PHY_SetTxPowerLevel8188E(Adapter, haldata->CurrentChannel); ++ ++/* Move by Neo for USB SS to below setp */ ++/* _RfPowerSave(Adapter); */ ++ ++ _InitAntenna_Selection(Adapter); ++ ++ /* */ ++ /* Disable BAR, suggested by Scott */ ++ /* 2010.04.09 add by hpfan */ ++ /* */ ++ rtw_write32(Adapter, REG_BAR_MODE_CTRL, 0x0201ffff); ++ ++ /* HW SEQ CTRL */ ++ /* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */ ++ rtw_write8(Adapter, REG_HWSEQ_CTRL, 0xFF); ++ ++ if (pregistrypriv->wifi_spec) ++ rtw_write16(Adapter, REG_FAST_EDCA_CTRL, 0); ++ ++ /* Nav limit , suggest by scott */ ++ rtw_write8(Adapter, 0x652, 0x0); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_HAL_DM); ++ rtl8188e_InitHalDm(Adapter); ++ ++ if (Adapter->registrypriv.mp_mode == 1) { ++ Adapter->mppriv.channel = haldata->CurrentChannel; ++ MPT_InitializeAdapter(Adapter, Adapter->mppriv.channel); ++ } else { ++ /* 2010/08/11 MH Merge from 8192SE for Minicard init. We need to confirm current radio status */ ++ /* and then decide to enable RF or not.!!!??? For Selective suspend mode. We may not */ ++ /* call initstruct adapter. May cause some problem?? */ ++ /* Fix the bug that Hw/Sw radio off before S3/S4, the RF off action will not be executed */ ++ /* in MgntActSet_RF_State() after wake up, because the value of haldata->eRFPowerState */ ++ /* is the same as eRfOff, we should change it to eRfOn after we config RF parameters. */ ++ /* Added by tynli. 2010.03.30. */ ++ pwrctrlpriv->rf_pwrstate = rf_on; ++ ++ /* enable Tx report. */ ++ rtw_write8(Adapter, REG_FWHW_TXQ_CTRL + 1, 0x0F); ++ ++ /* Suggested by SD1 pisa. Added by tynli. 2011.10.21. */ ++ rtw_write8(Adapter, REG_EARLY_MODE_CONTROL + 3, 0x01);/* Pretx_en, for WEP/TKIP SEC */ ++ ++ /* tynli_test_tx_report. */ ++ rtw_write16(Adapter, REG_TX_RPT_TIME, 0x3DF0); ++ ++ /* enable tx DMA to drop the redundate data of packet */ ++ rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK) | DROP_DATA_EN)); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK); ++ /* 2010/08/26 MH Merge from 8192CE. */ ++ if (pwrctrlpriv->rf_pwrstate == rf_on) { ++ if (haldata->odmpriv.RFCalibrateInfo.bIQKInitialized) { ++ PHY_IQCalibrate_8188E(Adapter, true); ++ } else { ++ PHY_IQCalibrate_8188E(Adapter, false); ++ haldata->odmpriv.RFCalibrateInfo.bIQKInitialized = true; ++ } ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_PW_TRACK); ++ ++ ODM_TXPowerTrackingCheck(&haldata->odmpriv); ++ ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_LCK); ++ PHY_LCCalibrate_8188E(Adapter); ++ } ++ } ++ ++/* HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PABIAS); */ ++/* _InitPABias(Adapter); */ ++ rtw_write8(Adapter, REG_USB_HRPWM, 0); ++ ++ /* ack for xmit mgmt frames. */ ++ rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, rtw_read32(Adapter, REG_FWHW_TXQ_CTRL) | BIT(12)); ++ ++exit: ++ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END); ++ ++ DBG_88E("%s in %dms\n", __func__, rtw_get_passing_time_ms(init_start_time)); ++ ++ return status; ++} ++ ++void _ps_open_RF(struct adapter *adapt) ++{ ++ /* here call with bRegSSPwrLvl 1, bRegSSPwrLvl 2 needs to be verified */ ++ /* phy_SsPwrSwitch92CU(adapt, rf_on, 1); */ ++} ++ ++static void _ps_close_RF(struct adapter *adapt) ++{ ++ /* here call with bRegSSPwrLvl 1, bRegSSPwrLvl 2 needs to be verified */ ++ /* phy_SsPwrSwitch92CU(adapt, rf_off, 1); */ ++} ++ ++static void CardDisableRTL8188EU(struct adapter *Adapter) ++{ ++ u8 val8; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ /* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */ ++ val8 = rtw_read8(Adapter, REG_TX_RPT_CTRL); ++ rtw_write8(Adapter, REG_TX_RPT_CTRL, val8 & (~BIT(1))); ++ ++ /* stop rx */ ++ rtw_write8(Adapter, REG_CR, 0x0); ++ ++ /* Run LPS WL RFOFF flow */ ++ HalPwrSeqCmdParsing(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_LPS_ENTER_FLOW); ++ ++ /* 2. 0x1F[7:0] = 0 turn off RF */ ++ ++ val8 = rtw_read8(Adapter, REG_MCUFWDL); ++ if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */ ++ /* Reset MCU 0x2[10]=0. */ ++ val8 = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1); ++ val8 &= ~BIT(2); /* 0x2[10], FEN_CPUEN */ ++ rtw_write8(Adapter, REG_SYS_FUNC_EN + 1, val8); ++ } ++ ++ /* reset MCU ready status */ ++ rtw_write8(Adapter, REG_MCUFWDL, 0); ++ ++ /* YJ,add,111212 */ ++ /* Disable 32k */ ++ val8 = rtw_read8(Adapter, REG_32K_CTRL); ++ rtw_write8(Adapter, REG_32K_CTRL, val8 & (~BIT(0))); ++ ++ /* Card disable power action flow */ ++ HalPwrSeqCmdParsing(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_DISABLE_FLOW); ++ ++ /* Reset MCU IO Wrapper */ ++ val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1); ++ rtw_write8(Adapter, REG_RSV_CTRL + 1, (val8 & (~BIT(3)))); ++ val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1); ++ rtw_write8(Adapter, REG_RSV_CTRL + 1, val8 | BIT(3)); ++ ++ /* YJ,test add, 111207. For Power Consumption. */ ++ val8 = rtw_read8(Adapter, GPIO_IN); ++ rtw_write8(Adapter, GPIO_OUT, val8); ++ rtw_write8(Adapter, GPIO_IO_SEL, 0xFF);/* Reg0x46 */ ++ ++ val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL); ++ rtw_write8(Adapter, REG_GPIO_IO_SEL, (val8 << 4)); ++ val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1); ++ rtw_write8(Adapter, REG_GPIO_IO_SEL + 1, val8 | 0x0F);/* Reg0x43 */ ++ rtw_write32(Adapter, REG_BB_PAD_CTRL, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */ ++ haldata->bMacPwrCtrlOn = false; ++ Adapter->bFWReady = false; ++} ++static void rtl8192cu_hw_power_down(struct adapter *adapt) ++{ ++ /* 2010/-8/09 MH For power down module, we need to enable register block contrl reg at 0x1c. */ ++ /* Then enable power down control bit of register 0x04 BIT(4) and BIT(15) as 1. */ ++ ++ /* Enable register area 0x0-0xc. */ ++ rtw_write8(adapt, REG_RSV_CTRL, 0x0); ++ rtw_write16(adapt, REG_APS_FSMCO, 0x8812); ++} ++ ++static u32 rtl8188eu_hal_deinit(struct adapter *Adapter) ++{ ++ ++ DBG_88E("==> %s\n", __func__); ++ ++ rtw_write32(Adapter, REG_HIMR_88E, IMR_DISABLED_88E); ++ rtw_write32(Adapter, REG_HIMRE_88E, IMR_DISABLED_88E); ++ ++ DBG_88E("bkeepfwalive(%x)\n", Adapter->pwrctrlpriv.bkeepfwalive); ++ if (Adapter->pwrctrlpriv.bkeepfwalive) { ++ _ps_close_RF(Adapter); ++ if ((Adapter->pwrctrlpriv.bHWPwrPindetect) && (Adapter->pwrctrlpriv.bHWPowerdown)) ++ rtl8192cu_hw_power_down(Adapter); ++ } else { ++ if (Adapter->hw_init_completed) { ++ CardDisableRTL8188EU(Adapter); ++ ++ if ((Adapter->pwrctrlpriv.bHWPwrPindetect) && (Adapter->pwrctrlpriv.bHWPowerdown)) ++ rtl8192cu_hw_power_down(Adapter); ++ } ++ } ++ return _SUCCESS; ++ } ++ ++static unsigned int rtl8188eu_inirp_init(struct adapter *Adapter) ++{ ++ u8 i; ++ struct recv_buf *precvbuf; ++ uint status; ++ struct intf_hdl *pintfhdl = &Adapter->iopriv.intf; ++ struct recv_priv *precvpriv = &Adapter->recvpriv; ++ u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); ++ ++ _read_port = pintfhdl->io_ops._read_port; ++ ++ status = _SUCCESS; ++ ++ precvpriv->ff_hwaddr = RECV_BULK_IN_ADDR; ++ ++ /* issue Rx irp to receive data */ ++ precvbuf = (struct recv_buf *)precvpriv->precv_buf; ++ for (i = 0; i < NR_RECVBUFF; i++) { ++ if (!_read_port(pintfhdl, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf)) { ++ status = _FAIL; ++ goto exit; ++ } ++ ++ precvbuf++; ++ precvpriv->free_recv_buf_queue_cnt--; ++ } ++ ++exit: ++ return status; ++} ++ ++static unsigned int rtl8188eu_inirp_deinit(struct adapter *Adapter) ++{ ++ rtw_read_port_cancel(Adapter); ++ ++ return _SUCCESS; ++} ++ ++/* */ ++/* */ ++/* EEPROM/EFUSE Content Parsing */ ++/* */ ++/* */ ++static void _ReadLEDSetting(struct adapter *Adapter, u8 *PROMContent, bool AutoloadFail) ++{ ++ struct led_priv *pledpriv = &Adapter->ledpriv; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ pledpriv->bRegUseLed = true; ++ pledpriv->LedStrategy = SW_LED_MODE1; ++ haldata->bLedOpenDrain = true;/* Support Open-drain arrangement for controlling the LED. */ ++} ++ ++static void Hal_EfuseParsePIDVID_8188EU(struct adapter *adapt, u8 *hwinfo, bool AutoLoadFail) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ ++ if (!AutoLoadFail) { ++ /* VID, PID */ ++ haldata->EEPROMVID = EF2BYTE(*(__le16 *)&hwinfo[EEPROM_VID_88EU]); ++ haldata->EEPROMPID = EF2BYTE(*(__le16 *)&hwinfo[EEPROM_PID_88EU]); ++ ++ /* Customer ID, 0x00 and 0xff are reserved for Realtek. */ ++ haldata->EEPROMCustomerID = *(u8 *)&hwinfo[EEPROM_CUSTOMERID_88E]; ++ haldata->EEPROMSubCustomerID = EEPROM_Default_SubCustomerID; ++ } else { ++ haldata->EEPROMVID = EEPROM_Default_VID; ++ haldata->EEPROMPID = EEPROM_Default_PID; ++ ++ /* Customer ID, 0x00 and 0xff are reserved for Realtek. */ ++ haldata->EEPROMCustomerID = EEPROM_Default_CustomerID; ++ haldata->EEPROMSubCustomerID = EEPROM_Default_SubCustomerID; ++ } ++ ++ DBG_88E("VID = 0x%04X, PID = 0x%04X\n", haldata->EEPROMVID, haldata->EEPROMPID); ++ DBG_88E("Customer ID: 0x%02X, SubCustomer ID: 0x%02X\n", haldata->EEPROMCustomerID, haldata->EEPROMSubCustomerID); ++} ++ ++static void Hal_EfuseParseMACAddr_8188EU(struct adapter *adapt, u8 *hwinfo, bool AutoLoadFail) ++{ ++ u16 i; ++ u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x88, 0x02}; ++ struct eeprom_priv *eeprom = GET_EEPROM_EFUSE_PRIV(adapt); ++ ++ if (AutoLoadFail) { ++ for (i = 0; i < 6; i++) ++ eeprom->mac_addr[i] = sMacAddr[i]; ++ } else { ++ /* Read Permanent MAC address */ ++ memcpy(eeprom->mac_addr, &hwinfo[EEPROM_MAC_ADDR_88EU], ETH_ALEN); ++ } ++} ++ ++static void Hal_CustomizeByCustomerID_8188EU(struct adapter *adapt) ++{ ++} ++ ++static void ++readAdapterInfo_8188EU( ++ struct adapter *adapt ++ ) ++{ ++ struct eeprom_priv *eeprom = GET_EEPROM_EFUSE_PRIV(adapt); ++ ++ /* parse the eeprom/efuse content */ ++ Hal_EfuseParseIDCode88E(adapt, eeprom->efuse_eeprom_data); ++ Hal_EfuseParsePIDVID_8188EU(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_EfuseParseMACAddr_8188EU(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ ++ Hal_ReadPowerSavingMode88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_ReadTxPowerInfo88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_EfuseParseEEPROMVer88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ rtl8188e_EfuseParseChnlPlan(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_EfuseParseXtal_8188E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_EfuseParseCustomerID88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_ReadAntennaDiversity88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_EfuseParseBoardType88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ Hal_ReadThermalMeter_88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++ ++ /* */ ++ /* The following part initialize some vars by PG info. */ ++ /* */ ++ Hal_InitChannelPlan(adapt); ++ Hal_CustomizeByCustomerID_8188EU(adapt); ++ ++ _ReadLEDSetting(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag); ++} ++ ++static void _ReadPROMContent( ++ struct adapter *Adapter ++ ) ++{ ++ struct eeprom_priv *eeprom = GET_EEPROM_EFUSE_PRIV(Adapter); ++ u8 eeValue; ++ ++ /* check system boot selection */ ++ eeValue = rtw_read8(Adapter, REG_9346CR); ++ eeprom->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false; ++ eeprom->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true; ++ ++ DBG_88E("Boot from %s, Autoload %s !\n", (eeprom->EepromOrEfuse ? "EEPROM" : "EFUSE"), ++ (eeprom->bautoload_fail_flag ? "Fail" : "OK")); ++ ++ Hal_InitPGData88E(Adapter); ++ readAdapterInfo_8188EU(Adapter); ++} ++ ++static void _ReadRFType(struct adapter *Adapter) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ ++ haldata->rf_chip = RF_6052; ++} ++ ++static int _ReadAdapterInfo8188EU(struct adapter *Adapter) ++{ ++ u32 start = jiffies; ++ ++ MSG_88E("====> %s\n", __func__); ++ ++ _ReadRFType(Adapter);/* rf_chip -> _InitRFType() */ ++ _ReadPROMContent(Adapter); ++ ++ MSG_88E("<==== %s in %d ms\n", __func__, rtw_get_passing_time_ms(start)); ++ ++ return _SUCCESS; ++} ++ ++static void ReadAdapterInfo8188EU(struct adapter *Adapter) ++{ ++ /* Read EEPROM size before call any EEPROM function */ ++ Adapter->EepromAddressSize = GetEEPROMSize8188E(Adapter); ++ ++ _ReadAdapterInfo8188EU(Adapter); ++} ++ ++#define GPIO_DEBUG_PORT_NUM 0 ++static void rtl8192cu_trigger_gpio_0(struct adapter *adapt) ++{ ++} ++ ++static void ResumeTxBeacon(struct adapter *adapt) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ ++ /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */ ++ /* which should be read from register to a global variable. */ ++ ++ rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl) | BIT(6)); ++ haldata->RegFwHwTxQCtrl |= BIT(6); ++ rtw_write8(adapt, REG_TBTT_PROHIBIT + 1, 0xff); ++ haldata->RegReg542 |= BIT(0); ++ rtw_write8(adapt, REG_TBTT_PROHIBIT + 2, haldata->RegReg542); ++} ++ ++static void StopTxBeacon(struct adapter *adapt) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ ++ /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */ ++ /* which should be read from register to a global variable. */ ++ ++ rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl) & (~BIT(6))); ++ haldata->RegFwHwTxQCtrl &= (~BIT(6)); ++ rtw_write8(adapt, REG_TBTT_PROHIBIT + 1, 0x64); ++ haldata->RegReg542 &= ~(BIT(0)); ++ rtw_write8(adapt, REG_TBTT_PROHIBIT + 2, haldata->RegReg542); ++ ++ /* todo: CheckFwRsvdPageContent(Adapter); 2010.06.23. Added by tynli. */ ++} ++ ++static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val) ++{ ++ u8 val8; ++ u8 mode = *((u8 *)val); ++ ++ /* disable Port0 TSF update */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4)); ++ ++ /* set net_type */ ++ val8 = rtw_read8(Adapter, MSR) & 0x0c; ++ val8 |= mode; ++ rtw_write8(Adapter, MSR, val8); ++ ++ DBG_88E("%s()-%d mode = %d\n", __func__, __LINE__, mode); ++ ++ if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) { ++ StopTxBeacon(Adapter); ++ ++ rtw_write8(Adapter, REG_BCN_CTRL, 0x19);/* disable atim wnd */ ++ } else if (mode == _HW_STATE_ADHOC_) { ++ ResumeTxBeacon(Adapter); ++ rtw_write8(Adapter, REG_BCN_CTRL, 0x1a); ++ } else if (mode == _HW_STATE_AP_) { ++ ResumeTxBeacon(Adapter); ++ ++ rtw_write8(Adapter, REG_BCN_CTRL, 0x12); ++ ++ /* Set RCR */ ++ rtw_write32(Adapter, REG_RCR, 0x7000208e);/* CBSSID_DATA must set to 0,reject ICV_ERR packet */ ++ /* enable to rx data frame */ ++ rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF); ++ /* enable to rx ps-poll */ ++ rtw_write16(Adapter, REG_RXFLTMAP1, 0x0400); ++ ++ /* Beacon Control related register for first time */ ++ rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms */ ++ ++ rtw_write8(Adapter, REG_ATIMWND, 0x0a); /* 10ms */ ++ rtw_write16(Adapter, REG_BCNTCFG, 0x00); ++ rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0xff04); ++ rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */ ++ ++ /* reset TSF */ ++ rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0)); ++ ++ /* BIT(3) - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */ ++ rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4)); ++ ++ /* enable BCN0 Function for if1 */ ++ /* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */ ++ rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP | EN_BCN_FUNCTION | BIT(1))); ++ ++ /* dis BCN1 ATIM WND if if2 is station */ ++ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) | BIT(0)); ++ } ++} ++ ++static void hw_var_set_macaddr(struct adapter *Adapter, u8 variable, u8 *val) ++{ ++ u8 idx = 0; ++ u32 reg_macid; ++ ++ reg_macid = REG_MACID; ++ ++ for (idx = 0; idx < 6; idx++) ++ rtw_write8(Adapter, (reg_macid + idx), val[idx]); ++} ++ ++static void hw_var_set_bssid(struct adapter *Adapter, u8 variable, u8 *val) ++{ ++ u8 idx = 0; ++ u32 reg_bssid; ++ ++ reg_bssid = REG_BSSID; ++ ++ for (idx = 0; idx < 6; idx++) ++ rtw_write8(Adapter, (reg_bssid + idx), val[idx]); ++} ++ ++static void hw_var_set_bcn_func(struct adapter *Adapter, u8 variable, u8 *val) ++{ ++ u32 bcn_ctrl_reg; ++ ++ bcn_ctrl_reg = REG_BCN_CTRL; ++ ++ if (*((u8 *)val)) ++ rtw_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT)); ++ else ++ rtw_write8(Adapter, bcn_ctrl_reg, rtw_read8(Adapter, bcn_ctrl_reg) & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT))); ++} ++ ++static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ struct dm_priv *pdmpriv = &haldata->dmpriv; ++ struct odm_dm_struct *podmpriv = &haldata->odmpriv; ++ ++ switch (variable) { ++ case HW_VAR_MEDIA_STATUS: ++ { ++ u8 val8; ++ ++ val8 = rtw_read8(Adapter, MSR) & 0x0c; ++ val8 |= *((u8 *)val); ++ rtw_write8(Adapter, MSR, val8); ++ } ++ break; ++ case HW_VAR_MEDIA_STATUS1: ++ { ++ u8 val8; ++ ++ val8 = rtw_read8(Adapter, MSR) & 0x03; ++ val8 |= *((u8 *)val) << 2; ++ rtw_write8(Adapter, MSR, val8); ++ } ++ break; ++ case HW_VAR_SET_OPMODE: ++ hw_var_set_opmode(Adapter, variable, val); ++ break; ++ case HW_VAR_MAC_ADDR: ++ hw_var_set_macaddr(Adapter, variable, val); ++ break; ++ case HW_VAR_BSSID: ++ hw_var_set_bssid(Adapter, variable, val); ++ break; ++ case HW_VAR_BASIC_RATE: ++ { ++ u16 BrateCfg = 0; ++ u8 RateIndex = 0; ++ ++ /* 2007.01.16, by Emily */ ++ /* Select RRSR (in Legacy-OFDM and CCK) */ ++ /* For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate. */ ++ /* We do not use other rates. */ ++ HalSetBrateCfg(Adapter, val, &BrateCfg); ++ DBG_88E("HW_VAR_BASIC_RATE: BrateCfg(%#x)\n", BrateCfg); ++ ++ /* 2011.03.30 add by Luke Lee */ ++ /* CCK 2M ACK should be disabled for some BCM and Atheros AP IOT */ ++ /* because CCK 2M has poor TXEVM */ ++ /* CCK 5.5M & 11M ACK should be enabled for better performance */ ++ ++ BrateCfg = (BrateCfg | 0xd) & 0x15d; ++ haldata->BasicRateSet = BrateCfg; ++ ++ BrateCfg |= 0x01; /* default enable 1M ACK rate */ ++ /* Set RRSR rate table. */ ++ rtw_write8(Adapter, REG_RRSR, BrateCfg & 0xff); ++ rtw_write8(Adapter, REG_RRSR + 1, (BrateCfg >> 8) & 0xff); ++ rtw_write8(Adapter, REG_RRSR + 2, rtw_read8(Adapter, REG_RRSR + 2) & 0xf0); ++ ++ /* Set RTS initial rate */ ++ while (BrateCfg > 0x1) { ++ BrateCfg = (BrateCfg >> 1); ++ RateIndex++; ++ } ++ /* Ziv - Check */ ++ rtw_write8(Adapter, REG_INIRTS_RATE_SEL, RateIndex); ++ } ++ break; ++ case HW_VAR_TXPAUSE: ++ rtw_write8(Adapter, REG_TXPAUSE, *((u8 *)val)); ++ break; ++ case HW_VAR_BCN_FUNC: ++ hw_var_set_bcn_func(Adapter, variable, val); ++ break; ++ case HW_VAR_CORRECT_TSF: ++ { ++ u64 tsf; ++ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ tsf = pmlmeext->TSFValue - do_div(pmlmeext->TSFValue, ++ pmlmeinfo->bcn_interval * 1024) - 1024; /* us */ ++ ++ if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) ++ StopTxBeacon(Adapter); ++ ++ /* disable related TSF function */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(3))); ++ ++ rtw_write32(Adapter, REG_TSFTR, tsf); ++ rtw_write32(Adapter, REG_TSFTR + 4, tsf >> 32); ++ ++ /* enable related TSF function */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(3)); ++ ++ if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) ++ ResumeTxBeacon(Adapter); ++ } ++ break; ++ case HW_VAR_CHECK_BSSID: ++ if (*((u8 *)val)) { ++ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN); ++ } else { ++ u32 val32; ++ ++ val32 = rtw_read32(Adapter, REG_RCR); ++ ++ val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); ++ ++ rtw_write32(Adapter, REG_RCR, val32); ++ } ++ break; ++ case HW_VAR_MLME_DISCONNECT: ++ /* Set RCR to not to receive data frame when NO LINK state */ ++ /* reject all data frames */ ++ rtw_write16(Adapter, REG_RXFLTMAP2, 0x00); ++ ++ /* reset TSF */ ++ rtw_write8(Adapter, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); ++ ++ /* disable update TSF */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4)); ++ break; ++ case HW_VAR_MLME_SITESURVEY: ++ if (*((u8 *)val)) { /* under sitesurvey */ ++ /* config RCR to receive different BSSID & not to receive data frame */ ++ u32 v = rtw_read32(Adapter, REG_RCR); ++ v &= ~(RCR_CBSSID_BCN); ++ rtw_write32(Adapter, REG_RCR, v); ++ /* reject all data frame */ ++ rtw_write16(Adapter, REG_RXFLTMAP2, 0x00); ++ ++ /* disable update TSF */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4)); ++ } else { /* sitesurvey done */ ++ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ if ((is_client_associated_to_ap(Adapter)) || ++ ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) { ++ /* enable to rx data frame */ ++ rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF); ++ ++ /* enable update TSF */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4))); ++ } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { ++ rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF); ++ /* enable update TSF */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4))); ++ } ++ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { ++ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN); ++ } else { ++ if (Adapter->in_cta_test) { ++ u32 v = rtw_read32(Adapter, REG_RCR); ++ v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */ ++ rtw_write32(Adapter, REG_RCR, v); ++ } else { ++ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN); ++ } ++ } ++ } ++ break; ++ case HW_VAR_MLME_JOIN: ++ { ++ u8 RetryLimit = 0x30; ++ u8 type = *((u8 *)val); ++ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; ++ ++ if (type == 0) { /* prepare to join */ ++ /* enable to rx data frame.Accept all data frame */ ++ rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF); ++ ++ if (Adapter->in_cta_test) { ++ u32 v = rtw_read32(Adapter, REG_RCR); ++ v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */ ++ rtw_write32(Adapter, REG_RCR, v); ++ } else { ++ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN); ++ } ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) ++ RetryLimit = (haldata->CustomerID == RT_CID_CCX) ? 7 : 48; ++ else /* Ad-hoc Mode */ ++ RetryLimit = 0x7; ++ } else if (type == 1) { ++ /* joinbss_event call back when join res < 0 */ ++ rtw_write16(Adapter, REG_RXFLTMAP2, 0x00); ++ } else if (type == 2) { ++ /* sta add event call back */ ++ /* enable update TSF */ ++ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4))); ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) ++ RetryLimit = 0x7; ++ } ++ rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT); ++ } ++ break; ++ case HW_VAR_BEACON_INTERVAL: ++ rtw_write16(Adapter, REG_BCN_INTERVAL, *((u16 *)val)); ++ break; ++ case HW_VAR_SLOT_TIME: ++ { ++ u8 u1bAIFS, aSifsTime; ++ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ ++ rtw_write8(Adapter, REG_SLOT, val[0]); ++ ++ if (pmlmeinfo->WMM_enable == 0) { ++ if (pmlmeext->cur_wireless_mode == WIRELESS_11B) ++ aSifsTime = 10; ++ else ++ aSifsTime = 16; ++ ++ u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime); ++ ++ /* Temporary removed, 2008.06.20. */ ++ rtw_write8(Adapter, REG_EDCA_VO_PARAM, u1bAIFS); ++ rtw_write8(Adapter, REG_EDCA_VI_PARAM, u1bAIFS); ++ rtw_write8(Adapter, REG_EDCA_BE_PARAM, u1bAIFS); ++ rtw_write8(Adapter, REG_EDCA_BK_PARAM, u1bAIFS); ++ } ++ } ++ break; ++ case HW_VAR_RESP_SIFS: ++ /* RESP_SIFS for CCK */ ++ rtw_write8(Adapter, REG_R2T_SIFS, val[0]); /* SIFS_T2T_CCK (0x08) */ ++ rtw_write8(Adapter, REG_R2T_SIFS + 1, val[1]); /* SIFS_R2T_CCK(0x08) */ ++ /* RESP_SIFS for OFDM */ ++ rtw_write8(Adapter, REG_T2T_SIFS, val[2]); /* SIFS_T2T_OFDM (0x0a) */ ++ rtw_write8(Adapter, REG_T2T_SIFS + 1, val[3]); /* SIFS_R2T_OFDM(0x0a) */ ++ break; ++ case HW_VAR_ACK_PREAMBLE: ++ { ++ u8 regTmp; ++ u8 bShortPreamble = *((bool *)val); ++ /* Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */ ++ regTmp = (haldata->nCur40MhzPrimeSC) << 5; ++ if (bShortPreamble) ++ regTmp |= 0x80; ++ ++ rtw_write8(Adapter, REG_RRSR + 2, regTmp); ++ } ++ break; ++ case HW_VAR_SEC_CFG: ++ rtw_write8(Adapter, REG_SECCFG, *((u8 *)val)); ++ break; ++ case HW_VAR_DM_FLAG: ++ podmpriv->SupportAbility = *((u8 *)val); ++ break; ++ case HW_VAR_DM_FUNC_OP: ++ if (val[0]) ++ podmpriv->BK_SupportAbility = podmpriv->SupportAbility; ++ else ++ podmpriv->SupportAbility = podmpriv->BK_SupportAbility; ++ break; ++ case HW_VAR_DM_FUNC_SET: ++ if (*((u32 *)val) == DYNAMIC_ALL_FUNC_ENABLE) { ++ pdmpriv->DMFlag = pdmpriv->InitDMFlag; ++ podmpriv->SupportAbility = pdmpriv->InitODMFlag; ++ } else { ++ podmpriv->SupportAbility |= *((u32 *)val); ++ } ++ break; ++ case HW_VAR_DM_FUNC_CLR: ++ podmpriv->SupportAbility &= *((u32 *)val); ++ break; ++ case HW_VAR_CAM_EMPTY_ENTRY: ++ { ++ u8 ucIndex = *((u8 *)val); ++ u8 i; ++ u32 ulCommand = 0; ++ u32 ulContent = 0; ++ u32 ulEncAlgo = CAM_AES; ++ ++ for (i = 0; i < CAM_CONTENT_COUNT; i++) { ++ /* filled id in CAM config 2 byte */ ++ if (i == 0) ++ ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2); ++ else ++ ulContent = 0; ++ /* polling bit, and No Write enable, and address */ ++ ulCommand = CAM_CONTENT_COUNT * ucIndex + i; ++ ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE; ++ /* write content 0 is equall to mark invalid */ ++ rtw_write32(Adapter, WCAMI, ulContent); /* delay_ms(40); */ ++ rtw_write32(Adapter, RWCAM, ulCommand); /* delay_ms(40); */ ++ } ++ } ++ break; ++ case HW_VAR_CAM_INVALID_ALL: ++ rtw_write32(Adapter, RWCAM, BIT(31) | BIT(30)); ++ break; ++ case HW_VAR_CAM_WRITE: ++ { ++ u32 cmd; ++ u32 *cam_val = (u32 *)val; ++ rtw_write32(Adapter, WCAMI, cam_val[0]); ++ ++ cmd = CAM_POLLINIG | CAM_WRITE | cam_val[1]; ++ rtw_write32(Adapter, RWCAM, cmd); ++ } ++ break; ++ case HW_VAR_AC_PARAM_VO: ++ rtw_write32(Adapter, REG_EDCA_VO_PARAM, ((u32 *)(val))[0]); ++ break; ++ case HW_VAR_AC_PARAM_VI: ++ rtw_write32(Adapter, REG_EDCA_VI_PARAM, ((u32 *)(val))[0]); ++ break; ++ case HW_VAR_AC_PARAM_BE: ++ haldata->AcParam_BE = ((u32 *)(val))[0]; ++ rtw_write32(Adapter, REG_EDCA_BE_PARAM, ((u32 *)(val))[0]); ++ break; ++ case HW_VAR_AC_PARAM_BK: ++ rtw_write32(Adapter, REG_EDCA_BK_PARAM, ((u32 *)(val))[0]); ++ break; ++ case HW_VAR_ACM_CTRL: ++ { ++ u8 acm_ctrl = *((u8 *)val); ++ u8 AcmCtrl = rtw_read8(Adapter, REG_ACMHWCTRL); ++ ++ if (acm_ctrl > 1) ++ AcmCtrl = AcmCtrl | 0x1; ++ ++ if (acm_ctrl & BIT(3)) ++ AcmCtrl |= AcmHw_VoqEn; ++ else ++ AcmCtrl &= (~AcmHw_VoqEn); ++ ++ if (acm_ctrl & BIT(2)) ++ AcmCtrl |= AcmHw_ViqEn; ++ else ++ AcmCtrl &= (~AcmHw_ViqEn); ++ ++ if (acm_ctrl & BIT(1)) ++ AcmCtrl |= AcmHw_BeqEn; ++ else ++ AcmCtrl &= (~AcmHw_BeqEn); ++ ++ DBG_88E("[HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl); ++ rtw_write8(Adapter, REG_ACMHWCTRL, AcmCtrl); ++ } ++ break; ++ case HW_VAR_AMPDU_MIN_SPACE: ++ { ++ u8 MinSpacingToSet; ++ u8 SecMinSpace; ++ ++ MinSpacingToSet = *((u8 *)val); ++ if (MinSpacingToSet <= 7) { ++ switch (Adapter->securitypriv.dot11PrivacyAlgrthm) { ++ case _NO_PRIVACY_: ++ case _AES_: ++ SecMinSpace = 0; ++ break; ++ case _WEP40_: ++ case _WEP104_: ++ case _TKIP_: ++ case _TKIP_WTMIC_: ++ SecMinSpace = 6; ++ break; ++ default: ++ SecMinSpace = 7; ++ break; ++ } ++ if (MinSpacingToSet < SecMinSpace) ++ MinSpacingToSet = SecMinSpace; ++ rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (rtw_read8(Adapter, REG_AMPDU_MIN_SPACE) & 0xf8) | MinSpacingToSet); ++ } ++ } ++ break; ++ case HW_VAR_AMPDU_FACTOR: ++ { ++ u8 RegToSet_Normal[4] = {0x41, 0xa8, 0x72, 0xb9}; ++ u8 FactorToSet; ++ u8 *pRegToSet; ++ u8 index = 0; ++ ++ pRegToSet = RegToSet_Normal; /* 0xb972a841; */ ++ FactorToSet = *((u8 *)val); ++ if (FactorToSet <= 3) { ++ FactorToSet = (1 << (FactorToSet + 2)); ++ if (FactorToSet > 0xf) ++ FactorToSet = 0xf; ++ ++ for (index = 0; index < 4; index++) { ++ if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4)) ++ pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet << 4); ++ ++ if ((pRegToSet[index] & 0x0f) > FactorToSet) ++ pRegToSet[index] = (pRegToSet[index] & 0xf0) | (FactorToSet); ++ ++ rtw_write8(Adapter, (REG_AGGLEN_LMT + index), pRegToSet[index]); ++ } ++ } ++ } ++ break; ++ case HW_VAR_RXDMA_AGG_PG_TH: ++ { ++ u8 threshold = *((u8 *)val); ++ if (threshold == 0) ++ threshold = haldata->UsbRxAggPageCount; ++ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, threshold); ++ } ++ break; ++ case HW_VAR_SET_RPWM: ++ break; ++ case HW_VAR_H2C_FW_PWRMODE: ++ { ++ u8 psmode = (*(u8 *)val); ++ ++ /* Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power */ ++ /* saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang. */ ++ if ((psmode != PS_MODE_ACTIVE) && (!IS_92C_SERIAL(haldata->VersionID))) ++ ODM_RF_Saving(podmpriv, true); ++ rtl8188e_set_FwPwrMode_cmd(Adapter, psmode); ++ } ++ break; ++ case HW_VAR_H2C_FW_JOINBSSRPT: ++ { ++ u8 mstatus = (*(u8 *)val); ++ rtl8188e_set_FwJoinBssReport_cmd(Adapter, mstatus); ++ } ++ break; ++#ifdef CONFIG_88EU_P2P ++ case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: ++ { ++ u8 p2p_ps_state = (*(u8 *)val); ++ rtl8188e_set_p2p_ps_offload_cmd(Adapter, p2p_ps_state); ++ } ++ break; ++#endif ++ case HW_VAR_INITIAL_GAIN: ++ { ++ struct rtw_dig *pDigTable = &podmpriv->DM_DigTable; ++ u32 rx_gain = ((u32 *)(val))[0]; ++ ++ if (rx_gain == 0xff) {/* restore rx gain */ ++ ODM_Write_DIG(podmpriv, pDigTable->BackupIGValue); ++ } else { ++ pDigTable->BackupIGValue = pDigTable->CurIGValue; ++ ODM_Write_DIG(podmpriv, rx_gain); ++ } ++ } ++ break; ++ case HW_VAR_TRIGGER_GPIO_0: ++ rtl8192cu_trigger_gpio_0(Adapter); ++ break; ++ case HW_VAR_RPT_TIMER_SETTING: ++ { ++ u16 min_rpt_time = (*(u16 *)val); ++ ODM_RA_Set_TxRPT_Time(podmpriv, min_rpt_time); ++ } ++ break; ++ case HW_VAR_ANTENNA_DIVERSITY_SELECT: ++ { ++ u8 Optimum_antenna = (*(u8 *)val); ++ u8 Ant; ++ /* switch antenna to Optimum_antenna */ ++ if (haldata->CurAntenna != Optimum_antenna) { ++ Ant = (Optimum_antenna == 2) ? MAIN_ANT : AUX_ANT; ++ ODM_UpdateRxIdleAnt_88E(&haldata->odmpriv, Ant); ++ ++ haldata->CurAntenna = Optimum_antenna; ++ } ++ } ++ break; ++ case HW_VAR_EFUSE_BYTES: /* To set EFUE total used bytes, added by Roger, 2008.12.22. */ ++ haldata->EfuseUsedBytes = *((u16 *)val); ++ break; ++ case HW_VAR_FIFO_CLEARN_UP: ++ { ++ struct pwrctrl_priv *pwrpriv = &Adapter->pwrctrlpriv; ++ u8 trycnt = 100; ++ ++ /* pause tx */ ++ rtw_write8(Adapter, REG_TXPAUSE, 0xff); ++ ++ /* keep sn */ ++ Adapter->xmitpriv.nqos_ssn = rtw_read16(Adapter, REG_NQOS_SEQ); ++ ++ if (!pwrpriv->bkeepfwalive) { ++ /* RX DMA stop */ ++ rtw_write32(Adapter, REG_RXPKT_NUM, (rtw_read32(Adapter, REG_RXPKT_NUM) | RW_RELEASE_EN)); ++ do { ++ if (!(rtw_read32(Adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) ++ break; ++ } while (trycnt--); ++ if (trycnt == 0) ++ DBG_88E("Stop RX DMA failed......\n"); ++ ++ /* RQPN Load 0 */ ++ rtw_write16(Adapter, REG_RQPN_NPQ, 0x0); ++ rtw_write32(Adapter, REG_RQPN, 0x80000000); ++ mdelay(10); ++ } ++ } ++ break; ++ case HW_VAR_CHECK_TXBUF: ++ break; ++ case HW_VAR_APFM_ON_MAC: ++ haldata->bMacPwrCtrlOn = *val; ++ DBG_88E("%s: bMacPwrCtrlOn=%d\n", __func__, haldata->bMacPwrCtrlOn); ++ break; ++ case HW_VAR_TX_RPT_MAX_MACID: ++ { ++ u8 maxMacid = *val; ++ DBG_88E("### MacID(%d),Set Max Tx RPT MID(%d)\n", maxMacid, maxMacid + 1); ++ rtw_write8(Adapter, REG_TX_RPT_CTRL + 1, maxMacid + 1); ++ } ++ break; ++ case HW_VAR_H2C_MEDIA_STATUS_RPT: ++ rtl8188e_set_FwMediaStatus_cmd(Adapter, (*(__le16 *)val)); ++ break; ++ case HW_VAR_BCN_VALID: ++ /* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */ ++ rtw_write8(Adapter, REG_TDECTRL + 2, rtw_read8(Adapter, REG_TDECTRL + 2) | BIT(0)); ++ break; ++ default: ++ break; ++ } ++ ++} ++ ++static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ struct odm_dm_struct *podmpriv = &haldata->odmpriv; ++ ++ switch (variable) { ++ case HW_VAR_BASIC_RATE: ++ *((u16 *)(val)) = haldata->BasicRateSet; ++ fallthrough; ++ case HW_VAR_TXPAUSE: ++ val[0] = rtw_read8(Adapter, REG_TXPAUSE); ++ break; ++ case HW_VAR_BCN_VALID: ++ /* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2 */ ++ val[0] = (BIT(0) & rtw_read8(Adapter, REG_TDECTRL + 2)) ? true : false; ++ break; ++ case HW_VAR_DM_FLAG: ++ val[0] = podmpriv->SupportAbility; ++ break; ++ case HW_VAR_RF_TYPE: ++ val[0] = haldata->rf_type; ++ break; ++ case HW_VAR_FWLPS_RF_ON: ++ { ++ /* When we halt NIC, we should check if FW LPS is leave. */ ++ if (Adapter->pwrctrlpriv.rf_pwrstate == rf_off) { ++ /* If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave, */ ++ /* because Fw is unload. */ ++ val[0] = true; ++ } else { ++ u32 valRCR; ++ valRCR = rtw_read32(Adapter, REG_RCR); ++ valRCR &= 0x00070000; ++ if (valRCR) ++ val[0] = false; ++ else ++ val[0] = true; ++ } ++ } ++ break; ++ case HW_VAR_CURRENT_ANTENNA: ++ val[0] = haldata->CurAntenna; ++ break; ++ case HW_VAR_EFUSE_BYTES: /* To get EFUE total used bytes, added by Roger, 2008.12.22. */ ++ *((u16 *)(val)) = haldata->EfuseUsedBytes; ++ break; ++ case HW_VAR_APFM_ON_MAC: ++ *val = haldata->bMacPwrCtrlOn; ++ break; ++ case HW_VAR_CHK_HI_QUEUE_EMPTY: ++ *val = ((rtw_read32(Adapter, REG_HGQ_INFORMATION) & 0x0000ff00) == 0) ? true : false; ++ break; ++ default: ++ break; ++ } ++ ++} ++ ++/* */ ++/* Description: */ ++/* Query setting of specified variable. */ ++/* */ ++static u8 ++GetHalDefVar8188EUsb( ++ struct adapter *Adapter, ++ enum hal_def_variable eVariable, ++ void *pValue ++ ) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ u8 bResult = _SUCCESS; ++ ++ switch (eVariable) { ++ case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: ++ { ++ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; ++ struct sta_priv *pstapriv = &Adapter->stapriv; ++ struct sta_info *psta; ++ psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress); ++ if (psta) ++ *((int *)pValue) = psta->rssi_stat.UndecoratedSmoothedPWDB; ++ } ++ break; ++ case HAL_DEF_IS_SUPPORT_ANT_DIV: ++ *((u8 *)pValue) = (haldata->AntDivCfg == 0) ? false : true; ++ break; ++ case HAL_DEF_CURRENT_ANTENNA: ++ *((u8 *)pValue) = haldata->CurAntenna; ++ break; ++ case HAL_DEF_DRVINFO_SZ: ++ *((u32 *)pValue) = DRVINFO_SZ; ++ break; ++ case HAL_DEF_MAX_RECVBUF_SZ: ++ *((u32 *)pValue) = MAX_RECVBUF_SZ; ++ break; ++ case HAL_DEF_RX_PACKET_OFFSET: ++ *((u32 *)pValue) = RXDESC_SIZE + DRVINFO_SZ; ++ break; ++ case HAL_DEF_DBG_DM_FUNC: ++ *((u32 *)pValue) = haldata->odmpriv.SupportAbility; ++ break; ++ case HAL_DEF_RA_DECISION_RATE: ++ { ++ u8 MacID = *((u8 *)pValue); ++ *((u8 *)pValue) = ODM_RA_GetDecisionRate_8188E(&haldata->odmpriv, MacID); ++ } ++ break; ++ case HAL_DEF_RA_SGI: ++ { ++ u8 MacID = *((u8 *)pValue); ++ *((u8 *)pValue) = ODM_RA_GetShortGI_8188E(&haldata->odmpriv, MacID); ++ } ++ break; ++ case HAL_DEF_PT_PWR_STATUS: ++ { ++ u8 MacID = *((u8 *)pValue); ++ *((u8 *)pValue) = ODM_RA_GetHwPwrStatus_8188E(&haldata->odmpriv, MacID); ++ } ++ break; ++ case HW_VAR_MAX_RX_AMPDU_FACTOR: ++ *((u32 *)pValue) = MAX_AMPDU_FACTOR_64K; ++ break; ++ case HW_DEF_RA_INFO_DUMP: ++ { ++ u8 entry_id = *((u8 *)pValue); ++ if (check_fwstate(&Adapter->mlmepriv, _FW_LINKED)) { ++ DBG_88E("============ RA status check ===================\n"); ++ DBG_88E("Mac_id:%d , RateID = %d, RAUseRate = 0x%08x, RateSGI = %d, DecisionRate = 0x%02x ,PTStage = %d\n", ++ entry_id, ++ haldata->odmpriv.RAInfo[entry_id].RateID, ++ haldata->odmpriv.RAInfo[entry_id].RAUseRate, ++ haldata->odmpriv.RAInfo[entry_id].RateSGI, ++ haldata->odmpriv.RAInfo[entry_id].DecisionRate, ++ haldata->odmpriv.RAInfo[entry_id].PTStage); ++ } ++ } ++ break; ++ case HAL_DEF_DBG_DUMP_RXPKT: ++ *((u8 *)pValue) = haldata->bDumpRxPkt; ++ break; ++ case HAL_DEF_DBG_DUMP_TXPKT: ++ *((u8 *)pValue) = haldata->bDumpTxPkt; ++ break; ++ default: ++ bResult = _FAIL; ++ break; ++ } ++ ++ return bResult; ++} ++ ++/* */ ++/* Description: */ ++/* Change default setting of specified variable. */ ++/* */ ++static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eVariable, void *pValue) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter); ++ u8 bResult = _SUCCESS; ++ ++ switch (eVariable) { ++ case HAL_DEF_DBG_DM_FUNC: ++ { ++ u8 dm_func = *((u8 *)pValue); ++ struct odm_dm_struct *podmpriv = &haldata->odmpriv; ++ ++ if (dm_func == 0) { /* disable all dynamic func */ ++ podmpriv->SupportAbility = DYNAMIC_FUNC_DISABLE; ++ DBG_88E("==> Disable all dynamic function...\n"); ++ } else if (dm_func == 1) {/* disable DIG */ ++ podmpriv->SupportAbility &= (~DYNAMIC_BB_DIG); ++ DBG_88E("==> Disable DIG...\n"); ++ } else if (dm_func == 2) {/* disable High power */ ++ podmpriv->SupportAbility &= (~DYNAMIC_BB_DYNAMIC_TXPWR); ++ } else if (dm_func == 3) {/* disable tx power tracking */ ++ podmpriv->SupportAbility &= (~DYNAMIC_RF_CALIBRATION); ++ DBG_88E("==> Disable tx power tracking...\n"); ++ } else if (dm_func == 5) {/* disable antenna diversity */ ++ podmpriv->SupportAbility &= (~DYNAMIC_BB_ANT_DIV); ++ } else if (dm_func == 6) {/* turn on all dynamic func */ ++ if (!(podmpriv->SupportAbility & DYNAMIC_BB_DIG)) { ++ struct rtw_dig *pDigTable = &podmpriv->DM_DigTable; ++ pDigTable->CurIGValue = rtw_read8(Adapter, 0xc50); ++ } ++ podmpriv->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE; ++ DBG_88E("==> Turn on all dynamic function...\n"); ++ } ++ } ++ break; ++ case HAL_DEF_DBG_DUMP_RXPKT: ++ haldata->bDumpRxPkt = *((u8 *)pValue); ++ break; ++ case HAL_DEF_DBG_DUMP_TXPKT: ++ haldata->bDumpTxPkt = *((u8 *)pValue); ++ break; ++ default: ++ bResult = _FAIL; ++ break; ++ } ++ ++ return bResult; ++} ++ ++static void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_level) ++{ ++ u8 init_rate = 0; ++ u8 networkType, raid; ++ u32 mask, rate_bitmap; ++ u8 shortGIrate = false; ++ int supportRateNum = 0; ++ struct sta_info *psta; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; ++ ++ if (mac_id >= NUM_STA) /* CAM_SIZE */ ++ return; ++ psta = pmlmeinfo->FW_sta_info[mac_id].psta; ++ if (!psta) ++ return; ++ switch (mac_id) { ++ case 0:/* for infra mode */ ++ supportRateNum = rtw_get_rateset_len(cur_network->SupportedRates); ++ networkType = judge_network_type(adapt, cur_network->SupportedRates, supportRateNum) & 0xf; ++ raid = networktype_to_raid(networkType); ++ mask = update_supported_rate(cur_network->SupportedRates, supportRateNum); ++ mask |= (pmlmeinfo->HT_enable) ? update_MSC_rate(&pmlmeinfo->HT_caps) : 0; ++ if (support_short_GI(adapt, &pmlmeinfo->HT_caps)) ++ shortGIrate = true; ++ break; ++ case 1:/* for broadcast/multicast */ ++ supportRateNum = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[mac_id].SupportedRates); ++ if (pmlmeext->cur_wireless_mode & WIRELESS_11B) ++ networkType = WIRELESS_11B; ++ else ++ networkType = WIRELESS_11G; ++ raid = networktype_to_raid(networkType); ++ mask = update_basic_rate(cur_network->SupportedRates, supportRateNum); ++ break; ++ default: /* for each sta in IBSS */ ++ supportRateNum = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[mac_id].SupportedRates); ++ networkType = judge_network_type(adapt, pmlmeinfo->FW_sta_info[mac_id].SupportedRates, supportRateNum) & 0xf; ++ raid = networktype_to_raid(networkType); ++ mask = update_supported_rate(cur_network->SupportedRates, supportRateNum); ++ ++ /* todo: support HT in IBSS */ ++ break; ++ } ++ ++ rate_bitmap = 0x0fffffff; ++ rate_bitmap = ODM_Get_Rate_Bitmap(&haldata->odmpriv, mac_id, mask, rssi_level); ++ DBG_88E("%s => mac_id:%d, networkType:0x%02x, mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n", ++ __func__, mac_id, networkType, mask, rssi_level, rate_bitmap); ++ ++ mask &= rate_bitmap; ++ ++ init_rate = get_highest_rate_idx(mask) & 0x3f; ++ ++ if (haldata->fw_ractrl) { ++ u8 arg; ++ ++ arg = mac_id & 0x1f;/* MACID */ ++ arg |= BIT(7); ++ if (shortGIrate) ++ arg |= BIT(5); ++ mask |= ((raid << 28) & 0xf0000000); ++ DBG_88E("update raid entry, mask=0x%x, arg=0x%x\n", mask, arg); ++ psta->ra_mask = mask; ++ mask |= ((raid << 28) & 0xf0000000); ++ ++ /* to do ,for 8188E-SMIC */ ++ rtl8188e_set_raid_cmd(adapt, mask); ++ } else { ++ ODM_RA_UpdateRateInfo_8188E(&haldata->odmpriv, ++ mac_id, ++ raid, ++ mask, ++ shortGIrate ++ ); ++ } ++ /* set ra_id */ ++ psta->raid = raid; ++ psta->init_rate = init_rate; ++} ++ ++static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt) ++{ ++ u32 value32; ++ struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ u32 bcn_ctrl_reg = REG_BCN_CTRL; ++ /* reset TSF, enable update TSF, correcting TSF On Beacon */ ++ ++ /* BCN interval */ ++ rtw_write16(adapt, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval); ++ rtw_write8(adapt, REG_ATIMWND, 0x02);/* 2ms */ ++ ++ _InitBeaconParameters(adapt); ++ ++ rtw_write8(adapt, REG_SLOT, 0x09); ++ ++ value32 = rtw_read32(adapt, REG_TCR); ++ value32 &= ~TSFRST; ++ rtw_write32(adapt, REG_TCR, value32); ++ ++ value32 |= TSFRST; ++ rtw_write32(adapt, REG_TCR, value32); ++ ++ /* NOTE: Fix test chip's bug (about contention windows's randomness) */ ++ rtw_write8(adapt, REG_RXTSF_OFFSET_CCK, 0x50); ++ rtw_write8(adapt, REG_RXTSF_OFFSET_OFDM, 0x50); ++ ++ _BeaconFunctionEnable(adapt, true, true); ++ ++ ResumeTxBeacon(adapt); ++ ++ rtw_write8(adapt, bcn_ctrl_reg, rtw_read8(adapt, bcn_ctrl_reg) | BIT(1)); ++} ++ ++static void rtl8188eu_init_default_value(struct adapter *adapt) ++{ ++ struct hal_data_8188e *haldata; ++ struct pwrctrl_priv *pwrctrlpriv; ++ u8 i; ++ ++ haldata = GET_HAL_DATA(adapt); ++ pwrctrlpriv = &adapt->pwrctrlpriv; ++ ++ /* init default value */ ++ haldata->fw_ractrl = false; ++ if (!pwrctrlpriv->bkeepfwalive) ++ haldata->LastHMEBoxNum = 0; ++ ++ /* init dm default value */ ++ haldata->odmpriv.RFCalibrateInfo.bIQKInitialized = false; ++ haldata->odmpriv.RFCalibrateInfo.TM_Trigger = 0;/* for IQK */ ++ haldata->pwrGroupCnt = 0; ++ haldata->PGMaxGroup = 13; ++ haldata->odmpriv.RFCalibrateInfo.ThermalValue_HP_index = 0; ++ for (i = 0; i < HP_THERMAL_NUM; i++) ++ haldata->odmpriv.RFCalibrateInfo.ThermalValue_HP[i] = 0; ++} ++ ++static u8 rtl8188eu_ps_func(struct adapter *Adapter, enum hal_intf_ps_func efunc_id, u8 *val) ++{ ++ u8 bResult = true; ++ return bResult; ++} ++ ++void rtl8188eu_set_hal_ops(struct adapter *adapt) ++{ ++ struct hal_ops *halfunc = &adapt->HalFunc; ++ ++ adapt->HalData = kzalloc(sizeof(struct hal_data_8188e), GFP_KERNEL); ++ if (!adapt->HalData) ++ DBG_88E("cant not alloc memory for HAL DATA\n"); ++ adapt->hal_data_sz = sizeof(struct hal_data_8188e); ++ ++ halfunc->hal_power_on = rtl8188eu_InitPowerOn; ++ halfunc->hal_init = &rtl8188eu_hal_init; ++ halfunc->hal_deinit = &rtl8188eu_hal_deinit; ++ ++ halfunc->inirp_init = &rtl8188eu_inirp_init; ++ halfunc->inirp_deinit = &rtl8188eu_inirp_deinit; ++ ++ halfunc->init_xmit_priv = &rtl8188eu_init_xmit_priv; ++ ++ halfunc->init_recv_priv = &rtl8188eu_init_recv_priv; ++ halfunc->free_recv_priv = &rtl8188eu_free_recv_priv; ++ halfunc->InitSwLeds = &rtl8188eu_InitSwLeds; ++ halfunc->DeInitSwLeds = &rtl8188eu_DeInitSwLeds; ++ ++ halfunc->init_default_value = &rtl8188eu_init_default_value; ++ halfunc->intf_chip_configure = &rtl8188eu_interface_configure; ++ halfunc->read_adapter_info = &ReadAdapterInfo8188EU; ++ ++ halfunc->SetHwRegHandler = &SetHwReg8188EU; ++ halfunc->GetHwRegHandler = &GetHwReg8188EU; ++ halfunc->GetHalDefVarHandler = &GetHalDefVar8188EUsb; ++ halfunc->SetHalDefVarHandler = &SetHalDefVar8188EUsb; ++ ++ halfunc->UpdateRAMaskHandler = &UpdateHalRAMask8188EUsb; ++ halfunc->SetBeaconRelatedRegistersHandler = &SetBeaconRelatedRegisters8188EUsb; ++ ++ halfunc->hal_xmit = &rtl8188eu_hal_xmit; ++ halfunc->mgnt_xmit = &rtl8188eu_mgnt_xmit; ++ ++ halfunc->interface_ps_func = &rtl8188eu_ps_func; ++ ++ rtl8188e_set_hal_ops(halfunc); ++ ++} +diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c +new file mode 100644 +index 000000000000..0cf69033c529 +--- /dev/null ++++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c +@@ -0,0 +1,562 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/osdep_intf.h" ++#include "../include/usb_ops.h" ++#include "../include/recv_osdep.h" ++#include "../include/rtl8188e_hal.h" ++ ++static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void *pdata, u16 len, u8 requesttype) ++{ ++ struct adapter *adapt = pintfhdl->padapter; ++ struct dvobj_priv *dvobjpriv = adapter_to_dvobj(adapt); ++ struct usb_device *udev = dvobjpriv->pusbdev; ++ unsigned int pipe; ++ int status = 0; ++ u8 *pIo_buf; ++ int vendorreq_times = 0; ++ ++ if ((adapt->bSurpriseRemoved) || (adapt->pwrctrlpriv.pnp_bstop_trx)) { ++ status = -EPERM; ++ goto exit; ++ } ++ ++ if (len > MAX_VENDOR_REQ_CMD_SIZE) { ++ DBG_88E("[%s] Buffer len error ,vendor request failed\n", __func__); ++ status = -EINVAL; ++ goto exit; ++ } ++ ++ _enter_critical_mutex(&dvobjpriv->usb_vendor_req_mutex, NULL); ++ ++ /* Acquire IO memory for vendorreq */ ++ pIo_buf = dvobjpriv->usb_vendor_req_buf; ++ ++ if (!pIo_buf) { ++ DBG_88E("[%s] pIo_buf == NULL\n", __func__); ++ status = -ENOMEM; ++ goto release_mutex; ++ } ++ ++ if (requesttype == REALTEK_USB_VENQT_READ) ++ pipe = usb_rcvctrlpipe(udev, 0);/* read_in */ ++ else ++ pipe = usb_sndctrlpipe(udev, 0);/* write_out */ ++ ++ while (++vendorreq_times <= MAX_USBCTRL_VENDORREQ_TIMES) { ++ if (requesttype == REALTEK_USB_VENQT_READ) ++ memset(pIo_buf, 0, len); ++ else ++ memcpy(pIo_buf, pdata, len); ++ ++ status = usb_control_msg(udev, pipe, REALTEK_USB_VENQT_CMD_REQ, ++ requesttype, value, REALTEK_USB_VENQT_CMD_IDX, ++ pIo_buf, len, RTW_USB_CONTROL_MSG_TIMEOUT); ++ ++ if (status == len) { /* Success this control transfer. */ ++ rtw_reset_continual_urb_error(dvobjpriv); ++ if (requesttype == REALTEK_USB_VENQT_READ) ++ memcpy(pdata, pIo_buf, len); ++ } else { /* error cases */ ++ DBG_88E("reg 0x%x, usb %s %u fail, status:%d value=0x%x, vendorreq_times:%d\n", ++ value, (requesttype == REALTEK_USB_VENQT_READ) ? "read" : "write", ++ len, status, *(u32 *)pdata, vendorreq_times); ++ ++ if (status < 0) { ++ if (status == (-ESHUTDOWN) || status == -ENODEV) { ++ adapt->bSurpriseRemoved = true; ++ } else { ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ haldata->srestpriv.wifi_error_status = USB_VEN_REQ_CMD_FAIL; ++ } ++ } else { /* status != len && status >= 0 */ ++ if (status > 0) { ++ if (requesttype == REALTEK_USB_VENQT_READ) { ++ /* For Control read transfer, we have to copy the read data from pIo_buf to pdata. */ ++ memcpy(pdata, pIo_buf, len); ++ } ++ } ++ } ++ ++ if (rtw_inc_and_chk_continual_urb_error(dvobjpriv)) { ++ adapt->bSurpriseRemoved = true; ++ break; ++ } ++ ++ } ++ ++ /* firmware download is checksumed, don't retry */ ++ if ((value >= FW_8188E_START_ADDRESS && value <= FW_8188E_END_ADDRESS) || status == len) ++ break; ++ } ++release_mutex: ++ _exit_critical_mutex(&dvobjpriv->usb_vendor_req_mutex, NULL); ++exit: ++ return status; ++} ++ ++static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr) ++{ ++ u16 wvalue = (u16)(addr & 0x0000ffff); ++ u8 data; ++ ++ usbctrl_vendorreq(pintfhdl, wvalue, &data, 1, REALTEK_USB_VENQT_READ); ++ ++ return data; ++} ++ ++static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr) ++{ ++ u16 wvalue = (u16)(addr & 0x0000ffff); ++ __le32 data; ++ ++ usbctrl_vendorreq(pintfhdl, wvalue, &data, 2, REALTEK_USB_VENQT_READ); ++ ++ return (u16)(le32_to_cpu(data) & 0xffff); ++} ++ ++static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr) ++{ ++ u16 wvalue = (u16)(addr & 0x0000ffff); ++ __le32 data; ++ ++ usbctrl_vendorreq(pintfhdl, wvalue, &data, 4, REALTEK_USB_VENQT_READ); ++ ++ return le32_to_cpu(data); ++} ++ ++static int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val) ++{ ++ u16 wvalue = (u16)(addr & 0x0000ffff); ++ ++ return usbctrl_vendorreq(pintfhdl, wvalue, &val, 1, REALTEK_USB_VENQT_WRITE); ++} ++ ++static int usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val) ++{ ++ u16 wvalue = (u16)(addr & 0x0000ffff); ++ __le32 data = cpu_to_le32(val & 0x0000ffff); ++ ++ return usbctrl_vendorreq(pintfhdl, wvalue, &data, 2, REALTEK_USB_VENQT_WRITE); ++} ++ ++static int usb_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val) ++{ ++ u16 wvalue = (u16)(addr & 0x0000ffff); ++ __le32 data = cpu_to_le32(val); ++ ++ return usbctrl_vendorreq(pintfhdl, wvalue, &data, 4, REALTEK_USB_VENQT_WRITE); ++} ++ ++static int usb_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata) ++{ ++ u16 wvalue = (u16)(addr & 0x0000ffff); ++ u8 buf[VENDOR_CMD_MAX_DATA_LEN] = {0}; ++ ++ if (length > VENDOR_CMD_MAX_DATA_LEN) ++ return -EINVAL; ++ ++ memcpy(buf, pdata, length); ++ ++ return usbctrl_vendorreq(pintfhdl, wvalue, buf, (length & 0xffff), REALTEK_USB_VENQT_WRITE); ++} ++ ++static void interrupt_handler_8188eu(struct adapter *adapt, u16 pkt_len, u8 *pbuf) ++{ ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ ++ if (pkt_len != INTERRUPT_MSG_FORMAT_LEN) { ++ DBG_88E("%s Invalid interrupt content length (%d)!\n", __func__, pkt_len); ++ return; ++ } ++ ++ /* HISR */ ++ memcpy(&haldata->IntArray[0], &pbuf[USB_INTR_CONTENT_HISR_OFFSET], 4); ++ memcpy(&haldata->IntArray[1], &pbuf[USB_INTR_CONTENT_HISRE_OFFSET], 4); ++ ++ /* C2H Event */ ++ if (pbuf[0] != 0) ++ memcpy(&haldata->C2hArray[0], &pbuf[USB_INTR_CONTENT_C2H_OFFSET], 16); ++} ++ ++static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb) ++{ ++ u8 *pbuf; ++ u8 shift_sz = 0; ++ u16 pkt_cnt; ++ u32 pkt_offset, skb_len, alloc_sz; ++ s32 transfer_len; ++ struct recv_stat *prxstat; ++ struct phy_stat *pphy_status = NULL; ++ struct sk_buff *pkt_copy = NULL; ++ struct recv_frame *precvframe = NULL; ++ struct rx_pkt_attrib *pattrib = NULL; ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ struct recv_priv *precvpriv = &adapt->recvpriv; ++ struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue; ++ ++ transfer_len = (s32)pskb->len; ++ pbuf = pskb->data; ++ ++ prxstat = (struct recv_stat *)pbuf; ++ pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff; ++ ++ do { ++ prxstat = (struct recv_stat *)pbuf; ++ ++ precvframe = rtw_alloc_recvframe(pfree_recv_queue); ++ if (!precvframe) { ++ DBG_88E("%s()-%d: rtw_alloc_recvframe() failed! RX Drop!\n", __func__, __LINE__); ++ goto _exit_recvbuf2recvframe; ++ } ++ ++ INIT_LIST_HEAD(&precvframe->list); ++ precvframe->precvbuf = NULL; /* can't access the precvbuf for new arch. */ ++ precvframe->len = 0; ++ ++ update_recvframe_attrib_88e(precvframe, prxstat); ++ ++ pattrib = &precvframe->attrib; ++ ++ if ((pattrib->crc_err) || (pattrib->icv_err)) { ++ DBG_88E("%s: RX Warning! crc_err=%d icv_err=%d, skip!\n", __func__, pattrib->crc_err, pattrib->icv_err); ++ ++ rtw_free_recvframe(precvframe, pfree_recv_queue); ++ goto _exit_recvbuf2recvframe; ++ } ++ ++ if ((pattrib->physt) && (pattrib->pkt_rpt_type == NORMAL_RX)) ++ pphy_status = (struct phy_stat *)(pbuf + RXDESC_OFFSET); ++ ++ pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len; ++ ++ if ((pattrib->pkt_len <= 0) || (pkt_offset > transfer_len)) { ++ DBG_88E("%s()-%d: RX Warning!,pkt_len<=0 or pkt_offset> transfoer_len\n", __func__, __LINE__); ++ rtw_free_recvframe(precvframe, pfree_recv_queue); ++ goto _exit_recvbuf2recvframe; ++ } ++ ++ /* Modified by Albert 20101213 */ ++ /* For 8 bytes IP header alignment. */ ++ if (pattrib->qos) /* Qos data, wireless lan header length is 26 */ ++ shift_sz = 6; ++ else ++ shift_sz = 0; ++ ++ skb_len = pattrib->pkt_len; ++ ++ /* for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. */ ++ /* modify alloc_sz for recvive crc error packet by thomas 2011-06-02 */ ++ if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) { ++ if (skb_len <= 1650) ++ alloc_sz = 1664; ++ else ++ alloc_sz = skb_len + 14; ++ } else { ++ alloc_sz = skb_len; ++ /* 6 is for IP header 8 bytes alignment in QoS packet case. */ ++ /* 8 is for skb->data 4 bytes alignment. */ ++ alloc_sz += 14; ++ } ++ ++ pkt_copy = netdev_alloc_skb(adapt->pnetdev, alloc_sz); ++ if (pkt_copy) { ++ pkt_copy->dev = adapt->pnetdev; ++ precvframe->pkt = pkt_copy; ++ precvframe->rx_head = pkt_copy->data; ++ precvframe->rx_end = pkt_copy->data + alloc_sz; ++ skb_reserve(pkt_copy, 8 - ((size_t)(pkt_copy->data) & 7));/* force pkt_copy->data at 8-byte alignment address */ ++ skb_reserve(pkt_copy, shift_sz);/* force ip_hdr at 8-byte alignment address according to shift_sz. */ ++ memcpy(pkt_copy->data, (pbuf + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len); ++ precvframe->rx_tail = pkt_copy->data; ++ precvframe->rx_data = pkt_copy->data; ++ } else { ++ if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) { ++ DBG_88E("recvbuf2recvframe: alloc_skb fail , drop frag frame\n"); ++ rtw_free_recvframe(precvframe, pfree_recv_queue); ++ goto _exit_recvbuf2recvframe; ++ } ++ precvframe->pkt = skb_clone(pskb, GFP_ATOMIC); ++ if (precvframe->pkt) { ++ precvframe->rx_tail = pbuf + pattrib->drvinfo_sz + RXDESC_SIZE; ++ precvframe->rx_head = precvframe->rx_tail; ++ precvframe->rx_data = precvframe->rx_tail; ++ precvframe->rx_end = pbuf + pattrib->drvinfo_sz + RXDESC_SIZE + alloc_sz; ++ } else { ++ DBG_88E("recvbuf2recvframe: skb_clone fail\n"); ++ rtw_free_recvframe(precvframe, pfree_recv_queue); ++ goto _exit_recvbuf2recvframe; ++ } ++ } ++ ++ recvframe_put(precvframe, skb_len); ++ ++ switch (haldata->UsbRxAggMode) { ++ case USB_RX_AGG_DMA: ++ case USB_RX_AGG_MIX: ++ pkt_offset = (u16)_RND128(pkt_offset); ++ break; ++ case USB_RX_AGG_USB: ++ pkt_offset = (u16)_RND4(pkt_offset); ++ break; ++ case USB_RX_AGG_DISABLE: ++ default: ++ break; ++ } ++ if (pattrib->pkt_rpt_type == NORMAL_RX) { /* Normal rx packet */ ++ if (pattrib->physt) ++ update_recvframe_phyinfo_88e(precvframe, (struct phy_stat *)pphy_status); ++ rtw_recv_entry(precvframe); ++ } else { ++ /* enqueue recvframe to txrtp queue */ ++ if (pattrib->pkt_rpt_type == TX_REPORT1) { ++ /* CCX-TXRPT ack for xmit mgmt frames. */ ++ handle_txrpt_ccx_88e(adapt, precvframe->rx_data); ++ } else if (pattrib->pkt_rpt_type == TX_REPORT2) { ++ ODM_RA_TxRPT2Handle_8188E( ++ &haldata->odmpriv, ++ precvframe->rx_data, ++ pattrib->pkt_len, ++ pattrib->MacIDValidEntry[0], ++ pattrib->MacIDValidEntry[1] ++ ); ++ } else if (pattrib->pkt_rpt_type == HIS_REPORT) { ++ interrupt_handler_8188eu(adapt, pattrib->pkt_len, precvframe->rx_data); ++ } ++ rtw_free_recvframe(precvframe, pfree_recv_queue); ++ } ++ pkt_cnt--; ++ transfer_len -= pkt_offset; ++ pbuf += pkt_offset; ++ precvframe = NULL; ++ pkt_copy = NULL; ++ ++ if (transfer_len > 0 && pkt_cnt == 0) ++ pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff; ++ ++ } while ((transfer_len > 0) && (pkt_cnt > 0)); ++ ++_exit_recvbuf2recvframe: ++ ++ return _SUCCESS; ++} ++ ++void rtl8188eu_recv_tasklet(unsigned long priv) ++{ ++ struct sk_buff *pskb; ++ struct adapter *adapt = (struct adapter *)priv; ++ struct recv_priv *precvpriv = &adapt->recvpriv; ++ ++ while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) { ++ if ((adapt->bDriverStopped) || (adapt->bSurpriseRemoved)) { ++ DBG_88E("recv_tasklet => bDriverStopped or bSurpriseRemoved\n"); ++ dev_kfree_skb_any(pskb); ++ break; ++ } ++ recvbuf2recvframe(adapt, pskb); ++ skb_reset_tail_pointer(pskb); ++ pskb->len = 0; ++ skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); ++ } ++} ++ ++static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs) ++{ ++ struct recv_buf *precvbuf = (struct recv_buf *)purb->context; ++ struct adapter *adapt = (struct adapter *)precvbuf->adapter; ++ struct recv_priv *precvpriv = &adapt->recvpriv; ++ ++ precvpriv->rx_pending_cnt--; ++ ++ if (adapt->bSurpriseRemoved || adapt->bDriverStopped || adapt->bReadPortCancel) { ++ precvbuf->reuse = true; ++ DBG_88E("%s() RX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bReadPortCancel(%d)\n", ++ __func__, adapt->bDriverStopped, ++ adapt->bSurpriseRemoved, adapt->bReadPortCancel); ++ return; ++ } ++ ++ if (purb->status == 0) { /* SUCCESS */ ++ if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)) { ++ precvbuf->reuse = true; ++ rtw_read_port(adapt, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); ++ DBG_88E("%s()-%d: RX Warning!\n", __func__, __LINE__); ++ } else { ++ rtw_reset_continual_urb_error(adapter_to_dvobj(adapt)); ++ ++ precvbuf->transfer_len = purb->actual_length; ++ skb_put(precvbuf->pskb, purb->actual_length); ++ skb_queue_tail(&precvpriv->rx_skb_queue, precvbuf->pskb); ++ ++ if (skb_queue_len(&precvpriv->rx_skb_queue) <= 1) ++ tasklet_schedule(&precvpriv->recv_tasklet); ++ ++ precvbuf->pskb = NULL; ++ precvbuf->reuse = false; ++ rtw_read_port(adapt, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); ++ } ++ } else { ++ DBG_88E("###=> usb_read_port_complete => urb status(%d)\n", purb->status); ++ skb_put(precvbuf->pskb, purb->actual_length); ++ precvbuf->pskb = NULL; ++ ++ if (rtw_inc_and_chk_continual_urb_error(adapter_to_dvobj(adapt))) ++ adapt->bSurpriseRemoved = true; ++ ++ switch (purb->status) { ++ case -EINVAL: ++ case -EPIPE: ++ case -ENODEV: ++ case -ESHUTDOWN: ++ case -ENOENT: ++ adapt->bDriverStopped = true; ++ break; ++ case -EPROTO: ++ case -EOVERFLOW: ++ { ++ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); ++ haldata->srestpriv.wifi_error_status = USB_READ_PORT_FAIL; ++ } ++ precvbuf->reuse = true; ++ rtw_read_port(adapt, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); ++ break; ++ case -EINPROGRESS: ++ DBG_88E("ERROR: URB IS IN PROGRESS!/n"); ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++static u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) ++{ ++ struct urb *purb = NULL; ++ struct recv_buf *precvbuf = (struct recv_buf *)rmem; ++ struct adapter *adapter = pintfhdl->padapter; ++ struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter); ++ struct recv_priv *precvpriv = &adapter->recvpriv; ++ struct usb_device *pusbd = pdvobj->pusbdev; ++ int err; ++ unsigned int pipe; ++ size_t tmpaddr = 0; ++ size_t alignment = 0; ++ u32 ret = _SUCCESS; ++ ++ if (adapter->bDriverStopped || adapter->bSurpriseRemoved || ++ adapter->pwrctrlpriv.pnp_bstop_trx) ++ return _FAIL; ++ ++ if (!precvbuf) ++ return _FAIL; ++ ++ if (!precvbuf->reuse || !precvbuf->pskb) { ++ precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue); ++ if (precvbuf->pskb) ++ precvbuf->reuse = true; ++ } ++ ++ rtl8188eu_init_recvbuf(adapter, precvbuf); ++ ++ /* re-assign for linux based on skb */ ++ if (!precvbuf->reuse || !precvbuf->pskb) { ++ precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); ++ if (!precvbuf->pskb) { ++ DBG_88E("#### usb_read_port() alloc_skb fail!#####\n"); ++ return _FAIL; ++ } ++ ++ tmpaddr = (size_t)precvbuf->pskb->data; ++ alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); ++ skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment)); ++ ++ precvbuf->phead = precvbuf->pskb->head; ++ precvbuf->pdata = precvbuf->pskb->data; ++ precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); ++ precvbuf->pend = skb_end_pointer(precvbuf->pskb); ++ precvbuf->pbuf = precvbuf->pskb->data; ++ } else { /* reuse skb */ ++ precvbuf->phead = precvbuf->pskb->head; ++ precvbuf->pdata = precvbuf->pskb->data; ++ precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); ++ precvbuf->pend = skb_end_pointer(precvbuf->pskb); ++ precvbuf->pbuf = precvbuf->pskb->data; ++ ++ precvbuf->reuse = false; ++ } ++ ++ precvpriv->rx_pending_cnt++; ++ ++ purb = precvbuf->purb; ++ ++ /* translate DMA FIFO addr to pipehandle */ ++ pipe = ffaddr2pipehdl(pdvobj, addr); ++ ++ usb_fill_bulk_urb(purb, pusbd, pipe, ++ precvbuf->pbuf, ++ MAX_RECVBUF_SZ, ++ usb_read_port_complete, ++ precvbuf);/* context is precvbuf */ ++ ++ err = usb_submit_urb(purb, GFP_ATOMIC); ++ if ((err) && (err != (-EPERM))) { ++ DBG_88E("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n", ++ err, purb->status); ++ ret = _FAIL; ++ } ++ ++ return ret; ++} ++ ++void rtl8188eu_xmit_tasklet(unsigned long priv) ++{ ++ int ret = false; ++ struct adapter *adapt = (struct adapter *)priv; ++ struct xmit_priv *pxmitpriv = &adapt->xmitpriv; ++ ++ if (check_fwstate(&adapt->mlmepriv, _FW_UNDER_SURVEY)) ++ return; ++ ++ while (1) { ++ if ((adapt->bDriverStopped) || ++ (adapt->bSurpriseRemoved) || ++ (adapt->bWritePortCancel)) { ++ DBG_88E("xmit_tasklet => bDriverStopped or bSurpriseRemoved or bWritePortCancel\n"); ++ break; ++ } ++ ++ ret = rtl8188eu_xmitframe_complete(adapt, pxmitpriv, NULL); ++ ++ if (!ret) ++ break; ++ } ++} ++ ++void rtl8188eu_set_intf_ops(struct _io_ops *pops) ++{ ++ ++ memset((u8 *)pops, 0, sizeof(struct _io_ops)); ++ pops->_read8 = &usb_read8; ++ pops->_read16 = &usb_read16; ++ pops->_read32 = &usb_read32; ++ pops->_read_mem = &usb_read_mem; ++ pops->_read_port = &usb_read_port; ++ pops->_write8 = &usb_write8; ++ pops->_write16 = &usb_write16; ++ pops->_write32 = &usb_write32; ++ pops->_writeN = &usb_writeN; ++ pops->_write_mem = &usb_write_mem; ++ pops->_write_port = &usb_write_port; ++ pops->_read_port_cancel = &usb_read_port_cancel; ++ pops->_write_port_cancel = &usb_write_port_cancel; ++ ++} ++ ++void rtl8188eu_set_hw_type(struct adapter *adapt) ++{ ++ adapt->chip_type = RTL8188E; ++ adapt->HardwareType = HARDWARE_TYPE_RTL8188EU; ++ DBG_88E("CHIP TYPE: RTL8188E\n"); ++} +diff --git a/drivers/staging/r8188eu/include/Hal8188EPhyCfg.h b/drivers/staging/r8188eu/include/Hal8188EPhyCfg.h +new file mode 100644 +index 000000000000..4370ec2fa981 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/Hal8188EPhyCfg.h +@@ -0,0 +1,249 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __INC_HAL8188EPHYCFG_H__ ++#define __INC_HAL8188EPHYCFG_H__ ++ ++/*--------------------------Define Parameters-------------------------------*/ ++#define LOOP_LIMIT 5 ++#define MAX_STALL_TIME 50 /* us */ ++#define AntennaDiversityValue 0x80 ++#define MAX_TXPWR_IDX_NMODE_92S 63 ++#define Reset_Cnt_Limit 3 ++ ++#define IQK_MAC_REG_NUM 4 ++#define IQK_ADDA_REG_NUM 16 ++#define IQK_BB_REG_NUM 9 ++#define HP_THERMAL_NUM 8 ++ ++#define MAX_AGGR_NUM 0x07 ++ ++/*--------------------------Define Parameters-------------------------------*/ ++ ++/*------------------------------Define structure----------------------------*/ ++enum sw_chnl_cmd_id { ++ CmdID_End, ++ CmdID_SetTxPowerLevel, ++ CmdID_BBRegWrite10, ++ CmdID_WritePortUlong, ++ CmdID_WritePortUshort, ++ CmdID_WritePortUchar, ++ CmdID_RF_WriteReg, ++}; ++ ++/* 1. Switch channel related */ ++struct sw_chnl_cmd { ++ enum sw_chnl_cmd_id CmdID; ++ u32 Para1; ++ u32 Para2; ++ u32 msDelay; ++}; ++ ++enum hw90_block { ++ HW90_BLOCK_MAC = 0, ++ HW90_BLOCK_PHY0 = 1, ++ HW90_BLOCK_PHY1 = 2, ++ HW90_BLOCK_RF = 3, ++ HW90_BLOCK_MAXIMUM = 4, /* Never use this */ ++}; ++ ++enum rf_radio_path { ++ RF_PATH_A = 0, /* Radio Path A */ ++ RF_PATH_B = 1, /* Radio Path B */ ++ RF_PATH_C = 2, /* Radio Path C */ ++ RF_PATH_D = 3, /* Radio Path D */ ++}; ++ ++#define MAX_PG_GROUP 13 ++ ++#define RF_PATH_MAX 3 ++#define MAX_TX_COUNT 4 /* path numbers */ ++ ++#define CHANNEL_MAX_NUMBER 14 /* 14 is the max chnl number */ ++#define MAX_CHNL_GROUP_24G 6 /* ch1~2, ch3~5, ch6~8, ++ *ch9~11, ch12~13, CH 14 ++ * total three groups */ ++#define CHANNEL_GROUP_MAX_88E 6 ++ ++enum wireless_mode { ++ WIRELESS_MODE_UNKNOWN = 0x00, ++ WIRELESS_MODE_B = BIT(0), ++ WIRELESS_MODE_G = BIT(1), ++ WIRELESS_MODE_AUTO = BIT(5), ++ WIRELESS_MODE_N_24G = BIT(3), ++}; ++ ++enum phy_rate_tx_offset_area { ++ RA_OFFSET_LEGACY_OFDM1, ++ RA_OFFSET_LEGACY_OFDM2, ++ RA_OFFSET_HT_OFDM1, ++ RA_OFFSET_HT_OFDM2, ++ RA_OFFSET_HT_OFDM3, ++ RA_OFFSET_HT_OFDM4, ++ RA_OFFSET_HT_CCK, ++}; ++ ++/* BB/RF related */ ++enum RF_TYPE_8190P { ++ RF_TYPE_MIN, /* 0 */ ++ RF_8225 = 1, /* 1 11b/g RF for verification only */ ++ RF_8256 = 2, /* 2 11b/g/n */ ++ RF_6052 = 4, /* 4 11b/g/n RF */ ++ /* TODO: We should remove this psudo PHY RF after we get new RF. */ ++ RF_PSEUDO_11N = 5, /* 5, It is a temporality RF. */ ++}; ++ ++struct bb_reg_def { ++ u32 rfintfs; /* set software control: */ ++ /* 0x870~0x877[8 bytes] */ ++ u32 rfintfi; /* readback data: */ ++ /* 0x8e0~0x8e7[8 bytes] */ ++ u32 rfintfo; /* output data: */ ++ /* 0x860~0x86f [16 bytes] */ ++ u32 rfintfe; /* output enable: */ ++ /* 0x860~0x86f [16 bytes] */ ++ u32 rf3wireOffset; /* LSSI data: */ ++ /* 0x840~0x84f [16 bytes] */ ++ u32 rfLSSI_Select; /* BB Band Select: */ ++ /* 0x878~0x87f [8 bytes] */ ++ u32 rfTxGainStage; /* Tx gain stage: */ ++ /* 0x80c~0x80f [4 bytes] */ ++ u32 rfHSSIPara1; /* wire parameter control1 : */ ++ /* 0x820~0x823,0x828~0x82b, ++ * 0x830~0x833, 0x838~0x83b [16 bytes] */ ++ u32 rfHSSIPara2; /* wire parameter control2 : */ ++ /* 0x824~0x827,0x82c~0x82f, 0x834~0x837, ++ * 0x83c~0x83f [16 bytes] */ ++ u32 rfSwitchControl; /* Tx Rx antenna control : */ ++ /* 0x858~0x85f [16 bytes] */ ++ u32 rfAGCControl1; /* AGC parameter control1 : */ ++ /* 0xc50~0xc53,0xc58~0xc5b, 0xc60~0xc63, ++ * 0xc68~0xc6b [16 bytes] */ ++ u32 rfAGCControl2; /* AGC parameter control2 : */ ++ /* 0xc54~0xc57,0xc5c~0xc5f, 0xc64~0xc67, ++ * 0xc6c~0xc6f [16 bytes] */ ++ u32 rfRxIQImbalance; /* OFDM Rx IQ imbalance matrix : */ ++ /* 0xc14~0xc17,0xc1c~0xc1f, 0xc24~0xc27, ++ * 0xc2c~0xc2f [16 bytes] */ ++ u32 rfRxAFE; /* Rx IQ DC ofset and Rx digital filter, ++ * Rx DC notch filter : */ ++ /* 0xc10~0xc13,0xc18~0xc1b, 0xc20~0xc23, ++ * 0xc28~0xc2b [16 bytes] */ ++ u32 rfTxIQImbalance; /* OFDM Tx IQ imbalance matrix */ ++ /* 0xc80~0xc83,0xc88~0xc8b, 0xc90~0xc93, ++ * 0xc98~0xc9b [16 bytes] */ ++ u32 rfTxAFE; /* Tx IQ DC Offset and Tx DFIR type */ ++ /* 0xc84~0xc87,0xc8c~0xc8f, 0xc94~0xc97, ++ * 0xc9c~0xc9f [16 bytes] */ ++ u32 rfLSSIReadBack; /* LSSI RF readback data SI mode */ ++ /* 0x8a0~0x8af [16 bytes] */ ++ u32 rfLSSIReadBackPi; /* LSSI RF readback data PI mode 0x8b8-8bc for ++ * Path A and B */ ++}; ++ ++struct ant_sel_ofdm { ++ u32 r_tx_antenna:4; ++ u32 r_ant_l:4; ++ u32 r_ant_non_ht:4; ++ u32 r_ant_ht1:4; ++ u32 r_ant_ht2:4; ++ u32 r_ant_ht_s1:4; ++ u32 r_ant_non_ht_s1:4; ++ u32 OFDM_TXSC:2; ++ u32 reserved:2; ++}; ++ ++struct ant_sel_cck { ++ u8 r_cckrx_enable_2:2; ++ u8 r_cckrx_enable:2; ++ u8 r_ccktx_enable:4; ++}; ++ ++/*------------------------------Define structure----------------------------*/ ++ ++/*------------------------Export global variable----------------------------*/ ++/*------------------------Export global variable----------------------------*/ ++ ++/*------------------------Export Marco Definition---------------------------*/ ++/*------------------------Export Marco Definition---------------------------*/ ++ ++/*--------------------------Exported Function prototype---------------------*/ ++/* */ ++/* BB and RF register read/write */ ++/* */ ++u32 rtl8188e_PHY_QueryBBReg(struct adapter *adapter, u32 regaddr, u32 mask); ++void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, ++ u32 mask, u32 data); ++u32 rtl8188e_PHY_QueryRFReg(struct adapter *adapter, enum rf_radio_path rfpath, ++ u32 regaddr, u32 mask); ++void rtl8188e_PHY_SetRFReg(struct adapter *adapter, enum rf_radio_path rfpath, ++ u32 regaddr, u32 mask, u32 data); ++ ++/* Initialization related function */ ++/* MAC/BB/RF HAL config */ ++int PHY_MACConfig8188E(struct adapter *adapter); ++int PHY_BBConfig8188E(struct adapter *adapter); ++int PHY_RFConfig8188E(struct adapter *adapter); ++ ++/* RF config */ ++int rtl8188e_PHY_ConfigRFWithParaFile(struct adapter *adapter, u8 *filename, ++ enum rf_radio_path rfpath); ++int rtl8188e_PHY_ConfigRFWithHeaderFile(struct adapter *adapter, ++ enum rf_radio_path rfpath); ++ ++/* Read initi reg value for tx power setting. */ ++void rtl8192c_PHY_GetHWRegOriginalValue(struct adapter *adapter); ++ ++/* BB TX Power R/W */ ++void PHY_GetTxPowerLevel8188E(struct adapter *adapter, u32 *powerlevel); ++void PHY_SetTxPowerLevel8188E(struct adapter *adapter, u8 channel); ++bool PHY_UpdateTxPowerDbm8188E(struct adapter *adapter, int power); ++ ++void PHY_ScanOperationBackup8188E(struct adapter *Adapter, u8 Operation); ++ ++/* Switch bandwidth for 8192S */ ++void PHY_SetBWMode8188E(struct adapter *adapter, ++ enum ht_channel_width chnlwidth, unsigned char offset); ++ ++/* channel switch related funciton */ ++void PHY_SwChnl8188E(struct adapter *adapter, u8 channel); ++/* Call after initialization */ ++void ChkFwCmdIoDone(struct adapter *adapter); ++ ++/* BB/MAC/RF other monitor API */ ++void PHY_SetRFPathSwitch_8188E(struct adapter *adapter, bool main); ++ ++void PHY_SwitchEphyParameter(struct adapter *adapter); ++ ++void PHY_EnableHostClkReq(struct adapter *adapter); ++ ++bool SetAntennaConfig92C(struct adapter *adapter, u8 defaultant); ++ ++void storePwrIndexDiffRateOffset(struct adapter *adapter, u32 regaddr, ++ u32 mask, u32 data); ++/*--------------------------Exported Function prototype---------------------*/ ++ ++#define PHY_QueryBBReg(adapt, regaddr, mask) \ ++ rtl8188e_PHY_QueryBBReg((adapt), (regaddr), (mask)) ++#define PHY_SetBBReg(adapt, regaddr, bitmask, data) \ ++ rtl8188e_PHY_SetBBReg((adapt), (regaddr), (bitmask), (data)) ++#define PHY_QueryRFReg(adapt, rfpath, regaddr, bitmask) \ ++ rtl8188e_PHY_QueryRFReg((adapt), (rfpath), (regaddr), (bitmask)) ++#define PHY_SetRFReg(adapt, rfpath, regaddr, bitmask, data) \ ++ rtl8188e_PHY_SetRFReg((adapt), (rfpath), (regaddr), (bitmask), (data)) ++ ++#define PHY_SetMacReg PHY_SetBBReg ++ ++#define SIC_HW_SUPPORT 0 ++ ++#define SIC_MAX_POLL_CNT 5 ++ ++#define SIC_CMD_READY 0 ++#define SIC_CMD_WRITE 1 ++#define SIC_CMD_READ 2 ++ ++#define SIC_CMD_REG 0x1EB /* 1byte */ ++#define SIC_ADDR_REG 0x1E8 /* 1b9~1ba, 2 bytes */ ++#define SIC_DATA_REG 0x1EC /* 1bc~1bf */ ++ ++#endif /* __INC_HAL8192CPHYCFG_H */ +diff --git a/drivers/staging/r8188eu/include/Hal8188EPhyReg.h b/drivers/staging/r8188eu/include/Hal8188EPhyReg.h +new file mode 100644 +index 000000000000..8b8c75a1f149 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/Hal8188EPhyReg.h +@@ -0,0 +1,1072 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __INC_HAL8188EPHYREG_H__ ++#define __INC_HAL8188EPHYREG_H__ ++/*--------------------------Define Parameters-------------------------------*/ ++/* */ ++/* BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF */ ++/* 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF */ ++/* 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 */ ++/* 3. RF register 0x00-2E */ ++/* 4. Bit Mask for BB/RF register */ ++/* 5. Other definition for BB/RF R/W */ ++/* */ ++ ++/* */ ++/* 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF */ ++/* 1. Page1(0x100) */ ++/* */ ++#define rPMAC_Reset 0x100 ++#define rPMAC_TxStart 0x104 ++#define rPMAC_TxLegacySIG 0x108 ++#define rPMAC_TxHTSIG1 0x10c ++#define rPMAC_TxHTSIG2 0x110 ++#define rPMAC_PHYDebug 0x114 ++#define rPMAC_TxPacketNum 0x118 ++#define rPMAC_TxIdle 0x11c ++#define rPMAC_TxMACHeader0 0x120 ++#define rPMAC_TxMACHeader1 0x124 ++#define rPMAC_TxMACHeader2 0x128 ++#define rPMAC_TxMACHeader3 0x12c ++#define rPMAC_TxMACHeader4 0x130 ++#define rPMAC_TxMACHeader5 0x134 ++#define rPMAC_TxDataType 0x138 ++#define rPMAC_TxRandomSeed 0x13c ++#define rPMAC_CCKPLCPPreamble 0x140 ++#define rPMAC_CCKPLCPHeader 0x144 ++#define rPMAC_CCKCRC16 0x148 ++#define rPMAC_OFDMRxCRC32OK 0x170 ++#define rPMAC_OFDMRxCRC32Er 0x174 ++#define rPMAC_OFDMRxParityEr 0x178 ++#define rPMAC_OFDMRxCRC8Er 0x17c ++#define rPMAC_CCKCRxRC16Er 0x180 ++#define rPMAC_CCKCRxRC32Er 0x184 ++#define rPMAC_CCKCRxRC32OK 0x188 ++#define rPMAC_TxStatus 0x18c ++ ++/* 2. Page2(0x200) */ ++/* The following two definition are only used for USB interface. */ ++#define RF_BB_CMD_ADDR 0x02c0 /* RF/BB r/w cmd address. */ ++#define RF_BB_CMD_DATA 0x02c4 /* RF/BB r/w cmd data. */ ++ ++/* 3. Page8(0x800) */ ++#define rFPGA0_RFMOD 0x800 /* RF mode & CCK TxSC RF BW Setting */ ++ ++#define rFPGA0_TxInfo 0x804 /* Status report?? */ ++#define rFPGA0_PSDFunction 0x808 ++ ++#define rFPGA0_TxGainStage 0x80c /* Set TX PWR init gain? */ ++ ++#define rFPGA0_RFTiming1 0x810 /* Useless now */ ++#define rFPGA0_RFTiming2 0x814 ++ ++#define rFPGA0_XA_HSSIParameter1 0x820 /* RF 3 wire register */ ++#define rFPGA0_XA_HSSIParameter2 0x824 ++#define rFPGA0_XB_HSSIParameter1 0x828 ++#define rFPGA0_XB_HSSIParameter2 0x82c ++ ++#define rFPGA0_XA_LSSIParameter 0x840 ++#define rFPGA0_XB_LSSIParameter 0x844 ++ ++#define rFPGA0_RFWakeUpParameter 0x850 /* Useless now */ ++#define rFPGA0_RFSleepUpParameter 0x854 ++ ++#define rFPGA0_XAB_SwitchControl 0x858 /* RF Channel switch */ ++#define rFPGA0_XCD_SwitchControl 0x85c ++ ++#define rFPGA0_XA_RFInterfaceOE 0x860 /* RF Channel switch */ ++#define rFPGA0_XB_RFInterfaceOE 0x864 ++ ++#define rFPGA0_XAB_RFInterfaceSW 0x870 /* RF Iface Software Control */ ++#define rFPGA0_XCD_RFInterfaceSW 0x874 ++ ++#define rFPGA0_XAB_RFParameter 0x878 /* RF Parameter */ ++#define rFPGA0_XCD_RFParameter 0x87c ++ ++/* Crystal cap setting RF-R/W protection for parameter4?? */ ++#define rFPGA0_AnalogParameter1 0x880 ++#define rFPGA0_AnalogParameter2 0x884 ++#define rFPGA0_AnalogParameter3 0x888 ++/* enable ad/da clock1 for dual-phy */ ++#define rFPGA0_AdDaClockEn 0x888 ++#define rFPGA0_AnalogParameter4 0x88c ++ ++#define rFPGA0_XA_LSSIReadBack 0x8a0 /* Tranceiver LSSI Readback */ ++#define rFPGA0_XB_LSSIReadBack 0x8a4 ++#define rFPGA0_XC_LSSIReadBack 0x8a8 ++#define rFPGA0_XD_LSSIReadBack 0x8ac ++ ++#define rFPGA0_PSDReport 0x8b4 /* Useless now */ ++/* Transceiver A HSPI Readback */ ++#define TransceiverA_HSPI_Readback 0x8b8 ++/* Transceiver B HSPI Readback */ ++#define TransceiverB_HSPI_Readback 0x8bc ++/* Useless now RF Interface Readback Value */ ++#define rFPGA0_XAB_RFInterfaceRB 0x8e0 ++#define rFPGA0_XCD_RFInterfaceRB 0x8e4 /* Useless now */ ++ ++/* 4. Page9(0x900) */ ++/* RF mode & OFDM TxSC RF BW Setting?? */ ++#define rFPGA1_RFMOD 0x900 ++ ++#define rFPGA1_TxBlock 0x904 /* Useless now */ ++#define rFPGA1_DebugSelect 0x908 /* Useless now */ ++#define rFPGA1_TxInfo 0x90c /* Useless now Status report */ ++ ++/* 5. PageA(0xA00) */ ++/* Set Control channel to upper or lower - required only for 40MHz */ ++#define rCCK0_System 0xa00 ++ ++/* Disable init gain now Select RX path by RSSI */ ++#define rCCK0_AFESetting 0xa04 ++/* Disable init gain now Init gain */ ++#define rCCK0_CCA 0xa08 ++ ++/* AGC default value, saturation level Antenna Diversity, RX AGC, LNA Threshold, ++ * RX LNA Threshold useless now. Not the same as 90 series */ ++#define rCCK0_RxAGC1 0xa0c ++#define rCCK0_RxAGC2 0xa10 /* AGC & DAGC */ ++ ++#define rCCK0_RxHP 0xa14 ++ ++/* Timing recovery & Channel estimation threshold */ ++#define rCCK0_DSPParameter1 0xa18 ++#define rCCK0_DSPParameter2 0xa1c /* SQ threshold */ ++ ++#define rCCK0_TxFilter1 0xa20 ++#define rCCK0_TxFilter2 0xa24 ++#define rCCK0_DebugPort 0xa28 /* debug port and Tx filter3 */ ++#define rCCK0_FalseAlarmReport 0xa2c /* 0xa2d useless now */ ++#define rCCK0_TRSSIReport 0xa50 ++#define rCCK0_RxReport 0xa54 /* 0xa57 */ ++#define rCCK0_FACounterLower 0xa5c /* 0xa5b */ ++#define rCCK0_FACounterUpper 0xa58 /* 0xa5c */ ++ ++/* */ ++/* PageB(0xB00) */ ++/* */ ++#define rPdp_AntA 0xb00 ++#define rPdp_AntA_4 0xb04 ++#define rConfig_Pmpd_AntA 0xb28 ++#define rConfig_AntA 0xb68 ++#define rConfig_AntB 0xb6c ++#define rPdp_AntB 0xb70 ++#define rPdp_AntB_4 0xb74 ++#define rConfig_Pmpd_AntB 0xb98 ++#define rAPK 0xbd8 ++ ++/* */ ++/* 6. PageC(0xC00) */ ++/* */ ++#define rOFDM0_LSTF 0xc00 ++ ++#define rOFDM0_TRxPathEnable 0xc04 ++#define rOFDM0_TRMuxPar 0xc08 ++#define rOFDM0_TRSWIsolation 0xc0c ++ ++/* RxIQ DC offset, Rx digital filter, DC notch filter */ ++#define rOFDM0_XARxAFE 0xc10 ++#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imblance matrix */ ++#define rOFDM0_XBRxAFE 0xc18 ++#define rOFDM0_XBRxIQImbalance 0xc1c ++#define rOFDM0_XCRxAFE 0xc20 ++#define rOFDM0_XCRxIQImbalance 0xc24 ++#define rOFDM0_XDRxAFE 0xc28 ++#define rOFDM0_XDRxIQImbalance 0xc2c ++ ++#define rOFDM0_RxDetector1 0xc30 /*PD,BW & SBD DM tune init gain*/ ++#define rOFDM0_RxDetector2 0xc34 /* SBD & Fame Sync. */ ++#define rOFDM0_RxDetector3 0xc38 /* Frame Sync. */ ++#define rOFDM0_RxDetector4 0xc3c /* PD, SBD, Frame Sync & Short-GI */ ++ ++#define rOFDM0_RxDSP 0xc40 /* Rx Sync Path */ ++#define rOFDM0_CFOandDAGC 0xc44 /* CFO & DAGC */ ++#define rOFDM0_CCADropThreshold 0xc48 /* CCA Drop threshold */ ++#define rOFDM0_ECCAThreshold 0xc4c /* energy CCA */ ++ ++#define rOFDM0_XAAGCCore1 0xc50 /* DIG */ ++#define rOFDM0_XAAGCCore2 0xc54 ++#define rOFDM0_XBAGCCore1 0xc58 ++#define rOFDM0_XBAGCCore2 0xc5c ++#define rOFDM0_XCAGCCore1 0xc60 ++#define rOFDM0_XCAGCCore2 0xc64 ++#define rOFDM0_XDAGCCore1 0xc68 ++#define rOFDM0_XDAGCCore2 0xc6c ++ ++#define rOFDM0_AGCParameter1 0xc70 ++#define rOFDM0_AGCParameter2 0xc74 ++#define rOFDM0_AGCRSSITable 0xc78 ++#define rOFDM0_HTSTFAGC 0xc7c ++ ++#define rOFDM0_XATxIQImbalance 0xc80 /* TX PWR TRACK and DIG */ ++#define rOFDM0_XATxAFE 0xc84 ++#define rOFDM0_XBTxIQImbalance 0xc88 ++#define rOFDM0_XBTxAFE 0xc8c ++#define rOFDM0_XCTxIQImbalance 0xc90 ++#define rOFDM0_XCTxAFE 0xc94 ++#define rOFDM0_XDTxIQImbalance 0xc98 ++#define rOFDM0_XDTxAFE 0xc9c ++ ++#define rOFDM0_RxIQExtAnta 0xca0 ++#define rOFDM0_TxCoeff1 0xca4 ++#define rOFDM0_TxCoeff2 0xca8 ++#define rOFDM0_TxCoeff3 0xcac ++#define rOFDM0_TxCoeff4 0xcb0 ++#define rOFDM0_TxCoeff5 0xcb4 ++#define rOFDM0_TxCoeff6 0xcb8 ++#define rOFDM0_RxHPParameter 0xce0 ++#define rOFDM0_TxPseudoNoiseWgt 0xce4 ++#define rOFDM0_FrameSync 0xcf0 ++#define rOFDM0_DFSReport 0xcf4 ++ ++/* */ ++/* 7. PageD(0xD00) */ ++/* */ ++#define rOFDM1_LSTF 0xd00 ++#define rOFDM1_TRxPathEnable 0xd04 ++ ++#define rOFDM1_CFO 0xd08 /* No setting now */ ++#define rOFDM1_CSI1 0xd10 ++#define rOFDM1_SBD 0xd14 ++#define rOFDM1_CSI2 0xd18 ++#define rOFDM1_CFOTracking 0xd2c ++#define rOFDM1_TRxMesaure1 0xd34 ++#define rOFDM1_IntfDet 0xd3c ++#define rOFDM1_PseudoNoiseStateAB 0xd50 ++#define rOFDM1_PseudoNoiseStateCD 0xd54 ++#define rOFDM1_RxPseudoNoiseWgt 0xd58 ++ ++#define rOFDM_PHYCounter1 0xda0 /* cca, parity fail */ ++#define rOFDM_PHYCounter2 0xda4 /* rate illegal, crc8 fail */ ++#define rOFDM_PHYCounter3 0xda8 /* MCS not support */ ++ ++#define rOFDM_ShortCFOAB 0xdac /* No setting now */ ++#define rOFDM_ShortCFOCD 0xdb0 ++#define rOFDM_LongCFOAB 0xdb4 ++#define rOFDM_LongCFOCD 0xdb8 ++#define rOFDM_TailCFOAB 0xdbc ++#define rOFDM_TailCFOCD 0xdc0 ++#define rOFDM_PWMeasure1 0xdc4 ++#define rOFDM_PWMeasure2 0xdc8 ++#define rOFDM_BWReport 0xdcc ++#define rOFDM_AGCReport 0xdd0 ++#define rOFDM_RxSNR 0xdd4 ++#define rOFDM_RxEVMCSI 0xdd8 ++#define rOFDM_SIGReport 0xddc ++ ++/* */ ++/* 8. PageE(0xE00) */ ++/* */ ++#define rTxAGC_A_Rate18_06 0xe00 ++#define rTxAGC_A_Rate54_24 0xe04 ++#define rTxAGC_A_CCK1_Mcs32 0xe08 ++#define rTxAGC_A_Mcs03_Mcs00 0xe10 ++#define rTxAGC_A_Mcs07_Mcs04 0xe14 ++#define rTxAGC_A_Mcs11_Mcs08 0xe18 ++#define rTxAGC_A_Mcs15_Mcs12 0xe1c ++ ++#define rTxAGC_B_Rate18_06 0x830 ++#define rTxAGC_B_Rate54_24 0x834 ++#define rTxAGC_B_CCK1_55_Mcs32 0x838 ++#define rTxAGC_B_Mcs03_Mcs00 0x83c ++#define rTxAGC_B_Mcs07_Mcs04 0x848 ++#define rTxAGC_B_Mcs11_Mcs08 0x84c ++#define rTxAGC_B_Mcs15_Mcs12 0x868 ++#define rTxAGC_B_CCK11_A_CCK2_11 0x86c ++ ++#define rFPGA0_IQK 0xe28 ++#define rTx_IQK_Tone_A 0xe30 ++#define rRx_IQK_Tone_A 0xe34 ++#define rTx_IQK_PI_A 0xe38 ++#define rRx_IQK_PI_A 0xe3c ++ ++#define rTx_IQK 0xe40 ++#define rRx_IQK 0xe44 ++#define rIQK_AGC_Pts 0xe48 ++#define rIQK_AGC_Rsp 0xe4c ++#define rTx_IQK_Tone_B 0xe50 ++#define rRx_IQK_Tone_B 0xe54 ++#define rTx_IQK_PI_B 0xe58 ++#define rRx_IQK_PI_B 0xe5c ++#define rIQK_AGC_Cont 0xe60 ++ ++#define rBlue_Tooth 0xe6c ++#define rRx_Wait_CCA 0xe70 ++#define rTx_CCK_RFON 0xe74 ++#define rTx_CCK_BBON 0xe78 ++#define rTx_OFDM_RFON 0xe7c ++#define rTx_OFDM_BBON 0xe80 ++#define rTx_To_Rx 0xe84 ++#define rTx_To_Tx 0xe88 ++#define rRx_CCK 0xe8c ++ ++#define rTx_Power_Before_IQK_A 0xe94 ++#define rTx_Power_After_IQK_A 0xe9c ++ ++#define rRx_Power_Before_IQK_A 0xea0 ++#define rRx_Power_Before_IQK_A_2 0xea4 ++#define rRx_Power_After_IQK_A 0xea8 ++#define rRx_Power_After_IQK_A_2 0xeac ++ ++#define rTx_Power_Before_IQK_B 0xeb4 ++#define rTx_Power_After_IQK_B 0xebc ++ ++#define rRx_Power_Before_IQK_B 0xec0 ++#define rRx_Power_Before_IQK_B_2 0xec4 ++#define rRx_Power_After_IQK_B 0xec8 ++#define rRx_Power_After_IQK_B_2 0xecc ++ ++#define rRx_OFDM 0xed0 ++#define rRx_Wait_RIFS 0xed4 ++#define rRx_TO_Rx 0xed8 ++#define rStandby 0xedc ++#define rSleep 0xee0 ++#define rPMPD_ANAEN 0xeec ++ ++/* */ ++/* 7. RF Register 0x00-0x2E (RF 8256) */ ++/* RF-0222D 0x00-3F */ ++/* */ ++/* Zebra1 */ ++#define rZebra1_HSSIEnable 0x0 /* Useless now */ ++#define rZebra1_TRxEnable1 0x1 ++#define rZebra1_TRxEnable2 0x2 ++#define rZebra1_AGC 0x4 ++#define rZebra1_ChargePump 0x5 ++#define rZebra1_Channel 0x7 /* RF channel switch */ ++ ++/* endif */ ++#define rZebra1_TxGain 0x8 /* Useless now */ ++#define rZebra1_TxLPF 0x9 ++#define rZebra1_RxLPF 0xb ++#define rZebra1_RxHPFCorner 0xc ++ ++/* Zebra4 */ ++#define rGlobalCtrl 0 /* Useless now */ ++#define rRTL8256_TxLPF 19 ++#define rRTL8256_RxLPF 11 ++ ++/* RTL8258 */ ++#define rRTL8258_TxLPF 0x11 /* Useless now */ ++#define rRTL8258_RxLPF 0x13 ++#define rRTL8258_RSSILPF 0xa ++ ++/* */ ++/* RL6052 Register definition */ ++/* */ ++#define RF_AC 0x00 /* */ ++ ++#define RF_IQADJ_G1 0x01 /* */ ++#define RF_IQADJ_G2 0x02 /* */ ++ ++#define RF_POW_TRSW 0x05 /* */ ++ ++#define RF_GAIN_RX 0x06 /* */ ++#define RF_GAIN_TX 0x07 /* */ ++ ++#define RF_TXM_IDAC 0x08 /* */ ++#define RF_IPA_G 0x09 /* */ ++#define RF_TXBIAS_G 0x0A ++#define RF_TXPA_AG 0x0B ++#define RF_IPA_A 0x0C /* */ ++#define RF_TXBIAS_A 0x0D ++#define RF_BS_PA_APSET_G9_G11 0x0E ++#define RF_BS_IQGEN 0x0F /* */ ++ ++#define RF_MODE1 0x10 /* */ ++#define RF_MODE2 0x11 /* */ ++ ++#define RF_RX_AGC_HP 0x12 /* */ ++#define RF_TX_AGC 0x13 /* */ ++#define RF_BIAS 0x14 /* */ ++#define RF_IPA 0x15 /* */ ++#define RF_TXBIAS 0x16 ++#define RF_POW_ABILITY 0x17 /* */ ++#define RF_CHNLBW 0x18 /* RF channel and BW switch */ ++#define RF_TOP 0x19 /* */ ++ ++#define RF_RX_G1 0x1A /* */ ++#define RF_RX_G2 0x1B /* */ ++ ++#define RF_RX_BB2 0x1C /* */ ++#define RF_RX_BB1 0x1D /* */ ++ ++#define RF_RCK1 0x1E /* */ ++#define RF_RCK2 0x1F /* */ ++ ++#define RF_TX_G1 0x20 /* */ ++#define RF_TX_G2 0x21 /* */ ++#define RF_TX_G3 0x22 /* */ ++ ++#define RF_TX_BB1 0x23 /* */ ++ ++#define RF_T_METER_92D 0x42 /* */ ++#define RF_T_METER_88E 0x42 /* */ ++#define RF_T_METER 0x24 /* */ ++ ++#define RF_SYN_G1 0x25 /* RF TX Power control */ ++#define RF_SYN_G2 0x26 /* RF TX Power control */ ++#define RF_SYN_G3 0x27 /* RF TX Power control */ ++#define RF_SYN_G4 0x28 /* RF TX Power control */ ++#define RF_SYN_G5 0x29 /* RF TX Power control */ ++#define RF_SYN_G6 0x2A /* RF TX Power control */ ++#define RF_SYN_G7 0x2B /* RF TX Power control */ ++#define RF_SYN_G8 0x2C /* RF TX Power control */ ++ ++#define RF_RCK_OS 0x30 /* RF TX PA control */ ++#define RF_TXPA_G1 0x31 /* RF TX PA control */ ++#define RF_TXPA_G2 0x32 /* RF TX PA control */ ++#define RF_TXPA_G3 0x33 /* RF TX PA control */ ++#define RF_TX_BIAS_A 0x35 ++#define RF_TX_BIAS_D 0x36 ++#define RF_LOBF_9 0x38 ++#define RF_RXRF_A3 0x3C /* */ ++#define RF_TRSW 0x3F ++ ++#define RF_TXRF_A2 0x41 ++#define RF_TXPA_G4 0x46 ++#define RF_TXPA_A4 0x4B ++#define RF_0x52 0x52 ++#define RF_WE_LUT 0xEF ++ ++/* */ ++/* Bit Mask */ ++/* */ ++/* 1. Page1(0x100) */ ++#define bBBResetB 0x100 /* Useless now? */ ++#define bGlobalResetB 0x200 ++#define bOFDMTxStart 0x4 ++#define bCCKTxStart 0x8 ++#define bCRC32Debug 0x100 ++#define bPMACLoopback 0x10 ++#define bTxLSIG 0xffffff ++#define bOFDMTxRate 0xf ++#define bOFDMTxReserved 0x10 ++#define bOFDMTxLength 0x1ffe0 ++#define bOFDMTxParity 0x20000 ++#define bTxHTSIG1 0xffffff ++#define bTxHTMCSRate 0x7f ++#define bTxHTBW 0x80 ++#define bTxHTLength 0xffff00 ++#define bTxHTSIG2 0xffffff ++#define bTxHTSmoothing 0x1 ++#define bTxHTSounding 0x2 ++#define bTxHTReserved 0x4 ++#define bTxHTAggreation 0x8 ++#define bTxHTSTBC 0x30 ++#define bTxHTAdvanceCoding 0x40 ++#define bTxHTShortGI 0x80 ++#define bTxHTNumberHT_LTF 0x300 ++#define bTxHTCRC8 0x3fc00 ++#define bCounterReset 0x10000 ++#define bNumOfOFDMTx 0xffff ++#define bNumOfCCKTx 0xffff0000 ++#define bTxIdleInterval 0xffff ++#define bOFDMService 0xffff0000 ++#define bTxMACHeader 0xffffffff ++#define bTxDataInit 0xff ++#define bTxHTMode 0x100 ++#define bTxDataType 0x30000 ++#define bTxRandomSeed 0xffffffff ++#define bCCKTxPreamble 0x1 ++#define bCCKTxSFD 0xffff0000 ++#define bCCKTxSIG 0xff ++#define bCCKTxService 0xff00 ++#define bCCKLengthExt 0x8000 ++#define bCCKTxLength 0xffff0000 ++#define bCCKTxCRC16 0xffff ++#define bCCKTxStatus 0x1 ++#define bOFDMTxStatus 0x2 ++ ++#define IS_BB_REG_OFFSET_92S(_Offset) \ ++ ((_Offset >= 0x800) && (_Offset <= 0xfff)) ++ ++/* 2. Page8(0x800) */ ++#define bRFMOD 0x1 /* Reg 0x800 rFPGA0_RFMOD */ ++#define bJapanMode 0x2 ++#define bCCKTxSC 0x30 ++#define bCCKEn 0x1000000 ++#define bOFDMEn 0x2000000 ++ ++#define bOFDMRxADCPhase 0x10000 /* Useless now */ ++#define bOFDMTxDACPhase 0x40000 ++#define bXATxAGC 0x3f ++ ++#define bAntennaSelect 0x0300 ++ ++#define bXBTxAGC 0xf00 /* Reg 80c rFPGA0_TxGainStage */ ++#define bXCTxAGC 0xf000 ++#define bXDTxAGC 0xf0000 ++ ++#define bPAStart 0xf0000000 /* Useless now */ ++#define bTRStart 0x00f00000 ++#define bRFStart 0x0000f000 ++#define bBBStart 0x000000f0 ++#define bBBCCKStart 0x0000000f ++#define bPAEnd 0xf /* Reg0x814 */ ++#define bTREnd 0x0f000000 ++#define bRFEnd 0x000f0000 ++#define bCCAMask 0x000000f0 /* T2R */ ++#define bR2RCCAMask 0x00000f00 ++#define bHSSI_R2TDelay 0xf8000000 ++#define bHSSI_T2RDelay 0xf80000 ++#define bContTxHSSI 0x400 /* change gain at continue Tx */ ++#define bIGFromCCK 0x200 ++#define bAGCAddress 0x3f ++#define bRxHPTx 0x7000 ++#define bRxHPT2R 0x38000 ++#define bRxHPCCKIni 0xc0000 ++#define bAGCTxCode 0xc00000 ++#define bAGCRxCode 0x300000 ++ ++/* Reg 0x820~84f rFPGA0_XA_HSSIParameter1 */ ++#define b3WireDataLength 0x800 ++#define b3WireAddressLength 0x400 ++ ++#define b3WireRFPowerDown 0x1 /* Useless now */ ++#define b5GPAPEPolarity 0x40000000 ++#define b2GPAPEPolarity 0x80000000 ++#define bRFSW_TxDefaultAnt 0x3 ++#define bRFSW_TxOptionAnt 0x30 ++#define bRFSW_RxDefaultAnt 0x300 ++#define bRFSW_RxOptionAnt 0x3000 ++#define bRFSI_3WireData 0x1 ++#define bRFSI_3WireClock 0x2 ++#define bRFSI_3WireLoad 0x4 ++#define bRFSI_3WireRW 0x8 ++#define bRFSI_3Wire 0xf ++ ++#define bRFSI_RFENV 0x10 /* Reg 0x870 rFPGA0_XAB_RFInterfaceSW */ ++ ++#define bRFSI_TRSW 0x20 /* Useless now */ ++#define bRFSI_TRSWB 0x40 ++#define bRFSI_ANTSW 0x100 ++#define bRFSI_ANTSWB 0x200 ++#define bRFSI_PAPE 0x400 ++#define bRFSI_PAPE5G 0x800 ++#define bBandSelect 0x1 ++#define bHTSIG2_GI 0x80 ++#define bHTSIG2_Smoothing 0x01 ++#define bHTSIG2_Sounding 0x02 ++#define bHTSIG2_Aggreaton 0x08 ++#define bHTSIG2_STBC 0x30 ++#define bHTSIG2_AdvCoding 0x40 ++#define bHTSIG2_NumOfHTLTF 0x300 ++#define bHTSIG2_CRC8 0x3fc ++#define bHTSIG1_MCS 0x7f ++#define bHTSIG1_BandWidth 0x80 ++#define bHTSIG1_HTLength 0xffff ++#define bLSIG_Rate 0xf ++#define bLSIG_Reserved 0x10 ++#define bLSIG_Length 0x1fffe ++#define bLSIG_Parity 0x20 ++#define bCCKRxPhase 0x4 ++ ++#define bLSSIReadAddress 0x7f800000 /* T65 RF */ ++ ++#define bLSSIReadEdge 0x80000000 /* LSSI "Read" edge signal */ ++ ++#define bLSSIReadBackData 0xfffff /* T65 RF */ ++ ++#define bLSSIReadOKFlag 0x1000 /* Useless now */ ++#define bCCKSampleRate 0x8 /* 0: 44MHz, 1:88MHz */ ++#define bRegulator0Standby 0x1 ++#define bRegulatorPLLStandby 0x2 ++#define bRegulator1Standby 0x4 ++#define bPLLPowerUp 0x8 ++#define bDPLLPowerUp 0x10 ++#define bDA10PowerUp 0x20 ++#define bAD7PowerUp 0x200 ++#define bDA6PowerUp 0x2000 ++#define bXtalPowerUp 0x4000 ++#define b40MDClkPowerUP 0x8000 ++#define bDA6DebugMode 0x20000 ++#define bDA6Swing 0x380000 ++ ++/* Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ */ ++#define bADClkPhase 0x4000000 ++ ++#define b80MClkDelay 0x18000000 /* Useless */ ++#define bAFEWatchDogEnable 0x20000000 ++ ++/* Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap */ ++#define bXtalCap01 0xc0000000 ++#define bXtalCap23 0x3 ++#define bXtalCap92x 0x0f000000 ++#define bXtalCap 0x0f000000 ++ ++#define bIntDifClkEnable 0x400 /* Useless */ ++#define bExtSigClkEnable 0x800 ++#define bBandgapMbiasPowerUp 0x10000 ++#define bAD11SHGain 0xc0000 ++#define bAD11InputRange 0x700000 ++#define bAD11OPCurrent 0x3800000 ++#define bIPathLoopback 0x4000000 ++#define bQPathLoopback 0x8000000 ++#define bAFELoopback 0x10000000 ++#define bDA10Swing 0x7e0 ++#define bDA10Reverse 0x800 ++#define bDAClkSource 0x1000 ++#define bAD7InputRange 0x6000 ++#define bAD7Gain 0x38000 ++#define bAD7OutputCMMode 0x40000 ++#define bAD7InputCMMode 0x380000 ++#define bAD7Current 0xc00000 ++#define bRegulatorAdjust 0x7000000 ++#define bAD11PowerUpAtTx 0x1 ++#define bDA10PSAtTx 0x10 ++#define bAD11PowerUpAtRx 0x100 ++#define bDA10PSAtRx 0x1000 ++#define bCCKRxAGCFormat 0x200 ++#define bPSDFFTSamplepPoint 0xc000 ++#define bPSDAverageNum 0x3000 ++#define bIQPathControl 0xc00 ++#define bPSDFreq 0x3ff ++#define bPSDAntennaPath 0x30 ++#define bPSDIQSwitch 0x40 ++#define bPSDRxTrigger 0x400000 ++#define bPSDTxTrigger 0x80000000 ++#define bPSDSineToneScale 0x7f000000 ++#define bPSDReport 0xffff ++ ++/* 3. Page9(0x900) */ ++#define bOFDMTxSC 0x30000000 /* Useless */ ++#define bCCKTxOn 0x1 ++#define bOFDMTxOn 0x2 ++#define bDebugPage 0xfff /* reset debug page and HWord, LWord */ ++#define bDebugItem 0xff /* reset debug page and LWord */ ++#define bAntL 0x10 ++#define bAntNonHT 0x100 ++#define bAntHT1 0x1000 ++#define bAntHT2 0x10000 ++#define bAntHT1S1 0x100000 ++#define bAntNonHTS1 0x1000000 ++ ++/* 4. PageA(0xA00) */ ++#define bCCKBBMode 0x3 /* Useless */ ++#define bCCKTxPowerSaving 0x80 ++#define bCCKRxPowerSaving 0x40 ++ ++#define bCCKSideBand 0x10 /* Reg 0xa00 rCCK0_System 20/40 */ ++ ++#define bCCKScramble 0x8 /* Useless */ ++#define bCCKAntDiversity 0x8000 ++#define bCCKCarrierRecovery 0x4000 ++#define bCCKTxRate 0x3000 ++#define bCCKDCCancel 0x0800 ++#define bCCKISICancel 0x0400 ++#define bCCKMatchFilter 0x0200 ++#define bCCKEqualizer 0x0100 ++#define bCCKPreambleDetect 0x800000 ++#define bCCKFastFalseCCA 0x400000 ++#define bCCKChEstStart 0x300000 ++#define bCCKCCACount 0x080000 ++#define bCCKcs_lim 0x070000 ++#define bCCKBistMode 0x80000000 ++#define bCCKCCAMask 0x40000000 ++#define bCCKTxDACPhase 0x4 ++#define bCCKRxADCPhase 0x20000000 /* r_rx_clk */ ++#define bCCKr_cp_mode0 0x0100 ++#define bCCKTxDCOffset 0xf0 ++#define bCCKRxDCOffset 0xf ++#define bCCKCCAMode 0xc000 ++#define bCCKFalseCS_lim 0x3f00 ++#define bCCKCS_ratio 0xc00000 ++#define bCCKCorgBit_sel 0x300000 ++#define bCCKPD_lim 0x0f0000 ++#define bCCKNewCCA 0x80000000 ++#define bCCKRxHPofIG 0x8000 ++#define bCCKRxIG 0x7f00 ++#define bCCKLNAPolarity 0x800000 ++#define bCCKRx1stGain 0x7f0000 ++#define bCCKRFExtend 0x20000000 /* CCK Rx Iinital gain polarity */ ++#define bCCKRxAGCSatLevel 0x1f000000 ++#define bCCKRxAGCSatCount 0xe0 ++#define bCCKRxRFSettle 0x1f /* AGCsamp_dly */ ++#define bCCKFixedRxAGC 0x8000 ++#define bCCKAntennaPolarity 0x2000 ++#define bCCKTxFilterType 0x0c00 ++#define bCCKRxAGCReportType 0x0300 ++#define bCCKRxDAGCEn 0x80000000 ++#define bCCKRxDAGCPeriod 0x20000000 ++#define bCCKRxDAGCSatLevel 0x1f000000 ++#define bCCKTimingRecovery 0x800000 ++#define bCCKTxC0 0x3f0000 ++#define bCCKTxC1 0x3f000000 ++#define bCCKTxC2 0x3f ++#define bCCKTxC3 0x3f00 ++#define bCCKTxC4 0x3f0000 ++#define bCCKTxC5 0x3f000000 ++#define bCCKTxC6 0x3f ++#define bCCKTxC7 0x3f00 ++#define bCCKDebugPort 0xff0000 ++#define bCCKDACDebug 0x0f000000 ++#define bCCKFalseAlarmEnable 0x8000 ++#define bCCKFalseAlarmRead 0x4000 ++#define bCCKTRSSI 0x7f ++#define bCCKRxAGCReport 0xfe ++#define bCCKRxReport_AntSel 0x80000000 ++#define bCCKRxReport_MFOff 0x40000000 ++#define bCCKRxRxReport_SQLoss 0x20000000 ++#define bCCKRxReport_Pktloss 0x10000000 ++#define bCCKRxReport_Lockedbit 0x08000000 ++#define bCCKRxReport_RateError 0x04000000 ++#define bCCKRxReport_RxRate 0x03000000 ++#define bCCKRxFACounterLower 0xff ++#define bCCKRxFACounterUpper 0xff000000 ++#define bCCKRxHPAGCStart 0xe000 ++#define bCCKRxHPAGCFinal 0x1c00 ++#define bCCKRxFalseAlarmEnable 0x8000 ++#define bCCKFACounterFreeze 0x4000 ++#define bCCKTxPathSel 0x10000000 ++#define bCCKDefaultRxPath 0xc000000 ++#define bCCKOptionRxPath 0x3000000 ++ ++/* 5. PageC(0xC00) */ ++#define bNumOfSTF 0x3 /* Useless */ ++#define bShift_L 0xc0 ++#define bGI_TH 0xc ++#define bRxPathA 0x1 ++#define bRxPathB 0x2 ++#define bRxPathC 0x4 ++#define bRxPathD 0x8 ++#define bTxPathA 0x1 ++#define bTxPathB 0x2 ++#define bTxPathC 0x4 ++#define bTxPathD 0x8 ++#define bTRSSIFreq 0x200 ++#define bADCBackoff 0x3000 ++#define bDFIRBackoff 0xc000 ++#define bTRSSILatchPhase 0x10000 ++#define bRxIDCOffset 0xff ++#define bRxQDCOffset 0xff00 ++#define bRxDFIRMode 0x1800000 ++#define bRxDCNFType 0xe000000 ++#define bRXIQImb_A 0x3ff ++#define bRXIQImb_B 0xfc00 ++#define bRXIQImb_C 0x3f0000 ++#define bRXIQImb_D 0xffc00000 ++#define bDC_dc_Notch 0x60000 ++#define bRxNBINotch 0x1f000000 ++#define bPD_TH 0xf ++#define bPD_TH_Opt2 0xc000 ++#define bPWED_TH 0x700 ++#define bIfMF_Win_L 0x800 ++#define bPD_Option 0x1000 ++#define bMF_Win_L 0xe000 ++#define bBW_Search_L 0x30000 ++#define bwin_enh_L 0xc0000 ++#define bBW_TH 0x700000 ++#define bED_TH2 0x3800000 ++#define bBW_option 0x4000000 ++#define bRatio_TH 0x18000000 ++#define bWindow_L 0xe0000000 ++#define bSBD_Option 0x1 ++#define bFrame_TH 0x1c ++#define bFS_Option 0x60 ++#define bDC_Slope_check 0x80 ++#define bFGuard_Counter_DC_L 0xe00 ++#define bFrame_Weight_Short 0x7000 ++#define bSub_Tune 0xe00000 ++#define bFrame_DC_Length 0xe000000 ++#define bSBD_start_offset 0x30000000 ++#define bFrame_TH_2 0x7 ++#define bFrame_GI2_TH 0x38 ++#define bGI2_Sync_en 0x40 ++#define bSarch_Short_Early 0x300 ++#define bSarch_Short_Late 0xc00 ++#define bSarch_GI2_Late 0x70000 ++#define bCFOAntSum 0x1 ++#define bCFOAcc 0x2 ++#define bCFOStartOffset 0xc ++#define bCFOLookBack 0x70 ++#define bCFOSumWeight 0x80 ++#define bDAGCEnable 0x10000 ++#define bTXIQImb_A 0x3ff ++#define bTXIQImb_B 0xfc00 ++#define bTXIQImb_C 0x3f0000 ++#define bTXIQImb_D 0xffc00000 ++#define bTxIDCOffset 0xff ++#define bTxQDCOffset 0xff00 ++#define bTxDFIRMode 0x10000 ++#define bTxPesudoNoiseOn 0x4000000 ++#define bTxPesudoNoise_A 0xff ++#define bTxPesudoNoise_B 0xff00 ++#define bTxPesudoNoise_C 0xff0000 ++#define bTxPesudoNoise_D 0xff000000 ++#define bCCADropOption 0x20000 ++#define bCCADropThres 0xfff00000 ++#define bEDCCA_H 0xf ++#define bEDCCA_L 0xf0 ++#define bLambda_ED 0x300 ++#define bRxInitialGain 0x7f ++#define bRxAntDivEn 0x80 ++#define bRxAGCAddressForLNA 0x7f00 ++#define bRxHighPowerFlow 0x8000 ++#define bRxAGCFreezeThres 0xc0000 ++#define bRxFreezeStep_AGC1 0x300000 ++#define bRxFreezeStep_AGC2 0xc00000 ++#define bRxFreezeStep_AGC3 0x3000000 ++#define bRxFreezeStep_AGC0 0xc000000 ++#define bRxRssi_Cmp_En 0x10000000 ++#define bRxQuickAGCEn 0x20000000 ++#define bRxAGCFreezeThresMode 0x40000000 ++#define bRxOverFlowCheckType 0x80000000 ++#define bRxAGCShift 0x7f ++#define bTRSW_Tri_Only 0x80 ++#define bPowerThres 0x300 ++#define bRxAGCEn 0x1 ++#define bRxAGCTogetherEn 0x2 ++#define bRxAGCMin 0x4 ++#define bRxHP_Ini 0x7 ++#define bRxHP_TRLNA 0x70 ++#define bRxHP_RSSI 0x700 ++#define bRxHP_BBP1 0x7000 ++#define bRxHP_BBP2 0x70000 ++#define bRxHP_BBP3 0x700000 ++#define bRSSI_H 0x7f0000 /* threshold for high power */ ++#define bRSSI_Gen 0x7f000000 /* threshold for ant diversity */ ++#define bRxSettle_TRSW 0x7 ++#define bRxSettle_LNA 0x38 ++#define bRxSettle_RSSI 0x1c0 ++#define bRxSettle_BBP 0xe00 ++#define bRxSettle_RxHP 0x7000 ++#define bRxSettle_AntSW_RSSI 0x38000 ++#define bRxSettle_AntSW 0xc0000 ++#define bRxProcessTime_DAGC 0x300000 ++#define bRxSettle_HSSI 0x400000 ++#define bRxProcessTime_BBPPW 0x800000 ++#define bRxAntennaPowerShift 0x3000000 ++#define bRSSITableSelect 0xc000000 ++#define bRxHP_Final 0x7000000 ++#define bRxHTSettle_BBP 0x7 ++#define bRxHTSettle_HSSI 0x8 ++#define bRxHTSettle_RxHP 0x70 ++#define bRxHTSettle_BBPPW 0x80 ++#define bRxHTSettle_Idle 0x300 ++#define bRxHTSettle_Reserved 0x1c00 ++#define bRxHTRxHPEn 0x8000 ++#define bRxHTAGCFreezeThres 0x30000 ++#define bRxHTAGCTogetherEn 0x40000 ++#define bRxHTAGCMin 0x80000 ++#define bRxHTAGCEn 0x100000 ++#define bRxHTDAGCEn 0x200000 ++#define bRxHTRxHP_BBP 0x1c00000 ++#define bRxHTRxHP_Final 0xe0000000 ++#define bRxPWRatioTH 0x3 ++#define bRxPWRatioEn 0x4 ++#define bRxMFHold 0x3800 ++#define bRxPD_Delay_TH1 0x38 ++#define bRxPD_Delay_TH2 0x1c0 ++#define bRxPD_DC_COUNT_MAX 0x600 ++#define bRxPD_Delay_TH 0x8000 ++#define bRxProcess_Delay 0xf0000 ++#define bRxSearchrange_GI2_Early 0x700000 ++#define bRxFrame_Guard_Counter_L 0x3800000 ++#define bRxSGI_Guard_L 0xc000000 ++#define bRxSGI_Search_L 0x30000000 ++#define bRxSGI_TH 0xc0000000 ++#define bDFSCnt0 0xff ++#define bDFSCnt1 0xff00 ++#define bDFSFlag 0xf0000 ++#define bMFWeightSum 0x300000 ++#define bMinIdxTH 0x7f000000 ++#define bDAFormat 0x40000 ++#define bTxChEmuEnable 0x01000000 ++#define bTRSWIsolation_A 0x7f ++#define bTRSWIsolation_B 0x7f00 ++#define bTRSWIsolation_C 0x7f0000 ++#define bTRSWIsolation_D 0x7f000000 ++#define bExtLNAGain 0x7c00 ++ ++/* 6. PageE(0xE00) */ ++#define bSTBCEn 0x4 /* Useless */ ++#define bAntennaMapping 0x10 ++#define bNss 0x20 ++#define bCFOAntSumD 0x200 ++#define bPHYCounterReset 0x8000000 ++#define bCFOReportGet 0x4000000 ++#define bOFDMContinueTx 0x10000000 ++#define bOFDMSingleCarrier 0x20000000 ++#define bOFDMSingleTone 0x40000000 ++#define bHTDetect 0x100 ++#define bCFOEn 0x10000 ++#define bCFOValue 0xfff00000 ++#define bSigTone_Re 0x3f ++#define bSigTone_Im 0x7f00 ++#define bCounter_CCA 0xffff ++#define bCounter_ParityFail 0xffff0000 ++#define bCounter_RateIllegal 0xffff ++#define bCounter_CRC8Fail 0xffff0000 ++#define bCounter_MCSNoSupport 0xffff ++#define bCounter_FastSync 0xffff ++#define bShortCFO 0xfff ++#define bShortCFOTLength 12 /* total */ ++#define bShortCFOFLength 11 /* fraction */ ++#define bLongCFO 0x7ff ++#define bLongCFOTLength 11 ++#define bLongCFOFLength 11 ++#define bTailCFO 0x1fff ++#define bTailCFOTLength 13 ++#define bTailCFOFLength 12 ++#define bmax_en_pwdB 0xffff ++#define bCC_power_dB 0xffff0000 ++#define bnoise_pwdB 0xffff ++#define bPowerMeasTLength 10 ++#define bPowerMeasFLength 3 ++#define bRx_HT_BW 0x1 ++#define bRxSC 0x6 ++#define bRx_HT 0x8 ++#define bNB_intf_det_on 0x1 ++#define bIntf_win_len_cfg 0x30 ++#define bNB_Intf_TH_cfg 0x1c0 ++#define bRFGain 0x3f ++#define bTableSel 0x40 ++#define bTRSW 0x80 ++#define bRxSNR_A 0xff ++#define bRxSNR_B 0xff00 ++#define bRxSNR_C 0xff0000 ++#define bRxSNR_D 0xff000000 ++#define bSNREVMTLength 8 ++#define bSNREVMFLength 1 ++#define bCSI1st 0xff ++#define bCSI2nd 0xff00 ++#define bRxEVM1st 0xff0000 ++#define bRxEVM2nd 0xff000000 ++#define bSIGEVM 0xff ++#define bPWDB 0xff00 ++#define bSGIEN 0x10000 ++ ++#define bSFactorQAM1 0xf /* Useless */ ++#define bSFactorQAM2 0xf0 ++#define bSFactorQAM3 0xf00 ++#define bSFactorQAM4 0xf000 ++#define bSFactorQAM5 0xf0000 ++#define bSFactorQAM6 0xf0000 ++#define bSFactorQAM7 0xf00000 ++#define bSFactorQAM8 0xf000000 ++#define bSFactorQAM9 0xf0000000 ++#define bCSIScheme 0x100000 ++ ++#define bNoiseLvlTopSet 0x3 /* Useless */ ++#define bChSmooth 0x4 ++#define bChSmoothCfg1 0x38 ++#define bChSmoothCfg2 0x1c0 ++#define bChSmoothCfg3 0xe00 ++#define bChSmoothCfg4 0x7000 ++#define bMRCMode 0x800000 ++#define bTHEVMCfg 0x7000000 ++ ++#define bLoopFitType 0x1 /* Useless */ ++#define bUpdCFO 0x40 ++#define bUpdCFOOffData 0x80 ++#define bAdvUpdCFO 0x100 ++#define bAdvTimeCtrl 0x800 ++#define bUpdClko 0x1000 ++#define bFC 0x6000 ++#define bTrackingMode 0x8000 ++#define bPhCmpEnable 0x10000 ++#define bUpdClkoLTF 0x20000 ++#define bComChCFO 0x40000 ++#define bCSIEstiMode 0x80000 ++#define bAdvUpdEqz 0x100000 ++#define bUChCfg 0x7000000 ++#define bUpdEqz 0x8000000 ++ ++/* Rx Pseduo noise */ ++#define bRxPesudoNoiseOn 0x20000000 /* Useless */ ++#define bRxPesudoNoise_A 0xff ++#define bRxPesudoNoise_B 0xff00 ++#define bRxPesudoNoise_C 0xff0000 ++#define bRxPesudoNoise_D 0xff000000 ++#define bPesudoNoiseState_A 0xffff ++#define bPesudoNoiseState_B 0xffff0000 ++#define bPesudoNoiseState_C 0xffff ++#define bPesudoNoiseState_D 0xffff0000 ++ ++/* 7. RF Register */ ++/* Zebra1 */ ++#define bZebra1_HSSIEnable 0x8 /* Useless */ ++#define bZebra1_TRxControl 0xc00 ++#define bZebra1_TRxGainSetting 0x07f ++#define bZebra1_RxCorner 0xc00 ++#define bZebra1_TxChargePump 0x38 ++#define bZebra1_RxChargePump 0x7 ++#define bZebra1_ChannelNum 0xf80 ++#define bZebra1_TxLPFBW 0x400 ++#define bZebra1_RxLPFBW 0x600 ++ ++/* Zebra4 */ ++#define bRTL8256RegModeCtrl1 0x100 /* Useless */ ++#define bRTL8256RegModeCtrl0 0x40 ++#define bRTL8256_TxLPFBW 0x18 ++#define bRTL8256_RxLPFBW 0x600 ++ ++/* RTL8258 */ ++#define bRTL8258_TxLPFBW 0xc /* Useless */ ++#define bRTL8258_RxLPFBW 0xc00 ++#define bRTL8258_RSSILPFBW 0xc0 ++ ++/* */ ++/* Other Definition */ ++/* */ ++ ++/* byte endable for sb_write */ ++#define bByte0 0x1 /* Useless */ ++#define bByte1 0x2 ++#define bByte2 0x4 ++#define bByte3 0x8 ++#define bWord0 0x3 ++#define bWord1 0xc ++#define bDWord 0xf ++ ++/* for PutRegsetting & GetRegSetting BitMask */ ++#define bMaskByte0 0xff /* Reg 0xc50 rOFDM0_XAAGCCore~0xC6f */ ++#define bMaskByte1 0xff00 ++#define bMaskByte2 0xff0000 ++#define bMaskByte3 0xff000000 ++#define bMaskHWord 0xffff0000 ++#define bMaskLWord 0x0000ffff ++#define bMaskDWord 0xffffffff ++#define bMask12Bits 0xfff ++#define bMaskH4Bits 0xf0000000 ++#define bMaskOFDM_D 0xffc00000 ++#define bMaskCCK 0x3f3f3f3f ++ ++/* for PutRFRegsetting & GetRFRegSetting BitMask */ ++#define bRFRegOffsetMask 0xfffff ++ ++#define bEnable 0x1 /* Useless */ ++#define bDisable 0x0 ++ ++#define LeftAntenna 0x0 /* Useless */ ++#define RightAntenna 0x1 ++ ++#define tCheckTxStatus 500 /* 500ms Useless */ ++#define tUpdateRxCounter 100 /* 100ms */ ++ ++#define rateCCK 0 /* Useless */ ++#define rateOFDM 1 ++#define rateHT 2 ++ ++/* define Register-End */ ++#define bPMAC_End 0x1ff /* Useless */ ++#define bFPGAPHY0_End 0x8ff ++#define bFPGAPHY1_End 0x9ff ++#define bCCKPHY0_End 0xaff ++#define bOFDMPHY0_End 0xcff ++#define bOFDMPHY1_End 0xdff ++ ++#define bPMACControl 0x0 /* Useless */ ++#define bWMACControl 0x1 ++#define bWNICControl 0x2 ++ ++#define PathA 0x0 /* Useless */ ++#define PathB 0x1 ++#define PathC 0x2 ++#define PathD 0x3 ++ ++/*--------------------------Define Parameters-------------------------------*/ ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/Hal8188EPwrSeq.h b/drivers/staging/r8188eu/include/Hal8188EPwrSeq.h +new file mode 100644 +index 000000000000..a73bd1a5d57b +--- /dev/null ++++ b/drivers/staging/r8188eu/include/Hal8188EPwrSeq.h +@@ -0,0 +1,155 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __HAL8188EPWRSEQ_H__ ++#define __HAL8188EPWRSEQ_H__ ++ ++#include "HalPwrSeqCmd.h" ++ ++/* ++ Check document WM-20110607-Paul-RTL8188E_Power_Architecture-R02.vsd ++ There are 6 HW Power States: ++ 0: POFF--Power Off ++ 1: PDN--Power Down ++ 2: CARDEMU--Card Emulation ++ 3: ACT--Active Mode ++ 4: LPS--Low Power State ++ 5: SUS--Suspend ++ ++ The transision from different states are defined below ++ TRANS_CARDEMU_TO_ACT ++ TRANS_ACT_TO_CARDEMU ++ TRANS_CARDEMU_TO_SUS ++ TRANS_SUS_TO_CARDEMU ++ TRANS_CARDEMU_TO_PDN ++ TRANS_ACT_TO_LPS ++ TRANS_LPS_TO_ACT ++ ++ TRANS_END ++ ++ PWR SEQ Version: rtl8188E_PwrSeq_V09.h ++*/ ++#define RTL8188E_TRANS_CARDEMU_TO_ACT_STEPS 10 ++#define RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS 10 ++#define RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS 10 ++#define RTL8188E_TRANS_SUS_TO_CARDEMU_STEPS 10 ++#define RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS 10 ++#define RTL8188E_TRANS_PDN_TO_CARDEMU_STEPS 10 ++#define RTL8188E_TRANS_ACT_TO_LPS_STEPS 15 ++#define RTL8188E_TRANS_LPS_TO_ACT_STEPS 15 ++#define RTL8188E_TRANS_END_STEPS 1 ++ ++#define RTL8188E_TRANS_CARDEMU_TO_ACT \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)},/* wait till 0x04[17] = 1 power ready*/ \ ++ {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0)|BIT(1), 0}, /* 0x02[1:0] = 0 reset BB*/ \ ++ {0x0026, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)}, /*0x24[23] = 2b'01 schmit trigger */ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, /* 0x04[15] = 0 disable HWPDN (control by DRV)*/\ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4)|BIT(3), 0}, /*0x04[12:11] = 2b'00 disable WL suspend*/ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*0x04[8] = 1 polling until return 0*/ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0}, /*wait till 0x04[8] = 0*/ \ ++ {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*LDO normal mode*/ \ ++ {0x0074, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*SDIO Driving*/ \ ++ ++#define RTL8188E_TRANS_ACT_TO_CARDEMU \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},/*0x1F[7:0] = 0 turn off RF*/ \ ++ {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*LDO Sleep mode*/ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \ ++ ++#define RTL8188E_TRANS_CARDEMU_TO_SUS \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, /*0x04[12:11] = 2b'01enable WL suspend*/ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)|BIT(4)}, /*0x04[12:11] = 2b'11enable WL suspend for PCIe*/ \ ++ {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, BIT(7)}, /* 0x04[31:30] = 2b'10 enable enable bandgap mbias in suspend */ \ ++ {0x0041, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*Clear SIC_EN register 0x40[12] = 1'b0 */ \ ++ {0xfe10, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*Set USB suspend enable local register 0xfe10[4]=1 */ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*Set SDIO suspend local register*/ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0}, /*wait power state to suspend*/ ++ ++#define RTL8188E_TRANS_SUS_TO_CARDEMU \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, /*Set SDIO suspend local register*/ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, /*wait power state to suspend*/\ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ ++ ++#define RTL8188E_TRANS_CARDEMU_TO_CARDDIS \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0x0026, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)}, /*0x24[23] = 2b'01 schmit trigger */ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ ++ {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, /* 0x04[31:30] = 2b'10 enable enable bandgap mbias in suspend */ \ ++ {0x0041, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*Clear SIC_EN register 0x40[12] = 1'b0 */ \ ++ {0xfe10, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*Set USB suspend enable local register 0xfe10[4]=1 */ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*Set SDIO suspend local register*/ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0}, /*wait power state to suspend*/ ++ ++#define RTL8188E_TRANS_CARDDIS_TO_CARDEMU \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, /*Set SDIO suspend local register*/ \ ++ {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, /*wait power state to suspend*/\ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ ++ ++#define RTL8188E_TRANS_CARDEMU_TO_PDN \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0},/* 0x04[16] = 0*/\ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)},/* 0x04[15] = 1*/ ++ ++#define RTL8188E_TRANS_PDN_TO_CARDEMU \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here */ \ ++ {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},/* 0x04[15] = 0*/ ++ ++/* This is used by driver for LPSRadioOff Procedure, not for FW LPS Step */ ++#define RTL8188E_TRANS_ACT_TO_LPS \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here */ \ ++ {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x7F},/*Tx Pause*/ \ ++ {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ ++ {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ ++ {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ ++ {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ ++ {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0},/*CCK and OFDM are disabled,and clock are gated*/ \ ++ {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ ++ {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x3F},/*Reset MAC TRX*/ \ ++ {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0},/*check if removed later*/ \ ++ {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)},/*Respond TxOK to scheduler*/ \ ++ ++#define RTL8188E_TRANS_LPS_TO_ACT \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here */ \ ++ {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/\ ++ {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\ ++ {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/\ ++ {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\ ++ {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*. 0x08[4] = 0 switch TSF to 40M*/\ ++ {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0}, /*Polling 0x109[7]=0 TSF in 40M*/\ ++ {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6)|BIT(7), 0}, /*. 0x29[7:6] = 2b'00 enable BB clock*/\ ++ {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, /*. 0x101[1] = 1*/\ ++ {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ ++ {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1)|BIT(0), BIT(1)|BIT(0)}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\ ++ {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ ++ ++#define RTL8188E_TRANS_END \ ++ /* format */ \ ++ /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here*/ \ ++ {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,0, PWR_CMD_END, 0, 0}, /* */ ++ ++extern struct wl_pwr_cfg rtl8188E_power_on_flow[RTL8188E_TRANS_CARDEMU_TO_ACT_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_radio_off_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_card_disable_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_card_enable_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_suspend_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_resume_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_hwpdn_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_enter_lps_flow[RTL8188E_TRANS_ACT_TO_LPS_STEPS+RTL8188E_TRANS_END_STEPS]; ++extern struct wl_pwr_cfg rtl8188E_leave_lps_flow[RTL8188E_TRANS_LPS_TO_ACT_STEPS+RTL8188E_TRANS_END_STEPS]; ++ ++#endif /* __HAL8188EPWRSEQ_H__ */ +diff --git a/drivers/staging/r8188eu/include/Hal8188ERateAdaptive.h b/drivers/staging/r8188eu/include/Hal8188ERateAdaptive.h +new file mode 100644 +index 000000000000..d5ced507a648 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/Hal8188ERateAdaptive.h +@@ -0,0 +1,64 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright (c) 2011 Realtek Semiconductor Corp. */ ++ ++#ifndef __INC_RA_H ++#define __INC_RA_H ++/* Module Name: RateAdaptive.h ++ * Abstract: Prototype of RA and related data structure. ++ */ ++ ++#include ++ ++/* Rate adaptive define */ ++#define PERENTRY 23 ++#define RETRYSIZE 5 ++#define RATESIZE 28 ++#define TX_RPT2_ITEM_SIZE 8 ++ ++/* TX report 2 format in Rx desc */ ++#define GET_TX_RPT2_DESC_PKT_LEN_88E(__rxstatusdesc) \ ++ le32_get_bits(*(__le32 *)__rxstatusdesc, GENMASK(8, 0)) ++#define GET_TX_RPT2_DESC_MACID_VALID_1_88E(__rxstatusdesc) \ ++ le32_to_cpu((*(__le32 *)(__rxstatusdesc + 16)) ++#define GET_TX_RPT2_DESC_MACID_VALID_2_88E(__rxstatusdesc) \ ++ le32_to_cpu((*(__le32 *)(__rxstatusdesc + 20)) ++ ++#define GET_TX_REPORT_TYPE1_RERTY_0(__paddr) \ ++ le16_get_bits(*(__le16 *)__paddr, GENMASK(15, 0)) ++#define GET_TX_REPORT_TYPE1_RERTY_1(__paddr) \ ++ LE_BITS_TO_1BYTE(__paddr + 2, 0, 8) ++#define GET_TX_REPORT_TYPE1_RERTY_2(__paddr) \ ++ LE_BITS_TO_1BYTE(__paddr + 3, 0, 8) ++#define GET_TX_REPORT_TYPE1_RERTY_3(__paddr) \ ++ LE_BITS_TO_1BYTE(__paddr + 4, 0, 8) ++#define GET_TX_REPORT_TYPE1_RERTY_4(__paddr) \ ++ LE_BITS_TO_1BYTE(__paddr + 5, 0, 8) ++#define GET_TX_REPORT_TYPE1_DROP_0(__paddr) \ ++ LE_BITS_TO_1BYTE(__paddr + 6, 0, 8) ++/* End rate adaptive define */ ++ ++void ODM_RASupport_Init(struct odm_dm_struct *dm_odm); ++ ++int ODM_RAInfo_Init_all(struct odm_dm_struct *dm_odm); ++ ++int ODM_RAInfo_Init(struct odm_dm_struct *dm_odm, u8 MacID); ++ ++u8 ODM_RA_GetShortGI_8188E(struct odm_dm_struct *dm_odm, u8 MacID); ++ ++u8 ODM_RA_GetDecisionRate_8188E(struct odm_dm_struct *dm_odm, u8 MacID); ++ ++u8 ODM_RA_GetHwPwrStatus_8188E(struct odm_dm_struct *dm_odm, u8 MacID); ++void ODM_RA_UpdateRateInfo_8188E(struct odm_dm_struct *dm_odm, u8 MacID, ++ u8 RateID, u32 RateMask, ++ u8 SGIEnable); ++ ++void ODM_RA_SetRSSI_8188E(struct odm_dm_struct *dm_odm, u8 macid, ++ u8 rssi); ++ ++void ODM_RA_TxRPT2Handle_8188E(struct odm_dm_struct *dm_odm, ++ u8 *txrpt_buf, u16 txrpt_len, ++ u32 validentry0, u32 validentry1); ++ ++void ODM_RA_Set_TxRPT_Time(struct odm_dm_struct *dm_odm, u16 minRptTime); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/HalHWImg8188E_BB.h b/drivers/staging/r8188eu/include/HalHWImg8188E_BB.h +new file mode 100644 +index 000000000000..8270fdbc2844 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/HalHWImg8188E_BB.h +@@ -0,0 +1,27 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __INC_BB_8188E_HW_IMG_H ++#define __INC_BB_8188E_HW_IMG_H ++ ++/* static bool CheckCondition(const u32 Condition, const u32 Hex); */ ++ ++/****************************************************************************** ++* AGC_TAB_1T.TXT ++******************************************************************************/ ++ ++enum HAL_STATUS ODM_ReadAndConfig_AGC_TAB_1T_8188E(struct odm_dm_struct *odm); ++ ++/****************************************************************************** ++* PHY_REG_1T.TXT ++******************************************************************************/ ++ ++enum HAL_STATUS ODM_ReadAndConfig_PHY_REG_1T_8188E(struct odm_dm_struct *odm); ++ ++/****************************************************************************** ++* PHY_REG_PG.TXT ++******************************************************************************/ ++ ++void ODM_ReadAndConfig_PHY_REG_PG_8188E(struct odm_dm_struct *dm_odm); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/HalHWImg8188E_FW.h b/drivers/staging/r8188eu/include/HalHWImg8188E_FW.h +new file mode 100644 +index 000000000000..5ddcd283097b +--- /dev/null ++++ b/drivers/staging/r8188eu/include/HalHWImg8188E_FW.h +@@ -0,0 +1,16 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __INC_FW_8188E_HW_IMG_H ++#define __INC_FW_8188E_HW_IMG_H ++ ++/****************************************************************************** ++* FW_AP.TXT ++******************************************************************************/ ++/****************************************************************************** ++* FW_WoWLAN.TXT ++******************************************************************************/ ++#define ArrayLength_8188E_FW_WoWLAN 15764 ++extern const u8 Array_8188E_FW_WoWLAN[ArrayLength_8188E_FW_WoWLAN]; ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/HalHWImg8188E_MAC.h b/drivers/staging/r8188eu/include/HalHWImg8188E_MAC.h +new file mode 100644 +index 000000000000..391c1754b0b6 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/HalHWImg8188E_MAC.h +@@ -0,0 +1,13 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __INC_MAC_8188E_HW_IMG_H ++#define __INC_MAC_8188E_HW_IMG_H ++ ++/****************************************************************************** ++* MAC_REG.TXT ++******************************************************************************/ ++ ++enum HAL_STATUS ODM_ReadAndConfig_MAC_REG_8188E(struct odm_dm_struct *pDM_Odm); ++ ++#endif /* end of HWIMG_SUPPORT */ +diff --git a/drivers/staging/r8188eu/include/HalHWImg8188E_RF.h b/drivers/staging/r8188eu/include/HalHWImg8188E_RF.h +new file mode 100644 +index 000000000000..0c67c3df20b9 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/HalHWImg8188E_RF.h +@@ -0,0 +1,13 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __INC_RF_8188E_HW_IMG_H ++#define __INC_RF_8188E_HW_IMG_H ++ ++/****************************************************************************** ++ * RadioA_1T.TXT ++ ******************************************************************************/ ++ ++enum HAL_STATUS ODM_ReadAndConfig_RadioA_1T_8188E(struct odm_dm_struct *odm); ++ ++#endif /* end of HWIMG_SUPPORT */ +diff --git a/drivers/staging/r8188eu/include/HalPhyRf_8188e.h b/drivers/staging/r8188eu/include/HalPhyRf_8188e.h +new file mode 100644 +index 000000000000..d4a27662309f +--- /dev/null ++++ b/drivers/staging/r8188eu/include/HalPhyRf_8188e.h +@@ -0,0 +1,41 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __HAL_PHY_RF_8188E_H__ ++#define __HAL_PHY_RF_8188E_H__ ++ ++/*--------------------------Define Parameters-------------------------------*/ ++#define IQK_DELAY_TIME_88E 10 /* ms */ ++#define index_mapping_NUM_88E 15 ++#define AVG_THERMAL_NUM_88E 4 ++ ++void ODM_TxPwrTrackAdjust88E(struct odm_dm_struct *pDM_Odm, ++ u8 Type, /* 0 = OFDM, 1 = CCK */ ++ u8 *pDirection,/* 1 = +(incr) 2 = -(decr) */ ++ u32 *pOutWriteVal); /* Tx tracking CCK/OFDM BB ++ * swing index adjust */ ++ ++void odm_TXPowerTrackingCallback_ThermalMeter_8188E(struct adapter *Adapter); ++ ++/* 1 7. IQK */ ++ ++void PHY_IQCalibrate_8188E(struct adapter *Adapter, bool ReCovery); ++ ++/* LC calibrate */ ++void PHY_LCCalibrate_8188E(struct adapter *pAdapter); ++ ++/* AP calibrate */ ++void PHY_DigitalPredistortion_8188E(struct adapter *pAdapter); ++ ++void _PHY_SaveADDARegisters(struct adapter *pAdapter, u32 *ADDAReg, ++ u32 *ADDABackup, u32 RegisterNum); ++ ++void _PHY_PathADDAOn(struct adapter *pAdapter, u32 *ADDAReg, ++ bool isPathAOn, bool is2T); ++ ++void _PHY_MACSettingCalibration(struct adapter *pAdapter, u32 *MACReg, ++ u32 *MACBackup); ++ ++void _PHY_PathAStandBy(struct adapter *pAdapter); ++ ++#endif /* #ifndef __HAL_PHY_RF_8188E_H__ */ +diff --git a/drivers/staging/r8188eu/include/HalPwrSeqCmd.h b/drivers/staging/r8188eu/include/HalPwrSeqCmd.h +new file mode 100644 +index 000000000000..fe7ac910beb8 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/HalPwrSeqCmd.h +@@ -0,0 +1,110 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __HALPWRSEQCMD_H__ ++#define __HALPWRSEQCMD_H__ ++ ++#include "drv_types.h" ++ ++/*---------------------------------------------*/ ++/* 3 The value of cmd: 4 bits */ ++/*---------------------------------------------*/ ++#define PWR_CMD_READ 0x00 ++ /* offset: the read register offset */ ++ /* msk: the mask of the read value */ ++ /* value: N/A, left by 0 */ ++ /* note: dirver shall implement this function by read & msk */ ++ ++#define PWR_CMD_WRITE 0x01 ++ /* offset: the read register offset */ ++ /* msk: the mask of the write bits */ ++ /* value: write value */ ++ /* note: driver shall implement this cmd by read & msk after write */ ++ ++#define PWR_CMD_POLLING 0x02 ++ /* offset: the read register offset */ ++ /* msk: the mask of the polled value */ ++ /* value: the value to be polled, masked by the msd field. */ ++ /* note: driver shall implement this cmd by */ ++ /* do{ */ ++ /* if ( (Read(offset) & msk) == (value & msk) ) */ ++ /* break; */ ++ /* } while (not timeout); */ ++ ++#define PWR_CMD_DELAY 0x03 ++ /* offset: the value to delay */ ++ /* msk: N/A */ ++ /* value: the unit of delay, 0: us, 1: ms */ ++ ++#define PWR_CMD_END 0x04 ++ /* offset: N/A */ ++ /* msk: N/A */ ++ /* value: N/A */ ++ ++/*---------------------------------------------*/ ++/* 3 The value of base: 4 bits */ ++/*---------------------------------------------*/ ++ /* define the base address of each block */ ++#define PWR_BASEADDR_MAC 0x00 ++#define PWR_BASEADDR_USB 0x01 ++#define PWR_BASEADDR_PCIE 0x02 ++#define PWR_BASEADDR_SDIO 0x03 ++ ++/*---------------------------------------------*/ ++/* 3 The value of interface_msk: 4 bits */ ++/*---------------------------------------------*/ ++#define PWR_INTF_SDIO_MSK BIT(0) ++#define PWR_INTF_USB_MSK BIT(1) ++#define PWR_INTF_PCI_MSK BIT(2) ++#define PWR_INTF_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) ++ ++/*---------------------------------------------*/ ++/* 3 The value of fab_msk: 4 bits */ ++/*---------------------------------------------*/ ++#define PWR_FAB_TSMC_MSK BIT(0) ++#define PWR_FAB_UMC_MSK BIT(1) ++#define PWR_FAB_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) ++ ++/*---------------------------------------------*/ ++/* 3 The value of cut_msk: 8 bits */ ++/*---------------------------------------------*/ ++#define PWR_CUT_TESTCHIP_MSK BIT(0) ++#define PWR_CUT_A_MSK BIT(1) ++#define PWR_CUT_B_MSK BIT(2) ++#define PWR_CUT_C_MSK BIT(3) ++#define PWR_CUT_D_MSK BIT(4) ++#define PWR_CUT_E_MSK BIT(5) ++#define PWR_CUT_F_MSK BIT(6) ++#define PWR_CUT_G_MSK BIT(7) ++#define PWR_CUT_ALL_MSK 0xFF ++ ++enum pwrseq_cmd_delat_unit { ++ PWRSEQ_DELAY_US, ++ PWRSEQ_DELAY_MS, ++}; ++ ++struct wl_pwr_cfg { ++ u16 offset; ++ u8 cut_msk; ++ u8 fab_msk:4; ++ u8 interface_msk:4; ++ u8 base:4; ++ u8 cmd:4; ++ u8 msk; ++ u8 value; ++}; ++ ++#define GET_PWR_CFG_OFFSET(__PWR_CMD) __PWR_CMD.offset ++#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) __PWR_CMD.cut_msk ++#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) __PWR_CMD.fab_msk ++#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) __PWR_CMD.interface_msk ++#define GET_PWR_CFG_BASE(__PWR_CMD) __PWR_CMD.base ++#define GET_PWR_CFG_CMD(__PWR_CMD) __PWR_CMD.cmd ++#define GET_PWR_CFG_MASK(__PWR_CMD) __PWR_CMD.msk ++#define GET_PWR_CFG_VALUE(__PWR_CMD) __PWR_CMD.value ++ ++/* Prototype of protected function. */ ++u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 CutVersion, u8 FabVersion, ++ u8 InterfaceType, struct wl_pwr_cfg PwrCfgCmd[]); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/HalVerDef.h b/drivers/staging/r8188eu/include/HalVerDef.h +new file mode 100644 +index 000000000000..a0f5bf52e75a +--- /dev/null ++++ b/drivers/staging/r8188eu/include/HalVerDef.h +@@ -0,0 +1,149 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++#ifndef __HAL_VERSION_DEF_H__ ++#define __HAL_VERSION_DEF_H__ ++ ++enum HAL_IC_TYPE { ++ CHIP_8192S = 0, ++ CHIP_8188C = 1, ++ CHIP_8192C = 2, ++ CHIP_8192D = 3, ++ CHIP_8723A = 4, ++ CHIP_8188E = 5, ++ CHIP_8881A = 6, ++ CHIP_8812A = 7, ++ CHIP_8821A = 8, ++ CHIP_8723B = 9, ++ CHIP_8192E = 10, ++}; ++ ++enum HAL_CHIP_TYPE { ++ TEST_CHIP = 0, ++ NORMAL_CHIP = 1, ++ FPGA = 2, ++}; ++ ++enum HAL_CUT_VERSION { ++ A_CUT_VERSION = 0, ++ B_CUT_VERSION = 1, ++ C_CUT_VERSION = 2, ++ D_CUT_VERSION = 3, ++ E_CUT_VERSION = 4, ++ F_CUT_VERSION = 5, ++ G_CUT_VERSION = 6, ++}; ++ ++enum HAL_VENDOR { ++ CHIP_VENDOR_TSMC = 0, ++ CHIP_VENDOR_UMC = 1, ++}; ++ ++enum HAL_RF_TYPE { ++ RF_TYPE_1T1R = 0, ++ RF_TYPE_1T2R = 1, ++ RF_TYPE_2T2R = 2, ++ RF_TYPE_2T3R = 3, ++ RF_TYPE_2T4R = 4, ++ RF_TYPE_3T3R = 5, ++ RF_TYPE_3T4R = 6, ++ RF_TYPE_4T4R = 7, ++}; ++ ++struct HAL_VERSION { ++ enum HAL_IC_TYPE ICType; ++ enum HAL_CHIP_TYPE ChipType; ++ enum HAL_CUT_VERSION CUTVersion; ++ enum HAL_VENDOR VendorType; ++ enum HAL_RF_TYPE RFType; ++ u8 ROMVer; ++}; ++ ++/* Get element */ ++#define GET_CVID_IC_TYPE(version) (((version).ICType)) ++#define GET_CVID_CHIP_TYPE(version) (((version).ChipType)) ++#define GET_CVID_RF_TYPE(version) (((version).RFType)) ++#define GET_CVID_MANUFACTUER(version) (((version).VendorType)) ++#define GET_CVID_CUT_VERSION(version) (((version).CUTVersion)) ++#define GET_CVID_ROM_VERSION(version) (((version).ROMVer) & ROM_VERSION_MASK) ++ ++/* Common Macro. -- */ ++/* HAL_VERSION VersionID */ ++ ++/* HAL_IC_TYPE_E */ ++#define IS_81XXC(version) \ ++ (((GET_CVID_IC_TYPE(version) == CHIP_8192C) || \ ++ (GET_CVID_IC_TYPE(version) == CHIP_8188C)) ? true : false) ++#define IS_8723_SERIES(version) \ ++ ((GET_CVID_IC_TYPE(version) == CHIP_8723A) ? true : false) ++#define IS_92D(version) \ ++ ((GET_CVID_IC_TYPE(version) == CHIP_8192D) ? true : false) ++#define IS_8188E(version) \ ++ ((GET_CVID_IC_TYPE(version) == CHIP_8188E) ? true : false) ++ ++/* HAL_CHIP_TYPE_E */ ++#define IS_TEST_CHIP(version) \ ++ ((GET_CVID_CHIP_TYPE(version) == TEST_CHIP) ? true : false) ++#define IS_NORMAL_CHIP(version) \ ++ ((GET_CVID_CHIP_TYPE(version) == NORMAL_CHIP) ? true : false) ++ ++/* HAL_CUT_VERSION_E */ ++#define IS_A_CUT(version) \ ++ ((GET_CVID_CUT_VERSION(version) == A_CUT_VERSION) ? true : false) ++#define IS_B_CUT(version) \ ++ ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? true : false) ++#define IS_C_CUT(version) \ ++ ((GET_CVID_CUT_VERSION(version) == C_CUT_VERSION) ? true : false) ++#define IS_D_CUT(version) \ ++ ((GET_CVID_CUT_VERSION(version) == D_CUT_VERSION) ? true : false) ++#define IS_E_CUT(version) \ ++ ((GET_CVID_CUT_VERSION(version) == E_CUT_VERSION) ? true : false) ++ ++/* HAL_VENDOR_E */ ++#define IS_CHIP_VENDOR_TSMC(version) \ ++ ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_TSMC) ? true : false) ++#define IS_CHIP_VENDOR_UMC(version) \ ++ ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_UMC) ? true : false) ++ ++/* HAL_RF_TYPE_E */ ++#define IS_1T1R(version) \ ++ ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T1R) ? true : false) ++#define IS_1T2R(version) \ ++ ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R) ? true : false) ++#define IS_2T2R(version) \ ++ ((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R) ? true : false) ++ ++/* Chip version Macro. -- */ ++#define IS_81XXC_TEST_CHIP(version) \ ++ ((IS_81XXC(version) && (!IS_NORMAL_CHIP(version))) ? true : false) ++ ++#define IS_92C_SERIAL(version) \ ++ ((IS_81XXC(version) && IS_2T2R(version)) ? true : false) ++#define IS_81xxC_VENDOR_UMC_A_CUT(version) \ ++ (IS_81XXC(version) ? (IS_CHIP_VENDOR_UMC(version) ? \ ++ (IS_A_CUT(version) ? true : false) : false) : false) ++#define IS_81xxC_VENDOR_UMC_B_CUT(version) \ ++ (IS_81XXC(version) ? (IS_CHIP_VENDOR_UMC(version) ? \ ++ (IS_B_CUT(version) ? true : false) : false) : false) ++#define IS_81xxC_VENDOR_UMC_C_CUT(version) \ ++ (IS_81XXC(version) ? (IS_CHIP_VENDOR_UMC(version) ? \ ++ (IS_C_CUT(version) ? true : false) : false) : false) ++ ++#define IS_NORMAL_CHIP92D(version) \ ++ ((IS_92D(version)) ? \ ++ ((GET_CVID_CHIP_TYPE(version) == NORMAL_CHIP) ? true : false) : false) ++ ++#define IS_92D_SINGLEPHY(version) \ ++ ((IS_92D(version)) ? (IS_2T2R(version) ? true : false) : false) ++#define IS_92D_C_CUT(version) \ ++ ((IS_92D(version)) ? (IS_C_CUT(version) ? true : false) : false) ++#define IS_92D_D_CUT(version) \ ++ ((IS_92D(version)) ? (IS_D_CUT(version) ? true : false) : false) ++#define IS_92D_E_CUT(version) \ ++ ((IS_92D(version)) ? (IS_E_CUT(version) ? true : false) : false) ++ ++#define IS_8723A_A_CUT(version) \ ++ ((IS_8723_SERIES(version)) ? (IS_A_CUT(version) ? true : false) : false) ++#define IS_8723A_B_CUT(version) \ ++ ((IS_8723_SERIES(version)) ? (IS_B_CUT(version) ? true : false) : false) ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/basic_types.h b/drivers/staging/r8188eu/include/basic_types.h +new file mode 100644 +index 000000000000..d82b2171d584 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/basic_types.h +@@ -0,0 +1,123 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __BASIC_TYPES_H__ ++#define __BASIC_TYPES_H__ ++ ++#define SUCCESS 0 ++#define FAIL (-1) ++ ++#include ++#define NDIS_OID uint ++ ++typedef void (*proc_t)(void *); ++ ++#define FIELD_OFFSET(s, field) ((ssize_t)&((s *)(0))->field) ++ ++#define MEM_ALIGNMENT_OFFSET (sizeof(size_t)) ++#define MEM_ALIGNMENT_PADDING (sizeof(size_t) - 1) ++ ++/* port from fw */ ++/* TODO: Macros Below are Sync from SD7-Driver. It is necessary ++ * to check correctness */ ++ ++/* ++ * Call endian free function when ++ * 1. Read/write packet content. ++ * 2. Before write integer to IO. ++ * 3. After read integer from IO. ++*/ ++ ++/* Convert little data endian to host ordering */ ++#define EF1BYTE(_val) \ ++ ((u8)(_val)) ++#define EF2BYTE(_val) \ ++ (le16_to_cpu(_val)) ++#define EF4BYTE(_val) \ ++ (le32_to_cpu(_val)) ++ ++/* Read data from memory */ ++#define READEF1BYTE(_ptr) \ ++ EF1BYTE(*((u8 *)(_ptr))) ++/* Read le16 data from memory and convert to host ordering */ ++#define READEF2BYTE(_ptr) \ ++ EF2BYTE(*(_ptr)) ++#define READEF4BYTE(_ptr) \ ++ EF4BYTE(*(_ptr)) ++ ++/* Write data to memory */ ++#define WRITEEF1BYTE(_ptr, _val) \ ++ do { \ ++ (*((u8 *)(_ptr))) = EF1BYTE(_val) \ ++ } while (0) ++/* Write le data to memory in host ordering */ ++#define WRITEEF2BYTE(_ptr, _val) \ ++ do { \ ++ (*((u16 *)(_ptr))) = EF2BYTE(_val) \ ++ } while (0) ++ ++#define WRITEEF4BYTE(_ptr, _val) \ ++ do { \ ++ (*((u32 *)(_ptr))) = EF2BYTE(_val) \ ++ } while (0) ++ ++/* Create a bit mask ++ * Examples: ++ * BIT_LEN_MASK_32(0) => 0x00000000 ++ * BIT_LEN_MASK_32(1) => 0x00000001 ++ * BIT_LEN_MASK_32(2) => 0x00000003 ++ * BIT_LEN_MASK_32(32) => 0xFFFFFFFF ++ */ ++#define BIT_LEN_MASK_32(__bitlen) \ ++ (0xFFFFFFFF >> (32 - (__bitlen))) ++#define BIT_LEN_MASK_16(__bitlen) \ ++ (0xFFFF >> (16 - (__bitlen))) ++#define BIT_LEN_MASK_8(__bitlen) \ ++ (0xFF >> (8 - (__bitlen))) ++ ++/* Create an offset bit mask ++ * Examples: ++ * BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003 ++ * BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000 ++ */ ++#define BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen) \ ++ (BIT_LEN_MASK_32(__bitlen) << (__bitoffset)) ++#define BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen) \ ++ (BIT_LEN_MASK_16(__bitlen) << (__bitoffset)) ++#define BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen) \ ++ (BIT_LEN_MASK_8(__bitlen) << (__bitoffset)) ++ ++/*Description: ++ * Return 4-byte value in host byte ordering from ++ * 4-byte pointer in little-endian system. ++ */ ++#define LE_P4BYTE_TO_HOST_4BYTE(__pstart) \ ++ (EF4BYTE(*((__le32 *)(__pstart)))) ++#define LE_P2BYTE_TO_HOST_2BYTE(__pstart) \ ++ (EF2BYTE(*((__le16 *)(__pstart)))) ++#define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \ ++ (EF1BYTE(*((u8 *)(__pstart)))) ++ ++/*Description: ++Translate subfield (continuous bits in little-endian) of 4-byte ++value to host byte ordering.*/ ++#define LE_BITS_TO_4BYTE(__pstart, __bitoffset, __bitlen) \ ++ ( \ ++ (LE_P4BYTE_TO_HOST_4BYTE(__pstart) >> (__bitoffset)) & \ ++ BIT_LEN_MASK_32(__bitlen) \ ++ ) ++#define LE_BITS_TO_2BYTE(__pstart, __bitoffset, __bitlen) \ ++ ( \ ++ (LE_P2BYTE_TO_HOST_2BYTE(__pstart) >> (__bitoffset)) & \ ++ BIT_LEN_MASK_16(__bitlen) \ ++ ) ++#define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \ ++ ( \ ++ (LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset)) & \ ++ BIT_LEN_MASK_8(__bitlen) \ ++ ) ++ ++#define N_BYTE_ALIGMENT(__value, __aligment) ((__aligment == 1) ? \ ++ (__value) : (((__value + __aligment - 1) / __aligment) * __aligment)) ++ ++#endif /* __BASIC_TYPES_H__ */ +diff --git a/drivers/staging/r8188eu/include/drv_types.h b/drivers/staging/r8188eu/include/drv_types.h +new file mode 100644 +index 000000000000..04f4224c11de +--- /dev/null ++++ b/drivers/staging/r8188eu/include/drv_types.h +@@ -0,0 +1,323 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++/*----------------------------------------------------------------------------- ++ ++ For type defines and data structure defines ++ ++------------------------------------------------------------------------------*/ ++ ++#ifndef __DRV_TYPES_H__ ++#define __DRV_TYPES_H__ ++ ++#define DRV_NAME "r8188eu" ++#define CONFIG_88EU_AP_MODE 1 ++#define CONFIG_88EU_P2P 1 ++ ++#include "osdep_service.h" ++#include "wlan_bssdef.h" ++#include "rtw_ht.h" ++#include "rtw_cmd.h" ++#include "rtw_xmit.h" ++#include "rtw_recv.h" ++#include "hal_intf.h" ++#include "hal_com.h" ++#include "rtw_security.h" ++#include "rtw_pwrctrl.h" ++#include "rtw_io.h" ++#include "rtw_eeprom.h" ++#include "sta_info.h" ++#include "rtw_mlme.h" ++#include "rtw_debug.h" ++#include "rtw_rf.h" ++#include "rtw_event.h" ++#include "rtw_led.h" ++#include "rtw_mlme_ext.h" ++#include "rtw_p2p.h" ++#include "rtw_ap.h" ++#include "rtw_mp.h" ++#include "rtw_br_ext.h" ++ ++#define DRIVERVERSION "v4.1.4_6773.20130222" ++ ++#define SPEC_DEV_ID_NONE BIT(0) ++#define SPEC_DEV_ID_DISABLE_HT BIT(1) ++#define SPEC_DEV_ID_ENABLE_PS BIT(2) ++#define SPEC_DEV_ID_RF_CONFIG_1T1R BIT(3) ++#define SPEC_DEV_ID_RF_CONFIG_2T2R BIT(4) ++#define SPEC_DEV_ID_ASSIGN_IFNAME BIT(5) ++ ++struct specific_device_id { ++ u32 flags; ++ u16 idVendor; ++ u16 idProduct; ++}; ++ ++struct registry_priv { ++ u8 chip_version; ++ u8 rfintfs; ++ u8 lbkmode; ++ u8 hci; ++ struct ndis_802_11_ssid ssid; ++ u8 network_mode; /* infra, ad-hoc, auto */ ++ u8 channel;/* ad-hoc support requirement */ ++ u8 wireless_mode;/* A, B, G, auto */ ++ u8 scan_mode;/* active, passive */ ++ u8 radio_enable; ++ u8 preamble;/* long, short, auto */ ++ u8 vrtl_carrier_sense;/* Enable, Disable, Auto */ ++ u8 vcs_type;/* RTS/CTS, CTS-to-self */ ++ u16 rts_thresh; ++ u16 frag_thresh; ++ u8 adhoc_tx_pwr; ++ u8 soft_ap; ++ u8 power_mgnt; ++ u8 ips_mode; ++ u8 smart_ps; ++ u8 long_retry_lmt; ++ u8 short_retry_lmt; ++ u16 busy_thresh; ++ u8 ack_policy; ++ u8 mp_mode; ++ u8 software_encrypt; ++ u8 software_decrypt; ++ u8 acm_method; ++ /* UAPSD */ ++ u8 wmm_enable; ++ u8 uapsd_enable; ++ u8 uapsd_max_sp; ++ u8 uapsd_acbk_en; ++ u8 uapsd_acbe_en; ++ u8 uapsd_acvi_en; ++ u8 uapsd_acvo_en; ++ ++ u8 led_enable; ++ ++ struct wlan_bssid_ex dev_network; ++ ++ u8 ht_enable; ++ u8 cbw40_enable; ++ u8 ampdu_enable;/* for tx */ ++ u8 rx_stbc; ++ u8 ampdu_amsdu;/* A-MPDU Supports A-MSDU is permitted */ ++ u8 lowrate_two_xmit; ++ ++ u8 rf_config; ++ u8 low_power; ++ ++ u8 wifi_spec;/* !turbo_mode */ ++ ++ u8 channel_plan; ++ bool bAcceptAddbaReq; ++ ++ u8 antdiv_cfg; ++ u8 antdiv_type; ++ ++ u8 usbss_enable;/* 0:disable,1:enable */ ++ u8 hwpdn_mode;/* 0:disable,1:enable,2:decide by EFUSE config */ ++ u8 hwpwrp_detect;/* 0:disable,1:enable */ ++ ++ u8 hw_wps_pbc;/* 0:disable,1:enable */ ++ ++ u8 max_roaming_times; /* the max number driver will try */ ++ ++ u8 fw_iol; /* enable iol without other concern */ ++ ++ u8 enable80211d; ++ ++ u8 ifname[16]; ++ u8 if2name[16]; ++ ++ u8 notch_filter; ++}; ++ ++/* For registry parameters */ ++#define RGTRY_OFT(field) ((u32)FIELD_OFFSET(struct registry_priv, field)) ++#define RGTRY_SZ(field) sizeof(((struct registry_priv *)0)->field) ++#define BSSID_OFT(field) ((u32)FIELD_OFFSET(struct wlan_bssid_ex, field)) ++#define BSSID_SZ(field) sizeof(((struct wlan_bssid_ex *)0)->field) ++ ++#define MAX_CONTINUAL_URB_ERR 4 ++ ++struct rt_firmware { ++ u8 *szFwBuffer; ++ u32 ulFwLength; ++}; ++ ++struct dvobj_priv { ++ struct adapter *if1; ++ struct adapter *if2; ++ ++ /* For 92D, DMDP have 2 interface. */ ++ u8 InterfaceNumber; ++ u8 NumInterfaces; ++ ++ /* In /Out Pipe information */ ++ int RtInPipe[2]; ++ int RtOutPipe[3]; ++ u8 Queue2Pipe[HW_QUEUE_ENTRY];/* for out pipe mapping */ ++ ++ u8 irq_alloc; ++ ++ struct rt_firmware firmware; ++ ++/*-------- below is for USB INTERFACE --------*/ ++ ++ u8 nr_endpoint; ++ u8 ishighspeed; ++ u8 RtNumInPipes; ++ u8 RtNumOutPipes; ++ int ep_num[5]; /* endpoint number */ ++ int RegUsbSS; ++ struct semaphore usb_suspend_sema; ++ struct mutex usb_vendor_req_mutex; ++ ++ u8 *usb_alloc_vendor_req_buf; ++ u8 *usb_vendor_req_buf; ++ ++ struct usb_interface *pusbintf; ++ struct usb_device *pusbdev; ++ ++ atomic_t continual_urb_error; ++ u8 signal_strength; ++}; ++ ++static inline struct device *dvobj_to_dev(struct dvobj_priv *dvobj) ++{ ++ /* todo: get interface type from dvobj and the return ++ * the dev accordingly */ ++ return &dvobj->pusbintf->dev; ++}; ++ ++enum _IFACE_TYPE { ++ IFACE_PORT0, /* mapping to port0 for C/D series chips */ ++ IFACE_PORT1, /* mapping to port1 for C/D series chip */ ++ MAX_IFACE_PORT, ++}; ++ ++enum _ADAPTER_TYPE { ++ PRIMARY_ADAPTER, ++ SECONDARY_ADAPTER, ++ MAX_ADAPTER, ++}; ++ ++enum driver_state { ++ DRIVER_NORMAL = 0, ++ DRIVER_DISAPPEAR = 1, ++ DRIVER_REPLACE_DONGLE = 2, ++}; ++ ++struct adapter { ++ int DriverState;/* for disable driver using module, use dongle toi ++ * replace module. */ ++ int pid[3];/* process id from UI, 0:wps, 1:hostapd, 2:dhcpcd */ ++ int bDongle;/* build-in module or external dongle */ ++ u16 chip_type; ++ u16 HardwareType; ++ u16 interface_type;/* USB,SDIO,SPI,PCI */ ++ ++ struct dvobj_priv *dvobj; ++ struct mlme_priv mlmepriv; ++ struct mlme_ext_priv mlmeextpriv; ++ struct cmd_priv cmdpriv; ++ struct evt_priv evtpriv; ++ struct io_priv iopriv; ++ struct xmit_priv xmitpriv; ++ struct recv_priv recvpriv; ++ struct sta_priv stapriv; ++ struct security_priv securitypriv; ++ struct registry_priv registrypriv; ++ struct pwrctrl_priv pwrctrlpriv; ++ struct eeprom_priv eeprompriv; ++ struct led_priv ledpriv; ++ struct mp_priv mppriv; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ struct hostapd_priv *phostapdpriv; ++#endif ++ ++ struct wifidirect_info wdinfo; ++ ++ void *HalData; ++ u32 hal_data_sz; ++ struct hal_ops HalFunc; ++ ++ s32 bDriverStopped; ++ s32 bSurpriseRemoved; ++ s32 bCardDisableWOHSM; ++ ++ u32 IsrContent; ++ u32 ImrContent; ++ ++ u8 EepromAddressSize; ++ u8 hw_init_completed; ++ u8 bDriverIsGoingToUnload; ++ u8 init_adpt_in_progress; ++ u8 bHaltInProgress; ++ s8 signal_strength; ++ ++ void *cmdThread; ++ void *evtThread; ++ void *xmitThread; ++ void *recvThread; ++ void (*intf_start)(struct adapter *adapter); ++ void (*intf_stop)(struct adapter *adapter); ++ struct net_device *pnetdev; ++ ++ /* used by rtw_rereg_nd_name related function */ ++ struct rereg_nd_name_data { ++ struct net_device *old_pnetdev; ++ char old_ifname[IFNAMSIZ]; ++ u8 old_ips_mode; ++ u8 old_bRegUseLed; ++ } rereg_nd_name_priv; ++ ++ int bup; ++ struct net_device_stats stats; ++ struct iw_statistics iwstats; ++ struct proc_dir_entry *dir_dev;/* for proc directory */ ++ ++ int net_closed; ++ u8 bFWReady; ++ u8 bBTFWReady; ++ u8 bReadPortCancel; ++ u8 bWritePortCancel; ++ u8 bRxRSSIDisplay; ++ /* The driver will show up the desired channel number ++ * when this flag is 1. */ ++ u8 bNotifyChannelChange; ++#ifdef CONFIG_88EU_P2P ++ /* The driver will show the current P2P status when the ++ * upper application reads it. */ ++ u8 bShowGetP2PState; ++#endif ++ struct adapter *pbuddy_adapter; ++ ++ struct mutex *hw_init_mutex; ++ ++ spinlock_t br_ext_lock; ++ struct nat25_network_db_entry *nethash[NAT25_HASH_SIZE]; ++ int pppoe_connection_in_progress; ++ unsigned char pppoe_addr[MACADDRLEN]; ++ unsigned char scdb_mac[MACADDRLEN]; ++ unsigned char scdb_ip[4]; ++ struct nat25_network_db_entry *scdb_entry; ++ unsigned char br_mac[MACADDRLEN]; ++ unsigned char br_ip[4]; ++ struct br_ext_info ethBrExtInfo; ++ ++ u8 fix_rate; ++ ++ unsigned char in_cta_test; ++}; ++ ++#define adapter_to_dvobj(adapter) (adapter->dvobj) ++ ++int rtw_handle_dualmac(struct adapter *adapter, bool init); ++ ++static inline u8 *myid(struct eeprom_priv *peepriv) ++{ ++ return peepriv->mac_addr; ++} ++ ++#endif /* __DRV_TYPES_H__ */ +diff --git a/drivers/staging/r8188eu/include/hal_com.h b/drivers/staging/r8188eu/include/hal_com.h +new file mode 100644 +index 000000000000..95167f0b327f +--- /dev/null ++++ b/drivers/staging/r8188eu/include/hal_com.h +@@ -0,0 +1,156 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __HAL_COMMON_H__ ++#define __HAL_COMMON_H__ ++ ++/* */ ++/* Rate Definition */ ++/* */ ++/* CCK */ ++#define RATR_1M 0x00000001 ++#define RATR_2M 0x00000002 ++#define RATR_55M 0x00000004 ++#define RATR_11M 0x00000008 ++/* OFDM */ ++#define RATR_6M 0x00000010 ++#define RATR_9M 0x00000020 ++#define RATR_12M 0x00000040 ++#define RATR_18M 0x00000080 ++#define RATR_24M 0x00000100 ++#define RATR_36M 0x00000200 ++#define RATR_48M 0x00000400 ++#define RATR_54M 0x00000800 ++/* MCS 1 Spatial Stream */ ++#define RATR_MCS0 0x00001000 ++#define RATR_MCS1 0x00002000 ++#define RATR_MCS2 0x00004000 ++#define RATR_MCS3 0x00008000 ++#define RATR_MCS4 0x00010000 ++#define RATR_MCS5 0x00020000 ++#define RATR_MCS6 0x00040000 ++#define RATR_MCS7 0x00080000 ++/* MCS 2 Spatial Stream */ ++#define RATR_MCS8 0x00100000 ++#define RATR_MCS9 0x00200000 ++#define RATR_MCS10 0x00400000 ++#define RATR_MCS11 0x00800000 ++#define RATR_MCS12 0x01000000 ++#define RATR_MCS13 0x02000000 ++#define RATR_MCS14 0x04000000 ++#define RATR_MCS15 0x08000000 ++ ++/* CCK */ ++#define RATE_1M BIT(0) ++#define RATE_2M BIT(1) ++#define RATE_5_5M BIT(2) ++#define RATE_11M BIT(3) ++/* OFDM */ ++#define RATE_6M BIT(4) ++#define RATE_9M BIT(5) ++#define RATE_12M BIT(6) ++#define RATE_18M BIT(7) ++#define RATE_24M BIT(8) ++#define RATE_36M BIT(9) ++#define RATE_48M BIT(10) ++#define RATE_54M BIT(11) ++/* MCS 1 Spatial Stream */ ++#define RATE_MCS0 BIT(12) ++#define RATE_MCS1 BIT(13) ++#define RATE_MCS2 BIT(14) ++#define RATE_MCS3 BIT(15) ++#define RATE_MCS4 BIT(16) ++#define RATE_MCS5 BIT(17) ++#define RATE_MCS6 BIT(18) ++#define RATE_MCS7 BIT(19) ++/* MCS 2 Spatial Stream */ ++#define RATE_MCS8 BIT(20) ++#define RATE_MCS9 BIT(21) ++#define RATE_MCS10 BIT(22) ++#define RATE_MCS11 BIT(23) ++#define RATE_MCS12 BIT(24) ++#define RATE_MCS13 BIT(25) ++#define RATE_MCS14 BIT(26) ++#define RATE_MCS15 BIT(27) ++ ++/* ALL CCK Rate */ ++#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) ++#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M | \ ++ RATR_24M | RATR_36M | RATR_48M | RATR_54M) ++#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \ ++ RATR_MCS3 | RATR_MCS4 | RATR_MCS5|RATR_MCS6 | \ ++ RATR_MCS7) ++#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \ ++ RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \ ++ RATR_MCS14 | RATR_MCS15) ++ ++/*------------------------------ Tx Desc definition Macro --------------------*/ ++/* pragma mark -- Tx Desc related definition. -- */ ++/* Rate */ ++/* CCK Rates, TxHT = 0 */ ++#define DESC_RATE1M 0x00 ++#define DESC_RATE2M 0x01 ++#define DESC_RATE5_5M 0x02 ++#define DESC_RATE11M 0x03 ++ ++/* OFDM Rates, TxHT = 0 */ ++#define DESC_RATE6M 0x04 ++#define DESC_RATE9M 0x05 ++#define DESC_RATE12M 0x06 ++#define DESC_RATE18M 0x07 ++#define DESC_RATE24M 0x08 ++#define DESC_RATE36M 0x09 ++#define DESC_RATE48M 0x0a ++#define DESC_RATE54M 0x0b ++ ++/* MCS Rates, TxHT = 1 */ ++#define DESC_RATEMCS0 0x0c ++#define DESC_RATEMCS1 0x0d ++#define DESC_RATEMCS2 0x0e ++#define DESC_RATEMCS3 0x0f ++#define DESC_RATEMCS4 0x10 ++#define DESC_RATEMCS5 0x11 ++#define DESC_RATEMCS6 0x12 ++#define DESC_RATEMCS7 0x13 ++#define DESC_RATEMCS8 0x14 ++#define DESC_RATEMCS9 0x15 ++#define DESC_RATEMCS10 0x16 ++#define DESC_RATEMCS11 0x17 ++#define DESC_RATEMCS12 0x18 ++#define DESC_RATEMCS13 0x19 ++#define DESC_RATEMCS14 0x1a ++#define DESC_RATEMCS15 0x1b ++#define DESC_RATEMCS15_SG 0x1c ++#define DESC_RATEMCS32 0x20 ++ ++/* 1 Byte long (in unit of TU) */ ++#define REG_P2P_CTWIN 0x0572 ++#define REG_NOA_DESC_SEL 0x05CF ++#define REG_NOA_DESC_DURATION 0x05E0 ++#define REG_NOA_DESC_INTERVAL 0x05E4 ++#define REG_NOA_DESC_START 0x05E8 ++#define REG_NOA_DESC_COUNT 0x05EC ++ ++#include "HalVerDef.h" ++void dump_chip_info(struct HAL_VERSION ChipVersion); ++ ++/* return the final channel plan decision */ ++u8 hal_com_get_channel_plan(struct adapter *padapter, ++ u8 hw_channel_plan, ++ u8 sw_channel_plan, ++ u8 def_channel_plan, ++ bool AutoLoadFail ++); ++ ++u8 MRateToHwRate(u8 rate); ++ ++void HalSetBrateCfg(struct adapter *Adapter, u8 *mBratesOS, u16 *pBrateCfg); ++ ++bool Hal_MappingOutPipe(struct adapter *pAdapter, u8 NumOutPipe); ++ ++void hal_init_macaddr(struct adapter *adapter); ++ ++void c2h_evt_clear(struct adapter *adapter); ++s32 c2h_evt_read(struct adapter *adapter, u8 *buf); ++ ++#endif /* __HAL_COMMON_H__ */ +diff --git a/drivers/staging/r8188eu/include/hal_intf.h b/drivers/staging/r8188eu/include/hal_intf.h +new file mode 100644 +index 000000000000..fa252540e596 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/hal_intf.h +@@ -0,0 +1,411 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#ifndef __HAL_INTF_H__ ++#define __HAL_INTF_H__ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "Hal8188EPhyCfg.h" ++ ++enum RTL871X_HCI_TYPE { ++ RTW_PCIE = BIT(0), ++ RTW_USB = BIT(1), ++ RTW_SDIO = BIT(2), ++ RTW_GSPI = BIT(3), ++}; ++ ++enum _CHIP_TYPE { ++ NULL_CHIP_TYPE, ++ RTL8712_8188S_8191S_8192S, ++ RTL8188C_8192C, ++ RTL8192D, ++ RTL8723A, ++ RTL8188E, ++ MAX_CHIP_TYPE ++}; ++ ++enum hw_variables { ++ HW_VAR_MEDIA_STATUS, ++ HW_VAR_MEDIA_STATUS1, ++ HW_VAR_SET_OPMODE, ++ HW_VAR_MAC_ADDR, ++ HW_VAR_BSSID, ++ HW_VAR_INIT_RTS_RATE, ++ HW_VAR_BASIC_RATE, ++ HW_VAR_TXPAUSE, ++ HW_VAR_BCN_FUNC, ++ HW_VAR_CORRECT_TSF, ++ HW_VAR_CHECK_BSSID, ++ HW_VAR_MLME_DISCONNECT, ++ HW_VAR_MLME_SITESURVEY, ++ HW_VAR_MLME_JOIN, ++ HW_VAR_BEACON_INTERVAL, ++ HW_VAR_SLOT_TIME, ++ HW_VAR_RESP_SIFS, ++ HW_VAR_ACK_PREAMBLE, ++ HW_VAR_SEC_CFG, ++ HW_VAR_BCN_VALID, ++ HW_VAR_RF_TYPE, ++ HW_VAR_DM_FLAG, ++ HW_VAR_DM_FUNC_OP, ++ HW_VAR_DM_FUNC_SET, ++ HW_VAR_DM_FUNC_CLR, ++ HW_VAR_CAM_EMPTY_ENTRY, ++ HW_VAR_CAM_INVALID_ALL, ++ HW_VAR_CAM_WRITE, ++ HW_VAR_CAM_READ, ++ HW_VAR_AC_PARAM_VO, ++ HW_VAR_AC_PARAM_VI, ++ HW_VAR_AC_PARAM_BE, ++ HW_VAR_AC_PARAM_BK, ++ HW_VAR_ACM_CTRL, ++ HW_VAR_AMPDU_MIN_SPACE, ++ HW_VAR_AMPDU_FACTOR, ++ HW_VAR_RXDMA_AGG_PG_TH, ++ HW_VAR_SET_RPWM, ++ HW_VAR_H2C_FW_PWRMODE, ++ HW_VAR_H2C_FW_JOINBSSRPT, ++ HW_VAR_FWLPS_RF_ON, ++ HW_VAR_H2C_FW_P2P_PS_OFFLOAD, ++ HW_VAR_TDLS_WRCR, ++ HW_VAR_TDLS_INIT_CH_SEN, ++ HW_VAR_TDLS_RS_RCR, ++ HW_VAR_TDLS_DONE_CH_SEN, ++ HW_VAR_INITIAL_GAIN, ++ HW_VAR_TRIGGER_GPIO_0, ++ HW_VAR_BT_SET_COEXIST, ++ HW_VAR_BT_ISSUE_DELBA, ++ HW_VAR_CURRENT_ANTENNA, ++ HW_VAR_ANTENNA_DIVERSITY_LINK, ++ HW_VAR_ANTENNA_DIVERSITY_SELECT, ++ HW_VAR_SWITCH_EPHY_WoWLAN, ++ HW_VAR_EFUSE_USAGE, ++ HW_VAR_EFUSE_BYTES, ++ HW_VAR_EFUSE_BT_USAGE, ++ HW_VAR_EFUSE_BT_BYTES, ++ HW_VAR_FIFO_CLEARN_UP, ++ HW_VAR_CHECK_TXBUF, ++ HW_VAR_APFM_ON_MAC, /* Auto FSM to Turn On, include clock, isolation, ++ * power control for MAC only */ ++ /* The valid upper nav range for the HW updating, if the true value is ++ * larger than the upper range, the HW won't update it. */ ++ /* Unit in microsecond. 0 means disable this function. */ ++ HW_VAR_NAV_UPPER, ++ HW_VAR_RPT_TIMER_SETTING, ++ HW_VAR_TX_RPT_MAX_MACID, ++ HW_VAR_H2C_MEDIA_STATUS_RPT, ++ HW_VAR_CHK_HI_QUEUE_EMPTY, ++}; ++ ++enum hal_def_variable { ++ HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, ++ HAL_DEF_IS_SUPPORT_ANT_DIV, ++ HAL_DEF_CURRENT_ANTENNA, ++ HAL_DEF_DRVINFO_SZ, ++ HAL_DEF_MAX_RECVBUF_SZ, ++ HAL_DEF_RX_PACKET_OFFSET, ++ HAL_DEF_DBG_DUMP_RXPKT,/* for dbg */ ++ HAL_DEF_DBG_DM_FUNC,/* for dbg */ ++ HAL_DEF_RA_DECISION_RATE, ++ HAL_DEF_RA_SGI, ++ HAL_DEF_PT_PWR_STATUS, ++ HW_VAR_MAX_RX_AMPDU_FACTOR, ++ HW_DEF_RA_INFO_DUMP, ++ HAL_DEF_DBG_DUMP_TXPKT, ++}; ++ ++enum hal_odm_variable { ++ HAL_ODM_STA_INFO, ++ HAL_ODM_P2P_STATE, ++ HAL_ODM_WIFI_DISPLAY_STATE, ++}; ++ ++enum hal_intf_ps_func { ++ HAL_USB_SELECT_SUSPEND, ++ HAL_MAX_ID, ++}; ++ ++typedef s32 (*c2h_id_filter)(u8 id); ++ ++struct hal_ops { ++ u32 (*hal_power_on)(struct adapter *padapter); ++ u32 (*hal_init)(struct adapter *padapter); ++ u32 (*hal_deinit)(struct adapter *padapter); ++ ++ void (*free_hal_data)(struct adapter *padapter); ++ ++ u32 (*inirp_init)(struct adapter *padapter); ++ u32 (*inirp_deinit)(struct adapter *padapter); ++ ++ s32 (*init_xmit_priv)(struct adapter *padapter); ++ ++ s32 (*init_recv_priv)(struct adapter *padapter); ++ void (*free_recv_priv)(struct adapter *padapter); ++ ++ void (*InitSwLeds)(struct adapter *padapter); ++ void (*DeInitSwLeds)(struct adapter *padapter); ++ ++ void (*dm_init)(struct adapter *padapter); ++ void (*dm_deinit)(struct adapter *padapter); ++ void (*read_chip_version)(struct adapter *padapter); ++ ++ void (*init_default_value)(struct adapter *padapter); ++ ++ void (*intf_chip_configure)(struct adapter *padapter); ++ ++ void (*read_adapter_info)(struct adapter *padapter); ++ ++ void (*enable_interrupt)(struct adapter *padapter); ++ void (*disable_interrupt)(struct adapter *padapter); ++ s32 (*interrupt_handler)(struct adapter *padapter); ++ ++ void (*set_bwmode_handler)(struct adapter *padapter, ++ enum ht_channel_width Bandwidth, ++ u8 Offset); ++ void (*set_channel_handler)(struct adapter *padapter, u8 channel); ++ ++ void (*hal_dm_watchdog)(struct adapter *padapter); ++ ++ void (*SetHwRegHandler)(struct adapter *padapter, u8 variable, ++ u8 *val); ++ void (*GetHwRegHandler)(struct adapter *padapter, u8 variable, ++ u8 *val); ++ ++ u8 (*GetHalDefVarHandler)(struct adapter *padapter, ++ enum hal_def_variable eVariable, ++ void *pValue); ++ u8 (*SetHalDefVarHandler)(struct adapter *padapter, ++ enum hal_def_variable eVariable, ++ void *pValue); ++ ++ void (*GetHalODMVarHandler)(struct adapter *padapter, ++ enum hal_odm_variable eVariable, ++ void *pValue1, bool bSet); ++ void (*SetHalODMVarHandler)(struct adapter *padapter, ++ enum hal_odm_variable eVariable, ++ void *pValue1, bool bSet); ++ ++ void (*UpdateRAMaskHandler)(struct adapter *padapter, ++ u32 mac_id, u8 rssi_level); ++ void (*SetBeaconRelatedRegistersHandler)(struct adapter *padapter); ++ ++ void (*Add_RateATid)(struct adapter *adapter, u32 bitmap, u8 arg, ++ u8 rssi_level); ++ void (*run_thread)(struct adapter *adapter); ++ void (*cancel_thread)(struct adapter *adapter); ++ ++ u8 (*AntDivBeforeLinkHandler)(struct adapter *adapter); ++ void (*AntDivCompareHandler)(struct adapter *adapter, ++ struct wlan_bssid_ex *dst, ++ struct wlan_bssid_ex *src); ++ u8 (*interface_ps_func)(struct adapter *padapter, ++ enum hal_intf_ps_func efunc_id, u8 *val); ++ ++ s32 (*hal_xmit)(struct adapter *padapter, ++ struct xmit_frame *pxmitframe); ++ s32 (*mgnt_xmit)(struct adapter *padapter, ++ struct xmit_frame *pmgntframe); ++ s32 (*hal_xmitframe_enqueue)(struct adapter *padapter, ++ struct xmit_frame *pxmitframe); ++ ++ u32 (*read_bbreg)(struct adapter *padapter, u32 RegAddr, ++ u32 BitMask); ++ void (*write_bbreg)(struct adapter *padapter, u32 RegAddr, ++ u32 BitMask, u32 Data); ++ u32 (*read_rfreg)(struct adapter *padapter, ++ enum rf_radio_path eRFPath, u32 RegAddr, ++ u32 BitMask); ++ void (*write_rfreg)(struct adapter *padapter, ++ enum rf_radio_path eRFPath, u32 RegAddr, ++ u32 BitMask, u32 Data); ++ ++ void (*EfusePowerSwitch)(struct adapter *padapter, u8 bWrite, ++ u8 PwrState); ++ void (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset, ++ u16 _size_byte, u8 *pbuf, bool bPseudoTest); ++ void (*EFUSEGetEfuseDefinition)(struct adapter *padapter, u8 efuseType, ++ u8 type, void *pOut, bool bPseudoTest); ++ u16 (*EfuseGetCurrentSize)(struct adapter *padapter, u8 efuseType, ++ bool bPseudoTest); ++ int (*Efuse_PgPacketRead)(struct adapter *adapter, u8 offset, ++ u8 *data, bool bPseudoTest); ++ int (*Efuse_PgPacketWrite)(struct adapter *padapter, u8 offset, ++ u8 word_en, u8 *data, bool bPseudoTest); ++ u8 (*Efuse_WordEnableDataWrite)(struct adapter *padapter, ++ u16 efuse_addr, u8 word_en, ++ u8 *data, bool bPseudoTest); ++ bool (*Efuse_PgPacketWrite_BT)(struct adapter *padapter, u8 offset, ++ u8 word_en, u8 *data, bool test); ++ ++ void (*sreset_init_value)(struct adapter *padapter); ++ void (*sreset_reset_value)(struct adapter *padapter); ++ void (*silentreset)(struct adapter *padapter); ++ void (*sreset_xmit_status_check)(struct adapter *padapter); ++ void (*sreset_linked_status_check) (struct adapter *padapter); ++ u8 (*sreset_get_wifi_status)(struct adapter *padapter); ++ ++ int (*IOL_exec_cmds_sync)(struct adapter *padapter, ++ struct xmit_frame *frame, u32 max_wait, ++ u32 bndy_cnt); ++ ++ void (*hal_notch_filter)(struct adapter *adapter, bool enable); ++ void (*hal_reset_security_engine)(struct adapter *adapter); ++ s32 (*c2h_handler)(struct adapter *padapter, ++ struct c2h_evt_hdr *c2h_evt); ++ c2h_id_filter c2h_id_filter_ccx; ++}; ++ ++enum rt_eeprom_type { ++ EEPROM_93C46, ++ EEPROM_93C56, ++ EEPROM_BOOT_EFUSE, ++}; ++ ++#define RF_CHANGE_BY_INIT 0 ++#define RF_CHANGE_BY_IPS BIT(28) ++#define RF_CHANGE_BY_PS BIT(29) ++#define RF_CHANGE_BY_HW BIT(30) ++#define RF_CHANGE_BY_SW BIT(31) ++ ++enum hardware_type { ++ HARDWARE_TYPE_RTL8180, ++ HARDWARE_TYPE_RTL8185, ++ HARDWARE_TYPE_RTL8187, ++ HARDWARE_TYPE_RTL8188, ++ HARDWARE_TYPE_RTL8190P, ++ HARDWARE_TYPE_RTL8192E, ++ HARDWARE_TYPE_RTL819xU, ++ HARDWARE_TYPE_RTL8192SE, ++ HARDWARE_TYPE_RTL8192SU, ++ HARDWARE_TYPE_RTL8192CE, ++ HARDWARE_TYPE_RTL8192CU, ++ HARDWARE_TYPE_RTL8192DE, ++ HARDWARE_TYPE_RTL8192DU, ++ HARDWARE_TYPE_RTL8723AE, ++ HARDWARE_TYPE_RTL8723AU, ++ HARDWARE_TYPE_RTL8723AS, ++ HARDWARE_TYPE_RTL8188EE, ++ HARDWARE_TYPE_RTL8188EU, ++ HARDWARE_TYPE_RTL8188ES, ++ HARDWARE_TYPE_MAX, ++}; ++ ++/* RTL8188E Series */ ++#define IS_HARDWARE_TYPE_8188EE(_Adapter) \ ++(((struct adapter *)_Adapter)->HardwareType == HARDWARE_TYPE_RTL8188EE) ++#define IS_HARDWARE_TYPE_8188EU(_Adapter) \ ++(((struct adapter *)_Adapter)->HardwareType == HARDWARE_TYPE_RTL8188EU) ++#define IS_HARDWARE_TYPE_8188ES(_Adapter) \ ++(((struct adapter *)_Adapter)->HardwareType == HARDWARE_TYPE_RTL8188ES) ++#define IS_HARDWARE_TYPE_8188E(_Adapter) \ ++(IS_HARDWARE_TYPE_8188EE(_Adapter) || IS_HARDWARE_TYPE_8188EU(_Adapter) || \ ++ IS_HARDWARE_TYPE_8188ES(_Adapter)) ++ ++#define GET_EEPROM_EFUSE_PRIV(adapter) (&adapter->eeprompriv) ++ ++#define is_boot_from_eeprom(adapter) (adapter->eeprompriv.EepromOrEfuse) ++ ++void rtl8188eu_set_hal_ops(struct adapter *padapter); ++void rtw_hal_def_value_init(struct adapter *padapter); ++ ++void rtw_hal_free_data(struct adapter *padapter); ++ ++void rtw_hal_dm_init(struct adapter *padapter); ++void rtw_hal_dm_deinit(struct adapter *padapter); ++void rtw_hal_sw_led_init(struct adapter *padapter); ++void rtw_hal_sw_led_deinit(struct adapter *padapter); ++ ++u32 rtw_hal_power_on(struct adapter *padapter); ++uint rtw_hal_init(struct adapter *padapter); ++uint rtw_hal_deinit(struct adapter *padapter); ++void rtw_hal_stop(struct adapter *padapter); ++void rtw_hal_set_hwreg(struct adapter *padapter, u8 variable, u8 *val); ++void rtw_hal_get_hwreg(struct adapter *padapter, u8 variable, u8 *val); ++ ++void rtw_hal_chip_configure(struct adapter *padapter); ++void rtw_hal_read_chip_info(struct adapter *padapter); ++void rtw_hal_read_chip_version(struct adapter *padapter); ++ ++u8 rtw_hal_set_def_var(struct adapter *padapter, ++ enum hal_def_variable eVariable, void *pValue); ++u8 rtw_hal_get_def_var(struct adapter *padapter, ++ enum hal_def_variable eVariable, void *pValue); ++ ++void rtw_hal_set_odm_var(struct adapter *padapter, ++ enum hal_odm_variable eVariable, void *pValue1, ++ bool bSet); ++void rtw_hal_get_odm_var(struct adapter *padapter, ++ enum hal_odm_variable eVariable, ++ void *pValue1, bool bSet); ++ ++void rtw_hal_enable_interrupt(struct adapter *padapter); ++void rtw_hal_disable_interrupt(struct adapter *padapter); ++ ++u32 rtw_hal_inirp_init(struct adapter *padapter); ++u32 rtw_hal_inirp_deinit(struct adapter *padapter); ++ ++u8 rtw_hal_intf_ps_func(struct adapter *padapter, ++ enum hal_intf_ps_func efunc_id, u8 *val); ++s32 rtw_hal_xmitframe_enqueue(struct adapter *padapter, ++ struct xmit_frame *pxmitframe); ++ ++s32 rtw_hal_xmit(struct adapter *padapter, struct xmit_frame *pxmitframe); ++s32 rtw_hal_mgnt_xmit(struct adapter *padapter, ++ struct xmit_frame *pmgntframe); ++ ++s32 rtw_hal_init_xmit_priv(struct adapter *padapter); ++ ++s32 rtw_hal_init_recv_priv(struct adapter *padapter); ++void rtw_hal_free_recv_priv(struct adapter *padapter); ++ ++void rtw_hal_update_ra_mask(struct adapter *padapter, u32 mac_id, u8 level); ++void rtw_hal_add_ra_tid(struct adapter *adapt, u32 bitmap, u8 arg, u8 level); ++void rtw_hal_clone_data(struct adapter *dst_adapt, ++ struct adapter *src_adapt); ++void rtw_hal_start_thread(struct adapter *padapter); ++void rtw_hal_stop_thread(struct adapter *padapter); ++ ++void rtw_hal_bcn_related_reg_setting(struct adapter *padapter); ++ ++u32 rtw_hal_read_bbreg(struct adapter *padapter, u32 RegAddr, u32 BitMask); ++void rtw_hal_write_bbreg(struct adapter *padapter, u32 RegAddr, u32 BitMask, ++ u32 Data); ++u32 rtw_hal_read_rfreg(struct adapter *padapter, enum rf_radio_path eRFPath, ++ u32 RegAddr, u32 BitMask); ++void rtw_hal_write_rfreg(struct adapter *padapter, ++ enum rf_radio_path eRFPath, u32 RegAddr, ++ u32 BitMask, u32 Data); ++ ++s32 rtw_hal_interrupt_handler(struct adapter *padapter); ++ ++void rtw_hal_set_bwmode(struct adapter *padapter, ++ enum ht_channel_width Bandwidth, u8 Offset); ++void rtw_hal_set_chan(struct adapter *padapter, u8 channel); ++void rtw_hal_dm_watchdog(struct adapter *padapter); ++ ++u8 rtw_hal_antdiv_before_linked(struct adapter *padapter); ++void rtw_hal_antdiv_rssi_compared(struct adapter *padapter, ++ struct wlan_bssid_ex *dst, ++ struct wlan_bssid_ex *src); ++ ++void rtw_hal_sreset_init(struct adapter *padapter); ++void rtw_hal_sreset_reset(struct adapter *padapter); ++void rtw_hal_sreset_reset_value(struct adapter *padapter); ++void rtw_hal_sreset_xmit_status_check(struct adapter *padapter); ++void rtw_hal_sreset_linked_status_check(struct adapter *padapter); ++u8 rtw_hal_sreset_get_wifi_status(struct adapter *padapter); ++ ++int rtw_hal_iol_cmd(struct adapter *adapter, struct xmit_frame *xmit_frame, ++ u32 max_wating_ms, u32 bndy_cnt); ++ ++void rtw_hal_notch_filter(struct adapter *adapter, bool enable); ++void rtw_hal_reset_security_engine(struct adapter *adapter); ++ ++s32 rtw_hal_c2h_handler(struct adapter *adapter, ++ struct c2h_evt_hdr *c2h_evt); ++c2h_id_filter rtw_hal_c2h_id_filter_ccx(struct adapter *adapter); ++void indicate_wx_scan_complete_event(struct adapter *padapter); ++u8 rtw_do_join(struct adapter *padapter); ++ ++#endif /* __HAL_INTF_H__ */ +diff --git a/drivers/staging/r8188eu/include/ieee80211.h b/drivers/staging/r8188eu/include/ieee80211.h +new file mode 100644 +index 000000000000..bc5b030e9c40 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/ieee80211.h +@@ -0,0 +1,1226 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __IEEE80211_H ++#define __IEEE80211_H ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "wifi.h" ++#include ++ ++#define MGMT_QUEUE_NUM 5 ++ ++#define ETH_ALEN 6 ++#define ETH_TYPE_LEN 2 ++#define PAYLOAD_TYPE_LEN 1 ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++#define RTL_IOCTL_HOSTAPD (SIOCIWFIRSTPRIV + 28) ++ ++/* RTL871X_IOCTL_HOSTAPD ioctl() cmd: */ ++enum { ++ RTL871X_HOSTAPD_FLUSH = 1, ++ RTL871X_HOSTAPD_ADD_STA = 2, ++ RTL871X_HOSTAPD_REMOVE_STA = 3, ++ RTL871X_HOSTAPD_GET_INFO_STA = 4, ++ /* REMOVED: PRISM2_HOSTAPD_RESET_TXEXC_STA = 5, */ ++ RTL871X_HOSTAPD_GET_WPAIE_STA = 5, ++ RTL871X_SET_ENCRYPTION = 6, ++ RTL871X_GET_ENCRYPTION = 7, ++ RTL871X_HOSTAPD_SET_FLAGS_STA = 8, ++ RTL871X_HOSTAPD_GET_RID = 9, ++ RTL871X_HOSTAPD_SET_RID = 10, ++ RTL871X_HOSTAPD_SET_ASSOC_AP_ADDR = 11, ++ RTL871X_HOSTAPD_SET_GENERIC_ELEMENT = 12, ++ RTL871X_HOSTAPD_MLME = 13, ++ RTL871X_HOSTAPD_SCAN_REQ = 14, ++ RTL871X_HOSTAPD_STA_CLEAR_STATS = 15, ++ RTL871X_HOSTAPD_SET_BEACON = 16, ++ RTL871X_HOSTAPD_SET_WPS_BEACON = 17, ++ RTL871X_HOSTAPD_SET_WPS_PROBE_RESP = 18, ++ RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP = 19, ++ RTL871X_HOSTAPD_SET_HIDDEN_SSID = 20, ++ RTL871X_HOSTAPD_SET_MACADDR_ACL = 21, ++ RTL871X_HOSTAPD_ACL_ADD_STA = 22, ++ RTL871X_HOSTAPD_ACL_REMOVE_STA = 23, ++}; ++ ++/* STA flags */ ++#define WLAN_STA_AUTH BIT(0) ++#define WLAN_STA_ASSOC BIT(1) ++#define WLAN_STA_PS BIT(2) ++#define WLAN_STA_TIM BIT(3) ++#define WLAN_STA_PERM BIT(4) ++#define WLAN_STA_AUTHORIZED BIT(5) ++#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */ ++#define WLAN_STA_SHORT_PREAMBLE BIT(7) ++#define WLAN_STA_PREAUTH BIT(8) ++#define WLAN_STA_WME BIT(9) ++#define WLAN_STA_MFP BIT(10) ++#define WLAN_STA_HT BIT(11) ++#define WLAN_STA_WPS BIT(12) ++#define WLAN_STA_MAYBE_WPS BIT(13) ++#define WLAN_STA_NONERP BIT(31) ++ ++#endif ++ ++#define IEEE_CMD_SET_WPA_PARAM 1 ++#define IEEE_CMD_SET_WPA_IE 2 ++#define IEEE_CMD_SET_ENCRYPTION 3 ++#define IEEE_CMD_MLME 4 ++ ++#define IEEE_PARAM_WPA_ENABLED 1 ++#define IEEE_PARAM_TKIP_COUNTERMEASURES 2 ++#define IEEE_PARAM_DROP_UNENCRYPTED 3 ++#define IEEE_PARAM_PRIVACY_INVOKED 4 ++#define IEEE_PARAM_AUTH_ALGS 5 ++#define IEEE_PARAM_IEEE_802_1X 6 ++#define IEEE_PARAM_WPAX_SELECT 7 ++ ++#define AUTH_ALG_OPEN_SYSTEM 0x1 ++#define AUTH_ALG_SHARED_KEY 0x2 ++#define AUTH_ALG_LEAP 0x00000004 ++ ++#define IEEE_MLME_STA_DEAUTH 1 ++#define IEEE_MLME_STA_DISASSOC 2 ++ ++#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2 ++#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3 ++#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4 ++#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5 ++#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6 ++#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7 ++ ++#define IEEE_CRYPT_ALG_NAME_LEN 16 ++ ++#define WPA_CIPHER_NONE BIT(0) ++#define WPA_CIPHER_WEP40 BIT(1) ++#define WPA_CIPHER_WEP104 BIT(2) ++#define WPA_CIPHER_TKIP BIT(3) ++#define WPA_CIPHER_CCMP BIT(4) ++ ++ ++#define WPA_SELECTOR_LEN 4 ++extern u8 RTW_WPA_OUI_TYPE[]; ++extern u16 RTW_WPA_VERSION; ++extern u8 WPA_AUTH_KEY_MGMT_NONE[]; ++extern u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[]; ++extern u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[]; ++extern u8 WPA_CIPHER_SUITE_NONE[]; ++extern u8 WPA_CIPHER_SUITE_WEP40[]; ++extern u8 WPA_CIPHER_SUITE_TKIP[]; ++extern u8 WPA_CIPHER_SUITE_WRAP[]; ++extern u8 WPA_CIPHER_SUITE_CCMP[]; ++extern u8 WPA_CIPHER_SUITE_WEP104[]; ++ ++#define RSN_HEADER_LEN 4 ++#define RSN_SELECTOR_LEN 4 ++ ++extern u16 RSN_VERSION_BSD; ++extern u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[]; ++extern u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[]; ++extern u8 RSN_CIPHER_SUITE_NONE[]; ++extern u8 RSN_CIPHER_SUITE_WEP40[]; ++extern u8 RSN_CIPHER_SUITE_TKIP[]; ++extern u8 RSN_CIPHER_SUITE_WRAP[]; ++extern u8 RSN_CIPHER_SUITE_CCMP[]; ++extern u8 RSN_CIPHER_SUITE_WEP104[]; ++ ++enum ratr_table_mode { ++ RATR_INX_WIRELESS_NGB = 0, /* BGN 40 Mhz 2SS 1SS */ ++ RATR_INX_WIRELESS_NG = 1, /* GN or N */ ++ RATR_INX_WIRELESS_NB = 2, /* BGN 20 Mhz 2SS 1SS or BN */ ++ RATR_INX_WIRELESS_N = 3, ++ RATR_INX_WIRELESS_GB = 4, ++ RATR_INX_WIRELESS_G = 5, ++ RATR_INX_WIRELESS_B = 6, ++ RATR_INX_WIRELESS_MC = 7, ++ RATR_INX_WIRELESS_AC_N = 8, ++}; ++ ++enum NETWORK_TYPE { ++ WIRELESS_INVALID = 0, ++ /* Sub-Element */ ++ WIRELESS_11B = BIT(0), /* tx:cck only, rx:cck only, hw: cck */ ++ WIRELESS_11G = BIT(1), /* tx:ofdm only, rx:ofdm & cck, hw:cck & ofdm*/ ++ WIRELESS_11_24N = BIT(3), /* tx:MCS only, rx:MCS & cck, hw:MCS & cck */ ++ ++ /* Combination */ ++ /* tx: cck & ofdm, rx: cck & ofdm & MCS, hw: cck & ofdm */ ++ WIRELESS_11BG = (WIRELESS_11B | WIRELESS_11G), ++ /* tx: ofdm & MCS, rx: ofdm & cck & MCS, hw: cck & ofdm */ ++ WIRELESS_11G_24N = (WIRELESS_11G | WIRELESS_11_24N), ++ /* tx: ofdm & cck & MCS, rx: ofdm & cck & MCS, hw: ofdm & cck */ ++ WIRELESS_11BG_24N = (WIRELESS_11B | WIRELESS_11G | WIRELESS_11_24N), ++}; ++ ++#define SUPPORTED_24G_NETTYPE_MSK \ ++ (WIRELESS_11B | WIRELESS_11G | WIRELESS_11_24N) ++ ++#define IsSupported24G(NetType) \ ++ ((NetType) & SUPPORTED_24G_NETTYPE_MSK ? true : false) ++ ++#define IsEnableHWCCK(NetType) \ ++ IsSupported24G(NetType) ++ ++#define IsSupportedRxCCK(NetType) IsEnableHWCCK(NetType) ++ ++#define IsSupportedTxCCK(NetType) \ ++ ((NetType) & (WIRELESS_11B) ? true : false) ++#define IsSupportedTxOFDM(NetType) \ ++ ((NetType) & (WIRELESS_11G) ? true : false) ++#define IsSupportedTxMCS(NetType) \ ++ ((NetType) & (WIRELESS_11_24N) ? true : false) ++ ++struct ieee_param { ++ u32 cmd; ++ u8 sta_addr[ETH_ALEN]; ++ union { ++ struct { ++ u8 name; ++ u32 value; ++ } wpa_param; ++ struct { ++ u32 len; ++ u8 reserved[32]; ++ u8 data[0]; ++ } wpa_ie; ++ struct { ++ int command; ++ int reason_code; ++ } mlme; ++ struct { ++ u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; ++ u8 set_tx; ++ u32 err; ++ u8 idx; ++ u8 seq[8]; /* sequence counter (set: RX, get: TX) */ ++ u16 key_len; ++ u8 key[0]; ++ } crypt; ++#ifdef CONFIG_88EU_AP_MODE ++ struct { ++ u16 aid; ++ u16 capability; ++ int flags; ++ u8 tx_supp_rates[16]; ++ struct ieee80211_ht_cap ht_cap; ++ } add_sta; ++ struct { ++ u8 reserved[2];/* for set max_num_sta */ ++ u8 buf[0]; ++ } bcn_ie; ++#endif ++ ++ } u; ++}; ++ ++#ifdef CONFIG_88EU_AP_MODE ++struct ieee_param_ex { ++ u32 cmd; ++ u8 sta_addr[ETH_ALEN]; ++ u8 data[0]; ++}; ++ ++struct sta_data { ++ u16 aid; ++ u16 capability; ++ int flags; ++ u32 sta_set; ++ u8 tx_supp_rates[16]; ++ u32 tx_supp_rates_len; ++ struct ieee80211_ht_cap ht_cap; ++ u64 rx_pkts; ++ u64 rx_bytes; ++ u64 rx_drops; ++ u64 tx_pkts; ++ u64 tx_bytes; ++ u64 tx_drops; ++}; ++#endif ++ ++#define IEEE80211_DATA_LEN 2304 ++/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section ++ 6.2.1.1.2. ++ ++ The figure in section 7.1.2 suggests a body size of up to 2312 ++ bytes is allowed, which is a bit confusing, I suspect this ++ represents the 2304 bytes of real data, plus a possible 8 bytes of ++ WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ ++ ++#define IEEE80211_HLEN 30 ++#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) ++ ++/* this is stolen from ipw2200 driver */ ++#define IEEE_IBSS_MAC_HASH_SIZE 31 ++ ++struct ieee_ibss_seq { ++ u8 mac[ETH_ALEN]; ++ u16 seq_num; ++ u16 frag_num; ++ unsigned long packet_time; ++ struct list_head list; ++}; ++ ++struct rtw_ieee80211_hdr { ++ __le16 frame_ctl; ++ __le16 duration_id; ++ u8 addr1[ETH_ALEN]; ++ u8 addr2[ETH_ALEN]; ++ u8 addr3[ETH_ALEN]; ++ u16 seq_ctl; ++ u8 addr4[ETH_ALEN]; ++} __packed; ++ ++struct rtw_ieee80211_hdr_3addr { ++ __le16 frame_ctl; ++ __le16 duration_id; ++ u8 addr1[ETH_ALEN]; ++ u8 addr2[ETH_ALEN]; ++ u8 addr3[ETH_ALEN]; ++ u16 seq_ctl; ++} __packed; ++ ++struct rtw_ieee80211_hdr_qos { ++ __le16 frame_ctl; ++ __le16 duration_id; ++ u8 addr1[ETH_ALEN]; ++ u8 addr2[ETH_ALEN]; ++ u8 addr3[ETH_ALEN]; ++ u16 seq_ctl; ++ u8 addr4[ETH_ALEN]; ++ u16 qc; ++} __packed; ++ ++struct rtw_ieee80211_hdr_3addr_qos { ++ __le16 frame_ctl; ++ __le16 duration_id; ++ u8 addr1[ETH_ALEN]; ++ u8 addr2[ETH_ALEN]; ++ u8 addr3[ETH_ALEN]; ++ u16 seq_ctl; ++ u16 qc; ++} __packed; ++ ++struct eapol { ++ u8 snap[6]; ++ u16 ethertype; ++ u8 version; ++ u8 type; ++ u16 length; ++} __packed; ++ ++enum eap_type { ++ EAP_PACKET = 0, ++ EAPOL_START, ++ EAPOL_LOGOFF, ++ EAPOL_KEY, ++ EAPOL_ENCAP_ASF_ALERT ++}; ++ ++#define IEEE80211_3ADDR_LEN 24 ++#define IEEE80211_4ADDR_LEN 30 ++#define IEEE80211_FCS_LEN 4 ++ ++#define MIN_FRAG_THRESHOLD 256U ++#define MAX_FRAG_THRESHOLD 2346U ++ ++/* Frame control field constants */ ++#define RTW_IEEE80211_FCTL_VERS 0x0003 ++#define RTW_IEEE80211_FCTL_FTYPE 0x000c ++#define RTW_IEEE80211_FCTL_STYPE 0x00f0 ++#define RTW_IEEE80211_FCTL_TODS 0x0100 ++#define RTW_IEEE80211_FCTL_FROMDS 0x0200 ++#define RTW_IEEE80211_FCTL_MOREFRAGS 0x0400 ++#define RTW_IEEE80211_FCTL_RETRY 0x0800 ++#define RTW_IEEE80211_FCTL_PM 0x1000 ++#define RTW_IEEE80211_FCTL_MOREDATA 0x2000 ++#define RTW_IEEE80211_FCTL_PROTECTED 0x4000 ++#define RTW_IEEE80211_FCTL_ORDER 0x8000 ++#define RTW_IEEE80211_FCTL_CTL_EXT 0x0f00 ++ ++#define RTW_IEEE80211_FTYPE_MGMT 0x0000 ++#define RTW_IEEE80211_FTYPE_CTL 0x0004 ++#define RTW_IEEE80211_FTYPE_DATA 0x0008 ++#define RTW_IEEE80211_FTYPE_EXT 0x000c ++ ++/* management */ ++#define RTW_IEEE80211_STYPE_ASSOC_REQ 0x0000 ++#define RTW_IEEE80211_STYPE_ASSOC_RESP 0x0010 ++#define RTW_IEEE80211_STYPE_REASSOC_REQ 0x0020 ++#define RTW_IEEE80211_STYPE_REASSOC_RESP 0x0030 ++#define RTW_IEEE80211_STYPE_PROBE_REQ 0x0040 ++#define RTW_IEEE80211_STYPE_PROBE_RESP 0x0050 ++#define RTW_IEEE80211_STYPE_BEACON 0x0080 ++#define RTW_IEEE80211_STYPE_ATIM 0x0090 ++#define RTW_IEEE80211_STYPE_DISASSOC 0x00A0 ++#define RTW_IEEE80211_STYPE_AUTH 0x00B0 ++#define RTW_IEEE80211_STYPE_DEAUTH 0x00C0 ++#define RTW_IEEE80211_STYPE_ACTION 0x00D0 ++ ++/* control */ ++#define RTW_IEEE80211_STYPE_CTL_EXT 0x0060 ++#define RTW_IEEE80211_STYPE_BACK_REQ 0x0080 ++#define RTW_IEEE80211_STYPE_BACK 0x0090 ++#define RTW_IEEE80211_STYPE_PSPOLL 0x00A0 ++#define RTW_IEEE80211_STYPE_RTS 0x00B0 ++#define RTW_IEEE80211_STYPE_CTS 0x00C0 ++#define RTW_IEEE80211_STYPE_ACK 0x00D0 ++#define RTW_IEEE80211_STYPE_CFEND 0x00E0 ++#define RTW_IEEE80211_STYPE_CFENDACK 0x00F0 ++ ++/* data */ ++#define RTW_IEEE80211_STYPE_DATA 0x0000 ++#define RTW_IEEE80211_STYPE_DATA_CFACK 0x0010 ++#define RTW_IEEE80211_STYPE_DATA_CFPOLL 0x0020 ++#define RTW_IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 ++#define RTW_IEEE80211_STYPE_NULLFUNC 0x0040 ++#define RTW_IEEE80211_STYPE_CFACK 0x0050 ++#define RTW_IEEE80211_STYPE_CFPOLL 0x0060 ++#define RTW_IEEE80211_STYPE_CFACKPOLL 0x0070 ++#define RTW_IEEE80211_STYPE_QOS_DATA 0x0080 ++#define RTW_IEEE80211_STYPE_QOS_DATA_CFACK 0x0090 ++#define RTW_IEEE80211_STYPE_QOS_DATA_CFPOLL 0x00A0 ++#define RTW_IEEE80211_STYPE_QOS_DATA_CFACKPOLL 0x00B0 ++#define RTW_IEEE80211_STYPE_QOS_NULLFUNC 0x00C0 ++#define RTW_IEEE80211_STYPE_QOS_CFACK 0x00D0 ++#define RTW_IEEE80211_STYPE_QOS_CFPOLL 0x00E0 ++#define RTW_IEEE80211_STYPE_QOS_CFACKPOLL 0x00F0 ++ ++/* sequence control field */ ++#define RTW_IEEE80211_SCTL_FRAG 0x000F ++#define RTW_IEEE80211_SCTL_SEQ 0xFFF0 ++ ++#define RTW_ERP_INFO_NON_ERP_PRESENT BIT(0) ++#define RTW_ERP_INFO_USE_PROTECTION BIT(1) ++#define RTW_ERP_INFO_BARKER_PREAMBLE_MODE BIT(2) ++ ++/* QoS, QOS */ ++#define NORMAL_ACK 0 ++#define NO_ACK 1 ++#define NON_EXPLICIT_ACK 2 ++#define BLOCK_ACK 3 ++ ++#ifndef ETH_P_PAE ++#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ ++#endif /* ETH_P_PAE */ ++ ++#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ ++ ++#define ETH_P_ECONET 0x0018 ++ ++#ifndef ETH_P_80211_RAW ++#define ETH_P_80211_RAW (ETH_P_ECONET + 1) ++#endif ++ ++/* IEEE 802.11 defines */ ++ ++#define P80211_OUI_LEN 3 ++ ++struct ieee80211_snap_hdr { ++ u8 dsap; /* always 0xAA */ ++ u8 ssap; /* always 0xAA */ ++ u8 ctrl; /* always 0x03 */ ++ u8 oui[P80211_OUI_LEN]; /* organizational universal id */ ++} __packed; ++ ++#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) ++ ++#define WLAN_FC_GET_TYPE(fc) ((fc) & RTW_IEEE80211_FCTL_FTYPE) ++#define WLAN_FC_GET_STYPE(fc) ((fc) & RTW_IEEE80211_FCTL_STYPE) ++ ++#define WLAN_QC_GET_TID(qc) ((qc) & 0x0f) ++ ++#define WLAN_GET_SEQ_FRAG(seq) ((seq) & RTW_IEEE80211_SCTL_FRAG) ++#define WLAN_GET_SEQ_SEQ(seq) ((seq) & RTW_IEEE80211_SCTL_SEQ) ++ ++/* Authentication algorithms */ ++#define WLAN_AUTH_OPEN 0 ++#define WLAN_AUTH_SHARED_KEY 1 ++ ++#define WLAN_AUTH_CHALLENGE_LEN 128 ++ ++#define WLAN_CAPABILITY_BSS (1<<0) ++#define WLAN_CAPABILITY_IBSS (1<<1) ++#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) ++#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) ++#define WLAN_CAPABILITY_PRIVACY (1<<4) ++#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) ++#define WLAN_CAPABILITY_PBCC (1<<6) ++#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) ++#define WLAN_CAPABILITY_SHORT_SLOT (1<<10) ++ ++/* Status codes */ ++#define WLAN_STATUS_SUCCESS 0 ++#define WLAN_STATUS_UNSPECIFIED_FAILURE 1 ++#define WLAN_STATUS_CAPS_UNSUPPORTED 10 ++#define WLAN_STATUS_REASSOC_NO_ASSOC 11 ++#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 ++#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 ++#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 ++#define WLAN_STATUS_CHALLENGE_FAIL 15 ++#define WLAN_STATUS_AUTH_TIMEOUT 16 ++#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 ++#define WLAN_STATUS_ASSOC_DENIED_RATES 18 ++/* 802.11b */ ++#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 ++#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20 ++#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21 ++ ++/* Reason codes */ ++#define WLAN_REASON_UNSPECIFIED 1 ++#define WLAN_REASON_PREV_AUTH_NOT_VALID 2 ++#define WLAN_REASON_DEAUTH_LEAVING 3 ++#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 ++#define WLAN_REASON_DISASSOC_AP_BUSY 5 ++#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 ++#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 ++#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 ++#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 ++#define WLAN_REASON_JOIN_WRONG_CHANNEL 65534 ++#define WLAN_REASON_EXPIRATION_CHK 65535 ++ ++/* Information Element IDs */ ++#define WLAN_EID_SSID 0 ++#define WLAN_EID_SUPP_RATES 1 ++#define WLAN_EID_FH_PARAMS 2 ++#define WLAN_EID_DS_PARAMS 3 ++#define WLAN_EID_CF_PARAMS 4 ++#define WLAN_EID_TIM 5 ++#define WLAN_EID_IBSS_PARAMS 6 ++#define WLAN_EID_CHALLENGE 16 ++/* EIDs defined by IEEE 802.11h - START */ ++#define WLAN_EID_PWR_CONSTRAINT 32 ++#define WLAN_EID_PWR_CAPABILITY 33 ++#define WLAN_EID_TPC_REQUEST 34 ++#define WLAN_EID_TPC_REPORT 35 ++#define WLAN_EID_SUPPORTED_CHANNELS 36 ++#define WLAN_EID_CHANNEL_SWITCH 37 ++#define WLAN_EID_MEASURE_REQUEST 38 ++#define WLAN_EID_MEASURE_REPORT 39 ++#define WLAN_EID_QUITE 40 ++#define WLAN_EID_IBSS_DFS 41 ++/* EIDs defined by IEEE 802.11h - END */ ++#define WLAN_EID_ERP_INFO 42 ++#define WLAN_EID_HT_CAP 45 ++#define WLAN_EID_RSN 48 ++#define WLAN_EID_EXT_SUPP_RATES 50 ++#define WLAN_EID_MOBILITY_DOMAIN 54 ++#define WLAN_EID_FAST_BSS_TRANSITION 55 ++#define WLAN_EID_TIMEOUT_INTERVAL 56 ++#define WLAN_EID_RIC_DATA 57 ++#define WLAN_EID_HT_OPERATION 61 ++#define WLAN_EID_SECONDARY_CHANNEL_OFFSET 62 ++#define WLAN_EID_20_40_BSS_COEXISTENCE 72 ++#define WLAN_EID_20_40_BSS_INTOLERANT 73 ++#define WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS 74 ++#define WLAN_EID_MMIE 76 ++#define WLAN_EID_VENDOR_SPECIFIC 221 ++#define WLAN_EID_GENERIC (WLAN_EID_VENDOR_SPECIFIC) ++ ++#define IEEE80211_MGMT_HDR_LEN 24 ++#define IEEE80211_DATA_HDR3_LEN 24 ++#define IEEE80211_DATA_HDR4_LEN 30 ++ ++#define IEEE80211_STATMASK_SIGNAL (1<<0) ++#define IEEE80211_STATMASK_RSSI (1<<1) ++#define IEEE80211_STATMASK_NOISE (1<<2) ++#define IEEE80211_STATMASK_RATE (1<<3) ++#define IEEE80211_STATMASK_WEMASK 0x7 ++ ++#define IEEE80211_CCK_MODULATION (1<<0) ++#define IEEE80211_OFDM_MODULATION (1<<1) ++ ++#define IEEE80211_24GHZ_BAND (1<<0) ++#define IEEE80211_52GHZ_BAND (1<<1) ++ ++#define IEEE80211_CCK_RATE_LEN 4 ++#define IEEE80211_NUM_OFDM_RATESLEN 8 ++ ++#define IEEE80211_CCK_RATE_1MB 0x02 ++#define IEEE80211_CCK_RATE_2MB 0x04 ++#define IEEE80211_CCK_RATE_5MB 0x0B ++#define IEEE80211_CCK_RATE_11MB 0x16 ++#define IEEE80211_OFDM_RATE_LEN 8 ++#define IEEE80211_OFDM_RATE_6MB 0x0C ++#define IEEE80211_OFDM_RATE_9MB 0x12 ++#define IEEE80211_OFDM_RATE_12MB 0x18 ++#define IEEE80211_OFDM_RATE_18MB 0x24 ++#define IEEE80211_OFDM_RATE_24MB 0x30 ++#define IEEE80211_OFDM_RATE_36MB 0x48 ++#define IEEE80211_OFDM_RATE_48MB 0x60 ++#define IEEE80211_OFDM_RATE_54MB 0x6C ++#define IEEE80211_BASIC_RATE_MASK 0x80 ++ ++#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) ++#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) ++#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) ++#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) ++#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) ++#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) ++#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) ++#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) ++#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) ++#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) ++#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) ++#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) ++ ++#define IEEE80211_CCK_RATES_MASK 0x0000000F ++#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ ++ IEEE80211_CCK_RATE_2MB_MASK) ++#define IEEE80211_CCK_DEFAULT_RATES_MASK \ ++ (IEEE80211_CCK_BASIC_RATES_MASK | \ ++ IEEE80211_CCK_RATE_5MB_MASK | \ ++ IEEE80211_CCK_RATE_11MB_MASK) ++ ++#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 ++#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ ++ IEEE80211_OFDM_RATE_12MB_MASK | \ ++ IEEE80211_OFDM_RATE_24MB_MASK) ++#define IEEE80211_OFDM_DEFAULT_RATES_MASK \ ++ (IEEE80211_OFDM_BASIC_RATES_MASK | \ ++ IEEE80211_OFDM_RATE_9MB_MASK | \ ++ IEEE80211_OFDM_RATE_18MB_MASK | \ ++ IEEE80211_OFDM_RATE_36MB_MASK | \ ++ IEEE80211_OFDM_RATE_48MB_MASK | \ ++ IEEE80211_OFDM_RATE_54MB_MASK) ++#define IEEE80211_DEFAULT_RATES_MASK \ ++ (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ ++ IEEE80211_CCK_DEFAULT_RATES_MASK) ++ ++#define IEEE80211_NUM_OFDM_RATES 8 ++#define IEEE80211_NUM_CCK_RATES 4 ++#define IEEE80211_OFDM_SHIFT_MASK_A 4 ++ ++/* NOTE: This data is for statistical purposes; not all hardware provides this ++ * information for frames received. Not setting these will not cause ++ * any adverse affects. */ ++struct ieee80211_rx_stats { ++ /* u32 mac_time[2]; */ ++ s8 rssi; ++ u8 signal; ++ u8 noise; ++ u8 received_channel; ++ u16 rate; /* in 100 kbps */ ++ /* u8 control; */ ++ u8 mask; ++ u8 freq; ++ u16 len; ++}; ++ ++/* IEEE 802.11 requires that STA supports concurrent reception of at least ++ * three fragmented frames. This define can be increased to support more ++ * concurrent frames, but it should be noted that each entry can consume about ++ * 2 kB of RAM and increasing cache size will slow down frame reassembly. */ ++#define IEEE80211_FRAG_CACHE_LEN 4 ++ ++struct ieee80211_frag_entry { ++ u32 first_frag_time; ++ uint seq; ++ uint last_frag; ++ uint qos; /* jackson */ ++ uint tid; /* jackson */ ++ struct sk_buff *skb; ++ u8 src_addr[ETH_ALEN]; ++ u8 dst_addr[ETH_ALEN]; ++}; ++ ++struct ieee80211_stats { ++ uint tx_unicast_frames; ++ uint tx_multicast_frames; ++ uint tx_fragments; ++ uint tx_unicast_octets; ++ uint tx_multicast_octets; ++ uint tx_deferred_transmissions; ++ uint tx_single_retry_frames; ++ uint tx_multiple_retry_frames; ++ uint tx_retry_limit_exceeded; ++ uint tx_discards; ++ uint rx_unicast_frames; ++ uint rx_multicast_frames; ++ uint rx_fragments; ++ uint rx_unicast_octets; ++ uint rx_multicast_octets; ++ uint rx_fcs_errors; ++ uint rx_discards_no_buffer; ++ uint tx_discards_wrong_sa; ++ uint rx_discards_undecryptable; ++ uint rx_message_in_msg_fragments; ++ uint rx_message_in_bad_msg_fragments; ++}; ++ ++struct ieee80211_softmac_stats { ++ uint rx_ass_ok; ++ uint rx_ass_err; ++ uint rx_probe_rq; ++ uint tx_probe_rs; ++ uint tx_beacons; ++ uint rx_auth_rq; ++ uint rx_auth_rs_ok; ++ uint rx_auth_rs_err; ++ uint tx_auth_rq; ++ uint no_auth_rs; ++ uint no_ass_rs; ++ uint tx_ass_rq; ++ uint rx_ass_rq; ++ uint tx_probe_rq; ++ uint reassoc; ++ uint swtxstop; ++ uint swtxawake; ++}; ++ ++#define SEC_KEY_1 (1<<0) ++#define SEC_KEY_2 (1<<1) ++#define SEC_KEY_3 (1<<2) ++#define SEC_KEY_4 (1<<3) ++#define SEC_ACTIVE_KEY (1<<4) ++#define SEC_AUTH_MODE (1<<5) ++#define SEC_UNICAST_GROUP (1<<6) ++#define SEC_LEVEL (1<<7) ++#define SEC_ENABLED (1<<8) ++ ++#define SEC_LEVEL_0 0 /* None */ ++#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */ ++#define SEC_LEVEL_2 2 /* Level 1 + TKIP */ ++#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */ ++#define SEC_LEVEL_3 4 /* Level 2 + CCMP */ ++ ++#define WEP_KEYS 4 ++#define WEP_KEY_LEN 13 ++ ++struct ieee80211_security { ++ u16 active_key:2, ++ enabled:1, ++ auth_mode:2, ++ auth_algo:4, ++ unicast_uses_group:1; ++ u8 key_sizes[WEP_KEYS]; ++ u8 keys[WEP_KEYS][WEP_KEY_LEN]; ++ u8 level; ++ u16 flags; ++} __packed; ++ ++/* ++ ++ 802.11 data frame from AP ++ ++ ,-------------------------------------------------------------------. ++Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | ++ |------|------|---------|---------|---------|------|---------|------| ++Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | ++ | | tion | (BSSID) | | | ence | data | | ++ `-------------------------------------------------------------------' ++ ++Total: 28-2340 bytes ++ ++*/ ++ ++struct ieee80211_header_data { ++ u16 frame_ctl; ++ u16 duration_id; ++ u8 addr1[6]; ++ u8 addr2[6]; ++ u8 addr3[6]; ++ u16 seq_ctrl; ++}; ++ ++#define BEACON_PROBE_SSID_ID_POSITION 12 ++ ++/* Management Frame Information Element Types */ ++#define MFIE_TYPE_SSID 0 ++#define MFIE_TYPE_RATES 1 ++#define MFIE_TYPE_FH_SET 2 ++#define MFIE_TYPE_DS_SET 3 ++#define MFIE_TYPE_CF_SET 4 ++#define MFIE_TYPE_TIM 5 ++#define MFIE_TYPE_IBSS_SET 6 ++#define MFIE_TYPE_CHALLENGE 16 ++#define MFIE_TYPE_ERP 42 ++#define MFIE_TYPE_RSN 48 ++#define MFIE_TYPE_RATES_EX 50 ++#define MFIE_TYPE_GENERIC 221 ++ ++struct ieee80211_info_element_hdr { ++ u8 id; ++ u8 len; ++} __packed; ++ ++struct ieee80211_info_element { ++ u8 id; ++ u8 len; ++ u8 data[0]; ++} __packed; ++ ++/* ++ * These are the data types that can make up management packets ++ * ++ u16 auth_algorithm; ++ u16 auth_sequence; ++ u16 beacon_interval; ++ u16 capability; ++ u8 current_ap[ETH_ALEN]; ++ u16 listen_interval; ++ struct { ++ u16 association_id:14, reserved:2; ++ } __packed; ++ u32 time_stamp[2]; ++ u16 reason; ++ u16 status; ++*/ ++ ++#define IEEE80211_DEFAULT_TX_ESSID "Penguin" ++#define IEEE80211_DEFAULT_BASIC_RATE 10 ++ ++struct ieee80211_authentication { ++ struct ieee80211_header_data header; ++ u16 algorithm; ++ u16 transaction; ++ u16 status; ++ /* struct ieee80211_info_element_hdr info_element; */ ++} __packed; ++ ++struct ieee80211_probe_response { ++ struct ieee80211_header_data header; ++ u32 time_stamp[2]; ++ u16 beacon_interval; ++ u16 capability; ++ struct ieee80211_info_element info_element; ++} __packed; ++ ++struct ieee80211_probe_request { ++ struct ieee80211_header_data header; ++} __packed; ++ ++struct ieee80211_assoc_request_frame { ++ struct rtw_ieee80211_hdr_3addr header; ++ u16 capability; ++ u16 listen_interval; ++ struct ieee80211_info_element_hdr info_element; ++} __packed; ++ ++struct ieee80211_assoc_response_frame { ++ struct rtw_ieee80211_hdr_3addr header; ++ u16 capability; ++ u16 status; ++ u16 aid; ++} __packed; ++ ++struct ieee80211_txb { ++ u8 nr_frags; ++ u8 encrypted; ++ u16 reserved; ++ u16 frag_size; ++ u16 payload_size; ++ struct sk_buff *fragments[0]; ++}; ++ ++/* SWEEP TABLE ENTRIES NUMBER*/ ++#define MAX_SWEEP_TAB_ENTRIES 42 ++#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7 ++/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs ++ * only use 8, and then use extended rates for the remaining supported ++ * rates. Other APs, however, stick all of their supported rates on the ++ * main rates information element... */ ++#define MAX_RATES_LENGTH ((u8)12) ++#define MAX_RATES_EX_LENGTH ((u8)16) ++#define MAX_NETWORK_COUNT 128 ++#define MAX_CHANNEL_NUMBER 161 ++#define IEEE80211_SOFTMAC_SCAN_TIME 400 ++/* HZ / 2) */ ++#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2) ++ ++#define CRC_LENGTH 4U ++ ++#define MAX_WPA_IE_LEN (256) ++#define MAX_WPS_IE_LEN (512) ++#define MAX_P2P_IE_LEN (256) ++#define MAX_WFD_IE_LEN (128) ++ ++#define NETWORK_EMPTY_ESSID (1<<0) ++#define NETWORK_HAS_OFDM (1<<1) ++#define NETWORK_HAS_CCK (1<<2) ++ ++#define IEEE80211_DTIM_MBCAST 4 ++#define IEEE80211_DTIM_UCAST 2 ++#define IEEE80211_DTIM_VALID 1 ++#define IEEE80211_DTIM_INVALID 0 ++ ++#define IEEE80211_PS_DISABLED 0 ++#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST ++#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST ++#define IW_ESSID_MAX_SIZE 32 ++/* ++join_res: ++-1: authentication fail ++-2: association fail ++> 0: TID ++*/ ++ ++enum ieee80211_state { ++ /* the card is not linked at all */ ++ IEEE80211_NOLINK = 0, ++ ++ /* IEEE80211_ASSOCIATING* are for BSS client mode ++ * the driver shall not perform RX filtering unless ++ * the state is LINKED. ++ * The driver shall just check for the state LINKED and ++ * defaults to NOLINK for ALL the other states (including ++ * LINKED_SCANNING) ++ */ ++ ++ /* the association procedure will start (wq scheduling)*/ ++ IEEE80211_ASSOCIATING, ++ IEEE80211_ASSOCIATING_RETRY, ++ ++ /* the association procedure is sending AUTH request*/ ++ IEEE80211_ASSOCIATING_AUTHENTICATING, ++ ++ /* the association procedure has successfully authentcated ++ * and is sending association request ++ */ ++ IEEE80211_ASSOCIATING_AUTHENTICATED, ++ ++ /* the link is ok. the card associated to a BSS or linked ++ * to a ibss cell or acting as an AP and creating the bss ++ */ ++ IEEE80211_LINKED, ++ ++ /* same as LINKED, but the driver shall apply RX filter ++ * rules as we are in NO_LINK mode. As the card is still ++ * logically linked, but it is doing a syncro site survey ++ * then it will be back to LINKED state. ++ */ ++ IEEE80211_LINKED_SCANNING, ++ ++}; ++ ++#define DEFAULT_MAX_SCAN_AGE (15 * HZ) ++#define DEFAULT_FTS 2346 ++ ++static inline int is_multicast_mac_addr(const u8 *addr) ++{ ++ return ((addr[0] != 0xff) && (0x01 & addr[0])); ++} ++ ++static inline int is_broadcast_mac_addr(const u8 *addr) ++{ ++ return (addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && ++ (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff); ++} ++ ++#define CFG_IEEE80211_RESERVE_FCS (1<<0) ++#define CFG_IEEE80211_COMPUTE_FCS (1<<1) ++ ++struct tx_pending { ++ int frag; ++ struct ieee80211_txb *txb; ++}; ++ ++#define MAXTID 16 ++ ++#define IEEE_A (1<<0) ++#define IEEE_B (1<<1) ++#define IEEE_G (1<<2) ++#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) ++ ++/* Baron move to ieee80211.c */ ++int ieee80211_is_empty_essid(const char *essid, int essid_len); ++int ieee80211_get_hdrlen(u16 fc); ++ ++/* Action category code */ ++enum rtw_ieee80211_category { ++ RTW_WLAN_CATEGORY_SPECTRUM_MGMT = 0, ++ RTW_WLAN_CATEGORY_QOS = 1, ++ RTW_WLAN_CATEGORY_DLS = 2, ++ RTW_WLAN_CATEGORY_BACK = 3, ++ RTW_WLAN_CATEGORY_PUBLIC = 4, /* IEEE 802.11 public action frames */ ++ RTW_WLAN_CATEGORY_RADIO_MEASUREMENT = 5, ++ RTW_WLAN_CATEGORY_FT = 6, ++ RTW_WLAN_CATEGORY_HT = 7, ++ RTW_WLAN_CATEGORY_SA_QUERY = 8, ++ RTW_WLAN_CATEGORY_TDLS = 12, ++ RTW_WLAN_CATEGORY_WMM = 17, ++ RTW_WLAN_CATEGORY_P2P = 0x7f,/* P2P action frames */ ++}; ++ ++/* SPECTRUM_MGMT action code */ ++enum rtw_ieee80211_spectrum_mgmt_actioncode { ++ RTW_WLAN_ACTION_SPCT_MSR_REQ = 0, ++ RTW_WLAN_ACTION_SPCT_MSR_RPRT = 1, ++ RTW_WLAN_ACTION_SPCT_TPC_REQ = 2, ++ RTW_WLAN_ACTION_SPCT_TPC_RPRT = 3, ++ RTW_WLAN_ACTION_SPCT_CHL_SWITCH = 4, ++ RTW_WLAN_ACTION_SPCT_EXT_CHL_SWITCH = 5, ++}; ++ ++enum _PUBLIC_ACTION { ++ ACT_PUBLIC_BSSCOEXIST = 0, /* 20/40 BSS Coexistence */ ++ ACT_PUBLIC_DSE_ENABLE = 1, ++ ACT_PUBLIC_DSE_DEENABLE = 2, ++ ACT_PUBLIC_DSE_REG_LOCATION = 3, ++ ACT_PUBLIC_EXT_CHL_SWITCH = 4, ++ ACT_PUBLIC_DSE_MSR_REQ = 5, ++ ACT_PUBLIC_DSE_MSR_RPRT = 6, ++ ACT_PUBLIC_MP = 7, /* Measurement Pilot */ ++ ACT_PUBLIC_DSE_PWR_CONSTRAINT = 8, ++ ACT_PUBLIC_VENDOR = 9, /* for WIFI_DIRECT */ ++ ACT_PUBLIC_GAS_INITIAL_REQ = 10, ++ ACT_PUBLIC_GAS_INITIAL_RSP = 11, ++ ACT_PUBLIC_GAS_COMEBACK_REQ = 12, ++ ACT_PUBLIC_GAS_COMEBACK_RSP = 13, ++ ACT_PUBLIC_TDLS_DISCOVERY_RSP = 14, ++ ACT_PUBLIC_LOCATION_TRACK = 15, ++ ACT_PUBLIC_MAX ++}; ++ ++/* BACK action code */ ++enum rtw_ieee80211_back_actioncode { ++ RTW_WLAN_ACTION_ADDBA_REQ = 0, ++ RTW_WLAN_ACTION_ADDBA_RESP = 1, ++ RTW_WLAN_ACTION_DELBA = 2, ++}; ++ ++/* HT features action code */ ++enum rtw_ieee80211_ht_actioncode { ++ RTW_WLAN_ACTION_NOTIFY_CH_WIDTH = 0, ++ RTW_WLAN_ACTION_SM_PS = 1, ++ RTW_WLAN_ACTION_PSPM = 2, ++ RTW_WLAN_ACTION_PCO_PHASE = 3, ++ RTW_WLAN_ACTION_MIMO_CSI_MX = 4, ++ RTW_WLAN_ACTION_MIMO_NONCP_BF = 5, ++ RTW_WLAN_ACTION_MIMP_CP_BF = 6, ++ RTW_WLAN_ACTION_ASEL_INDICATES_FB = 7, ++ RTW_WLAN_ACTION_HI_INFO_EXCHG = 8, ++}; ++ ++/* BACK (block-ack) parties */ ++enum rtw_ieee80211_back_parties { ++ RTW_WLAN_BACK_RECIPIENT = 0, ++ RTW_WLAN_BACK_INITIATOR = 1, ++ RTW_WLAN_BACK_TIMER = 2, ++}; ++ ++#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) ++ * 00:50:F2 */ ++#define WME_OUI_TYPE 2 ++#define WME_OUI_SUBTYPE_INFORMATION_ELEMENT 0 ++#define WME_OUI_SUBTYPE_PARAMETER_ELEMENT 1 ++#define WME_OUI_SUBTYPE_TSPEC_ELEMENT 2 ++#define WME_VERSION 1 ++ ++#define WME_ACTION_CODE_SETUP_REQUEST 0 ++#define WME_ACTION_CODE_SETUP_RESPONSE 1 ++#define WME_ACTION_CODE_TEARDOWN 2 ++ ++#define WME_SETUP_RESPONSE_STATUS_ADMISSION_ACCEPTED 0 ++#define WME_SETUP_RESPONSE_STATUS_INVALID_PARAMETERS 1 ++#define WME_SETUP_RESPONSE_STATUS_REFUSED 3 ++ ++#define WME_TSPEC_DIRECTION_UPLINK 0 ++#define WME_TSPEC_DIRECTION_DOWNLINK 1 ++#define WME_TSPEC_DIRECTION_BI_DIRECTIONAL 3 ++ ++#define OUI_BROADCOM 0x00904c /* Broadcom (Epigram) */ ++ ++#define VENDOR_HT_CAPAB_OUI_TYPE 0x33 /* 00-90-4c:0x33 */ ++ ++/** ++ * enum rtw_ieee80211_channel_flags - channel flags ++ * ++ * Channel flags set by the regulatory control code. ++ * ++ * @RTW_IEEE80211_CHAN_DISABLED: This channel is disabled. ++ * @RTW_IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted ++ * on this channel. ++ * @RTW_IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel. ++ * @RTW_IEEE80211_CHAN_RADAR: Radar detection is required on this channel. ++ * @RTW_IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel ++ * is not permitted. ++ * @RTW_IEEE80211_CHAN_NO_HT40MINUS: extension channel below this channel ++ * is not permitted. ++ */ ++enum rtw_ieee80211_channel_flags { ++ RTW_IEEE80211_CHAN_DISABLED = 1<<0, ++ RTW_IEEE80211_CHAN_PASSIVE_SCAN = 1<<1, ++ RTW_IEEE80211_CHAN_NO_IBSS = 1<<2, ++ RTW_IEEE80211_CHAN_RADAR = 1<<3, ++ RTW_IEEE80211_CHAN_NO_HT40PLUS = 1<<4, ++ RTW_IEEE80211_CHAN_NO_HT40MINUS = 1<<5, ++}; ++ ++#define RTW_IEEE80211_CHAN_NO_HT40 \ ++ (RTW_IEEE80211_CHAN_NO_HT40PLUS | RTW_IEEE80211_CHAN_NO_HT40MINUS) ++ ++/* Represent channel details, subset of ieee80211_channel */ ++struct rtw_ieee80211_channel { ++ u16 hw_value; ++ u32 flags; ++}; ++ ++#define CHAN_FMT \ ++ "hw_value:%u, " \ ++ "flags:0x%08x" \ ++ ++#define CHAN_ARG(channel) \ ++ (channel)->hw_value \ ++ , (channel)->flags \ ++ ++/* Parsed Information Elements */ ++struct rtw_ieee802_11_elems { ++ u8 *ssid; ++ u8 ssid_len; ++ u8 *supp_rates; ++ u8 supp_rates_len; ++ u8 *fh_params; ++ u8 fh_params_len; ++ u8 *ds_params; ++ u8 ds_params_len; ++ u8 *cf_params; ++ u8 cf_params_len; ++ u8 *tim; ++ u8 tim_len; ++ u8 *ibss_params; ++ u8 ibss_params_len; ++ u8 *challenge; ++ u8 challenge_len; ++ u8 *erp_info; ++ u8 erp_info_len; ++ u8 *ext_supp_rates; ++ u8 ext_supp_rates_len; ++ u8 *wpa_ie; ++ u8 wpa_ie_len; ++ u8 *rsn_ie; ++ u8 rsn_ie_len; ++ u8 *wme; ++ u8 wme_len; ++ u8 *wme_tspec; ++ u8 wme_tspec_len; ++ u8 *wps_ie; ++ u8 wps_ie_len; ++ u8 *power_cap; ++ u8 power_cap_len; ++ u8 *supp_channels; ++ u8 supp_channels_len; ++ u8 *mdie; ++ u8 mdie_len; ++ u8 *ftie; ++ u8 ftie_len; ++ u8 *timeout_int; ++ u8 timeout_int_len; ++ u8 *ht_capabilities; ++ u8 ht_capabilities_len; ++ u8 *ht_operation; ++ u8 ht_operation_len; ++ u8 *vendor_ht_cap; ++ u8 vendor_ht_cap_len; ++}; ++ ++enum parse_res { ++ ParseOK = 0, ++ ParseUnknown = 1, ++ ParseFailed = -1 ++}; ++ ++enum parse_res rtw_ieee802_11_parse_elems(u8 *start, uint len, ++ struct rtw_ieee802_11_elems *elems, ++ int show_errors); ++ ++u8 *rtw_set_fixed_ie(unsigned char *pbuf, unsigned int len, ++ unsigned char *source, unsigned int *frlen); ++u8 *rtw_set_ie(u8 *pbuf, int index, uint len, u8 *source, uint *frlen); ++ ++enum secondary_ch_offset { ++ SCN = 0, /* no secondary channel */ ++ SCA = 1, /* secondary channel above */ ++ SCB = 3, /* secondary channel below */ ++}; ++u8 secondary_ch_offset_to_hal_ch_offset(u8 ch_offset); ++u8 hal_ch_offset_to_secondary_ch_offset(u8 ch_offset); ++u8 *rtw_set_ie_ch_switch(u8 *buf, u32 *buf_len, u8 ch_switch_mode, ++ u8 new_ch, u8 ch_switch_cnt); ++u8 *rtw_set_ie_secondary_ch_offset(u8 *buf, u32 *buf_len, ++ u8 secondary_ch_offset); ++u8 *rtw_set_ie_mesh_ch_switch_parm(u8 *buf, u32 *buf_len, u8 ttl, ++ u8 flags, u16 reason, u16 precedence); ++ ++u8 *rtw_get_ie(u8 *pbuf, int index, int *len, int limit); ++u8 *rtw_get_ie_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, ++ u8 oui_len, u8 *ie, uint *ielen); ++int rtw_ies_remove_ie(u8 *ies, uint *ies_len, uint offset, ++ u8 eid, u8 *oui, u8 oui_len); ++ ++void rtw_set_supported_rate(u8 *SupportedRates, uint mode); ++ ++unsigned char *rtw_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit); ++unsigned char *rtw_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit); ++int rtw_get_wpa_cipher_suite(u8 *s); ++int rtw_get_wpa2_cipher_suite(u8 *s); ++int rtw_get_wapi_ie(u8 *in_ie, uint in_len, u8 *wapi_ie, u16 *wapi_len); ++int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, ++ int *pairwise_cipher, int *is_8021x); ++int rtw_parse_wpa2_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, ++ int *pairwise_cipher, int *is_8021x); ++ ++int rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, ++ u8 *wpa_ie, u16 *wpa_len); ++ ++u8 rtw_is_wps_ie(u8 *ie_ptr, uint *wps_ielen); ++u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen); ++u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, ++ u8 *buf_attr, u32 *len_attr); ++u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, ++ u8 *buf_content, uint *len_content); ++ ++/** ++ * for_each_ie - iterate over continuous IEs ++ * @ie: ++ * @buf: ++ * @buf_len: ++ */ ++#define for_each_ie(ie, buf, buf_len) \ ++ for (ie = (void *)buf; (((u8 *)ie) - ((u8 *)buf) + 1) < buf_len; \ ++ ie = (void *)(((u8 *)ie) + *(((u8 *)ie)+1) + 2)) ++ ++void dump_ies(u8 *buf, u32 buf_len); ++void dump_wps_ie(u8 *ie, u32 ie_len); ++ ++#ifdef CONFIG_88EU_P2P ++void dump_p2p_ie(u8 *ie, u32 ie_len); ++u8 *rtw_get_p2p_ie(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen); ++u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id, ++ u8 *buf_attr, u32 *len_attr); ++u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id, ++ u8 *buf_content, uint *len_content); ++u32 rtw_set_p2p_attr_content(u8 *pbuf, u8 attr_id, u16 attr_len, ++ u8 *pdata_attr); ++void rtw_wlan_bssid_ex_remove_p2p_attr(struct wlan_bssid_ex *bss_ex, ++ u8 attr_id); ++#endif ++ ++uint rtw_get_rateset_len(u8 *rateset); ++ ++struct registry_priv; ++int rtw_generate_ie(struct registry_priv *pregistrypriv); ++ ++int rtw_get_bit_value_from_ieee_value(u8 val); ++ ++uint rtw_is_cckrates_included(u8 *rate); ++ ++uint rtw_is_cckratesonly_included(u8 *rate); ++ ++int rtw_check_network_type(unsigned char *rate, int ratelen, int channel); ++ ++void rtw_get_bcn_info(struct wlan_network *pnetwork); ++ ++void rtw_macaddr_cfg(u8 *mac_addr); ++ ++u16 rtw_mcs_rate(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40, ++ unsigned char *MCS_rate); ++ ++int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category, ++ u8 *action); ++const char *action_public_str(u8 action); ++ ++#endif /* IEEE80211_H */ +diff --git a/drivers/staging/r8188eu/include/ieee80211_ext.h b/drivers/staging/r8188eu/include/ieee80211_ext.h +new file mode 100644 +index 000000000000..e7ade835d478 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/ieee80211_ext.h +@@ -0,0 +1,271 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __IEEE80211_EXT_H ++#define __IEEE80211_EXT_H ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define WMM_OUI_TYPE 2 ++#define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0 ++#define WMM_OUI_SUBTYPE_PARAMETER_ELEMENT 1 ++#define WMM_OUI_SUBTYPE_TSPEC_ELEMENT 2 ++#define WMM_VERSION 1 ++ ++#define WPA_PROTO_WPA BIT(0) ++#define WPA_PROTO_RSN BIT(1) ++ ++#define WPA_KEY_MGMT_IEEE8021X BIT(0) ++#define WPA_KEY_MGMT_PSK BIT(1) ++#define WPA_KEY_MGMT_NONE BIT(2) ++#define WPA_KEY_MGMT_IEEE8021X_NO_WPA BIT(3) ++#define WPA_KEY_MGMT_WPA_NONE BIT(4) ++ ++#define WPA_CAPABILITY_PREAUTH BIT(0) ++#define WPA_CAPABILITY_MGMT_FRAME_PROTECTION BIT(6) ++#define WPA_CAPABILITY_PEERKEY_ENABLED BIT(9) ++ ++#define PMKID_LEN 16 ++ ++struct wpa_ie_hdr { ++ u8 elem_id; ++ u8 len; ++ u8 oui[4]; /* 24-bit OUI followed by 8-bit OUI type */ ++ u8 version[2]; /* little endian */ ++} __packed; ++ ++struct rsn_ie_hdr { ++ u8 elem_id; /* WLAN_EID_RSN */ ++ u8 len; ++ u8 version[2]; /* little endian */ ++} __packed; ++ ++struct wme_ac_parameter { ++#if defined(__LITTLE_ENDIAN) ++ /* byte 1 */ ++ u8 aifsn:4, ++ acm:1, ++ aci:2, ++ reserved:1; ++ ++ /* byte 2 */ ++ u8 eCWmin:4, ++ eCWmax:4; ++#elif defined(__BIG_ENDIAN) ++ /* byte 1 */ ++ u8 reserved:1, ++ aci:2, ++ acm:1, ++ aifsn:4; ++ ++ /* byte 2 */ ++ u8 eCWmax:4, ++ eCWmin:4; ++#else ++#error "Please fix " ++#endif ++ ++ /* bytes 3 & 4 */ ++ u16 txopLimit; ++} __packed; ++ ++struct wme_parameter_element { ++ /* required fields for WME version 1 */ ++ u8 oui[3]; ++ u8 oui_type; ++ u8 oui_subtype; ++ u8 version; ++ u8 acInfo; ++ u8 reserved; ++ struct wme_ac_parameter ac[4]; ++ ++} __packed; ++ ++#define WPA_PUT_LE16(a, val) \ ++ do { \ ++ (a)[1] = ((u16) (val)) >> 8; \ ++ (a)[0] = ((u16) (val)) & 0xff; \ ++ } while (0) ++ ++#define WPA_PUT_BE32(a, val) \ ++ do { \ ++ (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ ++ (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ ++ (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ ++ (a)[3] = (u8) (((u32) (val)) & 0xff); \ ++ } while (0) ++ ++#define WPA_PUT_LE32(a, val) \ ++ do { \ ++ (a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \ ++ (a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \ ++ (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ ++ (a)[0] = (u8) (((u32) (val)) & 0xff); \ ++ } while (0) ++ ++#define RSN_SELECTOR_PUT(a, val) WPA_PUT_BE32((u8 *)(a), (val)) ++ ++/* Action category code */ ++enum ieee80211_category { ++ WLAN_CATEGORY_SPECTRUM_MGMT = 0, ++ WLAN_CATEGORY_QOS = 1, ++ WLAN_CATEGORY_DLS = 2, ++ WLAN_CATEGORY_BACK = 3, ++ WLAN_CATEGORY_HT = 7, ++ WLAN_CATEGORY_WMM = 17, ++}; ++ ++/* SPECTRUM_MGMT action code */ ++enum ieee80211_spectrum_mgmt_actioncode { ++ WLAN_ACTION_SPCT_MSR_REQ = 0, ++ WLAN_ACTION_SPCT_MSR_RPRT = 1, ++ WLAN_ACTION_SPCT_TPC_REQ = 2, ++ WLAN_ACTION_SPCT_TPC_RPRT = 3, ++ WLAN_ACTION_SPCT_CHL_SWITCH = 4, ++ WLAN_ACTION_SPCT_EXT_CHL_SWITCH = 5, ++}; ++ ++/* BACK action code */ ++enum ieee80211_back_actioncode { ++ WLAN_ACTION_ADDBA_REQ = 0, ++ WLAN_ACTION_ADDBA_RESP = 1, ++ WLAN_ACTION_DELBA = 2, ++}; ++ ++/* HT features action code */ ++enum ieee80211_ht_actioncode { ++ WLAN_ACTION_NOTIFY_CH_WIDTH = 0, ++ WLAN_ACTION_SM_PS = 1, ++ WLAN_ACTION_PSPM = 2, ++ WLAN_ACTION_PCO_PHASE = 3, ++ WLAN_ACTION_MIMO_CSI_MX = 4, ++ WLAN_ACTION_MIMO_NONCP_BF = 5, ++ WLAN_ACTION_MIMP_CP_BF = 6, ++ WLAN_ACTION_ASEL_INDICATES_FB = 7, ++ WLAN_ACTION_HI_INFO_EXCHG = 8, ++}; ++ ++/* BACK (block-ack) parties */ ++enum ieee80211_back_parties { ++ WLAN_BACK_RECIPIENT = 0, ++ WLAN_BACK_INITIATOR = 1, ++ WLAN_BACK_TIMER = 2, ++}; ++ ++struct ieee80211_mgmt { ++ u16 frame_control; ++ u16 duration; ++ u8 da[6]; ++ u8 sa[6]; ++ u8 bssid[6]; ++ u16 seq_ctrl; ++ union { ++ struct { ++ u16 auth_alg; ++ u16 auth_transaction; ++ u16 status_code; ++ /* possibly followed by Challenge text */ ++ u8 variable[0]; ++ } __packed auth; ++ struct { ++ u16 reason_code; ++ } __packed deauth; ++ struct { ++ u16 capab_info; ++ u16 listen_interval; ++ /* followed by SSID and Supported rates */ ++ u8 variable[0]; ++ } __packed assoc_req; ++ struct { ++ u16 capab_info; ++ u16 status_code; ++ u16 aid; ++ /* followed by Supported rates */ ++ u8 variable[0]; ++ } __packed assoc_resp, reassoc_resp; ++ struct { ++ u16 capab_info; ++ u16 listen_interval; ++ u8 current_ap[6]; ++ /* followed by SSID and Supported rates */ ++ u8 variable[0]; ++ } __packed reassoc_req; ++ struct { ++ u16 reason_code; ++ } __packed disassoc; ++ struct { ++ __le64 timestamp; ++ u16 beacon_int; ++ u16 capab_info; ++ /* followed by some of SSID, Supported rates, ++ * FH Params, DS Params, CF Params, IBSS Params, TIM */ ++ u8 variable[0]; ++ } __packed beacon; ++ struct { ++ /* only variable items: SSID, Supported rates */ ++ u8 variable[0]; ++ } __packed probe_req; ++ struct { ++ __le64 timestamp; ++ u16 beacon_int; ++ u16 capab_info; ++ /* followed by some of SSID, Supported rates, ++ * FH Params, DS Params, CF Params, IBSS Params */ ++ u8 variable[0]; ++ } __packed probe_resp; ++ struct { ++ u8 category; ++ union { ++ struct { ++ u8 action_code; ++ u8 dialog_token; ++ u8 status_code; ++ u8 variable[0]; ++ } __packed wme_action; ++ struct { ++ u8 action_code; ++ u8 dialog_token; ++ u16 capab; ++ u16 timeout; ++ u16 start_seq_num; ++ } __packed addba_req; ++ struct { ++ u8 action_code; ++ u8 dialog_token; ++ u16 status; ++ u16 capab; ++ u16 timeout; ++ } __packed addba_resp; ++ struct { ++ u8 action_code; ++ u16 params; ++ u16 reason_code; ++ } __packed delba; ++ structi { ++ u8 action_code; ++ /* capab_info for open and confirm, ++ * reason for close ++ */ ++ u16 aux; ++ /* Followed in plink_confirm by status ++ * code, AID and supported rates, ++ * and directly by supported rates in ++ * plink_open and plink_close ++ */ ++ u8 variable[0]; ++ } __packed plink_action; ++ struct{ ++ u8 action_code; ++ u8 variable[0]; ++ } __packed mesh_action; ++ } __packed u; ++ } __packed action; ++ } __packed u; ++} __packed; ++ ++/* mgmt header + 1 byte category code */ ++#define IEEE80211_MIN_ACTION_SIZE \ ++ FIELD_OFFSET(struct ieee80211_mgmt, u.action.u) ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/ioctl_cfg80211.h b/drivers/staging/r8188eu/include/ioctl_cfg80211.h +new file mode 100644 +index 000000000000..e22481050ef8 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/ioctl_cfg80211.h +@@ -0,0 +1,91 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. i*/ ++ ++#ifndef __IOCTL_CFG80211_H__ ++#define __IOCTL_CFG80211_H__ ++ ++struct rtw_wdev_invit_info { ++ u8 token; ++ u8 flags; ++ u8 status; ++ u8 req_op_ch; ++ u8 rsp_op_ch; ++}; ++ ++#define rtw_wdev_invit_info_init(invit_info) \ ++ do { \ ++ (invit_info)->token = 0; \ ++ (invit_info)->flags = 0x00; \ ++ (invit_info)->status = 0xff; \ ++ (invit_info)->req_op_ch = 0; \ ++ (invit_info)->rsp_op_ch = 0; \ ++ } while (0) ++ ++struct rtw_wdev_priv { ++ struct wireless_dev *rtw_wdev; ++ ++ struct adapter *padapter; ++ ++ struct cfg80211_scan_request *scan_request; ++ spinlock_t scan_req_lock; ++ ++ struct net_device *pmon_ndev;/* for monitor interface */ ++ char ifname_mon[IFNAMSIZ + 1]; /* name of monitor interface */ ++ ++ u8 p2p_enabled; ++ ++ u8 provdisc_req_issued; ++ ++ struct rtw_wdev_invit_info invit_info; ++ ++ u8 bandroid_scan; ++ bool block; ++ bool power_mgmt; ++}; ++ ++#define wdev_to_priv(w) ((struct rtw_wdev_priv *)(wdev_priv(w))) ++ ++#define wiphy_to_wdev(x) \ ++((struct wireless_dev *)(((struct rtw_wdev_priv *)wiphy_priv(x))->rtw_wdev)) ++ ++int rtw_wdev_alloc(struct adapter *padapter, struct device *dev); ++void rtw_wdev_free(struct wireless_dev *wdev); ++void rtw_wdev_unregister(struct wireless_dev *wdev); ++ ++void rtw_cfg80211_init_wiphy(struct adapter *padapter); ++ ++void rtw_cfg80211_surveydone_event_callback(struct adapter *padapter); ++ ++void rtw_cfg80211_indicate_connect(struct adapter *padapter); ++void rtw_cfg80211_indicate_disconnect(struct adapter *padapter); ++void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv, ++ bool aborted); ++ ++#ifdef CONFIG_88EU_AP_MODE ++void rtw_cfg80211_indicate_sta_assoc(struct adapter *padapter, ++ u8 *pmgmt_frame, uint frame_len); ++void rtw_cfg80211_indicate_sta_disassoc(struct adapter *padapter, ++ unsigned char *da, ++ unsigned short reason); ++#endif /* CONFIG_88EU_AP_MODE */ ++ ++void rtw_cfg80211_issue_p2p_provision_request(struct adapter *padapter, ++ const u8 *buf, size_t len); ++void rtw_cfg80211_rx_p2p_action_public(struct adapter *padapter, ++ u8 *pmgmt_frame, uint frame_len); ++void rtw_cfg80211_rx_action_p2p(struct adapter *padapter, u8 *pmgmt_frame, ++ uint frame_len); ++void rtw_cfg80211_rx_action(struct adapter *adapter, u8 *frame, ++ uint frame_len, const char *msg); ++ ++int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, ++ char *buf, int len, int type); ++ ++bool rtw_cfg80211_pwr_mgmt(struct adapter *adapter); ++ ++#define rtw_cfg80211_rx_mgmt(dev, freq, sig_dbm, buf, len, gfp) \ ++ cfg80211_rx_mgmt(dev, freq, sig_dbm, buf, len, gfp) ++#define rtw_cfg80211_send_rx_assoc(dev, bss, buf, len) \ ++ cfg80211_send_rx_assoc(dev, bss, buf, len) ++ ++#endif /* __IOCTL_CFG80211_H__ */ +diff --git a/drivers/staging/r8188eu/include/mlme_osdep.h b/drivers/staging/r8188eu/include/mlme_osdep.h +new file mode 100644 +index 000000000000..5b9f688f9424 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/mlme_osdep.h +@@ -0,0 +1,19 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __MLME_OSDEP_H_ ++#define __MLME_OSDEP_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++void rtw_init_mlme_timer(struct adapter *padapter); ++void rtw_os_indicate_disconnect(struct adapter *adapter); ++void rtw_os_indicate_connect(struct adapter *adapter); ++void rtw_os_indicate_scan_done(struct adapter *padapter, bool aborted); ++void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie); ++ ++void rtw_reset_securitypriv(struct adapter *adapter); ++void indicate_wx_scan_complete_event(struct adapter *padapter); ++ ++#endif /* _MLME_OSDEP_H_ */ +diff --git a/drivers/staging/r8188eu/include/mp_custom_oid.h b/drivers/staging/r8188eu/include/mp_custom_oid.h +new file mode 100644 +index 000000000000..7bcb857c795d +--- /dev/null ++++ b/drivers/staging/r8188eu/include/mp_custom_oid.h +@@ -0,0 +1,333 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __CUSTOM_OID_H ++#define __CUSTOM_OID_H ++ ++/* by Owen */ ++/* 0xFF818000 - 0xFF81802F RTL8180 Mass Production Kit */ ++/* 0xFF818500 - 0xFF81850F RTL8185 Setup Utility */ ++/* 0xFF818580 - 0xFF81858F RTL8185 Phy Status Utility */ ++ ++/* */ ++ ++/* by Owen for Production Kit */ ++/* For Production Kit with Agilent Equipments */ ++/* in order to make our custom oids hopefully somewhat unique */ ++/* we will use 0xFF (indicating implementation specific OID) */ ++/* 81(first byte of non zero Realtek unique identifier) */ ++/* 80 (second byte of non zero Realtek unique identifier) */ ++/* XX (the custom OID number - providing 255 possible custom oids) */ ++ ++#define OID_RT_PRO_RESET_DUT 0xFF818000 ++#define OID_RT_PRO_SET_DATA_RATE 0xFF818001 ++#define OID_RT_PRO_START_TEST 0xFF818002 ++#define OID_RT_PRO_STOP_TEST 0xFF818003 ++#define OID_RT_PRO_SET_PREAMBLE 0xFF818004 ++#define OID_RT_PRO_SET_SCRAMBLER 0xFF818005 ++#define OID_RT_PRO_SET_FILTER_BB 0xFF818006 ++#define OID_RT_PRO_SET_MANUAL_DIVERSITY_BB 0xFF818007 ++#define OID_RT_PRO_SET_CHANNEL_DIRECT_CALL 0xFF818008 ++#define OID_RT_PRO_SET_SLEEP_MODE_DIRECT_CALL 0xFF818009 ++#define OID_RT_PRO_SET_WAKE_MODE_DIRECT_CALL 0xFF81800A ++ ++#define OID_RT_PRO_SET_TX_ANTENNA_BB 0xFF81800D ++#define OID_RT_PRO_SET_ANTENNA_BB 0xFF81800E ++#define OID_RT_PRO_SET_CR_SCRAMBLER 0xFF81800F ++#define OID_RT_PRO_SET_CR_NEW_FILTER 0xFF818010 ++#define OID_RT_PRO_SET_TX_POWER_CONTROL 0xFF818011 ++#define OID_RT_PRO_SET_CR_TX_CONFIG 0xFF818012 ++#define OID_RT_PRO_GET_TX_POWER_CONTROL 0xFF818013 ++#define OID_RT_PRO_GET_CR_SIGNAL_QUALITY 0xFF818014 ++#define OID_RT_PRO_SET_CR_SETPOINT 0xFF818015 ++#define OID_RT_PRO_SET_INTEGRATOR 0xFF818016 ++#define OID_RT_PRO_SET_SIGNAL_QUALITY 0xFF818017 ++#define OID_RT_PRO_GET_INTEGRATOR 0xFF818018 ++#define OID_RT_PRO_GET_SIGNAL_QUALITY 0xFF818019 ++#define OID_RT_PRO_QUERY_EEPROM_TYPE 0xFF81801A ++#define OID_RT_PRO_WRITE_MAC_ADDRESS 0xFF81801B ++#define OID_RT_PRO_READ_MAC_ADDRESS 0xFF81801C ++#define OID_RT_PRO_WRITE_CIS_DATA 0xFF81801D ++#define OID_RT_PRO_READ_CIS_DATA 0xFF81801E ++#define OID_RT_PRO_WRITE_POWER_CONTROL 0xFF81801F ++#define OID_RT_PRO_READ_POWER_CONTROL 0xFF818020 ++#define OID_RT_PRO_WRITE_EEPROM 0xFF818021 ++#define OID_RT_PRO_READ_EEPROM 0xFF818022 ++#define OID_RT_PRO_RESET_TX_PACKET_SENT 0xFF818023 ++#define OID_RT_PRO_QUERY_TX_PACKET_SENT 0xFF818024 ++#define OID_RT_PRO_RESET_RX_PACKET_RECEIVED 0xFF818025 ++#define OID_RT_PRO_QUERY_RX_PACKET_RECEIVED 0xFF818026 ++#define OID_RT_PRO_QUERY_RX_PACKET_CRC32_ERROR 0xFF818027 ++#define OID_RT_PRO_QUERY_CURRENT_ADDRESS 0xFF818028 ++#define OID_RT_PRO_QUERY_PERMANENT_ADDRESS 0xFF818029 ++#define OID_RT_PRO_SET_PHILIPS_RF_PARAMETERS 0xFF81802A ++#define OID_RT_PRO_RECEIVE_PACKET 0xFF81802C ++/* added by Owen on 04/08/03 for Cameo's request */ ++#define OID_RT_PRO_WRITE_EEPROM_BYTE 0xFF81802D ++#define OID_RT_PRO_READ_EEPROM_BYTE 0xFF81802E ++#define OID_RT_PRO_SET_MODULATION 0xFF81802F ++/* */ ++ ++/* Sean */ ++#define OID_RT_DRIVER_OPTION 0xFF818080 ++#define OID_RT_RF_OFF 0xFF818081 ++#define OID_RT_AUTH_STATUS 0xFF818082 ++ ++/* */ ++#define OID_RT_PRO_SET_CONTINUOUS_TX 0xFF81800B ++#define OID_RT_PRO_SET_SINGLE_CARRIER_TX 0xFF81800C ++#define OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX 0xFF81802B ++#define OID_RT_PRO_SET_SINGLE_TONE_TX 0xFF818043 ++/* */ ++ ++/* by Owen for RTL8185 Phy Status Report Utility */ ++#define OID_RT_UTILITY_false_ALARM_COUNTERS 0xFF818580 ++#define OID_RT_UTILITY_SELECT_DEBUG_MODE 0xFF818581 ++#define OID_RT_UTILITY_SELECT_SUBCARRIER_NUMBER 0xFF818582 ++#define OID_RT_UTILITY_GET_RSSI_STATUS 0xFF818583 ++#define OID_RT_UTILITY_GET_FRAME_DETECTION_STATUS 0xFF818584 ++#define OID_RT_UTILITY_GET_AGC_AND_FREQUENCY_OFFSET_ESTIMATION_STATUS \ ++ 0xFF818585 ++#define OID_RT_UTILITY_GET_CHANNEL_ESTIMATION_STATUS 0xFF818586 ++/* */ ++ ++/* by Owen on 03/09/19-03/09/22 for RTL8185 */ ++#define OID_RT_WIRELESS_MODE 0xFF818500 ++#define OID_RT_SUPPORTED_RATES 0xFF818501 ++#define OID_RT_DESIRED_RATES 0xFF818502 ++#define OID_RT_WIRELESS_MODE_STARTING_ADHOC 0xFF818503 ++/* */ ++ ++#define OID_RT_GET_CONNECT_STATE 0xFF030001 ++#define OID_RT_RESCAN 0xFF030002 ++#define OID_RT_SET_KEY_LENGTH 0xFF030003 ++#define OID_RT_SET_DEFAULT_KEY_ID 0xFF030004 ++ ++#define OID_RT_SET_CHANNEL 0xFF010182 ++#define OID_RT_SET_SNIFFER_MODE 0xFF010183 ++#define OID_RT_GET_SIGNAL_QUALITY 0xFF010184 ++#define OID_RT_GET_SMALL_PACKET_CRC 0xFF010185 ++#define OID_RT_GET_MIDDLE_PACKET_CRC 0xFF010186 ++#define OID_RT_GET_LARGE_PACKET_CRC 0xFF010187 ++#define OID_RT_GET_TX_RETRY 0xFF010188 ++#define OID_RT_GET_RX_RETRY 0xFF010189 ++#define OID_RT_PRO_SET_FW_DIG_STATE 0xFF01018A/* S */ ++#define OID_RT_PRO_SET_FW_RA_STATE 0xFF01018B/* S */ ++ ++#define OID_RT_GET_RX_TOTAL_PACKET 0xFF010190 ++#define OID_RT_GET_TX_BEACON_OK 0xFF010191 ++#define OID_RT_GET_TX_BEACON_ERR 0xFF010192 ++#define OID_RT_GET_RX_ICV_ERR 0xFF010193 ++#define OID_RT_SET_ENCRYPTION_ALGORITHM 0xFF010194 ++#define OID_RT_SET_NO_AUTO_RESCAN 0xFF010195 ++#define OID_RT_GET_PREAMBLE_MODE 0xFF010196 ++#define OID_RT_GET_DRIVER_UP_DELTA_TIME 0xFF010197 ++#define OID_RT_GET_AP_IP 0xFF010198 ++#define OID_RT_GET_CHANNELPLAN 0xFF010199 ++#define OID_RT_SET_PREAMBLE_MODE 0xFF01019A ++#define OID_RT_SET_BCN_INTVL 0xFF01019B ++#define OID_RT_GET_RF_VENDER 0xFF01019C ++#define OID_RT_DEDICATE_PROBE 0xFF01019D ++#define OID_RT_PRO_RX_FILTER_PATTERN 0xFF01019E ++ ++#define OID_RT_GET_DCST_CURRENT_THRESHOLD 0xFF01019F ++ ++#define OID_RT_GET_CCA_ERR 0xFF0101A0 ++#define OID_RT_GET_CCA_UPGRADE_THRESHOLD 0xFF0101A1 ++#define OID_RT_GET_CCA_FALLBACK_THRESHOLD 0xFF0101A2 ++ ++#define OID_RT_GET_CCA_UPGRADE_EVALUATE_TIMES 0xFF0101A3 ++#define OID_RT_GET_CCA_FALLBACK_EVALUATE_TIMES 0xFF0101A4 ++ ++/* by Owen on 03/31/03 for Cameo's request */ ++#define OID_RT_SET_RATE_ADAPTIVE 0xFF0101A5 ++/* */ ++#define OID_RT_GET_DCST_EVALUATE_PERIOD 0xFF0101A5 ++#define OID_RT_GET_DCST_TIME_UNIT_INDEX 0xFF0101A6 ++#define OID_RT_GET_TOTAL_TX_BYTES 0xFF0101A7 ++#define OID_RT_GET_TOTAL_RX_BYTES 0xFF0101A8 ++#define OID_RT_CURRENT_TX_POWER_LEVEL 0xFF0101A9 ++#define OID_RT_GET_ENC_KEY_MISMATCH_COUNT 0xFF0101AA ++#define OID_RT_GET_ENC_KEY_MATCH_COUNT 0xFF0101AB ++#define OID_RT_GET_CHANNEL 0xFF0101AC ++ ++#define OID_RT_SET_CHANNELPLAN 0xFF0101AD ++#define OID_RT_GET_HARDWARE_RADIO_OFF 0xFF0101AE ++#define OID_RT_CHANNELPLAN_BY_COUNTRY 0xFF0101AF ++#define OID_RT_SCAN_AVAILABLE_BSSID 0xFF0101B0 ++#define OID_RT_GET_HARDWARE_VERSION 0xFF0101B1 ++#define OID_RT_GET_IS_ROAMING 0xFF0101B2 ++#define OID_RT_GET_IS_PRIVACY 0xFF0101B3 ++#define OID_RT_GET_KEY_MISMATCH 0xFF0101B4 ++#define OID_RT_SET_RSSI_ROAM_TRAFFIC_TH 0xFF0101B5 ++#define OID_RT_SET_RSSI_ROAM_SIGNAL_TH 0xFF0101B6 ++#define OID_RT_RESET_LOG 0xFF0101B7 ++#define OID_RT_GET_LOG 0xFF0101B8 ++#define OID_RT_SET_INDICATE_HIDDEN_AP 0xFF0101B9 ++#define OID_RT_GET_HEADER_FAIL 0xFF0101BA ++#define OID_RT_SUPPORTED_WIRELESS_MODE 0xFF0101BB ++#define OID_RT_GET_CHANNEL_LIST 0xFF0101BC ++#define OID_RT_GET_SCAN_IN_PROGRESS 0xFF0101BD ++#define OID_RT_GET_TX_INFO 0xFF0101BE ++#define OID_RT_RF_READ_WRITE_OFFSET 0xFF0101BF ++#define OID_RT_RF_READ_WRITE 0xFF0101C0 ++ ++/* For Netgear request. 2005.01.13, by rcnjko. */ ++#define OID_RT_FORCED_DATA_RATE 0xFF0101C1 ++#define OID_RT_WIRELESS_MODE_FOR_SCAN_LIST 0xFF0101C2 ++/* For Netgear request. 2005.02.17, by rcnjko. */ ++#define OID_RT_GET_BSS_WIRELESS_MODE 0xFF0101C3 ++/* For AZ project. 2005.06.27, by rcnjko. */ ++#define OID_RT_SCAN_WITH_MAGIC_PACKET 0xFF0101C4 ++ ++/* Vincent 8185MP */ ++#define OID_RT_PRO_RX_FILTER 0xFF0111C0 ++ ++#define OID_CE_USB_WRITE_REGISTRY 0xFF0111C1 ++#define OID_CE_USB_READ_REGISTRY 0xFF0111C2 ++ ++#define OID_RT_PRO_SET_INITIAL_GA 0xFF0111C3 ++#define OID_RT_PRO_SET_BB_RF_STANDBY_MODE 0xFF0111C4 ++#define OID_RT_PRO_SET_BB_RF_SHUTDOWN_MODE 0xFF0111C5 ++#define OID_RT_PRO_SET_TX_CHARGE_PUMP 0xFF0111C6 ++#define OID_RT_PRO_SET_RX_CHARGE_PUMP 0xFF0111C7 ++#define OID_RT_PRO_RF_WRITE_REGISTRY 0xFF0111C8 ++#define OID_RT_PRO_RF_READ_REGISTRY 0xFF0111C9 ++#define OID_RT_PRO_QUERY_RF_TYPE 0xFF0111CA ++ ++/* AP OID */ ++#define OID_RT_AP_GET_ASSOCIATED_STATION_LIST 0xFF010300 ++#define OID_RT_AP_GET_CURRENT_TIME_STAMP 0xFF010301 ++#define OID_RT_AP_SWITCH_INTO_AP_MODE 0xFF010302 ++#define OID_RT_AP_SET_DTIM_PERIOD 0xFF010303 ++/* Determine if driver supports AP mode. */ ++#define OID_RT_AP_SUPPORTED 0xFF010304 ++/* Set WPA-PSK passphrase into authenticator. */ ++#define OID_RT_AP_SET_PASSPHRASE 0xFF010305 ++ ++/* 8187MP. 2004.09.06, by rcnjko. */ ++#define OID_RT_PRO8187_WI_POLL 0xFF818780 ++#define OID_RT_PRO_WRITE_BB_REG 0xFF818781 ++#define OID_RT_PRO_READ_BB_REG 0xFF818782 ++#define OID_RT_PRO_WRITE_RF_REG 0xFF818783 ++#define OID_RT_PRO_READ_RF_REG 0xFF818784 ++ ++/* Meeting House. added by Annie, 2005-07-20. */ ++#define OID_RT_MH_VENDER_ID 0xFFEDC100 ++ ++/* 8711 MP OID added 20051230. */ ++#define OID_RT_PRO8711_JOIN_BSS 0xFF871100/* S */ ++ ++#define OID_RT_PRO_READ_REGISTER 0xFF871101 /* Q */ ++#define OID_RT_PRO_WRITE_REGISTER 0xFF871102 /* S */ ++ ++#define OID_RT_PRO_BURST_READ_REGISTER 0xFF871103 /* Q */ ++#define OID_RT_PRO_BURST_WRITE_REGISTER 0xFF871104 /* S */ ++ ++#define OID_RT_PRO_WRITE_TXCMD 0xFF871105 /* S */ ++ ++#define OID_RT_PRO_READ16_EEPROM 0xFF871106 /* Q */ ++#define OID_RT_PRO_WRITE16_EEPROM 0xFF871107 /* S */ ++ ++#define OID_RT_PRO_H2C_SET_COMMAND 0xFF871108 /* S */ ++#define OID_RT_PRO_H2C_QUERY_RESULT 0xFF871109 /* Q */ ++ ++#define OID_RT_PRO8711_WI_POLL 0xFF87110A /* Q */ ++#define OID_RT_PRO8711_PKT_LOSS 0xFF87110B /* Q */ ++#define OID_RT_RD_ATTRIB_MEM 0xFF87110C/* Q */ ++#define OID_RT_WR_ATTRIB_MEM 0xFF87110D/* S */ ++ ++/* Method 2 for H2C/C2H */ ++#define OID_RT_PRO_H2C_CMD_MODE 0xFF871110 /* S */ ++#define OID_RT_PRO_H2C_CMD_RSP_MODE 0xFF871111 /* Q */ ++#define OID_RT_PRO_H2C_CMD_EVENT_MODE 0xFF871112 /* S */ ++#define OID_RT_PRO_WAIT_C2H_EVENT 0xFF871113 /* Q */ ++#define OID_RT_PRO_RW_ACCESS_PROTOCOL_TEST 0xFF871114/* Q */ ++ ++#define OID_RT_PRO_SCSI_ACCESS_TEST 0xFF871115 /* Q, S */ ++ ++#define OID_RT_PRO_SCSI_TCPIPOFFLOAD_OUT 0xFF871116 /* S */ ++#define OID_RT_PRO_SCSI_TCPIPOFFLOAD_IN 0xFF871117 /* Q,S */ ++#define OID_RT_RRO_RX_PKT_VIA_IOCTRL 0xFF871118 /* Q */ ++#define OID_RT_RRO_RX_PKTARRAY_VIA_IOCTRL 0xFF871119 /* Q */ ++ ++#define OID_RT_RPO_SET_PWRMGT_TEST 0xFF87111A /* S */ ++#define OID_RT_PRO_QRY_PWRMGT_TEST 0XFF87111B /* Q */ ++#define OID_RT_RPO_ASYNC_RWIO_TEST 0xFF87111C /* S */ ++#define OID_RT_RPO_ASYNC_RWIO_POLL 0xFF87111D /* Q */ ++#define OID_RT_PRO_SET_RF_INTFS 0xFF87111E /* S */ ++#define OID_RT_POLL_RX_STATUS 0xFF87111F /* Q */ ++ ++#define OID_RT_PRO_CFG_DEBUG_MESSAGE 0xFF871120 /* Q,S */ ++#define OID_RT_PRO_SET_DATA_RATE_EX 0xFF871121/* S */ ++#define OID_RT_PRO_SET_BASIC_RATE 0xFF871122/* S */ ++#define OID_RT_PRO_READ_TSSI 0xFF871123/* S */ ++#define OID_RT_PRO_SET_POWER_TRACKING 0xFF871124/* S */ ++ ++#define OID_RT_PRO_QRY_PWRSTATE 0xFF871150 /* Q */ ++#define OID_RT_PRO_SET_PWRSTATE 0xFF871151 /* S */ ++ ++/* Method 2 , using workitem */ ++#define OID_RT_SET_READ_REG 0xFF871181 /* S */ ++#define OID_RT_SET_WRITE_REG 0xFF871182 /* S */ ++#define OID_RT_SET_BURST_READ_REG 0xFF871183 /* S */ ++#define OID_RT_SET_BURST_WRITE_REG 0xFF871184 /* S */ ++#define OID_RT_SET_WRITE_TXCMD 0xFF871185 /* S */ ++#define OID_RT_SET_READ16_EEPROM 0xFF871186 /* S */ ++#define OID_RT_SET_WRITE16_EEPROM 0xFF871187 /* S */ ++#define OID_RT_QRY_POLL_WKITEM 0xFF871188 /* Q */ ++ ++/* For SDIO INTERFACE only */ ++#define OID_RT_PRO_SYNCPAGERW_SRAM 0xFF8711A0 /* Q, S */ ++#define OID_RT_PRO_871X_DRV_EXT 0xFF8711A1 ++ ++/* For USB INTERFACE only */ ++#define OID_RT_PRO_USB_VENDOR_REQ 0xFF8711B0 /* Q, S */ ++#define OID_RT_PRO_SCSI_AUTO_TEST 0xFF8711B1 /* S */ ++#define OID_RT_PRO_USB_MAC_AC_FIFO_WRITE 0xFF8711B2 /* S */ ++#define OID_RT_PRO_USB_MAC_RX_FIFO_READ 0xFF8711B3 /* Q */ ++#define OID_RT_PRO_USB_MAC_RX_FIFO_POLLING 0xFF8711B4 /* Q */ ++ ++#define OID_RT_PRO_H2C_SET_RATE_TABLE 0xFF8711FB /* S */ ++#define OID_RT_PRO_H2C_GET_RATE_TABLE 0xFF8711FC /* S */ ++#define OID_RT_PRO_H2C_C2H_LBK_TEST 0xFF8711FE ++ ++#define OID_RT_PRO_ENCRYPTION_CTRL 0xFF871200 /* Q, S */ ++#define OID_RT_PRO_ADD_STA_INFO 0xFF871201 /* S */ ++#define OID_RT_PRO_DELE_STA_INFO 0xFF871202 /* S */ ++#define OID_RT_PRO_QUERY_DR_VARIABLE 0xFF871203 /* Q */ ++ ++#define OID_RT_PRO_RX_PACKET_TYPE 0xFF871204 /* Q, S */ ++ ++#define OID_RT_PRO_READ_EFUSE 0xFF871205 /* Q */ ++#define OID_RT_PRO_WRITE_EFUSE 0xFF871206 /* S */ ++#define OID_RT_PRO_RW_EFUSE_PGPKT 0xFF871207 /* Q, S */ ++#define OID_RT_GET_EFUSE_CURRENT_SIZE 0xFF871208 /* Q */ ++ ++#define OID_RT_SET_BANDWIDTH 0xFF871209 /* S */ ++#define OID_RT_SET_CRYSTAL_CAP 0xFF87120A /* S */ ++ ++#define OID_RT_SET_RX_PACKET_TYPE 0xFF87120B /* S */ ++ ++#define OID_RT_GET_EFUSE_MAX_SIZE 0xFF87120C /* Q */ ++ ++#define OID_RT_PRO_SET_TX_AGC_OFFSET 0xFF87120D /* S */ ++ ++#define OID_RT_PRO_SET_PKT_TEST_MODE 0xFF87120E /* S */ ++ ++#define OID_RT_PRO_FOR_EVM_TEST_SETTING 0xFF87120F /* S */ ++ ++#define OID_RT_PRO_GET_THERMAL_METER 0xFF871210 /* Q */ ++ ++#define OID_RT_RESET_PHY_RX_PACKET_COUNT 0xFF871211 /* S */ ++#define OID_RT_GET_PHY_RX_PACKET_RECEIVED 0xFF871212 /* Q */ ++#define OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR 0xFF871213 /* Q */ ++ ++#define OID_RT_SET_POWER_DOWN 0xFF871214 /* S */ ++ ++#define OID_RT_GET_POWER_MODE 0xFF871215 /* Q */ ++ ++#define OID_RT_PRO_EFUSE 0xFF871216 /* Q, S */ ++#define OID_RT_PRO_EFUSE_MAP 0xFF871217 /* Q, S */ ++ ++#endif /* ifndef __CUSTOM_OID_H */ +diff --git a/drivers/staging/r8188eu/include/odm.h b/drivers/staging/r8188eu/include/odm.h +new file mode 100644 +index 000000000000..d9041ee576bb +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm.h +@@ -0,0 +1,1154 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __HALDMOUTSRC_H__ ++#define __HALDMOUTSRC_H__ ++ ++/* Definition */ ++/* Define all team support ability. */ ++ ++/* Define for all teams. Please Define the constant in your precomp header. */ ++ ++/* define DM_ODM_SUPPORT_AP 0 */ ++/* define DM_ODM_SUPPORT_ADSL 0 */ ++/* define DM_ODM_SUPPORT_CE 0 */ ++/* define DM_ODM_SUPPORT_MP 1 */ ++ ++/* Define ODM SW team support flag. */ ++ ++/* Antenna Switch Relative Definition. */ ++ ++/* Add new function SwAntDivCheck8192C(). */ ++/* This is the main function of Antenna diversity function before link. */ ++/* Mainly, it just retains last scan result and scan again. */ ++/* After that, it compares the scan result to see which one gets better ++ * RSSI. It selects antenna with better receiving power and returns better ++ * scan result. */ ++ ++#define TP_MODE 0 ++#define RSSI_MODE 1 ++#define TRAFFIC_LOW 0 ++#define TRAFFIC_HIGH 1 ++ ++/* 3 Tx Power Tracking */ ++/* 3============================================================ */ ++#define DPK_DELTA_MAPPING_NUM 13 ++#define index_mapping_HP_NUM 15 ++ ++/* */ ++/* 3 PSD Handler */ ++/* 3============================================================ */ ++ ++#define AFH_PSD 1 /* 0:normal PSD scan, 1: only do 20 pts PSD */ ++#define MODE_40M 0 /* 0:20M, 1:40M */ ++#define PSD_TH2 3 ++#define PSD_CHM 20 /* Minimum channel number for BT AFH */ ++#define SIR_STEP_SIZE 3 ++#define Smooth_Size_1 5 ++#define Smooth_TH_1 3 ++#define Smooth_Size_2 10 ++#define Smooth_TH_2 4 ++#define Smooth_Size_3 20 ++#define Smooth_TH_3 4 ++#define Smooth_Step_Size 5 ++#define Adaptive_SIR 1 ++#define PSD_RESCAN 4 ++#define PSD_SCAN_INTERVAL 700 /* ms */ ++ ++/* 8723A High Power IGI Setting */ ++#define DM_DIG_HIGH_PWR_IGI_LOWER_BOUND 0x22 ++#define DM_DIG_Gmode_HIGH_PWR_IGI_LOWER_BOUND 0x28 ++#define DM_DIG_HIGH_PWR_THRESHOLD 0x3a ++ ++/* LPS define */ ++#define DM_DIG_FA_TH0_LPS 4 /* 4 in lps */ ++#define DM_DIG_FA_TH1_LPS 15 /* 15 lps */ ++#define DM_DIG_FA_TH2_LPS 30 /* 30 lps */ ++#define RSSI_OFFSET_DIG 0x05; ++ ++/* ANT Test */ ++#define ANTTESTALL 0x00 /* Ant A or B will be Testing */ ++#define ANTTESTA 0x01 /* Ant A will be Testing */ ++#define ANTTESTB 0x02 /* Ant B will be testing */ ++ ++/* structure and define */ ++ ++/* Add for AP/ADSLpseudo DM structuer requirement. */ ++/* We need to remove to other position??? */ ++struct rtl8192cd_priv { ++ u8 temp; ++}; ++ ++struct rtw_dig { ++ u8 Dig_Enable_Flag; ++ u8 Dig_Ext_Port_Stage; ++ ++ int RssiLowThresh; ++ int RssiHighThresh; ++ ++ u32 FALowThresh; ++ u32 FAHighThresh; ++ ++ u8 CurSTAConnectState; ++ u8 PreSTAConnectState; ++ u8 CurMultiSTAConnectState; ++ ++ u8 PreIGValue; ++ u8 CurIGValue; ++ u8 BackupIGValue; ++ ++ s8 BackoffVal; ++ s8 BackoffVal_range_max; ++ s8 BackoffVal_range_min; ++ u8 rx_gain_range_max; ++ u8 rx_gain_range_min; ++ u8 Rssi_val_min; ++ ++ u8 PreCCK_CCAThres; ++ u8 CurCCK_CCAThres; ++ u8 PreCCKPDState; ++ u8 CurCCKPDState; ++ ++ u8 LargeFAHit; ++ u8 ForbiddenIGI; ++ u32 Recover_cnt; ++ ++ u8 DIG_Dynamic_MIN_0; ++ u8 DIG_Dynamic_MIN_1; ++ bool bMediaConnect_0; ++ bool bMediaConnect_1; ++ ++ u32 AntDiv_RSSI_max; ++ u32 RSSI_max; ++}; ++ ++struct rtl_ps { ++ u8 pre_cca_state; ++ u8 cur_cca_state; ++ ++ u8 pre_rf_state; ++ u8 cur_rf_state; ++ ++ int rssi_val_min; ++ ++ u8 initialize; ++ u32 reg_874; ++ u32 reg_c70; ++ u32 reg_85c; ++ u32 reg_a74; ++ ++}; ++ ++struct false_alarm_stats { ++ u32 Cnt_Parity_Fail; ++ u32 Cnt_Rate_Illegal; ++ u32 Cnt_Crc8_fail; ++ u32 Cnt_Mcs_fail; ++ u32 Cnt_Ofdm_fail; ++ u32 Cnt_Cck_fail; ++ u32 Cnt_all; ++ u32 Cnt_Fast_Fsync; ++ u32 Cnt_SB_Search_fail; ++ u32 Cnt_OFDM_CCA; ++ u32 Cnt_CCK_CCA; ++ u32 Cnt_CCA_all; ++ u32 Cnt_BW_USC; /* Gary */ ++ u32 Cnt_BW_LSC; /* Gary */ ++}; ++ ++struct dyn_primary_cca { ++ u8 pri_cca_flag; ++ u8 intf_flag; ++ u8 intf_type; ++ u8 dup_rts_flag; ++ u8 monitor_flag; ++}; ++ ++struct rx_hpc { ++ u8 RXHP_flag; ++ u8 PSD_func_trigger; ++ u8 PSD_bitmap_RXHP[80]; ++ u8 Pre_IGI; ++ u8 Cur_IGI; ++ u8 Pre_pw_th; ++ u8 Cur_pw_th; ++ bool First_time_enter; ++ bool RXHP_enable; ++ u8 TP_Mode; ++ struct timer_list PSDTimer; ++}; ++ ++#define ASSOCIATE_ENTRY_NUM 32 /* Max size of AsocEntry[]. */ ++#define ODM_ASSOCIATE_ENTRY_NUM ASSOCIATE_ENTRY_NUM ++ ++/* This indicates two different steps. */ ++/* In SWAW_STEP_PEAK, driver needs to switch antenna and listen to ++ * the signal on the air. */ ++/* In SWAW_STEP_DETERMINE, driver just compares the signal captured in ++ * SWAW_STEP_PEAK with original RSSI to determine if it is necessary to ++ * switch antenna. */ ++ ++#define SWAW_STEP_PEAK 0 ++#define SWAW_STEP_DETERMINE 1 ++ ++#define TP_MODE 0 ++#define RSSI_MODE 1 ++#define TRAFFIC_LOW 0 ++#define TRAFFIC_HIGH 1 ++ ++struct sw_ant_switch { ++ u8 try_flag; ++ s32 PreRSSI; ++ u8 CurAntenna; ++ u8 PreAntenna; ++ u8 RSSI_Trying; ++ u8 TestMode; ++ u8 bTriggerAntennaSwitch; ++ u8 SelectAntennaMap; ++ u8 RSSI_target; ++ ++ /* Before link Antenna Switch check */ ++ u8 SWAS_NoLink_State; ++ u32 SWAS_NoLink_BK_Reg860; ++ bool ANTA_ON; /* To indicate Ant A is or not */ ++ bool ANTB_ON; /* To indicate Ant B is on or not */ ++ ++ s32 RSSI_sum_A; ++ s32 RSSI_sum_B; ++ s32 RSSI_cnt_A; ++ s32 RSSI_cnt_B; ++ u64 lastTxOkCnt; ++ u64 lastRxOkCnt; ++ u64 TXByteCnt_A; ++ u64 TXByteCnt_B; ++ u64 RXByteCnt_A; ++ u64 RXByteCnt_B; ++ u8 TrafficLoad; ++ struct timer_list SwAntennaSwitchTimer; ++ /* Hybrid Antenna Diversity */ ++ u32 CCK_Ant1_Cnt[ASSOCIATE_ENTRY_NUM]; ++ u32 CCK_Ant2_Cnt[ASSOCIATE_ENTRY_NUM]; ++ u32 OFDM_Ant1_Cnt[ASSOCIATE_ENTRY_NUM]; ++ u32 OFDM_Ant2_Cnt[ASSOCIATE_ENTRY_NUM]; ++ u32 RSSI_Ant1_Sum[ASSOCIATE_ENTRY_NUM]; ++ u32 RSSI_Ant2_Sum[ASSOCIATE_ENTRY_NUM]; ++ u8 TxAnt[ASSOCIATE_ENTRY_NUM]; ++ u8 TargetSTA; ++ u8 antsel; ++ u8 RxIdleAnt; ++}; ++ ++struct edca_turbo { ++ bool bCurrentTurboEDCA; ++ bool bIsCurRDLState; ++ u32 prv_traffic_idx; /* edca turbo */ ++}; ++ ++struct odm_rate_adapt { ++ u8 Type; /* DM_Type_ByFW/DM_Type_ByDriver */ ++ u8 HighRSSIThresh; /* if RSSI > HighRSSIThresh => RATRState is DM_RATR_STA_HIGH */ ++ u8 LowRSSIThresh; /* if RSSI <= LowRSSIThresh => RATRState is DM_RATR_STA_LOW */ ++ u8 RATRState; /* Current RSSI level, DM_RATR_STA_HIGH/DM_RATR_STA_MIDDLE/DM_RATR_STA_LOW */ ++ u32 LastRATR; /* RATR Register Content */ ++}; ++ ++#define IQK_MAC_REG_NUM 4 ++#define IQK_ADDA_REG_NUM 16 ++#define IQK_BB_REG_NUM_MAX 10 ++#define IQK_BB_REG_NUM 9 ++#define HP_THERMAL_NUM 8 ++ ++#define AVG_THERMAL_NUM 8 ++#define IQK_Matrix_REG_NUM 8 ++#define IQK_Matrix_Settings_NUM 1+24+21 ++ ++#define DM_Type_ByFWi 0 ++#define DM_Type_ByDriver 1 ++ ++/* Declare for common info */ ++ ++struct odm_phy_status_info { ++ u8 RxPWDBAll; ++ u8 SignalQuality; /* in 0-100 index. */ ++ u8 RxMIMOSignalQuality[MAX_PATH_NUM_92CS]; /* EVM */ ++ u8 RxMIMOSignalStrength[MAX_PATH_NUM_92CS];/* in 0~100 index */ ++ s8 RxPower; /* in dBm Translate from PWdB */ ++ s8 RecvSignalPower;/* Real power in dBm for this packet, no ++ * beautification and aggregation. Keep this raw ++ * info to be used for the other procedures. */ ++ u8 BTRxRSSIPercentage; ++ u8 SignalStrength; /* in 0-100 index. */ ++ u8 RxPwr[MAX_PATH_NUM_92CS];/* per-path's pwdb */ ++ u8 RxSNR[MAX_PATH_NUM_92CS];/* per-path's SNR */ ++}; ++ ++struct odm_phy_dbg_info { ++ /* ODM Write,debug info */ ++ s8 RxSNRdB[MAX_PATH_NUM_92CS]; ++ u64 NumQryPhyStatus; ++ u64 NumQryPhyStatusCCK; ++ u64 NumQryPhyStatusOFDM; ++ /* Others */ ++ s32 RxEVM[MAX_PATH_NUM_92CS]; ++}; ++ ++struct odm_per_pkt_info { ++ s8 Rate; ++ u8 StationID; ++ bool bPacketMatchBSSID; ++ bool bPacketToSelf; ++ bool bPacketBeacon; ++}; ++ ++struct odm_mac_status_info { ++ u8 test; ++}; ++ ++enum odm_ability { ++ /* BB Team */ ++ ODM_DIG = 0x00000001, ++ ODM_HIGH_POWER = 0x00000002, ++ ODM_CCK_CCA_TH = 0x00000004, ++ ODM_FA_STATISTICS = 0x00000008, ++ ODM_RAMASK = 0x00000010, ++ ODM_RSSI_MONITOR = 0x00000020, ++ ODM_SW_ANTDIV = 0x00000040, ++ ODM_HW_ANTDIV = 0x00000080, ++ ODM_BB_PWRSV = 0x00000100, ++ ODM_2TPATHDIV = 0x00000200, ++ ODM_1TPATHDIV = 0x00000400, ++ ODM_PSD2AFH = 0x00000800 ++}; ++ ++/* 2011/20/20 MH For MP driver RT_WLAN_STA = struct sta_info */ ++/* Please declare below ODM relative info in your STA info structure. */ ++ ++struct odm_sta_info { ++ /* Driver Write */ ++ bool bUsed; /* record the sta status link or not? */ ++ u8 IOTPeer; /* Enum value. HT_IOT_PEER_E */ ++ ++ /* ODM Write */ ++ /* 1 PHY_STATUS_INFO */ ++ u8 RSSI_Path[4]; /* */ ++ u8 RSSI_Ave; ++ u8 RXEVM[4]; ++ u8 RXSNR[4]; ++}; ++ ++/* 2011/10/20 MH Define Common info enum for all team. */ ++ ++enum odm_common_info_def { ++ /* Fixed value: */ ++ ++ /* HOOK BEFORE REG INIT----------- */ ++ ODM_CMNINFO_PLATFORM = 0, ++ ODM_CMNINFO_ABILITY, /* ODM_ABILITY_E */ ++ ODM_CMNINFO_INTERFACE, /* ODM_INTERFACE_E */ ++ ODM_CMNINFO_MP_TEST_CHIP, ++ ODM_CMNINFO_IC_TYPE, /* ODM_IC_TYPE_E */ ++ ODM_CMNINFO_CUT_VER, /* ODM_CUT_VERSION_E */ ++ ODM_CMNINFO_FAB_VER, /* ODM_FAB_E */ ++ ODM_CMNINFO_RF_TYPE, /* RF_PATH_E or ODM_RF_TYPE_E? */ ++ ODM_CMNINFO_BOARD_TYPE, /* ODM_BOARD_TYPE_E */ ++ ODM_CMNINFO_EXT_LNA, /* true */ ++ ODM_CMNINFO_EXT_PA, ++ ODM_CMNINFO_EXT_TRSW, ++ ODM_CMNINFO_PATCH_ID, /* CUSTOMER ID */ ++ ODM_CMNINFO_BINHCT_TEST, ++ ODM_CMNINFO_BWIFI_TEST, ++ ODM_CMNINFO_SMART_CONCURRENT, ++ /* HOOK BEFORE REG INIT----------- */ ++ ++ /* Dynamic value: */ ++/* POINTER REFERENCE----------- */ ++ ODM_CMNINFO_MAC_PHY_MODE, /* ODM_MAC_PHY_MODE_E */ ++ ODM_CMNINFO_TX_UNI, ++ ODM_CMNINFO_RX_UNI, ++ ODM_CMNINFO_WM_MODE, /* ODM_WIRELESS_MODE_E */ ++ ODM_CMNINFO_BAND, /* ODM_BAND_TYPE_E */ ++ ODM_CMNINFO_SEC_CHNL_OFFSET, /* ODM_SEC_CHNL_OFFSET_E */ ++ ODM_CMNINFO_SEC_MODE, /* ODM_SECURITY_E */ ++ ODM_CMNINFO_BW, /* ODM_BW_E */ ++ ODM_CMNINFO_CHNL, ++ ++ ODM_CMNINFO_DMSP_GET_VALUE, ++ ODM_CMNINFO_BUDDY_ADAPTOR, ++ ODM_CMNINFO_DMSP_IS_MASTER, ++ ODM_CMNINFO_SCAN, ++ ODM_CMNINFO_POWER_SAVING, ++ ODM_CMNINFO_ONE_PATH_CCA, /* ODM_CCA_PATH_E */ ++ ODM_CMNINFO_DRV_STOP, ++ ODM_CMNINFO_PNP_IN, ++ ODM_CMNINFO_INIT_ON, ++ ODM_CMNINFO_ANT_TEST, ++ ODM_CMNINFO_NET_CLOSED, ++ ODM_CMNINFO_MP_MODE, ++/* POINTER REFERENCE----------- */ ++ ++/* CALL BY VALUE------------- */ ++ ODM_CMNINFO_WIFI_DIRECT, ++ ODM_CMNINFO_WIFI_DISPLAY, ++ ODM_CMNINFO_LINK, ++ ODM_CMNINFO_RSSI_MIN, ++ ODM_CMNINFO_RA_THRESHOLD_HIGH, /* u8 */ ++ ODM_CMNINFO_RA_THRESHOLD_LOW, /* u8 */ ++ ODM_CMNINFO_RF_ANTENNA_TYPE, /* u8 */ ++ ODM_CMNINFO_BT_DISABLED, ++ ODM_CMNINFO_BT_OPERATION, ++ ODM_CMNINFO_BT_DIG, ++ ODM_CMNINFO_BT_BUSY, /* Check Bt is using or not */ ++ ODM_CMNINFO_BT_DISABLE_EDCA, ++/* CALL BY VALUE-------------*/ ++ ++ /* Dynamic ptr array hook itms. */ ++ ODM_CMNINFO_STA_STATUS, ++ ODM_CMNINFO_PHY_STATUS, ++ ODM_CMNINFO_MAC_STATUS, ++ ODM_CMNINFO_MAX, ++}; ++ ++/* 2011/10/20 MH Define ODM support ability. ODM_CMNINFO_ABILITY */ ++ ++enum odm_ability_def { ++ /* BB ODM section BIT 0-15 */ ++ ODM_BB_DIG = BIT(0), ++ ODM_BB_RA_MASK = BIT(1), ++ ODM_BB_DYNAMIC_TXPWR = BIT(2), ++ ODM_BB_FA_CNT = BIT(3), ++ ODM_BB_RSSI_MONITOR = BIT(4), ++ ODM_BB_CCK_PD = BIT(5), ++ ODM_BB_ANT_DIV = BIT(6), ++ ODM_BB_PWR_SAVE = BIT(7), ++ ODM_BB_PWR_TRA = BIT(8), ++ ODM_BB_RATE_ADAPTIVE = BIT(9), ++ ODM_BB_PATH_DIV = BIT(10), ++ ODM_BB_PSD = BIT(11), ++ ODM_BB_RXHP = BIT(12), ++ ++ /* MAC DM section BIT 16-23 */ ++ ODM_MAC_EDCA_TURBO = BIT(16), ++ ODM_MAC_EARLY_MODE = BIT(17), ++ ++ /* RF ODM section BIT 24-31 */ ++ ODM_RF_TX_PWR_TRACK = BIT(24), ++ ODM_RF_RX_GAIN_TRACK = BIT(25), ++ ODM_RF_CALIBRATION = BIT(26), ++}; ++ ++/* ODM_CMNINFO_INTERFACE */ ++enum odm_interface_def { ++ ODM_ITRF_PCIE = 0x1, ++ ODM_ITRF_USB = 0x2, ++ ODM_ITRF_SDIO = 0x4, ++ ODM_ITRF_ALL = 0x7, ++}; ++ ++/* ODM_CMNINFO_IC_TYPE */ ++enum odm_ic_type { ++ ODM_RTL8192S = BIT(0), ++ ODM_RTL8192C = BIT(1), ++ ODM_RTL8192D = BIT(2), ++ ODM_RTL8723A = BIT(3), ++ ODM_RTL8188E = BIT(4), ++ ODM_RTL8812 = BIT(5), ++ ODM_RTL8821 = BIT(6), ++}; ++ ++#define ODM_IC_11N_SERIES \ ++ (ODM_RTL8192S | ODM_RTL8192C | ODM_RTL8192D | \ ++ ODM_RTL8723A | ODM_RTL8188E) ++#define ODM_IC_11AC_SERIES (ODM_RTL8812) ++ ++/* ODM_CMNINFO_CUT_VER */ ++enum odm_cut_version { ++ ODM_CUT_A = 1, ++ ODM_CUT_B = 2, ++ ODM_CUT_C = 3, ++ ODM_CUT_D = 4, ++ ODM_CUT_E = 5, ++ ODM_CUT_F = 6, ++ ODM_CUT_TEST = 7, ++}; ++ ++/* ODM_CMNINFO_FAB_VER */ ++enum odm_fab_Version { ++ ODM_TSMC = 0, ++ ODM_UMC = 1, ++}; ++ ++/* ODM_CMNINFO_RF_TYPE */ ++/* For example 1T2R (A+AB = BIT(0)|BIT(4)|BIT(5)) */ ++enum odm_rf_path { ++ ODM_RF_TX_A = BIT(0), ++ ODM_RF_TX_B = BIT(1), ++ ODM_RF_TX_C = BIT(2), ++ ODM_RF_TX_D = BIT(3), ++ ODM_RF_RX_A = BIT(4), ++ ODM_RF_RX_B = BIT(5), ++ ODM_RF_RX_C = BIT(6), ++ ODM_RF_RX_D = BIT(7), ++}; ++ ++enum odm_rf_type { ++ ODM_1T1R = 0, ++ ODM_1T2R = 1, ++ ODM_2T2R = 2, ++ ODM_2T3R = 3, ++ ODM_2T4R = 4, ++ ODM_3T3R = 5, ++ ODM_3T4R = 6, ++ ODM_4T4R = 7, ++}; ++ ++/* ODM Dynamic common info value definition */ ++ ++enum odm_mac_phy_mode { ++ ODM_SMSP = 0, ++ ODM_DMSP = 1, ++ ODM_DMDP = 2, ++}; ++ ++enum odm_bt_coexist { ++ ODM_BT_BUSY = 1, ++ ODM_BT_ON = 2, ++ ODM_BT_OFF = 3, ++ ODM_BT_NONE = 4, ++}; ++ ++/* ODM_CMNINFO_OP_MODE */ ++enum odm_operation_mode { ++ ODM_NO_LINK = BIT(0), ++ ODM_LINK = BIT(1), ++ ODM_SCAN = BIT(2), ++ ODM_POWERSAVE = BIT(3), ++ ODM_AP_MODE = BIT(4), ++ ODM_CLIENT_MODE = BIT(5), ++ ODM_AD_HOC = BIT(6), ++ ODM_WIFI_DIRECT = BIT(7), ++ ODM_WIFI_DISPLAY = BIT(8), ++}; ++ ++/* ODM_CMNINFO_WM_MODE */ ++enum odm_wireless_mode { ++ ODM_WM_UNKNOW = 0x0, ++ ODM_WM_B = BIT(0), ++ ODM_WM_G = BIT(1), ++ ODM_WM_N24G = BIT(3), ++ ODM_WM_AUTO = BIT(5), ++}; ++ ++/* ODM_CMNINFO_BAND */ ++enum odm_band_type { ++ ODM_BAND_2_4G = BIT(0), ++}; ++ ++/* ODM_CMNINFO_SEC_CHNL_OFFSET */ ++enum odm_sec_chnl_offset { ++ ODM_DONT_CARE = 0, ++ ODM_BELOW = 1, ++ ODM_ABOVE = 2 ++}; ++ ++/* ODM_CMNINFO_SEC_MODE */ ++enum odm_security { ++ ODM_SEC_OPEN = 0, ++ ODM_SEC_WEP40 = 1, ++ ODM_SEC_TKIP = 2, ++ ODM_SEC_RESERVE = 3, ++ ODM_SEC_AESCCMP = 4, ++ ODM_SEC_WEP104 = 5, ++ ODM_WEP_WPA_MIXED = 6, /* WEP + WPA */ ++ ODM_SEC_SMS4 = 7, ++}; ++ ++/* ODM_CMNINFO_BW */ ++enum odm_bw { ++ ODM_BW20M = 0, ++ ODM_BW40M = 1, ++}; ++ ++/* ODM_CMNINFO_BOARD_TYPE */ ++enum odm_board_type { ++ ODM_BOARD_NORMAL = 0, ++ ODM_BOARD_HIGHPWR = 1, ++ ODM_BOARD_MINICARD = 2, ++ ODM_BOARD_SLIM = 3, ++ ODM_BOARD_COMBO = 4, ++}; ++ ++/* ODM_CMNINFO_ONE_PATH_CCA */ ++enum odm_cca_path { ++ ODM_CCA_2R = 0, ++ ODM_CCA_1R_A = 1, ++ ODM_CCA_1R_B = 2, ++}; ++ ++struct odm_ra_info { ++ u8 RateID; ++ u32 RateMask; ++ u32 RAUseRate; ++ u8 RateSGI; ++ u8 RssiStaRA; ++ u8 PreRssiStaRA; ++ u8 SGIEnable; ++ u8 DecisionRate; ++ u8 PreRate; ++ u8 HighestRate; ++ u8 LowestRate; ++ u32 NscUp; ++ u32 NscDown; ++ u16 RTY[5]; ++ u32 TOTAL; ++ u16 DROP; ++ u8 Active; ++ u16 RptTime; ++ u8 RAWaitingCounter; ++ u8 RAPendingCounter; ++ u8 PTActive; /* on or off */ ++ u8 PTTryState; /* 0 trying state, 1 for decision state */ ++ u8 PTStage; /* 0~6 */ ++ u8 PTStopCount; /* Stop PT counter */ ++ u8 PTPreRate; /* if rate change do PT */ ++ u8 PTPreRssi; /* if RSSI change 5% do PT */ ++ u8 PTModeSS; /* decide whitch rate should do PT */ ++ u8 RAstage; /* StageRA, decide how many times RA will be done ++ * between PT */ ++ u8 PTSmoothFactor; ++}; ++ ++struct ijk_matrix_regs_set { ++ bool bIQKDone; ++ s32 Value[1][IQK_Matrix_REG_NUM]; ++}; ++ ++struct odm_rf_cal { ++ /* for tx power tracking */ ++ u32 RegA24; /* for TempCCK */ ++ s32 RegE94; ++ s32 RegE9C; ++ s32 RegEB4; ++ s32 RegEBC; ++ ++ u8 TXPowercount; ++ bool bTXPowerTrackingInit; ++ bool bTXPowerTracking; ++ u8 TxPowerTrackControl; /* for mp mode, turn off txpwrtracking ++ * as default */ ++ u8 TM_Trigger; ++ u8 InternalPA5G[2]; /* pathA / pathB */ ++ ++ u8 ThermalMeter[2]; /* ThermalMeter, index 0 for RFIC0, ++ * and 1 for RFIC1 */ ++ u8 ThermalValue; ++ u8 ThermalValue_LCK; ++ u8 ThermalValue_IQK; ++ u8 ThermalValue_DPK; ++ u8 ThermalValue_AVG[AVG_THERMAL_NUM]; ++ u8 ThermalValue_AVG_index; ++ u8 ThermalValue_RxGain; ++ u8 ThermalValue_Crystal; ++ u8 ThermalValue_DPKstore; ++ u8 ThermalValue_DPKtrack; ++ bool TxPowerTrackingInProgress; ++ bool bDPKenable; ++ ++ bool bReloadtxpowerindex; ++ u8 bRfPiEnable; ++ u32 TXPowerTrackingCallbackCnt; /* cosa add for debug */ ++ ++ u8 bCCKinCH14; ++ u8 CCK_index; ++ u8 OFDM_index[2]; ++ bool bDoneTxpower; ++ ++ u8 ThermalValue_HP[HP_THERMAL_NUM]; ++ u8 ThermalValue_HP_index; ++ struct ijk_matrix_regs_set IQKMatrixRegSetting[IQK_Matrix_Settings_NUM]; ++ ++ u8 Delta_IQK; ++ u8 Delta_LCK; ++ ++ /* for IQK */ ++ u32 RegC04; ++ u32 Reg874; ++ u32 RegC08; ++ u32 RegB68; ++ u32 RegB6C; ++ u32 Reg870; ++ u32 Reg860; ++ u32 Reg864; ++ ++ bool bIQKInitialized; ++ bool bLCKInProgress; ++ bool bAntennaDetected; ++ u32 ADDA_backup[IQK_ADDA_REG_NUM]; ++ u32 IQK_MAC_backup[IQK_MAC_REG_NUM]; ++ u32 IQK_BB_backup_recover[9]; ++ u32 IQK_BB_backup[IQK_BB_REG_NUM]; ++ ++ /* for APK */ ++ u32 APKoutput[2][2]; /* path A/B; output1_1a/output1_2a */ ++ u8 bAPKdone; ++ u8 bAPKThermalMeterIgnore; ++ u8 bDPdone; ++ u8 bDPPathAOK; ++ u8 bDPPathBOK; ++}; ++ ++/* ODM Dynamic common info value definition */ ++ ++struct fast_ant_train { ++ u8 Bssid[6]; ++ u8 antsel_rx_keep_0; ++ u8 antsel_rx_keep_1; ++ u8 antsel_rx_keep_2; ++ u32 antSumRSSI[7]; ++ u32 antRSSIcnt[7]; ++ u32 antAveRSSI[7]; ++ u8 FAT_State; ++ u32 TrainIdx; ++ u8 antsel_a[ODM_ASSOCIATE_ENTRY_NUM]; ++ u8 antsel_b[ODM_ASSOCIATE_ENTRY_NUM]; ++ u8 antsel_c[ODM_ASSOCIATE_ENTRY_NUM]; ++ u32 MainAnt_Sum[ODM_ASSOCIATE_ENTRY_NUM]; ++ u32 AuxAnt_Sum[ODM_ASSOCIATE_ENTRY_NUM]; ++ u32 MainAnt_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; ++ u32 AuxAnt_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; ++ u8 RxIdleAnt; ++ bool bBecomeLinked; ++}; ++ ++enum fat_state { ++ FAT_NORMAL_STATE = 0, ++ FAT_TRAINING_STATE = 1, ++}; ++ ++enum ant_div_type { ++ NO_ANTDIV = 0xFF, ++ CG_TRX_HW_ANTDIV = 0x01, ++ CGCS_RX_HW_ANTDIV = 0x02, ++ FIXED_HW_ANTDIV = 0x03, ++ CG_TRX_SMART_ANTDIV = 0x04, ++ CGCS_RX_SW_ANTDIV = 0x05, ++}; ++ ++/* Copy from SD4 defined structure. We use to support PHY DM integration. */ ++struct odm_dm_struct { ++ /* Add for different team use temporarily */ ++ struct adapter *Adapter; /* For CE/NIC team */ ++ struct rtl8192cd_priv *priv; /* For AP/ADSL team */ ++ /* WHen you use above pointers, they must be initialized. */ ++ bool odm_ready; ++ ++ struct rtl8192cd_priv *fake_priv; ++ ++/* ODM HANDLE, DRIVER NEEDS NOT TO HOOK------ */ ++ bool bCckHighPower; ++ u8 RFPathRxEnable; /* ODM_CMNINFO_RFPATH_ENABLE */ ++ u8 ControlChannel; ++/* ODM HANDLE, DRIVER NEEDS NOT TO HOOK------ */ ++ ++/* 1 COMMON INFORMATION */ ++ /* Init Value */ ++/* HOOK BEFORE REG INIT----------- */ ++ /* ODM Platform info AP/ADSL/CE/MP = 1/2/3/4 */ ++ u8 SupportPlatform; ++ /* ODM Support Ability DIG/RATR/TX_PWR_TRACK/ �K�K = 1/2/3/�K */ ++ u32 SupportAbility; ++ /* ODM PCIE/USB/SDIO/GSPI = 0/1/2/3 */ ++ u8 SupportInterface; ++ /* ODM composite or independent. Bit oriented/ 92C+92D+ .... or any ++ * other type = 1/2/3/... */ ++ u32 SupportICType; ++ /* Cut Version TestChip/A-cut/B-cut... = 0/1/2/3/... */ ++ u8 CutVersion; ++ /* Fab Version TSMC/UMC = 0/1 */ ++ u8 FabVersion; ++ /* RF Type 4T4R/3T3R/2T2R/1T2R/1T1R/... */ ++ u8 RFType; ++ /* Board Type Normal/HighPower/MiniCard/SLIM/Combo/. = 0/1/2/3/4/. */ ++ u8 BoardType; ++ /* with external LNA NO/Yes = 0/1 */ ++ u8 ExtLNA; ++ /* with external PA NO/Yes = 0/1 */ ++ u8 ExtPA; ++ /* with external TRSW NO/Yes = 0/1 */ ++ u8 ExtTRSW; ++ u8 PatchID; /* Customer ID */ ++ bool bInHctTest; ++ bool bWIFITest; ++ ++ bool bDualMacSmartConcurrent; ++ u32 BK_SupportAbility; ++ u8 AntDivType; ++/* HOOK BEFORE REG INIT----------- */ ++ ++ /* Dynamic Value */ ++/* POINTER REFERENCE----------- */ ++ ++ u8 u8_temp; ++ bool bool_temp; ++ struct adapter *adapter_temp; ++ ++ /* MAC PHY Mode SMSP/DMSP/DMDP = 0/1/2 */ ++ u8 *pMacPhyMode; ++ /* TX Unicast byte count */ ++ u64 *pNumTxBytesUnicast; ++ /* RX Unicast byte count */ ++ u64 *pNumRxBytesUnicast; ++ /* Wireless mode B/G/A/N = BIT(0)/BIT(1)/BIT(2)/BIT(3) */ ++ u8 *pWirelessMode; /* ODM_WIRELESS_MODE_E */ ++ /* Frequence band 2.4G/5G = 0/1 */ ++ u8 *pBandType; ++ /* Secondary channel offset don't_care/below/above = 0/1/2 */ ++ u8 *pSecChOffset; ++ /* Security mode Open/WEP/AES/TKIP = 0/1/2/3 */ ++ u8 *pSecurity; ++ /* BW info 20M/40M/80M = 0/1/2 */ ++ u8 *pBandWidth; ++ /* Central channel location Ch1/Ch2/.... */ ++ u8 *pChannel; /* central channel number */ ++ /* Common info for 92D DMSP */ ++ ++ bool *pbGetValueFromOtherMac; ++ struct adapter **pBuddyAdapter; ++ bool *pbMasterOfDMSP; /* MAC0: master, MAC1: slave */ ++ /* Common info for Status */ ++ bool *pbScanInProcess; ++ bool *pbPowerSaving; ++ /* CCA Path 2-path/path-A/path-B = 0/1/2; using ODM_CCA_PATH_E. */ ++ u8 *pOnePathCCA; ++ /* pMgntInfo->AntennaTest */ ++ u8 *pAntennaTest; ++ bool *pbNet_closed; ++/* POINTER REFERENCE----------- */ ++ /* */ ++/* CALL BY VALUE------------- */ ++ bool bWIFI_Direct; ++ bool bWIFI_Display; ++ bool bLinked; ++ u8 RSSI_Min; ++ u8 InterfaceIndex; /* Add for 92D dual MAC: 0--Mac0 1--Mac1 */ ++ bool bIsMPChip; ++ bool bOneEntryOnly; ++ /* Common info for BTDM */ ++ bool bBtDisabled; /* BT is disabled */ ++ bool bBtHsOperation; /* BT HS mode is under progress */ ++ u8 btHsDigVal; /* use BT rssi to decide the DIG value */ ++ bool bBtDisableEdcaTurbo;/* Under some condition, don't enable the ++ * EDCA Turbo */ ++ bool bBtBusy; /* BT is busy. */ ++/* CALL BY VALUE------------- */ ++ ++ /* 2 Define STA info. */ ++ /* _ODM_STA_INFO */ ++ /* For MP, we need to reduce one array pointer for default port.?? */ ++ struct sta_info *pODM_StaInfo[ODM_ASSOCIATE_ENTRY_NUM]; ++ ++ u16 CurrminRptTime; ++ struct odm_ra_info RAInfo[ODM_ASSOCIATE_ENTRY_NUM]; /* Use MacID as ++ * array index. STA MacID=0, ++ * VWiFi Client MacID={1, ODM_ASSOCIATE_ENTRY_NUM-1} */ ++ /* */ ++ /* 2012/02/14 MH Add to share 88E ra with other SW team. */ ++ /* We need to colelct all support abilit to a proper area. */ ++ /* */ ++ bool RaSupport88E; ++ ++ /* Define ........... */ ++ ++ /* Latest packet phy info (ODM write) */ ++ struct odm_phy_dbg_info PhyDbgInfo; ++ ++ /* Latest packet phy info (ODM write) */ ++ struct odm_mac_status_info *pMacInfo; ++ ++ /* Different Team independt structure?? */ ++ ++ /* ODM Structure */ ++ struct fast_ant_train DM_FatTable; ++ struct rtw_dig DM_DigTable; ++ struct rtl_ps DM_PSTable; ++ struct dyn_primary_cca DM_PriCCA; ++ struct rx_hpc DM_RXHP_Table; ++ struct false_alarm_stats FalseAlmCnt; ++ struct false_alarm_stats FlaseAlmCntBuddyAdapter; ++ struct sw_ant_switch DM_SWAT_Table; ++ bool RSSI_test; ++ ++ struct edca_turbo DM_EDCA_Table; ++ u32 WMMEDCA_BE; ++ /* Copy from SD4 structure */ ++ /* */ ++ /* ================================================== */ ++ /* */ ++ ++ bool *pbDriverStopped; ++ bool *pbDriverIsGoingToPnpSetPowerSleep; ++ bool *pinit_adpt_in_progress; ++ ++ /* PSD */ ++ bool bUserAssignLevel; ++ struct timer_list PSDTimer; ++ u8 RSSI_BT; /* come from BT */ ++ bool bPSDinProcess; ++ bool bDMInitialGainEnable; ++ ++ /* for rate adaptive, in fact, 88c/92c fw will handle this */ ++ u8 bUseRAMask; ++ ++ struct odm_rate_adapt RateAdaptive; ++ ++ struct odm_rf_cal RFCalibrateInfo; ++ ++ /* TX power tracking */ ++ u8 BbSwingIdxOfdm; ++ u8 BbSwingIdxOfdmCurrent; ++ u8 BbSwingIdxOfdmBase; ++ bool BbSwingFlagOfdm; ++ u8 BbSwingIdxCck; ++ u8 BbSwingIdxCckCurrent; ++ u8 BbSwingIdxCckBase; ++ bool BbSwingFlagCck; ++ u8 *mp_mode; ++ /* ODM system resource. */ ++ ++ /* ODM relative time. */ ++ struct timer_list PathDivSwitchTimer; ++ /* 2011.09.27 add for Path Diversity */ ++ struct timer_list CCKPathDiversityTimer; ++ struct timer_list FastAntTrainingTimer; ++}; /* DM_Dynamic_Mechanism_Structure */ ++ ++enum ODM_RF_CONTENT { ++ odm_radioa_txt = 0x1000, ++ odm_radiob_txt = 0x1001, ++ odm_radioc_txt = 0x1002, ++ odm_radiod_txt = 0x1003 ++}; ++ ++enum odm_bb_config_type { ++ CONFIG_BB_PHY_REG, ++ CONFIG_BB_AGC_TAB, ++ CONFIG_BB_AGC_TAB_2G, ++ CONFIG_BB_PHY_REG_PG, ++}; ++ ++/* Status code */ ++enum rt_status { ++ RT_STATUS_SUCCESS, ++ RT_STATUS_FAILURE, ++ RT_STATUS_PENDING, ++ RT_STATUS_RESOURCE, ++ RT_STATUS_INVALID_CONTEXT, ++ RT_STATUS_INVALID_PARAMETER, ++ RT_STATUS_NOT_SUPPORT, ++ RT_STATUS_OS_API_FAILED, ++}; ++ ++/* 3=========================================================== */ ++/* 3 DIG */ ++/* 3=========================================================== */ ++ ++enum dm_dig_op { ++ RT_TYPE_THRESH_HIGH = 0, ++ RT_TYPE_THRESH_LOW = 1, ++ RT_TYPE_BACKOFF = 2, ++ RT_TYPE_RX_GAIN_MIN = 3, ++ RT_TYPE_RX_GAIN_MAX = 4, ++ RT_TYPE_ENABLE = 5, ++ RT_TYPE_DISABLE = 6, ++ DIG_OP_TYPE_MAX ++}; ++ ++#define DM_DIG_THRESH_HIGH 40 ++#define DM_DIG_THRESH_LOW 35 ++ ++#define DM_SCAN_RSSI_TH 0x14 /* scan return issue for LC */ ++ ++#define DM_false_ALARM_THRESH_LOW 400 ++#define DM_false_ALARM_THRESH_HIGH 1000 ++ ++#define DM_DIG_MAX_NIC 0x4e ++#define DM_DIG_MIN_NIC 0x1e /* 0x22/0x1c */ ++ ++#define DM_DIG_MAX_AP 0x32 ++#define DM_DIG_MIN_AP 0x20 ++ ++#define DM_DIG_MAX_NIC_HP 0x46 ++#define DM_DIG_MIN_NIC_HP 0x2e ++ ++#define DM_DIG_MAX_AP_HP 0x42 ++#define DM_DIG_MIN_AP_HP 0x30 ++ ++/* vivi 92c&92d has different definition, 20110504 */ ++/* this is for 92c */ ++#define DM_DIG_FA_TH0 0x200/* 0x20 */ ++#define DM_DIG_FA_TH1 0x300/* 0x100 */ ++#define DM_DIG_FA_TH2 0x400/* 0x200 */ ++/* this is for 92d */ ++#define DM_DIG_FA_TH0_92D 0x100 ++#define DM_DIG_FA_TH1_92D 0x400 ++#define DM_DIG_FA_TH2_92D 0x600 ++ ++#define DM_DIG_BACKOFF_MAX 12 ++#define DM_DIG_BACKOFF_MIN -4 ++#define DM_DIG_BACKOFF_DEFAULT 10 ++ ++/* 3=========================================================== */ ++/* 3 AGC RX High Power Mode */ ++/* 3=========================================================== */ ++#define LNA_Low_Gain_1 0x64 ++#define LNA_Low_Gain_2 0x5A ++#define LNA_Low_Gain_3 0x58 ++ ++#define FA_RXHP_TH1 5000 ++#define FA_RXHP_TH2 1500 ++#define FA_RXHP_TH3 800 ++#define FA_RXHP_TH4 600 ++#define FA_RXHP_TH5 500 ++ ++/* 3=========================================================== */ ++/* 3 EDCA */ ++/* 3=========================================================== */ ++ ++/* 3=========================================================== */ ++/* 3 Dynamic Tx Power */ ++/* 3=========================================================== */ ++/* Dynamic Tx Power Control Threshold */ ++#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 ++#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 ++#define TX_POWER_NEAR_FIELD_THRESH_AP 0x3F ++ ++#define TxHighPwrLevel_Normal 0 ++#define TxHighPwrLevel_Level1 1 ++#define TxHighPwrLevel_Level2 2 ++#define TxHighPwrLevel_BT1 3 ++#define TxHighPwrLevel_BT2 4 ++#define TxHighPwrLevel_15 5 ++#define TxHighPwrLevel_35 6 ++#define TxHighPwrLevel_50 7 ++#define TxHighPwrLevel_70 8 ++#define TxHighPwrLevel_100 9 ++ ++/* 3=========================================================== */ ++/* 3 Rate Adaptive */ ++/* 3=========================================================== */ ++#define DM_RATR_STA_INIT 0 ++#define DM_RATR_STA_HIGH 1 ++#define DM_RATR_STA_MIDDLE 2 ++#define DM_RATR_STA_LOW 3 ++ ++/* 3=========================================================== */ ++/* 3 BB Power Save */ ++/* 3=========================================================== */ ++ ++enum dm_1r_cca { ++ CCA_1R = 0, ++ CCA_2R = 1, ++ CCA_MAX = 2, ++}; ++ ++enum dm_rf { ++ RF_Save = 0, ++ RF_Normal = 1, ++ RF_MAX = 2, ++}; ++ ++/* 3=========================================================== */ ++/* 3 Antenna Diversity */ ++/* 3=========================================================== */ ++enum dm_swas { ++ Antenna_A = 1, ++ Antenna_B = 2, ++ Antenna_MAX = 3, ++}; ++ ++/* Maximal number of antenna detection mechanism needs to perform. */ ++#define MAX_ANTENNA_DETECTION_CNT 10 ++ ++/* Extern Global Variables. */ ++#define OFDM_TABLE_SIZE_92C 37 ++#define OFDM_TABLE_SIZE_92D 43 ++#define CCK_TABLE_SIZE 33 ++ ++extern u32 OFDMSwingTable[OFDM_TABLE_SIZE_92D]; ++extern u8 CCKSwingTable_Ch1_Ch13[CCK_TABLE_SIZE][8]; ++extern u8 CCKSwingTable_Ch14 [CCK_TABLE_SIZE][8]; ++ ++/* check Sta pointer valid or not */ ++#define IS_STA_VALID(pSta) (pSta) ++/* 20100514 Joseph: Add definition for antenna switching test after link. */ ++/* This indicates two different the steps. */ ++/* In SWAW_STEP_PEAK, driver needs to switch antenna and listen to the ++ * signal on the air. */ ++/* In SWAW_STEP_DETERMINE, driver just compares the signal captured in ++ * SWAW_STEP_PEAK */ ++/* with original RSSI to determine if it is necessary to switch antenna. */ ++#define SWAW_STEP_PEAK 0 ++#define SWAW_STEP_DETERMINE 1 ++ ++void ODM_Write_DIG(struct odm_dm_struct *pDM_Odm, u8 CurrentIGI); ++void ODM_Write_CCK_CCA_Thres(struct odm_dm_struct *pDM_Odm, u8 CurCCK_CCAThres); ++ ++void ODM_SetAntenna(struct odm_dm_struct *pDM_Odm, u8 Antenna); ++ ++#define dm_RF_Saving ODM_RF_Saving ++void ODM_RF_Saving(struct odm_dm_struct *pDM_Odm, u8 bForceInNormal); ++ ++#define SwAntDivRestAfterLink ODM_SwAntDivRestAfterLink ++void ODM_SwAntDivRestAfterLink(struct odm_dm_struct *pDM_Odm); ++ ++#define dm_CheckTXPowerTracking ODM_TXPowerTrackingCheck ++void ODM_TXPowerTrackingCheck(struct odm_dm_struct *pDM_Odm); ++ ++bool ODM_RAStateCheck(struct odm_dm_struct *pDM_Odm, s32 RSSI, ++ bool bForceUpdate, u8 *pRATRState); ++ ++#define dm_SWAW_RSSI_Check ODM_SwAntDivChkPerPktRssi ++void ODM_SwAntDivChkPerPktRssi(struct odm_dm_struct *pDM_Odm, u8 StationID, ++ struct odm_phy_status_info *pPhyInfo); ++ ++u32 ConvertTo_dB(u32 Value); ++ ++u32 GetPSDData(struct odm_dm_struct *pDM_Odm, unsigned int point, ++ u8 initial_gain_psd); ++ ++void odm_DIGbyRSSI_LPS(struct odm_dm_struct *pDM_Odm); ++ ++u32 ODM_Get_Rate_Bitmap(struct odm_dm_struct *pDM_Odm, u32 macid, ++ u32 ra_mask, u8 rssi_level); ++ ++void ODM_DMInit(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_DMWatchdog(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_CmnInfoInit(struct odm_dm_struct *pDM_Odm, ++ enum odm_common_info_def CmnInfo, u32 Value); ++ ++void ODM_CmnInfoHook(struct odm_dm_struct *pDM_Odm, ++ enum odm_common_info_def CmnInfo, void *pValue); ++ ++void ODM_CmnInfoPtrArrayHook(struct odm_dm_struct *pDM_Odm, ++ enum odm_common_info_def CmnInfo, ++ u16 Index, void *pValue); ++ ++void ODM_CmnInfoUpdate(struct odm_dm_struct *pDM_Odm, u32 CmnInfo, u64 Value); ++ ++void ODM_InitAllTimers(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_CancelAllTimers(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_ReleaseAllTimers(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_AntselStatistics_88C(struct odm_dm_struct *pDM_Odm, u8 MacId, ++ u32 PWDBAll, bool isCCKrate); ++ ++void ODM_SingleDualAntennaDefaultSetting(struct odm_dm_struct *pDM_Odm); ++ ++bool ODM_SingleDualAntennaDetection(struct odm_dm_struct *pDM_Odm, u8 mode); ++ ++void odm_dtc(struct odm_dm_struct *pDM_Odm); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/odm_HWConfig.h b/drivers/staging/r8188eu/include/odm_HWConfig.h +new file mode 100644 +index 000000000000..9b2ab3bcf992 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_HWConfig.h +@@ -0,0 +1,116 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __HALHWOUTSRC_H__ ++#define __HALHWOUTSRC_H__ ++ ++/* Definition */ ++/* CCK Rates, TxHT = 0 */ ++#define DESC92C_RATE1M 0x00 ++#define DESC92C_RATE2M 0x01 ++#define DESC92C_RATE5_5M 0x02 ++#define DESC92C_RATE11M 0x03 ++ ++/* OFDM Rates, TxHT = 0 */ ++#define DESC92C_RATE6M 0x04 ++#define DESC92C_RATE9M 0x05 ++#define DESC92C_RATE12M 0x06 ++#define DESC92C_RATE18M 0x07 ++#define DESC92C_RATE24M 0x08 ++#define DESC92C_RATE36M 0x09 ++#define DESC92C_RATE48M 0x0a ++#define DESC92C_RATE54M 0x0b ++ ++/* MCS Rates, TxHT = 1 */ ++#define DESC92C_RATEMCS0 0x0c ++#define DESC92C_RATEMCS1 0x0d ++#define DESC92C_RATEMCS2 0x0e ++#define DESC92C_RATEMCS3 0x0f ++#define DESC92C_RATEMCS4 0x10 ++#define DESC92C_RATEMCS5 0x11 ++#define DESC92C_RATEMCS6 0x12 ++#define DESC92C_RATEMCS7 0x13 ++#define DESC92C_RATEMCS8 0x14 ++#define DESC92C_RATEMCS9 0x15 ++#define DESC92C_RATEMCS10 0x16 ++#define DESC92C_RATEMCS11 0x17 ++#define DESC92C_RATEMCS12 0x18 ++#define DESC92C_RATEMCS13 0x19 ++#define DESC92C_RATEMCS14 0x1a ++#define DESC92C_RATEMCS15 0x1b ++#define DESC92C_RATEMCS15_SG 0x1c ++#define DESC92C_RATEMCS32 0x20 ++ ++/* structure and define */ ++ ++struct phy_rx_agc_info { ++ #ifdef __LITTLE_ENDIAN ++ u8 gain:7, trsw:1; ++ #else ++ u8 trsw:1, gain:7; ++ #endif ++}; ++ ++struct phy_status_rpt { ++ struct phy_rx_agc_info path_agc[3]; ++ u8 ch_corr[2]; ++ u8 cck_sig_qual_ofdm_pwdb_all; ++ u8 cck_agc_rpt_ofdm_cfosho_a; ++ u8 cck_rpt_b_ofdm_cfosho_b; ++ u8 rsvd_1;/* ch_corr_msb; */ ++ u8 noise_power_db_msb; ++ u8 path_cfotail[2]; ++ u8 pcts_mask[2]; ++ s8 stream_rxevm[2]; ++ u8 path_rxsnr[3]; ++ u8 noise_power_db_lsb; ++ u8 rsvd_2[3]; ++ u8 stream_csi[2]; ++ u8 stream_target_csi[2]; ++ s8 sig_evm; ++ u8 rsvd_3; ++ ++#ifdef __LITTLE_ENDIAN ++ u8 antsel_rx_keep_2:1; /* ex_intf_flg:1; */ ++ u8 sgi_en:1; ++ u8 rxsc:2; ++ u8 idle_long:1; ++ u8 r_ant_train_en:1; ++ u8 ant_sel_b:1; ++ u8 ant_sel:1; ++#else /* _BIG_ENDIAN_ */ ++ u8 ant_sel:1; ++ u8 ant_sel_b:1; ++ u8 r_ant_train_en:1; ++ u8 idle_long:1; ++ u8 rxsc:2; ++ u8 sgi_en:1; ++ u8 antsel_rx_keep_2:1; /* ex_intf_flg:1; */ ++#endif ++}; ++ ++void odm_Init_RSSIForDM(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_PhyStatusQuery(struct odm_dm_struct *pDM_Odm, ++ struct odm_phy_status_info *pPhyInfo, ++ u8 *pPhyStatus, ++ struct odm_per_pkt_info *pPktinfo, ++ struct adapter *adapt); ++ ++void ODM_MacStatusQuery(struct odm_dm_struct *pDM_Odm, ++ u8 *pMacStatus, ++ u8 MacID, ++ bool bPacketMatchBSSID, ++ bool bPacketToSelf, ++ bool bPacketBeacon); ++ ++enum HAL_STATUS ODM_ConfigRFWithHeaderFile(struct odm_dm_struct *pDM_Odm, ++ enum rf_radio_path Content, ++ enum rf_radio_path eRFPath); ++ ++enum HAL_STATUS ODM_ConfigBBWithHeaderFile(struct odm_dm_struct *pDM_Odm, ++ enum odm_bb_config_type ConfigType); ++ ++enum HAL_STATUS ODM_ConfigMACWithHeaderFile(struct odm_dm_struct *pDM_Odm); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/odm_RTL8188E.h b/drivers/staging/r8188eu/include/odm_RTL8188E.h +new file mode 100644 +index 000000000000..00d2678532f8 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_RTL8188E.h +@@ -0,0 +1,36 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __ODM_RTL8188E_H__ ++#define __ODM_RTL8188E_H__ ++ ++#define MAIN_ANT 0 ++#define AUX_ANT 1 ++#define MAIN_ANT_CG_TRX 1 ++#define AUX_ANT_CG_TRX 0 ++#define MAIN_ANT_CGCS_RX 0 ++#define AUX_ANT_CGCS_RX 1 ++ ++void ODM_DIG_LowerBound_88E(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_AntennaDiversityInit_88E(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_AntennaDiversity_88E(struct odm_dm_struct *pDM_Odm); ++ ++void ODM_SetTxAntByTxInfo_88E(struct odm_dm_struct *pDM_Odm, u8 *pDesc, ++ u8 macId); ++ ++void ODM_UpdateRxIdleAnt_88E(struct odm_dm_struct *pDM_Odm, u8 Ant); ++ ++void ODM_AntselStatistics_88E(struct odm_dm_struct *pDM_Odm, u8 antsel_tr_mux, ++ u32 MacId, u8 RxPWDBAll); ++ ++void odm_FastAntTraining(struct odm_dm_struct *pDM_Odm); ++ ++void odm_FastAntTrainingCallback(struct odm_dm_struct *pDM_Odm); ++ ++void odm_FastAntTrainingWorkItemCallback(struct odm_dm_struct *pDM_Odm); ++ ++void odm_PrimaryCCA_Init(struct odm_dm_struct *pDM_Odm); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/odm_RegConfig8188E.h b/drivers/staging/r8188eu/include/odm_RegConfig8188E.h +new file mode 100644 +index 000000000000..86b5b2d24210 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_RegConfig8188E.h +@@ -0,0 +1,27 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __INC_ODM_REGCONFIG_H_8188E ++#define __INC_ODM_REGCONFIG_H_8188E ++ ++void odm_ConfigRFReg_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Data, ++ enum rf_radio_path RF_PATH, u32 RegAddr); ++ ++void odm_ConfigRF_RadioA_8188E(struct odm_dm_struct *pDM_Odm, ++ u32 Addr, u32 Data); ++ ++void odm_ConfigRF_RadioB_8188E(struct odm_dm_struct *pDM_Odm, ++ u32 Addr, u32 Data); ++ ++void odm_ConfigMAC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u8 Data); ++ ++void odm_ConfigBB_AGC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, ++ u32 Bitmask, u32 Data); ++ ++void odm_ConfigBB_PHY_REG_PG_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, ++ u32 Bitmask, u32 Data); ++ ++void odm_ConfigBB_PHY_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, ++ u32 Bitmask, u32 Data); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/odm_RegDefine11AC.h b/drivers/staging/r8188eu/include/odm_RegDefine11AC.h +new file mode 100644 +index 000000000000..bba7511cf244 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_RegDefine11AC.h +@@ -0,0 +1,29 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __ODM_REGDEFINE11AC_H__ ++#define __ODM_REGDEFINE11AC_H__ ++ ++/* 2 RF REG LIST */ ++ ++/* 2 BB REG LIST */ ++/* PAGE 8 */ ++/* PAGE 9 */ ++#define ODM_REG_OFDM_FA_RST_11AC 0x9A4 ++/* PAGE A */ ++#define ODM_REG_CCK_CCA_11AC 0xA0A ++#define ODM_REG_CCK_FA_RST_11AC 0xA2C ++#define ODM_REG_CCK_FA_11AC 0xA5C ++/* PAGE C */ ++#define ODM_REG_IGI_A_11AC 0xC50 ++/* PAGE E */ ++#define ODM_REG_IGI_B_11AC 0xE50 ++/* PAGE F */ ++#define ODM_REG_OFDM_FA_11AC 0xF48 ++ ++/* 2 MAC REG LIST */ ++ ++/* DIG Related */ ++#define ODM_BIT_IGI_11AC 0xFFFFFFFF ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/odm_RegDefine11N.h b/drivers/staging/r8188eu/include/odm_RegDefine11N.h +new file mode 100644 +index 000000000000..5d1d73490c1c +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_RegDefine11N.h +@@ -0,0 +1,143 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __ODM_REGDEFINE11N_H__ ++#define __ODM_REGDEFINE11N_H__ ++ ++/* 2 RF REG LIST */ ++#define ODM_REG_RF_MODE_11N 0x00 ++#define ODM_REG_RF_0B_11N 0x0B ++#define ODM_REG_CHNBW_11N 0x18 ++#define ODM_REG_T_METER_11N 0x24 ++#define ODM_REG_RF_25_11N 0x25 ++#define ODM_REG_RF_26_11N 0x26 ++#define ODM_REG_RF_27_11N 0x27 ++#define ODM_REG_RF_2B_11N 0x2B ++#define ODM_REG_RF_2C_11N 0x2C ++#define ODM_REG_RXRF_A3_11N 0x3C ++#define ODM_REG_T_METER_92D_11N 0x42 ++#define ODM_REG_T_METER_88E_11N 0x42 ++ ++/* 2 BB REG LIST */ ++/* PAGE 8 */ ++#define ODM_REG_BB_CTRL_11N 0x800 ++#define ODM_REG_RF_PIN_11N 0x804 ++#define ODM_REG_PSD_CTRL_11N 0x808 ++#define ODM_REG_TX_ANT_CTRL_11N 0x80C ++#define ODM_REG_BB_PWR_SAV5_11N 0x818 ++#define ODM_REG_CCK_RPT_FORMAT_11N 0x824 ++#define ODM_REG_RX_DEFUALT_A_11N 0x858 ++#define ODM_REG_RX_DEFUALT_B_11N 0x85A ++#define ODM_REG_BB_PWR_SAV3_11N 0x85C ++#define ODM_REG_ANTSEL_CTRL_11N 0x860 ++#define ODM_REG_RX_ANT_CTRL_11N 0x864 ++#define ODM_REG_PIN_CTRL_11N 0x870 ++#define ODM_REG_BB_PWR_SAV1_11N 0x874 ++#define ODM_REG_ANTSEL_PATH_11N 0x878 ++#define ODM_REG_BB_3WIRE_11N 0x88C ++#define ODM_REG_SC_CNT_11N 0x8C4 ++#define ODM_REG_PSD_DATA_11N 0x8B4 ++/* PAGE 9 */ ++#define ODM_REG_ANT_MAPPING1_11N 0x914 ++#define ODM_REG_ANT_MAPPING2_11N 0x918 ++/* PAGE A */ ++#define ODM_REG_CCK_ANTDIV_PARA1_11N 0xA00 ++#define ODM_REG_CCK_CCA_11N 0xA0A ++#define ODM_REG_CCK_ANTDIV_PARA2_11N 0xA0C ++#define ODM_REG_CCK_ANTDIV_PARA3_11N 0xA10 ++#define ODM_REG_CCK_ANTDIV_PARA4_11N 0xA14 ++#define ODM_REG_CCK_FILTER_PARA1_11N 0xA22 ++#define ODM_REG_CCK_FILTER_PARA2_11N 0xA23 ++#define ODM_REG_CCK_FILTER_PARA3_11N 0xA24 ++#define ODM_REG_CCK_FILTER_PARA4_11N 0xA25 ++#define ODM_REG_CCK_FILTER_PARA5_11N 0xA26 ++#define ODM_REG_CCK_FILTER_PARA6_11N 0xA27 ++#define ODM_REG_CCK_FILTER_PARA7_11N 0xA28 ++#define ODM_REG_CCK_FILTER_PARA8_11N 0xA29 ++#define ODM_REG_CCK_FA_RST_11N 0xA2C ++#define ODM_REG_CCK_FA_MSB_11N 0xA58 ++#define ODM_REG_CCK_FA_LSB_11N 0xA5C ++#define ODM_REG_CCK_CCA_CNT_11N 0xA60 ++#define ODM_REG_BB_PWR_SAV4_11N 0xA74 ++/* PAGE B */ ++#define ODM_REG_LNA_SWITCH_11N 0xB2C ++#define ODM_REG_PATH_SWITCH_11N 0xB30 ++#define ODM_REG_RSSI_CTRL_11N 0xB38 ++#define ODM_REG_CONFIG_ANTA_11N 0xB68 ++#define ODM_REG_RSSI_BT_11N 0xB9C ++/* PAGE C */ ++#define ODM_REG_OFDM_FA_HOLDC_11N 0xC00 ++#define ODM_REG_RX_PATH_11N 0xC04 ++#define ODM_REG_TRMUX_11N 0xC08 ++#define ODM_REG_OFDM_FA_RSTC_11N 0xC0C ++#define ODM_REG_RXIQI_MATRIX_11N 0xC14 ++#define ODM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C ++#define ODM_REG_IGI_A_11N 0xC50 ++#define ODM_REG_ANTDIV_PARA2_11N 0xC54 ++#define ODM_REG_IGI_B_11N 0xC58 ++#define ODM_REG_ANTDIV_PARA3_11N 0xC5C ++#define ODM_REG_BB_PWR_SAV2_11N 0xC70 ++#define ODM_REG_RX_OFF_11N 0xC7C ++#define ODM_REG_TXIQK_MATRIXA_11N 0xC80 ++#define ODM_REG_TXIQK_MATRIXB_11N 0xC88 ++#define ODM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94 ++#define ODM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C ++#define ODM_REG_RXIQK_MATRIX_LSB_11N 0xCA0 ++#define ODM_REG_ANTDIV_PARA1_11N 0xCA4 ++#define ODM_REG_OFDM_FA_TYPE1_11N 0xCF0 ++/* PAGE D */ ++#define ODM_REG_OFDM_FA_RSTD_11N 0xD00 ++#define ODM_REG_OFDM_FA_TYPE2_11N 0xDA0 ++#define ODM_REG_OFDM_FA_TYPE3_11N 0xDA4 ++#define ODM_REG_OFDM_FA_TYPE4_11N 0xDA8 ++/* PAGE E */ ++#define ODM_REG_TXAGC_A_6_18_11N 0xE00 ++#define ODM_REG_TXAGC_A_24_54_11N 0xE04 ++#define ODM_REG_TXAGC_A_1_MCS32_11N 0xE08 ++#define ODM_REG_TXAGC_A_MCS0_3_11N 0xE10 ++#define ODM_REG_TXAGC_A_MCS4_7_11N 0xE14 ++#define ODM_REG_TXAGC_A_MCS8_11_11N 0xE18 ++#define ODM_REG_TXAGC_A_MCS12_15_11N 0xE1C ++#define ODM_REG_FPGA0_IQK_11N 0xE28 ++#define ODM_REG_TXIQK_TONE_A_11N 0xE30 ++#define ODM_REG_RXIQK_TONE_A_11N 0xE34 ++#define ODM_REG_TXIQK_PI_A_11N 0xE38 ++#define ODM_REG_RXIQK_PI_A_11N 0xE3C ++#define ODM_REG_TXIQK_11N 0xE40 ++#define ODM_REG_RXIQK_11N 0xE44 ++#define ODM_REG_IQK_AGC_PTS_11N 0xE48 ++#define ODM_REG_IQK_AGC_RSP_11N 0xE4C ++#define ODM_REG_BLUETOOTH_11N 0xE6C ++#define ODM_REG_RX_WAIT_CCA_11N 0xE70 ++#define ODM_REG_TX_CCK_RFON_11N 0xE74 ++#define ODM_REG_TX_CCK_BBON_11N 0xE78 ++#define ODM_REG_OFDM_RFON_11N 0xE7C ++#define ODM_REG_OFDM_BBON_11N 0xE80 ++#define ODM_REG_TX2RX_11N 0xE84 ++#define ODM_REG_TX2TX_11N 0xE88 ++#define ODM_REG_RX_CCK_11N 0xE8C ++#define ODM_REG_RX_OFDM_11N 0xED0 ++#define ODM_REG_RX_WAIT_RIFS_11N 0xED4 ++#define ODM_REG_RX2RX_11N 0xED8 ++#define ODM_REG_STANDBY_11N 0xEDC ++#define ODM_REG_SLEEP_11N 0xEE0 ++#define ODM_REG_PMPD_ANAEN_11N 0xEEC ++ ++/* 2 MAC REG LIST */ ++#define ODM_REG_BB_RST_11N 0x02 ++#define ODM_REG_ANTSEL_PIN_11N 0x4C ++#define ODM_REG_EARLY_MODE_11N 0x4D0 ++#define ODM_REG_RSSI_MONITOR_11N 0x4FE ++#define ODM_REG_EDCA_VO_11N 0x500 ++#define ODM_REG_EDCA_VI_11N 0x504 ++#define ODM_REG_EDCA_BE_11N 0x508 ++#define ODM_REG_EDCA_BK_11N 0x50C ++#define ODM_REG_TXPAUSE_11N 0x522 ++#define ODM_REG_RESP_TX_11N 0x6D8 ++#define ODM_REG_ANT_TRAIN_PARA1_11N 0x7b0 ++#define ODM_REG_ANT_TRAIN_PARA2_11N 0x7b4 ++ ++/* DIG Related */ ++#define ODM_BIT_IGI_11N 0x0000007F ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/odm_interface.h b/drivers/staging/r8188eu/include/odm_interface.h +new file mode 100644 +index 000000000000..6b589413d56c +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_interface.h +@@ -0,0 +1,147 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __ODM_INTERFACE_H__ ++#define __ODM_INTERFACE_H__ ++ ++/* */ ++/* =========== Constant/Structure/Enum/... Define */ ++/* */ ++ ++/* */ ++/* =========== Macro Define */ ++/* */ ++ ++#define _reg_all(_name) ODM_##_name ++#define _reg_ic(_name, _ic) ODM_##_name##_ic ++#define _bit_all(_name) BIT_##_name ++#define _bit_ic(_name, _ic) BIT_##_name##_ic ++ ++/* _cat: implemented by Token-Pasting Operator. */ ++ ++/*=================================== ++ ++#define ODM_REG_DIG_11N 0xC50 ++#define ODM_REG_DIG_11AC 0xDDD ++ ++ODM_REG(DIG,_pDM_Odm) ++=====================================*/ ++ ++#define _reg_11N(_name) ODM_REG_##_name##_11N ++#define _reg_11AC(_name) ODM_REG_##_name##_11AC ++#define _bit_11N(_name) ODM_BIT_##_name##_11N ++#define _bit_11AC(_name) ODM_BIT_##_name##_11AC ++ ++#define _cat(_name, _ic_type, _func) \ ++ ( \ ++ ((_ic_type) & ODM_IC_11N_SERIES) ? _func##_11N(_name) : \ ++ _func##_11AC(_name) \ ++ ) ++ ++/* _name: name of register or bit. */ ++/* Example: "ODM_REG(R_A_AGC_CORE1, pDM_Odm)" */ ++/* gets "ODM_R_A_AGC_CORE1" or "ODM_R_A_AGC_CORE1_8192C", ++ * depends on SupportICType. */ ++#define ODM_REG(_name, _pDM_Odm) _cat(_name, _pDM_Odm->SupportICType, _reg) ++#define ODM_BIT(_name, _pDM_Odm) _cat(_name, _pDM_Odm->SupportICType, _bit) ++ ++enum odm_h2c_cmd { ++ ODM_H2C_RSSI_REPORT = 0, ++ ODM_H2C_PSD_RESULT= 1, ++ ODM_H2C_PathDiv = 2, ++ ODM_MAX_H2CCMD ++}; ++ ++/* 2012/02/17 MH For non-MP compile pass only. Linux does not support workitem. */ ++/* Suggest HW team to use thread instead of workitem. Windows also support the feature. */ ++typedef void (*RT_WORKITEM_CALL_BACK)(void *pContext); ++ ++/* =========== Extern Variable ??? It should be forbidden. */ ++ ++/* =========== EXtern Function Prototype */ ++ ++u8 ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr); ++ ++u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr); ++ ++u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr); ++ ++void ODM_Write1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 Data); ++ ++void ODM_Write2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 Data); ++ ++void ODM_Write4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 Data); ++ ++void ODM_SetMACReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, ++ u32 BitMask, u32 Data); ++ ++u32 ODM_GetMACReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 BitMask); ++ ++void ODM_SetBBReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, ++ u32 BitMask, u32 Data); ++ ++u32 ODM_GetBBReg(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 BitMask); ++ ++void ODM_SetRFReg(struct odm_dm_struct *pDM_Odm, enum rf_radio_path eRFPath, ++ u32 RegAddr, u32 BitMask, u32 Data); ++ ++u32 ODM_GetRFReg(struct odm_dm_struct *pDM_Odm, enum rf_radio_path eRFPath, ++ u32 RegAddr, u32 BitMask); ++ ++/* Memory Relative Function. */ ++void ODM_AllocateMemory(struct odm_dm_struct *pDM_Odm, void **pPtr, u32 length); ++void ODM_FreeMemory(struct odm_dm_struct *pDM_Odm, void *pPtr, u32 length); ++ ++s32 ODM_CompareMemory(struct odm_dm_struct *pDM_Odm, void *pBuf1, void *pBuf2, ++ u32 length); ++ ++/* ODM MISC-spin lock relative API. */ ++void ODM_AcquireSpinLock(struct odm_dm_struct *pDM_Odm, ++ enum RT_SPINLOCK_TYPE type); ++ ++void ODM_ReleaseSpinLock(struct odm_dm_struct *pDM_Odm, ++ enum RT_SPINLOCK_TYPE type); ++ ++/* ODM MISC-workitem relative API. */ ++void ODM_InitializeWorkItem(struct odm_dm_struct *pDM_Odm, void *pRtWorkItem, ++ RT_WORKITEM_CALL_BACK RtWorkItemCallback, ++ void *pContext, const char *szID); ++ ++void ODM_StartWorkItem(void *pRtWorkItem); ++ ++void ODM_StopWorkItem(void *pRtWorkItem); ++ ++void ODM_FreeWorkItem(void *pRtWorkItem); ++ ++void ODM_ScheduleWorkItem(void *pRtWorkItem); ++ ++void ODM_IsWorkItemScheduled(void *pRtWorkItem); ++ ++/* ODM Timer relative API. */ ++void ODM_StallExecution(u32 usDelay); ++ ++void ODM_delay_ms(u32 ms); ++ ++void ODM_delay_us(u32 us); ++ ++void ODM_sleep_ms(u32 ms); ++ ++void ODM_sleep_us(u32 us); ++ ++void ODM_SetTimer(struct odm_dm_struct *pDM_Odm, struct timer_list *pTimer, ++ u32 msDelay); ++ ++void ODM_InitializeTimer(struct odm_dm_struct *pDM_Odm, ++ struct timer_list *pTimer, void *CallBackFunc, ++ void *pContext, const char *szID); ++ ++void ODM_CancelTimer(struct odm_dm_struct *pDM_Odm, struct timer_list *pTimer); ++ ++void ODM_ReleaseTimer(struct odm_dm_struct *pDM_Odm, struct timer_list *pTimer); ++ ++/* ODM FW relative API. */ ++u32 ODM_FillH2CCmd(u8 *pH2CBuffer, u32 H2CBufferLen, u32 CmdNum, ++ u32 *pElementID, u32 *pCmdLen, u8 **pCmbBuffer, ++ u8 *CmdStartSeq); ++ ++#endif /* __ODM_INTERFACE_H__ */ +diff --git a/drivers/staging/r8188eu/include/odm_precomp.h b/drivers/staging/r8188eu/include/odm_precomp.h +new file mode 100644 +index 000000000000..a1d6d674bda6 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_precomp.h +@@ -0,0 +1,76 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. i*/ ++ ++#ifndef __ODM_PRECOMP_H__ ++#define __ODM_PRECOMP_H__ ++ ++#include "odm_types.h" ++ ++#define TEST_FALG___ 1 ++ ++/* 2 Config Flags and Structs - defined by each ODM Type */ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "hal_intf.h" ++ ++/* 2 OutSrc Header Files */ ++ ++#include "odm.h" ++#include "odm_HWConfig.h" ++#include "odm_RegDefine11AC.h" ++#include "odm_RegDefine11N.h" ++ ++#include "HalPhyRf_8188e.h"/* for IQK,LCK,Power-tracking */ ++#include "Hal8188ERateAdaptive.h"/* for RA,Power training */ ++#include "rtl8188e_hal.h" ++ ++#include "odm_interface.h" ++#include "odm_reg.h" ++ ++#include "HalHWImg8188E_MAC.h" ++#include "HalHWImg8188E_RF.h" ++#include "HalHWImg8188E_BB.h" ++ ++#include "odm_RegConfig8188E.h" ++#include "odm_RTL8188E.h" ++ ++void odm_DIGInit(struct odm_dm_struct *pDM_Odm); ++void odm_RateAdaptiveMaskInit(struct odm_dm_struct *pDM_Odm); ++void odm_DynamicBBPowerSavingInit(struct odm_dm_struct *pDM_Odm); ++void odm_DynamicTxPowerInit(struct odm_dm_struct *pDM_Odm); ++void odm_TXPowerTrackingInit(struct odm_dm_struct *pDM_Odm); ++void ODM_EdcaTurboInit(struct odm_dm_struct *pDM_Odm); ++void odm_SwAntDivInit_NIC(struct odm_dm_struct *pDM_Odm); ++void odm_GlobalAdapterCheck(void); ++void odm_CommonInfoSelfUpdate(struct odm_dm_struct *pDM_Odm); ++void odm_FalseAlarmCounterStatistics(struct odm_dm_struct *pDM_Odm); ++void odm_DIG(struct odm_dm_struct *pDM_Odm); ++void odm_CCKPacketDetectionThresh(struct odm_dm_struct *pDM_Odm); ++void odm_RefreshRateAdaptiveMaskMP(struct odm_dm_struct *pDM_Odm); ++void odm_DynamicBBPowerSaving(struct odm_dm_struct *pDM_Odm); ++void odm_SwAntDivChkAntSwitch(struct odm_dm_struct *pDM_Odm, u8 Step); ++void odm_EdcaTurboCheck(struct odm_dm_struct *pDM_Odm); ++void odm_DynamicTxPower(struct odm_dm_struct *pDM_Odm); ++void odm_CommonInfoSelfInit(struct odm_dm_struct *pDM_Odm); ++void odm_SwAntDivInit(struct odm_dm_struct *pDM_Odm); ++void odm_RSSIMonitorCheck(struct odm_dm_struct *pDM_Odm); ++void odm_RefreshRateAdaptiveMask(struct odm_dm_struct *pDM_Odm); ++void odm_1R_CCA(struct odm_dm_struct *pDM_Odm); ++void odm_RefreshRateAdaptiveMaskCE(struct odm_dm_struct *pDM_Odm); ++void odm_RefreshRateAdaptiveMaskAPADSL(struct odm_dm_struct *pDM_Odm); ++void odm_DynamicTxPowerNIC(struct odm_dm_struct *pDM_Odm); ++void odm_DynamicTxPowerAP(struct odm_dm_struct *pDM_Odm); ++void odm_RSSIMonitorCheckMP(struct odm_dm_struct *pDM_Odm); ++void odm_RSSIMonitorCheckCE(struct odm_dm_struct *pDM_Odm); ++void odm_RSSIMonitorCheckAP(struct odm_dm_struct *pDM_Odm); ++void odm_TXPowerTrackingThermalMeterInit(struct odm_dm_struct *pDM_Odm); ++void odm_EdcaTurboCheckCE(struct odm_dm_struct *pDM_Odm); ++void odm_TXPowerTrackingCheckCE(struct odm_dm_struct *pDM_Odm); ++void odm_TXPowerTrackingCheckMP(struct odm_dm_struct *pDM_Odm); ++void odm_TXPowerTrackingCheckAP(struct odm_dm_struct *pDM_Odm); ++void odm_SwAntDivChkAntSwitchCallback(struct timer_list *t); ++void odm_InitHybridAntDiv(struct odm_dm_struct *pDM_Odm); ++void odm_HwAntDiv(struct odm_dm_struct *pDM_Odm); ++ ++#endif /* __ODM_PRECOMP_H__ */ +diff --git a/drivers/staging/r8188eu/include/odm_reg.h b/drivers/staging/r8188eu/include/odm_reg.h +new file mode 100644 +index 000000000000..78d7e904947c +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_reg.h +@@ -0,0 +1,89 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. i*/ ++ ++#ifndef __HAL_ODM_REG_H__ ++#define __HAL_ODM_REG_H__ ++ ++/* Register Definition */ ++ ++/* MAC REG */ ++#define ODM_BB_RESET 0x002 ++#define ODM_DUMMY 0x4fe ++#define ODM_EDCA_VO_PARAM 0x500 ++#define ODM_EDCA_VI_PARAM 0x504 ++#define ODM_EDCA_BE_PARAM 0x508 ++#define ODM_EDCA_BK_PARAM 0x50C ++#define ODM_TXPAUSE 0x522 ++ ++/* BB REG */ ++#define ODM_FPGA_PHY0_PAGE8 0x800 ++#define ODM_PSD_SETTING 0x808 ++#define ODM_AFE_SETTING 0x818 ++#define ODM_TXAGC_B_6_18 0x830 ++#define ODM_TXAGC_B_24_54 0x834 ++#define ODM_TXAGC_B_MCS32_5 0x838 ++#define ODM_TXAGC_B_MCS0_MCS3 0x83c ++#define ODM_TXAGC_B_MCS4_MCS7 0x848 ++#define ODM_TXAGC_B_MCS8_MCS11 0x84c ++#define ODM_ANALOG_REGISTER 0x85c ++#define ODM_RF_INTERFACE_OUTPUT 0x860 ++#define ODM_TXAGC_B_MCS12_MCS15 0x868 ++#define ODM_TXAGC_B_11_A_2_11 0x86c ++#define ODM_AD_DA_LSB_MASK 0x874 ++#define ODM_ENABLE_3_WIRE 0x88c ++#define ODM_PSD_REPORT 0x8b4 ++#define ODM_R_ANT_SELECT 0x90c ++#define ODM_CCK_ANT_SELECT 0xa07 ++#define ODM_CCK_PD_THRESH 0xa0a ++#define ODM_CCK_RF_REG1 0xa11 ++#define ODM_CCK_MATCH_FILTER 0xa20 ++#define ODM_CCK_RAKE_MAC 0xa2e ++#define ODM_CCK_CNT_RESET 0xa2d ++#define ODM_CCK_TX_DIVERSITY 0xa2f ++#define ODM_CCK_FA_CNT_MSB 0xa5b ++#define ODM_CCK_FA_CNT_LSB 0xa5c ++#define ODM_CCK_NEW_FUNCTION 0xa75 ++#define ODM_OFDM_PHY0_PAGE_C 0xc00 ++#define ODM_OFDM_RX_ANT 0xc04 ++#define ODM_R_A_RXIQI 0xc14 ++#define ODM_R_A_AGC_CORE1 0xc50 ++#define ODM_R_A_AGC_CORE2 0xc54 ++#define ODM_R_B_AGC_CORE1 0xc58 ++#define ODM_R_AGC_PAR 0xc70 ++#define ODM_R_HTSTF_AGC_PAR 0xc7c ++#define ODM_TX_PWR_TRAINING_A 0xc90 ++#define ODM_TX_PWR_TRAINING_B 0xc98 ++#define ODM_OFDM_FA_CNT1 0xcf0 ++#define ODM_OFDM_PHY0_PAGE_D 0xd00 ++#define ODM_OFDM_FA_CNT2 0xda0 ++#define ODM_OFDM_FA_CNT3 0xda4 ++#define ODM_OFDM_FA_CNT4 0xda8 ++#define ODM_TXAGC_A_6_18 0xe00 ++#define ODM_TXAGC_A_24_54 0xe04 ++#define ODM_TXAGC_A_1_MCS32 0xe08 ++#define ODM_TXAGC_A_MCS0_MCS3 0xe10 ++#define ODM_TXAGC_A_MCS4_MCS7 0xe14 ++#define ODM_TXAGC_A_MCS8_MCS11 0xe18 ++#define ODM_TXAGC_A_MCS12_MCS15 0xe1c ++ ++/* RF REG */ ++#define ODM_GAIN_SETTING 0x00 ++#define ODM_CHANNEL 0x18 ++ ++/* Ant Detect Reg */ ++#define ODM_DPDT 0x300 ++ ++/* PSD Init */ ++#define ODM_PSDREG 0x808 ++ ++/* 92D Path Div */ ++#define PATHDIV_REG 0xB30 ++#define PATHDIV_TRI 0xBA0 ++ ++/* */ ++/* Bitmap Definition */ ++/* */ ++ ++#define BIT_FA_RESET BIT(0) ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/odm_types.h b/drivers/staging/r8188eu/include/odm_types.h +new file mode 100644 +index 000000000000..6f4a4bd37ec1 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/odm_types.h +@@ -0,0 +1,45 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __ODM_TYPES_H__ ++#define __ODM_TYPES_H__ ++ ++/* */ ++/* Define Different SW team support */ ++/* */ ++#define ODM_AP 0x01 /* BIT(0) */ ++#define ODM_ADSL 0x02 /* BIT(1) */ ++#define ODM_CE 0x04 /* BIT(2) */ ++#define ODM_MP 0x08 /* BIT(3) */ ++ ++#define RT_PCI_INTERFACE 1 ++#define RT_USB_INTERFACE 2 ++#define RT_SDIO_INTERFACE 3 ++ ++enum HAL_STATUS { ++ HAL_STATUS_SUCCESS, ++ HAL_STATUS_FAILURE, ++}; ++ ++enum RT_SPINLOCK_TYPE { ++ RT_TEMP = 1, ++}; ++ ++#include "basic_types.h" ++ ++#define DEV_BUS_TYPE RT_USB_INTERFACE ++ ++#define SET_TX_DESC_ANTSEL_A_88E(__ptxdesc, __value) \ ++ le32p_replace_bits((__le32 *)(__ptxdesc + 8), __value, BIT(24)) ++#define SET_TX_DESC_ANTSEL_B_88E(__ptxdesc, __value) \ ++ le32p_replace_bits((__le32 *)(__ptxdesc + 8), __value, BIT(25)) ++#define SET_TX_DESC_ANTSEL_C_88E(__ptxdesc, __value) \ ++ le32p_replace_bits((__le32 *)(__ptxdesc + 28), __value, BIT(29)) ++ ++/* define useless flag to avoid compile warning */ ++#define USE_WORKITEM 0 ++#define FOR_BRAZIL_PRETEST 0 ++#define BT_30_SUPPORT 0 ++#define FPGA_TWO_MAC_VERIFICATION 0 ++ ++#endif /* __ODM_TYPES_H__ */ +diff --git a/drivers/staging/r8188eu/include/osdep_intf.h b/drivers/staging/r8188eu/include/osdep_intf.h +new file mode 100644 +index 000000000000..3ea60feee2db +--- /dev/null ++++ b/drivers/staging/r8188eu/include/osdep_intf.h +@@ -0,0 +1,64 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __OSDEP_INTF_H_ ++#define __OSDEP_INTF_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++struct intf_priv { ++ u8 *intf_dev; ++ u32 max_iosz; /* USB2.0: 128, USB1.1: 64, SDIO:64 */ ++ u32 max_xmitsz; /* USB2.0: unlimited, SDIO:512 */ ++ u32 max_recvsz; /* USB2.0: unlimited, SDIO:512 */ ++ ++ u8 *io_rwmem; ++ u8 *allocated_io_rwmem; ++ u32 io_wsz; /* unit: 4bytes */ ++ u32 io_rsz;/* unit: 4bytes */ ++ u8 intf_status; ++ ++ void (*_bus_io)(u8 *priv); ++ ++/* ++Under Sync. IRP (SDIO/USB) ++A protection mechanism is necessary for the io_rwmem(read/write protocol) ++ ++Under Async. IRP (SDIO/USB) ++The protection mechanism is through the pending queue. ++*/ ++ struct mutex ioctl_mutex; ++ /* when in USB, IO is through interrupt in/out endpoints */ ++ struct usb_device *udev; ++ struct urb *piorw_urb; ++ u8 io_irp_cnt; ++ u8 bio_irp_pending; ++ struct semaphore io_retevt; ++ struct timer_list io_timer; ++ u8 bio_irp_timeout; ++ u8 bio_timer_cancel; ++}; ++ ++u8 rtw_init_drv_sw(struct adapter *padapter); ++u8 rtw_free_drv_sw(struct adapter *padapter); ++u8 rtw_reset_drv_sw(struct adapter *padapter); ++ ++u32 rtw_start_drv_threads(struct adapter *padapter); ++void rtw_stop_drv_threads (struct adapter *padapter); ++void rtw_cancel_all_timer(struct adapter *padapter); ++ ++int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname); ++struct net_device *rtw_init_netdev(struct adapter *padapter); ++u16 rtw_recv_select_queue(struct sk_buff *skb); ++void rtw_proc_init_one(struct net_device *dev); ++void rtw_proc_remove_one(struct net_device *dev); ++ ++void rtw_ips_dev_unload(struct adapter *padapter); ++ ++int rtw_ips_pwr_up(struct adapter *padapter); ++void rtw_ips_pwr_down(struct adapter *padapter); ++int rtw_hw_suspend(struct adapter *padapter); ++int rtw_hw_resume(struct adapter *padapter); ++ ++#endif /* _OSDEP_INTF_H_ */ +diff --git a/drivers/staging/r8188eu/include/osdep_service.h b/drivers/staging/r8188eu/include/osdep_service.h +new file mode 100644 +index 000000000000..029aa4e92c9b +--- /dev/null ++++ b/drivers/staging/r8188eu/include/osdep_service.h +@@ -0,0 +1,315 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __OSDEP_SERVICE_H_ ++#define __OSDEP_SERVICE_H_ ++ ++#include ++#include "basic_types.h" ++ ++#define _FAIL 0 ++#define _SUCCESS 1 ++#define RTW_RX_HANDLED 2 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* Necessary because we use the proc fs */ ++#include /* for struct tasklet_struct */ ++#include ++#include ++#include ++ ++#include ++#include ++ ++struct __queue { ++ struct list_head queue; ++ spinlock_t lock; ++}; ++ ++#define thread_exit() complete_and_exit(NULL, 0) ++ ++static inline struct list_head *get_list_head(struct __queue *queue) ++{ ++ return (&(queue->queue)); ++} ++ ++static inline int _enter_critical_mutex(struct mutex *pmutex, unsigned long *pirqL) ++{ ++ int ret; ++ ++ ret = mutex_lock_interruptible(pmutex); ++ return ret; ++} ++ ++static inline void _exit_critical_mutex(struct mutex *pmutex, unsigned long *pirqL) ++{ ++ mutex_unlock(pmutex); ++} ++ ++static inline void rtw_list_delete(struct list_head *plist) ++{ ++ list_del_init(plist); ++} ++ ++static inline void _set_timer(struct timer_list *ptimer,u32 delay_time) ++{ ++ mod_timer(ptimer , (jiffies+(delay_time*HZ/1000))); ++} ++ ++static inline void _cancel_timer(struct timer_list *ptimer,u8 *bcancelled) ++{ ++ del_timer_sync(ptimer); ++ *bcancelled= true;/* true ==1; false==0 */ ++} ++ ++#define RTW_TIMER_HDL_ARGS void *FunctionContext ++#define RTW_TIMER_HDL_NAME(name) rtw_##name##_timer_hdl ++#define RTW_DECLARE_TIMER_HDL(name) void RTW_TIMER_HDL_NAME(name)(RTW_TIMER_HDL_ARGS) ++ ++static inline void _init_workitem(struct work_struct *pwork, void *pfunc, void * cntx) ++{ ++ INIT_WORK(pwork, pfunc); ++} ++ ++static inline void _set_workitem(struct work_struct *pwork) ++{ ++ schedule_work(pwork); ++} ++ ++static inline void _cancel_workitem_sync(struct work_struct *pwork) ++{ ++ cancel_work_sync(pwork); ++} ++/* */ ++/* Global Mutex: can only be used at PASSIVE level. */ ++/* */ ++ ++#define ACQUIRE_GLOBAL_MUTEX(_MutexCounter) \ ++{ \ ++ while (atomic_inc_return((atomic_t *)&(_MutexCounter)) != 1)\ ++ { \ ++ atomic_dec((atomic_t *)&(_MutexCounter)); \ ++ msleep(10); \ ++ } \ ++} ++ ++#define RELEASE_GLOBAL_MUTEX(_MutexCounter) \ ++{ \ ++ atomic_dec((atomic_t *)&(_MutexCounter)); \ ++} ++ ++static inline int rtw_netif_queue_stopped(struct net_device *pnetdev) ++{ ++ return netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 0)) && ++ netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 1)) && ++ netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 2)) && ++ netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 3)); ++} ++ ++static inline void rtw_netif_wake_queue(struct net_device *pnetdev) ++{ ++ netif_tx_wake_all_queues(pnetdev); ++} ++ ++static inline void rtw_netif_start_queue(struct net_device *pnetdev) ++{ ++ netif_tx_start_all_queues(pnetdev); ++} ++ ++static inline void rtw_netif_stop_queue(struct net_device *pnetdev) ++{ ++ netif_tx_stop_all_queues(pnetdev); ++} ++ ++extern int RTW_STATUS_CODE(int error_code); ++ ++extern unsigned char MCS_rate_2R[16]; ++extern unsigned char MCS_rate_1R[16]; ++extern unsigned char RTW_WPA_OUI[]; ++extern unsigned char WPA_TKIP_CIPHER[4]; ++extern unsigned char RSN_TKIP_CIPHER[4]; ++ ++void *rtw_malloc2d(int h, int w, int size); ++ ++u32 _rtw_down_sema(struct semaphore *sema); ++void _rtw_mutex_init(struct mutex *pmutex); ++void _rtw_mutex_free(struct mutex *pmutex); ++ ++void _rtw_init_queue(struct __queue *pqueue); ++ ++u32 rtw_systime_to_ms(u32 systime); ++u32 rtw_ms_to_systime(u32 ms); ++s32 rtw_get_passing_time_ms(u32 start); ++ ++void rtw_usleep_os(int us); ++ ++u32 rtw_atoi(u8 *s); ++ ++static inline unsigned char _cancel_timer_ex(struct timer_list *ptimer) ++{ ++ return del_timer_sync(ptimer); ++} ++ ++static __inline void thread_enter(char *name) ++{ ++#ifdef daemonize ++ daemonize("%s", name); ++#endif ++ allow_signal(SIGTERM); ++} ++ ++static inline void flush_signals_thread(void) ++{ ++ if (signal_pending (current)) ++ flush_signals(current); ++} ++ ++static inline int res_to_status(int res) ++{ ++ return res; ++} ++ ++#define _RND(sz, r) ((((sz)+((r)-1))/(r))*(r)) ++#define RND4(x) (((x >> 2) + (((x & 3) == 0) ? 0: 1)) << 2) ++ ++static inline u32 _RND4(u32 sz) ++{ ++ u32 val; ++ ++ val = ((sz >> 2) + ((sz & 3) ? 1: 0)) << 2; ++ return val; ++} ++ ++static inline u32 _RND8(u32 sz) ++{ ++ u32 val; ++ ++ val = ((sz >> 3) + ((sz & 7) ? 1: 0)) << 3; ++ return val; ++} ++ ++static inline u32 _RND128(u32 sz) ++{ ++ u32 val; ++ ++ val = ((sz >> 7) + ((sz & 127) ? 1: 0)) << 7; ++ return val; ++} ++ ++static inline u32 _RND256(u32 sz) ++{ ++ u32 val; ++ ++ val = ((sz >> 8) + ((sz & 255) ? 1: 0)) << 8; ++ return val; ++} ++ ++static inline u32 _RND512(u32 sz) ++{ ++ u32 val; ++ ++ val = ((sz >> 9) + ((sz & 511) ? 1: 0)) << 9; ++ return val; ++} ++ ++static inline u32 bitshift(u32 bitmask) ++{ ++ u32 i; ++ ++ for (i = 0; i <= 31; i++) ++ if (((bitmask>>i) & 0x1) == 1) break; ++ return i; ++} ++ ++/* limitation of path length */ ++#define PATH_LENGTH_MAX PATH_MAX ++ ++struct rtw_netdev_priv_indicator { ++ void *priv; ++ u32 sizeof_priv; ++}; ++struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, ++ void *old_priv); ++struct net_device *rtw_alloc_etherdev(int sizeof_priv); ++ ++#define rtw_netdev_priv(netdev) \ ++ (((struct rtw_netdev_priv_indicator *)netdev_priv(netdev))->priv) ++void rtw_free_netdev(struct net_device *netdev); ++ ++#define NDEV_FMT "%s" ++#define NDEV_ARG(ndev) ndev->name ++#define ADPT_FMT "%s" ++#define ADPT_ARG(adapter) adapter->pnetdev->name ++#define FUNC_NDEV_FMT "%s(%s)" ++#define FUNC_NDEV_ARG(ndev) __func__, ndev->name ++#define FUNC_ADPT_FMT "%s(%s)" ++#define FUNC_ADPT_ARG(adapter) __func__, adapter->pnetdev->name ++ ++#define rtw_signal_process(pid, sig) kill_pid(find_vpid((pid)),(sig), 1) ++ ++/* Macros for handling unaligned memory accesses */ ++ ++#define RTW_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1])) ++#define RTW_PUT_BE16(a, val) \ ++ do { \ ++ (a)[0] = ((u16) (val)) >> 8; \ ++ (a)[1] = ((u16) (val)) & 0xff; \ ++ } while (0) ++ ++#define RTW_PUT_LE16(a, val) \ ++ do { \ ++ (a)[1] = ((u16) (val)) >> 8; \ ++ (a)[0] = ((u16) (val)) & 0xff; \ ++ } while (0) ++ ++#define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \ ++ ((u32) (a)[2])) ++ ++#define RTW_PUT_BE32(a, val) \ ++ do { \ ++ (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ ++ (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ ++ (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ ++ (a)[3] = (u8) (((u32) (val)) & 0xff); \ ++ } while (0) ++ ++void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len); ++ ++struct rtw_cbuf { ++ u32 write; ++ u32 read; ++ u32 size; ++ void *bufs[0]; ++}; ++ ++bool rtw_cbuf_full(struct rtw_cbuf *cbuf); ++bool rtw_cbuf_empty(struct rtw_cbuf *cbuf); ++bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf); ++void *rtw_cbuf_pop(struct rtw_cbuf *cbuf); ++struct rtw_cbuf *rtw_cbuf_alloc(u32 size); ++int wifirate2_ratetbl_inx(unsigned char rate); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/recv_osdep.h b/drivers/staging/r8188eu/include/recv_osdep.h +new file mode 100644 +index 000000000000..72ddf515071e +--- /dev/null ++++ b/drivers/staging/r8188eu/include/recv_osdep.h +@@ -0,0 +1,37 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RECV_OSDEP_H_ ++#define __RECV_OSDEP_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++int _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter); ++void _rtw_free_recv_priv(struct recv_priv *precvpriv); ++ ++s32 rtw_recv_entry(struct recv_frame *precv_frame); ++int rtw_recv_indicatepkt(struct adapter *adapter, struct recv_frame *recv_frame); ++void rtw_recv_returnpacket(struct net_device *cnxt, struct sk_buff *retpkt); ++ ++void rtw_hostapd_mlme_rx(struct adapter *padapter, struct recv_frame *recv_fr); ++void rtw_handle_tkip_mic_err(struct adapter *padapter, u8 bgroup); ++ ++int rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter); ++void rtw_free_recv_priv(struct recv_priv *precvpriv); ++ ++int rtw_os_recv_resource_init(struct recv_priv *recvpr, struct adapter *adapt); ++int rtw_os_recv_resource_alloc(struct adapter *adapt, struct recv_frame *recvfr); ++void rtw_os_recv_resource_free(struct recv_priv *precvpriv); ++ ++int rtw_os_recvbuf_resource_alloc(struct adapter *adapt, struct recv_buf *buf); ++int rtw_os_recvbuf_resource_free(struct adapter *adapt, struct recv_buf *buf); ++ ++void rtw_os_read_port(struct adapter *padapter, struct recv_buf *precvbuf); ++ ++void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl); ++int _netdev_open(struct net_device *pnetdev); ++int netdev_open(struct net_device *pnetdev); ++int netdev_close(struct net_device *pnetdev); ++ ++#endif /* */ +diff --git a/drivers/staging/r8188eu/include/rtl8188e_cmd.h b/drivers/staging/r8188eu/include/rtl8188e_cmd.h +new file mode 100644 +index 000000000000..6fbf9a47430b +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_cmd.h +@@ -0,0 +1,106 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_CMD_H__ ++#define __RTL8188E_CMD_H__ ++ ++enum RTL8188E_H2C_CMD_ID { ++ /* Class Common */ ++ H2C_COM_RSVD_PAGE = 0x00, ++ H2C_COM_MEDIA_STATUS_RPT = 0x01, ++ H2C_COM_SCAN = 0x02, ++ H2C_COM_KEEP_ALIVE = 0x03, ++ H2C_COM_DISCNT_DECISION = 0x04, ++ H2C_COM_INIT_OFFLOAD = 0x06, ++ H2C_COM_REMOTE_WAKE_CTL = 0x07, ++ H2C_COM_AP_OFFLOAD = 0x08, ++ H2C_COM_BCN_RSVD_PAGE = 0x09, ++ H2C_COM_PROB_RSP_RSVD_PAGE = 0x0A, ++ ++ /* Class PS */ ++ H2C_PS_PWR_MODE = 0x20, ++ H2C_PS_TUNE_PARA = 0x21, ++ H2C_PS_TUNE_PARA_2 = 0x22, ++ H2C_PS_LPS_PARA = 0x23, ++ H2C_PS_P2P_OFFLOAD = 0x24, ++ ++ /* Class DM */ ++ H2C_DM_MACID_CFG = 0x40, ++ H2C_DM_TXBF = 0x41, ++ ++ /* Class BT */ ++ H2C_BT_COEX_MASK = 0x60, ++ H2C_BT_COEX_GPIO_MODE = 0x61, ++ H2C_BT_DAC_SWING_VAL = 0x62, ++ H2C_BT_PSD_RST = 0x63, ++ ++ /* Class */ ++ H2C_RESET_TSF = 0xc0, ++}; ++ ++struct cmd_msg_parm { ++ u8 eid; /* element id */ ++ u8 sz; /* sz */ ++ u8 buf[6]; ++}; ++ ++enum { ++ PWRS ++}; ++ ++struct setpwrmode_parm { ++ u8 Mode;/* 0:Active,1:LPS,2:WMMPS */ ++ u8 SmartPS_RLBM;/* LPS= 0:PS_Poll,1:PS_Poll,2:NullData,WMM= 0:PS_Poll,1:NullData */ ++ u8 AwakeInterval; /* unit: beacon interval */ ++ u8 bAllQueueUAPSD; ++ u8 PwrState;/* AllON(0x0c),RFON(0x04),RFOFF(0x00) */ ++}; ++ ++struct H2C_SS_RFOFF_PARAM { ++ u8 ROFOn; /* 1: on, 0:off */ ++ u16 gpio_period; /* unit: 1024 us */ ++} __packed; ++ ++struct joinbssrpt_parm { ++ u8 OpMode; /* RT_MEDIA_STATUS */ ++}; ++ ++struct rsvdpage_loc { ++ u8 LocProbeRsp; ++ u8 LocPsPoll; ++ u8 LocNullData; ++ u8 LocQosNull; ++ u8 LocBTQosNull; ++}; ++ ++struct P2P_PS_Offload_t { ++ u8 Offload_En:1; ++ u8 role:1; /* 1: Owner, 0: Client */ ++ u8 CTWindow_En:1; ++ u8 NoA0_En:1; ++ u8 NoA1_En:1; ++ u8 AllStaSleep:1; /* Only valid in Owner */ ++ u8 discovery:1; ++ u8 rsvd:1; ++}; ++ ++struct P2P_PS_CTWPeriod_t { ++ u8 CTWPeriod; /* TU */ ++}; ++ ++/* host message to firmware cmd */ ++void rtl8188e_set_FwPwrMode_cmd(struct adapter *padapter, u8 Mode); ++void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *padapter, u8 mstatus); ++u8 rtl8188e_set_rssi_cmd(struct adapter *padapter, u8 *param); ++u8 rtl8188e_set_raid_cmd(struct adapter *padapter, u32 mask); ++void rtl8188e_Add_RateATid(struct adapter *padapter, u32 bitmap, u8 arg, ++ u8 rssi_level); ++ ++#ifdef CONFIG_88EU_P2P ++void rtl8188e_set_p2p_ps_offload_cmd(struct adapter *adapt, u8 p2p_ps_state); ++#endif /* CONFIG_88EU_P2P */ ++ ++void CheckFwRsvdPageContent(struct adapter *adapt); ++void rtl8188e_set_FwMediaStatus_cmd(struct adapter *adapt, __le16 mstatus_rpt); ++ ++#endif/* __RTL8188E_CMD_H__ */ +diff --git a/drivers/staging/r8188eu/include/rtl8188e_dm.h b/drivers/staging/r8188eu/include/rtl8188e_dm.h +new file mode 100644 +index 000000000000..3ead20b321a9 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_dm.h +@@ -0,0 +1,47 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_DM_H__ ++#define __RTL8188E_DM_H__ ++ ++enum{ ++ UP_LINK, ++ DOWN_LINK, ++}; ++/* duplicate code,will move to ODM ######### */ ++#define IQK_MAC_REG_NUM 4 ++#define IQK_ADDA_REG_NUM 16 ++#define IQK_BB_REG_NUM 9 ++#define HP_THERMAL_NUM 8 ++/* duplicate code,will move to ODM ######### */ ++struct dm_priv { ++ u8 DM_Type; ++ u8 DMFlag; ++ u8 InitDMFlag; ++ u32 InitODMFlag; ++ ++ /* Upper and Lower Signal threshold for Rate Adaptive*/ ++ int UndecoratedSmoothedPWDB; ++ int UndecoratedSmoothedCCK; ++ int EntryMinUndecoratedSmoothedPWDB; ++ int EntryMaxUndecoratedSmoothedPWDB; ++ int MinUndecoratedPWDBForDM; ++ int LastMinUndecoratedPWDBForDM; ++ ++ /* for High Power */ ++ u8 bDynamicTxPowerEnable; ++ u8 LastDTPLvl; ++ u8 DynamicTxHighPowerLvl;/* Tx Power Control for Near/Far Range */ ++ u8 PowerIndex_backup[6]; ++}; ++ ++void rtl8188e_init_dm_priv(struct adapter *adapt); ++void rtl8188e_deinit_dm_priv(struct adapter *adapt); ++void rtl8188e_InitHalDm(struct adapter *adapt); ++void rtl8188e_HalDmWatchDog(struct adapter *adapt); ++ ++void AntDivCompare8188E(struct adapter *adapt, struct wlan_bssid_ex *dst, ++ struct wlan_bssid_ex *src); ++u8 AntDivBeforeLink8188E(struct adapter *adapt); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtl8188e_hal.h b/drivers/staging/r8188eu/include/rtl8188e_hal.h +new file mode 100644 +index 000000000000..3939bf053de1 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_hal.h +@@ -0,0 +1,452 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_HAL_H__ ++#define __RTL8188E_HAL_H__ ++ ++/* include HAL Related header after HAL Related compiling flags */ ++#include "rtl8188e_spec.h" ++#include "Hal8188EPhyReg.h" ++#include "Hal8188EPhyCfg.h" ++#include "rtl8188e_rf.h" ++#include "rtl8188e_dm.h" ++#include "rtl8188e_recv.h" ++#include "rtl8188e_xmit.h" ++#include "rtl8188e_cmd.h" ++#include "Hal8188EPwrSeq.h" ++#include "rtl8188e_sreset.h" ++#include "rtw_efuse.h" ++ ++#include "odm_precomp.h" ++ ++/* Fw Array */ ++#define Rtl8188E_FwImageArray Rtl8188EFwImgArray ++#define Rtl8188E_FWImgArrayLength Rtl8188EFWImgArrayLength ++ ++#define RTL8188E_FW_UMC_IMG "rtl8188E\\rtl8188efw.bin" ++#define RTL8188E_PHY_REG "rtl8188E\\PHY_REG_1T.txt" ++#define RTL8188E_PHY_RADIO_A "rtl8188E\\radio_a_1T.txt" ++#define RTL8188E_PHY_RADIO_B "rtl8188E\\radio_b_1T.txt" ++#define RTL8188E_AGC_TAB "rtl8188E\\AGC_TAB_1T.txt" ++#define RTL8188E_PHY_MACREG "rtl8188E\\MAC_REG.txt" ++#define RTL8188E_PHY_REG_PG "rtl8188E\\PHY_REG_PG.txt" ++#define RTL8188E_PHY_REG_MP "rtl8188E\\PHY_REG_MP.txt" ++ ++/* RTL8188E Power Configuration CMDs for USB/SDIO interfaces */ ++#define Rtl8188E_NIC_PWR_ON_FLOW rtl8188E_power_on_flow ++#define Rtl8188E_NIC_RF_OFF_FLOW rtl8188E_radio_off_flow ++#define Rtl8188E_NIC_DISABLE_FLOW rtl8188E_card_disable_flow ++#define Rtl8188E_NIC_ENABLE_FLOW rtl8188E_card_enable_flow ++#define Rtl8188E_NIC_SUSPEND_FLOW rtl8188E_suspend_flow ++#define Rtl8188E_NIC_RESUME_FLOW rtl8188E_resume_flow ++#define Rtl8188E_NIC_PDN_FLOW rtl8188E_hwpdn_flow ++#define Rtl8188E_NIC_LPS_ENTER_FLOW rtl8188E_enter_lps_flow ++#define Rtl8188E_NIC_LPS_LEAVE_FLOW rtl8188E_leave_lps_flow ++ ++#define DRVINFO_SZ 4 /* unit is 8bytes */ ++#define PageNum_128(_Len) (u32)(((_Len)>>7) + ((_Len) & 0x7F ? 1 : 0)) ++ ++/* download firmware related data structure */ ++#define FW_8188E_SIZE 0x4000 /* 16384,16k */ ++#define FW_8188E_START_ADDRESS 0x1000 ++#define FW_8188E_END_ADDRESS 0x1FFF /* 0x5FFF */ ++ ++#define MAX_PAGE_SIZE 4096 /* @ page : 4k bytes */ ++ ++#define IS_FW_HEADER_EXIST(_pFwHdr) \ ++ ((le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x92C0 || \ ++ (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x88C0 || \ ++ (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x2300 || \ ++ (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x88E0) ++ ++/* This structure must be careful with byte-ordering */ ++ ++struct rt_firmware_hdr { ++ /* 8-byte alinment required */ ++ /* LONG WORD 0 ---- */ ++ __le16 Signature; /* 92C0: test chip; 92C, ++ * 88C0: test chip; 88C1: MP A-cut; ++ * 92C1: MP A-cut */ ++ u8 Category; /* AP/NIC and USB/PCI */ ++ u8 Function; /* Reserved for different FW function ++ * indcation, for further use when ++ * driver needs to download different ++ * FW for different conditions */ ++ __le16 Version; /* FW Version */ ++ u8 Subversion; /* FW Subversion, default 0x00 */ ++ u16 Rsvd1; ++ ++ /* LONG WORD 1 ---- */ ++ u8 Month; /* Release time Month field */ ++ u8 Date; /* Release time Date field */ ++ u8 Hour; /* Release time Hour field */ ++ u8 Minute; /* Release time Minute field */ ++ __le16 RamCodeSize; /* The size of RAM code */ ++ u8 Foundry; ++ u8 Rsvd2; ++ ++ /* LONG WORD 2 ---- */ ++ __le32 SvnIdx; /* The SVN entry index */ ++ u32 Rsvd3; ++ ++ /* LONG WORD 3 ---- */ ++ u32 Rsvd4; ++ u32 Rsvd5; ++}; ++ ++#define DRIVER_EARLY_INT_TIME 0x05 ++#define BCN_DMA_ATIME_INT_TIME 0x02 ++ ++enum usb_rx_agg_mode { ++ USB_RX_AGG_DISABLE, ++ USB_RX_AGG_DMA, ++ USB_RX_AGG_USB, ++ USB_RX_AGG_MIX ++}; ++ ++#define MAX_RX_DMA_BUFFER_SIZE_88E \ ++ 0x2400 /* 9k for 88E nornal chip , MaxRxBuff=10k-max(TxReportSize(64*8), ++ * WOLPattern(16*24)) */ ++ ++#define MAX_TX_REPORT_BUFFER_SIZE 0x0400 /* 1k */ ++ ++/* BK, BE, VI, VO, HCCA, MANAGEMENT, COMMAND, HIGH, BEACON. */ ++#define MAX_TX_QUEUE 9 ++ ++#define TX_SELE_HQ BIT(0) /* High Queue */ ++#define TX_SELE_LQ BIT(1) /* Low Queue */ ++#define TX_SELE_NQ BIT(2) /* Normal Queue */ ++ ++/* Note: We will divide number of page equally for each queue other ++ * than public queue! */ ++/* 22k = 22528 bytes = 176 pages (@page = 128 bytes) */ ++/* must reserved about 7 pages for LPS => 176-7 = 169 (0xA9) */ ++/* 2*BCN / 1*ps-poll / 1*null-data /1*prob_rsp /1*QOS null-data /1*BT QOS ++ * null-data */ ++ ++#define TX_TOTAL_PAGE_NUMBER_88E 0xA9/* 169 (21632=> 21k) */ ++ ++#define TX_PAGE_BOUNDARY_88E (TX_TOTAL_PAGE_NUMBER_88E + 1) ++ ++/* Note: For Normal Chip Setting ,modify later */ ++#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER \ ++ TX_TOTAL_PAGE_NUMBER_88E /* 0xA9 , 0xb0=>176=>22k */ ++#define WMM_NORMAL_TX_PAGE_BOUNDARY_88E \ ++ (WMM_NORMAL_TX_TOTAL_PAGE_NUMBER + 1) /* 0xA9 */ ++ ++/* Chip specific */ ++#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3) ++#define CHIP_BONDING_92C_1T2R 0x1 ++#define CHIP_BONDING_88C_USB_MCARD 0x2 ++#define CHIP_BONDING_88C_USB_HP 0x1 ++#include "HalVerDef.h" ++#include "hal_com.h" ++ ++/* Channel Plan */ ++enum ChannelPlan { ++ CHPL_FCC = 0, ++ CHPL_IC = 1, ++ CHPL_ETSI = 2, ++ CHPL_SPA = 3, ++ CHPL_FRANCE = 4, ++ CHPL_MKK = 5, ++ CHPL_MKK1 = 6, ++ CHPL_ISRAEL = 7, ++ CHPL_TELEC = 8, ++ CHPL_GLOBAL = 9, ++ CHPL_WORLD = 10, ++}; ++ ++struct txpowerinfo24g { ++ u8 IndexCCK_Base[RF_PATH_MAX][MAX_CHNL_GROUP_24G]; ++ u8 IndexBW40_Base[RF_PATH_MAX][MAX_CHNL_GROUP_24G]; ++ /* If only one tx, only BW20 and OFDM are used. */ ++ s8 CCK_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++ s8 OFDM_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++ s8 BW20_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++ s8 BW40_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++}; ++ ++#define EFUSE_REAL_CONTENT_LEN 512 ++#define EFUSE_MAX_SECTION 16 ++#define EFUSE_IC_ID_OFFSET 506 /* For some inferior IC purpose*/ ++#define AVAILABLE_EFUSE_ADDR(addr) (addr < EFUSE_REAL_CONTENT_LEN) ++/* To prevent out of boundary programming case, */ ++/* leave 1byte and program full section */ ++/* 9bytes + 1byt + 5bytes and pre 1byte. */ ++/* For worst case: */ ++/* | 1byte|----8bytes----|1byte|--5bytes--| */ ++/* | | Reserved(14bytes) | */ ++ ++/* PG data exclude header, dummy 6 bytes frome CP test and reserved 1byte. */ ++#define EFUSE_OOB_PROTECT_BYTES 15 ++ ++#define HWSET_MAX_SIZE_88E 512 ++ ++#define EFUSE_REAL_CONTENT_LEN_88E 256 ++#define EFUSE_MAP_LEN_88E 512 ++#define EFUSE_MAP_LEN EFUSE_MAP_LEN_88E ++#define EFUSE_MAX_SECTION_88E 64 ++#define EFUSE_MAX_WORD_UNIT_88E 4 ++#define EFUSE_IC_ID_OFFSET_88E 506 ++#define AVAILABLE_EFUSE_ADDR_88E(addr) \ ++ (addr < EFUSE_REAL_CONTENT_LEN_88E) ++/* To prevent out of boundary programming case, leave 1byte and program ++ * full section */ ++/* 9bytes + 1byt + 5bytes and pre 1byte. */ ++/* For worst case: */ ++/* | 2byte|----8bytes----|1byte|--7bytes--| 92D */ ++/* PG data exclude header, dummy 7 bytes frome CP test and reserved 1byte. */ ++#define EFUSE_OOB_PROTECT_BYTES_88E 18 ++#define EFUSE_PROTECT_BYTES_BANK_88E 16 ++ ++/* EFUSE for BT definition */ ++#define EFUSE_BT_REAL_CONTENT_LEN 1536 /* 512*3 */ ++#define EFUSE_BT_MAP_LEN 1024 /* 1k bytes */ ++#define EFUSE_BT_MAX_SECTION 128 /* 1024/8 */ ++ ++#define EFUSE_PROTECT_BYTES_BANK 16 ++ ++/* For RTL8723 WiFi/BT/GPS multi-function configuration. */ ++enum rt_multi_func { ++ RT_MULTI_FUNC_NONE = 0x00, ++ RT_MULTI_FUNC_WIFI = 0x01, ++ RT_MULTI_FUNC_BT = 0x02, ++ RT_MULTI_FUNC_GPS = 0x04, ++}; ++ ++/* For RTL8723 regulator mode. */ ++enum rt_regulator_mode { ++ RT_SWITCHING_REGULATOR = 0, ++ RT_LDO_REGULATOR = 1, ++}; ++ ++struct hal_data_8188e { ++ struct HAL_VERSION VersionID; ++ enum rt_multi_func MultiFunc; /* For multi-function consideration. */ ++ enum rt_regulator_mode RegulatorMode; /* switching regulator or LDO */ ++ u16 CustomerID; ++ ++ u16 FirmwareVersion; ++ u16 FirmwareVersionRev; ++ u16 FirmwareSubVersion; ++ u16 FirmwareSignature; ++ u8 PGMaxGroup; ++ /* current WIFI_PHY values */ ++ u32 ReceiveConfig; ++ enum wireless_mode CurrentWirelessMode; ++ enum ht_channel_width CurrentChannelBW; ++ u8 CurrentChannel; ++ u8 nCur40MhzPrimeSC;/* Control channel sub-carrier */ ++ ++ u16 BasicRateSet; ++ ++ /* rf_ctrl */ ++ u8 rf_chip; ++ u8 rf_type; ++ u8 NumTotalRFPath; ++ ++ u8 BoardType; ++ ++ /* EEPROM setting. */ ++ u16 EEPROMVID; ++ u16 EEPROMPID; ++ u16 EEPROMSVID; ++ u16 EEPROMSDID; ++ u8 EEPROMCustomerID; ++ u8 EEPROMSubCustomerID; ++ u8 EEPROMVersion; ++ u8 EEPROMRegulatory; ++ ++ u8 bTXPowerDataReadFromEEPORM; ++ u8 EEPROMThermalMeter; ++ u8 bAPKThermalMeterIgnore; ++ ++ bool EepromOrEfuse; ++ struct efuse_hal EfuseHal; ++ ++ u8 Index24G_CCK_Base[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ u8 Index24G_BW40_Base[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ /* If only one tx, only BW20 and OFDM are used. */ ++ s8 CCK_24G_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++ s8 OFDM_24G_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++ s8 BW20_24G_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++ s8 BW40_24G_Diff[RF_PATH_MAX][MAX_TX_COUNT]; ++ ++ u8 TxPwrLevelCck[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ /* For HT 40MHZ pwr */ ++ u8 TxPwrLevelHT40_1S[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ /* For HT 40MHZ pwr */ ++ u8 TxPwrLevelHT40_2S[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ /* HT 20<->40 Pwr diff */ ++ u8 TxPwrHt20Diff[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ /* For HT<->legacy pwr diff */ ++ u8 TxPwrLegacyHtDiff[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ /* For power group */ ++ u8 PwrGroupHT20[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ u8 PwrGroupHT40[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; ++ ++ u8 LegacyHTTxPowerDiff;/* Legacy to HT rate power diff */ ++ /* The current Tx Power Level */ ++ u8 CurrentCckTxPwrIdx; ++ u8 CurrentOfdm24GTxPwrIdx; ++ u8 CurrentBW2024GTxPwrIdx; ++ u8 CurrentBW4024GTxPwrIdx; ++ ++ /* Read/write are allow for following hardware information variables */ ++ u8 framesync; ++ u32 framesyncC34; ++ u8 framesyncMonitor; ++ u8 DefaultInitialGain[4]; ++ u8 pwrGroupCnt; ++ u32 MCSTxPowerLevelOriginalOffset[MAX_PG_GROUP][16]; ++ u32 CCKTxPowerLevelOriginalOffset; ++ ++ u8 CrystalCap; ++ u32 AntennaTxPath; /* Antenna path Tx */ ++ u32 AntennaRxPath; /* Antenna path Rx */ ++ u8 BluetoothCoexist; ++ u8 ExternalPA; ++ ++ u8 bLedOpenDrain; /* Open-drain support for controlling the LED.*/ ++ ++ u8 b1x1RecvCombine; /* for 1T1R receive combining */ ++ ++ u32 AcParam_BE; /* Original parameter for BE, use for EDCA turbo. */ ++ ++ struct bb_reg_def PHYRegDef[4]; /* Radio A/B/C/D */ ++ ++ u32 RfRegChnlVal[2]; ++ ++ /* RDG enable */ ++ bool bRDGEnable; ++ ++ /* for host message to fw */ ++ u8 LastHMEBoxNum; ++ ++ u8 fw_ractrl; ++ u8 RegTxPause; ++ /* Beacon function related global variable. */ ++ u32 RegBcnCtrlVal; ++ u8 RegFwHwTxQCtrl; ++ u8 RegReg542; ++ u8 RegCR_1; ++ ++ struct dm_priv dmpriv; ++ struct odm_dm_struct odmpriv; ++ struct sreset_priv srestpriv; ++ ++ u8 CurAntenna; ++ u8 AntDivCfg; ++ u8 TRxAntDivType; ++ ++ u8 bDumpRxPkt;/* for debug */ ++ u8 bDumpTxPkt;/* for debug */ ++ u8 FwRsvdPageStartOffset; /* Reserve page start offset except ++ * beacon in TxQ. */ ++ ++ /* 2010/08/09 MH Add CU power down mode. */ ++ bool pwrdown; ++ ++ /* Add for dual MAC 0--Mac0 1--Mac1 */ ++ u32 interfaceIndex; ++ ++ u8 OutEpQueueSel; ++ u8 OutEpNumber; ++ ++ /* Add for USB aggreation mode dynamic shceme. */ ++ bool UsbRxHighSpeedMode; ++ ++ /* 2010/11/22 MH Add for slim combo debug mode selective. */ ++ /* This is used for fix the drawback of CU TSMC-A/UMC-A cut. ++ * HW auto suspend ability. Close BT clock. */ ++ bool SlimComboDbg; ++ ++ u16 EfuseUsedBytes; ++ ++#ifdef CONFIG_88EU_P2P ++ struct P2P_PS_Offload_t p2p_ps_offload; ++#endif ++ ++ /* Auto FSM to Turn On, include clock, isolation, power control ++ * for MAC only */ ++ u8 bMacPwrCtrlOn; ++ ++ u32 UsbBulkOutSize; ++ ++ /* Interrupt relatd register information. */ ++ u32 IntArray[3];/* HISR0,HISR1,HSISR */ ++ u32 IntrMask[3]; ++ u8 C2hArray[16]; ++ u8 UsbTxAggMode; ++ u8 UsbTxAggDescNum; ++ u16 HwRxPageSize; /* Hardware setting */ ++ u32 MaxUsbRxAggBlock; ++ ++ enum usb_rx_agg_mode UsbRxAggMode; ++ u8 UsbRxAggBlockCount; /* USB Block count. Block size is ++ * 512-byte in high speed and 64-byte ++ * in full speed */ ++ u8 UsbRxAggBlockTimeout; ++ u8 UsbRxAggPageCount; /* 8192C DMA page count */ ++ u8 UsbRxAggPageTimeout; ++}; ++ ++#define GET_HAL_DATA(__pAdapter) \ ++ ((struct hal_data_8188e *)((__pAdapter)->HalData)) ++#define GET_RF_TYPE(priv) (GET_HAL_DATA(priv)->rf_type) ++ ++#define INCLUDE_MULTI_FUNC_BT(_Adapter) \ ++ (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_BT) ++#define INCLUDE_MULTI_FUNC_GPS(_Adapter) \ ++ (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_GPS) ++ ++/* rtl8188e_hal_init.c */ ++s32 rtl8188e_FirmwareDownload(struct adapter *padapter); ++void _8051Reset88E(struct adapter *padapter); ++void rtl8188e_InitializeFirmwareVars(struct adapter *padapter); ++ ++s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy); ++ ++/* EFuse */ ++u8 GetEEPROMSize8188E(struct adapter *padapter); ++void Hal_InitPGData88E(struct adapter *padapter); ++void Hal_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo); ++void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *hwinfo, ++ bool AutoLoadFail); ++ ++void Hal_EfuseParseEEPROMVer88E(struct adapter *padapter, u8 *hwinfo, ++ bool AutoLoadFail); ++void rtl8188e_EfuseParseChnlPlan(struct adapter *padapter, u8 *hwinfo, ++ bool AutoLoadFail); ++void Hal_EfuseParseCustomerID88E(struct adapter *padapter, u8 *hwinfo, ++ bool AutoLoadFail); ++void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter,u8 *PROMContent, ++ bool AutoLoadFail); ++void Hal_ReadThermalMeter_88E(struct adapter * dapter, u8 *PROMContent, ++ bool AutoloadFail); ++void Hal_EfuseParseXtal_8188E(struct adapter *pAdapter, u8 *hwinfo, ++ bool AutoLoadFail); ++void Hal_EfuseParseBoardType88E(struct adapter *pAdapter, u8 *hwinfo, ++ bool AutoLoadFail); ++void Hal_ReadPowerSavingMode88E(struct adapter *pAdapter, u8 *hwinfo, ++ bool AutoLoadFail); ++ ++bool HalDetectPwrDownMode88E(struct adapter *Adapter); ++ ++void Hal_InitChannelPlan(struct adapter *padapter); ++void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc); ++ ++/* register */ ++void SetBcnCtrlReg(struct adapter *padapter, u8 SetBits, u8 ClearBits); ++ ++void rtl8188e_clone_haldata(struct adapter *dst, struct adapter *src); ++void rtl8188e_start_thread(struct adapter *padapter); ++void rtl8188e_stop_thread(struct adapter *padapter); ++ ++void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int len); ++s32 rtl8188e_iol_efuse_patch(struct adapter *padapter); ++void rtw_cancel_all_timer(struct adapter *padapter); ++void _ps_open_RF(struct adapter *adapt); ++ ++#endif /* __RTL8188E_HAL_H__ */ +diff --git a/drivers/staging/r8188eu/include/rtl8188e_led.h b/drivers/staging/r8188eu/include/rtl8188e_led.h +new file mode 100644 +index 000000000000..b00954198764 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_led.h +@@ -0,0 +1,18 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_LED_H__ ++#define __RTL8188E_LED_H__ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++/* */ ++/* Interface to manipulate LED objects. */ ++/* */ ++void rtl8188eu_InitSwLeds(struct adapter *padapter); ++void rtl8188eu_DeInitSwLeds(struct adapter *padapter); ++void SwLedOn(struct adapter *padapter, struct LED_871x *pLed); ++void SwLedOff(struct adapter *padapter, struct LED_871x *pLed); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtl8188e_recv.h b/drivers/staging/r8188eu/include/rtl8188e_recv.h +new file mode 100644 +index 000000000000..a91daf84d6c3 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_recv.h +@@ -0,0 +1,53 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_RECV_H__ ++#define __RTL8188E_RECV_H__ ++ ++#define TX_RPT1_PKT_LEN 8 ++ ++#define RECV_BLK_SZ 512 ++#define RECV_BLK_CNT 16 ++#define RECV_BLK_TH RECV_BLK_CNT ++#define RECV_BULK_IN_ADDR 0x80 ++#define RECV_INT_IN_ADDR 0x81 ++ ++#define NR_PREALLOC_RECV_SKB (8) ++ ++#define NR_RECVBUFF (4) ++ ++#define MAX_RECVBUF_SZ (15360) /* 15k < 16k */ ++ ++struct phy_stat { ++ unsigned int phydw0; ++ unsigned int phydw1; ++ unsigned int phydw2; ++ unsigned int phydw3; ++ unsigned int phydw4; ++ unsigned int phydw5; ++ unsigned int phydw6; ++ unsigned int phydw7; ++}; ++ ++/* Rx smooth factor */ ++#define Rx_Smooth_Factor (20) ++ ++enum rx_packet_type { ++ NORMAL_RX,/* Normal rx packet */ ++ TX_REPORT1,/* CCX */ ++ TX_REPORT2,/* TX RPT */ ++ HIS_REPORT,/* USB HISR RPT */ ++}; ++ ++#define INTERRUPT_MSG_FORMAT_LEN 60 ++void rtl8188eu_init_recvbuf(struct adapter *padapter, struct recv_buf *buf); ++s32 rtl8188eu_init_recv_priv(struct adapter *padapter); ++void rtl8188eu_free_recv_priv(struct adapter * padapter); ++void rtl8188eu_recv_hdl(struct adapter * padapter, struct recv_buf *precvbuf); ++void rtl8188eu_recv_tasklet(unsigned long priv); ++void rtl8188e_query_rx_phy_status(struct recv_frame *fr, struct phy_stat *phy); ++void rtl8188e_process_phy_info(struct adapter * padapter, void *prframe); ++void update_recvframe_phyinfo_88e(struct recv_frame *fra, struct phy_stat *phy); ++void update_recvframe_attrib_88e(struct recv_frame *fra, struct recv_stat *stat); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtl8188e_rf.h b/drivers/staging/r8188eu/include/rtl8188e_rf.h +new file mode 100644 +index 000000000000..da6b7f8212a3 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_rf.h +@@ -0,0 +1,19 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_RF_H__ ++#define __RTL8188E_RF_H__ ++ ++#define RF6052_MAX_TX_PWR 0x3F ++#define RF6052_MAX_REG 0x3F ++#define RF6052_MAX_PATH 2 ++ ++int PHY_RF6052_Config8188E(struct adapter *Adapter); ++void rtl8188e_RF_ChangeTxPath(struct adapter *Adapter, u16 DataRate); ++void rtl8188e_PHY_RF6052SetBandwidth(struct adapter *Adapter, ++ enum ht_channel_width Bandwidth); ++void rtl8188e_PHY_RF6052SetCckTxPower(struct adapter *Adapter, u8 *level); ++void rtl8188e_PHY_RF6052SetOFDMTxPower(struct adapter *Adapter, u8 *ofdm, ++ u8 *pwrbw20, u8 *pwrbw40, u8 channel); ++ ++#endif/* __RTL8188E_RF_H__ */ +diff --git a/drivers/staging/r8188eu/include/rtl8188e_spec.h b/drivers/staging/r8188eu/include/rtl8188e_spec.h +new file mode 100644 +index 000000000000..1c96f7b81245 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_spec.h +@@ -0,0 +1,1381 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_SPEC_H__ ++#define __RTL8188E_SPEC_H__ ++ ++/* 8192C Regsiter offset definition */ ++ ++#define HAL_PS_TIMER_INT_DELAY 50 /* 50 microseconds */ ++#define HAL_92C_NAV_UPPER_UNIT 128 /* micro-second */ ++ ++#define MAC_ADDR_LEN 6 ++/* 8188E PKT_BUFF_ACCESS_CTRL value */ ++#define TXPKT_BUF_SELECT 0x69 ++#define RXPKT_BUF_SELECT 0xA5 ++#define DISABLE_TRXPKT_BUF_ACCESS 0x0 ++ ++/* 0x0000h ~ 0x00FFh System Configuration */ ++#define REG_SYS_ISO_CTRL 0x0000 ++#define REG_SYS_FUNC_EN 0x0002 ++#define REG_APS_FSMCO 0x0004 ++#define REG_SYS_CLKR 0x0008 ++#define REG_9346CR 0x000A ++#define REG_EE_VPD 0x000C ++#define REG_AFE_MISC 0x0010 ++#define REG_SPS0_CTRL 0x0011 ++#define REG_SPS_OCP_CFG 0x0018 ++#define REG_RSV_CTRL 0x001C ++#define REG_RF_CTRL 0x001F ++#define REG_LDOA15_CTRL 0x0020 ++#define REG_LDOV12D_CTRL 0x0021 ++#define REG_LDOHCI12_CTRL 0x0022 ++#define REG_LPLDO_CTRL 0x0023 ++#define REG_AFE_XTAL_CTRL 0x0024 ++#define REG_AFE_PLL_CTRL 0x0028 ++#define REG_APE_PLL_CTRL_EXT 0x002c ++#define REG_EFUSE_CTRL 0x0030 ++#define REG_EFUSE_TEST 0x0034 ++#define REG_GPIO_MUXCFG 0x0040 ++#define REG_GPIO_IO_SEL 0x0042 ++#define REG_MAC_PINMUX_CFG 0x0043 ++#define REG_GPIO_PIN_CTRL 0x0044 ++#define REG_GPIO_INTM 0x0048 ++#define REG_LEDCFG0 0x004C ++#define REG_LEDCFG1 0x004D ++#define REG_LEDCFG2 0x004E ++#define REG_LEDCFG3 0x004F ++#define REG_FSIMR 0x0050 ++#define REG_FSISR 0x0054 ++#define REG_HSIMR 0x0058 ++#define REG_HSISR 0x005c ++#define REG_GPIO_PIN_CTRL_2 0x0060 /* RTL8723 WIFI/BT/GPS ++ * Multi-Function GPIO Pin Control. */ ++#define REG_GPIO_IO_SEL_2 0x0062 /* RTL8723 WIFI/BT/GPS ++ * Multi-Function GPIO Select. */ ++#define REG_BB_PAD_CTRL 0x0064 ++#define REG_MULTI_FUNC_CTRL 0x0068 /* RTL8723 WIFI/BT/GPS ++ * Multi-Function control source. */ ++#define REG_GPIO_OUTPUT 0x006c ++#define REG_AFE_XTAL_CTRL_EXT 0x0078 /* RTL8188E */ ++#define REG_XCK_OUT_CTRL 0x007c /* RTL8188E */ ++#define REG_MCUFWDL 0x0080 ++#define REG_WOL_EVENT 0x0081 /* RTL8188E */ ++#define REG_MCUTSTCFG 0x0084 ++#define REG_HMEBOX_E0 0x0088 ++#define REG_HMEBOX_E1 0x008A ++#define REG_HMEBOX_E2 0x008C ++#define REG_HMEBOX_E3 0x008E ++#define REG_HMEBOX_EXT_0 0x01F0 ++#define REG_HMEBOX_EXT_1 0x01F4 ++#define REG_HMEBOX_EXT_2 0x01F8 ++#define REG_HMEBOX_EXT_3 0x01FC ++#define REG_HIMR_88E 0x00B0 ++#define REG_HISR_88E 0x00B4 ++#define REG_HIMRE_88E 0x00B8 ++#define REG_HISRE_88E 0x00BC ++#define REG_EFUSE_ACCESS 0x00CF /* Efuse access protection ++ * for RTL8723 */ ++#define REG_BIST_SCAN 0x00D0 ++#define REG_BIST_RPT 0x00D4 ++#define REG_BIST_ROM_RPT 0x00D8 ++#define REG_USB_SIE_INTF 0x00E0 ++#define REG_PCIE_MIO_INTF 0x00E4 ++#define REG_PCIE_MIO_INTD 0x00E8 ++#define REG_HPON_FSM 0x00EC ++#define REG_SYS_CFG 0x00F0 ++#define REG_GPIO_OUTSTS 0x00F4 /* For RTL8723 only. */ ++#define REG_TYPE_ID 0x00FC ++ ++#define REG_MAC_PHY_CTRL_NORMAL 0x00f8 ++ ++/* 0x0100h ~ 0x01FFh MACTOP General Configuration */ ++#define REG_CR 0x0100 ++#define REG_PBP 0x0104 ++#define REG_PKT_BUFF_ACCESS_CTRL 0x0106 ++#define REG_TRXDMA_CTRL 0x010C ++#define REG_TRXFF_BNDY 0x0114 ++#define REG_TRXFF_STATUS 0x0118 ++#define REG_RXFF_PTR 0x011C ++/* define REG_HIMR 0x0120 */ ++/* define REG_HISR 0x0124 */ ++#define REG_HIMRE 0x0128 ++#define REG_HISRE 0x012C ++#define REG_CPWM 0x012F ++#define REG_FWIMR 0x0130 ++#define REG_FTIMR 0x0138 ++#define REG_FWISR 0x0134 ++#define REG_PKTBUF_DBG_CTRL 0x0140 ++#define REG_PKTBUF_DBG_ADDR (REG_PKTBUF_DBG_CTRL) ++#define REG_RXPKTBUF_DBG (REG_PKTBUF_DBG_CTRL+2) ++#define REG_TXPKTBUF_DBG (REG_PKTBUF_DBG_CTRL+3) ++#define REG_RXPKTBUF_CTRL (REG_PKTBUF_DBG_CTRL+2) ++#define REG_PKTBUF_DBG_DATA_L 0x0144 ++#define REG_PKTBUF_DBG_DATA_H 0x0148 ++ ++#define REG_TC0_CTRL 0x0150 ++#define REG_TC1_CTRL 0x0154 ++#define REG_TC2_CTRL 0x0158 ++#define REG_TC3_CTRL 0x015C ++#define REG_TC4_CTRL 0x0160 ++#define REG_TCUNIT_BASE 0x0164 ++#define REG_MBIST_START 0x0174 ++#define REG_MBIST_DONE 0x0178 ++#define REG_MBIST_FAIL 0x017C ++#define REG_32K_CTRL 0x0194 /* RTL8188E */ ++#define REG_C2HEVT_MSG_NORMAL 0x01A0 ++#define REG_C2HEVT_CLEAR 0x01AF ++#define REG_MCUTST_1 0x01c0 ++#define REG_FMETHR 0x01C8 ++#define REG_HMETFR 0x01CC ++#define REG_HMEBOX_0 0x01D0 ++#define REG_HMEBOX_1 0x01D4 ++#define REG_HMEBOX_2 0x01D8 ++#define REG_HMEBOX_3 0x01DC ++ ++#define REG_LLT_INIT 0x01E0 ++ ++/* 0x0200h ~ 0x027Fh TXDMA Configuration */ ++#define REG_RQPN 0x0200 ++#define REG_FIFOPAGE 0x0204 ++#define REG_TDECTRL 0x0208 ++#define REG_TXDMA_OFFSET_CHK 0x020C ++#define REG_TXDMA_STATUS 0x0210 ++#define REG_RQPN_NPQ 0x0214 ++ ++/* 0x0280h ~ 0x02FFh RXDMA Configuration */ ++#define REG_RXDMA_AGG_PG_TH 0x0280 ++#define REG_RXPKT_NUM 0x0284 ++#define REG_RXDMA_STATUS 0x0288 ++ ++/* 0x0300h ~ 0x03FFh PCIe */ ++#define REG_PCIE_CTRL_REG 0x0300 ++#define REG_INT_MIG 0x0304 /* Interrupt Migration */ ++#define REG_BCNQ_DESA 0x0308 /* TX Beacon Descr Address */ ++#define REG_HQ_DESA 0x0310 /* TX High Queue Descr Addr */ ++#define REG_MGQ_DESA 0x0318 /* TX Manage Queue Descr Addr*/ ++#define REG_VOQ_DESA 0x0320 /* TX VO Queue Descr Addr */ ++#define REG_VIQ_DESA 0x0328 /* TX VI Queue Descr Addr */ ++#define REG_BEQ_DESA 0x0330 /* TX BE Queue Descr Addr */ ++#define REG_BKQ_DESA 0x0338 /* TX BK Queue Descr Addr */ ++#define REG_RX_DESA 0x0340 /* RX Queue Descr Addr */ ++#define REG_MDIO 0x0354 /* MDIO for Access PCIE PHY */ ++#define REG_DBG_SEL 0x0360 /* Debug Selection Register */ ++#define REG_PCIE_HRPWM 0x0361 /* PCIe RPWM */ ++#define REG_PCIE_HCPWM 0x0363 /* PCIe CPWM */ ++#define REG_WATCH_DOG 0x0368 ++ ++/* RTL8723 series ------------------------------ */ ++#define REG_PCIE_HISR 0x03A0 ++ ++/* spec version 11 */ ++/* 0x0400h ~ 0x047Fh Protocol Configuration */ ++#define REG_VOQ_INFORMATION 0x0400 ++#define REG_VIQ_INFORMATION 0x0404 ++#define REG_BEQ_INFORMATION 0x0408 ++#define REG_BKQ_INFORMATION 0x040C ++#define REG_MGQ_INFORMATION 0x0410 ++#define REG_HGQ_INFORMATION 0x0414 ++#define REG_BCNQ_INFORMATION 0x0418 ++#define REG_TXPKT_EMPTY 0x041A ++ ++#define REG_CPU_MGQ_INFORMATION 0x041C ++#define REG_FWHW_TXQ_CTRL 0x0420 ++#define REG_HWSEQ_CTRL 0x0423 ++#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 ++#define REG_TXPKTBUF_MGQ_BDNY 0x0425 ++#define REG_LIFETIME_EN 0x0426 ++#define REG_MULTI_BCNQ_OFFSET 0x0427 ++#define REG_SPEC_SIFS 0x0428 ++#define REG_RL 0x042A ++#define REG_DARFRC 0x0430 ++#define REG_RARFRC 0x0438 ++#define REG_RRSR 0x0440 ++#define REG_ARFR0 0x0444 ++#define REG_ARFR1 0x0448 ++#define REG_ARFR2 0x044C ++#define REG_ARFR3 0x0450 ++#define REG_AGGLEN_LMT 0x0458 ++#define REG_AMPDU_MIN_SPACE 0x045C ++#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D ++#define REG_FAST_EDCA_CTRL 0x0460 ++#define REG_RD_RESP_PKT_TH 0x0463 ++#define REG_INIRTS_RATE_SEL 0x0480 ++/* define REG_INIDATA_RATE_SEL 0x0484 */ ++#define REG_POWER_STATUS 0x04A4 ++#define REG_POWER_STAGE1 0x04B4 ++#define REG_POWER_STAGE2 0x04B8 ++#define REG_PKT_VO_VI_LIFE_TIME 0x04C0 ++#define REG_PKT_BE_BK_LIFE_TIME 0x04C2 ++#define REG_STBC_SETTING 0x04C4 ++#define REG_PROT_MODE_CTRL 0x04C8 ++#define REG_MAX_AGGR_NUM 0x04CA ++#define REG_RTS_MAX_AGGR_NUM 0x04CB ++#define REG_BAR_MODE_CTRL 0x04CC ++#define REG_RA_TRY_RATE_AGG_LMT 0x04CF ++#define REG_EARLY_MODE_CONTROL 0x4D0 ++#define REG_NQOS_SEQ 0x04DC ++#define REG_QOS_SEQ 0x04DE ++#define REG_NEED_CPU_HANDLE 0x04E0 ++#define REG_PKT_LOSE_RPT 0x04E1 ++#define REG_PTCL_ERR_STATUS 0x04E2 ++#define REG_TX_RPT_CTRL 0x04EC ++#define REG_TX_RPT_TIME 0x04F0 /* 2 byte */ ++#define REG_DUMMY 0x04FC ++ ++/* 0x0500h ~ 0x05FFh EDCA Configuration */ ++#define REG_EDCA_VO_PARAM 0x0500 ++#define REG_EDCA_VI_PARAM 0x0504 ++#define REG_EDCA_BE_PARAM 0x0508 ++#define REG_EDCA_BK_PARAM 0x050C ++#define REG_BCNTCFG 0x0510 ++#define REG_PIFS 0x0512 ++#define REG_RDG_PIFS 0x0513 ++#define REG_SIFS_CTX 0x0514 ++#define REG_SIFS_TRX 0x0516 ++#define REG_TSFTR_SYN_OFFSET 0x0518 ++#define REG_AGGR_BREAK_TIME 0x051A ++#define REG_SLOT 0x051B ++#define REG_TX_PTCL_CTRL 0x0520 ++#define REG_TXPAUSE 0x0522 ++#define REG_DIS_TXREQ_CLR 0x0523 ++#define REG_RD_CTRL 0x0524 ++/* Format for offset 540h-542h: */ ++/* [3:0]: TBTT prohibit setup in unit of 32us. The time for HW getting ++ * beacon content before TBTT. */ ++/* [7:4]: Reserved. */ ++/* [19:8]: TBTT prohibit hold in unit of 32us. The time for HW holding ++ * to send the beacon packet. */ ++/* [23:20]: Reserved */ ++/* Description: */ ++/* | */ ++/* |<--Setup--|--Hold------------>| */ ++/* --------------|---------------------- */ ++/* | */ ++/* TBTT */ ++/* Note: We cannot update beacon content to HW or send any AC packets during ++ * the time between Setup and Hold. */ ++#define REG_TBTT_PROHIBIT 0x0540 ++#define REG_RD_NAV_NXT 0x0544 ++#define REG_NAV_PROT_LEN 0x0546 ++#define REG_BCN_CTRL 0x0550 ++#define REG_BCN_CTRL_1 0x0551 ++#define REG_MBID_NUM 0x0552 ++#define REG_DUAL_TSF_RST 0x0553 ++#define REG_BCN_INTERVAL 0x0554 ++#define REG_DRVERLYINT 0x0558 ++#define REG_BCNDMATIM 0x0559 ++#define REG_ATIMWND 0x055A ++#define REG_BCN_MAX_ERR 0x055D ++#define REG_RXTSF_OFFSET_CCK 0x055E ++#define REG_RXTSF_OFFSET_OFDM 0x055F ++#define REG_TSFTR 0x0560 ++#define REG_TSFTR1 0x0568 ++#define REG_ATIMWND_1 0x0570 ++#define REG_PSTIMER 0x0580 ++#define REG_TIMER0 0x0584 ++#define REG_TIMER1 0x0588 ++#define REG_ACMHWCTRL 0x05C0 ++ ++/* define REG_FW_TSF_SYNC_CNT 0x04A0 */ ++#define REG_FW_RESET_TSF_CNT_1 0x05FC ++#define REG_FW_RESET_TSF_CNT_0 0x05FD ++#define REG_FW_BCN_DIS_CNT 0x05FE ++ ++/* 0x0600h ~ 0x07FFh WMAC Configuration */ ++#define REG_APSD_CTRL 0x0600 ++#define REG_BWOPMODE 0x0603 ++#define REG_TCR 0x0604 ++#define REG_RCR 0x0608 ++#define REG_RX_PKT_LIMIT 0x060C ++#define REG_RX_DLK_TIME 0x060D ++#define REG_RX_DRVINFO_SZ 0x060F ++ ++#define REG_MACID 0x0610 ++#define REG_BSSID 0x0618 ++#define REG_MAR 0x0620 ++#define REG_MBIDCAMCFG 0x0628 ++ ++#define REG_USTIME_EDCA 0x0638 ++#define REG_MAC_SPEC_SIFS 0x063A ++ ++/* 20100719 Joseph: Hardware register definition change. (HW datasheet v54) */ ++/* [15:8]SIFS_R2T_OFDM, [7:0]SIFS_R2T_CCK */ ++#define REG_R2T_SIFS 0x063C ++/* [15:8]SIFS_T2T_OFDM, [7:0]SIFS_T2T_CCK */ ++#define REG_T2T_SIFS 0x063E ++#define REG_ACKTO 0x0640 ++#define REG_CTS2TO 0x0641 ++#define REG_EIFS 0x0642 ++ ++/* RXERR_RPT */ ++#define RXERR_TYPE_OFDM_PPDU 0 ++#define RXERR_TYPE_OFDM_false_ALARM 1 ++#define RXERR_TYPE_OFDM_MPDU_OK 2 ++#define RXERR_TYPE_OFDM_MPDU_FAIL 3 ++#define RXERR_TYPE_CCK_PPDU 4 ++#define RXERR_TYPE_CCK_false_ALARM 5 ++#define RXERR_TYPE_CCK_MPDU_OK 6 ++#define RXERR_TYPE_CCK_MPDU_FAIL 7 ++#define RXERR_TYPE_HT_PPDU 8 ++#define RXERR_TYPE_HT_false_ALARM 9 ++#define RXERR_TYPE_HT_MPDU_TOTAL 10 ++#define RXERR_TYPE_HT_MPDU_OK 11 ++#define RXERR_TYPE_HT_MPDU_FAIL 12 ++#define RXERR_TYPE_RX_FULL_DROP 15 ++ ++#define RXERR_COUNTER_MASK 0xFFFFF ++#define RXERR_RPT_RST BIT(27) ++#define _RXERR_RPT_SEL(type) ((type) << 28) ++ ++/* Note: */ ++/* The NAV upper value is very important to WiFi 11n 5.2.3 NAV test. ++ * The default value is always too small, but the WiFi TestPlan test ++ * by 25,000 microseconds of NAV through sending CTS in the air. ++ * We must update this value greater than 25,000 microseconds to pass ++ * the item. The offset of NAV_UPPER in 8192C Spec is incorrect, and ++ * the offset should be 0x0652. */ ++#define REG_NAV_UPPER 0x0652 /* unit of 128 */ ++ ++/* WMA, BA, CCX */ ++/* define REG_NAV_CTRL 0x0650 */ ++#define REG_BACAMCMD 0x0654 ++#define REG_BACAMCONTENT 0x0658 ++#define REG_LBDLY 0x0660 ++#define REG_FWDLY 0x0661 ++#define REG_RXERR_RPT 0x0664 ++#define REG_WMAC_TRXPTCL_CTL 0x0668 ++ ++/* Security */ ++#define REG_CAMCMD 0x0670 ++#define REG_CAMWRITE 0x0674 ++#define REG_CAMREAD 0x0678 ++#define REG_CAMDBG 0x067C ++#define REG_SECCFG 0x0680 ++ ++/* Power */ ++#define REG_WOW_CTRL 0x0690 ++#define REG_PS_RX_INFO 0x0692 ++#define REG_UAPSD_TID 0x0693 ++#define REG_WKFMCAM_CMD 0x0698 ++#define REG_WKFMCAM_NUM_88E 0x698 ++#define REG_RXFLTMAP0 0x06A0 ++#define REG_RXFLTMAP1 0x06A2 ++#define REG_RXFLTMAP2 0x06A4 ++#define REG_BCN_PSR_RPT 0x06A8 ++#define REG_BT_COEX_TABLE 0x06C0 ++ ++/* Hardware Port 2 */ ++#define REG_MACID1 0x0700 ++#define REG_BSSID1 0x0708 ++ ++/* 0xFE00h ~ 0xFE55h USB Configuration */ ++#define REG_USB_INFO 0xFE17 ++#define REG_USB_SPECIAL_OPTION 0xFE55 ++#define REG_USB_DMA_AGG_TO 0xFE5B ++#define REG_USB_AGG_TO 0xFE5C ++#define REG_USB_AGG_TH 0xFE5D ++ ++/* For normal chip */ ++#define REG_NORMAL_SIE_VID 0xFE60 /* 0xFE60~0xFE61 */ ++#define REG_NORMAL_SIE_PID 0xFE62 /* 0xFE62~0xFE63 */ ++#define REG_NORMAL_SIE_OPTIONAL 0xFE64 ++#define REG_NORMAL_SIE_EP 0xFE65 /* 0xFE65~0xFE67 */ ++#define REG_NORMAL_SIE_PHY 0xFE68 /* 0xFE68~0xFE6B */ ++#define REG_NORMAL_SIE_OPTIONAL2 0xFE6C ++#define REG_NORMAL_SIE_GPS_EP 0xFE6D /* 0xFE6D, for RTL8723 only. */ ++#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 /* 0xFE70~0xFE75 */ ++#define REG_NORMAL_SIE_STRING 0xFE80 /* 0xFE80~0xFEDF */ ++ ++/* TODO: use these definition when using REG_xxx naming rule. */ ++/* NOTE: DO NOT Remove these definition. Use later. */ ++ ++#define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */ ++#define EFUSE_TEST REG_EFUSE_TEST /* E-Fuse Test. */ ++#define MSR (REG_CR + 2) /* Media Status reg */ ++#define ISR REG_HISR_88E ++/* Timing Sync Function Timer Register. */ ++#define TSFR REG_TSFTR ++ ++#define PBP REG_PBP ++ ++/* Redifine MACID register, to compatible prior ICs. */ ++/* MAC ID Register, Offset 0x0050-0x0053 */ ++#define IDR0 REG_MACID ++/* MAC ID Register, Offset 0x0054-0x0055 */ ++#define IDR4 (REG_MACID + 4) ++ ++/* 9. Security Control Registers (Offset: ) */ ++/* IN 8190 Data Sheet is called CAMcmd */ ++#define RWCAM REG_CAMCMD ++/* Software write CAM input content */ ++#define WCAMI REG_CAMWRITE ++/* Software read/write CAM config */ ++#define RCAMO REG_CAMREAD ++#define CAMDBG REG_CAMDBG ++/* Security Configuration Register */ ++#define SECR REG_SECCFG ++ ++/* Unused register */ ++#define UnusedRegister 0x1BF ++#define DCAM UnusedRegister ++#define PSR UnusedRegister ++#define BBAddr UnusedRegister ++#define PhyDataR UnusedRegister ++ ++/* Min Spacing related settings. */ ++#define MAX_MSS_DENSITY_2T 0x13 ++#define MAX_MSS_DENSITY_1T 0x0A ++ ++/* EEPROM enable when set 1 */ ++#define CmdEEPROM_En BIT(5) ++/* System EEPROM select, 0: boot from E-FUSE, 1: The EEPROM used is 9346 */ ++#define CmdEERPOMSEL BIT(4) ++#define Cmd9346CR_9356SEL BIT(4) ++ ++/* 8192C GPIO MUX Configuration Register (offset 0x40, 4 byte) */ ++#define GPIOSEL_GPIO 0 ++#define GPIOSEL_ENBT BIT(5) ++ ++/* 8192C GPIO PIN Control Register (offset 0x44, 4 byte) */ ++/* GPIO pins input value */ ++#define GPIO_IN REG_GPIO_PIN_CTRL ++/* GPIO pins output value */ ++#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) ++/* GPIO pins output enable when a bit is set to "1"; otherwise, ++ * input is configured. */ ++#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) ++#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) ++ ++/* 8723/8188E Host System Interrupt Mask Register (offset 0x58, 32 byte) */ ++#define HSIMR_GPIO12_0_INT_EN BIT(0) ++#define HSIMR_SPS_OCP_INT_EN BIT(5) ++#define HSIMR_RON_INT_EN BIT(6) ++#define HSIMR_PDN_INT_EN BIT(7) ++#define HSIMR_GPIO9_INT_EN BIT(25) ++ ++/* 8723/8188E Host System Interrupt Status Register (offset 0x5C, 32 byte) */ ++#define HSISR_GPIO12_0_INT BIT(0) ++#define HSISR_SPS_OCP_INT BIT(5) ++#define HSISR_RON_INT_EN BIT(6) ++#define HSISR_PDNINT BIT(7) ++#define HSISR_GPIO9_INT BIT(25) ++ ++/* 8192C (MSR) Media Status Register (Offset 0x4C, 8 bits) */ ++/* ++Network Type ++00: No link ++01: Link in ad hoc network ++10: Link in infrastructure network ++11: AP mode ++Default: 00b. ++*/ ++#define MSR_NOLINK 0x00 ++#define MSR_ADHOC 0x01 ++#define MSR_INFRA 0x02 ++#define MSR_AP 0x03 ++ ++/* 88EU (MSR) Media Status Register (Offset 0x4C, 8 bits) */ ++#define USB_INTR_CONTENT_C2H_OFFSET 0 ++#define USB_INTR_CONTENT_CPWM1_OFFSET 16 ++#define USB_INTR_CONTENT_CPWM2_OFFSET 20 ++#define USB_INTR_CONTENT_HISR_OFFSET 48 ++#define USB_INTR_CONTENT_HISRE_OFFSET 52 ++ ++/* 88E Driver Initialization Offload REG_FDHM0(Offset 0x88, 8 bits) */ ++/* IOL config for REG_FDHM0(Reg0x88) */ ++#define CMD_INIT_LLT BIT(0) ++#define CMD_READ_EFUSE_MAP BIT(1) ++#define CMD_EFUSE_PATCH BIT(2) ++#define CMD_IOCONFIG BIT(3) ++#define CMD_INIT_LLT_ERR BIT(4) ++#define CMD_READ_EFUSE_MAP_ERR BIT(5) ++#define CMD_EFUSE_PATCH_ERR BIT(6) ++#define CMD_IOCONFIG_ERR BIT(7) ++ ++/* 6. Adaptive Control Registers (Offset: 0x0160 - 0x01CF) */ ++/* 8192C Response Rate Set Register (offset 0x181, 24bits) */ ++#define RRSR_1M BIT(0) ++#define RRSR_2M BIT(1) ++#define RRSR_5_5M BIT(2) ++#define RRSR_11M BIT(3) ++#define RRSR_6M BIT(4) ++#define RRSR_9M BIT(5) ++#define RRSR_12M BIT(6) ++#define RRSR_18M BIT(7) ++#define RRSR_24M BIT(8) ++#define RRSR_36M BIT(9) ++#define RRSR_48M BIT(10) ++#define RRSR_54M BIT(11) ++#define RRSR_MCS0 BIT(12) ++#define RRSR_MCS1 BIT(13) ++#define RRSR_MCS2 BIT(14) ++#define RRSR_MCS3 BIT(15) ++#define RRSR_MCS4 BIT(16) ++#define RRSR_MCS5 BIT(17) ++#define RRSR_MCS6 BIT(18) ++#define RRSR_MCS7 BIT(19) ++ ++/* 8192C Response Rate Set Register (offset 0x1BF, 8bits) */ ++/* WOL bit information */ ++#define HAL92C_WOL_PTK_UPDATE_EVENT BIT(0) ++#define HAL92C_WOL_GTK_UPDATE_EVENT BIT(1) ++ ++/* 8192C BW_OPMODE bits (Offset 0x203, 8bit) */ ++#define BW_OPMODE_20MHZ BIT(2) ++ ++/* 8192C CAM Config Setting (offset 0x250, 1 byte) */ ++#define CAM_VALID BIT(15) ++#define CAM_NOTVALID 0x0000 ++#define CAM_USEDK BIT(5) ++ ++#define CAM_CONTENT_COUNT 8 ++ ++#define CAM_NONE 0x0 ++#define CAM_WEP40 0x01 ++#define CAM_TKIP 0x02 ++#define CAM_AES 0x04 ++#define CAM_WEP104 0x05 ++#define CAM_SMS4 0x6 ++ ++#define TOTAL_CAM_ENTRY 32 ++#define HALF_CAM_ENTRY 16 ++ ++#define CAM_CONFIG_USEDK true ++#define CAM_CONFIG_NO_USEDK false ++ ++#define CAM_WRITE BIT(16) ++#define CAM_READ 0x00000000 ++#define CAM_POLLINIG BIT(31) ++ ++#define SCR_UseDK 0x01 ++#define SCR_TxSecEnable 0x02 ++#define SCR_RxSecEnable 0x04 ++ ++/* 10. Power Save Control Registers (Offset: 0x0260 - 0x02DF) */ ++#define WOW_PMEN BIT(0) /* Power management Enable. */ ++#define WOW_WOMEN BIT(1) /* WoW function on or off. */ ++#define WOW_MAGIC BIT(2) /* Magic packet */ ++#define WOW_UWF BIT(3) /* Unicast Wakeup frame. */ ++ ++/* 12. Host Interrupt Status Registers (Offset: 0x0300 - 0x030F) */ ++/* 8188 IMR/ISR bits */ ++#define IMR_DISABLED_88E 0x0 ++/* IMR DW0(0x0060-0063) Bit 0-31 */ ++#define IMR_TXCCK_88E BIT(30) /* TXRPT interrupt when CCX bit of the packet is set */ ++#define IMR_PSTIMEOUT_88E BIT(29) /* Power Save Time Out Interrupt */ ++#define IMR_GTINT4_88E BIT(28) /* When GTIMER4 expires, this bit is set to 1 */ ++#define IMR_GTINT3_88E BIT(27) /* When GTIMER3 expires, this bit is set to 1 */ ++#define IMR_TBDER_88E BIT(26) /* Transmit Beacon0 Error */ ++#define IMR_TBDOK_88E BIT(25) /* Transmit Beacon0 OK */ ++#define IMR_TSF_BIT32_TOGGLE_88E BIT(24) /* TSF Timer BIT32 toggle indication interrupt */ ++#define IMR_BCNDMAINT0_88E BIT(20) /* Beacon DMA Interrupt 0 */ ++#define IMR_BCNDERR0_88E BIT(16) /* Beacon Queue DMA Error 0 */ ++#define IMR_HSISR_IND_ON_INT_88E BIT(15) /* HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1) */ ++#define IMR_BCNDMAINT_E_88E BIT(14) /* Beacon DMA Interrupt Extension for Win7 */ ++#define IMR_ATIMEND_88E BIT(12) /* CTWidnow End or ATIM Window End */ ++#define IMR_HISR1_IND_INT_88E BIT(11) /* HISR1 Indicator (HISR1 & HIMR1 is true, this bit is set to 1) */ ++#define IMR_C2HCMD_88E BIT(10) /* CPU to Host Command INT Status, Write 1 clear */ ++#define IMR_CPWM2_88E BIT(9) /* CPU power Mode exchange INT Status, Write 1 clear */ ++#define IMR_CPWM_88E BIT(8) /* CPU power Mode exchange INT Status, Write 1 clear */ ++#define IMR_HIGHDOK_88E BIT(7) /* High Queue DMA OK */ ++#define IMR_MGNTDOK_88E BIT(6) /* Management Queue DMA OK */ ++#define IMR_BKDOK_88E BIT(5) /* AC_BK DMA OK */ ++#define IMR_BEDOK_88E BIT(4) /* AC_BE DMA OK */ ++#define IMR_VIDOK_88E BIT(3) /* AC_VI DMA OK */ ++#define IMR_VODOK_88E BIT(2) /* AC_VO DMA OK */ ++#define IMR_RDU_88E BIT(1) /* Rx Descriptor Unavailable */ ++#define IMR_ROK_88E BIT(0) /* Receive DMA OK */ ++ ++/* IMR DW1(0x00B4-00B7) Bit 0-31 */ ++#define IMR_BCNDMAINT7_88E BIT(27) /* Beacon DMA Interrupt 7 */ ++#define IMR_BCNDMAINT6_88E BIT(26) /* Beacon DMA Interrupt 6 */ ++#define IMR_BCNDMAINT5_88E BIT(25) /* Beacon DMA Interrupt 5 */ ++#define IMR_BCNDMAINT4_88E BIT(24) /* Beacon DMA Interrupt 4 */ ++#define IMR_BCNDMAINT3_88E BIT(23) /* Beacon DMA Interrupt 3 */ ++#define IMR_BCNDMAINT2_88E BIT(22) /* Beacon DMA Interrupt 2 */ ++#define IMR_BCNDMAINT1_88E BIT(21) /* Beacon DMA Interrupt 1 */ ++#define IMR_BCNDERR7_88E BIT(20) /* Beacon DMA Error Int 7 */ ++#define IMR_BCNDERR6_88E BIT(19) /* Beacon DMA Error Int 6 */ ++#define IMR_BCNDERR5_88E BIT(18) /* Beacon DMA Error Int 5 */ ++#define IMR_BCNDERR4_88E BIT(17) /* Beacon DMA Error Int 4 */ ++#define IMR_BCNDERR3_88E BIT(16) /* Beacon DMA Error Int 3 */ ++#define IMR_BCNDERR2_88E BIT(15) /* Beacon DMA Error Int 2 */ ++#define IMR_BCNDERR1_88E BIT(14) /* Beacon DMA Error Int 1 */ ++#define IMR_ATIMEND_E_88E BIT(13) /* ATIM Window End Ext for Win7 */ ++#define IMR_TXERR_88E BIT(11) /* Tx Err Flag Int Status, write 1 clear. */ ++#define IMR_RXERR_88E BIT(10) /* Rx Err Flag INT Status, Write 1 clear */ ++#define IMR_TXFOVW_88E BIT(9) /* Transmit FIFO Overflow */ ++#define IMR_RXFOVW_88E BIT(8) /* Receive FIFO Overflow */ ++ ++#define HAL_NIC_UNPLUG_ISR 0xFFFFFFFF /* The value when the NIC is unplugged for PCI. */ ++ ++/* 8192C EFUSE */ ++#define HWSET_MAX_SIZE 256 ++#define HWSET_MAX_SIZE_88E 512 ++ ++/*=================================================================== ++===================================================================== ++Here the register defines are for 92C. When the define is as same with 92C, ++we will use the 92C's define for the consistency ++So the following defines for 92C is not entire!!!!!! ++===================================================================== ++=====================================================================*/ ++/* ++Based on Datasheet V33---090401 ++Register Summary ++Current IOREG MAP ++0x0000h ~ 0x00FFh System Configuration (256 Bytes) ++0x0100h ~ 0x01FFh MACTOP General Configuration (256 Bytes) ++0x0200h ~ 0x027Fh TXDMA Configuration (128 Bytes) ++0x0280h ~ 0x02FFh RXDMA Configuration (128 Bytes) ++0x0300h ~ 0x03FFh PCIE EMAC Reserved Region (256 Bytes) ++0x0400h ~ 0x04FFh Protocol Configuration (256 Bytes) ++0x0500h ~ 0x05FFh EDCA Configuration (256 Bytes) ++0x0600h ~ 0x07FFh WMAC Configuration (512 Bytes) ++0x2000h ~ 0x3FFFh 8051 FW Download Region (8196 Bytes) ++*/ ++/* 8192C (TXPAUSE) transmission pause (Offset 0x522, 8 bits) */ ++/* Note: */ ++/* The bits of stopping AC(VO/VI/BE/BK) queue in datasheet ++ * RTL8192S/RTL8192C are wrong, */ ++/* the correct arragement is VO - Bit0, VI - Bit1, BE - Bit2, ++ * and BK - Bit3. */ ++/* 8723 and 88E may be not correct either in the earlier version. */ ++#define StopBecon BIT(6) ++#define StopHigh BIT(5) ++#define StopMgt BIT(4) ++#define StopBK BIT(3) ++#define StopBE BIT(2) ++#define StopVI BIT(1) ++#define StopVO BIT(0) ++ ++/* 8192C (RCR) Receive Configuration Register(Offset 0x608, 32 bits) */ ++#define RCR_APPFCS BIT(31) /* WMAC append FCS after payload */ ++#define RCR_APP_MIC BIT(30) ++#define RCR_APP_PHYSTS BIT(28) ++#define RCR_APP_ICV BIT(29) ++#define RCR_APP_PHYST_RXFF BIT(28) ++#define RCR_APP_BA_SSN BIT(27) /* Accept BA SSN */ ++#define RCR_ENMBID BIT(24) /* Enable Multiple BssId. */ ++#define RCR_LSIGEN BIT(23) ++#define RCR_MFBEN BIT(22) ++#define RCR_HTC_LOC_CTRL BIT(14) /* MFC<--HTC=1 MFC-->HTC=0 */ ++#define RCR_AMF BIT(13) /* Accept management type frame */ ++#define RCR_ACF BIT(12) /* Accept control type frame */ ++#define RCR_ADF BIT(11) /* Accept data type frame */ ++#define RCR_AICV BIT(9) /* Accept ICV error packet */ ++#define RCR_ACRC32 BIT(8) /* Accept CRC32 error packet */ ++#define RCR_CBSSID_BCN BIT(7) /* Accept BSSID match packet ++ * (Rx beacon, probe rsp) */ ++#define RCR_CBSSID_DATA BIT(6) /* Accept BSSID match (Data)*/ ++#define RCR_CBSSID RCR_CBSSID_DATA /* Accept BSSID match */ ++#define RCR_APWRMGT BIT(5) /* Accept power management pkt*/ ++#define RCR_ADD3 BIT(4) /* Accept address 3 match pkt */ ++#define RCR_AB BIT(3) /* Accept broadcast packet */ ++#define RCR_AM BIT(2) /* Accept multicast packet */ ++#define RCR_APM BIT(1) /* Accept physical match pkt */ ++#define RCR_AAP BIT(0) /* Accept all unicast packet */ ++#define RCR_MXDMA_OFFSET 8 ++#define RCR_FIFO_OFFSET 13 ++ ++/* 0xFE00h ~ 0xFE55h USB Configuration */ ++#define REG_USB_INFO 0xFE17 ++#define REG_USB_SPECIAL_OPTION 0xFE55 ++#define REG_USB_DMA_AGG_TO 0xFE5B ++#define REG_USB_AGG_TO 0xFE5C ++#define REG_USB_AGG_TH 0xFE5D ++ ++#define REG_USB_HRPWM 0xFE58 ++#define REG_USB_HCPWM 0xFE57 ++/* 8192C Regsiter Bit and Content definition */ ++/* 0x0000h ~ 0x00FFh System Configuration */ ++ ++/* 2 SYS_ISO_CTRL */ ++#define ISO_MD2PP BIT(0) ++#define ISO_UA2USB BIT(1) ++#define ISO_UD2CORE BIT(2) ++#define ISO_PA2PCIE BIT(3) ++#define ISO_PD2CORE BIT(4) ++#define ISO_IP2MAC BIT(5) ++#define ISO_DIOP BIT(6) ++#define ISO_DIOE BIT(7) ++#define ISO_EB2CORE BIT(8) ++#define ISO_DIOR BIT(9) ++#define PWC_EV12V BIT(15) ++ ++/* 2 SYS_FUNC_EN */ ++#define FEN_BBRSTB BIT(0) ++#define FEN_BB_GLB_RSTn BIT(1) ++#define FEN_USBA BIT(2) ++#define FEN_UPLL BIT(3) ++#define FEN_USBD BIT(4) ++#define FEN_DIO_PCIE BIT(5) ++#define FEN_PCIEA BIT(6) ++#define FEN_PPLL BIT(7) ++#define FEN_PCIED BIT(8) ++#define FEN_DIOE BIT(9) ++#define FEN_CPUEN BIT(10) ++#define FEN_DCORE BIT(11) ++#define FEN_ELDR BIT(12) ++#define FEN_DIO_RF BIT(13) ++#define FEN_HWPDN BIT(14) ++#define FEN_MREGEN BIT(15) ++ ++/* 2 APS_FSMCO */ ++#define PFM_LDALL BIT(0) ++#define PFM_ALDN BIT(1) ++#define PFM_LDKP BIT(2) ++#define PFM_WOWL BIT(3) ++#define EnPDN BIT(4) ++#define PDN_PL BIT(5) ++#define APFM_ONMAC BIT(8) ++#define APFM_OFF BIT(9) ++#define APFM_RSM BIT(10) ++#define AFSM_HSUS BIT(11) ++#define AFSM_PCIE BIT(12) ++#define APDM_MAC BIT(13) ++#define APDM_HOST BIT(14) ++#define APDM_HPDN BIT(15) ++#define RDY_MACON BIT(16) ++#define SUS_HOST BIT(17) ++#define ROP_ALD BIT(20) ++#define ROP_PWR BIT(21) ++#define ROP_SPS BIT(22) ++#define SOP_MRST BIT(25) ++#define SOP_FUSE BIT(26) ++#define SOP_ABG BIT(27) ++#define SOP_AMB BIT(28) ++#define SOP_RCK BIT(29) ++#define SOP_A8M BIT(30) ++#define XOP_BTCK BIT(31) ++ ++/* 2 SYS_CLKR */ ++#define ANAD16V_EN BIT(0) ++#define ANA8M BIT(1) ++#define MACSLP BIT(4) ++#define LOADER_CLK_EN BIT(5) ++ ++/* 2 9346CR */ ++ ++#define BOOT_FROM_EEPROM BIT(4) ++#define EEPROM_EN BIT(5) ++ ++/* 2 SPS0_CTRL */ ++ ++/* 2 SPS_OCP_CFG */ ++ ++/* 2 RF_CTRL */ ++#define RF_EN BIT(0) ++#define RF_RSTB BIT(1) ++#define RF_SDMRSTB BIT(2) ++ ++/* 2 LDOV12D_CTRL */ ++#define LDV12_EN BIT(0) ++#define LDV12_SDBY BIT(1) ++#define LPLDO_HSM BIT(2) ++#define LPLDO_LSM_DIS BIT(3) ++#define _LDV12_VADJ(x) (((x) & 0xF) << 4) ++ ++/* 2EFUSE_CTRL */ ++#define ALD_EN BIT(18) ++#define EF_PD BIT(19) ++#define EF_FLAG BIT(31) ++ ++/* 2 EFUSE_TEST (For RTL8723 partially) */ ++#define EF_TRPT BIT(7) ++/* 00: Wifi Efuse, 01: BT Efuse0, 10: BT Efuse1, 11: BT Efuse2 */ ++#define EF_CELL_SEL (BIT(8)|BIT(9)) ++#define LDOE25_EN BIT(31) ++#define EFUSE_SEL(x) (((x) & 0x3) << 8) ++#define EFUSE_SEL_MASK 0x300 ++#define EFUSE_WIFI_SEL_0 0x0 ++#define EFUSE_BT_SEL_0 0x1 ++#define EFUSE_BT_SEL_1 0x2 ++#define EFUSE_BT_SEL_2 0x3 ++ ++#define EFUSE_ACCESS_ON 0x69 /* For RTL8723 only. */ ++#define EFUSE_ACCESS_OFF 0x00 /* For RTL8723 only. */ ++ ++/* 2 8051FWDL */ ++/* 2 MCUFWDL */ ++#define MCUFWDL_EN BIT(0) ++#define MCUFWDL_RDY BIT(1) ++#define FWDL_ChkSum_rpt BIT(2) ++#define MACINI_RDY BIT(3) ++#define BBINI_RDY BIT(4) ++#define RFINI_RDY BIT(5) ++#define WINTINI_RDY BIT(6) ++#define RAM_DL_SEL BIT(7) /* 1:RAM, 0:ROM */ ++#define ROM_DLEN BIT(19) ++#define CPRST BIT(23) ++ ++/* 2 REG_SYS_CFG */ ++#define XCLK_VLD BIT(0) ++#define ACLK_VLD BIT(1) ++#define UCLK_VLD BIT(2) ++#define PCLK_VLD BIT(3) ++#define PCIRSTB BIT(4) ++#define V15_VLD BIT(5) ++#define SW_OFFLOAD_EN BIT(7) ++#define SIC_IDLE BIT(8) ++#define BD_MAC2 BIT(9) ++#define BD_MAC1 BIT(10) ++#define IC_MACPHY_MODE BIT(11) ++#define CHIP_VER (BIT(12)|BIT(13)|BIT(14)|BIT(15)) ++#define BT_FUNC BIT(16) ++#define VENDOR_ID BIT(19) ++#define PAD_HWPD_IDN BIT(22) ++#define TRP_VAUX_EN BIT(23) /* RTL ID */ ++#define TRP_BT_EN BIT(24) ++#define BD_PKG_SEL BIT(25) ++#define BD_HCI_SEL BIT(26) ++#define TYPE_ID BIT(27) ++ ++#define CHIP_VER_RTL_MASK 0xF000 /* Bit 12 ~ 15 */ ++#define CHIP_VER_RTL_SHIFT 12 ++ ++/* 2REG_GPIO_OUTSTS (For RTL8723 only) */ ++#define EFS_HCI_SEL (BIT(0)|BIT(1)) ++#define PAD_HCI_SEL (BIT(2)|BIT(3)) ++#define HCI_SEL (BIT(4)|BIT(5)) ++#define PKG_SEL_HCI BIT(6) ++#define FEN_GPS BIT(7) ++#define FEN_BT BIT(8) ++#define FEN_WL BIT(9) ++#define FEN_PCI BIT(10) ++#define FEN_USB BIT(11) ++#define BTRF_HWPDN_N BIT(12) ++#define WLRF_HWPDN_N BIT(13) ++#define PDN_BT_N BIT(14) ++#define PDN_GPS_N BIT(15) ++#define BT_CTL_HWPDN BIT(16) ++#define GPS_CTL_HWPDN BIT(17) ++#define PPHY_SUSB BIT(20) ++#define UPHY_SUSB BIT(21) ++#define PCI_SUSEN BIT(22) ++#define USB_SUSEN BIT(23) ++#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28)) ++ ++/* 2SYS_CFG */ ++#define RTL_ID BIT(23) /* TestChip ID, 1:Test(RLE); 0:MP(RL) */ ++ ++/* 0x0100h ~ 0x01FFh MACTOP General Configuration */ ++ ++/* 2 Function Enable Registers */ ++/* 2 CR */ ++ ++#define HCI_TXDMA_EN BIT(0) ++#define HCI_RXDMA_EN BIT(1) ++#define TXDMA_EN BIT(2) ++#define RXDMA_EN BIT(3) ++#define PROTOCOL_EN BIT(4) ++#define SCHEDULE_EN BIT(5) ++#define MACTXEN BIT(6) ++#define MACRXEN BIT(7) ++#define ENSWBCN BIT(8) ++#define ENSEC BIT(9) ++#define CALTMR_EN BIT(10) /* 32k CAL TMR enable */ ++ ++/* Network type */ ++#define _NETTYPE(x) (((x) & 0x3) << 16) ++#define MASK_NETTYPE 0x30000 ++#define NT_NO_LINK 0x0 ++#define NT_LINK_AD_HOC 0x1 ++#define NT_LINK_AP 0x2 ++#define NT_AS_AP 0x3 ++ ++/* 2 PBP - Page Size Register */ ++#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) ++#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) ++#define _PSRX_MASK 0xF ++#define _PSTX_MASK 0xF0 ++#define _PSRX(x) (x) ++#define _PSTX(x) ((x) << 4) ++ ++#define PBP_64 0x0 ++#define PBP_128 0x1 ++#define PBP_256 0x2 ++#define PBP_512 0x3 ++#define PBP_1024 0x4 ++ ++/* 2 TX/RXDMA */ ++#define RXDMA_ARBBW_EN BIT(0) ++#define RXSHFT_EN BIT(1) ++#define RXDMA_AGG_EN BIT(2) ++#define QS_VO_QUEUE BIT(8) ++#define QS_VI_QUEUE BIT(9) ++#define QS_BE_QUEUE BIT(10) ++#define QS_BK_QUEUE BIT(11) ++#define QS_MANAGER_QUEUE BIT(12) ++#define QS_HIGH_QUEUE BIT(13) ++ ++#define HQSEL_VOQ BIT(0) ++#define HQSEL_VIQ BIT(1) ++#define HQSEL_BEQ BIT(2) ++#define HQSEL_BKQ BIT(3) ++#define HQSEL_MGTQ BIT(4) ++#define HQSEL_HIQ BIT(5) ++ ++/* For normal driver, 0x10C */ ++#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) ++#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) ++#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) ++#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8 ) ++#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6 ) ++#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4 ) ++ ++#define QUEUE_LOW 1 ++#define QUEUE_NORMAL 2 ++#define QUEUE_HIGH 3 ++ ++/* 2 TRXFF_BNDY */ ++ ++/* 2 LLT_INIT */ ++#define _LLT_NO_ACTIVE 0x0 ++#define _LLT_WRITE_ACCESS 0x1 ++#define _LLT_READ_ACCESS 0x2 ++ ++#define _LLT_INIT_DATA(x) ((x) & 0xFF) ++#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) ++#define _LLT_OP(x) (((x) & 0x3) << 30) ++#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) ++ ++/* 0x0200h ~ 0x027Fh TXDMA Configuration */ ++/* 2RQPN */ ++#define _HPQ(x) ((x) & 0xFF) ++#define _LPQ(x) (((x) & 0xFF) << 8) ++#define _PUBQ(x) (((x) & 0xFF) << 16) ++/* NOTE: in RQPN_NPQ register */ ++#define _NPQ(x) ((x) & 0xFF) ++ ++#define HPQ_PUBLIC_DIS BIT(24) ++#define LPQ_PUBLIC_DIS BIT(25) ++#define LD_RQPN BIT(31) ++ ++/* 2TDECTRL */ ++#define BCN_VALID BIT(16) ++#define BCN_HEAD(x) (((x) & 0xFF) << 8) ++#define BCN_HEAD_MASK 0xFF00 ++ ++/* 2 TDECTL */ ++#define BLK_DESC_NUM_SHIFT 4 ++#define BLK_DESC_NUM_MASK 0xF ++ ++/* 2 TXDMA_OFFSET_CHK */ ++#define DROP_DATA_EN BIT(9) ++ ++/* 0x0280h ~ 0x028Bh RX DMA Configuration */ ++ ++/* REG_RXDMA_CONTROL, 0x0286h */ ++ ++/* 2 REG_RXPKT_NUM, 0x0284 */ ++#define RXPKT_RELEASE_POLL BIT(16) ++#define RXDMA_IDLE BIT(17) ++#define RW_RELEASE_EN BIT(18) ++ ++/* 0x0400h ~ 0x047Fh Protocol Configuration */ ++/* 2 FWHW_TXQ_CTRL */ ++#define EN_AMPDU_RTY_NEW BIT(7) ++ ++/* 2 SPEC SIFS */ ++#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) ++#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) ++ ++/* 2 RL */ ++#define RETRY_LIMIT_SHORT_SHIFT 8 ++#define RETRY_LIMIT_LONG_SHIFT 0 ++ ++/* 0x0500h ~ 0x05FFh EDCA Configuration */ ++ ++/* 2 EDCA setting */ ++#define AC_PARAM_TXOP_LIMIT_OFFSET 16 ++#define AC_PARAM_ECW_MAX_OFFSET 12 ++#define AC_PARAM_ECW_MIN_OFFSET 8 ++#define AC_PARAM_AIFS_OFFSET 0 ++ ++#define _LRL(x) ((x) & 0x3F) ++#define _SRL(x) (((x) & 0x3F) << 8) ++ ++/* 2 BCN_CTRL */ ++#define EN_MBSSID BIT(1) ++#define EN_TXBCN_RPT BIT(2) ++#define EN_BCN_FUNCTION BIT(3) ++#define DIS_TSF_UPDATE BIT(3) ++ ++/* The same function but different bit field. */ ++#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) ++#define DIS_TSF_UDT0_TEST_CHIP BIT(5) ++#define STOP_BCNQ BIT(6) ++ ++/* 2 ACMHWCTRL */ ++#define AcmHw_HwEn BIT(0) ++#define AcmHw_BeqEn BIT(1) ++#define AcmHw_ViqEn BIT(2) ++#define AcmHw_VoqEn BIT(3) ++#define AcmHw_BeqStatus BIT(4) ++#define AcmHw_ViqStatus BIT(5) ++#define AcmHw_VoqStatus BIT(6) ++ ++/* 0x0600h ~ 0x07FFh WMAC Configuration */ ++/* 2APSD_CTRL */ ++#define APSDOFF BIT(6) ++#define APSDOFF_STATUS BIT(7) ++ ++#define RATE_BITMAP_ALL 0xFFFFF ++ ++/* Only use CCK 1M rate for ACK */ ++#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 ++ ++/* 2 TCR */ ++#define TSFRST BIT(0) ++#define DIS_GCLK BIT(1) ++#define PAD_SEL BIT(2) ++#define PWR_ST BIT(6) ++#define PWRBIT_OW_EN BIT(7) ++#define ACRC BIT(8) ++#define CFENDFORM BIT(9) ++#define ICV BIT(10) ++ ++/* 2 RCR */ ++#define AAP BIT(0) ++#define APM BIT(1) ++#define AM BIT(2) ++#define AB BIT(3) ++#define ADD3 BIT(4) ++#define APWRMGT BIT(5) ++#define CBSSID BIT(6) ++#define CBSSID_DATA BIT(6) ++#define CBSSID_BCN BIT(7) ++#define ACRC32 BIT(8) ++#define AICV BIT(9) ++#define ADF BIT(11) ++#define ACF BIT(12) ++#define AMF BIT(13) ++#define HTC_LOC_CTRL BIT(14) ++#define UC_DATA_EN BIT(16) ++#define BM_DATA_EN BIT(17) ++#define MFBEN BIT(22) ++#define LSIGEN BIT(23) ++#define EnMBID BIT(24) ++#define APP_BASSN BIT(27) ++#define APP_PHYSTS BIT(28) ++#define APP_ICV BIT(29) ++#define APP_MIC BIT(30) ++#define APP_FCS BIT(31) ++ ++/* 2 SECCFG */ ++#define SCR_TxUseDK BIT(0) /* Force Tx Use Default Key */ ++#define SCR_RxUseDK BIT(1) /* Force Rx Use Default Key */ ++#define SCR_TxEncEnable BIT(2) /* Enable Tx Encryption */ ++#define SCR_RxDecEnable BIT(3) /* Enable Rx Decryption */ ++#define SCR_SKByA2 BIT(4) /* Search kEY BY A2 */ ++#define SCR_NoSKMC BIT(5) /* No Key Search Multicast */ ++#define SCR_TXBCUSEDK BIT(6) /* Force Tx Bcast pkt Use Default Key */ ++#define SCR_RXBCUSEDK BIT(7) /* Force Rx Bcast pkt Use Default Key */ ++ ++/* RTL8188E SDIO Configuration */ ++ ++/* I/O bus domain address mapping */ ++#define SDIO_LOCAL_BASE 0x10250000 ++#define WLAN_IOREG_BASE 0x10260000 ++#define FIRMWARE_FIFO_BASE 0x10270000 ++#define TX_HIQ_BASE 0x10310000 ++#define TX_MIQ_BASE 0x10320000 ++#define TX_LOQ_BASE 0x10330000 ++#define RX_RX0FF_BASE 0x10340000 ++ ++/* SDIO host local register space mapping. */ ++#define SDIO_LOCAL_MSK 0x0FFF ++#define WLAN_IOREG_MSK 0x7FFF ++#define WLAN_FIFO_MSK 0x1FFF /* Aggregation Length[12:0] */ ++#define WLAN_RX0FF_MSK 0x0003 ++ ++/* Without ref to the SDIO Device ID */ ++#define SDIO_WITHOUT_REF_DEVICE_ID 0 ++#define SDIO_LOCAL_DEVICE_ID 0 /* 0b[16], 000b[15:13] */ ++#define WLAN_TX_HIQ_DEVICE_ID 4 /* 0b[16], 100b[15:13] */ ++#define WLAN_TX_MIQ_DEVICE_ID 5 /* 0b[16], 101b[15:13] */ ++#define WLAN_TX_LOQ_DEVICE_ID 6 /* 0b[16], 110b[15:13] */ ++#define WLAN_RX0FF_DEVICE_ID 7 /* 0b[16], 111b[15:13] */ ++#define WLAN_IOREG_DEVICE_ID 8 /* 1b[16] */ ++ ++/* SDIO Tx Free Page Index */ ++#define HI_QUEUE_IDX 0 ++#define MID_QUEUE_IDX 1 ++#define LOW_QUEUE_IDX 2 ++#define PUBLIC_QUEUE_IDX 3 ++ ++#define SDIO_MAX_TX_QUEUE 3 /* HIQ, MIQ and LOQ */ ++#define SDIO_MAX_RX_QUEUE 1 ++ ++/* SDIO Tx Control */ ++#define SDIO_REG_TX_CTRL 0x0000 ++/* SDIO Host Interrupt Mask */ ++#define SDIO_REG_HIMR 0x0014 ++/* SDIO Host Interrupt Service Routine */ ++#define SDIO_REG_HISR 0x0018 ++/* HCI Current Power Mode */ ++#define SDIO_REG_HCPWM 0x0019 ++/* RXDMA Request Length */ ++#define SDIO_REG_RX0_REQ_LEN 0x001C ++/* Free Tx Buffer Page */ ++#define SDIO_REG_FREE_TXPG 0x0020 ++/* HCI Current Power Mode 1 */ ++#define SDIO_REG_HCPWM1 0x0024 ++/* HCI Current Power Mode 2 */ ++#define SDIO_REG_HCPWM2 0x0026 ++/* HTSF Informaion */ ++#define SDIO_REG_HTSFR_INFO 0x0030 ++/* HCI Request Power Mode 1 */ ++#define SDIO_REG_HRPWM1 0x0080 ++/* HCI Request Power Mode 2 */ ++#define SDIO_REG_HRPWM2 0x0082 ++/* HCI Power Save Clock */ ++#define SDIO_REG_HPS_CLKR 0x0084 ++/* SDIO HCI Suspend Control */ ++#define SDIO_REG_HSUS_CTRL 0x0086 ++/* SDIO Host Extension Interrupt Mask Always */ ++#define SDIO_REG_HIMR_ON 0x0090 ++/* SDIO Host Extension Interrupt Status Always */ ++#define SDIO_REG_HISR_ON 0x0091 ++ ++#define SDIO_HIMR_DISABLED 0 ++ ++/* RTL8188E SDIO Host Interrupt Mask Register */ ++#define SDIO_HIMR_RX_REQUEST_MSK BIT(0) ++#define SDIO_HIMR_AVAL_MSK BIT(1) ++#define SDIO_HIMR_TXERR_MSK BIT(2) ++#define SDIO_HIMR_RXERR_MSK BIT(3) ++#define SDIO_HIMR_TXFOVW_MSK BIT(4) ++#define SDIO_HIMR_RXFOVW_MSK BIT(5) ++#define SDIO_HIMR_TXBCNOK_MSK BIT(6) ++#define SDIO_HIMR_TXBCNERR_MSK BIT(7) ++#define SDIO_HIMR_BCNERLY_INT_MSK BIT(16) ++#define SDIO_HIMR_C2HCMD_MSK BIT(17) ++#define SDIO_HIMR_CPWM1_MSK BIT(18) ++#define SDIO_HIMR_CPWM2_MSK BIT(19) ++#define SDIO_HIMR_HSISR_IND_MSK BIT(20) ++#define SDIO_HIMR_GTINT3_IND_MSK BIT(21) ++#define SDIO_HIMR_GTINT4_IND_MSK BIT(22) ++#define SDIO_HIMR_PSTIMEOUT_MSK BIT(23) ++#define SDIO_HIMR_OCPINT_MSK BIT(24) ++#define SDIO_HIMR_ATIMEND_MSK BIT(25) ++#define SDIO_HIMR_ATIMEND_E_MSK BIT(26) ++#define SDIO_HIMR_CTWEND_MSK BIT(27) ++ ++/* RTL8188E SDIO Specific */ ++#define SDIO_HIMR_MCU_ERR_MSK BIT(28) ++#define SDIO_HIMR_TSF_BIT32_TOGGLE_MSK BIT(29) ++ ++/* SDIO Host Interrupt Service Routine */ ++#define SDIO_HISR_RX_REQUEST BIT(0) ++#define SDIO_HISR_AVAL BIT(1) ++#define SDIO_HISR_TXERR BIT(2) ++#define SDIO_HISR_RXERR BIT(3) ++#define SDIO_HISR_TXFOVW BIT(4) ++#define SDIO_HISR_RXFOVW BIT(5) ++#define SDIO_HISR_TXBCNOK BIT(6) ++#define SDIO_HISR_TXBCNERR BIT(7) ++#define SDIO_HISR_BCNERLY_INT BIT(16) ++#define SDIO_HISR_C2HCMD BIT(17) ++#define SDIO_HISR_CPWM1 BIT(18) ++#define SDIO_HISR_CPWM2 BIT(19) ++#define SDIO_HISR_HSISR_IND BIT(20) ++#define SDIO_HISR_GTINT3_IND BIT(21) ++#define SDIO_HISR_GTINT4_IND BIT(22) ++#define SDIO_HISR_PSTIME BIT(23) ++#define SDIO_HISR_OCPINT BIT(24) ++#define SDIO_HISR_ATIMEND BIT(25) ++#define SDIO_HISR_ATIMEND_E BIT(26) ++#define SDIO_HISR_CTWEND BIT(27) ++ ++/* RTL8188E SDIO Specific */ ++#define SDIO_HISR_MCU_ERR BIT(28) ++#define SDIO_HISR_TSF_BIT32_TOGGLE BIT(29) ++ ++#define MASK_SDIO_HISR_CLEAR \ ++ (SDIO_HISR_TXERR | SDIO_HISR_RXERR | SDIO_HISR_TXFOVW |\ ++ SDIO_HISR_RXFOVW | SDIO_HISR_TXBCNOK | SDIO_HISR_TXBCNERR |\ ++ SDIO_HISR_C2HCMD | SDIO_HISR_CPWM1 | SDIO_HISR_CPWM2 |\ ++ SDIO_HISR_HSISR_IND | SDIO_HISR_GTINT3_IND | SDIO_HISR_GTINT4_IND |\ ++ SDIO_HISR_PSTIMEOUT | SDIO_HISR_OCPINT) ++ ++/* SDIO HCI Suspend Control Register */ ++#define HCI_RESUME_PWR_RDY BIT(1) ++#define HCI_SUS_CTRL BIT(0) ++ ++/* SDIO Tx FIFO related */ ++/* The number of Tx FIFO free page */ ++#define SDIO_TX_FREE_PG_QUEUE 4 ++#define SDIO_TX_FIFO_PAGE_SZ 128 ++ ++/* 0xFE00h ~ 0xFE55h USB Configuration */ ++ ++/* 2 USB Information (0xFE17) */ ++#define USB_IS_HIGH_SPEED 0 ++#define USB_IS_FULL_SPEED 1 ++#define USB_SPEED_MASK BIT(5) ++ ++#define USB_NORMAL_SIE_EP_MASK 0xF ++#define USB_NORMAL_SIE_EP_SHIFT 4 ++ ++/* 2 Special Option */ ++#define USB_AGG_EN BIT(3) ++ ++/* 0; Use interrupt endpoint to upload interrupt pkt */ ++/* 1; Use bulk endpoint to upload interrupt pkt, */ ++#define INT_BULK_SEL BIT(4) ++ ++/* 2REG_C2HEVT_CLEAR */ ++/* Set by driver and notify FW that the driver has read ++ * the C2H command message */ ++#define C2H_EVT_HOST_CLOSE 0x00 ++/* Set by FW indicating that FW had set the C2H command ++ * message and it's not yet read by driver. */ ++#define C2H_EVT_FW_CLOSE 0xFF ++ ++/* 2REG_MULTI_FUNC_CTRL(For RTL8723 Only) */ ++/* Enable GPIO[9] as WiFi HW PDn source */ ++#define WL_HWPDN_EN BIT(0) ++/* WiFi HW PDn polarity control */ ++#define WL_HWPDN_SL BIT(1) ++/* WiFi function enable */ ++#define WL_FUNC_EN BIT(2) ++/* Enable GPIO[9] as WiFi RF HW PDn source */ ++#define WL_HWROF_EN BIT(3) ++/* Enable GPIO[11] as BT HW PDn source */ ++#define BT_HWPDN_EN BIT(16) ++/* BT HW PDn polarity control */ ++#define BT_HWPDN_SL BIT(17) ++/* BT function enable */ ++#define BT_FUNC_EN BIT(18) ++/* Enable GPIO[11] as BT/GPS RF HW PDn source */ ++#define BT_HWROF_EN BIT(19) ++/* Enable GPIO[10] as GPS HW PDn source */ ++#define GPS_HWPDN_EN BIT(20) ++/* GPS HW PDn polarity control */ ++#define GPS_HWPDN_SL BIT(21) ++/* GPS function enable */ ++#define GPS_FUNC_EN BIT(22) ++ ++/* 3 REG_LIFECTRL_CTRL */ ++#define HAL92C_EN_PKT_LIFE_TIME_BK BIT(3) ++#define HAL92C_EN_PKT_LIFE_TIME_BE BIT(2) ++#define HAL92C_EN_PKT_LIFE_TIME_VI BIT(1) ++#define HAL92C_EN_PKT_LIFE_TIME_VO BIT(0) ++ ++#define HAL92C_MSDU_LIFE_TIME_UNIT 128 /* in us */ ++ ++/* General definitions */ ++#define LAST_ENTRY_OF_TX_PKT_BUFFER 176 /* 22k 22528 bytes */ ++ ++#define POLLING_LLT_THRESHOLD 20 ++#define POLLING_READY_TIMEOUT_COUNT 1000 ++/* GPIO BIT */ ++#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) ++ ++/* 8192C EEPROM/EFUSE share register definition. */ ++ ++/* EEPROM/Efuse PG Offset for 88EE/88EU/88ES */ ++#define EEPROM_TX_PWR_INX_88E 0x10 ++ ++#define EEPROM_ChannelPlan_88E 0xB8 ++#define EEPROM_XTAL_88E 0xB9 ++#define EEPROM_THERMAL_METER_88E 0xBA ++#define EEPROM_IQK_LCK_88E 0xBB ++ ++#define EEPROM_RF_BOARD_OPTION_88E 0xC1 ++#define EEPROM_RF_FEATURE_OPTION_88E 0xC2 ++#define EEPROM_RF_BT_SETTING_88E 0xC3 ++#define EEPROM_VERSION_88E 0xC4 ++#define EEPROM_CUSTOMERID_88E 0xC5 ++#define EEPROM_RF_ANTENNA_OPT_88E 0xC9 ++ ++/* RTL88EE */ ++#define EEPROM_MAC_ADDR_88EE 0xD0 ++#define EEPROM_VID_88EE 0xD6 ++#define EEPROM_DID_88EE 0xD8 ++#define EEPROM_SVID_88EE 0xDA ++#define EEPROM_SMID_88EE 0xDC ++ ++/* RTL88EU */ ++#define EEPROM_MAC_ADDR_88EU 0xD7 ++#define EEPROM_VID_88EU 0xD0 ++#define EEPROM_PID_88EU 0xD2 ++#define EEPROM_USB_OPTIONAL_FUNCTION0 0xD4 ++ ++/* RTL88ES */ ++#define EEPROM_MAC_ADDR_88ES 0x11A ++ ++/* EEPROM/Efuse Value Type */ ++#define EETYPE_TX_PWR 0x0 ++ ++/* Default Value for EEPROM or EFUSE!!! */ ++#define EEPROM_Default_TSSI 0x0 ++#define EEPROM_Default_TxPowerDiff 0x0 ++#define EEPROM_Default_CrystalCap 0x5 ++/* Default: 2X2, RTL8192CE(QFPN68) */ ++#define EEPROM_Default_BoardType 0x02 ++#define EEPROM_Default_TxPower 0x1010 ++#define EEPROM_Default_HT2T_TxPwr 0x10 ++ ++#define EEPROM_Default_LegacyHTTxPowerDiff 0x3 ++#define EEPROM_Default_ThermalMeter 0x12 ++ ++#define EEPROM_Default_AntTxPowerDiff 0x0 ++#define EEPROM_Default_TxPwDiff_CrystalCap 0x5 ++#define EEPROM_Default_TxPowerLevel 0x2A ++ ++#define EEPROM_Default_HT40_2SDiff 0x0 ++/* HT20<->40 default Tx Power Index Difference */ ++#define EEPROM_Default_HT20_Diff 2 ++#define EEPROM_Default_LegacyHTTxPowerDiff 0x3 ++#define EEPROM_Default_HT40_PwrMaxOffset 0 ++#define EEPROM_Default_HT20_PwrMaxOffset 0 ++ ++#define EEPROM_Default_CrystalCap_88E 0x20 ++#define EEPROM_Default_ThermalMeter_88E 0x18 ++ ++/* New EFUSE deafult value */ ++#define EEPROM_DEFAULT_24G_INDEX 0x2D ++#define EEPROM_DEFAULT_24G_HT20_DIFF 0X02 ++#define EEPROM_DEFAULT_24G_OFDM_DIFF 0X04 ++ ++#define EEPROM_DEFAULT_DIFF 0XFE ++#define EEPROM_DEFAULT_CHANNEL_PLAN 0x7F ++#define EEPROM_DEFAULT_BOARD_OPTION 0x00 ++#define EEPROM_DEFAULT_FEATURE_OPTION 0x00 ++#define EEPROM_DEFAULT_BT_OPTION 0x10 ++ ++/* For debug */ ++#define EEPROM_Default_PID 0x1234 ++#define EEPROM_Default_VID 0x5678 ++#define EEPROM_Default_CustomerID 0xAB ++#define EEPROM_Default_CustomerID_8188E 0x00 ++#define EEPROM_Default_SubCustomerID 0xCD ++#define EEPROM_Default_Version 0 ++ ++#define EEPROM_CHANNEL_PLAN_FCC 0x0 ++#define EEPROM_CHANNEL_PLAN_IC 0x1 ++#define EEPROM_CHANNEL_PLAN_ETSI 0x2 ++#define EEPROM_CHANNEL_PLAN_SPA 0x3 ++#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 ++#define EEPROM_CHANNEL_PLAN_MKK 0x5 ++#define EEPROM_CHANNEL_PLAN_MKK1 0x6 ++#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 ++#define EEPROM_CHANNEL_PLAN_TELEC 0x8 ++#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMA 0x9 ++#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA ++#define EEPROM_CHANNEL_PLAN_NCC 0xB ++#define EEPROM_USB_OPTIONAL1 0xE ++#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 ++ ++#define EEPROM_CID_DEFAULT 0x0 ++#define EEPROM_CID_TOSHIBA 0x4 ++#define EEPROM_CID_CCX 0x10 /* CCX test. */ ++#define EEPROM_CID_QMI 0x0D ++#define EEPROM_CID_WHQL 0xFE ++#define RTL_EEPROM_ID 0x8129 ++ ++#endif /* __RTL8188E_SPEC_H__ */ +diff --git a/drivers/staging/r8188eu/include/rtl8188e_sreset.h b/drivers/staging/r8188eu/include/rtl8188e_sreset.h +new file mode 100644 +index 000000000000..880c5792d5dd +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_sreset.h +@@ -0,0 +1,15 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTL8188E_SRESET_H_ ++#define _RTL8188E_SRESET_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "rtw_sreset.h" ++ ++void rtl8188e_silentreset_for_specific_platform(struct adapter *padapter); ++void rtl8188e_sreset_xmit_status_check(struct adapter *padapter); ++void rtl8188e_sreset_linked_status_check(struct adapter *padapter); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtl8188e_xmit.h b/drivers/staging/r8188eu/include/rtl8188e_xmit.h +new file mode 100644 +index 000000000000..f1f2ccfc765e +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtl8188e_xmit.h +@@ -0,0 +1,150 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTL8188E_XMIT_H__ ++#define __RTL8188E_XMIT_H__ ++ ++#define MAX_TX_AGG_PACKET_NUMBER 0xFF ++/* */ ++/* Queue Select Value in TxDesc */ ++/* */ ++#define QSLT_BK 0x2/* 0x01 */ ++#define QSLT_BE 0x0 ++#define QSLT_VI 0x5/* 0x4 */ ++#define QSLT_VO 0x7/* 0x6 */ ++#define QSLT_BEACON 0x10 ++#define QSLT_HIGH 0x11 ++#define QSLT_MGNT 0x12 ++#define QSLT_CMD 0x13 ++ ++/* For 88e early mode */ ++#define SET_EARLYMODE_PKTNUM(__paddr, __value) \ ++ le32p_replace_bits((__le32 *)__paddr, __value, GENMASK(2, 0)) ++#define SET_EARLYMODE_LEN0(__pAddr, __Value) \ ++ le32p_replace_bits((__le32 *)__paddr, __value, GENMASK(15, 4)) ++#define SET_EARLYMODE_LEN1(__paddr, __value) \ ++ le32p_replace_bits((__le32 *)__paddr, __value, GENMASK(27, 16)) ++#define SET_EARLYMODE_LEN2_1(__pdr, __vValue) \ ++ le32p_replace_bits((__le32 *)__paddr, __value, GENMASK(31, 28)) ++#define SET_EARLYMODE_LEN2_2(__paddr, __value) \ ++ le32p_replace_bits((__le32 *)(__paddr + 4), __value, GENMASK(7, 0)) ++#define SET_EARLYMODE_LEN3(__pAddr, __Value) \ ++ le32p_replace_bits((__le32 *)(__paddr + 4), __value, GENMASK(19, 8)) ++#define SET_EARLYMODE_LEN4(__paAddr, __vValue) \ ++ le32p_replace_bits((__le32 *)(__paddr + 4), __value, GENMASK(31, 20)) ++ ++/* defined for TX DESC Operation */ ++ ++#define MAX_TID (15) ++ ++/* OFFSET 0 */ ++#define OFFSET_SZ 0 ++#define OFFSET_SHT 16 ++#define BMC BIT(24) ++#define LSG BIT(26) ++#define FSG BIT(27) ++#define OWN BIT(31) ++ ++/* OFFSET 4 */ ++#define PKT_OFFSET_SZ 0 ++#define QSEL_SHT 8 ++#define RATE_ID_SHT 16 ++#define NAVUSEHDR BIT(20) ++#define SEC_TYPE_SHT 22 ++#define PKT_OFFSET_SHT 26 ++ ++/* OFFSET 8 */ ++#define AGG_EN BIT(12) ++#define AGG_BK BIT(16) ++#define AMPDU_DENSITY_SHT 20 ++#define ANTSEL_A BIT(24) ++#define ANTSEL_B BIT(25) ++#define TX_ANT_CCK_SHT 26 ++#define TX_ANTL_SHT 28 ++#define TX_ANT_HT_SHT 30 ++ ++/* OFFSET 12 */ ++#define SEQ_SHT 16 ++#define EN_HWSEQ BIT(31) ++ ++/* OFFSET 16 */ ++#define QOS BIT(6) ++#define HW_SSN BIT(7) ++#define USERATE BIT(8) ++#define DISDATAFB BIT(10) ++#define CTS_2_SELF BIT(11) ++#define RTS_EN BIT(12) ++#define HW_RTS_EN BIT(13) ++#define DATA_SHORT BIT(24) ++#define PWR_STATUS_SHT 15 ++#define DATA_SC_SHT 20 ++#define DATA_BW BIT(25) ++ ++/* OFFSET 20 */ ++#define RTY_LMT_EN BIT(17) ++ ++enum TXDESC_SC { ++ SC_DONT_CARE = 0x00, ++ SC_UPPER = 0x01, ++ SC_LOWER = 0x02, ++ SC_DUPLICATE = 0x03 ++}; ++/* OFFSET 20 */ ++#define SGI BIT(6) ++#define USB_TXAGG_NUM_SHT 24 ++ ++#define txdesc_set_ccx_sw_88e(txdesc, value) \ ++ do { \ ++ ((struct txdesc_88e *)(txdesc))->sw1 = (((value)>>8) & 0x0f); \ ++ ((struct txdesc_88e *)(txdesc))->sw0 = ((value) & 0xff); \ ++ } while (0) ++ ++struct txrpt_ccx_88e { ++ /* offset 0 */ ++ u8 tag1:1; ++ u8 pkt_num:3; ++ u8 txdma_underflow:1; ++ u8 int_bt:1; ++ u8 int_tri:1; ++ u8 int_ccx:1; ++ ++ /* offset 1 */ ++ u8 mac_id:6; ++ u8 pkt_ok:1; ++ u8 bmc:1; ++ ++ /* offset 2 */ ++ u8 retry_cnt:6; ++ u8 lifetime_over:1; ++ u8 retry_over:1; ++ ++ /* offset 3 */ ++ u8 ccx_qtime0; ++ u8 ccx_qtime1; ++ ++ /* offset 5 */ ++ u8 final_data_rate; ++ ++ /* offset 6 */ ++ u8 sw1:4; ++ u8 qsel:4; ++ ++ /* offset 7 */ ++ u8 sw0; ++}; ++ ++void rtl8188e_fill_fake_txdesc(struct adapter *padapter, u8 *pDesc, ++ u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull); ++s32 rtl8188eu_init_xmit_priv(struct adapter *padapter); ++s32 rtl8188eu_hal_xmit(struct adapter *padapter, struct xmit_frame *frame); ++s32 rtl8188eu_mgnt_xmit(struct adapter *padapter, struct xmit_frame *frame); ++s32 rtl8188eu_xmit_buf_handler(struct adapter *padapter); ++#define hal_xmit_handler rtl8188eu_xmit_buf_handler ++void rtl8188eu_xmit_tasklet(unsigned long priv); ++s32 rtl8188eu_xmitframe_complete(struct adapter *padapter, ++ struct xmit_priv *pxmitpriv, ++ struct xmit_buf *pxmitbuf); ++ ++void handle_txrpt_ccx_88e(struct adapter *adapter, u8 *buf); ++ ++#endif /* __RTL8188E_XMIT_H__ */ +diff --git a/drivers/staging/r8188eu/include/rtw_ap.h b/drivers/staging/r8188eu/include/rtw_ap.h +new file mode 100644 +index 000000000000..2eb556968509 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_ap.h +@@ -0,0 +1,47 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#ifndef __RTW_AP_H_ ++#define __RTW_AP_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++/* external function */ ++void rtw_indicate_sta_assoc_event(struct adapter *padapter, ++ struct sta_info *psta); ++void rtw_indicate_sta_disassoc_event(struct adapter *padapter, ++ struct sta_info *psta); ++void init_mlme_ap_info(struct adapter *padapter); ++void free_mlme_ap_info(struct adapter *padapter); ++void update_beacon(struct adapter *padapter, u8 ie_id, ++ u8 *oui, u8 tx); ++void add_RATid(struct adapter *padapter, struct sta_info *psta, ++ u8 rssi_level); ++void expire_timeout_chk(struct adapter *padapter); ++void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta); ++int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len); ++void rtw_ap_restore_network(struct adapter *padapter); ++void rtw_set_macaddr_acl(struct adapter *padapter, int mode); ++int rtw_acl_add_sta(struct adapter *padapter, u8 *addr); ++int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr); ++ ++#ifdef CONFIG_88EU_AP_MODE ++void associated_clients_update(struct adapter *padapter, u8 updated); ++void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta); ++u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta); ++void sta_info_update(struct adapter *padapter, struct sta_info *psta); ++void ap_sta_info_defer_update(struct adapter *padapter, struct sta_info *psta); ++u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta, ++ bool active, u16 reason); ++int rtw_sta_flush(struct adapter *padapter); ++int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset); ++void start_ap_mode(struct adapter *padapter); ++void stop_ap_mode(struct adapter *padapter); ++#endif ++#endif /* end of CONFIG_88EU_AP_MODE */ ++void update_bmc_sta(struct adapter *padapter); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_br_ext.h b/drivers/staging/r8188eu/include/rtw_br_ext.h +new file mode 100644 +index 000000000000..69905d30c191 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_br_ext.h +@@ -0,0 +1,49 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_BR_EXT_H_ ++#define _RTW_BR_EXT_H_ ++ ++#define MACADDRLEN 6 ++#define _DEBUG_ERR DBG_88E ++#define _DEBUG_INFO DBG_88E ++#define DEBUG_WARN DBG_88E ++#define DEBUG_INFO DBG_88E ++#define DEBUG_ERR DBG_88E ++#define GET_MY_HWADDR(padapter) ((padapter)->eeprompriv.mac_addr) ++ ++#define NAT25_HASH_BITS 4 ++#define NAT25_HASH_SIZE (1 << NAT25_HASH_BITS) ++#define NAT25_AGEING_TIME 300 ++ ++#define MAX_NETWORK_ADDR_LEN 17 ++ ++struct nat25_network_db_entry { ++ struct nat25_network_db_entry *next_hash; ++ struct nat25_network_db_entry **pprev_hash; ++ atomic_t use_count; ++ unsigned char macAddr[6]; ++ unsigned long ageing_timer; ++ unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; ++}; ++ ++enum NAT25_METHOD { ++ NAT25_MIN, ++ NAT25_CHECK, ++ NAT25_INSERT, ++ NAT25_PARSE, ++ NAT25_MAX ++}; ++ ++struct br_ext_info { ++ unsigned int nat25_disable; ++ unsigned int macclone_enable; ++ unsigned int dhcp_bcst_disable; ++ int addPPPoETag; /* 1: Add PPPoE relay-SID, 0: disable */ ++ unsigned char nat25_dmzMac[MACADDRLEN]; ++ unsigned int nat25sc_disable; ++}; ++ ++void nat25_db_cleanup(struct adapter *priv); ++ ++#endif /* _RTW_BR_EXT_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_cmd.h b/drivers/staging/r8188eu/include/rtw_cmd.h +new file mode 100644 +index 000000000000..c14d9052b997 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_cmd.h +@@ -0,0 +1,975 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_CMD_H_ ++#define __RTW_CMD_H_ ++ ++#include "wlan_bssdef.h" ++#include "rtw_rf.h" ++#include "rtw_led.h" ++ ++#define C2H_MEM_SZ (16*1024) ++ ++#include "osdep_service.h" ++#include "ieee80211.h" /* */ ++ ++#define FREE_CMDOBJ_SZ 128 ++ ++#define MAX_CMDSZ 1024 ++#define MAX_RSPSZ 512 ++#define MAX_EVTSZ 1024 ++ ++#define CMDBUFF_ALIGN_SZ 512 ++ ++struct cmd_obj { ++ struct adapter *padapter; ++ u16 cmdcode; ++ u8 res; ++ u8 *parmbuf; ++ u32 cmdsz; ++ u8 *rsp; ++ u32 rspsz; ++ struct list_head list; ++}; ++ ++struct cmd_priv { ++ struct semaphore cmd_queue_sema; ++ struct semaphore terminate_cmdthread_sema; ++ struct __queue cmd_queue; ++ u8 cmd_seq; ++ u8 *cmd_buf; /* shall be non-paged, and 4 bytes aligned */ ++ u8 *cmd_allocated_buf; ++ u8 *rsp_buf; /* shall be non-paged, and 4 bytes aligned */ ++ u8 *rsp_allocated_buf; ++ u32 cmd_issued_cnt; ++ u32 cmd_done_cnt; ++ u32 rsp_cnt; ++ u8 cmdthd_running; ++ struct adapter *padapter; ++}; ++ ++struct evt_priv { ++ struct work_struct c2h_wk; ++ bool c2h_wk_alive; ++ struct rtw_cbuf *c2h_queue; ++ #define C2H_QUEUE_MAX_LEN 10 ++ atomic_t event_seq; ++ u8 *evt_buf; /* shall be non-paged, and 4 bytes aligned */ ++ u8 *evt_allocated_buf; ++ u32 evt_done_cnt; ++}; ++ ++#define init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code) \ ++do {\ ++ INIT_LIST_HEAD(&pcmd->list);\ ++ pcmd->cmdcode = code;\ ++ pcmd->parmbuf = (u8 *)(pparm);\ ++ pcmd->cmdsz = sizeof(*pparm);\ ++ pcmd->rsp = NULL;\ ++ pcmd->rspsz = 0;\ ++} while (0) ++ ++struct c2h_evt_hdr { ++ u8 id:4; ++ u8 plen:4; ++ u8 seq; ++ u8 payload[0]; ++}; ++ ++#define c2h_evt_exist(c2h_evt) ((c2h_evt)->id || (c2h_evt)->plen) ++ ++u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *obj); ++struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv); ++void rtw_free_cmd_obj(struct cmd_obj *pcmd); ++ ++int rtw_cmd_thread(void *context); ++ ++u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv); ++void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv); ++ ++u32 rtw_init_evt_priv(struct evt_priv *pevtpriv); ++void rtw_free_evt_priv(struct evt_priv *pevtpriv); ++void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv); ++void rtw_evt_notify_isr(struct evt_priv *pevtpriv); ++#ifdef CONFIG_88EU_P2P ++u8 p2p_protocol_wk_cmd(struct adapter *padapter, int intCmdType); ++#endif /* CONFIG_88EU_P2P */ ++ ++enum rtw_drvextra_cmd_id { ++ NONE_WK_CID, ++ DYNAMIC_CHK_WK_CID, ++ DM_CTRL_WK_CID, ++ PBC_POLLING_WK_CID, ++ POWER_SAVING_CTRL_WK_CID,/* IPS,AUTOSuspend */ ++ LPS_CTRL_WK_CID, ++ ANT_SELECT_WK_CID, ++ P2P_PS_WK_CID, ++ P2P_PROTO_WK_CID, ++ CHECK_HIQ_WK_CID,/* for softap mode, check hi queue if empty */ ++ INTEl_WIDI_WK_CID, ++ C2H_WK_CID, ++ RTP_TIMER_CFG_WK_CID, ++ MAX_WK_CID ++}; ++ ++enum LPS_CTRL_TYPE { ++ LPS_CTRL_SCAN = 0, ++ LPS_CTRL_JOINBSS = 1, ++ LPS_CTRL_CONNECT = 2, ++ LPS_CTRL_DISCONNECT = 3, ++ LPS_CTRL_SPECIAL_PACKET = 4, ++ LPS_CTRL_LEAVE = 5, ++}; ++ ++enum RFINTFS { ++ SWSI, ++ HWSI, ++ HWPI, ++}; ++ ++/* ++Caller Mode: Infra, Ad-HoC(C) ++ ++Notes: To enter USB suspend mode ++ ++Command Mode ++ ++*/ ++struct usb_suspend_parm { ++ u32 action;/* 1: sleep, 0:resume */ ++}; ++ ++/* ++Caller Mode: Infra, Ad-HoC ++ ++Notes: To join a known BSS. ++ ++Command-Event Mode ++ ++*/ ++ ++/* ++Caller Mode: Infra, Ad-Hoc ++ ++Notes: To join the specified bss ++ ++Command Event Mode ++ ++*/ ++struct joinbss_parm { ++ struct wlan_bssid_ex network; ++}; ++ ++/* ++Caller Mode: Infra, Ad-HoC(C) ++ ++Notes: To disconnect the current associated BSS ++ ++Command Mode ++ ++*/ ++struct disconnect_parm { ++ u32 deauth_timeout_ms; ++}; ++ ++/* ++Caller Mode: AP, Ad-HoC(M) ++ ++Notes: To create a BSS ++ ++Command Mode ++*/ ++struct createbss_parm { ++ struct wlan_bssid_ex network; ++}; ++ ++struct setopmode_parm { ++ u8 mode; ++ u8 rsvd[3]; ++}; ++ ++/* ++Caller Mode: AP, Ad-HoC, Infra ++ ++Notes: To ask RTL8711 performing site-survey ++ ++Command-Event Mode ++ ++*/ ++ ++#define RTW_SSID_SCAN_AMOUNT 9 /* for WEXT_CSCAN_AMOUNT 9 */ ++#define RTW_CHANNEL_SCAN_AMOUNT (14+37) ++struct sitesurvey_parm { ++ int scan_mode; /* active: 1, passive: 0 */ ++ u8 ssid_num; ++ u8 ch_num; ++ struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT]; ++ struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT]; ++}; ++ ++/* ++Caller Mode: Any ++ ++Notes: To set the auth type of RTL8711. open/shared/802.1x ++ ++Command Mode ++ ++*/ ++struct setauth_parm { ++ u8 mode; /* 0: legacy open, 1: legacy shared 2: 802.1x */ ++ u8 _1x; /* 0: PSK, 1: TLS */ ++ u8 rsvd[2]; ++}; ++ ++/* ++Caller Mode: Infra ++ ++a. algorithm: wep40, wep104, tkip & aes ++b. keytype: grp key/unicast key ++c. key contents ++ ++when shared key ==> keyid is the camid ++when 802.1x ==> keyid [0:1] ==> grp key ++when 802.1x ==> keyid > 2 ==> unicast key ++ ++*/ ++struct setkey_parm { ++ u8 algorithm; /* could be none, wep40, TKIP, CCMP, wep104 */ ++ u8 keyid; ++ u8 grpkey; /* 1: this is the grpkey for 802.1x. ++ * 0: this is the unicast key for 802.1x */ ++ u8 set_tx; /* 1: main tx key for wep. 0: other key. */ ++ u8 key[16]; /* this could be 40 or 104 */ ++}; ++ ++/* ++When in AP or Ad-Hoc mode, this is used to ++allocate an sw/hw entry for a newly associated sta. ++ ++Command ++ ++when shared key ==> algorithm/keyid ++ ++*/ ++struct set_stakey_parm { ++ u8 addr[ETH_ALEN]; ++ u8 algorithm; ++ u8 id;/* currently for erasing cam entry if ++ * algorithm == _NO_PRIVACY_ */ ++ u8 key[16]; ++}; ++ ++struct set_stakey_rsp { ++ u8 addr[ETH_ALEN]; ++ u8 keyid; ++ u8 rsvd; ++}; ++ ++/* ++Caller Ad-Hoc/AP ++ ++Command -Rsp(AID == CAMID) mode ++ ++This is to force fw to add an sta_data entry per driver's request. ++ ++FW will write an cam entry associated with it. ++ ++*/ ++struct set_assocsta_parm { ++ u8 addr[ETH_ALEN]; ++}; ++ ++struct set_assocsta_rsp { ++ u8 cam_id; ++ u8 rsvd[3]; ++}; ++ ++/* ++ Caller Ad-Hoc/AP ++ ++ Command mode ++ ++ This is to force fw to del an sta_data entry per driver's request ++ ++ FW will invalidate the cam entry associated with it. ++ ++*/ ++struct del_assocsta_parm { ++ u8 addr[ETH_ALEN]; ++}; ++ ++/* ++Caller Mode: AP/Ad-HoC(M) ++ ++Notes: To notify fw that given staid has changed its power state ++ ++Command Mode ++ ++*/ ++struct setstapwrstate_parm { ++ u8 staid; ++ u8 status; ++ u8 hwaddr[6]; ++}; ++ ++/* ++Caller Mode: Any ++ ++Notes: To setup the basic rate of RTL8711 ++ ++Command Mode ++ ++*/ ++struct setbasicrate_parm { ++ u8 basicrates[NumRates]; ++}; ++ ++/* ++Caller Mode: Any ++ ++Notes: To read the current basic rate ++ ++Command-Rsp Mode ++ ++*/ ++struct getbasicrate_parm { ++ u32 rsvd; ++}; ++ ++struct getbasicrate_rsp { ++ u8 basicrates[NumRates]; ++}; ++ ++/* ++Caller Mode: Any ++ ++Notes: To setup the data rate of RTL8711 ++ ++Command Mode ++ ++*/ ++struct setdatarate_parm { ++ u8 mac_id; ++ u8 datarates[NumRates]; ++}; ++ ++/* ++Caller Mode: Any ++ ++Notes: To read the current data rate ++ ++Command-Rsp Mode ++ ++*/ ++struct getdatarate_parm { ++ u32 rsvd; ++ ++}; ++struct getdatarate_rsp { ++ u8 datarates[NumRates]; ++}; ++ ++/* ++Caller Mode: Any ++AP: AP can use the info for the contents of beacon frame ++Infra: STA can use the info when sitesurveying ++Ad-HoC(M): Like AP ++Ad-HoC(C): Like STA ++ ++Notes: To set the phy capability of the NIC ++ ++Command Mode ++ ++*/ ++ ++struct setphyinfo_parm { ++ struct regulatory_class class_sets[NUM_REGULATORYS]; ++ u8 status; ++}; ++ ++struct getphyinfo_parm { ++ u32 rsvd; ++}; ++ ++struct getphyinfo_rsp { ++ struct regulatory_class class_sets[NUM_REGULATORYS]; ++ u8 status; ++}; ++ ++/* ++Caller Mode: Any ++ ++Notes: To set the channel/modem/band ++This command will be used when channel/modem/band is changed. ++ ++Command Mode ++ ++*/ ++struct setphy_parm { ++ u8 rfchannel; ++ u8 modem; ++}; ++ ++/* ++Caller Mode: Any ++ ++Notes: To get the current setting of channel/modem/band ++ ++Command-Rsp Mode ++ ++*/ ++struct getphy_parm { ++ u32 rsvd; ++ ++}; ++struct getphy_rsp { ++ u8 rfchannel; ++ u8 modem; ++}; ++ ++struct readBB_parm { ++ u8 offset; ++}; ++struct readBB_rsp { ++ u8 value; ++}; ++ ++struct readTSSI_parm { ++ u8 offset; ++}; ++struct readTSSI_rsp { ++ u8 value; ++}; ++ ++struct writeBB_parm { ++ u8 offset; ++ u8 value; ++}; ++ ++struct readRF_parm { ++ u8 offset; ++}; ++struct readRF_rsp { ++ u32 value; ++}; ++ ++struct writeRF_parm { ++ u32 offset; ++ u32 value; ++}; ++ ++struct getrfintfs_parm { ++ u8 rfintfs; ++}; ++ ++struct Tx_Beacon_param ++{ ++ struct wlan_bssid_ex network; ++}; ++ ++/* ++ Notes: This command is used for H2C/C2H loopback testing ++ ++ mac[0] == 0 ++ ==> CMD mode, return H2C_SUCCESS. ++ The following condition must be ture under CMD mode ++ mac[1] == mac[4], mac[2] == mac[3], mac[0]=mac[5]= 0; ++ s0 == 0x1234, s1 == 0xabcd, w0 == 0x78563412, w1 == 0x5aa5def7; ++ s2 == (b1 << 8 | b0); ++ ++ mac[0] == 1 ++ ==> CMD_RSP mode, return H2C_SUCCESS_RSP ++ ++ The rsp layout shall be: ++ rsp: parm: ++ mac[0] = mac[5]; ++ mac[1] = mac[4]; ++ mac[2] = mac[3]; ++ mac[3] = mac[2]; ++ mac[4] = mac[1]; ++ mac[5] = mac[0]; ++ s0 = s1; ++ s1 = swap16(s0); ++ w0 = swap32(w1); ++ b0 = b1 ++ s2 = s0 + s1 ++ b1 = b0 ++ w1 = w0 ++ ++ mac[0] == 2 ++ ==> CMD_EVENT mode, return H2C_SUCCESS ++ The event layout shall be: ++ event: parm: ++ mac[0] = mac[5]; ++ mac[1] = mac[4]; ++ mac[2] = event's seq no, starting from 1 to parm's marc[3] ++ mac[3] = mac[2]; ++ mac[4] = mac[1]; ++ mac[5] = mac[0]; ++ s0 = swap16(s0) - event.mac[2]; ++ s1 = s1 + event.mac[2]; ++ w0 = swap32(w0); ++ b0 = b1 ++ s2 = s0 + event.mac[2] ++ b1 = b0 ++ w1 = swap32(w1) - event.mac[2]; ++ ++ parm->mac[3] is the total event counts that host requested. ++ event will be the same with the cmd's param. ++*/ ++ ++/* CMD param Format for driver extra cmd handler */ ++struct drvextra_cmd_parm { ++ int ec_id; /* extra cmd id */ ++ int type_size; /* Can use this field as the type id or command size */ ++ unsigned char *pbuf; ++}; ++ ++/*------------------- Below are used for RF/BB tunning ---------------------*/ ++ ++struct setantenna_parm { ++ u8 tx_antset; ++ u8 rx_antset; ++ u8 tx_antenna; ++ u8 rx_antenna; ++}; ++ ++struct enrateadaptive_parm { ++ u32 en; ++}; ++ ++struct settxagctbl_parm { ++ u32 txagc[MAX_RATES_LENGTH]; ++}; ++ ++struct gettxagctbl_parm { ++ u32 rsvd; ++}; ++struct gettxagctbl_rsp { ++ u32 txagc[MAX_RATES_LENGTH]; ++}; ++ ++struct setagcctrl_parm { ++ u32 agcctrl; /* 0: pure hw, 1: fw */ ++}; ++ ++struct setssup_parm { ++ u32 ss_ForceUp[MAX_RATES_LENGTH]; ++}; ++ ++struct getssup_parm { ++ u32 rsvd; ++}; ++ ++struct getssup_rsp { ++ u8 ss_ForceUp[MAX_RATES_LENGTH]; ++}; ++ ++struct setssdlevel_parm { ++ u8 ss_DLevel[MAX_RATES_LENGTH]; ++}; ++ ++struct getssdlevel_parm { ++ u32 rsvd; ++}; ++ ++struct getssdlevel_rsp { ++ u8 ss_DLevel[MAX_RATES_LENGTH]; ++}; ++ ++struct setssulevel_parm { ++ u8 ss_ULevel[MAX_RATES_LENGTH]; ++}; ++ ++struct getssulevel_parm { ++ u32 rsvd; ++}; ++ ++struct getssulevel_rsp { ++ u8 ss_ULevel[MAX_RATES_LENGTH]; ++}; ++ ++struct setcountjudge_parm { ++ u8 count_judge[MAX_RATES_LENGTH]; ++}; ++ ++struct getcountjudge_parm { ++ u32 rsvd; ++}; ++ ++struct getcountjudge_rsp { ++ u8 count_judge[MAX_RATES_LENGTH]; ++}; ++ ++struct setratable_parm { ++ u8 ss_ForceUp[NumRates]; ++ u8 ss_ULevel[NumRates]; ++ u8 ss_DLevel[NumRates]; ++ u8 count_judge[NumRates]; ++}; ++ ++struct getratable_parm { ++ uint rsvd; ++}; ++ ++struct getratable_rsp { ++ u8 ss_ForceUp[NumRates]; ++ u8 ss_ULevel[NumRates]; ++ u8 ss_DLevel[NumRates]; ++ u8 count_judge[NumRates]; ++}; ++ ++/* to get TX,RX retry count */ ++ ++struct gettxretrycnt_parm { ++ unsigned int rsvd; ++}; ++ ++struct gettxretrycnt_rsp { ++ unsigned long tx_retrycnt; ++}; ++ ++struct getrxretrycnt_parm { ++ unsigned int rsvd; ++}; ++ ++struct getrxretrycnt_rsp { ++ unsigned long rx_retrycnt; ++}; ++ ++/* to get BCNOK,BCNERR count */ ++struct getbcnokcnt_parm { ++ unsigned int rsvd; ++}; ++ ++struct getbcnokcnt_rsp { ++ unsigned long bcnokcnt; ++}; ++ ++struct getbcnerrcnt_parm { ++ unsigned int rsvd; ++}; ++ ++struct getbcnerrcnt_rsp { ++ unsigned long bcnerrcnt; ++}; ++ ++/* to get current TX power level */ ++struct getcurtxpwrlevel_parm { ++ unsigned int rsvd; ++}; ++struct getcurtxpwrlevel_rspi { ++ unsigned short tx_power; ++}; ++ ++struct setprobereqextraie_parm { ++ unsigned char e_id; ++ unsigned char ie_len; ++ unsigned char ie[0]; ++}; ++ ++struct setassocreqextraie_parm { ++ unsigned char e_id; ++ unsigned char ie_len; ++ unsigned char ie[0]; ++}; ++ ++struct setproberspextraie_parm { ++ unsigned char e_id; ++ unsigned char ie_len; ++ unsigned char ie[0]; ++}; ++ ++struct setassocrspextraie_parm { ++ unsigned char e_id; ++ unsigned char ie_len; ++ unsigned char ie[0]; ++}; ++ ++struct addBaReq_parm { ++ unsigned int tid; ++ u8 addr[ETH_ALEN]; ++}; ++ ++/*H2C Handler index: 46 */ ++struct set_ch_parm { ++ u8 ch; ++ u8 bw; ++ u8 ch_offset; ++}; ++ ++/*H2C Handler index: 59 */ ++struct SetChannelPlan_param ++{ ++ u8 channel_plan; ++}; ++ ++/*H2C Handler index: 60 */ ++struct LedBlink_param ++{ ++ struct LED_871x *pLed; ++}; ++ ++/*H2C Handler index: 61 */ ++struct SetChannelSwitch_param ++{ ++ u8 new_ch_no; ++}; ++ ++/*H2C Handler index: 62 */ ++struct TDLSoption_param ++{ ++ u8 addr[ETH_ALEN]; ++ u8 option; ++}; ++ ++#define GEN_CMD_CODE(cmd) cmd ## _CMD_ ++ ++/* ++ ++Result: ++0x00: success ++0x01: success, and check Response. ++0x02: cmd ignored due to duplicated sequcne number ++0x03: cmd dropped due to invalid cmd code ++0x04: reserved. ++ ++*/ ++ ++#define H2C_RSP_OFFSET 512 ++ ++#define H2C_SUCCESS 0x00 ++#define H2C_SUCCESS_RSP 0x01 ++#define H2C_DUPLICATED 0x02 ++#define H2C_DROPPED 0x03 ++#define H2C_PARAMETERS_ERROR 0x04 ++#define H2C_REJECTED 0x05 ++#define H2C_CMD_OVERFLOW 0x06 ++#define H2C_RESERVED 0x07 ++ ++u8 rtw_setassocsta_cmd(struct adapter *padapter, u8 *mac_addr); ++u8 rtw_setstandby_cmd(struct adapter *padapter, uint action); ++u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, ++ int ssid_num, struct rtw_ieee80211_channel *ch, ++ int ch_num); ++u8 rtw_createbss_cmd(struct adapter *padapter); ++u8 rtw_createbss_cmd_ex(struct adapter *padapter, unsigned char *pbss, ++ unsigned int sz); ++u8 rtw_setphy_cmd(struct adapter *padapter, u8 modem, u8 ch); ++u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key); ++u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry, u8 enqueue); ++u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network* pnetwork); ++u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueue); ++u8 rtw_setopmode_cmd(struct adapter *padapter, enum ndis_802_11_network_infra networktype); ++u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset); ++u8 rtw_setbasicrate_cmd(struct adapter *padapter, u8 *rateset); ++u8 rtw_setbbreg_cmd(struct adapter * padapter, u8 offset, u8 val); ++u8 rtw_setrfreg_cmd(struct adapter * padapter, u8 offset, u32 val); ++u8 rtw_getbbreg_cmd(struct adapter * padapter, u8 offset, u8 * pval); ++u8 rtw_getrfreg_cmd(struct adapter * padapter, u8 offset, u8 * pval); ++u8 rtw_setrfintfs_cmd(struct adapter *padapter, u8 mode); ++u8 rtw_setrttbl_cmd(struct adapter *padapter, struct setratable_parm *prate_table); ++u8 rtw_getrttbl_cmd(struct adapter *padapter, struct getratable_rsp *pval); ++ ++u8 rtw_gettssi_cmd(struct adapter *padapter, u8 offset,u8 *pval); ++u8 rtw_setfwdig_cmd(struct adapter*padapter, u8 type); ++u8 rtw_setfwra_cmd(struct adapter*padapter, u8 type); ++ ++u8 rtw_addbareq_cmd(struct adapter*padapter, u8 tid, u8 *addr); ++ ++u8 rtw_dynamic_chk_wk_cmd(struct adapter *adapter); ++ ++u8 rtw_lps_ctrl_wk_cmd(struct adapter*padapter, u8 lps_ctrl_type, u8 enqueue); ++u8 rtw_rpt_timer_cfg_cmd(struct adapter*padapter, u16 minRptTime); ++ ++ u8 rtw_antenna_select_cmd(struct adapter*padapter, u8 antenna,u8 enqueue); ++u8 rtw_ps_cmd(struct adapter*padapter); ++ ++#ifdef CONFIG_88EU_AP_MODE ++u8 rtw_chk_hi_queue_cmd(struct adapter*padapter); ++#endif ++ ++u8 rtw_set_ch_cmd(struct adapter*padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue); ++u8 rtw_set_chplan_cmd(struct adapter*padapter, u8 chplan, u8 enqueue); ++u8 rtw_led_blink_cmd(struct adapter*padapter, struct LED_871x * pLed); ++u8 rtw_set_csa_cmd(struct adapter*padapter, u8 new_ch_no); ++u8 rtw_tdls_cmd(struct adapter *padapter, u8 *addr, u8 option); ++ ++u8 rtw_c2h_wk_cmd(struct adapter *padapter, u8 *c2h_evt); ++ ++u8 rtw_drvextra_cmd_hdl(struct adapter *padapter, unsigned char *pbuf); ++ ++void rtw_survey_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd); ++void rtw_disassoc_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd); ++void rtw_joinbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd); ++void rtw_createbss_cmd_callback(struct adapter *adapt, struct cmd_obj *pcmd); ++void rtw_getbbrfreg_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cmd); ++void rtw_readtssi_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cmd); ++ ++void rtw_setstaKey_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cmd); ++void rtw_setassocsta_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cm); ++void rtw_getrttbl_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cmd); ++ ++struct _cmd_callback { ++ u32 cmd_code; ++ void (*callback)(struct adapter *padapter, struct cmd_obj *cmd); ++}; ++ ++enum rtw_h2c_cmd { ++ GEN_CMD_CODE(_Read_MACREG), /*0*/ ++ GEN_CMD_CODE(_Write_MACREG), ++ GEN_CMD_CODE(_Read_BBREG), ++ GEN_CMD_CODE(_Write_BBREG), ++ GEN_CMD_CODE(_Read_RFREG), ++ GEN_CMD_CODE(_Write_RFREG), /*5*/ ++ GEN_CMD_CODE(_Read_EEPROM), ++ GEN_CMD_CODE(_Write_EEPROM), ++ GEN_CMD_CODE(_Read_EFUSE), ++ GEN_CMD_CODE(_Write_EFUSE), ++ ++ GEN_CMD_CODE(_Read_CAM), /*10*/ ++ GEN_CMD_CODE(_Write_CAM), ++ GEN_CMD_CODE(_setBCNITV), ++ GEN_CMD_CODE(_setMBIDCFG), ++ GEN_CMD_CODE(_JoinBss), /*14*/ ++ GEN_CMD_CODE(_DisConnect), /*15*/ ++ GEN_CMD_CODE(_CreateBss), ++ GEN_CMD_CODE(_SetOpMode), ++ GEN_CMD_CODE(_SiteSurvey), /*18*/ ++ GEN_CMD_CODE(_SetAuth), ++ ++ GEN_CMD_CODE(_SetKey), /*20*/ ++ GEN_CMD_CODE(_SetStaKey), ++ GEN_CMD_CODE(_SetAssocSta), ++ GEN_CMD_CODE(_DelAssocSta), ++ GEN_CMD_CODE(_SetStaPwrState), ++ GEN_CMD_CODE(_SetBasicRate), /*25*/ ++ GEN_CMD_CODE(_GetBasicRate), ++ GEN_CMD_CODE(_SetDataRate), ++ GEN_CMD_CODE(_GetDataRate), ++ GEN_CMD_CODE(_SetPhyInfo), ++ ++ GEN_CMD_CODE(_GetPhyInfo), /*30*/ ++ GEN_CMD_CODE(_SetPhy), ++ GEN_CMD_CODE(_GetPhy), ++ GEN_CMD_CODE(_readRssi), ++ GEN_CMD_CODE(_readGain), ++ GEN_CMD_CODE(_SetAtim), /*35*/ ++ GEN_CMD_CODE(_SetPwrMode), ++ GEN_CMD_CODE(_JoinbssRpt), ++ GEN_CMD_CODE(_SetRaTable), ++ GEN_CMD_CODE(_GetRaTable), ++ ++ GEN_CMD_CODE(_GetCCXReport), /*40*/ ++ GEN_CMD_CODE(_GetDTMReport), ++ GEN_CMD_CODE(_GetTXRateStatistics), ++ GEN_CMD_CODE(_SetUsbSuspend), ++ GEN_CMD_CODE(_SetH2cLbk), ++ GEN_CMD_CODE(_AddBAReq), /*45*/ ++ GEN_CMD_CODE(_SetChannel), /*46*/ ++ GEN_CMD_CODE(_SetTxPower), ++ GEN_CMD_CODE(_SwitchAntenna), ++ GEN_CMD_CODE(_SetCrystalCap), ++ GEN_CMD_CODE(_SetSingleCarrierTx), /*50*/ ++ ++ GEN_CMD_CODE(_SetSingleToneTx),/*51*/ ++ GEN_CMD_CODE(_SetCarrierSuppressionTx), ++ GEN_CMD_CODE(_SetContinuousTx), ++ GEN_CMD_CODE(_SwitchBandwidth), /*54*/ ++ GEN_CMD_CODE(_TX_Beacon), /*55*/ ++ ++ GEN_CMD_CODE(_Set_MLME_EVT), /*56*/ ++ GEN_CMD_CODE(_Set_Drv_Extra), /*57*/ ++ GEN_CMD_CODE(_Set_H2C_MSG), /*58*/ ++ ++ GEN_CMD_CODE(_SetChannelPlan), /*59*/ ++ GEN_CMD_CODE(_LedBlink), /*60*/ ++ ++ GEN_CMD_CODE(_SetChannelSwitch), /*61*/ ++ GEN_CMD_CODE(_TDLS), /*62*/ ++ ++ MAX_H2CCMD ++}; ++ ++#define _GetBBReg_CMD_ _Read_BBREG_CMD_ ++#define _SetBBReg_CMD_ _Write_BBREG_CMD_ ++#define _GetRFReg_CMD_ _Read_RFREG_CMD_ ++#define _SetRFReg_CMD_ _Write_RFREG_CMD_ ++ ++#ifdef _RTW_CMD_C_ ++static struct _cmd_callback rtw_cmd_callback[] = ++{ ++ {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/ ++ {GEN_CMD_CODE(_Write_MACREG), NULL}, ++ {GEN_CMD_CODE(_Read_BBREG), &rtw_getbbrfreg_cmdrsp_callback}, ++ {GEN_CMD_CODE(_Write_BBREG), NULL}, ++ {GEN_CMD_CODE(_Read_RFREG), &rtw_getbbrfreg_cmdrsp_callback}, ++ {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/ ++ {GEN_CMD_CODE(_Read_EEPROM), NULL}, ++ {GEN_CMD_CODE(_Write_EEPROM), NULL}, ++ {GEN_CMD_CODE(_Read_EFUSE), NULL}, ++ {GEN_CMD_CODE(_Write_EFUSE), NULL}, ++ ++ {GEN_CMD_CODE(_Read_CAM), NULL}, /*10*/ ++ {GEN_CMD_CODE(_Write_CAM), NULL}, ++ {GEN_CMD_CODE(_setBCNITV), NULL}, ++ {GEN_CMD_CODE(_setMBIDCFG), NULL}, ++ {GEN_CMD_CODE(_JoinBss), &rtw_joinbss_cmd_callback}, /*14*/ ++ {GEN_CMD_CODE(_DisConnect), &rtw_disassoc_cmd_callback}, /*15*/ ++ {GEN_CMD_CODE(_CreateBss), &rtw_createbss_cmd_callback}, ++ {GEN_CMD_CODE(_SetOpMode), NULL}, ++ {GEN_CMD_CODE(_SiteSurvey), &rtw_survey_cmd_callback}, /*18*/ ++ {GEN_CMD_CODE(_SetAuth), NULL}, ++ ++ {GEN_CMD_CODE(_SetKey), NULL}, /*20*/ ++ {GEN_CMD_CODE(_SetStaKey), &rtw_setstaKey_cmdrsp_callback}, ++ {GEN_CMD_CODE(_SetAssocSta), &rtw_setassocsta_cmdrsp_callback}, ++ {GEN_CMD_CODE(_DelAssocSta), NULL}, ++ {GEN_CMD_CODE(_SetStaPwrState), NULL}, ++ {GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/ ++ {GEN_CMD_CODE(_GetBasicRate), NULL}, ++ {GEN_CMD_CODE(_SetDataRate), NULL}, ++ {GEN_CMD_CODE(_GetDataRate), NULL}, ++ {GEN_CMD_CODE(_SetPhyInfo), NULL}, ++ ++ {GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/ ++ {GEN_CMD_CODE(_SetPhy), NULL}, ++ {GEN_CMD_CODE(_GetPhy), NULL}, ++ {GEN_CMD_CODE(_readRssi), NULL}, ++ {GEN_CMD_CODE(_readGain), NULL}, ++ {GEN_CMD_CODE(_SetAtim), NULL}, /*35*/ ++ {GEN_CMD_CODE(_SetPwrMode), NULL}, ++ {GEN_CMD_CODE(_JoinbssRpt), NULL}, ++ {GEN_CMD_CODE(_SetRaTable), NULL}, ++ {GEN_CMD_CODE(_GetRaTable), NULL}, ++ ++ {GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/ ++ {GEN_CMD_CODE(_GetDTMReport), NULL}, ++ {GEN_CMD_CODE(_GetTXRateStatistics), NULL}, ++ {GEN_CMD_CODE(_SetUsbSuspend), NULL}, ++ {GEN_CMD_CODE(_SetH2cLbk), NULL}, ++ {GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/ ++ {GEN_CMD_CODE(_SetChannel), NULL}, /*46*/ ++ {GEN_CMD_CODE(_SetTxPower), NULL}, ++ {GEN_CMD_CODE(_SwitchAntenna), NULL}, ++ {GEN_CMD_CODE(_SetCrystalCap), NULL}, ++ {GEN_CMD_CODE(_SetSingleCarrierTx), NULL}, /*50*/ ++ ++ {GEN_CMD_CODE(_SetSingleToneTx), NULL}, /*51*/ ++ {GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL}, ++ {GEN_CMD_CODE(_SetContinuousTx), NULL}, ++ {GEN_CMD_CODE(_SwitchBandwidth), NULL}, /*54*/ ++ {GEN_CMD_CODE(_TX_Beacon), NULL},/*55*/ ++ ++ {GEN_CMD_CODE(_Set_MLME_EVT), NULL},/*56*/ ++ {GEN_CMD_CODE(_Set_Drv_Extra), NULL},/*57*/ ++ {GEN_CMD_CODE(_Set_H2C_MSG), NULL},/*58*/ ++ {GEN_CMD_CODE(_SetChannelPlan), NULL},/*59*/ ++ {GEN_CMD_CODE(_LedBlink), NULL},/*60*/ ++ ++ {GEN_CMD_CODE(_SetChannelSwitch), NULL},/*61*/ ++ {GEN_CMD_CODE(_TDLS), NULL},/*62*/ ++}; ++#endif ++ ++#endif /* _CMD_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_debug.h b/drivers/staging/r8188eu/include/rtw_debug.h +new file mode 100644 +index 000000000000..3c3bf2a4f30e +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_debug.h +@@ -0,0 +1,231 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_DEBUG_H__ ++#define __RTW_DEBUG_H__ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define _drv_always_ 1 ++#define _drv_emerg_ 2 ++#define _drv_alert_ 3 ++#define _drv_crit_ 4 ++#define _drv_err_ 5 ++#define _drv_warning_ 6 ++#define _drv_notice_ 7 ++#define _drv_info_ 8 ++#define _drv_debug_ 9 ++ ++#define _module_rtl871x_xmit_c_ BIT(0) ++#define _module_xmit_osdep_c_ BIT(1) ++#define _module_rtl871x_recv_c_ BIT(2) ++#define _module_recv_osdep_c_ BIT(3) ++#define _module_rtl871x_mlme_c_ BIT(4) ++#define _module_mlme_osdep_c_ BIT(5) ++#define _module_rtl871x_sta_mgt_c_ BIT(6) ++#define _module_rtl871x_cmd_c_ BIT(7) ++#define _module_cmd_osdep_c_ BIT(8) ++#define _module_rtl871x_io_c_ BIT(9) ++#define _module_io_osdep_c_ BIT(10) ++#define _module_os_intfs_c_ BIT(11) ++#define _module_rtl871x_security_c_ BIT(12) ++#define _module_rtl871x_eeprom_c_ BIT(13) ++#define _module_hal_init_c_ BIT(14) ++#define _module_hci_hal_init_c_ BIT(15) ++#define _module_rtl871x_ioctl_c_ BIT(16) ++#define _module_rtl871x_ioctl_set_c_ BIT(17) ++#define _module_rtl871x_ioctl_query_c_ BIT(18) ++#define _module_rtl871x_pwrctrl_c_ BIT(19) ++#define _module_hci_intfs_c_ BIT(20) ++#define _module_hci_ops_c_ BIT(21) ++#define _module_osdep_service_c_ BIT(22) ++#define _module_mp_ BIT(23) ++#define _module_hci_ops_os_c_ BIT(24) ++#define _module_rtl871x_ioctl_os_c BIT(25) ++#define _module_rtl8712_cmd_c_ BIT(26) ++#define _module_rtl8192c_xmit_c_ BIT(27) ++#define _module_hal_xmit_c_ BIT(28) ++#define _module_efuse_ BIT(29) ++#define _module_rtl8712_recv_c_ BIT(30) ++#define _module_rtl8712_led_c_ BIT(31) ++ ++#define DRIVER_PREFIX "R8188EU: " ++ ++extern u32 GlobalDebugLevel; ++ ++#define DBG_88E_LEVEL(_level, fmt, arg...) \ ++ do { \ ++ if (_level <= GlobalDebugLevel) \ ++ pr_info(DRIVER_PREFIX"INFO " fmt, ##arg); \ ++ } while (0) ++ ++#define DBG_88E(...) \ ++ do { \ ++ if (_drv_err_ <= GlobalDebugLevel) \ ++ pr_info(DRIVER_PREFIX __VA_ARGS__); \ ++ } while (0) ++ ++#define MSG_88E(...) \ ++ do { \ ++ if (_drv_err_ <= GlobalDebugLevel) \ ++ pr_info(DRIVER_PREFIX __VA_ARGS__); \ ++ } while (0) ++ ++int proc_get_drv_version(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_write_reg(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_write_reg(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++int proc_get_read_reg(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_read_reg(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++ ++int proc_get_fwstate(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++int proc_get_sec_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++int proc_get_mlmext_state(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_qos_option(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++int proc_get_ht_option(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++int proc_get_rf_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++int proc_get_ap_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_adapter_state(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_trx_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_mac_reg_dump1(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_mac_reg_dump2(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_mac_reg_dump3(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_bb_reg_dump1(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_bb_reg_dump2(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_bb_reg_dump3(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_rf_reg_dump1(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_rf_reg_dump2(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_rf_reg_dump3(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_rf_reg_dump4(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++int proc_get_all_sta_info(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++#endif ++ ++int proc_get_best_channel(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_rx_signal(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_rx_signal(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++ ++int proc_get_ht_enable(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_ht_enable(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++ ++int proc_get_cbw40_enable(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_cbw40_enable(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++ ++int proc_get_ampdu_enable(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_ampdu_enable(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++ ++int proc_get_rx_stbc(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_rx_stbc(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++ ++int proc_get_two_path_rssi(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_get_rssi_disp(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_rssi_disp(struct file *file, const char __user *buffer, ++ unsigned long count, void *data); ++ ++#ifdef CONFIG_BT_COEXIST ++int proc_get_btcoex_dbg(char *page, char **start, ++ off_t offset, int count, ++ int *eof, void *data); ++ ++int proc_set_btcoex_dbg(struct file *file, const char *buffer, ++ signed long count, void *data); ++ ++#endif /* CONFIG_BT_COEXIST */ ++ ++#endif /* __RTW_DEBUG_H__ */ +diff --git a/drivers/staging/r8188eu/include/rtw_eeprom.h b/drivers/staging/r8188eu/include/rtw_eeprom.h +new file mode 100644 +index 000000000000..9f8a9c070339 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_eeprom.h +@@ -0,0 +1,114 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_EEPROM_H__ ++#define __RTW_EEPROM_H__ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define RTL8712_EEPROM_ID 0x8712 ++ ++#define HWSET_MAX_SIZE_512 512 ++#define EEPROM_MAX_SIZE HWSET_MAX_SIZE_512 ++ ++#define CLOCK_RATE 50 /* 100us */ ++ ++/* EEPROM opcodes */ ++#define EEPROM_READ_OPCODE 06 ++#define EEPROM_WRITE_OPCODE 05 ++#define EEPROM_ERASE_OPCODE 07 ++#define EEPROM_EWEN_OPCODE 19 /* Erase/write enable */ ++#define EEPROM_EWDS_OPCODE 16 /* Erase/write disable */ ++ ++/* Country codes */ ++#define USA 0x555320 ++#define EUROPE 0x1 /* temp, should be provided later */ ++#define JAPAN 0x2 /* temp, should be provided later */ ++ ++#define EEPROM_CID_DEFAULT 0x0 ++#define EEPROM_CID_ALPHA 0x1 ++#define EEPROM_CID_Senao 0x3 ++#define EEPROM_CID_NetCore 0x5 ++#define EEPROM_CID_CAMEO 0X8 ++#define EEPROM_CID_SITECOM 0x9 ++#define EEPROM_CID_COREGA 0xB ++#define EEPROM_CID_EDIMAX_BELK 0xC ++#define EEPROM_CID_SERCOMM_BELK 0xE ++#define EEPROM_CID_CAMEO1 0xF ++#define EEPROM_CID_WNC_COREGA 0x12 ++#define EEPROM_CID_CLEVO 0x13 ++#define EEPROM_CID_WHQL 0xFE ++ ++/* Customer ID, note that: */ ++/* This variable is initiailzed through EEPROM or registry, */ ++/* however, its definition may be different with that in EEPROM for */ ++/* EEPROM size consideration. So, we have to perform proper translation ++ * between them. */ ++/* Besides, CustomerID of registry has precedence of that of EEPROM. */ ++/* defined below. 060703, by rcnjko. */ ++enum RT_CUSTOMER_ID { ++ RT_CID_DEFAULT = 0, ++ RT_CID_8187_ALPHA0 = 1, ++ RT_CID_8187_SERCOMM_PS = 2, ++ RT_CID_8187_HW_LED = 3, ++ RT_CID_8187_NETGEAR = 4, ++ RT_CID_WHQL = 5, ++ RT_CID_819x_CAMEO = 6, ++ RT_CID_819x_RUNTOP = 7, ++ RT_CID_819x_Senao = 8, ++ RT_CID_TOSHIBA = 9, /* Merge by Jacken, 2008/01/31. */ ++ RT_CID_819x_Netcore = 10, ++ RT_CID_Nettronix = 11, ++ RT_CID_DLINK = 12, ++ RT_CID_PRONET = 13, ++ RT_CID_COREGA = 14, ++ RT_CID_CHINA_MOBILE = 15, ++ RT_CID_819x_ALPHA = 16, ++ RT_CID_819x_Sitecom = 17, ++ RT_CID_CCX = 18, /* It's set under CCX logo test and isn't demanded ++ * for CCX functions, but for test behavior like retry ++ * limit and tx report. By Bruce, 2009-02-17. */ ++ RT_CID_819x_Lenovo = 19, ++ RT_CID_819x_QMI = 20, ++ RT_CID_819x_Edimax_Belkin = 21, ++ RT_CID_819x_Sercomm_Belkin = 22, ++ RT_CID_819x_CAMEO1 = 23, ++ RT_CID_819x_MSI = 24, ++ RT_CID_819x_Acer = 25, ++ RT_CID_819x_AzWave_ASUS = 26, ++ RT_CID_819x_AzWave = 27, /* For AzWave in PCIe,i ++ * The ID is AzWave use and not only Asus */ ++ RT_CID_819x_HP = 28, ++ RT_CID_819x_WNC_COREGA = 29, ++ RT_CID_819x_Arcadyan_Belkin = 30, ++ RT_CID_819x_SAMSUNG = 31, ++ RT_CID_819x_CLEVO = 32, ++ RT_CID_819x_DELL = 33, ++ RT_CID_819x_PRONETS = 34, ++ RT_CID_819x_Edimax_ASUS = 35, ++ RT_CID_819x_CAMEO_NETGEAR = 36, ++ RT_CID_PLANEX = 37, ++ RT_CID_CC_C = 38, ++ RT_CID_819x_Xavi = 39, ++ RT_CID_819x_FUNAI_TV = 40, ++ RT_CID_819x_ALPHA_WD=41, ++}; ++ ++struct eeprom_priv { ++ u8 bautoload_fail_flag; ++ u8 bloadfile_fail_flag; ++ u8 bloadmac_fail_flag; ++ u8 mac_addr[6]; /* PermanentAddress */ ++ u16 channel_plan; ++ u8 EepromOrEfuse; ++ u8 efuse_eeprom_data[HWSET_MAX_SIZE_512] __aligned(4); ++}; ++ ++void eeprom_write16(struct adapter *padapter, u16 reg, u16 data); ++u16 eeprom_read16(struct adapter *padapter, u16 reg); ++void read_eeprom_content(struct adapter *padapter); ++void eeprom_read_sz(struct adapter *adapt, u16 reg, u8 *data, u32 sz); ++void read_eeprom_content_by_attrib(struct adapter *padapter); ++ ++#endif /* __RTL871X_EEPROM_H__ */ +diff --git a/drivers/staging/r8188eu/include/rtw_efuse.h b/drivers/staging/r8188eu/include/rtw_efuse.h +new file mode 100644 +index 000000000000..b3ff46db2091 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_efuse.h +@@ -0,0 +1,134 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_EFUSE_H__ ++#define __RTW_EFUSE_H__ ++ ++#include "osdep_service.h" ++ ++#define EFUSE_ERROE_HANDLE 1 ++ ++#define PG_STATE_HEADER 0x01 ++#define PG_STATE_WORD_0 0x02 ++#define PG_STATE_WORD_1 0x04 ++#define PG_STATE_WORD_2 0x08 ++#define PG_STATE_WORD_3 0x10 ++#define PG_STATE_DATA 0x20 ++ ++#define PG_SWBYTE_H 0x01 ++#define PG_SWBYTE_L 0x02 ++ ++#define PGPKT_DATA_SIZE 8 ++ ++#define EFUSE_WIFI 0 ++#define EFUSE_BT 1 ++ ++enum _EFUSE_DEF_TYPE { ++ TYPE_EFUSE_MAX_SECTION = 0, ++ TYPE_EFUSE_REAL_CONTENT_LEN = 1, ++ TYPE_AVAILABLE_EFUSE_BYTES_BANK = 2, ++ TYPE_AVAILABLE_EFUSE_BYTES_TOTAL = 3, ++ TYPE_EFUSE_MAP_LEN = 4, ++ TYPE_EFUSE_PROTECT_BYTES_BANK = 5, ++ TYPE_EFUSE_CONTENT_LEN_BANK = 6, ++}; ++ ++/* E-Fuse */ ++#define EFUSE_MAP_SIZE 512 ++#define EFUSE_MAX_SIZE 256 ++/* end of E-Fuse */ ++ ++#define EFUSE_MAX_MAP_LEN 512 ++#define EFUSE_MAX_HW_SIZE 512 ++#define EFUSE_MAX_SECTION_BASE 16 ++ ++#define EXT_HEADER(header) ((header & 0x1F) == 0x0F) ++#define ALL_WORDS_DISABLED(wde) ((wde & 0x0F) == 0x0F) ++#define GET_HDR_OFFSET_2_0(header) ((header & 0xE0) >> 5) ++ ++#define EFUSE_REPEAT_THRESHOLD_ 3 ++ ++/* The following is for BT Efuse definition */ ++#define EFUSE_BT_MAX_MAP_LEN 1024 ++#define EFUSE_MAX_BANK 4 ++#define EFUSE_MAX_BT_BANK (EFUSE_MAX_BANK-1) ++/*--------------------------Define Parameters-------------------------------*/ ++#define EFUSE_MAX_WORD_UNIT 4 ++ ++/*------------------------------Define structure----------------------------*/ ++struct pgpkt { ++ u8 offset; ++ u8 word_en; ++ u8 data[8]; ++ u8 word_cnts; ++}; ++ ++/*------------------------------Define structure----------------------------*/ ++struct efuse_hal { ++ u8 fakeEfuseBank; ++ u32 fakeEfuseUsedBytes; ++ u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE]; ++ u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN]; ++ u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN]; ++ ++ u16 BTEfuseUsedBytes; ++ u8 BTEfuseUsedPercentage; ++ u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; ++ u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]; ++ u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]; ++ ++ u16 fakeBTEfuseUsedBytes; ++ u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; ++ u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]; ++ u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]; ++}; ++ ++/*------------------------Export global variable----------------------------*/ ++extern u8 fakeEfuseBank; ++extern u32 fakeEfuseUsedBytes; ++extern u8 fakeEfuseContent[]; ++extern u8 fakeEfuseInitMap[]; ++extern u8 fakeEfuseModifiedMap[]; ++ ++extern u32 BTEfuseUsedBytes; ++extern u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; ++extern u8 BTEfuseInitMap[]; ++extern u8 BTEfuseModifiedMap[]; ++ ++extern u32 fakeBTEfuseUsedBytes; ++extern u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; ++extern u8 fakeBTEfuseInitMap[]; ++extern u8 fakeBTEfuseModifiedMap[]; ++/*------------------------Export global variable----------------------------*/ ++ ++u8 efuse_GetCurrentSize(struct adapter *adapter, u16 *size); ++u16 efuse_GetMaxSize(struct adapter *adapter); ++u8 rtw_efuse_access(struct adapter *adapter, u8 read, u16 start_addr, ++ u16 cnts, u8 *data); ++u8 rtw_efuse_map_read(struct adapter *adapter, u16 addr, u16 cnts, u8 *data); ++u8 rtw_efuse_map_write(struct adapter *adapter, u16 addr, u16 cnts, u8 *data); ++u8 rtw_BT_efuse_map_read(struct adapter *adapter, u16 addr, ++ u16 cnts, u8 *data); ++u8 rtw_BT_efuse_map_write(struct adapter *adapter, u16 addr, ++ u16 cnts, u8 *data); ++u16 Efuse_GetCurrentSize(struct adapter *adapter, u8 efusetype, bool test); ++u8 Efuse_CalculateWordCnts(u8 word_en); ++void ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf, bool test); ++void EFUSE_GetEfuseDefinition(struct adapter *adapt, u8 type, u8 type1, ++ void *out, bool bPseudoTest); ++u8 efuse_OneByteRead(struct adapter *adapter, u16 addr, u8 *data, bool test); ++u8 efuse_OneByteWrite(struct adapter *adapter, u16 addr, u8 data, bool test); ++ ++void Efuse_PowerSwitch(struct adapter *adapt,u8 bWrite,u8 PwrState); ++int Efuse_PgPacketRead(struct adapter *adapt, u8 offset, u8 *data, bool test); ++int Efuse_PgPacketWrite(struct adapter *adapter, u8 offset, u8 word, u8 *data, ++ bool test); ++void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata); ++u8 Efuse_WordEnableDataWrite(struct adapter *adapter, u16 efuse_addr, ++ u8 word_en, u8 *data, bool test); ++ ++u8 EFUSE_Read1Byte(struct adapter *adapter, u16 address); ++void EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype, bool test); ++void EFUSE_ShadowRead(struct adapter *adapt, u8 type, u16 offset, u32 *val); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_event.h b/drivers/staging/r8188eu/include/rtw_event.h +new file mode 100644 +index 000000000000..54dc1ea437fc +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_event.h +@@ -0,0 +1,97 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_EVENT_H_ ++#define _RTW_EVENT_H_ ++ ++#include "osdep_service.h" ++ ++#include "wlan_bssdef.h" ++#include ++#include ++ ++/* ++Used to report a bss has been scanned ++*/ ++struct survey_event { ++ struct wlan_bssid_ex bss; ++}; ++ ++/* ++Used to report that the requested site survey has been done. ++ ++bss_cnt indicates the number of bss that has been reported. ++ ++*/ ++struct surveydone_event { ++ unsigned int bss_cnt; ++ ++}; ++ ++/* ++Used to report the link result of joinning the given bss ++ ++join_res: ++-1: authentication fail ++-2: association fail ++> 0: TID ++ ++*/ ++struct joinbss_event { ++ struct wlan_network network; ++}; ++ ++/* ++Used to report a given STA has joinned the created BSS. ++It is used in AP/Ad-HoC(M) mode. ++*/ ++ ++struct stassoc_event { ++ unsigned char macaddr[6]; ++ unsigned char rsvd[2]; ++ int cam_id; ++}; ++ ++struct stadel_event { ++ unsigned char macaddr[6]; ++ unsigned char rsvd[2]; /* for reason */ ++ int mac_id; ++}; ++ ++struct addba_event { ++ unsigned int tid; ++}; ++ ++#define GEN_EVT_CODE(event) event ## _EVT_ ++ ++struct fwevent { ++ u32 parmsize; ++ void (*event_callback)(struct adapter *dev, u8 *pbuf); ++}; ++ ++#define C2HEVENT_SZ 32 ++ ++struct event_node { ++ unsigned char *node; ++ unsigned char evt_code; ++ unsigned short evt_sz; ++ int *caller_ff_tail; ++ int caller_ff_sz; ++}; ++ ++struct c2hevent_queue { ++ int head; ++ int tail; ++ struct event_node nodes[C2HEVENT_SZ]; ++ unsigned char seq; ++}; ++ ++#define NETWORK_QUEUE_SZ 4 ++ ++struct network_queue { ++ int head; ++ int tail; ++ struct wlan_bssid_ex networks[NETWORK_QUEUE_SZ]; ++}; ++ ++#endif /* _WLANEVENT_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_ht.h b/drivers/staging/r8188eu/include/rtw_ht.h +new file mode 100644 +index 000000000000..2b56b7c38c86 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_ht.h +@@ -0,0 +1,28 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_HT_H_ ++#define _RTW_HT_H_ ++ ++#include "osdep_service.h" ++#include "wifi.h" ++ ++struct ht_priv { ++ u32 ht_option; ++ u32 ampdu_enable;/* for enable Tx A-MPDU */ ++ u32 tx_amsdu_enable;/* for enable Tx A-MSDU */ ++ u32 tx_amdsu_maxlen; /* 1: 8k, 0:4k ; default:8k, for tx */ ++ u32 rx_ampdu_maxlen; /* for rx reordering ctrl win_sz, ++ * updated when join_callback. */ ++ u8 bwmode;/* */ ++ u8 ch_offset;/* PRIME_CHNL_OFFSET */ ++ u8 sgi;/* short GI */ ++ ++ /* for processing Tx A-MPDU */ ++ u8 agg_enable_bitmap; ++ u8 candidate_tid_bitmap; ++ ++ struct ieee80211_ht_cap ht_cap; ++}; ++ ++#endif /* _RTL871X_HT_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h +new file mode 100644 +index 000000000000..4b41c7b03972 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_io.h +@@ -0,0 +1,367 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_IO_H_ ++#define _RTW_IO_H_ ++ ++#include "osdep_service.h" ++#include "osdep_intf.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define rtw_usb_buffer_alloc(dev, size, dma) \ ++ usb_alloc_coherent((dev), (size), (in_interrupt() ? \ ++ GFP_ATOMIC : GFP_KERNEL), (dma)) ++#define rtw_usb_buffer_free(dev, size, addr, dma) \ ++ usb_free_coherent((dev), (size), (addr), (dma)) ++ ++#define NUM_IOREQ 8 ++ ++#define MAX_PROT_SZ (64-16) ++ ++#define _IOREADY 0 ++#define _IO_WAIT_COMPLETE 1 ++#define _IO_WAIT_RSP 2 ++ ++/* IO COMMAND TYPE */ ++#define _IOSZ_MASK_ (0x7F) ++#define _IO_WRITE_ BIT(7) ++#define _IO_FIXED_ BIT(8) ++#define _IO_BURST_ BIT(9) ++#define _IO_BYTE_ BIT(10) ++#define _IO_HW_ BIT(11) ++#define _IO_WORD_ BIT(12) ++#define _IO_SYNC_ BIT(13) ++#define _IO_CMDMASK_ (0x1F80) ++ ++/* ++ For prompt mode accessing, caller shall free io_req ++ Otherwise, io_handler will free io_req ++*/ ++ ++/* IO STATUS TYPE */ ++#define _IO_ERR_ BIT(2) ++#define _IO_SUCCESS_ BIT(1) ++#define _IO_DONE_ BIT(0) ++ ++#define IO_RD32 (_IO_SYNC_ | _IO_WORD_) ++#define IO_RD16 (_IO_SYNC_ | _IO_HW_) ++#define IO_RD8 (_IO_SYNC_ | _IO_BYTE_) ++ ++#define IO_RD32_ASYNC (_IO_WORD_) ++#define IO_RD16_ASYNC (_IO_HW_) ++#define IO_RD8_ASYNC (_IO_BYTE_) ++ ++#define IO_WR32 (_IO_WRITE_ | _IO_SYNC_ | _IO_WORD_) ++#define IO_WR16 (_IO_WRITE_ | _IO_SYNC_ | _IO_HW_) ++#define IO_WR8 (_IO_WRITE_ | _IO_SYNC_ | _IO_BYTE_) ++ ++#define IO_WR32_ASYNC (_IO_WRITE_ | _IO_WORD_) ++#define IO_WR16_ASYNC (_IO_WRITE_ | _IO_HW_) ++#define IO_WR8_ASYNC (_IO_WRITE_ | _IO_BYTE_) ++ ++/* ++ Only Sync. burst accessing is provided. ++*/ ++ ++#define IO_WR_BURST(x) \ ++ (_IO_WRITE_ | _IO_SYNC_ | _IO_BURST_ | ((x) & _IOSZ_MASK_)) ++#define IO_RD_BURST(x) \ ++ (_IO_SYNC_ | _IO_BURST_ | ((x) & _IOSZ_MASK_)) ++ ++/* below is for the intf_option bit defition... */ ++ ++#define _INTF_ASYNC_ BIT(0) /* support async io */ ++ ++struct intf_priv; ++struct intf_hdl; ++struct io_queue; ++ ++struct _io_ops { ++ u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr); ++ u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr); ++ u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr); ++ int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); ++ int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val); ++ int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val); ++ int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr, u32 length, ++ u8 *pdata); ++ int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val); ++ int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val); ++ int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val); ++ void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, ++ u8 *pmem); ++ void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, ++ u8 *pmem); ++ u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, ++ u8 *pmem); ++ u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, ++ u8 *pmem); ++ void (*_read_port_cancel)(struct intf_hdl *pintfhdl); ++ void (*_write_port_cancel)(struct intf_hdl *pintfhdl); ++}; ++ ++struct io_req { ++ struct list_head list; ++ u32 addr; ++ u32 val; ++ u32 command; ++ u32 status; ++ u8 *pbuf; ++ struct semaphore sema; ++ ++ void (*_async_io_callback)(struct adapter *padater, ++ struct io_req *pio_req, u8 *cnxt); ++ u8 *cnxt; ++}; ++ ++struct intf_hdl { ++ struct adapter *padapter; ++ struct dvobj_priv *pintf_dev; ++ struct _io_ops io_ops; ++}; ++ ++struct reg_protocol_rd { ++#ifdef __LITTLE_ENDIAN ++ /* DW1 */ ++ u32 NumOfTrans:4; ++ u32 Reserved1:4; ++ u32 Reserved2:24; ++ /* DW2 */ ++ u32 ByteCount:7; ++ u32 WriteEnable:1; /* 0:read, 1:write */ ++ u32 FixOrContinuous:1; /* 0:continuous, 1: Fix */ ++ u32 BurstMode:1; ++ u32 Byte1Access:1; ++ u32 Byte2Access:1; ++ u32 Byte4Access:1; ++ u32 Reserved3:3; ++ u32 Reserved4:16; ++ /* DW3 */ ++ u32 BusAddress; ++ /* DW4 */ ++ /* u32 Value; */ ++#else ++/* DW1 */ ++ u32 Reserved1:4; ++ u32 NumOfTrans:4; ++ u32 Reserved2:24; ++ /* DW2 */ ++ u32 WriteEnable:1; ++ u32 ByteCount:7; ++ u32 Reserved3:3; ++ u32 Byte4Access:1; ++ ++ u32 Byte2Access:1; ++ u32 Byte1Access:1; ++ u32 BurstMode:1; ++ u32 FixOrContinuous:1; ++ u32 Reserved4:16; ++ /* DW3 */ ++ u32 BusAddress; ++ ++ /* DW4 */ ++#endif ++}; ++ ++struct reg_protocol_wt { ++#ifdef __LITTLE_ENDIAN ++ /* DW1 */ ++ u32 NumOfTrans:4; ++ u32 Reserved1:4; ++ u32 Reserved2:24; ++ /* DW2 */ ++ u32 ByteCount:7; ++ u32 WriteEnable:1; /* 0:read, 1:write */ ++ u32 FixOrContinuous:1; /* 0:continuous, 1: Fix */ ++ u32 BurstMode:1; ++ u32 Byte1Access:1; ++ u32 Byte2Access:1; ++ u32 Byte4Access:1; ++ u32 Reserved3:3; ++ u32 Reserved4:16; ++ /* DW3 */ ++ u32 BusAddress; ++ /* DW4 */ ++ u32 Value; ++#else ++ /* DW1 */ ++ u32 Reserved1 :4; ++ u32 NumOfTrans:4; ++ u32 Reserved2:24; ++ /* DW2 */ ++ u32 WriteEnable:1; ++ u32 ByteCount:7; ++ u32 Reserved3:3; ++ u32 Byte4Access:1; ++ u32 Byte2Access:1; ++ u32 Byte1Access:1; ++ u32 BurstMode:1; ++ u32 FixOrContinuous:1; ++ u32 Reserved4:16; ++ /* DW3 */ ++ u32 BusAddress; ++ /* DW4 */ ++ u32 Value; ++#endif ++}; ++ ++/* ++Below is the data structure used by _io_handler ++*/ ++ ++struct io_queue { ++ spinlock_t lock; ++ struct list_head free_ioreqs; ++ struct list_head pending; /* The io_req list that will be served ++ * in the single protocol read/write.*/ ++ struct list_head processing; ++ u8 *free_ioreqs_buf; /* 4-byte aligned */ ++ u8 *pallocated_free_ioreqs_buf; ++ struct intf_hdl intf; ++}; ++ ++struct io_priv { ++ struct adapter *padapter; ++ struct intf_hdl intf; ++}; ++ ++uint ioreq_flush(struct adapter *adapter, struct io_queue *ioqueue); ++void sync_ioreq_enqueue(struct io_req *preq,struct io_queue *ioqueue); ++uint sync_ioreq_flush(struct adapter *adapter, struct io_queue *ioqueue); ++uint free_ioreq(struct io_req *preq, struct io_queue *pio_queue); ++struct io_req *alloc_ioreq(struct io_queue *pio_q); ++ ++uint register_intf_hdl(u8 *dev, struct intf_hdl *pintfhdl); ++void unregister_intf_hdl(struct intf_hdl *pintfhdl); ++ ++void _rtw_attrib_read(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++ ++u8 _rtw_read8(struct adapter *adapter, u32 addr); ++u16 _rtw_read16(struct adapter *adapter, u32 addr); ++u32 _rtw_read32(struct adapter *adapter, u32 addr); ++void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++void _rtw_read_port_cancel(struct adapter *adapter); ++ ++int _rtw_write8(struct adapter *adapter, u32 addr, u8 val); ++int _rtw_write16(struct adapter *adapter, u32 addr, u16 val); ++int _rtw_write32(struct adapter *adapter, u32 addr, u32 val); ++int _rtw_writeN(struct adapter *adapter, u32 addr, u32 length, u8 *pdata); ++ ++int _rtw_write8_async(struct adapter *adapter, u32 addr, u8 val); ++int _rtw_write16_async(struct adapter *adapter, u32 addr, u16 val); ++int _rtw_write32_async(struct adapter *adapter, u32 addr, u32 val); ++ ++void _rtw_write_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++u32 _rtw_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt, ++ u8 *pmem, int timeout_ms); ++void _rtw_write_port_cancel(struct adapter *adapter); ++ ++#define rtw_read8(adapter, addr) _rtw_read8((adapter), (addr)) ++#define rtw_read16(adapter, addr) _rtw_read16((adapter), (addr)) ++#define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr)) ++#define rtw_read_mem(adapter, addr, cnt, mem) \ ++ _rtw_read_mem((adapter), (addr), (cnt), (mem)) ++#define rtw_read_port(adapter, addr, cnt, mem) \ ++ _rtw_read_port((adapter), (addr), (cnt), (mem)) ++#define rtw_read_port_cancel(adapter) _rtw_read_port_cancel((adapter)) ++ ++#define rtw_write8(adapter, addr, val) \ ++ _rtw_write8((adapter), (addr), (val)) ++#define rtw_write16(adapter, addr, val) \ ++ _rtw_write16((adapter), (addr), (val)) ++#define rtw_write32(adapter, addr, val) \ ++ _rtw_write32((adapter), (addr), (val)) ++#define rtw_writeN(adapter, addr, length, data) \ ++ _rtw_writeN((adapter), (addr), (length), (data)) ++#define rtw_write8_async(adapter, addr, val) \ ++ _rtw_write8_async((adapter), (addr), (val)) ++#define rtw_write16_async(adapter, addr, val) \ ++ _rtw_write16_async((adapter), (addr), (val)) ++#define rtw_write32_async(adapter, addr, val) \ ++ _rtw_write32_async((adapter), (addr), (val)) ++#define rtw_write_mem(adapter, addr, cnt, mem) \ ++ _rtw_write_mem((adapter), (addr), (cnt), (mem)) ++#define rtw_write_port(adapter, addr, cnt, mem) \ ++ _rtw_write_port((adapter), (addr), (cnt), (mem)) ++#define rtw_write_port_and_wait(adapter, addr, cnt, mem, timeout_ms) \ ++ _rtw_write_port_and_wait((adapter), (addr), (cnt), (mem), (timeout_ms)) ++#define rtw_write_port_cancel(adapter) _rtw_write_port_cancel((adapter)) ++ ++void rtw_write_scsi(struct adapter *adapter, u32 cnt, u8 *pmem); ++ ++/* ioreq */ ++void ioreq_read8(struct adapter *adapter, u32 addr, u8 *pval); ++void ioreq_read16(struct adapter *adapter, u32 addr, u16 *pval); ++void ioreq_read32(struct adapter *adapter, u32 addr, u32 *pval); ++void ioreq_write8(struct adapter *adapter, u32 addr, u8 val); ++void ioreq_write16(struct adapter *adapter, u32 addr, u16 val); ++void ioreq_write32(struct adapter *adapter, u32 addr, u32 val); ++ ++uint async_read8(struct adapter *adapter, u32 addr, u8 *pbuff, ++ void (*_async_io_callback)(struct adapter *padater, ++ struct io_req *pio_req, ++ u8 *cnxt), u8 *cnxt); ++uint async_read16(struct adapter *adapter, u32 addr, u8 *pbuff, ++ void (*_async_io_callback)(struct adapter *padater, ++ struct io_req *pio_req, ++ u8 *cnxt), u8 *cnxt); ++uint async_read32(struct adapter *adapter, u32 addr, u8 *pbuff, ++ void (*_async_io_callback)(struct adapter *padater, ++ struct io_req *pio_req, ++ u8 *cnxt), u8 *cnxt); ++ ++void async_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++void async_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++ ++void async_write8(struct adapter *adapter, u32 addr, u8 val, ++ void (*_async_io_callback)(struct adapter *padater, ++ struct io_req *pio_req, ++ u8 *cnxt), u8 *cnxt); ++void async_write16(struct adapter *adapter, u32 addr, u16 val, ++ void (*_async_io_callback)(struct adapter *padater, ++ struct io_req *pio_req, ++ u8 *cnxt), u8 *cnxt); ++void async_write32(struct adapter *adapter, u32 addr, u32 val, ++ void (*_async_io_callback)(struct adapter *padater, ++ struct io_req *pio_req, ++ u8 *cnxt), u8 *cnxt); ++ ++void async_write_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++void async_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem); ++ ++int rtw_init_io_priv(struct adapter *padapter, ++ void (*set_intf_ops)(struct _io_ops *pops)); ++ ++uint alloc_io_queue(struct adapter *adapter); ++void free_io_queue(struct adapter *adapter); ++void async_bus_io(struct io_queue *pio_q); ++void bus_sync_io(struct io_queue *pio_q); ++u32 _ioreq2rwmem(struct io_queue *pio_q); ++void dev_power_down(struct adapter * Adapter, u8 bpwrup); ++ ++#define PlatformEFIOWrite1Byte(_a,_b,_c) \ ++ rtw_write8(_a,_b,_c) ++#define PlatformEFIOWrite2Byte(_a,_b,_c) \ ++ rtw_write16(_a,_b,_c) ++#define PlatformEFIOWrite4Byte(_a,_b,_c) \ ++ rtw_write32(_a,_b,_c) ++ ++#define PlatformEFIORead1Byte(_a,_b) \ ++ rtw_read8(_a,_b) ++#define PlatformEFIORead2Byte(_a,_b) \ ++ rtw_read16(_a,_b) ++#define PlatformEFIORead4Byte(_a,_b) \ ++ rtw_read32(_a,_b) ++ ++#endif /* _RTL8711_IO_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_ioctl.h b/drivers/staging/r8188eu/include/rtw_ioctl.h +new file mode 100644 +index 000000000000..a36bd7313755 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_ioctl.h +@@ -0,0 +1,92 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_IOCTL_H_ ++#define _RTW_IOCTL_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#ifndef OID_802_11_CAPABILITY ++ #define OID_802_11_CAPABILITY 0x0d010122 ++#endif ++ ++#ifndef OID_802_11_PMKID ++ #define OID_802_11_PMKID 0x0d010123 ++#endif ++ ++/* For DDK-defined OIDs */ ++#define OID_NDIS_SEG1 0x00010100 ++#define OID_NDIS_SEG2 0x00010200 ++#define OID_NDIS_SEG3 0x00020100 ++#define OID_NDIS_SEG4 0x01010100 ++#define OID_NDIS_SEG5 0x01020100 ++#define OID_NDIS_SEG6 0x01020200 ++#define OID_NDIS_SEG7 0xFD010100 ++#define OID_NDIS_SEG8 0x0D010100 ++#define OID_NDIS_SEG9 0x0D010200 ++#define OID_NDIS_SEG10 0x0D020200 ++ ++#define SZ_OID_NDIS_SEG1 23 ++#define SZ_OID_NDIS_SEG2 3 ++#define SZ_OID_NDIS_SEG3 6 ++#define SZ_OID_NDIS_SEG4 6 ++#define SZ_OID_NDIS_SEG5 4 ++#define SZ_OID_NDIS_SEG6 8 ++#define SZ_OID_NDIS_SEG7 7 ++#define SZ_OID_NDIS_SEG8 36 ++#define SZ_OID_NDIS_SEG9 24 ++#define SZ_OID_NDIS_SEG10 19 ++ ++/* For Realtek-defined OIDs */ ++#define OID_MP_SEG1 0xFF871100 ++#define OID_MP_SEG2 0xFF818000 ++ ++#define OID_MP_SEG3 0xFF818700 ++#define OID_MP_SEG4 0xFF011100 ++ ++enum oid_type { ++ QUERY_OID, ++ SET_OID ++}; ++ ++struct oid_funs_node { ++ unsigned int oid_start; /* the starting number for OID */ ++ unsigned int oid_end; /* the ending number for OID */ ++ struct oid_obj_priv *node_array; ++ unsigned int array_sz; /* the size of node_array */ ++ int query_counter; /* count the number of query hits for this segment */ ++ int set_counter; /* count the number of set hits for this segment */ ++}; ++ ++struct oid_par_priv { ++ void *adapter_context; ++ NDIS_OID oid; ++ void *information_buf; ++ u32 information_buf_len; ++ u32 *bytes_rw; ++ u32 *bytes_needed; ++ enum oid_type type_of_oid; ++ u32 dbg; ++}; ++ ++struct oid_obj_priv { ++ unsigned char dbg; /* 0: without OID debug message ++ * 1: with OID debug message */ ++ int (*oidfuns)(struct oid_par_priv *poid_par_priv); ++}; ++ ++extern struct iw_handler_def rtw_handlers_def; ++ ++int drv_query_info(struct net_device *miniportadaptercontext, NDIS_OID oid, ++ void *informationbuffer, u32 informationbufferlength, ++ u32 *byteswritten, u32 *bytesneeded); ++ ++int drv_set_info(struct net_device *MiniportAdapterContext, ++ NDIS_OID oid, void *informationbuffer, ++ u32 informationbufferlength, u32 *bytesread, ++ u32 *bytesneeded); ++ ++extern int ui_pid[3]; ++ ++#endif /* #ifndef __INC_CEINFO_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_ioctl_rtl.h b/drivers/staging/r8188eu/include/rtw_ioctl_rtl.h +new file mode 100644 +index 000000000000..6d3d1ef923f6 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_ioctl_rtl.h +@@ -0,0 +1,63 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_IOCTL_RTL_H_ ++#define _RTW_IOCTL_RTL_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++/* oid_rtl_seg_01_01 ************** */ ++int oid_rt_get_signal_quality_hdl(struct oid_par_priv *poid_par_priv);/* 84 */ ++int oid_rt_get_small_packet_crc_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_middle_packet_crc_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_large_packet_crc_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_tx_retry_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_rx_retry_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_rx_total_packet_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_tx_beacon_ok_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_tx_beacon_err_hdl(struct oid_par_priv *poid_par_priv); ++ ++int oid_rt_pro_set_fw_dig_state_hdl(struct oid_par_priv *poid_par_priv);/* 8a */ ++int oid_rt_pro_set_fw_ra_state_hdl(struct oid_par_priv *poid_par_priv); /* 8b */ ++ ++int oid_rt_get_rx_icv_err_hdl(struct oid_par_priv *poid_par_priv);/* 93 */ ++int oid_rt_set_encryption_algorithm_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_preamble_mode_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_ap_ip_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_channelplan_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_set_channelplan_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_set_preamble_mode_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_set_bcn_intvl_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_dedicate_probe_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_total_tx_bytes_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_total_rx_bytes_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_current_tx_power_level_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_enc_key_mismatch_count_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_enc_key_match_count_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_channel_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_hardware_radio_off_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_key_mismatch_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_supported_wireless_mode_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_channel_list_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_scan_in_progress_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_forced_data_rate_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_wireless_mode_for_scan_list_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_get_bss_wireless_mode_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_scan_with_magic_packet_hdl(struct oid_par_priv *poid_par_priv); ++ ++/* oid_rtl_seg_01_03 section start ************** */ ++int oid_rt_ap_get_associated_station_list_hdl(struct oid_par_priv *priv); ++int oid_rt_ap_switch_into_ap_mode_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_ap_supported_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_ap_set_passphrase_hdl(struct oid_par_priv *poid_par_priv); ++ ++/* oid_rtl_seg_01_11 */ ++int oid_rt_pro_rf_write_registry_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_pro_rf_read_registry_hdl(struct oid_par_priv *poid_par_priv); ++ ++/* oid_rtl_seg_03_00 section start ************** */ ++int oid_rt_get_connect_state_hdl(struct oid_par_priv *poid_par_priv); ++int oid_rt_set_default_key_id_hdl(struct oid_par_priv *poid_par_priv); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_ioctl_set.h b/drivers/staging/r8188eu/include/rtw_ioctl_set.h +new file mode 100644 +index 000000000000..6216b8ab3a79 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_ioctl_set.h +@@ -0,0 +1,33 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_IOCTL_SET_H_ ++#define __RTW_IOCTL_SET_H_ ++ ++#include "drv_types.h" ++ ++typedef u8 NDIS_802_11_PMKID_VALUE[16]; ++ ++u8 rtw_set_802_11_add_key(struct adapter *adapt, struct ndis_802_11_key *key); ++u8 rtw_set_802_11_authentication_mode(struct adapter *adapt, ++ enum ndis_802_11_auth_mode authmode); ++u8 rtw_set_802_11_bssid(struct adapter*adapter, u8 *bssid); ++u8 rtw_set_802_11_add_wep(struct adapter *adapter, struct ndis_802_11_wep *wep); ++u8 rtw_set_802_11_disassociate(struct adapter *adapter); ++u8 rtw_set_802_11_bssid_list_scan(struct adapter*adapter, ++ struct ndis_802_11_ssid *pssid, ++ int ssid_max_num); ++u8 rtw_set_802_11_infrastructure_mode(struct adapter *adapter, ++ enum ndis_802_11_network_infra type); ++u8 rtw_set_802_11_remove_wep(struct adapter *adapter, u32 keyindex); ++u8 rtw_set_802_11_ssid(struct adapter *adapt, struct ndis_802_11_ssid *ssid); ++u8 rtw_set_802_11_remove_key(struct adapter *adapt, ++ struct ndis_802_11_remove_key *key); ++u8 rtw_validate_ssid(struct ndis_802_11_ssid *ssid); ++u16 rtw_get_cur_max_rate(struct adapter *adapter); ++int rtw_set_scan_mode(struct adapter *adapter, enum rt_scan_type scan_mode); ++int rtw_set_channel_plan(struct adapter *adapter, u8 channel_plan); ++int rtw_set_country(struct adapter *adapter, const char *country_code); ++int rtw_change_ifname(struct adapter *padapter, const char *ifname); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_iol.h b/drivers/staging/r8188eu/include/rtw_iol.h +new file mode 100644 +index 000000000000..471f9ca092a8 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_iol.h +@@ -0,0 +1,68 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_IOL_H_ ++#define __RTW_IOL_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define IOREG_CMD_END_LEN 4 ++ ++struct ioreg_cfg { ++ u8 length; ++ u8 cmd_id; ++ __le16 address; ++ __le32 data; ++ __le32 mask; ++}; ++ ++enum ioreg_cmd { ++ IOREG_CMD_LLT = 0x01, ++ IOREG_CMD_REFUSE = 0x02, ++ IOREG_CMD_EFUSE_PATH = 0x03, ++ IOREG_CMD_WB_REG = 0x04, ++ IOREG_CMD_WW_REG = 0x05, ++ IOREG_CMD_WD_REG = 0x06, ++ IOREG_CMD_W_RF = 0x07, ++ IOREG_CMD_DELAY_US = 0x10, ++ IOREG_CMD_DELAY_MS = 0x11, ++ IOREG_CMD_END = 0xFF, ++}; ++ ++struct xmit_frame *rtw_IOL_accquire_xmit_frame(struct adapter *adapter); ++int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, ++ u32 cmd_len); ++int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary); ++int rtw_IOL_exec_cmds_sync(struct adapter *adapter, ++ struct xmit_frame *xmit_frame, u32 max_wating_ms, ++ u32 bndy_cnt); ++bool rtw_IOL_applied(struct adapter *adapter); ++int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us); ++int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms); ++int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame); ++ ++void read_efuse_from_txpktbuf(struct adapter *adapter, int bcnhead, ++ u8 *content, u16 *size); ++ ++int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, ++ u8 value, u8 mask); ++int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, ++ u16 value, u16 mask); ++int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, ++ u32 value, u32 mask); ++int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, ++ u16 addr, u32 value, u32 mask); ++#define rtw_IOL_append_WB_cmd(xmit_frame, addr, value, mask) \ ++ _rtw_IOL_append_WB_cmd((xmit_frame), (addr), (value) ,(mask)) ++#define rtw_IOL_append_WW_cmd(xmit_frame, addr, value, mask) \ ++ _rtw_IOL_append_WW_cmd((xmit_frame), (addr), (value),(mask)) ++#define rtw_IOL_append_WD_cmd(xmit_frame, addr, value, mask) \ ++ _rtw_IOL_append_WD_cmd((xmit_frame), (addr), (value), (mask)) ++#define rtw_IOL_append_WRF_cmd(xmit_frame, rf_path, addr, value, mask) \ ++ _rtw_IOL_append_WRF_cmd((xmit_frame),(rf_path), (addr), (value), (mask)) ++ ++u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame); ++void rtw_IOL_cmd_buf_dump(struct adapter *Adapter,int buf_len,u8 *pbuf); ++ ++#endif /* __RTW_IOL_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_led.h b/drivers/staging/r8188eu/include/rtw_led.h +new file mode 100644 +index 000000000000..f0965aa5b470 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_led.h +@@ -0,0 +1,181 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_LED_H_ ++#define __RTW_LED_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define MSECS(t) (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000) ++ ++#define LED_BLINK_NORMAL_INTERVAL 100 ++#define LED_BLINK_SLOWLY_INTERVAL 200 ++#define LED_BLINK_LONG_INTERVAL 400 ++ ++#define LED_BLINK_NO_LINK_INTERVAL_ALPHA 1000 ++#define LED_BLINK_LINK_INTERVAL_ALPHA 500 /* 500 */ ++#define LED_BLINK_SCAN_INTERVAL_ALPHA 180 /* 150 */ ++#define LED_BLINK_FASTER_INTERVAL_ALPHA 50 ++#define LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA 5000 ++ ++#define LED_BLINK_NORMAL_INTERVAL_NETTRONIX 100 ++#define LED_BLINK_SLOWLY_INTERVAL_NETTRONIX 2000 ++ ++#define LED_BLINK_SLOWLY_INTERVAL_PORNET 1000 ++#define LED_BLINK_NORMAL_INTERVAL_PORNET 100 ++ ++#define LED_BLINK_FAST_INTERVAL_BITLAND 30 ++ ++/* 060403, rcnjko: Customized for AzWave. */ ++#define LED_CM2_BLINK_ON_INTERVAL 250 ++#define LED_CM2_BLINK_OFF_INTERVAL 4750 ++ ++#define LED_CM8_BLINK_INTERVAL 500 /* for QMI */ ++#define LED_CM8_BLINK_OFF_INTERVAL 3750 /* for QMI */ ++ ++/* 080124, lanhsin: Customized for RunTop */ ++#define LED_RunTop_BLINK_INTERVAL 300 ++ ++/* 060421, rcnjko: Customized for Sercomm Printer Server case. */ ++#define LED_CM3_BLINK_INTERVAL 1500 ++ ++enum LED_CTL_MODE { ++ LED_CTL_POWER_ON = 1, ++ LED_CTL_LINK = 2, ++ LED_CTL_NO_LINK = 3, ++ LED_CTL_TX = 4, ++ LED_CTL_RX = 5, ++ LED_CTL_SITE_SURVEY = 6, ++ LED_CTL_POWER_OFF = 7, ++ LED_CTL_START_TO_LINK = 8, ++ LED_CTL_START_WPS = 9, ++ LED_CTL_STOP_WPS = 10, ++ LED_CTL_START_WPS_BOTTON = 11, /* added for runtop */ ++ LED_CTL_STOP_WPS_FAIL = 12, /* added for ALPHA */ ++ LED_CTL_STOP_WPS_FAIL_OVERLAP = 13, /* added for BELKIN */ ++ LED_CTL_CONNECTION_NO_TRANSFER = 14, ++}; ++ ++enum LED_STATE_871x { ++ LED_UNKNOWN = 0, ++ RTW_LED_ON = 1, ++ RTW_LED_OFF = 2, ++ LED_BLINK_NORMAL = 3, ++ LED_BLINK_SLOWLY = 4, ++ LED_BLINK_POWER_ON = 5, ++ LED_BLINK_SCAN = 6, /* LED is blinking during scanning period, ++ * the # of times to blink is depend on time ++ * for scanning. */ ++ LED_BLINK_NO_LINK = 7, /* LED is blinking during no link state. */ ++ LED_BLINK_StartToBlink = 8,/* Customzied for Sercomm Printer ++ * Server case */ ++ LED_BLINK_TXRX = 9, ++ LED_BLINK_WPS = 10, /* LED is blinkg during WPS communication */ ++ LED_BLINK_WPS_STOP = 11, /* for ALPHA */ ++ LED_BLINK_WPS_STOP_OVERLAP = 12, /* for BELKIN */ ++ LED_BLINK_RUNTOP = 13, /* Customized for RunTop */ ++ LED_BLINK_CAMEO = 14, ++ LED_BLINK_XAVI = 15, ++ LED_BLINK_ALWAYS_ON = 16, ++}; ++ ++enum LED_PIN_871x { ++ LED_PIN_NULL = 0, ++ LED_PIN_LED0 = 1, ++ LED_PIN_LED1 = 2, ++ LED_PIN_LED2 = 3, ++ LED_PIN_GPIO0 = 4, ++}; ++ ++struct LED_871x { ++ struct adapter *padapter; ++ ++ enum LED_PIN_871x LedPin; /* Identify how to implement this ++ * SW led. */ ++ enum LED_STATE_871x CurrLedState; /* Current LED state. */ ++ enum LED_STATE_871x BlinkingLedState; /* Next state for blinking, ++ * either RTW_LED_ON or RTW_LED_OFF are. */ ++ ++ u8 bLedOn; /* true if LED is ON, false if LED is OFF. */ ++ ++ u8 bLedBlinkInProgress; /* true if it is blinking, false o.w.. */ ++ ++ u8 bLedWPSBlinkInProgress; ++ ++ u32 BlinkTimes; /* Number of times to toggle led state for blinking. */ ++ ++ struct timer_list BlinkTimer; /* Timer object for led blinking. */ ++ ++ u8 bSWLedCtrl; ++ ++ /* ALPHA, added by chiyoko, 20090106 */ ++ u8 bLedNoLinkBlinkInProgress; ++ u8 bLedLinkBlinkInProgress; ++ u8 bLedStartToLinkBlinkInProgress; ++ u8 bLedScanBlinkInProgress; ++ struct work_struct BlinkWorkItem; /* Workitem used by BlinkTimer to ++ * manipulate H/W to blink LED. */ ++}; ++ ++#define IS_LED_WPS_BLINKING(_LED_871x) \ ++ (((struct LED_871x *)_LED_871x)->CurrLedState == LED_BLINK_WPS || \ ++ ((struct LED_871x *)_LED_871x)->CurrLedState == LED_BLINK_WPS_STOP || \ ++ ((struct LED_871x *)_LED_871x)->bLedWPSBlinkInProgress) ++ ++#define IS_LED_BLINKING(_LED_871x) \ ++ (((struct LED_871x *)_LED_871x)->bLedWPSBlinkInProgress || \ ++ ((struct LED_871x *)_LED_871x)->bLedScanBlinkInProgress) ++ ++/* LED customization. */ ++ ++enum LED_STRATEGY_871x { ++ SW_LED_MODE0 = 0, /* SW control 1 LED via GPIO0. It is default option.*/ ++ SW_LED_MODE1= 1, /* 2 LEDs, through LED0 and LED1. For ALPHA. */ ++ SW_LED_MODE2 = 2, /* SW control 1 LED via GPIO0, customized for AzWave ++ * 8187 minicard. */ ++ SW_LED_MODE3 = 3, /* SW control 1 LED via GPIO0, customized for Sercomm ++ * Printer Server case. */ ++ SW_LED_MODE4 = 4, /* for Edimax / Belkin */ ++ SW_LED_MODE5 = 5, /* for Sercomm / Belkin */ ++ SW_LED_MODE6 = 6, /* for 88CU minicard, porting from ce SW_LED_MODE7 */ ++ HW_LED = 50, /* HW control 2 LEDs, LED0 and LED1 (there are 4 ++ * different control modes, see MAC.CONFIG1 for details.)*/ ++ LED_ST_NONE = 99, ++}; ++ ++void LedControl8188eu(struct adapter *padapter, enum LED_CTL_MODE LedAction); ++ ++struct led_priv{ ++ /* add for led control */ ++ struct LED_871x SwLed0; ++ struct LED_871x SwLed1; ++ enum LED_STRATEGY_871x LedStrategy; ++ u8 bRegUseLed; ++ void (*LedControlHandler)(struct adapter *padapter, ++ enum LED_CTL_MODE LedAction); ++ /* add for led control */ ++}; ++ ++#define rtw_led_control(adapt, action) \ ++ do { \ ++ if ((adapt)->ledpriv.LedControlHandler) \ ++ (adapt)->ledpriv.LedControlHandler((adapt), (action)); \ ++ } while (0) ++ ++void BlinkTimerCallback(struct timer_list *t); ++void BlinkWorkItemCallback(struct work_struct *work); ++ ++void ResetLedStatus(struct LED_871x * pLed); ++ ++void InitLed871x(struct adapter *padapter, struct LED_871x *pLed, ++ enum LED_PIN_871x LedPin); ++ ++void DeInitLed871x(struct LED_871x *pLed); ++ ++/* hal... */ ++void BlinkHandler(struct LED_871x * pLed); ++void SwLedOn(struct adapter *padapter, struct LED_871x *pLed); ++void SwLedOff(struct adapter *padapter, struct LED_871x *pLed); ++ ++#endif /* __RTW_LED_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_mlme.h b/drivers/staging/r8188eu/include/rtw_mlme.h +new file mode 100644 +index 000000000000..bbb41471472d +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_mlme.h +@@ -0,0 +1,632 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_MLME_H_ ++#define __RTW_MLME_H_ ++ ++#include "osdep_service.h" ++#include "mlme_osdep.h" ++#include "drv_types.h" ++#include "wlan_bssdef.h" ++ ++#define MAX_BSS_CNT 128 ++#define MAX_JOIN_TIMEOUT 6500 ++ ++/* Increase the scanning timeout because of increasing the SURVEY_TO value. */ ++ ++#define SCANNING_TIMEOUT 8000 ++ ++#define SCAN_INTERVAL (30) /* unit:2sec, 30*2=60sec */ ++ ++#define SCANQUEUE_LIFETIME 20 /* unit:sec */ ++ ++#define WIFI_NULL_STATE 0x00000000 ++ ++#define WIFI_ASOC_STATE 0x00000001 /* Under Linked state */ ++#define WIFI_REASOC_STATE 0x00000002 ++#define WIFI_SLEEP_STATE 0x00000004 ++#define WIFI_STATION_STATE 0x00000008 ++ ++#define WIFI_AP_STATE 0x00000010 ++#define WIFI_ADHOC_STATE 0x00000020 ++#define WIFI_ADHOC_MASTER_STATE 0x00000040 ++#define WIFI_UNDER_LINKING 0x00000080 ++ ++#define WIFI_UNDER_WPS 0x00000100 ++#define WIFI_STA_ALIVE_CHK_STATE 0x00000400 ++#define WIFI_SITE_MONITOR 0x00000800 /* to indicate the station is under site surveying */ ++ ++#define WIFI_MP_STATE 0x00010000 ++#define WIFI_MP_CTX_BACKGROUND 0x00020000 /* in continuous tx background */ ++#define WIFI_MP_CTX_ST 0x00040000 /* in continuous tx with single-tone */ ++#define WIFI_MP_CTX_BACKGROUND_PENDING 0x00080000 /* pending in continuous tx background due to out of skb */ ++#define WIFI_MP_CTX_CCK_HW 0x00100000 /* in continuous tx */ ++#define WIFI_MP_CTX_CCK_CS 0x00200000 /* in continuous tx with carrier suppression */ ++#define WIFI_MP_LPBK_STATE 0x00400000 ++ ++#define _FW_UNDER_LINKING WIFI_UNDER_LINKING ++#define _FW_LINKED WIFI_ASOC_STATE ++#define _FW_UNDER_SURVEY WIFI_SITE_MONITOR ++ ++enum dot11AuthAlgrthmNum { ++ dot11AuthAlgrthm_Open = 0, ++ dot11AuthAlgrthm_Shared, ++ dot11AuthAlgrthm_8021X, ++ dot11AuthAlgrthm_Auto, ++ dot11AuthAlgrthm_WAPI, ++ dot11AuthAlgrthm_MaxNum ++}; ++ ++/* Scan type including active and passive scan. */ ++enum rt_scan_type { ++ SCAN_PASSIVE, ++ SCAN_ACTIVE, ++ SCAN_MIX, ++}; ++ ++enum SCAN_RESULT_TYPE { ++ SCAN_RESULT_P2P_ONLY = 0, /* Will return all the P2P devices. */ ++ SCAN_RESULT_ALL = 1, /* Will return all the scanned device, ++ * include AP. */ ++ SCAN_RESULT_WFD_TYPE = 2 /* Will just return the correct WFD ++ * device. */ ++ /* If this device is Miracast sink ++ * device, it will just return all the ++ * Miracast source devices. */ ++}; ++ ++/* ++there are several "locks" in mlme_priv, ++since mlme_priv is a shared resource between many threads, ++like ISR/Call-Back functions, the OID handlers, and even timer functions. ++ ++Each _queue has its own locks, already. ++Other items are protected by mlme_priv.lock. ++ ++To avoid possible dead lock, any thread trying to modifiying mlme_priv ++SHALL not lock up more than one lock at a time! ++*/ ++ ++#define traffic_threshold 10 ++#define traffic_scan_period 500 ++ ++struct sitesurvey_ctrl { ++ u64 last_tx_pkts; ++ uint last_rx_pkts; ++ int traffic_busy; ++ struct timer_list sitesurvey_ctrl_timer; ++}; ++ ++struct rt_link_detect { ++ u32 NumTxOkInPeriod; ++ u32 NumRxOkInPeriod; ++ u32 NumRxUnicastOkInPeriod; ++ bool bBusyTraffic; ++ bool bTxBusyTraffic; ++ bool bRxBusyTraffic; ++ bool bHigherBusyTraffic; /* For interrupt migration purpose. */ ++ bool bHigherBusyRxTraffic; /* We may disable Tx interrupt according ++ * to Rx traffic. */ ++ bool bHigherBusyTxTraffic; /* We may disable Tx interrupt according ++ * to Tx traffic. */ ++}; ++ ++struct profile_info { ++ u8 ssidlen; ++ u8 ssid[ WLAN_SSID_MAXLEN ]; ++ u8 peermac[ ETH_ALEN ]; ++}; ++ ++struct tx_invite_req_info { ++ u8 token; ++ u8 benable; ++ u8 go_ssid[ WLAN_SSID_MAXLEN ]; ++ u8 ssidlen; ++ u8 go_bssid[ ETH_ALEN ]; ++ u8 peer_macaddr[ ETH_ALEN ]; ++ u8 operating_ch; /* This information will be set by using the ++ * p2p_set op_ch=x */ ++ u8 peer_ch; /* The listen channel for peer P2P device */ ++}; ++ ++struct tx_invite_resp_info { ++ u8 token; /* Used to record the dialog token of p2p invitation ++ * request frame. */ ++}; ++ ++struct tx_provdisc_req_info { ++ u16 wps_config_method_request; /* Used when sending the ++ * provisioning request frame*/ ++ u16 peer_channel_num[2]; /* The channel number which the ++ * receiver stands. */ ++ struct ndis_802_11_ssid ssid; ++ u8 peerDevAddr[ETH_ALEN]; /* Peer device address */ ++ u8 peerIFAddr[ETH_ALEN]; /* Peer interface address */ ++ u8 benable; /* This provision discovery ++ * request frame is trigger ++ * to send or not */ ++}; ++ ++/* When peer device issue prov_disc_req first, we should store the following ++ * information */ ++/* The UI must know this information to know which config method the ++ * remote p2p device needs. */ ++struct rx_provdisc_req_info { ++ u8 peerDevAddr[ETH_ALEN]; /* Peer device address */ ++ u8 strconfig_method_desc_of_prov_disc_req[4]; /* description ++ * for the config method located in the provisioning ++ * discovery request frame. */ ++}; ++ ++struct tx_nego_req_info { ++ u16 peer_channel_num[2]; /* The channel number. */ ++ u8 peerDevAddr[ETH_ALEN]; /* Peer device address */ ++ u8 benable; /* This negotiation request frame is ++ * trigger to send or not */ ++}; ++ ++struct group_id_info { ++ u8 go_device_addr[ ETH_ALEN ]; /* The GO's device address of ++ * this P2P group */ ++ u8 ssid[ WLAN_SSID_MAXLEN ]; /* The SSID of this P2P group */ ++}; ++ ++struct scan_limit_info { ++ u8 scan_op_ch_only; /* When this flag is set, the driver ++ * should only scan the op. channel */ ++ u8 operation_ch[2]; /* Store the op. chan of invitation */ ++}; ++ ++struct wifidirect_info { ++ struct adapter *padapter; ++ struct timer_list find_phase_timer; ++ struct timer_list restore_p2p_state_timer; ++ ++ /* Used to do the scanning. After confirming the peer is availalble, ++ * the driver transmits the P2P frame to peer. */ ++ struct timer_list pre_tx_scan_timer; ++ struct timer_list reset_ch_sitesurvey; ++ struct timer_list reset_ch_sitesurvey2; /* Just for resetting the scan ++ * limit function by using p2p nego */ ++ struct tx_provdisc_req_info tx_prov_disc_info; ++ struct rx_provdisc_req_info rx_prov_disc_info; ++ struct tx_invite_req_info invitereq_info; ++ /* Store the profile information of persistent group */ ++ struct profile_info profileinfo[P2P_MAX_PERSISTENT_GROUP_NUM]; ++ struct tx_invite_resp_info inviteresp_info; ++ struct tx_nego_req_info nego_req_info; ++ /* Store the group id info when doing the group negot handshake. */ ++ struct group_id_info groupid_info; ++ /* Used for get the limit scan channel from the Invitation procedure */ ++ struct scan_limit_info rx_invitereq_info; ++ /* Used for get the limit scan chan from the P2P negotiation handshake*/ ++ struct scan_limit_info p2p_info; ++ enum P2P_ROLE role; ++ enum P2P_STATE pre_p2p_state; ++ enum P2P_STATE p2p_state; ++ /* The device address should be the mac address of this device. */ ++ u8 device_addr[ETH_ALEN]; ++ u8 interface_addr[ETH_ALEN]; ++ u8 social_chan[4]; ++ u8 listen_channel; ++ u8 operating_channel; ++ u8 listen_dwell; /* This value should be between 1 and 3 */ ++ u8 support_rate[8]; ++ u8 p2p_wildcard_ssid[P2P_WILDCARD_SSID_LEN]; ++ u8 intent; /* should only include the intent value. */ ++ u8 p2p_peer_interface_addr[ETH_ALEN]; ++ u8 p2p_peer_device_addr[ETH_ALEN]; ++ u8 peer_intent; /* Included the intent value and tie breaker value. */ ++ /* Device name for displaying on searching device screen */ ++ u8 device_name[WPS_MAX_DEVICE_NAME_LEN]; ++ u8 device_name_len; ++ u8 profileindex; /* Used to point to the index of profileinfo array */ ++ u8 peer_operating_ch; ++ u8 find_phase_state_exchange_cnt; ++ /* The device password ID for group negotiation */ ++ u16 device_password_id_for_nego; ++ u8 negotiation_dialog_token; ++ /* SSID information for group negotitation */ ++ u8 nego_ssid[WLAN_SSID_MAXLEN]; ++ u8 nego_ssidlen; ++ u8 p2p_group_ssid[WLAN_SSID_MAXLEN]; ++ u8 p2p_group_ssid_len; ++ /* Flag to know if the persistent function should be supported or not.*/ ++ u8 persistent_supported; ++ /* In the Sigma test, the Sigma will provide this enable from the ++ * sta_set_p2p CAPI. */ ++ /* 0: disable */ ++ /* 1: enable */ ++ u8 session_available; /* Flag to set the WFD session available to ++ * enable or disable "by Sigma" */ ++ /* In the Sigma test, the Sigma will disable the session available ++ * by using the sta_preset CAPI. */ ++ /* 0: disable */ ++ /* 1: enable */ ++ u8 wfd_tdls_enable; /* Flag to enable or disable the TDLS by WFD Sigma*/ ++ /* 0: disable */ ++ /* 1: enable */ ++ u8 wfd_tdls_weaksec; /* Flag to enable or disable the weak security ++ * function for TDLS by WFD Sigma */ ++ /* 0: disable */ ++ /* In this case, the driver can't issue the tdsl ++ * setup request frame. */ ++ /* 1: enable */ ++ /* In this case, the driver can issue the tdls ++ * setup request frame */ ++ /* even the current security is weak security. */ ++ ++ /* This field will store the WPS value (PIN value or PBC) that UI had ++ * got from the user. */ ++ enum P2P_WPSINFO ui_got_wps_info; ++ u16 supported_wps_cm; /* This field describes the WPS config method ++ * which this driver supported. */ ++ /* The value should be the combination of config ++ * method defined in page104 of WPS v2.0 spec.*/ ++ /* This field will contain the length of body of P2P Channel List ++ * attribute of group negotiation response frame. */ ++ uint channel_list_attr_len; ++ /* This field will contain the body of P2P Channel List attribute of ++ * group negotitation response frame. */ ++ /* We will use the channel_cnt and channel_list fields when constructing ++ * the group negotiation confirm frame. */ ++ u8 channel_list_attr[100]; ++ enum P2P_PS_MODE p2p_ps_mode; /* indicate p2p ps mode */ ++ enum P2P_PS_STATE p2p_ps_state; /* indicate p2p ps state */ ++ u8 noa_index; /* Identifies and instance of Notice of Absence timing. */ ++ u8 ctwindow; /* Client traffic window. A period of time in TU after TBTT. */ ++ u8 opp_ps; /* opportunistic power save. */ ++ u8 noa_num; /* number of NoA descriptor in P2P IE. */ ++ u8 noa_count[P2P_MAX_NOA_NUM]; /* Count for owner, Type of client. */ ++ /* Max duration for owner, preferred or min acceptable duration for ++ * client. */ ++ u32 noa_duration[P2P_MAX_NOA_NUM]; ++ /* Length of interval for owner, preferred or max acceptable interval ++ * of client. */ ++ u32 noa_interval[P2P_MAX_NOA_NUM]; ++ /* schedule expressed in terms of the lower 4 bytes of the TSF timer. */ ++ u32 noa_start_time[P2P_MAX_NOA_NUM]; ++}; ++ ++struct tdls_ss_record { /* signal strength record */ ++ u8 macaddr[ETH_ALEN]; ++ u8 RxPWDBAll; ++ u8 is_tdls_sta; /* true: direct link sta, false: else */ ++}; ++ ++struct tdls_info { ++ u8 ap_prohibited; ++ uint setup_state; ++ u8 sta_cnt; ++ u8 sta_maximum; /* 1:tdls sta is equal (NUM_STA-1), reach max direct link number; 0: else; */ ++ struct tdls_ss_record ss_record; ++ u8 macid_index; /* macid entry that is ready to write */ ++ u8 clear_cam; /* cam entry that is trying to clear, using it in direct link teardown */ ++ u8 ch_sensing; ++ u8 cur_channel; ++ u8 candidate_ch; ++ u8 collect_pkt_num[MAX_CHANNEL_NUM]; ++ spinlock_t cmd_lock; ++ spinlock_t hdl_lock; ++ u8 watchdog_count; ++ u8 dev_discovered; /* WFD_TDLS: for sigma test */ ++ u8 enable; ++}; ++ ++struct qos_priv { ++ /* bit mask option: u-apsd, ++ * s-apsd, ts, block ack... */ ++ unsigned int qos_option; ++}; ++ ++struct mlme_priv { ++ spinlock_t lock; ++ int fw_state; /* shall we protect this variable? maybe not necessarily... */ ++ u8 bScanInProcess; ++ u8 to_join; /* flag */ ++ u8 to_roaming; /* roaming trying times */ ++ ++ u8 *nic_hdl; ++ ++ u8 not_indic_disco; ++ struct list_head *pscanned; ++ struct __queue free_bss_pool; ++ struct __queue scanned_queue; ++ u8 *free_bss_buf; ++ u8 key_mask; /* use to restore wep key after hal_init */ ++ u32 num_of_scanned; ++ ++ struct ndis_802_11_ssid assoc_ssid; ++ u8 assoc_bssid[6]; ++ ++ struct wlan_network cur_network; ++ struct wlan_network *cur_network_scanned; ++ ++ u32 scan_interval; ++ ++ struct timer_list assoc_timer; ++ ++ uint assoc_by_bssid; ++ uint assoc_by_rssi; ++ ++ struct timer_list scan_to_timer; /* driver itself handles scan_timeout status. */ ++ u32 scan_start_time; /* used to evaluate the time spent in scanning */ ++ ++ struct qos_priv qospriv; ++ ++ /* Number of non-HT AP/stations */ ++ int num_sta_no_ht; ++ ++ /* Number of HT AP/stations 20 MHz */ ++ /* int num_sta_ht_20mhz; */ ++ ++ int num_FortyMHzIntolerant; ++ struct ht_priv htpriv; ++ struct rt_link_detect LinkDetectInfo; ++ struct timer_list dynamic_chk_timer; /* dynamic/periodic check timer */ ++ ++ u8 acm_mask; /* for wmm acm mask */ ++ u8 ChannelPlan; ++ enum rt_scan_type scan_mode; /* active: 1, passive: 0 */ ++ ++ /* u8 probereq_wpsie[MAX_WPS_IE_LEN];added in probe req */ ++ /* int probereq_wpsie_len; */ ++ u8 *wps_probe_req_ie; ++ u32 wps_probe_req_ie_len; ++ ++ u8 *assoc_req; ++ u32 assoc_req_len; ++ u8 *assoc_rsp; ++ u32 assoc_rsp_len; ++ ++#if defined (CONFIG_88EU_AP_MODE) ++ /* Number of associated Non-ERP stations (i.e., stations using 802.11b ++ * in 802.11g BSS) */ ++ int num_sta_non_erp; ++ ++ /* Number of associated stations that do not support Short Slot Time */ ++ int num_sta_no_short_slot_time; ++ ++ /* Number of associated stations that do not support Short Preamble */ ++ int num_sta_no_short_preamble; ++ ++ int olbc; /* Overlapping Legacy BSS Condition */ ++ ++ /* Number of HT assoc sta that do not support greenfield */ ++ int num_sta_ht_no_gf; ++ ++ /* Number of associated non-HT stations */ ++ /* int num_sta_no_ht; */ ++ ++ /* Number of HT associated stations 20 MHz */ ++ int num_sta_ht_20mhz; ++ ++ /* Overlapping BSS information */ ++ int olbc_ht; ++ ++ u16 ht_op_mode; ++ ++ u8 *wps_beacon_ie; ++ /* u8 *wps_probe_req_ie; */ ++ u8 *wps_probe_resp_ie; ++ u8 *wps_assoc_resp_ie; ++ ++ u32 wps_beacon_ie_len; ++ u32 wps_probe_resp_ie_len; ++ u32 wps_assoc_resp_ie_len; ++ ++ u8 *p2p_beacon_ie; ++ u8 *p2p_probe_req_ie; ++ u8 *p2p_probe_resp_ie; ++ u8 *p2p_go_probe_resp_ie; /* for GO */ ++ u8 *p2p_assoc_req_ie; ++ ++ u32 p2p_beacon_ie_len; ++ u32 p2p_probe_req_ie_len; ++ u32 p2p_probe_resp_ie_len; ++ u32 p2p_go_probe_resp_ie_len; /* for GO */ ++ u32 p2p_assoc_req_ie_len; ++ spinlock_t bcn_update_lock; ++ u8 update_bcn; ++#endif /* if defined (CONFIG_88EU_AP_MODE) */ ++}; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++struct hostapd_priv { ++ struct adapter *padapter; ++}; ++ ++int hostapd_mode_init(struct adapter *padapter); ++void hostapd_mode_unload(struct adapter *padapter); ++#endif ++ ++extern unsigned char WPA_TKIP_CIPHER[4]; ++extern unsigned char RSN_TKIP_CIPHER[4]; ++extern unsigned char REALTEK_96B_IE[]; ++extern unsigned char MCS_rate_2R[16]; ++extern unsigned char MCS_rate_1R[16]; ++ ++void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf); ++void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf); ++void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf); ++void rtw_joinbss_event_callback(struct adapter *adapter, u8 *pbuf); ++void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf); ++void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf); ++void indicate_wx_scan_complete_event(struct adapter *padapter); ++void rtw_indicate_wx_assoc_event(struct adapter *padapter); ++void rtw_indicate_wx_disassoc_event(struct adapter *padapter); ++int event_thread(void *context); ++void rtw_join_timeout_handler (struct timer_list *t); ++void _rtw_scan_timeout_handler (struct timer_list *t); ++void rtw_free_network_queue(struct adapter *adapter, u8 isfreeall); ++int rtw_init_mlme_priv(struct adapter *adapter); ++void rtw_free_mlme_priv (struct mlme_priv *pmlmepriv); ++int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv); ++int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, ++ int keyid, u8 set_tx); ++int rtw_set_auth(struct adapter *adapter, struct security_priv *psecuritypriv); ++ ++static inline u8 *get_bssid(struct mlme_priv *pmlmepriv) ++{ /* if sta_mode:pmlmepriv->cur_network.network.MacAddress=> bssid */ ++ /* if adhoc_mode:pmlmepriv->cur_network.network.MacAddress=> ibss mac address */ ++ return pmlmepriv->cur_network.network.MacAddress; ++} ++ ++static inline int check_fwstate(struct mlme_priv *pmlmepriv, int state) ++{ ++ if (pmlmepriv->fw_state & state) ++ return true; ++ ++ return false; ++} ++ ++static inline int get_fwstate(struct mlme_priv *pmlmepriv) ++{ ++ return pmlmepriv->fw_state; ++} ++ ++/* ++ * No Limit on the calling context, ++ * therefore set it to be the critical section... ++ * ++ * ### NOTE:#### (!!!!) ++ * MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock ++ */ ++static inline void set_fwstate(struct mlme_priv *pmlmepriv, int state) ++{ ++ pmlmepriv->fw_state |= state; ++ /* FOR HW integration */ ++ if (_FW_UNDER_SURVEY==state) ++ pmlmepriv->bScanInProcess = true; ++} ++ ++static inline void _clr_fwstate_(struct mlme_priv *pmlmepriv, int state) ++{ ++ pmlmepriv->fw_state &= ~state; ++ /* FOR HW integration */ ++ if (_FW_UNDER_SURVEY==state) ++ pmlmepriv->bScanInProcess = false; ++} ++ ++/* ++ * No Limit on the calling context, ++ * therefore set it to be the critical section... ++ */ ++static inline void clr_fwstate(struct mlme_priv *pmlmepriv, int state) ++{ ++ spin_lock_bh(&pmlmepriv->lock); ++ if (check_fwstate(pmlmepriv, state)) ++ pmlmepriv->fw_state ^= state; ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++static inline void clr_fwstate_ex(struct mlme_priv *pmlmepriv, int state) ++{ ++ spin_lock_bh(&pmlmepriv->lock); ++ _clr_fwstate_(pmlmepriv, state); ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++static inline void up_scanned_network(struct mlme_priv *pmlmepriv) ++{ ++ spin_lock_bh(&pmlmepriv->lock); ++ pmlmepriv->num_of_scanned++; ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++static inline void down_scanned_network(struct mlme_priv *pmlmepriv) ++{ ++ spin_lock_bh(&pmlmepriv->lock); ++ pmlmepriv->num_of_scanned--; ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++static inline void set_scanned_network_val(struct mlme_priv *pmlmepriv, int val) ++{ ++ spin_lock_bh(&pmlmepriv->lock); ++ pmlmepriv->num_of_scanned = val; ++ spin_unlock_bh(&pmlmepriv->lock); ++} ++ ++u16 rtw_get_capability(struct wlan_bssid_ex *bss); ++void rtw_update_scanned_network(struct adapter *adapter, ++ struct wlan_bssid_ex *target); ++void rtw_disconnect_hdl_under_linked(struct adapter *adapter, ++ struct sta_info *psta, u8 free_assoc); ++void rtw_generate_random_ibss(u8 *pibss); ++struct wlan_network *rtw_find_network(struct __queue *scanned_queue, u8 *addr); ++struct wlan_network *rtw_get_oldest_wlan_network(struct __queue *scanned_queue); ++ ++void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue); ++void rtw_indicate_disconnect(struct adapter *adapter); ++void rtw_indicate_connect(struct adapter *adapter); ++void rtw_indicate_scan_done( struct adapter *padapter, bool aborted); ++void rtw_scan_abort(struct adapter *adapter); ++ ++int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, ++ uint in_len); ++int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, ++ uint in_len, uint initial_out_len); ++void rtw_init_registrypriv_dev_network(struct adapter *adapter); ++ ++void rtw_update_registrypriv_dev_network(struct adapter *adapter); ++ ++void rtw_get_encrypt_decrypt_from_registrypriv(struct adapter *adapter); ++ ++void _rtw_join_timeout_handler(struct adapter *adapter); ++void rtw_scan_timeout_handler(struct adapter *adapter); ++ ++ void rtw_dynamic_check_timer_handlder(struct adapter *adapter); ++#define rtw_is_scan_deny(adapter) false ++#define rtw_clear_scan_deny(adapter) do {} while (0) ++#define rtw_set_scan_deny_timer_hdl(adapter) do {} while (0) ++#define rtw_set_scan_deny(adapter, ms) do {} while (0) ++ ++int _rtw_init_mlme_priv(struct adapter *padapter); ++ ++void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv); ++ ++void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv); ++ ++int _rtw_enqueue_network(struct __queue *queue, struct wlan_network *pnetwork); ++ ++struct wlan_network *_rtw_dequeue_network(struct __queue *queue); ++ ++ struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv); ++ ++void _rtw_free_network(struct mlme_priv *pmlmepriv, ++ struct wlan_network *pnetwork, u8 isfreeall); ++void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, ++ struct wlan_network *pnetwork); ++ ++struct wlan_network* _rtw_find_network(struct __queue *scanned_queue, u8 *addr); ++ ++void _rtw_free_network_queue(struct adapter *padapter, u8 isfreeall); ++ ++int rtw_if_up(struct adapter *padapter); ++ ++u8 *rtw_get_capability_from_ie(u8 *ie); ++u8 *rtw_get_timestampe_from_ie(u8 *ie); ++u8 *rtw_get_beacon_interval_from_ie(u8 *ie); ++ ++void rtw_joinbss_reset(struct adapter *padapter); ++ ++unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, ++ u8 *out_ie, uint in_len, uint *pout_len); ++void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len); ++void rtw_issue_addbareq_cmd(struct adapter *padapter, ++ struct xmit_frame *pxmitframe); ++ ++int rtw_is_same_ibss(struct adapter *adapter, struct wlan_network *pnetwork); ++int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst); ++ ++void rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network); ++void _rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network); ++void rtw_set_roaming(struct adapter *adapter, u8 to_roaming); ++u8 rtw_to_roaming(struct adapter *adapter); ++ ++void rtw_sta_media_status_rpt(struct adapter *adapter, struct sta_info *psta, ++ u32 mstatus); ++ ++#endif /* __RTL871X_MLME_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h +new file mode 100644 +index 000000000000..d2f4d3ce7b90 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h +@@ -0,0 +1,857 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_MLME_EXT_H_ ++#define __RTW_MLME_EXT_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "wlan_bssdef.h" ++ ++/* Commented by Albert 20101105 */ ++/* Increase the SURVEY_TO value from 100 to 150 ( 100ms to 150ms ) */ ++/* The Realtek 8188CE SoftAP will spend around 100ms to send the probe response after receiving the probe request. */ ++/* So, this driver tried to extend the dwell time for each scanning channel. */ ++/* This will increase the chance to receive the probe response from SoftAP. */ ++ ++#define SURVEY_TO (100) ++#define REAUTH_TO (300) /* 50) */ ++#define REASSOC_TO (300) /* 50) */ ++/* define DISCONNECT_TO (3000) */ ++#define ADDBA_TO (2000) ++ ++#define LINKED_TO (1) /* unit:2 sec, 1x2=2 sec */ ++ ++#define REAUTH_LIMIT (4) ++#define REASSOC_LIMIT (4) ++#define READDBA_LIMIT (2) ++ ++#define ROAMING_LIMIT 8 ++ ++#define DYNAMIC_FUNC_DISABLE (0x0) ++ ++/* ====== ODM_ABILITY_E ======== */ ++/* BB ODM section BIT 0-15 */ ++#define DYNAMIC_BB_DIG BIT(0) ++#define DYNAMIC_BB_RA_MASK BIT(1) ++#define DYNAMIC_BB_DYNAMIC_TXPWR BIT(2) ++#define DYNAMIC_BB_BB_FA_CNT BIT(3) ++ ++#define DYNAMIC_BB_RSSI_MONITOR BIT(4) ++#define DYNAMIC_BB_CCK_PD BIT(5) ++#define DYNAMIC_BB_ANT_DIV BIT(6) ++#define DYNAMIC_BB_PWR_SAVE BIT(7) ++#define DYNAMIC_BB_PWR_TRA BIT(8) ++#define DYNAMIC_BB_RATE_ADAPTIVE BIT(9) ++#define DYNAMIC_BB_PATH_DIV BIT(10) ++#define DYNAMIC_BB_PSD BIT(11) ++ ++/* MAC DM section BIT 16-23 */ ++#define DYNAMIC_MAC_EDCA_TURBO BIT(16) ++#define DYNAMIC_MAC_EARLY_MODE BIT(17) ++ ++/* RF ODM section BIT 24-31 */ ++#define DYNAMIC_RF_TX_PWR_TRACK BIT(24) ++#define DYNAMIC_RF_RX_GAIN_TRACK BIT(25) ++#define DYNAMIC_RF_CALIBRATION BIT(26) ++ ++#define DYNAMIC_ALL_FUNC_ENABLE 0xFFFFFFF ++ ++#define _HW_STATE_NOLINK_ 0x00 ++#define _HW_STATE_ADHOC_ 0x01 ++#define _HW_STATE_STATION_ 0x02 ++#define _HW_STATE_AP_ 0x03 ++ ++#define _1M_RATE_ 0 ++#define _2M_RATE_ 1 ++#define _5M_RATE_ 2 ++#define _11M_RATE_ 3 ++#define _6M_RATE_ 4 ++#define _9M_RATE_ 5 ++#define _12M_RATE_ 6 ++#define _18M_RATE_ 7 ++#define _24M_RATE_ 8 ++#define _36M_RATE_ 9 ++#define _48M_RATE_ 10 ++#define _54M_RATE_ 11 ++ ++extern unsigned char RTW_WPA_OUI[]; ++extern unsigned char WMM_OUI[]; ++extern unsigned char WPS_OUI[]; ++extern unsigned char WFD_OUI[]; ++extern unsigned char P2P_OUI[]; ++ ++extern unsigned char WMM_INFO_OUI[]; ++extern unsigned char WMM_PARA_OUI[]; ++ ++/* Channel Plan Type. */ ++/* Note: */ ++/* We just add new channel plan when the new channel plan is different ++ * from any of the following channel plan. */ ++/* If you just want to customize the actions(scan period or join actions) ++ * about one of the channel plan, */ ++/* customize them in struct rt_channel_info in the RT_CHANNEL_LIST. */ ++enum RT_CHANNEL_DOMAIN { ++ /* old channel plan mapping ===== */ ++ RT_CHANNEL_DOMAIN_FCC = 0x00, ++ RT_CHANNEL_DOMAIN_IC = 0x01, ++ RT_CHANNEL_DOMAIN_ETSI = 0x02, ++ RT_CHANNEL_DOMAIN_SPAIN = 0x03, ++ RT_CHANNEL_DOMAIN_FRANCE = 0x04, ++ RT_CHANNEL_DOMAIN_MKK = 0x05, ++ RT_CHANNEL_DOMAIN_MKK1 = 0x06, ++ RT_CHANNEL_DOMAIN_ISRAEL = 0x07, ++ RT_CHANNEL_DOMAIN_TELEC = 0x08, ++ RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN = 0x09, ++ RT_CHANNEL_DOMAIN_WORLD_WIDE_13 = 0x0A, ++ RT_CHANNEL_DOMAIN_TAIWAN = 0x0B, ++ RT_CHANNEL_DOMAIN_CHINA = 0x0C, ++ RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO = 0x0D, ++ RT_CHANNEL_DOMAIN_KOREA = 0x0E, ++ RT_CHANNEL_DOMAIN_TURKEY = 0x0F, ++ RT_CHANNEL_DOMAIN_JAPAN = 0x10, ++ RT_CHANNEL_DOMAIN_FCC_NO_DFS = 0x11, ++ RT_CHANNEL_DOMAIN_JAPAN_NO_DFS = 0x12, ++ RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS = 0x14, ++ ++ /* new channel plan mapping, (2GDOMAIN_5GDOMAIN) ===== */ ++ RT_CHANNEL_DOMAIN_WORLD_NULL = 0x20, ++ RT_CHANNEL_DOMAIN_ETSI1_NULL = 0x21, ++ RT_CHANNEL_DOMAIN_FCC1_NULL = 0x22, ++ RT_CHANNEL_DOMAIN_MKK1_NULL = 0x23, ++ RT_CHANNEL_DOMAIN_ETSI2_NULL = 0x24, ++ RT_CHANNEL_DOMAIN_FCC1_FCC1 = 0x25, ++ RT_CHANNEL_DOMAIN_WORLD_ETSI1 = 0x26, ++ RT_CHANNEL_DOMAIN_MKK1_MKK1 = 0x27, ++ RT_CHANNEL_DOMAIN_WORLD_KCC1 = 0x28, ++ RT_CHANNEL_DOMAIN_WORLD_FCC2 = 0x29, ++ RT_CHANNEL_DOMAIN_WORLD_FCC3 = 0x30, ++ RT_CHANNEL_DOMAIN_WORLD_FCC4 = 0x31, ++ RT_CHANNEL_DOMAIN_WORLD_FCC5 = 0x32, ++ RT_CHANNEL_DOMAIN_WORLD_FCC6 = 0x33, ++ RT_CHANNEL_DOMAIN_FCC1_FCC7 = 0x34, ++ RT_CHANNEL_DOMAIN_WORLD_ETSI2 = 0x35, ++ RT_CHANNEL_DOMAIN_WORLD_ETSI3 = 0x36, ++ RT_CHANNEL_DOMAIN_MKK1_MKK2 = 0x37, ++ RT_CHANNEL_DOMAIN_MKK1_MKK3 = 0x38, ++ RT_CHANNEL_DOMAIN_FCC1_NCC1 = 0x39, ++ RT_CHANNEL_DOMAIN_FCC1_NCC2 = 0x40, ++ RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G = 0x41, ++ /* Add new channel plan above this line=============== */ ++ RT_CHANNEL_DOMAIN_MAX, ++ RT_CHANNEL_DOMAIN_REALTEK_DEFINE = 0x7F, ++}; ++ ++enum RT_CHANNEL_DOMAIN_2G { ++ RT_CHANNEL_DOMAIN_2G_WORLD = 0x00, /* Worldwide 13 */ ++ RT_CHANNEL_DOMAIN_2G_ETSI1 = 0x01, /* Europe */ ++ RT_CHANNEL_DOMAIN_2G_FCC1 = 0x02, /* US */ ++ RT_CHANNEL_DOMAIN_2G_MKK1 = 0x03, /* Japan */ ++ RT_CHANNEL_DOMAIN_2G_ETSI2 = 0x04, /* France */ ++ RT_CHANNEL_DOMAIN_2G_NULL = 0x05, ++ /* Add new channel plan above this line=============== */ ++ RT_CHANNEL_DOMAIN_2G_MAX, ++}; ++ ++#define rtw_is_channel_plan_valid(chplan) \ ++ (chplan < RT_CHANNEL_DOMAIN_MAX || \ ++ chplan == RT_CHANNEL_DOMAIN_REALTEK_DEFINE) ++ ++struct rt_channel_plan { ++ unsigned char Channel[MAX_CHANNEL_NUM]; ++ unsigned char Len; ++}; ++ ++struct rt_channel_plan_2g { ++ unsigned char Channel[MAX_CHANNEL_NUM_2G]; ++ unsigned char Len; ++}; ++ ++struct rt_channel_plan_map { ++ unsigned char Index2G; ++}; ++ ++enum Associated_AP { ++ atherosAP = 0, ++ broadcomAP = 1, ++ ciscoAP = 2, ++ marvellAP = 3, ++ ralinkAP = 4, ++ realtekAP = 5, ++ airgocapAP = 6, ++ unknownAP = 7, ++ maxAP, ++}; ++ ++enum HT_IOT_PEER { ++ HT_IOT_PEER_UNKNOWN = 0, ++ HT_IOT_PEER_REALTEK = 1, ++ HT_IOT_PEER_REALTEK_92SE = 2, ++ HT_IOT_PEER_BROADCOM = 3, ++ HT_IOT_PEER_RALINK = 4, ++ HT_IOT_PEER_ATHEROS = 5, ++ HT_IOT_PEER_CISCO = 6, ++ HT_IOT_PEER_MERU = 7, ++ HT_IOT_PEER_MARVELL = 8, ++ HT_IOT_PEER_REALTEK_SOFTAP = 9,/* peer is RealTek SOFT_AP */ ++ HT_IOT_PEER_SELF_SOFTAP = 10, /* Self is SoftAP */ ++ HT_IOT_PEER_AIRGO = 11, ++ HT_IOT_PEER_INTEL = 12, ++ HT_IOT_PEER_RTK_APCLIENT = 13, ++ HT_IOT_PEER_REALTEK_81XX = 14, ++ HT_IOT_PEER_REALTEK_WOW = 15, ++ HT_IOT_PEER_TENDA = 16, ++ HT_IOT_PEER_MAX = 17 ++}; ++ ++enum SCAN_STATE { ++ SCAN_DISABLE = 0, ++ SCAN_START = 1, ++ SCAN_TXNULL = 2, ++ SCAN_PROCESS = 3, ++ SCAN_COMPLETE = 4, ++ SCAN_STATE_MAX, ++}; ++ ++struct mlme_handler { ++ unsigned int num; ++ char *str; ++ unsigned int (*func)(struct adapter *adapt, struct recv_frame *frame); ++}; ++ ++struct action_handler { ++ unsigned int num; ++ char* str; ++ unsigned int (*func)(struct adapter *adapt, struct recv_frame *frame); ++}; ++ ++struct ss_res { ++ int state; ++ int bss_cnt; ++ int channel_idx; ++ int scan_mode; ++ u8 ssid_num; ++ u8 ch_num; ++ struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT]; ++ struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT]; ++}; ++ ++/* define AP_MODE 0x0C */ ++/* define STATION_MODE 0x08 */ ++/* define AD_HOC_MODE 0x04 */ ++/* define NO_LINK_MODE 0x00 */ ++ ++#define WIFI_FW_NULL_STATE _HW_STATE_NOLINK_ ++#define WIFI_FW_STATION_STATE _HW_STATE_STATION_ ++#define WIFI_FW_AP_STATE _HW_STATE_AP_ ++#define WIFI_FW_ADHOC_STATE _HW_STATE_ADHOC_ ++ ++#define WIFI_FW_AUTH_NULL 0x00000100 ++#define WIFI_FW_AUTH_STATE 0x00000200 ++#define WIFI_FW_AUTH_SUCCESS 0x00000400 ++ ++#define WIFI_FW_ASSOC_STATE 0x00002000 ++#define WIFI_FW_ASSOC_SUCCESS 0x00004000 ++ ++#define WIFI_FW_LINKING_STATE (WIFI_FW_AUTH_NULL | \ ++ WIFI_FW_AUTH_STATE | \ ++ WIFI_FW_AUTH_SUCCESS | \ ++ WIFI_FW_ASSOC_STATE) ++ ++struct FW_Sta_Info { ++ struct sta_info *psta; ++ u32 status; ++ u32 rx_pkt; ++ u32 retry; ++ unsigned char SupportedRates[NDIS_802_11_LENGTH_RATES_EX]; ++}; ++ ++/* ++ * Usage: ++ * When one iface acted as AP mode and the other iface is STA mode and scanning, ++ * it should switch back to AP's operating channel periodically. ++ * Parameters info: ++ * When the driver scanned RTW_SCAN_NUM_OF_CH channels, it would switch back to ++ * AP's operating channel for ++ * RTW_STAY_AP_CH_MILLISECOND * SURVEY_TO milliseconds. ++ * Example: ++ * For chip supports 2.4G + 5GHz and AP mode is operating in channel 1, ++ * RTW_SCAN_NUM_OF_CH is 8, RTW_STAY_AP_CH_MS is 3 and SURVEY_TO is 100. ++ * When it's STA mode gets set_scan command, ++ * it would ++ * 1. Doing the scan on channel 1.2.3.4.5.6.7.8 ++ * 2. Back to channel 1 for 300 milliseconds ++ * 3. Go through doing site survey on channel 9.10.11.36.40.44.48.52 ++ * 4. Back to channel 1 for 300 milliseconds ++ * 5. ... and so on, till survey done. ++ */ ++ ++struct mlme_ext_info { ++ u32 state; ++ u32 reauth_count; ++ u32 reassoc_count; ++ u32 link_count; ++ u32 auth_seq; ++ u32 auth_algo; /* 802.11 auth, could be open, shared, auto */ ++ u32 authModeToggle; ++ u32 enc_algo;/* encrypt algorithm; */ ++ u32 key_index; /* this is only valid for legacy wep, ++ * 0~3 for key id. */ ++ u32 iv; ++ u8 chg_txt[128]; ++ u16 aid; ++ u16 bcn_interval; ++ u16 capability; ++ u8 assoc_AP_vendor; ++ u8 slotTime; ++ u8 preamble_mode; ++ u8 WMM_enable; ++ u8 ERP_enable; ++ u8 ERP_IE; ++ u8 HT_enable; ++ u8 HT_caps_enable; ++ u8 HT_info_enable; ++ u8 HT_protection; ++ u8 turboMode_cts2self; ++ u8 turboMode_rtsen; ++ u8 SM_PS; ++ u8 agg_enable_bitmap; ++ u8 ADDBA_retry_count; ++ u8 candidate_tid_bitmap; ++ u8 dialogToken; ++ /* Accept ADDBA Request */ ++ bool bAcceptAddbaReq; ++ u8 bwmode_updated; ++ u8 hidden_ssid_mode; ++ ++ struct ADDBA_request ADDBA_req; ++ struct WMM_para_element WMM_param; ++ struct HT_caps_element HT_caps; ++ struct HT_info_element HT_info; ++ struct wlan_bssid_ex network;/* join network or bss_network, ++ * if in ap mode, it is the same ++ * as cur_network.network */ ++ struct FW_Sta_Info FW_sta_info[NUM_STA]; ++}; ++ ++/* The channel information about this channel including joining, ++ * scanning, and power constraints. */ ++struct rt_channel_info { ++ u8 ChannelNum; /* The channel number. */ ++ enum rt_scan_type ScanType; /* Scan type such as passive ++ * or active scan. */ ++ u32 rx_count; ++}; ++ ++int rtw_ch_set_search_ch(struct rt_channel_info *ch_set, const u32 ch); ++ ++/* P2P_MAX_REG_CLASSES - Maximum number of regulatory classes */ ++#define P2P_MAX_REG_CLASSES 10 ++ ++/* P2P_MAX_REG_CLASS_CHANNELS - Maximum number of chan per regulatory class */ ++#define P2P_MAX_REG_CLASS_CHANNELS 20 ++ ++/* struct p2p_channels - List of supported channels */ ++struct p2p_channels { ++ /* struct p2p_reg_class - Supported regulatory class */ ++ struct p2p_reg_class { ++ /* reg_class - Regulatory class (IEEE 802.11-2007, Annex J) */ ++ u8 reg_class; ++ ++ /* channel - Supported channels */ ++ u8 channel[P2P_MAX_REG_CLASS_CHANNELS]; ++ ++ /* channels - Number of channel entries in use */ ++ size_t channels; ++ } reg_class[P2P_MAX_REG_CLASSES]; ++ ++ /* reg_classes - Number of reg_class entries in use */ ++ size_t reg_classes; ++}; ++ ++struct p2p_oper_class_map { ++ enum hw_mode {IEEE80211G} mode; ++ u8 op_class; ++ u8 min_chan; ++ u8 max_chan; ++ u8 inc; ++ enum {BW20, BW40PLUS, BW40MINUS} bw; ++}; ++ ++struct mlme_ext_priv { ++ struct adapter *padapter; ++ u8 mlmeext_init; ++ atomic_t event_seq; ++ u16 mgnt_seq; ++ ++ unsigned char cur_channel; ++ unsigned char cur_bwmode; ++ unsigned char cur_ch_offset;/* PRIME_CHNL_OFFSET */ ++ unsigned char cur_wireless_mode; /* NETWORK_TYPE */ ++ ++ unsigned char oper_channel; /* saved chan info when call ++ * set_channel_bw */ ++ unsigned char oper_bwmode; ++ unsigned char oper_ch_offset;/* PRIME_CHNL_OFFSET */ ++ ++ unsigned char max_chan_nums; ++ struct rt_channel_info channel_set[MAX_CHANNEL_NUM]; ++ struct p2p_channels channel_list; ++ unsigned char basicrate[NumRates]; ++ unsigned char datarate[NumRates]; ++ ++ struct ss_res sitesurvey_res; ++ struct mlme_ext_info mlmext_info;/* for sta/adhoc mode, including ++ * current scan/connecting/connected ++ * related info. For ap mode, ++ * network includes ap's cap_info*/ ++ struct timer_list survey_timer; ++ struct timer_list link_timer; ++ u16 chan_scan_time; ++ ++ u8 scan_abort; ++ u8 tx_rate; /* TXRATE when USERATE is set. */ ++ ++ u32 retry; /* retry for issue probereq */ ++ ++ u64 TSFValue; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ unsigned char bstart_bss; ++#endif ++ u8 update_channel_plan_by_ap_done; ++ /* recv_decache check for Action_public frame */ ++ u8 action_public_dialog_token; ++ u16 action_public_rxseq; ++ u8 active_keep_alive_check; ++}; ++ ++int init_mlme_ext_priv(struct adapter *adapter); ++int init_hw_mlme_ext(struct adapter *padapter); ++void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext); ++extern void init_mlme_ext_timer(struct adapter *padapter); ++extern void init_addba_retry_timer(struct adapter *adapt, struct sta_info *sta); ++extern struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv); ++ ++unsigned char networktype_to_raid(unsigned char network_type); ++u8 judge_network_type(struct adapter *padapter, unsigned char *rate, int len); ++void get_rate_set(struct adapter *padapter, unsigned char *pbssrate, int *len); ++void UpdateBrateTbl(struct adapter *padapter, u8 *mBratesOS); ++void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen); ++ ++void Save_DM_Func_Flag(struct adapter *padapter); ++void Restore_DM_Func_Flag(struct adapter *padapter); ++void Switch_DM_Func(struct adapter *padapter, u32 mode, u8 enable); ++ ++void Set_MSR(struct adapter *padapter, u8 type); ++ ++u8 rtw_get_oper_ch(struct adapter *adapter); ++void rtw_set_oper_ch(struct adapter *adapter, u8 ch); ++u8 rtw_get_oper_bw(struct adapter *adapter); ++void rtw_set_oper_bw(struct adapter *adapter, u8 bw); ++u8 rtw_get_oper_choffset(struct adapter *adapter); ++void rtw_set_oper_choffset(struct adapter *adapter, u8 offset); ++ ++void set_channel_bwmode(struct adapter *padapter, unsigned char channel, ++ unsigned char channel_offset, unsigned short bwmode); ++void SelectChannel(struct adapter *padapter, unsigned char channel); ++void SetBWMode(struct adapter *padapter, unsigned short bwmode, ++ unsigned char channel_offset); ++ ++unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval); ++ ++void write_cam(struct adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key); ++void clear_cam_entry(struct adapter *padapter, u8 entry); ++ ++void invalidate_cam_all(struct adapter *padapter); ++void CAM_empty_entry(struct adapter * Adapter, u8 ucIndex); ++ ++int allocate_fw_sta_entry(struct adapter *padapter); ++void flush_all_cam_entry(struct adapter *padapter); ++ ++void site_survey(struct adapter *padapter); ++u8 collect_bss_info(struct adapter *padapter, struct recv_frame *precv_frame, ++ struct wlan_bssid_ex *bssid); ++void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, ++ struct adapter *adapter, bool update_ie); ++ ++int get_bsstype(unsigned short capability); ++u8 *get_my_bssid(struct wlan_bssid_ex *pnetwork); ++u16 get_beacon_interval(struct wlan_bssid_ex *bss); ++ ++int is_client_associated_to_ap(struct adapter *padapter); ++int is_client_associated_to_ibss(struct adapter *padapter); ++int is_IBSS_empty(struct adapter *padapter); ++ ++unsigned char check_assoc_AP(u8 *pframe, uint len); ++ ++int WMM_param_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE); ++void WMMOnAssocRsp(struct adapter *padapter); ++ ++void HT_caps_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE); ++void HT_info_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE); ++void HTOnAssocRsp(struct adapter *padapter); ++ ++void ERP_IE_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE); ++void VCS_update(struct adapter *padapter, struct sta_info *psta); ++ ++void update_beacon_info(struct adapter *padapter, u8 *pframe, uint len, ++ struct sta_info *psta); ++int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len); ++void update_IOT_info(struct adapter *padapter); ++void update_capinfo(struct adapter *adapter, u16 updatecap); ++void update_wireless_mode(struct adapter *padapter); ++void update_tx_basic_rate(struct adapter *padapter, u8 modulation); ++void update_bmc_sta_support_rate(struct adapter *padapter, u32 mac_id); ++int update_sta_support_rate(struct adapter *padapter, u8 *pvar_ie, ++ uint var_ie_len, int cam_idx); ++ ++/* for sta/adhoc mode */ ++void update_sta_info(struct adapter *padapter, struct sta_info *psta); ++unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz); ++unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz); ++unsigned int update_MSC_rate(struct HT_caps_element *pHT_caps); ++void Update_RA_Entry(struct adapter *padapter, u32 mac_id); ++void set_sta_rate(struct adapter *padapter, struct sta_info *psta); ++ ++unsigned int receive_disconnect(struct adapter *padapter, ++ unsigned char *macaddr, unsigned short reason); ++ ++unsigned char get_highest_rate_idx(u32 mask); ++int support_short_GI(struct adapter *padapter, struct HT_caps_element *caps); ++unsigned int is_ap_in_tkip(struct adapter *padapter); ++unsigned int is_ap_in_wep(struct adapter *padapter); ++unsigned int should_forbid_n_rate(struct adapter *padapter); ++ ++void report_join_res(struct adapter *padapter, int res); ++void report_survey_event(struct adapter *padapter, struct recv_frame *precv_frame); ++void report_surveydone_event(struct adapter *padapter); ++void report_del_sta_event(struct adapter *padapter, ++ unsigned char *addr, unsigned short reason); ++void report_add_sta_event(struct adapter *padapter, unsigned char* addr, ++ int cam_idx); ++ ++void beacon_timing_control(struct adapter *padapter); ++extern u8 set_tx_beacon_cmd(struct adapter*padapter); ++unsigned int setup_beacon_frame(struct adapter *padapter, ++ unsigned char *beacon_frame); ++void update_mgnt_tx_rate(struct adapter *padapter, u8 rate); ++void update_mgntframe_attrib(struct adapter *padapter, ++ struct pkt_attrib *pattrib); ++void dump_mgntframe(struct adapter *padapter, struct xmit_frame *pmgntframe); ++s32 dump_mgntframe_and_wait(struct adapter *padapter, ++ struct xmit_frame *pmgntframe, int timeout_ms); ++s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, ++ struct xmit_frame *pmgntframe); ++ ++#ifdef CONFIG_88EU_P2P ++void issue_probersp_p2p(struct adapter *padapter, unsigned char *da); ++void issue_p2p_provision_request(struct adapter *padapter, u8 *pssid, ++ u8 ussidlen, u8 *pdev_raddr); ++void issue_p2p_GO_request(struct adapter *padapter, u8 *raddr); ++void issue_probereq_p2p(struct adapter *padapter, u8 *da); ++int issue_probereq_p2p_ex(struct adapter *adapter, u8 *da, int try_cnt, ++ int wait_ms); ++void issue_p2p_invitation_response(struct adapter *padapter, u8 *raddr, ++ u8 dialogToken, u8 success); ++void issue_p2p_invitation_request(struct adapter *padapter, u8* raddr); ++#endif /* CONFIG_88EU_P2P */ ++void issue_beacon(struct adapter *padapter, int timeout_ms); ++void issue_probersp(struct adapter *padapter, unsigned char *da, ++ u8 is_valid_p2p_probereq); ++void issue_assocreq(struct adapter *padapter); ++void issue_asocrsp(struct adapter *padapter, unsigned short status, ++ struct sta_info *pstat, int pkt_type); ++void issue_auth(struct adapter *padapter, struct sta_info *psta, ++ unsigned short status); ++void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, ++ u8 *da); ++s32 issue_probereq_ex(struct adapter *adapter, struct ndis_802_11_ssid *pssid, ++ u8* da, int try_cnt, int wait_ms); ++int issue_nulldata(struct adapter *padapter, unsigned char *da, ++ unsigned int power_mode, int try_cnt, int wait_ms); ++int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, ++ u16 tid, int try_cnt, int wait_ms); ++int issue_deauth(struct adapter *padapter, unsigned char *da, ++ unsigned short reason); ++int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason, ++ int try_cnt, int wait_ms); ++void issue_action_spct_ch_switch(struct adapter *padapter, u8 *ra, u8 new_ch, ++ u8 ch_offset); ++void issue_action_BA(struct adapter *padapter, unsigned char *raddr, ++ unsigned char action, unsigned short status); ++unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr); ++unsigned int send_beacon(struct adapter *padapter); ++ ++void start_clnt_assoc(struct adapter *padapter); ++void start_clnt_auth(struct adapter *padapter); ++void start_clnt_join(struct adapter *padapter); ++void start_create_ibss(struct adapter *padapter); ++ ++unsigned int OnAssocReq(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAssocRsp(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnProbeReq(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnProbeRsp(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int DoReserved(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnBeacon(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAtim(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnDisassoc(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAuth(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAuthClient(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnDeAuth(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAction(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++ ++unsigned int on_action_spct(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAction_qos(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAction_dls(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAction_back(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int on_action_public(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAction_ht(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAction_wmm(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++unsigned int OnAction_p2p(struct adapter *padapter, ++ struct recv_frame *precv_frame); ++ ++void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res); ++void mlmeext_sta_del_event_callback(struct adapter *padapter); ++void mlmeext_sta_add_event_callback(struct adapter *padapter, ++ struct sta_info *psta); ++ ++void linked_status_chk(struct adapter *padapter); ++ ++void survey_timer_hdl (struct adapter *padapter); ++void link_timer_hdl (struct adapter *padapter); ++void addba_timer_hdl(struct sta_info *psta); ++ ++#define set_survey_timer(mlmeext, ms) \ ++ do { \ ++ _set_timer(&(mlmeext)->survey_timer, (ms)); \ ++ } while (0) ++ ++#define set_link_timer(mlmeext, ms) \ ++ do { \ ++ _set_timer(&(mlmeext)->link_timer, (ms)); \ ++ } while (0) ++ ++int cckrates_included(unsigned char *rate, int ratelen); ++int cckratesonly_included(unsigned char *rate, int ratelen); ++ ++void process_addba_req(struct adapter *padapter, u8 *paddba_req, u8 *addr); ++ ++void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len); ++void correct_TSF(struct adapter *padapter, struct mlme_ext_priv *pmlmeext); ++ ++struct cmd_hdl { ++ uint parmsize; ++ u8 (*h2cfuns)(struct adapter *padapter, u8 *pbuf); ++}; ++ ++u8 read_macreg_hdl(struct adapter *padapter, u8 *pbuf); ++u8 write_macreg_hdl(struct adapter *padapter, u8 *pbuf); ++u8 read_bbreg_hdl(struct adapter *padapter, u8 *pbuf); ++u8 write_bbreg_hdl(struct adapter *padapter, u8 *pbuf); ++u8 read_rfreg_hdl(struct adapter *padapter, u8 *pbuf); ++u8 write_rfreg_hdl(struct adapter *padapter, u8 *pbuf); ++u8 NULL_hdl(struct adapter *padapter, u8 *pbuf); ++u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf); ++u8 disconnect_hdl(struct adapter *padapter, u8 *pbuf); ++u8 createbss_hdl(struct adapter *padapter, u8 *pbuf); ++u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf); ++u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf); ++u8 setauth_hdl(struct adapter *padapter, u8 *pbuf); ++u8 setkey_hdl(struct adapter *padapter, u8 *pbuf); ++u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf); ++u8 set_assocsta_hdl(struct adapter *padapter, u8 *pbuf); ++u8 del_assocsta_hdl(struct adapter *padapter, u8 *pbuf); ++u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf); ++ ++u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf); ++u8 h2c_msg_hdl(struct adapter *padapter, unsigned char *pbuf); ++u8 tx_beacon_hdl(struct adapter *padapter, unsigned char *pbuf); ++u8 set_ch_hdl(struct adapter *padapter, u8 *pbuf); ++u8 set_chplan_hdl(struct adapter *padapter, unsigned char *pbuf); ++u8 led_blink_hdl(struct adapter *padapter, unsigned char *pbuf); ++/* Handling DFS channel switch announcement ie. */ ++u8 set_csa_hdl(struct adapter *padapter, unsigned char *pbuf); ++u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf); ++ ++#define GEN_DRV_CMD_HANDLER(size, cmd) {size, &cmd ## _hdl}, ++#define GEN_MLME_EXT_HANDLER(size, cmd) {size, cmd}, ++ ++#ifdef _RTW_CMD_C_ ++ ++static struct cmd_hdl wlancmds[] = { ++ GEN_DRV_CMD_HANDLER(0, NULL) /*0*/ ++ GEN_DRV_CMD_HANDLER(0, NULL) ++ GEN_DRV_CMD_HANDLER(0, NULL) ++ GEN_DRV_CMD_HANDLER(0, NULL) ++ GEN_DRV_CMD_HANDLER(0, NULL) ++ GEN_DRV_CMD_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) /*10*/ ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct joinbss_parm), join_cmd_hdl) /*14*/ ++ GEN_MLME_EXT_HANDLER(sizeof (struct disconnect_parm), disconnect_hdl) ++ GEN_MLME_EXT_HANDLER(sizeof (struct createbss_parm), createbss_hdl) ++ GEN_MLME_EXT_HANDLER(sizeof (struct setopmode_parm), setopmode_hdl) ++ GEN_MLME_EXT_HANDLER(sizeof (struct sitesurvey_parm), ++ sitesurvey_cmd_hdl) /*18*/ ++ GEN_MLME_EXT_HANDLER(sizeof (struct setauth_parm), setauth_hdl) ++ GEN_MLME_EXT_HANDLER(sizeof (struct setkey_parm), setkey_hdl) /*20*/ ++ GEN_MLME_EXT_HANDLER(sizeof (struct set_stakey_parm), set_stakey_hdl) ++ GEN_MLME_EXT_HANDLER(sizeof (struct set_assocsta_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct del_assocsta_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct setstapwrstate_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct setbasicrate_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct getbasicrate_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct setdatarate_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct getdatarate_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct setphyinfo_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct getphyinfo_parm), NULL) /*30*/ ++ GEN_MLME_EXT_HANDLER(sizeof (struct setphy_parm), NULL) ++ GEN_MLME_EXT_HANDLER(sizeof (struct getphy_parm), NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) /*40*/ ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl) ++ GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), set_ch_hdl) /* 46 */ ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) /*50*/ ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(0, NULL) ++ GEN_MLME_EXT_HANDLER(sizeof(struct Tx_Beacon_param), ++ tx_beacon_hdl) /*55*/ ++ ++ GEN_MLME_EXT_HANDLER(0, mlme_evt_hdl) /*56*/ ++ GEN_MLME_EXT_HANDLER(0, rtw_drvextra_cmd_hdl) /*57*/ ++ ++ GEN_MLME_EXT_HANDLER(0, h2c_msg_hdl) /*58*/ ++ GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param), ++ set_chplan_hdl) /*59*/ ++ GEN_MLME_EXT_HANDLER(sizeof(struct LedBlink_param), ++ led_blink_hdl) /*60*/ ++ ++ GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelSwitch_param), ++ set_csa_hdl) /*61*/ ++ GEN_MLME_EXT_HANDLER(sizeof(struct TDLSoption_param), ++ tdls_hdl) /*62*/ ++}; ++ ++#endif ++ ++struct C2HEvent_Header { ++#ifdef __LITTLE_ENDIAN ++ unsigned int len:16; ++ unsigned int ID:8; ++ unsigned int seq:8; ++#elif defined(__BIG_ENDIAN) ++ unsigned int seq:8; ++ unsigned int ID:8; ++ unsigned int len:16; ++#endif ++ unsigned int rsvd; ++}; ++ ++void rtw_dummy_event_callback(struct adapter *adapter, u8 *pbuf); ++void rtw_fwdbg_event_callback(struct adapter *adapter, u8 *pbuf); ++ ++enum rtw_c2h_event { ++ GEN_EVT_CODE(_Read_MACREG) = 0, /*0*/ ++ GEN_EVT_CODE(_Read_BBREG), ++ GEN_EVT_CODE(_Read_RFREG), ++ GEN_EVT_CODE(_Read_EEPROM), ++ GEN_EVT_CODE(_Read_EFUSE), ++ GEN_EVT_CODE(_Read_CAM), /*5*/ ++ GEN_EVT_CODE(_Get_BasicRate), ++ GEN_EVT_CODE(_Get_DataRate), ++ GEN_EVT_CODE(_Survey), /*8*/ ++ GEN_EVT_CODE(_SurveyDone), /*9*/ ++ ++ GEN_EVT_CODE(_JoinBss) , /*10*/ ++ GEN_EVT_CODE(_AddSTA), ++ GEN_EVT_CODE(_DelSTA), ++ GEN_EVT_CODE(_AtimDone), ++ GEN_EVT_CODE(_TX_Report), ++ GEN_EVT_CODE(_CCX_Report), /*15*/ ++ GEN_EVT_CODE(_DTM_Report), ++ GEN_EVT_CODE(_TX_Rate_Statistics), ++ GEN_EVT_CODE(_C2HLBK), ++ GEN_EVT_CODE(_FWDBG), ++ GEN_EVT_CODE(_C2HFEEDBACK), /*20*/ ++ GEN_EVT_CODE(_ADDBA), ++ GEN_EVT_CODE(_C2HBCN), ++ GEN_EVT_CODE(_ReportPwrState), /* filen: only for PCIE, USB */ ++ GEN_EVT_CODE(_CloseRF), /* filen: only for PCIE, ++ * work around ASPM */ ++ MAX_C2HEVT ++}; ++ ++#ifdef _RTW_MLME_EXT_C_ ++ ++static struct fwevent wlanevents[] = { ++ {0, rtw_dummy_event_callback}, /*0*/ ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++ {0, &rtw_survey_event_callback}, /*8*/ ++ {sizeof (struct surveydone_event), &rtw_surveydone_event_callback},/*9*/ ++ {0, &rtw_joinbss_event_callback}, /*10*/ ++ {sizeof(struct stassoc_event), &rtw_stassoc_event_callback}, ++ {sizeof(struct stadel_event), &rtw_stadel_event_callback}, ++ {0, NULL}, ++ {0, rtw_dummy_event_callback}, ++ {0, NULL}, /*15*/ ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++ {0, rtw_fwdbg_event_callback}, ++ {0, NULL}, /*20*/ ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++ {0, NULL}, ++}; ++ ++#endif/* _RTL_MLME_EXT_C_ */ ++ ++#endif /* __RTW_MLME_EXT_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_mp.h b/drivers/staging/r8188eu/include/rtw_mp.h +new file mode 100644 +index 000000000000..3a259d991348 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_mp.h +@@ -0,0 +1,474 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_MP_H_ ++#define _RTW_MP_H_ ++ ++/* 00 - Success */ ++/* 11 - Error */ ++#define STATUS_SUCCESS (0x00000000L) ++#define STATUS_PENDING (0x00000103L) ++ ++#define STATUS_UNSUCCESSFUL (0xC0000001L) ++#define STATUS_INSUFFICIENT_RESOURCES (0xC000009AL) ++#define STATUS_NOT_SUPPORTED (0xC00000BBL) ++ ++#define NDIS_STATUS_SUCCESS ((int)STATUS_SUCCESS) ++#define NDIS_STATUS_PENDING ((int)STATUS_PENDING) ++#define NDIS_STATUS_NOT_RECOGNIZED ((int)0x00010001L) ++#define NDIS_STATUS_NOT_COPIED ((int)0x00010002L) ++#define NDIS_STATUS_NOT_ACCEPTED ((int)0x00010003L) ++#define NDIS_STATUS_CALL_ACTIVE ((int)0x00010007L) ++ ++#define NDIS_STATUS_FAILURE ((int)STATUS_UNSUCCESSFUL) ++#define NDIS_STATUS_RESOURCES ((int)STATUS_INSUFFICIENT_RESOURCES) ++#define NDIS_STATUS_CLOSING ((int)0xC0010002L) ++#define NDIS_STATUS_BAD_VERSION ((int)0xC0010004L) ++#define NDIS_STATUS_BAD_CHARACTERISTICS ((int)0xC0010005L) ++#define NDIS_STATUS_ADAPTER_NOT_FOUND ((int)0xC0010006L) ++#define NDIS_STATUS_OPEN_FAILED ((int)0xC0010007L) ++#define NDIS_STATUS_DEVICE_FAILED ((int)0xC0010008L) ++#define NDIS_STATUS_MULTICAST_FULL ((int)0xC0010009L) ++#define NDIS_STATUS_MULTICAST_EXISTS ((int)0xC001000AL) ++#define NDIS_STATUS_MULTICAST_NOT_FOUND ((int)0xC001000BL) ++#define NDIS_STATUS_REQUEST_ABORTED ((int)0xC001000CL) ++#define NDIS_STATUS_RESET_IN_PROGRESS ((int)0xC001000DL) ++#define NDIS_STATUS_CLOSING_INDICATING ((int)0xC001000EL) ++#define NDIS_STATUS_NOT_SUPPORTED ((int)STATUS_NOT_SUPPORTED) ++#define NDIS_STATUS_INVALID_PACKET ((int)0xC001000FL) ++#define NDIS_STATUS_OPEN_LIST_FULL ((int)0xC0010010L) ++#define NDIS_STATUS_ADAPTER_NOT_READY ((int)0xC0010011L) ++#define NDIS_STATUS_ADAPTER_NOT_OPEN ((int)0xC0010012L) ++#define NDIS_STATUS_NOT_INDICATING ((int)0xC0010013L) ++#define NDIS_STATUS_INVALID_LENGTH ((int)0xC0010014L) ++#define NDIS_STATUS_INVALID_DATA ((int)0xC0010015L) ++#define NDIS_STATUS_BUFFER_TOO_SHORT ((int)0xC0010016L) ++#define NDIS_STATUS_INVALID_OID ((int)0xC0010017L) ++#define NDIS_STATUS_ADAPTER_REMOVED ((int)0xC0010018L) ++#define NDIS_STATUS_UNSUPPORTED_MEDIA ((int)0xC0010019L) ++#define NDIS_STATUS_GROUP_ADDRESS_IN_USE ((int)0xC001001AL) ++#define NDIS_STATUS_FILE_NOT_FOUND ((int)0xC001001BL) ++#define NDIS_STATUS_ERROR_READING_FILE ((int)0xC001001CL) ++#define NDIS_STATUS_ALREADY_MAPPED ((int)0xC001001DL) ++#define NDIS_STATUS_RESOURCE_CONFLICT ((int)0xC001001EL) ++#define NDIS_STATUS_NO_CABLE ((int)0xC001001FL) ++ ++#define NDIS_STATUS_INVALID_SAP ((int)0xC0010020L) ++#define NDIS_STATUS_SAP_IN_USE ((int)0xC0010021L) ++#define NDIS_STATUS_INVALID_ADDRESS ((int)0xC0010022L) ++#define NDIS_STATUS_VC_NOT_ACTIVATED ((int)0xC0010023L) ++#define NDIS_STATUS_DEST_OUT_OF_ORDER ((int)0xC0010024L) /*cause 27*/ ++#define NDIS_STATUS_VC_NOT_AVAILABLE ((int)0xC0010025L) /*cause 35,45 */ ++#define NDIS_STATUS_CELLRATE_NOT_AVAILABLE ((int)0xC0010026L) /*cause 37*/ ++#define NDIS_STATUS_INCOMPATABLE_QOS ((int)0xC0010027L) /*cause 49*/ ++#define NDIS_STATUS_AAL_PARAMS_UNSUPPORTED ((int)0xC0010028L) /*cause 93*/ ++#define NDIS_STATUS_NO_ROUTE_TO_DESTINATION ((int)0xC0010029L) /*cause 3 */ ++ ++enum antenna_path { ++ ANTENNA_NONE = 0x00, ++ ANTENNA_D, ++ ANTENNA_C, ++ ANTENNA_CD, ++ ANTENNA_B, ++ ANTENNA_BD, ++ ANTENNA_BC, ++ ANTENNA_BCD, ++ ANTENNA_A, ++ ANTENNA_AD, ++ ANTENNA_AC, ++ ANTENNA_ACD, ++ ANTENNA_AB, ++ ANTENNA_ABD, ++ ANTENNA_ABC, ++ ANTENNA_ABCD ++}; ++ ++#define MAX_MP_XMITBUF_SZ 2048 ++#define NR_MP_XMITFRAME 8 ++ ++struct mp_xmit_frame { ++ struct list_head list; ++ struct pkt_attrib attrib; ++ struct sk_buff *pkt; ++ int frame_tag; ++ struct adapter *padapter; ++ struct urb *pxmit_urb[8]; ++ /* insert urb, irp, and irpcnt info below... */ ++ u8 *mem_addr; ++ u32 sz[8]; ++ u8 bpending[8]; ++ int ac_tag[8]; ++ int last[8]; ++ uint irpcnt; ++ uint fragcnt; ++ uint mem[(MAX_MP_XMITBUF_SZ >> 2)]; ++}; ++ ++struct mp_wiparam { ++ u32 bcompleted; ++ u32 act_type; ++ u32 io_offset; ++ u32 io_value; ++}; ++ ++typedef void(*wi_act_func)(void *padapter); ++ ++struct mp_tx { ++ u8 stop; ++ u32 count, sended; ++ u8 payload; ++ struct pkt_attrib attrib; ++ struct tx_desc desc; ++ u8 *pallocated_buf; ++ u8 *buf; ++ u32 buf_size, write_size; ++ void *PktTxThread; ++}; ++ ++#include "Hal8188EPhyCfg.h" ++ ++#define MP_MAX_LINES 1000 ++#define MP_MAX_LINES_BYTES 256 ++ ++typedef void (*MPT_WORK_ITEM_HANDLER)(void *Adapter); ++ ++struct mpt_context { ++ /* Indicate if we have started Mass Production Test. */ ++ bool bMassProdTest; ++ ++ /* Indicate if the driver is unloading or unloaded. */ ++ bool bMptDrvUnload; ++ ++ struct semaphore MPh2c_Sema; ++ struct timer_list MPh2c_timeout_timer; ++/* Event used to sync H2c for BT control */ ++ ++ bool MptH2cRspEvent; ++ bool MptBtC2hEvent; ++ bool bMPh2c_timeout; ++ ++ /* 8190 PCI does not support NDIS_WORK_ITEM. */ ++ /* Work Item for Mass Production Test. */ ++ /* Event used to sync the case unloading driver and MptWorkItem ++ * is still in progress. */ ++ /* Indicate a MptWorkItem is scheduled and not yet finished. */ ++ bool bMptWorkItemInProgress; ++ /* An instance which implements function and context of MptWorkItem. */ ++ MPT_WORK_ITEM_HANDLER CurrMptAct; ++ ++ /* 1=Start, 0=Stop from UI. */ ++ u32 MptTestStart; ++ /* _TEST_MODE, defined in MPT_Req2.h */ ++ u32 MptTestItem; ++ /* Variable needed in each implementation of CurrMptAct. */ ++ u32 MptActType; /* Type of action performed in CurrMptAct. */ ++ /* The Offset of IO operation is depend of MptActType. */ ++ u32 MptIoOffset; ++ /* The Value of IO operation is depend of MptActType. */ ++ u32 MptIoValue; ++ /* The RfPath of IO operation is depend of MptActType. */ ++ u32 MptRfPath; ++ ++ enum wireless_mode MptWirelessModeToSw; /* Wireless mode to switch. */ ++ u8 MptChannelToSw; /* Channel to switch. */ ++ u8 MptInitGainToSet; /* Initial gain to set. */ ++ u32 MptBandWidth; /* bandwidth to switch. */ ++ u32 MptRateIndex; /* rate index. */ ++ /* Register value kept for Single Carrier Tx test. */ ++ u8 btMpCckTxPower; ++ /* Register value kept for Single Carrier Tx test. */ ++ u8 btMpOfdmTxPower; ++ /* For MP Tx Power index */ ++ u8 TxPwrLevel[2]; /* rf-A, rf-B */ ++ ++ /* Content of RCR Regsiter for Mass Production Test. */ ++ u32 MptRCR; ++ /* true if we only receive packets with specific pattern. */ ++ bool bMptFilterPattern; ++ /* Rx OK count, statistics used in Mass Production Test. */ ++ u32 MptRxOkCnt; ++ /* Rx CRC32 error count, statistics used in Mass Production Test. */ ++ u32 MptRxCrcErrCnt; ++ ++ bool bCckContTx; /* true if we are in CCK Continuous Tx test. */ ++ bool bOfdmContTx; /* true if we are in OFDM Continuous Tx test. */ ++ bool bStartContTx; /* true if we have start Continuous Tx test. */ ++ /* true if we are in Single Carrier Tx test. */ ++ bool bSingleCarrier; ++ /* true if we are in Carrier Suppression Tx Test. */ ++ bool bCarrierSuppression; ++ /* true if we are in Single Tone Tx test. */ ++ bool bSingleTone; ++ ++ /* ACK counter asked by K.Y.. */ ++ bool bMptEnableAckCounter; ++ u32 MptAckCounter; ++ ++ u8 APK_bound[2]; /* for APK path A/path B */ ++ bool bMptIndexEven; ++ ++ u8 backup0xc50; ++ u8 backup0xc58; ++ u8 backup0xc30; ++ u8 backup0x52_RF_A; ++ u8 backup0x52_RF_B; ++ ++ u8 h2cReqNum; ++ u8 c2hBuf[20]; ++ ++ u8 btInBuf[100]; ++ u32 mptOutLen; ++ u8 mptOutBuf[100]; ++}; ++ ++enum { ++ WRITE_REG = 1, ++ READ_REG, ++ WRITE_RF, ++ READ_RF, ++ MP_START, ++ MP_STOP, ++ MP_RATE, ++ MP_CHANNEL, ++ MP_BANDWIDTH, ++ MP_TXPOWER, ++ MP_ANT_TX, ++ MP_ANT_RX, ++ MP_CTX, ++ MP_QUERY, ++ MP_ARX, ++ MP_PSD, ++ MP_PWRTRK, ++ MP_THER, ++ MP_IOCTL, ++ EFUSE_GET, ++ EFUSE_SET, ++ MP_RESET_STATS, ++ MP_DUMP, ++ MP_PHYPARA, ++ MP_SetRFPathSwh, ++ MP_QueryDrvStats, ++ MP_SetBT, ++ CTA_TEST, ++ MP_NULL, ++}; ++ ++struct mp_priv { ++ struct adapter *papdater; ++ ++ /* Testing Flag */ ++ /* 0 for normal type packet, 1 for loopback packet (16bytes TXCMD) */ ++ u32 mode; ++ ++ u32 prev_fw_state; ++ ++ /* OID cmd handler */ ++ struct mp_wiparam workparam; ++ ++ /* Tx Section */ ++ u8 TID; ++ u32 tx_pktcount; ++ struct mp_tx tx; ++ ++ /* Rx Section */ ++ u32 rx_pktcount; ++ u32 rx_crcerrpktcount; ++ u32 rx_pktloss; ++ ++ struct recv_stat rxstat; ++ ++ /* RF/BB relative */ ++ u8 channel; ++ u8 bandwidth; ++ u8 prime_channel_offset; ++ u8 txpoweridx; ++ u8 txpoweridx_b; ++ u8 rateidx; ++ u32 preamble; ++ u32 CrystalCap; ++ ++ u16 antenna_tx; ++ u16 antenna_rx; ++ ++ u8 check_mp_pkt; ++ ++ u8 bSetTxPower; ++ ++ struct wlan_network mp_network; ++ unsigned char network_macaddr[ETH_ALEN]; ++ ++ u8 *pallocated_mp_xmitframe_buf; ++ u8 *pmp_xmtframe_buf; ++ struct __queue free_mp_xmitqueue; ++ u32 free_mp_xmitframe_cnt; ++ ++ struct mpt_context MptCtx; ++}; ++ ++struct iocmd_struct { ++ u8 cmdclass; ++ u16 value; ++ u8 index; ++}; ++ ++struct rf_reg_param { ++ u32 path; ++ u32 offset; ++ u32 value; ++}; ++ ++struct bb_reg_param { ++ u32 offset; ++ u32 value; ++}; ++/* */ ++ ++#define LOWER true ++#define RAISE false ++ ++/* Hardware Registers */ ++#define BB_REG_BASE_ADDR 0x800 ++ ++/* MP variables */ ++enum mp_mode_{ ++ MP_OFF, ++ MP_ON, ++ MP_ERR, ++ MP_CONTINUOUS_TX, ++ MP_SINGLE_CARRIER_TX, ++ MP_CARRIER_SUPPRISSION_TX, ++ MP_SINGLE_TONE_TX, ++ MP_PACKET_TX, ++ MP_PACKET_RX ++}; ++ ++extern u8 mpdatarate[NumRates]; ++ ++/* MP set force data rate base on the definition. */ ++enum mpt_rate_index { ++ /* CCK rate. */ ++ MPT_RATE_1M, /* 0 */ ++ MPT_RATE_2M, ++ MPT_RATE_55M, ++ MPT_RATE_11M, /* 3 */ ++ ++ /* OFDM rate. */ ++ MPT_RATE_6M, /* 4 */ ++ MPT_RATE_9M, ++ MPT_RATE_12M, ++ MPT_RATE_18M, ++ MPT_RATE_24M, ++ MPT_RATE_36M, ++ MPT_RATE_48M, ++ MPT_RATE_54M, /* 11 */ ++ ++ /* HT rate. */ ++ MPT_RATE_MCS0, /* 12 */ ++ MPT_RATE_MCS1, ++ MPT_RATE_MCS2, ++ MPT_RATE_MCS3, ++ MPT_RATE_MCS4, ++ MPT_RATE_MCS5, ++ MPT_RATE_MCS6, ++ MPT_RATE_MCS7, /* 19 */ ++ MPT_RATE_MCS8, ++ MPT_RATE_MCS9, ++ MPT_RATE_MCS10, ++ MPT_RATE_MCS11, ++ MPT_RATE_MCS12, ++ MPT_RATE_MCS13, ++ MPT_RATE_MCS14, ++ MPT_RATE_MCS15, /* 27 */ ++ MPT_RATE_LAST ++}; ++ ++#define MAX_TX_PWR_INDEX_N_MODE 64 /* 0x3F */ ++ ++enum power_mode { ++ POWER_LOW = 0, ++ POWER_NORMAL ++}; ++ ++#define RX_PKT_BROADCAST 1 ++#define RX_PKT_DEST_ADDR 2 ++#define RX_PKT_PHY_MATCH 3 ++ ++enum encry_ctrl_state { ++ HW_CONTROL, /* hw encryption& decryption */ ++ SW_CONTROL, /* sw encryption& decryption */ ++ HW_ENCRY_SW_DECRY, /* hw encryption & sw decryption */ ++ SW_ENCRY_HW_DECRY /* sw encryption & hw decryption */ ++}; ++ ++s32 init_mp_priv(struct adapter *padapter); ++void free_mp_priv(struct mp_priv *pmp_priv); ++s32 MPT_InitializeAdapter(struct adapter *padapter, u8 Channel); ++void MPT_DeInitAdapter(struct adapter *padapter); ++s32 mp_start_test(struct adapter *padapter); ++void mp_stop_test(struct adapter *padapter); ++ ++u32 _read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask); ++void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val); ++ ++u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask); ++void write_bbreg(struct adapter *padapter, u32 addr, u32 bitmask, u32 val); ++u32 read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr); ++void write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 val); ++ ++void SetChannel(struct adapter *pAdapter); ++void SetBandwidth(struct adapter *pAdapter); ++void SetTxPower(struct adapter *pAdapter); ++void SetAntennaPathPower(struct adapter *pAdapter); ++void SetDataRate(struct adapter *pAdapter); ++ ++void SetAntenna(struct adapter *pAdapter); ++ ++s32 SetThermalMeter(struct adapter *pAdapter, u8 target_ther); ++void GetThermalMeter(struct adapter *pAdapter, u8 *value); ++ ++void SetContinuousTx(struct adapter *pAdapter, u8 bStart); ++void SetSingleCarrierTx(struct adapter *pAdapter, u8 bStart); ++void SetSingleToneTx(struct adapter *pAdapter, u8 bStart); ++void SetCarrierSuppressionTx(struct adapter *pAdapter, u8 bStart); ++void PhySetTxPowerLevel(struct adapter *pAdapter); ++ ++void fill_txdesc_for_mp(struct adapter *padapter, struct tx_desc *ptxdesc); ++void SetPacketTx(struct adapter *padapter); ++void SetPacketRx(struct adapter *pAdapter, u8 bStartRx); ++ ++void ResetPhyRxPktCount(struct adapter *pAdapter); ++u32 GetPhyRxPktReceived(struct adapter *pAdapter); ++u32 GetPhyRxPktCRC32Error(struct adapter *pAdapter); ++ ++s32 SetPowerTracking(struct adapter *padapter, u8 enable); ++void GetPowerTracking(struct adapter *padapter, u8 *enable); ++u32 mp_query_psd(struct adapter *pAdapter, u8 *data); ++void Hal_SetAntenna(struct adapter *pAdapter); ++void Hal_SetBandwidth(struct adapter *pAdapter); ++void Hal_SetTxPower(struct adapter *pAdapter); ++void Hal_SetCarrierSuppressionTx(struct adapter *pAdapter, u8 bStart); ++void Hal_SetSingleToneTx(struct adapter *pAdapter, u8 bStart); ++void Hal_SetSingleCarrierTx (struct adapter *pAdapter, u8 bStart); ++void Hal_SetContinuousTx (struct adapter *pAdapter, u8 bStart); ++void Hal_SetBandwidth(struct adapter *pAdapter); ++void Hal_SetDataRate(struct adapter *pAdapter); ++void Hal_SetChannel(struct adapter *pAdapter); ++void Hal_SetAntennaPathPower(struct adapter *pAdapter); ++s32 Hal_SetThermalMeter(struct adapter *pAdapter, u8 target_ther); ++s32 Hal_SetPowerTracking(struct adapter *padapter, u8 enable); ++void Hal_GetPowerTracking(struct adapter *padapter, u8 * enable); ++void Hal_GetThermalMeter(struct adapter *pAdapter, u8 *value); ++void Hal_mpt_SwitchRfSetting(struct adapter *pAdapter); ++void Hal_MPT_CCKTxPowerAdjust(struct adapter * Adapter, bool bInCH14); ++void Hal_MPT_CCKTxPowerAdjustbyIndex(struct adapter *pAdapter, bool beven); ++void Hal_SetCCKTxPower(struct adapter *pAdapter, u8 * TxPower); ++void Hal_SetOFDMTxPower(struct adapter *pAdapter, u8 * TxPower); ++void Hal_TriggerRFThermalMeter(struct adapter *pAdapter); ++u8 Hal_ReadRFThermalMeter(struct adapter *pAdapter); ++void Hal_SetCCKContinuousTx(struct adapter *pAdapter, u8 bStart); ++void Hal_SetOFDMContinuousTx(struct adapter *pAdapter, u8 bStart); ++void Hal_ProSetCrystalCap (struct adapter *pAdapter , u32 CrystalCapVal); ++void _rtw_mp_xmit_priv(struct xmit_priv *pxmitpriv); ++void MP_PHY_SetRFPathSwitch(struct adapter *pAdapter ,bool bMain); ++ ++#endif /* _RTW_MP_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_mp_ioctl.h b/drivers/staging/r8188eu/include/rtw_mp_ioctl.h +new file mode 100644 +index 000000000000..cf99f39a582e +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_mp_ioctl.h +@@ -0,0 +1,242 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_MP_IOCTL_H_ ++#define _RTW_MP_IOCTL_H_ ++ ++#include "drv_types.h" ++#include "mp_custom_oid.h" ++#include "rtw_ioctl.h" ++#include "rtw_ioctl_rtl.h" ++#include "rtw_efuse.h" ++#include "rtw_mp.h" ++ ++struct cfg_dbg_msg_struct { ++ u32 DebugLevel; ++ u32 DebugComponent_H32; ++ u32 DebugComponent_L32; ++}; ++ ++struct mp_rw_reg { ++ u32 offset; ++ u32 width; ++ u32 value; ++}; ++ ++struct efuse_access_struct { ++ u16 start_addr; ++ u16 cnts; ++ u8 data[0]; ++}; ++ ++struct burst_rw_reg { ++ u32 offset; ++ u32 len; ++ u8 Data[256]; ++}; ++ ++struct usb_vendor_req { ++ u8 bRequest; ++ u16 wValue; ++ u16 wIndex; ++ u16 wLength; ++ u8 u8Dir;/* 0:OUT, 1:IN */ ++ u8 u8InData; ++}; ++ ++struct dr_variable_struct { ++ u8 offset; ++ u32 variable; ++}; ++ ++#define _irqlevel_changed_(a, b) ++ ++int rtl8188eu_oid_rt_pro_set_data_rate_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_tx_power_control_hdl(struct oid_par_priv *poid_par_priv); ++ ++int rtl8188eu_oid_rt_pro_query_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_query_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_query_rx_packet_crc32_error_hdl(struct oid_par_priv *par_priv); ++int rtl8188eu_oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv *par_priv); ++int rtl8188eu_oid_rt_pro_set_modulation_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv *par_priv); ++int rtl8188eu_oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv *poid_par_priv); ++ ++/* rtl8188eu_oid_rtl_seg_81_87 */ ++int rtl8188eu_oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv); ++ ++int rtl8188eu_oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv); ++ ++/* rtl8188eu_oid_rtl_seg_87_11_00 */ ++int rtl8188eu_oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_burst_read_register_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_burst_write_register_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_write16_eeprom_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_wr_attrib_mem_hdl (struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv); ++/* rtl8188eu_oid_rtl_seg_87_11_20 */ ++int rtl8188eu_oid_rt_pro_cfg_debug_message_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_data_rate_ex_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_basic_rate_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_read_tssi_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_power_tracking_hdl(struct oid_par_priv *poid_par_priv); ++/* rtl8188eu_oid_rtl_seg_87_11_50 */ ++int rtl8188eu_oid_rt_pro_qry_pwrstate_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_pwrstate_hdl(struct oid_par_priv *poid_par_priv); ++/* rtl8188eu_oid_rtl_seg_87_11_F0 */ ++int rtl8188eu_oid_rt_pro_h2c_set_rate_table_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_h2c_get_rate_table_hdl(struct oid_par_priv *poid_par_priv); ++ ++/* rtl8188eu_oid_rtl_seg_87_12_00 */ ++int rtl8188eu_oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_query_dr_variable_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_get_efuse_current_size_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_tx_agc_offset_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_set_pkt_test_mode_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv *par_priv); ++int rtl8188eu_oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_get_power_mode_hdl(struct oid_par_priv *poid_par_priv); ++int rtl8188eu_oid_rt_pro_trigger_gpio_hdl(struct oid_par_priv *poid_par_priv); ++ ++struct rwreg_param { ++ u32 offset; ++ u32 width; ++ u32 value; ++}; ++ ++struct bbreg_param { ++ u32 offset; ++ u32 phymask; ++ u32 value; ++}; ++ ++struct txpower_param { ++ u32 pwr_index; ++}; ++ ++struct datarate_param { ++ u32 rate_index; ++}; ++ ++struct rfintfs_parm { ++ u32 rfintfs; ++}; ++ ++struct mp_xmit_parm { ++ u8 enable; ++ u32 count; ++ u16 length; ++ u8 payload_type; ++ u8 da[ETH_ALEN]; ++}; ++ ++struct mp_xmit_packet { ++ u32 len; ++ u32 mem[MAX_MP_XMITBUF_SZ >> 2]; ++}; ++ ++struct psmode_param { ++ u32 ps_mode; ++ u32 smart_ps; ++}; ++ ++/* for OID_RT_PRO_READ16_EEPROM & OID_RT_PRO_WRITE16_EEPROM */ ++struct eeprom_rw_param { ++ u32 offset; ++ u16 value; ++}; ++ ++struct mp_ioctl_handler { ++ u32 paramsize; ++ s32 (*handler)(struct oid_par_priv* poid_par_priv); ++ u32 oid; ++}; ++ ++struct mp_ioctl_param{ ++ u32 subcode; ++ u32 len; ++ u8 data[0]; ++}; ++ ++#define GEN_MP_IOCTL_SUBCODE(code) _MP_IOCTL_ ## code ## _CMD_ ++ ++enum RTL871X_MP_IOCTL_SUBCODE { ++ GEN_MP_IOCTL_SUBCODE(MP_START), /*0*/ ++ GEN_MP_IOCTL_SUBCODE(MP_STOP), ++ GEN_MP_IOCTL_SUBCODE(READ_REG), ++ GEN_MP_IOCTL_SUBCODE(WRITE_REG), ++ GEN_MP_IOCTL_SUBCODE(READ_BB_REG), ++ GEN_MP_IOCTL_SUBCODE(WRITE_BB_REG), /*5*/ ++ GEN_MP_IOCTL_SUBCODE(READ_RF_REG), ++ GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG), ++ GEN_MP_IOCTL_SUBCODE(SET_CHANNEL), ++ GEN_MP_IOCTL_SUBCODE(SET_TXPOWER), ++ GEN_MP_IOCTL_SUBCODE(SET_DATARATE), /*10*/ ++ GEN_MP_IOCTL_SUBCODE(SET_BANDWIDTH), ++ GEN_MP_IOCTL_SUBCODE(SET_ANTENNA), ++ GEN_MP_IOCTL_SUBCODE(CNTU_TX), ++ GEN_MP_IOCTL_SUBCODE(SC_TX), ++ GEN_MP_IOCTL_SUBCODE(CS_TX), /*15*/ ++ GEN_MP_IOCTL_SUBCODE(ST_TX), ++ GEN_MP_IOCTL_SUBCODE(IOCTL_XMIT_PACKET), ++ GEN_MP_IOCTL_SUBCODE(SET_RX_PKT_TYPE), ++ GEN_MP_IOCTL_SUBCODE(RESET_PHY_RX_PKT_CNT), ++ GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_RECV), /*20*/ ++ GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_ERROR), ++ GEN_MP_IOCTL_SUBCODE(READ16_EEPROM), ++ GEN_MP_IOCTL_SUBCODE(WRITE16_EEPROM), ++ GEN_MP_IOCTL_SUBCODE(EFUSE), ++ GEN_MP_IOCTL_SUBCODE(EFUSE_MAP), /*25*/ ++ GEN_MP_IOCTL_SUBCODE(GET_EFUSE_MAX_SIZE), ++ GEN_MP_IOCTL_SUBCODE(GET_EFUSE_CURRENT_SIZE), ++ GEN_MP_IOCTL_SUBCODE(GET_THERMAL_METER), ++ GEN_MP_IOCTL_SUBCODE(SET_PTM), ++ GEN_MP_IOCTL_SUBCODE(SET_POWER_DOWN), /*30*/ ++ GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO), ++ GEN_MP_IOCTL_SUBCODE(SET_DM_BT), /*35*/ ++ GEN_MP_IOCTL_SUBCODE(DEL_BA), /*36*/ ++ GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS), /*37*/ ++ MAX_MP_IOCTL_SUBCODE, ++}; ++ ++s32 rtl8188eu_mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv); ++ ++#define GEN_HANDLER(sz, hdl, oid) {sz, hdl, oid}, ++ ++#define EXT_MP_IOCTL_HANDLER(sz, subcode, oid) \ ++ {sz, rtl8188eu_mp_ioctl_##subcode##_hdl, oid}, ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_mp_phy_regdef.h b/drivers/staging/r8188eu/include/rtw_mp_phy_regdef.h +new file mode 100644 +index 000000000000..c2be770a5f5d +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_mp_phy_regdef.h +@@ -0,0 +1,1063 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++/***************************************************************************** ++ * ++ * Module: __RTW_MP_PHY_REGDEF_H_ ++ * ++ * ++ * Note: 1. Define PMAC/BB register map ++ * 2. Define RF register map ++ * 3. PMAC/BB register bit mask. ++ * 4. RF reg bit mask. ++ * 5. Other BB/RF relative definition. ++ * ++ * ++ * Export: Constants, macro, functions(API), global variables(None). ++ * ++ * Abbrev: ++ * ++ * History: ++ * Data Who Remark ++ * 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h. ++ * 2. Reorganize code architecture. ++ * 09/25/2008 MH 1. Add RL6052 register definition ++ * ++ *****************************************************************************/ ++#ifndef __RTW_MP_PHY_REGDEF_H_ ++#define __RTW_MP_PHY_REGDEF_H_ ++ ++/*--------------------------Define Parameters-------------------------------*/ ++ ++/* */ ++/* 8192S Regsiter offset definition */ ++/* */ ++ ++/* */ ++/* BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF */ ++/* 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF */ ++/* 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 */ ++/* 3. RF register 0x00-2E */ ++/* 4. Bit Mask for BB/RF register */ ++/* 5. Other definition for BB/RF R/W */ ++/* */ ++ ++/* */ ++/* 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF */ ++/* 1. Page1(0x100) */ ++/* */ ++#define rPMAC_Reset 0x100 ++#define rPMAC_TxStart 0x104 ++#define rPMAC_TxLegacySIG 0x108 ++#define rPMAC_TxHTSIG1 0x10c ++#define rPMAC_TxHTSIG2 0x110 ++#define rPMAC_PHYDebug 0x114 ++#define rPMAC_TxPacketNum 0x118 ++#define rPMAC_TxIdle 0x11c ++#define rPMAC_TxMACHeader0 0x120 ++#define rPMAC_TxMACHeader1 0x124 ++#define rPMAC_TxMACHeader2 0x128 ++#define rPMAC_TxMACHeader3 0x12c ++#define rPMAC_TxMACHeader4 0x130 ++#define rPMAC_TxMACHeader5 0x134 ++#define rPMAC_TxDataType 0x138 ++#define rPMAC_TxRandomSeed 0x13c ++#define rPMAC_CCKPLCPPreamble 0x140 ++#define rPMAC_CCKPLCPHeader 0x144 ++#define rPMAC_CCKCRC16 0x148 ++#define rPMAC_OFDMRxCRC32OK 0x170 ++#define rPMAC_OFDMRxCRC32Er 0x174 ++#define rPMAC_OFDMRxParityEr 0x178 ++#define rPMAC_OFDMRxCRC8Er 0x17c ++#define rPMAC_CCKCRxRC16Er 0x180 ++#define rPMAC_CCKCRxRC32Er 0x184 ++#define rPMAC_CCKCRxRC32OK 0x188 ++#define rPMAC_TxStatus 0x18c ++ ++/* */ ++/* 2. Page2(0x200) */ ++/* */ ++/* The following two definition are only used for USB interface. */ ++/* define RF_BB_CMD_ADDR 0x02c0 RF/BB read/write command address. */ ++/* define RF_BB_CMD_DATA 0x02c4 RF/BB read/write command data. */ ++ ++/* */ ++/* 3. Page8(0x800) */ ++/* */ ++#define rFPGA0_RFMOD 0x800 /* RF mode & CCK TxSC RF BW Setting?? */ ++ ++#define rFPGA0_TxInfo 0x804 /* Status report?? */ ++#define rFPGA0_PSDFunction 0x808 ++ ++#define rFPGA0_TxGainStage 0x80c /* Set TX PWR init gain? */ ++ ++#define rFPGA0_RFTiming1 0x810 /* Useless now */ ++#define rFPGA0_RFTiming2 0x814 ++/* define rFPGA0_XC_RFTiming 0x818 */ ++/* define rFPGA0_XD_RFTiming 0x81c */ ++ ++#define rFPGA0_XA_HSSIParameter1 0x820 /* RF 3 wire register */ ++#define rFPGA0_XA_HSSIParameter2 0x824 ++#define rFPGA0_XB_HSSIParameter1 0x828 ++#define rFPGA0_XB_HSSIParameter2 0x82c ++#define rFPGA0_XC_HSSIParameter1 0x830 ++#define rFPGA0_XC_HSSIParameter2 0x834 ++#define rFPGA0_XD_HSSIParameter1 0x838 ++#define rFPGA0_XD_HSSIParameter2 0x83c ++#define rFPGA0_XA_LSSIParameter 0x840 ++#define rFPGA0_XB_LSSIParameter 0x844 ++#define rFPGA0_XC_LSSIParameter 0x848 ++#define rFPGA0_XD_LSSIParameter 0x84c ++ ++#define rFPGA0_RFWakeUpParameter 0x850 /* Useless now */ ++#define rFPGA0_RFSleepUpParameter 0x854 ++ ++#define rFPGA0_XAB_SwitchControl 0x858 /* RF Channel switch */ ++#define rFPGA0_XCD_SwitchControl 0x85c ++ ++#define rFPGA0_XA_RFInterfaceOE 0x860 /* RF Channel switch */ ++#define rFPGA0_XB_RFInterfaceOE 0x864 ++#define rFPGA0_XC_RFInterfaceOE 0x868 ++#define rFPGA0_XD_RFInterfaceOE 0x86c ++ ++#define rFPGA0_XAB_RFInterfaceSW 0x870 /* RF Interface Software Control */ ++#define rFPGA0_XCD_RFInterfaceSW 0x874 ++ ++#define rFPGA0_XAB_RFParameter 0x878 /* RF Parameter */ ++#define rFPGA0_XCD_RFParameter 0x87c ++ ++#define rFPGA0_AnalogParameter1 0x880 /* Crystal cap setting RF-R/W protection for parameter4?? */ ++#define rFPGA0_AnalogParameter2 0x884 ++#define rFPGA0_AnalogParameter3 0x888 /* Useless now */ ++#define rFPGA0_AnalogParameter4 0x88c ++ ++#define rFPGA0_XA_LSSIReadBack 0x8a0 /* Tranceiver LSSI Readback */ ++#define rFPGA0_XB_LSSIReadBack 0x8a4 ++#define rFPGA0_XC_LSSIReadBack 0x8a8 ++#define rFPGA0_XD_LSSIReadBack 0x8ac ++ ++#define rFPGA0_PSDReport 0x8b4 /* Useless now */ ++#define rFPGA0_XAB_RFInterfaceRB 0x8e0 /* Useless now RF Interface Readback Value */ ++#define rFPGA0_XCD_RFInterfaceRB 0x8e4 /* Useless now */ ++ ++/* */ ++/* 4. Page9(0x900) */ ++/* */ ++#define rFPGA1_RFMOD 0x900 /* RF mode & OFDM TxSC RF BW Setting?? */ ++ ++#define rFPGA1_TxBlock 0x904 /* Useless now */ ++#define rFPGA1_DebugSelect 0x908 /* Useless now */ ++#define rFPGA1_TxInfo 0x90c /* Useless now Status report?? */ ++ ++/* */ ++/* 5. PageA(0xA00) */ ++/* */ ++/* Set Control channel to upper or lower. These settings are required only for 40MHz */ ++#define rCCK0_System 0xa00 ++ ++#define rCCK0_AFESetting 0xa04 /* Disable init gain now Select RX path by RSSI */ ++#define rCCK0_CCA 0xa08 /* Disable init gain now Init gain */ ++ ++#define rCCK0_RxAGC1 0xa0c /* AGC default value, saturation level Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. Not the same as 90 series */ ++#define rCCK0_RxAGC2 0xa10 /* AGC & DAGC */ ++ ++#define rCCK0_RxHP 0xa14 ++ ++#define rCCK0_DSPParameter1 0xa18 /* Timing recovery & Channel estimation threshold */ ++#define rCCK0_DSPParameter2 0xa1c /* SQ threshold */ ++ ++#define rCCK0_TxFilter1 0xa20 ++#define rCCK0_TxFilter2 0xa24 ++#define rCCK0_DebugPort 0xa28 /* debug port and Tx filter3 */ ++#define rCCK0_FalseAlarmReport 0xa2c /* 0xa2d useless now 0xa30-a4f channel report */ ++#define rCCK0_TRSSIReport 0xa50 ++#define rCCK0_RxReport 0xa54 /* 0xa57 */ ++#define rCCK0_FACounterLower 0xa5c /* 0xa5b */ ++#define rCCK0_FACounterUpper 0xa58 /* 0xa5c */ ++ ++/* */ ++/* 6. PageC(0xC00) */ ++/* */ ++#define rOFDM0_LSTF 0xc00 ++ ++#define rOFDM0_TRxPathEnable 0xc04 ++#define rOFDM0_TRMuxPar 0xc08 ++#define rOFDM0_TRSWIsolation 0xc0c ++ ++#define rOFDM0_XARxAFE 0xc10 /* RxIQ DC offset, Rx digital filter, DC notch filter */ ++#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imblance matrix */ ++#define rOFDM0_XBRxAFE 0xc18 ++#define rOFDM0_XBRxIQImbalance 0xc1c ++#define rOFDM0_XCRxAFE 0xc20 ++#define rOFDM0_XCRxIQImbalance 0xc24 ++#define rOFDM0_XDRxAFE 0xc28 ++#define rOFDM0_XDRxIQImbalance 0xc2c ++ ++#define rOFDM0_RxDetector1 0xc30 /* PD,BW & SBD DM tune init gain */ ++#define rOFDM0_RxDetector2 0xc34 /* SBD & Fame Sync. */ ++#define rOFDM0_RxDetector3 0xc38 /* Frame Sync. */ ++#define rOFDM0_RxDetector4 0xc3c /* PD, SBD, Frame Sync & Short-GI */ ++ ++#define rOFDM0_RxDSP 0xc40 /* Rx Sync Path */ ++#define rOFDM0_CFOandDAGC 0xc44 /* CFO & DAGC */ ++#define rOFDM0_CCADropThreshold 0xc48 /* CCA Drop threshold */ ++#define rOFDM0_ECCAThreshold 0xc4c /* energy CCA */ ++ ++#define rOFDM0_XAAGCCore1 0xc50 /* DIG */ ++#define rOFDM0_XAAGCCore2 0xc54 ++#define rOFDM0_XBAGCCore1 0xc58 ++#define rOFDM0_XBAGCCore2 0xc5c ++#define rOFDM0_XCAGCCore1 0xc60 ++#define rOFDM0_XCAGCCore2 0xc64 ++#define rOFDM0_XDAGCCore1 0xc68 ++#define rOFDM0_XDAGCCore2 0xc6c ++ ++#define rOFDM0_AGCParameter1 0xc70 ++#define rOFDM0_AGCParameter2 0xc74 ++#define rOFDM0_AGCRSSITable 0xc78 ++#define rOFDM0_HTSTFAGC 0xc7c ++ ++#define rOFDM0_XATxIQImbalance 0xc80 /* TX PWR TRACK and DIG */ ++#define rOFDM0_XATxAFE 0xc84 ++#define rOFDM0_XBTxIQImbalance 0xc88 ++#define rOFDM0_XBTxAFE 0xc8c ++#define rOFDM0_XCTxIQImbalance 0xc90 ++#define rOFDM0_XCTxAFE 0xc94 ++#define rOFDM0_XDTxIQImbalance 0xc98 ++#define rOFDM0_XDTxAFE 0xc9c ++#define rOFDM0_RxIQExtAnta 0xca0 ++ ++#define rOFDM0_RxHPParameter 0xce0 ++#define rOFDM0_TxPseudoNoiseWgt 0xce4 ++#define rOFDM0_FrameSync 0xcf0 ++#define rOFDM0_DFSReport 0xcf4 ++#define rOFDM0_TxCoeff1 0xca4 ++#define rOFDM0_TxCoeff2 0xca8 ++#define rOFDM0_TxCoeff3 0xcac ++#define rOFDM0_TxCoeff4 0xcb0 ++#define rOFDM0_TxCoeff5 0xcb4 ++#define rOFDM0_TxCoeff6 0xcb8 ++ ++/* 7. PageD(0xD00) */ ++#define rOFDM1_LSTF 0xd00 ++#define rOFDM1_TRxPathEnable 0xd04 ++ ++#define rOFDM1_CFO 0xd08 /* No setting now */ ++#define rOFDM1_CSI1 0xd10 ++#define rOFDM1_SBD 0xd14 ++#define rOFDM1_CSI2 0xd18 ++#define rOFDM1_CFOTracking 0xd2c ++#define rOFDM1_TRxMesaure1 0xd34 ++#define rOFDM1_IntfDet 0xd3c ++#define rOFDM1_PseudoNoiseStateAB 0xd50 ++#define rOFDM1_PseudoNoiseStateCD 0xd54 ++#define rOFDM1_RxPseudoNoiseWgt 0xd58 ++ ++#define rOFDM_PHYCounter1 0xda0 /* cca, parity fail */ ++#define rOFDM_PHYCounter2 0xda4 /* rate illegal, crc8 fail */ ++#define rOFDM_PHYCounter3 0xda8 /* MCS not support */ ++ ++#define rOFDM_ShortCFOAB 0xdac /* No setting now */ ++#define rOFDM_ShortCFOCD 0xdb0 ++#define rOFDM_LongCFOAB 0xdb4 ++#define rOFDM_LongCFOCD 0xdb8 ++#define rOFDM_TailCFOAB 0xdbc ++#define rOFDM_TailCFOCD 0xdc0 ++#define rOFDM_PWMeasure1 0xdc4 ++#define rOFDM_PWMeasure2 0xdc8 ++#define rOFDM_BWReport 0xdcc ++#define rOFDM_AGCReport 0xdd0 ++#define rOFDM_RxSNR 0xdd4 ++#define rOFDM_RxEVMCSI 0xdd8 ++#define rOFDM_SIGReport 0xddc ++ ++/* */ ++/* 8. PageE(0xE00) */ ++/* */ ++#define rTxAGC_Rate18_06 0xe00 ++#define rTxAGC_Rate54_24 0xe04 ++#define rTxAGC_CCK_Mcs32 0xe08 ++#define rTxAGC_Mcs03_Mcs00 0xe10 ++#define rTxAGC_Mcs07_Mcs04 0xe14 ++#define rTxAGC_Mcs11_Mcs08 0xe18 ++#define rTxAGC_Mcs15_Mcs12 0xe1c ++ ++/* Analog- control in RX_WAIT_CCA : REG: EE0 [Analog- Power & Control Register] */ ++#define rRx_Wait_CCCA 0xe70 ++#define rAnapar_Ctrl_BB 0xee0 ++ ++/* */ ++/* 7. RF Register 0x00-0x2E (RF 8256) */ ++/* RF-0222D 0x00-3F */ ++/* */ ++/* Zebra1 */ ++#define RTL92SE_FPGA_VERIFY 0 ++#define rZebra1_HSSIEnable 0x0 /* Useless now */ ++#define rZebra1_TRxEnable1 0x1 ++#define rZebra1_TRxEnable2 0x2 ++#define rZebra1_AGC 0x4 ++#define rZebra1_ChargePump 0x5 ++/* if (RTL92SE_FPGA_VERIFY == 1) */ ++#define rZebra1_Channel 0x7 /* RF channel switch */ ++/* else */ ++ ++/* endif */ ++#define rZebra1_TxGain 0x8 /* Useless now */ ++#define rZebra1_TxLPF 0x9 ++#define rZebra1_RxLPF 0xb ++#define rZebra1_RxHPFCorner 0xc ++ ++/* Zebra4 */ ++#define rGlobalCtrl 0 /* Useless now */ ++#define rRTL8256_TxLPF 19 ++#define rRTL8256_RxLPF 11 ++ ++/* RTL8258 */ ++#define rRTL8258_TxLPF 0x11 /* Useless now */ ++#define rRTL8258_RxLPF 0x13 ++#define rRTL8258_RSSILPF 0xa ++ ++/* */ ++/* RL6052 Register definition */ ++#define RF_AC 0x00 /* */ ++ ++#define RF_IQADJ_G1 0x01 /* */ ++#define RF_IQADJ_G2 0x02 /* */ ++#define RF_POW_TRSW 0x05 /* */ ++ ++#define RF_GAIN_RX 0x06 /* */ ++#define RF_GAIN_TX 0x07 /* */ ++ ++#define RF_TXM_IDAC 0x08 /* */ ++#define RF_BS_IQGEN 0x0F /* */ ++ ++#define RF_MODE1 0x10 /* */ ++#define RF_MODE2 0x11 /* */ ++ ++#define RF_RX_AGC_HP 0x12 /* */ ++#define RF_TX_AGC 0x13 /* */ ++#define RF_BIAS 0x14 /* */ ++#define RF_IPA 0x15 /* */ ++#define RF_TXBIAS 0x16 /* */ ++#define RF_POW_ABILITY 0x17 /* */ ++#define RF_MODE_AG 0x18 /* */ ++#define rRfChannel 0x18 /* RF channel and BW switch */ ++#define RF_CHNLBW 0x18 /* RF channel and BW switch */ ++#define RF_TOP 0x19 /* */ ++ ++#define RF_RX_G1 0x1A /* */ ++#define RF_RX_G2 0x1B /* */ ++ ++#define RF_RX_BB2 0x1C /* */ ++#define RF_RX_BB1 0x1D /* */ ++ ++#define RF_RCK1 0x1E /* */ ++#define RF_RCK2 0x1F /* */ ++ ++#define RF_TX_G1 0x20 /* */ ++#define RF_TX_G2 0x21 /* */ ++#define RF_TX_G3 0x22 /* */ ++ ++#define RF_TX_BB1 0x23 /* */ ++ ++#define RF_T_METER 0x24 /* */ ++ ++#define RF_SYN_G1 0x25 /* RF TX Power control */ ++#define RF_SYN_G2 0x26 /* RF TX Power control */ ++#define RF_SYN_G3 0x27 /* RF TX Power control */ ++#define RF_SYN_G4 0x28 /* RF TX Power control */ ++#define RF_SYN_G5 0x29 /* RF TX Power control */ ++#define RF_SYN_G6 0x2A /* RF TX Power control */ ++#define RF_SYN_G7 0x2B /* RF TX Power control */ ++#define RF_SYN_G8 0x2C /* RF TX Power control */ ++ ++#define RF_RCK_OS 0x30 /* RF TX PA control */ ++#define RF_TXPA_G1 0x31 /* RF TX PA control */ ++#define RF_TXPA_G2 0x32 /* RF TX PA control */ ++#define RF_TXPA_G3 0x33 /* RF TX PA control */ ++ ++/* */ ++/* Bit Mask */ ++/* */ ++/* 1. Page1(0x100) */ ++#define bBBResetB 0x100 /* Useless now? */ ++#define bGlobalResetB 0x200 ++#define bOFDMTxStart 0x4 ++#define bCCKTxStart 0x8 ++#define bCRC32Debug 0x100 ++#define bPMACLoopback 0x10 ++#define bTxLSIG 0xffffff ++#define bOFDMTxRate 0xf ++#define bOFDMTxReserved 0x10 ++#define bOFDMTxLength 0x1ffe0 ++#define bOFDMTxParity 0x20000 ++#define bTxHTSIG1 0xffffff ++#define bTxHTMCSRate 0x7f ++#define bTxHTBW 0x80 ++#define bTxHTLength 0xffff00 ++#define bTxHTSIG2 0xffffff ++#define bTxHTSmoothing 0x1 ++#define bTxHTSounding 0x2 ++#define bTxHTReserved 0x4 ++#define bTxHTAggreation 0x8 ++#define bTxHTSTBC 0x30 ++#define bTxHTAdvanceCoding 0x40 ++#define bTxHTShortGI 0x80 ++#define bTxHTNumberHT_LTF 0x300 ++#define bTxHTCRC8 0x3fc00 ++#define bCounterReset 0x10000 ++#define bNumOfOFDMTx 0xffff ++#define bNumOfCCKTx 0xffff0000 ++#define bTxIdleInterval 0xffff ++#define bOFDMService 0xffff0000 ++#define bTxMACHeader 0xffffffff ++#define bTxDataInit 0xff ++#define bTxHTMode 0x100 ++#define bTxDataType 0x30000 ++#define bTxRandomSeed 0xffffffff ++#define bCCKTxPreamble 0x1 ++#define bCCKTxSFD 0xffff0000 ++#define bCCKTxSIG 0xff ++#define bCCKTxService 0xff00 ++#define bCCKLengthExt 0x8000 ++#define bCCKTxLength 0xffff0000 ++#define bCCKTxCRC16 0xffff ++#define bCCKTxStatus 0x1 ++#define bOFDMTxStatus 0x2 ++ ++#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && (_Offset <= 0xfff)) ++ ++/* 2. Page8(0x800) */ ++#define bRFMOD 0x1 /* Reg 0x800 rFPGA0_RFMOD */ ++#define bJapanMode 0x2 ++#define bCCKTxSC 0x30 ++#define bCCKEn 0x1000000 ++#define bOFDMEn 0x2000000 ++ ++#define bOFDMRxADCPhase 0x10000 /* Useless now */ ++#define bOFDMTxDACPhase 0x40000 ++#define bXATxAGC 0x3f ++ ++#define bXBTxAGC 0xf00 /* Reg 80c rFPGA0_TxGainStage */ ++#define bXCTxAGC 0xf000 ++#define bXDTxAGC 0xf0000 ++ ++#define bPAStart 0xf0000000 /* Useless now */ ++#define bTRStart 0x00f00000 ++#define bRFStart 0x0000f000 ++#define bBBStart 0x000000f0 ++#define bBBCCKStart 0x0000000f ++#define bPAEnd 0xf /* Reg0x814 */ ++#define bTREnd 0x0f000000 ++#define bRFEnd 0x000f0000 ++#define bCCAMask 0x000000f0 /* T2R */ ++#define bR2RCCAMask 0x00000f00 ++#define bHSSI_R2TDelay 0xf8000000 ++#define bHSSI_T2RDelay 0xf80000 ++#define bContTxHSSI 0x400 /* chane gain at continue Tx */ ++#define bIGFromCCK 0x200 ++#define bAGCAddress 0x3f ++#define bRxHPTx 0x7000 ++#define bRxHPT2R 0x38000 ++#define bRxHPCCKIni 0xc0000 ++#define bAGCTxCode 0xc00000 ++#define bAGCRxCode 0x300000 ++ ++#define b3WireDataLength 0x800 /* Reg 0x820~84f rFPGA0_XA_HSSIParameter1 */ ++#define b3WireAddressLength 0x400 ++ ++#define b3WireRFPowerDown 0x1 /* Useless now */ ++/* define bHWSISelect 0x8 */ ++#define b5GPAPEPolarity 0x40000000 ++#define b2GPAPEPolarity 0x80000000 ++#define bRFSW_TxDefaultAnt 0x3 ++#define bRFSW_TxOptionAnt 0x30 ++#define bRFSW_RxDefaultAnt 0x300 ++#define bRFSW_RxOptionAnt 0x3000 ++#define bRFSI_3WireData 0x1 ++#define bRFSI_3WireClock 0x2 ++#define bRFSI_3WireLoad 0x4 ++#define bRFSI_3WireRW 0x8 ++#define bRFSI_3Wire 0xf ++ ++#define bRFSI_RFENV 0x10 /* Reg 0x870 rFPGA0_XAB_RFInterfaceSW */ ++ ++#define bRFSI_TRSW 0x20 /* Useless now */ ++#define bRFSI_TRSWB 0x40 ++#define bRFSI_ANTSW 0x100 ++#define bRFSI_ANTSWB 0x200 ++#define bRFSI_PAPE 0x400 ++#define bRFSI_PAPE5G 0x800 ++#define bBandSelect 0x1 ++#define bHTSIG2_GI 0x80 ++#define bHTSIG2_Smoothing 0x01 ++#define bHTSIG2_Sounding 0x02 ++#define bHTSIG2_Aggreaton 0x08 ++#define bHTSIG2_STBC 0x30 ++#define bHTSIG2_AdvCoding 0x40 ++#define bHTSIG2_NumOfHTLTF 0x300 ++#define bHTSIG2_CRC8 0x3fc ++#define bHTSIG1_MCS 0x7f ++#define bHTSIG1_BandWidth 0x80 ++#define bHTSIG1_HTLength 0xffff ++#define bLSIG_Rate 0xf ++#define bLSIG_Reserved 0x10 ++#define bLSIG_Length 0x1fffe ++#define bLSIG_Parity 0x20 ++#define bCCKRxPhase 0x4 ++#if (RTL92SE_FPGA_VERIFY == 1) ++#define bLSSIReadAddress 0x3f000000 /* LSSI "Read" Address ++ Reg 0x824 rFPGA0_XA_HSSIParameter2 */ ++#else ++#define bLSSIReadAddress 0x7f800000 /* T65 RF */ ++#endif ++#define bLSSIReadEdge 0x80000000 /* LSSI "Read" edge signal */ ++#if (RTL92SE_FPGA_VERIFY == 1) ++#define bLSSIReadBackData 0xfff /* Reg 0x8a0 ++ rFPGA0_XA_LSSIReadBack */ ++#else ++#define bLSSIReadBackData 0xfffff /* T65 RF */ ++#endif ++#define bLSSIReadOKFlag 0x1000 /* Useless now */ ++#define bCCKSampleRate 0x8 /* 0: 44MHz, 1:88MHz */ ++#define bRegulator0Standby 0x1 ++#define bRegulatorPLLStandby 0x2 ++#define bRegulator1Standby 0x4 ++#define bPLLPowerUp 0x8 ++#define bDPLLPowerUp 0x10 ++#define bDA10PowerUp 0x20 ++#define bAD7PowerUp 0x200 ++#define bDA6PowerUp 0x2000 ++#define bXtalPowerUp 0x4000 ++#define b40MDClkPowerUP 0x8000 ++#define bDA6DebugMode 0x20000 ++#define bDA6Swing 0x380000 ++ ++#define bADClkPhase 0x4000000 /* Reg 0x880 ++ rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ */ ++ ++#define b80MClkDelay 0x18000000 /* Useless */ ++#define bAFEWatchDogEnable 0x20000000 ++ ++#define bXtalCap01 0xc0000000 /* Reg 0x884 ++ rFPGA0_AnalogParameter2 Crystal cap */ ++#define bXtalCap23 0x3 ++#define bXtalCap92x 0x0f000000 ++#define bXtalCap 0x0f000000 ++ ++#define bIntDifClkEnable 0x400 /* Useless */ ++#define bExtSigClkEnable 0x800 ++#define bBandgapMbiasPowerUp 0x10000 ++#define bAD11SHGain 0xc0000 ++#define bAD11InputRange 0x700000 ++#define bAD11OPCurrent 0x3800000 ++#define bIPathLoopback 0x4000000 ++#define bQPathLoopback 0x8000000 ++#define bAFELoopback 0x10000000 ++#define bDA10Swing 0x7e0 ++#define bDA10Reverse 0x800 ++#define bDAClkSource 0x1000 ++#define bAD7InputRange 0x6000 ++#define bAD7Gain 0x38000 ++#define bAD7OutputCMMode 0x40000 ++#define bAD7InputCMMode 0x380000 ++#define bAD7Current 0xc00000 ++#define bRegulatorAdjust 0x7000000 ++#define bAD11PowerUpAtTx 0x1 ++#define bDA10PSAtTx 0x10 ++#define bAD11PowerUpAtRx 0x100 ++#define bDA10PSAtRx 0x1000 ++#define bCCKRxAGCFormat 0x200 ++#define bPSDFFTSamplepPoint 0xc000 ++#define bPSDAverageNum 0x3000 ++#define bIQPathControl 0xc00 ++#define bPSDFreq 0x3ff ++#define bPSDAntennaPath 0x30 ++#define bPSDIQSwitch 0x40 ++#define bPSDRxTrigger 0x400000 ++#define bPSDTxTrigger 0x80000000 ++#define bPSDSineToneScale 0x7f000000 ++#define bPSDReport 0xffff ++ ++/* 3. Page9(0x900) */ ++#define bOFDMTxSC 0x30000000 /* Useless */ ++#define bCCKTxOn 0x1 ++#define bOFDMTxOn 0x2 ++#define bDebugPage 0xfff /* reset debug page and HWord, ++ * LWord */ ++#define bDebugItem 0xff /* reset debug page and LWord */ ++#define bAntL 0x10 ++#define bAntNonHT 0x100 ++#define bAntHT1 0x1000 ++#define bAntHT2 0x10000 ++#define bAntHT1S1 0x100000 ++#define bAntNonHTS1 0x1000000 ++ ++/* 4. PageA(0xA00) */ ++#define bCCKBBMode 0x3 /* Useless */ ++#define bCCKTxPowerSaving 0x80 ++#define bCCKRxPowerSaving 0x40 ++ ++#define bCCKSideBand 0x10 /* Reg 0xa00 rCCK0 20/40 sw */ ++ ++#define bCCKScramble 0x8 /* Useless */ ++#define bCCKAntDiversity 0x8000 ++#define bCCKCarrierRecovery 0x4000 ++#define bCCKTxRate 0x3000 ++#define bCCKDCCancel 0x0800 ++#define bCCKISICancel 0x0400 ++#define bCCKMatchFilter 0x0200 ++#define bCCKEqualizer 0x0100 ++#define bCCKPreambleDetect 0x800000 ++#define bCCKFastFalseCCA 0x400000 ++#define bCCKChEstStart 0x300000 ++#define bCCKCCACount 0x080000 ++#define bCCKcs_lim 0x070000 ++#define bCCKBistMode 0x80000000 ++#define bCCKCCAMask 0x40000000 ++#define bCCKTxDACPhase 0x4 ++#define bCCKRxADCPhase 0x20000000 /* r_rx_clk */ ++#define bCCKr_cp_mode0 0x0100 ++#define bCCKTxDCOffset 0xf0 ++#define bCCKRxDCOffset 0xf ++#define bCCKCCAMode 0xc000 ++#define bCCKFalseCS_lim 0x3f00 ++#define bCCKCS_ratio 0xc00000 ++#define bCCKCorgBit_sel 0x300000 ++#define bCCKPD_lim 0x0f0000 ++#define bCCKNewCCA 0x80000000 ++#define bCCKRxHPofIG 0x8000 ++#define bCCKRxIG 0x7f00 ++#define bCCKLNAPolarity 0x800000 ++#define bCCKRx1stGain 0x7f0000 ++#define bCCKRFExtend 0x20000000 /* CCK Rx init gain polar */ ++#define bCCKRxAGCSatLevel 0x1f000000 ++#define bCCKRxAGCSatCount 0xe0 ++#define bCCKRxRFSettle 0x1f /* AGCsamp_dly */ ++#define bCCKFixedRxAGC 0x8000 ++#define bCCKAntennaPolarity 0x2000 ++#define bCCKTxFilterType 0x0c00 ++#define bCCKRxAGCReportType 0x0300 ++#define bCCKRxDAGCEn 0x80000000 ++#define bCCKRxDAGCPeriod 0x20000000 ++#define bCCKRxDAGCSatLevel 0x1f000000 ++#define bCCKTimingRecovery 0x800000 ++#define bCCKTxC0 0x3f0000 ++#define bCCKTxC1 0x3f000000 ++#define bCCKTxC2 0x3f ++#define bCCKTxC3 0x3f00 ++#define bCCKTxC4 0x3f0000 ++#define bCCKTxC5 0x3f000000 ++#define bCCKTxC6 0x3f ++#define bCCKTxC7 0x3f00 ++#define bCCKDebugPort 0xff0000 ++#define bCCKDACDebug 0x0f000000 ++#define bCCKFalseAlarmEnable 0x8000 ++#define bCCKFalseAlarmRead 0x4000 ++#define bCCKTRSSI 0x7f ++#define bCCKRxAGCReport 0xfe ++#define bCCKRxReport_AntSel 0x80000000 ++#define bCCKRxReport_MFOff 0x40000000 ++#define bCCKRxRxReport_SQLoss 0x20000000 ++#define bCCKRxReport_Pktloss 0x10000000 ++#define bCCKRxReport_Lockedbit 0x08000000 ++#define bCCKRxReport_RateError 0x04000000 ++#define bCCKRxReport_RxRate 0x03000000 ++#define bCCKRxFACounterLower 0xff ++#define bCCKRxFACounterUpper 0xff000000 ++#define bCCKRxHPAGCStart 0xe000 ++#define bCCKRxHPAGCFinal 0x1c00 ++#define bCCKRxFalseAlarmEnable 0x8000 ++#define bCCKFACounterFreeze 0x4000 ++#define bCCKTxPathSel 0x10000000 ++#define bCCKDefaultRxPath 0xc000000 ++#define bCCKOptionRxPath 0x3000000 ++ ++/* 5. PageC(0xC00) */ ++#define bNumOfSTF 0x3 /* Useless */ ++#define bShift_L 0xc0 ++#define bGI_TH 0xc ++#define bRxPathA 0x1 ++#define bRxPathB 0x2 ++#define bRxPathC 0x4 ++#define bRxPathD 0x8 ++#define bTxPathA 0x1 ++#define bTxPathB 0x2 ++#define bTxPathC 0x4 ++#define bTxPathD 0x8 ++#define bTRSSIFreq 0x200 ++#define bADCBackoff 0x3000 ++#define bDFIRBackoff 0xc000 ++#define bTRSSILatchPhase 0x10000 ++#define bRxIDCOffset 0xff ++#define bRxQDCOffset 0xff00 ++#define bRxDFIRMode 0x1800000 ++#define bRxDCNFType 0xe000000 ++#define bRXIQImb_A 0x3ff ++#define bRXIQImb_B 0xfc00 ++#define bRXIQImb_C 0x3f0000 ++#define bRXIQImb_D 0xffc00000 ++#define bDC_dc_Notch 0x60000 ++#define bRxNBINotch 0x1f000000 ++#define bPD_TH 0xf ++#define bPD_TH_Opt2 0xc000 ++#define bPWED_TH 0x700 ++#define bIfMF_Win_L 0x800 ++#define bPD_Option 0x1000 ++#define bMF_Win_L 0xe000 ++#define bBW_Search_L 0x30000 ++#define bwin_enh_L 0xc0000 ++#define bBW_TH 0x700000 ++#define bED_TH2 0x3800000 ++#define bBW_option 0x4000000 ++#define bRatio_TH 0x18000000 ++#define bWindow_L 0xe0000000 ++#define bSBD_Option 0x1 ++#define bFrame_TH 0x1c ++#define bFS_Option 0x60 ++#define bDC_Slope_check 0x80 ++#define bFGuard_Counter_DC_L 0xe00 ++#define bFrame_Weight_Short 0x7000 ++#define bSub_Tune 0xe00000 ++#define bFrame_DC_Length 0xe000000 ++#define bSBD_start_offset 0x30000000 ++#define bFrame_TH_2 0x7 ++#define bFrame_GI2_TH 0x38 ++#define bGI2_Sync_en 0x40 ++#define bSarch_Short_Early 0x300 ++#define bSarch_Short_Late 0xc00 ++#define bSarch_GI2_Late 0x70000 ++#define bCFOAntSum 0x1 ++#define bCFOAcc 0x2 ++#define bCFOStartOffset 0xc ++#define bCFOLookBack 0x70 ++#define bCFOSumWeight 0x80 ++#define bDAGCEnable 0x10000 ++#define bTXIQImb_A 0x3ff ++#define bTXIQImb_B 0xfc00 ++#define bTXIQImb_C 0x3f0000 ++#define bTXIQImb_D 0xffc00000 ++#define bTxIDCOffset 0xff ++#define bTxQDCOffset 0xff00 ++#define bTxDFIRMode 0x10000 ++#define bTxPesudoNoiseOn 0x4000000 ++#define bTxPesudoNoise_A 0xff ++#define bTxPesudoNoise_B 0xff00 ++#define bTxPesudoNoise_C 0xff0000 ++#define bTxPesudoNoise_D 0xff000000 ++#define bCCADropOption 0x20000 ++#define bCCADropThres 0xfff00000 ++#define bEDCCA_H 0xf ++#define bEDCCA_L 0xf0 ++#define bLambda_ED 0x300 ++#define bRxInitialGain 0x7f ++#define bRxAntDivEn 0x80 ++#define bRxAGCAddressForLNA 0x7f00 ++#define bRxHighPowerFlow 0x8000 ++#define bRxAGCFreezeThres 0xc0000 ++#define bRxFreezeStep_AGC1 0x300000 ++#define bRxFreezeStep_AGC2 0xc00000 ++#define bRxFreezeStep_AGC3 0x3000000 ++#define bRxFreezeStep_AGC0 0xc000000 ++#define bRxRssi_Cmp_En 0x10000000 ++#define bRxQuickAGCEn 0x20000000 ++#define bRxAGCFreezeThresMode 0x40000000 ++#define bRxOverFlowCheckType 0x80000000 ++#define bRxAGCShift 0x7f ++#define bTRSW_Tri_Only 0x80 ++#define bPowerThres 0x300 ++#define bRxAGCEn 0x1 ++#define bRxAGCTogetherEn 0x2 ++#define bRxAGCMin 0x4 ++#define bRxHP_Ini 0x7 ++#define bRxHP_TRLNA 0x70 ++#define bRxHP_RSSI 0x700 ++#define bRxHP_BBP1 0x7000 ++#define bRxHP_BBP2 0x70000 ++#define bRxHP_BBP3 0x700000 ++#define bRSSI_H 0x7f0000 /* thresh for hi power */ ++#define bRSSI_Gen 0x7f000000 /* thresh for ant div */ ++#define bRxSettle_TRSW 0x7 ++#define bRxSettle_LNA 0x38 ++#define bRxSettle_RSSI 0x1c0 ++#define bRxSettle_BBP 0xe00 ++#define bRxSettle_RxHP 0x7000 ++#define bRxSettle_AntSW_RSSI 0x38000 ++#define bRxSettle_AntSW 0xc0000 ++#define bRxProcessTime_DAGC 0x300000 ++#define bRxSettle_HSSI 0x400000 ++#define bRxProcessTime_BBPPW 0x800000 ++#define bRxAntennaPowerShift 0x3000000 ++#define bRSSITableSelect 0xc000000 ++#define bRxHP_Final 0x7000000 ++#define bRxHTSettle_BBP 0x7 ++#define bRxHTSettle_HSSI 0x8 ++#define bRxHTSettle_RxHP 0x70 ++#define bRxHTSettle_BBPPW 0x80 ++#define bRxHTSettle_Idle 0x300 ++#define bRxHTSettle_Reserved 0x1c00 ++#define bRxHTRxHPEn 0x8000 ++#define bRxHTAGCFreezeThres 0x30000 ++#define bRxHTAGCTogetherEn 0x40000 ++#define bRxHTAGCMin 0x80000 ++#define bRxHTAGCEn 0x100000 ++#define bRxHTDAGCEn 0x200000 ++#define bRxHTRxHP_BBP 0x1c00000 ++#define bRxHTRxHP_Final 0xe0000000 ++#define bRxPWRatioTH 0x3 ++#define bRxPWRatioEn 0x4 ++#define bRxMFHold 0x3800 ++#define bRxPD_Delay_TH1 0x38 ++#define bRxPD_Delay_TH2 0x1c0 ++#define bRxPD_DC_COUNT_MAX 0x600 ++/* define bRxMF_Hold 0x3800 */ ++#define bRxPD_Delay_TH 0x8000 ++#define bRxProcess_Delay 0xf0000 ++#define bRxSearchrange_GI2_Early 0x700000 ++#define bRxFrame_Guard_Counter_L 0x3800000 ++#define bRxSGI_Guard_L 0xc000000 ++#define bRxSGI_Search_L 0x30000000 ++#define bRxSGI_TH 0xc0000000 ++#define bDFSCnt0 0xff ++#define bDFSCnt1 0xff00 ++#define bDFSFlag 0xf0000 ++#define bMFWeightSum 0x300000 ++#define bMinIdxTH 0x7f000000 ++#define bDAFormat 0x40000 ++#define bTxChEmuEnable 0x01000000 ++#define bTRSWIsolation_A 0x7f ++#define bTRSWIsolation_B 0x7f00 ++#define bTRSWIsolation_C 0x7f0000 ++#define bTRSWIsolation_D 0x7f000000 ++#define bExtLNAGain 0x7c00 ++ ++/* 6. PageE(0xE00) */ ++#define bSTBCEn 0x4 /* Useless */ ++#define bAntennaMapping 0x10 ++#define bNss 0x20 ++#define bCFOAntSumD 0x200 ++#define bPHYCounterReset 0x8000000 ++#define bCFOReportGet 0x4000000 ++#define bOFDMContinueTx 0x10000000 ++#define bOFDMSingleCarrier 0x20000000 ++#define bOFDMSingleTone 0x40000000 ++/* define bRxPath1 0x01 */ ++/* define bRxPath2 0x02 */ ++/* define bRxPath3 0x04 */ ++/* define bRxPath4 0x08 */ ++/* define bTxPath1 0x10 */ ++/* define bTxPath2 0x20 */ ++#define bHTDetect 0x100 ++#define bCFOEn 0x10000 ++#define bCFOValue 0xfff00000 ++#define bSigTone_Re 0x3f ++#define bSigTone_Im 0x7f00 ++#define bCounter_CCA 0xffff ++#define bCounter_ParityFail 0xffff0000 ++#define bCounter_RateIllegal 0xffff ++#define bCounter_CRC8Fail 0xffff0000 ++#define bCounter_MCSNoSupport 0xffff ++#define bCounter_FastSync 0xffff ++#define bShortCFO 0xfff ++#define bShortCFOTLength 12 /* total */ ++#define bShortCFOFLength 11 /* fraction */ ++#define bLongCFO 0x7ff ++#define bLongCFOTLength 11 ++#define bLongCFOFLength 11 ++#define bTailCFO 0x1fff ++#define bTailCFOTLength 13 ++#define bTailCFOFLength 12 ++#define bmax_en_pwdB 0xffff ++#define bCC_power_dB 0xffff0000 ++#define bnoise_pwdB 0xffff ++#define bPowerMeasTLength 10 ++#define bPowerMeasFLength 3 ++#define bRx_HT_BW 0x1 ++#define bRxSC 0x6 ++#define bRx_HT 0x8 ++#define bNB_intf_det_on 0x1 ++#define bIntf_win_len_cfg 0x30 ++#define bNB_Intf_TH_cfg 0x1c0 ++#define bRFGain 0x3f ++#define bTableSel 0x40 ++#define bTRSW 0x80 ++#define bRxSNR_A 0xff ++#define bRxSNR_B 0xff00 ++#define bRxSNR_C 0xff0000 ++#define bRxSNR_D 0xff000000 ++#define bSNREVMTLength 8 ++#define bSNREVMFLength 1 ++#define bCSI1st 0xff ++#define bCSI2nd 0xff00 ++#define bRxEVM1st 0xff0000 ++#define bRxEVM2nd 0xff000000 ++#define bSIGEVM 0xff ++#define bPWDB 0xff00 ++#define bSGIEN 0x10000 ++ ++#define bSFactorQAM1 0xf /* Useless */ ++#define bSFactorQAM2 0xf0 ++#define bSFactorQAM3 0xf00 ++#define bSFactorQAM4 0xf000 ++#define bSFactorQAM5 0xf0000 ++#define bSFactorQAM6 0xf0000 ++#define bSFactorQAM7 0xf00000 ++#define bSFactorQAM8 0xf000000 ++#define bSFactorQAM9 0xf0000000 ++#define bCSIScheme 0x100000 ++ ++#define bNoiseLvlTopSet 0x3 /* Useless */ ++#define bChSmooth 0x4 ++#define bChSmoothCfg1 0x38 ++#define bChSmoothCfg2 0x1c0 ++#define bChSmoothCfg3 0xe00 ++#define bChSmoothCfg4 0x7000 ++#define bMRCMode 0x800000 ++#define bTHEVMCfg 0x7000000 ++ ++#define bLoopFitType 0x1 /* Useless */ ++#define bUpdCFO 0x40 ++#define bUpdCFOOffData 0x80 ++#define bAdvUpdCFO 0x100 ++#define bAdvTimeCtrl 0x800 ++#define bUpdClko 0x1000 ++#define bFC 0x6000 ++#define bTrackingMode 0x8000 ++#define bPhCmpEnable 0x10000 ++#define bUpdClkoLTF 0x20000 ++#define bComChCFO 0x40000 ++#define bCSIEstiMode 0x80000 ++#define bAdvUpdEqz 0x100000 ++#define bUChCfg 0x7000000 ++#define bUpdEqz 0x8000000 ++ ++#define bTxAGCRate18_06 0x7f7f7f7f /* Useless */ ++#define bTxAGCRate54_24 0x7f7f7f7f ++#define bTxAGCRateMCS32 0x7f ++#define bTxAGCRateCCK 0x7f00 ++#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f ++#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f ++#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f ++#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f ++ ++/* Rx Pseduo noise */ ++#define bRxPesudoNoiseOn 0x20000000 /* Useless */ ++#define bRxPesudoNoise_A 0xff ++#define bRxPesudoNoise_B 0xff00 ++#define bRxPesudoNoise_C 0xff0000 ++#define bRxPesudoNoise_D 0xff000000 ++#define bPesudoNoiseState_A 0xffff ++#define bPesudoNoiseState_B 0xffff0000 ++#define bPesudoNoiseState_C 0xffff ++#define bPesudoNoiseState_D 0xffff0000 ++ ++/* 7. RF Register */ ++/* Zebra1 */ ++#define bZebra1_HSSIEnable 0x8 /* Useless */ ++#define bZebra1_TRxControl 0xc00 ++#define bZebra1_TRxGainSetting 0x07f ++#define bZebra1_RxCorner 0xc00 ++#define bZebra1_TxChargePump 0x38 ++#define bZebra1_RxChargePump 0x7 ++#define bZebra1_ChannelNum 0xf80 ++#define bZebra1_TxLPFBW 0x400 ++#define bZebra1_RxLPFBW 0x600 ++ ++/* Zebra4 */ ++#define bRTL8256RegModeCtrl1 0x100 /* Useless */ ++#define bRTL8256RegModeCtrl0 0x40 ++#define bRTL8256_TxLPFBW 0x18 ++#define bRTL8256_RxLPFBW 0x600 ++ ++/* RTL8258 */ ++#define bRTL8258_TxLPFBW 0xc /* Useless */ ++#define bRTL8258_RxLPFBW 0xc00 ++#define bRTL8258_RSSILPFBW 0xc0 ++ ++/* */ ++/* Other Definition */ ++/* */ ++ ++/* byte endable for sb_write */ ++#define bByte0 0x1 /* Useless */ ++#define bByte1 0x2 ++#define bByte2 0x4 ++#define bByte3 0x8 ++#define bWord0 0x3 ++#define bWord1 0xc ++#define bDWord 0xf ++ ++/* for PutRegsetting & GetRegSetting BitMask */ ++#define bMaskByte0 0xff /* Reg 0xc50 rOFDM0_XAAGCCore~0xC6f */ ++#define bMaskByte1 0xff00 ++#define bMaskByte2 0xff0000 ++#define bMaskByte3 0xff000000 ++#define bMaskHWord 0xffff0000 ++#define bMaskLWord 0x0000ffff ++#define bMaskDWord 0xffffffff ++#define bMaskH4Bits 0xf0000000 ++#define bMaskOFDM_D 0xffc00000 ++#define bMaskCCK 0x3f3f3f3f ++#define bMask12Bits 0xfff ++ ++/* for PutRFRegsetting & GetRFRegSetting BitMask */ ++#if (RTL92SE_FPGA_VERIFY == 1) ++#define bRFRegOffsetMask 0xfff ++#else ++#define bRFRegOffsetMask 0xfffff ++#endif ++#define bEnable 0x1 /* Useless */ ++#define bDisabl 0x0 ++ ++#define LeftAntenna 0x0 /* Useless */ ++#define RightAntenna 0x1 ++ ++#define tCheckTxStatus 500 /* 500ms Useless */ ++#define tUpdateRxCounter 100 /* 100ms */ ++ ++#define rateCCK 0 /* Useless */ ++#define rateOFDM 1 ++#define rateHT 2 ++ ++/* define Register-End */ ++#define bPMAC_End 0x1ff /* Useless */ ++#define bFPGAPHY0_End 0x8ff ++#define bFPGAPHY1_End 0x9ff ++#define bCCKPHY0_End 0xaff ++#define bOFDMPHY0_End 0xcff ++#define bOFDMPHY1_End 0xdff ++ ++/* define max debug item in each debug page */ ++/* define bMaxItem_FPGA_PHY0 0x9 */ ++/* define bMaxItem_FPGA_PHY1 0x3 */ ++/* define bMaxItem_PHY_11B 0x16 */ ++/* define bMaxItem_OFDM_PHY0 0x29 */ ++/* define bMaxItem_OFDM_PHY1 0x0 */ ++ ++#define bPMACControl 0x0 /* Useless */ ++#define bWMACControl 0x1 ++#define bWNICControl 0x2 ++ ++#define RCR_AAP BIT(0) /* accept all physical address */ ++#define RCR_APM BIT(1) /* accept physical match */ ++#define RCR_AM BIT(2) /* accept multicast */ ++#define RCR_AB BIT(3) /* accept broadcast */ ++#define RCR_ACRC32 BIT(5) /* accept error packet */ ++#define RCR_9356SEL BIT(6) ++#define RCR_AICV BIT(12) /* Accept ICV error packet */ ++#define RCR_RXFTH0 (BIT(13)|BIT(14)|BIT(15)) /* Rx FIFO threshold */ ++#define RCR_ADF BIT(18) /* Accept Data(frame type) frame */ ++#define RCR_ACF BIT(19) /* Accept control frame */ ++#define RCR_AMF BIT(20) /* Accept management frame */ ++#define RCR_ADD3 BIT(21) ++#define RCR_APWRMGT BIT(22) /* Accept power management packet */ ++#define RCR_CBSSID BIT(23) /* Accept BSSID match packet */ ++#define RCR_ENMARP BIT(28) /* enable mac auto reset phy */ ++#define RCR_EnCS1 BIT(29) /* enable carrier sense method 1 */ ++#define RCR_EnCS2 BIT(30) /* enable carrier sense method 2 */ ++#define RCR_OnlyErlPkt BIT(31) /* Rx Early mode is performed for ++ * packet size greater than 1536 */ ++ ++/*--------------------------Define Parameters-------------------------------*/ ++ ++#endif /* __INC_HAL8192SPHYREG_H */ +diff --git a/drivers/staging/r8188eu/include/rtw_p2p.h b/drivers/staging/r8188eu/include/rtw_p2p.h +new file mode 100644 +index 000000000000..92b9bfe3ea0b +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_p2p.h +@@ -0,0 +1,119 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_P2P_H_ ++#define __RTW_P2P_H_ ++ ++#include "drv_types.h" ++ ++u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); ++u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); ++u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo, ++ u8 *pbuf, u8 *pssid, u8 ussidlen, ++ u8 *pdev_raddr); ++u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo, ++ u8 *pbuf, u8 status_code); ++u32 build_deauth_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); ++u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len); ++u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len, struct sta_info *psta); ++u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len); ++u32 process_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len); ++u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len); ++u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe); ++u8 process_p2p_group_negotation_req(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len); ++u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len); ++u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo, ++ u8 *pframe, uint len); ++u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe, ++ uint len); ++void p2p_protocol_wk_hdl(struct adapter *padapter, int intcmdtype); ++void process_p2p_ps_ie(struct adapter *padapter, u8 *ies, u32 ielength); ++void p2p_ps_wk_hdl(struct adapter *padapter, u8 p2p_ps_state); ++u8 p2p_ps_wk_cmd(struct adapter *padapter, u8 p2p_ps_state, u8 enqueue); ++void reset_global_wifidirect_info(struct adapter *padapter); ++int rtw_init_wifi_display_info(struct adapter *padapter); ++void rtw_init_wifidirect_timers(struct adapter *padapter); ++void rtw_init_wifidirect_addrs(struct adapter *padapter, u8 *dev_addr, ++ u8 *iface_addr); ++void init_wifidirect_info(struct adapter *padapter, enum P2P_ROLE role); ++int rtw_p2p_enable(struct adapter *padapter, enum P2P_ROLE role); ++ ++static inline void _rtw_p2p_set_state(struct wifidirect_info *wdinfo, ++ enum P2P_STATE state) ++{ ++ if (wdinfo->p2p_state != state) ++ wdinfo->p2p_state = state; ++} ++ ++static inline void _rtw_p2p_set_pre_state(struct wifidirect_info *wdinfo, ++ enum P2P_STATE state) ++{ ++ if (wdinfo->pre_p2p_state != state) ++ wdinfo->pre_p2p_state = state; ++} ++ ++static inline void _rtw_p2p_set_role(struct wifidirect_info *wdinfo, ++ enum P2P_ROLE role) ++{ ++ if (wdinfo->role != role) ++ wdinfo->role = role; ++} ++ ++static inline int _rtw_p2p_state(struct wifidirect_info *wdinfo) ++{ ++ return wdinfo->p2p_state; ++} ++ ++static inline int _rtw_p2p_pre_state(struct wifidirect_info *wdinfo) ++{ ++ return wdinfo->pre_p2p_state; ++} ++ ++static inline int _rtw_p2p_role(struct wifidirect_info *wdinfo) ++{ ++ return wdinfo->role; ++} ++ ++static inline bool _rtw_p2p_chk_state(struct wifidirect_info *wdinfo, ++ enum P2P_STATE state) ++{ ++ return wdinfo->p2p_state == state; ++} ++ ++static inline bool _rtw_p2p_chk_role(struct wifidirect_info *wdinfo, ++ enum P2P_ROLE role) ++{ ++ return wdinfo->role == role; ++} ++ ++#define rtw_p2p_set_state(wdinfo, state) _rtw_p2p_set_state(wdinfo, state) ++#define rtw_p2p_set_pre_state(wdinfo, state) \ ++ _rtw_p2p_set_pre_state(wdinfo, state) ++#define rtw_p2p_set_role(wdinfo, role) _rtw_p2p_set_role(wdinfo, role) ++ ++#define rtw_p2p_state(wdinfo) _rtw_p2p_state(wdinfo) ++#define rtw_p2p_pre_state(wdinfo) _rtw_p2p_pre_state(wdinfo) ++#define rtw_p2p_role(wdinfo) _rtw_p2p_role(wdinfo) ++#define rtw_p2p_chk_state(wdinfo, state) _rtw_p2p_chk_state(wdinfo, state) ++#define rtw_p2p_chk_role(wdinfo, role) _rtw_p2p_chk_role(wdinfo, role) ++ ++#define rtw_p2p_findphase_ex_set(wdinfo, value) \ ++ ((wdinfo)->find_phase_state_exchange_cnt = (value)) ++ ++/* is this find phase exchange for social channel scan? */ ++#define rtw_p2p_findphase_ex_is_social(wdinfo) \ ++((wdinfo)->find_phase_state_exchange_cnt >= P2P_FINDPHASE_EX_SOCIAL_FIRST) ++ ++/* should we need find phase exchange anymore? */ ++#define rtw_p2p_findphase_ex_is_needed(wdinfo) \ ++ ((wdinfo)->find_phase_state_exchange_cnt < P2P_FINDPHASE_EX_MAX && \ ++ (wdinfo)->find_phase_state_exchange_cnt != P2P_FINDPHASE_EX_NONE) ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_pwrctrl.h b/drivers/staging/r8188eu/include/rtw_pwrctrl.h +new file mode 100644 +index 000000000000..543f928e8089 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_pwrctrl.h +@@ -0,0 +1,266 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#ifndef __RTW_PWRCTRL_H_ ++#define __RTW_PWRCTRL_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define FW_PWR0 0 ++#define FW_PWR1 1 ++#define FW_PWR2 2 ++#define FW_PWR3 3 ++#define HW_PWR0 7 ++#define HW_PWR1 6 ++#define HW_PWR2 2 ++#define HW_PWR3 0 ++#define HW_PWR4 8 ++ ++#define FW_PWRMSK 0x7 ++ ++#define XMIT_ALIVE BIT(0) ++#define RECV_ALIVE BIT(1) ++#define CMD_ALIVE BIT(2) ++#define EVT_ALIVE BIT(3) ++ ++enum power_mgnt { ++ PS_MODE_ACTIVE = 0, ++ PS_MODE_MIN, ++ PS_MODE_MAX, ++ PS_MODE_DTIM, ++ PS_MODE_VOIP, ++ PS_MODE_UAPSD_WMM, ++ PS_MODE_UAPSD, ++ PS_MODE_IBSS, ++ PS_MODE_WWLAN, ++ PM_Radio_Off, ++ PM_Card_Disable, ++ PS_MODE_NUM ++}; ++ ++/* ++ BIT[2:0] = HW state ++ BIT[3] = Protocol PS state, 0: register active state, ++ 1: register sleep state ++ BIT[4] = sub-state ++*/ ++ ++#define PS_DPS BIT(0) ++#define PS_LCLK (PS_DPS) ++#define PS_RF_OFF BIT(1) ++#define PS_ALL_ON BIT(2) ++#define PS_ST_ACTIVE BIT(3) ++ ++#define PS_ISR_ENABLE BIT(4) ++#define PS_IMR_ENABLE BIT(5) ++#define PS_ACK BIT(6) ++#define PS_TOGGLE BIT(7) ++ ++#define PS_STATE_MASK (0x0F) ++#define PS_STATE_HW_MASK (0x07) ++#define PS_SEQ_MASK (0xc0) ++ ++#define PS_STATE(x) (PS_STATE_MASK & (x)) ++#define PS_STATE_HW(x) (PS_STATE_HW_MASK & (x)) ++#define PS_SEQ(x) (PS_SEQ_MASK & (x)) ++ ++#define PS_STATE_S0 (PS_DPS) ++#define PS_STATE_S1 (PS_LCLK) ++#define PS_STATE_S2 (PS_RF_OFF) ++#define PS_STATE_S3 (PS_ALL_ON) ++#define PS_STATE_S4 ((PS_ST_ACTIVE) | (PS_ALL_ON)) ++ ++#define PS_IS_RF_ON(x) ((x) & (PS_ALL_ON)) ++#define PS_IS_ACTIVE(x) ((x) & (PS_ST_ACTIVE)) ++#define CLR_PS_STATE(x) ((x) = ((x) & (0xF0))) ++ ++struct reportpwrstate_parm { ++ unsigned char mode; ++ unsigned char state; /* the CPWM value */ ++ unsigned short rsvd; ++}; ++ ++static inline void _init_pwrlock(struct semaphore *plock) ++{ ++ sema_init(plock, 1); ++} ++ ++static inline void _free_pwrlock(struct semaphore *plock) ++{ ++} ++ ++static inline void _enter_pwrlock(struct semaphore *plock) ++{ ++ _rtw_down_sema(plock); ++} ++ ++static inline void _exit_pwrlock(struct semaphore *plock) ++{ ++ up(plock); ++} ++ ++#define LPS_DELAY_TIME 1*HZ /* 1 sec */ ++ ++#define EXE_PWR_NONE 0x01 ++#define EXE_PWR_IPS 0x02 ++#define EXE_PWR_LPS 0x04 ++ ++/* RF state. */ ++enum rt_rf_power_state { ++ rf_on, /* RF is on after RFSleep or RFOff */ ++ rf_sleep, /* 802.11 Power Save mode */ ++ rf_off, /* HW/SW Radio OFF or Inactive Power Save */ ++ /* Add the new RF state above this line===== */ ++ rf_max ++}; ++ ++/* RF Off Level for IPS or HW/SW radio off */ ++#define RT_RF_OFF_LEVL_ASPM BIT(0) /* PCI ASPM */ ++#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /* PCI clock request */ ++#define RT_RF_OFF_LEVL_PCI_D3 BIT(2) /* PCI D3 mode */ ++#define RT_RF_OFF_LEVL_HALT_NIC BIT(3) /* NIC halt, re-init hw param*/ ++#define RT_RF_OFF_LEVL_FREE_FW BIT(4) /* FW free, re-download the FW*/ ++#define RT_RF_OFF_LEVL_FW_32K BIT(5) /* FW in 32k */ ++#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6) /* Always enable ASPM and Clock ++ * Req in initialization. */ ++#define RT_RF_LPS_DISALBE_2R BIT(30) /* When LPS is on, disable 2R ++ * if no packet is RX or TX. */ ++#define RT_RF_LPS_LEVEL_ASPM BIT(31) /* LPS with ASPM */ ++ ++#define RT_IN_PS_LEVEL(ppsc, _PS_FLAG) \ ++ ((ppsc->cur_ps_level & _PS_FLAG) ? true : false) ++#define RT_CLEAR_PS_LEVEL(ppsc, _PS_FLAG) \ ++ (ppsc->cur_ps_level &= (~(_PS_FLAG))) ++#define RT_SET_PS_LEVEL(ppsc, _PS_FLAG) \ ++ (ppsc->cur_ps_level |= _PS_FLAG) ++ ++enum _PS_BBRegBackup_ { ++ PSBBREG_RF0 = 0, ++ PSBBREG_RF1, ++ PSBBREG_RF2, ++ PSBBREG_AFE0, ++ PSBBREG_TOTALCNT ++}; ++ ++enum { /* for ips_mode */ ++ IPS_NONE = 0, ++ IPS_NORMAL, ++ IPS_LEVEL_2, ++}; ++ ++struct pwrctrl_priv { ++ struct semaphore lock; ++ volatile u8 rpwm; /* requested power state for fw */ ++ volatile u8 cpwm; /* fw current power state. updated when ++ * 1. read from HCPWM 2. driver lowers power level */ ++ volatile u8 tog; /* toggling */ ++ volatile u8 cpwm_tog; /* toggling */ ++ ++ u8 pwr_mode; ++ u8 smart_ps; ++ u8 bcn_ant_mode; ++ ++ u32 alives; ++ struct work_struct cpwm_event; ++ u8 bpower_saving; ++ ++ u8 b_hw_radio_off; ++ u8 reg_rfoff; ++ u8 reg_pdnmode; /* powerdown mode */ ++ u32 rfoff_reason; ++ ++ /* RF OFF Level */ ++ u32 cur_ps_level; ++ u32 reg_rfps_level; ++ uint ips_enter_cnts; ++ uint ips_leave_cnts; ++ ++ u8 ips_mode; ++ u8 ips_mode_req; /* used to accept the mode setting request, ++ * will update to ipsmode later */ ++ uint bips_processing; ++ u32 ips_deny_time; /* will deny IPS when system time less than this */ ++ u8 ps_processing; /* temp used to mark whether in rtw_ps_processor */ ++ ++ u8 bLeisurePs; ++ u8 LpsIdleCount; ++ u8 power_mgnt; ++ u8 bFwCurrentInPSMode; ++ u32 DelayLPSLastTimeStamp; ++ u8 btcoex_rfon; ++ s32 pnp_current_pwr_state; ++ u8 pnp_bstop_trx; ++ ++ u8 bInternalAutoSuspend; ++ u8 bInSuspend; ++#ifdef CONFIG_BT_COEXIST ++ u8 bAutoResume; ++ u8 autopm_cnt; ++#endif ++ u8 bSupportRemoteWakeup; ++ struct timer_list pwr_state_check_timer; ++ int pwr_state_check_interval; ++ u8 pwr_state_check_cnts; ++ ++ int ps_flag; ++ ++ enum rt_rf_power_state rf_pwrstate;/* cur power state */ ++ enum rt_rf_power_state change_rfpwrstate; ++ ++ u8 wepkeymask; ++ u8 bHWPowerdown;/* if support hw power down */ ++ u8 bHWPwrPindetect; ++ u8 bkeepfwalive; ++ u8 brfoffbyhw; ++ unsigned long PS_BBRegBackup[PSBBREG_TOTALCNT]; ++}; ++ ++#define rtw_get_ips_mode_req(pwrctrlpriv) \ ++ (pwrctrlpriv)->ips_mode_req ++ ++#define rtw_ips_mode_req(pwrctrlpriv, ips_mode) \ ++ ((pwrctrlpriv)->ips_mode_req = (ips_mode)) ++ ++#define RTW_PWR_STATE_CHK_INTERVAL 2000 ++ ++#define _rtw_set_pwr_state_check_timer(pwrctrlpriv, ms) \ ++ do { \ ++ _set_timer(&(pwrctrlpriv)->pwr_state_check_timer, (ms)); \ ++ } while (0) ++ ++#define rtw_set_pwr_state_check_timer(pwrctrl) \ ++ _rtw_set_pwr_state_check_timer((pwrctrl), \ ++ (pwrctrl)->pwr_state_check_interval) ++ ++void rtw_init_pwrctrl_priv(struct adapter *adapter); ++void rtw_free_pwrctrl_priv(struct adapter *adapter); ++ ++void rtw_set_ps_mode(struct adapter *adapter, u8 ps_mode, u8 smart_ps, ++ u8 bcn_ant_mode); ++void rtw_set_rpwm(struct adapter *adapter, u8 val8); ++void LeaveAllPowerSaveMode(struct adapter *adapter); ++void ips_enter(struct adapter *padapter); ++int ips_leave(struct adapter *padapter); ++ ++void rtw_ps_processor(struct adapter *padapter); ++ ++enum rt_rf_power_state RfOnOffDetect(struct adapter *iadapter); ++ ++s32 LPS_RF_ON_check(struct adapter *adapter, u32 delay_ms); ++void LPS_Enter(struct adapter *adapter); ++void LPS_Leave(struct adapter *adapter); ++ ++u8 rtw_interface_ps_func(struct adapter *adapter, ++ enum hal_intf_ps_func efunc_id, u8 *val); ++void rtw_set_ips_deny(struct adapter *adapter, u32 ms); ++int _rtw_pwr_wakeup(struct adapter *adapter, u32 ips_defer_ms, ++ const char *caller); ++#define rtw_pwr_wakeup(adapter) \ ++ _rtw_pwr_wakeup(adapter, RTW_PWR_STATE_CHK_INTERVAL, __func__) ++#define rtw_pwr_wakeup_ex(adapter, ips_deffer_ms) \ ++ _rtw_pwr_wakeup(adapter, ips_deffer_ms, __func__) ++int rtw_pm_set_ips(struct adapter *adapter, u8 mode); ++int rtw_pm_set_lps(struct adapter *adapter, u8 mode); ++ ++#endif /* __RTL871X_PWRCTRL_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_recv.h b/drivers/staging/r8188eu/include/rtw_recv.h +new file mode 100644 +index 000000000000..d1d1ca0e56d6 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_recv.h +@@ -0,0 +1,413 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#ifndef _RTW_RECV_H_ ++#define _RTW_RECV_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define NR_RECVFRAME 256 ++ ++#define RXFRAME_ALIGN 8 ++#define RXFRAME_ALIGN_SZ (1<signal_stat_timer, \ ++ (recvpriv)->signal_stat_sampling_interval) ++ ++struct sta_recv_priv { ++ spinlock_t lock; ++ int option; ++ struct __queue defrag_q; /* keeping the fragment frame until defrag */ ++ struct stainfo_rxcache rxcache; ++}; ++ ++struct recv_buf { ++ struct list_head list; ++ spinlock_t recvbuf_lock; ++ u32 ref_cnt; ++ struct adapter *adapter; ++ u8 *pbuf; ++ u8 *pallocated_buf; ++ u32 len; ++ u8 *phead; ++ u8 *pdata; ++ u8 *ptail; ++ u8 *pend; ++ struct urb *purb; ++ dma_addr_t dma_transfer_addr; /* (in) dma addr for transfer_buffer */ ++ u32 alloc_sz; ++ u8 irp_pending; ++ int transfer_len; ++ struct sk_buff *pskb; ++ u8 reuse; ++}; ++ ++/* ++ head -----> ++ ++ data -----> ++ ++ payload ++ ++ tail -----> ++ ++ end -----> ++ ++ len = (unsigned int )(tail - data); ++ ++*/ ++struct recv_frame { ++ struct list_head list; ++ struct sk_buff *pkt; ++ struct sk_buff *pkt_newalloc; ++ struct adapter *adapter; ++ u8 fragcnt; ++ int frame_tag; ++ struct rx_pkt_attrib attrib; ++ uint len; ++ u8 *rx_head; ++ u8 *rx_data; ++ u8 *rx_tail; ++ u8 *rx_end; ++ void *precvbuf; ++ struct sta_info *psta; ++ /* for A-MPDU Rx reordering buffer control */ ++ struct recv_reorder_ctrl *preorder_ctrl; ++}; ++ ++struct recv_frame *_rtw_alloc_recvframe(struct __queue *pfree_recv_queue); ++struct recv_frame *rtw_alloc_recvframe(struct __queue *pfree_recv_queue); ++void rtw_init_recvframe(struct recv_frame *precvframe, ++ struct recv_priv *precvpriv); ++int rtw_free_recvframe(struct recv_frame *precvframe, ++ struct __queue *pfree_recv_queue); ++#define rtw_dequeue_recvframe(queue) rtw_alloc_recvframe(queue) ++int _rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue); ++int rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue); ++void rtw_free_recvframe_queue(struct __queue *pframequeue, ++ struct __queue *pfree_recv_queue); ++u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter); ++int rtw_enqueue_recvbuf_to_head(struct recv_buf *buf, struct __queue *queue); ++int rtw_enqueue_recvbuf(struct recv_buf *precvbuf, struct __queue *queue); ++struct recv_buf *rtw_dequeue_recvbuf(struct __queue *queue); ++ ++void rtw_reordering_ctrl_timeout_handler(void *pcontext); ++ ++static inline u8 *get_rxmem(struct recv_frame *precvframe) ++{ ++ /* always return rx_head... */ ++ if (precvframe == NULL) ++ return NULL; ++ return precvframe->rx_head; ++} ++ ++static inline u8 *get_rx_status(struct recv_frame *precvframe) ++{ ++ return get_rxmem(precvframe); ++} ++ ++static inline u8 *get_recvframe_data(struct recv_frame *precvframe) ++{ ++ /* always return rx_data */ ++ if (precvframe == NULL) ++ return NULL; ++ ++ return precvframe->rx_data; ++} ++ ++static inline u8 *recvframe_push(struct recv_frame *precvframe, int sz) ++{ ++ /* append data before rx_data */ ++ ++ /* add data to the start of recv_frame ++ * ++ * This function extends the used data area of the recv_frame at the buffer ++ * start. rx_data must be still larger than rx_head, after pushing. ++ */ ++ if (precvframe == NULL) ++ return NULL; ++ precvframe->rx_data -= sz ; ++ if (precvframe->rx_data < precvframe->rx_head) { ++ precvframe->rx_data += sz; ++ return NULL; ++ } ++ precvframe->len += sz; ++ return precvframe->rx_data; ++} ++ ++static inline u8 *recvframe_pull(struct recv_frame *precvframe, int sz) ++{ ++ /* rx_data += sz; move rx_data sz bytes hereafter */ ++ ++ /* used for extract sz bytes from rx_data, update rx_data and return ++ * the updated rx_data to the caller */ ++ ++ if (precvframe == NULL) ++ return NULL; ++ precvframe->rx_data += sz; ++ if (precvframe->rx_data > precvframe->rx_tail) { ++ precvframe->rx_data -= sz; ++ return NULL; ++ } ++ precvframe->len -= sz; ++ return precvframe->rx_data; ++} ++ ++static inline u8 *recvframe_put(struct recv_frame *precvframe, int sz) ++{ ++ /* used for append sz bytes from ptr to rx_tail, update rx_tail ++ * and return the updated rx_tail to the caller */ ++ /* after putting, rx_tail must be still larger than rx_end. */ ++ ++ if (precvframe == NULL) ++ return NULL; ++ ++ precvframe->rx_tail += sz; ++ ++ if (precvframe->rx_tail > precvframe->rx_end) { ++ precvframe->rx_tail -= sz; ++ return NULL; ++ } ++ precvframe->len += sz; ++ return precvframe->rx_tail; ++} ++ ++static inline u8 *recvframe_pull_tail(struct recv_frame *precvframe, int sz) ++{ ++ /* rmv data from rx_tail (by yitsen) */ ++ ++ /* used for extract sz bytes from rx_end, update rx_end and return ++ * the updated rx_end to the caller */ ++ /* after pulling, rx_end must be still larger than rx_data. */ ++ ++ if (precvframe == NULL) ++ return NULL; ++ precvframe->rx_tail -= sz; ++ if (precvframe->rx_tail < precvframe->rx_data) { ++ precvframe->rx_tail += sz; ++ return NULL; ++ } ++ precvframe->len -= sz; ++ return precvframe->rx_tail; ++} ++ ++static inline int get_recvframe_len(struct recv_frame *precvframe) ++{ ++ return precvframe->len; ++} ++ ++static inline s32 translate_percentage_to_dbm(u32 sig_stren_index) ++{ ++ s32 power; /* in dBm. */ ++ ++ /* Translate to dBm (x=0.5y-95). */ ++ power = (s32)((sig_stren_index + 1) >> 1); ++ power -= 95; ++ ++ return power; ++} ++ ++struct sta_info; ++ ++void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv); ++ ++void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_rf.h b/drivers/staging/r8188eu/include/rtw_rf.h +new file mode 100644 +index 000000000000..48129da9c93f +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_rf.h +@@ -0,0 +1,126 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_RF_H_ ++#define __RTW_RF_H_ ++ ++#include "rtw_cmd.h" ++ ++#define OFDM_PHY 1 ++#define MIXED_PHY 2 ++#define CCK_PHY 3 ++ ++#define NumRates (13) ++ ++/* slot time for 11g */ ++#define SHORT_SLOT_TIME 9 ++#define NON_SHORT_SLOT_TIME 20 ++ ++#define RTL8711_RF_MAX_SENS 6 ++#define RTL8711_RF_DEF_SENS 4 ++ ++/* We now define the following channels as the max channels in each ++ * channel plan. */ ++/* 2G, total 14 chnls */ ++/* {1,2,3,4,5,6,7,8,9,10,11,12,13,14} */ ++#define MAX_CHANNEL_NUM_2G 14 ++#define MAX_CHANNEL_NUM 14 /* 2.4 GHz only */ ++ ++#define NUM_REGULATORYS 1 ++ ++/* Country codes */ ++#define USA 0x555320 ++#define EUROPE 0x1 /* temp, should be provided later */ ++#define JAPAN 0x2 /* temp, should be provided later */ ++ ++struct regulatory_class { ++ u32 starting_freq; /* MHz, */ ++ u8 channel_set[MAX_CHANNEL_NUM]; ++ u8 channel_cck_power[MAX_CHANNEL_NUM]; /* dbm */ ++ u8 channel_ofdm_power[MAX_CHANNEL_NUM]; /* dbm */ ++ u8 txpower_limit; /* dbm */ ++ u8 channel_spacing; /* MHz */ ++ u8 modem; ++}; ++ ++enum capability { ++ cESS = 0x0001, ++ cIBSS = 0x0002, ++ cPollable = 0x0004, ++ cPollReq = 0x0008, ++ cPrivacy = 0x0010, ++ cShortPreamble = 0x0020, ++ cPBCC = 0x0040, ++ cChannelAgility = 0x0080, ++ cSpectrumMgnt = 0x0100, ++ cQos = 0x0200, /* For HCCA, use with CF-Pollable ++ * and CF-PollReq */ ++ cShortSlotTime = 0x0400, ++ cAPSD = 0x0800, ++ cRM = 0x1000, /* RRM (Radio Request Measurement) */ ++ cDSSS_OFDM = 0x2000, ++ cDelayedBA = 0x4000, ++ cImmediateBA = 0x8000, ++}; ++ ++enum _REG_PREAMBLE_MODE { ++ PREAMBLE_LONG = 1, ++ PREAMBLE_AUTO = 2, ++ PREAMBLE_SHORT = 3, ++}; ++ ++enum _RTL8712_RF_MIMO_CONFIG_ { ++ RTL8712_RFCONFIG_1T = 0x10, ++ RTL8712_RFCONFIG_2T = 0x20, ++ RTL8712_RFCONFIG_1R = 0x01, ++ RTL8712_RFCONFIG_2R = 0x02, ++ RTL8712_RFCONFIG_1T1R = 0x11, ++ RTL8712_RFCONFIG_1T2R = 0x12, ++ RTL8712_RFCONFIG_TURBO = 0x92, ++ RTL8712_RFCONFIG_2T2R = 0x22 ++}; ++ ++enum rf90_radio_path { ++ RF90_PATH_A = 0, /* Radio Path A */ ++ RF90_PATH_B = 1, /* Radio Path B */ ++ RF90_PATH_C = 2, /* Radio Path C */ ++ RF90_PATH_D = 3 /* Radio Path D */ ++}; ++ ++/* Bandwidth Offset */ ++#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 ++#define HAL_PRIME_CHNL_OFFSET_LOWER 1 ++#define HAL_PRIME_CHNL_OFFSET_UPPER 2 ++ ++/* Represent Channel Width in HT Capabilities */ ++/* */ ++enum ht_channel_width { ++ HT_CHANNEL_WIDTH_20 = 0, ++ HT_CHANNEL_WIDTH_40 = 1, ++}; ++ ++/* */ ++/* Represent Extension Channel Offset in HT Capabilities */ ++/* This is available only in 40Mhz mode. */ ++/* */ ++enum ht_extchnl_offset { ++ HT_EXTCHNL_OFFSET_NO_EXT = 0, ++ HT_EXTCHNL_OFFSET_UPPER = 1, ++ HT_EXTCHNL_OFFSET_NO_DEF = 2, ++ HT_EXTCHNL_OFFSET_LOWER = 3, ++}; ++ ++/* 2007/11/15 MH Define different RF type. */ ++enum rt_rf_type_def { ++ RF_1T2R = 0, ++ RF_2T4R = 1, ++ RF_2T2R = 2, ++ RF_1T1R = 3, ++ RF_2T2R_GREEN = 4, ++ RF_819X_MAX_TYPE = 5, ++}; ++ ++u32 rtw_ch2freq(u32 ch); ++u32 rtw_freq2ch(u32 freq); ++ ++#endif /* _RTL8711_RF_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_security.h b/drivers/staging/r8188eu/include/rtw_security.h +new file mode 100644 +index 000000000000..ec6ecdb7bc98 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_security.h +@@ -0,0 +1,341 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __RTW_SECURITY_H_ ++#define __RTW_SECURITY_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define _NO_PRIVACY_ 0x0 ++#define _WEP40_ 0x1 ++#define _TKIP_ 0x2 ++#define _TKIP_WTMIC_ 0x3 ++#define _AES_ 0x4 ++#define _WEP104_ 0x5 ++#define _WEP_WPA_MIXED_ 0x07 /* WEP + WPA */ ++#define _SMS4_ 0x06 ++ ++#define is_wep_enc(alg) (((alg) == _WEP40_) || ((alg) == _WEP104_)) ++ ++#define _WPA_IE_ID_ 0xdd ++#define _WPA2_IE_ID_ 0x30 ++ ++#define SHA256_MAC_LEN 32 ++#define AES_BLOCK_SIZE 16 ++#define AES_PRIV_SIZE (4 * 44) ++ ++enum { ++ ENCRYP_PROTOCOL_OPENSYS, /* open system */ ++ ENCRYP_PROTOCOL_WEP, /* WEP */ ++ ENCRYP_PROTOCOL_WPA, /* WPA */ ++ ENCRYP_PROTOCOL_WPA2, /* WPA2 */ ++ ENCRYP_PROTOCOL_WAPI, /* WAPI: Not support in this version */ ++ ENCRYP_PROTOCOL_MAX ++}; ++ ++#ifndef Ndis802_11AuthModeWPA2 ++#define Ndis802_11AuthModeWPA2 (Ndis802_11AuthModeWPANone + 1) ++#endif ++ ++#ifndef Ndis802_11AuthModeWPA2PSK ++#define Ndis802_11AuthModeWPA2PSK (Ndis802_11AuthModeWPANone + 2) ++#endif ++ ++union pn48 { ++ u64 val; ++ ++#ifdef __LITTLE_ENDIAN ++ struct { ++ u8 TSC0; ++ u8 TSC1; ++ u8 TSC2; ++ u8 TSC3; ++ u8 TSC4; ++ u8 TSC5; ++ u8 TSC6; ++ u8 TSC7; ++ } _byte_; ++ ++#elif defined(__BIG_ENDIAN) ++ ++ struct { ++ u8 TSC7; ++ u8 TSC6; ++ u8 TSC5; ++ u8 TSC4; ++ u8 TSC3; ++ u8 TSC2; ++ u8 TSC1; ++ u8 TSC0; ++ } _byte_; ++#endif ++}; ++ ++union Keytype { ++ u8 skey[16]; ++ u32 lkey[4]; ++}; ++ ++struct rt_pmkid_list { ++ u8 bUsed; ++ u8 Bssid[6]; ++ u8 PMKID[16]; ++ u8 SsidBuf[33]; ++ u8 *ssid_octet; ++ u16 ssid_length; ++}; ++ ++struct security_priv { ++ u32 dot11AuthAlgrthm; /* 802.11 auth, could be open, ++ * shared, 8021x and authswitch */ ++ u32 dot11PrivacyAlgrthm; /* This specify the privacy for ++ * shared auth. algorithm. */ ++ /* WEP */ ++ u32 dot11PrivacyKeyIndex; /* this is only valid for legendary ++ * wep, 0~3 for key id.(tx key index) */ ++ union Keytype dot11DefKey[4]; /* this is only valid for def. key */ ++ u32 dot11DefKeylen[4]; ++ u32 dot118021XGrpPrivacy; /* This specify the privacy algthm. ++ * used for Grp key */ ++ u32 dot118021XGrpKeyid; /* key id used for Grp Key ++ * ( tx key index) */ ++ union Keytype dot118021XGrpKey[4]; /* 802.1x Group Key, ++ * for inx0 and inx1 */ ++ union Keytype dot118021XGrptxmickey[4]; ++ union Keytype dot118021XGrprxmickey[4]; ++ union pn48 dot11Grptxpn; /* PN48 used for Grp Key xmit.*/ ++ union pn48 dot11Grprxpn; /* PN48 used for Grp Key recv.*/ ++#ifdef CONFIG_88EU_AP_MODE ++ /* extend security capabilities for AP_MODE */ ++ unsigned int dot8021xalg;/* 0:disable, 1:psk, 2:802.1x */ ++ unsigned int wpa_psk;/* 0:disable, bit(0): WPA, bit(1):WPA2 */ ++ unsigned int wpa_group_cipher; ++ unsigned int wpa2_group_cipher; ++ unsigned int wpa_pairwise_cipher; ++ unsigned int wpa2_pairwise_cipher; ++#endif ++ u8 wps_ie[MAX_WPS_IE_LEN];/* added in assoc req */ ++ int wps_ie_len; ++ u8 binstallGrpkey; ++ u8 busetkipkey; ++ u8 bcheck_grpkey; ++ u8 bgrpkey_handshake; ++ s32 sw_encrypt;/* from registry_priv */ ++ s32 sw_decrypt;/* from registry_priv */ ++ s32 hw_decrypted;/* if the rx packets is hw_decrypted==false,i ++ * it means the hw has not been ready. */ ++ ++ /* keeps the auth_type & enc_status from upper layer ++ * ioctl(wpa_supplicant or wzc) */ ++ u32 ndisauthtype; /* NDIS_802_11_AUTHENTICATION_MODE */ ++ u32 ndisencryptstatus; /* NDIS_802_11_ENCRYPTION_STATUS */ ++ struct wlan_bssid_ex sec_bss; /* for joinbss (h2c buffer) usage */ ++ struct ndis_802_11_wep ndiswep; ++ u8 assoc_info[600]; ++ u8 szofcapability[256]; /* for wpa2 usage */ ++ u8 oidassociation[512]; /* for wpa/wpa2 usage */ ++ u8 authenticator_ie[256]; /* store ap security information element */ ++ u8 supplicant_ie[256]; /* store sta security information element */ ++ ++ /* for tkip countermeasure */ ++ u32 last_mic_err_time; ++ u8 btkip_countermeasure; ++ u8 btkip_wait_report; ++ u32 btkip_countermeasure_time; ++ ++ /* */ ++ /* For WPA2 Pre-Authentication. */ ++ /* */ ++ struct rt_pmkid_list PMKIDList[NUM_PMKID_CACHE]; ++ u8 PMKIDIndex; ++ u8 bWepDefaultKeyIdxSet; ++}; ++ ++#define GET_ENCRY_ALGO(psecuritypriv, psta, encry_algo, bmcst) \ ++do { \ ++ switch (psecuritypriv->dot11AuthAlgrthm) { \ ++ case dot11AuthAlgrthm_Open: \ ++ case dot11AuthAlgrthm_Shared: \ ++ case dot11AuthAlgrthm_Auto: \ ++ encry_algo = (u8)psecuritypriv->dot11PrivacyAlgrthm; \ ++ break; \ ++ case dot11AuthAlgrthm_8021X: \ ++ if (bmcst) \ ++ encry_algo = (u8)psecuritypriv->dot118021XGrpPrivacy;\ ++ else \ ++ encry_algo = (u8)psta->dot118021XPrivacy; \ ++ break; \ ++ case dot11AuthAlgrthm_WAPI: \ ++ encry_algo = (u8)psecuritypriv->dot11PrivacyAlgrthm; \ ++ break; \ ++ } \ ++} while (0) ++ ++#define SET_ICE_IV_LEN(iv_len, icv_len, encrypt) \ ++do { \ ++ switch (encrypt) { \ ++ case _WEP40_: \ ++ case _WEP104_: \ ++ iv_len = 4; \ ++ icv_len = 4; \ ++ break; \ ++ case _TKIP_: \ ++ iv_len = 8; \ ++ icv_len = 4; \ ++ break; \ ++ case _AES_: \ ++ iv_len = 8; \ ++ icv_len = 8; \ ++ break; \ ++ case _SMS4_: \ ++ iv_len = 18; \ ++ icv_len = 16; \ ++ break; \ ++ default: \ ++ iv_len = 0; \ ++ icv_len = 0; \ ++ break; \ ++ } \ ++} while (0) ++ ++#define GET_TKIP_PN(iv, dot11txpn) \ ++do { \ ++ dot11txpn._byte_.TSC0 = iv[2]; \ ++ dot11txpn._byte_.TSC1 = iv[0]; \ ++ dot11txpn._byte_.TSC2 = iv[4]; \ ++ dot11txpn._byte_.TSC3 = iv[5]; \ ++ dot11txpn._byte_.TSC4 = iv[6]; \ ++ dot11txpn._byte_.TSC5 = iv[7]; \ ++} while (0) ++ ++#define ROL32(A, n) (((A) << (n)) | (((A)>>(32-(n))) & ((1UL << (n)) - 1))) ++#define ROR32(A, n) ROL32((A), 32-(n)) ++ ++struct mic_data { ++ u32 K0, K1; /* Key */ ++ u32 L, R; /* Current state */ ++ u32 M; /* Message accumulator (single word) */ ++ u32 nBytesInM; /* # bytes in M */ ++}; ++ ++extern const u32 Te0[256]; ++extern const u32 Te1[256]; ++extern const u32 Te2[256]; ++extern const u32 Te3[256]; ++extern const u32 Te4[256]; ++extern const u32 Td0[256]; ++extern const u32 Td1[256]; ++extern const u32 Td2[256]; ++extern const u32 Td3[256]; ++extern const u32 Td4[256]; ++extern const u32 rcon[10]; ++extern const u8 Td4s[256]; ++extern const u8 rcons[10]; ++ ++#define RCON(i) (rcons[(i)] << 24) ++ ++static inline u32 rotr(u32 val, int bits) ++{ ++ return (val >> bits) | (val << (32 - bits)); ++} ++ ++#define TE0(i) Te0[((i) >> 24) & 0xff] ++#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8) ++#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16) ++#define TE3(i) rotr(Te0[(i) & 0xff], 24) ++#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000) ++#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000) ++#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00) ++#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff) ++#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000) ++#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000) ++#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00) ++#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff) ++#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff) ++ ++#define TD0(i) Td0[((i) >> 24) & 0xff] ++#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8) ++#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16) ++#define TD3(i) rotr(Td0[(i) & 0xff], 24) ++#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24) ++#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16) ++#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8) ++#define TD44(i) (Td4s[(i) & 0xff]) ++#define TD0_(i) Td0[(i) & 0xff] ++#define TD1_(i) rotr(Td0[(i) & 0xff], 8) ++#define TD2_(i) rotr(Td0[(i) & 0xff], 16) ++#define TD3_(i) rotr(Td0[(i) & 0xff], 24) ++ ++#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \ ++ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) ++ ++#define PUTU32(ct, st) { \ ++(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \ ++(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } ++ ++#define WPA_GET_BE32(a) ((((u32)(a)[0]) << 24) | (((u32)(a)[1]) << 16) | \ ++ (((u32)(a)[2]) << 8) | ((u32)(a)[3])) ++ ++#define WPA_PUT_LE16(a, val) \ ++ do { \ ++ (a)[1] = ((u16)(val)) >> 8; \ ++ (a)[0] = ((u16)(val)) & 0xff; \ ++ } while (0) ++ ++#define WPA_PUT_BE32(a, val) \ ++ do { \ ++ (a)[0] = (u8)((((u32)(val)) >> 24) & 0xff); \ ++ (a)[1] = (u8)((((u32)(val)) >> 16) & 0xff); \ ++ (a)[2] = (u8)((((u32)(val)) >> 8) & 0xff); \ ++ (a)[3] = (u8)(((u32)(val)) & 0xff); \ ++ } while (0) ++ ++#define WPA_PUT_BE64(a, val) \ ++ do { \ ++ (a)[0] = (u8)(((u64)(val)) >> 56); \ ++ (a)[1] = (u8)(((u64)(val)) >> 48); \ ++ (a)[2] = (u8)(((u64)(val)) >> 40); \ ++ (a)[3] = (u8)(((u64)(val)) >> 32); \ ++ (a)[4] = (u8)(((u64)(val)) >> 24); \ ++ (a)[5] = (u8)(((u64)(val)) >> 16); \ ++ (a)[6] = (u8)(((u64)(val)) >> 8); \ ++ (a)[7] = (u8)(((u64)(val)) & 0xff); \ ++ } while (0) ++ ++/* ===== start - public domain SHA256 implementation ===== */ ++ ++/* This is based on SHA256 implementation in LibTomCrypt that was released into ++ * public domain by Tom St Denis. */ ++ ++/* Various logical functions */ ++#define RORc(x, y) \ ++ (((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y)&31)) | \ ++ ((unsigned long)(x) << (unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) ++#define Ch(x, y ,z) (z ^ (x & (y ^ z))) ++#define Maj(x, y, z) (((x | y) & z) | (x & y)) ++#define S(x, n) RORc((x), (n)) ++#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) ++#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) ++#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) ++#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) ++#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) ++#ifndef MIN ++#define MIN(x, y) (((x) < (y)) ? (x) : (y)) ++#endif ++ ++void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key); ++void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b); ++void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nBytes); ++void rtw_secgetmic(struct mic_data *pmicdata, u8 *dst); ++void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, ++ u8 *Miccode, u8 priority); ++u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe); ++u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe); ++void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe); ++u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe); ++u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe); ++void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe); ++void rtw_use_tkipkey_handler(void *FunctionContext); ++ ++#endif /* __RTL871X_SECURITY_H_ */ +diff --git a/drivers/staging/r8188eu/include/rtw_sreset.h b/drivers/staging/r8188eu/include/rtw_sreset.h +new file mode 100644 +index 000000000000..4e97997c305b +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_sreset.h +@@ -0,0 +1,34 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#ifndef _RTW_SRESET_C_ ++#define _RTW_SRESET_C_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++struct sreset_priv { ++ struct mutex silentreset_mutex; ++ u8 silent_reset_inprogress; ++ u8 wifi_error_status; ++ unsigned long last_tx_time; ++ unsigned long last_tx_complete_time; ++}; ++ ++#include "rtl8188e_hal.h" ++ ++#define WIFI_STATUS_SUCCESS 0 ++#define USB_VEN_REQ_CMD_FAIL BIT(0) ++#define USB_READ_PORT_FAIL BIT(1) ++#define USB_WRITE_PORT_FAIL BIT(2) ++#define WIFI_MAC_TXDMA_ERROR BIT(3) ++#define WIFI_TX_HANG BIT(4) ++#define WIFI_RX_HANG BIT(5) ++#define WIFI_IF_NOT_EXIST BIT(6) ++ ++void sreset_init_value(struct adapter *padapter); ++void sreset_reset_value(struct adapter *padapter); ++u8 sreset_get_wifi_status(struct adapter *padapter); ++void sreset_set_wifi_error_status(struct adapter *padapter, u32 status); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/rtw_xmit.h b/drivers/staging/r8188eu/include/rtw_xmit.h +new file mode 100644 +index 000000000000..5f6e2402e5c4 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/rtw_xmit.h +@@ -0,0 +1,367 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _RTW_XMIT_H_ ++#define _RTW_XMIT_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++#define MAX_XMITBUF_SZ (20480) /* 20k */ ++#define NR_XMITBUFF (4) ++ ++#define XMITBUF_ALIGN_SZ 4 ++ ++/* xmit extension buff defination */ ++#define MAX_XMIT_EXTBUF_SZ (1536) ++#define NR_XMIT_EXTBUFF (32) ++ ++#define MAX_NUMBLKS (1) ++ ++#define XMIT_VO_QUEUE (0) ++#define XMIT_VI_QUEUE (1) ++#define XMIT_BE_QUEUE (2) ++#define XMIT_BK_QUEUE (3) ++ ++#define VO_QUEUE_INX 0 ++#define VI_QUEUE_INX 1 ++#define BE_QUEUE_INX 2 ++#define BK_QUEUE_INX 3 ++#define BCN_QUEUE_INX 4 ++#define MGT_QUEUE_INX 5 ++#define HIGH_QUEUE_INX 6 ++#define TXCMD_QUEUE_INX 7 ++ ++#define HW_QUEUE_ENTRY 8 ++ ++#define WEP_IV(pattrib_iv, dot11txpn, keyidx)\ ++do {\ ++ pattrib_iv[0] = dot11txpn._byte_.TSC0;\ ++ pattrib_iv[1] = dot11txpn._byte_.TSC1;\ ++ pattrib_iv[2] = dot11txpn._byte_.TSC2;\ ++ pattrib_iv[3] = ((keyidx & 0x3)<<6);\ ++ dot11txpn.val = (dot11txpn.val == 0xffffff) ? 0 : (dot11txpn.val+1);\ ++} while (0) ++ ++#define TKIP_IV(pattrib_iv, dot11txpn, keyidx)\ ++do {\ ++ pattrib_iv[0] = dot11txpn._byte_.TSC1;\ ++ pattrib_iv[1] = (dot11txpn._byte_.TSC1 | 0x20) & 0x7f;\ ++ pattrib_iv[2] = dot11txpn._byte_.TSC0;\ ++ pattrib_iv[3] = BIT(5) | ((keyidx & 0x3)<<6);\ ++ pattrib_iv[4] = dot11txpn._byte_.TSC2;\ ++ pattrib_iv[5] = dot11txpn._byte_.TSC3;\ ++ pattrib_iv[6] = dot11txpn._byte_.TSC4;\ ++ pattrib_iv[7] = dot11txpn._byte_.TSC5;\ ++ dot11txpn.val = dot11txpn.val == 0xffffffffffffULL ? 0 : (dot11txpn.val+1);\ ++} while (0) ++ ++#define AES_IV(pattrib_iv, dot11txpn, keyidx)\ ++do { \ ++ pattrib_iv[0] = dot11txpn._byte_.TSC0; \ ++ pattrib_iv[1] = dot11txpn._byte_.TSC1; \ ++ pattrib_iv[2] = 0; \ ++ pattrib_iv[3] = BIT(5) | ((keyidx & 0x3)<<6); \ ++ pattrib_iv[4] = dot11txpn._byte_.TSC2; \ ++ pattrib_iv[5] = dot11txpn._byte_.TSC3; \ ++ pattrib_iv[6] = dot11txpn._byte_.TSC4; \ ++ pattrib_iv[7] = dot11txpn._byte_.TSC5; \ ++ dot11txpn.val = dot11txpn.val == 0xffffffffffffULL ? 0 : (dot11txpn.val+1);\ ++} while (0) ++ ++#define HWXMIT_ENTRY 4 ++ ++#define TXDESC_SIZE 32 ++ ++#define PACKET_OFFSET_SZ (8) ++#define TXDESC_OFFSET (TXDESC_SIZE + PACKET_OFFSET_SZ) ++ ++struct tx_desc { ++ /* DWORD 0 */ ++ __le32 txdw0; ++ __le32 txdw1; ++ __le32 txdw2; ++ __le32 txdw3; ++ __le32 txdw4; ++ __le32 txdw5; ++ __le32 txdw6; ++ __le32 txdw7; ++}; ++ ++union txdesc { ++ struct tx_desc txdesc; ++ unsigned int value[TXDESC_SIZE>>2]; ++}; ++ ++struct hw_xmit { ++ struct __queue *sta_queue; ++ int accnt; ++}; ++ ++/* reduce size */ ++struct pkt_attrib { ++ u8 type; ++ u8 subtype; ++ u8 bswenc; ++ u8 dhcp_pkt; ++ u16 ether_type; ++ u16 seqnum; ++ u16 pkt_hdrlen; /* the original 802.3 pkt header len */ ++ u16 hdrlen; /* the WLAN Header Len */ ++ u32 pktlen; /* the original 802.3 pkt raw_data len (not include ++ * ether_hdr data) */ ++ u32 last_txcmdsz; ++ u8 nr_frags; ++ u8 encrypt; /* when 0 indicate no encrypt. when non-zero, ++ * indicate the encrypt algorith */ ++ u8 iv_len; ++ u8 icv_len; ++ u8 iv[18]; ++ u8 icv[16]; ++ u8 priority; ++ u8 ack_policy; ++ u8 mac_id; ++ u8 vcs_mode; /* virtual carrier sense method */ ++ u8 dst[ETH_ALEN] __aligned(2); ++ u8 src[ETH_ALEN] __aligned(2); ++ u8 ta[ETH_ALEN] __aligned(2); ++ u8 ra[ETH_ALEN] __aligned(2); ++ u8 key_idx; ++ u8 qos_en; ++ u8 ht_en; ++ u8 raid;/* rate adpative id */ ++ u8 bwmode; ++ u8 ch_offset;/* PRIME_CHNL_OFFSET */ ++ u8 sgi;/* short GI */ ++ u8 ampdu_en;/* tx ampdu enable */ ++ u8 mdata;/* more data bit */ ++ u8 pctrl;/* per packet txdesc control enable */ ++ u8 triggered;/* for ap mode handling Power Saving sta */ ++ u8 qsel; ++ u8 eosp; ++ u8 rate; ++ u8 intel_proxim; ++ u8 retry_ctrl; ++ struct sta_info *psta; ++}; ++ ++#define WLANHDR_OFFSET 64 ++ ++#define NULL_FRAMETAG (0x0) ++#define DATA_FRAMETAG 0x01 ++#define L2_FRAMETAG 0x02 ++#define MGNT_FRAMETAG 0x03 ++#define AMSDU_FRAMETAG 0x04 ++ ++#define EII_FRAMETAG 0x05 ++#define IEEE8023_FRAMETAG 0x06 ++ ++#define MP_FRAMETAG 0x07 ++ ++#define TXAGG_FRAMETAG 0x08 ++ ++struct submit_ctx { ++ u32 submit_time; /* */ ++ u32 timeout_ms; /* <0: not synchronous, 0: wait forever, >0: up to ms waiting */ ++ int status; /* status for operation */ ++ struct completion done; ++}; ++ ++enum { ++ RTW_SCTX_SUBMITTED = -1, ++ RTW_SCTX_DONE_SUCCESS = 0, ++ RTW_SCTX_DONE_UNKNOWN, ++ RTW_SCTX_DONE_TIMEOUT, ++ RTW_SCTX_DONE_BUF_ALLOC, ++ RTW_SCTX_DONE_BUF_FREE, ++ RTW_SCTX_DONE_WRITE_PORT_ERR, ++ RTW_SCTX_DONE_TX_DESC_NA, ++ RTW_SCTX_DONE_TX_DENY, ++ RTW_SCTX_DONE_CCX_PKT_FAIL, ++ RTW_SCTX_DONE_DRV_STOP, ++ RTW_SCTX_DONE_DEV_REMOVE, ++}; ++ ++void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms); ++int rtw_sctx_wait(struct submit_ctx *sctx); ++void rtw_sctx_done_err(struct submit_ctx **sctx, int status); ++void rtw_sctx_done(struct submit_ctx **sctx); ++ ++struct xmit_buf { ++ struct list_head list; ++ struct adapter *padapter; ++ u8 *pallocated_buf; ++ u8 *pbuf; ++ void *priv_data; ++ u16 ext_tag; /* 0: Normal xmitbuf, 1: extension xmitbuf. */ ++ u16 flags; ++ u32 alloc_sz; ++ u32 len; ++ struct submit_ctx *sctx; ++ u32 ff_hwaddr; ++ struct urb *pxmit_urb[8]; ++ dma_addr_t dma_transfer_addr; /* (in) dma addr for transfer_buffer */ ++ u8 bpending[8]; ++ int last[8]; ++}; ++ ++struct xmit_frame { ++ struct list_head list; ++ struct pkt_attrib attrib; ++ struct sk_buff *pkt; ++ int frame_tag; ++ struct adapter *padapter; ++ u8 *buf_addr; ++ struct xmit_buf *pxmitbuf; ++ ++ u8 agg_num; ++ s8 pkt_offset; ++ u8 ack_report; ++}; ++ ++struct tx_servq { ++ struct list_head tx_pending; ++ struct __queue sta_pending; ++ int qcnt; ++}; ++ ++struct sta_xmit_priv { ++ spinlock_t lock; ++ int option; ++ int apsd_setting; /* When bit mask is on, the associated edca ++ * queue supports APSD. */ ++ struct tx_servq be_q; /* priority == 0,3 */ ++ struct tx_servq bk_q; /* priority == 1,2 */ ++ struct tx_servq vi_q; /* priority == 4,5 */ ++ struct tx_servq vo_q; /* priority == 6,7 */ ++ struct list_head legacy_dz; ++ struct list_head apsd; ++ u16 txseq_tid[16]; ++}; ++ ++struct hw_txqueue { ++ volatile int head; ++ volatile int tail; ++ volatile int free_sz; /* in units of 64 bytes */ ++ volatile int free_cmdsz; ++ volatile int txsz[8]; ++ uint ff_hwaddr; ++ uint cmd_hwaddr; ++ int ac_tag; ++}; ++ ++struct agg_pkt_info { ++ u16 offset; ++ u16 pkt_len; ++}; ++ ++struct xmit_priv { ++ spinlock_t lock; ++ struct semaphore xmit_sema; ++ struct semaphore terminate_xmitthread_sema; ++ struct __queue be_pending; ++ struct __queue bk_pending; ++ struct __queue vi_pending; ++ struct __queue vo_pending; ++ struct __queue bm_pending; ++ u8 *pallocated_frame_buf; ++ u8 *pxmit_frame_buf; ++ uint free_xmitframe_cnt; ++ struct __queue free_xmit_queue; ++ uint frag_len; ++ struct adapter *adapter; ++ u8 vcs_setting; ++ u8 vcs; ++ u8 vcs_type; ++ u64 tx_bytes; ++ u64 tx_pkts; ++ u64 tx_drop; ++ u64 last_tx_bytes; ++ u64 last_tx_pkts; ++ struct hw_xmit *hwxmits; ++ u8 hwxmit_entry; ++ u8 wmm_para_seq[4];/* sequence for wmm ac parameter strength ++ * from large to small. it's value is 0->vo, ++ * 1->vi, 2->be, 3->bk. */ ++ struct semaphore tx_retevt;/* all tx return event; */ ++ u8 txirp_cnt;/* */ ++ struct tasklet_struct xmit_tasklet; ++ /* per AC pending irp */ ++ int beq_cnt; ++ int bkq_cnt; ++ int viq_cnt; ++ int voq_cnt; ++ struct __queue free_xmitbuf_queue; ++ struct __queue pending_xmitbuf_queue; ++ u8 *pallocated_xmitbuf; ++ u8 *pxmitbuf; ++ uint free_xmitbuf_cnt; ++ struct __queue free_xmit_extbuf_queue; ++ u8 *pallocated_xmit_extbuf; ++ u8 *pxmit_extbuf; ++ uint free_xmit_extbuf_cnt; ++ u16 nqos_ssn; ++ int ack_tx; ++ struct mutex ack_tx_mutex; ++ struct submit_ctx ack_tx_ops; ++}; ++ ++struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv); ++s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, ++ struct xmit_buf *pxmitbuf); ++struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv); ++s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, ++ struct xmit_buf *pxmitbuf); ++void rtw_count_tx_stats(struct adapter *padapter, ++ struct xmit_frame *pxmitframe, int sz); ++void rtw_update_protection(struct adapter *padapter, u8 *ie, uint ie_len); ++s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, ++ struct pkt_attrib *pattrib); ++s32 rtw_put_snap(u8 *data, u16 h_proto); ++ ++struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv); ++s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, ++ struct xmit_frame *pxmitframe); ++void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, ++ struct __queue *pframequeue); ++struct tx_servq *rtw_get_sta_pending(struct adapter *padapter, ++ struct sta_info *psta, int up, u8 *ac); ++s32 rtw_xmitframe_enqueue(struct adapter *padapter, ++ struct xmit_frame *pxmitframe); ++struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, ++ struct hw_xmit *phwxmit_i, int entry); ++ ++s32 rtw_xmit_classifier(struct adapter *padapter, ++ struct xmit_frame *pxmitframe); ++u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib); ++#define rtw_wlan_pkt_size(f) rtw_calculate_wlan_pkt_size_by_attribue(&f->attrib) ++s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, ++ struct xmit_frame *pxmitframe); ++s32 _rtw_init_hw_txqueue(struct hw_txqueue *phw_txqueue, u8 ac_tag); ++void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv); ++s32 rtw_txframes_pending(struct adapter *padapter); ++s32 rtw_txframes_sta_ac_pending(struct adapter *padapter, ++ struct pkt_attrib *pattrib); ++void rtw_init_hwxmits(struct hw_xmit *phwxmit, int entry); ++s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter); ++void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv); ++void rtw_alloc_hwxmits(struct adapter *padapter); ++void rtw_free_hwxmits(struct adapter *padapter); ++s32 rtw_xmit(struct adapter *padapter, struct sk_buff **pkt); ++ ++#if defined(CONFIG_88EU_AP_MODE) ++int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_frame *pxmitframe); ++void stop_sta_xmit(struct adapter *padapter, struct sta_info *psta); ++void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta); ++void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *psta); ++#endif ++ ++u8 qos_acm(u8 acm_mask, u8 priority); ++u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe); ++int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms); ++void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status); ++ ++/* include after declaring struct xmit_buf, in order to avoid warning */ ++#include "xmit_osdep.h" ++ ++#endif /* _RTL871X_XMIT_H_ */ +diff --git a/drivers/staging/r8188eu/include/sta_info.h b/drivers/staging/r8188eu/include/sta_info.h +new file mode 100644 +index 000000000000..8ff99fc6381d +--- /dev/null ++++ b/drivers/staging/r8188eu/include/sta_info.h +@@ -0,0 +1,368 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __STA_INFO_H_ ++#define __STA_INFO_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "wifi.h" ++ ++#define IBSS_START_MAC_ID 2 ++#define NUM_STA 32 ++#define NUM_ACL 16 ++ ++/* if mode ==0, then the sta is allowed once the addr is hit. */ ++/* if mode ==1, then the sta is rejected once the addr is non-hit. */ ++struct rtw_wlan_acl_node { ++ struct list_head list; ++ u8 addr[ETH_ALEN]; ++ u8 valid; ++}; ++ ++/* mode=0, disable */ ++/* mode=1, accept unless in deny list */ ++/* mode=2, deny unless in accept list */ ++struct wlan_acl_pool { ++ int mode; ++ int num; ++ struct rtw_wlan_acl_node aclnode[NUM_ACL]; ++ struct __queue acl_node_q; ++}; ++ ++struct rssi_sta { ++ s32 UndecoratedSmoothedPWDB; ++ s32 UndecoratedSmoothedCCK; ++ s32 UndecoratedSmoothedOFDM; ++ u64 PacketMap; ++ u8 ValidBit; ++}; ++ ++struct stainfo_stats { ++ u64 rx_mgnt_pkts; ++ u64 rx_beacon_pkts; ++ u64 rx_probereq_pkts; ++ u64 rx_probersp_pkts; ++ u64 rx_probersp_bm_pkts; ++ u64 rx_probersp_uo_pkts; ++ u64 rx_ctrl_pkts; ++ u64 rx_data_pkts; ++ ++ u64 last_rx_mgnt_pkts; ++ u64 last_rx_beacon_pkts; ++ u64 last_rx_probereq_pkts; ++ u64 last_rx_probersp_pkts; ++ u64 last_rx_probersp_bm_pkts; ++ u64 last_rx_probersp_uo_pkts; ++ u64 last_rx_ctrl_pkts; ++ u64 last_rx_data_pkts; ++ u64 rx_bytes; ++ u64 rx_drops; ++ u64 tx_pkts; ++ u64 tx_bytes; ++ u64 tx_drops; ++}; ++ ++struct sta_info { ++ spinlock_t lock; ++ struct list_head list; /* free_sta_queue */ ++ struct list_head hash_list; /* sta_hash */ ++ ++ struct sta_xmit_priv sta_xmitpriv; ++ struct sta_recv_priv sta_recvpriv; ++ ++ struct __queue sleep_q; ++ unsigned int sleepq_len; ++ ++ uint state; ++ uint aid; ++ uint mac_id; ++ uint qos_option; ++ u8 hwaddr[ETH_ALEN]; ++ ++ uint ieee8021x_blocked; /* 0: allowed, 1:blocked */ ++ uint dot118021XPrivacy; /* aes, tkip... */ ++ union Keytype dot11tkiptxmickey; ++ union Keytype dot11tkiprxmickey; ++ union Keytype dot118021x_UncstKey; ++ union pn48 dot11txpn; /* PN48 used for Unicast xmit. */ ++ union pn48 dot11rxpn; /* PN48 used for Unicast recv. */ ++ u8 bssrateset[16]; ++ u32 bssratelen; ++ s32 rssi; ++ s32 signal_quality; ++ ++ u8 cts2self; ++ u8 rtsen; ++ ++ u8 raid; ++ u8 init_rate; ++ u32 ra_mask; ++ u8 wireless_mode; /* NETWORK_TYPE */ ++ struct stainfo_stats sta_stats; ++ ++ /* for A-MPDU TX, ADDBA timeout check */ ++ struct timer_list addba_retry_timer; ++ ++ /* for A-MPDU Rx reordering buffer control */ ++ struct recv_reorder_ctrl recvreorder_ctrl[16]; ++ ++ /* for A-MPDU Tx */ ++ /* unsigned char ampdu_txen_bitmap; */ ++ u16 BA_starting_seqctrl[16]; ++ ++ struct ht_priv htpriv; ++ ++ /* Notes: */ ++ /* STA_Mode: */ ++ /* curr_network(mlme_priv/security_priv/qos/ht) + ++ * sta_info: (STA & AP) CAP/INFO */ ++ /* scan_q: AP CAP/INFO */ ++ ++ /* AP_Mode: */ ++ /* curr_network(mlme_priv/security_priv/qos/ht) : AP CAP/INFO */ ++ /* sta_info: (AP & STA) CAP/INFO */ ++ ++ struct list_head asoc_list; ++#ifdef CONFIG_88EU_AP_MODE ++ struct list_head auth_list; ++ ++ unsigned int expire_to; ++ unsigned int auth_seq; ++ unsigned int authalg; ++ unsigned char chg_txt[128]; ++ ++ u16 capability; ++ int flags; ++ ++ int dot8021xalg;/* 0:disable, 1:psk, 2:802.1x */ ++ int wpa_psk;/* 0:disable, bit(0): WPA, bit(1):WPA2 */ ++ int wpa_group_cipher; ++ int wpa2_group_cipher; ++ int wpa_pairwise_cipher; ++ int wpa2_pairwise_cipher; ++ ++ u8 bpairwise_key_installed; ++ ++ u8 wpa_ie[32]; ++ ++ u8 nonerp_set; ++ u8 no_short_slot_time_set; ++ u8 no_short_preamble_set; ++ u8 no_ht_gf_set; ++ u8 no_ht_set; ++ u8 ht_20mhz_set; ++ ++ unsigned int tx_ra_bitmap; ++ u8 qos_info; ++ ++ u8 max_sp_len; ++ u8 uapsd_bk;/* BIT(0): Delivery enabled, BIT(1): Trigger enabled */ ++ u8 uapsd_be; ++ u8 uapsd_vi; ++ u8 uapsd_vo; ++ ++ u8 has_legacy_ac; ++ unsigned int sleepq_ac_len; ++#endif /* CONFIG_88EU_AP_MODE */ ++ ++#ifdef CONFIG_88EU_P2P ++ /* p2p priv data */ ++ u8 is_p2p_device; ++ u8 p2p_status_code; ++ ++ /* p2p client info */ ++ u8 dev_addr[ETH_ALEN]; ++ u8 dev_cap; ++ u16 config_methods; ++ u8 primary_dev_type[8]; ++ u8 num_of_secdev_type; ++ u8 secdev_types_list[32];/* 32/8 == 4; */ ++ u16 dev_name_len; ++ u8 dev_name[32]; ++#endif /* CONFIG_88EU_P2P */ ++ u8 under_exist_checking; ++ u8 keep_alive_trycnt; ++ ++ /* for DM */ ++ struct rssi_sta rssi_stat; ++ ++ /* ================ODM Relative Info======================= */ ++ /* Please be careful, don't declare too much structure here. ++ * It will cost memory * STA support num. */ ++ /* 2011/10/20 MH Add for ODM STA info. */ ++ /* Driver Write */ ++ u8 bValid; /* record the sta status link or not? */ ++ u8 IOTPeer; /* Enum value. HT_IOT_PEER_E */ ++ u8 rssi_level; /* for Refresh RA mask */ ++ /* ODM Write */ ++ /* 1 PHY_STATUS_INFO */ ++ u8 RSSI_Path[4]; /* */ ++ u8 RSSI_Ave; ++ u8 RXEVM[4]; ++ u8 RXSNR[4]; ++ ++ /* ================ODM Relative Info======================= */ ++ /* */ ++ ++ /* To store the sequence number of received management frame */ ++ u16 RxMgmtFrameSeqNum; ++}; ++ ++#define sta_rx_pkts(sta) \ ++ (sta->sta_stats.rx_mgnt_pkts \ ++ + sta->sta_stats.rx_ctrl_pkts \ ++ + sta->sta_stats.rx_data_pkts) ++ ++#define sta_last_rx_pkts(sta) \ ++ (sta->sta_stats.last_rx_mgnt_pkts \ ++ + sta->sta_stats.last_rx_ctrl_pkts \ ++ + sta->sta_stats.last_rx_data_pkts) ++ ++#define sta_rx_data_pkts(sta) \ ++ (sta->sta_stats.rx_data_pkts) ++ ++#define sta_last_rx_data_pkts(sta) \ ++ (sta->sta_stats.last_rx_data_pkts) ++ ++#define sta_rx_mgnt_pkts(sta) \ ++ (sta->sta_stats.rx_mgnt_pkts) ++ ++#define sta_last_rx_mgnt_pkts(sta) \ ++ (sta->sta_stats.last_rx_mgnt_pkts) ++ ++#define sta_rx_beacon_pkts(sta) \ ++ (sta->sta_stats.rx_beacon_pkts) ++ ++#define sta_last_rx_beacon_pkts(sta) \ ++ (sta->sta_stats.last_rx_beacon_pkts) ++ ++#define sta_rx_probereq_pkts(sta) \ ++ (sta->sta_stats.rx_probereq_pkts) ++ ++#define sta_last_rx_probereq_pkts(sta) \ ++ (sta->sta_stats.last_rx_probereq_pkts) ++ ++#define sta_rx_probersp_pkts(sta) \ ++ (sta->sta_stats.rx_probersp_pkts) ++ ++#define sta_last_rx_probersp_pkts(sta) \ ++ (sta->sta_stats.last_rx_probersp_pkts) ++ ++#define sta_rx_probersp_bm_pkts(sta) \ ++ (sta->sta_stats.rx_probersp_bm_pkts) ++ ++#define sta_last_rx_probersp_bm_pkts(sta) \ ++ (sta->sta_stats.last_rx_probersp_bm_pkts) ++ ++#define sta_rx_probersp_uo_pkts(sta) \ ++ (sta->sta_stats.rx_probersp_uo_pkts) ++ ++#define sta_last_rx_probersp_uo_pkts(sta) \ ++ (sta->sta_stats.last_rx_probersp_uo_pkts) ++ ++#define sta_update_last_rx_pkts(sta) \ ++do { \ ++ sta->sta_stats.last_rx_mgnt_pkts = sta->sta_stats.rx_mgnt_pkts; \ ++ sta->sta_stats.last_rx_beacon_pkts = sta->sta_stats.rx_beacon_pkts; \ ++ sta->sta_stats.last_rx_probereq_pkts = sta->sta_stats.rx_probereq_pkts; \ ++ sta->sta_stats.last_rx_probersp_pkts = sta->sta_stats.rx_probersp_pkts; \ ++ sta->sta_stats.last_rx_probersp_bm_pkts = sta->sta_stats.rx_probersp_bm_pkts; \ ++ sta->sta_stats.last_rx_probersp_uo_pkts = sta->sta_stats.rx_probersp_uo_pkts; \ ++ sta->sta_stats.last_rx_ctrl_pkts = sta->sta_stats.rx_ctrl_pkts; \ ++ sta->sta_stats.last_rx_data_pkts = sta->sta_stats.rx_data_pkts; \ ++} while (0) ++ ++#define STA_RX_PKTS_ARG(sta) \ ++ sta->sta_stats.rx_mgnt_pkts \ ++ , sta->sta_stats.rx_ctrl_pkts \ ++ , sta->sta_stats.rx_data_pkts ++ ++#define STA_LAST_RX_PKTS_ARG(sta) \ ++ sta->sta_stats.last_rx_mgnt_pkts \ ++ , sta->sta_stats.last_rx_ctrl_pkts \ ++ , sta->sta_stats.last_rx_data_pkts ++ ++#define STA_RX_PKTS_DIFF_ARG(sta) \ ++ sta->sta_stats.rx_mgnt_pkts - sta->sta_stats.last_rx_mgnt_pkts \ ++ , sta->sta_stats.rx_ctrl_pkts - sta->sta_stats.last_rx_ctrl_pkts \ ++ , sta->sta_stats.rx_data_pkts - sta->sta_stats.last_rx_data_pkts ++ ++#define STA_PKTS_FMT "(m:%llu, c:%llu, d:%llu)" ++ ++struct sta_priv { ++ u8 *pallocated_stainfo_buf; ++ u8 *pstainfo_buf; ++ struct __queue free_sta_queue; ++ ++ spinlock_t sta_hash_lock; ++ struct list_head sta_hash[NUM_STA]; ++ int asoc_sta_count; ++ struct __queue sleep_q; ++ struct __queue wakeup_q; ++ ++ struct adapter *padapter; ++ ++ spinlock_t asoc_list_lock; ++ struct list_head asoc_list; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ struct list_head auth_list; ++ spinlock_t auth_list_lock; ++ u8 asoc_list_cnt; ++ u8 auth_list_cnt; ++ ++ unsigned int auth_to; /* sec, time to expire in authenticating. */ ++ unsigned int assoc_to; /* sec, time to expire before associating. */ ++ unsigned int expire_to; /* sec , time to expire after associated. */ ++ ++ /* pointers to STA info; based on allocated AID or NULL if AID free ++ * AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1 ++ * and so on ++ */ ++ struct sta_info *sta_aid[NUM_STA]; ++ ++ u16 sta_dz_bitmap;/* only support 15 stations, station aid bitmap ++ * for sleeping sta. */ ++ u16 tim_bitmap; /* only support 15 stations, aid=0~15 mapping ++ * bit0~bit15 */ ++ ++ u16 max_num_sta; ++ ++ struct wlan_acl_pool acl_list; ++#endif ++ ++}; ++ ++static inline u32 wifi_mac_hash(u8 *mac) ++{ ++ u32 x; ++ ++ x = mac[0]; ++ x = (x << 2) ^ mac[1]; ++ x = (x << 2) ^ mac[2]; ++ x = (x << 2) ^ mac[3]; ++ x = (x << 2) ^ mac[4]; ++ x = (x << 2) ^ mac[5]; ++ ++ x ^= x >> 8; ++ x = x & (NUM_STA - 1); ++ return x; ++} ++ ++extern u32 _rtw_init_sta_priv(struct sta_priv *pstapriv); ++extern u32 _rtw_free_sta_priv(struct sta_priv *pstapriv); ++ ++#define stainfo_offset_valid(offset) (offset < NUM_STA && offset >= 0) ++int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta); ++struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int off); ++ ++extern struct sta_info *rtw_alloc_stainfo(struct sta_priv *stapriv, u8 *hwaddr); ++extern u32 rtw_free_stainfo(struct adapter *adapt, struct sta_info *psta); ++extern void rtw_free_all_stainfo(struct adapter *adapt); ++extern struct sta_info *rtw_get_stainfo(struct sta_priv *stapriv, u8 *hwaddr); ++extern u32 rtw_init_bcmc_stainfo(struct adapter *adapt); ++extern struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter); ++extern u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr); ++ ++#endif /* _STA_INFO_H_ */ +diff --git a/drivers/staging/r8188eu/include/usb_ops.h b/drivers/staging/r8188eu/include/usb_ops.h +new file mode 100644 +index 000000000000..c53cc54b6b87 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/usb_ops.h +@@ -0,0 +1,72 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __USB_OPS_H_ ++#define __USB_OPS_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "osdep_intf.h" ++ ++#define REALTEK_USB_VENQT_READ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE) ++#define REALTEK_USB_VENQT_WRITE (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) ++#define REALTEK_USB_VENQT_CMD_REQ 0x05 ++#define REALTEK_USB_VENQT_CMD_IDX 0x00 ++ ++#define ALIGNMENT_UNIT 16 ++#define MAX_VENDOR_REQ_CMD_SIZE 254 /* 8188cu SIE Support */ ++#define MAX_USB_IO_CTL_SIZE (MAX_VENDOR_REQ_CMD_SIZE + ALIGNMENT_UNIT) ++ ++#include "usb_ops_linux.h" ++ ++void rtl8188eu_set_hw_type(struct adapter *padapter); ++#define hal_set_hw_type rtl8188eu_set_hw_type ++void rtl8188eu_set_intf_ops(struct _io_ops *pops); ++#define usb_set_intf_ops rtl8188eu_set_intf_ops ++ ++/* ++ * Increase and check if the continual_urb_error of this @param dvobjprivei ++ * is larger than MAX_CONTINUAL_URB_ERR ++ * @return true: ++ * @return false: ++ */ ++static inline int rtw_inc_and_chk_continual_urb_error(struct dvobj_priv *dvobj) ++{ ++ int ret = false; ++ int value; ++ value = atomic_inc_return(&dvobj->continual_urb_error); ++ if (value > MAX_CONTINUAL_URB_ERR) { ++ DBG_88E("[dvobj:%p][ERROR] continual_urb_error:%d > %d\n", ++ dvobj, value, MAX_CONTINUAL_URB_ERR); ++ ret = true; ++ } ++ return ret; ++} ++ ++/* ++* Set the continual_urb_error of this @param dvobjprive to 0 ++*/ ++static inline void rtw_reset_continual_urb_error(struct dvobj_priv *dvobj) ++{ ++ atomic_set(&dvobj->continual_urb_error, 0); ++} ++ ++#define USB_HIGH_SPEED_BULK_SIZE 512 ++#define USB_FULL_SPEED_BULK_SIZE 64 ++ ++static inline u8 rtw_usb_bulk_size_boundary(struct adapter *padapter, ++ int buf_len) ++{ ++ u8 rst = true; ++ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); ++ ++ if (pdvobjpriv->ishighspeed) ++ rst = (0 == (buf_len) % USB_HIGH_SPEED_BULK_SIZE) ? ++ true : false; ++ else ++ rst = (0 == (buf_len) % USB_FULL_SPEED_BULK_SIZE) ? ++ true : false; ++ return rst; ++} ++ ++#endif /* __USB_OPS_H_ */ +diff --git a/drivers/staging/r8188eu/include/usb_ops_linux.h b/drivers/staging/r8188eu/include/usb_ops_linux.h +new file mode 100644 +index 000000000000..c357a3b1560e +--- /dev/null ++++ b/drivers/staging/r8188eu/include/usb_ops_linux.h +@@ -0,0 +1,39 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __USB_OPS_LINUX_H__ ++#define __USB_OPS_LINUX_H__ ++ ++#define VENDOR_CMD_MAX_DATA_LEN 254 ++ ++#define RTW_USB_CONTROL_MSG_TIMEOUT_TEST 10/* ms */ ++#define RTW_USB_CONTROL_MSG_TIMEOUT 500/* ms */ ++ ++#define MAX_USBCTRL_VENDORREQ_TIMES 10 ++ ++#define RTW_USB_BULKOUT_TIME 5000/* ms */ ++ ++#define _usbctrl_vendorreq_async_callback(urb, regs) \ ++ _usbctrl_vendorreq_async_callback(urb) ++#define usb_bulkout_zero_complete(purb, regs) \ ++ usb_bulkout_zero_complete(purb) ++#define usb_write_mem_complete(purb, regs) \ ++ usb_write_mem_complete(purb) ++#define usb_write_port_complete(purb, regs) \ ++ usb_write_port_complete(purb) ++#define usb_read_port_complete(purb, regs) \ ++ usb_read_port_complete(purb) ++#define usb_read_interrupt_complete(purb, regs) \ ++ usb_read_interrupt_complete(purb) ++ ++unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr); ++ ++void usb_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem); ++void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem); ++ ++void usb_read_port_cancel(struct intf_hdl *pintfhdl); ++ ++u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem); ++void usb_write_port_cancel(struct intf_hdl *pintfhdl); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/usb_osintf.h b/drivers/staging/r8188eu/include/usb_osintf.h +new file mode 100644 +index 000000000000..d1a1f739309c +--- /dev/null ++++ b/drivers/staging/r8188eu/include/usb_osintf.h +@@ -0,0 +1,29 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __USB_OSINTF_H ++#define __USB_OSINTF_H ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++#include "usb_vendor_req.h" ++ ++extern char *rtw_initmac; ++extern int rtw_mc2u_disable; ++ ++#define USBD_HALTED(Status) ((u32)(Status) >> 30 == 3) ++ ++u8 usbvendorrequest(struct dvobj_priv *pdvobjpriv, enum bt_usb_request brequest, ++ enum rt_usb_wvalue wvalue, u8 windex, void *data, ++ u8 datalen, u8 isdirectionin); ++int pm_netdev_open(struct net_device *pnetdev, u8 bnormal); ++void netdev_br_init(struct net_device *netdev); ++void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb); ++void *scdb_findEntry(struct adapter *priv, unsigned char *macAddr, ++ unsigned char *ipAddr); ++void nat25_db_expire(struct adapter *priv); ++int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method); ++ ++int rtw_resume_process(struct adapter *padapter); ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/usb_vendor_req.h b/drivers/staging/r8188eu/include/usb_vendor_req.h +new file mode 100644 +index 000000000000..7337b1b7419f +--- /dev/null ++++ b/drivers/staging/r8188eu/include/usb_vendor_req.h +@@ -0,0 +1,35 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef _USB_VENDOR_REQUEST_H_ ++#define _USB_VENDOR_REQUEST_H_ ++ ++/* 4 Set/Get Register related wIndex/Data */ ++#define RT_USB_RESET_MASK_OFF 0 ++#define RT_USB_RESET_MASK_ON 1 ++#define RT_USB_SLEEP_MASK_OFF 0 ++#define RT_USB_SLEEP_MASK_ON 1 ++#define RT_USB_LDO_ON 1 ++#define RT_USB_LDO_OFF 0 ++ ++/* 4 Set/Get SYSCLK related wValue or Data */ ++#define RT_USB_SYSCLK_32KHZ 0 ++#define RT_USB_SYSCLK_40MHZ 1 ++#define RT_USB_SYSCLK_60MHZ 2 ++ ++enum bt_usb_request { ++ RT_USB_SET_REGISTER = 1, ++ RT_USB_SET_SYSCLK = 2, ++ RT_USB_GET_SYSCLK = 3, ++ RT_USB_GET_REGISTER = 4 ++}; ++ ++enum rt_usb_wvalue { ++ RT_USB_RESET_MASK = 1, ++ RT_USB_SLEEP_MASK = 2, ++ RT_USB_USB_HRCPWM = 3, ++ RT_USB_LDO = 4, ++ RT_USB_BOOT_TYPE = 5 ++}; ++ ++#endif +diff --git a/drivers/staging/r8188eu/include/wifi.h b/drivers/staging/r8188eu/include/wifi.h +new file mode 100644 +index 000000000000..0b3fd94cea18 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/wifi.h +@@ -0,0 +1,1029 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#ifndef _WIFI_H_ ++#define _WIFI_H_ ++ ++#include ++ ++#ifdef BIT ++/* error "BIT define occurred earlier elsewhere!\n" */ ++#undef BIT ++#endif ++#define BIT(x) (1 << (x)) ++ ++#define WLAN_ETHHDR_LEN 14 ++#define WLAN_ETHADDR_LEN 6 ++#define WLAN_IEEE_OUI_LEN 3 ++#define WLAN_ADDR_LEN 6 ++#define WLAN_CRC_LEN 4 ++#define WLAN_BSSID_LEN 6 ++#define WLAN_BSS_TS_LEN 8 ++#define WLAN_HDR_A3_LEN 24 ++#define WLAN_HDR_A4_LEN 30 ++#define WLAN_HDR_A3_QOS_LEN 26 ++#define WLAN_HDR_A4_QOS_LEN 32 ++#define WLAN_SSID_MAXLEN 32 ++#define WLAN_DATA_MAXLEN 2312 ++ ++#define WLAN_A3_PN_OFFSET 24 ++#define WLAN_A4_PN_OFFSET 30 ++ ++#define WLAN_MIN_ETHFRM_LEN 60 ++#define WLAN_MAX_ETHFRM_LEN 1514 ++#define WLAN_ETHHDR_LEN 14 ++ ++#define P80211CAPTURE_VERSION 0x80211001 ++ ++/* This value is tested by WiFi 11n Test Plan 5.2.3. */ ++/* This test verifies the WLAN NIC can update the NAV through sending ++ * the CTS with large duration. */ ++#define WiFiNavUpperUs 30000 /* 30 ms */ ++ ++enum WIFI_FRAME_TYPE { ++ WIFI_MGT_TYPE = (0), ++ WIFI_CTRL_TYPE = (BIT(2)), ++ WIFI_DATA_TYPE = (BIT(3)), ++ WIFI_QOS_DATA_TYPE = (BIT(7)|BIT(3)), /* QoS Data */ ++}; ++ ++enum WIFI_FRAME_SUBTYPE { ++ /* below is for mgt frame */ ++ WIFI_ASSOCREQ = (0 | WIFI_MGT_TYPE), ++ WIFI_ASSOCRSP = (BIT(4) | WIFI_MGT_TYPE), ++ WIFI_REASSOCREQ = (BIT(5) | WIFI_MGT_TYPE), ++ WIFI_REASSOCRSP = (BIT(5) | BIT(4) | WIFI_MGT_TYPE), ++ WIFI_PROBEREQ = (BIT(6) | WIFI_MGT_TYPE), ++ WIFI_PROBERSP = (BIT(6) | BIT(4) | WIFI_MGT_TYPE), ++ WIFI_BEACON = (BIT(7) | WIFI_MGT_TYPE), ++ WIFI_ATIM = (BIT(7) | BIT(4) | WIFI_MGT_TYPE), ++ WIFI_DISASSOC = (BIT(7) | BIT(5) | WIFI_MGT_TYPE), ++ WIFI_AUTH = (BIT(7) | BIT(5) | BIT(4) | WIFI_MGT_TYPE), ++ WIFI_DEAUTH = (BIT(7) | BIT(6) | WIFI_MGT_TYPE), ++ WIFI_ACTION = (BIT(7) | BIT(6) | BIT(4) | WIFI_MGT_TYPE), ++ ++ /* below is for control frame */ ++ WIFI_PSPOLL = (BIT(7) | BIT(5) | WIFI_CTRL_TYPE), ++ WIFI_RTS = (BIT(7) | BIT(5) | BIT(4) | WIFI_CTRL_TYPE), ++ WIFI_CTS = (BIT(7) | BIT(6) | WIFI_CTRL_TYPE), ++ WIFI_ACK = (BIT(7) | BIT(6) | BIT(4) | WIFI_CTRL_TYPE), ++ WIFI_CFEND = (BIT(7) | BIT(6) | BIT(5) | WIFI_CTRL_TYPE), ++ WIFI_CFEND_CFACK = (BIT(7) | BIT(6) | BIT(5) | BIT(4) | ++ WIFI_CTRL_TYPE), ++ ++ /* below is for data frame */ ++ WIFI_DATA = (0 | WIFI_DATA_TYPE), ++ WIFI_DATA_CFACK = (BIT(4) | WIFI_DATA_TYPE), ++ WIFI_DATA_CFPOLL = (BIT(5) | WIFI_DATA_TYPE), ++ WIFI_DATA_CFACKPOLL = (BIT(5) | BIT(4) | WIFI_DATA_TYPE), ++ WIFI_DATA_NULL = (BIT(6) | WIFI_DATA_TYPE), ++ WIFI_CF_ACK = (BIT(6) | BIT(4) | WIFI_DATA_TYPE), ++ WIFI_CF_POLL = (BIT(6) | BIT(5) | WIFI_DATA_TYPE), ++ WIFI_CF_ACKPOLL = (BIT(6) | BIT(5) | BIT(4) | WIFI_DATA_TYPE), ++ WIFI_QOS_DATA_NULL = (BIT(6) | WIFI_QOS_DATA_TYPE), ++}; ++ ++enum WIFI_REASON_CODE { ++ _RSON_RESERVED_ = 0, ++ _RSON_UNSPECIFIED_ = 1, ++ _RSON_AUTH_NO_LONGER_VALID_ = 2, ++ _RSON_DEAUTH_STA_LEAVING_ = 3, ++ _RSON_INACTIVITY_ = 4, ++ _RSON_UNABLE_HANDLE_ = 5, ++ _RSON_CLS2_ = 6, ++ _RSON_CLS3_ = 7, ++ _RSON_DISAOC_STA_LEAVING_ = 8, ++ _RSON_ASOC_NOT_AUTH_ = 9, ++ ++ /* WPA reason */ ++ _RSON_INVALID_IE_ = 13, ++ _RSON_MIC_FAILURE_ = 14, ++ _RSON_4WAY_HNDSHK_TIMEOUT_ = 15, ++ _RSON_GROUP_KEY_UPDATE_TIMEOUT_ = 16, ++ _RSON_DIFF_IE_ = 17, ++ _RSON_MLTCST_CIPHER_NOT_VALID_ = 18, ++ _RSON_UNICST_CIPHER_NOT_VALID_ = 19, ++ _RSON_AKMP_NOT_VALID_ = 20, ++ _RSON_UNSUPPORT_RSNE_VER_ = 21, ++ _RSON_INVALID_RSNE_CAP_ = 22, ++ _RSON_IEEE_802DOT1X_AUTH_FAIL_ = 23, ++ ++ /* belowing are Realtek definition */ ++ _RSON_PMK_NOT_AVAILABLE_ = 24, ++ _RSON_TDLS_TEAR_TOOFAR_ = 25, ++ _RSON_TDLS_TEAR_UN_RSN_ = 26, ++}; ++ ++/* Reason codes (IEEE 802.11-2007, 7.3.1.7, Table 7-22) ++ ++#define WLAN_REASON_UNSPECIFIED 1 ++#define WLAN_REASON_PREV_AUTH_NOT_VALID 2 ++#define WLAN_REASON_DEAUTH_LEAVING 3 ++#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 ++#define WLAN_REASON_DISASSOC_AP_BUSY 5 ++#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 ++#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 ++#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 ++#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 */ ++/* IEEE 802.11h */ ++#define WLAN_REASON_PWR_CAPABILITY_NOT_VALID 10 ++#define WLAN_REASON_SUPPORTED_CHANNEL_NOT_VALID 11 ++ ++/* IEEE 802.11i ++#define WLAN_REASON_INVALID_IE 13 ++#define WLAN_REASON_MICHAEL_MIC_FAILURE 14 ++#define WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT 15 ++#define WLAN_REASON_GROUP_KEY_UPDATE_TIMEOUT 16 ++#define WLAN_REASON_IE_IN_4WAY_DIFFERS 17 ++#define WLAN_REASON_GROUP_CIPHER_NOT_VALID 18 ++#define WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID 19 ++#define WLAN_REASON_AKMP_NOT_VALID 20 ++#define WLAN_REASON_UNSUPPORTED_RSN_IE_VERSION 21 ++#define WLAN_REASON_INVALID_RSN_IE_CAPAB 22 ++#define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23 ++#define WLAN_REASON_CIPHER_SUITE_REJECTED 24 */ ++ ++enum WIFI_STATUS_CODE { ++ _STATS_SUCCESSFUL_ = 0, ++ _STATS_FAILURE_ = 1, ++ _STATS_CAP_FAIL_ = 10, ++ _STATS_NO_ASOC_ = 11, ++ _STATS_OTHER_ = 12, ++ _STATS_NO_SUPP_ALG_ = 13, ++ _STATS_OUT_OF_AUTH_SEQ_ = 14, ++ _STATS_CHALLENGE_FAIL_ = 15, ++ _STATS_AUTH_TIMEOUT_ = 16, ++ _STATS_UNABLE_HANDLE_STA_ = 17, ++ _STATS_RATE_FAIL_ = 18, ++}; ++ ++/* Status codes (IEEE 802.11-2007, 7.3.1.9, Table 7-23) ++#define WLAN_STATUS_SUCCESS 0 ++#define WLAN_STATUS_UNSPECIFIED_FAILURE 1 ++#define WLAN_STATUS_CAPS_UNSUPPORTED 10 ++#define WLAN_STATUS_REASSOC_NO_ASSOC 11 ++#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 ++#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 ++#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 ++#define WLAN_STATUS_CHALLENGE_FAIL 15 ++#define WLAN_STATUS_AUTH_TIMEOUT 16 ++#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 ++#define WLAN_STATUS_ASSOC_DENIED_RATES 18 */ ++ ++/* entended */ ++/* IEEE 802.11b */ ++#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 ++#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20 ++#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21 ++/* IEEE 802.11h */ ++#define WLAN_STATUS_SPEC_MGMT_REQUIRED 22 ++#define WLAN_STATUS_PWR_CAPABILITY_NOT_VALID 23 ++#define WLAN_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24 ++/* IEEE 802.11g */ ++#define WLAN_STATUS_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25 ++#define WLAN_STATUS_ASSOC_DENIED_NO_ER_PBCC 26 ++#define WLAN_STATUS_ASSOC_DENIED_NO_DSSS_OFDM 27 ++/* IEEE 802.11w */ ++#define WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY 30 ++#define WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31 ++/* IEEE 802.11i */ ++#define WLAN_STATUS_INVALID_IE 40 ++#define WLAN_STATUS_GROUP_CIPHER_NOT_VALID 41 ++#define WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID 42 ++#define WLAN_STATUS_AKMP_NOT_VALID 43 ++#define WLAN_STATUS_UNSUPPORTED_RSN_IE_VERSION 44 ++#define WLAN_STATUS_INVALID_RSN_IE_CAPAB 45 ++#define WLAN_STATUS_CIPHER_REJECTED_PER_POLICY 46 ++#define WLAN_STATUS_TS_NOT_CREATED 47 ++#define WLAN_STATUS_DIRECT_LINK_NOT_ALLOWED 48 ++#define WLAN_STATUS_DEST_STA_NOT_PRESENT 49 ++#define WLAN_STATUS_DEST_STA_NOT_QOS_STA 50 ++#define WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE 51 ++/* IEEE 802.11r */ ++#define WLAN_STATUS_INVALID_FT_ACTION_FRAME_COUNT 52 ++#define WLAN_STATUS_INVALID_PMKID 53 ++#define WLAN_STATUS_INVALID_MDIE 54 ++#define WLAN_STATUS_INVALID_FTIE 55 ++ ++enum WIFI_REG_DOMAIN { ++ DOMAIN_FCC = 1, ++ DOMAIN_IC = 2, ++ DOMAIN_ETSI = 3, ++ DOMAIN_SPA = 4, ++ DOMAIN_FRANCE = 5, ++ DOMAIN_MKK = 6, ++ DOMAIN_ISRAEL = 7, ++ DOMAIN_MKK1 = 8, ++ DOMAIN_MKK2 = 9, ++ DOMAIN_MKK3 = 10, ++ DOMAIN_MAX ++}; ++ ++#define _TO_DS_ BIT(8) ++#define _FROM_DS_ BIT(9) ++#define _MORE_FRAG_ BIT(10) ++#define _RETRY_ BIT(11) ++#define _PWRMGT_ BIT(12) ++#define _MORE_DATA_ BIT(13) ++#define _PRIVACY_ BIT(14) ++#define _ORDER_ BIT(15) ++ ++#define SetToDs(pbuf) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(_TO_DS_) ++ ++#define GetToDs(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_TO_DS_)) != 0) ++ ++#define ClearToDs(pbuf) \ ++ *(__le16 *)(pbuf) &= (~cpu_to_le16(_TO_DS_)) ++ ++#define SetFrDs(pbuf) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(_FROM_DS_) ++ ++#define GetFrDs(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_FROM_DS_)) != 0) ++ ++#define ClearFrDs(pbuf) \ ++ *(__le16 *)(pbuf) &= (~cpu_to_le16(_FROM_DS_)) ++ ++#define get_tofr_ds(pframe) ((GetToDs(pframe) << 1) | GetFrDs(pframe)) ++ ++#define SetMFrag(pbuf) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(_MORE_FRAG_) ++ ++#define GetMFrag(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_MORE_FRAG_)) != 0) ++ ++#define ClearMFrag(pbuf) \ ++ *(__le16 *)(pbuf) &= (~cpu_to_le16(_MORE_FRAG_)) ++ ++#define SetRetry(pbuf) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(_RETRY_) ++ ++#define GetRetry(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_RETRY_)) != 0) ++ ++#define ClearRetry(pbuf) \ ++ *(__le16 *)(pbuf) &= (~cpu_to_le16(_RETRY_)) ++ ++#define SetPwrMgt(pbuf) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(_PWRMGT_) ++ ++#define GetPwrMgt(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_PWRMGT_)) != 0) ++ ++#define ClearPwrMgt(pbuf) \ ++ *(__le16 *)(pbuf) &= (~cpu_to_le16(_PWRMGT_)) ++ ++#define SetMData(pbuf) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(_MORE_DATA_) ++ ++#define GetMData(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(_MORE_DATA_)) != 0) ++ ++#define ClearMData(pbuf) \ ++ *(__le16 *)(pbuf) &= (~cpu_to_le16(_MORE_DATA_)) ++ ++#define SetPrivacy(pbuf) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(_PRIVACY_) ++ ++#define GetPrivacy(pbuf) \ ++ (((*(__le16 *)(pbuf)) & cpu_to_le16(_PRIVACY_)) != 0) ++ ++#define ClearPrivacy(pbuf) \ ++ *(__le16 *)(pbuf) &= (~cpu_to_le16(_PRIVACY_)) ++ ++#define GetOrder(pbuf) \ ++ (((*(__le16 *)(pbuf)) & cpu_to_le16(_ORDER_)) != 0) ++ ++#define GetFrameType(pbuf) \ ++ (le16_to_cpu(*(__le16 *)(pbuf)) & (BIT(3) | BIT(2))) ++ ++#define SetFrameType(pbuf, type) \ ++ do { \ ++ *(unsigned short *)(pbuf) &= __constant_cpu_to_le16(~(BIT(3) | BIT(2))); \ ++ *(unsigned short *)(pbuf) |= __constant_cpu_to_le16(type); \ ++ } while (0) ++ ++#define GetFrameSubType(pbuf) (le16_to_cpu(*(__le16 *)(pbuf)) & (BIT(7) |\ ++ BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2))) ++ ++#define SetFrameSubType(pbuf, type) \ ++ do { \ ++ *(__le16 *)(pbuf) &= cpu_to_le16(~(BIT(7) | BIT(6) | \ ++ BIT(5) | BIT(4) | BIT(3) | BIT(2))); \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(type); \ ++ } while (0) ++ ++#define GetSequence(pbuf) \ ++ (le16_to_cpu(*(__le16 *)((size_t)(pbuf) + 22)) >> 4) ++ ++#define GetFragNum(pbuf) \ ++ (le16_to_cpu(*(__le16 *)((size_t)(pbuf) + 22)) & 0x0f) ++ ++#define GetTupleCache(pbuf) \ ++ (cpu_to_le16(*(unsigned short *)((size_t)(pbuf) + 22))) ++ ++#define SetFragNum(pbuf, num) \ ++ do { \ ++ *(unsigned short *)((size_t)(pbuf) + 22) = \ ++ ((*(unsigned short *)((size_t)(pbuf) + 22)) & \ ++ le16_to_cpu(~(0x000f))) | \ ++ cpu_to_le16(0x0f & (num)); \ ++ } while (0) ++ ++#define SetSeqNum(pbuf, num) \ ++ do { \ ++ *(__le16 *)((size_t)(pbuf) + 22) = \ ++ ((*(__le16 *)((size_t)(pbuf) + 22)) & cpu_to_le16((unsigned short)0x000f)) | \ ++ cpu_to_le16((unsigned short)(0xfff0 & (num << 4))); \ ++ } while (0) ++ ++#define SetDuration(pbuf, dur) \ ++ *(__le16 *)((size_t)(pbuf) + 2) = cpu_to_le16(0xffff & (dur)) ++ ++#define SetPriority(pbuf, tid) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16(tid & 0xf) ++ ++#define GetPriority(pbuf) ((le16_to_cpu(*(__le16 *)(pbuf))) & 0xf) ++ ++#define SetEOSP(pbuf, eosp) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16((eosp & 1) << 4) ++ ++#define SetAckpolicy(pbuf, ack) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16((ack & 3) << 5) ++ ++#define GetAckpolicy(pbuf) (((le16_to_cpu(*(__le16 *)pbuf)) >> 5) & 0x3) ++ ++#define GetAMsdu(pbuf) (((le16_to_cpu(*(__le16 *)pbuf)) >> 7) & 0x1) ++ ++#define SetAMsdu(pbuf, amsdu) \ ++ *(__le16 *)(pbuf) |= cpu_to_le16((amsdu & 1) << 7) ++ ++#define GetAid(pbuf) (le16_to_cpu(*(__le16 *)((size_t)(pbuf) + 2)) & 0x3fff) ++ ++#define GetTid(pbuf) (le16_to_cpu(*(__le16 *)((size_t)(pbuf) + \ ++ (((GetToDs(pbuf)<<1) | GetFrDs(pbuf)) == 3 ? \ ++ 30 : 24))) & 0x000f) ++ ++#define GetAddr1Ptr(pbuf) ((unsigned char *)((size_t)(pbuf) + 4)) ++ ++#define GetAddr2Ptr(pbuf) ((unsigned char *)((size_t)(pbuf) + 10)) ++ ++#define GetAddr3Ptr(pbuf) ((unsigned char *)((size_t)(pbuf) + 16)) ++ ++#define GetAddr4Ptr(pbuf) ((unsigned char *)((size_t)(pbuf) + 24)) ++ ++static inline int IS_MCAST(unsigned char *da) ++{ ++ if ((*da) & 0x01) ++ return true; ++ else ++ return false; ++} ++ ++static inline unsigned char *get_da(unsigned char *pframe) ++{ ++ unsigned char *da; ++ unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); ++ ++ switch (to_fr_ds) { ++ case 0x00: /* ToDs=0, FromDs=0 */ ++ da = GetAddr1Ptr(pframe); ++ break; ++ case 0x01: /* ToDs=0, FromDs=1 */ ++ da = GetAddr1Ptr(pframe); ++ break; ++ case 0x02: /* ToDs=1, FromDs=0 */ ++ da = GetAddr3Ptr(pframe); ++ break; ++ default: /* ToDs=1, FromDs=1 */ ++ da = GetAddr3Ptr(pframe); ++ break; ++ } ++ return da; ++} ++ ++static inline unsigned char *get_sa(unsigned char *pframe) ++{ ++ unsigned char *sa; ++ unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); ++ ++ switch (to_fr_ds) { ++ case 0x00: /* ToDs=0, FromDs=0 */ ++ sa = GetAddr2Ptr(pframe); ++ break; ++ case 0x01: /* ToDs=0, FromDs=1 */ ++ sa = GetAddr3Ptr(pframe); ++ break; ++ case 0x02: /* ToDs=1, FromDs=0 */ ++ sa = GetAddr2Ptr(pframe); ++ break; ++ default: /* ToDs=1, FromDs=1 */ ++ sa = GetAddr4Ptr(pframe); ++ break; ++ } ++ return sa; ++} ++ ++static inline unsigned char *get_hdr_bssid(unsigned char *pframe) ++{ ++ unsigned char *sa; ++ unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); ++ ++ switch (to_fr_ds) { ++ case 0x00: /* ToDs=0, FromDs=0 */ ++ sa = GetAddr3Ptr(pframe); ++ break; ++ case 0x01: /* ToDs=0, FromDs=1 */ ++ sa = GetAddr2Ptr(pframe); ++ break; ++ case 0x02: /* ToDs=1, FromDs=0 */ ++ sa = GetAddr1Ptr(pframe); ++ break; ++ case 0x03: /* ToDs=1, FromDs=1 */ ++ sa = GetAddr1Ptr(pframe); ++ break; ++ default: ++ sa = NULL; /* */ ++ break; ++ } ++ return sa; ++} ++ ++static inline int IsFrameTypeCtrl(unsigned char *pframe) ++{ ++ if (WIFI_CTRL_TYPE == GetFrameType(pframe)) ++ return true; ++ else ++ return false; ++} ++/*----------------------------------------------------------------------------- ++ Below is for the security related definition ++------------------------------------------------------------------------------*/ ++#define _RESERVED_FRAME_TYPE_ 0 ++#define _SKB_FRAME_TYPE_ 2 ++#define _PRE_ALLOCMEM_ 1 ++#define _PRE_ALLOCHDR_ 3 ++#define _PRE_ALLOCLLCHDR_ 4 ++#define _PRE_ALLOCICVHDR_ 5 ++#define _PRE_ALLOCMICHDR_ 6 ++ ++#define _SIFSTIME_ \ ++ (priv->pmib->dot11BssType.net_work_type = 10) ++#define _ACKCTSLNG_ 14 /* 14 bytes long, including crclng */ ++#define _CRCLNG_ 4 ++ ++#define _ASOCREQ_IE_OFFSET_ 4 /* excluding wlan_hdr */ ++#define _ASOCRSP_IE_OFFSET_ 6 ++#define _REASOCREQ_IE_OFFSET_ 10 ++#define _REASOCRSP_IE_OFFSET_ 6 ++#define _PROBEREQ_IE_OFFSET_ 0 ++#define _PROBERSP_IE_OFFSET_ 12 ++#define _AUTH_IE_OFFSET_ 6 ++#define _DEAUTH_IE_OFFSET_ 0 ++#define _BEACON_IE_OFFSET_ 12 ++#define _PUBLIC_ACTION_IE_OFFSET_ 8 ++ ++#define _FIXED_IE_LENGTH_ _BEACON_IE_OFFSET_ ++ ++#define _SSID_IE_ 0 ++#define _SUPPORTEDRATES_IE_ 1 ++#define _DSSET_IE_ 3 ++#define _TIM_IE_ 5 ++#define _IBSS_PARA_IE_ 6 ++#define _COUNTRY_IE_ 7 ++#define _CHLGETXT_IE_ 16 ++#define _SUPPORTED_CH_IE_ 36 ++#define _CH_SWTICH_ANNOUNCE_ 37 /* Secondary Channel Offset */ ++#define _RSN_IE_2_ 48 ++#define _SSN_IE_1_ 221 ++#define _ERPINFO_IE_ 42 ++#define _EXT_SUPPORTEDRATES_IE_ 50 ++ ++#define _HT_CAPABILITY_IE_ 45 ++#define _FTIE_ 55 ++#define _TIMEOUT_ITVL_IE_ 56 ++#define _SRC_IE_ 59 ++#define _HT_EXTRA_INFO_IE_ 61 ++#define _HT_ADD_INFO_IE_ 61 /* _HT_EXTRA_INFO_IE_ */ ++#define _WAPI_IE_ 68 ++ ++#define EID_BSSCoexistence 72 /* 20/40 BSS Coexistence */ ++#define EID_BSSIntolerantChlReport 73 ++#define _RIC_Descriptor_IE_ 75 ++ ++#define _LINK_ID_IE_ 101 ++#define _CH_SWITCH_TIMING_ 104 ++#define _PTI_BUFFER_STATUS_ 106 ++#define _EXT_CAP_IE_ 127 ++#define _VENDOR_SPECIFIC_IE_ 221 ++ ++#define _RESERVED47_ 47 ++ ++/* --------------------------------------------------------------------------- ++ Below is the fixed elements... ++-----------------------------------------------------------------------------*/ ++#define _AUTH_ALGM_NUM_ 2 ++#define _AUTH_SEQ_NUM_ 2 ++#define _BEACON_ITERVAL_ 2 ++#define _CAPABILITY_ 2 ++#define _CURRENT_APADDR_ 6 ++#define _LISTEN_INTERVAL_ 2 ++#define _RSON_CODE_ 2 ++#define _ASOC_ID_ 2 ++#define _STATUS_CODE_ 2 ++#define _TIMESTAMP_ 8 ++ ++#define AUTH_ODD_TO 0 ++#define AUTH_EVEN_TO 1 ++ ++#define WLAN_ETHCONV_ENCAP 1 ++#define WLAN_ETHCONV_RFC1042 2 ++#define WLAN_ETHCONV_8021h 3 ++ ++#define cap_ESS BIT(0) ++#define cap_IBSS BIT(1) ++#define cap_CFPollable BIT(2) ++#define cap_CFRequest BIT(3) ++#define cap_Privacy BIT(4) ++#define cap_ShortPremble BIT(5) ++#define cap_PBCC BIT(6) ++#define cap_ChAgility BIT(7) ++#define cap_SpecMgmt BIT(8) ++#define cap_QoSi BIT(9) ++#define cap_ShortSlot BIT(10) ++ ++/*----------------------------------------------------------------------------- ++ Below is the definition for 802.11i / 802.1x ++------------------------------------------------------------------------------*/ ++#define _IEEE8021X_MGT_ 1 /* WPA */ ++#define _IEEE8021X_PSK_ 2 /* WPA with pre-shared key */ ++ ++/* ++#define _NO_PRIVACY_ 0 ++#define _WEP_40_PRIVACY_ 1 ++#define _TKIP_PRIVACY_ 2 ++#define _WRAP_PRIVACY_ 3 ++#define _CCMP_PRIVACY_ 4 ++#define _WEP_104_PRIVACY_ 5 ++#define _WEP_WPA_MIXED_PRIVACY_ 6 WEP + WPA ++*/ ++ ++/*----------------------------------------------------------------------------- ++ Below is the definition for WMM ++------------------------------------------------------------------------------*/ ++#define _WMM_IE_Length_ 7 /* for WMM STA */ ++#define _WMM_Para_Element_Length_ 24 ++ ++/*----------------------------------------------------------------------------- ++ Below is the definition for 802.11n ++------------------------------------------------------------------------------*/ ++ ++#define SetOrderBit(pbuf) \ ++ do { \ ++ *(unsigned short *)(pbuf) |= cpu_to_le16(_ORDER_); \ ++ } while (0) ++ ++#define GetOrderBit(pbuf) \ ++ (((*(unsigned short *)(pbuf)) & le16_to_cpu(_ORDER_)) != 0) ++ ++/** ++ * struct rtw_ieee80211_bar - HT Block Ack Request ++ * ++ * This structure refers to "HT BlockAckReq" as ++ * described in 802.11n draft section 7.2.1.7.1 ++ */ ++struct rtw_ieee80211_bar { ++ __le16 frame_control; ++ __le16 duration; ++ unsigned char ra[ETH_ALEN]; ++ unsigned char ta[ETH_ALEN]; ++ __le16 control; ++ __le16 start_seq_num; ++} __packed; ++ ++/** ++ * struct ieee80211_ht_cap - HT additional information ++ * ++ * This structure refers to "HT information element" as ++ * described in 802.11n draft section 7.3.2.53 ++ */ ++struct ieee80211_ht_addt_info { ++ unsigned char control_chan; ++ unsigned char ht_param; ++ __le16 operation_mode; ++ __le16 stbc_param; ++ unsigned char basic_set[16]; ++} __packed; ++ ++struct HT_caps_element { ++ union { ++ struct { ++ __le16 HT_caps_info; ++ unsigned char AMPDU_para; ++ unsigned char MCS_rate[16]; ++ __le16 HT_ext_caps; ++ __le16 Beamforming_caps; ++ unsigned char ASEL_caps; ++ } HT_cap_element; ++ unsigned char HT_cap[26]; ++ } u; ++} __packed; ++ ++struct HT_info_element { ++ unsigned char primary_channel; ++ unsigned char infos[5]; ++ unsigned char MCS_rate[16]; ++} __packed; ++ ++struct AC_param { ++ unsigned char ACI_AIFSN; ++ unsigned char CW; ++ __le16 TXOP_limit; ++} __packed; ++ ++struct WMM_para_element { ++ unsigned char QoS_info; ++ unsigned char reserved; ++ struct AC_param ac_param[4]; ++} __packed; ++ ++struct ADDBA_request { ++ unsigned char action_code; ++ unsigned char dialog_token; ++ __le16 BA_para_set; ++ __le16 BA_timeout_value; ++ __le16 BA_starting_seqctrl; ++} __packed; ++ ++enum ht_cap_ampdu_factor { ++ MAX_AMPDU_FACTOR_8K = 0, ++ MAX_AMPDU_FACTOR_16K = 1, ++ MAX_AMPDU_FACTOR_32K = 2, ++ MAX_AMPDU_FACTOR_64K = 3, ++}; ++ ++/* Spatial Multiplexing Power Save Modes */ ++#define WLAN_HT_CAP_SM_PS_STATIC 0 ++#define WLAN_HT_CAP_SM_PS_DYNAMIC 1 ++#define WLAN_HT_CAP_SM_PS_INVALID 2 ++#define WLAN_HT_CAP_SM_PS_DISABLED 3 ++ ++#define OP_MODE_PURE 0 ++#define OP_MODE_MAY_BE_LEGACY_STAS 1 ++#define OP_MODE_20MHZ_HT_STA_ASSOCED 2 ++#define OP_MODE_MIXED 3 ++ ++#define HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK ((u8) BIT(0) | BIT(1)) ++#define HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE ((u8) BIT(0)) ++#define HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW ((u8) BIT(0) | BIT(1)) ++#define HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH ((u8) BIT(2)) ++#define HT_INFO_HT_PARAM_RIFS_MODE ((u8) BIT(3)) ++#define HT_INFO_HT_PARAM_CTRL_ACCESS_ONLY ((u8) BIT(4)) ++#define HT_INFO_HT_PARAM_SRV_INTERVAL_GRANULARITY ((u8) BIT(5)) ++ ++#define HT_INFO_OPERATION_MODE_OP_MODE_MASK \ ++ ((u16) (0x0001 | 0x0002)) ++#define HT_INFO_OPERATION_MODE_OP_MODE_OFFSET 0 ++#define HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT ((u8) BIT(2)) ++#define HT_INFO_OPERATION_MODE_TRANSMIT_BURST_LIMIT ((u8) BIT(3)) ++#define HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT ((u8) BIT(4)) ++ ++#define HT_INFO_STBC_PARAM_DUAL_BEACON ((u16) BIT(6)) ++#define HT_INFO_STBC_PARAM_DUAL_STBC_PROTECT ((u16) BIT(7)) ++#define HT_INFO_STBC_PARAM_SECONDARY_BC ((u16) BIT(8)) ++#define HT_INFO_STBC_PARAM_LSIG_TXOP_PROTECT_ALLOWED ((u16) BIT(9)) ++#define HT_INFO_STBC_PARAM_PCO_ACTIVE ((u16) BIT(10)) ++#define HT_INFO_STBC_PARAM_PCO_PHASE ((u16) BIT(11)) ++ ++/* ===============WPS Section=============== */ ++/* For WPSv1.0 */ ++#define WPSOUI 0x0050f204 ++/* WPS attribute ID */ ++#define WPS_ATTR_VER1 0x104A ++#define WPS_ATTR_SIMPLE_CONF_STATE 0x1044 ++#define WPS_ATTR_RESP_TYPE 0x103B ++#define WPS_ATTR_UUID_E 0x1047 ++#define WPS_ATTR_MANUFACTURER 0x1021 ++#define WPS_ATTR_MODEL_NAME 0x1023 ++#define WPS_ATTR_MODEL_NUMBER 0x1024 ++#define WPS_ATTR_SERIAL_NUMBER 0x1042 ++#define WPS_ATTR_PRIMARY_DEV_TYPE 0x1054 ++#define WPS_ATTR_SEC_DEV_TYPE_LIST 0x1055 ++#define WPS_ATTR_DEVICE_NAME 0x1011 ++#define WPS_ATTR_CONF_METHOD 0x1008 ++#define WPS_ATTR_RF_BANDS 0x103C ++#define WPS_ATTR_DEVICE_PWID 0x1012 ++#define WPS_ATTR_REQUEST_TYPE 0x103A ++#define WPS_ATTR_ASSOCIATION_STATE 0x1002 ++#define WPS_ATTR_CONFIG_ERROR 0x1009 ++#define WPS_ATTR_VENDOR_EXT 0x1049 ++#define WPS_ATTR_SELECTED_REGISTRAR 0x1041 ++ ++/* Value of WPS attribute "WPS_ATTR_DEVICE_NAME */ ++#define WPS_MAX_DEVICE_NAME_LEN 32 ++ ++/* Value of WPS Request Type Attribute */ ++#define WPS_REQ_TYPE_ENROLLEE_INFO_ONLY 0x00 ++#define WPS_REQ_TYPE_ENROLLEE_OPEN_8021X 0x01 ++#define WPS_REQ_TYPE_REGISTRAR 0x02 ++#define WPS_REQ_TYPE_WLAN_MANAGER_REGISTRAR 0x03 ++ ++/* Value of WPS Response Type Attribute */ ++#define WPS_RESPONSE_TYPE_INFO_ONLY 0x00 ++#define WPS_RESPONSE_TYPE_8021X 0x01 ++#define WPS_RESPONSE_TYPE_REGISTRAR 0x02 ++#define WPS_RESPONSE_TYPE_AP 0x03 ++ ++/* Value of WPS WiFi Simple Configuration State Attribute */ ++#define WPS_WSC_STATE_NOT_CONFIG 0x01 ++#define WPS_WSC_STATE_CONFIG 0x02 ++ ++/* Value of WPS Version Attribute */ ++#define WPS_VERSION_1 0x10 ++ ++/* Value of WPS Configuration Method Attribute */ ++#define WPS_CONFIG_METHOD_FLASH 0x0001 ++#define WPS_CONFIG_METHOD_ETHERNET 0x0002 ++#define WPS_CONFIG_METHOD_LABEL 0x0004 ++#define WPS_CONFIG_METHOD_DISPLAY 0x0008 ++#define WPS_CONFIG_METHOD_E_NFC 0x0010 ++#define WPS_CONFIG_METHOD_I_NFC 0x0020 ++#define WPS_CONFIG_METHOD_NFC 0x0040 ++#define WPS_CONFIG_METHOD_PBC 0x0080 ++#define WPS_CONFIG_METHOD_KEYPAD 0x0100 ++#define WPS_CONFIG_METHOD_VPBC 0x0280 ++#define WPS_CONFIG_METHOD_PPBC 0x0480 ++#define WPS_CONFIG_METHOD_VDISPLAY 0x2008 ++#define WPS_CONFIG_METHOD_PDISPLAY 0x4008 ++ ++/* Value of Category ID of WPS Primary Device Type Attribute */ ++#define WPS_PDT_CID_DISPLAYS 0x0007 ++#define WPS_PDT_CID_MULIT_MEDIA 0x0008 ++#define WPS_PDT_CID_RTK_WIDI WPS_PDT_CID_MULIT_MEDIA ++ ++/* Value of Sub Category ID of WPS Primary Device Type Attribute */ ++#define WPS_PDT_SCID_MEDIA_SERVER 0x0005 ++#define WPS_PDT_SCID_RTK_DMP WPS_PDT_SCID_MEDIA_SERVER ++ ++/* Value of Device Password ID */ ++#define WPS_DPID_P 0x0000 ++#define WPS_DPID_USER_SPEC 0x0001 ++#define WPS_DPID_MACHINE_SPEC 0x0002 ++#define WPS_DPID_REKEY 0x0003 ++#define WPS_DPID_PBC 0x0004 ++#define WPS_DPID_REGISTRAR_SPEC 0x0005 ++ ++/* Value of WPS RF Bands Attribute */ ++#define WPS_RF_BANDS_2_4_GHZ 0x01 ++#define WPS_RF_BANDS_5_GHZ 0x02 ++ ++/* Value of WPS Association State Attribute */ ++#define WPS_ASSOC_STATE_NOT_ASSOCIATED 0x00 ++#define WPS_ASSOC_STATE_CONNECTION_SUCCESS 0x01 ++#define WPS_ASSOC_STATE_CONFIGURATION_FAILURE 0x02 ++#define WPS_ASSOC_STATE_ASSOCIATION_FAILURE 0x03 ++#define WPS_ASSOC_STATE_IP_FAILURE 0x04 ++ ++/* =====================P2P Section===================== */ ++/* For P2P */ ++#define P2POUI 0x506F9A09 ++ ++/* P2P Attribute ID */ ++#define P2P_ATTR_STATUS 0x00 ++#define P2P_ATTR_MINOR_REASON_CODE 0x01 ++#define P2P_ATTR_CAPABILITY 0x02 ++#define P2P_ATTR_DEVICE_ID 0x03 ++#define P2P_ATTR_GO_INTENT 0x04 ++#define P2P_ATTR_CONF_TIMEOUT 0x05 ++#define P2P_ATTR_LISTEN_CH 0x06 ++#define P2P_ATTR_GROUP_BSSID 0x07 ++#define P2P_ATTR_EX_LISTEN_TIMING 0x08 ++#define P2P_ATTR_INTENTED_IF_ADDR 0x09 ++#define P2P_ATTR_MANAGEABILITY 0x0A ++#define P2P_ATTR_CH_LIST 0x0B ++#define P2P_ATTR_NOA 0x0C ++#define P2P_ATTR_DEVICE_INFO 0x0D ++#define P2P_ATTR_GROUP_INFO 0x0E ++#define P2P_ATTR_GROUP_ID 0x0F ++#define P2P_ATTR_INTERFACE 0x10 ++#define P2P_ATTR_OPERATING_CH 0x11 ++#define P2P_ATTR_INVITATION_FLAGS 0x12 ++ ++/* Value of Status Attribute */ ++#define P2P_STATUS_SUCCESS 0x00 ++#define P2P_STATUS_FAIL_INFO_UNAVAILABLE 0x01 ++#define P2P_STATUS_FAIL_INCOMPATIBLE_PARAM 0x02 ++#define P2P_STATUS_FAIL_LIMIT_REACHED 0x03 ++#define P2P_STATUS_FAIL_INVALID_PARAM 0x04 ++#define P2P_STATUS_FAIL_REQUEST_UNABLE 0x05 ++#define P2P_STATUS_FAIL_PREVOUS_PROTO_ERR 0x06 ++#define P2P_STATUS_FAIL_NO_COMMON_CH 0x07 ++#define P2P_STATUS_FAIL_UNKNOWN_P2PGROUP 0x08 ++#define P2P_STATUS_FAIL_BOTH_GOINTENT_15 0x09 ++#define P2P_STATUS_FAIL_INCOMPATIBLE_PROVSION 0x0A ++#define P2P_STATUS_FAIL_USER_REJECT 0x0B ++ ++/* Value of Inviation Flags Attribute */ ++#define P2P_INVITATION_FLAGS_PERSISTENT BIT(0) ++ ++#define DMP_P2P_DEVCAP_SUPPORT (P2P_DEVCAP_SERVICE_DISCOVERY | \ ++ P2P_DEVCAP_CLIENT_DISCOVERABILITY | \ ++ P2P_DEVCAP_CONCURRENT_OPERATION | \ ++ P2P_DEVCAP_INVITATION_PROC) ++ ++#define DMP_P2P_GRPCAP_SUPPORT (P2P_GRPCAP_INTRABSS) ++ ++/* Value of Device Capability Bitmap */ ++#define P2P_DEVCAP_SERVICE_DISCOVERY BIT(0) ++#define P2P_DEVCAP_CLIENT_DISCOVERABILITY BIT(1) ++#define P2P_DEVCAP_CONCURRENT_OPERATION BIT(2) ++#define P2P_DEVCAP_INFRA_MANAGED BIT(3) ++#define P2P_DEVCAP_DEVICE_LIMIT BIT(4) ++#define P2P_DEVCAP_INVITATION_PROC BIT(5) ++ ++/* Value of Group Capability Bitmap */ ++#define P2P_GRPCAP_GO BIT(0) ++#define P2P_GRPCAP_PERSISTENT_GROUP BIT(1) ++#define P2P_GRPCAP_GROUP_LIMIT BIT(2) ++#define P2P_GRPCAP_INTRABSS BIT(3) ++#define P2P_GRPCAP_CROSS_CONN BIT(4) ++#define P2P_GRPCAP_PERSISTENT_RECONN BIT(5) ++#define P2P_GRPCAP_GROUP_FORMATION BIT(6) ++ ++/* P2P Public Action Frame (Management Frame) */ ++#define P2P_PUB_ACTION_ACTION 0x09 ++ ++/* P2P Public Action Frame Type */ ++#define P2P_GO_NEGO_REQ 0 ++#define P2P_GO_NEGO_RESP 1 ++#define P2P_GO_NEGO_CONF 2 ++#define P2P_INVIT_REQ 3 ++#define P2P_INVIT_RESP 4 ++#define P2P_DEVDISC_REQ 5 ++#define P2P_DEVDISC_RESP 6 ++#define P2P_PROVISION_DISC_REQ 7 ++#define P2P_PROVISION_DISC_RESP 8 ++ ++/* P2P Action Frame Type */ ++#define P2P_NOTICE_OF_ABSENCE 0 ++#define P2P_PRESENCE_REQUEST 1 ++#define P2P_PRESENCE_RESPONSE 2 ++#define P2P_GO_DISC_REQUEST 3 ++ ++#define P2P_MAX_PERSISTENT_GROUP_NUM 10 ++ ++#define P2P_PROVISIONING_SCAN_CNT 3 ++ ++#define P2P_WILDCARD_SSID_LEN 7 ++ ++/* default value, used when: (1)p2p disabed or (2)p2p enabled ++ * but only do 1 scan phase */ ++#define P2P_FINDPHASE_EX_NONE 0 ++/* used when p2p enabled and want to do 1 scan phase and ++ * P2P_FINDPHASE_EX_MAX-1 find phase */ ++#define P2P_FINDPHASE_EX_FULL 1 ++#define P2P_FINDPHASE_EX_SOCIAL_FIRST (P2P_FINDPHASE_EX_FULL+1) ++#define P2P_FINDPHASE_EX_MAX 4 ++#define P2P_FINDPHASE_EX_SOCIAL_LAST P2P_FINDPHASE_EX_MAX ++ ++/* 5 seconds timeout for sending the provision discovery request */ ++#define P2P_PROVISION_TIMEOUT 5000 ++/* 3 seconds timeout for sending the prov disc request concurrent mode */ ++#define P2P_CONCURRENT_PROVISION_TIME 3000 ++/* 5 seconds timeout for receiving the group negotiation response */ ++#define P2P_GO_NEGO_TIMEOUT 5000 ++/* 3 seconds timeout for sending the negotiation request under concurrent mode */ ++#define P2P_CONCURRENT_GO_NEGO_TIME 3000 ++/* 100ms */ ++#define P2P_TX_PRESCAN_TIMEOUT 100 ++/* 5 seconds timeout for sending the invitation request */ ++#define P2P_INVITE_TIMEOUT 5000 ++/* 3 seconds timeout for sending the invitation request under concurrent mode */ ++#define P2P_CONCURRENT_INVITE_TIME 3000 ++/* 25 seconds timeout to reset the scan channel (based on channel plan) */ ++#define P2P_RESET_SCAN_CH 25000 ++#define P2P_MAX_INTENT 15 ++ ++#define P2P_MAX_NOA_NUM 2 ++ ++/* WPS Configuration Method */ ++#define WPS_CM_NONE 0x0000 ++#define WPS_CM_LABEL 0x0004 ++#define WPS_CM_DISPLYA 0x0008 ++#define WPS_CM_EXTERNAL_NFC_TOKEN 0x0010 ++#define WPS_CM_INTEGRATED_NFC_TOKEN 0x0020 ++#define WPS_CM_NFC_INTERFACE 0x0040 ++#define WPS_CM_PUSH_BUTTON 0x0080 ++#define WPS_CM_KEYPAD 0x0100 ++#define WPS_CM_SW_PUHS_BUTTON 0x0280 ++#define WPS_CM_HW_PUHS_BUTTON 0x0480 ++#define WPS_CM_SW_DISPLAY_P 0x2008 ++#define WPS_CM_LCD_DISPLAY_P 0x4008 ++ ++enum P2P_ROLE { ++ P2P_ROLE_DISABLE = 0, ++ P2P_ROLE_DEVICE = 1, ++ P2P_ROLE_CLIENT = 2, ++ P2P_ROLE_GO = 3 ++}; ++ ++enum P2P_STATE { ++ P2P_STATE_NONE = 0, /* P2P disable */ ++ /* P2P had enabled and do nothing */ ++ P2P_STATE_IDLE = 1, ++ P2P_STATE_LISTEN = 2, /* In pure listen state */ ++ P2P_STATE_SCAN = 3, /* In scan phase */ ++ /* In the listen state of find phase */ ++ P2P_STATE_FIND_PHASE_LISTEN = 4, ++ /* In the search state of find phase */ ++ P2P_STATE_FIND_PHASE_SEARCH = 5, ++ /* In P2P provisioning discovery */ ++ P2P_STATE_TX_PROVISION_DIS_REQ = 6, ++ P2P_STATE_RX_PROVISION_DIS_RSP = 7, ++ P2P_STATE_RX_PROVISION_DIS_REQ = 8, ++ /* Doing the group owner negoitation handshake */ ++ P2P_STATE_GONEGO_ING = 9, ++ /* finish the group negoitation handshake with success */ ++ P2P_STATE_GONEGO_OK = 10, ++ /* finish the group negoitation handshake with failure */ ++ P2P_STATE_GONEGO_FAIL = 11, ++ /* receiving the P2P Inviation request and match with the profile. */ ++ P2P_STATE_RECV_INVITE_REQ_MATCH = 12, ++ /* Doing the P2P WPS */ ++ P2P_STATE_PROVISIONING_ING = 13, ++ /* Finish the P2P WPS */ ++ P2P_STATE_PROVISIONING_DONE = 14, ++ /* Transmit the P2P Invitation request */ ++ P2P_STATE_TX_INVITE_REQ = 15, ++ /* Receiving the P2P Invitation response */ ++ P2P_STATE_RX_INVITE_RESP_OK = 16, ++ /* receiving the P2P Inviation request and dismatch with the profile. */ ++ P2P_STATE_RECV_INVITE_REQ_DISMATCH = 17, ++ /* receiving the P2P Inviation request and this wifi is GO. */ ++ P2P_STATE_RECV_INVITE_REQ_GO = 18, ++ /* receiving the P2P Inviation request to join an existing P2P Group. */ ++ P2P_STATE_RECV_INVITE_REQ_JOIN = 19, ++ /* recveing the P2P Inviation response with failure */ ++ P2P_STATE_RX_INVITE_RESP_FAIL = 20, ++ /* receiving p2p negoitation response with information is not available */ ++ P2P_STATE_RX_INFOR_NOREADY = 21, ++ /* sending p2p negoitation response with information is not available */ ++ P2P_STATE_TX_INFOR_NOREADY = 22, ++}; ++ ++enum P2P_WPSINFO { ++ P2P_NO_WPSINFO = 0, ++ P2P_GOT_WPSINFO_PEER_DISPLAY_PIN = 1, ++ P2P_GOT_WPSINFO_SELF_DISPLAY_PIN = 2, ++ P2P_GOT_WPSINFO_PBC = 3, ++}; ++ ++#define P2P_PRIVATE_IOCTL_SET_LEN 64 ++ ++enum P2P_PROTO_WK_ID { ++ P2P_FIND_PHASE_WK = 0, ++ P2P_RESTORE_STATE_WK = 1, ++ P2P_PRE_TX_PROVDISC_PROCESS_WK = 2, ++ P2P_PRE_TX_NEGOREQ_PROCESS_WK = 3, ++ P2P_PRE_TX_INVITEREQ_PROCESS_WK = 4, ++ P2P_AP_P2P_CH_SWITCH_PROCESS_WK =5, ++ P2P_RO_CH_WK = 6, ++}; ++ ++enum P2P_PS_STATE { ++ P2P_PS_DISABLE = 0, ++ P2P_PS_ENABLE = 1, ++ P2P_PS_SCAN = 2, ++ P2P_PS_SCAN_DONE = 3, ++ P2P_PS_ALLSTASLEEP = 4, /* for P2P GO */ ++}; ++ ++enum P2P_PS_MODE { ++ P2P_PS_NONE = 0, ++ P2P_PS_CTWINDOW = 1, ++ P2P_PS_NOA = 2, ++ P2P_PS_MIX = 3, /* CTWindow and NoA */ ++}; ++ ++/* =====================WFD Section===================== */ ++/* For Wi-Fi Display */ ++#define WFD_ATTR_DEVICE_INFO 0x00 ++#define WFD_ATTR_ASSOC_BSSID 0x01 ++#define WFD_ATTR_COUPLED_SINK_INFO 0x06 ++#define WFD_ATTR_LOCAL_IP_ADDR 0x08 ++#define WFD_ATTR_SESSION_INFO 0x09 ++#define WFD_ATTR_ALTER_MAC 0x0a ++ ++/* For WFD Device Information Attribute */ ++#define WFD_DEVINFO_SOURCE 0x0000 ++#define WFD_DEVINFO_PSINK 0x0001 ++#define WFD_DEVINFO_SSINK 0x0002 ++#define WFD_DEVINFO_DUAL 0x0003 ++ ++#define WFD_DEVINFO_SESSION_AVAIL 0x0010 ++#define WFD_DEVINFO_WSD 0x0040 ++#define WFD_DEVINFO_PC_TDLS 0x0080 ++#define WFD_DEVINFO_HDCP_SUPPORT 0x0100 ++ ++#define IP_MCAST_MAC(mac) \ ++ ((mac[0] == 0x01) && (mac[1] == 0x00) && (mac[2] == 0x5e)) ++#define ICMPV6_MCAST_MAC(mac) \ ++ ((mac[0] == 0x33) && (mac[1] == 0x33) && (mac[2] != 0xff)) ++ ++#endif /* _WIFI_H_ */ +diff --git a/drivers/staging/r8188eu/include/wlan_bssdef.h b/drivers/staging/r8188eu/include/wlan_bssdef.h +new file mode 100644 +index 000000000000..99ca097b8edd +--- /dev/null ++++ b/drivers/staging/r8188eu/include/wlan_bssdef.h +@@ -0,0 +1,327 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __WLAN_BSSDEF_H__ ++#define __WLAN_BSSDEF_H__ ++ ++#define MAX_IE_SZ 768 ++ ++#define NDIS_802_11_LENGTH_SSID 32 ++#define NDIS_802_11_LENGTH_RATES 8 ++#define NDIS_802_11_LENGTH_RATES_EX 16 ++ ++#define NDIS_802_11_RSSI long /* in dBm */ ++ ++struct ndis_802_11_ssid { ++ u32 SsidLength; ++ u8 Ssid[32]; ++}; ++ ++enum NDIS_802_11_NETWORK_TYPE { ++ Ndis802_11FH, ++ Ndis802_11DS, ++ Ndis802_11OFDM5, ++ Ndis802_11OFDM24, ++ Ndis802_11NetworkTypeMax /* dummy upper bound */ ++}; ++ ++struct ndis_802_11_config_fh { ++ u32 Length; /* Length of structure */ ++ u32 HopPattern; /* As defined by 802.11, MSB set */ ++ u32 HopSet; /* to one if non-802.11 */ ++ u32 DwellTime; /* units are Kusec */ ++}; ++ ++/* ++ * FW will only save the channel number in DSConfig. ++ * ODI Handler will convert the channel number to freq. number. ++ */ ++struct ndis_802_11_config { ++ u32 Length; /* Length of structure */ ++ u32 BeaconPeriod; /* units are Kusec */ ++ u32 ATIMWindow; /* units are Kusec */ ++ u32 DSConfig; /* Frequency, units are kHz */ ++ struct ndis_802_11_config_fh FHConfig; ++}; ++ ++enum ndis_802_11_network_infra { ++ Ndis802_11IBSS, ++ Ndis802_11Infrastructure, ++ Ndis802_11AutoUnknown, ++ Ndis802_11InfrastructureMax, /* dummy upper bound */ ++ Ndis802_11APMode ++}; ++ ++struct ndis_802_11_fixed_ie { ++ u8 Timestamp[8]; ++ u16 BeaconInterval; ++ u16 Capabilities; ++}; ++ ++struct ndis_802_11_var_ie { ++ u8 ElementID; ++ u8 Length; ++ u8 data[1]; ++}; ++ ++/* ++ * Length is the 4 bytes multiples of the sume of ++ * [ETH_ALEN] + 2 + sizeof (struct ndis_802_11_ssid) + sizeof (u32) ++ * + sizeof (NDIS_802_11_RSSI) + sizeof (enum NDIS_802_11_NETWORK_TYPE) ++ * + sizeof (struct ndis_802_11_config) ++ * + NDIS_802_11_LENGTH_RATES_EX + IELength ++ * ++ * Except the IELength, all other fields are fixed length. ++ * Therefore, we can define a macro to represent the partial sum. */ ++ ++enum ndis_802_11_auth_mode { ++ Ndis802_11AuthModeOpen, ++ Ndis802_11AuthModeShared, ++ Ndis802_11AuthModeAutoSwitch, ++ Ndis802_11AuthModeWPA, ++ Ndis802_11AuthModeWPAPSK, ++ Ndis802_11AuthModeWPANone, ++ Ndis802_11AuthModeWAPI, ++ Ndis802_11AuthModeMax /* Not a real mode, upper bound */ ++}; ++ ++enum ndis_802_11_wep_status { ++ Ndis802_11WEPEnabled, ++ Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, ++ Ndis802_11WEPDisabled, ++ Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, ++ Ndis802_11WEPKeyAbsent, ++ Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, ++ Ndis802_11WEPNotSupported, ++ Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, ++ Ndis802_11Encryption2Enabled, ++ Ndis802_11Encryption2KeyAbsent, ++ Ndis802_11Encryption3Enabled, ++ Ndis802_11Encryption3KeyAbsent, ++ Ndis802_11_EncryptionWAPI ++}; ++ ++#define NDIS_802_11_AI_REQFI_CAPABILITIES 1 ++#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2 ++#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4 ++ ++#define NDIS_802_11_AI_RESFI_CAPABILITIES 1 ++#define NDIS_802_11_AI_RESFI_STATUSCODE 2 ++#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4 ++ ++struct ndis_802_11_ai_reqfi { ++ u16 Capabilities; ++ u16 ListenInterval; ++ unsigned char CurrentAPAddress[ETH_ALEN]; ++}; ++ ++struct ndis_802_11_ai_resfi { ++ u16 Capabilities; ++ u16 StatusCode; ++ u16 AssociationId; ++}; ++ ++struct ndis_802_11_assoc_info { ++ u32 Length; ++ u16 AvailableRequestFixedIEs; ++ struct ndis_802_11_ai_reqfi RequestFixedIEs; ++ u32 RequestIELength; ++ u32 OffsetRequestIEs; ++ u16 AvailableResponseFixedIEs; ++ struct ndis_802_11_ai_resfi ResponseFixedIEs; ++ u32 ResponseIELength; ++ u32 OffsetResponseIEs; ++}; ++ ++enum ndis_802_11_reload_def { ++ Ndis802_11ReloadWEPKeys ++}; ++ ++/* Key mapping keys require a BSSID */ ++struct ndis_802_11_key { ++ u32 Length; /* Length of this structure */ ++ u32 KeyIndex; ++ u32 KeyLength; /* length of key in bytes */ ++ unsigned char BSSID[ETH_ALEN]; ++ unsigned long long KeyRSC; ++ u8 KeyMaterial[32]; /* var len depending on above field */ ++}; ++ ++struct ndis_802_11_remove_key { ++ u32 Length; /* Length */ ++ u32 KeyIndex; ++ unsigned char BSSID[ETH_ALEN]; ++}; ++ ++struct ndis_802_11_wep { ++ u32 Length; /* Length of this structure */ ++ u32 KeyIndex; /* 0 is the per-client key, ++ * 1-N are the global keys */ ++ u32 KeyLength; /* length of key in bytes */ ++ u8 KeyMaterial[16];/* variable len depending on above field */ ++}; ++ ++struct ndis_802_11_auth_req { ++ u32 Length; /* Length of structure */ ++ unsigned char Bssid[ETH_ALEN]; ++ u32 Flags; ++}; ++ ++enum ndis_802_11_status_type { ++ Ndis802_11StatusType_Authentication, ++ Ndis802_11StatusType_MediaStreamMode, ++ Ndis802_11StatusType_PMKID_CandidateList, ++ Ndis802_11StatusTypeMax /* not a real type, defined as ++ * an upper bound */ ++}; ++ ++struct ndis_802_11_status_ind { ++ enum ndis_802_11_status_type StatusType; ++}; ++ ++/* mask for authentication/integrity fields */ ++#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f ++#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01 ++#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02 ++#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06 ++#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E ++ ++/* MIC check time, 60 seconds. */ ++#define MIC_CHECK_TIME 60000000 ++ ++struct ndis_802_11_auth_evt { ++ struct ndis_802_11_status_ind Status; ++ struct ndis_802_11_auth_req Request[1]; ++}; ++ ++struct ndis_802_11_test { ++ u32 Length; ++ u32 Type; ++ union { ++ struct ndis_802_11_auth_evt AuthenticationEvent; ++ NDIS_802_11_RSSI RssiTrigger; ++ } tt; ++}; ++ ++#ifndef Ndis802_11APMode ++#define Ndis802_11APMode (Ndis802_11InfrastructureMax+1) ++#endif ++ ++struct wlan_phy_info { ++ u8 SignalStrength;/* in percentage) */ ++ u8 SignalQuality;/* in percentage) */ ++ u8 Optimum_antenna; /* for Antenna diversity */ ++ u8 Reserved_0; ++}; ++ ++struct wlan_bcn_info { ++ /* these infor get from rtw_get_encrypt_info when ++ * * translate scan to UI */ ++ u8 encryp_protocol;/* ENCRYP_PROTOCOL_E: OPEN/WEP/WPA/WPA2/WAPI */ ++ int group_cipher; /* WPA/WPA2 group cipher */ ++ int pairwise_cipher;/* WPA/WPA2/WEP pairwise cipher */ ++ int is_8021x; ++ ++ /* bwmode 20/40 and ch_offset UP/LOW */ ++ unsigned short ht_cap_info; ++ unsigned char ht_info_infos_0; ++}; ++ ++/* temporally add #pragma pack for structure alignment issue of ++* struct wlan_bssid_ex and get_struct wlan_bssid_ex_sz() ++*/ ++struct wlan_bssid_ex { ++ u32 Length; ++ unsigned char MacAddress[ETH_ALEN]; ++ u8 Reserved[2];/* 0]: IS beacon frame */ ++ struct ndis_802_11_ssid Ssid; ++ u32 Privacy; ++ NDIS_802_11_RSSI Rssi;/* in dBM,raw data ,get from PHY) */ ++ enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; ++ struct ndis_802_11_config Configuration; ++ enum ndis_802_11_network_infra InfrastructureMode; ++ unsigned char SupportedRates[NDIS_802_11_LENGTH_RATES_EX]; ++ struct wlan_phy_info PhyInfo; ++ u32 IELength; ++ u8 IEs[MAX_IE_SZ]; /* timestamp, beacon interval, and ++ * capability information) */ ++} __packed; ++ ++static inline uint get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss) ++{ ++ return sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + bss->IELength; ++} ++ ++struct wlan_network { ++ struct list_head list; ++ int network_type; /* refer to ieee80211.h for WIRELESS_11B/G */ ++ int fixed; /* set fixed when not to be removed ++ * in site-surveying */ ++ unsigned long last_scanned; /* timestamp for the network */ ++ int aid; /* will only be valid when a BSS is joinned. */ ++ int join_res; ++ struct wlan_bssid_ex network; /* must be the last item */ ++ struct wlan_bcn_info BcnInfo; ++}; ++ ++enum VRTL_CARRIER_SENSE { ++ DISABLE_VCS, ++ ENABLE_VCS, ++ AUTO_VCS ++}; ++ ++enum VCS_TYPE { ++ NONE_VCS, ++ RTS_CTS, ++ CTS_TO_SELF ++}; ++ ++#define PWR_CAM 0 ++#define PWR_MINPS 1 ++#define PWR_MAXPS 2 ++#define PWR_UAPSD 3 ++#define PWR_VOIP 4 ++ ++enum UAPSD_MAX_SP { ++ NO_LIMIT, ++ TWO_MSDU, ++ FOUR_MSDU, ++ SIX_MSDU ++}; ++ ++#define NUM_PRE_AUTH_KEY 16 ++#define NUM_PMKID_CACHE NUM_PRE_AUTH_KEY ++ ++/* ++* WPA2 ++*/ ++ ++struct pmkid_candidate { ++ unsigned char BSSID[ETH_ALEN]; ++ u32 Flags; ++}; ++ ++struct ndis_802_11_pmkid_list { ++ u32 Version; /* Version of the structure */ ++ u32 NumCandidates; /* No. of pmkid candidates */ ++ struct pmkid_candidate CandidateList[1]; ++}; ++ ++struct ndis_802_11_auth_encrypt { ++ enum ndis_802_11_auth_mode AuthModeSupported; ++ enum ndis_802_11_wep_status EncryptStatusSupported; ++}; ++ ++struct ndis_802_11_cap { ++ u32 Length; ++ u32 Version; ++ u32 NoOfPMKIDs; ++ u32 NoOfAuthEncryptPairsSupported; ++ struct ndis_802_11_auth_encrypt AuthenticationEncryptionSupported[1]; ++}; ++ ++u8 key_2char2num(u8 hch, u8 lch); ++u8 key_char2num(u8 ch); ++u8 str_2char2num(u8 hch, u8 lch); ++ ++#endif /* ifndef WLAN_BSSDEF_H_ */ +diff --git a/drivers/staging/r8188eu/include/xmit_osdep.h b/drivers/staging/r8188eu/include/xmit_osdep.h +new file mode 100644 +index 000000000000..191c36361b63 +--- /dev/null ++++ b/drivers/staging/r8188eu/include/xmit_osdep.h +@@ -0,0 +1,51 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#ifndef __XMIT_OSDEP_H_ ++#define __XMIT_OSDEP_H_ ++ ++#include "osdep_service.h" ++#include "drv_types.h" ++ ++struct pkt_file { ++ struct sk_buff *pkt; ++ size_t pkt_len; /* the remainder length of the open_file */ ++ unsigned char *cur_buffer; ++ u8 *buf_start; ++ u8 *cur_addr; ++ size_t buf_len; ++}; ++ ++extern int rtw_ht_enable; ++extern int rtw_cbw40_enable; ++extern int rtw_ampdu_enable;/* for enable tx_ampdu */ ++ ++#define NR_XMITFRAME 256 ++ ++struct xmit_priv; ++struct pkt_attrib; ++struct sta_xmit_priv; ++struct xmit_frame; ++struct xmit_buf; ++ ++int rtw_xmit_entry(struct sk_buff *pkt, struct net_device *pnetdev); ++ ++void rtw_os_xmit_schedule(struct adapter *padapter); ++ ++int rtw_os_xmit_resource_alloc(struct adapter *padapter, ++ struct xmit_buf *pxmitbuf, u32 alloc_sz); ++void rtw_os_xmit_resource_free(struct adapter *padapter, ++ struct xmit_buf *pxmitbuf, u32 free_sz); ++ ++void rtw_set_tx_chksum_offload(struct sk_buff *pkt, struct pkt_attrib *pattrib); ++ ++uint rtw_remainder_len(struct pkt_file *pfile); ++void _rtw_open_pktfile(struct sk_buff *pkt, struct pkt_file *pfile); ++uint _rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen); ++int rtw_endofpktfile(struct pkt_file *pfile); ++ ++void rtw_os_pkt_complete(struct adapter *padapter, struct sk_buff *pkt); ++void rtw_os_xmit_complete(struct adapter *padapter, ++ struct xmit_frame *pxframe); ++ ++#endif /* __XMIT_OSDEP_H_ */ +diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c +new file mode 100644 +index 000000000000..1fd375076001 +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c +@@ -0,0 +1,6649 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _IOCTL_LINUX_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wlan_bssdef.h" ++#include "../include/rtw_debug.h" ++#include "../include/wifi.h" ++#include "../include/rtw_mlme.h" ++#include "../include/rtw_mlme_ext.h" ++#include "../include/rtw_ioctl.h" ++#include "../include/rtw_ioctl_set.h" ++#include "../include/rtw_mp_ioctl.h" ++#include "../include/usb_ops.h" ++#include "../include/rtl8188e_hal.h" ++ ++#include "../include/rtw_mp.h" ++#include "../include/rtw_iol.h" ++ ++#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30) ++ ++#define SCAN_ITEM_SIZE 768 ++#define MAX_CUSTOM_LEN 64 ++#define RATE_COUNT 4 ++ ++/* combo scan */ ++#define WEXT_CSCAN_AMOUNT 9 ++#define WEXT_CSCAN_BUF_LEN 360 ++#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00" ++#define WEXT_CSCAN_HEADER_SIZE 12 ++#define WEXT_CSCAN_SSID_SECTION 'S' ++#define WEXT_CSCAN_CHANNEL_SECTION 'C' ++#define WEXT_CSCAN_NPROBE_SECTION 'N' ++#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A' ++#define WEXT_CSCAN_PASV_DWELL_SECTION 'P' ++#define WEXT_CSCAN_HOME_DWELL_SECTION 'H' ++#define WEXT_CSCAN_TYPE_SECTION 'T' ++ ++static struct mp_ioctl_handler mp_ioctl_hdl[] = { ++/*0*/ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_start_test_hdl, OID_RT_PRO_START_TEST) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_stop_test_hdl, OID_RT_PRO_STOP_TEST) ++ ++ GEN_HANDLER(sizeof(struct rwreg_param), rtl8188eu_oid_rt_pro_read_register_hdl, OID_RT_PRO_READ_REGISTER) ++ GEN_HANDLER(sizeof(struct rwreg_param), rtl8188eu_oid_rt_pro_write_register_hdl, OID_RT_PRO_WRITE_REGISTER) ++ GEN_HANDLER(sizeof(struct bb_reg_param), rtl8188eu_oid_rt_pro_read_bb_reg_hdl, OID_RT_PRO_READ_BB_REG) ++/*5*/ GEN_HANDLER(sizeof(struct bb_reg_param), rtl8188eu_oid_rt_pro_write_bb_reg_hdl, OID_RT_PRO_WRITE_BB_REG) ++ GEN_HANDLER(sizeof(struct rf_reg_param), rtl8188eu_oid_rt_pro_read_rf_reg_hdl, OID_RT_PRO_RF_READ_REGISTRY) ++ GEN_HANDLER(sizeof(struct rf_reg_param), rtl8188eu_oid_rt_pro_write_rf_reg_hdl, OID_RT_PRO_RF_WRITE_REGISTRY) ++ ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_channel_direct_call_hdl, OID_RT_PRO_SET_CHANNEL_DIRECT_CALL) ++ GEN_HANDLER(sizeof(struct txpower_param), rtl8188eu_oid_rt_pro_set_tx_power_control_hdl, OID_RT_PRO_SET_TX_POWER_CONTROL) ++/*10*/ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_data_rate_hdl, OID_RT_PRO_SET_DATA_RATE) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_set_bandwidth_hdl, OID_RT_SET_BANDWIDTH) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_antenna_bb_hdl, OID_RT_PRO_SET_ANTENNA_BB) ++ ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_continuous_tx_hdl, OID_RT_PRO_SET_CONTINUOUS_TX) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_single_carrier_tx_hdl, OID_RT_PRO_SET_SINGLE_CARRIER_TX) ++/*15*/ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_carrier_suppression_tx_hdl, OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_single_tone_tx_hdl, OID_RT_PRO_SET_SINGLE_TONE_TX) ++ ++ EXT_MP_IOCTL_HANDLER(0, xmit_packet, 0) ++ ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_set_rx_packet_type_hdl, OID_RT_SET_RX_PACKET_TYPE) ++ GEN_HANDLER(0, rtl8188eu_oid_rt_reset_phy_rx_packet_count_hdl, OID_RT_RESET_PHY_RX_PACKET_COUNT) ++/*20*/ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_phy_rx_packet_received_hdl, OID_RT_GET_PHY_RX_PACKET_RECEIVED) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_phy_rx_packet_crc32_error_hdl, OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR) ++ ++ GEN_HANDLER(sizeof(struct eeprom_rw_param), NULL, 0) ++ GEN_HANDLER(sizeof(struct eeprom_rw_param), NULL, 0) ++ GEN_HANDLER(sizeof(struct efuse_access_struct), rtl8188eu_oid_rt_pro_efuse_hdl, OID_RT_PRO_EFUSE) ++/*25*/ GEN_HANDLER(0, rtl8188eu_oid_rt_pro_efuse_map_hdl, OID_RT_PRO_EFUSE_MAP) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_efuse_max_size_hdl, OID_RT_GET_EFUSE_MAX_SIZE) ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_efuse_current_size_hdl, OID_RT_GET_EFUSE_CURRENT_SIZE) ++ ++ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_thermal_meter_hdl, OID_RT_PRO_GET_THERMAL_METER) ++ GEN_HANDLER(sizeof(u8), rtl8188eu_oid_rt_pro_set_power_tracking_hdl, OID_RT_PRO_SET_POWER_TRACKING) ++/*30*/ GEN_HANDLER(sizeof(u8), rtl8188eu_oid_rt_set_power_down_hdl, OID_RT_SET_POWER_DOWN) ++/*31*/ GEN_HANDLER(0, rtl8188eu_oid_rt_pro_trigger_gpio_hdl, 0) ++}; ++ ++static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000, ++ 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, ++ 48000000, 54000000}; ++ ++void indicate_wx_scan_complete_event(struct adapter *padapter) ++{ ++ union iwreq_data wrqu; ++ ++ memset(&wrqu, 0, sizeof(union iwreq_data)); ++ wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL); ++} ++ ++void rtw_indicate_wx_assoc_event(struct adapter *padapter) ++{ ++ union iwreq_data wrqu; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ memset(&wrqu, 0, sizeof(union iwreq_data)); ++ ++ wrqu.ap_addr.sa_family = ARPHRD_ETHER; ++ ++ memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN); ++ ++ DBG_88E_LEVEL(_drv_always_, "assoc success\n"); ++ wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); ++} ++ ++void rtw_indicate_wx_disassoc_event(struct adapter *padapter) ++{ ++ union iwreq_data wrqu; ++ ++ memset(&wrqu, 0, sizeof(union iwreq_data)); ++ ++ wrqu.ap_addr.sa_family = ARPHRD_ETHER; ++ memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); ++ ++ DBG_88E_LEVEL(_drv_always_, "indicate disassoc\n"); ++ wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); ++} ++ ++static char *translate_scan(struct adapter *padapter, ++ struct iw_request_info *info, ++ struct wlan_network *pnetwork, ++ char *start, char *stop) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct iw_event iwe; ++ u16 cap; ++ __le16 le_tmp; ++ u32 ht_ielen = 0; ++ char *custom; ++ char *p; ++ u16 max_rate = 0, rate, ht_cap = false; ++ u32 i = 0; ++ u8 bw_40MHz = 0, short_GI = 0; ++ u16 mcs_rate = 0; ++ u8 ss, sq; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ++ u32 blnGotP2PIE = false; ++ ++ /* User is doing the P2P device discovery */ ++ /* The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE. */ ++ /* If not, the driver should ignore this AP and go to the next AP. */ ++ ++ /* Verifying the SSID */ ++ if (!memcmp(pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN)) { ++ u32 p2pielen = 0; ++ ++ if (pnetwork->network.Reserved[0] == 2) {/* Probe Request */ ++ /* Verifying the P2P IE */ ++ if (rtw_get_p2p_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &p2pielen)) ++ blnGotP2PIE = true; ++ } else {/* Beacon or Probe Respones */ ++ /* Verifying the P2P IE */ ++ if (rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen)) ++ blnGotP2PIE = true; ++ } ++ } ++ ++ if (!blnGotP2PIE) ++ return start; ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ /* AP MAC address */ ++ iwe.cmd = SIOCGIWAP; ++ iwe.u.ap_addr.sa_family = ARPHRD_ETHER; ++ ++ memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN); ++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN); ++ ++ /* Add the ESSID */ ++ iwe.cmd = SIOCGIWESSID; ++ iwe.u.data.flags = 1; ++ iwe.u.data.length = min_t(u16, pnetwork->network.Ssid.SsidLength, 32); ++ start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid); ++ ++ /* parsing HT_CAP_IE */ ++ p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - 12); ++ ++ if (p && ht_ielen > 0) { ++ struct ieee80211_ht_cap *pht_capie; ++ ++ ht_cap = true; ++ pht_capie = (struct ieee80211_ht_cap *)(p + 2); ++ memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2); ++ bw_40MHz = (le16_to_cpu(pht_capie->cap_info) & ++ IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0; ++ short_GI = (le16_to_cpu(pht_capie->cap_info) & ++ (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0; ++ } ++ ++ /* Add the protocol name */ ++ iwe.cmd = SIOCGIWNAME; ++ if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates))) { ++ if (ht_cap) ++ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn"); ++ else ++ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b"); ++ } else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates))) { ++ if (ht_cap) ++ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn"); ++ else ++ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg"); ++ } else { ++ if (ht_cap) ++ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn"); ++ else ++ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g"); ++ } ++ ++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN); ++ ++ /* Add mode */ ++ iwe.cmd = SIOCGIWMODE; ++ memcpy(&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2); ++ ++ cap = le16_to_cpu(le_tmp); ++ ++ if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) { ++ if (cap & WLAN_CAPABILITY_BSS) ++ iwe.u.mode = IW_MODE_MASTER; ++ else ++ iwe.u.mode = IW_MODE_ADHOC; ++ ++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN); ++ } ++ ++ if (pnetwork->network.Configuration.DSConfig < 1) ++ pnetwork->network.Configuration.DSConfig = 1; ++ ++ /* Add frequency/channel */ ++ iwe.cmd = SIOCGIWFREQ; ++ iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000; ++ iwe.u.freq.e = 1; ++ iwe.u.freq.i = pnetwork->network.Configuration.DSConfig; ++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN); ++ ++ /* Add encryption capability */ ++ iwe.cmd = SIOCGIWENCODE; ++ if (cap & WLAN_CAPABILITY_PRIVACY) ++ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; ++ else ++ iwe.u.data.flags = IW_ENCODE_DISABLED; ++ iwe.u.data.length = 0; ++ start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid); ++ ++ /*Add basic and extended rates */ ++ max_rate = 0; ++ custom = kzalloc(MAX_CUSTOM_LEN, GFP_ATOMIC); ++ if (!custom) ++ return start; ++ p = custom; ++ p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): "); ++ while (pnetwork->network.SupportedRates[i] != 0) { ++ rate = pnetwork->network.SupportedRates[i] & 0x7F; ++ if (rate > max_rate) ++ max_rate = rate; ++ p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), ++ "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); ++ i++; ++ } ++ ++ if (ht_cap) { ++ if (mcs_rate & 0x8000)/* MCS15 */ ++ max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130); ++ else if (mcs_rate & 0x0080)/* MCS7 */ ++ ; ++ else/* default MCS7 */ ++ max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65); ++ ++ max_rate = max_rate * 2;/* Mbps/2; */ ++ } ++ ++ iwe.cmd = SIOCGIWRATE; ++ iwe.u.bitrate.fixed = 0; ++ iwe.u.bitrate.disabled = 0; ++ iwe.u.bitrate.value = max_rate * 500000; ++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN); ++ ++ /* parsing WPA/WPA2 IE */ ++ { ++ u8 *buf; ++ u8 *wpa_ie, *rsn_ie; ++ u16 wpa_len = 0, rsn_len = 0; ++ u8 *p; ++ ++ buf = kzalloc(MAX_WPA_IE_LEN, GFP_ATOMIC); ++ if (!buf) ++ goto exit; ++ wpa_ie = kzalloc(255, GFP_ATOMIC); ++ if (!wpa_ie) { ++ kfree(buf); ++ goto exit; ++ } ++ rsn_ie = kzalloc(255, GFP_ATOMIC); ++ if (!rsn_ie) { ++ kfree(buf); ++ kfree(wpa_ie); ++ goto exit; ++ } ++ rtw_get_sec_ie(pnetwork->network.IEs, pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len); ++ ++ if (wpa_len > 0) { ++ p = buf; ++ memset(buf, 0, MAX_WPA_IE_LEN); ++ p += sprintf(p, "wpa_ie ="); ++ for (i = 0; i < wpa_len; i++) ++ p += sprintf(p, "%02x", wpa_ie[i]); ++ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = IWEVCUSTOM; ++ iwe.u.data.length = strlen(buf); ++ start = iwe_stream_add_point(info, start, stop, &iwe, buf); ++ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = IWEVGENIE; ++ iwe.u.data.length = wpa_len; ++ start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie); ++ } ++ if (rsn_len > 0) { ++ p = buf; ++ memset(buf, 0, MAX_WPA_IE_LEN); ++ p += sprintf(p, "rsn_ie ="); ++ for (i = 0; i < rsn_len; i++) ++ p += sprintf(p, "%02x", rsn_ie[i]); ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = IWEVCUSTOM; ++ iwe.u.data.length = strlen(buf); ++ start = iwe_stream_add_point(info, start, stop, &iwe, buf); ++ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = IWEVGENIE; ++ iwe.u.data.length = rsn_len; ++ start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie); ++ } ++ kfree(buf); ++ kfree(wpa_ie); ++ kfree(rsn_ie); ++ } ++ ++ {/* parsing WPS IE */ ++ uint cnt = 0, total_ielen; ++ u8 *wpsie_ptr = NULL; ++ uint wps_ielen = 0; ++ ++ u8 *ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_; ++ total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_; ++ ++ while (cnt < total_ielen) { ++ if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) { ++ wpsie_ptr = &ie_ptr[cnt]; ++ iwe.cmd = IWEVGENIE; ++ iwe.u.data.length = (u16)wps_ielen; ++ start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr); ++ } ++ cnt += ie_ptr[cnt + 1] + 2; /* goto next */ ++ } ++ } ++ ++ /* Add quality statistics */ ++ iwe.cmd = IWEVQUAL; ++ iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED) && ++ is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) { ++ ss = padapter->recvpriv.signal_strength; ++ sq = padapter->recvpriv.signal_qual; ++ } else { ++ ss = pnetwork->network.PhyInfo.SignalStrength; ++ sq = pnetwork->network.PhyInfo.SignalQuality; ++ } ++ ++ iwe.u.qual.level = (u8)ss; ++ iwe.u.qual.qual = (u8)sq; /* signal quality */ ++ iwe.u.qual.noise = 0; /* noise level */ ++ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN); ++exit: ++ kfree(custom); ++ return start; ++} ++ ++static int wpa_set_auth_algs(struct net_device *dev, u32 value) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ int ret = 0; ++ ++ if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) { ++ DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value); ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch; ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; ++ } else if (value & AUTH_ALG_SHARED_KEY) { ++ DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n", value); ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ ++ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared; ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; ++ } else if (value & AUTH_ALG_OPEN_SYSTEM) { ++ DBG_88E("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n"); ++ if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) { ++ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; ++ } ++ } else if (value & AUTH_ALG_LEAP) { ++ DBG_88E("wpa_set_auth_algs, AUTH_ALG_LEAP\n"); ++ } else { ++ DBG_88E("wpa_set_auth_algs, error!\n"); ++ ret = -EINVAL; ++ } ++ return ret; ++} ++ ++static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len) ++{ ++ int ret = 0; ++ u32 wep_key_idx, wep_key_len, wep_total_len; ++ struct ndis_802_11_wep *pwep = NULL; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ param->u.crypt.err = 0; ++ param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; ++ ++ if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && ++ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && ++ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { ++ if (param->u.crypt.idx >= WEP_KEYS) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ } else { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ if (strcmp(param->u.crypt.alg, "WEP") == 0) { ++ DBG_88E("wpa_set_encryption, crypt.alg = WEP\n"); ++ ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; ++ padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_; ++ ++ wep_key_idx = param->u.crypt.idx; ++ wep_key_len = param->u.crypt.key_len; ++ ++ DBG_88E("(1)wep_key_idx =%d\n", wep_key_idx); ++ ++ if (wep_key_idx > WEP_KEYS) ++ return -EINVAL; ++ ++ if (wep_key_len > 0) { ++ wep_key_len = wep_key_len <= 5 ? 5 : 13; ++ wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial); ++ pwep = kmalloc(wep_total_len, GFP_KERNEL); ++ if (!pwep) ++ goto exit; ++ ++ memset(pwep, 0, wep_total_len); ++ pwep->KeyLength = wep_key_len; ++ pwep->Length = wep_total_len; ++ if (wep_key_len == 13) { ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; ++ padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_; ++ } ++ } else { ++ ret = -EINVAL; ++ goto exit; ++ } ++ pwep->KeyIndex = wep_key_idx; ++ pwep->KeyIndex |= 0x80000000; ++ memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength); ++ if (param->u.crypt.set_tx) { ++ DBG_88E("wep, set_tx = 1\n"); ++ if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL) ++ ret = -EOPNOTSUPP; ++ } else { ++ DBG_88E("wep, set_tx = 0\n"); ++ if (wep_key_idx >= WEP_KEYS) { ++ ret = -EOPNOTSUPP; ++ goto exit; ++ } ++ memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0], pwep->KeyMaterial, pwep->KeyLength); ++ psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength; ++ rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0); ++ } ++ goto exit; ++ } ++ ++ if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802_1x */ ++ struct sta_info *psta, *pbcmc_sta; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE)) { /* sta mode */ ++ psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); ++ if (!psta) { ++ ; ++ } else { ++ if (strcmp(param->u.crypt.alg, "none") != 0) ++ psta->ieee8021x_blocked = false; ++ ++ if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) || ++ (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) ++ psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; ++ ++ if (param->u.crypt.set_tx == 1) { /* pairwise key */ ++ memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); ++ ++ if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */ ++ memcpy(psta->dot11tkiptxmickey.skey, ¶m->u.crypt.key[16], 8); ++ memcpy(psta->dot11tkiprxmickey.skey, ¶m->u.crypt.key[24], 8); ++ padapter->securitypriv.busetkipkey = false; ++ } ++ ++ DBG_88E(" ~~~~set sta key:unicastkey\n"); ++ ++ rtw_setstakey_cmd(padapter, (unsigned char *)psta, true); ++ } else { /* group key */ ++ memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len)); ++ memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[16], 8); ++ memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[24], 8); ++ padapter->securitypriv.binstallGrpkey = true; ++ DBG_88E(" ~~~~set sta key:groupkey\n"); ++ ++ padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx; ++ ++ rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1); ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE); ++#endif /* CONFIG_88EU_P2P */ ++ } ++ } ++ pbcmc_sta = rtw_get_bcmc_stainfo(padapter); ++ if (!pbcmc_sta) { ++ ; ++ } else { ++ /* Jeff: don't disable ieee8021x_blocked while clearing key */ ++ if (strcmp(param->u.crypt.alg, "none") != 0) ++ pbcmc_sta->ieee8021x_blocked = false; ++ ++ if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) || ++ (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) ++ pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; ++ } ++ } ++ } ++ ++exit: ++ ++ kfree(pwep); ++ ++ return ret; ++} ++ ++static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ielen) ++{ ++ u8 *buf = NULL; ++ int group_cipher = 0, pairwise_cipher = 0; ++ int ret = 0; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ if (ielen > MAX_WPA_IE_LEN || !pie) { ++ _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); ++ if (!pie) ++ return ret; ++ else ++ return -EINVAL; ++ } ++ ++ if (ielen) { ++ buf = kzalloc(ielen, GFP_KERNEL); ++ if (!buf) { ++ ret = -ENOMEM; ++ goto exit; ++ } ++ ++ memcpy(buf, pie, ielen); ++ ++ /* dump */ ++ { ++ int i; ++ DBG_88E("\n wpa_ie(length:%d):\n", ielen); ++ for (i = 0; i < ielen; i += 8) ++ DBG_88E("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", buf[i], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]); ++ } ++ ++ if (ielen < RSN_HEADER_LEN) { ++ ret = -1; ++ goto exit; ++ } ++ ++ if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; ++ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; ++ memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen); ++ } ++ ++ if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; ++ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; ++ memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen); ++ } ++ ++ switch (group_cipher) { ++ case WPA_CIPHER_NONE: ++ padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; ++ break; ++ case WPA_CIPHER_WEP40: ++ padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ break; ++ case WPA_CIPHER_TKIP: ++ padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; ++ break; ++ case WPA_CIPHER_CCMP: ++ padapter->securitypriv.dot118021XGrpPrivacy = _AES_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; ++ break; ++ case WPA_CIPHER_WEP104: ++ padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ break; ++ } ++ ++ switch (pairwise_cipher) { ++ case WPA_CIPHER_NONE: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; ++ break; ++ case WPA_CIPHER_WEP40: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ break; ++ case WPA_CIPHER_TKIP: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; ++ break; ++ case WPA_CIPHER_CCMP: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _AES_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; ++ break; ++ case WPA_CIPHER_WEP104: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ break; ++ } ++ ++ _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); ++ {/* set wps_ie */ ++ u16 cnt = 0; ++ u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; ++ ++ while (cnt < ielen) { ++ eid = buf[cnt]; ++ if ((eid == _VENDOR_SPECIFIC_IE_) && (!memcmp(&buf[cnt + 2], wps_oui, 4))) { ++ DBG_88E("SET WPS_IE\n"); ++ ++ padapter->securitypriv.wps_ie_len = ((buf[cnt + 1] + 2) < (MAX_WPA_IE_LEN << 2)) ? (buf[cnt + 1] + 2) : (MAX_WPA_IE_LEN << 2); ++ ++ memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len); ++ ++ set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS); ++#ifdef CONFIG_88EU_P2P ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK)) ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING); ++#endif /* CONFIG_88EU_P2P */ ++ cnt += buf[cnt + 1] + 2; ++ break; ++ } else { ++ cnt += buf[cnt + 1] + 2; /* goto next */ ++ } ++ } ++ } ++ } ++ ++exit: ++ kfree(buf); ++ return ret; ++} ++ ++typedef unsigned char NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; ++ ++static int rtw_wx_get_name(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u32 ht_ielen = 0; ++ char *p; ++ u8 ht_cap = false; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; ++ NDIS_802_11_RATES_EX *prates = NULL; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) { ++ /* parsing HT_CAP_IE */ ++ p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength - 12); ++ if (p && ht_ielen > 0) ++ ht_cap = true; ++ ++ prates = &pcur_bss->SupportedRates; ++ ++ if (rtw_is_cckratesonly_included((u8 *)prates)) { ++ if (ht_cap) ++ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn"); ++ else ++ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b"); ++ } else if (rtw_is_cckrates_included((u8 *)prates)) { ++ if (ht_cap) ++ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn"); ++ else ++ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg"); ++ } else { ++ if (ht_cap) ++ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn"); ++ else ++ snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); ++ } ++ } else { ++ snprintf(wrqu->name, IFNAMSIZ, "unassociated"); ++ } ++ ++ ++ ++ return 0; ++} ++ ++static int rtw_wx_get_freq(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ /* wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000; */ ++ wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000; ++ wrqu->freq.e = 1; ++ wrqu->freq.i = pcur_bss->Configuration.DSConfig; ++ } else { ++ wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000; ++ wrqu->freq.e = 1; ++ wrqu->freq.i = padapter->mlmeextpriv.cur_channel; ++ } ++ ++ return 0; ++} ++ ++static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a, ++ union iwreq_data *wrqu, char *b) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ enum ndis_802_11_network_infra networkType; ++ int ret = 0; ++ ++ ++ ++ if (_FAIL == rtw_pwr_wakeup(padapter)) { ++ ret = -EPERM; ++ goto exit; ++ } ++ ++ if (!padapter->hw_init_completed) { ++ ret = -EPERM; ++ goto exit; ++ } ++ ++ switch (wrqu->mode) { ++ case IW_MODE_AUTO: ++ networkType = Ndis802_11AutoUnknown; ++ DBG_88E("set_mode = IW_MODE_AUTO\n"); ++ break; ++ case IW_MODE_ADHOC: ++ networkType = Ndis802_11IBSS; ++ DBG_88E("set_mode = IW_MODE_ADHOC\n"); ++ break; ++ case IW_MODE_MASTER: ++ networkType = Ndis802_11APMode; ++ DBG_88E("set_mode = IW_MODE_MASTER\n"); ++ break; ++ case IW_MODE_INFRA: ++ networkType = Ndis802_11Infrastructure; ++ DBG_88E("set_mode = IW_MODE_INFRA\n"); ++ break; ++ default: ++ ret = -EINVAL; ++ goto exit; ++ } ++ if (!rtw_set_802_11_infrastructure_mode(padapter, networkType)) { ++ ret = -EPERM; ++ goto exit; ++ } ++ rtw_setopmode_cmd(padapter, networkType); ++exit: ++ ++ return ret; ++} ++ ++static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a, ++ union iwreq_data *wrqu, char *b) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) ++ wrqu->mode = IW_MODE_INFRA; ++ else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) || ++ (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))) ++ wrqu->mode = IW_MODE_ADHOC; ++ else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ wrqu->mode = IW_MODE_MASTER; ++ else ++ wrqu->mode = IW_MODE_AUTO; ++ ++ ++ ++ return 0; ++} ++ ++static int rtw_wx_set_pmkid(struct net_device *dev, ++ struct iw_request_info *a, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u8 j, blInserted = false; ++ int ret = false; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct iw_pmksa *pPMK = (struct iw_pmksa *)extra; ++ u8 strZeroMacAddress[ETH_ALEN] = {0x00}; ++ u8 strIssueBssid[ETH_ALEN] = {0x00}; ++ ++ memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN); ++ if (pPMK->cmd == IW_PMKSA_ADD) { ++ DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n"); ++ if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN)) ++ return ret; ++ else ++ ret = true; ++ blInserted = false; ++ ++ /* overwrite PMKID */ ++ for (j = 0; j < NUM_PMKID_CACHE; j++) { ++ if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) { ++ /* BSSID is matched, the same AP => rewrite with new PMKID. */ ++ DBG_88E("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n"); ++ memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN); ++ psecuritypriv->PMKIDList[j].bUsed = true; ++ psecuritypriv->PMKIDIndex = j + 1; ++ blInserted = true; ++ break; ++ } ++ } ++ ++ if (!blInserted) { ++ /* Find a new entry */ ++ DBG_88E("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n", ++ psecuritypriv->PMKIDIndex); ++ ++ memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN); ++ memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN); ++ ++ psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = true; ++ psecuritypriv->PMKIDIndex++; ++ if (psecuritypriv->PMKIDIndex == 16) ++ psecuritypriv->PMKIDIndex = 0; ++ } ++ } else if (pPMK->cmd == IW_PMKSA_REMOVE) { ++ DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n"); ++ ret = true; ++ for (j = 0; j < NUM_PMKID_CACHE; j++) { ++ if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) { ++ /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */ ++ memset(psecuritypriv->PMKIDList[j].Bssid, 0x00, ETH_ALEN); ++ psecuritypriv->PMKIDList[j].bUsed = false; ++ break; ++ } ++ } ++ } else if (pPMK->cmd == IW_PMKSA_FLUSH) { ++ DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n"); ++ memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); ++ psecuritypriv->PMKIDIndex = 0; ++ ret = true; ++ } ++ return ret; ++} ++ ++static int rtw_wx_get_sens(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ wrqu->sens.value = 0; ++ wrqu->sens.fixed = 0; /* no auto select */ ++ wrqu->sens.disabled = 1; ++ return 0; ++} ++ ++static int rtw_wx_get_range(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct iw_range *range = (struct iw_range *)extra; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ u16 val; ++ int i; ++ ++ wrqu->data.length = sizeof(*range); ++ memset(range, 0, sizeof(*range)); ++ ++ /* Let's try to keep this struct in the same order as in ++ * linux/include/wireless.h ++ */ ++ ++ /* TODO: See what values we can set, and remove the ones we can't ++ * set, or fill them with some default data. ++ */ ++ ++ /* ~5 Mb/s real (802.11b) */ ++ range->throughput = 5 * 1000 * 1000; ++ ++ /* signal level threshold range */ ++ ++ /* percent values between 0 and 100. */ ++ range->max_qual.qual = 100; ++ range->max_qual.level = 100; ++ range->max_qual.noise = 100; ++ range->max_qual.updated = 7; /* Updated all three */ ++ ++ range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ ++ /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ ++ range->avg_qual.level = 178; /* -78 dBm */ ++ range->avg_qual.noise = 0; ++ range->avg_qual.updated = 7; /* Updated all three */ ++ ++ range->num_bitrates = RATE_COUNT; ++ ++ for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) ++ range->bitrate[i] = rtw_rates[i]; ++ ++ range->min_frag = MIN_FRAG_THRESHOLD; ++ range->max_frag = MAX_FRAG_THRESHOLD; ++ ++ range->pm_capa = 0; ++ ++ range->we_version_compiled = WIRELESS_EXT; ++ range->we_version_source = 16; ++ ++ for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) { ++ /* Include only legal frequencies for some countries */ ++ if (pmlmeext->channel_set[i].ChannelNum != 0) { ++ range->freq[val].i = pmlmeext->channel_set[i].ChannelNum; ++ range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000; ++ range->freq[val].e = 1; ++ val++; ++ } ++ ++ if (val == IW_MAX_FREQUENCIES) ++ break; ++ } ++ ++ range->num_channels = val; ++ range->num_frequency = val; ++ ++/* The following code will proivde the security capability to network manager. */ ++/* If the driver doesn't provide this capability to network manager, */ ++/* the WPA/WPA2 routers can't be chosen in the network manager. */ ++ ++/* ++#define IW_SCAN_CAPA_NONE 0x00 ++#define IW_SCAN_CAPA_ESSID 0x01 ++#define IW_SCAN_CAPA_BSSID 0x02 ++#define IW_SCAN_CAPA_CHANNEL 0x04 ++#define IW_SCAN_CAPA_MODE 0x08 ++#define IW_SCAN_CAPA_RATE 0x10 ++#define IW_SCAN_CAPA_TYPE 0x20 ++#define IW_SCAN_CAPA_TIME 0x40 ++*/ ++ ++ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | ++ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; ++ ++ range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | ++ IW_SCAN_CAPA_BSSID | IW_SCAN_CAPA_CHANNEL | ++ IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE; ++ ++ ++ return 0; ++} ++ ++/* set bssid flow */ ++/* s1. rtw_set_802_11_infrastructure_mode() */ ++/* s2. rtw_set_802_11_authentication_mode() */ ++/* s3. set_802_11_encryption_mode() */ ++/* s4. rtw_set_802_11_bssid() */ ++static int rtw_wx_set_wap(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *awrq, ++ char *extra) ++{ ++ uint ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct sockaddr *temp = (struct sockaddr *)awrq; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *phead; ++ u8 *dst_bssid, *src_bssid; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ enum ndis_802_11_auth_mode authmode; ++ ++ ++ ++ if (_FAIL == rtw_pwr_wakeup(padapter)) { ++ ret = -1; ++ goto exit; ++ } ++ ++ if (!padapter->bup) { ++ ret = -1; ++ goto exit; ++ } ++ ++ if (temp->sa_family != ARPHRD_ETHER) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ authmode = padapter->securitypriv.ndisauthtype; ++ spin_lock_bh(&queue->lock); ++ phead = get_list_head(queue); ++ pmlmepriv->pscanned = phead->next; ++ ++ while (phead != pmlmepriv->pscanned) { ++ ++ pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list); ++ ++ pmlmepriv->pscanned = pmlmepriv->pscanned->next; ++ ++ dst_bssid = pnetwork->network.MacAddress; ++ ++ src_bssid = temp->sa_data; ++ ++ if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) { ++ if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) { ++ ret = -1; ++ spin_unlock_bh(&queue->lock); ++ goto exit; ++ } ++ ++ break; ++ } ++ } ++ spin_unlock_bh(&queue->lock); ++ ++ rtw_set_802_11_authentication_mode(padapter, authmode); ++ /* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */ ++ if (!rtw_set_802_11_bssid(padapter, temp->sa_data)) { ++ ret = -1; ++ goto exit; ++ } ++ ++exit: ++ ++ ++ ++ return ret; ++} ++ ++static int rtw_wx_get_wap(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; ++ ++ wrqu->ap_addr.sa_family = ARPHRD_ETHER; ++ ++ memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED) || ++ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || ++ check_fwstate(pmlmepriv, WIFI_AP_STATE)) ++ memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN); ++ else ++ memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); ++ ++ ++ ++ return 0; ++} ++ ++static int rtw_wx_set_mlme(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ u16 reason; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct iw_mlme *mlme = (struct iw_mlme *)extra; ++ ++ if (!mlme) ++ return -1; ++ ++ DBG_88E("%s\n", __func__); ++ ++ reason = mlme->reason_code; ++ ++ DBG_88E("%s, cmd =%d, reason =%d\n", __func__, mlme->cmd, reason); ++ ++ switch (mlme->cmd) { ++ case IW_MLME_DEAUTH: ++ if (!rtw_set_802_11_disassociate(padapter)) ++ ret = -1; ++ break; ++ case IW_MLME_DISASSOC: ++ if (!rtw_set_802_11_disassociate(padapter)) ++ ret = -1; ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ return ret; ++} ++ ++static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, ++ union iwreq_data *wrqu, char *extra) ++{ ++ u8 _status = false; ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT]; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ if (padapter->registrypriv.mp_mode == 1) { ++ if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { ++ ret = -1; ++ goto exit; ++ } ++ } ++ if (_FAIL == rtw_pwr_wakeup(padapter)) { ++ ret = -1; ++ goto exit; ++ } ++ ++ if (padapter->bDriverStopped) { ++ DBG_88E("bDriverStopped =%d\n", padapter->bDriverStopped); ++ ret = -1; ++ goto exit; ++ } ++ ++ if (!padapter->bup) { ++ ret = -1; ++ goto exit; ++ } ++ ++ if (!padapter->hw_init_completed) { ++ ret = -1; ++ goto exit; ++ } ++ ++ /* When Busy Traffic, driver do not site survey. So driver return success. */ ++ /* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */ ++ /* modify by thomas 2011-02-22. */ ++ if (pmlmepriv->LinkDetectInfo.bBusyTraffic) { ++ indicate_wx_scan_complete_event(padapter); ++ goto exit; ++ } ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) { ++ indicate_wx_scan_complete_event(padapter); ++ goto exit; ++ } ++ ++/* For the DMP WiFi Display project, the driver won't to scan because */ ++/* the pmlmepriv->scan_interval is always equal to 3. */ ++/* So, the wpa_supplicant won't find out the WPS SoftAP. */ ++ ++#ifdef CONFIG_88EU_P2P ++ if (pwdinfo->p2p_state != P2P_STATE_NONE) { ++ rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH); ++ rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL); ++ rtw_free_network_queue(padapter, true); ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ memset(ssid, 0, sizeof(struct ndis_802_11_ssid) * RTW_SSID_SCAN_AMOUNT); ++ ++ if (wrqu->data.length == sizeof(struct iw_scan_req)) { ++ struct iw_scan_req *req = (struct iw_scan_req *)extra; ++ ++ if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { ++ int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE); ++ ++ memcpy(ssid[0].Ssid, req->essid, len); ++ ssid[0].SsidLength = len; ++ ++ DBG_88E("IW_SCAN_THIS_ESSID, ssid =%s, len =%d\n", req->essid, req->essid_len); ++ ++ spin_lock_bh(&pmlmepriv->lock); ++ ++ _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0); ++ ++ spin_unlock_bh(&pmlmepriv->lock); ++ } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { ++ DBG_88E("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n"); ++ } ++ } else { ++ if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE && ++ !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) { ++ int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE; ++ char *pos = extra + WEXT_CSCAN_HEADER_SIZE; ++ char section; ++ char sec_len; ++ int ssid_index = 0; ++ ++ while (len >= 1) { ++ section = *(pos++); ++ len -= 1; ++ ++ switch (section) { ++ case WEXT_CSCAN_SSID_SECTION: ++ if (len < 1) { ++ len = 0; ++ break; ++ } ++ sec_len = *(pos++); len -= 1; ++ if (sec_len > 0 && sec_len <= len) { ++ ssid[ssid_index].SsidLength = sec_len; ++ memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength); ++ ssid_index++; ++ } ++ pos += sec_len; ++ len -= sec_len; ++ break; ++ case WEXT_CSCAN_TYPE_SECTION: ++ case WEXT_CSCAN_CHANNEL_SECTION: ++ pos += 1; ++ len -= 1; ++ break; ++ case WEXT_CSCAN_PASV_DWELL_SECTION: ++ case WEXT_CSCAN_HOME_DWELL_SECTION: ++ case WEXT_CSCAN_ACTV_DWELL_SECTION: ++ pos += 2; ++ len -= 2; ++ break; ++ default: ++ len = 0; /* stop parsing */ ++ } ++ } ++ ++ /* it has still some scan parameter to parse, we only do this now... */ ++ _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT); ++ } else { ++ _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0); ++ } ++ } ++ ++ if (!_status) ++ ret = -1; ++ ++exit: ++ ++ return ret; ++} ++ ++static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct list_head *plist, *phead; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ char *ev = extra; ++ char *stop = ev + wrqu->data.length; ++ u32 ret = 0; ++ u32 cnt = 0; ++ u32 wait_for_surveydone; ++ int wait_status; ++#ifdef CONFIG_88EU_P2P ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++#endif /* CONFIG_88EU_P2P */ ++ ++ if (padapter->pwrctrlpriv.brfoffbyhw && padapter->bDriverStopped) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++#ifdef CONFIG_88EU_P2P ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ++ /* P2P is enabled */ ++ wait_for_surveydone = 200; ++ } else { ++ /* P2P is disabled */ ++ wait_for_surveydone = 100; ++ } ++#else ++ { ++ wait_for_surveydone = 100; ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ wait_status = _FW_UNDER_SURVEY | _FW_UNDER_LINKING; ++ ++ while (check_fwstate(pmlmepriv, wait_status)) { ++ msleep(30); ++ cnt++; ++ if (cnt > wait_for_surveydone) ++ break; ++ } ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ if ((stop - ev) < SCAN_ITEM_SIZE) { ++ ret = -E2BIG; ++ break; ++ } ++ ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ /* report network only if the current channel set contains the channel to which this network belongs */ ++ if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0) ++ ev = translate_scan(padapter, a, pnetwork, ev, stop); ++ ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ wrqu->data.length = ev - extra; ++ wrqu->data.flags = 0; ++ ++exit: ++ ++ return ret; ++} ++ ++/* set ssid flow */ ++/* s1. rtw_set_802_11_infrastructure_mode() */ ++/* s2. set_802_11_authenticaion_mode() */ ++/* s3. set_802_11_encryption_mode() */ ++/* s4. rtw_set_802_11_ssid() */ ++static int rtw_wx_set_essid(struct net_device *dev, ++ struct iw_request_info *a, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct list_head *phead; ++ struct wlan_network *pnetwork = NULL; ++ enum ndis_802_11_auth_mode authmode; ++ struct ndis_802_11_ssid ndis_ssid; ++ u8 *dst_ssid, *src_ssid; ++ ++ uint ret = 0, len; ++ ++ if (_FAIL == rtw_pwr_wakeup(padapter)) { ++ ret = -1; ++ goto exit; ++ } ++ ++ if (!padapter->bup) { ++ ret = -1; ++ goto exit; ++ } ++ ++ if (wrqu->essid.length > IW_ESSID_MAX_SIZE) { ++ ret = -E2BIG; ++ goto exit; ++ } ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ ret = -1; ++ goto exit; ++ } ++ ++ authmode = padapter->securitypriv.ndisauthtype; ++ DBG_88E("=>%s\n", __func__); ++ if (wrqu->essid.flags && wrqu->essid.length) { ++ len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE; ++ ++ if (wrqu->essid.length != 33) ++ DBG_88E("ssid =%s, len =%d\n", extra, wrqu->essid.length); ++ ++ memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid)); ++ ndis_ssid.SsidLength = len; ++ memcpy(ndis_ssid.Ssid, extra, len); ++ src_ssid = ndis_ssid.Ssid; ++ ++ spin_lock_bh(&queue->lock); ++ phead = get_list_head(queue); ++ pmlmepriv->pscanned = phead->next; ++ ++ while (phead != pmlmepriv->pscanned) { ++ pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list); ++ ++ pmlmepriv->pscanned = pmlmepriv->pscanned->next; ++ ++ dst_ssid = pnetwork->network.Ssid.Ssid; ++ ++ if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) && ++ (pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) { ++ ++ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { ++ if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode) ++ continue; ++ } ++ ++ if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) { ++ ret = -1; ++ spin_unlock_bh(&queue->lock); ++ goto exit; ++ } ++ ++ break; ++ } ++ } ++ spin_unlock_bh(&queue->lock); ++ rtw_set_802_11_authentication_mode(padapter, authmode); ++ if (!rtw_set_802_11_ssid(padapter, &ndis_ssid)) { ++ ret = -1; ++ goto exit; ++ } ++ } ++ ++exit: ++ ++ DBG_88E("<=%s, ret %d\n", __func__, ret); ++ ++ ++ ++ return ret; ++} ++ ++static int rtw_wx_get_essid(struct net_device *dev, ++ struct iw_request_info *a, ++ union iwreq_data *wrqu, char *extra) ++{ ++ u32 len, ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; ++ ++ if ((check_fwstate(pmlmepriv, _FW_LINKED)) || ++ (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) { ++ len = pcur_bss->Ssid.SsidLength; ++ memcpy(extra, pcur_bss->Ssid.Ssid, len); ++ } else { ++ len = 0; ++ *extra = 0; ++ } ++ wrqu->essid.length = len; ++ wrqu->essid.flags = 1; ++ ++ return ret; ++} ++ ++static int rtw_wx_set_rate(struct net_device *dev, ++ struct iw_request_info *a, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int i, ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u8 datarates[NumRates]; ++ u32 target_rate = wrqu->bitrate.value; ++ u32 fixed = wrqu->bitrate.fixed; ++ u32 ratevalue = 0; ++ u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff}; ++ ++ if (target_rate == -1) { ++ ratevalue = 11; ++ goto set_rate; ++ } ++ target_rate = target_rate / 100000; ++ ++ switch (target_rate) { ++ case 10: ++ ratevalue = 0; ++ break; ++ case 20: ++ ratevalue = 1; ++ break; ++ case 55: ++ ratevalue = 2; ++ break; ++ case 60: ++ ratevalue = 3; ++ break; ++ case 90: ++ ratevalue = 4; ++ break; ++ case 110: ++ ratevalue = 5; ++ break; ++ case 120: ++ ratevalue = 6; ++ break; ++ case 180: ++ ratevalue = 7; ++ break; ++ case 240: ++ ratevalue = 8; ++ break; ++ case 360: ++ ratevalue = 9; ++ break; ++ case 480: ++ ratevalue = 10; ++ break; ++ case 540: ++ ratevalue = 11; ++ break; ++ default: ++ ratevalue = 11; ++ break; ++ } ++ ++set_rate: ++ ++ for (i = 0; i < NumRates; i++) { ++ if (ratevalue == mpdatarate[i]) { ++ datarates[i] = mpdatarate[i]; ++ if (fixed == 0) ++ break; ++ } else { ++ datarates[i] = 0xff; ++ } ++ } ++ ++ if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS) ++ ret = -1; ++ ++ return ret; ++} ++ ++static int rtw_wx_get_rate(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ u16 max_rate = 0; ++ ++ max_rate = rtw_get_cur_max_rate((struct adapter *)rtw_netdev_priv(dev)); ++ ++ if (max_rate == 0) ++ return -EPERM; ++ ++ wrqu->bitrate.fixed = 0; /* no auto select */ ++ wrqu->bitrate.value = max_rate * 100000; ++ ++ return 0; ++} ++ ++static int rtw_wx_set_rts(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ ++ ++ if (wrqu->rts.disabled) { ++ padapter->registrypriv.rts_thresh = 2347; ++ } else { ++ if (wrqu->rts.value < 0 || ++ wrqu->rts.value > 2347) ++ return -EINVAL; ++ ++ padapter->registrypriv.rts_thresh = wrqu->rts.value; ++ } ++ ++ DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh); ++ ++ ++ ++ return 0; ++} ++ ++static int rtw_wx_get_rts(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ ++ ++ DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh); ++ ++ wrqu->rts.value = padapter->registrypriv.rts_thresh; ++ wrqu->rts.fixed = 0; /* no auto select */ ++ /* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */ ++ ++ ++ ++ return 0; ++} ++ ++static int rtw_wx_set_frag(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ ++ ++ if (wrqu->frag.disabled) { ++ padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD; ++ } else { ++ if (wrqu->frag.value < MIN_FRAG_THRESHOLD || ++ wrqu->frag.value > MAX_FRAG_THRESHOLD) ++ return -EINVAL; ++ ++ padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1; ++ } ++ ++ DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len); ++ ++ ++ ++ return 0; ++} ++ ++static int rtw_wx_get_frag(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ ++ ++ DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len); ++ ++ wrqu->frag.value = padapter->xmitpriv.frag_len; ++ wrqu->frag.fixed = 0; /* no auto select */ ++ ++ ++ ++ return 0; ++} ++ ++static int rtw_wx_get_retry(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ wrqu->retry.value = 7; ++ wrqu->retry.fixed = 0; /* no auto select */ ++ wrqu->retry.disabled = 1; ++ ++ return 0; ++} ++ ++static int rtw_wx_set_enc(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *keybuf) ++{ ++ u32 key, ret = 0; ++ u32 keyindex_provided; ++ struct ndis_802_11_wep wep; ++ enum ndis_802_11_auth_mode authmode; ++ ++ struct iw_point *erq = &wrqu->encoding; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ DBG_88E("+rtw_wx_set_enc, flags = 0x%x\n", erq->flags); ++ ++ memset(&wep, 0, sizeof(struct ndis_802_11_wep)); ++ ++ key = erq->flags & IW_ENCODE_INDEX; ++ ++ ++ ++ if (erq->flags & IW_ENCODE_DISABLED) { ++ DBG_88E("EncryptionDisabled\n"); ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; ++ padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ ++ authmode = Ndis802_11AuthModeOpen; ++ padapter->securitypriv.ndisauthtype = authmode; ++ ++ goto exit; ++ } ++ ++ if (key) { ++ if (key > WEP_KEYS) ++ return -EINVAL; ++ key--; ++ keyindex_provided = 1; ++ } else { ++ keyindex_provided = 0; ++ key = padapter->securitypriv.dot11PrivacyKeyIndex; ++ DBG_88E("rtw_wx_set_enc, key =%d\n", key); ++ } ++ ++ /* set authentication mode */ ++ if (erq->flags & IW_ENCODE_OPEN) { ++ DBG_88E("rtw_wx_set_enc():IW_ENCODE_OPEN\n"); ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */ ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; ++ padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; ++ authmode = Ndis802_11AuthModeOpen; ++ padapter->securitypriv.ndisauthtype = authmode; ++ } else if (erq->flags & IW_ENCODE_RESTRICTED) { ++ DBG_88E("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n"); ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; ++ padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_; ++ authmode = Ndis802_11AuthModeShared; ++ padapter->securitypriv.ndisauthtype = authmode; ++ } else { ++ DBG_88E("rtw_wx_set_enc():erq->flags = 0x%x\n", erq->flags); ++ ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */ ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ ++ padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; ++ authmode = Ndis802_11AuthModeOpen; ++ padapter->securitypriv.ndisauthtype = authmode; ++ } ++ ++ wep.KeyIndex = key; ++ if (erq->length > 0) { ++ wep.KeyLength = erq->length <= 5 ? 5 : 13; ++ ++ wep.Length = wep.KeyLength + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial); ++ } else { ++ wep.KeyLength = 0; ++ ++ if (keyindex_provided == 1) { ++ /* set key_id only, no given KeyMaterial(erq->length == 0). */ ++ padapter->securitypriv.dot11PrivacyKeyIndex = key; ++ ++ DBG_88E("(keyindex_provided == 1), keyid =%d, key_len =%d\n", key, padapter->securitypriv.dot11DefKeylen[key]); ++ ++ switch (padapter->securitypriv.dot11DefKeylen[key]) { ++ case 5: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_; ++ break; ++ case 13: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_; ++ break; ++ default: ++ padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ break; ++ } ++ ++ goto exit; ++ } ++ } ++ ++ wep.KeyIndex |= 0x80000000; ++ ++ memcpy(wep.KeyMaterial, keybuf, wep.KeyLength); ++ ++ if (!rtw_set_802_11_add_wep(padapter, &wep)) { ++ if (rf_on == pwrpriv->rf_pwrstate) ++ ret = -EOPNOTSUPP; ++ goto exit; ++ } ++ ++exit: ++ ++ ++ ++ return ret; ++} ++ ++static int rtw_wx_get_enc(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *keybuf) ++{ ++ uint key, ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct iw_point *erq = &wrqu->encoding; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED) != true) { ++ if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { ++ erq->length = 0; ++ erq->flags |= IW_ENCODE_DISABLED; ++ return 0; ++ } ++ } ++ ++ key = erq->flags & IW_ENCODE_INDEX; ++ ++ if (key) { ++ if (key > WEP_KEYS) ++ return -EINVAL; ++ key--; ++ } else { ++ key = padapter->securitypriv.dot11PrivacyKeyIndex; ++ } ++ ++ erq->flags = key + 1; ++ ++ switch (padapter->securitypriv.ndisencryptstatus) { ++ case Ndis802_11EncryptionNotSupported: ++ case Ndis802_11EncryptionDisabled: ++ erq->length = 0; ++ erq->flags |= IW_ENCODE_DISABLED; ++ break; ++ case Ndis802_11Encryption1Enabled: ++ erq->length = padapter->securitypriv.dot11DefKeylen[key]; ++ if (erq->length) { ++ memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]); ++ ++ erq->flags |= IW_ENCODE_ENABLED; ++ ++ if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) ++ erq->flags |= IW_ENCODE_OPEN; ++ else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared) ++ erq->flags |= IW_ENCODE_RESTRICTED; ++ } else { ++ erq->length = 0; ++ erq->flags |= IW_ENCODE_DISABLED; ++ } ++ break; ++ case Ndis802_11Encryption2Enabled: ++ case Ndis802_11Encryption3Enabled: ++ erq->length = 16; ++ erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY); ++ break; ++ default: ++ erq->length = 0; ++ erq->flags |= IW_ENCODE_DISABLED; ++ break; ++ } ++ ++ ++ return ret; ++} ++ ++static int rtw_wx_get_power(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ wrqu->power.value = 0; ++ wrqu->power.fixed = 0; /* no auto select */ ++ wrqu->power.disabled = 1; ++ ++ return 0; ++} ++ ++static int rtw_wx_set_gen_ie(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length); ++ return ret; ++} ++ ++static int rtw_wx_set_auth(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct iw_param *param = (struct iw_param *)&wrqu->param; ++ int ret = 0; ++ ++ switch (param->flags & IW_AUTH_INDEX) { ++ case IW_AUTH_WPA_VERSION: ++ break; ++ case IW_AUTH_CIPHER_PAIRWISE: ++ ++ break; ++ case IW_AUTH_CIPHER_GROUP: ++ ++ break; ++ case IW_AUTH_KEY_MGMT: ++ /* ++ * ??? does not use these parameters ++ */ ++ break; ++ case IW_AUTH_TKIP_COUNTERMEASURES: ++ if (param->value) { ++ /* wpa_supplicant is enabling the tkip countermeasure. */ ++ padapter->securitypriv.btkip_countermeasure = true; ++ } else { ++ /* wpa_supplicant is disabling the tkip countermeasure. */ ++ padapter->securitypriv.btkip_countermeasure = false; ++ } ++ break; ++ case IW_AUTH_DROP_UNENCRYPTED: ++ /* HACK: ++ * ++ * wpa_supplicant calls set_wpa_enabled when the driver ++ * is loaded and unloaded, regardless of if WPA is being ++ * used. No other calls are made which can be used to ++ * determine if encryption will be used or not prior to ++ * association being expected. If encryption is not being ++ * used, drop_unencrypted is set to false, else true -- we ++ * can use this to determine if the CAP_PRIVACY_ON bit should ++ * be set. ++ */ ++ ++ if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled) ++ break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */ ++ /* then it needn't reset it; */ ++ ++ if (param->value) { ++ padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; ++ padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_; ++ padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ ++ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; ++ } ++ ++ break; ++ case IW_AUTH_80211_AUTH_ALG: ++ /* ++ * It's the starting point of a link layer connection using wpa_supplicant ++ */ ++ if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { ++ LeaveAllPowerSaveMode(padapter); ++ rtw_disassoc_cmd(padapter, 500, false); ++ DBG_88E("%s...call rtw_indicate_disconnect\n ", __func__); ++ rtw_indicate_disconnect(padapter); ++ rtw_free_assoc_resources(padapter, 1); ++ } ++ ret = wpa_set_auth_algs(dev, (u32)param->value); ++ break; ++ case IW_AUTH_WPA_ENABLED: ++ break; ++ case IW_AUTH_RX_UNENCRYPTED_EAPOL: ++ break; ++ case IW_AUTH_PRIVACY_INVOKED: ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return ret; ++} ++ ++static int rtw_wx_set_enc_ext(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ char *alg_name; ++ u32 param_len; ++ struct ieee_param *param = NULL; ++ struct iw_point *pencoding = &wrqu->encoding; ++ struct iw_encode_ext *pext = (struct iw_encode_ext *)extra; ++ int ret = 0; ++ ++ param_len = sizeof(struct ieee_param) + pext->key_len; ++ param = kzalloc(param_len, GFP_KERNEL); ++ if (!param) ++ return -ENOMEM; ++ ++ param->cmd = IEEE_CMD_SET_ENCRYPTION; ++ memset(param->sta_addr, 0xff, ETH_ALEN); ++ ++ switch (pext->alg) { ++ case IW_ENCODE_ALG_NONE: ++ /* todo: remove key */ ++ /* remove = 1; */ ++ alg_name = "none"; ++ break; ++ case IW_ENCODE_ALG_WEP: ++ alg_name = "WEP"; ++ break; ++ case IW_ENCODE_ALG_TKIP: ++ alg_name = "TKIP"; ++ break; ++ case IW_ENCODE_ALG_CCMP: ++ alg_name = "CCMP"; ++ break; ++ default: ++ return -1; ++ } ++ ++ strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN); ++ ++ if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) ++ param->u.crypt.set_tx = 1; ++ ++ /* cliW: WEP does not have group key ++ * just not checking GROUP key setting ++ */ ++ if ((pext->alg != IW_ENCODE_ALG_WEP) && ++ (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)) ++ param->u.crypt.set_tx = 0; ++ ++ param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1; ++ ++ if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) ++ memcpy(param->u.crypt.seq, pext->rx_seq, 8); ++ ++ if (pext->key_len) { ++ param->u.crypt.key_len = pext->key_len; ++ memcpy(param->u.crypt.key, pext + 1, pext->key_len); ++ } ++ ++ ret = wpa_set_encryption(dev, param, param_len); ++ ++ kfree(param); ++ return ret; ++} ++ ++static int rtw_wx_get_nick(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ if (extra) { ++ wrqu->data.length = 14; ++ wrqu->data.flags = 1; ++ memcpy(extra, "", 14); ++ } ++ ++ /* dump debug info here */ ++ return 0; ++} ++ ++static int rtw_wx_read32(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter; ++ struct iw_point *p; ++ u16 len; ++ u32 addr; ++ u32 data32; ++ u32 bytes; ++ u8 *ptmp; ++ ++ padapter = (struct adapter *)rtw_netdev_priv(dev); ++ p = &wrqu->data; ++ len = p->length; ++ ptmp = kmalloc(len, GFP_KERNEL); ++ if (!ptmp) ++ return -ENOMEM; ++ ++ if (copy_from_user(ptmp, p->pointer, len)) { ++ kfree(ptmp); ++ return -EFAULT; ++ } ++ ++ bytes = 0; ++ addr = 0; ++ sscanf(ptmp, "%d,%x", &bytes, &addr); ++ ++ switch (bytes) { ++ case 1: ++ data32 = rtw_read8(padapter, addr); ++ sprintf(extra, "0x%02X", data32); ++ break; ++ case 2: ++ data32 = rtw_read16(padapter, addr); ++ sprintf(extra, "0x%04X", data32); ++ break; ++ case 4: ++ data32 = rtw_read32(padapter, addr); ++ sprintf(extra, "0x%08X", data32); ++ break; ++ default: ++ DBG_88E(KERN_INFO "%s: usage> read [bytes],[address(hex)]\n", __func__); ++ return -EINVAL; ++ } ++ DBG_88E(KERN_INFO "%s: addr = 0x%08X data =%s\n", __func__, addr, extra); ++ ++ kfree(ptmp); ++ return 0; ++} ++ ++static int rtw_wx_write32(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ u32 addr; ++ u32 data32; ++ u32 bytes; ++ ++ bytes = 0; ++ addr = 0; ++ data32 = 0; ++ sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32); ++ ++ switch (bytes) { ++ case 1: ++ rtw_write8(padapter, addr, (u8)data32); ++ DBG_88E(KERN_INFO "%s: addr = 0x%08X data = 0x%02X\n", __func__, addr, (u8)data32); ++ break; ++ case 2: ++ rtw_write16(padapter, addr, (u16)data32); ++ DBG_88E(KERN_INFO "%s: addr = 0x%08X data = 0x%04X\n", __func__, addr, (u16)data32); ++ break; ++ case 4: ++ rtw_write32(padapter, addr, data32); ++ DBG_88E(KERN_INFO "%s: addr = 0x%08X data = 0x%08X\n", __func__, addr, data32); ++ break; ++ default: ++ DBG_88E(KERN_INFO "%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int rtw_wx_read_rf(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u32 path, addr, data32; ++ ++ path = *(u32 *)extra; ++ addr = *((u32 *)extra + 1); ++ data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF); ++ /* ++ * IMPORTANT!! ++ * Only when wireless private ioctl is at odd order, ++ * "extra" would be copied to user space. ++ */ ++ sprintf(extra, "0x%05x", data32); ++ ++ return 0; ++} ++ ++static int rtw_wx_write_rf(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u32 path, addr, data32; ++ ++ path = *(u32 *)extra; ++ addr = *((u32 *)extra + 1); ++ data32 = *((u32 *)extra + 2); ++ rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32); ++ ++ return 0; ++} ++ ++static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a, ++ union iwreq_data *wrqu, char *b) ++{ ++ return -1; ++} ++ ++static int dummy(struct net_device *dev, struct iw_request_info *a, ++ union iwreq_data *wrqu, char *b) ++{ ++ return -1; ++} ++ ++static int rtw_wx_set_channel_plan(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 channel_plan_req = (u8)(*((int *)wrqu)); ++ ++ if (_SUCCESS == rtw_set_chplan_cmd(padapter, channel_plan_req, 1)) ++ DBG_88E("%s set channel_plan = 0x%02X\n", __func__, pmlmepriv->ChannelPlan); ++ else ++ return -EPERM; ++ ++ return 0; ++} ++ ++static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev, ++ struct iw_request_info *a, ++ union iwreq_data *wrqu, char *b) ++{ ++ return 0; ++} ++ ++static int rtw_wx_get_sensitivity(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *buf) ++{ ++ return 0; ++} ++ ++static int rtw_wx_set_mtk_wps_ie(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ return 0; ++} ++ ++/* ++ * For all data larger than 16 octets, we need to use a ++ * pointer to memory allocated in user space. ++ */ ++static int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ return 0; ++} ++ ++static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 len) ++{ ++ struct mp_rw_reg *RegRWStruct; ++ struct rf_reg_param *prfreg; ++ u8 path; ++ u8 offset; ++ u32 value; ++ ++ DBG_88E("%s\n", __func__); ++ ++ switch (id) { ++ case GEN_MP_IOCTL_SUBCODE(MP_START): ++ DBG_88E("871x_driver is only for normal mode, can't enter mp mode\n"); ++ break; ++ case GEN_MP_IOCTL_SUBCODE(READ_REG): ++ RegRWStruct = (struct mp_rw_reg *)pdata; ++ switch (RegRWStruct->width) { ++ case 1: ++ RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset); ++ break; ++ case 2: ++ RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset); ++ break; ++ case 4: ++ RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset); ++ break; ++ default: ++ break; ++ } ++ ++ break; ++ case GEN_MP_IOCTL_SUBCODE(WRITE_REG): ++ RegRWStruct = (struct mp_rw_reg *)pdata; ++ switch (RegRWStruct->width) { ++ case 1: ++ rtw_write8(padapter, RegRWStruct->offset, (u8)RegRWStruct->value); ++ break; ++ case 2: ++ rtw_write16(padapter, RegRWStruct->offset, (u16)RegRWStruct->value); ++ break; ++ case 4: ++ rtw_write32(padapter, RegRWStruct->offset, (u32)RegRWStruct->value); ++ break; ++ default: ++ break; ++ } ++ ++ break; ++ case GEN_MP_IOCTL_SUBCODE(READ_RF_REG): ++ ++ prfreg = (struct rf_reg_param *)pdata; ++ ++ path = (u8)prfreg->path; ++ offset = (u8)prfreg->offset; ++ ++ value = rtw_hal_read_rfreg(padapter, path, offset, 0xffffffff); ++ ++ prfreg->value = value; ++ ++ break; ++ case GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG): ++ ++ prfreg = (struct rf_reg_param *)pdata; ++ ++ path = (u8)prfreg->path; ++ offset = (u8)prfreg->offset; ++ value = prfreg->value; ++ ++ rtw_hal_write_rfreg(padapter, path, offset, 0xffffffff, value); ++ ++ break; ++ case GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO): ++ DBG_88E("==> trigger gpio 0\n"); ++ rtw_hal_set_hwreg(padapter, HW_VAR_TRIGGER_GPIO_0, NULL); ++ break; ++ case GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS): ++ *pdata = rtw_hal_sreset_get_wifi_status(padapter); ++ break; ++ default: ++ break; ++ } ++} ++ ++static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ u32 BytesRead, BytesWritten, BytesNeeded; ++ struct oid_par_priv oid_par; ++ struct mp_ioctl_handler *phandler; ++ struct mp_ioctl_param *poidparam; ++ uint status = 0; ++ u16 len; ++ u8 *pparmbuf = NULL, bset; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct iw_point *p = &wrqu->data; ++ ++ if ((!p->length) || (!p->pointer)) { ++ ret = -EINVAL; ++ goto _rtw_mp_ioctl_hdl_exit; ++ } ++ pparmbuf = NULL; ++ bset = (u8)(p->flags & 0xFFFF); ++ len = p->length; ++ pparmbuf = kmalloc(len, GFP_KERNEL); ++ if (!pparmbuf) { ++ ret = -ENOMEM; ++ goto _rtw_mp_ioctl_hdl_exit; ++ } ++ ++ if (copy_from_user(pparmbuf, p->pointer, len)) { ++ ret = -EFAULT; ++ goto _rtw_mp_ioctl_hdl_exit; ++ } ++ ++ poidparam = (struct mp_ioctl_param *)pparmbuf; ++ ++ if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) { ++ ret = -EINVAL; ++ goto _rtw_mp_ioctl_hdl_exit; ++ } ++ ++ if (padapter->registrypriv.mp_mode == 1) { ++ phandler = mp_ioctl_hdl + poidparam->subcode; ++ ++ if ((phandler->paramsize != 0) && (poidparam->len < phandler->paramsize)) { ++ ret = -EINVAL; ++ goto _rtw_mp_ioctl_hdl_exit; ++ } ++ ++ if (phandler->handler) { ++ oid_par.adapter_context = padapter; ++ oid_par.oid = phandler->oid; ++ oid_par.information_buf = poidparam->data; ++ oid_par.information_buf_len = poidparam->len; ++ oid_par.dbg = 0; ++ ++ BytesWritten = 0; ++ BytesNeeded = 0; ++ ++ if (bset) { ++ oid_par.bytes_rw = &BytesRead; ++ oid_par.bytes_needed = &BytesNeeded; ++ oid_par.type_of_oid = SET_OID; ++ } else { ++ oid_par.bytes_rw = &BytesWritten; ++ oid_par.bytes_needed = &BytesNeeded; ++ oid_par.type_of_oid = QUERY_OID; ++ } ++ ++ status = phandler->handler(&oid_par); ++ } else { ++ DBG_88E("rtw_mp_ioctl_hdl(): err!, subcode =%d, oid =%d, handler =%p\n", ++ poidparam->subcode, phandler->oid, phandler->handler); ++ ret = -EFAULT; ++ goto _rtw_mp_ioctl_hdl_exit; ++ } ++ } else { ++ rtw_dbg_mode_hdl(padapter, poidparam->subcode, poidparam->data, poidparam->len); ++ } ++ ++ if (bset == 0x00) {/* query info */ ++ if (copy_to_user(p->pointer, pparmbuf, len)) ++ ret = -EFAULT; ++ } ++ ++ if (status) { ++ ret = -EFAULT; ++ goto _rtw_mp_ioctl_hdl_exit; ++ } ++ ++_rtw_mp_ioctl_hdl_exit: ++ ++ kfree(pparmbuf); ++ return ret; ++} ++ ++static int rtw_get_ap_info(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ u32 cnt = 0, wpa_ielen; ++ struct list_head *plist, *phead; ++ unsigned char *pbuf; ++ u8 bssid[ETH_ALEN]; ++ char data[32]; ++ struct wlan_network *pnetwork = NULL; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct iw_point *pdata = &wrqu->data; ++ ++ DBG_88E("+rtw_get_aplist_info\n"); ++ ++ if (padapter->bDriverStopped || !pdata) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING)))) { ++ msleep(30); ++ cnt++; ++ if (cnt > 100) ++ break; ++ } ++ pdata->flags = 0; ++ if (pdata->length >= 32) { ++ if (copy_from_user(data, pdata->pointer, 32)) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ } else { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ if (!mac_pton(data, bssid)) { ++ DBG_88E("Invalid BSSID '%s'.\n", (u8 *)data); ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ return -EINVAL; ++ } ++ ++ if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) { ++ /* BSSID match, then check if supporting wpa/wpa2 */ ++ DBG_88E("BSSID:%pM\n", (bssid)); ++ ++ pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12); ++ if (pbuf && (wpa_ielen > 0)) { ++ pdata->flags = 1; ++ break; ++ } ++ ++ pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12); ++ if (pbuf && (wpa_ielen > 0)) { ++ pdata->flags = 2; ++ break; ++ } ++ } ++ ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (pdata->length >= 34) { ++ if (copy_to_user(pdata->pointer + 32, (u8 *)&pdata->flags, 1)) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ } ++ ++exit: ++ ++ return ret; ++} ++ ++static int rtw_set_pid(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ int *pdata = (int *)wrqu; ++ int selector; ++ ++ if (padapter->bDriverStopped || !pdata) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ selector = *pdata; ++ if (selector < 3 && selector >= 0) { ++ padapter->pid[selector] = *(pdata + 1); ++ ui_pid[selector] = *(pdata + 1); ++ DBG_88E("%s set pid[%d] =%d\n", __func__, selector, padapter->pid[selector]); ++ } else { ++ DBG_88E("%s selector %d error\n", __func__, selector); ++ } ++exit: ++ return ret; ++} ++ ++static int rtw_wps_start(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct iw_point *pdata = &wrqu->data; ++ u32 u32wps_start = 0; ++ ++ if (!pdata) ++ return -EINVAL; ++ ret = copy_from_user((void *)&u32wps_start, pdata->pointer, 4); ++ if (ret) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ if (padapter->bDriverStopped) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ if (u32wps_start == 0) ++ u32wps_start = *extra; ++ ++ DBG_88E("[%s] wps_start = %d\n", __func__, u32wps_start); ++ ++ if (u32wps_start == 1) /* WPS Start */ ++ rtw_led_control(padapter, LED_CTL_START_WPS); ++ else if (u32wps_start == 2) /* WPS Stop because of wps success */ ++ rtw_led_control(padapter, LED_CTL_STOP_WPS); ++ else if (u32wps_start == 3) /* WPS Stop because of wps fail */ ++ rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL); ++ ++exit: ++ return ret; ++} ++ ++#ifdef CONFIG_88EU_P2P ++static int rtw_wext_p2p_enable(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ enum P2P_ROLE init_role = P2P_ROLE_DISABLE; ++ ++ if (*extra == '0') ++ init_role = P2P_ROLE_DISABLE; ++ else if (*extra == '1') ++ init_role = P2P_ROLE_DEVICE; ++ else if (*extra == '2') ++ init_role = P2P_ROLE_CLIENT; ++ else if (*extra == '3') ++ init_role = P2P_ROLE_GO; ++ ++ if (_FAIL == rtw_p2p_enable(padapter, init_role)) { ++ ret = -EFAULT; ++ goto exit; ++ } ++ ++ /* set channel/bandwidth */ ++ if (init_role != P2P_ROLE_DISABLE) { ++ u8 channel, ch_offset; ++ u16 bwmode; ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) { ++ /* Stay at the listen state and wait for discovery. */ ++ channel = pwdinfo->listen_channel; ++ pwdinfo->operating_channel = pwdinfo->listen_channel; ++ ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; ++ bwmode = HT_CHANNEL_WIDTH_20; ++ } else { ++ pwdinfo->operating_channel = pmlmeext->cur_channel; ++ ++ channel = pwdinfo->operating_channel; ++ ch_offset = pmlmeext->cur_ch_offset; ++ bwmode = pmlmeext->cur_bwmode; ++ } ++ ++ set_channel_bwmode(padapter, channel, ch_offset, bwmode); ++ } ++ ++exit: ++ return ret; ++} ++ ++static int rtw_p2p_set_go_nego_ssid(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] ssid = %s, len = %zu\n", __func__, extra, strlen(extra)); ++ memcpy(pwdinfo->nego_ssid, extra, strlen(extra)); ++ pwdinfo->nego_ssidlen = strlen(extra); ++ ++ return ret; ++} ++ ++static int rtw_p2p_set_intent(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 intent = pwdinfo->intent; ++ ++ switch (wrqu->data.length) { ++ case 1: ++ intent = extra[0] - '0'; ++ break; ++ case 2: ++ intent = str_2char2num(extra[0], extra[1]); ++ break; ++ } ++ if (intent <= 15) ++ pwdinfo->intent = intent; ++ else ++ ret = -1; ++ DBG_88E("[%s] intent = %d\n", __func__, intent); ++ return ret; ++} ++ ++static int rtw_p2p_set_listen_ch(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 listen_ch = pwdinfo->listen_channel; /* Listen channel number */ ++ ++ switch (wrqu->data.length) { ++ case 1: ++ listen_ch = extra[0] - '0'; ++ break; ++ case 2: ++ listen_ch = str_2char2num(extra[0], extra[1]); ++ break; ++ } ++ ++ if ((listen_ch == 1) || (listen_ch == 6) || (listen_ch == 11)) { ++ pwdinfo->listen_channel = listen_ch; ++ set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ } else { ++ ret = -1; ++ } ++ ++ DBG_88E("[%s] listen_ch = %d\n", __func__, pwdinfo->listen_channel); ++ ++ return ret; ++} ++ ++static int rtw_p2p_set_op_ch(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++/* Commented by Albert 20110524 */ ++/* This function is used to set the operating channel if the driver will become the group owner */ ++ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 op_ch = pwdinfo->operating_channel; /* Operating channel number */ ++ ++ switch (wrqu->data.length) { ++ case 1: ++ op_ch = extra[0] - '0'; ++ break; ++ case 2: ++ op_ch = str_2char2num(extra[0], extra[1]); ++ break; ++ } ++ ++ if (op_ch > 0) ++ pwdinfo->operating_channel = op_ch; ++ else ++ ret = -1; ++ ++ DBG_88E("[%s] op_ch = %d\n", __func__, pwdinfo->operating_channel); ++ ++ return ret; ++} ++ ++static int rtw_p2p_profilefound(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ /* Comment by Albert 2010/10/13 */ ++ /* Input data format: */ ++ /* Ex: 0 */ ++ /* Ex: 1XX:XX:XX:XX:XX:XXYYSSID */ ++ /* 0 => Reflush the profile record list. */ ++ /* 1 => Add the profile list */ ++ /* XX:XX:XX:XX:XX:XX => peer's MAC Address (ex: 00:E0:4C:00:00:01) */ ++ /* YY => SSID Length */ ++ /* SSID => SSID for persistence group */ ++ ++ DBG_88E("[%s] In value = %s, len = %d\n", __func__, extra, wrqu->data.length - 1); ++ ++ /* The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function. */ ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ++ if (extra[0] == '0') { ++ /* Remove all the profile information of wifidirect_info structure. */ ++ memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM); ++ pwdinfo->profileindex = 0; ++ } else { ++ if (pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM) { ++ ret = -1; ++ } else { ++ int jj, kk; ++ ++ /* Add this profile information into pwdinfo->profileinfo */ ++ /* Ex: 1XX:XX:XX:XX:XX:XXYYSSID */ ++ for (jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3) ++ pwdinfo->profileinfo[pwdinfo->profileindex].peermac[jj] = key_2char2num(extra[kk], extra[kk + 1]); ++ ++ pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen = (extra[18] - '0') * 10 + (extra[19] - '0'); ++ memcpy(pwdinfo->profileinfo[pwdinfo->profileindex].ssid, &extra[20], pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen); ++ pwdinfo->profileindex++; ++ } ++ } ++ } ++ ++ return ret; ++} ++ ++static int rtw_p2p_setDN(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] %s %d\n", __func__, extra, wrqu->data.length - 1); ++ memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN); ++ memcpy(pwdinfo->device_name, extra, wrqu->data.length - 1); ++ pwdinfo->device_name_len = wrqu->data.length - 1; ++ ++ return ret; ++} ++ ++static int rtw_p2p_get_status(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ if (padapter->bShowGetP2PState) ++ DBG_88E("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), ++ pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2], ++ pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]); ++ ++ /* Commented by Albert 2010/10/12 */ ++ /* Because of the output size limitation, I had removed the "Role" information. */ ++ /* About the "Role" information, we will use the new private IOCTL to get the "Role" information. */ ++ sprintf(extra, "\n\nStatus =%.2d\n", rtw_p2p_state(pwdinfo)); ++ wrqu->data.length = strlen(extra); ++ ++ return ret; ++} ++ ++/* Commented by Albert 20110520 */ ++/* This function will return the config method description */ ++/* This config method description will show us which config method the remote P2P device is intended to use */ ++/* by sending the provisioning discovery request frame. */ ++ ++static int rtw_p2p_get_req_cm(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ sprintf(extra, "\n\nCM =%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req); ++ wrqu->data.length = strlen(extra); ++ return ret; ++} ++ ++static int rtw_p2p_get_role(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), ++ pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2], ++ pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]); ++ ++ sprintf(extra, "\n\nRole =%.2d\n", rtw_p2p_role(pwdinfo)); ++ wrqu->data.length = strlen(extra); ++ return ret; ++} ++ ++static int rtw_p2p_get_peer_ifaddr(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] Role = %d, Status = %d, peer addr = %pM\n", __func__, ++ rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), ++ pwdinfo->p2p_peer_interface_addr); ++ sprintf(extra, "\nMAC %pM", ++ pwdinfo->p2p_peer_interface_addr); ++ wrqu->data.length = strlen(extra); ++ return ret; ++} ++ ++static int rtw_p2p_get_peer_devaddr(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++ ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] Role = %d, Status = %d, peer addr = %pM\n", __func__, ++ rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), ++ pwdinfo->rx_prov_disc_info.peerDevAddr); ++ sprintf(extra, "\n%pM", ++ pwdinfo->rx_prov_disc_info.peerDevAddr); ++ wrqu->data.length = strlen(extra); ++ return ret; ++} ++ ++static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++ ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] Role = %d, Status = %d, peer addr = %pM\n", ++ __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), ++ pwdinfo->p2p_peer_device_addr); ++ sprintf(extra, "\nMAC %pM", ++ pwdinfo->p2p_peer_device_addr); ++ wrqu->data.length = strlen(extra); ++ return ret; ++} ++ ++static int rtw_p2p_get_groupid(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++ ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ sprintf(extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s", ++ pwdinfo->groupid_info.go_device_addr[0], pwdinfo->groupid_info.go_device_addr[1], ++ pwdinfo->groupid_info.go_device_addr[2], pwdinfo->groupid_info.go_device_addr[3], ++ pwdinfo->groupid_info.go_device_addr[4], pwdinfo->groupid_info.go_device_addr[5], ++ pwdinfo->groupid_info.ssid); ++ wrqu->data.length = strlen(extra); ++ return ret; ++} ++ ++static int rtw_p2p_get_op_ch(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++ ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] Op_ch = %02x\n", __func__, pwdinfo->operating_channel); ++ ++ sprintf(extra, "\n\nOp_ch =%.2d\n", pwdinfo->operating_channel); ++ wrqu->data.length = strlen(extra); ++ return ret; ++} ++ ++static int rtw_p2p_get_wps_configmethod(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u8 peerMAC[ETH_ALEN] = {0x00}; ++ int jj, kk; ++ u8 peerMACStr[17] = {0x00}; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ u8 blnMatch = 0; ++ u16 attr_content = 0; ++ uint attr_contentlen = 0; ++ /* 6 is the string "wpsCM =", 17 is the MAC addr, we have to clear it at wrqu->data.pointer */ ++ u8 attr_content_str[6 + 17] = {0x00}; ++ ++ /* Commented by Albert 20110727 */ ++ /* The input data is the MAC address which the application wants to know its WPS config method. */ ++ /* After knowing its WPS config method, the application can decide the config method for provisioning discovery. */ ++ /* Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05 */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, (char *)extra); ++ if (copy_from_user(peerMACStr, wrqu->data.pointer + 6, 17)) ++ return -EFAULT; ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]); ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) { ++ u8 *wpsie; ++ uint wpsie_len = 0; ++ __be16 be_tmp; ++ ++ /* The mac address is matched. */ ++ wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len); ++ if (wpsie) { ++ rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&be_tmp, &attr_contentlen); ++ if (attr_contentlen) { ++ attr_content = be16_to_cpu(be_tmp); ++ sprintf(attr_content_str, "\n\nM =%.4d", attr_content); ++ blnMatch = 1; ++ } ++ } ++ break; ++ } ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (!blnMatch) ++ sprintf(attr_content_str, "\n\nM = 0000"); ++ ++ if (copy_to_user(wrqu->data.pointer, attr_content_str, 6 + 17)) ++ return -EFAULT; ++ return ret; ++} ++ ++static int rtw_p2p_get_go_device_address(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u8 peerMAC[ETH_ALEN] = {0x00}; ++ int jj, kk; ++ u8 peerMACStr[17] = {0x00}; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ u8 blnMatch = 0; ++ u8 *p2pie; ++ uint p2pielen = 0, attr_contentlen = 0; ++ u8 attr_content[100] = {0x00}; ++ ++ u8 go_devadd_str[100 + 10] = {0x00}; ++ /* +10 is for the str "go_devadd =", we have to clear it at wrqu->data.pointer */ ++ ++ /* Commented by Albert 20121209 */ ++ /* The input data is the GO's interface address which the application wants to know its device address. */ ++ /* Format: iwpriv wlanx p2p_get2 go_devadd = 00:E0:4C:00:00:05 */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, (char *)extra); ++ if (copy_from_user(peerMACStr, wrqu->data.pointer + 10, 17)) ++ return -EFAULT; ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]); ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) { ++ /* Commented by Albert 2011/05/18 */ ++ /* Match the device address located in the P2P IE */ ++ /* This is for the case that the P2P device address is not the same as the P2P interface address. */ ++ ++ p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen); ++ if (p2pie) { ++ while (p2pie) { ++ /* The P2P Device ID attribute is included in the Beacon frame. */ ++ /* The P2P Device Info attribute is included in the probe response frame. */ ++ ++ memset(attr_content, 0x00, 100); ++ if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) { ++ /* Handle the P2P Device ID attribute of Beacon first */ ++ blnMatch = 1; ++ break; ++ } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) { ++ /* Handle the P2P Device Info attribute of probe response */ ++ blnMatch = 1; ++ break; ++ } ++ ++ /* Get the next P2P IE */ ++ p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen); ++ } ++ } ++ } ++ ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (!blnMatch) ++ sprintf(go_devadd_str, "\n\ndev_add = NULL"); ++ else ++ sprintf(go_devadd_str, "\ndev_add =%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", ++ attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]); ++ ++ if (copy_to_user(wrqu->data.pointer, go_devadd_str, 10 + 17)) ++ return -EFAULT; ++ return ret; ++} ++ ++static int rtw_p2p_get_device_type(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u8 peerMAC[ETH_ALEN] = {0x00}; ++ int jj, kk; ++ u8 peerMACStr[17] = {0x00}; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ u8 blnMatch = 0; ++ u8 dev_type[8] = {0x00}; ++ uint dev_type_len = 0; ++ u8 dev_type_str[17 + 9] = {0x00}; /* +9 is for the str "dev_type =", we have to clear it at wrqu->data.pointer */ ++ ++ /* Commented by Albert 20121209 */ ++ /* The input data is the MAC address which the application wants to know its device type. */ ++ /* Such user interface could know the device type. */ ++ /* Format: iwpriv wlanx p2p_get2 dev_type = 00:E0:4C:00:00:05 */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, (char *)extra); ++ if (copy_from_user(peerMACStr, wrqu->data.pointer + 9, 17)) ++ return -EFAULT; ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]); ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) { ++ u8 *wpsie; ++ uint wpsie_len = 0; ++ ++ /* The mac address is matched. */ ++ ++ wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], ++ pnetwork->network.IELength - 12, ++ NULL, &wpsie_len); ++ if (wpsie) { ++ rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len); ++ if (dev_type_len) { ++ u16 type = 0; ++ __be16 be_tmp; ++ ++ memcpy(&be_tmp, dev_type, 2); ++ type = be16_to_cpu(be_tmp); ++ sprintf(dev_type_str, "\n\nN =%.2d", type); ++ blnMatch = 1; ++ } ++ } ++ break; ++ } ++ ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (!blnMatch) ++ sprintf(dev_type_str, "\n\nN = 00"); ++ ++ if (copy_to_user(wrqu->data.pointer, dev_type_str, 9 + 17)) { ++ return -EFAULT; ++ } ++ ++ return ret; ++} ++ ++static int rtw_p2p_get_device_name(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u8 peerMAC[ETH_ALEN] = {0x00}; ++ int jj, kk; ++ u8 peerMACStr[17] = {0x00}; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ u8 blnMatch = 0; ++ u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = {0x00}; ++ uint dev_len = 0; ++ u8 dev_name_str[WPS_MAX_DEVICE_NAME_LEN + 5] = {0x00}; /* +5 is for the str "devN =", we have to clear it at wrqu->data.pointer */ ++ ++ /* Commented by Albert 20121225 */ ++ /* The input data is the MAC address which the application wants to know its device name. */ ++ /* Such user interface could show peer device's device name instead of ssid. */ ++ /* Format: iwpriv wlanx p2p_get2 devN = 00:E0:4C:00:00:05 */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, (char *)extra); ++ if (copy_from_user(peerMACStr, wrqu->data.pointer + 5, 17)) ++ return -EFAULT; ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]); ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) { ++ u8 *wpsie; ++ uint wpsie_len = 0; ++ ++ /* The mac address is matched. */ ++ wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len); ++ if (wpsie) { ++ rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len); ++ if (dev_len) { ++ sprintf(dev_name_str, "\n\nN =%s", dev_name); ++ blnMatch = 1; ++ } ++ } ++ break; ++ } ++ ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (!blnMatch) ++ sprintf(dev_name_str, "\n\nN = 0000"); ++ ++ if (copy_to_user(wrqu->data.pointer, dev_name_str, 5 + ((dev_len > 17) ? dev_len : 17))) ++ return -EFAULT; ++ return ret; ++} ++ ++static int rtw_p2p_get_invitation_procedure(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ u8 peerMAC[ETH_ALEN] = {0x00}; ++ int jj, kk; ++ u8 peerMACStr[17] = {0x00}; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ u8 blnMatch = 0; ++ u8 *p2pie; ++ uint p2pielen = 0, attr_contentlen = 0; ++ u8 attr_content[2] = {0x00}; ++ ++ u8 inv_proc_str[17 + 8] = {0x00}; ++ /* +8 is for the str "InvProc =", we have to clear it at wrqu->data.pointer */ ++ ++ /* Commented by Ouden 20121226 */ ++ /* The application wants to know P2P initiation procedure is supported or not. */ ++ /* Format: iwpriv wlanx p2p_get2 InvProc = 00:E0:4C:00:00:05 */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, (char *)extra); ++ if (copy_from_user(peerMACStr, wrqu->data.pointer + 8, 17)) ++ return -EFAULT; ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]); ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) { ++ /* Commented by Albert 20121226 */ ++ /* Match the device address located in the P2P IE */ ++ /* This is for the case that the P2P device address is not the same as the P2P interface address. */ ++ ++ p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen); ++ if (p2pie) { ++ while (p2pie) { ++ if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen)) { ++ /* Handle the P2P capability attribute */ ++ blnMatch = 1; ++ break; ++ } ++ ++ /* Get the next P2P IE */ ++ p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen); ++ } ++ } ++ } ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (!blnMatch) { ++ sprintf(inv_proc_str, "\nIP =-1"); ++ } else { ++ if (attr_content[0] & 0x20) ++ sprintf(inv_proc_str, "\nIP = 1"); ++ else ++ sprintf(inv_proc_str, "\nIP = 0"); ++ } ++ if (copy_to_user(wrqu->data.pointer, inv_proc_str, 8 + 17)) ++ return -EFAULT; ++ return ret; ++} ++ ++static int rtw_p2p_connect(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 peerMAC[ETH_ALEN] = {0x00}; ++ int jj, kk; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ uint uintPeerChannel = 0; ++ ++ /* Commented by Albert 20110304 */ ++ /* The input data contains two informations. */ ++ /* 1. First information is the MAC address which wants to formate with */ ++ /* 2. Second information is the WPS PINCode or "pbc" string for push button method */ ++ /* Format: 00:E0:4C:00:00:05 */ ++ /* Format: 00:E0:4C:00:00:05 */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, extra); ++ ++ if (pwdinfo->p2p_state == P2P_STATE_NONE) { ++ DBG_88E("[%s] WiFi Direct is disable!\n", __func__); ++ return ret; ++ } ++ ++ if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO) ++ return -1; ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]); ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) { ++ uintPeerChannel = pnetwork->network.Configuration.DSConfig; ++ break; ++ } ++ ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (uintPeerChannel) { ++ memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info)); ++ memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info)); ++ ++ pwdinfo->nego_req_info.peer_channel_num[0] = uintPeerChannel; ++ memcpy(pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN); ++ pwdinfo->nego_req_info.benable = true; ++ ++ _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); ++ if (rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK) { ++ /* Restore to the listen state if the current p2p state is not nego OK */ ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); ++ } ++ ++ rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING); ++ ++ DBG_88E("[%s] Start PreTx Procedure!\n", __func__); ++ _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); ++ _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT); ++ } else { ++ DBG_88E("[%s] Not Found in Scanning Queue~\n", __func__); ++ ret = -1; ++ } ++ return ret; ++} ++ ++static int rtw_p2p_invite_req(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ int jj, kk; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ uint uintPeerChannel = 0; ++ u8 attr_content[50] = {0x00}; ++ u8 *p2pie; ++ uint p2pielen = 0, attr_contentlen = 0; ++ struct tx_invite_req_info *pinvite_req_info = &pwdinfo->invitereq_info; ++ ++ /* The input data contains two informations. */ ++ /* 1. First information is the P2P device address which you want to send to. */ ++ /* 2. Second information is the group id which combines with GO's mac address, space and GO's ssid. */ ++ /* Command line sample: iwpriv wlan0 p2p_set invite ="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */ ++ /* Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, extra); ++ ++ if (wrqu->data.length <= 37) { ++ DBG_88E("[%s] Wrong format!\n", __func__); ++ return ret; ++ } ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ++ DBG_88E("[%s] WiFi Direct is disable!\n", __func__); ++ return ret; ++ } else { ++ /* Reset the content of struct tx_invite_req_info */ ++ pinvite_req_info->benable = false; ++ memset(pinvite_req_info->go_bssid, 0x00, ETH_ALEN); ++ memset(pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN); ++ pinvite_req_info->ssidlen = 0x00; ++ pinvite_req_info->operating_ch = pwdinfo->operating_channel; ++ memset(pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN); ++ pinvite_req_info->token = 3; ++ } ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ pinvite_req_info->peer_macaddr[jj] = key_2char2num(extra[kk], extra[kk + 1]); ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ /* Commented by Albert 2011/05/18 */ ++ /* Match the device address located in the P2P IE */ ++ /* This is for the case that the P2P device address is not the same as the P2P interface address. */ ++ ++ p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen); ++ if (p2pie) { ++ /* The P2P Device ID attribute is included in the Beacon frame. */ ++ /* The P2P Device Info attribute is included in the probe response frame. */ ++ ++ if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) { ++ /* Handle the P2P Device ID attribute of Beacon first */ ++ if (!memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) { ++ uintPeerChannel = pnetwork->network.Configuration.DSConfig; ++ break; ++ } ++ } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) { ++ /* Handle the P2P Device Info attribute of probe response */ ++ if (!memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) { ++ uintPeerChannel = pnetwork->network.Configuration.DSConfig; ++ break; ++ } ++ } ++ } ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (uintPeerChannel) { ++ /* Store the GO's bssid */ ++ for (jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3) ++ pinvite_req_info->go_bssid[jj] = key_2char2num(extra[kk], extra[kk + 1]); ++ ++ /* Store the GO's ssid */ ++ pinvite_req_info->ssidlen = wrqu->data.length - 36; ++ memcpy(pinvite_req_info->go_ssid, &extra[36], (u32)pinvite_req_info->ssidlen); ++ pinvite_req_info->benable = true; ++ pinvite_req_info->peer_ch = uintPeerChannel; ++ ++ rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ); ++ ++ set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ ++ _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); ++ ++ _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT); ++ } else { ++ DBG_88E("[%s] NOT Found in the Scanning Queue!\n", __func__); ++ } ++ return ret; ++} ++ ++static int rtw_p2p_set_persistent(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ /* The input data is 0 or 1 */ ++ /* 0: disable persistent group functionality */ ++ /* 1: enable persistent group founctionality */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, extra); ++ ++ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ++ DBG_88E("[%s] WiFi Direct is disable!\n", __func__); ++ return ret; ++ } else { ++ if (extra[0] == '0') /* Disable the persistent group function. */ ++ pwdinfo->persistent_supported = false; ++ else if (extra[0] == '1') /* Enable the persistent group function. */ ++ pwdinfo->persistent_supported = true; ++ else ++ pwdinfo->persistent_supported = false; ++ } ++ pr_info("[%s] persistent_supported = %d\n", __func__, pwdinfo->persistent_supported); ++ return ret; ++} ++ ++static int rtw_p2p_prov_disc(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ u8 peerMAC[ETH_ALEN] = {0x00}; ++ int jj, kk; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct list_head *plist, *phead; ++ struct __queue *queue = &pmlmepriv->scanned_queue; ++ struct wlan_network *pnetwork = NULL; ++ uint uintPeerChannel = 0; ++ u8 attr_content[100] = {0x00}; ++ u8 *p2pie; ++ uint p2pielen = 0, attr_contentlen = 0; ++ ++ /* The input data contains two informations. */ ++ /* 1. First information is the MAC address which wants to issue the provisioning discovery request frame. */ ++ /* 2. Second information is the WPS configuration method which wants to discovery */ ++ /* Format: 00:E0:4C:00:00:05_display */ ++ /* Format: 00:E0:4C:00:00:05_keypad */ ++ /* Format: 00:E0:4C:00:00:05_pbc */ ++ /* Format: 00:E0:4C:00:00:05_label */ ++ ++ DBG_88E("[%s] data = %s\n", __func__, extra); ++ ++ if (pwdinfo->p2p_state == P2P_STATE_NONE) { ++ DBG_88E("[%s] WiFi Direct is disable!\n", __func__); ++ return ret; ++ } else { ++ /* Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request. */ ++ memset(pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN); ++ memset(pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN); ++ memset(&pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof(struct ndis_802_11_ssid)); ++ pwdinfo->tx_prov_disc_info.peer_channel_num[0] = 0; ++ pwdinfo->tx_prov_disc_info.peer_channel_num[1] = 0; ++ pwdinfo->tx_prov_disc_info.benable = false; ++ } ++ ++ for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) ++ peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]); ++ ++ if (!memcmp(&extra[18], "display", 7)) { ++ pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA; ++ } else if (!memcmp(&extra[18], "keypad", 7)) { ++ pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD; ++ } else if (!memcmp(&extra[18], "pbc", 3)) { ++ pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON; ++ } else if (!memcmp(&extra[18], "label", 5)) { ++ pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL; ++ } else { ++ DBG_88E("[%s] Unknown WPS config methodn", __func__); ++ return ret; ++ } ++ ++ spin_lock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ phead = get_list_head(queue); ++ plist = phead->next; ++ ++ while (phead != plist) { ++ if (uintPeerChannel != 0) ++ break; ++ ++ pnetwork = container_of(plist, struct wlan_network, list); ++ ++ /* Commented by Albert 2011/05/18 */ ++ /* Match the device address located in the P2P IE */ ++ /* This is for the case that the P2P device address is not the same as the P2P interface address. */ ++ ++ p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen); ++ if (p2pie) { ++ while (p2pie) { ++ /* The P2P Device ID attribute is included in the Beacon frame. */ ++ /* The P2P Device Info attribute is included in the probe response frame. */ ++ ++ if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) { ++ /* Handle the P2P Device ID attribute of Beacon first */ ++ if (!memcmp(attr_content, peerMAC, ETH_ALEN)) { ++ uintPeerChannel = pnetwork->network.Configuration.DSConfig; ++ break; ++ } ++ } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) { ++ /* Handle the P2P Device Info attribute of probe response */ ++ if (!memcmp(attr_content, peerMAC, ETH_ALEN)) { ++ uintPeerChannel = pnetwork->network.Configuration.DSConfig; ++ break; ++ } ++ } ++ ++ /* Get the next P2P IE */ ++ p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen); ++ } ++ } ++ ++ plist = plist->next; ++ } ++ ++ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); ++ ++ if (uintPeerChannel) { ++ DBG_88E("[%s] peer channel: %d!\n", __func__, uintPeerChannel); ++ memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN); ++ memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN); ++ pwdinfo->tx_prov_disc_info.peer_channel_num[0] = (u16)uintPeerChannel; ++ pwdinfo->tx_prov_disc_info.benable = true; ++ rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ); ++ ++ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) { ++ memcpy(&pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof(struct ndis_802_11_ssid)); ++ } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { ++ memcpy(pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN); ++ pwdinfo->tx_prov_disc_info.ssid.SsidLength = P2P_WILDCARD_SSID_LEN; ++ } ++ ++ set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); ++ ++ _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); ++ ++ _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT); ++ } else { ++ DBG_88E("[%s] NOT Found in the Scanning Queue!\n", __func__); ++ } ++ return ret; ++} ++ ++/* This function is used to inform the driver the user had specified the pin code value or pbc */ ++/* to application. */ ++ ++static int rtw_p2p_got_wpsinfo(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ ++ DBG_88E("[%s] data = %s\n", __func__, extra); ++ /* Added by Albert 20110328 */ ++ /* if the input data is P2P_NO_WPSINFO -> reset the wpsinfo */ ++ /* if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device. */ ++ /* if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself. */ ++ /* if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC */ ++ ++ if (*extra == '0') ++ pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO; ++ else if (*extra == '1') ++ pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN; ++ else if (*extra == '2') ++ pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN; ++ else if (*extra == '3') ++ pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC; ++ else ++ pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO; ++ return ret; ++} ++ ++#endif /* CONFIG_88EU_P2P */ ++ ++static int rtw_p2p_set(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ ++#ifdef CONFIG_88EU_P2P ++ DBG_88E("[%s] extra = %s\n", __func__, extra); ++ if (!memcmp(extra, "enable =", 7)) { ++ rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]); ++ } else if (!memcmp(extra, "setDN =", 6)) { ++ wrqu->data.length -= 6; ++ rtw_p2p_setDN(dev, info, wrqu, &extra[6]); ++ } else if (!memcmp(extra, "profilefound =", 13)) { ++ wrqu->data.length -= 13; ++ rtw_p2p_profilefound(dev, info, wrqu, &extra[13]); ++ } else if (!memcmp(extra, "prov_disc =", 10)) { ++ wrqu->data.length -= 10; ++ rtw_p2p_prov_disc(dev, info, wrqu, &extra[10]); ++ } else if (!memcmp(extra, "nego =", 5)) { ++ wrqu->data.length -= 5; ++ rtw_p2p_connect(dev, info, wrqu, &extra[5]); ++ } else if (!memcmp(extra, "intent =", 7)) { ++ /* Commented by Albert 2011/03/23 */ ++ /* The wrqu->data.length will include the null character */ ++ /* So, we will decrease 7 + 1 */ ++ wrqu->data.length -= 8; ++ rtw_p2p_set_intent(dev, info, wrqu, &extra[7]); ++ } else if (!memcmp(extra, "ssid =", 5)) { ++ wrqu->data.length -= 5; ++ rtw_p2p_set_go_nego_ssid(dev, info, wrqu, &extra[5]); ++ } else if (!memcmp(extra, "got_wpsinfo =", 12)) { ++ wrqu->data.length -= 12; ++ rtw_p2p_got_wpsinfo(dev, info, wrqu, &extra[12]); ++ } else if (!memcmp(extra, "listen_ch =", 10)) { ++ /* Commented by Albert 2011/05/24 */ ++ /* The wrqu->data.length will include the null character */ ++ /* So, we will decrease (10 + 1) */ ++ wrqu->data.length -= 11; ++ rtw_p2p_set_listen_ch(dev, info, wrqu, &extra[10]); ++ } else if (!memcmp(extra, "op_ch =", 6)) { ++ /* Commented by Albert 2011/05/24 */ ++ /* The wrqu->data.length will include the null character */ ++ /* So, we will decrease (6 + 1) */ ++ wrqu->data.length -= 7; ++ rtw_p2p_set_op_ch(dev, info, wrqu, &extra[6]); ++ } else if (!memcmp(extra, "invite =", 7)) { ++ wrqu->data.length -= 8; ++ rtw_p2p_invite_req(dev, info, wrqu, &extra[7]); ++ } else if (!memcmp(extra, "persistent =", 11)) { ++ wrqu->data.length -= 11; ++ rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]); ++ } ++#endif /* CONFIG_88EU_P2P */ ++ ++ return ret; ++} ++ ++static int rtw_p2p_get(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ ++#ifdef CONFIG_88EU_P2P ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ if (padapter->bShowGetP2PState) ++ DBG_88E("[%s] extra = %s\n", __func__, (char *)wrqu->data.pointer); ++ if (!memcmp(wrqu->data.pointer, "status", 6)) { ++ rtw_p2p_get_status(dev, info, wrqu, extra); ++ } else if (!memcmp(wrqu->data.pointer, "role", 4)) { ++ rtw_p2p_get_role(dev, info, wrqu, extra); ++ } else if (!memcmp(wrqu->data.pointer, "peer_ifa", 8)) { ++ rtw_p2p_get_peer_ifaddr(dev, info, wrqu, extra); ++ } else if (!memcmp(wrqu->data.pointer, "req_cm", 6)) { ++ rtw_p2p_get_req_cm(dev, info, wrqu, extra); ++ } else if (!memcmp(wrqu->data.pointer, "peer_deva", 9)) { ++ /* Get the P2P device address when receiving the provision discovery request frame. */ ++ rtw_p2p_get_peer_devaddr(dev, info, wrqu, extra); ++ } else if (!memcmp(wrqu->data.pointer, "group_id", 8)) { ++ rtw_p2p_get_groupid(dev, info, wrqu, extra); ++ } else if (!memcmp(wrqu->data.pointer, "peer_deva_inv", 9)) { ++ /* Get the P2P device address when receiving the P2P Invitation request frame. */ ++ rtw_p2p_get_peer_devaddr_by_invitation(dev, info, wrqu, extra); ++ } else if (!memcmp(wrqu->data.pointer, "op_ch", 5)) { ++ rtw_p2p_get_op_ch(dev, info, wrqu, extra); ++ } ++#endif /* CONFIG_88EU_P2P */ ++ return ret; ++} ++ ++static int rtw_p2p_get2(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ ++#ifdef CONFIG_88EU_P2P ++ DBG_88E("[%s] extra = %s\n", __func__, (char *)wrqu->data.pointer); ++ if (!memcmp(extra, "wpsCM =", 6)) { ++ wrqu->data.length -= 6; ++ rtw_p2p_get_wps_configmethod(dev, info, wrqu, &extra[6]); ++ } else if (!memcmp(extra, "devN =", 5)) { ++ wrqu->data.length -= 5; ++ rtw_p2p_get_device_name(dev, info, wrqu, &extra[5]); ++ } else if (!memcmp(extra, "dev_type =", 9)) { ++ wrqu->data.length -= 9; ++ rtw_p2p_get_device_type(dev, info, wrqu, &extra[9]); ++ } else if (!memcmp(extra, "go_devadd =", 10)) { ++ wrqu->data.length -= 10; ++ rtw_p2p_get_go_device_address(dev, info, wrqu, &extra[10]); ++ } else if (!memcmp(extra, "InvProc =", 8)) { ++ wrqu->data.length -= 8; ++ rtw_p2p_get_invitation_procedure(dev, info, wrqu, &extra[8]); ++ } ++ ++#endif /* CONFIG_88EU_P2P */ ++ ++ return ret; ++} ++ ++static int rtw_cta_test_start(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ DBG_88E("%s %s\n", __func__, extra); ++ if (!strcmp(extra, "1")) ++ padapter->in_cta_test = 1; ++ else ++ padapter->in_cta_test = 0; ++ ++ if (padapter->in_cta_test) { ++ u32 v = rtw_read32(padapter, REG_RCR); ++ v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */ ++ rtw_write32(padapter, REG_RCR, v); ++ DBG_88E("enable RCR_ADF\n"); ++ } else { ++ u32 v = rtw_read32(padapter, REG_RCR); ++ v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;/* RCR_ADF */ ++ rtw_write32(padapter, REG_RCR, v); ++ DBG_88E("disable RCR_ADF\n"); ++ } ++ return ret; ++} ++ ++static int rtw_rereg_nd_name(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv; ++ char new_ifname[IFNAMSIZ]; ++ ++ if (rereg_priv->old_ifname[0] == 0) { ++ char *reg_ifname; ++ reg_ifname = padapter->registrypriv.if2name; ++ ++ strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ); ++ rereg_priv->old_ifname[IFNAMSIZ - 1] = 0; ++ } ++ ++ if (wrqu->data.length > IFNAMSIZ) ++ return -EFAULT; ++ ++ if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ)) ++ return -EFAULT; ++ ++ if (0 == strcmp(rereg_priv->old_ifname, new_ifname)) ++ return ret; ++ ++ DBG_88E("%s new_ifname:%s\n", __func__, new_ifname); ++ ret = rtw_change_ifname(padapter, new_ifname); ++ if (0 != ret) ++ goto exit; ++ ++ if (!memcmp(rereg_priv->old_ifname, "disable%d", 9)) { ++ padapter->ledpriv.bRegUseLed = rereg_priv->old_bRegUseLed; ++ rtw_hal_sw_led_init(padapter); ++ rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode); ++ } ++ ++ strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ); ++ rereg_priv->old_ifname[IFNAMSIZ - 1] = 0; ++ ++ if (!memcmp(new_ifname, "disable%d", 9)) { ++ DBG_88E("%s disable\n", __func__); ++ /* free network queue for Android's timming issue */ ++ rtw_free_network_queue(padapter, true); ++ ++ /* close led */ ++ rtw_led_control(padapter, LED_CTL_POWER_OFF); ++ rereg_priv->old_bRegUseLed = padapter->ledpriv.bRegUseLed; ++ padapter->ledpriv.bRegUseLed = false; ++ rtw_hal_sw_led_deinit(padapter); ++ ++ /* the interface is being "disabled", we can do deeper IPS */ ++ rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv); ++ rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL); ++ } ++exit: ++ return ret; ++} ++ ++static void mac_reg_dump(struct adapter *padapter) ++{ ++ int i, j = 1; ++ pr_info("\n ======= MAC REG =======\n"); ++ for (i = 0x0; i < 0x300; i += 4) { ++ if (j % 4 == 1) ++ pr_info("0x%02x", i); ++ pr_info(" 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ pr_info("\n"); ++ } ++ for (i = 0x400; i < 0x800; i += 4) { ++ if (j % 4 == 1) ++ pr_info("0x%02x", i); ++ pr_info(" 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ pr_info("\n"); ++ } ++} ++ ++static void bb_reg_dump(struct adapter *padapter) ++{ ++ int i, j = 1; ++ pr_info("\n ======= BB REG =======\n"); ++ for (i = 0x800; i < 0x1000; i += 4) { ++ if (j % 4 == 1) ++ pr_info("0x%02x", i); ++ ++ pr_info(" 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ pr_info("\n"); ++ } ++} ++ ++static void rf_reg_dump(struct adapter *padapter) ++{ ++ int i, j = 1, path; ++ u32 value; ++ u8 rf_type, path_nums = 0; ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ ++ pr_info("\n ======= RF REG =======\n"); ++ if ((RF_1T2R == rf_type) || (RF_1T1R == rf_type)) ++ path_nums = 1; ++ else ++ path_nums = 2; ++ ++ for (path = 0; path < path_nums; path++) { ++ pr_info("\nRF_Path(%x)\n", path); ++ for (i = 0; i < 0x100; i++) { ++ value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); ++ if (j % 4 == 1) ++ pr_info("0x%02x ", i); ++ pr_info(" 0x%08x ", value); ++ if ((j++) % 4 == 0) ++ pr_info("\n"); ++ } ++ } ++} ++ ++static int rtw_dbg_port(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ u8 major_cmd, minor_cmd; ++ u16 arg; ++ s32 extra_arg; ++ u32 *pdata, val32; ++ struct sta_info *psta; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ struct wlan_network *cur_network = &pmlmepriv->cur_network; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ pdata = (u32 *)&wrqu->data; ++ ++ val32 = *pdata; ++ arg = (u16)(val32 & 0x0000ffff); ++ major_cmd = (u8)(val32 >> 24); ++ minor_cmd = (u8)((val32 >> 16) & 0x00ff); ++ ++ extra_arg = *(pdata + 1); ++ ++ switch (major_cmd) { ++ case 0x70:/* read_reg */ ++ switch (minor_cmd) { ++ case 1: ++ DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg)); ++ break; ++ case 2: ++ DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg)); ++ break; ++ case 4: ++ DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg)); ++ break; ++ } ++ break; ++ case 0x71:/* write_reg */ ++ switch (minor_cmd) { ++ case 1: ++ rtw_write8(padapter, arg, extra_arg); ++ DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg)); ++ break; ++ case 2: ++ rtw_write16(padapter, arg, extra_arg); ++ DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg)); ++ break; ++ case 4: ++ rtw_write32(padapter, arg, extra_arg); ++ DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg)); ++ break; ++ } ++ break; ++ case 0x72:/* read_bb */ ++ DBG_88E("read_bbreg(0x%x) = 0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff)); ++ break; ++ case 0x73:/* write_bb */ ++ rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg); ++ DBG_88E("write_bbreg(0x%x) = 0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff)); ++ break; ++ case 0x74:/* read_rf */ ++ DBG_88E("read RF_reg path(0x%02x), offset(0x%x), value(0x%08x)\n", minor_cmd, arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff)); ++ break; ++ case 0x75:/* write_rf */ ++ rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg); ++ DBG_88E("write RF_reg path(0x%02x), offset(0x%x), value(0x%08x)\n", minor_cmd, arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff)); ++ break; ++ ++ case 0x76: ++ switch (minor_cmd) { ++ case 0x00: /* normal mode, */ ++ padapter->recvpriv.is_signal_dbg = 0; ++ break; ++ case 0x01: /* dbg mode */ ++ padapter->recvpriv.is_signal_dbg = 1; ++ extra_arg = extra_arg > 100 ? 100 : extra_arg; ++ extra_arg = extra_arg < 0 ? 0 : extra_arg; ++ padapter->recvpriv.signal_strength_dbg = extra_arg; ++ break; ++ } ++ break; ++ case 0x78: /* IOL test */ ++ switch (minor_cmd) { ++ case 0x04: /* LLT table initialization test */ ++ { ++ u8 page_boundary = 0xf9; ++ struct xmit_frame *xmit_frame; ++ ++ xmit_frame = rtw_IOL_accquire_xmit_frame(padapter); ++ if (!xmit_frame) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary); ++ ++ if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500, 0)) ++ ret = -EPERM; ++ } ++ break; ++ case 0x05: /* blink LED test */ ++ { ++ u16 reg = 0x4c; ++ u32 blink_num = 50; ++ u32 blink_delay_ms = 200; ++ int i; ++ struct xmit_frame *xmit_frame; ++ ++ xmit_frame = rtw_IOL_accquire_xmit_frame(padapter); ++ if (!xmit_frame) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ for (i = 0; i < blink_num; i++) { ++ rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00, 0xff); ++ rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms); ++ rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08, 0xff); ++ rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms); ++ } ++ if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms * blink_num * 2) + 200, 0)) ++ ret = -EPERM; ++ } ++ break; ++ ++ case 0x06: /* continuous write byte test */ ++ { ++ u16 reg = arg; ++ u16 start_value = 0; ++ u32 write_num = extra_arg; ++ int i; ++ u8 final; ++ struct xmit_frame *xmit_frame; ++ ++ xmit_frame = rtw_IOL_accquire_xmit_frame(padapter); ++ if (!xmit_frame) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ for (i = 0; i < write_num; i++) ++ rtw_IOL_append_WB_cmd(xmit_frame, reg, i + start_value, 0xFF); ++ if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0)) ++ ret = -EPERM; ++ ++ final = rtw_read8(padapter, reg); ++ if (start_value + write_num - 1 == final) ++ DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final); ++ else ++ DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final); ++ } ++ break; ++ ++ case 0x07: /* continuous write word test */ ++ { ++ u16 reg = arg; ++ u16 start_value = 200; ++ u32 write_num = extra_arg; ++ ++ int i; ++ u16 final; ++ struct xmit_frame *xmit_frame; ++ ++ xmit_frame = rtw_IOL_accquire_xmit_frame(padapter); ++ if (!xmit_frame) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ for (i = 0; i < write_num; i++) ++ rtw_IOL_append_WW_cmd(xmit_frame, reg, i + start_value, 0xFFFF); ++ if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0)) ++ ret = -EPERM; ++ ++ final = rtw_read16(padapter, reg); ++ if (start_value + write_num - 1 == final) ++ DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final); ++ else ++ DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final); ++ } ++ break; ++ case 0x08: /* continuous write dword test */ ++ { ++ u16 reg = arg; ++ u32 start_value = 0x110000c7; ++ u32 write_num = extra_arg; ++ ++ int i; ++ u32 final; ++ struct xmit_frame *xmit_frame; ++ ++ xmit_frame = rtw_IOL_accquire_xmit_frame(padapter); ++ if (!xmit_frame) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ for (i = 0; i < write_num; i++) ++ rtw_IOL_append_WD_cmd(xmit_frame, reg, i + start_value, 0xFFFFFFFF); ++ if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0)) ++ ret = -EPERM; ++ ++ final = rtw_read32(padapter, reg); ++ if (start_value + write_num - 1 == final) ++ DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n", ++ reg, write_num, start_value, final); ++ else ++ DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Fail, start:%u, final:%u\n", ++ reg, write_num, start_value, final); ++ } ++ break; ++ } ++ break; ++ case 0x79: ++ { ++ /* ++ * dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15 ++ * dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15 ++ */ ++ u8 value = extra_arg & 0x0f; ++ u8 sign = minor_cmd; ++ u16 write_value = 0; ++ ++ DBG_88E("%s set RESP_TXAGC to %s %u\n", __func__, sign ? "minus" : "plus", value); ++ ++ if (sign) ++ value = value | 0x10; ++ ++ write_value = value | (value << 5); ++ rtw_write16(padapter, 0x6d9, write_value); ++ } ++ break; ++ case 0x7a: ++ receive_disconnect(padapter, pmlmeinfo->network.MacAddress ++ , WLAN_REASON_EXPIRATION_CHK); ++ break; ++ case 0x7F: ++ switch (minor_cmd) { ++ case 0x0: ++ DBG_88E("fwstate = 0x%x\n", get_fwstate(pmlmepriv)); ++ break; ++ case 0x01: ++ DBG_88E("auth_alg = 0x%x, enc_alg = 0x%x, auth_type = 0x%x, enc_type = 0x%x\n", ++ psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, ++ psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus); ++ break; ++ case 0x02: ++ DBG_88E("pmlmeinfo->state = 0x%x\n", pmlmeinfo->state); ++ break; ++ case 0x03: ++ DBG_88E("qos_option =%d\n", pmlmepriv->qospriv.qos_option); ++ DBG_88E("ht_option =%d\n", pmlmepriv->htpriv.ht_option); ++ break; ++ case 0x04: ++ DBG_88E("cur_ch =%d\n", pmlmeext->cur_channel); ++ DBG_88E("cur_bw =%d\n", pmlmeext->cur_bwmode); ++ DBG_88E("cur_ch_off =%d\n", pmlmeext->cur_ch_offset); ++ break; ++ case 0x05: ++ psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress); ++ if (psta) { ++ int i; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ ++ DBG_88E("SSID =%s\n", cur_network->network.Ssid.Ssid); ++ DBG_88E("sta's macaddr: %pM\n", psta->hwaddr); ++ DBG_88E("cur_channel =%d, cur_bwmode =%d, cur_ch_offset =%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); ++ DBG_88E("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self); ++ DBG_88E("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); ++ DBG_88E("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); ++ DBG_88E("bwmode =%d, ch_offset =%d, sgi =%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi); ++ DBG_88E("ampdu_enable = %d\n", psta->htpriv.ampdu_enable); ++ DBG_88E("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); ++ for (i = 0; i < 16; i++) { ++ preorder_ctrl = &psta->recvreorder_ctrl[i]; ++ if (preorder_ctrl->enable) ++ DBG_88E("tid =%d, indicate_seq =%d\n", i, preorder_ctrl->indicate_seq); ++ } ++ } else { ++ DBG_88E("can't get sta's macaddr, cur_network's macaddr:%pM\n", (cur_network->network.MacAddress)); ++ } ++ break; ++ case 0x06: ++ { ++ u32 ODMFlag; ++ rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag)); ++ DBG_88E("(B)DMFlag = 0x%x, arg = 0x%x\n", ODMFlag, arg); ++ ODMFlag = (u32)(0x0f & arg); ++ DBG_88E("(A)DMFlag = 0x%x\n", ODMFlag); ++ rtw_hal_set_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag)); ++ } ++ break; ++ case 0x07: ++ DBG_88E("bSurpriseRemoved =%d, bDriverStopped =%d\n", ++ padapter->bSurpriseRemoved, padapter->bDriverStopped); ++ break; ++ case 0x08: ++ { ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ ++ DBG_88E("free_xmitbuf_cnt =%d, free_xmitframe_cnt =%d, free_xmit_extbuf_cnt =%d\n", ++ pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmit_extbuf_cnt); ++ DBG_88E("rx_urb_pending_cn =%d\n", precvpriv->rx_pending_cnt); ++ } ++ break; ++ case 0x09: ++ { ++ int i, j; ++ struct list_head *plist, *phead; ++ struct recv_reorder_ctrl *preorder_ctrl; ++ ++#ifdef CONFIG_88EU_AP_MODE ++ DBG_88E("sta_dz_bitmap = 0x%x, tim_bitmap = 0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap); ++#endif ++ spin_lock_bh(&pstapriv->sta_hash_lock); ++ ++ for (i = 0; i < NUM_STA; i++) { ++ phead = &pstapriv->sta_hash[i]; ++ plist = phead->next; ++ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, hash_list); ++ ++ plist = plist->next; ++ ++ if (extra_arg == psta->aid) { ++ DBG_88E("sta's macaddr:%pM\n", (psta->hwaddr)); ++ DBG_88E("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self); ++ DBG_88E("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); ++ DBG_88E("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); ++ DBG_88E("bwmode =%d, ch_offset =%d, sgi =%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi); ++ DBG_88E("ampdu_enable = %d\n", psta->htpriv.ampdu_enable); ++ DBG_88E("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ DBG_88E("capability = 0x%x\n", psta->capability); ++ DBG_88E("flags = 0x%x\n", psta->flags); ++ DBG_88E("wpa_psk = 0x%x\n", psta->wpa_psk); ++ DBG_88E("wpa2_group_cipher = 0x%x\n", psta->wpa2_group_cipher); ++ DBG_88E("wpa2_pairwise_cipher = 0x%x\n", psta->wpa2_pairwise_cipher); ++ DBG_88E("qos_info = 0x%x\n", psta->qos_info); ++#endif ++ DBG_88E("dot118021XPrivacy = 0x%x\n", psta->dot118021XPrivacy); ++ ++ for (j = 0; j < 16; j++) { ++ preorder_ctrl = &psta->recvreorder_ctrl[j]; ++ if (preorder_ctrl->enable) ++ DBG_88E("tid =%d, indicate_seq =%d\n", j, preorder_ctrl->indicate_seq); ++ } ++ } ++ } ++ } ++ spin_unlock_bh(&pstapriv->sta_hash_lock); ++ } ++ break; ++ case 0x0c:/* dump rx/tx packet */ ++ if (arg == 0) { ++ DBG_88E("dump rx packet (%d)\n", extra_arg); ++ rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg)); ++ } else if (arg == 1) { ++ DBG_88E("dump tx packet (%d)\n", extra_arg); ++ rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg)); ++ } ++ break; ++ case 0x0f: ++ if (extra_arg == 0) { ++ DBG_88E("###### silent reset test.......#####\n"); ++ rtw_hal_sreset_reset(padapter); ++ } ++ break; ++ case 0x15: ++ { ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ DBG_88E("==>silent resete cnts:%d\n", pwrpriv->ips_enter_cnts); ++ } ++ break; ++ case 0x10:/* driver version display */ ++ DBG_88E("rtw driver version =%s\n", DRIVERVERSION); ++ break; ++ case 0x11: ++ DBG_88E("turn %s Rx RSSI display function\n", (extra_arg == 1) ? "on" : "off"); ++ padapter->bRxRSSIDisplay = extra_arg; ++ break; ++ case 0x12: /* set rx_stbc */ ++ { ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ /* 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g */ ++ /* default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */ ++ if (pregpriv && ++ (extra_arg == 0 || ++ extra_arg == 1 || ++ extra_arg == 2 || ++ extra_arg == 3)) { ++ pregpriv->rx_stbc = extra_arg; ++ DBG_88E("set rx_stbc =%d\n", pregpriv->rx_stbc); ++ } else { ++ DBG_88E("get rx_stbc =%d\n", pregpriv->rx_stbc); ++ } ++ } ++ break; ++ case 0x13: /* set ampdu_enable */ ++ { ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ /* 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec) */ ++ if (pregpriv && extra_arg >= 0 && extra_arg < 3) { ++ pregpriv->ampdu_enable = extra_arg; ++ DBG_88E("set ampdu_enable =%d\n", pregpriv->ampdu_enable); ++ } else { ++ DBG_88E("get ampdu_enable =%d\n", pregpriv->ampdu_enable); ++ } ++ } ++ break; ++ case 0x14: /* get wifi_spec */ ++ { ++ struct registry_priv *pregpriv = &padapter->registrypriv; ++ DBG_88E("get wifi_spec =%d\n", pregpriv->wifi_spec); ++ } ++ break; ++ case 0x23: ++ DBG_88E("turn %s the bNotifyChannelChange Variable\n", (extra_arg == 1) ? "on" : "off"); ++ padapter->bNotifyChannelChange = extra_arg; ++ break; ++ case 0x24: ++#ifdef CONFIG_88EU_P2P ++ DBG_88E("turn %s the bShowGetP2PState Variable\n", (extra_arg == 1) ? "on" : "off"); ++ padapter->bShowGetP2PState = extra_arg; ++#endif /* CONFIG_88EU_P2P */ ++ break; ++ case 0xaa: ++ if (extra_arg > 0x13) ++ extra_arg = 0xFF; ++ DBG_88E("chang data rate to :0x%02x\n", extra_arg); ++ padapter->fix_rate = extra_arg; ++ break; ++ case 0xdd:/* registers dump, 0 for mac reg, 1 for bb reg, 2 for rf reg */ ++ if (extra_arg == 0) ++ mac_reg_dump(padapter); ++ else if (extra_arg == 1) ++ bb_reg_dump(padapter); ++ else if (extra_arg == 2) ++ rf_reg_dump(padapter); ++ break; ++ case 0xee:/* turn on/off dynamic funcs */ ++ { ++ u32 odm_flag; ++ ++ if (0xf == extra_arg) { ++ rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &odm_flag); ++ DBG_88E(" === DMFlag(0x%08x) ===\n", odm_flag); ++ DBG_88E("extra_arg = 0 - disable all dynamic func\n"); ++ DBG_88E("extra_arg = 1 - disable DIG- BIT(0)\n"); ++ DBG_88E("extra_arg = 2 - disable High power - BIT(1)\n"); ++ DBG_88E("extra_arg = 3 - disable tx power tracking - BIT(2)\n"); ++ DBG_88E("extra_arg = 4 - disable BT coexistence - BIT(3)\n"); ++ DBG_88E("extra_arg = 5 - disable antenna diversity - BIT(4)\n"); ++ DBG_88E("extra_arg = 6 - enable all dynamic func\n"); ++ } else { ++ /* extra_arg = 0 - disable all dynamic func ++ extra_arg = 1 - disable DIG ++ extra_arg = 2 - disable tx power tracking ++ extra_arg = 3 - turn on all dynamic func ++ */ ++ rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &(extra_arg)); ++ rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &odm_flag); ++ DBG_88E(" === DMFlag(0x%08x) ===\n", odm_flag); ++ } ++ } ++ break; ++ ++ case 0xfd: ++ rtw_write8(padapter, 0xc50, arg); ++ DBG_88E("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50)); ++ rtw_write8(padapter, 0xc58, arg); ++ DBG_88E("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58)); ++ break; ++ case 0xfe: ++ DBG_88E("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50)); ++ DBG_88E("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58)); ++ break; ++ case 0xff: ++ DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210)); ++ DBG_88E("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608)); ++ DBG_88E("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280)); ++ DBG_88E("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284)); ++ DBG_88E("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288)); ++ ++ DBG_88E("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664)); ++ ++ DBG_88E("\n"); ++ ++ DBG_88E("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430)); ++ DBG_88E("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438)); ++ ++ DBG_88E("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440)); ++ ++ DBG_88E("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458)); ++ ++ DBG_88E("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484)); ++ DBG_88E("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488)); ++ ++ DBG_88E("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444)); ++ DBG_88E("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448)); ++ DBG_88E("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c)); ++ DBG_88E("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450)); ++ break; ++ } ++ break; ++ default: ++ DBG_88E("error dbg cmd!\n"); ++ break; ++ } ++ return ret; ++} ++ ++static int rtw_wx_set_priv(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *awrq, ++ char *extra) ++{ ++ int ret = 0; ++ int len = 0; ++ char *ext; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct iw_point *dwrq = (struct iw_point *)awrq; ++ ++ if (dwrq->length == 0) ++ return -EFAULT; ++ ++ len = dwrq->length; ++ ext = vmalloc(len); ++ if (!ext) ++ return -ENOMEM; ++ ++ if (copy_from_user(ext, dwrq->pointer, len)) { ++ vfree(ext); ++ return -EFAULT; ++ } ++ ++ /* added for wps2.0 @20110524 */ ++ if (dwrq->flags == 0x8766 && len > 8) { ++ u32 cp_sz; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ u8 *probereq_wpsie = ext; ++ int probereq_wpsie_len = len; ++ u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; ++ ++ if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) && ++ (!memcmp(&probereq_wpsie[2], wps_oui, 4))) { ++ cp_sz = probereq_wpsie_len > MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN : probereq_wpsie_len; ++ ++ pmlmepriv->wps_probe_req_ie_len = 0; ++ kfree(pmlmepriv->wps_probe_req_ie); ++ pmlmepriv->wps_probe_req_ie = NULL; ++ ++ pmlmepriv->wps_probe_req_ie = kmalloc(cp_sz, GFP_KERNEL); ++ if (!pmlmepriv->wps_probe_req_ie) { ++ ret = -EINVAL; ++ goto FREE_EXT; ++ } ++ memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz); ++ pmlmepriv->wps_probe_req_ie_len = cp_sz; ++ } ++ goto FREE_EXT; ++ } ++ ++ if (len >= WEXT_CSCAN_HEADER_SIZE && ++ !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) { ++ ret = rtw_wx_set_scan(dev, info, awrq, ext); ++ goto FREE_EXT; ++ } ++ ++FREE_EXT: ++ ++ vfree(ext); ++ ++ return ret; ++} ++ ++static int rtw_pm_set(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int ret = 0; ++ unsigned mode = 0; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ ++ DBG_88E("[%s] extra = %s\n", __func__, extra); ++ ++ if (!memcmp(extra, "lps =", 4)) { ++ sscanf(extra + 4, "%u", &mode); ++ ret = rtw_pm_set_lps(padapter, mode); ++ } else if (!memcmp(extra, "ips =", 4)) { ++ sscanf(extra + 4, "%u", &mode); ++ ret = rtw_pm_set_ips(padapter, mode); ++ } else { ++ ret = -EINVAL; ++ } ++ ++ return ret; ++} ++ ++static int rtw_mp_efuse_get(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wdata, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); ++ struct hal_data_8188e *haldata = GET_HAL_DATA(padapter); ++ struct efuse_hal *pEfuseHal; ++ struct iw_point *wrqu; ++ ++ u8 *PROMContent = pEEPROM->efuse_eeprom_data; ++ u8 ips_mode = 0, lps_mode = 0; ++ struct pwrctrl_priv *pwrctrlpriv; ++ u8 *data = NULL; ++ u8 *rawdata = NULL; ++ char *pch, *ptmp, *token, *tmp[3] = {NULL, NULL, NULL}; ++ u16 i = 0, j = 0, mapLen = 0, addr = 0, cnts = 0; ++ u16 max_available_size = 0, raw_cursize = 0, raw_maxsize = 0; ++ int err; ++ u8 org_fw_iol = padapter->registrypriv.fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */ ++ ++ wrqu = (struct iw_point *)wdata; ++ pwrctrlpriv = &padapter->pwrctrlpriv; ++ pEfuseHal = &haldata->EfuseHal; ++ ++ err = 0; ++ data = kzalloc(EFUSE_BT_MAX_MAP_LEN, GFP_KERNEL); ++ if (!data) { ++ err = -ENOMEM; ++ goto exit; ++ } ++ rawdata = kzalloc(EFUSE_BT_MAX_MAP_LEN, GFP_KERNEL); ++ if (!rawdata) { ++ err = -ENOMEM; ++ goto exit; ++ } ++ ++ if (copy_from_user(extra, wrqu->pointer, wrqu->length)) { ++ err = -EFAULT; ++ goto exit; ++ } ++ lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */ ++ rtw_pm_set_lps(padapter, PS_MODE_ACTIVE); ++ ++ ips_mode = pwrctrlpriv->ips_mode;/* keep org value */ ++ rtw_pm_set_ips(padapter, IPS_NONE); ++ ++ pch = extra; ++ DBG_88E("%s: in =%s\n", __func__, extra); ++ ++ i = 0; ++ /* mac 16 "00e04c871200" rmap, 00, 2 */ ++ while ((token = strsep(&pch, ",")) != NULL) { ++ if (i > 2) ++ break; ++ tmp[i] = token; ++ i++; ++ } ++ padapter->registrypriv.fw_iol = 0;/* 0:Disable, 1:enable, 2:by usb speed */ ++ ++ if (strcmp(tmp[0], "status") == 0) { ++ sprintf(extra, "Load File efuse =%s, Load File MAC =%s", (pEEPROM->bloadfile_fail_flag ? "FAIL" : "OK"), (pEEPROM->bloadmac_fail_flag ? "FAIL" : "OK")); ++ ++ goto exit; ++ } else if (strcmp(tmp[0], "filemap") == 0) { ++ mapLen = EFUSE_MAP_SIZE; ++ ++ sprintf(extra, "\n"); ++ for (i = 0; i < EFUSE_MAP_SIZE; i += 16) { ++ sprintf(extra + strlen(extra), "0x%02x\t", i); ++ for (j = 0; j < 8; j++) ++ sprintf(extra + strlen(extra), "%02X ", PROMContent[i + j]); ++ sprintf(extra + strlen(extra), "\t"); ++ for (; j < 16; j++) ++ sprintf(extra + strlen(extra), "%02X ", PROMContent[i + j]); ++ sprintf(extra + strlen(extra), "\n"); ++ } ++ } else if (strcmp(tmp[0], "realmap") == 0) { ++ mapLen = EFUSE_MAP_SIZE; ++ if (rtw_efuse_map_read(padapter, 0, mapLen, pEfuseHal->fakeEfuseInitMap) == _FAIL) { ++ DBG_88E("%s: read realmap Fail!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ sprintf(extra, "\n"); ++ for (i = 0; i < EFUSE_MAP_SIZE; i += 16) { ++ sprintf(extra + strlen(extra), "0x%02x\t", i); ++ for (j = 0; j < 8; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeEfuseInitMap[i + j]); ++ sprintf(extra + strlen(extra), "\t"); ++ for (; j < 16; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeEfuseInitMap[i + j]); ++ sprintf(extra + strlen(extra), "\n"); ++ } ++ } else if (strcmp(tmp[0], "rmap") == 0) { ++ if (!tmp[1] || !tmp[2]) { ++ DBG_88E("%s: rmap Fail!! Parameters error!\n", __func__); ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ /* rmap addr cnts */ ++ addr = simple_strtoul(tmp[1], &ptmp, 16); ++ DBG_88E("%s: addr =%x\n", __func__, addr); ++ ++ cnts = simple_strtoul(tmp[2], &ptmp, 10); ++ if (cnts == 0) { ++ DBG_88E("%s: rmap Fail!! cnts error!\n", __func__); ++ err = -EINVAL; ++ goto exit; ++ } ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_map_read error!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ *extra = 0; ++ for (i = 0; i < cnts; i++) ++ sprintf(extra + strlen(extra), "0x%02X ", data[i]); ++ } else if (strcmp(tmp[0], "realraw") == 0) { ++ addr = 0; ++ mapLen = EFUSE_MAX_SIZE; ++ if (rtw_efuse_access(padapter, false, addr, mapLen, rawdata) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_access Fail!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ sprintf(extra, "\n"); ++ for (i = 0; i < mapLen; i++) { ++ sprintf(extra + strlen(extra), "%02X", rawdata[i]); ++ ++ if ((i & 0xF) == 0xF) ++ sprintf(extra + strlen(extra), "\n"); ++ else if ((i & 0x7) == 0x7) ++ sprintf(extra + strlen(extra), "\t"); ++ else ++ sprintf(extra + strlen(extra), " "); ++ } ++ } else if (strcmp(tmp[0], "mac") == 0) { ++ cnts = 6; ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_map_read error!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ *extra = 0; ++ for (i = 0; i < cnts; i++) { ++ sprintf(extra + strlen(extra), "%02X", data[i]); ++ if (i != (cnts - 1)) ++ sprintf(extra + strlen(extra), ":"); ++ } ++ } else if (strcmp(tmp[0], "vidpid") == 0) { ++ cnts = 4; ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EFAULT; ++ goto exit; ++ } ++ if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_access error!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ *extra = 0; ++ for (i = 0; i < cnts; i++) { ++ sprintf(extra + strlen(extra), "0x%02X", data[i]); ++ if (i != (cnts - 1)) ++ sprintf(extra + strlen(extra), ","); ++ } ++ } else if (strcmp(tmp[0], "ableraw") == 0) { ++ efuse_GetCurrentSize(padapter, &raw_cursize); ++ raw_maxsize = efuse_GetMaxSize(padapter); ++ sprintf(extra, "[available raw size] = %d bytes", raw_maxsize - raw_cursize); ++ } else if (strcmp(tmp[0], "btfmap") == 0) { ++ mapLen = EFUSE_BT_MAX_MAP_LEN; ++ if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) { ++ DBG_88E("%s: rtw_BT_efuse_map_read Fail!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ sprintf(extra, "\n"); ++ for (i = 0; i < 512; i += 16) { ++ /* set 512 because the iwpriv's extra size have limit 0x7FF */ ++ sprintf(extra + strlen(extra), "0x%03x\t", i); ++ for (j = 0; j < 8; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->BTEfuseInitMap[i + j]); ++ sprintf(extra + strlen(extra), "\t"); ++ for (; j < 16; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->BTEfuseInitMap[i + j]); ++ sprintf(extra + strlen(extra), "\n"); ++ } ++ } else if (strcmp(tmp[0], "btbmap") == 0) { ++ mapLen = EFUSE_BT_MAX_MAP_LEN; ++ if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) { ++ DBG_88E("%s: rtw_BT_efuse_map_read Fail!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ sprintf(extra, "\n"); ++ for (i = 512; i < 1024; i += 16) { ++ sprintf(extra + strlen(extra), "0x%03x\t", i); ++ for (j = 0; j < 8; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->BTEfuseInitMap[i + j]); ++ sprintf(extra + strlen(extra), "\t"); ++ for (; j < 16; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->BTEfuseInitMap[i + j]); ++ sprintf(extra + strlen(extra), "\n"); ++ } ++ } else if (strcmp(tmp[0], "btrmap") == 0) { ++ if (!tmp[1] || !tmp[2]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ /* rmap addr cnts */ ++ addr = simple_strtoul(tmp[1], &ptmp, 16); ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ ++ cnts = simple_strtoul(tmp[2], &ptmp, 10); ++ if (cnts == 0) { ++ DBG_88E("%s: btrmap Fail!! cnts error!\n", __func__); ++ err = -EINVAL; ++ goto exit; ++ } ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_BT_efuse_map_read(padapter, addr, cnts, data) == _FAIL) { ++ DBG_88E("%s: rtw_BT_efuse_map_read error!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ *extra = 0; ++ for (i = 0; i < cnts; i++) ++ sprintf(extra + strlen(extra), " 0x%02X ", data[i]); ++ } else if (strcmp(tmp[0], "btffake") == 0) { ++ sprintf(extra, "\n"); ++ for (i = 0; i < 512; i += 16) { ++ sprintf(extra + strlen(extra), "0x%03x\t", i); ++ for (j = 0; j < 8; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]); ++ sprintf(extra + strlen(extra), "\t"); ++ for (; j < 16; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]); ++ sprintf(extra + strlen(extra), "\n"); ++ } ++ } else if (strcmp(tmp[0], "btbfake") == 0) { ++ sprintf(extra, "\n"); ++ for (i = 512; i < 1024; i += 16) { ++ sprintf(extra + strlen(extra), "0x%03x\t", i); ++ for (j = 0; j < 8; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]); ++ sprintf(extra + strlen(extra), "\t"); ++ for (; j < 16; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]); ++ sprintf(extra + strlen(extra), "\n"); ++ } ++ } else if (strcmp(tmp[0], "wlrfkmap") == 0) { ++ sprintf(extra, "\n"); ++ for (i = 0; i < EFUSE_MAP_SIZE; i += 16) { ++ sprintf(extra + strlen(extra), "0x%02x\t", i); ++ for (j = 0; j < 8; j++) ++ sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeEfuseModifiedMap[i + j]); ++ sprintf(extra + strlen(extra), "\t"); ++ for (; j < 16; j++) ++ sprintf(extra + strlen(extra), " %02X", pEfuseHal->fakeEfuseModifiedMap[i + j]); ++ sprintf(extra + strlen(extra), "\n"); ++ } ++ } else { ++ sprintf(extra, "Command not found!"); ++ } ++ ++exit: ++ kfree(data); ++ kfree(rawdata); ++ if (!err) ++ wrqu->length = strlen(extra); ++ ++ rtw_pm_set_ips(padapter, ips_mode); ++ rtw_pm_set_lps(padapter, lps_mode); ++ padapter->registrypriv.fw_iol = org_fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */ ++ return err; ++} ++ ++static int rtw_mp_efuse_set(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wdata, char *extra) ++{ ++ struct adapter *padapter; ++ struct pwrctrl_priv *pwrctrlpriv; ++ struct hal_data_8188e *haldata; ++ struct efuse_hal *pEfuseHal; ++ ++ u8 ips_mode = 0, lps_mode = 0; ++ u32 i, jj, kk; ++ u8 *setdata = NULL; ++ u8 *ShadowMapBT = NULL; ++ u8 *ShadowMapWiFi = NULL; ++ u8 *setrawdata = NULL; ++ char *pch, *ptmp, *token, *tmp[3] = {NULL, NULL, NULL}; ++ u16 addr = 0, cnts = 0, max_available_size = 0; ++ int err; ++ ++ padapter = rtw_netdev_priv(dev); ++ pwrctrlpriv = &padapter->pwrctrlpriv; ++ haldata = GET_HAL_DATA(padapter); ++ pEfuseHal = &haldata->EfuseHal; ++ err = 0; ++ setdata = kzalloc(1024, GFP_KERNEL); ++ if (!setdata) { ++ err = -ENOMEM; ++ goto exit; ++ } ++ ShadowMapBT = kmalloc(EFUSE_BT_MAX_MAP_LEN, GFP_KERNEL); ++ if (!ShadowMapBT) { ++ err = -ENOMEM; ++ goto exit; ++ } ++ ShadowMapWiFi = kmalloc(EFUSE_MAP_SIZE, GFP_KERNEL); ++ if (!ShadowMapWiFi) { ++ err = -ENOMEM; ++ goto exit; ++ } ++ setrawdata = kmalloc(EFUSE_MAX_SIZE, GFP_KERNEL); ++ if (!setrawdata) { ++ err = -ENOMEM; ++ goto exit; ++ } ++ ++ lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */ ++ rtw_pm_set_lps(padapter, PS_MODE_ACTIVE); ++ ++ ips_mode = pwrctrlpriv->ips_mode;/* keep org value */ ++ rtw_pm_set_ips(padapter, IPS_NONE); ++ ++ pch = extra; ++ DBG_88E("%s: in =%s\n", __func__, extra); ++ ++ i = 0; ++ while ((token = strsep(&pch, ",")) != NULL) { ++ if (i > 2) ++ break; ++ tmp[i] = token; ++ i++; ++ } ++ ++ /* tmp[0],[1],[2] */ ++ /* wmap, addr, 00e04c871200 */ ++ if (strcmp(tmp[0], "wmap") == 0) { ++ if (!tmp[1] || !tmp[2]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ addr = simple_strtoul(tmp[1], &ptmp, 16); ++ addr &= 0xFFF; ++ ++ cnts = strlen(tmp[2]); ++ if (cnts % 2) { ++ err = -EINVAL; ++ goto exit; ++ } ++ cnts /= 2; ++ if (cnts == 0) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ DBG_88E("%s: map data =%s\n", __func__, tmp[2]); ++ ++ for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) ++ setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]); ++ /* Change to check TYPE_EFUSE_MAP_LEN, because 8188E raw 256, logic map over 256. */ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_map_write error!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ } else if (strcmp(tmp[0], "wraw") == 0) { ++ if (!tmp[1] || !tmp[2]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ addr = simple_strtoul(tmp[1], &ptmp, 16); ++ addr &= 0xFFF; ++ ++ cnts = strlen(tmp[2]); ++ if (cnts % 2) { ++ err = -EINVAL; ++ goto exit; ++ } ++ cnts /= 2; ++ if (cnts == 0) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ DBG_88E("%s: raw data =%s\n", __func__, tmp[2]); ++ ++ for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) ++ setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]); ++ ++ if (rtw_efuse_access(padapter, true, addr, cnts, setrawdata) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_access error!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ } else if (strcmp(tmp[0], "mac") == 0) { ++ if (!tmp[1]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ /* mac, 00e04c871200 */ ++ addr = EEPROM_MAC_ADDR_88EU; ++ cnts = strlen(tmp[1]); ++ if (cnts % 2) { ++ err = -EINVAL; ++ goto exit; ++ } ++ cnts /= 2; ++ if (cnts == 0) { ++ err = -EINVAL; ++ goto exit; ++ } ++ if (cnts > 6) { ++ DBG_88E("%s: error data for mac addr =\"%s\"\n", __func__, tmp[1]); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ DBG_88E("%s: MAC address =%s\n", __func__, tmp[1]); ++ ++ for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) ++ setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]); ++ /* Change to check TYPE_EFUSE_MAP_LEN, because 8188E raw 256, logic map over 256. */ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_map_write error!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ } else if (strcmp(tmp[0], "vidpid") == 0) { ++ if (!tmp[1]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ /* pidvid, da0b7881 */ ++ addr = EEPROM_VID_88EE; ++ cnts = strlen(tmp[1]); ++ if (cnts % 2) { ++ err = -EINVAL; ++ goto exit; ++ } ++ cnts /= 2; ++ if (cnts == 0) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ DBG_88E("%s: VID/PID =%s\n", __func__, tmp[1]); ++ ++ for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) ++ setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]); ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_map_write error!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ } else if (strcmp(tmp[0], "btwmap") == 0) { ++ if (!tmp[1] || !tmp[2]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ addr = simple_strtoul(tmp[1], &ptmp, 16); ++ addr &= 0xFFF; ++ ++ cnts = strlen(tmp[2]); ++ if (cnts % 2) { ++ err = -EINVAL; ++ goto exit; ++ } ++ cnts /= 2; ++ if (cnts == 0) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ DBG_88E("%s: BT data =%s\n", __func__, tmp[2]); ++ ++ for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) ++ setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]); ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if ((addr + cnts) > max_available_size) { ++ DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts); ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_BT_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) { ++ DBG_88E("%s: rtw_BT_efuse_map_write error!!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ } else if (strcmp(tmp[0], "btwfake") == 0) { ++ if (!tmp[1] || !tmp[2]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ addr = simple_strtoul(tmp[1], &ptmp, 16); ++ addr &= 0xFFF; ++ ++ cnts = strlen(tmp[2]); ++ if (cnts % 2) { ++ err = -EINVAL; ++ goto exit; ++ } ++ cnts /= 2; ++ if (cnts == 0) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ DBG_88E("%s: BT tmp data =%s\n", __func__, tmp[2]); ++ ++ for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) ++ pEfuseHal->fakeBTEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]); ++ } else if (strcmp(tmp[0], "btdumpfake") == 0) { ++ if (rtw_BT_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _SUCCESS) { ++ DBG_88E("%s: BT read all map success\n", __func__); ++ } else { ++ DBG_88E("%s: BT read all map Fail!\n", __func__); ++ err = -EFAULT; ++ } ++ } else if (strcmp(tmp[0], "wldumpfake") == 0) { ++ if (rtw_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeEfuseModifiedMap) == _SUCCESS) { ++ DBG_88E("%s: BT read all map success\n", __func__); ++ } else { ++ DBG_88E("%s: BT read all map Fail\n", __func__); ++ err = -EFAULT; ++ } ++ } else if (strcmp(tmp[0], "btfk2map") == 0) { ++ memcpy(pEfuseHal->BTEfuseModifiedMap, pEfuseHal->fakeBTEfuseModifiedMap, EFUSE_BT_MAX_MAP_LEN); ++ ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if (max_available_size < 1) { ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL) { ++ DBG_88E("%s: rtw_BT_efuse_map_write error!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ } else if (strcmp(tmp[0], "wlfk2map") == 0) { ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if (max_available_size < 1) { ++ err = -EFAULT; ++ goto exit; ++ } ++ ++ if (rtw_efuse_map_write(padapter, 0x00, EFUSE_MAX_MAP_LEN, pEfuseHal->fakeEfuseModifiedMap) == _FAIL) { ++ DBG_88E("%s: rtw_efuse_map_write error!\n", __func__); ++ err = -EFAULT; ++ goto exit; ++ } ++ } else if (strcmp(tmp[0], "wlwfake") == 0) { ++ if (!tmp[1] || !tmp[2]) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ addr = simple_strtoul(tmp[1], &ptmp, 16); ++ addr &= 0xFFF; ++ ++ cnts = strlen(tmp[2]); ++ if (cnts % 2) { ++ err = -EINVAL; ++ goto exit; ++ } ++ cnts /= 2; ++ if (cnts == 0) { ++ err = -EINVAL; ++ goto exit; ++ } ++ ++ DBG_88E("%s: addr = 0x%X\n", __func__, addr); ++ DBG_88E("%s: cnts =%d\n", __func__, cnts); ++ DBG_88E("%s: map tmp data =%s\n", __func__, tmp[2]); ++ ++ for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) ++ pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]); ++ } ++ ++exit: ++ kfree(setdata); ++ kfree(ShadowMapBT); ++ kfree(ShadowMapWiFi); ++ kfree(setrawdata); ++ ++ rtw_pm_set_ips(padapter, ips_mode); ++ rtw_pm_set_lps(padapter, lps_mode); ++ ++ return err; ++} ++ ++/* ++ * Input Format: %s,%d,%d ++ * %s is width, could be ++ * "b" for 1 byte ++ * "w" for WORD (2 bytes) ++ * "dw" for DWORD (4 bytes) ++ * 1st %d is address(offset) ++ * 2st %d is data to write ++ */ ++static int rtw_mp_write_reg(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ char *pch, *pnext, *ptmp; ++ char *width_str; ++ char width; ++ u32 addr, data; ++ int ret; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ pch = extra; ++ pnext = strpbrk(pch, ",.-"); ++ if (!pnext) ++ return -EINVAL; ++ *pnext = 0; ++ width_str = pch; ++ ++ pch = pnext + 1; ++ pnext = strpbrk(pch, ",.-"); ++ if (!pnext) ++ return -EINVAL; ++ *pnext = 0; ++ addr = simple_strtoul(pch, &ptmp, 16); ++ if (addr > 0x3FFF) ++ return -EINVAL; ++ ++ pch = pnext + 1; ++ if ((pch - extra) >= wrqu->length) ++ return -EINVAL; ++ data = simple_strtoul(pch, &ptmp, 16); ++ ++ ret = 0; ++ width = width_str[0]; ++ switch (width) { ++ case 'b': ++ /* 1 byte */ ++ if (data > 0xFF) { ++ ret = -EINVAL; ++ break; ++ } ++ rtw_write8(padapter, addr, data); ++ break; ++ case 'w': ++ /* 2 bytes */ ++ if (data > 0xFFFF) { ++ ret = -EINVAL; ++ break; ++ } ++ rtw_write16(padapter, addr, data); ++ break; ++ case 'd': ++ /* 4 bytes */ ++ rtw_write32(padapter, addr, data); ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ return ret; ++} ++ ++/* ++ * Input Format: %s,%d ++ * %s is width, could be ++ * "b" for 1 byte ++ * "w" for WORD (2 bytes) ++ * "dw" for DWORD (4 bytes) ++ * %d is address(offset) ++ * ++ * Return: ++ * %d for data readed ++ */ ++static int rtw_mp_read_reg(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ char *pch, *pnext, *ptmp; ++ char *width_str; ++ char width; ++ char data[20], tmp[20]; ++ u32 addr; ++ u32 ret, i = 0, j = 0, strtout = 0; ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ memset(data, 0, 20); ++ memset(tmp, 0, 20); ++ memset(extra, 0, wrqu->length); ++ ++ pch = input; ++ pnext = strpbrk(pch, ",.-"); ++ if (!pnext) { ++ kfree(input); ++ return -EINVAL; ++ } ++ *pnext = 0; ++ width_str = pch; ++ ++ pch = pnext + 1; ++ if ((pch - input) >= wrqu->length) { ++ kfree(input); ++ return -EINVAL; ++ } ++ kfree(input); ++ addr = simple_strtoul(pch, &ptmp, 16); ++ if (addr > 0x3FFF) ++ return -EINVAL; ++ ++ ret = 0; ++ width = width_str[0]; ++ switch (width) { ++ case 'b': ++ /* 1 byte */ ++ sprintf(extra, "%d\n", rtw_read8(padapter, addr)); ++ wrqu->length = strlen(extra); ++ break; ++ case 'w': ++ /* 2 bytes */ ++ sprintf(data, "%04x\n", rtw_read16(padapter, addr)); ++ for (i = 0; i <= strlen(data); i++) { ++ if (i % 2 == 0) { ++ tmp[j] = ' '; ++ j++; ++ } ++ if (data[i] != '\0') ++ tmp[j] = data[i]; ++ j++; ++ } ++ pch = tmp; ++ DBG_88E("pch =%s", pch); ++ ++ while (*pch != '\0') { ++ pnext = strpbrk(pch, " "); ++ if (!pnext) ++ break; ++ ++ pnext++; ++ if (*pnext != '\0') { ++ strtout = simple_strtoul(pnext, &ptmp, 16); ++ sprintf(extra + strlen(extra), " %d", strtout); ++ } else { ++ break; ++ } ++ pch = pnext; ++ } ++ wrqu->length = 6; ++ break; ++ case 'd': ++ /* 4 bytes */ ++ sprintf(data, "%08x", rtw_read32(padapter, addr)); ++ /* add read data format blank */ ++ for (i = 0; i <= strlen(data); i++) { ++ if (i % 2 == 0) { ++ tmp[j] = ' '; ++ j++; ++ } ++ if (data[i] != '\0') ++ tmp[j] = data[i]; ++ ++ j++; ++ } ++ pch = tmp; ++ DBG_88E("pch =%s", pch); ++ ++ while (*pch != '\0') { ++ pnext = strpbrk(pch, " "); ++ if (!pnext) ++ break; ++ pnext++; ++ if (*pnext != '\0') { ++ strtout = simple_strtoul(pnext, &ptmp, 16); ++ sprintf(extra + strlen(extra), " %d", strtout); ++ } else { ++ break; ++ } ++ pch = pnext; ++ } ++ wrqu->length = strlen(extra); ++ break; ++ default: ++ wrqu->length = 0; ++ ret = -EINVAL; ++ break; ++ } ++ ++ return ret; ++} ++ ++/* ++ * Input Format: %d,%x,%x ++ * %d is RF path, should be smaller than RF_PATH_MAX ++ * 1st %x is address(offset) ++ * 2st %x is data to write ++ */ ++ static int rtw_mp_write_rf(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u32 path, addr, data; ++ int ret; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ ret = sscanf(extra, "%d,%x,%x", &path, &addr, &data); ++ if (ret < 3) ++ return -EINVAL; ++ ++ if (path >= RF_PATH_MAX) ++ return -EINVAL; ++ if (addr > 0xFF) ++ return -EINVAL; ++ if (data > 0xFFFFF) ++ return -EINVAL; ++ ++ memset(extra, 0, wrqu->length); ++ ++ write_rfreg(padapter, path, addr, data); ++ ++ sprintf(extra, "write_rf completed\n"); ++ wrqu->length = strlen(extra); ++ ++ return 0; ++} ++ ++/* ++ * Input Format: %d,%x ++ * %d is RF path, should be smaller than RF_PATH_MAX ++ * %x is address(offset) ++ * ++ * Return: ++ * %d for data readed ++ */ ++static int rtw_mp_read_rf(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ char *pch, *pnext, *ptmp; ++ char data[20], tmp[20]; ++ u32 path, addr; ++ u32 ret, i = 0, j = 0, strtou = 0; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ ret = sscanf(input, "%d,%x", &path, &addr); ++ kfree(input); ++ if (ret < 2) ++ return -EINVAL; ++ ++ if (path >= RF_PATH_MAX) ++ return -EINVAL; ++ if (addr > 0xFF) ++ return -EINVAL; ++ ++ memset(extra, 0, wrqu->length); ++ ++ sprintf(data, "%08x", read_rfreg(padapter, path, addr)); ++ /* add read data format blank */ ++ for (i = 0; i <= strlen(data); i++) { ++ if (i % 2 == 0) { ++ tmp[j] = ' '; ++ j++; ++ } ++ tmp[j] = data[i]; ++ j++; ++ } ++ pch = tmp; ++ DBG_88E("pch =%s", pch); ++ ++ while (*pch != '\0') { ++ pnext = strpbrk(pch, " "); ++ pnext++; ++ if (*pnext != '\0') { ++ strtou = simple_strtoul(pnext, &ptmp, 16); ++ sprintf(extra + strlen(extra), " %d", strtou); ++ } else { ++ break; ++ } ++ pch = pnext; ++ } ++ wrqu->length = strlen(extra); ++ return 0; ++} ++ ++static int rtw_mp_start(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (padapter->registrypriv.mp_mode == 0) { ++ padapter->registrypriv.mp_mode = 1; ++ ++ rtw_pm_set_ips(padapter, IPS_NONE); ++ LeaveAllPowerSaveMode(padapter); ++ ++ MPT_InitializeAdapter(padapter, 1); ++ } ++ if (padapter->registrypriv.mp_mode == 0) ++ return -EPERM; ++ if (padapter->mppriv.mode == MP_OFF) { ++ if (mp_start_test(padapter) == _FAIL) ++ return -EPERM; ++ padapter->mppriv.mode = MP_ON; ++ } ++ return 0; ++} ++ ++static int rtw_mp_stop(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (padapter->registrypriv.mp_mode == 1) { ++ MPT_DeInitAdapter(padapter); ++ padapter->registrypriv.mp_mode = 0; ++ } ++ ++ if (padapter->mppriv.mode != MP_OFF) { ++ mp_stop_test(padapter); ++ padapter->mppriv.mode = MP_OFF; ++ } ++ ++ return 0; ++} ++ ++extern int wifirate2_ratetbl_inx(unsigned char rate); ++ ++static int rtw_mp_rate(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u32 rate = MPT_RATE_1M; ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ rate = rtw_atoi(input); ++ sprintf(extra, "Set data rate to %d", rate); ++ kfree(input); ++ if (rate <= 0x7f) ++ rate = wifirate2_ratetbl_inx((u8)rate); ++ else ++ rate = (rate - 0x80 + MPT_RATE_MCS0); ++ ++ if (rate >= MPT_RATE_LAST) ++ return -EINVAL; ++ ++ padapter->mppriv.rateidx = rate; ++ Hal_SetDataRate(padapter); ++ ++ wrqu->length = strlen(extra) + 1; ++ return 0; ++} ++ ++static int rtw_mp_channel(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ u32 channel = 1; ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ channel = rtw_atoi(input); ++ sprintf(extra, "Change channel %d to channel %d", padapter->mppriv.channel, channel); ++ ++ padapter->mppriv.channel = channel; ++ Hal_SetChannel(padapter); ++ ++ wrqu->length = strlen(extra) + 1; ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_bandwidth(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u32 bandwidth = 0, sg = 0; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ sscanf(extra, "40M =%d, shortGI =%d", &bandwidth, &sg); ++ ++ if (bandwidth != HT_CHANNEL_WIDTH_40) ++ bandwidth = HT_CHANNEL_WIDTH_20; ++ ++ padapter->mppriv.bandwidth = (u8)bandwidth; ++ padapter->mppriv.preamble = sg; ++ ++ SetBandwidth(padapter); ++ ++ return 0; ++} ++ ++static int rtw_mp_txpower(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u32 idx_a = 0, idx_b = 0; ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ sscanf(input, "patha =%d, pathb =%d", &idx_a, &idx_b); ++ ++ sprintf(extra, "Set power level path_A:%d path_B:%d", idx_a, idx_b); ++ padapter->mppriv.txpoweridx = (u8)idx_a; ++ padapter->mppriv.txpoweridx_b = (u8)idx_b; ++ padapter->mppriv.bSetTxPower = 1; ++ Hal_SetAntennaPathPower(padapter); ++ ++ wrqu->length = strlen(extra) + 1; ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_ant_tx(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u8 i; ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ u16 antenna = 0; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ ++ sprintf(extra, "switch Tx antenna to %s", input); ++ ++ for (i = 0; i < strlen(input); i++) { ++ switch (input[i]) { ++ case 'a': ++ antenna |= ANTENNA_A; ++ break; ++ case 'b': ++ antenna |= ANTENNA_B; ++ break; ++ } ++ } ++ padapter->mppriv.antenna_tx = antenna; ++ ++ Hal_SetAntenna(padapter); ++ ++ wrqu->length = strlen(extra) + 1; ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_ant_rx(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u8 i; ++ u16 antenna = 0; ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ memset(extra, 0, wrqu->length); ++ ++ sprintf(extra, "switch Rx antenna to %s", input); ++ ++ for (i = 0; i < strlen(input); i++) { ++ switch (input[i]) { ++ case 'a': ++ antenna |= ANTENNA_A; ++ break; ++ case 'b': ++ antenna |= ANTENNA_B; ++ break; ++ } ++ } ++ ++ padapter->mppriv.antenna_rx = antenna; ++ Hal_SetAntenna(padapter); ++ wrqu->length = strlen(extra); ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_ctx(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u32 pkTx = 1, countPkTx = 1, cotuTx = 1, CarrSprTx = 1, scTx = 1, sgleTx = 1, stop = 1; ++ u32 bStartTest = 1; ++ u32 count = 0; ++ struct mp_priv *pmp_priv; ++ struct pkt_attrib *pattrib; ++ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ pmp_priv = &padapter->mppriv; ++ ++ if (copy_from_user(extra, wrqu->pointer, wrqu->length)) ++ return -EFAULT; ++ ++ DBG_88E("%s: in =%s\n", __func__, extra); ++ ++ countPkTx = strncmp(extra, "count =", 5); /* strncmp true is 0 */ ++ cotuTx = strncmp(extra, "background", 20); ++ CarrSprTx = strncmp(extra, "background, cs", 20); ++ scTx = strncmp(extra, "background, sc", 20); ++ sgleTx = strncmp(extra, "background, stone", 20); ++ pkTx = strncmp(extra, "background, pkt", 20); ++ stop = strncmp(extra, "stop", 4); ++ sscanf(extra, "count =%d, pkt", &count); ++ ++ memset(extra, '\0', sizeof(*extra)); ++ ++ if (stop == 0) { ++ bStartTest = 0; /* To set Stop */ ++ pmp_priv->tx.stop = 1; ++ sprintf(extra, "Stop continuous Tx"); ++ } else { ++ bStartTest = 1; ++ if (pmp_priv->mode != MP_ON) { ++ if (pmp_priv->tx.stop != 1) { ++ DBG_88E("%s: MP_MODE != ON %d\n", __func__, pmp_priv->mode); ++ return -EFAULT; ++ } ++ } ++ } ++ ++ if (pkTx == 0 || countPkTx == 0) ++ pmp_priv->mode = MP_PACKET_TX; ++ if (sgleTx == 0) ++ pmp_priv->mode = MP_SINGLE_TONE_TX; ++ if (cotuTx == 0) ++ pmp_priv->mode = MP_CONTINUOUS_TX; ++ if (CarrSprTx == 0) ++ pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX; ++ if (scTx == 0) ++ pmp_priv->mode = MP_SINGLE_CARRIER_TX; ++ ++ switch (pmp_priv->mode) { ++ case MP_PACKET_TX: ++ if (bStartTest == 0) { ++ pmp_priv->tx.stop = 1; ++ pmp_priv->mode = MP_ON; ++ sprintf(extra, "Stop continuous Tx"); ++ } else if (pmp_priv->tx.stop == 1) { ++ sprintf(extra, "Start continuous DA = ffffffffffff len = 1500 count =%u,\n", count); ++ pmp_priv->tx.stop = 0; ++ pmp_priv->tx.count = count; ++ pmp_priv->tx.payload = 2; ++ pattrib = &pmp_priv->tx.attrib; ++ pattrib->pktlen = 1500; ++ memset(pattrib->dst, 0xFF, ETH_ALEN); ++ SetPacketTx(padapter); ++ } else { ++ return -EFAULT; ++ } ++ wrqu->length = strlen(extra); ++ return 0; ++ case MP_SINGLE_TONE_TX: ++ if (bStartTest != 0) ++ sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes."); ++ Hal_SetSingleToneTx(padapter, (u8)bStartTest); ++ break; ++ case MP_CONTINUOUS_TX: ++ if (bStartTest != 0) ++ sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes."); ++ Hal_SetContinuousTx(padapter, (u8)bStartTest); ++ break; ++ case MP_CARRIER_SUPPRISSION_TX: ++ if (bStartTest != 0) { ++ if (pmp_priv->rateidx <= MPT_RATE_11M) { ++ sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes."); ++ Hal_SetCarrierSuppressionTx(padapter, (u8)bStartTest); ++ } else { ++ sprintf(extra, "Specify carrier suppression but not CCK rate"); ++ } ++ } ++ break; ++ case MP_SINGLE_CARRIER_TX: ++ if (bStartTest != 0) ++ sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes."); ++ Hal_SetSingleCarrierTx(padapter, (u8)bStartTest); ++ break; ++ default: ++ sprintf(extra, "Error! Continuous-Tx is not on-going."); ++ return -EFAULT; ++ } ++ ++ if (bStartTest == 1 && pmp_priv->mode != MP_ON) { ++ struct mp_priv *pmp_priv = &padapter->mppriv; ++ if (pmp_priv->tx.stop == 0) { ++ pmp_priv->tx.stop = 1; ++ msleep(5); ++ } ++ pmp_priv->tx.stop = 0; ++ pmp_priv->tx.count = 1; ++ SetPacketTx(padapter); ++ } else { ++ pmp_priv->mode = MP_ON; ++ } ++ ++ wrqu->length = strlen(extra); ++ return 0; ++} ++ ++static int rtw_mp_arx(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u8 bStartRx = 0, bStopRx = 0, bQueryPhy; ++ u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0; ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!input) ++ return -ENOMEM; ++ ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ DBG_88E("%s: %s\n", __func__, input); ++ ++ bStartRx = (strncmp(input, "start", 5) == 0) ? 1 : 0; /* strncmp true is 0 */ ++ bStopRx = (strncmp(input, "stop", 5) == 0) ? 1 : 0; /* strncmp true is 0 */ ++ bQueryPhy = (strncmp(input, "phy", 3) == 0) ? 1 : 0; /* strncmp true is 0 */ ++ ++ if (bStartRx) { ++ sprintf(extra, "start"); ++ SetPacketRx(padapter, bStartRx); ++ } else if (bStopRx) { ++ SetPacketRx(padapter, 0); ++ sprintf(extra, "Received packet OK:%d CRC error:%d", padapter->mppriv.rx_pktcount, padapter->mppriv.rx_crcerrpktcount); ++ } else if (bQueryPhy) { ++ /* ++ OFDM FA ++ RegCF0[15:0] ++ RegCF2[31:16] ++ RegDA0[31:16] ++ RegDA4[15:0] ++ RegDA4[31:16] ++ RegDA8[15:0] ++ CCK FA ++ (RegA5B<<8) | RegA5C ++ */ ++ cckok = read_bbreg(padapter, 0xf88, 0xffffffff); ++ cckcrc = read_bbreg(padapter, 0xf84, 0xffffffff); ++ ofdmok = read_bbreg(padapter, 0xf94, 0x0000FFFF); ++ ofdmcrc = read_bbreg(padapter, 0xf94, 0xFFFF0000); ++ htok = read_bbreg(padapter, 0xf90, 0x0000FFFF); ++ htcrc = read_bbreg(padapter, 0xf90, 0xFFFF0000); ++ ++ OFDM_FA = read_bbreg(padapter, 0xcf0, 0x0000FFFF); ++ OFDM_FA = read_bbreg(padapter, 0xcf2, 0xFFFF0000); ++ OFDM_FA = read_bbreg(padapter, 0xda0, 0xFFFF0000); ++ OFDM_FA = read_bbreg(padapter, 0xda4, 0x0000FFFF); ++ OFDM_FA = read_bbreg(padapter, 0xda4, 0xFFFF0000); ++ OFDM_FA = read_bbreg(padapter, 0xda8, 0x0000FFFF); ++ CCK_FA = (rtw_read8(padapter, 0xa5b) << 8) | (rtw_read8(padapter, 0xa5c)); ++ ++ sprintf(extra, "Phy Received packet OK:%d CRC error:%d FA Counter: %d", cckok + ofdmok + htok, cckcrc + ofdmcrc + htcrc, OFDM_FA + CCK_FA); ++ } ++ wrqu->length = strlen(extra) + 1; ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_trx_query(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u32 txok, txfail, rxok, rxfail; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ txok = padapter->mppriv.tx.sended; ++ txfail = 0; ++ rxok = padapter->mppriv.rx_pktcount; ++ rxfail = padapter->mppriv.rx_crcerrpktcount; ++ ++ memset(extra, '\0', 128); ++ ++ sprintf(extra, "Tx OK:%d, Tx Fail:%d, Rx OK:%d, CRC error:%d ", txok, txfail, rxok, rxfail); ++ ++ wrqu->length = strlen(extra) + 1; ++ ++ return 0; ++} ++ ++static int rtw_mp_pwrtrk(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u8 enable; ++ u32 thermal; ++ s32 ret; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ memset(extra, 0, wrqu->length); ++ ++ enable = 1; ++ if (wrqu->length > 1) {/* not empty string */ ++ if (strncmp(input, "stop", 4) == 0) { ++ enable = 0; ++ sprintf(extra, "mp tx power tracking stop"); ++ } else if (sscanf(input, "ther =%d", &thermal)) { ++ ret = Hal_SetThermalMeter(padapter, (u8)thermal); ++ if (ret == _FAIL) ++ return -EPERM; ++ sprintf(extra, "mp tx power tracking start, target value =%d ok ", thermal); ++ } else { ++ kfree(input); ++ return -EINVAL; ++ } ++ } ++ ++ kfree(input); ++ ret = Hal_SetPowerTracking(padapter, enable); ++ if (ret == _FAIL) ++ return -EPERM; ++ ++ wrqu->length = strlen(extra); ++ return 0; ++} ++ ++static int rtw_mp_psd(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ ++ strcpy(extra, input); ++ ++ wrqu->length = mp_query_psd(padapter, extra); ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_thermal(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u8 val; ++ u16 bwrite = 1; ++ u16 addr = EEPROM_THERMAL_METER_88E; ++ ++ u16 cnt = 1; ++ u16 max_available_size = 0; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (copy_from_user(extra, wrqu->pointer, wrqu->length)) ++ return -EFAULT; ++ ++ bwrite = strncmp(extra, "write", 6); /* strncmp true is 0 */ ++ ++ Hal_GetThermalMeter(padapter, &val); ++ ++ if (bwrite == 0) { ++ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); ++ if (2 > max_available_size) { ++ DBG_88E("no available efuse!\n"); ++ return -EFAULT; ++ } ++ if (rtw_efuse_map_write(padapter, addr, cnt, &val) == _FAIL) { ++ DBG_88E("rtw_efuse_map_write error\n"); ++ return -EFAULT; ++ } else { ++ sprintf(extra, " efuse write ok :%d", val); ++ } ++ } else { ++ sprintf(extra, "%d", val); ++ } ++ wrqu->length = strlen(extra); ++ ++ return 0; ++} ++ ++static int rtw_mp_reset_stats(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ struct mp_priv *pmp_priv; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ pmp_priv = &padapter->mppriv; ++ ++ pmp_priv->tx.sended = 0; ++ pmp_priv->tx_pktcount = 0; ++ pmp_priv->rx_pktcount = 0; ++ pmp_priv->rx_crcerrpktcount = 0; ++ ++ /* reset phy counter */ ++ write_bbreg(padapter, 0xf14, BIT(16), 0x1); ++ msleep(10); ++ write_bbreg(padapter, 0xf14, BIT(16), 0x0); ++ ++ return 0; ++} ++ ++static int rtw_mp_dump(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ u32 value; ++ u8 rf_type, path_nums = 0; ++ u32 i, j = 1, path; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (strncmp(extra, "all", 4) == 0) { ++ DBG_88E("\n ======= MAC REG =======\n"); ++ for (i = 0x0; i < 0x300; i += 4) { ++ if (j % 4 == 1) ++ DBG_88E("0x%02x", i); ++ DBG_88E(" 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ DBG_88E("\n"); ++ } ++ for (i = 0x400; i < 0x1000; i += 4) { ++ if (j % 4 == 1) ++ DBG_88E("0x%02x", i); ++ DBG_88E(" 0x%08x ", rtw_read32(padapter, i)); ++ if ((j++) % 4 == 0) ++ DBG_88E("\n"); ++ } ++ ++ j = 1; ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ ++ DBG_88E("\n ======= RF REG =======\n"); ++ if ((RF_1T2R == rf_type) || (RF_1T1R == rf_type)) ++ path_nums = 1; ++ else ++ path_nums = 2; ++ ++ for (path = 0; path < path_nums; path++) { ++ for (i = 0; i < 0x34; i++) { ++ value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); ++ if (j % 4 == 1) ++ DBG_88E("0x%02x ", i); ++ DBG_88E(" 0x%08x ", value); ++ if ((j++) % 4 == 0) ++ DBG_88E("\n"); ++ } ++ } ++ } ++ return 0; ++} ++ ++static int rtw_mp_phypara(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *wrqu, char *extra) ++{ ++ char *input = kmalloc(wrqu->length, GFP_KERNEL); ++ u32 valxcap; ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->pointer, wrqu->length)) { ++ kfree(input); ++ return -EFAULT; ++ } ++ ++ DBG_88E("%s:iwpriv in =%s\n", __func__, input); ++ ++ sscanf(input, "xcap =%d", &valxcap); ++ ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_SetRFPath(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ char *input = kmalloc(wrqu->data.length, GFP_KERNEL); ++ u8 bMain = 1, bTurnoff = 1; ++ ++ if (!input) ++ return -ENOMEM; ++ if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length)) ++ return -EFAULT; ++ DBG_88E("%s:iwpriv in =%s\n", __func__, input); ++ ++ bMain = strncmp(input, "1", 2); /* strncmp true is 0 */ ++ bTurnoff = strncmp(input, "0", 3); /* strncmp true is 0 */ ++ ++ if (bMain == 0) { ++ MP_PHY_SetRFPathSwitch(padapter, true); ++ DBG_88E("%s:PHY_SetRFPathSwitch = true\n", __func__); ++ } else if (bTurnoff == 0) { ++ MP_PHY_SetRFPathSwitch(padapter, false); ++ DBG_88E("%s:PHY_SetRFPathSwitch = false\n", __func__); ++ } ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_QueryDrv(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ char *input = kmalloc(wrqu->data.length, GFP_KERNEL); ++ u8 qAutoLoad = 1; ++ struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); ++ ++ if (!input) ++ return -ENOMEM; ++ ++ if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length)) ++ return -EFAULT; ++ DBG_88E("%s:iwpriv in =%s\n", __func__, input); ++ ++ qAutoLoad = strncmp(input, "autoload", 8); /* strncmp true is 0 */ ++ ++ if (qAutoLoad == 0) { ++ DBG_88E("%s:qAutoLoad\n", __func__); ++ ++ if (pEEPROM->bautoload_fail_flag) ++ sprintf(extra, "fail"); ++ else ++ sprintf(extra, "ok"); ++ } ++ wrqu->data.length = strlen(extra) + 1; ++ kfree(input); ++ return 0; ++} ++ ++static int rtw_mp_set(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wdata, char *extra) ++{ ++ struct iw_point *wrqu = (struct iw_point *)wdata; ++ u32 subcmd = wrqu->flags; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!padapter) ++ return -ENETDOWN; ++ ++ if (!extra) { ++ wrqu->length = 0; ++ return -EIO; ++ } ++ ++ switch (subcmd) { ++ case MP_START: ++ DBG_88E("set case mp_start\n"); ++ rtw_mp_start(dev, info, wrqu, extra); ++ break; ++ case MP_STOP: ++ DBG_88E("set case mp_stop\n"); ++ rtw_mp_stop(dev, info, wrqu, extra); ++ break; ++ case MP_BANDWIDTH: ++ DBG_88E("set case mp_bandwidth\n"); ++ rtw_mp_bandwidth(dev, info, wrqu, extra); ++ break; ++ case MP_RESET_STATS: ++ DBG_88E("set case MP_RESET_STATS\n"); ++ rtw_mp_reset_stats(dev, info, wrqu, extra); ++ break; ++ case MP_SetRFPathSwh: ++ DBG_88E("set MP_SetRFPathSwitch\n"); ++ rtw_mp_SetRFPath(dev, info, wdata, extra); ++ break; ++ case CTA_TEST: ++ DBG_88E("set CTA_TEST\n"); ++ rtw_cta_test_start(dev, info, wdata, extra); ++ break; ++ } ++ ++ return 0; ++} ++ ++static int rtw_mp_get(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wdata, char *extra) ++{ ++ struct iw_point *wrqu = (struct iw_point *)wdata; ++ u32 subcmd = wrqu->flags; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ ++ if (!padapter) ++ return -ENETDOWN; ++ if (!extra) { ++ wrqu->length = 0; ++ return -EIO; ++ } ++ ++ switch (subcmd) { ++ case WRITE_REG: ++ rtw_mp_write_reg(dev, info, wrqu, extra); ++ break; ++ case WRITE_RF: ++ rtw_mp_write_rf(dev, info, wrqu, extra); ++ break; ++ case MP_PHYPARA: ++ DBG_88E("mp_get MP_PHYPARA\n"); ++ rtw_mp_phypara(dev, info, wrqu, extra); ++ break; ++ case MP_CHANNEL: ++ DBG_88E("set case mp_channel\n"); ++ rtw_mp_channel(dev, info, wrqu, extra); ++ break; ++ case READ_REG: ++ DBG_88E("mp_get READ_REG\n"); ++ rtw_mp_read_reg(dev, info, wrqu, extra); ++ break; ++ case READ_RF: ++ DBG_88E("mp_get READ_RF\n"); ++ rtw_mp_read_rf(dev, info, wrqu, extra); ++ break; ++ case MP_RATE: ++ DBG_88E("set case mp_rate\n"); ++ rtw_mp_rate(dev, info, wrqu, extra); ++ break; ++ case MP_TXPOWER: ++ DBG_88E("set case MP_TXPOWER\n"); ++ rtw_mp_txpower(dev, info, wrqu, extra); ++ break; ++ case MP_ANT_TX: ++ DBG_88E("set case MP_ANT_TX\n"); ++ rtw_mp_ant_tx(dev, info, wrqu, extra); ++ break; ++ case MP_ANT_RX: ++ DBG_88E("set case MP_ANT_RX\n"); ++ rtw_mp_ant_rx(dev, info, wrqu, extra); ++ break; ++ case MP_QUERY: ++ rtw_mp_trx_query(dev, info, wrqu, extra); ++ break; ++ case MP_CTX: ++ DBG_88E("set case MP_CTX\n"); ++ rtw_mp_ctx(dev, info, wrqu, extra); ++ break; ++ case MP_ARX: ++ DBG_88E("set case MP_ARX\n"); ++ rtw_mp_arx(dev, info, wrqu, extra); ++ break; ++ case EFUSE_GET: ++ DBG_88E("efuse get EFUSE_GET\n"); ++ rtw_mp_efuse_get(dev, info, wdata, extra); ++ break; ++ case MP_DUMP: ++ DBG_88E("set case MP_DUMP\n"); ++ rtw_mp_dump(dev, info, wrqu, extra); ++ break; ++ case MP_PSD: ++ DBG_88E("set case MP_PSD\n"); ++ rtw_mp_psd(dev, info, wrqu, extra); ++ break; ++ case MP_THER: ++ DBG_88E("set case MP_THER\n"); ++ rtw_mp_thermal(dev, info, wrqu, extra); ++ break; ++ case MP_QueryDrvStats: ++ DBG_88E("mp_get MP_QueryDrvStats\n"); ++ rtw_mp_QueryDrv(dev, info, wdata, extra); ++ break; ++ case MP_PWRTRK: ++ DBG_88E("set case MP_PWRTRK\n"); ++ rtw_mp_pwrtrk(dev, info, wrqu, extra); ++ break; ++ case EFUSE_SET: ++ DBG_88E("set case efuse set\n"); ++ rtw_mp_efuse_set(dev, info, wdata, extra); ++ break; ++ } ++ ++ msleep(10); /* delay 5ms for sending pkt before exit adb shell operation */ ++ return 0; ++} ++ ++static int rtw_tdls(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ return 0; ++} ++ ++static int rtw_tdls_get(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ return 0; ++} ++ ++static int rtw_test( ++ struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ u32 len; ++ u8 *pbuf, *pch; ++ char *ptmp; ++ u8 *delim = ","; ++ ++ DBG_88E("+%s\n", __func__); ++ len = wrqu->data.length; ++ ++ pbuf = kzalloc(len, GFP_KERNEL); ++ if (!pbuf) { ++ DBG_88E("%s: no memory!\n", __func__); ++ return -ENOMEM; ++ } ++ ++ if (copy_from_user(pbuf, wrqu->data.pointer, len)) { ++ kfree(pbuf); ++ DBG_88E("%s: copy from user fail!\n", __func__); ++ return -EFAULT; ++ } ++ DBG_88E("%s: string =\"%s\"\n", __func__, pbuf); ++ ++ ptmp = (char *)pbuf; ++ pch = strsep(&ptmp, delim); ++ if (!pch || strlen(pch) == 0) { ++ kfree(pbuf); ++ DBG_88E("%s: parameter error(level 1)!\n", __func__); ++ return -EFAULT; ++ } ++ kfree(pbuf); ++ return 0; ++} ++ ++static iw_handler rtw_handlers[] = { ++ IW_HANDLER(SIOCGIWNAME, rtw_wx_get_name), ++ IW_HANDLER(SIOCSIWNWID, dummy), ++ IW_HANDLER(SIOCGIWNWID, dummy), ++ IW_HANDLER(SIOCGIWFREQ, rtw_wx_get_freq), ++ IW_HANDLER(SIOCSIWMODE, rtw_wx_set_mode), ++ IW_HANDLER(SIOCGIWMODE, rtw_wx_get_mode), ++ IW_HANDLER(SIOCSIWSENS, dummy), ++ IW_HANDLER(SIOCGIWSENS, rtw_wx_get_sens), ++ IW_HANDLER(SIOCGIWRANGE, rtw_wx_get_range), ++ IW_HANDLER(SIOCSIWPRIV, rtw_wx_set_priv), ++ IW_HANDLER(SIOCSIWSPY, dummy), ++ IW_HANDLER(SIOCGIWSPY, dummy), ++ IW_HANDLER(SIOCSIWAP, rtw_wx_set_wap), ++ IW_HANDLER(SIOCGIWAP, rtw_wx_get_wap), ++ IW_HANDLER(SIOCSIWMLME, rtw_wx_set_mlme), ++ IW_HANDLER(SIOCGIWAPLIST, dummy), ++ IW_HANDLER(SIOCSIWSCAN, rtw_wx_set_scan), ++ IW_HANDLER(SIOCGIWSCAN, rtw_wx_get_scan), ++ IW_HANDLER(SIOCSIWESSID, rtw_wx_set_essid), ++ IW_HANDLER(SIOCGIWESSID, rtw_wx_get_essid), ++ IW_HANDLER(SIOCSIWNICKN, dummy), ++ IW_HANDLER(SIOCGIWNICKN, rtw_wx_get_nick), ++ IW_HANDLER(SIOCSIWRATE, rtw_wx_set_rate), ++ IW_HANDLER(SIOCGIWRATE, rtw_wx_get_rate), ++ IW_HANDLER(SIOCSIWRTS, rtw_wx_set_rts), ++ IW_HANDLER(SIOCGIWRTS, rtw_wx_get_rts), ++ IW_HANDLER(SIOCSIWFRAG, rtw_wx_set_frag), ++ IW_HANDLER(SIOCGIWFRAG, rtw_wx_get_frag), ++ IW_HANDLER(SIOCSIWTXPOW, dummy), ++ IW_HANDLER(SIOCGIWTXPOW, dummy), ++ IW_HANDLER(SIOCSIWRETRY, dummy), ++ IW_HANDLER(SIOCGIWRETRY, rtw_wx_get_retry), ++ IW_HANDLER(SIOCSIWENCODE, rtw_wx_set_enc), ++ IW_HANDLER(SIOCGIWENCODE, rtw_wx_get_enc), ++ IW_HANDLER(SIOCSIWPOWER, dummy), ++ IW_HANDLER(SIOCGIWPOWER, rtw_wx_get_power), ++ IW_HANDLER(SIOCSIWGENIE, rtw_wx_set_gen_ie), ++ IW_HANDLER(SIOCSIWAUTH, rtw_wx_set_auth), ++ IW_HANDLER(SIOCSIWENCODEEXT, rtw_wx_set_enc_ext), ++ IW_HANDLER(SIOCSIWPMKSA, rtw_wx_set_pmkid), ++}; ++ ++static const struct iw_priv_args rtw_private_args[] = { ++ { ++ SIOCIWFIRSTPRIV + 0x0, ++ IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x1, ++ IW_PRIV_TYPE_CHAR | 0x7FF, ++ IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x4, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x5, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x6, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x7, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x8, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x9, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie" ++ }, ++ ++ { ++ SIOCIWFIRSTPRIV + 0xA, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan" ++ }, ++ ++ { ++ SIOCIWFIRSTPRIV + 0xB, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0xC, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0xD, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x10, ++ IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, 0, "p2p_set" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x11, ++ IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | P2P_PRIVATE_IOCTL_SET_LEN, "p2p_get" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x12, ++ IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IFNAMSIZ, "p2p_get2" ++ }, ++ {SIOCIWFIRSTPRIV + 0x13, IW_PRIV_TYPE_CHAR | 128, 0, "NULL"}, ++ { ++ SIOCIWFIRSTPRIV + 0x14, ++ IW_PRIV_TYPE_CHAR | 64, 0, "tdls" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x15, ++ IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | P2P_PRIVATE_IOCTL_SET_LEN, "tdls_get" ++ }, ++ { ++ SIOCIWFIRSTPRIV + 0x16, ++ IW_PRIV_TYPE_CHAR | 64, 0, "pm_set" ++ }, ++ ++ {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ, 0, "rereg_nd_name"}, ++ ++ {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"}, ++ {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"}, ++ {SIOCIWFIRSTPRIV + 0x1D, IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test" ++ }, ++ ++ {SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0, ""}, /* set */ ++ {SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, ""},/* get */ ++/* --- sub-ioctls definitions --- */ ++ ++ {MP_START, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_start"}, /* set */ ++ {MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara"},/* get */ ++ {MP_STOP, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_stop"}, /* set */ ++ {MP_CHANNEL, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel"},/* get */ ++ {MP_BANDWIDTH, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_bandwidth"}, /* set */ ++ {MP_RATE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate"},/* get */ ++ {MP_RESET_STATS, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_reset_stats"}, ++ {MP_QUERY, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_query"}, /* get */ ++ {READ_REG, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg"}, ++ {MP_RATE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate"}, ++ {READ_RF, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf"}, ++ {MP_PSD, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"}, ++ {MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump"}, ++ {MP_TXPOWER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"}, ++ {MP_ANT_TX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"}, ++ {MP_ANT_RX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"}, ++ {WRITE_REG, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg"}, ++ {WRITE_RF, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf"}, ++ {MP_CTX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"}, ++ {MP_ARX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"}, ++ {MP_THER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"}, ++ {EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_set"}, ++ {EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"}, ++ {MP_PWRTRK, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_pwrtrk"}, ++ {MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery"}, ++ {MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"}, /* mp_ioctl */ ++ {MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_setrfpath"}, ++ {CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"}, ++}; ++ ++static iw_handler rtw_private_handler[] = { ++rtw_wx_write32, /* 0x00 */ ++rtw_wx_read32, /* 0x01 */ ++rtw_drvext_hdl, /* 0x02 */ ++rtw_mp_ioctl_hdl, /* 0x03 */ ++ ++/* for MM DTV platform */ ++ rtw_get_ap_info, /* 0x04 */ ++ ++ rtw_set_pid, /* 0x05 */ ++ rtw_wps_start, /* 0x06 */ ++ ++ rtw_wx_get_sensitivity, /* 0x07 */ ++ rtw_wx_set_mtk_wps_probe_ie, /* 0x08 */ ++ rtw_wx_set_mtk_wps_ie, /* 0x09 */ ++ ++/* Set Channel depend on the country code */ ++ rtw_wx_set_channel_plan, /* 0x0A */ ++ ++ rtw_dbg_port, /* 0x0B */ ++ rtw_wx_write_rf, /* 0x0C */ ++ rtw_wx_read_rf, /* 0x0D */ ++ ++ rtw_mp_set, /* 0x0E */ ++ rtw_mp_get, /* 0x0F */ ++ rtw_p2p_set, /* 0x10 */ ++ rtw_p2p_get, /* 0x11 */ ++ rtw_p2p_get2, /* 0x12 */ ++ ++ NULL, /* 0x13 */ ++ rtw_tdls, /* 0x14 */ ++ rtw_tdls_get, /* 0x15 */ ++ ++ rtw_pm_set, /* 0x16 */ ++ rtw_wx_priv_null, /* 0x17 */ ++ rtw_rereg_nd_name, /* 0x18 */ ++ rtw_wx_priv_null, /* 0x19 */ ++ ++ rtw_mp_efuse_set, /* 0x1A */ ++ rtw_mp_efuse_get, /* 0x1B */ ++ NULL, /* 0x1C is reserved for hostapd */ ++ rtw_test, /* 0x1D */ ++}; ++ ++static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); ++ struct iw_statistics *piwstats = &padapter->iwstats; ++ int tmp_noise = 0; ++ int tmp; ++ ++ if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { ++ piwstats->qual.qual = 0; ++ piwstats->qual.level = 0; ++ piwstats->qual.noise = 0; ++ } else { ++ tmp_noise = padapter->recvpriv.noise; ++ ++ piwstats->qual.level = padapter->signal_strength; ++ tmp = 219 + 3 * padapter->signal_strength; ++ tmp = min(100, tmp); ++ tmp = max(0, tmp); ++ piwstats->qual.qual = tmp; ++ piwstats->qual.noise = tmp_noise; ++ } ++ piwstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; ++ return &padapter->iwstats; ++} ++ ++struct iw_handler_def rtw_handlers_def = { ++ .standard = rtw_handlers, ++ .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler), ++ .private = rtw_private_handler, ++ .private_args = (struct iw_priv_args *)rtw_private_args, ++ .num_private = sizeof(rtw_private_handler) / sizeof(iw_handler), ++ .num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args), ++ .get_wireless_stats = rtw_get_wireless_stats, ++}; +diff --git a/drivers/staging/r8188eu/os_dep/mlme_linux.c b/drivers/staging/r8188eu/os_dep/mlme_linux.c +new file mode 100644 +index 000000000000..e3ee9dc7ab90 +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/mlme_linux.c +@@ -0,0 +1,216 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. i*/ ++ ++#define _MLME_OSDEP_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/mlme_osdep.h" ++ ++void rtw_join_timeout_handler (struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, mlmepriv.assoc_timer); ++ ++ _rtw_join_timeout_handler(adapter); ++} ++ ++void _rtw_scan_timeout_handler (struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, mlmepriv.scan_to_timer); ++ ++ rtw_scan_timeout_handler(adapter); ++} ++ ++static void _dynamic_check_timer_handlder(struct timer_list *t) ++{ ++ struct adapter *adapter = from_timer(adapter, t, mlmepriv.dynamic_chk_timer); ++ ++ if (adapter->registrypriv.mp_mode == 1) ++ return; ++ rtw_dynamic_check_timer_handlder(adapter); ++ _set_timer(&adapter->mlmepriv.dynamic_chk_timer, 2000); ++} ++ ++void rtw_init_mlme_timer(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ timer_setup(&pmlmepriv->assoc_timer, rtw_join_timeout_handler, 0); ++ timer_setup(&pmlmepriv->scan_to_timer, _rtw_scan_timeout_handler, 0); ++ timer_setup(&pmlmepriv->dynamic_chk_timer, _dynamic_check_timer_handlder, 0); ++} ++ ++void rtw_os_indicate_connect(struct adapter *adapter) ++{ ++ ++ rtw_indicate_wx_assoc_event(adapter); ++ netif_carrier_on(adapter->pnetdev); ++ if (adapter->pid[2] != 0) ++ rtw_signal_process(adapter->pid[2], SIGALRM); ++ ++} ++ ++void rtw_os_indicate_scan_done(struct adapter *padapter, bool aborted) ++{ ++ indicate_wx_scan_complete_event(padapter); ++} ++ ++static struct rt_pmkid_list backup_pmkid[NUM_PMKID_CACHE]; ++ ++void rtw_reset_securitypriv(struct adapter *adapter) ++{ ++ u8 backup_index = 0; ++ u8 backup_counter = 0x00; ++ u32 backup_time = 0; ++ ++ if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { ++ /* 802.1x */ ++ /* We have to backup the PMK information for WiFi PMK Caching test item. */ ++ /* Backup the btkip_countermeasure information. */ ++ /* When the countermeasure is trigger, the driver have to disconnect with AP for 60 seconds. */ ++ memset(&backup_pmkid[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); ++ memcpy(&backup_pmkid[0], &adapter->securitypriv.PMKIDList[0], sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); ++ backup_index = adapter->securitypriv.PMKIDIndex; ++ backup_counter = adapter->securitypriv.btkip_countermeasure; ++ backup_time = adapter->securitypriv.btkip_countermeasure_time; ++ memset((unsigned char *)&adapter->securitypriv, 0, sizeof(struct security_priv)); ++ ++ /* Restore the PMK information to securitypriv structure for the following connection. */ ++ memcpy(&adapter->securitypriv.PMKIDList[0], ++ &backup_pmkid[0], ++ sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); ++ adapter->securitypriv.PMKIDIndex = backup_index; ++ adapter->securitypriv.btkip_countermeasure = backup_counter; ++ adapter->securitypriv.btkip_countermeasure_time = backup_time; ++ adapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; ++ adapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled; ++ } else { ++ /* reset values in securitypriv */ ++ struct security_priv *psec_priv = &adapter->securitypriv; ++ ++ psec_priv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ ++ psec_priv->dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ psec_priv->dot11PrivacyKeyIndex = 0; ++ psec_priv->dot118021XGrpPrivacy = _NO_PRIVACY_; ++ psec_priv->dot118021XGrpKeyid = 1; ++ psec_priv->ndisauthtype = Ndis802_11AuthModeOpen; ++ psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled; ++ } ++} ++ ++void rtw_os_indicate_disconnect(struct adapter *adapter) ++{ ++ ++ netif_carrier_off(adapter->pnetdev); /* Do it first for tx broadcast pkt after disconnection issue! */ ++ rtw_indicate_wx_disassoc_event(adapter); ++ rtw_reset_securitypriv(adapter); ++} ++ ++void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie) ++{ ++ uint len; ++ u8 *buff, *p, i; ++ union iwreq_data wrqu; ++ ++ buff = NULL; ++ if (authmode == _WPA_IE_ID_) { ++ buff = kzalloc(IW_CUSTOM_MAX, GFP_KERNEL); ++ if (!buff) ++ return; ++ p = buff; ++ p += sprintf(p, "ASSOCINFO(ReqIEs ="); ++ len = sec_ie[1] + 2; ++ len = (len < IW_CUSTOM_MAX) ? len : IW_CUSTOM_MAX; ++ for (i = 0; i < len; i++) ++ p += sprintf(p, "%02x", sec_ie[i]); ++ p += sprintf(p, ")"); ++ memset(&wrqu, 0, sizeof(wrqu)); ++ wrqu.data.length = p - buff; ++ wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ? ++ wrqu.data.length : IW_CUSTOM_MAX; ++ wireless_send_event(adapter->pnetdev, IWEVCUSTOM, &wrqu, buff); ++ kfree(buff); ++ } ++} ++ ++static void _survey_timer_hdl(struct timer_list *t) ++{ ++ struct adapter *padapter = from_timer(padapter, t, mlmeextpriv.survey_timer); ++ ++ survey_timer_hdl(padapter); ++} ++ ++static void _link_timer_hdl(struct timer_list *t) ++{ ++ struct adapter *padapter = from_timer(padapter, t, mlmeextpriv.link_timer); ++ link_timer_hdl(padapter); ++} ++ ++static void _addba_timer_hdl(struct timer_list *t) ++{ ++ struct sta_info *psta = from_timer(psta, t, addba_retry_timer); ++ addba_timer_hdl(psta); ++} ++ ++void init_addba_retry_timer(struct adapter *padapter, struct sta_info *psta) ++{ ++ timer_setup(&psta->addba_retry_timer, _addba_timer_hdl, 0); ++} ++ ++void init_mlme_ext_timer(struct adapter *padapter) ++{ ++ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; ++ ++ timer_setup(&pmlmeext->survey_timer, _survey_timer_hdl, 0); ++ timer_setup(&pmlmeext->link_timer, _link_timer_hdl, 0); ++} ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++void rtw_indicate_sta_assoc_event(struct adapter *padapter, struct sta_info *psta) ++{ ++ union iwreq_data wrqu; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ if (!psta) ++ return; ++ ++ if (psta->aid > NUM_STA) ++ return; ++ ++ if (pstapriv->sta_aid[psta->aid - 1] != psta) ++ return; ++ ++ wrqu.addr.sa_family = ARPHRD_ETHER; ++ ++ memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN); ++ ++ DBG_88E("+rtw_indicate_sta_assoc_event\n"); ++ ++ wireless_send_event(padapter->pnetdev, IWEVREGISTERED, &wrqu, NULL); ++} ++ ++void rtw_indicate_sta_disassoc_event(struct adapter *padapter, struct sta_info *psta) ++{ ++ union iwreq_data wrqu; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ ++ if (!psta) ++ return; ++ ++ if (psta->aid > NUM_STA) ++ return; ++ ++ if (pstapriv->sta_aid[psta->aid - 1] != psta) ++ return; ++ ++ wrqu.addr.sa_family = ARPHRD_ETHER; ++ ++ memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN); ++ ++ DBG_88E("+rtw_indicate_sta_disassoc_event\n"); ++ ++ wireless_send_event(padapter->pnetdev, IWEVEXPIRED, &wrqu, NULL); ++} ++ ++#endif +diff --git a/drivers/staging/r8188eu/os_dep/os_intfs.c b/drivers/staging/r8188eu/os_dep/os_intfs.c +new file mode 100644 +index 000000000000..8d0158f4a45d +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/os_intfs.c +@@ -0,0 +1,1199 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _OS_INTFS_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/xmit_osdep.h" ++#include "../include/recv_osdep.h" ++#include "../include/hal_intf.h" ++#include "../include/rtw_ioctl.h" ++ ++#include "../include/usb_osintf.h" ++#include "../include/rtw_br_ext.h" ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Realtek Wireless Lan Driver"); ++MODULE_AUTHOR("Realtek Semiconductor Corp."); ++MODULE_VERSION(DRIVERVERSION); ++ ++#define CONFIG_BR_EXT_BRNAME "br0" ++#define RTW_NOTCH_FILTER 0 /* 0:Disable, 1:Enable, */ ++ ++/* module param defaults */ ++static int rtw_chip_version = 0x00; ++static int rtw_rfintfs = HWPI; ++static int rtw_lbkmode;/* RTL8712_AIR_TRX; */ ++static int rtw_network_mode = Ndis802_11IBSS;/* Ndis802_11Infrastructure; infra, ad-hoc, auto */ ++static int rtw_channel = 1;/* ad-hoc support requirement */ ++static int rtw_wireless_mode = WIRELESS_11BG_24N; ++static int rtw_vrtl_carrier_sense = AUTO_VCS; ++static int rtw_vcs_type = RTS_CTS;/* */ ++static int rtw_rts_thresh = 2347;/* */ ++static int rtw_frag_thresh = 2346;/* */ ++static int rtw_preamble = PREAMBLE_LONG;/* long, short, auto */ ++static int rtw_scan_mode = 1;/* active, passive */ ++static int rtw_adhoc_tx_pwr = 1; ++static int rtw_soft_ap; ++static int rtw_power_mgnt = 1; ++static int rtw_ips_mode = IPS_NORMAL; ++ ++static int rtw_smart_ps = 2; ++ ++module_param(rtw_ips_mode, int, 0644); ++MODULE_PARM_DESC(rtw_ips_mode, "The default IPS mode"); ++ ++static int rtw_debug = 1; ++static int rtw_radio_enable = 1; ++static int rtw_long_retry_lmt = 7; ++static int rtw_short_retry_lmt = 7; ++static int rtw_busy_thresh = 40; ++static int rtw_ack_policy = NORMAL_ACK; ++ ++static int rtw_mp_mode; ++ ++static int rtw_software_encrypt; ++static int rtw_software_decrypt; ++ ++static int rtw_acm_method;/* 0:By SW 1:By HW. */ ++ ++static int rtw_wmm_enable = 1;/* default is set to enable the wmm. */ ++static int rtw_uapsd_enable; ++static int rtw_uapsd_max_sp = NO_LIMIT; ++static int rtw_uapsd_acbk_en; ++static int rtw_uapsd_acbe_en; ++static int rtw_uapsd_acvi_en; ++static int rtw_uapsd_acvo_en; ++ ++static int rtw_led_enable = 1; ++ ++int rtw_ht_enable = 1; ++int rtw_cbw40_enable = 3; /* 0 :disable, bit(0): enable 2.4g, bit(1): enable 5g */ ++int rtw_ampdu_enable = 1;/* for enable tx_ampdu */ ++static int rtw_rx_stbc = 1;/* 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */ ++static int rtw_ampdu_amsdu;/* 0: disabled, 1:enabled, 2:auto */ ++ ++static int rtw_lowrate_two_xmit = 1;/* Use 2 path Tx to transmit MCS0~7 and legacy mode */ ++ ++static int rtw_rf_config = RF_819X_MAX_TYPE; /* auto */ ++static int rtw_low_power; ++static int rtw_wifi_spec; ++static int rtw_channel_plan = RT_CHANNEL_DOMAIN_MAX; ++static int rtw_AcceptAddbaReq = true;/* 0:Reject AP's Add BA req, 1:Accept AP's Add BA req. */ ++ ++static int rtw_antdiv_cfg = 2; /* 0:OFF , 1:ON, 2:decide by Efuse config */ ++static int rtw_antdiv_type; /* 0:decide by efuse 1: for 88EE, 1Tx and 1RxCG are diversity.(2 Ant with SPDT), 2: for 88EE, 1Tx and 2Rx are diversity.(2 Ant, Tx and RxCG are both on aux port, RxCS is on main port), 3: for 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port) */ ++ ++static int rtw_enusbss;/* 0:disable, 1:enable */ ++ ++static int rtw_hwpdn_mode = 2;/* 0:disable, 1:enable, 2: by EFUSE config */ ++ ++static int rtw_hwpwrp_detect; /* HW power ping detect 0:disable , 1:enable */ ++ ++static int rtw_hw_wps_pbc = 1; ++ ++int rtw_mc2u_disable; ++ ++static int rtw_80211d; ++ ++static char *ifname = "wlan%d"; ++module_param(ifname, charp, 0644); ++MODULE_PARM_DESC(ifname, "The default name to allocate for first interface"); ++ ++static char *if2name = "wlan%d"; ++module_param(if2name, charp, 0644); ++MODULE_PARM_DESC(if2name, "The default name to allocate for second interface"); ++ ++char *rtw_initmac; /* temp mac address if users want to use instead of the mac address in Efuse */ ++ ++module_param(rtw_initmac, charp, 0644); ++module_param(rtw_channel_plan, int, 0644); ++module_param(rtw_chip_version, int, 0644); ++module_param(rtw_rfintfs, int, 0644); ++module_param(rtw_lbkmode, int, 0644); ++module_param(rtw_network_mode, int, 0644); ++module_param(rtw_channel, int, 0644); ++module_param(rtw_mp_mode, int, 0644); ++module_param(rtw_wmm_enable, int, 0644); ++module_param(rtw_vrtl_carrier_sense, int, 0644); ++module_param(rtw_vcs_type, int, 0644); ++module_param(rtw_busy_thresh, int, 0644); ++module_param(rtw_led_enable, int, 0644); ++module_param(rtw_ht_enable, int, 0644); ++module_param(rtw_cbw40_enable, int, 0644); ++module_param(rtw_ampdu_enable, int, 0644); ++module_param(rtw_rx_stbc, int, 0644); ++module_param(rtw_ampdu_amsdu, int, 0644); ++module_param(rtw_lowrate_two_xmit, int, 0644); ++module_param(rtw_rf_config, int, 0644); ++module_param(rtw_power_mgnt, int, 0644); ++module_param(rtw_smart_ps, int, 0644); ++module_param(rtw_low_power, int, 0644); ++module_param(rtw_wifi_spec, int, 0644); ++module_param(rtw_antdiv_cfg, int, 0644); ++module_param(rtw_antdiv_type, int, 0644); ++module_param(rtw_enusbss, int, 0644); ++module_param(rtw_hwpdn_mode, int, 0644); ++module_param(rtw_hwpwrp_detect, int, 0644); ++module_param(rtw_hw_wps_pbc, int, 0644); ++ ++static uint rtw_max_roaming_times = 2; ++module_param(rtw_max_roaming_times, uint, 0644); ++MODULE_PARM_DESC(rtw_max_roaming_times, "The max roaming times to try"); ++ ++static int rtw_fw_iol = 1;/* 0:Disable, 1:enable, 2:by usb speed */ ++module_param(rtw_fw_iol, int, 0644); ++MODULE_PARM_DESC(rtw_fw_iol, "FW IOL"); ++ ++module_param(rtw_mc2u_disable, int, 0644); ++ ++module_param(rtw_80211d, int, 0644); ++MODULE_PARM_DESC(rtw_80211d, "Enable 802.11d mechanism"); ++ ++static uint rtw_notch_filter = RTW_NOTCH_FILTER; ++module_param(rtw_notch_filter, uint, 0644); ++MODULE_PARM_DESC(rtw_notch_filter, "0:Disable, 1:Enable, 2:Enable only for P2P"); ++module_param_named(debug, rtw_debug, int, 0444); ++MODULE_PARM_DESC(debug, "Set debug level (1-9) (default 1)"); ++ ++/* dummy routines */ ++void rtw_proc_remove_one(struct net_device *dev) ++{ ++} ++ ++void rtw_proc_init_one(struct net_device *dev) ++{ ++} ++ ++#if 0 /* TODO: Convert these to /sys */ ++void rtw_proc_init_one(struct net_device *dev) ++{ ++ struct proc_dir_entry *dir_dev = NULL; ++ struct proc_dir_entry *entry = NULL; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ u8 rf_type; ++ ++ if (!rtw_proc) { ++ memcpy(rtw_proc_name, DRV_NAME, sizeof(DRV_NAME)); ++ ++ rtw_proc = create_proc_entry(rtw_proc_name, S_IFDIR, init_net.proc_net); ++ if (!rtw_proc) { ++ DBG_88E(KERN_ERR "Unable to create rtw_proc directory\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("ver_info", S_IFREG | S_IRUGO, rtw_proc, proc_get_drv_version, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ } ++ ++ if (!padapter->dir_dev) { ++ padapter->dir_dev = create_proc_entry(dev->name, ++ S_IFDIR | S_IRUGO | S_IXUGO, ++ rtw_proc); ++ dir_dev = padapter->dir_dev; ++ if (!dir_dev) { ++ if (rtw_proc_cnt == 0) { ++ if (rtw_proc) { ++ remove_proc_entry(rtw_proc_name, init_net.proc_net); ++ rtw_proc = NULL; ++ } ++ } ++ ++ pr_info("Unable to create dir_dev directory\n"); ++ return; ++ } ++ } else { ++ return; ++ } ++ ++ rtw_proc_cnt++; ++ ++ entry = create_proc_read_entry("write_reg", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_write_reg, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_write_reg; ++ ++ entry = create_proc_read_entry("read_reg", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_read_reg, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_read_reg; ++ ++ entry = create_proc_read_entry("fwstate", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_fwstate, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("sec_info", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_sec_info, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("mlmext_state", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_mlmext_state, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("qos_option", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_qos_option, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("ht_option", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_ht_option, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("rf_info", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rf_info, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("ap_info", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_ap_info, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("adapter_state", S_IFREG | S_IRUGO, ++ dir_dev, proc_getstruct adapter_state, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("trx_info", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_trx_info, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("mac_reg_dump1", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_mac_reg_dump1, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("mac_reg_dump2", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_mac_reg_dump2, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("mac_reg_dump3", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_mac_reg_dump3, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("bb_reg_dump1", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_bb_reg_dump1, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("bb_reg_dump2", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_bb_reg_dump2, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("bb_reg_dump3", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_bb_reg_dump3, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("rf_reg_dump1", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rf_reg_dump1, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("rf_reg_dump2", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rf_reg_dump2, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ if ((RF_1T2R == rf_type) || (RF_1T1R == rf_type)) { ++ entry = create_proc_read_entry("rf_reg_dump3", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rf_reg_dump3, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("rf_reg_dump4", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rf_reg_dump4, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ } ++ ++#ifdef CONFIG_88EU_AP_MODE ++ ++ entry = create_proc_read_entry("all_sta_info", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_all_sta_info, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++#endif ++ ++ entry = create_proc_read_entry("best_channel", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_best_channel, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ ++ entry = create_proc_read_entry("rx_signal", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rx_signal, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_rx_signal; ++ entry = create_proc_read_entry("ht_enable", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_ht_enable, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_ht_enable; ++ ++ entry = create_proc_read_entry("cbw40_enable", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_cbw40_enable, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_cbw40_enable; ++ ++ entry = create_proc_read_entry("ampdu_enable", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_ampdu_enable, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_ampdu_enable; ++ ++ entry = create_proc_read_entry("rx_stbc", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rx_stbc, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_rx_stbc; ++ ++ entry = create_proc_read_entry("path_rssi", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_two_path_rssi, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry = create_proc_read_entry("rssi_disp", S_IFREG | S_IRUGO, ++ dir_dev, proc_get_rssi_disp, dev); ++ if (!entry) { ++ pr_info("Unable to create_proc_read_entry!\n"); ++ return; ++ } ++ entry->write_proc = proc_set_rssi_disp; ++} ++ ++void rtw_proc_remove_one(struct net_device *dev) ++{ ++ struct proc_dir_entry *dir_dev = NULL; ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ u8 rf_type; ++ ++ dir_dev = padapter->dir_dev; ++ padapter->dir_dev = NULL; ++ ++ if (dir_dev) { ++ remove_proc_entry("write_reg", dir_dev); ++ remove_proc_entry("read_reg", dir_dev); ++ remove_proc_entry("fwstate", dir_dev); ++ remove_proc_entry("sec_info", dir_dev); ++ remove_proc_entry("mlmext_state", dir_dev); ++ remove_proc_entry("qos_option", dir_dev); ++ remove_proc_entry("ht_option", dir_dev); ++ remove_proc_entry("rf_info", dir_dev); ++ remove_proc_entry("ap_info", dir_dev); ++ remove_proc_entry("adapter_state", dir_dev); ++ remove_proc_entry("trx_info", dir_dev); ++ remove_proc_entry("mac_reg_dump1", dir_dev); ++ remove_proc_entry("mac_reg_dump2", dir_dev); ++ remove_proc_entry("mac_reg_dump3", dir_dev); ++ remove_proc_entry("bb_reg_dump1", dir_dev); ++ remove_proc_entry("bb_reg_dump2", dir_dev); ++ remove_proc_entry("bb_reg_dump3", dir_dev); ++ remove_proc_entry("rf_reg_dump1", dir_dev); ++ remove_proc_entry("rf_reg_dump2", dir_dev); ++ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); ++ if ((RF_1T2R == rf_type) || (RF_1T1R == rf_type)) { ++ remove_proc_entry("rf_reg_dump3", dir_dev); ++ remove_proc_entry("rf_reg_dump4", dir_dev); ++ } ++#ifdef CONFIG_88EU_AP_MODE ++ remove_proc_entry("all_sta_info", dir_dev); ++#endif ++ ++ remove_proc_entry("best_channel", dir_dev); ++ remove_proc_entry("rx_signal", dir_dev); ++ remove_proc_entry("cbw40_enable", dir_dev); ++ remove_proc_entry("ht_enable", dir_dev); ++ remove_proc_entry("ampdu_enable", dir_dev); ++ remove_proc_entry("rx_stbc", dir_dev); ++ remove_proc_entry("path_rssi", dir_dev); ++ remove_proc_entry("rssi_disp", dir_dev); ++ remove_proc_entry(dev->name, rtw_proc); ++ dir_dev = NULL; ++ } else { ++ return; ++ } ++ rtw_proc_cnt--; ++ ++ if (rtw_proc_cnt == 0) { ++ if (rtw_proc) { ++ remove_proc_entry("ver_info", rtw_proc); ++ ++ remove_proc_entry(rtw_proc_name, init_net.proc_net); ++ rtw_proc = NULL; ++ } ++ } ++} ++#endif ++ ++static uint loadparam(struct adapter *padapter, struct net_device *pnetdev) ++{ ++ struct registry_priv *registry_par = &padapter->registrypriv; ++ ++ GlobalDebugLevel = rtw_debug; ++ registry_par->chip_version = (u8)rtw_chip_version; ++ registry_par->rfintfs = (u8)rtw_rfintfs; ++ registry_par->lbkmode = (u8)rtw_lbkmode; ++ registry_par->network_mode = (u8)rtw_network_mode; ++ ++ memcpy(registry_par->ssid.Ssid, "ANY", 3); ++ registry_par->ssid.SsidLength = 3; ++ ++ registry_par->channel = (u8)rtw_channel; ++ registry_par->wireless_mode = (u8)rtw_wireless_mode; ++ registry_par->vrtl_carrier_sense = (u8)rtw_vrtl_carrier_sense; ++ registry_par->vcs_type = (u8)rtw_vcs_type; ++ registry_par->rts_thresh = (u16)rtw_rts_thresh; ++ registry_par->frag_thresh = (u16)rtw_frag_thresh; ++ registry_par->preamble = (u8)rtw_preamble; ++ registry_par->scan_mode = (u8)rtw_scan_mode; ++ registry_par->adhoc_tx_pwr = (u8)rtw_adhoc_tx_pwr; ++ registry_par->soft_ap = (u8)rtw_soft_ap; ++ registry_par->smart_ps = (u8)rtw_smart_ps; ++ registry_par->power_mgnt = (u8)rtw_power_mgnt; ++ registry_par->ips_mode = (u8)rtw_ips_mode; ++ registry_par->radio_enable = (u8)rtw_radio_enable; ++ registry_par->long_retry_lmt = (u8)rtw_long_retry_lmt; ++ registry_par->short_retry_lmt = (u8)rtw_short_retry_lmt; ++ registry_par->busy_thresh = (u16)rtw_busy_thresh; ++ registry_par->ack_policy = (u8)rtw_ack_policy; ++ registry_par->mp_mode = (u8)rtw_mp_mode; ++ registry_par->software_encrypt = (u8)rtw_software_encrypt; ++ registry_par->software_decrypt = (u8)rtw_software_decrypt; ++ registry_par->acm_method = (u8)rtw_acm_method; ++ ++ /* UAPSD */ ++ registry_par->wmm_enable = (u8)rtw_wmm_enable; ++ registry_par->uapsd_enable = (u8)rtw_uapsd_enable; ++ registry_par->uapsd_max_sp = (u8)rtw_uapsd_max_sp; ++ registry_par->uapsd_acbk_en = (u8)rtw_uapsd_acbk_en; ++ registry_par->uapsd_acbe_en = (u8)rtw_uapsd_acbe_en; ++ registry_par->uapsd_acvi_en = (u8)rtw_uapsd_acvi_en; ++ registry_par->uapsd_acvo_en = (u8)rtw_uapsd_acvo_en; ++ ++ registry_par->led_enable = (u8)rtw_led_enable; ++ ++ registry_par->ht_enable = (u8)rtw_ht_enable; ++ registry_par->cbw40_enable = (u8)rtw_cbw40_enable; ++ registry_par->ampdu_enable = (u8)rtw_ampdu_enable; ++ registry_par->rx_stbc = (u8)rtw_rx_stbc; ++ registry_par->ampdu_amsdu = (u8)rtw_ampdu_amsdu; ++ registry_par->lowrate_two_xmit = (u8)rtw_lowrate_two_xmit; ++ registry_par->rf_config = (u8)rtw_rf_config; ++ registry_par->low_power = (u8)rtw_low_power; ++ registry_par->wifi_spec = (u8)rtw_wifi_spec; ++ registry_par->channel_plan = (u8)rtw_channel_plan; ++ registry_par->bAcceptAddbaReq = (u8)rtw_AcceptAddbaReq; ++ registry_par->antdiv_cfg = (u8)rtw_antdiv_cfg; ++ registry_par->antdiv_type = (u8)rtw_antdiv_type; ++ registry_par->hwpdn_mode = (u8)rtw_hwpdn_mode;/* 0:disable, 1:enable, 2:by EFUSE config */ ++ registry_par->hwpwrp_detect = (u8)rtw_hwpwrp_detect;/* 0:disable, 1:enable */ ++ registry_par->hw_wps_pbc = (u8)rtw_hw_wps_pbc; ++ ++ registry_par->max_roaming_times = (u8)rtw_max_roaming_times; ++ ++ registry_par->fw_iol = rtw_fw_iol; ++ ++ registry_par->enable80211d = (u8)rtw_80211d; ++ snprintf(registry_par->ifname, 16, "%s", ifname); ++ snprintf(registry_par->if2name, 16, "%s", if2name); ++ registry_par->notch_filter = (u8)rtw_notch_filter; ++ ++ return _SUCCESS; ++} ++ ++static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); ++ struct sockaddr *addr = p; ++ ++ if (!padapter->bup) ++ memcpy(padapter->eeprompriv.mac_addr, addr->sa_data, ETH_ALEN); ++ ++ return 0; ++} ++ ++static struct net_device_stats *rtw_net_get_stats(struct net_device *pnetdev) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ ++ padapter->stats.tx_packets = pxmitpriv->tx_pkts;/* pxmitpriv->tx_pkts++; */ ++ padapter->stats.rx_packets = precvpriv->rx_pkts;/* precvpriv->rx_pkts++; */ ++ padapter->stats.tx_dropped = pxmitpriv->tx_drop; ++ padapter->stats.rx_dropped = precvpriv->rx_drop; ++ padapter->stats.tx_bytes = pxmitpriv->tx_bytes; ++ padapter->stats.rx_bytes = precvpriv->rx_bytes; ++ return &padapter->stats; ++} ++ ++/* ++ * AC to queue mapping ++ * ++ * AC_VO -> queue 0 ++ * AC_VI -> queue 1 ++ * AC_BE -> queue 2 ++ * AC_BK -> queue 3 ++ */ ++static const u16 rtw_1d_to_queue[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; ++ ++/* Given a data frame determine the 802.1p/1d tag to use. */ ++static unsigned int rtw_classify8021d(struct sk_buff *skb) ++{ ++ unsigned int dscp; ++ ++ /* skb->priority values from 256->263 are magic values to ++ * directly indicate a specific 802.1d priority. This is used ++ * to allow 802.1d priority to be passed directly in from VLAN ++ * tags, etc. ++ */ ++ if (skb->priority >= 256 && skb->priority <= 263) ++ return skb->priority - 256; ++ ++ switch (skb->protocol) { ++ case htons(ETH_P_IP): ++ dscp = ip_hdr(skb)->tos & 0xfc; ++ break; ++ default: ++ return 0; ++ } ++ ++ return dscp >> 5; ++} ++ ++static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb, struct net_device *sb_dev) ++{ ++ struct adapter *padapter = rtw_netdev_priv(dev); ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ skb->priority = rtw_classify8021d(skb); ++ ++ if (pmlmepriv->acm_mask != 0) ++ skb->priority = qos_acm(pmlmepriv->acm_mask, skb->priority); ++ ++ return rtw_1d_to_queue[skb->priority]; ++} ++ ++u16 rtw_recv_select_queue(struct sk_buff *skb) ++{ ++ struct iphdr *piphdr; ++ unsigned int dscp; ++ __be16 eth_type; ++ u32 priority; ++ u8 *pdata = skb->data; ++ ++ memcpy(ð_type, pdata + (ETH_ALEN << 1), 2); ++ ++ switch (eth_type) { ++ case htons(ETH_P_IP): ++ piphdr = (struct iphdr *)(pdata + ETH_HLEN); ++ dscp = piphdr->tos & 0xfc; ++ priority = dscp >> 5; ++ break; ++ default: ++ priority = 0; ++ } ++ ++ return rtw_1d_to_queue[priority]; ++} ++ ++static const struct net_device_ops rtw_netdev_ops = { ++ .ndo_open = netdev_open, ++ .ndo_stop = netdev_close, ++ .ndo_start_xmit = rtw_xmit_entry, ++ .ndo_select_queue = rtw_select_queue, ++ .ndo_set_mac_address = rtw_net_set_mac_address, ++ .ndo_get_stats = rtw_net_get_stats, ++}; ++ ++int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname) ++{ ++ int err; ++ ++ err = dev_alloc_name(pnetdev, ifname); ++ if (err < 0) ++ return err; ++ ++ netif_carrier_off(pnetdev); ++ return 0; ++} ++ ++static const struct device_type wlan_type = { ++ .name = "wlan", ++}; ++ ++struct net_device *rtw_init_netdev(struct adapter *old_padapter) ++{ ++ struct adapter *padapter; ++ struct net_device *pnetdev; ++ ++ if (old_padapter) ++ pnetdev = rtw_alloc_etherdev_with_old_priv(sizeof(struct adapter), (void *)old_padapter); ++ else ++ pnetdev = rtw_alloc_etherdev(sizeof(struct adapter)); ++ ++ if (!pnetdev) ++ return NULL; ++ ++ pnetdev->dev.type = &wlan_type; ++ padapter = rtw_netdev_priv(pnetdev); ++ padapter->pnetdev = pnetdev; ++ DBG_88E("register rtw_netdev_ops to netdev_ops\n"); ++ pnetdev->netdev_ops = &rtw_netdev_ops; ++ pnetdev->watchdog_timeo = HZ * 3; /* 3 second timeout */ ++ pnetdev->wireless_handlers = (struct iw_handler_def *)&rtw_handlers_def; ++ ++ /* step 2. */ ++ loadparam(padapter, pnetdev); ++ ++ return pnetdev; ++} ++ ++u32 rtw_start_drv_threads(struct adapter *padapter) ++{ ++ u32 _status = _SUCCESS; ++ ++ padapter->cmdThread = kthread_run(rtw_cmd_thread, padapter, "RTW_CMD_THREAD"); ++ if (IS_ERR(padapter->cmdThread)) ++ _status = _FAIL; ++ else ++ _rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema); /* wait for cmd_thread to run */ ++ ++ rtw_hal_start_thread(padapter); ++ return _status; ++} ++ ++void rtw_stop_drv_threads(struct adapter *padapter) ++{ ++ /* Below is to termindate rtw_cmd_thread & event_thread... */ ++ up(&padapter->cmdpriv.cmd_queue_sema); ++ if (padapter->cmdThread) ++ _rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema); ++ ++ rtw_hal_stop_thread(padapter); ++} ++ ++static u8 rtw_init_default_value(struct adapter *padapter) ++{ ++ struct registry_priv *pregistrypriv = &padapter->registrypriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ ++ /* xmit_priv */ ++ pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense; ++ pxmitpriv->vcs = pregistrypriv->vcs_type; ++ pxmitpriv->vcs_type = pregistrypriv->vcs_type; ++ pxmitpriv->frag_len = pregistrypriv->frag_thresh; ++ ++ /* mlme_priv */ ++ pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */ ++ pmlmepriv->scan_mode = SCAN_ACTIVE; ++ ++ /* ht_priv */ ++ pmlmepriv->htpriv.ampdu_enable = false;/* set to disabled */ ++ ++ /* security_priv */ ++ psecuritypriv->binstallGrpkey = _FAIL; ++ psecuritypriv->sw_encrypt = pregistrypriv->software_encrypt; ++ psecuritypriv->sw_decrypt = pregistrypriv->software_decrypt; ++ psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ ++ psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; ++ psecuritypriv->dot11PrivacyKeyIndex = 0; ++ psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; ++ psecuritypriv->dot118021XGrpKeyid = 1; ++ psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; ++ psecuritypriv->ndisencryptstatus = Ndis802_11WEPDisabled; ++ ++ /* registry_priv */ ++ rtw_init_registrypriv_dev_network(padapter); ++ rtw_update_registrypriv_dev_network(padapter); ++ ++ /* hal_priv */ ++ rtw_hal_def_value_init(padapter); ++ ++ /* misc. */ ++ padapter->bReadPortCancel = false; ++ padapter->bWritePortCancel = false; ++ padapter->bRxRSSIDisplay = 0; ++ padapter->bNotifyChannelChange = 0; ++#ifdef CONFIG_88EU_P2P ++ padapter->bShowGetP2PState = 1; ++#endif ++ return _SUCCESS; ++} ++ ++u8 rtw_reset_drv_sw(struct adapter *padapter) ++{ ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; ++ ++ /* hal_priv */ ++ rtw_hal_def_value_init(padapter); ++ padapter->bReadPortCancel = false; ++ padapter->bWritePortCancel = false; ++ padapter->bRxRSSIDisplay = 0; ++ pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */ ++ ++ padapter->xmitpriv.tx_pkts = 0; ++ padapter->recvpriv.rx_pkts = 0; ++ ++ pmlmepriv->LinkDetectInfo.bBusyTraffic = false; ++ ++ _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING); ++ ++ rtw_hal_sreset_reset_value(padapter); ++ pwrctrlpriv->pwr_state_check_cnts = 0; ++ ++ /* mlmeextpriv */ ++ padapter->mlmeextpriv.sitesurvey_res.state = SCAN_DISABLE; ++ ++ rtw_set_signal_stat_timer(&padapter->recvpriv); ++ ++ return _SUCCESS; ++} ++ ++u8 rtw_init_drv_sw(struct adapter *padapter) ++{ ++ u8 ret8 = _SUCCESS; ++ ++ if ((rtw_init_cmd_priv(&padapter->cmdpriv)) == _FAIL) { ++ ret8 = _FAIL; ++ goto exit; ++ } ++ ++ padapter->cmdpriv.padapter = padapter; ++ ++ if ((rtw_init_evt_priv(&padapter->evtpriv)) == _FAIL) { ++ ret8 = _FAIL; ++ goto exit; ++ } ++ ++ if (rtw_init_mlme_priv(padapter) == _FAIL) { ++ ret8 = _FAIL; ++ goto exit; ++ } ++ ++#ifdef CONFIG_88EU_P2P ++ rtw_init_wifidirect_timers(padapter); ++ init_wifidirect_info(padapter, P2P_ROLE_DISABLE); ++ reset_global_wifidirect_info(padapter); ++#endif /* CONFIG_88EU_P2P */ ++ ++ if (init_mlme_ext_priv(padapter) == _FAIL) { ++ ret8 = _FAIL; ++ goto exit; ++ } ++ ++ if (_rtw_init_xmit_priv(&padapter->xmitpriv, padapter) == _FAIL) { ++ DBG_88E("Can't _rtw_init_xmit_priv\n"); ++ ret8 = _FAIL; ++ goto exit; ++ } ++ ++ if (_rtw_init_recv_priv(&padapter->recvpriv, padapter) == _FAIL) { ++ DBG_88E("Can't _rtw_init_recv_priv\n"); ++ ret8 = _FAIL; ++ goto exit; ++ } ++ ++ if (_rtw_init_sta_priv(&padapter->stapriv) == _FAIL) { ++ DBG_88E("Can't _rtw_init_sta_priv\n"); ++ ret8 = _FAIL; ++ goto exit; ++ } ++ ++ padapter->stapriv.padapter = padapter; ++ ++ rtw_init_bcmc_stainfo(padapter); ++ ++ rtw_init_pwrctrl_priv(padapter); ++ ++ if (init_mp_priv(padapter) == _FAIL) ++ DBG_88E("%s: initialize MP private data Fail!\n", __func__); ++ ++ ret8 = rtw_init_default_value(padapter); ++ ++ rtw_hal_dm_init(padapter); ++ rtw_hal_sw_led_init(padapter); ++ ++ rtw_hal_sreset_init(padapter); ++ ++ spin_lock_init(&padapter->br_ext_lock); ++ ++exit: ++ return ret8; ++} ++ ++void rtw_cancel_all_timer(struct adapter *padapter) ++{ ++ _cancel_timer_ex(&padapter->mlmepriv.assoc_timer); ++ ++ _cancel_timer_ex(&padapter->mlmepriv.scan_to_timer); ++ ++ _cancel_timer_ex(&padapter->mlmepriv.dynamic_chk_timer); ++ ++ /* cancel sw led timer */ ++ rtw_hal_sw_led_deinit(padapter); ++ ++ _cancel_timer_ex(&padapter->pwrctrlpriv.pwr_state_check_timer); ++ ++ _cancel_timer_ex(&padapter->recvpriv.signal_stat_timer); ++ /* cancel dm timer */ ++ rtw_hal_dm_deinit(padapter); ++} ++ ++u8 rtw_free_drv_sw(struct adapter *padapter) ++{ ++ /* we can call rtw_p2p_enable here, but: */ ++ /* 1. rtw_p2p_enable may have IO operation */ ++ /* 2. rtw_p2p_enable is bundled with wext interface */ ++ #ifdef CONFIG_88EU_P2P ++ { ++ struct wifidirect_info *pwdinfo = &padapter->wdinfo; ++ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { ++ _cancel_timer_ex(&pwdinfo->find_phase_timer); ++ _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); ++ _cancel_timer_ex(&pwdinfo->pre_tx_scan_timer); ++ rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE); ++ } ++ } ++ #endif ++ ++ free_mlme_ext_priv(&padapter->mlmeextpriv); ++ ++ rtw_free_cmd_priv(&padapter->cmdpriv); ++ ++ rtw_free_evt_priv(&padapter->evtpriv); ++ ++ rtw_free_mlme_priv(&padapter->mlmepriv); ++ _rtw_free_xmit_priv(&padapter->xmitpriv); ++ ++ _rtw_free_sta_priv(&padapter->stapriv); /* will free bcmc_stainfo here */ ++ ++ _rtw_free_recv_priv(&padapter->recvpriv); ++ ++ rtw_free_pwrctrl_priv(padapter); ++ ++ rtw_hal_free_data(padapter); ++ ++ /* free the old_pnetdev */ ++ if (padapter->rereg_nd_name_priv.old_pnetdev) { ++ free_netdev(padapter->rereg_nd_name_priv.old_pnetdev); ++ padapter->rereg_nd_name_priv.old_pnetdev = NULL; ++ } ++ ++ /* clear pbuddystruct adapter to avoid access wrong pointer. */ ++ if (padapter->pbuddy_adapter) ++ padapter->pbuddy_adapter->pbuddy_adapter = NULL; ++ ++ return _SUCCESS; ++} ++ ++void netdev_br_init(struct net_device *netdev) ++{ ++ struct adapter *adapter = (struct adapter *)rtw_netdev_priv(netdev); ++ ++ rcu_read_lock(); ++ ++ if (rcu_dereference(adapter->pnetdev->rx_handler_data)) { ++ struct net_device *br_netdev; ++ struct net *devnet = NULL; ++ ++ devnet = dev_net(netdev); ++ br_netdev = dev_get_by_name(devnet, CONFIG_BR_EXT_BRNAME); ++ if (br_netdev) { ++ memcpy(adapter->br_mac, br_netdev->dev_addr, ETH_ALEN); ++ dev_put(br_netdev); ++ } else { ++ pr_info("%s()-%d: dev_get_by_name(%s) failed!", ++ __func__, __LINE__, CONFIG_BR_EXT_BRNAME); ++ } ++ } ++ adapter->ethBrExtInfo.addPPPoETag = 1; ++ ++ rcu_read_unlock(); ++} ++ ++int _netdev_open(struct net_device *pnetdev) ++{ ++ uint status; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); ++ struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; ++ ++ DBG_88E("+88eu_drv - drv_open, bup =%d\n", padapter->bup); ++ ++ if (pwrctrlpriv->ps_flag) { ++ padapter->net_closed = false; ++ goto netdev_open_normal_process; ++ } ++ ++ if (!padapter->bup) { ++ padapter->bDriverStopped = false; ++ padapter->bSurpriseRemoved = false; ++ padapter->bCardDisableWOHSM = false; ++ ++ status = rtw_hal_init(padapter); ++ if (status == _FAIL) ++ goto netdev_open_error; ++ ++ pr_info("MAC Address = %pM\n", pnetdev->dev_addr); ++ ++ status = rtw_start_drv_threads(padapter); ++ if (status == _FAIL) { ++ pr_info("Initialize driver software resource Failed!\n"); ++ goto netdev_open_error; ++ } ++ ++ if (init_hw_mlme_ext(padapter) == _FAIL) { ++ pr_info("can't init mlme_ext_priv\n"); ++ goto netdev_open_error; ++ } ++ if (padapter->intf_start) ++ padapter->intf_start(padapter); ++ rtw_proc_init_one(pnetdev); ++ ++ rtw_led_control(padapter, LED_CTL_NO_LINK); ++ ++ padapter->bup = true; ++ } ++ padapter->net_closed = false; ++ ++ _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); ++ ++ padapter->pwrctrlpriv.bips_processing = false; ++ rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); ++ ++ if (!rtw_netif_queue_stopped(pnetdev)) ++ rtw_netif_start_queue(pnetdev); ++ else ++ rtw_netif_wake_queue(pnetdev); ++ ++ netdev_br_init(pnetdev); ++ ++netdev_open_normal_process: ++ DBG_88E("-88eu_drv - drv_open, bup =%d\n", padapter->bup); ++ return 0; ++ ++netdev_open_error: ++ padapter->bup = false; ++ netif_carrier_off(pnetdev); ++ rtw_netif_stop_queue(pnetdev); ++ DBG_88E("-88eu_drv - drv_open fail, bup =%d\n", padapter->bup); ++ return -1; ++} ++ ++int netdev_open(struct net_device *pnetdev) ++{ ++ int ret; ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); ++ ++ _enter_critical_mutex(padapter->hw_init_mutex, NULL); ++ ret = _netdev_open(pnetdev); ++ _exit_critical_mutex(padapter->hw_init_mutex, NULL); ++ return ret; ++} ++ ++static int ips_netdrv_open(struct adapter *padapter) ++{ ++ int status = _SUCCESS; ++ padapter->net_closed = false; ++ DBG_88E("===> %s.........\n", __func__); ++ ++ padapter->bDriverStopped = false; ++ padapter->bSurpriseRemoved = false; ++ padapter->bCardDisableWOHSM = false; ++ ++ status = rtw_hal_init(padapter); ++ if (status == _FAIL) ++ goto netdev_open_error; ++ ++ if (padapter->intf_start) ++ padapter->intf_start(padapter); ++ ++ rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); ++ _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 5000); ++ ++ return _SUCCESS; ++ ++netdev_open_error: ++ DBG_88E("-ips_netdrv_open - drv_open failure, bup =%d\n", padapter->bup); ++ ++ return _FAIL; ++} ++ ++int rtw_ips_pwr_up(struct adapter *padapter) ++{ ++ int result; ++ u32 start_time = jiffies; ++ DBG_88E("===> rtw_ips_pwr_up..............\n"); ++ rtw_reset_drv_sw(padapter); ++ ++ result = ips_netdrv_open(padapter); ++ ++ rtw_led_control(padapter, LED_CTL_NO_LINK); ++ ++ DBG_88E("<=== rtw_ips_pwr_up.............. in %dms\n", rtw_get_passing_time_ms(start_time)); ++ return result; ++} ++ ++void rtw_ips_pwr_down(struct adapter *padapter) ++{ ++ u32 start_time = jiffies; ++ DBG_88E("===> rtw_ips_pwr_down...................\n"); ++ ++ padapter->bCardDisableWOHSM = true; ++ padapter->net_closed = true; ++ ++ rtw_led_control(padapter, LED_CTL_POWER_OFF); ++ ++ rtw_ips_dev_unload(padapter); ++ padapter->bCardDisableWOHSM = false; ++ DBG_88E("<=== rtw_ips_pwr_down..................... in %dms\n", rtw_get_passing_time_ms(start_time)); ++} ++ ++void rtw_ips_dev_unload(struct adapter *padapter) ++{ ++ DBG_88E("====> %s...\n", __func__); ++ ++ rtw_hal_set_hwreg(padapter, HW_VAR_FIFO_CLEARN_UP, NULL); ++ ++ if (padapter->intf_stop) ++ padapter->intf_stop(padapter); ++ ++ /* s5. */ ++ if (!padapter->bSurpriseRemoved) ++ rtw_hal_deinit(padapter); ++} ++ ++int pm_netdev_open(struct net_device *pnetdev, u8 bnormal) ++{ ++ int status; ++ ++ if (bnormal) ++ status = netdev_open(pnetdev); ++ else ++ status = (_SUCCESS == ips_netdrv_open((struct adapter *)rtw_netdev_priv(pnetdev))) ? (0) : (-1); ++ return status; ++} ++ ++int netdev_close(struct net_device *pnetdev) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); ++ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); ++ ++ if (padapter->pwrctrlpriv.bInternalAutoSuspend) { ++ if (padapter->pwrctrlpriv.rf_pwrstate == rf_off) ++ padapter->pwrctrlpriv.ps_flag = true; ++ } ++ padapter->net_closed = true; ++ ++ if (padapter->pwrctrlpriv.rf_pwrstate == rf_on) { ++ DBG_88E("(2)88eu_drv - drv_close, bup =%d, hw_init_completed =%d\n", ++ padapter->bup, padapter->hw_init_completed); ++ ++ /* s1. */ ++ if (pnetdev) { ++ if (!rtw_netif_queue_stopped(pnetdev)) ++ rtw_netif_stop_queue(pnetdev); ++ } ++ ++ /* s2. */ ++ LeaveAllPowerSaveMode(padapter); ++ rtw_disassoc_cmd(padapter, 500, false); ++ /* s2-2. indicate disconnect to os */ ++ rtw_indicate_disconnect(padapter); ++ /* s2-3. */ ++ rtw_free_assoc_resources(padapter, 1); ++ /* s2-4. */ ++ rtw_free_network_queue(padapter, true); ++ /* Close LED */ ++ rtw_led_control(padapter, LED_CTL_POWER_OFF); ++ } ++ ++ nat25_db_cleanup(padapter); ++ ++#ifdef CONFIG_88EU_P2P ++ rtw_p2p_enable(padapter, P2P_ROLE_DISABLE); ++#endif /* CONFIG_88EU_P2P */ ++ ++ kfree(dvobj->firmware.szFwBuffer); ++ dvobj->firmware.szFwBuffer = NULL; ++ ++ DBG_88E("-88eu_drv - drv_close, bup =%d\n", padapter->bup); ++ return 0; ++} +diff --git a/drivers/staging/r8188eu/os_dep/osdep_service.c b/drivers/staging/r8188eu/os_dep/osdep_service.c +new file mode 100644 +index 000000000000..95ac6086370b +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/osdep_service.c +@@ -0,0 +1,343 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _OSDEP_SERVICE_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/rtw_ioctl_set.h" ++ ++/* ++* Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE ++* @return: one of RTW_STATUS_CODE ++*/ ++inline int RTW_STATUS_CODE(int error_code) ++{ ++ if (error_code >= 0) ++ return _SUCCESS; ++ return _FAIL; ++} ++ ++u32 rtw_atoi(u8 *s) ++{ ++ int num = 0, flag = 0; ++ int i; ++ for (i = 0; i <= strlen(s); i++) { ++ if (s[i] >= '0' && s[i] <= '9') ++ num = num * 10 + s[i] - '0'; ++ else if (s[0] == '-' && i == 0) ++ flag = 1; ++ else ++ break; ++ } ++ if (flag == 1) ++ num = num * -1; ++ return num; ++} ++ ++void *rtw_malloc2d(int h, int w, int size) ++{ ++ int j; ++ ++ void **a = kzalloc(h * sizeof(void *) + h * w * size, GFP_KERNEL); ++ if (!a) ++ return NULL; ++ ++ for (j = 0; j < h; j++) ++ a[j] = ((char *)(a + h)) + j * w * size; ++ ++ return a; ++} ++ ++/* ++For the following list_xxx operations, ++caller must guarantee the atomic context. ++Otherwise, there will be racing condition. ++*/ ++/* ++Caller must check if the list is empty before calling rtw_list_delete ++*/ ++ ++u32 _rtw_down_sema(struct semaphore *sema) ++{ ++ if (down_interruptible(sema)) ++ return _FAIL; ++ else ++ return _SUCCESS; ++} ++ ++void _rtw_mutex_init(struct mutex *pmutex) ++{ ++ mutex_init(pmutex); ++} ++ ++void _rtw_mutex_free(struct mutex *pmutex) ++{ ++ mutex_destroy(pmutex); ++} ++ ++void _rtw_init_queue(struct __queue *pqueue) ++{ ++ INIT_LIST_HEAD(&pqueue->queue); ++ spin_lock_init(&pqueue->lock); ++} ++ ++inline u32 rtw_systime_to_ms(u32 systime) ++{ ++ return systime * 1000 / HZ; ++} ++ ++inline u32 rtw_ms_to_systime(u32 ms) ++{ ++ return ms * HZ / 1000; ++} ++ ++/* the input parameter start use the same unit as jiffies */ ++inline s32 rtw_get_passing_time_ms(u32 start) ++{ ++ return rtw_systime_to_ms(jiffies - start); ++} ++ ++void rtw_usleep_os(int us) ++{ ++ if (1 < (us / 1000)) ++ msleep(1); ++ else ++ msleep((us / 1000) + 1); ++} ++ ++#define RTW_SUSPEND_LOCK_NAME "rtw_wifi" ++ ++static const struct device_type wlan_type = { ++ .name = "wlan", ++}; ++ ++struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, ++ void *old_priv) ++{ ++ struct net_device *pnetdev; ++ struct rtw_netdev_priv_indicator *pnpi; ++ ++ pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4); ++ if (!pnetdev) ++ goto RETURN; ++ ++ pnetdev->dev.type = &wlan_type; ++ pnpi = netdev_priv(pnetdev); ++ pnpi->priv = old_priv; ++ pnpi->sizeof_priv = sizeof_priv; ++ ++RETURN: ++ return pnetdev; ++} ++ ++struct net_device *rtw_alloc_etherdev(int sizeof_priv) ++{ ++ struct net_device *pnetdev; ++ struct rtw_netdev_priv_indicator *pnpi; ++ ++ pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4); ++ if (!pnetdev) ++ goto RETURN; ++ ++ pnpi = netdev_priv(pnetdev); ++ ++ pnpi->priv = vzalloc(sizeof_priv); ++ if (!pnpi->priv) { ++ free_netdev(pnetdev); ++ pnetdev = NULL; ++ goto RETURN; ++ } ++ ++ pnpi->sizeof_priv = sizeof_priv; ++RETURN: ++ return pnetdev; ++} ++ ++void rtw_free_netdev(struct net_device *netdev) ++{ ++ struct rtw_netdev_priv_indicator *pnpi; ++ ++ if (!netdev) ++ goto RETURN; ++ ++ pnpi = netdev_priv(netdev); ++ ++ if (!pnpi->priv) ++ goto RETURN; ++ ++ vfree(pnpi->priv); ++ free_netdev(netdev); ++ ++RETURN: ++ return; ++} ++ ++int rtw_change_ifname(struct adapter *padapter, const char *ifname) ++{ ++ struct net_device *pnetdev; ++ struct net_device *cur_pnetdev; ++ struct rereg_nd_name_data *rereg_priv; ++ int ret; ++ ++ if (!padapter) ++ goto error; ++ ++ cur_pnetdev = padapter->pnetdev; ++ rereg_priv = &padapter->rereg_nd_name_priv; ++ ++ /* free the old_pnetdev */ ++ if (rereg_priv->old_pnetdev) { ++ free_netdev(rereg_priv->old_pnetdev); ++ rereg_priv->old_pnetdev = NULL; ++ } ++ ++ if (!rtnl_is_locked()) ++ unregister_netdev(cur_pnetdev); ++ else ++ unregister_netdevice(cur_pnetdev); ++ ++ rtw_proc_remove_one(cur_pnetdev); ++ ++ rereg_priv->old_pnetdev = cur_pnetdev; ++ ++ pnetdev = rtw_init_netdev(padapter); ++ if (!pnetdev) { ++ ret = -1; ++ goto error; ++ } ++ ++ SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter))); ++ ++ rtw_init_netdev_name(pnetdev, ifname); ++ ++ memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); ++ ++ if (!rtnl_is_locked()) ++ ret = register_netdev(pnetdev); ++ else ++ ret = register_netdevice(pnetdev); ++ if (ret != 0) ++ goto error; ++ ++ rtw_proc_init_one(pnetdev); ++ return 0; ++error: ++ return -1; ++} ++ ++void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len) ++{ ++ u32 dup_len = 0; ++ u8 *ori = NULL; ++ u8 *dup = NULL; ++ ++ if (!buf || !buf_len) ++ return; ++ ++ if (!src || !src_len) ++ goto keep_ori; ++ ++ /* duplicate src */ ++ dup = kmalloc(src_len, GFP_ATOMIC); ++ if (dup) { ++ dup_len = src_len; ++ memcpy(dup, src, dup_len); ++ } ++ ++keep_ori: ++ ori = *buf; ++ ++ /* replace buf with dup */ ++ *buf_len = 0; ++ *buf = dup; ++ *buf_len = dup_len; ++ ++ /* free ori */ ++ kfree(ori); ++} ++ ++/** ++ * rtw_cbuf_full - test if cbuf is full ++ * @cbuf: pointer of struct rtw_cbuf ++ * ++ * Returns: true if cbuf is full ++ */ ++inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf) ++{ ++ return (cbuf->write == cbuf->read - 1) ? true : false; ++} ++ ++/** ++ * rtw_cbuf_empty - test if cbuf is empty ++ * @cbuf: pointer of struct rtw_cbuf ++ * ++ * Returns: true if cbuf is empty ++ */ ++inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf) ++{ ++ return (cbuf->write == cbuf->read) ? true : false; ++} ++ ++/** ++ * rtw_cbuf_push - push a pointer into cbuf ++ * @cbuf: pointer of struct rtw_cbuf ++ * @buf: pointer to push in ++ * ++ * Lock free operation, be careful of the use scheme ++ * Returns: true push success ++ */ ++bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf) ++{ ++ if (rtw_cbuf_full(cbuf)) ++ return _FAIL; ++ ++ if (0) ++ DBG_88E("%s on %u\n", __func__, cbuf->write); ++ cbuf->bufs[cbuf->write] = buf; ++ cbuf->write = (cbuf->write + 1) % cbuf->size; ++ ++ return _SUCCESS; ++} ++ ++/** ++ * rtw_cbuf_pop - pop a pointer from cbuf ++ * @cbuf: pointer of struct rtw_cbuf ++ * ++ * Lock free operation, be careful of the use scheme ++ * Returns: pointer popped out ++ */ ++void *rtw_cbuf_pop(struct rtw_cbuf *cbuf) ++{ ++ void *buf; ++ if (rtw_cbuf_empty(cbuf)) ++ return NULL; ++ ++ if (0) ++ DBG_88E("%s on %u\n", __func__, cbuf->read); ++ buf = cbuf->bufs[cbuf->read]; ++ cbuf->read = (cbuf->read + 1) % cbuf->size; ++ ++ return buf; ++} ++ ++/** ++ * rtw_cbuf_alloc - allocate a rtw_cbuf with given size and do initialization ++ * @size: size of pointer ++ * ++ * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure ++ */ ++struct rtw_cbuf *rtw_cbuf_alloc(u32 size) ++{ ++ struct rtw_cbuf *cbuf; ++ ++ cbuf = kmalloc(sizeof(*cbuf) + sizeof(void *) * size, GFP_KERNEL); ++ ++ if (cbuf) { ++ cbuf->write = 0; ++ cbuf->read = 0; ++ cbuf->size = size; ++ } ++ return cbuf; ++} +diff --git a/drivers/staging/r8188eu/os_dep/recv_linux.c b/drivers/staging/r8188eu/os_dep/recv_linux.c +new file mode 100644 +index 000000000000..917a63e3e94c +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/recv_linux.c +@@ -0,0 +1,214 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _RECV_OSDEP_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++ ++#include "../include/wifi.h" ++#include "../include/recv_osdep.h" ++ ++#include "../include/osdep_intf.h" ++#include "../include/usb_ops.h" ++ ++/* init os related resource in struct recv_priv */ ++int rtw_os_recv_resource_init(struct recv_priv *precvpriv, ++ struct adapter *padapter) ++{ ++ return _SUCCESS; ++} ++ ++/* alloc os related resource in struct recv_frame */ ++int rtw_os_recv_resource_alloc(struct adapter *padapter, ++ struct recv_frame *precvframe) ++{ ++ precvframe->pkt_newalloc = NULL; ++ precvframe->pkt = NULL; ++ return _SUCCESS; ++} ++ ++/* free os related resource in struct recv_frame */ ++void rtw_os_recv_resource_free(struct recv_priv *precvpriv) ++{ ++} ++ ++/* alloc os related resource in struct recv_buf */ ++int rtw_os_recvbuf_resource_alloc(struct adapter *padapter, ++ struct recv_buf *precvbuf) ++{ ++ int res = _SUCCESS; ++ ++ precvbuf->irp_pending = false; ++ precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!precvbuf->purb) ++ res = _FAIL; ++ precvbuf->pskb = NULL; ++ precvbuf->reuse = false; ++ precvbuf->pallocated_buf = NULL; ++ precvbuf->pbuf = NULL; ++ precvbuf->pdata = NULL; ++ precvbuf->phead = NULL; ++ precvbuf->ptail = NULL; ++ precvbuf->pend = NULL; ++ precvbuf->transfer_len = 0; ++ precvbuf->len = 0; ++ return res; ++} ++ ++/* free os related resource in struct recv_buf */ ++int rtw_os_recvbuf_resource_free(struct adapter *padapter, ++ struct recv_buf *precvbuf) ++{ ++ usb_free_urb(precvbuf->purb); ++ return _SUCCESS; ++} ++ ++void rtw_handle_tkip_mic_err(struct adapter *padapter, u8 bgroup) ++{ ++ union iwreq_data wrqu; ++ struct iw_michaelmicfailure ev; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct security_priv *psecuritypriv = &padapter->securitypriv; ++ u32 cur_time = 0; ++ ++ if (psecuritypriv->last_mic_err_time == 0) { ++ psecuritypriv->last_mic_err_time = jiffies; ++ } else { ++ cur_time = jiffies; ++ ++ if (cur_time - psecuritypriv->last_mic_err_time < 60 * HZ) { ++ psecuritypriv->btkip_countermeasure = true; ++ psecuritypriv->last_mic_err_time = 0; ++ psecuritypriv->btkip_countermeasure_time = cur_time; ++ } else { ++ psecuritypriv->last_mic_err_time = jiffies; ++ } ++ } ++ ++ memset(&ev, 0x00, sizeof(ev)); ++ if (bgroup) ++ ev.flags |= IW_MICFAILURE_GROUP; ++ else ++ ev.flags |= IW_MICFAILURE_PAIRWISE; ++ ++ ev.src_addr.sa_family = ARPHRD_ETHER; ++ memcpy(ev.src_addr.sa_data, &pmlmepriv->assoc_bssid[0], ETH_ALEN); ++ memset(&wrqu, 0x00, sizeof(wrqu)); ++ wrqu.data.length = sizeof(ev); ++ wireless_send_event(padapter->pnetdev, IWEVMICHAELMICFAILURE, ++ &wrqu, (char *)&ev); ++} ++ ++void rtw_hostapd_mlme_rx(struct adapter *padapter, ++ struct recv_frame *precv_frame) ++{ ++} ++ ++int rtw_recv_indicatepkt(struct adapter *padapter, ++ struct recv_frame *precv_frame) ++{ ++ struct recv_priv *precvpriv; ++ struct __queue *pfree_recv_queue; ++ struct sk_buff *skb; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ precvpriv = &padapter->recvpriv; ++ pfree_recv_queue = &precvpriv->free_recv_queue; ++ ++ skb = precv_frame->pkt; ++ if (!skb) ++ goto _recv_indicatepkt_drop; ++ ++ skb->data = precv_frame->rx_data; ++ ++ skb_set_tail_pointer(skb, precv_frame->len); ++ ++ skb->len = precv_frame->len; ++ ++ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { ++ struct sk_buff *pskb2 = NULL; ++ struct sta_info *psta = NULL; ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct rx_pkt_attrib *pattrib = &precv_frame->attrib; ++ bool bmcast = is_multicast_ether_addr(pattrib->dst); ++ ++ if (memcmp(pattrib->dst, myid(&padapter->eeprompriv), ++ ETH_ALEN)) { ++ if (bmcast) { ++ psta = rtw_get_bcmc_stainfo(padapter); ++ pskb2 = skb_clone(skb, GFP_ATOMIC); ++ } else { ++ psta = rtw_get_stainfo(pstapriv, pattrib->dst); ++ } ++ ++ if (psta) { ++ struct net_device *pnetdev; ++ ++ pnetdev = (struct net_device *)padapter->pnetdev; ++ skb->dev = pnetdev; ++ skb_set_queue_mapping(skb, rtw_recv_select_queue(skb)); ++ ++ rtw_xmit_entry(skb, pnetdev); ++ ++ if (bmcast) ++ skb = pskb2; ++ else ++ goto _recv_indicatepkt_end; ++ } ++ } ++ } ++ ++ rcu_read_lock(); ++ rcu_dereference(padapter->pnetdev->rx_handler_data); ++ rcu_read_unlock(); ++ ++ skb->ip_summed = CHECKSUM_NONE; ++ skb->dev = padapter->pnetdev; ++ skb->protocol = eth_type_trans(skb, padapter->pnetdev); ++ ++ netif_rx(skb); ++ ++_recv_indicatepkt_end: ++ ++ /* pointers to NULL before rtw_free_recvframe() */ ++ precv_frame->pkt = NULL; ++ ++ rtw_free_recvframe(precv_frame, pfree_recv_queue); ++ ++ return _SUCCESS; ++ ++_recv_indicatepkt_drop: ++ ++ /* enqueue back to free_recv_queue */ ++ rtw_free_recvframe(precv_frame, pfree_recv_queue); ++ ++ return _FAIL; ++} ++ ++void rtw_os_read_port(struct adapter *padapter, struct recv_buf *precvbuf) ++{ ++ struct recv_priv *precvpriv = &padapter->recvpriv; ++ ++ precvbuf->ref_cnt--; ++ /* free skb in recv_buf */ ++ dev_kfree_skb_any(precvbuf->pskb); ++ precvbuf->pskb = NULL; ++ precvbuf->reuse = false; ++ if (!precvbuf->irp_pending) ++ rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, ++ (unsigned char *)precvbuf); ++} ++ ++static void _rtw_reordering_ctrl_timeout_handler(struct timer_list *t) ++{ ++ struct recv_reorder_ctrl *preorder_ctrl; ++ ++ preorder_ctrl = from_timer(preorder_ctrl, t, reordering_ctrl_timer); ++ rtw_reordering_ctrl_timeout_handler(preorder_ctrl); ++} ++ ++void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl) ++{ ++ timer_setup(&preorder_ctrl->reordering_ctrl_timer, _rtw_reordering_ctrl_timeout_handler, 0); ++} +diff --git a/drivers/staging/r8188eu/os_dep/usb_intf.c b/drivers/staging/r8188eu/os_dep/usb_intf.c +new file mode 100644 +index 000000000000..bb85ab77fd26 +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/usb_intf.c +@@ -0,0 +1,781 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2011 Realtek Corporation. */ ++ ++#define _HCI_INTF_C_ ++ ++#include ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/recv_osdep.h" ++#include "../include/xmit_osdep.h" ++#include "../include/hal_intf.h" ++#include "../include/osdep_intf.h" ++#include "../include/usb_vendor_req.h" ++#include "../include/usb_ops.h" ++#include "../include/usb_osintf.h" ++#include "../include/rtw_ioctl.h" ++ ++int ui_pid[3] = {0, 0, 0}; ++ ++static int rtw_suspend(struct usb_interface *intf, pm_message_t message); ++static int rtw_resume(struct usb_interface *intf); ++ ++static int rtw_drv_init(struct usb_interface *pusb_intf, const struct usb_device_id *pdid); ++static void rtw_dev_remove(struct usb_interface *pusb_intf); ++ ++#define USB_VENDER_ID_REALTEK 0x0bda ++ ++/* DID_USB_v916_20130116 */ ++static struct usb_device_id rtw_usb_id_tbl[] = { ++ /*=== Realtek demoboard ===*/ ++ {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8179)}, /* 8188EUS */ ++ {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0179)}, /* 8188ETV */ ++ {USB_DEVICE(USB_VENDER_ID_REALTEK, 0xf179)}, /* 8188FU */ ++ /*=== Customer ID ===*/ ++ /****** 8188EUS ********/ ++ {USB_DEVICE(0x07B8, 0x8179)}, /* Abocom - Abocom */ ++ {USB_DEVICE(0x0DF6, 0x0076)}, /* Sitecom N150 v2 */ ++ {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */ ++ {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */ ++ {USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */ ++ {USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */ ++ {USB_DEVICE(0x056E, 0x4008)}, /* Elecom WDC-150SU2M */ ++ {USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */ ++ {USB_DEVICE(0x2357, 0x0111)}, /* TP-Link TL-WN727N v5.21 */ ++ {USB_DEVICE(0x2C4E, 0x0102)}, /* MERCUSYS MW150US v2 */ ++ {USB_DEVICE(0x0B05, 0x18F0)}, /* ASUS USB-N10 Nano B1 */ ++ {USB_DEVICE(0x7392, 0xb811)}, /* Edimax EW-7811Un V2 */ ++ {} /* Terminating entry */ ++}; ++ ++MODULE_DEVICE_TABLE(usb, rtw_usb_id_tbl); ++ ++static struct specific_device_id specific_device_id_tbl[] = { ++ {} /* empty table for now */ ++}; ++ ++struct rtw_usb_drv { ++ struct usb_driver usbdrv; ++ int drv_registered; ++ struct mutex hw_init_mutex; ++}; ++ ++static struct rtw_usb_drv rtl8188e_usb_drv = { ++ .usbdrv.name = "r8188eu", ++ .usbdrv.probe = rtw_drv_init, ++ .usbdrv.disconnect = rtw_dev_remove, ++ .usbdrv.id_table = rtw_usb_id_tbl, ++ .usbdrv.suspend = rtw_suspend, ++ .usbdrv.resume = rtw_resume, ++ .usbdrv.reset_resume = rtw_resume, ++}; ++ ++static struct rtw_usb_drv *usb_drv = &rtl8188e_usb_drv; ++ ++static inline int RT_usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd) ++{ ++ return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN; ++} ++ ++static inline int RT_usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd) ++{ ++ return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT; ++} ++ ++static inline int RT_usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd) ++{ ++ return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT; ++} ++ ++static inline int RT_usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd) ++{ ++ return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK; ++} ++ ++static inline int RT_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd) ++{ ++ return RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_in(epd); ++} ++ ++static inline int RT_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd) ++{ ++ return RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_out(epd); ++} ++ ++static inline int usb_endpoint_is_int(const struct usb_endpoint_descriptor *epd) ++{ ++ return RT_usb_endpoint_xfer_int(epd) && RT_usb_endpoint_dir_in(epd); ++} ++ ++static inline int RT_usb_endpoint_num(const struct usb_endpoint_descriptor *epd) ++{ ++ return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; ++} ++ ++static u8 rtw_init_intf_priv(struct dvobj_priv *dvobj) ++{ ++ u8 rst = _SUCCESS; ++ ++ _rtw_mutex_init(&dvobj->usb_vendor_req_mutex); ++ ++ dvobj->usb_alloc_vendor_req_buf = kzalloc(MAX_USB_IO_CTL_SIZE, GFP_KERNEL); ++ if (!dvobj->usb_alloc_vendor_req_buf) { ++ DBG_88E("alloc usb_vendor_req_buf failed... /n"); ++ rst = _FAIL; ++ goto exit; ++ } ++ dvobj->usb_vendor_req_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(dvobj->usb_alloc_vendor_req_buf), ALIGNMENT_UNIT); ++exit: ++ return rst; ++} ++ ++static void rtw_deinit_intf_priv(struct dvobj_priv *dvobj) ++{ ++ kfree(dvobj->usb_alloc_vendor_req_buf); ++ _rtw_mutex_free(&dvobj->usb_vendor_req_mutex); ++} ++ ++static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf) ++{ ++ int i; ++ int status = _FAIL; ++ struct dvobj_priv *pdvobjpriv; ++ struct usb_host_config *phost_conf; ++ struct usb_config_descriptor *pconf_desc; ++ struct usb_host_interface *phost_iface; ++ struct usb_interface_descriptor *piface_desc; ++ struct usb_endpoint_descriptor *pendp_desc; ++ struct usb_device *pusbd; ++ ++ pdvobjpriv = kzalloc(sizeof(*pdvobjpriv), GFP_KERNEL); ++ if (!pdvobjpriv) ++ goto exit; ++ ++ pdvobjpriv->pusbintf = usb_intf; ++ pusbd = interface_to_usbdev(usb_intf); ++ pdvobjpriv->pusbdev = pusbd; ++ usb_set_intfdata(usb_intf, pdvobjpriv); ++ ++ pdvobjpriv->RtNumInPipes = 0; ++ pdvobjpriv->RtNumOutPipes = 0; ++ ++ phost_conf = pusbd->actconfig; ++ pconf_desc = &phost_conf->desc; ++ ++ phost_iface = &usb_intf->altsetting[0]; ++ piface_desc = &phost_iface->desc; ++ ++ pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces; ++ pdvobjpriv->InterfaceNumber = piface_desc->bInterfaceNumber; ++ pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints; ++ ++ for (i = 0; i < pdvobjpriv->nr_endpoint; i++) { ++ int ep_num; ++ pendp_desc = &phost_iface->endpoint[i].desc; ++ ++ ep_num = usb_endpoint_num(pendp_desc); ++ ++ if (usb_endpoint_is_bulk_in(pendp_desc)) { ++ pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = ep_num; ++ pdvobjpriv->RtNumInPipes++; ++ } else if (usb_endpoint_is_int_in(pendp_desc)) { ++ pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = ep_num; ++ pdvobjpriv->RtNumInPipes++; ++ } else if (usb_endpoint_is_bulk_out(pendp_desc)) { ++ pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] = ++ ep_num; ++ pdvobjpriv->RtNumOutPipes++; ++ } ++ pdvobjpriv->ep_num[i] = ep_num; ++ } ++ ++ if (pusbd->speed == USB_SPEED_HIGH) { ++ pdvobjpriv->ishighspeed = true; ++ DBG_88E("USB_SPEED_HIGH\n"); ++ } else { ++ pdvobjpriv->ishighspeed = false; ++ DBG_88E("NON USB_SPEED_HIGH\n"); ++ } ++ ++ if (rtw_init_intf_priv(pdvobjpriv) == _FAIL) ++ goto free_dvobj; ++ ++ /* 3 misc */ ++ sema_init(&pdvobjpriv->usb_suspend_sema, 0); ++ rtw_reset_continual_urb_error(pdvobjpriv); ++ ++ usb_get_dev(pusbd); ++ ++ status = _SUCCESS; ++ ++free_dvobj: ++ if (status != _SUCCESS && pdvobjpriv) { ++ usb_set_intfdata(usb_intf, NULL); ++ kfree(pdvobjpriv); ++ pdvobjpriv = NULL; ++ } ++exit: ++ return pdvobjpriv; ++} ++ ++static void usb_dvobj_deinit(struct usb_interface *usb_intf) ++{ ++ struct dvobj_priv *dvobj = usb_get_intfdata(usb_intf); ++ ++ usb_set_intfdata(usb_intf, NULL); ++ if (dvobj) { ++ /* Modify condition for 92DU DMDP 2010.11.18, by Thomas */ ++ if ((dvobj->NumInterfaces != 2 && ++ dvobj->NumInterfaces != 3) || ++ (dvobj->InterfaceNumber == 1)) { ++ if (interface_to_usbdev(usb_intf)->state != ++ USB_STATE_NOTATTACHED) { ++ /* If we didn't unplug usb dongle and ++ * remove/insert module, driver fails ++ * on sitesurvey for the first time when ++ * device is up . Reset usb port for sitesurvey ++ * fail issue. */ ++ DBG_88E("usb attached..., try to reset usb device\n"); ++ usb_reset_device(interface_to_usbdev(usb_intf)); ++ } ++ } ++ rtw_deinit_intf_priv(dvobj); ++ kfree(dvobj); ++ } ++ ++ usb_put_dev(interface_to_usbdev(usb_intf)); ++ ++} ++ ++static void chip_by_usb_id(struct adapter *padapter) ++{ ++ padapter->chip_type = NULL_CHIP_TYPE; ++ hal_set_hw_type(padapter); ++} ++ ++static void usb_intf_start(struct adapter *padapter) ++{ ++ rtw_hal_inirp_init(padapter); ++} ++ ++static void usb_intf_stop(struct adapter *padapter) ++{ ++ /* cancel in irp */ ++ rtw_hal_inirp_deinit(padapter); ++ ++ /* cancel out irp */ ++ rtw_write_port_cancel(padapter); ++ ++ /* todo:cancel other irps */ ++} ++ ++static void rtw_dev_unload(struct adapter *padapter) ++{ ++ if (padapter->bup) { ++ DBG_88E("===> rtw_dev_unload\n"); ++ padapter->bDriverStopped = true; ++ if (padapter->xmitpriv.ack_tx) ++ rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP); ++ /* s3. */ ++ if (padapter->intf_stop) ++ padapter->intf_stop(padapter); ++ /* s4. */ ++ if (!padapter->pwrctrlpriv.bInternalAutoSuspend) ++ rtw_stop_drv_threads(padapter); ++ ++ /* s5. */ ++ if (!padapter->bSurpriseRemoved) { ++ rtw_hal_deinit(padapter); ++ padapter->bSurpriseRemoved = true; ++ } ++ ++ padapter->bup = false; ++ } ++ ++ DBG_88E("<=== rtw_dev_unload\n"); ++} ++ ++static void process_spec_devid(const struct usb_device_id *pdid) ++{ ++ u16 vid, pid; ++ u32 flags; ++ int i; ++ int num = sizeof(specific_device_id_tbl) / ++ sizeof(struct specific_device_id); ++ ++ for (i = 0; i < num; i++) { ++ vid = specific_device_id_tbl[i].idVendor; ++ pid = specific_device_id_tbl[i].idProduct; ++ flags = specific_device_id_tbl[i].flags; ++ ++ if ((pdid->idVendor == vid) && (pdid->idProduct == pid) && ++ (flags & SPEC_DEV_ID_DISABLE_HT)) { ++ rtw_ht_enable = 0; ++ rtw_cbw40_enable = 0; ++ rtw_ampdu_enable = 0; ++ } ++ } ++} ++ ++int rtw_hw_suspend(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ struct net_device *pnetdev = padapter->pnetdev; ++ ++ ++ if (!padapter) ++ goto error_exit; ++ if ((!padapter->bup) || (padapter->bDriverStopped) || ++ (padapter->bSurpriseRemoved)) { ++ DBG_88E("padapter->bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n", ++ padapter->bup, padapter->bDriverStopped, ++ padapter->bSurpriseRemoved); ++ goto error_exit; ++ } ++ ++ LeaveAllPowerSaveMode(padapter); ++ ++ DBG_88E("==> rtw_hw_suspend\n"); ++ _enter_pwrlock(&pwrpriv->lock); ++ pwrpriv->bips_processing = true; ++ /* s1. */ ++ if (pnetdev) { ++ netif_carrier_off(pnetdev); ++ rtw_netif_stop_queue(pnetdev); ++ } ++ ++ /* s2. */ ++ rtw_disassoc_cmd(padapter, 500, false); ++ ++ /* s2-2. indicate disconnect to os */ ++ { ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) { ++ _clr_fwstate_(pmlmepriv, _FW_LINKED); ++ ++ rtw_led_control(padapter, LED_CTL_NO_LINK); ++ ++ rtw_os_indicate_disconnect(padapter); ++ ++ /* donnot enqueue cmd */ ++ rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 0); ++ } ++ } ++ /* s2-3. */ ++ rtw_free_assoc_resources(padapter, 1); ++ ++ /* s2-4. */ ++ rtw_free_network_queue(padapter, true); ++ rtw_ips_dev_unload(padapter); ++ pwrpriv->rf_pwrstate = rf_off; ++ pwrpriv->bips_processing = false; ++ ++ _exit_pwrlock(&pwrpriv->lock); ++ return 0; ++ ++error_exit: ++ DBG_88E("%s, failed\n", __func__); ++ return -1; ++} ++ ++int rtw_hw_resume(struct adapter *padapter) ++{ ++ struct pwrctrl_priv *pwrpriv; ++ struct net_device *pnetdev = padapter->pnetdev; ++ ++ if (!padapter) ++ goto error_exit; ++ pwrpriv = &padapter->pwrctrlpriv; ++ DBG_88E("==> rtw_hw_resume\n"); ++ _enter_pwrlock(&pwrpriv->lock); ++ pwrpriv->bips_processing = true; ++ rtw_reset_drv_sw(padapter); ++ ++ if (pm_netdev_open(pnetdev, false) != 0) { ++ _exit_pwrlock(&pwrpriv->lock); ++ goto error_exit; ++ } ++ ++ netif_device_attach(pnetdev); ++ netif_carrier_on(pnetdev); ++ ++ if (!netif_queue_stopped(pnetdev)) ++ netif_start_queue(pnetdev); ++ else ++ netif_wake_queue(pnetdev); ++ ++ pwrpriv->bkeepfwalive = false; ++ pwrpriv->brfoffbyhw = false; ++ ++ pwrpriv->rf_pwrstate = rf_on; ++ pwrpriv->bips_processing = false; ++ ++ _exit_pwrlock(&pwrpriv->lock); ++ ++ return 0; ++error_exit: ++ DBG_88E("%s, Open net dev failed\n", __func__); ++ return -1; ++} ++ ++static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) ++{ ++ struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); ++ struct adapter *padapter = dvobj->if1; ++ struct net_device *pnetdev = padapter->pnetdev; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ ++ int ret = 0; ++ u32 start_time = jiffies; ++ ++ ++ DBG_88E("==> %s (%s:%d)\n", __func__, current->comm, current->pid); ++ ++ if ((!padapter->bup) || (padapter->bDriverStopped) || ++ (padapter->bSurpriseRemoved)) { ++ DBG_88E("padapter->bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n", ++ padapter->bup, padapter->bDriverStopped, ++ padapter->bSurpriseRemoved); ++ goto exit; ++ } ++ ++ pwrpriv->bInSuspend = true; ++ rtw_cancel_all_timer(padapter); ++ LeaveAllPowerSaveMode(padapter); ++ ++ _enter_pwrlock(&pwrpriv->lock); ++ /* s1. */ ++ if (pnetdev) { ++ netif_carrier_off(pnetdev); ++ rtw_netif_stop_queue(pnetdev); ++ } ++ ++ /* s2. */ ++ rtw_disassoc_cmd(padapter, 0, false); ++ ++ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && ++ check_fwstate(pmlmepriv, _FW_LINKED)) { ++ DBG_88E("%s:%d %s(%pM), length:%d assoc_ssid.length:%d\n", ++ __func__, __LINE__, ++ pmlmepriv->cur_network.network.Ssid.Ssid, ++ pmlmepriv->cur_network.network.MacAddress, ++ pmlmepriv->cur_network.network.Ssid.SsidLength, ++ pmlmepriv->assoc_ssid.SsidLength); ++ ++ pmlmepriv->to_roaming = 1; ++ } ++ /* s2-2. indicate disconnect to os */ ++ rtw_indicate_disconnect(padapter); ++ /* s2-3. */ ++ rtw_free_assoc_resources(padapter, 1); ++ /* s2-4. */ ++ rtw_free_network_queue(padapter, true); ++ ++ rtw_dev_unload(padapter); ++ _exit_pwrlock(&pwrpriv->lock); ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) ++ rtw_indicate_scan_done(padapter, 1); ++ ++ if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) ++ rtw_indicate_disconnect(padapter); ++ ++exit: ++ DBG_88E("<=== %s return %d.............. in %dms\n", __func__ ++ , ret, rtw_get_passing_time_ms(start_time)); ++ ++ return ret; ++} ++ ++static int rtw_resume(struct usb_interface *pusb_intf) ++{ ++ struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); ++ struct adapter *padapter = dvobj->if1; ++ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; ++ int ret = 0; ++ ++ if (pwrpriv->bInternalAutoSuspend) ++ ret = rtw_resume_process(padapter); ++ else ++ ret = rtw_resume_process(padapter); ++ return ret; ++} ++ ++int rtw_resume_process(struct adapter *padapter) ++{ ++ struct net_device *pnetdev; ++ struct pwrctrl_priv *pwrpriv = NULL; ++ int ret = -1; ++ u32 start_time = jiffies; ++ ++ DBG_88E("==> %s (%s:%d)\n", __func__, current->comm, current->pid); ++ ++ if (padapter) { ++ pnetdev = padapter->pnetdev; ++ pwrpriv = &padapter->pwrctrlpriv; ++ } else { ++ goto exit; ++ } ++ ++ _enter_pwrlock(&pwrpriv->lock); ++ rtw_reset_drv_sw(padapter); ++ if (pwrpriv) ++ pwrpriv->bkeepfwalive = false; ++ ++ DBG_88E("bkeepfwalive(%x)\n", pwrpriv->bkeepfwalive); ++ if (pm_netdev_open(pnetdev, true) != 0) ++ goto exit; ++ ++ netif_device_attach(pnetdev); ++ netif_carrier_on(pnetdev); ++ ++ _exit_pwrlock(&pwrpriv->lock); ++ ++ if (padapter->pid[1] != 0) { ++ DBG_88E("pid[1]:%d\n", padapter->pid[1]); ++ rtw_signal_process(padapter->pid[1], SIGUSR2); ++ } ++ ++ rtw_roaming(padapter, NULL); ++ ++ ret = 0; ++exit: ++ if (pwrpriv) ++ pwrpriv->bInSuspend = false; ++ DBG_88E("<=== %s return %d.............. in %dms\n", __func__, ++ ret, rtw_get_passing_time_ms(start_time)); ++ ++ ++ return ret; ++} ++ ++/* ++ * drv_init() - a device potentially for us ++ * ++ * notes: drv_init() is called when the bus driver has located ++ * a card for us to support. ++ * We accept the new device by returning 0. ++ */ ++ ++static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj, ++ struct usb_interface *pusb_intf) ++{ ++ struct adapter *padapter = NULL; ++ struct net_device *pnetdev = NULL; ++ int status = _FAIL; ++ ++ padapter = vzalloc(sizeof(*padapter)); ++ if (!padapter) ++ goto exit; ++ padapter->dvobj = dvobj; ++ dvobj->if1 = padapter; ++ ++ padapter->bDriverStopped = true; ++ ++ padapter->hw_init_mutex = &usb_drv->hw_init_mutex; ++ ++ /* step 1-1., decide the chip_type via vid/pid */ ++ padapter->interface_type = RTW_USB; ++ chip_by_usb_id(padapter); ++ ++ if (rtw_handle_dualmac(padapter, 1) != _SUCCESS) ++ goto free_adapter; ++ ++ pnetdev = rtw_init_netdev(padapter); ++ if (!pnetdev) ++ goto handle_dualmac; ++ SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj)); ++ padapter = rtw_netdev_priv(pnetdev); ++ ++ /* step 2. hook HalFunc, allocate HalData */ ++ rtl8188eu_set_hal_ops(padapter); ++ ++ padapter->intf_start = &usb_intf_start; ++ padapter->intf_stop = &usb_intf_stop; ++ ++ /* step init_io_priv */ ++ rtw_init_io_priv(padapter, usb_set_intf_ops); ++ ++ /* step read_chip_version */ ++ rtw_hal_read_chip_version(padapter); ++ ++ /* step usb endpoint mapping */ ++ rtw_hal_chip_configure(padapter); ++ ++ /* step read efuse/eeprom data and get mac_addr */ ++ rtw_hal_read_chip_info(padapter); ++ ++ /* step 5. */ ++ if (rtw_init_drv_sw(padapter) == _FAIL) ++ goto free_hal_data; ++ ++#ifdef CONFIG_PM ++ if (padapter->pwrctrlpriv.bSupportRemoteWakeup) { ++ dvobj->pusbdev->do_remote_wakeup = 1; ++ pusb_intf->needs_remote_wakeup = 1; ++ device_init_wakeup(&pusb_intf->dev, 1); ++ DBG_88E("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~[%d]~~~\n", ++ device_may_wakeup(&pusb_intf->dev)); ++ } ++#endif ++ ++ /* 2012-07-11 Move here to prevent the 8723AS-VAU BT auto ++ * suspend influence */ ++ if (usb_autopm_get_interface(pusb_intf) < 0) ++ DBG_88E("can't get autopm:\n"); ++ ++ /* alloc dev name after read efuse. */ ++ rtw_init_netdev_name(pnetdev, padapter->registrypriv.ifname); ++ rtw_macaddr_cfg(padapter->eeprompriv.mac_addr); ++#ifdef CONFIG_88EU_P2P ++ rtw_init_wifidirect_addrs(padapter, padapter->eeprompriv.mac_addr, ++ padapter->eeprompriv.mac_addr); ++#endif ++ memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); ++ DBG_88E("MAC Address from pnetdev->dev_addr = %pM\n", ++ pnetdev->dev_addr); ++ ++ /* step 6. Tell the network stack we exist */ ++ if (register_netdev(pnetdev) != 0) ++ goto free_hal_data; ++ ++ DBG_88E("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n" ++ , padapter->bDriverStopped ++ , padapter->bSurpriseRemoved ++ , padapter->bup ++ , padapter->hw_init_completed ++ ); ++ ++ status = _SUCCESS; ++ ++free_hal_data: ++ if (status != _SUCCESS) ++ kfree(padapter->HalData); ++handle_dualmac: ++ if (status != _SUCCESS) ++ rtw_handle_dualmac(padapter, 0); ++free_adapter: ++ if (status != _SUCCESS) { ++ if (pnetdev) ++ rtw_free_netdev(pnetdev); ++ else if (padapter) ++ vfree(padapter); ++ padapter = NULL; ++ } ++exit: ++ return padapter; ++} ++ ++static void rtw_usb_if1_deinit(struct adapter *if1) ++{ ++ struct net_device *pnetdev = if1->pnetdev; ++ struct mlme_priv *pmlmepriv = &if1->mlmepriv; ++ ++ if (check_fwstate(pmlmepriv, _FW_LINKED)) ++ rtw_disassoc_cmd(if1, 0, false); ++ ++#ifdef CONFIG_88EU_AP_MODE ++ free_mlme_ap_info(if1); ++#endif ++ ++ if (if1->DriverState != DRIVER_DISAPPEAR) { ++ if (pnetdev) { ++ /* will call netdev_close() */ ++ unregister_netdev(pnetdev); ++ rtw_proc_remove_one(pnetdev); ++ } ++ } ++ rtw_cancel_all_timer(if1); ++ ++ rtw_dev_unload(if1); ++ DBG_88E("+r871xu_dev_remove, hw_init_completed=%d\n", ++ if1->hw_init_completed); ++ rtw_handle_dualmac(if1, 0); ++ rtw_free_drv_sw(if1); ++ if (pnetdev) ++ rtw_free_netdev(pnetdev); ++} ++ ++static int rtw_drv_init(struct usb_interface *pusb_intf, const struct usb_device_id *pdid) ++{ ++ struct adapter *if1 = NULL; ++ struct dvobj_priv *dvobj; ++ ++ /* step 0. */ ++ process_spec_devid(pdid); ++ ++ /* Initialize dvobj_priv */ ++ dvobj = usb_dvobj_init(pusb_intf); ++ if (!dvobj) ++ goto err; ++ ++ if1 = rtw_usb_if1_init(dvobj, pusb_intf); ++ if (!if1) { ++ DBG_88E("rtw_init_primarystruct adapter Failed!\n"); ++ goto free_dvobj; ++ } ++ ++ if (ui_pid[1] != 0) { ++ DBG_88E("ui_pid[1]:%d\n", ui_pid[1]); ++ rtw_signal_process(ui_pid[1], SIGUSR2); ++ } ++ ++ return 0; ++ ++free_dvobj: ++ usb_dvobj_deinit(pusb_intf); ++err: ++ return -ENODEV; ++} ++ ++/* ++ * dev_remove() - our device is being removed ++*/ ++/* rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove() => how to recognize both */ ++static void rtw_dev_remove(struct usb_interface *pusb_intf) ++{ ++ struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); ++ struct adapter *padapter = dvobj->if1; ++ ++ DBG_88E("+rtw_dev_remove\n"); ++ ++ if (usb_drv->drv_registered) ++ padapter->bSurpriseRemoved = true; ++ ++ rtw_pm_set_ips(padapter, IPS_NONE); ++ rtw_pm_set_lps(padapter, PS_MODE_ACTIVE); ++ ++ LeaveAllPowerSaveMode(padapter); ++ ++ rtw_usb_if1_deinit(padapter); ++ ++ usb_dvobj_deinit(pusb_intf); ++ ++ DBG_88E("-r871xu_dev_remove, done\n"); ++} ++ ++static int __init rtw_drv_entry(void) ++{ ++ DBG_88E(DRV_NAME " driver version=%s\n", DRIVERVERSION); ++ ++ _rtw_mutex_init(&usb_drv->hw_init_mutex); ++ ++ usb_drv->drv_registered = true; ++ return usb_register(&usb_drv->usbdrv); ++} ++ ++static void __exit rtw_drv_halt(void) ++{ ++ DBG_88E("+rtw_drv_halt\n"); ++ ++ usb_drv->drv_registered = false; ++ usb_deregister(&usb_drv->usbdrv); ++ ++ _rtw_mutex_free(&usb_drv->hw_init_mutex); ++ DBG_88E("-rtw_drv_halt\n"); ++} ++ ++module_init(rtw_drv_entry); ++module_exit(rtw_drv_halt); +diff --git a/drivers/staging/r8188eu/os_dep/usb_ops_linux.c b/drivers/staging/r8188eu/os_dep/usb_ops_linux.c +new file mode 100644 +index 000000000000..62dd4a131534 +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/usb_ops_linux.c +@@ -0,0 +1,253 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _USB_OPS_LINUX_C_ ++ ++#include "../include/drv_types.h" ++#include "../include/usb_ops_linux.h" ++#include "../include/rtw_sreset.h" ++ ++unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr) ++{ ++ unsigned int pipe = 0, ep_num = 0; ++ struct usb_device *pusbd = pdvobj->pusbdev; ++ ++ if (addr == RECV_BULK_IN_ADDR) { ++ pipe = usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[0]); ++ } else if (addr == RECV_INT_IN_ADDR) { ++ pipe = usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[1]); ++ } else if (addr < HW_QUEUE_ENTRY) { ++ ep_num = pdvobj->Queue2Pipe[addr]; ++ pipe = usb_sndbulkpipe(pusbd, ep_num); ++ } ++ ++ return pipe; ++} ++ ++struct zero_bulkout_context { ++ void *pbuf; ++ void *purb; ++ void *pirp; ++ void *padapter; ++}; ++ ++void usb_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) ++{ ++} ++ ++void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) ++{ ++} ++ ++void usb_read_port_cancel(struct intf_hdl *pintfhdl) ++{ ++ int i; ++ struct recv_buf *precvbuf; ++ struct adapter *padapter = pintfhdl->padapter; ++ precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf; ++ ++ DBG_88E("%s\n", __func__); ++ ++ padapter->bReadPortCancel = true; ++ ++ for (i = 0; i < NR_RECVBUFF; i++) { ++ precvbuf->reuse = true; ++ if (precvbuf->purb) ++ usb_kill_urb(precvbuf->purb); ++ precvbuf++; ++ } ++} ++ ++static void usb_write_port_complete(struct urb *purb, struct pt_regs *regs) ++{ ++ struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context; ++ struct adapter *padapter = pxmitbuf->padapter; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct hal_data_8188e *haldata; ++ ++ switch (pxmitbuf->flags) { ++ case VO_QUEUE_INX: ++ pxmitpriv->voq_cnt--; ++ break; ++ case VI_QUEUE_INX: ++ pxmitpriv->viq_cnt--; ++ break; ++ case BE_QUEUE_INX: ++ pxmitpriv->beq_cnt--; ++ break; ++ case BK_QUEUE_INX: ++ pxmitpriv->bkq_cnt--; ++ break; ++ case HIGH_QUEUE_INX: ++#ifdef CONFIG_88EU_AP_MODE ++ rtw_chk_hi_queue_cmd(padapter); ++#endif ++ break; ++ default: ++ break; ++ } ++ ++ if (padapter->bSurpriseRemoved || padapter->bDriverStopped || ++ padapter->bWritePortCancel) { ++ DBG_88E("%s(): TX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bWritePortCancel(%d) pxmitbuf->ext_tag(%x)\n", ++ __func__, padapter->bDriverStopped, ++ padapter->bSurpriseRemoved, padapter->bReadPortCancel, ++ pxmitbuf->ext_tag); ++ ++ goto check_completion; ++ } ++ ++ if (purb->status) { ++ DBG_88E("###=> urb_write_port_complete status(%d)\n", purb->status); ++ if ((purb->status == -EPIPE) || (purb->status == -EPROTO)) { ++ sreset_set_wifi_error_status(padapter, USB_WRITE_PORT_FAIL); ++ } else if (purb->status == -EINPROGRESS) { ++ goto check_completion; ++ } else if (purb->status == -ENOENT) { ++ DBG_88E("%s: -ENOENT\n", __func__); ++ goto check_completion; ++ } else if (purb->status == -ECONNRESET) { ++ DBG_88E("%s: -ECONNRESET\n", __func__); ++ goto check_completion; ++ } else if (purb->status == -ESHUTDOWN) { ++ padapter->bDriverStopped = true; ++ goto check_completion; ++ } else { ++ padapter->bSurpriseRemoved = true; ++ DBG_88E("bSurpriseRemoved = true\n"); ++ ++ goto check_completion; ++ } ++ } ++ ++ haldata = GET_HAL_DATA(padapter); ++ haldata->srestpriv.last_tx_complete_time = jiffies; ++ ++check_completion: ++ rtw_sctx_done_err(&pxmitbuf->sctx, ++ purb->status ? RTW_SCTX_DONE_WRITE_PORT_ERR : ++ RTW_SCTX_DONE_SUCCESS); ++ ++ rtw_free_xmitbuf(pxmitpriv, pxmitbuf); ++ ++ tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); ++ ++} ++ ++u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) ++{ ++ unsigned long irqL; ++ unsigned int pipe; ++ int status; ++ u32 ret = _FAIL; ++ struct urb *purb = NULL; ++ struct adapter *padapter = (struct adapter *)pintfhdl->padapter; ++ struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct xmit_buf *pxmitbuf = (struct xmit_buf *)wmem; ++ struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data; ++ struct usb_device *pusbd = pdvobj->pusbdev; ++ ++ if ((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) || ++ (padapter->pwrctrlpriv.pnp_bstop_trx)) { ++ rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY); ++ goto exit; ++ } ++ ++ spin_lock_irqsave(&pxmitpriv->lock, irqL); ++ ++ switch (addr) { ++ case VO_QUEUE_INX: ++ pxmitpriv->voq_cnt++; ++ pxmitbuf->flags = VO_QUEUE_INX; ++ break; ++ case VI_QUEUE_INX: ++ pxmitpriv->viq_cnt++; ++ pxmitbuf->flags = VI_QUEUE_INX; ++ break; ++ case BE_QUEUE_INX: ++ pxmitpriv->beq_cnt++; ++ pxmitbuf->flags = BE_QUEUE_INX; ++ break; ++ case BK_QUEUE_INX: ++ pxmitpriv->bkq_cnt++; ++ pxmitbuf->flags = BK_QUEUE_INX; ++ break; ++ case HIGH_QUEUE_INX: ++ pxmitbuf->flags = HIGH_QUEUE_INX; ++ break; ++ default: ++ pxmitbuf->flags = MGT_QUEUE_INX; ++ break; ++ } ++ ++ spin_unlock_irqrestore(&pxmitpriv->lock, irqL); ++ ++ purb = pxmitbuf->pxmit_urb[0]; ++ ++ /* translate DMA FIFO addr to pipehandle */ ++ pipe = ffaddr2pipehdl(pdvobj, addr); ++ ++ usb_fill_bulk_urb(purb, pusbd, pipe, ++ pxmitframe->buf_addr, /* pxmitbuf->pbuf */ ++ cnt, ++ usb_write_port_complete, ++ pxmitbuf);/* context is pxmitbuf */ ++ ++ status = usb_submit_urb(purb, GFP_ATOMIC); ++ if (!status) { ++ struct hal_data_8188e *haldata = GET_HAL_DATA(padapter); ++ ++ haldata->srestpriv.last_tx_time = jiffies; ++ } else { ++ rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR); ++ DBG_88E("usb_write_port, status =%d\n", status); ++ ++ switch (status) { ++ case -ENODEV: ++ padapter->bDriverStopped = true; ++ break; ++ default: ++ break; ++ } ++ goto exit; ++ } ++ ++ ret = _SUCCESS; ++ ++/* We add the URB_ZERO_PACKET flag to urb so that the host will send the zero packet automatically. */ ++ ++exit: ++ if (ret != _SUCCESS) ++ rtw_free_xmitbuf(pxmitpriv, pxmitbuf); ++ ++ return ret; ++} ++ ++void usb_write_port_cancel(struct intf_hdl *pintfhdl) ++{ ++ int i, j; ++ struct adapter *padapter = pintfhdl->padapter; ++ struct xmit_buf *pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmitbuf; ++ ++ DBG_88E("%s\n", __func__); ++ ++ padapter->bWritePortCancel = true; ++ ++ for (i = 0; i < NR_XMITBUFF; i++) { ++ for (j = 0; j < 8; j++) { ++ if (pxmitbuf->pxmit_urb[j]) ++ usb_kill_urb(pxmitbuf->pxmit_urb[j]); ++ } ++ pxmitbuf++; ++ } ++ ++ pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmit_extbuf; ++ for (i = 0; i < NR_XMIT_EXTBUFF; i++) { ++ for (j = 0; j < 8; j++) { ++ if (pxmitbuf->pxmit_urb[j]) ++ usb_kill_urb(pxmitbuf->pxmit_urb[j]); ++ } ++ pxmitbuf++; ++ } ++} +diff --git a/drivers/staging/r8188eu/os_dep/xmit_linux.c b/drivers/staging/r8188eu/os_dep/xmit_linux.c +new file mode 100644 +index 000000000000..565ac5be7db3 +--- /dev/null ++++ b/drivers/staging/r8188eu/os_dep/xmit_linux.c +@@ -0,0 +1,251 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright(c) 2007 - 2012 Realtek Corporation. */ ++ ++#define _XMIT_OSDEP_C_ ++ ++#include "../include/osdep_service.h" ++#include "../include/drv_types.h" ++#include "../include/wifi.h" ++#include "../include/mlme_osdep.h" ++#include "../include/xmit_osdep.h" ++#include "../include/osdep_intf.h" ++#include "../include/usb_osintf.h" ++ ++uint rtw_remainder_len(struct pkt_file *pfile) ++{ ++ return pfile->buf_len - ((size_t)(pfile->cur_addr) - ++ (size_t)(pfile->buf_start)); ++} ++ ++void _rtw_open_pktfile(struct sk_buff *pktptr, struct pkt_file *pfile) ++{ ++ ++ if (!pktptr) { ++ pr_err("8188eu: pktptr is NULL\n"); ++ return; ++ } ++ if (!pfile) { ++ pr_err("8188eu: pfile is NULL\n"); ++ return; ++ } ++ pfile->pkt = pktptr; ++ pfile->cur_addr = pktptr->data; ++ pfile->buf_start = pktptr->data; ++ pfile->pkt_len = pktptr->len; ++ pfile->buf_len = pktptr->len; ++ ++ pfile->cur_buffer = pfile->buf_start; ++ ++} ++ ++uint _rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen) ++{ ++ uint len = 0; ++ ++ len = rtw_remainder_len(pfile); ++ len = (rlen > len) ? len : rlen; ++ ++ if (rmem) ++ skb_copy_bits(pfile->pkt, pfile->buf_len - pfile->pkt_len, rmem, len); ++ ++ pfile->cur_addr += len; ++ pfile->pkt_len -= len; ++ ++ return len; ++} ++ ++int rtw_endofpktfile(struct pkt_file *pfile) ++{ ++ ++ if (pfile->pkt_len == 0) { ++ ++ return true; ++ } ++ ++ return false; ++} ++ ++void rtw_set_tx_chksum_offload(struct sk_buff *pkt, struct pkt_attrib *pattrib) ++{ ++} ++ ++int rtw_os_xmit_resource_alloc(struct adapter *padapter, struct xmit_buf *pxmitbuf, u32 alloc_sz) ++{ ++ int i; ++ ++ pxmitbuf->pallocated_buf = kzalloc(alloc_sz, GFP_KERNEL); ++ if (!pxmitbuf->pallocated_buf) ++ return _FAIL; ++ ++ pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ); ++ pxmitbuf->dma_transfer_addr = 0; ++ ++ for (i = 0; i < 8; i++) { ++ pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL); ++ if (!pxmitbuf->pxmit_urb[i]) { ++ DBG_88E("pxmitbuf->pxmit_urb[i]==NULL"); ++ return _FAIL; ++ } ++ } ++ return _SUCCESS; ++} ++ ++void rtw_os_xmit_resource_free(struct adapter *padapter, ++ struct xmit_buf *pxmitbuf, u32 free_sz) ++{ ++ int i; ++ ++ for (i = 0; i < 8; i++) ++ usb_free_urb(pxmitbuf->pxmit_urb[i]); ++ ++ kfree(pxmitbuf->pallocated_buf); ++} ++ ++#define WMM_XMIT_THRESHOLD (NR_XMITFRAME * 2 / 5) ++ ++void rtw_os_pkt_complete(struct adapter *padapter, struct sk_buff *pkt) ++{ ++ u16 queue; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ ++ queue = skb_get_queue_mapping(pkt); ++ if (padapter->registrypriv.wifi_spec) { ++ if (__netif_subqueue_stopped(padapter->pnetdev, queue) && ++ (pxmitpriv->hwxmits[queue].accnt < WMM_XMIT_THRESHOLD)) ++ netif_wake_subqueue(padapter->pnetdev, queue); ++ } else { ++ if (__netif_subqueue_stopped(padapter->pnetdev, queue)) ++ netif_wake_subqueue(padapter->pnetdev, queue); ++ } ++ ++ dev_kfree_skb_any(pkt); ++} ++ ++void rtw_os_xmit_complete(struct adapter *padapter, struct xmit_frame *pxframe) ++{ ++ if (pxframe->pkt) ++ rtw_os_pkt_complete(padapter, pxframe->pkt); ++ pxframe->pkt = NULL; ++} ++ ++void rtw_os_xmit_schedule(struct adapter *padapter) ++{ ++ struct xmit_priv *pxmitpriv; ++ ++ if (!padapter) ++ return; ++ ++ pxmitpriv = &padapter->xmitpriv; ++ ++ spin_lock_bh(&pxmitpriv->lock); ++ ++ if (rtw_txframes_pending(padapter)) ++ tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); ++ ++ spin_unlock_bh(&pxmitpriv->lock); ++} ++ ++static void rtw_check_xmit_resource(struct adapter *padapter, struct sk_buff *pkt) ++{ ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ u16 queue; ++ ++ queue = skb_get_queue_mapping(pkt); ++ if (padapter->registrypriv.wifi_spec) { ++ /* No free space for Tx, tx_worker is too slow */ ++ if (pxmitpriv->hwxmits[queue].accnt > WMM_XMIT_THRESHOLD) ++ netif_stop_subqueue(padapter->pnetdev, queue); ++ } else { ++ if (pxmitpriv->free_xmitframe_cnt <= 4) { ++ if (!netif_tx_queue_stopped(netdev_get_tx_queue(padapter->pnetdev, queue))) ++ netif_stop_subqueue(padapter->pnetdev, queue); ++ } ++ } ++} ++ ++static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb) ++{ ++ struct sta_priv *pstapriv = &padapter->stapriv; ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct list_head *phead, *plist; ++ struct sk_buff *newskb; ++ struct sta_info *psta = NULL; ++ s32 res; ++ ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ phead = &pstapriv->asoc_list; ++ plist = phead->next; ++ ++ /* free sta asoc_queue */ ++ while (phead != plist) { ++ psta = container_of(plist, struct sta_info, asoc_list); ++ ++ plist = plist->next; ++ ++ /* avoid come from STA1 and send back STA1 */ ++ if (!memcmp(psta->hwaddr, &skb->data[6], 6)) ++ continue; ++ ++ newskb = skb_copy(skb, GFP_ATOMIC); ++ ++ if (newskb) { ++ memcpy(newskb->data, psta->hwaddr, 6); ++ res = rtw_xmit(padapter, &newskb); ++ if (res < 0) { ++ DBG_88E("%s()-%d: rtw_xmit() return error!\n", __func__, __LINE__); ++ pxmitpriv->tx_drop++; ++ dev_kfree_skb_any(newskb); ++ } else { ++ pxmitpriv->tx_pkts++; ++ } ++ } else { ++ DBG_88E("%s-%d: skb_copy() failed!\n", __func__, __LINE__); ++ pxmitpriv->tx_drop++; ++ ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ return false; /* Caller shall tx this multicast frame via normal way. */ ++ } ++ } ++ ++ spin_unlock_bh(&pstapriv->asoc_list_lock); ++ dev_kfree_skb_any(skb); ++ return true; ++} ++ ++int rtw_xmit_entry(struct sk_buff *pkt, struct net_device *pnetdev) ++{ ++ struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); ++ struct xmit_priv *pxmitpriv = &padapter->xmitpriv; ++ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; ++ s32 res = 0; ++ ++ if (!rtw_if_up(padapter)) ++ goto drop_packet; ++ ++ rtw_check_xmit_resource(padapter, pkt); ++ ++ if (!rtw_mc2u_disable && check_fwstate(pmlmepriv, WIFI_AP_STATE) && ++ (IP_MCAST_MAC(pkt->data) || ICMPV6_MCAST_MAC(pkt->data)) && ++ (padapter->registrypriv.wifi_spec == 0)) { ++ if (pxmitpriv->free_xmitframe_cnt > (NR_XMITFRAME / 4)) { ++ res = rtw_mlcst2unicst(padapter, pkt); ++ if (res) ++ goto exit; ++ } ++ } ++ ++ res = rtw_xmit(padapter, &pkt); ++ if (res < 0) ++ goto drop_packet; ++ ++ pxmitpriv->tx_pkts++; ++ goto exit; ++ ++drop_packet: ++ pxmitpriv->tx_drop++; ++ dev_kfree_skb_any(pkt); ++ ++exit: ++ ++ return 0; ++} diff --git a/kernel/tools/cpupowertools/pspec.xml b/kernel/tools/cpupowertools/pspec.xml index 55b67896..22a5adad 100644 --- a/kernel/tools/cpupowertools/pspec.xml +++ b/kernel/tools/cpupowertools/pspec.xml @@ -18,10 +18,10 @@ - patches/linux/patch-5.15.81.xz + patches/linux/patch-5.15.86.xz - patches/aufs5/aufs5.15.41-20220620.patch + patches/aufs5/aufs5.15.41-20221219.patch patches/aufs5/aufs5-base.patch patches/aufs5/aufs5-kbuild.patch patches/aufs5/aufs5-loopback.patch @@ -32,56 +32,56 @@ patches/mageia/fs-procfs-do-not-list-TID-0-in-proc-pid-task.patch - + patches/mageia/CVE-2019-12379.patch patches/mageia/CVE-2020-16119-DCCP-CCID-structure-use-after-free.patch - + patches/mageia/platform-x86-add-shuttle-wmi-driver.patch - patches/mageia/platform-x86-shuttle-wmi-drop-devinit-exit.patch - patches/mageia/platform-x86-shuttle-wmi-4.2-buildfix.patch - patches/mageia/platform-x86-shuttle-wmi-4.13-buildfix.patch - patches/mageia/platform-x86-shuttle-wmi-kernel-5.5.patch - + patches/mageia/platform-x86-shuttle-wmi-drop-devinit-exit.patch + patches/mageia/platform-x86-shuttle-wmi-4.2-buildfix.patch + patches/mageia/platform-x86-shuttle-wmi-4.13-buildfix.patch + patches/mageia/platform-x86-shuttle-wmi-kernel-5.5.patch + patches/mageia/3rd-3rdparty-tree.patch patches/mageia/3rd-3rdparty-merge.patch - + patches/mageia/3rd-ndiswrapper-1.63.patch patches/mageia/3rd-ndiswrapper-Kconfig.patch patches/mageia/3rd-ndiswrapper-Makefile-build-fix.patch patches/mageia/3rd-niswrapper-Kconfig-Makefile.patch - + patches/mageia/3rd-rtl8812au.patch patches/mageia/3rd-rtl8812au-Kconfig-Makefile.patch patches/mageia/3rd-rtl8812au-rename.patch patches/mageia/3rd-rtl8812au-kernel-5.12.patch patches/mageia/3rd-rtl8812au-kernel-5.15.patch - + patches/mageia/3rd-rtl8723de.patch patches/mageia/3rd-rtl8723de-Kconfig-Makefile.patch patches/mageia/3rd-rtl8723de-fix-redefine.patch patches/mageia/3rd-rtl8723de-nodebug.patch patches/mageia/3rd-rtl8223de-kernel-5.6.patch patches/mageia/3rd-rtl8723de-add-kernel-5.8-support.patch - + patches/mageia/3rd-viahss-0.92.patch patches/mageia/3rd-viahss-config.patch patches/mageia/3rd-viahss-module-license.patch patches/mageia/3rd-viahss-2.6.35-buildfix.patch patches/mageia/3rd-viahss-3.0-buildfix.patch patches/mageia/3rd-viahss-Kconfig-Makefile.patch - + patches/mageia/3rd-rtl8821ce.patch patches/mageia/3rd-rtl8821ce-Kconfig-Makefile.patch patches/mageia/3rd-rtl8821ce-5.8-fix.patch patches/mageia/3rd-rtl8821ce-kernel-5.10.patch patches/mageia/3rd-rtl8821ce-kernel-5.12.patch patches/mageia/3rd-rtl8821ce-kernel-5.15.patch - + patches/mageia/3rd-fix-kconfig.patch - - - - + + patches/mageia/net-wireless-rtw88-dont-check-CRC-of-VHT-SIG-B-in-802.11ac-signal.patch + patches/mageia/net-wireless-rtw89-add-Realtek-802.11ax-driver.patch + patches/mageia/net-wireless-rtw88-add-r8822be-alias.patch @@ -109,6 +109,13 @@ + + 2023-01-03 + 5.15.86 + Version bump + Mustafa Cinasal + muscnsl@gmail.com + 2022-12-07 5.15.81